Loading ...
Sorry, an error occurred while loading the content.

Re: [PATCH] (10/7) Consistency and refactoring

Expand Messages
  • ZyX
    “XXX undetected error” fix is the change described in the previous message. # HG changeset patch # User ZyX # Date 1371669021 -14400 #
    Message 1 of 25 , Jun 19, 2013
    • 0 Attachment
      “XXX undetected error” fix is the change described in the previous message.

      # HG changeset patch
      # User ZyX <kp-pav@...>
      # Date 1371669021 -14400
      # Wed Jun 19 23:10:21 2013 +0400
      # Branch python-fixes
      # Node ID 38acdea8fd7d2179916c4e67bdc8e54941929093
      # Parent 42e166b5c6ff07cd7810780b1d3704b8ce61bac0
      Some fixes:

      - Remove object_adder and attribute_getter populate_module arguments as they are
      now the same for both pythons.
      - Type cast PySequence_Fast_GET_SIZE
      - Make tests also work on python-2.7
      - Fix “XXX undetected error” problem (`if (PyErr_Occurred)` part).
      - Fix “negative refcount” crash (`Py_DECREF(rObj)` part)
      - Mark NotImplementedError’s in tests, also solve absence of sys problem in
      test86

      diff -r 42e166b5c6ff -r 38acdea8fd7d src/if_py_both.h
      --- a/src/if_py_both.h Mon Jun 17 07:54:07 2013 +0400
      +++ b/src/if_py_both.h Wed Jun 19 23:10:21 2013 +0400
      @@ -1610,7 +1610,7 @@

      ret = (rObj == Py_True);

      - Py_DECREF(Py_True);
      + Py_DECREF(rObj);

      return ret;
      }
      @@ -1909,7 +1909,7 @@
      PyErr_FORMAT(PyExc_ValueError,
      "expected sequence element of size 2, "
      "but got sequence of size %d",
      - PySequence_Fast_GET_SIZE(fast));
      + (int) PySequence_Fast_GET_SIZE(fast));
      return NULL;
      }

      @@ -2433,6 +2433,10 @@
      clear_tv(&v);
      }
      Py_DECREF(iterator);
      +
      + if (PyErr_Occurred())
      + return -1;
      +
      return 0;
      }

      @@ -3514,7 +3518,7 @@
      char *str;
      char *save;
      PyObject *bytes = NULL;
      - Py_ssize_t len;
      + Py_ssize_t len = 0;
      PyInt i;
      char *p;

      @@ -5479,6 +5483,7 @@
      #endif
      else if (PyObject_HasAttrString(obj, "keys"))
      return convert_dl(obj, tv, pymap_to_tv, lookup_dict);
      + /* PyObject_GetIter can create built-in iterator for any sequence object */
      else if (PyIter_Check(obj) || PySequence_Check(obj))
      return convert_dl(obj, tv, pyseq_to_tv, lookup_dict);
      else if (PyMapping_Check(obj))
      @@ -5926,11 +5931,8 @@
      {"_Loader", (PyObject *)&LoaderType},
      };

      -typedef int (*object_adder)(PyObject *, const char *, PyObject *);
      -typedef PyObject *(*attr_getter)(PyObject *, const char *);
      -
      #define ADD_OBJECT(m, name, obj) \
      - if (add_object(m, name, obj)) \
      + if (PyModule_AddObject(m, name, obj)) \
      return -1;

      #define ADD_CHECKED_OBJECT(m, name, obj) \
      @@ -5942,7 +5944,7 @@
      }

      static int
      -populate_module(PyObject *m, object_adder add_object, attr_getter get_attr)
      +populate_module(PyObject *m)
      {
      int i;
      PyObject *other_module;
      @@ -5986,7 +5988,7 @@
      if (!(py_chdir = PyObject_GetAttrString(other_module, "chdir")))
      return -1;
      ADD_OBJECT(m, "_chdir", py_chdir);
      - if (!(attr = get_attr(m, "chdir")))
      + if (!(attr = PyObject_GetAttrString(m, "chdir")))
      return -1;
      if (PyObject_SetAttrString(other_module, "chdir", attr))
      {
      @@ -5998,7 +6000,7 @@
      if ((py_fchdir = PyObject_GetAttrString(other_module, "fchdir")))
      {
      ADD_OBJECT(m, "_fchdir", py_fchdir);
      - if (!(attr = get_attr(m, "fchdir")))
      + if (!(attr = PyObject_GetAttrString(m, "fchdir")))
      return -1;
      if (PyObject_SetAttrString(other_module, "fchdir", attr))
      {
      diff -r 42e166b5c6ff -r 38acdea8fd7d src/if_python.c
      --- a/src/if_python.c Mon Jun 17 07:54:07 2013 +0400
      +++ b/src/if_python.c Wed Jun 19 23:10:21 2013 +0400
      @@ -1404,8 +1404,7 @@
      vim_module = Py_InitModule4("vim", VimMethods, (char *)NULL,
      (PyObject *)NULL, PYTHON_API_VERSION);

      - if (populate_module(vim_module, PyModule_AddObject,
      - PyObject_GetAttrString))
      + if (populate_module(vim_module))
      return -1;

      if (init_sys_path())
      diff -r 42e166b5c6ff -r 38acdea8fd7d src/if_python3.c
      --- a/src/if_python3.c Mon Jun 17 07:54:07 2013 +0400
      +++ b/src/if_python3.c Wed Jun 19 23:10:21 2013 +0400
      @@ -1623,7 +1623,7 @@
      if ((vim_module = PyModule_Create(&vimmodule)) == NULL)
      return NULL;

      - if (populate_module(vim_module, PyModule_AddObject, PyObject_GetAttrString))
      + if (populate_module(vim_module))
      return NULL;

      if (init_sys_path())
      diff -r 42e166b5c6ff -r 38acdea8fd7d src/testdir/test86.in
      --- a/src/testdir/test86.in Mon Jun 17 07:54:07 2013 +0400
      +++ b/src/testdir/test86.in Wed Jun 19 23:10:21 2013 +0400
      @@ -216,6 +216,7 @@
      :let messages=[]
      :delfunction DictNew
      py <<EOF
      +import sys
      d=vim.bindeval('{}')
      m=vim.bindeval('messages')
      def em(expr, g=globals(), l=locals()):
      @@ -297,7 +298,7 @@
      :" threading
      :let l = [0]
      :py l=vim.bindeval('l')
      -:py <<EOF
      +py <<EOF
      import threading
      import time

      @@ -327,7 +328,7 @@
      :" settrace
      :let l = []
      :py l=vim.bindeval('l')
      -:py <<EOF
      +py <<EOF
      import sys

      def traceit(frame, event, arg):
      @@ -880,10 +881,16 @@
      if expr.find('None') > -1:
      msg = msg.replace('TypeError:(\'iteration over non-sequence\',)',
      'TypeError:("\'NoneType\' object is not iterable",)')
      + if expr.find('FailingNumber') > -1:
      + msg = msg.replace(', not \'FailingNumber\'', '').replace('"', '\'')
      + msg = msg.replace('TypeError:(\'iteration over non-sequence\',)',
      + 'TypeError:("\'FailingNumber\' object is not iterable",)')
      + if msg.find('(\'\'') > -1 or msg.find('(\'can\'t') > -1:
      + msg = msg.replace('(\'', '("').replace('\',)', '",)')
      if expr == 'fd(self=[])':
      # HACK: PyMapping_Check changed meaning
      msg = msg.replace('AttributeError:(\'keys\',)',
      - 'TypeError:(\'unable to convert object to vim dictionary\',)')
      + 'TypeError:(\'unable to convert list to vim dictionary\',)')
      cb.append(expr + ':' + msg)
      else:
      cb.append(expr + ':NOT FAILED')
      @@ -968,37 +975,37 @@

      class FailingTrue(object):
      def __nonzero__(self):
      - raise NotImplementedError
      + raise NotImplementedError('bool')

      class FailingIter(object):
      def __iter__(self):
      - raise NotImplementedError
      + raise NotImplementedError('iter')

      class FailingIterNext(object):
      def __iter__(self):
      return self

      def next(self):
      - raise NotImplementedError
      + raise NotImplementedError('next')

      class FailingMappingKey(object):
      def __getitem__(self, item):
      - raise NotImplementedError
      + raise NotImplementedError('getitem:mappingkey')

      def keys(self):
      return list("abcH")

      class FailingMapping(object):
      def __getitem__(self):
      - raise NotImplementedError
      + raise NotImplementedError('getitem:mapping')

      def keys(self):
      - raise NotImplementedError
      + raise NotImplementedError('keys')

      class FailingList(list):
      def __getitem__(self, idx):
      if i == 2:
      - raise NotImplementedError
      + raise NotImplementedError('getitem:list')
      else:
      return super(FailingList, self).__getitem__(idx)

      @@ -1008,11 +1015,11 @@

      class FailingCall(object):
      def __call__(self, path):
      - raise NotImplementedError
      + raise NotImplementedError('call')

      class FailingNumber(object):
      def __int__(self):
      - raise NotImplementedError
      + raise NotImplementedError('int')

      cb.append("> Output")
      cb.append(">> OutputSetattr")
      @@ -1295,6 +1302,7 @@
      :call garbagecollect(1)
      :"
      :/^start:/,$wq! test.out
      +:" vim: et ts=4 isk-=\:
      :call getchar()
      ENDTEST

      diff -r 42e166b5c6ff -r 38acdea8fd7d src/testdir/test86.ok
      --- a/src/testdir/test86.ok Mon Jun 17 07:54:07 2013 +0400
      +++ b/src/testdir/test86.ok Wed Jun 19 23:10:21 2013 +0400
      @@ -458,8 +458,8 @@
      sys.stdout.writelines(None):TypeError:("'NoneType' object is not iterable",)
      sys.stdout.writelines([1]):TypeError:('coercing to Unicode: need string or buffer, int found',)
      >>> Testing *Iter* using sys.stdout.writelines(%s)
      -sys.stdout.writelines(FailingIter()):NotImplementedError:()
      -sys.stdout.writelines(FailingIterNext()):NotImplementedError:()
      +sys.stdout.writelines(FailingIter()):NotImplementedError:('iter',)
      +sys.stdout.writelines(FailingIterNext()):NotImplementedError:('next',)
      <<< Finished
      > VimCommand
      >>> Testing StringToChars using vim.command(%s)
      @@ -492,7 +492,7 @@
      > VimForeachRTP
      vim.foreach_rtp(None):TypeError:("'NoneType' object is not callable",)
      vim.foreach_rtp(NoArgsCall()):TypeError:('__call__() takes exactly 1 argument (2 given)',)
      -vim.foreach_rtp(FailingCall()):NotImplementedError:()
      +vim.foreach_rtp(FailingCall()):NotImplementedError:('call',)
      vim.foreach_rtp(int, 2):TypeError:('foreach_rtp() takes exactly one argument (2 given)',)
      > import
      import xxx_no_such_module_xxx:ImportError:('No module named xxx_no_such_module_xxx',)
      @@ -503,7 +503,7 @@
      vim.Dictionary("abcI"):ValueError:('expected sequence element of size 2, but got sequence of size 1',)
      >> DictionarySetattr
      del d.locked:AttributeError:('cannot delete vim.Dictionary attributes',)
      -d.locked = FailingTrue():NotImplementedError:()
      +d.locked = FailingTrue():NotImplementedError:('bool',)
      vim.vvars.locked = False:TypeError:('cannot modify fixed dictionary',)
      d.scope = True:AttributeError:('cannot set attribute scope',)
      d.xxx = True:AttributeError:('cannot set attribute xxx',)
      @@ -542,14 +542,14 @@
      <<< Finished
      >>> Testing *Iter* using d["a"] = {"abcF" : %s}
      d["a"] = {"abcF" : FailingIter()}:TypeError:('unable to convert FailingIter to vim structure',)
      -d["a"] = {"abcF" : FailingIterNext()}:NotImplementedError:()
      +d["a"] = {"abcF" : FailingIterNext()}:NotImplementedError:('next',)
      <<< Finished
      >>> Testing ConvertFromPyObject using d["a"] = {"abcF" : %s}
      d["a"] = {"abcF" : None}:TypeError:('unable to convert NoneType to vim structure',)
      d["a"] = {"abcF" : {"": 1}}:ValueError:('empty keys are not allowed',)
      d["a"] = {"abcF" : {u"": 1}}:ValueError:('empty keys are not allowed',)
      -d["a"] = {"abcF" : FailingMapping()}:NotImplementedError:()
      -d["a"] = {"abcF" : FailingMappingKey()}:NotImplementedError:()
      +d["a"] = {"abcF" : FailingMapping()}:NotImplementedError:('keys',)
      +d["a"] = {"abcF" : FailingMappingKey()}:NotImplementedError:('getitem:mappingkey',)
      d["a"] = {"abcF" : FailingNumber()}:TypeError:('long() argument must be a string or a number',)
      <<< Finished
      >>> Testing StringToChars using d["a"] = Mapping({%s : 1})
      @@ -569,36 +569,36 @@
      <<< Finished
      >>> Testing *Iter* using d["a"] = Mapping({"abcG" : %s})
      d["a"] = Mapping({"abcG" : FailingIter()}):TypeError:('unable to convert FailingIter to vim structure',)
      -d["a"] = Mapping({"abcG" : FailingIterNext()}):NotImplementedError:()
      +d["a"] = Mapping({"abcG" : FailingIterNext()}):NotImplementedError:('next',)
      <<< Finished
      >>> Testing ConvertFromPyObject using d["a"] = Mapping({"abcG" : %s})
      d["a"] = Mapping({"abcG" : None}):TypeError:('unable to convert NoneType to vim structure',)
      d["a"] = Mapping({"abcG" : {"": 1}}):ValueError:('empty keys are not allowed',)
      d["a"] = Mapping({"abcG" : {u"": 1}}):ValueError:('empty keys are not allowed',)
      -d["a"] = Mapping({"abcG" : FailingMapping()}):NotImplementedError:()
      -d["a"] = Mapping({"abcG" : FailingMappingKey()}):NotImplementedError:()
      +d["a"] = Mapping({"abcG" : FailingMapping()}):NotImplementedError:('keys',)
      +d["a"] = Mapping({"abcG" : FailingMappingKey()}):NotImplementedError:('getitem:mappingkey',)
      d["a"] = Mapping({"abcG" : FailingNumber()}):TypeError:('long() argument must be a string or a number',)
      <<< Finished
      >>> Testing *Iter* using d["a"] = %s
      d["a"] = FailingIter():TypeError:('unable to convert FailingIter to vim structure',)
      -d["a"] = FailingIterNext():NotImplementedError:()
      +d["a"] = FailingIterNext():NotImplementedError:('next',)
      <<< Finished
      >>> Testing ConvertFromPyObject using d["a"] = %s
      d["a"] = None:TypeError:('unable to convert NoneType to vim structure',)
      d["a"] = {"": 1}:ValueError:('empty keys are not allowed',)
      d["a"] = {u"": 1}:ValueError:('empty keys are not allowed',)
      -d["a"] = FailingMapping():NotImplementedError:()
      -d["a"] = FailingMappingKey():NotImplementedError:()
      +d["a"] = FailingMapping():NotImplementedError:('keys',)
      +d["a"] = FailingMappingKey():NotImplementedError:('getitem:mappingkey',)
      d["a"] = FailingNumber():TypeError:('long() argument must be a string or a number',)
      <<< Finished
      >> DictionaryUpdate
      >>> kwargs
      >>> iter
      -d.update(FailingMapping()):NotImplementedError:()
      -d.update([FailingIterNext()]):NotImplementedError:()
      +d.update(FailingMapping()):NotImplementedError:('keys',)
      +d.update([FailingIterNext()]):NotImplementedError:('next',)
      >>> Testing *Iter* using d.update(%s)
      -d.update(FailingIter()):NotImplementedError:()
      -d.update(FailingIterNext()):NotImplementedError:()
      +d.update(FailingIter()):NotImplementedError:('iter',)
      +d.update(FailingIterNext()):NotImplementedError:('next',)
      <<< Finished
      >>> Testing StringToChars using d.update({%s : 1})
      d.update({1 : 1}):TypeError:('expected str() or unicode() instance, but got int',)
      @@ -617,14 +617,14 @@
      <<< Finished
      >>> Testing *Iter* using d.update({"abcF" : %s})
      d.update({"abcF" : FailingIter()}):TypeError:('unable to convert FailingIter to vim structure',)
      -d.update({"abcF" : FailingIterNext()}):NotImplementedError:()
      +d.update({"abcF" : FailingIterNext()}):NotImplementedError:('next',)
      <<< Finished
      >>> Testing ConvertFromPyObject using d.update({"abcF" : %s})
      d.update({"abcF" : None}):TypeError:('unable to convert NoneType to vim structure',)
      d.update({"abcF" : {"": 1}}):ValueError:('empty keys are not allowed',)
      d.update({"abcF" : {u"": 1}}):ValueError:('empty keys are not allowed',)
      -d.update({"abcF" : FailingMapping()}):NotImplementedError:()
      -d.update({"abcF" : FailingMappingKey()}):NotImplementedError:()
      +d.update({"abcF" : FailingMapping()}):NotImplementedError:('keys',)
      +d.update({"abcF" : FailingMappingKey()}):NotImplementedError:('getitem:mappingkey',)
      d.update({"abcF" : FailingNumber()}):TypeError:('long() argument must be a string or a number',)
      <<< Finished
      >>> Testing StringToChars using d.update(Mapping({%s : 1}))
      @@ -644,27 +644,27 @@
      <<< Finished
      >>> Testing *Iter* using d.update(Mapping({"abcG" : %s}))
      d.update(Mapping({"abcG" : FailingIter()})):TypeError:('unable to convert FailingIter to vim structure',)
      -d.update(Mapping({"abcG" : FailingIterNext()})):NotImplementedError:()
      +d.update(Mapping({"abcG" : FailingIterNext()})):NotImplementedError:('next',)
      <<< Finished
      >>> Testing ConvertFromPyObject using d.update(Mapping({"abcG" : %s}))
      d.update(Mapping({"abcG" : None})):TypeError:('unable to convert NoneType to vim structure',)
      d.update(Mapping({"abcG" : {"": 1}})):ValueError:('empty keys are not allowed',)
      d.update(Mapping({"abcG" : {u"": 1}})):ValueError:('empty keys are not allowed',)
      -d.update(Mapping({"abcG" : FailingMapping()})):NotImplementedError:()
      -d.update(Mapping({"abcG" : FailingMappingKey()})):NotImplementedError:()
      +d.update(Mapping({"abcG" : FailingMapping()})):NotImplementedError:('keys',)
      +d.update(Mapping({"abcG" : FailingMappingKey()})):NotImplementedError:('getitem:mappingkey',)
      d.update(Mapping({"abcG" : FailingNumber()})):TypeError:('long() argument must be a string or a number',)
      <<< Finished
      >>> Testing *Iter* using d.update(%s)
      -d.update(FailingIter()):NotImplementedError:()
      -d.update(FailingIterNext()):NotImplementedError:()
      +d.update(FailingIter()):NotImplementedError:('iter',)
      +d.update(FailingIterNext()):NotImplementedError:('next',)
      <<< Finished
      >>> Testing ConvertFromPyObject using d.update(%s)
      d.update(None):TypeError:("'NoneType' object is not iterable",)
      d.update({"": 1}):ValueError:('empty keys are not allowed',)
      d.update({u"": 1}):ValueError:('empty keys are not allowed',)
      -d.update(FailingMapping()):NotImplementedError:()
      -d.update(FailingMappingKey()):NotImplementedError:()
      -d.update(FailingNumber()):TypeError:('iteration over non-sequence',)
      +d.update(FailingMapping()):NotImplementedError:('keys',)
      +d.update(FailingMappingKey()):NotImplementedError:('getitem:mappingkey',)
      +d.update(FailingNumber()):TypeError:("'FailingNumber' object is not iterable",)
      <<< Finished
      >>> Testing StringToChars using d.update(((%s, 0),))
      d.update(((1, 0),)):TypeError:('expected str() or unicode() instance, but got int',)
      @@ -688,14 +688,14 @@
      <<< Finished
      >>> Testing *Iter* using d.update((("a", {"abcF" : %s}),))
      d.update((("a", {"abcF" : FailingIter()}),)):TypeError:('unable to convert FailingIter to vim structure',)
      -d.update((("a", {"abcF" : FailingIterNext()}),)):NotImplementedError:()
      +d.update((("a", {"abcF" : FailingIterNext()}),)):NotImplementedError:('next',)
      <<< Finished
      >>> Testing ConvertFromPyObject using d.update((("a", {"abcF" : %s}),))
      d.update((("a", {"abcF" : None}),)):TypeError:('unable to convert NoneType to vim structure',)
      d.update((("a", {"abcF" : {"": 1}}),)):ValueError:('empty keys are not allowed',)
      d.update((("a", {"abcF" : {u"": 1}}),)):ValueError:('empty keys are not allowed',)
      -d.update((("a", {"abcF" : FailingMapping()}),)):NotImplementedError:()
      -d.update((("a", {"abcF" : FailingMappingKey()}),)):NotImplementedError:()
      +d.update((("a", {"abcF" : FailingMapping()}),)):NotImplementedError:('keys',)
      +d.update((("a", {"abcF" : FailingMappingKey()}),)):NotImplementedError:('getitem:mappingkey',)
      d.update((("a", {"abcF" : FailingNumber()}),)):TypeError:('long() argument must be a string or a number',)
      <<< Finished
      >>> Testing StringToChars using d.update((("a", Mapping({%s : 1})),))
      @@ -715,26 +715,26 @@
      <<< Finished
      >>> Testing *Iter* using d.update((("a", Mapping({"abcG" : %s})),))
      d.update((("a", Mapping({"abcG" : FailingIter()})),)):TypeError:('unable to convert FailingIter to vim structure',)
      -d.update((("a", Mapping({"abcG" : FailingIterNext()})),)):NotImplementedError:()
      +d.update((("a", Mapping({"abcG" : FailingIterNext()})),)):NotImplementedError:('next',)
      <<< Finished
      >>> Testing ConvertFromPyObject using d.update((("a", Mapping({"abcG" : %s})),))
      d.update((("a", Mapping({"abcG" : None})),)):TypeError:('unable to convert NoneType to vim structure',)
      d.update((("a", Mapping({"abcG" : {"": 1}})),)):ValueError:('empty keys are not allowed',)
      d.update((("a", Mapping({"abcG" : {u"": 1}})),)):ValueError:('empty keys are not allowed',)
      -d.update((("a", Mapping({"abcG" : FailingMapping()})),)):NotImplementedError:()
      -d.update((("a", Mapping({"abcG" : FailingMappingKey()})),)):NotImplementedError:()
      +d.update((("a", Mapping({"abcG" : FailingMapping()})),)):NotImplementedError:('keys',)
      +d.update((("a", Mapping({"abcG" : FailingMappingKey()})),)):NotImplementedError:('getitem:mappingkey',)
      d.update((("a", Mapping({"abcG" : FailingNumber()})),)):TypeError:('long() argument must be a string or a number',)
      <<< Finished
      >>> Testing *Iter* using d.update((("a", %s),))
      d.update((("a", FailingIter()),)):TypeError:('unable to convert FailingIter to vim structure',)
      -d.update((("a", FailingIterNext()),)):NotImplementedError:()
      +d.update((("a", FailingIterNext()),)):NotImplementedError:('next',)
      <<< Finished
      >>> Testing ConvertFromPyObject using d.update((("a", %s),))
      d.update((("a", None),)):TypeError:('unable to convert NoneType to vim structure',)
      d.update((("a", {"": 1}),)):ValueError:('empty keys are not allowed',)
      d.update((("a", {u"": 1}),)):ValueError:('empty keys are not allowed',)
      -d.update((("a", FailingMapping()),)):NotImplementedError:()
      -d.update((("a", FailingMappingKey()),)):NotImplementedError:()
      +d.update((("a", FailingMapping()),)):NotImplementedError:('keys',)
      +d.update((("a", FailingMappingKey()),)):NotImplementedError:('getitem:mappingkey',)
      d.update((("a", FailingNumber()),)):TypeError:('long() argument must be a string or a number',)
      <<< Finished
      >> DictionaryPopItem
      @@ -746,8 +746,8 @@
      vim.List(1, 2):TypeError:('function takes at most 1 argument (2 given)',)
      vim.List(a=1):TypeError:('list constructor does not accept keyword arguments',)
      >>> Testing *Iter* using vim.List(%s)
      -vim.List(FailingIter()):NotImplementedError:()
      -vim.List(FailingIterNext()):NotImplementedError:()
      +vim.List(FailingIter()):NotImplementedError:('iter',)
      +vim.List(FailingIterNext()):NotImplementedError:('next',)
      <<< Finished
      >>> Testing StringToChars using vim.List([{%s : 1}])
      vim.List([{1 : 1}]):TypeError:('expected str() or unicode() instance, but got int',)
      @@ -766,14 +766,14 @@
      <<< Finished
      >>> Testing *Iter* using vim.List([{"abcF" : %s}])
      vim.List([{"abcF" : FailingIter()}]):TypeError:('unable to convert FailingIter to vim structure',)
      -vim.List([{"abcF" : FailingIterNext()}]):NotImplementedError:()
      +vim.List([{"abcF" : FailingIterNext()}]):NotImplementedError:('next',)
      <<< Finished
      >>> Testing ConvertFromPyObject using vim.List([{"abcF" : %s}])
      vim.List([{"abcF" : None}]):TypeError:('unable to convert NoneType to vim structure',)
      vim.List([{"abcF" : {"": 1}}]):ValueError:('empty keys are not allowed',)
      vim.List([{"abcF" : {u"": 1}}]):ValueError:('empty keys are not allowed',)
      -vim.List([{"abcF" : FailingMapping()}]):NotImplementedError:()
      -vim.List([{"abcF" : FailingMappingKey()}]):NotImplementedError:()
      +vim.List([{"abcF" : FailingMapping()}]):NotImplementedError:('keys',)
      +vim.List([{"abcF" : FailingMappingKey()}]):NotImplementedError:('getitem:mappingkey',)
      vim.List([{"abcF" : FailingNumber()}]):TypeError:('long() argument must be a string or a number',)
      <<< Finished
      >>> Testing StringToChars using vim.List([Mapping({%s : 1})])
      @@ -793,26 +793,26 @@
      <<< Finished
      >>> Testing *Iter* using vim.List([Mapping({"abcG" : %s})])
      vim.List([Mapping({"abcG" : FailingIter()})]):TypeError:('unable to convert FailingIter to vim structure',)
      -vim.List([Mapping({"abcG" : FailingIterNext()})]):NotImplementedError:()
      +vim.List([Mapping({"abcG" : FailingIterNext()})]):NotImplementedError:('next',)
      <<< Finished
      >>> Testing ConvertFromPyObject using vim.List([Mapping({"abcG" : %s})])
      vim.List([Mapping({"abcG" : None})]):TypeError:('unable to convert NoneType to vim structure',)
      vim.List([Mapping({"abcG" : {"": 1}})]):ValueError:('empty keys are not allowed',)
      vim.List([Mapping({"abcG" : {u"": 1}})]):ValueError:('empty keys are not allowed',)
      -vim.List([Mapping({"abcG" : FailingMapping()})]):NotImplementedError:()
      -vim.List([Mapping({"abcG" : FailingMappingKey()})]):NotImplementedError:()
      +vim.List([Mapping({"abcG" : FailingMapping()})]):NotImplementedError:('keys',)
      +vim.List([Mapping({"abcG" : FailingMappingKey()})]):NotImplementedError:('getitem:mappingkey',)
      vim.List([Mapping({"abcG" : FailingNumber()})]):TypeError:('long() argument must be a string or a number',)
      <<< Finished
      >>> Testing *Iter* using vim.List([%s])
      vim.List([FailingIter()]):TypeError:('unable to convert FailingIter to vim structure',)
      -vim.List([FailingIterNext()]):NotImplementedError:()
      +vim.List([FailingIterNext()]):NotImplementedError:('next',)
      <<< Finished
      >>> Testing ConvertFromPyObject using vim.List([%s])
      vim.List([None]):TypeError:('unable to convert NoneType to vim structure',)
      vim.List([{"": 1}]):ValueError:('empty keys are not allowed',)
      vim.List([{u"": 1}]):ValueError:('empty keys are not allowed',)
      -vim.List([FailingMapping()]):NotImplementedError:()
      -vim.List([FailingMappingKey()]):NotImplementedError:()
      +vim.List([FailingMapping()]):NotImplementedError:('keys',)
      +vim.List([FailingMappingKey()]):NotImplementedError:('getitem:mappingkey',)
      vim.List([FailingNumber()]):TypeError:('long() argument must be a string or a number',)
      <<< Finished
      >> ListItem
      @@ -823,8 +823,8 @@
      >> ListAssSlice
      ll[1:100] = "abcJ":error:('list is locked',)
      >>> Testing *Iter* using l[:] = %s
      -l[:] = FailingIter():NotImplementedError:()
      -l[:] = FailingIterNext():NotImplementedError:()
      +l[:] = FailingIter():NotImplementedError:('iter',)
      +l[:] = FailingIterNext():NotImplementedError:('next',)
      <<< Finished
      >>> Testing StringToChars using l[:] = [{%s : 1}]
      l[:] = [{1 : 1}]:TypeError:('expected str() or unicode() instance, but got int',)
      @@ -843,14 +843,14 @@
      <<< Finished
      >>> Testing *Iter* using l[:] = [{"abcF" : %s}]
      l[:] = [{"abcF" : FailingIter()}]:TypeError:('unable to convert FailingIter to vim structure',)
      -l[:] = [{"abcF" : FailingIterNext()}]:NotImplementedError:()
      +l[:] = [{"abcF" : FailingIterNext()}]:NotImplementedError:('next',)
      <<< Finished
      >>> Testing ConvertFromPyObject using l[:] = [{"abcF" : %s}]
      l[:] = [{"abcF" : None}]:TypeError:('unable to convert NoneType to vim structure',)
      l[:] = [{"abcF" : {"": 1}}]:ValueError:('empty keys are not allowed',)
      l[:] = [{"abcF" : {u"": 1}}]:ValueError:('empty keys are not allowed',)
      -l[:] = [{"abcF" : FailingMapping()}]:NotImplementedError:()
      -l[:] = [{"abcF" : FailingMappingKey()}]:NotImplementedError:()
      +l[:] = [{"abcF" : FailingMapping()}]:NotImplementedError:('keys',)
      +l[:] = [{"abcF" : FailingMappingKey()}]:NotImplementedError:('getitem:mappingkey',)
      l[:] = [{"abcF" : FailingNumber()}]:TypeError:('long() argument must be a string or a number',)
      <<< Finished
      >>> Testing StringToChars using l[:] = [Mapping({%s : 1})]
      @@ -870,32 +870,32 @@
      <<< Finished
      >>> Testing *Iter* using l[:] = [Mapping({"abcG" : %s})]
      l[:] = [Mapping({"abcG" : FailingIter()})]:TypeError:('unable to convert FailingIter to vim structure',)
      -l[:] = [Mapping({"abcG" : FailingIterNext()})]:NotImplementedError:()
      +l[:] = [Mapping({"abcG" : FailingIterNext()})]:NotImplementedError:('next',)
      <<< Finished
      >>> Testing ConvertFromPyObject using l[:] = [Mapping({"abcG" : %s})]
      l[:] = [Mapping({"abcG" : None})]:TypeError:('unable to convert NoneType to vim structure',)
      l[:] = [Mapping({"abcG" : {"": 1}})]:ValueError:('empty keys are not allowed',)
      l[:] = [Mapping({"abcG" : {u"": 1}})]:ValueError:('empty keys are not allowed',)
      -l[:] = [Mapping({"abcG" : FailingMapping()})]:NotImplementedError:()
      -l[:] = [Mapping({"abcG" : FailingMappingKey()})]:NotImplementedError:()
      +l[:] = [Mapping({"abcG" : FailingMapping()})]:NotImplementedError:('keys',)
      +l[:] = [Mapping({"abcG" : FailingMappingKey()})]:NotImplementedError:('getitem:mappingkey',)
      l[:] = [Mapping({"abcG" : FailingNumber()})]:TypeError:('long() argument must be a string or a number',)
      <<< Finished
      >>> Testing *Iter* using l[:] = [%s]
      l[:] = [FailingIter()]:TypeError:('unable to convert FailingIter to vim structure',)
      -l[:] = [FailingIterNext()]:NotImplementedError:()
      +l[:] = [FailingIterNext()]:NotImplementedError:('next',)
      <<< Finished
      >>> Testing ConvertFromPyObject using l[:] = [%s]
      l[:] = [None]:TypeError:('unable to convert NoneType to vim structure',)
      l[:] = [{"": 1}]:ValueError:('empty keys are not allowed',)
      l[:] = [{u"": 1}]:ValueError:('empty keys are not allowed',)
      -l[:] = [FailingMapping()]:NotImplementedError:()
      -l[:] = [FailingMappingKey()]:NotImplementedError:()
      +l[:] = [FailingMapping()]:NotImplementedError:('keys',)
      +l[:] = [FailingMappingKey()]:NotImplementedError:('getitem:mappingkey',)
      l[:] = [FailingNumber()]:TypeError:('long() argument must be a string or a number',)
      <<< Finished
      >> ListConcatInPlace
      >>> Testing *Iter* using l.extend(%s)
      -l.extend(FailingIter()):NotImplementedError:()
      -l.extend(FailingIterNext()):NotImplementedError:()
      +l.extend(FailingIter()):NotImplementedError:('iter',)
      +l.extend(FailingIterNext()):NotImplementedError:('next',)
      <<< Finished
      >>> Testing StringToChars using l.extend([{%s : 1}])
      l.extend([{1 : 1}]):TypeError:('expected str() or unicode() instance, but got int',)
      @@ -914,14 +914,14 @@
      <<< Finished
      >>> Testing *Iter* using l.extend([{"abcF" : %s}])
      l.extend([{"abcF" : FailingIter()}]):TypeError:('unable to convert FailingIter to vim structure',)
      -l.extend([{"abcF" : FailingIterNext()}]):NotImplementedError:()
      +l.extend([{"abcF" : FailingIterNext()}]):NotImplementedError:('next',)
      <<< Finished
      >>> Testing ConvertFromPyObject using l.extend([{"abcF" : %s}])
      l.extend([{"abcF" : None}]):TypeError:('unable to convert NoneType to vim structure',)
      l.extend([{"abcF" : {"": 1}}]):ValueError:('empty keys are not allowed',)
      l.extend([{"abcF" : {u"": 1}}]):ValueError:('empty keys are not allowed',)
      -l.extend([{"abcF" : FailingMapping()}]):NotImplementedError:()
      -l.extend([{"abcF" : FailingMappingKey()}]):NotImplementedError:()
      +l.extend([{"abcF" : FailingMapping()}]):NotImplementedError:('keys',)
      +l.extend([{"abcF" : FailingMappingKey()}]):NotImplementedError:('getitem:mappingkey',)
      l.extend([{"abcF" : FailingNumber()}]):TypeError:('long() argument must be a string or a number',)
      <<< Finished
      >>> Testing StringToChars using l.extend([Mapping({%s : 1})])
      @@ -941,31 +941,31 @@
      <<< Finished
      >>> Testing *Iter* using l.extend([Mapping({"abcG" : %s})])
      l.extend([Mapping({"abcG" : FailingIter()})]):TypeError:('unable to convert FailingIter to vim structure',)
      -l.extend([Mapping({"abcG" : FailingIterNext()})]):NotImplementedError:()
      +l.extend([Mapping({"abcG" : FailingIterNext()})]):NotImplementedError:('next',)
      <<< Finished
      >>> Testing ConvertFromPyObject using l.extend([Mapping({"abcG" : %s})])
      l.extend([Mapping({"abcG" : None})]):TypeError:('unable to convert NoneType to vim structure',)
      l.extend([Mapping({"abcG" : {"": 1}})]):ValueError:('empty keys are not allowed',)
      l.extend([Mapping({"abcG" : {u"": 1}})]):ValueError:('empty keys are not allowed',)
      -l.extend([Mapping({"abcG" : FailingMapping()})]):NotImplementedError:()
      -l.extend([Mapping({"abcG" : FailingMappingKey()})]):NotImplementedError:()
      +l.extend([Mapping({"abcG" : FailingMapping()})]):NotImplementedError:('keys',)
      +l.extend([Mapping({"abcG" : FailingMappingKey()})]):NotImplementedError:('getitem:mappingkey',)
      l.extend([Mapping({"abcG" : FailingNumber()})]):TypeError:('long() argument must be a string or a number',)
      <<< Finished
      >>> Testing *Iter* using l.extend([%s])
      l.extend([FailingIter()]):TypeError:('unable to convert FailingIter to vim structure',)
      -l.extend([FailingIterNext()]):NotImplementedError:()
      +l.extend([FailingIterNext()]):NotImplementedError:('next',)
      <<< Finished
      >>> Testing ConvertFromPyObject using l.extend([%s])
      l.extend([None]):TypeError:('unable to convert NoneType to vim structure',)
      l.extend([{"": 1}]):ValueError:('empty keys are not allowed',)
      l.extend([{u"": 1}]):ValueError:('empty keys are not allowed',)
      -l.extend([FailingMapping()]):NotImplementedError:()
      -l.extend([FailingMappingKey()]):NotImplementedError:()
      +l.extend([FailingMapping()]):NotImplementedError:('keys',)
      +l.extend([FailingMappingKey()]):NotImplementedError:('getitem:mappingkey',)
      l.extend([FailingNumber()]):TypeError:('long() argument must be a string or a number',)
      <<< Finished
      >> ListSetattr
      del l.locked:AttributeError:('cannot delete vim.List attributes',)
      -l.locked = FailingTrue():NotImplementedError:()
      +l.locked = FailingTrue():NotImplementedError:('bool',)
      l.xxx = True:AttributeError:('cannot set attribute xxx',)
      > Function
      >> FunctionConstructor
      @@ -990,14 +990,14 @@
      <<< Finished
      >>> Testing *Iter* using f({"abcF" : %s})
      f({"abcF" : FailingIter()}):TypeError:('unable to convert FailingIter to vim structure',)
      -f({"abcF" : FailingIterNext()}):NotImplementedError:()
      +f({"abcF" : FailingIterNext()}):NotImplementedError:('next',)
      <<< Finished
      >>> Testing ConvertFromPyObject using f({"abcF" : %s})
      f({"abcF" : None}):TypeError:('unable to convert NoneType to vim structure',)
      f({"abcF" : {"": 1}}):ValueError:('empty keys are not allowed',)
      f({"abcF" : {u"": 1}}):ValueError:('empty keys are not allowed',)
      -f({"abcF" : FailingMapping()}):NotImplementedError:()
      -f({"abcF" : FailingMappingKey()}):NotImplementedError:()
      +f({"abcF" : FailingMapping()}):NotImplementedError:('keys',)
      +f({"abcF" : FailingMappingKey()}):NotImplementedError:('getitem:mappingkey',)
      f({"abcF" : FailingNumber()}):TypeError:('long() argument must be a string or a number',)
      <<< Finished
      >>> Testing StringToChars using f(Mapping({%s : 1}))
      @@ -1017,26 +1017,26 @@
      <<< Finished
      >>> Testing *Iter* using f(Mapping({"abcG" : %s}))
      f(Mapping({"abcG" : FailingIter()})):TypeError:('unable to convert FailingIter to vim structure',)
      -f(Mapping({"abcG" : FailingIterNext()})):NotImplementedError:()
      +f(Mapping({"abcG" : FailingIterNext()})):NotImplementedError:('next',)
      <<< Finished
      >>> Testing ConvertFromPyObject using f(Mapping({"abcG" : %s}))
      f(Mapping({"abcG" : None})):TypeError:('unable to convert NoneType to vim structure',)
      f(Mapping({"abcG" : {"": 1}})):ValueError:('empty keys are not allowed',)
      f(Mapping({"abcG" : {u"": 1}})):ValueError:('empty keys are not allowed',)
      -f(Mapping({"abcG" : FailingMapping()})):NotImplementedError:()
      -f(Mapping({"abcG" : FailingMappingKey()})):NotImplementedError:()
      +f(Mapping({"abcG" : FailingMapping()})):NotImplementedError:('keys',)
      +f(Mapping({"abcG" : FailingMappingKey()})):NotImplementedError:('getitem:mappingkey',)
      f(Mapping({"abcG" : FailingNumber()})):TypeError:('long() argument must be a string or a number',)
      <<< Finished
      >>> Testing *Iter* using f(%s)
      f(FailingIter()):TypeError:('unable to convert FailingIter to vim structure',)
      -f(FailingIterNext()):NotImplementedError:()
      +f(FailingIterNext()):NotImplementedError:('next',)
      <<< Finished
      >>> Testing ConvertFromPyObject using f(%s)
      f(None):TypeError:('unable to convert NoneType to vim structure',)
      f({"": 1}):ValueError:('empty keys are not allowed',)
      f({u"": 1}):ValueError:('empty keys are not allowed',)
      -f(FailingMapping()):NotImplementedError:()
      -f(FailingMappingKey()):NotImplementedError:()
      +f(FailingMapping()):NotImplementedError:('keys',)
      +f(FailingMappingKey()):NotImplementedError:('getitem:mappingkey',)
      f(FailingNumber()):TypeError:('long() argument must be a string or a number',)
      <<< Finished
      >>> Testing StringToChars using fd(self={%s : 1})
      @@ -1056,14 +1056,14 @@
      <<< Finished
      >>> Testing *Iter* using fd(self={"abcF" : %s})
      fd(self={"abcF" : FailingIter()}):TypeError:('unable to convert FailingIter to vim structure',)
      -fd(self={"abcF" : FailingIterNext()}):NotImplementedError:()
      +fd(self={"abcF" : FailingIterNext()}):NotImplementedError:('next',)
      <<< Finished
      >>> Testing ConvertFromPyObject using fd(self={"abcF" : %s})
      fd(self={"abcF" : None}):TypeError:('unable to convert NoneType to vim structure',)
      fd(self={"abcF" : {"": 1}}):ValueError:('empty keys are not allowed',)
      fd(self={"abcF" : {u"": 1}}):ValueError:('empty keys are not allowed',)
      -fd(self={"abcF" : FailingMapping()}):NotImplementedError:()
      -fd(self={"abcF" : FailingMappingKey()}):NotImplementedError:()
      +fd(self={"abcF" : FailingMapping()}):NotImplementedError:('keys',)
      +fd(self={"abcF" : FailingMappingKey()}):NotImplementedError:('getitem:mappingkey',)
      fd(self={"abcF" : FailingNumber()}):TypeError:('long() argument must be a string or a number',)
      <<< Finished
      >>> Testing StringToChars using fd(self=Mapping({%s : 1}))
      @@ -1083,14 +1083,14 @@
      <<< Finished
      >>> Testing *Iter* using fd(self=Mapping({"abcG" : %s}))
      fd(self=Mapping({"abcG" : FailingIter()})):TypeError:('unable to convert FailingIter to vim structure',)
      -fd(self=Mapping({"abcG" : FailingIterNext()})):NotImplementedError:()
      +fd(self=Mapping({"abcG" : FailingIterNext()})):NotImplementedError:('next',)
      <<< Finished
      >>> Testing ConvertFromPyObject using fd(self=Mapping({"abcG" : %s}))
      fd(self=Mapping({"abcG" : None})):TypeError:('unable to convert NoneType to vim structure',)
      fd(self=Mapping({"abcG" : {"": 1}})):ValueError:('empty keys are not allowed',)
      fd(self=Mapping({"abcG" : {u"": 1}})):ValueError:('empty keys are not allowed',)
      -fd(self=Mapping({"abcG" : FailingMapping()})):NotImplementedError:()
      -fd(self=Mapping({"abcG" : FailingMappingKey()})):NotImplementedError:()
      +fd(self=Mapping({"abcG" : FailingMapping()})):NotImplementedError:('keys',)
      +fd(self=Mapping({"abcG" : FailingMappingKey()})):NotImplementedError:('getitem:mappingkey',)
      fd(self=Mapping({"abcG" : FailingNumber()})):TypeError:('long() argument must be a string or a number',)
      <<< Finished
      >>> Testing *Iter* using fd(self=%s)
      @@ -1101,12 +1101,12 @@
      fd(self=None):TypeError:('unable to convert NoneType to vim dictionary',)
      fd(self={"": 1}):ValueError:('empty keys are not allowed',)
      fd(self={u"": 1}):ValueError:('empty keys are not allowed',)
      -fd(self=FailingMapping()):NotImplementedError:()
      -fd(self=FailingMappingKey()):NotImplementedError:()
      +fd(self=FailingMapping()):NotImplementedError:('keys',)
      +fd(self=FailingMappingKey()):NotImplementedError:('getitem:mappingkey',)
      fd(self=FailingNumber()):TypeError:('unable to convert FailingNumber to vim dictionary',)
      <<< Finished
      >>> Testing ConvertFromPyMapping using fd(self=%s)
      -fd(self=[]):TypeError:('unable to convert object to vim dictionary',)
      +fd(self=[]):TypeError:('unable to convert list to vim dictionary',)
      <<< Finished
      > TabPage
      >> TabPageAttr
      diff -r 42e166b5c6ff -r 38acdea8fd7d src/testdir/test87.in
      --- a/src/testdir/test87.in Mon Jun 17 07:54:07 2013 +0400
      +++ b/src/testdir/test87.in Wed Jun 19 23:10:21 2013 +0400
      @@ -290,7 +290,7 @@
      :" threading
      :let l = [0]
      :py3 l=vim.bindeval('l')
      -:py3 <<EOF
      +py3 <<EOF
      import threading
      import time

      @@ -320,7 +320,7 @@
      :" settrace
      :let l = []
      :py3 l=vim.bindeval('l')
      -:py3 <<EOF
      +py3 <<EOF
      import sys

      def traceit(frame, event, arg):
      @@ -924,37 +924,37 @@

      class FailingTrue(object):
      def __bool__(self):
      - raise NotImplementedError
      + raise NotImplementedError('bool')

      class FailingIter(object):
      def __iter__(self):
      - raise NotImplementedError
      + raise NotImplementedError('iter')

      class FailingIterNext(object):
      def __iter__(self):
      return self

      def __next__(self):
      - raise NotImplementedError
      + raise NotImplementedError('next')

      class FailingMappingKey(object):
      def __getitem__(self, item):
      - raise NotImplementedError
      + raise NotImplementedError('getitem:mappingkey')

      def keys(self):
      return list("abcH")

      class FailingMapping(object):
      def __getitem__(self):
      - raise NotImplementedError
      + raise NotImplementedError('getitem:mapping')

      def keys(self):
      - raise NotImplementedError
      + raise NotImplementedError('keys')

      class FailingList(list):
      def __getitem__(self, idx):
      if i == 2:
      - raise NotImplementedError
      + raise NotImplementedError('getitem:list')
      else:
      return super(FailingList, self).__getitem__(idx)

      @@ -964,11 +964,11 @@

      class FailingCall(object):
      def __call__(self, path):
      - raise NotImplementedError
      + raise NotImplementedError('call')

      class FailingNumber(object):
      def __int__(self):
      - raise NotImplementedError
      + raise NotImplementedError('int')

      cb.append("> Output")
      cb.append(">> OutputSetattr")
      @@ -1251,6 +1251,7 @@
      :call garbagecollect(1)
      :"
      :/^start:/,$wq! test.out
      +:" vim: et ts=4 isk-=\:
      :call getchar()
      ENDTEST

      diff -r 42e166b5c6ff -r 38acdea8fd7d src/testdir/test87.ok
      --- a/src/testdir/test87.ok Mon Jun 17 07:54:07 2013 +0400
      +++ b/src/testdir/test87.ok Wed Jun 19 23:10:21 2013 +0400
      @@ -447,8 +447,8 @@
      sys.stdout.writelines(None):(<class 'TypeError'>, TypeError("'NoneType' object is not iterable",))
      sys.stdout.writelines([1]):(<class 'TypeError'>, TypeError("Can't convert 'int' object to str implicitly",))
      >>> Testing *Iter* using sys.stdout.writelines(%s)
      -sys.stdout.writelines(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError())
      -sys.stdout.writelines(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError())
      +sys.stdout.writelines(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError('iter',))
      +sys.stdout.writelines(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
      <<< Finished
      > VimCommand
      >>> Testing StringToChars using vim.command(%s)
      @@ -481,7 +481,7 @@
      > VimForeachRTP
      vim.foreach_rtp(None):(<class 'TypeError'>, TypeError("'NoneType' object is not callable",))
      vim.foreach_rtp(NoArgsCall()):(<class 'TypeError'>, TypeError('__call__() takes exactly 1 positional argument (2 given)',))
      -vim.foreach_rtp(FailingCall()):(<class 'NotImplementedError'>, NotImplementedError())
      +vim.foreach_rtp(FailingCall()):(<class 'NotImplementedError'>, NotImplementedError('call',))
      vim.foreach_rtp(int, 2):(<class 'TypeError'>, TypeError('foreach_rtp() takes exactly one argument (2 given)',))
      > import
      import xxx_no_such_module_xxx:(<class 'ImportError'>, ImportError('No module named xxx_no_such_module_xxx',))
      @@ -492,7 +492,7 @@
      vim.Dictionary("abcI"):(<class 'ValueError'>, ValueError('expected sequence element of size 2, but got sequence of size 1',))
      >> DictionarySetattr
      del d.locked:(<class 'AttributeError'>, AttributeError('cannot delete vim.Dictionary attributes',))
      -d.locked = FailingTrue():(<class 'NotImplementedError'>, NotImplementedError())
      +d.locked = FailingTrue():(<class 'NotImplementedError'>, NotImplementedError('bool',))
      vim.vvars.locked = False:(<class 'TypeError'>, TypeError('cannot modify fixed dictionary',))
      d.scope = True:(<class 'AttributeError'>, AttributeError('cannot set attribute scope',))
      d.xxx = True:(<class 'AttributeError'>, AttributeError('cannot set attribute xxx',))
      @@ -531,15 +531,15 @@
      <<< Finished
      >>> Testing *Iter* using d["a"] = {"abcF" : %s}
      d["a"] = {"abcF" : FailingIter()}:(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
      -d["a"] = {"abcF" : FailingIterNext()}:(<class 'NotImplementedError'>, NotImplementedError())
      +d["a"] = {"abcF" : FailingIterNext()}:(<class 'NotImplementedError'>, NotImplementedError('next',))
      <<< Finished
      >>> Testing ConvertFromPyObject using d["a"] = {"abcF" : %s}
      d["a"] = {"abcF" : None}:(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',))
      d["a"] = {"abcF" : {b"": 1}}:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
      d["a"] = {"abcF" : {"": 1}}:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
      -d["a"] = {"abcF" : FailingMapping()}:(<class 'NotImplementedError'>, NotImplementedError())
      -d["a"] = {"abcF" : FailingMappingKey()}:(<class 'NotImplementedError'>, NotImplementedError())
      -d["a"] = {"abcF" : FailingNumber()}:(<class 'NotImplementedError'>, NotImplementedError())
      +d["a"] = {"abcF" : FailingMapping()}:(<class 'NotImplementedError'>, NotImplementedError('keys',))
      +d["a"] = {"abcF" : FailingMappingKey()}:(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
      +d["a"] = {"abcF" : FailingNumber()}:(<class 'NotImplementedError'>, NotImplementedError('int',))
      <<< Finished
      >>> Testing StringToChars using d["a"] = Mapping({%s : 1})
      d["a"] = Mapping({1 : 1}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
      @@ -558,36 +558,36 @@
      <<< Finished
      >>> Testing *Iter* using d["a"] = Mapping({"abcG" : %s})
      d["a"] = Mapping({"abcG" : FailingIter()}):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
      -d["a"] = Mapping({"abcG" : FailingIterNext()}):(<class 'NotImplementedError'>, NotImplementedError())
      +d["a"] = Mapping({"abcG" : FailingIterNext()}):(<class 'NotImplementedError'>, NotImplementedError('next',))
      <<< Finished
      >>> Testing ConvertFromPyObject using d["a"] = Mapping({"abcG" : %s})
      d["a"] = Mapping({"abcG" : None}):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',))
      d["a"] = Mapping({"abcG" : {b"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
      d["a"] = Mapping({"abcG" : {"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
      -d["a"] = Mapping({"abcG" : FailingMapping()}):(<class 'NotImplementedError'>, NotImplementedError())
      -d["a"] = Mapping({"abcG" : FailingMappingKey()}):(<class 'NotImplementedError'>, NotImplementedError())
      -d["a"] = Mapping({"abcG" : FailingNumber()}):(<class 'NotImplementedError'>, NotImplementedError())
      +d["a"] = Mapping({"abcG" : FailingMapping()}):(<class 'NotImplementedError'>, NotImplementedError('keys',))
      +d["a"] = Mapping({"abcG" : FailingMappingKey()}):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
      +d["a"] = Mapping({"abcG" : FailingNumber()}):(<class 'NotImplementedError'>, NotImplementedError('int',))
      <<< Finished
      >>> Testing *Iter* using d["a"] = %s
      d["a"] = FailingIter():(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
      -d["a"] = FailingIterNext():(<class 'NotImplementedError'>, NotImplementedError())
      +d["a"] = FailingIterNext():(<class 'NotImplementedError'>, NotImplementedError('next',))
      <<< Finished
      >>> Testing ConvertFromPyObject using d["a"] = %s
      d["a"] = None:(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',))
      d["a"] = {b"": 1}:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
      d["a"] = {"": 1}:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
      -d["a"] = FailingMapping():(<class 'NotImplementedError'>, NotImplementedError())
      -d["a"] = FailingMappingKey():(<class 'NotImplementedError'>, NotImplementedError())
      -d["a"] = FailingNumber():(<class 'NotImplementedError'>, NotImplementedError())
      +d["a"] = FailingMapping():(<class 'NotImplementedError'>, NotImplementedError('keys',))
      +d["a"] = FailingMappingKey():(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
      +d["a"] = FailingNumber():(<class 'NotImplementedError'>, NotImplementedError('int',))
      <<< Finished
      >> DictionaryUpdate
      >>> kwargs
      >>> iter
      -d.update(FailingMapping()):(<class 'NotImplementedError'>, NotImplementedError())
      -d.update([FailingIterNext()]):(<class 'NotImplementedError'>, NotImplementedError())
      +d.update(FailingMapping()):(<class 'NotImplementedError'>, NotImplementedError('keys',))
      +d.update([FailingIterNext()]):(<class 'NotImplementedError'>, NotImplementedError('next',))
      >>> Testing *Iter* using d.update(%s)
      -d.update(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError())
      -d.update(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError())
      +d.update(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError('iter',))
      +d.update(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
      <<< Finished
      >>> Testing StringToChars using d.update({%s : 1})
      d.update({1 : 1}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
      @@ -606,15 +606,15 @@
      <<< Finished
      >>> Testing *Iter* using d.update({"abcF" : %s})
      d.update({"abcF" : FailingIter()}):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
      -d.update({"abcF" : FailingIterNext()}):(<class 'NotImplementedError'>, NotImplementedError())
      +d.update({"abcF" : FailingIterNext()}):(<class 'NotImplementedError'>, NotImplementedError('next',))
      <<< Finished
      >>> Testing ConvertFromPyObject using d.update({"abcF" : %s})
      d.update({"abcF" : None}):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',))
      d.update({"abcF" : {b"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
      d.update({"abcF" : {"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
      -d.update({"abcF" : FailingMapping()}):(<class 'NotImplementedError'>, NotImplementedError())
      -d.update({"abcF" : FailingMappingKey()}):(<class 'NotImplementedError'>, NotImplementedError())
      -d.update({"abcF" : FailingNumber()}):(<class 'NotImplementedError'>, NotImplementedError())
      +d.update({"abcF" : FailingMapping()}):(<class 'NotImplementedError'>, NotImplementedError('keys',))
      +d.update({"abcF" : FailingMappingKey()}):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
      +d.update({"abcF" : FailingNumber()}):(<class 'NotImplementedError'>, NotImplementedError('int',))
      <<< Finished
      >>> Testing StringToChars using d.update(Mapping({%s : 1}))
      d.update(Mapping({1 : 1})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
      @@ -633,26 +633,26 @@
      <<< Finished
      >>> Testing *Iter* using d.update(Mapping({"abcG" : %s}))
      d.update(Mapping({"abcG" : FailingIter()})):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
      -d.update(Mapping({"abcG" : FailingIterNext()})):(<class 'NotImplementedError'>, NotImplementedError())
      +d.update(Mapping({"abcG" : FailingIterNext()})):(<class 'NotImplementedError'>, NotImplementedError('next',))
      <<< Finished
      >>> Testing ConvertFromPyObject using d.update(Mapping({"abcG" : %s}))
      d.update(Mapping({"abcG" : None})):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',))
      d.update(Mapping({"abcG" : {b"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
      d.update(Mapping({"abcG" : {"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
      -d.update(Mapping({"abcG" : FailingMapping()})):(<class 'NotImplementedError'>, NotImplementedError())
      -d.update(Mapping({"abcG" : FailingMappingKey()})):(<class 'NotImplementedError'>, NotImplementedError())
      -d.update(Mapping({"abcG" : FailingNumber()})):(<class 'NotImplementedError'>, NotImplementedError())
      +d.update(Mapping({"abcG" : FailingMapping()})):(<class 'NotImplementedError'>, NotImplementedError('keys',))
      +d.update(Mapping({"abcG" : FailingMappingKey()})):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
      +d.update(Mapping({"abcG" : FailingNumber()})):(<class 'NotImplementedError'>, NotImplementedError('int',))
      <<< Finished
      >>> Testing *Iter* using d.update(%s)
      -d.update(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError())
      -d.update(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError())
      +d.update(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError('iter',))
      +d.update(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
      <<< Finished
      >>> Testing ConvertFromPyObject using d.update(%s)
      d.update(None):(<class 'TypeError'>, TypeError("'NoneType' object is not iterable",))
      d.update({b"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
      d.update({"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
      -d.update(FailingMapping()):(<class 'NotImplementedError'>, NotImplementedError())
      -d.update(FailingMappingKey()):(<class 'NotImplementedError'>, NotImplementedError())
      +d.update(FailingMapping()):(<class 'NotImplementedError'>, NotImplementedError('keys',))
      +d.update(FailingMappingKey()):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
      d.update(FailingNumber()):(<class 'TypeError'>, TypeError("'FailingNumber' object is not iterable",))
      <<< Finished
      >>> Testing StringToChars using d.update(((%s, 0),))
      @@ -677,15 +677,15 @@
      <<< Finished
      >>> Testing *Iter* using d.update((("a", {"abcF" : %s}),))
      d.update((("a", {"abcF" : FailingIter()}),)):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
      -d.update((("a", {"abcF" : FailingIterNext()}),)):(<class 'NotImplementedError'>, NotImplementedError())
      +d.update((("a", {"abcF" : FailingIterNext()}),)):(<class 'NotImplementedError'>, NotImplementedError('next',))
      <<< Finished
      >>> Testing ConvertFromPyObject using d.update((("a", {"abcF" : %s}),))
      d.update((("a", {"abcF" : None}),)):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',))
      d.update((("a", {"abcF" : {b"": 1}}),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
      d.update((("a", {"abcF" : {"": 1}}),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
      -d.update((("a", {"abcF" : FailingMapping()}),)):(<class 'NotImplementedError'>, NotImplementedError())
      -d.update((("a", {"abcF" : FailingMappingKey()}),)):(<class 'NotImplementedError'>, NotImplementedError())
      -d.update((("a", {"abcF" : FailingNumber()}),)):(<class 'NotImplementedError'>, NotImplementedError())
      +d.update((("a", {"abcF" : FailingMapping()}),)):(<class 'NotImplementedError'>, NotImplementedError('keys',))
      +d.update((("a", {"abcF" : FailingMappingKey()}),)):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
      +d.update((("a", {"abcF" : FailingNumber()}),)):(<class 'NotImplementedError'>, NotImplementedError('int',))
      <<< Finished
      >>> Testing StringToChars using d.update((("a", Mapping({%s : 1})),))
      d.update((("a", Mapping({1 : 1})),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
      @@ -704,27 +704,27 @@
      <<< Finished
      >>> Testing *Iter* using d.update((("a", Mapping({"abcG" : %s})),))
      d.update((("a", Mapping({"abcG" : FailingIter()})),)):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
      -d.update((("a", Mapping({"abcG" : FailingIterNext()})),)):(<class 'NotImplementedError'>, NotImplementedError())
      +d.update((("a", Mapping({"abcG" : FailingIterNext()})),)):(<class 'NotImplementedError'>, NotImplementedError('next',))
      <<< Finished
      >>> Testing ConvertFromPyObject using d.update((("a", Mapping({"abcG" : %s})),))
      d.update((("a", Mapping({"abcG" : None})),)):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',))
      d.update((("a", Mapping({"abcG" : {b"": 1}})),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
      d.update((("a", Mapping({"abcG" : {"": 1}})),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
      -d.update((("a", Mapping({"abcG" : FailingMapping()})),)):(<class 'NotImplementedError'>, NotImplementedError())
      -d.update((("a", Mapping({"abcG" : FailingMappingKey()})),)):(<class 'NotImplementedError'>, NotImplementedError())
      -d.update((("a", Mapping({"abcG" : FailingNumber()})),)):(<class 'NotImplementedError'>, NotImplementedError())
      +d.update((("a", Mapping({"abcG" : FailingMapping()})),)):(<class 'NotImplementedError'>, NotImplementedError('keys',))
      +d.update((("a", Mapping({"abcG" : FailingMappingKey()})),)):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
      +d.update((("a", Mapping({"abcG" : FailingNumber()})),)):(<class 'NotImplementedError'>, NotImplementedError('int',))
      <<< Finished
      >>> Testing *Iter* using d.update((("a", %s),))
      d.update((("a", FailingIter()),)):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
      -d.update((("a", FailingIterNext()),)):(<class 'NotImplementedError'>, NotImplementedError())
      +d.update((("a", FailingIterNext()),)):(<class 'NotImplementedError'>, NotImplementedError('next',))
      <<< Finished
      >>> Testing ConvertFromPyObject using d.update((("a", %s),))
      d.update((("a", None),)):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',))
      d.update((("a", {b"": 1}),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
      d.update((("a", {"": 1}),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
      -d.update((("a", FailingMapping()),)):(<class 'NotImplementedError'>, NotImplementedError())
      -d.update((("a", FailingMappingKey()),)):(<class 'NotImplementedError'>, NotImplementedError())
      -d.update((("a", FailingNumber()),)):(<class 'NotImplementedError'>, NotImplementedError())
      +d.update((("a", FailingMapping()),)):(<class 'NotImplementedError'>, NotImplementedError('keys',))
      +d.update((("a", FailingMappingKey()),)):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
      +d.update((("a", FailingNumber()),)):(<class 'NotImplementedError'>, NotImplementedError('int',))
      <<< Finished
      >> DictionaryPopItem
      d.popitem(1, 2):(<class 'TypeError'>, TypeError('popitem() takes no arguments (2 given)',))
      @@ -735,8 +735,8 @@
      vim.List(1, 2):(<class 'TypeError'>, TypeError('function takes at most 1 argument (2 given)',))
      vim.List(a=1):(<class 'TypeError'>, TypeError('list constructor does not accept keyword arguments',))
      >>> Testing *Iter* using vim.List(%s)
      -vim.List(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError())
      -vim.List(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError())
      +vim.List(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError('iter',))
      +vim.List(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
      <<< Finished
      >>> Testing StringToChars using vim.List([{%s : 1}])
      vim.List([{1 : 1}]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
      @@ -755,15 +755,15 @@
      <<< Finished
      >>> Testing *Iter* using vim.List([{"abcF" : %s}])
      vim.List([{"abcF" : FailingIter()}]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
      -vim.List([{"abcF" : FailingIterNext()}]):(<class 'NotImplementedError'>, NotImplementedError())
      +vim.List([{"abcF" : FailingIterNext()}]):(<class 'NotImplementedError'>, NotImplementedError('next',))
      <<< Finished
      >>> Testing ConvertFromPyObject using vim.List([{"abcF" : %s}])
      vim.List([{"abcF" : None}]):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',))
      vim.List([{"abcF" : {b"": 1}}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
      vim.List([{"abcF" : {"": 1}}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
      -vim.List([{"abcF" : FailingMapping()}]):(<class 'NotImplementedError'>, NotImplementedError())
      -vim.List([{"abcF" : FailingMappingKey()}]):(<class 'NotImplementedError'>, NotImplementedError())
      -vim.List([{"abcF" : FailingNumber()}]):(<class 'NotImplementedError'>, NotImplementedError())
      +vim.List([{"abcF" : FailingMapping()}]):(<class 'NotImplementedError'>, NotImplementedError('keys',))
      +vim.List([{"abcF" : FailingMappingKey()}]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
      +vim.List([{"abcF" : FailingNumber()}]):(<class 'NotImplementedError'>, NotImplementedError('int',))
      <<< Finished
      >>> Testing StringToChars using vim.List([Mapping({%s : 1})])
      vim.List([Mapping({1 : 1})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
      @@ -782,27 +782,27 @@
      <<< Finished
      >>> Testing *Iter* using vim.List([Mapping({"abcG" : %s})])
      vim.List([Mapping({"abcG" : FailingIter()})]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
      -vim.List([Mapping({"abcG" : FailingIterNext()})]):(<class 'NotImplementedError'>, NotImplementedError())
      +vim.List([Mapping({"abcG" : FailingIterNext()})]):(<class 'NotImplementedError'>, NotImplementedError('next',))
      <<< Finished
      >>> Testing ConvertFromPyObject using vim.List([Mapping({"abcG" : %s})])
      vim.List([Mapping({"abcG" : None})]):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',))
      vim.List([Mapping({"abcG" : {b"": 1}})]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
      vim.List([Mapping({"abcG" : {"": 1}})]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
      -vim.List([Mapping({"abcG" : FailingMapping()})]):(<class 'NotImplementedError'>, NotImplementedError())
      -vim.List([Mapping({"abcG" : FailingMappingKey()})]):(<class 'NotImplementedError'>, NotImplementedError())
      -vim.List([Mapping({"abcG" : FailingNumber()})]):(<class 'NotImplementedError'>, NotImplementedError())
      +vim.List([Mapping({"abcG" : FailingMapping()})]):(<class 'NotImplementedError'>, NotImplementedError('keys',))
      +vim.List([Mapping({"abcG" : FailingMappingKey()})]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
      +vim.List([Mapping({"abcG" : FailingNumber()})]):(<class 'NotImplementedError'>, NotImplementedError('int',))
      <<< Finished
      >>> Testing *Iter* using vim.List([%s])
      vim.List([FailingIter()]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
      -vim.List([FailingIterNext()]):(<class 'NotImplementedError'>, NotImplementedError())
      +vim.List([FailingIterNext()]):(<class 'NotImplementedError'>, NotImplementedError('next',))
      <<< Finished
      >>> Testing ConvertFromPyObject using vim.List([%s])
      vim.List([None]):(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',))
      vim.List([{b"": 1}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
      vim.List([{"": 1}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
      -vim.List([FailingMapping()]):(<class 'NotImplementedError'>, NotImplementedError())
      -vim.List([FailingMappingKey()]):(<class 'NotImplementedError'>, NotImplementedError())
      -vim.List([FailingNumber()]):(<class 'NotImplementedError'>, NotImplementedError())
      +vim.List([FailingMapping()]):(<class 'NotImplementedError'>, NotImplementedError('keys',))
      +vim.List([FailingMappingKey()]):(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
      +vim.List([FailingNumber()]):(<class 'NotImplementedError'>, NotImplementedError('int',))
      <<< Finished
      >> ListItem
      l[1000]:(<class 'IndexError'>, IndexError('list index out of range',))
      @@ -812,8 +812,8 @@
      >> ListAssSlice
      ll[1:100] = "abcJ":(<class 'vim.error'>, error('list is locked',))
      >>> Testing *Iter* using l[:] = %s
      -l[:] = FailingIter():(<class 'NotImplementedError'>, NotImplementedError())
      -l[:] = FailingIterNext()::(<class 'NotImplementedError'>, NotImplementedError())
      +l[:] = FailingIter():(<class 'NotImplementedError'>, NotImplementedError('iter',))
      +l[:] = FailingIterNext():(<class 'NotImplementedError'>, NotImplementedError('next',))
      <<< Finished
      >>> Testing StringToChars using l[:] = [{%s : 1}]
      l[:] = [{1 : 1}]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
      @@ -832,15 +832,15 @@
      <<< Finished
      >>> Testing *Iter* using l[:] = [{"abcF" : %s}]
      l[:] = [{"abcF" : FailingIter()}]:(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
      -l[:] = [{"abcF" : FailingIterNext()}]:(<class 'NotImplementedError'>, NotImplementedError())
      +l[:] = [{"abcF" : FailingIterNext()}]:(<class 'NotImplementedError'>, NotImplementedError('next',))
      <<< Finished
      >>> Testing ConvertFromPyObject using l[:] = [{"abcF" : %s}]
      l[:] = [{"abcF" : None}]:(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',))
      l[:] = [{"abcF" : {b"": 1}}]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
      l[:] = [{"abcF" : {"": 1}}]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
      -l[:] = [{"abcF" : FailingMapping()}]:(<class 'NotImplementedError'>, NotImplementedError())
      -l[:] = [{"abcF" : FailingMappingKey()}]:(<class 'NotImplementedError'>, NotImplementedError())
      -l[:] = [{"abcF" : FailingNumber()}]:(<class 'NotImplementedError'>, NotImplementedError())
      +l[:] = [{"abcF" : FailingMapping()}]:(<class 'NotImplementedError'>, NotImplementedError('keys',))
      +l[:] = [{"abcF" : FailingMappingKey()}]:(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
      +l[:] = [{"abcF" : FailingNumber()}]:(<class 'NotImplementedError'>, NotImplementedError('int',))
      <<< Finished
      >>> Testing StringToChars using l[:] = [Mapping({%s : 1})]
      l[:] = [Mapping({1 : 1})]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
      @@ -859,32 +859,32 @@
      <<< Finished
      >>> Testing *Iter* using l[:] = [Mapping({"abcG" : %s})]
      l[:] = [Mapping({"abcG" : FailingIter()})]:(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
      -l[:] = [Mapping({"abcG" : FailingIterNext()})]:(<class 'NotImplementedError'>, NotImplementedError())
      +l[:] = [Mapping({"abcG" : FailingIterNext()})]:(<class 'NotImplementedError'>, NotImplementedError('next',))
      <<< Finished
      >>> Testing ConvertFromPyObject using l[:] = [Mapping({"abcG" : %s})]
      l[:] = [Mapping({"abcG" : None})]:(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',))
      l[:] = [Mapping({"abcG" : {b"": 1}})]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
      l[:] = [Mapping({"abcG" : {"": 1}})]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
      -l[:] = [Mapping({"abcG" : FailingMapping()})]:(<class 'NotImplementedError'>, NotImplementedError())
      -l[:] = [Mapping({"abcG" : FailingMappingKey()})]:(<class 'NotImplementedError'>, NotImplementedError())
      -l[:] = [Mapping({"abcG" : FailingNumber()})]:(<class 'NotImplementedError'>, NotImplementedError())
      +l[:] = [Mapping({"abcG" : FailingMapping()})]:(<class 'NotImplementedError'>, NotImplementedError('keys',))
      +l[:] = [Mapping({"abcG" : FailingMappingKey()})]:(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
      +l[:] = [Mapping({"abcG" : FailingNumber()})]:(<class 'NotImplementedError'>, NotImplementedError('int',))
      <<< Finished
      >>> Testing *Iter* using l[:] = [%s]
      l[:] = [FailingIter()]:(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
      -l[:] = [FailingIterNext()]:(<class 'NotImplementedError'>, NotImplementedError())
      +l[:] = [FailingIterNext()]:(<class 'NotImplementedError'>, NotImplementedError('next',))
      <<< Finished
      >>> Testing ConvertFromPyObject using l[:] = [%s]
      l[:] = [None]:(<class 'TypeError'>, TypeError('unable to convert NoneType to vim structure',))
      l[:] = [{b"": 1}]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
      l[:] = [{"": 1}]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
      -l[:] = [FailingMapping()]:(<class 'NotImplementedError'>, NotImplementedError())
      -l[:] = [FailingMappingKey()]:(<class 'NotImplementedError'>, NotImplementedError())
      -l[:] = [FailingNumber()]:(<class 'NotImplementedError'>, NotImplementedError())
      +l[:] = [FailingMapping()]:(<class 'NotImplementedError'>, NotImplementedError('keys',))
      +l[:] = [FailingMappingKey()]:(<class 'NotImplementedError'>, NotImplementedError('getitem:mappingkey',))
      +l[:] = [FailingNumber()]:(<class 'NotImplementedError'>, NotImplementedError<br/><br/>(Message over 64 KB, truncated)
    • ZyX
      Fixes the Note: mentioned before. # HG changeset patch # User ZyX # Date 1371701162 -14400 # Thu Jun 20 08:06:02 2013 +0400 # Branch
      Message 2 of 25 , Jun 19, 2013
      • 0 Attachment
        Fixes the Note: mentioned before.

        # HG changeset patch
        # User ZyX <kp-pav@...>
        # Date 1371701162 -14400
        # Thu Jun 20 08:06:02 2013 +0400
        # Branch python-fixes
        # Node ID 32abf0ae95195d73a017a8d53af65e9deea20856
        # Parent 38acdea8fd7d2179916c4e67bdc8e54941929093
        Let non-ImportError exceptions pass the finder

        diff -r 38acdea8fd7d -r 32abf0ae9519 src/if_py_both.h
        --- a/src/if_py_both.h Wed Jun 19 23:10:21 2013 +0400
        +++ b/src/if_py_both.h Thu Jun 20 08:06:02 2013 +0400
        @@ -1199,6 +1199,14 @@

        if (!module)
        {
        + if (PyErr_Occurred())
        + {
        + if (PyErr_ExceptionMatches(PyExc_ImportError))
        + PyErr_Clear();
        + else
        + return NULL;
        + }
        +
        Py_INCREF(Py_None);
        return Py_None;
        }
        diff -r 38acdea8fd7d -r 32abf0ae9519 src/testdir/test86.ok
        --- a/src/testdir/test86.ok Wed Jun 19 23:10:21 2013 +0400
        +++ b/src/testdir/test86.ok Thu Jun 20 08:06:02 2013 +0400
        @@ -497,7 +497,7 @@
        > import
        import xxx_no_such_module_xxx:ImportError:('No module named xxx_no_such_module_xxx',)
        import failing_import:ImportError:('No module named failing_import',)
        -import failing:ImportError:('No module named failing',)
        +import failing:NotImplementedError:()
        > Dictionary
        >> DictionaryConstructor
        vim.Dictionary("abcI"):ValueError:('expected sequence element of size 2, but got sequence of size 1',)
        diff -r 38acdea8fd7d -r 32abf0ae9519 src/testdir/test87.ok
        --- a/src/testdir/test87.ok Wed Jun 19 23:10:21 2013 +0400
        +++ b/src/testdir/test87.ok Thu Jun 20 08:06:02 2013 +0400
        @@ -486,7 +486,7 @@
        > import
        import xxx_no_such_module_xxx:(<class 'ImportError'>, ImportError('No module named xxx_no_such_module_xxx',))
        import failing_import:(<class 'ImportError'>, ImportError('No module named failing_import',))
        -import failing:(<class 'ImportError'>, ImportError('No module named failing',))
        +import failing:(<class 'NotImplementedError'>, NotImplementedError())
        > Dictionary
        >> DictionaryConstructor
        vim.Dictionary("abcI"):(<class 'ValueError'>, ValueError('expected sequence element of size 2, but got sequence of size 1',))

        --
        --
        You received this message from the "vim_dev" maillist.
        Do not top-post! Type your reply below the text you are replying to.
        For more information, visit http://www.vim.org/maillist.php

        ---
        You received this message because you are subscribed to the Google Groups "vim_dev" group.
        To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscribe@....
        For more options, visit https://groups.google.com/groups/opt_out.
      • ZyX
        Wrong patch. Correct one: # HG changeset patch # User ZyX # Date 1371441247 -14400 # Mon Jun 17 07:54:07 2013 +0400 # Branch python-fixes #
        Message 3 of 25 , Jun 19, 2013
        • 0 Attachment
          Wrong patch. Correct one:

          # HG changeset patch
          # User ZyX <kp-pav@...>
          # Date 1371441247 -14400
          # Mon Jun 17 07:54:07 2013 +0400
          # Branch python-fixes
          # Node ID 42e166b5c6ff07cd7810780b1d3704b8ce61bac0
          # Parent 4a00cd941a883917f6d740f9f06aca7baadcb45e
          Add NUMBER_UNSIGNED to WindowSetattr(, "width"|"height")
          And more tests

          Note: in ee('import failing') it was expected to raise NotImplementedError, but
          actually raises ImportError

          diff --git a/src/if_py_both.h b/src/if_py_both.h
          --- a/src/if_py_both.h
          +++ b/src/if_py_both.h
          @@ -3357,7 +3357,7 @@
          long height;
          win_T *savewin;

          - if (NumberToLong(valObject, &height, NUMBER_INT))
          + if (NumberToLong(valObject, &height, NUMBER_INT|NUMBER_UNSIGNED))
          return -1;

          #ifdef FEAT_GUI
          @@ -3380,7 +3380,7 @@
          long width;
          win_T *savewin;

          - if (NumberToLong(valObject, &width, NUMBER_INT))
          + if (NumberToLong(valObject, &width, NUMBER_INT|NUMBER_UNSIGNED))
          return -1;

          #ifdef FEAT_GUI
          diff --git a/src/testdir/pythonx/failing.py b/src/testdir/pythonx/failing.py
          new file mode 100644
          --- /dev/null
          +++ b/src/testdir/pythonx/failing.py
          @@ -0,0 +1,1 @@
          +raise NotImplementedError
          diff --git a/src/testdir/pythonx/failing_import.py b/src/testdir/pythonx/failing_import.py
          new file mode 100644
          --- /dev/null
          +++ b/src/testdir/pythonx/failing_import.py
          @@ -0,0 +1,1 @@
          +raise ImportError
          diff --git a/src/testdir/pythonx/topmodule/__init__.py b/src/testdir/pythonx/topmodule/__init__.py
          new file mode 100644
          diff --git a/src/testdir/pythonx/topmodule/submodule/__init__.py b/src/testdir/pythonx/topmodule/submodule/__init__.py
          new file mode 100644
          diff --git a/src/testdir/pythonx/topmodule/submodule/subsubmodule/__init__.py b/src/testdir/pythonx/topmodule/submodule/subsubmodule/__init__.py
          new file mode 100644
          diff --git a/src/testdir/pythonx/topmodule/submodule/subsubmodule/subsubsubmodule.py b/src/testdir/pythonx/topmodule/submodule/subsubmodule/subsubsubmodule.py
          new file mode 100644
          diff --git a/src/testdir/test86.in b/src/testdir/test86.in
          --- a/src/testdir/test86.in
          +++ b/src/testdir/test86.in
          @@ -342,9 +342,9 @@
          EOF
          :py sys.settrace(traceit)
          :py trace_main()
          +:py sys.settrace(None)
          :py del traceit
          :py del trace_main
          -:py sys.settrace(None)
          :$put =string(l)
          :"
          :" Slice
          @@ -942,6 +942,7 @@
          '{u"": 1}', # Same, but with unicode object
          'FailingMapping()', #
          'FailingMappingKey()', #
          + 'FailingNumber()', #
          ))

          def convertfrompymapping_test(expr):
          @@ -956,6 +957,15 @@
          'FailingIterNext()',
          ))

          +def number_test(expr, natural=False, unsigned=False):
          + if natural:
          + unsigned = True
          + return subexpr_test(expr, 'NumberToLong', (
          + '[]',
          + 'None',
          + ) + (unsigned and ('-1',) or ())
          + + (natural and ('0',) or ()))
          +
          class FailingTrue(object):
          def __nonzero__(self):
          raise NotImplementedError
          @@ -992,30 +1002,59 @@
          else:
          return super(FailingList, self).__getitem__(idx)

          +class NoArgsCall(object):
          + def __call__(self):
          + pass
          +
          +class FailingCall(object):
          + def __call__(self, path):
          + raise NotImplementedError
          +
          +class FailingNumber(object):
          + def __int__(self):
          + raise NotImplementedError
          +
          cb.append("> Output")
          cb.append(">> OutputSetattr")
          ee('del sys.stdout.softspace')
          -ee('sys.stdout.softspace = []')
          +number_test('sys.stdout.softspace = %s', unsigned=True)
          +number_test('sys.stderr.softspace = %s', unsigned=True)
          ee('sys.stdout.attr = None')
          cb.append(">> OutputWrite")
          ee('sys.stdout.write(None)')
          cb.append(">> OutputWriteLines")
          ee('sys.stdout.writelines(None)')
          ee('sys.stdout.writelines([1])')
          -#iter_test('sys.stdout.writelines(%s)')
          +iter_test('sys.stdout.writelines(%s)')
          cb.append("> VimCommand")
          -ee('vim.command(1)')
          +stringtochars_test('vim.command(%s)')
          +ee('vim.command("", 2)')
          #! Not checked: vim->python exceptions translating: checked later
          cb.append("> VimToPython")
          #! Not checked: everything: needs errors in internal python functions
          cb.append("> VimEval")
          -ee('vim.eval(1)')
          +stringtochars_test('vim.eval(%s)')
          +ee('vim.eval("", FailingTrue())')
          #! Not checked: everything: needs errors in internal python functions
          cb.append("> VimEvalPy")
          -ee('vim.bindeval(1)')
          +stringtochars_test('vim.bindeval(%s)')
          +ee('vim.eval("", 2)')
          #! Not checked: vim->python exceptions translating: checked later
          cb.append("> VimStrwidth")
          -ee('vim.strwidth(1)')
          +stringtochars_test('vim.strwidth(%s)')
          +cb.append("> VimForeachRTP")
          +ee('vim.foreach_rtp(None)')
          +ee('vim.foreach_rtp(NoArgsCall())')
          +ee('vim.foreach_rtp(FailingCall())')
          +ee('vim.foreach_rtp(int, 2)')
          +cb.append('> import')
          +old_rtp = vim.options['rtp']
          +vim.options['rtp'] = os.getcwd().replace(',', '\\,').replace('\\', '\\\\')
          +ee('import xxx_no_such_module_xxx')
          +ee('import failing_import')
          +ee('import failing')
          +vim.options['rtp'] = old_rtp
          +del old_rtp
          cb.append("> Dictionary")
          cb.append(">> DictionaryConstructor")
          ee('vim.Dictionary("abcI")')
          @@ -1043,7 +1082,7 @@
          cb.append(">>> iter")
          ee('d.update(FailingMapping())')
          ee('d.update([FailingIterNext()])')
          -#iter_test('d.update(%s)')
          +iter_test('d.update(%s)')
          convertfrompyobject_test('d.update(%s)')
          stringtochars_test('d.update(((%s, 0),))')
          convertfrompyobject_test('d.update((("a", %s),))')
          @@ -1055,7 +1094,7 @@
          cb.append(">> ListConstructor")
          ee('vim.List(1, 2)')
          ee('vim.List(a=1)')
          -#iter_test('vim.List(%s)')
          +iter_test('vim.List(%s)')
          convertfrompyobject_test('vim.List([%s])')
          cb.append(">> ListItem")
          ee('l[1000]')
          @@ -1064,10 +1103,10 @@
          ee('l[1000] = 3')
          cb.append(">> ListAssSlice")
          ee('ll[1:100] = "abcJ"')
          -#iter_test('l[:] = %s')
          +iter_test('l[:] = %s')
          convertfrompyobject_test('l[:] = [%s]')
          cb.append(">> ListConcatInPlace")
          -#iter_test('l.extend(%s)')
          +iter_test('l.extend(%s)')
          convertfrompyobject_test('l.extend([%s])')
          cb.append(">> ListSetattr")
          ee('del l.locked')
          @@ -1094,14 +1133,15 @@
          ee('vim.current.window.buffer = 0')
          ee('vim.current.window.cursor = (100000000, 100000000)')
          ee('vim.current.window.cursor = True')
          -ee('vim.current.window.height = "abcK"')
          -ee('vim.current.window.width = "abcL"')
          +number_test('vim.current.window.height = %s', unsigned=True)
          +number_test('vim.current.window.width = %s', unsigned=True)
          ee('vim.current.window.xxxxxx = True')
          cb.append("> WinList")
          cb.append(">> WinListItem")
          ee('vim.windows[1000]')
          cb.append("> Buffer")
          cb.append(">> StringToLine (indirect)")
          +ee('vim.current.buffer[0] = u"\\na"')
          ee('vim.current.buffer[0] = "\\na"')
          cb.append(">> SetBufferLine (indirect)")
          ee('vim.current.buffer[0] = True')
          @@ -1129,8 +1169,8 @@
          ee('vim.current.buffer.range(1, 2, 3)')
          cb.append("> BufMap")
          cb.append(">> BufMapItem")
          -ee('vim.buffers[None]')
          ee('vim.buffers[100000000]')
          +number_test('vim.buffers[%s]', natural=True)
          cb.append("> Current")
          cb.append(">> CurrentGetattr")
          ee('vim.current.xxx')
          @@ -1154,12 +1194,16 @@
          del convertfrompyobject_test
          del convertfrompymapping_test
          del iter_test
          +del number_test
          del FailingTrue
          del FailingIter
          del FailingIterNext
          del FailingMapping
          del FailingMappingKey
          del FailingList
          +del NoArgsCall
          +del FailingCall
          +del FailingNumber
          EOF
          :delfunction F
          :"
          @@ -1168,6 +1212,16 @@
          sys.path.insert(0, os.path.join(os.getcwd(), 'python_before'))
          sys.path.append(os.path.join(os.getcwd(), 'python_after'))
          vim.options['rtp'] = os.getcwd().replace(',', '\\,').replace('\\', '\\\\')
          +l = []
          +def callback(path):
          + l.append(path[-len('/testdir'):])
          +vim.foreach_rtp(callback)
          +cb.append(repr(l))
          +del l
          +def callback(path):
          + return path[-len('/testdir'):]
          +cb.append(repr(vim.foreach_rtp(callback)))
          +del callback
          from module import dir as d
          from modulex import ddir
          cb.append(d + ',' + ddir)
          @@ -1175,10 +1229,19 @@
          cb.append(before.dir)
          import after
          cb.append(after.dir)
          +import topmodule as tm
          +import topmodule.submodule as tms
          +import topmodule.submodule.subsubmodule.subsubsubmodule as tmsss
          +cb.append(tm.__file__.replace('.pyc', '.py')[-len('modulex/topmodule/__init__.py'):])
          +cb.append(tms.__file__.replace('.pyc', '.py')[-len('modulex/topmodule/submodule/__init__.py'):])
          +cb.append(tmsss.__file__.replace('.pyc', '.py')[-len('modulex/topmodule/submodule/subsubmodule/subsubsubmodule.py'):])
          del before
          del after
          del d
          del ddir
          +del tm
          +del tms
          +del tmsss
          EOF
          :"
          :" Test exceptions
          diff --git a/src/testdir/test86.ok b/src/testdir/test86.ok
          --- a/src/testdir/test86.ok
          +++ b/src/testdir/test86.ok
          @@ -441,22 +441,63 @@
          > Output
          >> OutputSetattr
          del sys.stdout.softspace:AttributeError:("can't delete OutputObject attributes",)
          +>>> Testing NumberToLong using sys.stdout.softspace = %s
          sys.stdout.softspace = []:TypeError:('expected int(), long() or something supporting coercing to long(), but got list',)
          +sys.stdout.softspace = None:TypeError:('expected int(), long() or something supporting coercing to long(), but got NoneType',)
          +sys.stdout.softspace = -1:ValueError:('number must be greater or equal to zero',)
          +<<< Finished
          +>>> Testing NumberToLong using sys.stderr.softspace = %s
          +sys.stderr.softspace = []:TypeError:('expected int(), long() or something supporting coercing to long(), but got list',)
          +sys.stderr.softspace = None:TypeError:('expected int(), long() or something supporting coercing to long(), but got NoneType',)
          +sys.stderr.softspace = -1:ValueError:('number must be greater or equal to zero',)
          +<<< Finished
          sys.stdout.attr = None:AttributeError:('invalid attribute: attr',)
          >> OutputWrite
          sys.stdout.write(None):TypeError:('coercing to Unicode: need string or buffer, NoneType found',)
          >> OutputWriteLines
          sys.stdout.writelines(None):TypeError:("'NoneType' object is not iterable",)
          sys.stdout.writelines([1]):TypeError:('coercing to Unicode: need string or buffer, int found',)
          +>>> Testing *Iter* using sys.stdout.writelines(%s)
          +sys.stdout.writelines(FailingIter()):NotImplementedError:()
          +sys.stdout.writelines(FailingIterNext()):NotImplementedError:()
          +<<< Finished
          > VimCommand
          +>>> Testing StringToChars using vim.command(%s)
          vim.command(1):TypeError:('expected str() or unicode() instance, but got int',)
          +vim.command(u"\0"):TypeError:('expected string without null bytes',)
          +vim.command("\0"):TypeError:('expected string without null bytes',)
          +<<< Finished
          +vim.command("", 2):TypeError:('command() takes exactly one argument (2 given)',)
          > VimToPython
          > VimEval
          +>>> Testing StringToChars using vim.eval(%s)
          vim.eval(1):TypeError:('expected str() or unicode() instance, but got int',)
          +vim.eval(u"\0"):TypeError:('expected string without null bytes',)
          +vim.eval("\0"):TypeError:('expected string without null bytes',)
          +<<< Finished
          +vim.eval("", FailingTrue()):TypeError:('function takes exactly 1 argument (2 given)',)
          > VimEvalPy
          +>>> Testing StringToChars using vim.bindeval(%s)
          vim.bindeval(1):TypeError:('expected str() or unicode() instance, but got int',)
          +vim.bindeval(u"\0"):TypeError:('expected string without null bytes',)
          +vim.bindeval("\0"):TypeError:('expected string without null bytes',)
          +<<< Finished
          +vim.eval("", 2):TypeError:('function takes exactly 1 argument (2 given)',)
          > VimStrwidth
          +>>> Testing StringToChars using vim.strwidth(%s)
          vim.strwidth(1):TypeError:('expected str() or unicode() instance, but got int',)
          +vim.strwidth(u"\0"):TypeError:('expected string without null bytes',)
          +vim.strwidth("\0"):TypeError:('expected string without null bytes',)
          +<<< Finished
          +> VimForeachRTP
          +vim.foreach_rtp(None):TypeError:("'NoneType' object is not callable",)
          +vim.foreach_rtp(NoArgsCall()):TypeError:('__call__() takes exactly 1 argument (2 given)',)
          +vim.foreach_rtp(FailingCall()):NotImplementedError:()
          +vim.foreach_rtp(int, 2):TypeError:('foreach_rtp() takes exactly one argument (2 given)',)
          +> import
          +import xxx_no_such_module_xxx:ImportError:('No module named xxx_no_such_module_xxx',)
          +import failing_import:ImportError:('No module named failing_import',)
          +import failing:ImportError:('No module named failing',)
          > Dictionary
          >> DictionaryConstructor
          vim.Dictionary("abcI"):ValueError:('expected sequence element of size 2, but got sequence of size 1',)
          @@ -509,6 +550,7 @@
          d["a"] = {"abcF" : {u"": 1}}:ValueError:('empty keys are not allowed',)
          d["a"] = {"abcF" : FailingMapping()}:NotImplementedError:()
          d["a"] = {"abcF" : FailingMappingKey()}:NotImplementedError:()
          +d["a"] = {"abcF" : FailingNumber()}:TypeError:('long() argument must be a string or a number',)
          <<< Finished
          >>> Testing StringToChars using d["a"] = Mapping({%s : 1})
          d["a"] = Mapping({1 : 1}):TypeError:('expected str() or unicode() instance, but got int',)
          @@ -535,6 +577,7 @@
          d["a"] = Mapping({"abcG" : {u"": 1}}):ValueError:('empty keys are not allowed',)
          d["a"] = Mapping({"abcG" : FailingMapping()}):NotImplementedError:()
          d["a"] = Mapping({"abcG" : FailingMappingKey()}):NotImplementedError:()
          +d["a"] = Mapping({"abcG" : FailingNumber()}):TypeError:('long() argument must be a string or a number',)
          <<< Finished
          >>> Testing *Iter* using d["a"] = %s
          d["a"] = FailingIter():TypeError:('unable to convert FailingIter to vim structure',)
          @@ -546,12 +589,17 @@
          d["a"] = {u"": 1}:ValueError:('empty keys are not allowed',)
          d["a"] = FailingMapping():NotImplementedError:()
          d["a"] = FailingMappingKey():NotImplementedError:()
          +d["a"] = FailingNumber():TypeError:('long() argument must be a string or a number',)
          <<< Finished
          >> DictionaryUpdate
          >>> kwargs
          >>> iter
          d.update(FailingMapping()):NotImplementedError:()
          d.update([FailingIterNext()]):NotImplementedError:()
          +>>> Testing *Iter* using d.update(%s)
          +d.update(FailingIter()):NotImplementedError:()
          +d.update(FailingIterNext()):NotImplementedError:()
          +<<< Finished
          >>> Testing StringToChars using d.update({%s : 1})
          d.update({1 : 1}):TypeError:('expected str() or unicode() instance, but got int',)
          d.update({u"\0" : 1}):TypeError:('expected string without null bytes',)
          @@ -577,6 +625,7 @@
          d.update({"abcF" : {u"": 1}}):ValueError:('empty keys are not allowed',)
          d.update({"abcF" : FailingMapping()}):NotImplementedError:()
          d.update({"abcF" : FailingMappingKey()}):NotImplementedError:()
          +d.update({"abcF" : FailingNumber()}):TypeError:('long() argument must be a string or a number',)
          <<< Finished
          >>> Testing StringToChars using d.update(Mapping({%s : 1}))
          d.update(Mapping({1 : 1})):TypeError:('expected str() or unicode() instance, but got int',)
          @@ -603,6 +652,7 @@
          d.update(Mapping({"abcG" : {u"": 1}})):ValueError:('empty keys are not allowed',)
          d.update(Mapping({"abcG" : FailingMapping()})):NotImplementedError:()
          d.update(Mapping({"abcG" : FailingMappingKey()})):NotImplementedError:()
          +d.update(Mapping({"abcG" : FailingNumber()})):TypeError:('long() argument must be a string or a number',)
          <<< Finished
          >>> Testing *Iter* using d.update(%s)
          d.update(FailingIter()):NotImplementedError:()
          @@ -614,6 +664,7 @@
          d.update({u"": 1}):ValueError:('empty keys are not allowed',)
          d.update(FailingMapping()):NotImplementedError:()
          d.update(FailingMappingKey()):NotImplementedError:()
          +d.update(FailingNumber()):TypeError:('iteration over non-sequence',)
          <<< Finished
          >>> Testing StringToChars using d.update(((%s, 0),))
          d.update(((1, 0),)):TypeError:('expected str() or unicode() instance, but got int',)
          @@ -645,6 +696,7 @@
          d.update((("a", {"abcF" : {u"": 1}}),)):ValueError:('empty keys are not allowed',)
          d.update((("a", {"abcF" : FailingMapping()}),)):NotImplementedError:()
          d.update((("a", {"abcF" : FailingMappingKey()}),)):NotImplementedError:()
          +d.update((("a", {"abcF" : FailingNumber()}),)):TypeError:('long() argument must be a string or a number',)
          <<< Finished
          >>> Testing StringToChars using d.update((("a", Mapping({%s : 1})),))
          d.update((("a", Mapping({1 : 1})),)):TypeError:('expected str() or unicode() instance, but got int',)
          @@ -671,6 +723,7 @@
          d.update((("a", Mapping({"abcG" : {u"": 1}})),)):ValueError:('empty keys are not allowed',)
          d.update((("a", Mapping({"abcG" : FailingMapping()})),)):NotImplementedError:()
          d.update((("a", Mapping({"abcG" : FailingMappingKey()})),)):NotImplementedError:()
          +d.update((("a", Mapping({"abcG" : FailingNumber()})),)):TypeError:('long() argument must be a string or a number',)
          <<< Finished
          >>> Testing *Iter* using d.update((("a", %s),))
          d.update((("a", FailingIter()),)):TypeError:('unable to convert FailingIter to vim structure',)
          @@ -682,6 +735,7 @@
          d.update((("a", {u"": 1}),)):ValueError:('empty keys are not allowed',)
          d.update((("a", FailingMapping()),)):NotImplementedError:()
          d.update((("a", FailingMappingKey()),)):NotImplementedError:()
          +d.update((("a", FailingNumber()),)):TypeError:('long() argument must be a string or a number',)
          <<< Finished
          >> DictionaryPopItem
          d.popitem(1, 2):TypeError:('popitem() takes no arguments (2 given)',)
          @@ -691,6 +745,10 @@
          >> ListConstructor
          vim.List(1, 2):TypeError:('function takes at most 1 argument (2 given)',)
          vim.List(a=1):TypeError:('list constructor does not accept keyword arguments',)
          +>>> Testing *Iter* using vim.List(%s)
          +vim.List(FailingIter()):NotImplementedError:()
          +vim.List(FailingIterNext()):NotImplementedError:()
          +<<< Finished
          >>> Testing StringToChars using vim.List([{%s : 1}])
          vim.List([{1 : 1}]):TypeError:('expected str() or unicode() instance, but got int',)
          vim.List([{u"\0" : 1}]):TypeError:('expected string without null bytes',)
          @@ -716,6 +774,7 @@
          vim.List([{"abcF" : {u"": 1}}]):ValueError:('empty keys are not allowed',)
          vim.List([{"abcF" : FailingMapping()}]):NotImplementedError:()
          vim.List([{"abcF" : FailingMappingKey()}]):NotImplementedError:()
          +vim.List([{"abcF" : FailingNumber()}]):TypeError:('long() argument must be a string or a number',)
          <<< Finished
          >>> Testing StringToChars using vim.List([Mapping({%s : 1})])
          vim.List([Mapping({1 : 1})]):TypeError:('expected str() or unicode() instance, but got int',)
          @@ -742,6 +801,7 @@
          vim.List([Mapping({"abcG" : {u"": 1}})]):ValueError:('empty keys are not allowed',)
          vim.List([Mapping({"abcG" : FailingMapping()})]):NotImplementedError:()
          vim.List([Mapping({"abcG" : FailingMappingKey()})]):NotImplementedError:()
          +vim.List([Mapping({"abcG" : FailingNumber()})]):TypeError:('long() argument must be a string or a number',)
          <<< Finished
          >>> Testing *Iter* using vim.List([%s])
          vim.List([FailingIter()]):TypeError:('unable to convert FailingIter to vim structure',)
          @@ -753,6 +813,7 @@
          vim.List([{u"": 1}]):ValueError:('empty keys are not allowed',)
          vim.List([FailingMapping()]):NotImplementedError:()
          vim.List([FailingMappingKey()]):NotImplementedError:()
          +vim.List([FailingNumber()]):TypeError:('long() argument must be a string or a number',)
          <<< Finished
          >> ListItem
          l[1000]:IndexError:('list index out of range',)
          @@ -761,6 +822,10 @@
          l[1000] = 3:IndexError:('list index out of range',)
          >> ListAssSlice
          ll[1:100] = "abcJ":error:('list is locked',)
          +>>> Testing *Iter* using l[:] = %s
          +l[:] = FailingIter():NotImplementedError:()
          +l[:] = FailingIterNext():NotImplementedError:()
          +<<< Finished
          >>> Testing StringToChars using l[:] = [{%s : 1}]
          l[:] = [{1 : 1}]:TypeError:('expected str() or unicode() instance, but got int',)
          l[:] = [{u"\0" : 1}]:TypeError:('expected string without null bytes',)
          @@ -786,6 +851,7 @@
          l[:] = [{"abcF" : {u"": 1}}]:ValueError:('empty keys are not allowed',)
          l[:] = [{"abcF" : FailingMapping()}]:NotImplementedError:()
          l[:] = [{"abcF" : FailingMappingKey()}]:NotImplementedError:()
          +l[:] = [{"abcF" : FailingNumber()}]:TypeError:('long() argument must be a string or a number',)
          <<< Finished
          >>> Testing StringToChars using l[:] = [Mapping({%s : 1})]
          l[:] = [Mapping({1 : 1})]:TypeError:('expected str() or unicode() instance, but got int',)
          @@ -812,6 +878,7 @@
          l[:] = [Mapping({"abcG" : {u"": 1}})]:ValueError:('empty keys are not allowed',)
          l[:] = [Mapping({"abcG" : FailingMapping()})]:NotImplementedError:()
          l[:] = [Mapping({"abcG" : FailingMappingKey()})]:NotImplementedError:()
          +l[:] = [Mapping({"abcG" : FailingNumber()})]:TypeError:('long() argument must be a string or a number',)
          <<< Finished
          >>> Testing *Iter* using l[:] = [%s]
          l[:] = [FailingIter()]:TypeError:('unable to convert FailingIter to vim structure',)
          @@ -823,8 +890,13 @@
          l[:] = [{u"": 1}]:ValueError:('empty keys are not allowed',)
          l[:] = [FailingMapping()]:NotImplementedError:()
          l[:] = [FailingMappingKey()]:NotImplementedError:()
          +l[:] = [FailingNumber()]:TypeError:('long() argument must be a string or a number',)
          <<< Finished
          >> ListConcatInPlace
          +>>> Testing *Iter* using l.extend(%s)
          +l.extend(FailingIter()):NotImplementedError:()
          +l.extend(FailingIterNext()):NotImplementedError:()
          +<<< Finished
          >>> Testing StringToChars using l.extend([{%s : 1}])
          l.extend([{1 : 1}]):TypeError:('expected str() or unicode() instance, but got int',)
          l.extend([{u"\0" : 1}]):TypeError:('expected string without null bytes',)
          @@ -850,6 +922,7 @@
          l.extend([{"abcF" : {u"": 1}}]):ValueError:('empty keys are not allowed',)
          l.extend([{"abcF" : FailingMapping()}]):NotImplementedError:()
          l.extend([{"abcF" : FailingMappingKey()}]):NotImplementedError:()
          +l.extend([{"abcF" : FailingNumber()}]):TypeError:('long() argument must be a string or a number',)
          <<< Finished
          >>> Testing StringToChars using l.extend([Mapping({%s : 1})])
          l.extend([Mapping({1 : 1})]):TypeError:('expected str() or unicode() instance, but got int',)
          @@ -876,6 +949,7 @@
          l.extend([Mapping({"abcG" : {u"": 1}})]):ValueError:('empty keys are not allowed',)
          l.extend([Mapping({"abcG" : FailingMapping()})]):NotImplementedError:()
          l.extend([Mapping({"abcG" : FailingMappingKey()})]):NotImplementedError:()
          +l.extend([Mapping({"abcG" : FailingNumber()})]):TypeError:('long() argument must be a string or a number',)
          <<< Finished
          >>> Testing *Iter* using l.extend([%s])
          l.extend([FailingIter()]):TypeError:('unable to convert FailingIter to vim structure',)
          @@ -887,6 +961,7 @@
          l.extend([{u"": 1}]):ValueError:('empty keys are not allowed',)
          l.extend([FailingMapping()]):NotImplementedError:()
          l.extend([FailingMappingKey()]):NotImplementedError:()
          +l.extend([FailingNumber()]):TypeError:('long() argument must be a string or a number',)
          <<< Finished
          >> ListSetattr
          del l.locked:AttributeError:('cannot delete vim.List attributes',)
          @@ -923,6 +998,7 @@
          f({"abcF" : {u"": 1}}):ValueError:('empty keys are not allowed',)
          f({"abcF" : FailingMapping()}):NotImplementedError:()
          f({"abcF" : FailingMappingKey()}):NotImplementedError:()
          +f({"abcF" : FailingNumber()}):TypeError:('long() argument must be a string or a number',)
          <<< Finished
          >>> Testing StringToChars using f(Mapping({%s : 1}))
          f(Mapping({1 : 1})):TypeError:('expected str() or unicode() instance, but got int',)
          @@ -949,6 +1025,7 @@
          f(Mapping({"abcG" : {u"": 1}})):ValueError:('empty keys are not allowed',)
          f(Mapping({"abcG" : FailingMapping()})):NotImplementedError:()
          f(Mapping({"abcG" : FailingMappingKey()})):NotImplementedError:()
          +f(Mapping({"abcG" : FailingNumber()})):TypeError:('long() argument must be a string or a number',)
          <<< Finished
          >>> Testing *Iter* using f(%s)
          f(FailingIter()):TypeError:('unable to convert FailingIter to vim structure',)
          @@ -960,6 +1037,7 @@
          f({u"": 1}):ValueError:('empty keys are not allowed',)
          f(FailingMapping()):NotImplementedError:()
          f(FailingMappingKey()):NotImplementedError:()
          +f(FailingNumber()):TypeError:('long() argument must be a string or a number',)
          <<< Finished
          >>> Testing StringToChars using fd(self={%s : 1})
          fd(self={1 : 1}):TypeError:('expected str() or unicode() instance, but got int',)
          @@ -986,6 +1064,7 @@
          fd(self={"abcF" : {u"": 1}}):ValueError:('empty keys are not allowed',)
          fd(self={"abcF" : FailingMapping()}):NotImplementedError:()
          fd(self={"abcF" : FailingMappingKey()}):NotImplementedError:()
          +fd(self={"abcF" : FailingNumber()}):TypeError:('long() argument must be a string or a number',)
          <<< Finished
          >>> Testing StringToChars using fd(self=Mapping({%s : 1}))
          fd(self=Mapping({1 : 1})):TypeError:('expected str() or unicode() instance, but got int',)
          @@ -1012,6 +1091,7 @@
          fd(self=Mapping({"abcG" : {u"": 1}})):ValueError:('empty keys are not allowed',)
          fd(self=Mapping({"abcG" : FailingMapping()})):NotImplementedError:()
          fd(self=Mapping({"abcG" : FailingMappingKey()})):NotImplementedError:()
          +fd(self=Mapping({"abcG" : FailingNumber()})):TypeError:('long() argument must be a string or a number',)
          <<< Finished
          >>> Testing *Iter* using fd(self=%s)
          fd(self=FailingIter()):TypeError:('unable to convert FailingIter to vim dictionary',)
          @@ -1023,6 +1103,7 @@
          fd(self={u"": 1}):ValueError:('empty keys are not allowed',)
          fd(self=FailingMapping()):NotImplementedError:()
          fd(self=FailingMappingKey()):NotImplementedError:()
          +fd(self=FailingNumber()):TypeError:('unable to convert FailingNumber to vim dictionary',)
          <<< Finished
          >>> Testing ConvertFromPyMapping using fd(self=%s)
          fd(self=[]):TypeError:('unable to convert object to vim dictionary',)
          @@ -1040,14 +1121,23 @@
          vim.current.window.buffer = 0:TypeError:('readonly attribute: buffer',)
          vim.current.window.cursor = (100000000, 100000000):error:('cursor position outside buffer',)
          vim.current.window.cursor = True:TypeError:('argument must be 2-item sequence, not bool',)
          -vim.current.window.height = "abcK":TypeError:('expected int(), long() or something supporting coercing to long(), but got str',)
          -vim.current.window.width = "abcL":TypeError:('expected int(), long() or something supporting coercing to long(), but got str',)
          +>>> Testing NumberToLong using vim.current.window.height = %s
          +vim.current.window.height = []:TypeError:('expected int(), long() or something supporting coercing to long(), but got list',)
          +vim.current.window.height = None:TypeError:('expected int(), long() or something supporting coercing to long(), but got NoneType',)
          +vim.current.window.height = -1:ValueError:('number must be greater or equal to zero',)
          +<<< Finished
          +>>> Testing NumberToLong using vim.current.window.width = %s
          +vim.current.window.width = []:TypeError:('expected int(), long() or something supporting coercing to long(), but got list',)
          +vim.current.window.width = None:TypeError:('expected int(), long() or something supporting coercing to long(), but got NoneType',)
          +vim.current.window.width = -1:ValueError:('number must be greater or equal to zero',)
          +<<< Finished
          vim.current.window.xxxxxx = True:AttributeError:('xxxxxx',)
          > WinList
          >> WinListItem
          vim.windows[1000]:IndexError:('no such window',)
          > Buffer
          >> StringToLine (indirect)
          +vim.current.buffer[0] = u"\na":error:('string cannot contain newlines',)
          vim.current.buffer[0] = "\na":error:('string cannot contain newlines',)
          >> SetBufferLine (indirect)
          vim.current.buffer[0] = True:TypeError:('bad argument type for built-in operation',)
          @@ -1075,8 +1165,13 @@
          vim.current.buffer.range(1, 2, 3):TypeError:('function takes exactly 2 arguments (3 given)',)
          > BufMap
          >> BufMapItem
          +vim.buffers[100000000]:KeyError:(100000000,)
          +>>> Testing NumberToLong using vim.buffers[%s]
          +vim.buffers[[]]:TypeError:('expected int(), long() or something supporting coercing to long(), but got list',)
          vim.buffers[None]:TypeError:('expected int(), long() or something supporting coercing to long(), but got NoneType',)
          -vim.buffers[100000000]:KeyError:(100000000,)
          +vim.buffers[-1]:ValueError:('number must be greater then zero',)
          +vim.buffers[0]:ValueError:('number must be greater then zero',)
          +<<< Finished
          > Current
          >> CurrentGetattr
          vim.current.xxx:AttributeError:('xxx',)
          @@ -1086,9 +1181,14 @@
          vim.current.window = True:TypeError:('expected vim.Window object, but got bool',)
          vim.current.tabpage = True:TypeError:('expected vim.TabPage object, but got bool',)
          vim.current.xxx = True:AttributeError:('xxx',)
          +['/testdir']
          +'/testdir'
          2,xx
          before
          after
          +pythonx/topmodule/__init__.py
          +pythonx/topmodule/submodule/__init__.py
          +pythonx/topmodule/submodule/subsubmodule/subsubsubmodule.py
          vim.command("throw 'abcN'"):error:('abcN',)
          Exe("throw 'def'"):error:('def',)
          vim.eval("Exe('throw ''ghi''')"):error:('ghi',)
          diff --git a/src/testdir/test87.in b/src/testdir/test87.in
          --- a/src/testdir/test87.in
          +++ b/src/testdir/test87.in
          @@ -335,9 +335,9 @@
          EOF
          :py3 sys.settrace(traceit)
          :py3 trace_main()
          +:py3 sys.settrace(None)
          :py3 del traceit
          :py3 del trace_main
          -:py3 sys.settrace(None)
          :$put =string(l)
          :"
          :" Vars
          @@ -898,6 +898,7 @@
          '{"": 1}', # Same, but with unicode object
          'FailingMapping()', #
          'FailingMappingKey()', #
          + 'FailingNumber()', #
          ))

          def convertfrompymapping_test(expr):
          @@ -912,6 +913,15 @@
          'FailingIterNext()',
          ))

          +def number_test(expr, natural=False, unsigned=False):
          + if natural:
          + unsigned = True
          + return subexpr_test(expr, 'NumberToLong', (
          + '[]',
          + 'None',
          + ) + (('-1',) if unsigned else ())
          + + (('0',) if natural else ()))
          +
          class FailingTrue(object):
          def __bool__(self):
          raise NotImplementedError
          @@ -948,10 +958,23 @@
          else:
          return super(FailingList, self).__getitem__(idx)

          +class NoArgsCall(object):
          + def __call__(self):
          + pass
          +
          +class FailingCall(object):
          + def __call__(self, path):
          + raise NotImplementedError
          +
          +class FailingNumber(object):
          + def __int__(self):
          + raise NotImplementedError
          +
          cb.append("> Output")
          cb.append(">> OutputSetattr")
          ee('del sys.stdout.softspace')
          -ee('sys.stdout.softspace = []')
          +number_test('sys.stdout.softspace = %s', unsigned=True)
          +number_test('sys.stderr.softspace = %s', unsigned=True)
          ee('sys.stdout.attr = None')
          cb.append(">> OutputWrite")
          ee('sys.stdout.write(None)')
          @@ -960,18 +983,34 @@
          ee('sys.stdout.writelines([1])')
          iter_test('sys.stdout.writelines(%s)')
          cb.append("> VimCommand")
          -ee('vim.command(1)')
          +stringtochars_test('vim.command(%s)')
          +ee('vim.command("", 2)')
          #! Not checked: vim->python exceptions translating: checked later
          cb.append("> VimToPython")
          #! Not checked: everything: needs errors in internal python functions
          cb.append("> VimEval")
          -ee('vim.eval(1)')
          +stringtochars_test('vim.eval(%s)')
          +ee('vim.eval("", FailingTrue())')
          #! Not checked: everything: needs errors in internal python functions
          cb.append("> VimEvalPy")
          -ee('vim.bindeval(1)')
          +stringtochars_test('vim.bindeval(%s)')
          +ee('vim.eval("", 2)')
          #! Not checked: vim->python exceptions translating: checked later
          cb.append("> VimStrwidth")
          -ee('vim.strwidth(1)')
          +stringtochars_test('vim.strwidth(%s)')
          +cb.append("> VimForeachRTP")
          +ee('vim.foreach_rtp(None)')
          +ee('vim.foreach_rtp(NoArgsCall())')
          +ee('vim.foreach_rtp(FailingCall())')
          +ee('vim.foreach_rtp(int, 2)')
          +cb.append('> import')
          +old_rtp = vim.options['rtp']
          +vim.options['rtp'] = os.getcwd().replace(',', '\\,').replace('\\', '\\\\')
          +ee('import xxx_no_such_module_xxx')
          +ee('import failing_import')
          +ee('import failing')
          +vim.options['rtp'] = old_rtp
          +del old_rtp
          cb.append("> Dictionary")
          cb.append(">> DictionaryConstructor")
          ee('vim.Dictionary("abcI")')
          @@ -1050,8 +1089,8 @@
          ee('vim.current.window.buffer = 0')
          ee('vim.current.window.cursor = (100000000, 100000000)')
          ee('vim.current.window.cursor = True')
          -ee('vim.current.window.height = "abcK"')
          -ee('vim.current.window.width = "abcL"')
          +number_test('vim.current.window.height = %s', unsigned=True)
          +number_test('vim.current.window.width = %s', unsigned=True)
          ee('vim.current.window.xxxxxx = True')
          cb.append("> WinList")
          cb.append(">> WinListItem")
          @@ -1059,6 +1098,7 @@
          cb.append("> Buffer")
          cb.append(">> StringToLine (indirect)")
          ee('vim.current.buffer[0] = "\\na"')
          +ee('vim.current.buffer[0] = b"\\na"')
          cb.append(">> SetBufferLine (indirect)")
          ee('vim.current.buffer[0] = True')
          cb.append(">> SetBufferLineList (indirect)")
          @@ -1085,8 +1125,8 @@
          ee('vim.current.buffer.range(1, 2, 3)')
          cb.append("> BufMap")
          cb.append(">> BufMapItem")
          -ee('vim.buffers[None]')
          ee('vim.buffers[100000000]')
          +number_test('vim.buffers[%s]', natural=True)
          cb.append("> Current")
          cb.append(">> CurrentGetattr")
          ee('vim.current.xxx')
          @@ -1110,12 +1150,16 @@
          del convertfrompyobject_test
          del convertfrompymapping_test
          del iter_test
          +del number_test
          del FailingTrue
          del FailingIter
          del FailingIterNext
          del FailingMapping
          del FailingMappingKey
          del FailingList
          +del NoArgsCall
          +del FailingCall
          +del FailingNumber
          EOF
          :delfunction F
          :"
          @@ -1124,6 +1168,16 @@
          sys.path.insert(0, os.path.join(os.getcwd(), 'python_before'))
          sys.path.append(os.path.join(os.getcwd(), 'python_after'))
          vim.options['rtp'] = os.getcwd().replace(',', '\\,').replace('\\', '\\\\')
          +l = []
          +def callback(path):
          + l.append(os.path.relpath(path))
          +vim.foreach_rtp(callback)
          +cb.append(repr(l))
          +del l
          +def callback(path):
          + return os.path.relpath(path)
          +cb.append(repr(vim.foreach_rtp(callback)))
          +del callback
          from module import dir as d
          from modulex import ddir
          cb.append(d + ',' + ddir)
          @@ -1131,10 +1185,19 @@
          cb.append(before.dir)
          import after
          cb.append(after.dir)
          +import topmodule as tm
          +import topmodule.submodule as tms
          +import topmodule.submodule.subsubmodule.subsubsubmodule as tmsss
          +cb.append(tm.__file__[-len('modulex/topmodule/__init__.py'):])
          +cb.append(tms.__file__[-len('modulex/topmodule/submodule/__init__.py'):])
          +cb.append(tmsss.__file__[-len('modulex/topmodule/submodule/subsubmodule/subsubsubmodule.py'):])
          del before
          del after
          del d
          del ddir
          +del tm
          +del tms
          +del tmsss
          EOF
          :"
          :" Test exceptions
          diff --git a/src/testdir/test87.ok b/src/testdir/test87.ok
          --- a/src/testdir/test87.ok
          +++ b/src/testdir/test87.ok
          @@ -430,7 +430,16 @@
          > Output
          >> OutputSetattr
          del sys.stdout.softspace:(<class 'AttributeError'>, AttributeError("can't delete OutputObject attributes",))
          +>>> Testing NumberToLong using sys.stdout.softspace = %s
          sys.stdout.softspace = []:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',))
          +sys.stdout.softspace = None:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',))
          +sys.stdout.softspace = -1:(<class 'ValueError'>, ValueError('number must be greater or equal to zero',))
          +<<< Finished
          +>>> Testing NumberToLong using sys.stderr.softspace = %s
          +sys.stderr.softspace = []:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',))
          +sys.stderr.softspace = None:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',))
          +sys.stderr.softspace = -1:(<class 'ValueError'>, ValueError('number must be greater or equal to zero',))
          +<<< Finished
          sys.stdout.attr = None:(<class 'AttributeError'>, AttributeError('invalid attribute: attr',))
          >> OutputWrite
          sys.stdout.write(None):(<class 'TypeError'>, TypeError("Can't convert 'NoneType' object to str implicitly",))
          @@ -442,14 +451,42 @@
          sys.stdout.writelines(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError())
          <<< Finished
          > VimCommand
          +>>> Testing StringToChars using vim.command(%s)
          vim.command(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
          +vim.command(b"\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
          +vim.command("\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
          +<<< Finished
          +vim.command("", 2):(<class 'TypeError'>, TypeError('command() takes exactly one argument (2 given)',))
          > VimToPython
          > VimEval
          +>>> Testing StringToChars using vim.eval(%s)
          vim.eval(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
          +vim.eval(b"\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
          +vim.eval("\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
          +<<< Finished
          +vim.eval("", FailingTrue()):(<class 'TypeError'>, TypeError('function takes exactly 1 argument (2 given)',))
          > VimEvalPy
          +>>> Testing StringToChars using vim.bindeval(%s)
          vim.bindeval(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
          +vim.bindeval(b"\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
          +vim.bindeval("\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
          +<<< Finished
          +vim.eval("", 2):(<class 'TypeError'>, TypeError('function takes exactly 1 argument (2 given)',))
          > VimStrwidth
          +>>> Testing StringToChars using vim.strwidth(%s)
          vim.strwidth(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
          +vim.strwidth(b"\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
          +vim.strwidth("\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
          +<<< Finished
          +> VimForeachRTP
          +vim.foreach_rtp(None):(<class 'TypeError'>, TypeError("'NoneType' object is not callable",))
          +vim.foreach_rtp(NoArgsCall()):(<class 'TypeError'>, TypeError('__call__() takes exactly 1 positional argument (2 given)',))
          +vim.foreach_rtp(FailingCall()):(<class 'NotImplementedError'>, NotImplementedError())
          +vim.foreach_rtp(int, 2):(<class 'TypeError'>, TypeError('foreach_rtp() takes exactly one argument (2 given)',))
          +> import
          +import xxx_no_such_module_xxx:(<class 'ImportError'>, ImportError('No module named xxx_no_such_module_xxx',))
          +import failing_import:(<class 'ImportError'>, ImportError('No module named failing_import',))
          +import failing:(<class 'ImportError'>, ImportError('No module named failing',))
          > Dictionary
          >> DictionaryConstructor
          vim.Dictionary("abcI"):(<class 'ValueError'>, ValueError('expected sequence element of size 2, but got sequence of size 1',))
          @@ -502,6 +539,7 @@
          d["a"] = {"abcF" : {"": 1}}:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
          d["a"] = {"abcF" : FailingMapping()}:(<class 'NotImplementedError'>, NotImplementedError())
          d["a"] = {"abcF" : FailingMappingKey()}:(<class 'NotImplementedError'>, NotImplementedError())
          +d["a"] = {"abcF" : FailingNumber()}:(<class 'NotImplementedError'>, NotImplementedError())
          <<< Finished
          >>> Testing StringToChars using d["a"] = Mapping({%s : 1})
          d["a"] = Mapping({1 : 1}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
          @@ -528,6 +566,7 @@
          d["a"] = Mapping({"abcG" : {"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
          d["a"] = Mapping({"abcG" : FailingMapping()}):(<class 'NotImplementedError'>, NotImplementedError())
          d["a"] = Mapping({"abcG" : FailingMappingKey()}):(<class 'NotImplementedError'>, NotImplementedError())
          +d["a"] = Mapping({"abcG" : FailingNumber()}):(<class 'NotImplementedError'>, NotImplementedError())
          <<< Finished
          >>> Testing *Iter* using d["a"] = %s
          d["a"] = FailingIter():(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
          @@ -539,6 +578,7 @@
          d["a"] = {"": 1}:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
          d["a"] = FailingMapping():(<class 'NotImplementedError'>, NotImplementedError())
          d["a"] = FailingMappingKey():(<class 'NotImplementedError'>, NotImplementedError())
          +d["a"] = FailingNumber():(<class 'NotImplementedError'>, NotImplementedError())
          <<< Finished
          >> DictionaryUpdate
          >>> kwargs
          @@ -574,6 +614,7 @@
          d.update({"abcF" : {"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
          d.update({"abcF" : FailingMapping()}):(<class 'NotImplementedError'>, NotImplementedError())
          d.update({"abcF" : FailingMappingKey()}):(<class 'NotImplementedError'>, NotImplementedError())
          +d.update({"abcF" : FailingNumber()}):(<class 'NotImplementedError'>, NotImplementedError())
          <<< Finished
          >>> Testing StringToChars using d.update(Mapping({%s : 1}))
          d.update(Mapping({1 : 1})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
          @@ -600,6 +641,7 @@
          d.update(Mapping({"abcG" : {"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
          d.update(Mapping({"abcG" : FailingMapping()})):(<class 'NotImplementedError'>, NotImplementedError())
          d.update(Mapping({"abcG" : FailingMappingKey()})):(<class 'NotImplementedError'>, NotImplementedError())
          +d.update(Mapping({"abcG" : FailingNumber()})):(<class 'NotImplementedError'>, NotImplementedError())
          <<< Finished
          >>> Testing *Iter* using d.update(%s)
          d.update(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError())
          @@ -611,6 +653,7 @@
          d.update({"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
          d.update(FailingMapping()):(<class 'NotImplementedError'>, NotImplementedError())
          d.update(FailingMappingKey()):(<class 'NotImplementedError'>, NotImplementedError())
          +d.update(FailingNumber()):(<class 'TypeError'>, TypeError("'FailingNumber' object is not iterable",))
          <<< Finished
          >>> Testing StringToChars using d.update(((%s, 0),))
          d.update(((1, 0),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
          @@ -642,6 +685,7 @@
          d.update((("a", {"abcF" : {"": 1}}),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
          d.update((("a", {"abcF" : FailingMapping()}),)):(<class 'NotImplementedError'>, NotImplementedError())
          d.update((("a", {"abcF" : FailingMappingKey()}),)):(<class 'NotImplementedError'>, NotImplementedError())
          +d.update((("a", {"abcF" : FailingNumber()}),)):(<class 'NotImplementedError'>, NotImplementedError())
          <<< Finished
          >>> Testing StringToChars using d.update((("a", Mapping({%s : 1})),))
          d.update((("a", Mapping({1 : 1})),)):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
          @@ -668,6 +712,7 @@
          d.update((("a", Mapping({"abcG" : {"": 1}})),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
          d.update((("a", Mapping({"abcG" : FailingMapping()})),)):(<class 'NotImplementedError'>, NotImplementedError())
          d.update((("a", Mapping({"abcG" : FailingMappingKey()})),)):(<class 'NotImplementedError'>, NotImplementedError())
          +d.update((("a", Mapping({"abcG" : FailingNumber()})),)):(<class 'NotImplementedError'>, NotImplementedError())
          <<< Finished
          >>> Testing *Iter* using d.update((("a", %s),))
          d.update((("a", FailingIter()),)):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
          @@ -679,6 +724,7 @@
          d.update((("a", {"": 1}),)):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
          d.update((("a", FailingMapping()),)):(<class 'NotImplementedError'>, NotImplementedError())
          d.update((("a", FailingMappingKey()),)):(<class 'NotImplementedError'>, NotImplementedError())
          +d.update((("a", FailingNumber()),)):(<class 'NotImplementedError'>, NotImplementedError())
          <<< Finished
          >> DictionaryPopItem
          d.popitem(1, 2):(<class 'TypeError'>, TypeError('popitem() takes no arguments (2 given)',))
          @@ -717,6 +763,7 @@
          vim.List([{"abcF" : {"": 1}}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
          vim.List([{"abcF" : FailingMapping()}]):(<class 'NotImplementedError'>, NotImplementedError())
          vim.List([{"abcF" : FailingMappingKey()}]):(<class 'NotImplementedError'>, NotImplementedError())
          +vim.List([{"abcF" : FailingNumber()}]):(<class 'NotImplementedError'>, NotImplementedError())
          <<< Finished
          >>> Testing StringToChars using vim.List([Mapping({%s : 1})])
          vim.List([Mapping({1 : 1})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
          @@ -743,6 +790,7 @@
          vim.List([Mapping({"abcG" : {"": 1}})]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
          vim.List([Mapping({"abcG" : FailingMapping()})]):(<class 'NotImplementedError'>, NotImplementedError())
          vim.List([Mapping({"abcG" : FailingMappingKey()})]):(<class 'NotImplementedError'>, NotImplementedError())
          +vim.List([Mapping({"abcG" : FailingNumber()})]):(<class 'NotImplementedError'>, NotImplementedError())
          <<< Finished
          >>> Testing *Iter* using vim.List([%s])
          vim.List([FailingIter()]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
          @@ -754,6 +802,7 @@
          vim.List([{"": 1}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
          vim.List([FailingMapping()]):(<class 'NotImplementedError'>, NotImplementedError())
          vim.List([FailingMappingKey()]):(<class 'NotImplementedError'>, NotImplementedError())
          +vim.List([FailingNumber()]):(<class 'NotImplementedError'>, NotImplementedError())
          <<< Finished
          >> ListItem
          l[1000]:(<class 'IndexError'>, IndexError('list index out of range',))
          @@ -791,6 +840,7 @@
          l[:] = [{"abcF" : {"": 1}}]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
          l[:] = [{"abcF" : FailingMapping()}]:(<class 'NotImplementedError'>, NotImplementedError())
          l[:] = [{"abcF" : FailingMappingKey()}]:(<class 'NotImplementedError'>, NotImplementedError())
          +l[:] = [{"abcF" : FailingNumber()}]:(<class 'NotImplementedError'>, NotImplementedError())
          <<< Finished
          >>> Testing StringToChars using l[:] = [Mapping({%s : 1})]
          l[:] = [Mapping({1 : 1})]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
          @@ -817,6 +867,7 @@
          l[:] = [Mapping({"abcG" : {"": 1}})]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
          l[:] = [Mapping({"abcG" : FailingMapping()})]:(<class 'NotImplementedError'>, NotImplementedError())
          l[:] = [Mapping({"abcG" : FailingMappingKey()})]:(<class 'NotImplementedError'>, NotImplementedError())
          +l[:] = [Mapping({"abcG" : FailingNumber()})]:(<class 'NotImplementedError'>, NotImplementedError())
          <<< Finished
          >>> Testing *Iter* using l[:] = [%s]
          l[:] = [FailingIter()]:(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
          @@ -828,6 +879,7 @@
          l[:] = [{"": 1}]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
          l[:] = [FailingMapping()]:(<class 'NotImplementedError'>, NotImplementedError())
          l[:] = [FailingMappingKey()]:(<class 'NotImplementedError'>, NotImplementedError())
          +l[:] = [FailingNumber()]:(<class 'NotImplementedError'>, NotImplementedError())
          <<< Finished
          >> ListConcatInPlace
          >>> Testing *Iter* using l.extend(%s)
          @@ -859,6 +911,7 @@
          l.extend([{"abcF" : {"": 1}}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
          l.extend([{"abcF" : FailingMapping()}]):(<class 'NotImplementedError'>, NotImplementedError())
          l.extend([{"abcF" : FailingMappingKey()}]):(<class 'NotImplementedError'>, NotImplementedError())
          +l.extend([{"abcF" : FailingNumber()}]):(<class 'NotImplementedError'>, NotImplementedError())
          <<< Finished
          >>> Testing StringToChars using l.extend([Mapping({%s : 1})])
          l.extend([Mapping({1 : 1})]):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
          @@ -885,6 +938,7 @@
          l.extend([Mapping({"abcG" : {"": 1}})]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
          l.extend([Mapping({"abcG" : FailingMapping()})]):(<class 'NotImplementedError'>, NotImplementedError())
          l.extend([Mapping({"abcG" : FailingMappingKey()})]):(<class 'NotImplementedError'>, NotImplementedError())
          +l.extend([Mapping({"abcG" : FailingNumber()})]):(<class 'NotImplementedError'>, NotImplementedError())
          <<< Finished
          >>> Testing *Iter* using l.extend([%s])
          l.extend([FailingIter()]):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
          @@ -896,6 +950,7 @@
          l.extend([{"": 1}]):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
          l.extend([FailingMapping()]):(<class 'NotImplementedError'>, NotImplementedError())
          l.extend([FailingMappingKey()]):(<class 'NotImplementedError'>, NotImplementedError())
          +l.extend([FailingNumber()]):(<class 'NotImplementedError'>, NotImplementedError())
          <<< Finished
          >> ListSetattr
          del l.locked:(<class 'AttributeError'>, AttributeError('cannot delete vim.List attributes',))
          @@ -932,6 +987,7 @@
          f({"abcF" : {"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
          f({"abcF" : FailingMapping()}):(<class 'NotImplementedError'>, NotImplementedError())
          f({"abcF" : FailingMappingKey()}):(<class 'NotImplementedError'>, NotImplementedError())
          +f({"abcF" : FailingNumber()}):(<class 'NotImplementedError'>, NotImplementedError())
          <<< Finished
          >>> Testing StringToChars using f(Mapping({%s : 1}))
          f(Mapping({1 : 1})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
          @@ -958,6 +1014,7 @@
          f(Mapping({"abcG" : {"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
          f(Mapping({"abcG" : FailingMapping()})):(<class 'NotImplementedError'>, NotImplementedError())
          f(Mapping({"abcG" : FailingMappingKey()})):(<class 'NotImplementedError'>, NotImplementedError())
          +f(Mapping({"abcG" : FailingNumber()})):(<class 'NotImplementedError'>, NotImplementedError())
          <<< Finished
          >>> Testing *Iter* using f(%s)
          f(FailingIter()):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim structure',))
          @@ -969,6 +1026,7 @@
          f({"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
          f(FailingMapping()):(<class 'NotImplementedError'>, NotImplementedError())
          f(FailingMappingKey()):(<class 'NotImplementedError'>, NotImplementedError())
          +f(FailingNumber()):(<class 'NotImplementedError'>, NotImplementedError())
          <<< Finished
          >>> Testing StringToChars using fd(self={%s : 1})
          fd(self={1 : 1}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
          @@ -995,6 +1053,7 @@
          fd(self={"abcF" : {"": 1}}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
          fd(self={"abcF" : FailingMapping()}):(<class 'NotImplementedError'>, NotImplementedError())
          fd(self={"abcF" : FailingMappingKey()}):(<class 'NotImplementedError'>, NotImplementedError())
          +fd(self={"abcF" : FailingNumber()}):(<class 'NotImplementedError'>, NotImplementedError())
          <<< Finished
          >>> Testing StringToChars using fd(self=Mapping({%s : 1}))
          fd(self=Mapping({1 : 1})):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
          @@ -1021,6 +1080,7 @@
          fd(self=Mapping({"abcG" : {"": 1}})):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
          fd(self=Mapping({"abcG" : FailingMapping()})):(<class 'NotImplementedError'>, NotImplementedError())
          fd(self=Mapping({"abcG" : FailingMappingKey()})):(<class 'NotImplementedError'>, NotImplementedError())
          +fd(self=Mapping({"abcG" : FailingNumber()})):(<class 'NotImplementedError'>, NotImplementedError())
          <<< Finished
          >>> Testing *Iter* using fd(self=%s)
          fd(self=FailingIter()):(<class 'TypeError'>, TypeError('unable to convert FailingIter to vim dictionary',))
          @@ -1032,6 +1092,7 @@
          fd(self={"": 1}):(<class 'ValueError'>, ValueError('empty keys are not allowed',))
          fd(self=FailingMapping()):(<class 'NotImplementedError'>, NotImplementedError())
          fd(self=FailingMappingKey()):(<class 'NotImplementedError'>, NotImplementedError())
          +fd(self=FailingNumber()):(<class 'TypeError'>, TypeError('unable to convert FailingNumber to vim dictionary',))
          <<< Finished
          >>> Testing ConvertFromPyMapping using fd(self=%s)
          fd(self=[]):(<class 'AttributeError'>, AttributeError('keys',))
          @@ -1049,8 +1110,16 @@
          vim.current.window.buffer = 0:(<class 'TypeError'>, TypeError('readonly attribute: buffer',))
          vim.current.window.cursor = (100000000, 100000000):(<class 'vim.error'>, error('cursor position outside buffer',))
          vim.current.window.cursor = True:(<class 'TypeError'>, TypeError('argument must be 2-item sequence, not bool',))
          -vim.current.window.height = "abcK":(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got str',))
          -vim.current.window.width = "abcL":(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got str',))
          +>>> Testing NumberToLong using vim.current.window.height = %s
          +vim.current.window.height = []:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',))
          +vim.current.window.height = None:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',))
          +vim.current.window.height = -1:(<class 'ValueError'>, ValueError('number must be greater or equal to zero',))
          +<<< Finished
          +>>> Testing NumberToLong using vim.current.window.width = %s
          +vim.current.window.width = []:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',))
          +vim.current.window.width = None:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',))
          +vim.current.window.width = -1:(<class 'ValueError'>, ValueError('number must be greater or equal to zero',))
          +<<< Finished
          vim.current.window.xxxxxx = True:(<class 'AttributeError'>, AttributeError('xxxxxx',))
          > WinList
          >> WinListItem
          @@ -1058,6 +1127,7 @@
          > Buffer
          >> StringToLine (indirect)
          vim.current.buffer[0] = "\na":(<class 'vim.error'>, error('string cannot contain newlines',))
          +vim.current.buffer[0] = b"\na":(<class 'vim.error'>, error('string cannot contain newlines',))
          >> SetBufferLine (indirect)
          vim.current.buffer[0] = True:(<class 'TypeError'>, TypeError('bad argument type for built-in operation',))
          >> SetBufferLineList (indirect)
          @@ -1084,8 +1154,13 @@
          vim.current.buffer.range(1, 2, 3):(<class 'TypeError'>, TypeError('function takes exactly 2 arguments (3 given)',))
          > BufMap
          >> BufMapItem
          +vim.buffers[100000000]:(<class 'KeyError'>, KeyError(100000000,))
          +>>> Testing NumberToLong using vim.buffers[%s]
          +vim.buffers[[]]:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',))
          vim.buffers[None]:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',))
          -vim.buffers[100000000]:(<class 'KeyError'>, KeyError(100000000,))
          +vim.buffers[-1]:(<class 'ValueError'>, ValueError('number must be greater then zero',))
          +vim.buffers[0]:(<class 'ValueError'>, ValueError('number must be greater then zero',))
          +<<< Finished
          > Current
          >> CurrentGetattr
          vim.current.xxx:(<class 'AttributeError'>, AttributeError("'vim.currentdata' object has no attribute 'xxx'",))
          @@ -1095,9 +1170,14 @@
          vim.current.window = True:(<class 'TypeError'>, TypeError('expected vim.Window object, but got bool',))
          vim.current.tabpage = True:(<class 'TypeError'>, TypeError('expected vim.TabPage object, but got bool',))
          vim.current.xxx = True:(<class 'AttributeError'>, AttributeError('xxx',))
          +['.']
          +'.'
          3,xx
          before
          after
          +pythonx/topmodule/__init__.py
          +pythonx/topmodule/submodule/__init__.py
          +pythonx/topmodule/submodule/subsubmodule/subsubsubmodule.py
          vim.command("throw 'abcN'"):(<class 'vim.error'>, error('abcN',))
          Exe("throw 'def'"):(<class 'vim.error'>, error('def',))
          vim.eval("Exe('throw ''ghi''')"):(<class 'vim.error'>, error('ghi',))

          --
          --
          You received this message from the "vim_dev" maillist.
          Do not top-post! Type your reply below the text you are replying to.
          For more information, visit http://www.vim.org/maillist.php

          ---
          You received this message because you are subscribed to the Google Groups "vim_dev" group.
          To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscribe@....
          For more options, visit https://groups.google.com/groups/opt_out.
        • Bram Moolenaar
          ... Unfortunately this breaks all translations. E.g.: @@ -120,7 +122,7 @@ } else { - PyErr_SetString(PyExc_TypeError, _( object must be string )); +
          Message 4 of 25 , Jun 23, 2013
          • 0 Attachment
            ZyX wrote:

            > # HG changeset patch
            > # User ZyX <kp-pav@...>
            > # Date 1371238936 -14400
            > # Fri Jun 14 23:42:16 2013 +0400
            > # Branch python-fixes
            > # Node ID abcf5d9458ee826516c1051cfd14d279b1097174
            > # Parent b9d4dfa09951d4fb75972df34802675edf24a17e
            > Make macros do translation of exception messages
            >
            > Reason: it will be easy to delete/restore translating

            Unfortunately this breaks all translations. E.g.:

            @@ -120,7 +122,7 @@
            }
            else
            {
            - PyErr_SetString(PyExc_TypeError, _("object must be string"));
            + PyErr_SET_STRING(PyExc_TypeError, "object must be string");
            return NULL;
            }

            This string will not be translated. It should have been:

            + PyErr_SET_STRING(PyExc_TypeError, N_("object must be string"));

            The N_() macro marks a string as translatable.

            I'll include this patch now, since otherwise there will be problems with
            all following patches. But please fix this ASAP.


            --
            GOD: That is your purpose Arthur ... the Quest for the Holy Grail ...
            "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD

            /// Bram Moolenaar -- Bram@... -- http://www.Moolenaar.net \\\
            /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
            \\\ an exciting new programming language -- http://www.Zimbu.org ///
            \\\ help me help AIDS victims -- http://ICCF-Holland.org ///

            --
            --
            You received this message from the "vim_dev" maillist.
            Do not top-post! Type your reply below the text you are replying to.
            For more information, visit http://www.vim.org/maillist.php

            ---
            You received this message because you are subscribed to the Google Groups "vim_dev" group.
            To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscribe@....
            For more options, visit https://groups.google.com/groups/opt_out.
          • Bram Moolenaar
            ... This patch causes test 86 to fail: 1025c1025
            Message 5 of 25 , Jun 23, 2013
            • 0 Attachment
              ZyX wrote:

              > # HG changeset patch
              > # User ZyX <kp-pav@...>
              > # Date 1371375798 -14400
              > # Sun Jun 16 13:43:18 2013 +0400
              > # Branch python-fixes
              > # Node ID 81c6385adb920b486a9f3b912de3b7e86e57569d
              > # Parent abcf5d9458ee826516c1051cfd14d279b1097174
              > Make exception messages more verbose

              This patch causes test 86 to fail:

              1025c1025
              < fd(self=[]):TypeError:('unable to convert list to vim dictionary',)
              ---
              > fd(self=[]):TypeError:('unable to convert object to vim dictionary',)

              I'll change the .ok file to work around it, but pleae check the cause of
              the failure.


              --
              "Time flies like an arrow". So I put an arrow on my desk, now
              awaiting one of these time flies showing up.

              /// Bram Moolenaar -- Bram@... -- http://www.Moolenaar.net \\\
              /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
              \\\ an exciting new programming language -- http://www.Zimbu.org ///
              \\\ help me help AIDS victims -- http://ICCF-Holland.org ///

              --
              --
              You received this message from the "vim_dev" maillist.
              Do not top-post! Type your reply below the text you are replying to.
              For more information, visit http://www.vim.org/maillist.php

              ---
              You received this message because you are subscribed to the Google Groups "vim_dev" group.
              To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscribe@....
              For more options, visit https://groups.google.com/groups/opt_out.
            • ZyX
              ... I do not understand. `_()` was moved into the macros. How is PyErr_SET_STRING(exc, message ) different from PyErr_SetString(exc, _( message )) if macros
              Message 6 of 25 , Jun 23, 2013
              • 0 Attachment
                On Sunday, June 23, 2013 3:27:39 PM UTC+4, Bram Moolenaar wrote:
                > ZyX wrote:
                >
                > > # HG changeset patch
                > > # User ZyX <kp-pav@...>
                > > # Date 1371238936 -14400
                > > # Fri Jun 14 23:42:16 2013 +0400
                > > # Branch python-fixes
                > > # Node ID abcf5d9458ee826516c1051cfd14d279b1097174
                > > # Parent b9d4dfa09951d4fb75972df34802675edf24a17e
                > > Make macros do translation of exception messages
                > >
                > > Reason: it will be easy to delete/restore translating
                >
                > Unfortunately this breaks all translations. E.g.:
                >
                > @@ -120,7 +122,7 @@
                > }
                > else
                > {
                > - PyErr_SetString(PyExc_TypeError, _("object must be string"));
                > + PyErr_SET_STRING(PyExc_TypeError, "object must be string");
                > return NULL;
                > }
                >
                > This string will not be translated. It should have been:
                >
                > + PyErr_SET_STRING(PyExc_TypeError, N_("object must be string"));
                >
                > The N_() macro marks a string as translatable.
                >
                > I'll include this patch now, since otherwise there will be problems with
                > all following patches. But please fix this ASAP.

                I do not understand. `_()` was moved into the macros. How is PyErr_SET_STRING(exc, "message") different from PyErr_SetString(exc, _("message")) if macros `PyErr_SET_STRING(exc, msg)` is defined to `PyErr_SetString(exc, _(msg))`?

                If I need to have `N_()` there (in the macros definition) I will write a patch, but I won't write `PyErr_SET_STRING(exc, N_(msg))`. It is the very intention: move all _() out of the code to the macros in case I find some better argument to not ever translate any exception messages then I have currently.

                ---

                Just tested: translations do work. Steps to reproduce:

                src/vim -u NONE -N -c 'lang ru_RU.UTF-8' -c 'py import vim' -c 'py b=vim.current.buffer' -c 'bw!' -c 'py print b.name' a

                . If this locale is supported it prints "vim.error: попытка сослаться на уничтоженный буфер" in place of "vim.error: attempt to refer to deleted buffer".

                --
                --
                You received this message from the "vim_dev" maillist.
                Do not top-post! Type your reply below the text you are replying to.
                For more information, visit http://www.vim.org/maillist.php

                ---
                You received this message because you are subscribed to the Google Groups "vim_dev" group.
                To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscribe@....
                For more options, visit https://groups.google.com/groups/opt_out.
              • Bram Moolenaar
                ... Please follow my instructions. gettext searches the source code for _() and N_() , nothing else. After patch 7.3.1229 existing translations will work,
                Message 7 of 25 , Jun 23, 2013
                • 0 Attachment
                  ZyX wrote:

                  > > > # HG changeset patch
                  > > > # User ZyX <kp-pav@...>
                  > > > # Date 1371238936 -14400
                  > > > # Fri Jun 14 23:42:16 2013 +0400
                  > > > # Branch python-fixes
                  > > > # Node ID abcf5d9458ee826516c1051cfd14d279b1097174
                  > > > # Parent b9d4dfa09951d4fb75972df34802675edf24a17e
                  > > > Make macros do translation of exception messages
                  > > >
                  > > > Reason: it will be easy to delete/restore translating
                  > >
                  > > Unfortunately this breaks all translations. E.g.:
                  > >
                  > > @@ -120,7 +122,7 @@
                  > > }
                  > > else
                  > > {
                  > > - PyErr_SetString(PyExc_TypeError, _("object must be string"));
                  > > + PyErr_SET_STRING(PyExc_TypeError, "object must be string");
                  > > return NULL;
                  > > }
                  > >
                  > > This string will not be translated. It should have been:
                  > >
                  > > + PyErr_SET_STRING(PyExc_TypeError, N_("object must be string"));
                  > >
                  > > The N_() macro marks a string as translatable.
                  > >
                  > > I'll include this patch now, since otherwise there will be problems with
                  > > all following patches. But please fix this ASAP.
                  >
                  > I do not understand. `_()` was moved into the macros. How is
                  > PyErr_SET_STRING(exc, "message") different from PyErr_SetString(exc,
                  > _("message")) if macros `PyErr_SET_STRING(exc, msg)` is defined to
                  > `PyErr_SetString(exc, _(msg))`?
                  >
                  > If I need to have `N_()` there (in the macros definition) I will write
                  > a patch, but I won't write `PyErr_SET_STRING(exc, N_(msg))`. It is the
                  > very intention: move all _() out of the code to the macros in case I
                  > find some better argument to not ever translate any exception messages
                  > then I have currently.
                  >
                  > ---
                  >
                  > Just tested: translations do work. Steps to reproduce:
                  >
                  > src/vim -u NONE -N -c 'lang ru_RU.UTF-8' -c 'py import vim' -c 'py b=vim.current.buffer' -c 'bw!' -c 'py print b.name' a
                  >
                  > . If this locale is supported it prints "vim.error: попытка сослаться
                  > на уничтоженный буфер" in place of "vim.error: attempt to refer to
                  > deleted buffer".

                  Please follow my instructions. gettext searches the source code for
                  "_()" and "N_()", nothing else. After patch 7.3.1229 existing
                  translations will work, but the next time the translations are updated
                  they will be gone.

                  You can see the effect by running "make ru" in src/po.

                  --
                  A cow comes flying over the battlements, lowing aggressively. The cow
                  lands on GALAHAD'S PAGE, squashing him completely.
                  "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD

                  /// Bram Moolenaar -- Bram@... -- http://www.Moolenaar.net \\\
                  /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
                  \\\ an exciting new programming language -- http://www.Zimbu.org ///
                  \\\ help me help AIDS victims -- http://ICCF-Holland.org ///

                  --
                  --
                  You received this message from the "vim_dev" maillist.
                  Do not top-post! Type your reply below the text you are replying to.
                  For more information, visit http://www.vim.org/maillist.php

                  ---
                  You received this message because you are subscribed to the Google Groups "vim_dev" group.
                  To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscribe@....
                  For more options, visit https://groups.google.com/groups/opt_out.
                • ZyX
                  ... # HG changeset patch # User ZyX # Date 1371991354 -14400 # Sun Jun 23 16:42:34 2013 +0400 # Branch python-fixes # Node ID
                  Message 8 of 25 , Jun 23, 2013
                  • 0 Attachment
                    > Please follow my instructions. gettext searches the source code for
                    > "_()" and "N_()", nothing else. After patch 7.3.1229 existing
                    > translations will work, but the next time the translations are updated
                    > they will be gone.
                    >
                    > You can see the effect by running "make ru" in src/po.

                    # HG changeset patch
                    # User ZyX <kp-pav@...>
                    # Date 1371991354 -14400
                    # Sun Jun 23 16:42:34 2013 +0400
                    # Branch python-fixes
                    # Node ID 3c21dc7cfad1f22855bd64b2a4a79d75cd36b1e3
                    # Parent 8b539b192fd5eae19f61bd3d55a28811ea5bae0c
                    Use N_() to mark strings for translation

                    diff --git a/src/if_py_both.h b/src/if_py_both.h
                    --- a/src/if_py_both.h
                    +++ b/src/if_py_both.h
                    @@ -37,16 +37,17 @@
                    : obj->ob_type->tp_name)

                    #define RAISE_NO_EMPTY_KEYS PyErr_SET_STRING(PyExc_ValueError, \
                    - "empty keys are not allowed")
                    -#define RAISE_LOCKED(type) PyErr_SET_VIM(_(type " is locked"))
                    -#define RAISE_LOCKED_DICTIONARY RAISE_LOCKED("dictionary")
                    -#define RAISE_LOCKED_LIST RAISE_LOCKED("list")
                    -#define RAISE_UNDO_FAIL PyErr_SET_VIM("cannot save undo information")
                    -#define RAISE_LINE_FAIL(act) PyErr_SET_VIM("cannot " act " line")
                    + N_("empty keys are not allowed"))
                    +#define RAISE_LOCKED_DICTIONARY PyErr_SET_VIM(N_("dictionary is locked"))
                    +#define RAISE_LOCKED_LIST PyErr_SET_VIM(N_("list is locked"))
                    +#define RAISE_UNDO_FAIL PyErr_SET_VIM(N_("cannot save undo information"))
                    +#define RAISE_DELETE_LINE_FAIL PyErr_SET_VIM(N_("cannot delete line"))
                    +#define RAISE_INSERT_LINE_FAIL PyErr_SET_VIM(N_("cannot insert line"))
                    +#define RAISE_REPLACE_LINE_FAIL PyErr_SET_VIM(N_("cannot replace line"))
                    #define RAISE_KEY_ADD_FAIL(key) \
                    - PyErr_VIM_FORMAT("failed to add key '%s' to dictionary", key)
                    + PyErr_VIM_FORMAT(N_("failed to add key '%s' to dictionary"), key)
                    #define RAISE_INVALID_INDEX_TYPE(idx) \
                    - PyErr_FORMAT(PyExc_TypeError, "index must be int or slice, not %s", \
                    + PyErr_FORMAT(PyExc_TypeError, N_("index must be int or slice, not %s"), \
                    Py_TYPE_NAME(idx));

                    #define INVALID_BUFFER_VALUE ((buf_T *)(-1))
                    @@ -140,9 +141,9 @@
                    {
                    PyErr_FORMAT(PyExc_TypeError,
                    #if PY_MAJOR_VERSION < 3
                    - "expected str() or unicode() instance, but got %s"
                    + N_("expected str() or unicode() instance, but got %s")
                    #else
                    - "expected bytes() or str() instance, but got %s"
                    + N_("expected bytes() or str() instance, but got %s")
                    #endif
                    , Py_TYPE_NAME(obj));
                    return NULL;
                    @@ -192,11 +193,11 @@
                    {
                    PyErr_FORMAT(PyExc_TypeError,
                    #if PY_MAJOR_VERSION < 3
                    - "expected int(), long() or something supporting "
                    - "coercing to long(), but got %s"
                    + N_("expected int(), long() or something supporting "
                    + "coercing to long(), but got %s")
                    #else
                    - "expected int() or something supporting coercing to int(), "
                    - "but got %s"
                    + N_("expected int() or something supporting coercing to int(), "
                    + "but got %s")
                    #endif
                    , Py_TYPE_NAME(obj));
                    return -1;
                    @@ -207,13 +208,13 @@
                    if (*result > INT_MAX)
                    {
                    PyErr_SET_STRING(PyExc_OverflowError,
                    - "value is too large to fit into C int type");
                    + N_("value is too large to fit into C int type"));
                    return -1;
                    }
                    else if (*result < INT_MIN)
                    {
                    PyErr_SET_STRING(PyExc_OverflowError,
                    - "value is too small to fit into C int type");
                    + N_("value is too small to fit into C int type"));
                    return -1;
                    }
                    }
                    @@ -223,7 +224,7 @@
                    if (*result <= 0)
                    {
                    PyErr_SET_STRING(PyExc_ValueError,
                    - "number must be greater then zero");
                    + N_("number must be greater then zero"));
                    return -1;
                    }
                    }
                    @@ -232,7 +233,7 @@
                    if (*result < 0)
                    {
                    PyErr_SET_STRING(PyExc_ValueError,
                    - "number must be greater or equal to zero");
                    + N_("number must be greater or equal to zero"));
                    return -1;
                    }
                    }
                    @@ -326,7 +327,7 @@
                    if (valObject == NULL)
                    {
                    PyErr_SET_STRING(PyExc_AttributeError,
                    - "can't delete OutputObject attributes");
                    + N_("can't delete OutputObject attributes"));
                    return -1;
                    }

                    @@ -337,7 +338,7 @@
                    return 0;
                    }

                    - PyErr_FORMAT(PyExc_AttributeError, "invalid attribute: %s", name);
                    + PyErr_FORMAT(PyExc_AttributeError, N_("invalid attribute: %s"), name);
                    return -1;
                    }

                    @@ -786,7 +787,7 @@

                    if (our_tv == NULL)
                    {
                    - PyErr_SET_VIM("invalid expression");
                    + PyErr_SET_VIM(N_("invalid expression"));
                    return NULL;
                    }

                    @@ -837,7 +838,7 @@

                    if (our_tv == NULL)
                    {
                    - PyErr_SET_VIM("invalid expression");
                    + PyErr_SET_VIM(N_("invalid expression"));
                    return NULL;
                    }

                    @@ -909,7 +910,7 @@
                    if (VimTryEnd())
                    return NULL;

                    - PyErr_SET_VIM("failed to change directory");
                    + PyErr_SET_VIM(N_("failed to change directory"));
                    return NULL;
                    }

                    @@ -1087,15 +1088,15 @@
                    if (!PyTuple_Check(find_module_result))
                    {
                    PyErr_FORMAT(PyExc_TypeError,
                    - "expected 3-tuple as imp.find_module() result, but got %s",
                    + N_("expected 3-tuple as imp.find_module() result, but got %s"),
                    Py_TYPE_NAME(find_module_result));
                    return NULL;
                    }
                    if (PyTuple_GET_SIZE(find_module_result) != 3)
                    {
                    PyErr_FORMAT(PyExc_TypeError,
                    - "expected 3-tuple as imp.find_module() result, but got "
                    - "tuple of size %d",
                    + N_("expected 3-tuple as imp.find_module() result, but got "
                    + "tuple of size %d"),
                    (int) PyTuple_GET_SIZE(find_module_result));
                    return NULL;
                    }
                    @@ -1105,7 +1106,7 @@
                    || !(description = PyTuple_GET_ITEM(find_module_result, 2)))
                    {
                    PyErr_SET_STRING(PyExc_RuntimeError,
                    - "internal error: imp.find_module returned tuple with NULL");
                    + N_("internal error: imp.find_module returned tuple with NULL"));
                    return NULL;
                    }

                    @@ -1485,7 +1486,7 @@
                    if (valObject == NULL)
                    {
                    PyErr_SET_STRING(PyExc_AttributeError,
                    - "cannot delete vim.Dictionary attributes");
                    + N_("cannot delete vim.Dictionary attributes"));
                    return -1;
                    }

                    @@ -1493,7 +1494,8 @@
                    {
                    if (self->dict->dv_lock == VAR_FIXED)
                    {
                    - PyErr_SET_STRING(PyExc_TypeError, "cannot modify fixed dictionary");
                    + PyErr_SET_STRING(PyExc_TypeError,
                    + N_("cannot modify fixed dictionary"));
                    return -1;
                    }
                    else
                    @@ -1510,7 +1512,7 @@
                    }
                    else
                    {
                    - PyErr_FORMAT(PyExc_AttributeError, "cannot set attribute %s", name);
                    + PyErr_FORMAT(PyExc_AttributeError, N_("cannot set attribute %s"), name);
                    return -1;
                    }
                    }
                    @@ -1644,7 +1646,7 @@
                    (*dii)->ht->ht_used != (*dii)->ht_used)
                    {
                    PyErr_SET_STRING(PyExc_RuntimeError,
                    - "hashtab changed during iteration");
                    + N_("hashtab changed during iteration"));
                    return NULL;
                    }

                    @@ -1915,8 +1917,8 @@
                    Py_DECREF(iterator);
                    Py_DECREF(fast);
                    PyErr_FORMAT(PyExc_ValueError,
                    - "expected sequence element of size 2, "
                    - "but got sequence of size %d",
                    + N_("expected sequence element of size 2, "
                    + "but got sequence of size %d"),
                    (int) PySequence_Fast_GET_SIZE(fast));
                    return NULL;
                    }
                    @@ -2159,7 +2161,7 @@
                    if (kwargs)
                    {
                    PyErr_SET_STRING(PyExc_TypeError,
                    - "list constructor does not accept keyword arguments");
                    + N_("list constructor does not accept keyword arguments"));
                    return NULL;
                    }

                    @@ -2214,14 +2216,14 @@

                    if (index >= ListLength(self))
                    {
                    - PyErr_SET_STRING(PyExc_IndexError, "list index out of range");
                    + PyErr_SET_STRING(PyExc_IndexError, N_("list index out of range"));
                    return NULL;
                    }
                    li = list_find(self->list, (long) index);
                    if (li == NULL)
                    {
                    /* No more suitable format specifications in python-2.3 */
                    - PyErr_VIM_FORMAT("internal error: failed to get vim list item %d",
                    + PyErr_VIM_FORMAT(N_("internal error: failed to get vim list item %d"),
                    (int) index);
                    return NULL;
                    }
                    @@ -2340,7 +2342,7 @@
                    }
                    if (index > length || (index == length && obj == NULL))
                    {
                    - PyErr_SET_STRING(PyExc_IndexError, "list index out of range");
                    + PyErr_SET_STRING(PyExc_IndexError, N_("list index out of range"));
                    return -1;
                    }

                    @@ -2361,7 +2363,7 @@
                    if (list_append_tv(l, &tv) == FAIL)
                    {
                    clear_tv(&tv);
                    - PyErr_SET_VIM("failed to add item to list");
                    + PyErr_SET_VIM(N_("failed to add item to list"));
                    return -1;
                    }
                    }
                    @@ -2402,7 +2404,8 @@
                    li = list_find(l, (long) first);
                    if (li == NULL)
                    {
                    - PyErr_VIM_FORMAT("internal error: no vim list item %d", (int)first);
                    + PyErr_VIM_FORMAT(N_("internal error: no vim list item %d"),
                    + (int)first);
                    return -1;
                    }
                    if (last > first)
                    @@ -2435,7 +2438,7 @@
                    if (list_insert_tv(l, &v, li) == FAIL)
                    {
                    clear_tv(&v);
                    - PyErr_SET_VIM("internal error: failed to add item to list");
                    + PyErr_SET_VIM(N_("internal error: failed to add item to list"));
                    return -1;
                    }
                    clear_tv(&v);
                    @@ -2491,7 +2494,7 @@
                    if (valObject == NULL)
                    {
                    PyErr_SET_STRING(PyExc_AttributeError,
                    - "cannot delete vim.List attributes");
                    + N_("cannot delete vim.List attributes"));
                    return -1;
                    }

                    @@ -2499,7 +2502,7 @@
                    {
                    if (self->list->lv_lock == VAR_FIXED)
                    {
                    - PyErr_SET_STRING(PyExc_TypeError, "cannot modify fixed list");
                    + PyErr_SET_STRING(PyExc_TypeError, N_("cannot modify fixed list"));
                    return -1;
                    }
                    else
                    @@ -2516,7 +2519,7 @@
                    }
                    else
                    {
                    - PyErr_FORMAT(PyExc_AttributeError, "cannot set attribute %s", name);
                    + PyErr_FORMAT(PyExc_AttributeError, N_("cannot set attribute %s"), name);
                    return -1;
                    }
                    }
                    @@ -2552,7 +2555,7 @@
                    if (!translated_function_exists(name))
                    {
                    PyErr_FORMAT(PyExc_ValueError,
                    - "unnamed function %s does not exist", name);
                    + N_("unnamed function %s does not exist"), name);
                    return NULL;
                    }
                    self->name = vim_strsave(name);
                    @@ -2563,7 +2566,8 @@
                    vim_strchr(name, AUTOLOAD_CHAR) == NULL))
                    == NULL)
                    {
                    - PyErr_FORMAT(PyExc_ValueError, "function %s does not exist", name);
                    + PyErr_FORMAT(PyExc_ValueError,
                    + N_("function %s does not exist"), name);
                    return NULL;
                    }

                    @@ -2579,7 +2583,7 @@
                    if (kwargs)
                    {
                    PyErr_SET_STRING(PyExc_TypeError,
                    - "function constructor does not accept keyword arguments");
                    + N_("function constructor does not accept keyword arguments"));
                    return NULL;
                    }

                    @@ -2656,7 +2660,7 @@
                    else if (error != OK)
                    {
                    ret = NULL;
                    - PyErr_VIM_FORMAT("failed to run function %s", (char *)name);
                    + PyErr_VIM_FORMAT(N_("failed to run function %s"), (char *)name);
                    }
                    else
                    ret = ConvertToPyObject(&rettv);
                    @@ -2809,13 +2813,13 @@
                    else
                    {
                    PyErr_SET_STRING(PyExc_RuntimeError,
                    - "unable to get option value");
                    + N_("unable to get option value"));
                    return NULL;
                    }
                    }
                    else
                    {
                    - PyErr_SET_VIM("internal error: unknown option type");
                    + PyErr_SET_VIM(N_("internal error: unknown option type"));
                    return NULL;
                    }
                    }
                    @@ -2858,7 +2862,7 @@
                    {
                    if (VimTryEnd())
                    return -1;
                    - PyErr_SET_VIM("problem while switching windows");
                    + PyErr_SET_VIM(N_("problem while switching windows"));
                    return -1;
                    }
                    set_ret = set_option_value_err(key, numval, stringval, opt_flags);
                    @@ -2915,15 +2919,15 @@
                    if (self->opt_type == SREQ_GLOBAL)
                    {
                    PyErr_FORMAT(PyExc_ValueError,
                    - "unable to unset global option %s", key);
                    + N_("unable to unset global option %s"), key);
                    Py_XDECREF(todecref);
                    return -1;
                    }
                    else if (!(flags & SOPT_GLOBAL))
                    {
                    PyErr_FORMAT(PyExc_ValueError,
                    - "unable to unset option %s "
                    - "which does not have global value", key);
                    + N_("unable to unset option %s "
                    + "which does not have global value"), key);
                    Py_XDECREF(todecref);
                    return -1;
                    }
                    @@ -3001,7 +3005,7 @@
                    {
                    if (self->tab == INVALID_TABPAGE_VALUE)
                    {
                    - PyErr_SET_VIM("attempt to refer to deleted tab page");
                    + PyErr_SET_VIM(N_("attempt to refer to deleted tab page"));
                    return -1;
                    }

                    @@ -3145,7 +3149,7 @@
                    if (n == 0)
                    return TabPageNew(tp);

                    - PyErr_SET_STRING(PyExc_IndexError, "no such tab page");
                    + PyErr_SET_STRING(PyExc_IndexError, N_("no such tab page"));
                    return NULL;
                    }

                    @@ -3166,7 +3170,7 @@
                    {
                    if (self->win == INVALID_WINDOW_VALUE)
                    {
                    - PyErr_SET_VIM("attempt to refer to deleted window");
                    + PyErr_SET_VIM(N_("attempt to refer to deleted window"));
                    return -1;
                    }

                    @@ -3332,7 +3336,7 @@

                    if (strcmp(name, "buffer") == 0)
                    {
                    - PyErr_SET_STRING(PyExc_TypeError, "readonly attribute: buffer");
                    + PyErr_SET_STRING(PyExc_TypeError, N_("readonly attribute: buffer"));
                    return -1;
                    }
                    else if (strcmp(name, "cursor") == 0)
                    @@ -3345,7 +3349,7 @@

                    if (lnum <= 0 || lnum > self->win->w_buffer->b_ml.ml_line_count)
                    {
                    - PyErr_SET_VIM("cursor position outside buffer");
                    + PyErr_SET_VIM(N_("cursor position outside buffer"));
                    return -1;
                    }

                    @@ -3508,7 +3512,7 @@
                    if (n == 0)
                    return WindowNew(w, self->tabObject? self->tabObject->tab: curtab);

                    - PyErr_SET_STRING(PyExc_IndexError, "no such window");
                    + PyErr_SET_STRING(PyExc_IndexError, N_("no such window"));
                    return NULL;
                    }

                    @@ -3562,7 +3566,7 @@
                    --len;
                    else
                    {
                    - PyErr_SET_VIM("string cannot contain newlines");
                    + PyErr_SET_VIM(N_("string cannot contain newlines"));
                    Py_XDECREF(bytes);
                    return NULL;
                    }
                    @@ -3700,7 +3704,7 @@
                    if (u_savedel((linenr_T)n, 1L) == FAIL)
                    RAISE_UNDO_FAIL;
                    else if (ml_delete((linenr_T)n, FALSE) == FAIL)
                    - RAISE_LINE_FAIL("delete");
                    + RAISE_DELETE_LINE_FAIL;
                    else
                    {
                    if (buf == savebuf)
                    @@ -3739,7 +3743,7 @@
                    }
                    else if (ml_replace((linenr_T)n, (char_u *)save, FALSE) == FAIL)
                    {
                    - RAISE_LINE_FAIL("replace");
                    + RAISE_REPLACE_LINE_FAIL;
                    vim_free(save);
                    }
                    else
                    @@ -3806,7 +3810,7 @@
                    {
                    if (ml_delete((linenr_T)lo, FALSE) == FAIL)
                    {
                    - RAISE_LINE_FAIL("delete");
                    + RAISE_DELETE_LINE_FAIL;
                    break;
                    }
                    }
                    @@ -3878,7 +3882,7 @@
                    for (i = 0; i < old_len - new_len; ++i)
                    if (ml_delete((linenr_T)lo, FALSE) == FAIL)
                    {
                    - RAISE_LINE_FAIL("delete");
                    + RAISE_DELETE_LINE_FAIL;
                    break;
                    }
                    extra -= i;
                    @@ -3894,7 +3898,7 @@
                    if (ml_replace((linenr_T)(lo+i), (char_u *)array[i], FALSE)
                    == FAIL)
                    {
                    - RAISE_LINE_FAIL("replace");
                    + RAISE_REPLACE_LINE_FAIL;
                    break;
                    }
                    }
                    @@ -3912,7 +3916,7 @@
                    if (ml_append((linenr_T)(lo + i - 1),
                    (char_u *)array[i], 0, FALSE) == FAIL)
                    {
                    - RAISE_LINE_FAIL("insert");
                    + RAISE_INSERT_LINE_FAIL;
                    break;
                    }
                    vim_free(array[i]);
                    @@ -3991,7 +3995,7 @@
                    if (u_save((linenr_T)n, (linenr_T)(n+1)) == FAIL)
                    RAISE_UNDO_FAIL;
                    else if (ml_append((linenr_T)n, (char_u *)str, 0, FALSE) == FAIL)
                    - RAISE_LINE_FAIL("insert");
                    + RAISE_INSERT_LINE_FAIL;
                    else
                    appended_lines_mark((linenr_T)n, 1L);

                    @@ -4048,7 +4052,7 @@
                    if (ml_append((linenr_T)(n + i),
                    (char_u *)array[i], 0, FALSE) == FAIL)
                    {
                    - RAISE_LINE_FAIL("insert");
                    + RAISE_INSERT_LINE_FAIL;

                    /* Free the rest of the lines */
                    while (i < size)
                    @@ -4101,7 +4105,7 @@
                    {
                    if (self->buf == INVALID_BUFFER_VALUE)
                    {
                    - PyErr_SET_VIM("attempt to refer to deleted buffer");
                    + PyErr_SET_VIM(N_("attempt to refer to deleted buffer"));
                    return -1;
                    }

                    @@ -4122,7 +4126,7 @@

                    if (n < 0 || n > end - start)
                    {
                    - PyErr_SET_STRING(PyExc_IndexError, "line number out of range");
                    + PyErr_SET_STRING(PyExc_IndexError, N_("line number out of range"));
                    return NULL;
                    }

                    @@ -4178,7 +4182,7 @@

                    if (n < 0 || n > end - start)
                    {
                    - PyErr_SET_STRING(PyExc_IndexError, "line number out of range");
                    + PyErr_SET_STRING(PyExc_IndexError, N_("line number out of range"));
                    return -1;
                    }

                    @@ -4262,7 +4266,7 @@

                    if (n < 0 || n > max)
                    {
                    - PyErr_SET_STRING(PyExc_IndexError, "line number out of range");
                    + PyErr_SET_STRING(PyExc_IndexError, N_("line number out of range"));
                    return NULL;
                    }

                    @@ -4545,7 +4549,7 @@

                    if (ren_ret == FAIL)
                    {
                    - PyErr_SET_VIM("failed to rename buffer");
                    + PyErr_SET_VIM(N_("failed to rename buffer"));
                    return -1;
                    }
                    return 0;
                    @@ -4581,7 +4585,7 @@
                    if (pmark[0] == '\0' || pmark[1] != '\0')
                    {
                    PyErr_SET_STRING(PyExc_ValueError,
                    - "mark name must be a single character");
                    + N_("mark name must be a single character"));
                    Py_XDECREF(todecref);
                    return NULL;
                    }
                    @@ -4599,7 +4603,7 @@

                    if (posp == NULL)
                    {
                    - PyErr_SET_VIM("invalid mark name");
                    + PyErr_SET_VIM(N_("invalid mark name"));
                    return NULL;
                    }

                    @@ -4824,7 +4828,7 @@
                    if (valObject->ob_type != &BufferType)
                    {
                    PyErr_FORMAT(PyExc_TypeError,
                    - "expected vim.Buffer object, but got %s",
                    + N_("expected vim.Buffer object, but got %s"),
                    Py_TYPE_NAME(valObject));
                    return -1;
                    }
                    @@ -4838,7 +4842,7 @@
                    {
                    if (VimTryEnd())
                    return -1;
                    - PyErr_VIM_FORMAT("failed to switch to buffer %d", count);
                    + PyErr_VIM_FORMAT(N_("failed to switch to buffer %d"), count);
                    return -1;
                    }

                    @@ -4851,7 +4855,7 @@
                    if (valObject->ob_type != &WindowType)
                    {
                    PyErr_FORMAT(PyExc_TypeError,
                    - "expected vim.Window object, but got %s",
                    + N_("expected vim.Window object, but got %s"),
                    Py_TYPE_NAME(valObject));
                    return -1;
                    }
                    @@ -4863,7 +4867,7 @@
                    if (!count)
                    {
                    PyErr_SET_STRING(PyExc_ValueError,
                    - "failed to find window in the current tab page");
                    + N_("failed to find window in the current tab page"));
                    return -1;
                    }

                    @@ -4874,7 +4878,7 @@
                    if (VimTryEnd())
                    return -1;
                    PyErr_SET_STRING(PyExc_RuntimeError,
                    - "did not switch to the specified window");
                    + N_("did not switch to the specified window"));
                    return -1;
                    }

                    @@ -4885,7 +4889,7 @@
                    if (valObject->ob_type != &TabPageType)
                    {
                    PyErr_FORMAT(PyExc_TypeError,
                    - "expected vim.TabPage object, but got %s",
                    + N_("expected vim.TabPage object, but got %s"),
                    Py_TYPE_NAME(valObject));
                    return -1;
                    }
                    @@ -4900,7 +4904,7 @@
                    if (VimTryEnd())
                    return -1;
                    PyErr_SET_STRING(PyExc_RuntimeError,
                    - "did not switch to the specified tab page");
                    + N_("did not switch to the specified tab page"));
                    return -1;
                    }

                    @@ -5383,7 +5387,7 @@
                    else
                    {
                    PyErr_FORMAT(PyExc_TypeError,
                    - "unable to convert %s to vim dictionary",
                    + N_("unable to convert %s to vim dictionary"),
                    Py_TYPE_NAME(obj));
                    ret = -1;
                    }
                    @@ -5511,7 +5515,7 @@
                    else
                    {
                    PyErr_FORMAT(PyExc_TypeError,
                    - "unable to convert %s to vim structure",
                    + N_("unable to convert %s to vim structure"),
                    Py_TYPE_NAME(obj));
                    return -1;
                    }
                    @@ -5523,7 +5527,7 @@
                    {
                    if (tv == NULL)
                    {
                    - PyErr_SET_VIM("internal error: NULL reference passed");
                    + PyErr_SET_VIM(N_("internal error: NULL reference passed"));
                    return NULL;
                    }
                    switch (tv->v_type)
                    @@ -5548,7 +5552,7 @@
                    Py_INCREF(Py_None);
                    return Py_None;
                    default:
                    - PyErr_SET_VIM("internal error: invalid value type");
                    + PyErr_SET_VIM(N_("internal error: invalid value type"));
                    return NULL;
                    }
                    }

                    --
                    --
                    You received this message from the "vim_dev" maillist.
                    Do not top-post! Type your reply below the text you are replying to.
                    For more information, visit http://www.vim.org/maillist.php

                    ---
                    You received this message because you are subscribed to the Google Groups "vim_dev" group.
                    To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscribe@....
                    For more options, visit https://groups.google.com/groups/opt_out.
                  • Bram Moolenaar
                    ... After including this patch test 86 and 87 fail. Test 87 has only a ... +++ testdir/test87.ok 2013-06-23 14:43:28.000000000 +0200 @@ -1175,6 +1175,9 @@
                    Message 9 of 25 , Jun 23, 2013
                    • 0 Attachment
                      ZyX wrote:

                      > Wrong patch. Correct one:
                      >
                      > # HG changeset patch
                      > # User ZyX <kp-pav@...>
                      > # Date 1371441247 -14400
                      > # Mon Jun 17 07:54:07 2013 +0400
                      > # Branch python-fixes
                      > # Node ID 42e166b5c6ff07cd7810780b1d3704b8ce61bac0
                      > # Parent 4a00cd941a883917f6d740f9f06aca7baadcb45e
                      > Add NUMBER_UNSIGNED to WindowSetattr(, "width"|"height")
                      > And more tests
                      >
                      > Note: in ee('import failing') it was expected to raise NotImplementedError, but
                      > actually raises ImportError

                      After including this patch test 86 and 87 fail. Test 87 has only a
                      small diff:

                      --- testdir/test87.failed 2013-06-23 14:45:47.000000000 +0200
                      +++ testdir/test87.ok 2013-06-23 14:43:28.000000000 +0200
                      @@ -1175,6 +1175,9 @@
                      3,xx
                      before
                      after
                      +pythonx/topmodule/__init__.py
                      +pythonx/topmodule/submodule/__init__.py
                      +pythonx/topmodule/submodule/subsubmodule/subsubsubmodule.py
                      vim.command("throw 'abcN'"):(<class 'vim.error'>, error('abcN',))
                      Exe("throw 'def'"):(<class 'vim.error'>, error('def',))
                      vim.eval("Exe('throw ''ghi''')"):(<class 'vim.error'>, error('ghi',))


                      Test 86 has very many differences. Here are a few typical examples:

                      --- testdir/test86.failed 2013-06-23 14:44:51.000000000 +0200
                      +++ testdir/test86.ok 2013-06-23 14:43:28.000000000 +0200
                      @@ -550,7 +550,7 @@
                      d["a"] = {"abcF" : {u"": 1}}:ValueError:('empty keys are not allowed',)
                      d["a"] = {"abcF" : FailingMapping()}:NotImplementedError:()
                      d["a"] = {"abcF" : FailingMappingKey()}:NotImplementedError:()
                      -d["a"] = {"abcF" : FailingNumber()}:TypeError:("long() argument must be a string or a number, not 'FailingNumber'",)
                      +d["a"] = {"abcF" : FailingNumber()}:TypeError:('long() argument must be a string or a number',)
                      <<< Finished
                      >>> Testing StringToChars using d["a"] = Mapping({%s : 1})
                      d["a"] = Mapping({1 : 1}):TypeError:('expected str() or unicode() instance, but got int',)


                      @@ -652,7 +652,7 @@
                      d.update(Mapping({"abcG" : {u"": 1}})):ValueError:('empty keys are not allowed',)
                      d.update(Mapping({"abcG" : FailingMapping()})):NotImplementedError:()
                      d.update(Mapping({"abcG" : FailingMappingKey()})):NotImplementedError:()
                      -d.update(Mapping({"abcG" : FailingNumber()})):TypeError:("long() argument must be a string or a number, not 'FailingNumber'",)
                      +d.update(Mapping({"abcG" : FailingNumber()})):TypeError:('long() argument must be a string or a number',)
                      <<< Finished
                      >>> Testing *Iter* using d.update(%s)
                      d.update(FailingIter()):NotImplementedError:()


                      @@ -824,11 +824,371 @@
                      ll[1:100] = "abcJ":error:('list is locked',)
                      >>> Testing *Iter* using l[:] = %s
                      l[:] = FailingIter():NotImplementedError:()
                      +l[:] = FailingIterNext():NotImplementedError:()
                      +<<< Finished
                      +>>> Testing StringToChars using l[:] = [{%s : 1}]
                      +l[:] = [{1 : 1}]:TypeError:('expected str() or unicode() instance, but got int',)
                      +l[:] = [{u"\0" : 1}]:TypeError:('expected string without null bytes',)
                      +l[:] = [{"\0" : 1}]:TypeError:('expected string without null bytes',)
                      +<<< Finished
                      +>>> Testing StringToChars using l[:] = [{"abcF" : {%s : 1}}]
                      +l[:] = [{"abcF" : {1 : 1}}]:TypeError:('expected str() or unicode() instance, but got int',)
                      +l[:] = [{"abcF" : {u"\0" : 1}}]:TypeError:('expected string without null bytes',)
                      +l[:] = [{"abcF" : {"\0" : 1}}]:TypeError:('expected string without null bytes',)
                      [...]


                      I suspect following patches won't apply cleanly without this one, thus I
                      will stop here. Please start a new sequence of patches against
                      7.3.1233.

                      --
                      ARTHUR: (as the MAN next to him is squashed by a sheep) Knights! Run away!
                      Midst echoing shouts of "run away" the KNIGHTS retreat to cover with the odd
                      cow or goose hitting them still. The KNIGHTS crouch down under cover.
                      "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD

                      /// Bram Moolenaar -- Bram@... -- http://www.Moolenaar.net \\\
                      /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
                      \\\ an exciting new programming language -- http://www.Zimbu.org ///
                      \\\ help me help AIDS victims -- http://ICCF-Holland.org ///

                      --
                      --
                      You received this message from the "vim_dev" maillist.
                      Do not top-post! Type your reply below the text you are replying to.
                      For more information, visit http://www.vim.org/maillist.php

                      ---
                      You received this message because you are subscribed to the Google Groups "vim_dev" group.
                      To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscribe@....
                      For more options, visit https://groups.google.com/groups/opt_out.
                    • ZyX
                      The tests are fixed in next patch. To make them work with the patch you refer to you have to run tests with python-2.3. -- -- You received this message from
                      Message 10 of 25 , Jun 23, 2013
                      • 0 Attachment
                        The tests are fixed in next patch. To make them work with the patch you refer to you have to run tests with python-2.3.

                        --
                        --
                        You received this message from the "vim_dev" maillist.
                        Do not top-post! Type your reply below the text you are replying to.
                        For more information, visit http://www.vim.org/maillist.php

                        ---
                        You received this message because you are subscribed to the Google Groups "vim_dev" group.
                        To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscribe@....
                        For more options, visit https://groups.google.com/groups/opt_out.
                      • ZyX
                        ... This should be fixed with the following diff. Though with hg export --git (“fixed” version of the patch) it should not be necessary as empty files do
                        Message 11 of 25 , Jun 23, 2013
                        • 0 Attachment
                          > --- testdir/test87.failed 2013-06-23 14:45:47.000000000 +0200
                          > +++ testdir/test87.ok 2013-06-23 14:43:28.000000000 +0200
                          > @@ -1175,6 +1175,9 @@
                          > 3,xx
                          > before
                          > after
                          > +pythonx/topmodule/__init__.py
                          > +pythonx/topmodule/submodule/__init__.py
                          > +pythonx/topmodule/submodule/subsubmodule/subsubsubmodule.py
                          > vim.command("throw 'abcN'"):(<class 'vim.error'>, error('abcN',))
                          > Exe("throw 'def'"):(<class 'vim.error'>, error('def',))
                          > vim.eval("Exe('throw ''ghi''')"):(<class 'vim.error'>, error('ghi',))


                          This should be fixed with the following diff. Though with hg export --git (“fixed” version of the patch) it should not be necessary as empty files do appear in its output.

                          # HG changeset patch
                          # User ZyX <kp-pav@...>
                          # Date 1371993246 -14400
                          # Sun Jun 23 17:14:06 2013 +0400
                          # Branch python-fixes
                          # Node ID bec8c9e957010b4a87424de12456d7e98df8776c
                          # Parent 3c21dc7cfad1f22855bd64b2a4a79d75cd36b1e3
                          Use 2-bytes files with a comment in place of empty files

                          diff --git a/src/testdir/pythonx/topmodule/__init__.py b/src/testdir/pythonx/topmodule/__init__.py
                          --- a/src/testdir/pythonx/topmodule/__init__.py
                          +++ b/src/testdir/pythonx/topmodule/__init__.py
                          @@ -0,0 +1,1 @@
                          +#
                          diff --git a/src/testdir/pythonx/topmodule/submodule/__init__.py b/src/testdir/pythonx/topmodule/submodule/__init__.py
                          --- a/src/testdir/pythonx/topmodule/submodule/__init__.py
                          +++ b/src/testdir/pythonx/topmodule/submodule/__init__.py
                          @@ -0,0 +1,1 @@
                          +#
                          diff --git a/src/testdir/pythonx/topmodule/submodule/subsubmodule/__init__.py b/src/testdir/pythonx/topmodule/submodule/subsubmodule/__init__.py
                          --- a/src/testdir/pythonx/topmodule/submodule/subsubmodule/__init__.py
                          +++ b/src/testdir/pythonx/topmodule/submodule/subsubmodule/__init__.py
                          @@ -0,0 +1,1 @@
                          +#
                          diff --git a/src/testdir/pythonx/topmodule/submodule/subsubmodule/subsubsubmodule.py b/src/testdir/pythonx/topmodule/submodule/subsubmodule/subsubsubmodule.py
                          --- a/src/testdir/pythonx/topmodule/submodule/subsubmodule/subsubsubmodule.py
                          +++ b/src/testdir/pythonx/topmodule/submodule/subsubmodule/subsubsubmodule.py
                          @@ -0,0 +1,1 @@
                          +#

                          --
                          --
                          You received this message from the "vim_dev" maillist.
                          Do not top-post! Type your reply below the text you are replying to.
                          For more information, visit http://www.vim.org/maillist.php

                          ---
                          You received this message because you are subscribed to the Google Groups "vim_dev" group.
                          To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscribe@....
                          For more options, visit https://groups.google.com/groups/opt_out.
                        • Bram Moolenaar
                          ... Thanks for the quick fix. -- A KNIGHT rides into shot and hacks him to the ground. He rides off. We stay for a moment on the glade. A MIDDLE-AGED LADY in
                          Message 12 of 25 , Jun 23, 2013
                          • 0 Attachment
                            ZyX wrote:

                            > > Please follow my instructions. gettext searches the source code for
                            > > "_()" and "N_()", nothing else. After patch 7.3.1229 existing
                            > > translations will work, but the next time the translations are updated
                            > > they will be gone.
                            > >
                            > > You can see the effect by running "make ru" in src/po.
                            >
                            > # HG changeset patch
                            > # User ZyX <kp-pav@...>
                            > # Date 1371991354 -14400
                            > # Sun Jun 23 16:42:34 2013 +0400
                            > # Branch python-fixes
                            > # Node ID 3c21dc7cfad1f22855bd64b2a4a79d75cd36b1e3
                            > # Parent 8b539b192fd5eae19f61bd3d55a28811ea5bae0c
                            > Use N_() to mark strings for translation

                            Thanks for the quick fix.

                            --
                            A KNIGHT rides into shot and hacks him to the ground. He rides off.
                            We stay for a moment on the glade. A MIDDLE-AGED LADY in a C. & A.
                            twin-set emerges from the trees and looks in horror at the body of her
                            HUSBAND.
                            MRS HISTORIAN: FRANK!
                            "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD

                            /// Bram Moolenaar -- Bram@... -- http://www.Moolenaar.net \\\
                            /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
                            \\\ an exciting new programming language -- http://www.Zimbu.org ///
                            \\\ help me help AIDS victims -- http://ICCF-Holland.org ///

                            --
                            --
                            You received this message from the "vim_dev" maillist.
                            Do not top-post! Type your reply below the text you are replying to.
                            For more information, visit http://www.vim.org/maillist.php

                            ---
                            You received this message because you are subscribed to the Google Groups "vim_dev" group.
                            To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscribe@....
                            For more options, visit https://groups.google.com/groups/opt_out.
                          • Bram Moolenaar
                            ... Thanks. When I apply both patches 9 and 10 , plus this one then the tests are passing. I ll send this out as one big patch. -- press CTRL-ALT-DEL for
                            Message 13 of 25 , Jun 23, 2013
                            • 0 Attachment
                              ZyX wrote:

                              > > --- testdir/test87.failed 2013-06-23 14:45:47.000000000 +0200
                              > > +++ testdir/test87.ok 2013-06-23 14:43:28.000000000 +0200
                              > > @@ -1175,6 +1175,9 @@
                              > > 3,xx
                              > > before
                              > > after
                              > > +pythonx/topmodule/__init__.py
                              > > +pythonx/topmodule/submodule/__init__.py
                              > > +pythonx/topmodule/submodule/subsubmodule/subsubsubmodule.py
                              > > vim.command("throw 'abcN'"):(<class 'vim.error'>, error('abcN',))
                              > > Exe("throw 'def'"):(<class 'vim.error'>, error('def',))
                              > > vim.eval("Exe('throw ''ghi''')"):(<class 'vim.error'>, error('ghi',))
                              >
                              >
                              > This should be fixed with the following diff. Though with hg export
                              > --git (“fixed” version of the patch) it should not be necessary as
                              > empty files do appear in its output.

                              Thanks. When I apply both patches "9" and "10", plus this one then the
                              tests are passing. I'll send this out as one big patch.

                              --
                              press CTRL-ALT-DEL for more information

                              /// Bram Moolenaar -- Bram@... -- http://www.Moolenaar.net \\\
                              /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
                              \\\ an exciting new programming language -- http://www.Zimbu.org ///
                              \\\ help me help AIDS victims -- http://ICCF-Holland.org ///

                              --
                              --
                              You received this message from the "vim_dev" maillist.
                              Do not top-post! Type your reply below the text you are replying to.
                              For more information, visit http://www.vim.org/maillist.php

                              ---
                              You received this message because you are subscribed to the Google Groups "vim_dev" group.
                              To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscribe@....
                              For more options, visit https://groups.google.com/groups/opt_out.
                            • ZyX
                              After make ru I find many incorrect fuzzy-matched translations in src/po/ru.po. Am not sure whether the following is the right fix though. # HG changeset
                              Message 14 of 25 , Jun 23, 2013
                              • 0 Attachment
                                After "make ru" I find many incorrect fuzzy-matched translations in src/po/ru.po. Am not sure whether the following is the right fix though.

                                # HG changeset patch
                                # User ZyX <kp-pav@...>
                                # Date 1371999908 -14400
                                # Sun Jun 23 19:05:08 2013 +0400
                                # Branch python-fixes
                                # Node ID 6d47c9fe0c735245337578a76d3ece1c5a4a1b52
                                # Parent bec8c9e957010b4a87424de12456d7e98df8776c
                                Translation update: replace fuzzy-matched strings found after `make ru` with proper ones

                                diff --git a/src/po/ru.po b/src/po/ru.po
                                --- a/src/po/ru.po
                                +++ b/src/po/ru.po
                                @@ -6573,110 +6573,126 @@
                                msgid "Need encryption key for \"%s\""
                                msgstr "Требуется ключ шифрования для \"%s\""

                                +msgid "empty keys are not allowed"
                                +msgstr "пустые ключи не допустимы"
                                +
                                +msgid "dictionary is locked"
                                +msgstr "словарь заблокирован"
                                +
                                +msgid "list is locked"
                                +msgstr "список заблокирован"
                                +
                                +#, c-format
                                +msgid "failed to add key '%s' to dictionary"
                                +msgstr "не удалось добавить ключ <<%s>> к словарю"
                                +
                                msgid "can't delete OutputObject attributes"
                                msgstr "невозможно удалить атрибуты OutputObject"

                                -msgid "softspace must be an integer"
                                -msgstr "значение softspace должно быть целым числом"
                                -
                                -msgid "invalid attribute"
                                -msgstr "неправильный атрибут"
                                -
                                -msgid "writelines() requires list of strings"
                                -msgstr "writelines() требует указания списка строк"
                                +#, c-format
                                +msgid "invalid attribute: %s"
                                +msgstr "неправильный атрибут: %s"

                                msgid "E264: Python: Error initialising I/O objects"
                                msgstr "E264: Python: Ошибка инициализации объектов I/O"

                                -msgid "no such buffer"
                                -msgstr "нет такого буфера"
                                -
                                -msgid "empty keys are not allowed"
                                -msgstr "пустые ключи не допустимы"
                                -
                                -msgid "failed to add key to dictionary"
                                -msgstr "невозможно добавить ключ к словарю"
                                -
                                -msgid "Cannot delete DictionaryObject attributes"
                                -msgstr "Невозможно удалить атрибуты DictionaryObject"
                                -
                                -msgid "Cannot modify fixed dictionary"
                                -msgstr "Невозможно изменить фиксированный словарь"
                                -
                                -msgid "Only boolean objects are allowed"
                                -msgstr "Разрешено использовать только логические объекты"
                                -
                                -msgid "Cannot set this attribute"
                                -msgstr "Невозможно установить этот атрибут"
                                -
                                -msgid "no such key in dictionary"
                                -msgstr "нет такого ключа в словаре"
                                -
                                -msgid "dict is locked"
                                -msgstr "словарь заблокирован"
                                -
                                -msgid "internal error: failed to get vim list item"
                                -msgstr "внутренняя ошибка: не удалось получить элемент списка VIM"
                                -
                                -msgid "list is locked"
                                -msgstr "список заблокирован"
                                -
                                -msgid "Failed to add item to list"
                                -msgstr "Невозможно добавить элемент в список"
                                -
                                -msgid "internal error: no vim list item"
                                -msgstr "внутренняя ошибка: нет элемента списка VIM"
                                -
                                -msgid "can only assign lists to slice"
                                -msgstr "назначение выборки возможно только для списков"
                                +msgid "failed to change directory"
                                +msgstr "не удалось изменить текущий каталог"
                                +
                                +msgid "cannot delete vim.Dictionary attributes"
                                +msgstr "невозможно удалить атрибуты vim.Dictionary"
                                +
                                +msgid "cannot modify fixed dictionary"
                                +msgstr "невозможно изменить фиксированный словарь"
                                +
                                +#, c-format
                                +msgid "cannot set attribute %s"
                                +msgstr "невозможно установить аттрибут %s"
                                +
                                +msgid "list index out of range"
                                +msgstr "номер элемента за пределами диапазона"
                                +
                                +#, c-format
                                +msgid "internal error: failed to get vim list item %d"
                                +msgstr "внутренняя ошибка: не удалось получить элемент %d списка VIM"
                                +
                                +msgid "failed to add item to list"
                                +msgstr "не удалось добавить элемент в список"
                                +
                                +#, c-format
                                +msgid "internal error: no vim list item %d"
                                +msgstr "внутренняя ошибка: нет элемента %d списка VIM"

                                msgid "internal error: failed to add item to list"
                                msgstr "внутренняя ошибка: не удалось добавить элемент в список"

                                -msgid "can only concatenate with lists"
                                -msgstr "можно объединить только списки"
                                -
                                -msgid "Cannot modify fixed list"
                                -msgstr "Невозможно изменить фиксированный список"
                                -
                                -msgid "'self' argument must be a dictionary"
                                -msgstr "параметр 'self' должен быть словарём"
                                -
                                -msgid "failed to run function"
                                -msgstr "невозможно выполнить функцию"
                                +msgid "cannot delete vim.List attributes"
                                +msgstr "невозможно удалить атрибуты vim.List"
                                +
                                +msgid "cannot modify fixed list"
                                +msgstr "невозможно изменить фиксированный список"
                                +
                                +#, c-format
                                +msgid "unnamed function %s does not exist"
                                +msgstr "анонимная функция %s не существует"
                                +
                                +#, c-format
                                +msgid "function %s does not exist"
                                +msgstr "функция %s не существует"
                                +
                                +#, c-format
                                +msgid "failed to run function %s"
                                +msgstr "не удалось выполнить функцию %s"
                                +
                                +msgid "unable to get option value"
                                +msgstr "не удалось получить значение настройки"
                                +
                                +msgid "internal error: unknown option type"
                                +msgstr "внутренняя ошибка: неизвестный тип настройки"
                                +
                                +msgid "attempt to refer to deleted tab page"
                                +msgstr "попытка сослаться на уничтоженную вкладку"
                                +
                                +msgid "no such tab page"
                                +msgstr "нет такой вкладки"

                                msgid "attempt to refer to deleted window"
                                msgstr "попытка сослаться на закрытое окно"

                                -msgid "readonly attribute"
                                -msgstr "атрибут доступен только для чтения"
                                +msgid "readonly attribute: buffer"
                                +msgstr "атрибут buffer доступен только для чтения"

                                msgid "cursor position outside buffer"
                                msgstr "позиция курсора находится вне буфера"

                                -#, c-format
                                -msgid "<window object (deleted) at %p>"
                                -msgstr "<объект окна (удален) в %p>"
                                -
                                -#, c-format
                                -msgid "<window object (unknown) at %p>"
                                -msgstr "<объект окна (неизвестен) в %p>"
                                -
                                -#, c-format
                                -msgid "<window %d>"
                                -msgstr "<окно %d>"
                                -
                                msgid "no such window"
                                msgstr "нет такого окна"

                                msgid "attempt to refer to deleted buffer"
                                msgstr "попытка сослаться на уничтоженный буфер"

                                -msgid "unable to convert to vim structure"
                                -msgstr "невозможно преобразовать в структуру VIM"
                                -
                                -msgid "NULL reference passed"
                                -msgstr "передана ссылка на NULL"
                                +msgid "failed to rename buffer"
                                +msgstr "не удалось переименовать буфер"
                                +
                                +msgid "failed to run the code"
                                +msgstr "невозможно выполнить функцию"
                                +
                                +msgid "E858: Eval did not return a valid python object"
                                +msgstr "E858: Eval не возвратил допустимого объекта Python"
                                +
                                +msgid "E859: Failed to convert returned python object to vim value"
                                +msgstr "E859: Не удалось преобразовать возвращённый объект Python в значение VIM"
                                +
                                +#, c-format
                                +msgid "unable to convert %s to vim dictionary"
                                +msgstr "невозможно преобразовать %s в словарь Vim"
                                +
                                +#, c-format
                                +msgid "unable to convert %s to vim structure"
                                +msgstr "невозможно преобразовать %s в структуру Vim"
                                +
                                +msgid "internal error: NULL reference passed"
                                +msgstr "внутренняя ошибка: передана ссылка на NULL"

                                msgid "internal error: invalid value type"
                                msgstr "внутренняя ошибка: неправильный тип значения"

                                --
                                --
                                You received this message from the "vim_dev" maillist.
                                Do not top-post! Type your reply below the text you are replying to.
                                For more information, visit http://www.vim.org/maillist.php

                                ---
                                You received this message because you are subscribed to the Google Groups "vim_dev" group.
                                To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscribe@....
                                For more options, visit https://groups.google.com/groups/opt_out.
                              • Bram Moolenaar
                                ... Sergey Alyoshin was maintaining the Russian translations. Sergey, are you OK with including this? -- He was not in the least bit scared to be mashed into a
                                Message 15 of 25 , Jun 23, 2013
                                • 0 Attachment
                                  ZyX wrote:

                                  > After "make ru" I find many incorrect fuzzy-matched translations in
                                  > src/po/ru.po. Am not sure whether the following is the right fix
                                  > though.
                                  >
                                  > # HG changeset patch
                                  > # User ZyX <kp-pav@...>
                                  > # Date 1371999908 -14400
                                  > # Sun Jun 23 19:05:08 2013 +0400
                                  > # Branch python-fixes
                                  > # Node ID 6d47c9fe0c735245337578a76d3ece1c5a4a1b52
                                  > # Parent bec8c9e957010b4a87424de12456d7e98df8776c
                                  > Translation update: replace fuzzy-matched strings found after `make
                                  > ru` with proper ones

                                  Sergey Alyoshin was maintaining the Russian translations.

                                  Sergey, are you OK with including this?

                                  --
                                  He was not in the least bit scared to be mashed into a pulp
                                  Or to have his eyes gouged out and his elbows broken;
                                  To have his kneecaps split and his body burned away
                                  And his limbs all hacked and mangled, brave Sir Robin.
                                  "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD

                                  /// Bram Moolenaar -- Bram@... -- http://www.Moolenaar.net \\\
                                  /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
                                  \\\ an exciting new programming language -- http://www.Zimbu.org ///
                                  \\\ help me help AIDS victims -- http://ICCF-Holland.org ///

                                  --
                                  --
                                  You received this message from the "vim_dev" maillist.
                                  Do not top-post! Type your reply below the text you are replying to.
                                  For more information, visit http://www.vim.org/maillist.php

                                  ---
                                  You received this message because you are subscribed to the Google Groups "vim_dev" group.
                                  To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscribe@....
                                  For more options, visit https://groups.google.com/groups/opt_out.
                                Your message has been successfully submitted and would be delivered to recipients shortly.