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

[PATCH] (0/7) Consistency and refactoring

Expand Messages
  • ZyX
    -- -- 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
    Message 1 of 25 , Jun 16, 2013
    • 0 Attachment
      --
      --
      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 1371218395 -14400 # Fri Jun 14 17:59:55 2013 +0400 # Branch python-fixes # Node ID
      Message 2 of 25 , Jun 16, 2013
      • 0 Attachment
        # HG changeset patch
        # User ZyX <kp-pav@...>
        # Date 1371218395 -14400
        # Fri Jun 14 17:59:55 2013 +0400
        # Branch python-fixes
        # Node ID d0320d1f7ff29076f01fb39e431446f5c98e8ba2
        # Parent 8991454c00246d1561474090cfbbb8cda7c88dd5
        Use same code both for OutputWrite and OutputWritelines

        diff -r 8991454c0024 -r d0320d1f7ff2 src/if_py_both.h
        --- a/src/if_py_both.h Sun Jun 16 16:57:46 2013 +0200
        +++ b/src/if_py_both.h Fri Jun 14 17:59:55 2013 +0400
        @@ -281,15 +281,15 @@
        }
        }

        - static PyObject *
        -OutputWrite(OutputObject *self, PyObject *args)
        -{
        - Py_ssize_t len = 0;
        - char *str = NULL;
        - int error = self->error;
        -
        - if (!PyArg_ParseTuple(args, "et#", ENC_OPT, &str, &len))
        - return NULL;
        + static int
        +write_output(OutputObject *self, PyObject *string)
        +{
        + Py_ssize_t len = 0;
        + char *str = NULL;
        + int error = self->error;
        +
        + if (!PyArg_Parse(string, "et#", ENC_OPT, &str, &len))
        + return -1;

        Py_BEGIN_ALLOW_THREADS
        Python_Lock_Vim();
        @@ -298,44 +298,38 @@
        Py_END_ALLOW_THREADS
        PyMem_Free(str);

        + return 0;
        +}
        +
        + static PyObject *
        +OutputWrite(OutputObject *self, PyObject *string)
        +{
        + if (write_output(self, string))
        + return NULL;
        +
        Py_INCREF(Py_None);
        return Py_None;
        }

        static PyObject *
        -OutputWritelines(OutputObject *self, PyObject *args)
        -{
        - PyObject *seq;
        +OutputWritelines(OutputObject *self, PyObject *seq)
        +{
        PyObject *iterator;
        PyObject *item;
        int error = self->error;

        - if (!PyArg_ParseTuple(args, "O", &seq))
        - return NULL;
        -
        if (!(iterator = PyObject_GetIter(seq)))
        return NULL;

        while ((item = PyIter_Next(iterator)))
        {
        - char *str = NULL;
        - PyInt len;
        -
        - if (!PyArg_Parse(item, "et#", ENC_OPT, &str, &len))
        + if (write_output(self, item))
        {
        - PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
        Py_DECREF(iterator);
        Py_DECREF(item);
        return NULL;
        }
        Py_DECREF(item);
        -
        - Py_BEGIN_ALLOW_THREADS
        - Python_Lock_Vim();
        - writer((writefn)(error ? emsg : msg), (char_u *)str, len);
        - Python_Release_Vim();
        - Py_END_ALLOW_THREADS
        - PyMem_Free(str);
        }

        Py_DECREF(iterator);
        @@ -360,8 +354,8 @@

        static struct PyMethodDef OutputMethods[] = {
        /* name, function, calling, doc */
        - {"write", (PyCFunction)OutputWrite, METH_VARARGS, ""},
        - {"writelines", (PyCFunction)OutputWritelines, METH_VARARGS, ""},
        + {"write", (PyCFunction)OutputWrite, METH_O, ""},
        + {"writelines", (PyCFunction)OutputWritelines, METH_O, ""},
        {"flush", (PyCFunction)OutputFlush, METH_NOARGS, ""},
        {"__dir__", (PyCFunction)OutputDir, METH_NOARGS, ""},
        { NULL, NULL, 0, NULL}
        diff -r 8991454c0024 -r d0320d1f7ff2 src/testdir/test86.ok
        --- a/src/testdir/test86.ok Sun Jun 16 16:57:46 2013 +0200
        +++ b/src/testdir/test86.ok Fri Jun 14 17:59:55 2013 +0400
        @@ -444,7 +444,7 @@
        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:('writelines() requires list of strings',)
        +sys.stdout.writelines([1]):TypeError:('coercing to Unicode: need string or buffer, int found',)
        > VimCommand
        vim.command(1):TypeError:('must be string, not int',)
        > VimToPython
        diff -r 8991454c0024 -r d0320d1f7ff2 src/testdir/test87.ok
        --- a/src/testdir/test87.ok Sun Jun 16 16:57:46 2013 +0200
        +++ b/src/testdir/test87.ok Fri Jun 14 17:59:55 2013 +0400
        @@ -433,7 +433,7 @@
        sys.stdout.write(None):(<class 'TypeError'>, TypeError("Can't convert 'NoneType' object to str implicitly",))
        >> OutputWriteLines
        sys.stdout.writelines(None):(<class 'TypeError'>, TypeError("'NoneType' object is not iterable",))
        -sys.stdout.writelines([1]):(<class 'TypeError'>, TypeError('writelines() requires list of strings',))
        +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())

        --
        --
        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 1371222892 -14400 # Fri Jun 14 19:14:52 2013 +0400 # Branch python-fixes # Node ID
        Message 3 of 25 , Jun 16, 2013
        • 0 Attachment
          # HG changeset patch
          # User ZyX <kp-pav@...>
          # Date 1371222892 -14400
          # Fri Jun 14 19:14:52 2013 +0400
          # Branch python-fixes
          # Node ID c40e953fe93696087c7f0a4e2b7fb25e2d2ad60c
          # Parent d0320d1f7ff29076f01fb39e431446f5c98e8ba2
          Use METH_O in place of METH_VARARGS where appropriate and
          Use StringToChars or PyArg_Parse(, "et"/"es") to convert to strings for consistency

          Note: changes in behavior:

          1. Python 3: Previously str() objects were converted to UTF-8 C strings, now
          they are converted to strings in &encoding.
          2. Python 3: Previously on bytes() objects were not accepted by changed methods
          (e.g. vim.command), now they are used unmodified.
          3. Python 2: Previously trying to use unicode objects with non-ASCII characters
          resulted in UnicodeEncodeError, now they are treated as python 3 str()
          objects.

          Not applicable for Dictionary.has_key and vim.foreach_rtp as they did not use
          PyArg_ParseTuple(args, "s", …), using "O" instead.

          vim.eval was changed to use the same method to make it consistent.

          vim.eval does not use METH_O because optional argument may be added in the
          future, see RFC.

          Changed methods:

          - vim.Function() was changed to use PyArg_ParseTuple(, "et", "ascii"): non-ASCII
          characters are not allowed in function names thus UnicodeEncodeError in this
          case is fine. But TypeError when trying to use bytes() objects is not.
          - vim.command, vim.bindeval, vim.strwidth, vim.Buffer.mark now use StringToChars
          and METH_O
          - vim.Dictionary.has_key now uses METH_O
          - VimEval now uses StringToChars
          - vim.Buffer.mark now directly checks first two bytes of its argument in place
          of running STRLEN() == 1 check.

          Not changed (uses "s" in PyArg_Parse):

          - vim.Finder.find_module: not changed as strings passed to it have nothing to do
          with vim. No need to be consistent with other functions.
          - vim.path_hook: it is intended to handle only one single string object, all
          other data (strings, non-strings: whatever) raises ImportError. No need to
          handle strings consistently with other functions.

          diff -r d0320d1f7ff2 -r c40e953fe936 src/if_py_both.h
          --- a/src/if_py_both.h Fri Jun 14 17:59:55 2013 +0400
          +++ b/src/if_py_both.h Fri Jun 14 19:14:52 2013 +0400
          @@ -467,21 +467,20 @@
          */

          static PyObject *
          -VimCommand(PyObject *self UNUSED, PyObject *args)
          -{
          - char *cmd;
          - PyObject *result;
          -
          - if (!PyArg_ParseTuple(args, "s", &cmd))
          +VimCommand(PyObject *self UNUSED, PyObject *string)
          +{
          + char_u *cmd;
          + PyObject *result;
          + PyObject *todecref;
          +
          + if (!(cmd = StringToChars(string, &todecref)))
          return NULL;

          - PyErr_Clear();
          -
          Py_BEGIN_ALLOW_THREADS
          Python_Lock_Vim();

          VimTryStart();
          - do_cmdline_cmd((char_u *)cmd);
          + do_cmdline_cmd(cmd);
          update_screen(VALID);

          Python_Release_Vim();
          @@ -492,8 +491,8 @@
          else
          result = Py_None;

          -
          Py_XINCREF(result);
          + Py_XDECREF(todecref);
          return result;
          }

          @@ -642,21 +641,28 @@
          static PyObject *
          VimEval(PyObject *self UNUSED, PyObject *args)
          {
          - char *expr;
          + char_u *expr;
          typval_T *our_tv;
          + PyObject *string;
          + PyObject *todecref;
          PyObject *result;
          - PyObject *lookup_dict;
          -
          - if (!PyArg_ParseTuple(args, "s", &expr))
          + PyObject *lookup_dict;
          +
          + if (!PyArg_ParseTuple(args, "O", &string))
          + return NULL;
          +
          + if (!(expr = StringToChars(string, &todecref)))
          return NULL;

          Py_BEGIN_ALLOW_THREADS
          Python_Lock_Vim();
          VimTryStart();
          - our_tv = eval_expr((char_u *)expr, NULL);
          + our_tv = eval_expr(expr, NULL);
          Python_Release_Vim();
          Py_END_ALLOW_THREADS

          + Py_XDECREF(todecref);
          +
          if (VimTryEnd())
          return NULL;

          @@ -689,22 +695,25 @@
          static PyObject *ConvertToPyObject(typval_T *);

          static PyObject *
          -VimEvalPy(PyObject *self UNUSED, PyObject *args)
          -{
          - char *expr;
          +VimEvalPy(PyObject *self UNUSED, PyObject *string)
          +{
          typval_T *our_tv;
          PyObject *result;
          -
          - if (!PyArg_ParseTuple(args, "s", &expr))
          + char_u *expr;
          + PyObject *todecref;
          +
          + if (!(expr = StringToChars(string, &todecref)))
          return NULL;

          Py_BEGIN_ALLOW_THREADS
          Python_Lock_Vim();
          VimTryStart();
          - our_tv = eval_expr((char_u *)expr, NULL);
          + our_tv = eval_expr(expr, NULL);
          Python_Release_Vim();
          Py_END_ALLOW_THREADS

          + Py_XDECREF(todecref);
          +
          if (VimTryEnd())
          return NULL;

          @@ -725,20 +734,24 @@
          }

          static PyObject *
          -VimStrwidth(PyObject *self UNUSED, PyObject *args)
          -{
          - char *expr;
          -
          - if (!PyArg_ParseTuple(args, "s", &expr))
          +VimStrwidth(PyObject *self UNUSED, PyObject *string)
          +{
          + char_u *str;
          + PyObject *todecref;
          + int result;
          +
          + if (!(str = StringToChars(string, &todecref)))
          return NULL;

          - return PyLong_FromLong(
          #ifdef FEAT_MBYTE
          - mb_string2cells((char_u *)expr, (int)STRLEN(expr))
          + result = mb_string2cells(str, (int)STRLEN(str));
          #else
          - STRLEN(expr)
          + result = STRLEN(str);
          #endif
          - );
          +
          + Py_XDECREF(todecref);
          +
          + return PyLong_FromLong(result);
          }

          static PyObject *
          @@ -841,13 +854,11 @@
          }

          static PyObject *
          -VimForeachRTP(PyObject *self UNUSED, PyObject *args)
          +VimForeachRTP(PyObject *self UNUSED, PyObject *callable)
          {
          map_rtp_data data;

          - if (!PyArg_ParseTuple(args, "O", &data.callable))
          - return NULL;
          -
          + data.callable = callable;
          data.result = NULL;

          do_in_runtimepath(NULL, FALSE, &map_rtp_callback, &data);
          @@ -1100,13 +1111,13 @@

          static struct PyMethodDef VimMethods[] = {
          /* name, function, calling, documentation */
          - {"command", VimCommand, METH_VARARGS, "Execute a Vim ex-mode command" },
          + {"command", VimCommand, METH_O, "Execute a Vim ex-mode command" },
          {"eval", VimEval, METH_VARARGS, "Evaluate an expression using Vim evaluator" },
          - {"bindeval", VimEvalPy, METH_VARARGS, "Like eval(), but returns objects attached to vim ones"},
          - {"strwidth", VimStrwidth, METH_VARARGS, "Screen string width, counts <Tab> as having width 1"},
          + {"bindeval", VimEvalPy, METH_O, "Like eval(), but returns objects attached to vim ones"},
          + {"strwidth", VimStrwidth, METH_O, "Screen string width, counts <Tab> as having width 1"},
          {"chdir", (PyCFunction)VimChdir, METH_VARARGS|METH_KEYWORDS, "Change directory"},
          {"fchdir", (PyCFunction)VimFchdir, METH_VARARGS|METH_KEYWORDS, "Change directory"},
          - {"foreach_rtp", VimForeachRTP, METH_VARARGS, "Call given callable for each path in &rtp"},
          + {"foreach_rtp", VimForeachRTP, METH_O, "Call given callable for each path in &rtp"},
          {"find_module", FinderFindModule, METH_VARARGS, "Internal use only, returns loader object for any input it receives"},
          {"path_hook", VimPathHook, METH_VARARGS, "Hook function to install in sys.path_hooks"},
          {"_get_paths", (PyCFunction)Vim_GetPaths, METH_NOARGS, "Get &rtp-based additions to sys.path"},
          @@ -1734,7 +1745,7 @@
          {
          PyObject *object;

          - if (!PyArg_Parse(args, "(O)", &object))
          + if (!PyArg_ParseTuple(args, "O", &object))
          return NULL;

          if (PyObject_HasAttrString(object, "keys"))
          @@ -1878,13 +1889,8 @@
          }

          static PyObject *
          -DictionaryHasKey(DictionaryObject *self, PyObject *args)
          -{
          - PyObject *keyObject;
          -
          - if (!PyArg_ParseTuple(args, "O", &keyObject))
          - return NULL;
          -
          +DictionaryHasKey(DictionaryObject *self, PyObject *keyObject)
          +{
          return _DictionaryItem(self, keyObject, DICT_FLAG_RETURN_BOOL);
          }

          @@ -1915,7 +1921,7 @@
          {"get", (PyCFunction)DictionaryGet, METH_VARARGS, ""},
          {"pop", (PyCFunction)DictionaryPop, METH_VARARGS, ""},
          {"popitem", (PyCFunction)DictionaryPopItem, METH_NOARGS, ""},
          - {"has_key", (PyCFunction)DictionaryHasKey, METH_VARARGS, ""},
          + {"has_key", (PyCFunction)DictionaryHasKey, METH_O, ""},
          {"__dir__", (PyCFunction)DictionaryDir, METH_NOARGS, ""},
          { NULL, NULL, 0, NULL}
          };
          @@ -2435,11 +2441,13 @@
          return NULL;
          }

          - if (!PyArg_ParseTuple(args, "s", &name))
          + if (!PyArg_ParseTuple(args, "et", "ascii", &name))
          return NULL;

          self = FunctionNew(subtype, name);

          + PyMem_Free(name);
          +
          return self;
          }

          @@ -4383,20 +4391,21 @@
          }

          static PyObject *
          -BufferMark(BufferObject *self, PyObject *args)
          +BufferMark(BufferObject *self, PyObject *pmarkObject)
          {
          pos_T *posp;
          - char *pmark;
          - char mark;
          + char_u *pmark;
          + char_u mark;
          buf_T *savebuf;
          + PyObject *todecref;

          if (CheckBuffer(self))
          return NULL;

          - if (!PyArg_ParseTuple(args, "s", &pmark))
          + if (!(pmark = StringToChars(pmarkObject, &todecref)))
          return NULL;

          - if (STRLEN(pmark) != 1)
          + if (pmark[0] == '\0' || pmark[1] != '\0')
          {
          PyErr_SetString(PyExc_ValueError,
          _("mark name must be a single character"));
          @@ -4404,6 +4413,9 @@
          }

          mark = *pmark;
          +
          + Py_XDECREF(todecref);
          +
          VimTryStart();
          switch_buffer(&savebuf, self->buf);
          posp = getmark(mark, FALSE);
          @@ -4461,7 +4473,7 @@
          static struct PyMethodDef BufferMethods[] = {
          /* name, function, calling, documentation */
          {"append", (PyCFunction)BufferAppend, METH_VARARGS, "Append data to Vim buffer" },
          - {"mark", (PyCFunction)BufferMark, METH_VARARGS, "Return (row,col) representing position of named mark" },
          + {"mark", (PyCFunction)BufferMark, METH_O, "Return (row,col) representing position of named mark" },
          {"range", (PyCFunction)BufferRange, METH_VARARGS, "Return a range object which represents the part of the given buffer between line numbers s and e" },
          {"__dir__", (PyCFunction)BufferDir, METH_NOARGS, ""},
          { NULL, NULL, 0, NULL}
          diff -r d0320d1f7ff2 -r c40e953fe936 src/testdir/test86.ok
          --- a/src/testdir/test86.ok Fri Jun 14 17:59:55 2013 +0400
          +++ b/src/testdir/test86.ok Fri Jun 14 19:14:52 2013 +0400
          @@ -446,14 +446,14 @@
          sys.stdout.writelines(None):TypeError:("'NoneType' object is not iterable",)
          sys.stdout.writelines([1]):TypeError:('coercing to Unicode: need string or buffer, int found',)
          > VimCommand
          -vim.command(1):TypeError:('must be string, not int',)
          +vim.command(1):TypeError:('object must be string',)
          > VimToPython
          > VimEval
          -vim.eval(1):TypeError:('must be string, not int',)
          +vim.eval(1):TypeError:('object must be string',)
          > VimEvalPy
          -vim.bindeval(1):TypeError:('must be string, not int',)
          +vim.bindeval(1):TypeError:('object must be string',)
          > VimStrwidth
          -vim.strwidth(1):TypeError:('must be string, not int',)
          +vim.strwidth(1):TypeError:('object must be string',)
          > Dictionary
          >> DictionaryConstructor
          vim.Dictionary("abc"):ValueError:('expected sequence element of size 2',)
          @@ -683,7 +683,7 @@
          >> DictionaryPopItem
          d.popitem(1, 2):TypeError:('popitem() takes no arguments (2 given)',)
          >> DictionaryHasKey
          -d.has_key():TypeError:('function takes exactly 1 argument (0 given)',)
          +d.has_key():TypeError:('has_key() takes exactly one argument (0 given)',)
          > List
          >> ListConstructor
          vim.List(1, 2):TypeError:('function takes at most 1 argument (2 given)',)
          @@ -1065,7 +1065,7 @@
          vim.current.buffer.name = True:TypeError:('object must be string',)
          vim.current.buffer.xxx = True:AttributeError:('xxx',)
          >> BufferMark
          -vim.current.buffer.mark(0):TypeError:('must be string, not int',)
          +vim.current.buffer.mark(0):TypeError:('object must be string',)
          vim.current.buffer.mark("abc"):ValueError:('mark name must be a single character',)
          vim.current.buffer.mark("!"):error:('invalid mark name',)
          >> BufferRange
          diff -r d0320d1f7ff2 -r c40e953fe936 src/testdir/test87.ok
          --- a/src/testdir/test87.ok Fri Jun 14 17:59:55 2013 +0400
          +++ b/src/testdir/test87.ok Fri Jun 14 19:14:52 2013 +0400
          @@ -439,14 +439,14 @@
          sys.stdout.writelines(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError())
          <<< Finished
          > VimCommand
          -vim.command(1):(<class 'TypeError'>, TypeError('must be str, not int',))
          +vim.command(1):(<class 'TypeError'>, TypeError('object must be string',))
          > VimToPython
          > VimEval
          -vim.eval(1):(<class 'TypeError'>, TypeError('must be str, not int',))
          +vim.eval(1):(<class 'TypeError'>, TypeError('object must be string',))
          > VimEvalPy
          -vim.bindeval(1):(<class 'TypeError'>, TypeError('must be str, not int',))
          +vim.bindeval(1):(<class 'TypeError'>, TypeError('object must be string',))
          > VimStrwidth
          -vim.strwidth(1):(<class 'TypeError'>, TypeError('must be str, not int',))
          +vim.strwidth(1):(<class 'TypeError'>, TypeError('object must be string',))
          > Dictionary
          >> DictionaryConstructor
          vim.Dictionary("abc"):(<class 'ValueError'>, ValueError('expected sequence element of size 2',))
          @@ -680,7 +680,7 @@
          >> DictionaryPopItem
          d.popitem(1, 2):(<class 'TypeError'>, TypeError('popitem() takes no arguments (2 given)',))
          >> DictionaryHasKey
          -d.has_key():(<class 'TypeError'>, TypeError('function takes exactly 1 argument (0 given)',))
          +d.has_key():(<class 'TypeError'>, TypeError('has_key() takes exactly one argument (0 given)',))
          > List
          >> ListConstructor
          vim.List(1, 2):(<class 'TypeError'>, TypeError('function takes at most 1 argument (2 given)',))
          @@ -1074,7 +1074,7 @@
          vim.current.buffer.name = True:(<class 'TypeError'>, TypeError('object must be string',))
          vim.current.buffer.xxx = True:(<class 'AttributeError'>, AttributeError('xxx',))
          >> BufferMark
          -vim.current.buffer.mark(0):(<class 'TypeError'>, TypeError('must be str, not int',))
          +vim.current.buffer.mark(0):(<class 'TypeError'>, TypeError('object must be string',))
          vim.current.buffer.mark("abc"):(<class 'ValueError'>, ValueError('mark name must be a single character',))
          vim.current.buffer.mark("!"):(<class 'vim.error'>, error('invalid mark name',))
          >> BufferRange

          --
          --
          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 1371223647 -14400 # Fri Jun 14 19:27:27 2013 +0400 # Branch python-fixes # Node ID
          Message 4 of 25 , Jun 16, 2013
          • 0 Attachment
            # HG changeset patch
            # User ZyX <kp-pav@...>
            # Date 1371223647 -14400
            # Fri Jun 14 19:27:27 2013 +0400
            # Branch python-fixes
            # Node ID b9d4dfa09951d4fb75972df34802675edf24a17e
            # Parent c40e953fe93696087c7f0a4e2b7fb25e2d2ad60c
            More consistency changes:

            - StringToLine now supports both bytes() and unicode() objects
            - In if_py_both.h PyBytes_* points to bytes()-manipulating functions,
            PyString_* points to bytes() (python 2) or unicode()
            manipulating functions
            PyUnicode_* points to unicode() manipulating functions
            It may not be so in if_python*.c.

            * Memory leak fixed in StringToLine in case conversion bytes to char* failed.
            * Both PyBytes_AsStringAndSize failure checks were squashed.
            * ENC_OPT now always has char* type.

            (note: bytes() is str() on python 2; unicode() is str() on python 3)

            diff -r c40e953fe936 -r b9d4dfa09951 src/if_py_both.h
            --- a/src/if_py_both.h Fri Jun 14 19:14:52 2013 +0400
            +++ b/src/if_py_both.h Fri Jun 14 19:27:27 2013 +0400
            @@ -18,7 +18,7 @@
            #endif

            #ifdef FEAT_MBYTE
            -# define ENC_OPT p_enc
            +# define ENC_OPT ((char *)p_enc)
            #else
            # define ENC_OPT "latin1"
            #endif
            @@ -92,28 +92,29 @@
            StringToChars(PyObject *object, PyObject **todecref)
            {
            char_u *p;
            - PyObject *bytes = NULL;

            if (PyBytes_Check(object))
            {

            - if (PyString_AsStringAndSize(object, (char **) &p, NULL) == -1)
            + if (PyBytes_AsStringAndSize(object, (char **) &p, NULL) == -1
            + || p == NULL)
            return NULL;
            - if (p == NULL)
            +
            + *todecref = NULL;
            + }
            + else if (PyUnicode_Check(object))
            + {
            + PyObject *bytes;
            +
            + if (!(bytes = PyUnicode_AsEncodedString(object, ENC_OPT, NULL)))
            return NULL;

            - *todecref = NULL;
            - }
            - else if (PyUnicode_Check(object))
            - {
            - bytes = PyUnicode_AsEncodedString(object, (char *)ENC_OPT, NULL);
            - if (bytes == NULL)
            + if(PyBytes_AsStringAndSize(bytes, (char **) &p, NULL) == -1
            + || p == NULL)
            + {
            + Py_DECREF(bytes);
            return NULL;
            -
            - if(PyString_AsStringAndSize(bytes, (char **) &p, NULL) == -1)
            - return NULL;
            - if (p == NULL)
            - return NULL;
            + }

            *todecref = bytes;
            }
            @@ -133,6 +134,7 @@

            if (!(string = PyString_FromString(s)))
            return -1;
            +
            if (PyList_Append(list, string))
            {
            Py_DECREF(string);
            @@ -535,10 +537,8 @@
            }

            if (our_tv->v_type == VAR_STRING)
            - {
            result = PyString_FromString(our_tv->vval.v_string == NULL
            ? "" : (char *)our_tv->vval.v_string);
            - }
            else if (our_tv->v_type == VAR_NUMBER)
            {
            char buf[NUMBUFLEN];
            @@ -3385,22 +3385,31 @@
            static char *
            StringToLine(PyObject *obj)
            {
            - const char *str;
            - char *save;
            - PyObject *bytes;
            - PyInt len;
            - PyInt i;
            - char *p;
            -
            - if (obj == NULL || !PyString_Check(obj))
            - {
            - PyErr_BadArgument();
            - return NULL;
            - }
            -
            - bytes = PyString_AsBytes(obj); /* for Python 2 this does nothing */
            - str = PyString_AsString(bytes);
            - len = PyString_Size(bytes);
            + char *str;
            + char *save;
            + PyObject *bytes = NULL;
            + Py_ssize_t len;
            + PyInt i;
            + char *p;
            +
            + if (PyBytes_Check(obj))
            + {
            + if (PyBytes_AsStringAndSize(obj, &str, &len) == -1
            + || str == NULL)
            + return NULL;
            + }
            + else if (PyUnicode_Check(obj))
            + {
            + if (!(bytes = PyUnicode_AsEncodedString(obj, ENC_OPT, NULL)))
            + return NULL;
            +
            + if(PyBytes_AsStringAndSize(bytes, &str, &len) == -1
            + || str == NULL)
            + {
            + Py_DECREF(bytes);
            + return NULL;
            + }
            + }

            /*
            * Error checking: String must not contain newlines, as we
            @@ -3439,7 +3448,7 @@
            }

            save[i] = '\0';
            - PyString_FreeBytes(bytes); /* Python 2 does nothing here */
            + Py_XDECREF(bytes); /* Python 2 does nothing here */

            return save;
            }
            @@ -3568,10 +3577,10 @@

            return OK;
            }
            - else if (PyString_Check(line))
            - {
            - char *save = StringToLine(line);
            - buf_T *savebuf;
            + else if (PyBytes_Check(line) || PyUnicode_Check(line))
            + {
            + char *save = StringToLine(line);
            + buf_T *savebuf;

            if (save == NULL)
            return FAIL;
            @@ -3821,7 +3830,7 @@
            /* First of all, we check the type of the supplied Python object.
            * It must be a string or a list, or the call is in error.
            */
            - if (PyString_Check(lines))
            + if (PyBytes_Check(lines) || PyUnicode_Check(lines))
            {
            char *str = StringToLine(lines);
            buf_T *savebuf;
            @@ -5254,7 +5263,7 @@
            {
            char_u *result;

            - if (PyString_AsStringAndSize(obj, (char **) &result, NULL) == -1)
            + if (PyBytes_AsStringAndSize(obj, (char **) &result, NULL) == -1)
            return -1;
            if (result == NULL)
            return -1;
            @@ -5269,11 +5278,11 @@
            PyObject *bytes;
            char_u *result;

            - bytes = PyUnicode_AsEncodedString(obj, (char *)ENC_OPT, NULL);
            + bytes = PyUnicode_AsEncodedString(obj, ENC_OPT, NULL);
            if (bytes == NULL)
            return -1;

            - if(PyString_AsStringAndSize(bytes, (char **) &result, NULL) == -1)
            + if(PyBytes_AsStringAndSize(bytes, (char **) &result, NULL) == -1)
            return -1;
            if (result == NULL)
            return -1;
            diff -r c40e953fe936 -r b9d4dfa09951 src/if_python.c
            --- a/src/if_python.c Fri Jun 14 19:14:52 2013 +0400
            +++ b/src/if_python.c Fri Jun 14 19:27:27 2013 +0400
            @@ -68,12 +68,9 @@
            #undef main /* Defined in python.h - aargh */
            #undef HAVE_FCNTL_H /* Clash with os_win32.h */

            -#define PyBytes_FromString PyString_FromString
            -#define PyBytes_Check PyString_Check
            -
            -/* No-op conversion functions, use with care! */
            -#define PyString_AsBytes(obj) (obj)
            -#define PyString_FreeBytes(obj)
            +#define PyBytes_FromString PyString_FromString
            +#define PyBytes_Check PyString_Check
            +#define PyBytes_AsStringAndSize PyString_AsStringAndSize

            #if !defined(FEAT_PYTHON) && defined(PROTO)
            /* Use this to be able to generate prototypes without python being used. */
            diff -r c40e953fe936 -r b9d4dfa09951 src/if_python3.c
            --- a/src/if_python3.c Fri Jun 14 19:14:52 2013 +0400
            +++ b/src/if_python3.c Fri Jun 14 19:27:27 2013 +0400
            @@ -84,13 +84,8 @@

            #define PyInt Py_ssize_t
            #define PyString_Check(obj) PyUnicode_Check(obj)
            -#define PyString_AsBytes(obj) PyUnicode_AsEncodedString(obj, (char *)ENC_OPT, CODEC_ERROR_HANDLER)
            -#define PyString_FreeBytes(obj) Py_XDECREF(bytes)
            -#define PyString_AsString(obj) PyBytes_AsString(obj)
            -#define PyString_Size(obj) PyBytes_GET_SIZE(bytes)
            #define PyString_FromString(repr) PyUnicode_FromString(repr)
            #define PyString_FromFormat PyUnicode_FromFormat
            -#define PyString_AsStringAndSize(obj, buffer, len) PyBytes_AsStringAndSize(obj, buffer, len)
            #define PyInt_Check(obj) PyLong_Check(obj)
            #define PyInt_FromLong(i) PyLong_FromLong(i)
            #define PyInt_AsLong(obj) PyLong_AsLong(obj)
            @@ -357,7 +352,7 @@
            # endif
            static PyObject* (*py3_PyUnicode_AsEncodedString)(PyObject *unicode, const char* encoding, const char* errors);
            static char* (*py3_PyBytes_AsString)(PyObject *bytes);
            -static int (*py3_PyBytes_AsStringAndSize)(PyObject *bytes, char **buffer, int *length);
            +static int (*py3_PyBytes_AsStringAndSize)(PyObject *bytes, char **buffer, Py_ssize_t *length);
            static PyObject* (*py3_PyBytes_FromString)(char *str);
            static PyObject* (*py3_PyFloat_FromDouble)(double num);
            static double (*py3_PyFloat_AsDouble)(PyObject *);

            --
            --
            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 1371238936 -14400 # Fri Jun 14 23:42:16 2013 +0400 # Branch python-fixes # Node ID
            Message 5 of 25 , Jun 16, 2013
            • 0 Attachment
              # 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

              diff -r b9d4dfa09951 -r abcf5d9458ee src/if_py_both.h
              --- a/src/if_py_both.h Fri Jun 14 19:27:27 2013 +0400
              +++ b/src/if_py_both.h Fri Jun 14 23:42:16 2013 +0400
              @@ -26,10 +26,12 @@

              static const char *vim_special_path = "_vim_path_";

              +#define PyErr_SET_STRING(exc, str) PyErr_SetString(exc, _(str))
              #define PyErr_SetVim(str) PyErr_SetString(VimError, str)
              -
              -#define RAISE_NO_EMPTY_KEYS PyErr_SetString(PyExc_ValueError, \
              - _("empty keys are not allowed"))
              +#define PyErr_SET_VIM(str) PyErr_SET_STRING(VimError, str)
              +
              +#define RAISE_NO_EMPTY_KEYS PyErr_SET_STRING(PyExc_ValueError, \
              + "empty keys are not allowed")

              #define INVALID_BUFFER_VALUE ((buf_T *)(-1))
              #define INVALID_WINDOW_VALUE ((win_T *)(-1))
              @@ -120,7 +122,7 @@
              }
              else
              {
              - PyErr_SetString(PyExc_TypeError, _("object must be string"));
              + PyErr_SET_STRING(PyExc_TypeError, "object must be string");
              return NULL;
              }

              @@ -212,8 +214,8 @@
              {
              if (val == NULL)
              {
              - PyErr_SetString(PyExc_AttributeError,
              - _("can't delete OutputObject attributes"));
              + PyErr_SET_STRING(PyExc_AttributeError,
              + "can't delete OutputObject attributes");
              return -1;
              }

              @@ -221,7 +223,7 @@
              {
              if (!PyInt_Check(val))
              {
              - PyErr_SetString(PyExc_TypeError, _("softspace must be an integer"));
              + PyErr_SET_STRING(PyExc_TypeError, "softspace must be an integer");
              return -1;
              }

              @@ -229,7 +231,7 @@
              return 0;
              }

              - PyErr_SetString(PyExc_AttributeError, _("invalid attribute"));
              + PyErr_SET_STRING(PyExc_AttributeError, "invalid attribute");
              return -1;
              }

              @@ -668,7 +670,7 @@

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

              @@ -719,7 +721,7 @@

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

              @@ -791,7 +793,7 @@
              if (VimTryEnd())
              return NULL;

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

              @@ -969,8 +971,8 @@
              if (!PyTuple_Check(find_module_result)
              || PyTuple_GET_SIZE(find_module_result) != 3)
              {
              - PyErr_SetString(PyExc_TypeError,
              - _("expected 3-tuple as imp.find_module() result"));
              + PyErr_SET_STRING(PyExc_TypeError,
              + "expected 3-tuple as imp.find_module() result");
              return NULL;
              }

              @@ -978,8 +980,8 @@
              || !(pathname = PyTuple_GET_ITEM(find_module_result, 1))
              || !(description = PyTuple_GET_ITEM(find_module_result, 2)))
              {
              - PyErr_SetString(PyExc_RuntimeError,
              - _("internal error: imp.find_module returned tuple with NULL"));
              + PyErr_SET_STRING(PyExc_RuntimeError,
              + "internal error: imp.find_module returned tuple with NULL");
              return NULL;
              }

              @@ -1350,8 +1352,8 @@
              {
              if (val == NULL)
              {
              - PyErr_SetString(PyExc_AttributeError,
              - _("cannot delete vim.Dictionary attributes"));
              + PyErr_SET_STRING(PyExc_AttributeError,
              + "cannot delete vim.Dictionary attributes");
              return -1;
              }

              @@ -1359,7 +1361,7 @@
              {
              if (self->dict->dv_lock == VAR_FIXED)
              {
              - PyErr_SetString(PyExc_TypeError, _("cannot modify fixed dictionary"));
              + PyErr_SET_STRING(PyExc_TypeError, "cannot modify fixed dictionary");
              return -1;
              }
              else
              @@ -1376,7 +1378,7 @@
              }
              else
              {
              - PyErr_SetString(PyExc_AttributeError, _("cannot set this attribute"));
              + PyErr_SET_STRING(PyExc_AttributeError, "cannot set this attribute");
              return -1;
              }
              }
              @@ -1458,7 +1460,7 @@
              {
              if (dict->dv_lock)
              {
              - PyErr_SetVim(_("dict is locked"));
              + PyErr_SET_VIM("dict is locked");
              Py_DECREF(r);
              return NULL;
              }
              @@ -1509,8 +1511,8 @@
              if ((*dii)->ht->ht_array != (*dii)->ht_array ||
              (*dii)->ht->ht_used != (*dii)->ht_used)
              {
              - PyErr_SetString(PyExc_RuntimeError,
              - _("hashtab changed during iteration"));
              + PyErr_SET_STRING(PyExc_RuntimeError,
              + "hashtab changed during iteration");
              return NULL;
              }

              @@ -1561,7 +1563,7 @@

              if (dict->dv_lock)
              {
              - PyErr_SetVim(_("dict is locked"));
              + PyErr_SET_VIM("dict is locked");
              return -1;
              }

              @@ -1616,7 +1618,7 @@
              Py_XDECREF(todecref);
              vim_free(di);
              dictitem_free(di);
              - PyErr_SetVim(_("failed to add key to dictionary"));
              + PyErr_SET_VIM("failed to add key to dictionary");
              return -1;
              }
              }
              @@ -1724,7 +1726,7 @@

              if (dict->dv_lock)
              {
              - PyErr_SetVim(_("dict is locked"));
              + PyErr_SET_VIM("dict is locked");
              return NULL;
              }

              @@ -1780,8 +1782,8 @@
              {
              Py_DECREF(iterator);
              Py_DECREF(fast);
              - PyErr_SetString(PyExc_ValueError,
              - _("expected sequence element of size 2"));
              + PyErr_SET_STRING(PyExc_ValueError,
              + "expected sequence element of size 2");
              return NULL;
              }

              @@ -1824,7 +1826,7 @@
              {
              Py_DECREF(iterator);
              dictitem_free(di);
              - PyErr_SetVim(_("failed to add key to dictionary"));
              + PyErr_SET_VIM("failed to add key to dictionary");
              return NULL;
              }
              }
              @@ -2022,8 +2024,8 @@

              if (kwargs)
              {
              - PyErr_SetString(PyExc_TypeError,
              - _("list constructor does not accept keyword arguments"));
              + PyErr_SET_STRING(PyExc_TypeError,
              + "list constructor does not accept keyword arguments");
              return NULL;
              }

              @@ -2078,13 +2080,13 @@

              if (index >= ListLength(self))
              {
              - PyErr_SetString(PyExc_IndexError, _("list index out of range"));
              + PyErr_SET_STRING(PyExc_IndexError, "list index out of range");
              return NULL;
              }
              li = list_find(self->list, (long) index);
              if (li == NULL)
              {
              - PyErr_SetVim(_("internal error: failed to get vim list item"));
              + PyErr_SET_VIM("internal error: failed to get vim list item");
              return NULL;
              }
              return ConvertToPyObject(&li->li_tv);
              @@ -2197,12 +2199,12 @@

              if (l->lv_lock)
              {
              - PyErr_SetVim(_("list is locked"));
              + PyErr_SET_VIM("list is locked");
              return -1;
              }
              if (index>length || (index==length && obj==NULL))
              {
              - PyErr_SetString(PyExc_IndexError, _("list index out of range"));
              + PyErr_SET_STRING(PyExc_IndexError, "list index out of range");
              return -1;
              }

              @@ -2223,7 +2225,7 @@
              if (list_append_tv(l, &tv) == FAIL)
              {
              clear_tv(&tv);
              - PyErr_SetVim(_("failed to add item to list"));
              + PyErr_SET_VIM("failed to add item to list");
              return -1;
              }
              }
              @@ -2251,7 +2253,7 @@

              if (l->lv_lock)
              {
              - PyErr_SetVim(_("list is locked"));
              + PyErr_SET_VIM("list is locked");
              return -1;
              }

              @@ -2264,7 +2266,7 @@
              li = list_find(l, (long) first);
              if (li == NULL)
              {
              - PyErr_SetVim(_("internal error: no vim list item"));
              + PyErr_SET_VIM("internal error: no vim list item");
              return -1;
              }
              if (last > first)
              @@ -2297,7 +2299,7 @@
              if (list_insert_tv(l, &v, li) == FAIL)
              {
              clear_tv(&v);
              - PyErr_SetVim(_("internal error: failed to add item to list"));
              + PyErr_SET_VIM("internal error: failed to add item to list");
              return -1;
              }
              clear_tv(&v);
              @@ -2314,7 +2316,7 @@

              if (l->lv_lock)
              {
              - PyErr_SetVim(_("list is locked"));
              + PyErr_SET_VIM("list is locked");
              return NULL;
              }

              @@ -2348,8 +2350,8 @@
              {
              if (val == NULL)
              {
              - PyErr_SetString(PyExc_AttributeError,
              - _("cannot delete vim.List attributes"));
              + PyErr_SET_STRING(PyExc_AttributeError,
              + "cannot delete vim.List attributes");
              return -1;
              }

              @@ -2357,7 +2359,7 @@
              {
              if (self->list->lv_lock == VAR_FIXED)
              {
              - PyErr_SetString(PyExc_TypeError, _("cannot modify fixed list"));
              + PyErr_SET_STRING(PyExc_TypeError, "cannot modify fixed list");
              return -1;
              }
              else
              @@ -2374,7 +2376,7 @@
              }
              else
              {
              - PyErr_SetString(PyExc_AttributeError, _("cannot set this attribute"));
              + PyErr_SET_STRING(PyExc_AttributeError, "cannot set this attribute");
              return -1;
              }
              }
              @@ -2409,8 +2411,8 @@
              {
              if (!translated_function_exists(name))
              {
              - PyErr_SetString(PyExc_ValueError,
              - _("unnamed function does not exist"));
              + PyErr_SET_STRING(PyExc_ValueError,
              + "unnamed function does not exist");
              return NULL;
              }
              self->name = vim_strsave(name);
              @@ -2421,7 +2423,7 @@
              vim_strchr(name, AUTOLOAD_CHAR) == NULL))
              == NULL)
              {
              - PyErr_SetString(PyExc_ValueError, _("function does not exist"));
              + PyErr_SET_STRING(PyExc_ValueError, "function does not exist");
              return NULL;
              }

              @@ -2436,8 +2438,8 @@

              if (kwargs)
              {
              - PyErr_SetString(PyExc_TypeError,
              - _("function constructor does not accept keyword arguments"));
              + PyErr_SET_STRING(PyExc_TypeError,
              + "function constructor does not accept keyword arguments");
              return NULL;
              }

              @@ -2514,7 +2516,7 @@
              else if (error != OK)
              {
              result = NULL;
              - PyErr_SetVim(_("failed to run function"));
              + PyErr_SET_VIM("failed to run function");
              }
              else
              result = ConvertToPyObject(&rettv);
              @@ -2659,14 +2661,14 @@
              }
              else
              {
              - PyErr_SetString(PyExc_RuntimeError,
              - _("unable to get option value"));
              + PyErr_SET_STRING(PyExc_RuntimeError,
              + "unable to get option value");
              return NULL;
              }
              }
              else
              {
              - PyErr_SetVim("Internal error: unknown option type. Should not happen");
              + PyErr_SET_VIM("internal error: unknown option type");
              return NULL;
              }
              }
              @@ -2709,7 +2711,7 @@
              {
              if (VimTryEnd())
              return -1;
              - PyErr_SetVim("Problem while switching windows.");
              + PyErr_SET_VIM("problem while switching windows");
              return -1;
              }
              r = set_option_value_err(key, numval, stringval, opt_flags);
              @@ -2769,15 +2771,14 @@
              {
              if (self->opt_type == SREQ_GLOBAL)
              {
              - PyErr_SetString(PyExc_ValueError,
              - _("unable to unset global option"));
              + PyErr_SET_STRING(PyExc_ValueError, "unable to unset global option");
              Py_XDECREF(todecref);
              return -1;
              }
              else if (!(flags & SOPT_GLOBAL))
              {
              - PyErr_SetString(PyExc_ValueError, _("unable to unset option "
              - "without global value"));
              + PyErr_SET_STRING(PyExc_ValueError, "unable to unset option "
              + "without global value");
              Py_XDECREF(todecref);
              return -1;
              }
              @@ -2814,7 +2815,7 @@
              val = PyLong_AsLong(valObject);
              else
              {
              - PyErr_SetString(PyExc_TypeError, _("object must be integer"));
              + PyErr_SET_STRING(PyExc_TypeError, "object must be integer");
              Py_XDECREF(todecref);
              return -1;
              }
              @@ -2863,7 +2864,7 @@
              {
              if (self->tab == INVALID_TABPAGE_VALUE)
              {
              - PyErr_SetVim(_("attempt to refer to deleted tab page"));
              + PyErr_SET_VIM("attempt to refer to deleted tab page");
              return -1;
              }

              @@ -3007,7 +3008,7 @@
              if (n == 0)
              return TabPageNew(tp);

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

              @@ -3028,7 +3029,7 @@
              {
              if (self->win == INVALID_WINDOW_VALUE)
              {
              - PyErr_SetVim(_("attempt to refer to deleted window"));
              + PyErr_SET_VIM("attempt to refer to deleted window");
              return -1;
              }

              @@ -3194,7 +3195,7 @@

              if (strcmp(name, "buffer") == 0)
              {
              - PyErr_SetString(PyExc_TypeError, _("readonly attribute"));
              + PyErr_SET_STRING(PyExc_TypeError, "readonly attribute");
              return -1;
              }
              else if (strcmp(name, "cursor") == 0)
              @@ -3207,7 +3208,7 @@

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

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

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

              @@ -3424,7 +3425,7 @@
              --len;
              else
              {
              - PyErr_SetVim(_("string cannot contain newlines"));
              + PyErr_SET_VIM("string cannot contain newlines");
              return NULL;
              }
              }
              @@ -3557,9 +3558,9 @@
              VimTryStart();

              if (u_savedel((linenr_T)n, 1L) == FAIL)
              - PyErr_SetVim(_("cannot save undo information"));
              + PyErr_SET_VIM("cannot save undo information");
              else if (ml_delete((linenr_T)n, FALSE) == FAIL)
              - PyErr_SetVim(_("cannot delete line"));
              + PyErr_SET_VIM("cannot delete line");
              else
              {
              if (buf == savebuf)
              @@ -3593,12 +3594,12 @@

              if (u_savesub((linenr_T)n) == FAIL)
              {
              - PyErr_SetVim(_("cannot save undo information"));
              + PyErr_SET_VIM("cannot save undo information");
              vim_free(save);
              }
              else if (ml_replace((linenr_T)n, (char_u *)save, FALSE) == FAIL)
              {
              - PyErr_SetVim(_("cannot replace line"));
              + PyErr_SET_VIM("cannot replace line");
              vim_free(save);
              }
              else
              @@ -3653,14 +3654,14 @@
              switch_buffer(&savebuf, buf);

              if (u_savedel((linenr_T)lo, (long)n) == FAIL)
              - PyErr_SetVim(_("cannot save undo information"));
              + PyErr_SET_VIM("cannot save undo information");
              else
              {
              for (i = 0; i < n; ++i)
              {
              if (ml_delete((linenr_T)lo, FALSE) == FAIL)
              {
              - PyErr_SetVim(_("cannot delete line"));
              + PyErr_SET_VIM("cannot delete line");
              break;
              }
              }
              @@ -3721,7 +3722,7 @@
              switch_buffer(&savebuf, buf);

              if (u_save((linenr_T)(lo-1), (linenr_T)hi) == FAIL)
              - PyErr_SetVim(_("cannot save undo information"));
              + PyErr_SET_VIM("cannot save undo information");

              /* If the size of the range is reducing (ie, new_len < old_len) we
              * need to delete some old_len. We do this at the start, by
              @@ -3732,7 +3733,7 @@
              for (i = 0; i < old_len - new_len; ++i)
              if (ml_delete((linenr_T)lo, FALSE) == FAIL)
              {
              - PyErr_SetVim(_("cannot delete line"));
              + PyErr_SET_VIM("cannot delete line");
              break;
              }
              extra -= i;
              @@ -3748,7 +3749,7 @@
              if (ml_replace((linenr_T)(lo+i), (char_u *)array[i], FALSE)
              == FAIL)
              {
              - PyErr_SetVim(_("cannot replace line"));
              + PyErr_SET_VIM("cannot replace line");
              break;
              }
              }
              @@ -3766,7 +3767,7 @@
              if (ml_append((linenr_T)(lo + i - 1),
              (char_u *)array[i], 0, FALSE) == FAIL)
              {
              - PyErr_SetVim(_("cannot insert line"));
              + PyErr_SET_VIM("cannot insert line");
              break;
              }
              vim_free(array[i]);
              @@ -3843,9 +3844,9 @@
              switch_buffer(&savebuf, buf);

              if (u_save((linenr_T)n, (linenr_T)(n+1)) == FAIL)
              - PyErr_SetVim(_("cannot save undo information"));
              + PyErr_SET_VIM("cannot save undo information");
              else if (ml_append((linenr_T)n, (char_u *)str, 0, FALSE) == FAIL)
              - PyErr_SetVim(_("cannot insert line"));
              + PyErr_SET_VIM("cannot insert line");
              else
              appended_lines_mark((linenr_T)n, 1L);

              @@ -3894,7 +3895,7 @@
              switch_buffer(&savebuf, buf);

              if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
              - PyErr_SetVim(_("cannot save undo information"));
              + PyErr_SET_VIM("cannot save undo information");
              else
              {
              for (i = 0; i < size; ++i)
              @@ -3902,7 +3903,7 @@
              if (ml_append((linenr_T)(n + i),
              (char_u *)array[i], 0, FALSE) == FAIL)
              {
              - PyErr_SetVim(_("cannot insert line"));
              + PyErr_SET_VIM("cannot insert line");

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

              @@ -3976,7 +3977,7 @@

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

              @@ -4026,7 +4027,7 @@

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

              @@ -4098,7 +4099,7 @@

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

              @@ -4381,7 +4382,7 @@

              if (r == FAIL)
              {
              - PyErr_SetVim(_("failed to rename buffer"));
              + PyErr_SET_VIM("failed to rename buffer");
              return -1;
              }
              return 0;
              @@ -4416,8 +4417,8 @@

              if (pmark[0] == '\0' || pmark[1] != '\0')
              {
              - PyErr_SetString(PyExc_ValueError,
              - _("mark name must be a single character"));
              + PyErr_SET_STRING(PyExc_ValueError,
              + "mark name must be a single character");
              return NULL;
              }

              @@ -4434,7 +4435,7 @@

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

              @@ -4529,7 +4530,7 @@
              bnr = PyLong_AsLong(keyObject);
              else
              {
              - PyErr_SetString(PyExc_TypeError, _("key must be integer"));
              + PyErr_SET_STRING(PyExc_TypeError, "key must be integer");
              return NULL;
              }

              @@ -4667,7 +4668,7 @@

              if (value->ob_type != &BufferType)
              {
              - PyErr_SetString(PyExc_TypeError, _("expected vim.Buffer object"));
              + PyErr_SET_STRING(PyExc_TypeError, "expected vim.Buffer object");
              return -1;
              }

              @@ -4680,7 +4681,7 @@
              {
              if (VimTryEnd())
              return -1;
              - PyErr_SetVim(_("failed to switch to given buffer"));
              + PyErr_SET_VIM("failed to switch to given buffer");
              return -1;
              }

              @@ -4692,7 +4693,7 @@

              if (value->ob_type != &WindowType)
              {
              - PyErr_SetString(PyExc_TypeError, _("expected vim.Window object"));
              + PyErr_SET_STRING(PyExc_TypeError, "expected vim.Window object");
              return -1;
              }

              @@ -4702,8 +4703,8 @@

              if (!count)
              {
              - PyErr_SetString(PyExc_ValueError,
              - _("failed to find window in the current tab page"));
              + PyErr_SET_STRING(PyExc_ValueError,
              + "failed to find window in the current tab page");
              return -1;
              }

              @@ -4713,8 +4714,8 @@
              {
              if (VimTryEnd())
              return -1;
              - PyErr_SetString(PyExc_RuntimeError,
              - _("did not switch to the specified window"));
              + PyErr_SET_STRING(PyExc_RuntimeError,
              + "did not switch to the specified window");
              return -1;
              }

              @@ -4724,7 +4725,7 @@
              {
              if (value->ob_type != &TabPageType)
              {
              - PyErr_SetString(PyExc_TypeError, _("expected vim.TabPage object"));
              + PyErr_SET_STRING(PyExc_TypeError, "expected vim.TabPage object");
              return -1;
              }

              @@ -4737,8 +4738,8 @@
              {
              if (VimTryEnd())
              return -1;
              - PyErr_SetString(PyExc_RuntimeError,
              - _("did not switch to the specified tab page"));
              + PyErr_SET_STRING(PyExc_RuntimeError,
              + "did not switch to the specified tab page");
              return -1;
              }

              @@ -5005,7 +5006,7 @@
              clear_tv(&di->di_tv);
              vim_free(di);
              dict_unref(dict);
              - PyErr_SetVim(_("failed to add key to dictionary"));
              + PyErr_SET_VIM("failed to add key to dictionary");
              return -1;
              }
              }
              @@ -5107,7 +5108,7 @@
              Py_DECREF(iterator);
              dictitem_free(di);
              dict_unref(dict);
              - PyErr_SetVim(_("failed to add key to dictionary"));
              + PyErr_SET_VIM("failed to add key to dictionary");
              return -1;
              }
              }
              @@ -5215,8 +5216,8 @@
              r = convert_dl(obj, tv, pymap_to_tv, lookup_dict);
              else
              {
              - PyErr_SetString(PyExc_TypeError,
              - _("unable to convert object to vim dictionary"));
              + PyErr_SET_STRING(PyExc_TypeError,
              + "unable to convert object to vim dictionary");
              r = -1;
              }
              Py_DECREF(lookup_dict);
              @@ -5325,8 +5326,8 @@
              return convert_dl(obj, tv, pymap_to_tv, lookup_dict);
              else
              {
              - PyErr_SetString(PyExc_TypeError,
              - _("unable to convert to vim structure"));
              + PyErr_SET_STRING(PyExc_TypeError,
              + "unable to convert to vim structure");
              return -1;
              }
              return 0;
              @@ -5337,7 +5338,7 @@
              {
              if (tv == NULL)
              {
              - PyErr_SetVim(_("NULL reference passed"));
              + PyErr_SET_VIM("NULL reference passed");
              return NULL;
              }
              switch (tv->v_type)
              @@ -5362,7 +5363,7 @@
              Py_INCREF(Py_None);
              return Py_None;
              default:
              - PyErr_SetVim(_("internal error: invalid value type"));
              + PyErr_SET_VIM("internal error: invalid value type");
              return NULL;
              }
              }
              diff -r b9d4dfa09951 -r abcf5d9458ee src/if_python3.c
              --- a/src/if_python3.c Fri Jun 14 19:27:27 2013 +0400
              +++ b/src/if_python3.c Fri Jun 14 23:42:16 2013 +0400
              @@ -1169,7 +1169,7 @@
              }
              else
              {
              - PyErr_SetString(PyExc_TypeError, _("index must be int or slice"));
              + PyErr_SET_STRING(PyExc_TypeError, "index must be int or slice");
              return NULL;
              }
              }
              @@ -1203,7 +1203,7 @@
              }
              else
              {
              - PyErr_SetString(PyExc_TypeError, _("index must be int or slice"));
              + PyErr_SET_STRING(PyExc_TypeError, "index must be int or slice");
              return -1;
              }
              }
              @@ -1285,7 +1285,7 @@
              }
              else
              {
              - PyErr_SetString(PyExc_TypeError, _("index must be int or slice"));
              + PyErr_SET_STRING(PyExc_TypeError, "index must be int or slice");
              return NULL;
              }
              }
              @@ -1312,7 +1312,7 @@
              }
              else
              {
              - PyErr_SetString(PyExc_TypeError, _("index must be int or slice"));
              + PyErr_SET_STRING(PyExc_TypeError, "index must be int or slice");
              return -1;
              }
              }
              @@ -1491,7 +1491,7 @@
              }
              else
              {
              - PyErr_SetString(PyExc_TypeError, _("index must be int or slice"));
              + PyErr_SET_STRING(PyExc_TypeError, "index must be int or slice");
              return NULL;
              }
              }
              @@ -1515,7 +1515,7 @@
              }
              else
              {
              - PyErr_SetString(PyExc_TypeError, _("index must be int or slice"));
              + PyErr_SET_STRING(PyExc_TypeError, "index must be int or slice");
              return -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
              # HG changeset patch # User ZyX # Date 1371375798 -14400 # Sun Jun 16 13:43:18 2013 +0400 # Branch python-fixes # Node ID
              Message 6 of 25 , Jun 16, 2013
              • 0 Attachment
                # 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

                diff -r abcf5d9458ee -r 81c6385adb92 src/if_py_both.h
                --- a/src/if_py_both.h Fri Jun 14 23:42:16 2013 +0400
                +++ b/src/if_py_both.h Sun Jun 16 13:43:18 2013 +0400
                @@ -29,9 +29,25 @@
                #define PyErr_SET_STRING(exc, str) PyErr_SetString(exc, _(str))
                #define PyErr_SetVim(str) PyErr_SetString(VimError, str)
                #define PyErr_SET_VIM(str) PyErr_SET_STRING(VimError, str)
                +#define PyErr_FORMAT(exc, str, tail) PyErr_Format(exc, _(str), tail)
                +#define PyErr_VIM_FORMAT(str, tail) PyErr_FORMAT(VimError, str, tail)
                +
                +#define Py_TYPE_NAME(obj) (obj->ob_type->tp_name == NULL \
                + ? "(NULL)" \
                + : 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")
                +#define RAISE_KEY_ADD_FAIL(key) \
                + PyErr_VIM_FORMAT("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", \
                + Py_TYPE_NAME(idx));

                #define INVALID_BUFFER_VALUE ((buf_T *)(-1))
                #define INVALID_WINDOW_VALUE ((win_T *)(-1))
                @@ -122,7 +138,13 @@
                }
                else
                {
                - PyErr_SET_STRING(PyExc_TypeError, "object must be string");
                + PyErr_FORMAT(PyExc_TypeError,
                +#if PY_MAJOR_VERSION < 3
                + "expected str() or unicode() instance, but got %s"
                +#else
                + "expected bytes() or str() instance, but got %s"
                +#endif
                + , Py_TYPE_NAME(object));
                return NULL;
                }

                @@ -231,7 +253,7 @@
                return 0;
                }

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

                @@ -968,11 +990,19 @@
                {
                PyObject *fd, *pathname, *description;

                - if (!PyTuple_Check(find_module_result)
                - || PyTuple_GET_SIZE(find_module_result) != 3)
                - {
                - PyErr_SET_STRING(PyExc_TypeError,
                - "expected 3-tuple as imp.find_module() result");
                + if (!PyTuple_Check(find_module_result))
                + {
                + PyErr_FORMAT(PyExc_TypeError,
                + "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",
                + (int) PyTuple_GET_SIZE(find_module_result));
                return NULL;
                }

                @@ -1378,7 +1408,7 @@
                }
                else
                {
                - PyErr_SET_STRING(PyExc_AttributeError, "cannot set this attribute");
                + PyErr_FORMAT(PyExc_AttributeError, "cannot set attribute %s", name);
                return -1;
                }
                }
                @@ -1460,7 +1490,7 @@
                {
                if (dict->dv_lock)
                {
                - PyErr_SET_VIM("dict is locked");
                + RAISE_LOCKED_DICTIONARY;
                Py_DECREF(r);
                return NULL;
                }
                @@ -1563,7 +1593,7 @@

                if (dict->dv_lock)
                {
                - PyErr_SET_VIM("dict is locked");
                + RAISE_LOCKED_DICTIONARY;
                return -1;
                }

                @@ -1615,10 +1645,10 @@

                if (dict_add(dict, di) == FAIL)
                {
                - Py_XDECREF(todecref);
                vim_free(di);
                dictitem_free(di);
                - PyErr_SET_VIM("failed to add key to dictionary");
                + RAISE_KEY_ADD_FAIL(key);
                + Py_XDECREF(todecref);
                return -1;
                }
                }
                @@ -1726,7 +1756,7 @@

                if (dict->dv_lock)
                {
                - PyErr_SET_VIM("dict is locked");
                + RAISE_LOCKED_DICTIONARY;
                return NULL;
                }

                @@ -1782,8 +1812,10 @@
                {
                Py_DECREF(iterator);
                Py_DECREF(fast);
                - PyErr_SET_STRING(PyExc_ValueError,
                - "expected sequence element of size 2");
                + PyErr_FORMAT(PyExc_ValueError,
                + "expected sequence element of size 2, "
                + "but got sequence of size %d",
                + PySequence_Fast_GET_SIZE(fast));
                return NULL;
                }

                @@ -1824,9 +1856,9 @@

                if (dict_add(dict, di) == FAIL)
                {
                + RAISE_KEY_ADD_FAIL(di->di_key);
                Py_DECREF(iterator);
                dictitem_free(di);
                - PyErr_SET_VIM("failed to add key to dictionary");
                return NULL;
                }
                }
                @@ -2086,7 +2118,9 @@
                li = list_find(self->list, (long) index);
                if (li == NULL)
                {
                - PyErr_SET_VIM("internal error: failed to get vim list item");
                + /* No more suitable format specifications in python-2.3 */
                + PyErr_VIM_FORMAT("internal error: failed to get vim list item %d",
                + (int) index);
                return NULL;
                }
                return ConvertToPyObject(&li->li_tv);
                @@ -2199,7 +2233,7 @@

                if (l->lv_lock)
                {
                - PyErr_SET_VIM("list is locked");
                + RAISE_LOCKED_LIST;
                return -1;
                }
                if (index>length || (index==length && obj==NULL))
                @@ -2253,7 +2287,7 @@

                if (l->lv_lock)
                {
                - PyErr_SET_VIM("list is locked");
                + RAISE_LOCKED_LIST;
                return -1;
                }

                @@ -2266,7 +2300,7 @@
                li = list_find(l, (long) first);
                if (li == NULL)
                {
                - PyErr_SET_VIM("internal error: no vim list item");
                + PyErr_VIM_FORMAT("internal error: no vim list item %d", (int)first);
                return -1;
                }
                if (last > first)
                @@ -2316,7 +2350,7 @@

                if (l->lv_lock)
                {
                - PyErr_SET_VIM("list is locked");
                + RAISE_LOCKED_LIST;
                return NULL;
                }

                @@ -2376,7 +2410,7 @@
                }
                else
                {
                - PyErr_SET_STRING(PyExc_AttributeError, "cannot set this attribute");
                + PyErr_FORMAT(PyExc_AttributeError, "cannot set attribute %s", name);
                return -1;
                }
                }
                @@ -2411,8 +2445,8 @@
                {
                if (!translated_function_exists(name))
                {
                - PyErr_SET_STRING(PyExc_ValueError,
                - "unnamed function does not exist");
                + PyErr_FORMAT(PyExc_ValueError,
                + "unnamed function %s does not exist", name);
                return NULL;
                }
                self->name = vim_strsave(name);
                @@ -2423,7 +2457,7 @@
                vim_strchr(name, AUTOLOAD_CHAR) == NULL))
                == NULL)
                {
                - PyErr_SET_STRING(PyExc_ValueError, "function does not exist");
                + PyErr_FORMAT(PyExc_ValueError, "function %s does not exist", name);
                return NULL;
                }

                @@ -2516,7 +2550,7 @@
                else if (error != OK)
                {
                result = NULL;
                - PyErr_SET_VIM("failed to run function");
                + PyErr_VIM_FORMAT("failed to run function %s", (char *)name);
                }
                else
                result = ConvertToPyObject(&rettv);
                @@ -2771,14 +2805,16 @@
                {
                if (self->opt_type == SREQ_GLOBAL)
                {
                - PyErr_SET_STRING(PyExc_ValueError, "unable to unset global option");
                + PyErr_FORMAT(PyExc_ValueError,
                + "unable to unset global option %s", key);
                Py_XDECREF(todecref);
                return -1;
                }
                else if (!(flags & SOPT_GLOBAL))
                {
                - PyErr_SET_STRING(PyExc_ValueError, "unable to unset option "
                - "without global value");
                + PyErr_FORMAT(PyExc_ValueError,
                + "unable to unset option %s "
                + "which does not have global value", key);
                Py_XDECREF(todecref);
                return -1;
                }
                @@ -3195,7 +3231,7 @@

                if (strcmp(name, "buffer") == 0)
                {
                - PyErr_SET_STRING(PyExc_TypeError, "readonly attribute");
                + PyErr_SET_STRING(PyExc_TypeError, "readonly attribute: buffer");
                return -1;
                }
                else if (strcmp(name, "cursor") == 0)
                @@ -3558,9 +3594,9 @@
                VimTryStart();

                if (u_savedel((linenr_T)n, 1L) == FAIL)
                - PyErr_SET_VIM("cannot save undo information");
                + RAISE_UNDO_FAIL;
                else if (ml_delete((linenr_T)n, FALSE) == FAIL)
                - PyErr_SET_VIM("cannot delete line");
                + RAISE_LINE_FAIL("delete");
                else
                {
                if (buf == savebuf)
                @@ -3594,12 +3630,12 @@

                if (u_savesub((linenr_T)n) == FAIL)
                {
                - PyErr_SET_VIM("cannot save undo information");
                + RAISE_UNDO_FAIL;
                vim_free(save);
                }
                else if (ml_replace((linenr_T)n, (char_u *)save, FALSE) == FAIL)
                {
                - PyErr_SET_VIM("cannot replace line");
                + RAISE_LINE_FAIL("replace");
                vim_free(save);
                }
                else
                @@ -3654,14 +3690,14 @@
                switch_buffer(&savebuf, buf);

                if (u_savedel((linenr_T)lo, (long)n) == FAIL)
                - PyErr_SET_VIM("cannot save undo information");
                + RAISE_UNDO_FAIL;
                else
                {
                for (i = 0; i < n; ++i)
                {
                if (ml_delete((linenr_T)lo, FALSE) == FAIL)
                {
                - PyErr_SET_VIM("cannot delete line");
                + RAISE_LINE_FAIL("delete");
                break;
                }
                }
                @@ -3722,7 +3758,7 @@
                switch_buffer(&savebuf, buf);

                if (u_save((linenr_T)(lo-1), (linenr_T)hi) == FAIL)
                - PyErr_SET_VIM("cannot save undo information");
                + RAISE_UNDO_FAIL;

                /* If the size of the range is reducing (ie, new_len < old_len) we
                * need to delete some old_len. We do this at the start, by
                @@ -3733,7 +3769,7 @@
                for (i = 0; i < old_len - new_len; ++i)
                if (ml_delete((linenr_T)lo, FALSE) == FAIL)
                {
                - PyErr_SET_VIM("cannot delete line");
                + RAISE_LINE_FAIL("delete");
                break;
                }
                extra -= i;
                @@ -3749,7 +3785,7 @@
                if (ml_replace((linenr_T)(lo+i), (char_u *)array[i], FALSE)
                == FAIL)
                {
                - PyErr_SET_VIM("cannot replace line");
                + RAISE_LINE_FAIL("replace");
                break;
                }
                }
                @@ -3767,7 +3803,7 @@
                if (ml_append((linenr_T)(lo + i - 1),
                (char_u *)array[i], 0, FALSE) == FAIL)
                {
                - PyErr_SET_VIM("cannot insert line");
                + RAISE_LINE_FAIL("insert");
                break;
                }
                vim_free(array[i]);
                @@ -3844,9 +3880,9 @@
                switch_buffer(&savebuf, buf);

                if (u_save((linenr_T)n, (linenr_T)(n+1)) == FAIL)
                - PyErr_SET_VIM("cannot save undo information");
                + RAISE_UNDO_FAIL;
                else if (ml_append((linenr_T)n, (char_u *)str, 0, FALSE) == FAIL)
                - PyErr_SET_VIM("cannot insert line");
                + RAISE_LINE_FAIL("insert");
                else
                appended_lines_mark((linenr_T)n, 1L);

                @@ -3895,7 +3931,7 @@
                switch_buffer(&savebuf, buf);

                if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
                - PyErr_SET_VIM("cannot save undo information");
                + RAISE_UNDO_FAIL;
                else
                {
                for (i = 0; i < size; ++i)
                @@ -3903,7 +3939,7 @@
                if (ml_append((linenr_T)(n + i),
                (char_u *)array[i], 0, FALSE) == FAIL)
                {
                - PyErr_SET_VIM("cannot insert line");
                + RAISE_LINE_FAIL("insert");

                /* Free the rest of the lines */
                while (i < size)
                @@ -4668,7 +4704,9 @@

                if (value->ob_type != &BufferType)
                {
                - PyErr_SET_STRING(PyExc_TypeError, "expected vim.Buffer object");
                + PyErr_FORMAT(PyExc_TypeError,
                + "expected vim.Buffer object, but got %s",
                + Py_TYPE_NAME(value));
                return -1;
                }

                @@ -4681,7 +4719,7 @@
                {
                if (VimTryEnd())
                return -1;
                - PyErr_SET_VIM("failed to switch to given buffer");
                + PyErr_VIM_FORMAT("failed to switch to buffer %d", count);
                return -1;
                }

                @@ -4693,7 +4731,9 @@

                if (value->ob_type != &WindowType)
                {
                - PyErr_SET_STRING(PyExc_TypeError, "expected vim.Window object");
                + PyErr_FORMAT(PyExc_TypeError,
                + "expected vim.Window object, but got %s",
                + Py_TYPE_NAME(value));
                return -1;
                }

                @@ -4725,7 +4765,9 @@
                {
                if (value->ob_type != &TabPageType)
                {
                - PyErr_SET_STRING(PyExc_TypeError, "expected vim.TabPage object");
                + PyErr_FORMAT(PyExc_TypeError,
                + "expected vim.TabPage object, but got %s",
                + Py_TYPE_NAME(value));
                return -1;
                }

                @@ -5003,10 +5045,10 @@

                if (dict_add(dict, di) == FAIL)
                {
                + RAISE_KEY_ADD_FAIL(di->di_key);
                clear_tv(&di->di_tv);
                vim_free(di);
                dict_unref(dict);
                - PyErr_SET_VIM("failed to add key to dictionary");
                return -1;
                }
                }
                @@ -5105,10 +5147,10 @@

                if (dict_add(dict, di) == FAIL)
                {
                + RAISE_KEY_ADD_FAIL(di->di_key);
                Py_DECREF(iterator);
                dictitem_free(di);
                dict_unref(dict);
                - PyErr_SET_VIM("failed to add key to dictionary");
                return -1;
                }
                }
                @@ -5216,8 +5258,9 @@
                r = convert_dl(obj, tv, pymap_to_tv, lookup_dict);
                else
                {
                - PyErr_SET_STRING(PyExc_TypeError,
                - "unable to convert object to vim dictionary");
                + PyErr_FORMAT(PyExc_TypeError,
                + "unable to convert %s to vim dictionary",
                + Py_TYPE_NAME(obj));
                r = -1;
                }
                Py_DECREF(lookup_dict);
                @@ -5326,8 +5369,9 @@
                return convert_dl(obj, tv, pymap_to_tv, lookup_dict);
                else
                {
                - PyErr_SET_STRING(PyExc_TypeError,
                - "unable to convert to vim structure");
                + PyErr_FORMAT(PyExc_TypeError,
                + "unable to convert %s to vim structure",
                + Py_TYPE_NAME(obj));
                return -1;
                }
                return 0;
                @@ -5338,7 +5382,7 @@
                {
                if (tv == NULL)
                {
                - PyErr_SET_VIM("NULL reference passed");
                + PyErr_SET_VIM("internal error: NULL reference passed");
                return NULL;
                }
                switch (tv->v_type)
                diff -r abcf5d9458ee -r 81c6385adb92 src/if_python.c
                --- a/src/if_python.c Fri Jun 14 23:42:16 2013 +0400
                +++ b/src/if_python.c Sun Jun 16 13:43:18 2013 +0400
                @@ -160,6 +160,7 @@
                # define PyErr_BadArgument dll_PyErr_BadArgument
                # define PyErr_NewException dll_PyErr_NewException
                # define PyErr_Clear dll_PyErr_Clear
                +# define PyErr_Format dll_PyErr_Format
                # define PyErr_PrintEx dll_PyErr_PrintEx
                # define PyErr_NoMemory dll_PyErr_NoMemory
                # define PyErr_Occurred dll_PyErr_Occurred
                @@ -301,6 +302,7 @@
                static int(*dll_PyErr_BadArgument)(void);
                static PyObject *(*dll_PyErr_NewException)(char *, PyObject *, PyObject *);
                static void(*dll_PyErr_Clear)(void);
                +static PyObject*(*dll_PyErr_Format)(PyObject *, const char *, ...);
                static void(*dll_PyErr_PrintEx)(int);
                static PyObject*(*dll_PyErr_NoMemory)(void);
                static PyObject*(*dll_PyErr_Occurred)(void);
                @@ -473,6 +475,7 @@
                {"PyErr_BadArgument", (PYTHON_PROC*)&dll_PyErr_BadArgument},
                {"PyErr_NewException", (PYTHON_PROC*)&dll_PyErr_NewException},
                {"PyErr_Clear", (PYTHON_PROC*)&dll_PyErr_Clear},
                + {"PyErr_Format", (PYTHON_PROC*)&dll_PyErr_Format},
                {"PyErr_PrintEx", (PYTHON_PROC*)&dll_PyErr_PrintEx},
                {"PyErr_NoMemory", (PYTHON_PROC*)&dll_PyErr_NoMemory},
                {"PyErr_Occurred", (PYTHON_PROC*)&dll_PyErr_Occurred},
                diff -r abcf5d9458ee -r 81c6385adb92 src/if_python3.c
                --- a/src/if_python3.c Fri Jun 14 23:42:16 2013 +0400
                +++ b/src/if_python3.c Sun Jun 16 13:43:18 2013 +0400
                @@ -122,6 +122,7 @@
                # define PyDict_SetItemString py3_PyDict_SetItemString
                # define PyErr_BadArgument py3_PyErr_BadArgument
                # define PyErr_Clear py3_PyErr_Clear
                +# define PyErr_Format py3_PyErr_Format
                # define PyErr_PrintEx py3_PyErr_PrintEx
                # define PyErr_NoMemory py3_PyErr_NoMemory
                # define PyErr_Occurred py3_PyErr_Occurred
                @@ -337,6 +338,7 @@
                static void* (*py3_PyMem_Malloc)(size_t);
                static int (*py3_Py_IsInitialized)(void);
                static void (*py3_PyErr_Clear)(void);
                +static PyObject* (*py3_PyErr_Format)(PyObject *, const char *, ...);
                static void (*py3_PyErr_PrintEx)(int);
                static PyObject*(*py3__PyObject_Init)(PyObject *, PyTypeObject *);
                static iternextfunc py3__PyObject_NextNotImplemented;
                @@ -485,6 +487,7 @@
                {"_Py_FalseStruct", (PYTHON_PROC*)&py3__Py_FalseStruct},
                {"_Py_TrueStruct", (PYTHON_PROC*)&py3__Py_TrueStruct},
                {"PyErr_Clear", (PYTHON_PROC*)&py3_PyErr_Clear},
                + {"PyErr_Format", (PYTHON_PROC*)&py3_PyErr_Format},
                {"PyErr_PrintEx", (PYTHON_PROC*)&py3_PyErr_PrintEx},
                {"PyObject_Init", (PYTHON_PROC*)&py3__PyObject_Init},
                {"PyModule_AddObject", (PYTHON_PROC*)&py3_PyModule_AddObject},
                @@ -1169,7 +1172,7 @@
                }
                else
                {
                - PyErr_SET_STRING(PyExc_TypeError, "index must be int or slice");
                + RAISE_INVALID_INDEX_TYPE(idx);
                return NULL;
                }
                }
                @@ -1203,7 +1206,7 @@
                }
                else
                {
                - PyErr_SET_STRING(PyExc_TypeError, "index must be int or slice");
                + RAISE_INVALID_INDEX_TYPE(idx);
                return -1;
                }
                }
                @@ -1285,7 +1288,7 @@
                }
                else
                {
                - PyErr_SET_STRING(PyExc_TypeError, "index must be int or slice");
                + RAISE_INVALID_INDEX_TYPE(idx);
                return NULL;
                }
                }
                @@ -1312,7 +1315,7 @@
                }
                else
                {
                - PyErr_SET_STRING(PyExc_TypeError, "index must be int or slice");
                + RAISE_INVALID_INDEX_TYPE(idx);
                return -1;
                }
                }
                @@ -1491,7 +1494,7 @@
                }
                else
                {
                - PyErr_SET_STRING(PyExc_TypeError, "index must be int or slice");
                + RAISE_INVALID_INDEX_TYPE(idx);
                return NULL;
                }
                }
                @@ -1515,7 +1518,7 @@
                }
                else
                {
                - PyErr_SET_STRING(PyExc_TypeError, "index must be int or slice");
                + RAISE_INVALID_INDEX_TYPE(idx);
                return -1;
                }
                }
                diff -r abcf5d9458ee -r 81c6385adb92 src/testdir/test86.ok
                --- a/src/testdir/test86.ok Fri Jun 14 23:42:16 2013 +0400
                +++ b/src/testdir/test86.ok Sun Jun 16 13:43:18 2013 +0400
                @@ -439,106 +439,106 @@
                >> OutputSetattr
                del sys.stdout.softspace:AttributeError:("can't delete OutputObject attributes",)
                sys.stdout.softspace = []:TypeError:('softspace must be an integer',)
                -sys.stdout.attr = None:AttributeError:('invalid attribute',)
                +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',)
                > VimCommand
                -vim.command(1):TypeError:('object must be string',)
                +vim.command(1):TypeError:('expected str() or unicode() instance, but got int',)
                > VimToPython
                > VimEval
                -vim.eval(1):TypeError:('object must be string',)
                +vim.eval(1):TypeError:('expected str() or unicode() instance, but got int',)
                > VimEvalPy
                -vim.bindeval(1):TypeError:('object must be string',)
                +vim.bindeval(1):TypeError:('expected str() or unicode() instance, but got int',)
                > VimStrwidth
                -vim.strwidth(1):TypeError:('object must be string',)
                +vim.strwidth(1):TypeError:('expected str() or unicode() instance, but got int',)
                > Dictionary
                >> DictionaryConstructor
                -vim.Dictionary("abc"):ValueError:('expected sequence element of size 2',)
                +vim.Dictionary("abc"):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:()
                vim.vvars.locked = False:TypeError:('cannot modify fixed dictionary',)
                -d.scope = True:AttributeError:('cannot set this attribute',)
                -d.xxx = True:AttributeError:('cannot set this attribute',)
                +d.scope = True:AttributeError:('cannot set attribute scope',)
                +d.xxx = True:AttributeError:('cannot set attribute xxx',)
                >> _DictionaryItem
                d.get("a", 2, 3):TypeError:('function takes at most 2 arguments (3 given)',)
                >>> Testing StringToChars using d.get(%s)
                -d.get(1):TypeError:('object must be string',)
                +d.get(1):TypeError:('expected str() or unicode() instance, but got int',)
                d.get(u"\0"):TypeError:('expected string without null bytes',)
                d.get("\0"):TypeError:('expected string without null bytes',)
                <<< Finished
                d.pop("a"):KeyError:('a',)
                -dl.pop("a"):error:('dict is locked',)
                +dl.pop("a"):error:('dictionary is locked',)
                >> DictionaryIterNext
                for i in ned: ned["a"] = 1:RuntimeError:('hashtab changed during iteration',)
                >> DictionaryAssItem
                -dl["b"] = 1:error:('dict is locked',)
                +dl["b"] = 1:error:('dictionary is locked',)
                >>> Testing StringToChars using d[%s] = 1
                -d[1] = 1:TypeError:('object must be string',)
                +d[1] = 1:TypeError:('expected str() or unicode() instance, but got int',)
                d[u"\0"] = 1:TypeError:('expected string without null bytes',)
                d["\0"] = 1:TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing StringToChars using d["a"] = {%s : 1}
                -d["a"] = {1 : 1}:TypeError:('object must be string',)
                +d["a"] = {1 : 1}:TypeError:('expected str() or unicode() instance, but got int',)
                d["a"] = {u"\0" : 1}:TypeError:('expected string without null bytes',)
                d["a"] = {"\0" : 1}:TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing StringToChars using d["a"] = {"abc" : {%s : 1}}
                -d["a"] = {"abc" : {1 : 1}}:TypeError:('object must be string',)
                +d["a"] = {"abc" : {1 : 1}}:TypeError:('expected str() or unicode() instance, but got int',)
                d["a"] = {"abc" : {u"\0" : 1}}:TypeError:('expected string without null bytes',)
                d["a"] = {"abc" : {"\0" : 1}}:TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing StringToChars using d["a"] = {"abc" : Mapping({%s : 1})}
                -d["a"] = {"abc" : Mapping({1 : 1})}:TypeError:('object must be string',)
                +d["a"] = {"abc" : Mapping({1 : 1})}:TypeError:('expected str() or unicode() instance, but got int',)
                d["a"] = {"abc" : Mapping({u"\0" : 1})}:TypeError:('expected string without null bytes',)
                d["a"] = {"abc" : Mapping({"\0" : 1})}:TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing *Iter* using d["a"] = {"abc" : %s}
                -d["a"] = {"abc" : FailingIter()}:TypeError:('unable to convert to vim structure',)
                +d["a"] = {"abc" : FailingIter()}:TypeError:('unable to convert FailingIter to vim structure',)
                d["a"] = {"abc" : FailingIterNext()}:NotImplementedError:()
                <<< Finished
                >>> Testing ConvertFromPyObject using d["a"] = {"abc" : %s}
                -d["a"] = {"abc" : None}:TypeError:('unable to convert to vim structure',)
                +d["a"] = {"abc" : None}:TypeError:('unable to convert NoneType to vim structure',)
                d["a"] = {"abc" : {"": 1}}:ValueError:('empty keys are not allowed',)
                d["a"] = {"abc" : {u"": 1}}:ValueError:('empty keys are not allowed',)
                d["a"] = {"abc" : FailingMapping()}:NotImplementedError:()
                d["a"] = {"abc" : FailingMappingKey()}:NotImplementedError:()
                <<< Finished
                >>> Testing StringToChars using d["a"] = Mapping({%s : 1})
                -d["a"] = Mapping({1 : 1}):TypeError:('object must be string',)
                +d["a"] = Mapping({1 : 1}):TypeError:('expected str() or unicode() instance, but got int',)
                d["a"] = Mapping({u"\0" : 1}):TypeError:('expected string without null bytes',)
                d["a"] = Mapping({"\0" : 1}):TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing StringToChars using d["a"] = Mapping({"abc" : {%s : 1}})
                -d["a"] = Mapping({"abc" : {1 : 1}}):TypeError:('object must be string',)
                +d["a"] = Mapping({"abc" : {1 : 1}}):TypeError:('expected str() or unicode() instance, but got int',)
                d["a"] = Mapping({"abc" : {u"\0" : 1}}):TypeError:('expected string without null bytes',)
                d["a"] = Mapping({"abc" : {"\0" : 1}}):TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing StringToChars using d["a"] = Mapping({"abc" : Mapping({%s : 1})})
                -d["a"] = Mapping({"abc" : Mapping({1 : 1})}):TypeError:('object must be string',)
                +d["a"] = Mapping({"abc" : Mapping({1 : 1})}):TypeError:('expected str() or unicode() instance, but got int',)
                d["a"] = Mapping({"abc" : Mapping({u"\0" : 1})}):TypeError:('expected string without null bytes',)
                d["a"] = Mapping({"abc" : Mapping({"\0" : 1})}):TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing *Iter* using d["a"] = Mapping({"abc" : %s})
                -d["a"] = Mapping({"abc" : FailingIter()}):TypeError:('unable to convert to vim structure',)
                +d["a"] = Mapping({"abc" : FailingIter()}):TypeError:('unable to convert FailingIter to vim structure',)
                d["a"] = Mapping({"abc" : FailingIterNext()}):NotImplementedError:()
                <<< Finished
                >>> Testing ConvertFromPyObject using d["a"] = Mapping({"abc" : %s})
                -d["a"] = Mapping({"abc" : None}):TypeError:('unable to convert to vim structure',)
                +d["a"] = Mapping({"abc" : None}):TypeError:('unable to convert NoneType to vim structure',)
                d["a"] = Mapping({"abc" : {"": 1}}):ValueError:('empty keys are not allowed',)
                d["a"] = Mapping({"abc" : {u"": 1}}):ValueError:('empty keys are not allowed',)
                d["a"] = Mapping({"abc" : FailingMapping()}):NotImplementedError:()
                d["a"] = Mapping({"abc" : FailingMappingKey()}):NotImplementedError:()
                <<< Finished
                >>> Testing *Iter* using d["a"] = %s
                -d["a"] = FailingIter():TypeError:('unable to convert to vim structure',)
                +d["a"] = FailingIter():TypeError:('unable to convert FailingIter to vim structure',)
                d["a"] = FailingIterNext():NotImplementedError:()
                <<< Finished
                >>> Testing ConvertFromPyObject using d["a"] = %s
                -d["a"] = None:TypeError:('unable to convert to vim structure',)
                +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:()
                @@ -550,52 +550,52 @@
                d.update(FailingMapping()):NotImplementedError:()
                d.update([FailingIterNext()]):NotImplementedError:()
                >>> Testing StringToChars using d.update({%s : 1})
                -d.update({1 : 1}):TypeError:('object must be string',)
                +d.update({1 : 1}):TypeError:('expected str() or unicode() instance, but got int',)
                d.update({u"\0" : 1}):TypeError:('expected string without null bytes',)
                d.update({"\0" : 1}):TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing StringToChars using d.update({"abc" : {%s : 1}})
                -d.update({"abc" : {1 : 1}}):TypeError:('object must be string',)
                +d.update({"abc" : {1 : 1}}):TypeError:('expected str() or unicode() instance, but got int',)
                d.update({"abc" : {u"\0" : 1}}):TypeError:('expected string without null bytes',)
                d.update({"abc" : {"\0" : 1}}):TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing StringToChars using d.update({"abc" : Mapping({%s : 1})})
                -d.update({"abc" : Mapping({1 : 1})}):TypeError:('object must be string',)
                +d.update({"abc" : Mapping({1 : 1})}):TypeError:('expected str() or unicode() instance, but got int',)
                d.update({"abc" : Mapping({u"\0" : 1})}):TypeError:('expected string without null bytes',)
                d.update({"abc" : Mapping({"\0" : 1})}):TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing *Iter* using d.update({"abc" : %s})
                -d.update({"abc" : FailingIter()}):TypeError:('unable to convert to vim structure',)
                +d.update({"abc" : FailingIter()}):TypeError:('unable to convert FailingIter to vim structure',)
                d.update({"abc" : FailingIterNext()}):NotImplementedError:()
                <<< Finished
                >>> Testing ConvertFromPyObject using d.update({"abc" : %s})
                -d.update({"abc" : None}):TypeError:('unable to convert to vim structure',)
                +d.update({"abc" : None}):TypeError:('unable to convert NoneType to vim structure',)
                d.update({"abc" : {"": 1}}):ValueError:('empty keys are not allowed',)
                d.update({"abc" : {u"": 1}}):ValueError:('empty keys are not allowed',)
                d.update({"abc" : FailingMapping()}):NotImplementedError:()
                d.update({"abc" : FailingMappingKey()}):NotImplementedError:()
                <<< Finished
                >>> Testing StringToChars using d.update(Mapping({%s : 1}))
                -d.update(Mapping({1 : 1})):TypeError:('object must be string',)
                +d.update(Mapping({1 : 1})):TypeError:('expected str() or unicode() instance, but got int',)
                d.update(Mapping({u"\0" : 1})):TypeError:('expected string without null bytes',)
                d.update(Mapping({"\0" : 1})):TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing StringToChars using d.update(Mapping({"abc" : {%s : 1}}))
                -d.update(Mapping({"abc" : {1 : 1}})):TypeError:('object must be string',)
                +d.update(Mapping({"abc" : {1 : 1}})):TypeError:('expected str() or unicode() instance, but got int',)
                d.update(Mapping({"abc" : {u"\0" : 1}})):TypeError:('expected string without null bytes',)
                d.update(Mapping({"abc" : {"\0" : 1}})):TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing StringToChars using d.update(Mapping({"abc" : Mapping({%s : 1})}))
                -d.update(Mapping({"abc" : Mapping({1 : 1})})):TypeError:('object must be string',)
                +d.update(Mapping({"abc" : Mapping({1 : 1})})):TypeError:('expected str() or unicode() instance, but got int',)
                d.update(Mapping({"abc" : Mapping({u"\0" : 1})})):TypeError:('expected string without null bytes',)
                d.update(Mapping({"abc" : Mapping({"\0" : 1})})):TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing *Iter* using d.update(Mapping({"abc" : %s}))
                -d.update(Mapping({"abc" : FailingIter()})):TypeError:('unable to convert to vim structure',)
                +d.update(Mapping({"abc" : FailingIter()})):TypeError:('unable to convert FailingIter to vim structure',)
                d.update(Mapping({"abc" : FailingIterNext()})):NotImplementedError:()
                <<< Finished
                >>> Testing ConvertFromPyObject using d.update(Mapping({"abc" : %s}))
                -d.update(Mapping({"abc" : None})):TypeError:('unable to convert to vim structure',)
                +d.update(Mapping({"abc" : None})):TypeError:('unable to convert NoneType to vim structure',)
                d.update(Mapping({"abc" : {"": 1}})):ValueError:('empty keys are not allowed',)
                d.update(Mapping({"abc" : {u"": 1}})):ValueError:('empty keys are not allowed',)
                d.update(Mapping({"abc" : FailingMapping()})):NotImplementedError:()
                @@ -613,68 +613,68 @@
                d.update(FailingMappingKey()):NotImplementedError:()
                <<< Finished
                >>> Testing StringToChars using d.update(((%s, 0),))
                -d.update(((1, 0),)):TypeError:('object must be string',)
                +d.update(((1, 0),)):TypeError:('expected str() or unicode() instance, but got int',)
                d.update(((u"\0", 0),)):TypeError:('expected string without null bytes',)
                d.update((("\0", 0),)):TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing StringToChars using d.update((("a", {%s : 1}),))
                -d.update((("a", {1 : 1}),)):TypeError:('object must be string',)
                +d.update((("a", {1 : 1}),)):TypeError:('expected str() or unicode() instance, but got int',)
                d.update((("a", {u"\0" : 1}),)):TypeError:('expected string without null bytes',)
                d.update((("a", {"\0" : 1}),)):TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing StringToChars using d.update((("a", {"abc" : {%s : 1}}),))
                -d.update((("a", {"abc" : {1 : 1}}),)):TypeError:('object must be string',)
                +d.update((("a", {"abc" : {1 : 1}}),)):TypeError:('expected str() or unicode() instance, but got int',)
                d.update((("a", {"abc" : {u"\0" : 1}}),)):TypeError:('expected string without null bytes',)
                d.update((("a", {"abc" : {"\0" : 1}}),)):TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing StringToChars using d.update((("a", {"abc" : Mapping({%s : 1})}),))
                -d.update((("a", {"abc" : Mapping({1 : 1})}),)):TypeError:('object must be string',)
                +d.update((("a", {"abc" : Mapping({1 : 1})}),)):TypeError:('expected str() or unicode() instance, but got int',)
                d.update((("a", {"abc" : Mapping({u"\0" : 1})}),)):TypeError:('expected string without null bytes',)
                d.update((("a", {"abc" : Mapping({"\0" : 1})}),)):TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing *Iter* using d.update((("a", {"abc" : %s}),))
                -d.update((("a", {"abc" : FailingIter()}),)):TypeError:('unable to convert to vim structure',)
                +d.update((("a", {"abc" : FailingIter()}),)):TypeError:('unable to convert FailingIter to vim structure',)
                d.update((("a", {"abc" : FailingIterNext()}),)):NotImplementedError:()
                <<< Finished
                >>> Testing ConvertFromPyObject using d.update((("a", {"abc" : %s}),))
                -d.update((("a", {"abc" : None}),)):TypeError:('unable to convert to vim structure',)
                +d.update((("a", {"abc" : None}),)):TypeError:('unable to convert NoneType to vim structure',)
                d.update((("a", {"abc" : {"": 1}}),)):ValueError:('empty keys are not allowed',)
                d.update((("a", {"abc" : {u"": 1}}),)):ValueError:('empty keys are not allowed',)
                d.update((("a", {"abc" : FailingMapping()}),)):NotImplementedError:()
                d.update((("a", {"abc" : FailingMappingKey()}),)):NotImplementedError:()
                <<< Finished
                >>> Testing StringToChars using d.update((("a", Mapping({%s : 1})),))
                -d.update((("a", Mapping({1 : 1})),)):TypeError:('object must be string',)
                +d.update((("a", Mapping({1 : 1})),)):TypeError:('expected str() or unicode() instance, but got int',)
                d.update((("a", Mapping({u"\0" : 1})),)):TypeError:('expected string without null bytes',)
                d.update((("a", Mapping({"\0" : 1})),)):TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing StringToChars using d.update((("a", Mapping({"abc" : {%s : 1}})),))
                -d.update((("a", Mapping({"abc" : {1 : 1}})),)):TypeError:('object must be string',)
                +d.update((("a", Mapping({"abc" : {1 : 1}})),)):TypeError:('expected str() or unicode() instance, but got int',)
                d.update((("a", Mapping({"abc" : {u"\0" : 1}})),)):TypeError:('expected string without null bytes',)
                d.update((("a", Mapping({"abc" : {"\0" : 1}})),)):TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing StringToChars using d.update((("a", Mapping({"abc" : Mapping({%s : 1})})),))
                -d.update((("a", Mapping({"abc" : Mapping({1 : 1})})),)):TypeError:('object must be string',)
                +d.update((("a", Mapping({"abc" : Mapping({1 : 1})})),)):TypeError:('expected str() or unicode() instance, but got int',)
                d.update((("a", Mapping({"abc" : Mapping({u"\0" : 1})})),)):TypeError:('expected string without null bytes',)
                d.update((("a", Mapping({"abc" : Mapping({"\0" : 1})})),)):TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing *Iter* using d.update((("a", Mapping({"abc" : %s})),))
                -d.update((("a", Mapping({"abc" : FailingIter()})),)):TypeError:('unable to convert to vim structure',)
                +d.update((("a", Mapping({"abc" : FailingIter()})),)):TypeError:('unable to convert FailingIter to vim structure',)
                d.update((("a", Mapping({"abc" : FailingIterNext()})),)):NotImplementedError:()
                <<< Finished
                >>> Testing ConvertFromPyObject using d.update((("a", Mapping({"abc" : %s})),))
                -d.update((("a", Mapping({"abc" : None})),)):TypeError:('unable to convert to vim structure',)
                +d.update((("a", Mapping({"abc" : None})),)):TypeError:('unable to convert NoneType to vim structure',)
                d.update((("a", Mapping({"abc" : {"": 1}})),)):ValueError:('empty keys are not allowed',)
                d.update((("a", Mapping({"abc" : {u"": 1}})),)):ValueError:('empty keys are not allowed',)
                d.update((("a", Mapping({"abc" : FailingMapping()})),)):NotImplementedError:()
                d.update((("a", Mapping({"abc" : FailingMappingKey()})),)):NotImplementedError:()
                <<< Finished
                >>> Testing *Iter* using d.update((("a", %s),))
                -d.update((("a", FailingIter()),)):TypeError:('unable to convert to vim structure',)
                +d.update((("a", FailingIter()),)):TypeError:('unable to convert FailingIter to vim structure',)
                d.update((("a", FailingIterNext()),)):NotImplementedError:()
                <<< Finished
                >>> Testing ConvertFromPyObject using d.update((("a", %s),))
                -d.update((("a", None),)):TypeError:('unable to convert to vim structure',)
                +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:()
                @@ -689,63 +689,63 @@
                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 StringToChars using vim.List([{%s : 1}])
                -vim.List([{1 : 1}]):TypeError:('object must be string',)
                +vim.List([{1 : 1}]):TypeError:('expected str() or unicode() instance, but got int',)
                vim.List([{u"\0" : 1}]):TypeError:('expected string without null bytes',)
                vim.List([{"\0" : 1}]):TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing StringToChars using vim.List([{"abc" : {%s : 1}}])
                -vim.List([{"abc" : {1 : 1}}]):TypeError:('object must be string',)
                +vim.List([{"abc" : {1 : 1}}]):TypeError:('expected str() or unicode() instance, but got int',)
                vim.List([{"abc" : {u"\0" : 1}}]):TypeError:('expected string without null bytes',)
                vim.List([{"abc" : {"\0" : 1}}]):TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing StringToChars using vim.List([{"abc" : Mapping({%s : 1})}])
                -vim.List([{"abc" : Mapping({1 : 1})}]):TypeError:('object must be string',)
                +vim.List([{"abc" : Mapping({1 : 1})}]):TypeError:('expected str() or unicode() instance, but got int',)
                vim.List([{"abc" : Mapping({u"\0" : 1})}]):TypeError:('expected string without null bytes',)
                vim.List([{"abc" : Mapping({"\0" : 1})}]):TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing *Iter* using vim.List([{"abc" : %s}])
                -vim.List([{"abc" : FailingIter()}]):TypeError:('unable to convert to vim structure',)
                +vim.List([{"abc" : FailingIter()}]):TypeError:('unable to convert FailingIter to vim structure',)
                vim.List([{"abc" : FailingIterNext()}]):NotImplementedError:()
                <<< Finished
                >>> Testing ConvertFromPyObject using vim.List([{"abc" : %s}])
                -vim.List([{"abc" : None}]):TypeError:('unable to convert to vim structure',)
                +vim.List([{"abc" : None}]):TypeError:('unable to convert NoneType to vim structure',)
                vim.List([{"abc" : {"": 1}}]):ValueError:('empty keys are not allowed',)
                vim.List([{"abc" : {u"": 1}}]):ValueError:('empty keys are not allowed',)
                vim.List([{"abc" : FailingMapping()}]):NotImplementedError:()
                vim.List([{"abc" : FailingMappingKey()}]):NotImplementedError:()
                <<< Finished
                >>> Testing StringToChars using vim.List([Mapping({%s : 1})])
                -vim.List([Mapping({1 : 1})]):TypeError:('object must be string',)
                +vim.List([Mapping({1 : 1})]):TypeError:('expected str() or unicode() instance, but got int',)
                vim.List([Mapping({u"\0" : 1})]):TypeError:('expected string without null bytes',)
                vim.List([Mapping({"\0" : 1})]):TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing StringToChars using vim.List([Mapping({"abc" : {%s : 1}})])
                -vim.List([Mapping({"abc" : {1 : 1}})]):TypeError:('object must be string',)
                +vim.List([Mapping({"abc" : {1 : 1}})]):TypeError:('expected str() or unicode() instance, but got int',)
                vim.List([Mapping({"abc" : {u"\0" : 1}})]):TypeError:('expected string without null bytes',)
                vim.List([Mapping({"abc" : {"\0" : 1}})]):TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing StringToChars using vim.List([Mapping({"abc" : Mapping({%s : 1})})])
                -vim.List([Mapping({"abc" : Mapping({1 : 1})})]):TypeError:('object must be string',)
                +vim.List([Mapping({"abc" : Mapping({1 : 1})})]):TypeError:('expected str() or unicode() instance, but got int',)
                vim.List([Mapping({"abc" : Mapping({u"\0" : 1})})]):TypeError:('expected string without null bytes',)
                vim.List([Mapping({"abc" : Mapping({"\0" : 1})})]):TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing *Iter* using vim.List([Mapping({"abc" : %s})])
                -vim.List([Mapping({"abc" : FailingIter()})]):TypeError:('unable to convert to vim structure',)
                +vim.List([Mapping({"abc" : FailingIter()})]):TypeError:('unable to convert FailingIter to vim structure',)
                vim.List([Mapping({"abc" : FailingIterNext()})]):NotImplementedError:()
                <<< Finished
                >>> Testing ConvertFromPyObject using vim.List([Mapping({"abc" : %s})])
                -vim.List([Mapping({"abc" : None})]):TypeError:('unable to convert to vim structure',)
                +vim.List([Mapping({"abc" : None})]):TypeError:('unable to convert NoneType to vim structure',)
                vim.List([Mapping({"abc" : {"": 1}})]):ValueError:('empty keys are not allowed',)
                vim.List([Mapping({"abc" : {u"": 1}})]):ValueError:('empty keys are not allowed',)
                vim.List([Mapping({"abc" : FailingMapping()})]):NotImplementedError:()
                vim.List([Mapping({"abc" : FailingMappingKey()})]):NotImplementedError:()
                <<< Finished
                >>> Testing *Iter* using vim.List([%s])
                -vim.List([FailingIter()]):TypeError:('unable to convert to vim structure',)
                +vim.List([FailingIter()]):TypeError:('unable to convert FailingIter to vim structure',)
                vim.List([FailingIterNext()]):NotImplementedError:()
                <<< Finished
                >>> Testing ConvertFromPyObject using vim.List([%s])
                -vim.List([None]):TypeError:('unable to convert to vim structure',)
                +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:()
                @@ -759,63 +759,63 @@
                >> ListAssSlice
                ll[1:100] = "abc":error:('list is locked',)
                >>> Testing StringToChars using l[:] = [{%s : 1}]
                -l[:] = [{1 : 1}]:TypeError:('object must be string',)
                +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[:] = [{"abc" : {%s : 1}}]
                -l[:] = [{"abc" : {1 : 1}}]:TypeError:('object must be string',)
                +l[:] = [{"abc" : {1 : 1}}]:TypeError:('expected str() or unicode() instance, but got int',)
                l[:] = [{"abc" : {u"\0" : 1}}]:TypeError:('expected string without null bytes',)
                l[:] = [{"abc" : {"\0" : 1}}]:TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing StringToChars using l[:] = [{"abc" : Mapping({%s : 1})}]
                -l[:] = [{"abc" : Mapping({1 : 1})}]:TypeError:('object must be string',)
                +l[:] = [{"abc" : Mapping({1 : 1})}]:TypeError:('expected str() or unicode() instance, but got int',)
                l[:] = [{"abc" : Mapping({u"\0" : 1})}]:TypeError:('expected string without null bytes',)
                l[:] = [{"abc" : Mapping({"\0" : 1})}]:TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing *Iter* using l[:] = [{"abc" : %s}]
                -l[:] = [{"abc" : FailingIter()}]:TypeError:('unable to convert to vim structure',)
                +l[:] = [{"abc" : FailingIter()}]:TypeError:('unable to convert FailingIter to vim structure',)
                l[:] = [{"abc" : FailingIterNext()}]:NotImplementedError:()
                <<< Finished
                >>> Testing ConvertFromPyObject using l[:] = [{"abc" : %s}]
                -l[:] = [{"abc" : None}]:TypeError:('unable to convert to vim structure',)
                +l[:] = [{"abc" : None}]:TypeError:('unable to convert NoneType to vim structure',)
                l[:] = [{"abc" : {"": 1}}]:ValueError:('empty keys are not allowed',)
                l[:] = [{"abc" : {u"": 1}}]:ValueError:('empty keys are not allowed',)
                l[:] = [{"abc" : FailingMapping()}]:NotImplementedError:()
                l[:] = [{"abc" : FailingMappingKey()}]:NotImplementedError:()
                <<< Finished
                >>> Testing StringToChars using l[:] = [Mapping({%s : 1})]
                -l[:] = [Mapping({1 : 1})]:TypeError:('object must be string',)
                +l[:] = [Mapping({1 : 1})]:TypeError:('expected str() or unicode() instance, but got int',)
                l[:] = [Mapping({u"\0" : 1})]:TypeError:('expected string without null bytes',)
                l[:] = [Mapping({"\0" : 1})]:TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing StringToChars using l[:] = [Mapping({"abc" : {%s : 1}})]
                -l[:] = [Mapping({"abc" : {1 : 1}})]:TypeError:('object must be string',)
                +l[:] = [Mapping({"abc" : {1 : 1}})]:TypeError:('expected str() or unicode() instance, but got int',)
                l[:] = [Mapping({"abc" : {u"\0" : 1}})]:TypeError:('expected string without null bytes',)
                l[:] = [Mapping({"abc" : {"\0" : 1}})]:TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing StringToChars using l[:] = [Mapping({"abc" : Mapping({%s : 1})})]
                -l[:] = [Mapping({"abc" : Mapping({1 : 1})})]:TypeError:('object must be string',)
                +l[:] = [Mapping({"abc" : Mapping({1 : 1})})]:TypeError:('expected str() or unicode() instance, but got int',)
                l[:] = [Mapping({"abc" : Mapping({u"\0" : 1})})]:TypeError:('expected string without null bytes',)
                l[:] = [Mapping({"abc" : Mapping({"\0" : 1})})]:TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing *Iter* using l[:] = [Mapping({"abc" : %s})]
                -l[:] = [Mapping({"abc" : FailingIter()})]:TypeError:('unable to convert to vim structure',)
                +l[:] = [Mapping({"abc" : FailingIter()})]:TypeError:('unable to convert FailingIter to vim structure',)
                l[:] = [Mapping({"abc" : FailingIterNext()})]:NotImplementedError:()
                <<< Finished
                >>> Testing ConvertFromPyObject using l[:] = [Mapping({"abc" : %s})]
                -l[:] = [Mapping({"abc" : None})]:TypeError:('unable to convert to vim structure',)
                +l[:] = [Mapping({"abc" : None})]:TypeError:('unable to convert NoneType to vim structure',)
                l[:] = [Mapping({"abc" : {"": 1}})]:ValueError:('empty keys are not allowed',)
                l[:] = [Mapping({"abc" : {u"": 1}})]:ValueError:('empty keys are not allowed',)
                l[:] = [Mapping({"abc" : FailingMapping()})]:NotImplementedError:()
                l[:] = [Mapping({"abc" : FailingMappingKey()})]:NotImplementedError:()
                <<< Finished
                >>> Testing *Iter* using l[:] = [%s]
                -l[:] = [FailingIter()]:TypeError:('unable to convert to vim structure',)
                +l[:] = [FailingIter()]:TypeError:('unable to convert FailingIter to vim structure',)
                l[:] = [FailingIterNext()]:NotImplementedError:()
                <<< Finished
                >>> Testing ConvertFromPyObject using l[:] = [%s]
                -l[:] = [None]:TypeError:('unable to convert to vim structure',)
                +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:()
                @@ -823,63 +823,63 @@
                <<< Finished
                >> ListConcatInPlace
                >>> Testing StringToChars using l.extend([{%s : 1}])
                -l.extend([{1 : 1}]):TypeError:('object must be string',)
                +l.extend([{1 : 1}]):TypeError:('expected str() or unicode() instance, but got int',)
                l.extend([{u"\0" : 1}]):TypeError:('expected string without null bytes',)
                l.extend([{"\0" : 1}]):TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing StringToChars using l.extend([{"abc" : {%s : 1}}])
                -l.extend([{"abc" : {1 : 1}}]):TypeError:('object must be string',)
                +l.extend([{"abc" : {1 : 1}}]):TypeError:('expected str() or unicode() instance, but got int',)
                l.extend([{"abc" : {u"\0" : 1}}]):TypeError:('expected string without null bytes',)
                l.extend([{"abc" : {"\0" : 1}}]):TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing StringToChars using l.extend([{"abc" : Mapping({%s : 1})}])
                -l.extend([{"abc" : Mapping({1 : 1})}]):TypeError:('object must be string',)
                +l.extend([{"abc" : Mapping({1 : 1})}]):TypeError:('expected str() or unicode() instance, but got int',)
                l.extend([{"abc" : Mapping({u"\0" : 1})}]):TypeError:('expected string without null bytes',)
                l.extend([{"abc" : Mapping({"\0" : 1})}]):TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing *Iter* using l.extend([{"abc" : %s}])
                -l.extend([{"abc" : FailingIter()}]):TypeError:('unable to convert to vim structure',)
                +l.extend([{"abc" : FailingIter()}]):TypeError:('unable to convert FailingIter to vim structure',)
                l.extend([{"abc" : FailingIterNext()}]):NotImplementedError:()
                <<< Finished
                >>> Testing ConvertFromPyObject using l.extend([{"abc" : %s}])
                -l.extend([{"abc" : None}]):TypeError:('unable to convert to vim structure',)
                +l.extend([{"abc" : None}]):TypeError:('unable to convert NoneType to vim structure',)
                l.extend([{"abc" : {"": 1}}]):ValueError:('empty keys are not allowed',)
                l.extend([{"abc" : {u"": 1}}]):ValueError:('empty keys are not allowed',)
                l.extend([{"abc" : FailingMapping()}]):NotImplementedError:()
                l.extend([{"abc" : FailingMappingKey()}]):NotImplementedError:()
                <<< Finished
                >>> Testing StringToChars using l.extend([Mapping({%s : 1})])
                -l.extend([Mapping({1 : 1})]):TypeError:('object must be string',)
                +l.extend([Mapping({1 : 1})]):TypeError:('expected str() or unicode() instance, but got int',)
                l.extend([Mapping({u"\0" : 1})]):TypeError:('expected string without null bytes',)
                l.extend([Mapping({"\0" : 1})]):TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing StringToChars using l.extend([Mapping({"abc" : {%s : 1}})])
                -l.extend([Mapping({"abc" : {1 : 1}})]):TypeError:('object must be string',)
                +l.extend([Mapping({"abc" : {1 : 1}})]):TypeError:('expected str() or unicode() instance, but got int',)
                l.extend([Mapping({"abc" : {u"\0" : 1}})]):TypeError:('expected string without null bytes',)
                l.extend([Mapping({"abc" : {"\0" : 1}})]):TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing StringToChars using l.extend([Mapping({"abc" : Mapping({%s : 1})})])
                -l.extend([Mapping({"abc" : Mapping({1 : 1})})]):TypeError:('object must be string',)
                +l.extend([Mapping({"abc" : Mapping({1 : 1})})]):TypeError:('expected str() or unicode() instance, but got int',)
                l.extend([Mapping({"abc" : Mapping({u"\0" : 1})})]):TypeError:('expected string without null bytes',)
                l.extend([Mapping({"abc" : Mapping({"\0" : 1})})]):TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing *Iter* using l.extend([Mapping({"abc" : %s})])
                -l.extend([Mapping({"abc" : FailingIter()})]):TypeError:('unable to convert to vim structure',)
                +l.extend([Mapping({"abc" : FailingIter()})]):TypeError:('unable to convert FailingIter to vim structure',)
                l.extend([Mapping({"abc" : FailingIterNext()})]):NotImplementedError:()
                <<< Finished
                >>> Testing ConvertFromPyObject using l.extend([Mapping({"abc" : %s})])
                -l.extend([Mapping({"abc" : None})]):TypeError:('unable to convert to vim structure',)
                +l.extend([Mapping({"abc" : None})]):TypeError:('unable to convert NoneType to vim structure',)
                l.extend([Mapping({"abc" : {"": 1}})]):ValueError:('empty keys are not allowed',)
                l.extend([Mapping({"abc" : {u"": 1}})]):ValueError:('empty keys are not allowed',)
                l.extend([Mapping({"abc" : FailingMapping()})]):NotImplementedError:()
                l.extend([Mapping({"abc" : FailingMappingKey()})]):NotImplementedError:()
                <<< Finished
                >>> Testing *Iter* using l.extend([%s])
                -l.extend([FailingIter()]):TypeError:('unable to convert to vim structure',)
                +l.extend([FailingIter()]):TypeError:('unable to convert FailingIter to vim structure',)
                l.extend([FailingIterNext()]):NotImplementedError:()
                <<< Finished
                >>> Testing ConvertFromPyObject using l.extend([%s])
                -l.extend([None]):TypeError:('unable to convert to vim structure',)
                +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:()
                @@ -888,134 +888,134 @@
                >> ListSetattr
                del l.locked:AttributeError:('cannot delete vim.List attributes',)
                l.locked = FailingTrue():NotImplementedError:()
                -l.xxx = True:AttributeError:('cannot set this attribute',)
                +l.xxx = True:AttributeError:('cannot set attribute xxx',)
                > Function
                >> FunctionConstructor
                -vim.Function("123"):ValueError:('unnamed function does not exist',)
                -vim.Function("xxx_non_existent_function_xxx"):ValueError:('function does not exist',)
                +vim.Function("123"):ValueError:('unnamed function 123 does not exist',)
                +vim.Function("xxx_non_existent_function_xxx"):ValueError:('function xxx_non_existent_function_xxx does not exist',)
                vim.Function("xxx#non#existent#function#xxx"):NOT FAILED
                >> FunctionCall
                >>> Testing StringToChars using f({%s : 1})
                -f({1 : 1}):TypeError:('object must be string',)
                +f({1 : 1}):TypeError:('expected str() or unicode() instance, but got int',)
                f({u"\0" : 1}):TypeError:('expected string without null bytes',)
                f({"\0" : 1}):TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing StringToChars using f({"abc" : {%s : 1}})
                -f({"abc" : {1 : 1}}):TypeError:('object must be string',)
                +f({"abc" : {1 : 1}}):TypeError:('expected str() or unicode() instance, but got int',)
                f({"abc" : {u"\0" : 1}}):TypeError:('expected string without null bytes',)
                f({"abc" : {"\0" : 1}}):TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing StringToChars using f({"abc" : Mapping({%s : 1})})
                -f({"abc" : Mapping({1 : 1})}):TypeError:('object must be string',)
                +f({"abc" : Mapping({1 : 1})}):TypeError:('expected str() or unicode() instance, but got int',)
                f({"abc" : Mapping({u"\0" : 1})}):TypeError:('expected string without null bytes',)
                f({"abc" : Mapping({"\0" : 1})}):TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing *Iter* using f({"abc" : %s})
                -f({"abc" : FailingIter()}):TypeError:('unable to convert to vim structure',)
                +f({"abc" : FailingIter()}):TypeError:('unable to convert FailingIter to vim structure',)
                f({"abc" : FailingIterNext()}):NotImplementedError:()
                <<< Finished
                >>> Testing ConvertFromPyObject using f({"abc" : %s})
                -f({"abc" : None}):TypeError:('unable to convert to vim structure',)
                +f({"abc" : None}):TypeError:('unable to convert NoneType to vim structure',)
                f({"abc" : {"": 1}}):ValueError:('empty keys are not allowed',)
                f({"abc" : {u"": 1}}):ValueError:('empty keys are not allowed',)
                f({"abc" : FailingMapping()}):NotImplementedError:()
                f({"abc" : FailingMappingKey()}):NotImplementedError:()
                <<< Finished
                >>> Testing StringToChars using f(Mapping({%s : 1}))
                -f(Mapping({1 : 1})):TypeError:('object must be string',)
                +f(Mapping({1 : 1})):TypeError:('expected str() or unicode() instance, but got int',)
                f(Mapping({u"\0" : 1})):TypeError:('expected string without null bytes',)
                f(Mapping({"\0" : 1})):TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing StringToChars using f(Mapping({"abc" : {%s : 1}}))
                -f(Mapping({"abc" : {1 : 1}})):TypeError:('object must be string',)
                +f(Mapping({"abc" : {1 : 1}})):TypeError:('expected str() or unicode() instance, but got int',)
                f(Mapping({"abc" : {u"\0" : 1}})):TypeError:('expected string without null bytes',)
                f(Mapping({"abc" : {"\0" : 1}})):TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing StringToChars using f(Mapping({"abc" : Mapping({%s : 1})}))
                -f(Mapping({"abc" : Mapping({1 : 1})})):TypeError:('object must be string',)
                +f(Mapping({"abc" : Mapping({1 : 1})})):TypeError:('expected str() or unicode() instance, but got int',)
                f(Mapping({"abc" : Mapping({u"\0" : 1})})):TypeError:('expected string without null bytes',)
                f(Mapping({"abc" : Mapping({"\0" : 1})})):TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing *Iter* using f(Mapping({"abc" : %s}))
                -f(Mapping({"abc" : FailingIter()})):TypeError:('unable to convert to vim structure',)
                +f(Mapping({"abc" : FailingIter()})):TypeError:('unable to convert FailingIter to vim structure',)
                f(Mapping({"abc" : FailingIterNext()})):NotImplementedError:()
                <<< Finished
                >>> Testing ConvertFromPyObject using f(Mapping({"abc" : %s}))
                -f(Mapping({"abc" : None})):TypeError:('unable to convert to vim structure',)
                +f(Mapping({"abc" : None})):TypeError:('unable to convert NoneType to vim structure',)
                f(Mapping({"abc" : {"": 1}})):ValueError:('empty keys are not allowed',)
                f(Mapping({"abc" : {u"": 1}})):ValueError:('empty keys are not allowed',)
                f(Mapping({"abc" : FailingMapping()})):NotImplementedError:()
                f(Mapping({"abc" : FailingMappingKey()})):NotImplementedError:()
                <<< Finished
                >>> Testing *Iter* using f(%s)
                -f(FailingIter()):TypeError:('unable to convert to vim structure',)
                +f(FailingIter()):TypeError:('unable to convert FailingIter to vim structure',)
                f(FailingIterNext()):NotImplementedError:()
                <<< Finished
                >>> Testing ConvertFromPyObject using f(%s)
                -f(None):TypeError:('unable to convert to vim structure',)
                +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:()
                <<< Finished
                >>> Testing StringToChars using fd(self={%s : 1})
                -fd(self={1 : 1}):TypeError:('object must be string',)
                +fd(self={1 : 1}):TypeError:('expected str() or unicode() instance, but got int',)
                fd(self={u"\0" : 1}):TypeError:('expected string without null bytes',)
                fd(self={"\0" : 1}):TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing StringToChars using fd(self={"abc" : {%s : 1}})
                -fd(self={"abc" : {1 : 1}}):TypeError:('object must be string',)
                +fd(self={"abc" : {1 : 1}}):TypeError:('expected str() or unicode() instance, but got int',)
                fd(self={"abc" : {u"\0" : 1}}):TypeError:('expected string without null bytes',)
                fd(self={"abc" : {"\0" : 1}}):TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing StringToChars using fd(self={"abc" : Mapping({%s : 1})})
                -fd(self={"abc" : Mapping({1 : 1})}):TypeError:('object must be string',)
                +fd(self={"abc" : Mapping({1 : 1})}):TypeError:('expected str() or unicode() instance, but got int',)
                fd(self={"abc" : Mapping({u"\0" : 1})}):TypeError:('expected string without null bytes',)
                fd(self={"abc" : Mapping({"\0" : 1})}):TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing *Iter* using fd(self={"abc" : %s})
                -fd(self={"abc" : FailingIter()}):TypeError:('unable to convert to vim structure',)
                +fd(self={"abc" : FailingIter()}):TypeError:('unable to convert FailingIter to vim structure',)
                fd(self={"abc" : FailingIterNext()}):NotImplementedError:()
                <<< Finished
                >>> Testing ConvertFromPyObject using fd(self={"abc" : %s})
                -fd(self={"abc" : None}):TypeError:('unable to convert to vim structure',)
                +fd(self={"abc" : None}):TypeError:('unable to convert NoneType to vim structure',)
                fd(self={"abc" : {"": 1}}):ValueError:('empty keys are not allowed',)
                fd(self={"abc" : {u"": 1}}):ValueError:('empty keys are not allowed',)
                fd(self={"abc" : FailingMapping()}):NotImplementedError:()
                fd(self={"abc" : FailingMappingKey()}):NotImplementedError:()
                <<< Finished
                >>> Testing StringToChars using fd(self=Mapping({%s : 1}))
                -fd(self=Mapping({1 : 1})):TypeError:('object must be string',)
                +fd(self=Mapping({1 : 1})):TypeError:('expected str() or unicode() instance, but got int',)
                fd(self=Mapping({u"\0" : 1})):TypeError:('expected string without null bytes',)
                fd(self=Mapping({"\0" : 1})):TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing StringToChars using fd(self=Mapping({"abc" : {%s : 1}}))
                -fd(self=Mapping({"abc" : {1 : 1}})):TypeError:('object must be string',)
                +fd(self=Mapping({"abc" : {1 : 1}})):TypeError:('expected str() or unicode() instance, but got int',)
                fd(self=Mapping({"abc" : {u"\0" : 1}})):TypeError:('expected string without null bytes',)
                fd(self=Mapping({"abc" : {"\0" : 1}})):TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing StringToChars using fd(self=Mapping({"abc" : Mapping({%s : 1})}))
                -fd(self=Mapping({"abc" : Mapping({1 : 1})})):TypeError:('object must be string',)
                +fd(self=Mapping({"abc" : Mapping({1 : 1})})):TypeError:('expected str() or unicode() instance, but got int',)
                fd(self=Mapping({"abc" : Mapping({u"\0" : 1})})):TypeError:('expected string without null bytes',)
                fd(self=Mapping({"abc" : Mapping({"\0" : 1})})):TypeError:('expected string without null bytes',)
                <<< Finished
                >>> Testing *Iter* using fd(self=Mapping({"abc" : %s}))
                -fd(self=Mapping({"abc" : FailingIter()})):TypeError:('unable to convert to vim structure',)
                +fd(self=Mapping({"abc" : FailingIter()})):TypeError:('unable to convert FailingIter to vim structure',)
                fd(self=Mapping({"abc" : FailingIterNext()})):NotImplementedError:()
                <<< Finished
                >>> Testing ConvertFromPyObject using fd(self=Mapping({"abc" : %s}))
                -fd(self=Mapping({"abc" : None})):TypeError:('unable to convert to vim structure',)
                +fd(self=Mapping({"abc" : None})):TypeError:('unable to convert NoneType to vim structure',)
                fd(self=Mapping({"abc" : {"": 1}})):ValueError:('empty keys are not allowed',)
                fd(self=Mapping({"abc" : {u"": 1}})):ValueError:('empty keys are not allowed',)
                fd(self=Mapping({"abc" : FailingMapping()})):NotImplementedError:()
                fd(self=Mapping({"abc" : FailingMappingKey()})):NotImplementedError:()
                <<< Finished
                >>> Testing *Iter* using fd(self=%s)
                -fd(self=FailingIter()):TypeError:('unable to convert object to vim dictionary',)
                -fd(self=FailingIterNext()):TypeError:('unable to convert object to vim dictionary',)
                +fd(self=FailingIter()):TypeError:('unable to convert FailingIter to vim dictionary',)
                +fd(self=FailingIterNext()):TypeError:('unable to convert FailingIterNext to vim dictionary',)
                <<< Finished
                >>> Testing ConvertFromPyObject using fd(self=%s)
                -fd(self=None):TypeError:('unable to convert object to vim dictionary',)
                +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:()
                @@ -1034,7 +1034,7 @@
                >> WindowAttr
                vim.current.window.xxx:AttributeError:('xxx',)
                >> WindowSetattr
                -vim.current.window.buffer = 0:TypeError:('readonly attribute',)
                +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 = "abc":TypeError:('an integer is required',)
                @@ -1062,10 +1062,10 @@
                >> BufferAttr
                vim.current.buffer.xxx:AttributeError:('xxx',)
                >> BufferSetattr
                -vim.current.buffer.name = True:TypeError:('object must be string',)
                +vim.current.buffer.name = True:TypeError:('expected str() or unicode() instance, but got bool',)
                vim.current.buffer.xxx = True:AttributeError:('xxx',)
                >> BufferMark
                -vim.current.buffer.mark(0):TypeError:('object must be string',)
                +vim.current.buffer.mark(0):TypeError:('expected str() or unicode() instance, but got int',)
                vim.current.buffer.mark("abc"):ValueError:('mark name must be a single character',)
                vim.current.buffer.mark("!"):error:('invalid mark name',)
                >> BufferRange
                @@ -1079,9 +1079,9 @@
                vim.current.xxx:AttributeError:('xxx',)
                >> CurrentSetattr
                vim.current.line = True:TypeError:('bad argument type for built-in operation',)
                -vim.current.buffer = True:TypeError:('expected vim.Buffer object',)
                -vim.current.window = True:TypeError:('expected vim.Window object',)
                -vim.current.tabpage = True:TypeError:('expected vim.TabPage object',)
                +vim.current.buffer = True:TypeError:('expected vim.Buffer object, but got bool',)
                +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',)
                2,xx
                before
                diff -r abcf5d9458ee -r 81c6385adb92 src/testdir/test87.ok
                --- a/src/testdir/test87.ok Fri Jun 14 23:42:16 2013 +0400
                +++ b/src/testdir/test87.ok Sun Jun 16 13:43:18 2013 +0400
                @@ -428,7 +428,7 @@
                >> OutputSetattr
                del sys.stdout.softspace:(<class 'AttributeError'>, AttributeError("can't delete OutputObject attributes",))
                sys.stdout.softspace = []:(<class 'TypeError'>, TypeError('softspace must be an integer',))
                -sys.stdout.attr = None:(<class 'AttributeError'>, AttributeError('invalid attribute',))
                +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",))
                >> OutputWriteLines
                @@ -439,99 +439,99 @@
                sys.stdout.writelines(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError())
                <<< Finished
                > VimCommand
                -vim.command(1):(<class 'TypeError'>, TypeError('object must be string',))
                +vim.command(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
                > VimToPython
                > VimEval
                -vim.eval(1):(<class 'TypeError'>, TypeError('object must be string',))
                +vim.eval(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
                > VimEvalPy
                -vim.bindeval(1):(<class 'TypeError'>, TypeError('object must be string',))
                +vim.bindeval(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
                > VimStrwidth
                -vim.strwidth(1):(<class 'TypeError'>, TypeError('object must be string',))
                +vim.strwidth(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
                > Dictionary
                >> DictionaryConstructor
                -vim.Dictionary("abc"):(<class 'ValueError'>, ValueError('expected sequence element of size 2',))
                +vim.Dictionary("abc"):(<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())
                vim.vvars.locked = False:(<class 'TypeError'>, TypeError('cannot modify fixed dictionary',))
                -d.scope = True:(<class 'AttributeError'>, AttributeError('cannot set this attribute',))
                -d.xxx = True:(<class 'AttributeError'>, AttributeError('cannot set this attribute',))
                +d.scope = True:(<class 'AttributeError'>, AttributeError('cannot set attribute scope',))
                +d.xxx = True:(<class 'AttributeError'>, AttributeError('cannot set attribute xxx',))
                >> _DictionaryItem
                d.get("a", 2, 3):(<class 'TypeError'>, TypeError('function takes at most 2 arguments (3 given)',))
                >>> Testing StringToChars using d.get(%s)
                -d.get(1):(<class 'TypeError'>, TypeError('object must be string',))
                +d.get(1):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
                d.get(b"\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
                d.get("\0"):(<class 'TypeError'>, TypeError('expected bytes with no null',))
                <<< Finished
                d.pop("a"):(<class 'KeyError'>, KeyError('a',))
                -dl.pop("a"):(<class 'vim.error'>, error('dict is locked',))
                +dl.pop("a"):(<class 'vim.error'>, error('dictionary is locked',))
                >> DictionaryIterNext
                for i in ned: ned["a"] = 1:(<class 'RuntimeError'>, RuntimeError('hashtab changed during iteration',))
                >> DictionaryAssItem
                -dl["b"] = 1:(<class 'vim.error'>, error('dict is locked',))
                +dl["b"] = 1:(<class 'vim.error'>, error('dictionary is locked',))
                >>> Testing StringToChars using d[%s] = 1
                -d[1] = 1:(<class 'TypeError'>, TypeError('object must be string',))
                +d[1] = 1:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
                d[b<br/><br/>(Message over 64 KB, truncated)
              • ZyX
                # HG changeset patch # User ZyX # Date 1371374174 -14400 # Sun Jun 16 13:16:14 2013 +0400 # Branch python-fixes # Node ID
                Message 7 of 25 , Jun 16, 2013
                • 0 Attachment
                  # HG changeset patch
                  # User ZyX <kp-pav@...>
                  # Date 1371374174 -14400
                  # Sun Jun 16 13:16:14 2013 +0400
                  # Branch python-fixes
                  # Node ID 55671c8e22056cd070287fc271e1f0aba731ec58
                  # Parent 81c6385adb920b486a9f3b912de3b7e86e57569d
                  Add support for Number protocol:

                  - Add and use NumberToLong to obtain various numbers (supports Number protocol)
                  - Support objects using Number protocol in ConvertFromPyObject

                  diff -r 81c6385adb92 -r 55671c8e2205 src/if_py_both.h
                  --- a/src/if_py_both.h Sun Jun 16 13:43:18 2013 +0400
                  +++ b/src/if_py_both.h Sun Jun 16 13:16:14 2013 +0400
                  @@ -151,6 +151,95 @@
                  return (char_u *) p;
                  }

                  +#define NUMBER_LONG 1
                  +#define NUMBER_INT 2
                  +#define NUMBER_NATURAL 4
                  +#define NUMBER_UNSIGNED 8
                  +
                  + static int
                  +NumberToLong(PyObject *obj, long *result, int flags)
                  +{
                  +#if PY_MAJOR_VERSION < 3
                  + if (PyInt_Check(obj))
                  + {
                  + *result = PyInt_AsLong(obj);
                  + if (PyErr_Occurred())
                  + return -1;
                  + }
                  + else
                  +#endif
                  + if (PyLong_Check(obj))
                  + {
                  + *result = PyLong_AsLong(obj);
                  + if (PyErr_Occurred())
                  + return -1;
                  + }
                  + else if (PyNumber_Check(obj))
                  + {
                  + PyObject *num;
                  +
                  + if (!(num = PyNumber_Long(obj)))
                  + return -1;
                  +
                  + *result = PyLong_AsLong(num);
                  +
                  + Py_DECREF(num);
                  +
                  + if (PyErr_Occurred())
                  + return -1;
                  + }
                  + else
                  + {
                  + PyErr_FORMAT(PyExc_TypeError,
                  +#if PY_MAJOR_VERSION < 3
                  + "expected int(), long() or something supporting "
                  + "coercing to long(), but got %s"
                  +#else
                  + "expected int() or something supporting coercing to int(), "
                  + "but got %s"
                  +#endif
                  + , Py_TYPE_NAME(obj));
                  + return -1;
                  + }
                  +
                  + if (flags & NUMBER_INT)
                  + {
                  + if (*result > INT_MAX)
                  + {
                  + PyErr_SET_STRING(PyExc_OverflowError,
                  + "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");
                  + return -1;
                  + }
                  + }
                  +
                  + if (flags & NUMBER_NATURAL)
                  + {
                  + if (*result <= 0)
                  + {
                  + PyErr_SET_STRING(PyExc_ValueError,
                  + "number must be greater then zero");
                  + return -1;
                  + }
                  + }
                  + else if (flags & NUMBER_UNSIGNED)
                  + {
                  + if (*result < 0)
                  + {
                  + PyErr_SET_STRING(PyExc_ValueError,
                  + "number must be greater or equal to zero");
                  + return -1;
                  + }
                  + }
                  +
                  + return 0;
                  +}
                  +
                  static int
                  add_string(PyObject *list, char *s)
                  {
                  @@ -243,13 +332,8 @@

                  if (strcmp(name, "softspace") == 0)
                  {
                  - if (!PyInt_Check(val))
                  - {
                  - PyErr_SET_STRING(PyExc_TypeError, "softspace must be an integer");
                  + if (NumberToLong(val, &(self->softspace), NUMBER_UNSIGNED))
                  return -1;
                  - }
                  -
                  - self->softspace = PyInt_AsLong(val);
                  return 0;
                  }

                  @@ -2840,23 +2924,15 @@
                  }
                  else if (flags & SOPT_NUM)
                  {
                  - int val;
                  -
                  -#if PY_MAJOR_VERSION < 3
                  - if (PyInt_Check(valObject))
                  - val = PyInt_AsLong(valObject);
                  - else
                  -#endif
                  - if (PyLong_Check(valObject))
                  - val = PyLong_AsLong(valObject);
                  - else
                  + long val;
                  +
                  + if (NumberToLong(valObject, &val, NUMBER_INT))
                  {
                  - PyErr_SET_STRING(PyExc_TypeError, "object must be integer");
                  Py_XDECREF(todecref);
                  return -1;
                  }

                  - r = set_option_value_for(key, val, NULL, opt_flags,
                  + r = set_option_value_for(key, (int) val, NULL, opt_flags,
                  self->opt_type, self->from);
                  }
                  else
                  @@ -3265,10 +3341,10 @@
                  }
                  else if (strcmp(name, "height") == 0)
                  {
                  - int height;
                  + long height;
                  win_T *savewin;

                  - if (!PyArg_Parse(val, "i", &height))
                  + if (NumberToLong(val, &height, NUMBER_INT))
                  return -1;

                  #ifdef FEAT_GUI
                  @@ -3278,7 +3354,7 @@
                  curwin = self->win;

                  VimTryStart();
                  - win_setheight(height);
                  + win_setheight((int) height);
                  curwin = savewin;
                  if (VimTryEnd())
                  return -1;
                  @@ -3288,10 +3364,10 @@
                  #ifdef FEAT_VERTSPLIT
                  else if (strcmp(name, "width") == 0)
                  {
                  - int width;
                  + long width;
                  win_T *savewin;

                  - if (!PyArg_Parse(val, "i", &width))
                  + if (NumberToLong(val, &width, NUMBER_INT))
                  return -1;

                  #ifdef FEAT_GUI
                  @@ -3301,7 +3377,7 @@
                  curwin = self->win;

                  VimTryStart();
                  - win_setwidth(width);
                  + win_setwidth((int) width);
                  curwin = savewin;
                  if (VimTryEnd())
                  return -1;
                  @@ -4555,22 +4631,12 @@
                  BufMapItem(PyObject *self UNUSED, PyObject *keyObject)
                  {
                  buf_T *b;
                  - int bnr;
                  -
                  -#if PY_MAJOR_VERSION < 3
                  - if (PyInt_Check(keyObject))
                  - bnr = PyInt_AsLong(keyObject);
                  - else
                  -#endif
                  - if (PyLong_Check(keyObject))
                  - bnr = PyLong_AsLong(keyObject);
                  - else
                  - {
                  - PyErr_SET_STRING(PyExc_TypeError, "key must be integer");
                  + long bnr;
                  +
                  + if (NumberToLong(keyObject, &bnr, NUMBER_INT|NUMBER_NATURAL))
                  return NULL;
                  - }
                  -
                  - b = buflist_findnr(bnr);
                  +
                  + b = buflist_findnr((int) bnr);

                  if (b)
                  return BufferNew(b);
                  @@ -5345,12 +5411,16 @@
                  {
                  tv->v_type = VAR_NUMBER;
                  tv->vval.v_number = (varnumber_T) PyInt_AsLong(obj);
                  + if (PyErr_Occurred())
                  + return -1;
                  }
                  #endif
                  else if (PyLong_Check(obj))
                  {
                  tv->v_type = VAR_NUMBER;
                  tv->vval.v_number = (varnumber_T) PyLong_AsLong(obj);
                  + if (PyErr_Occurred())
                  + return -1;
                  }
                  else if (PyDict_Check(obj))
                  return convert_dl(obj, tv, pydict_to_tv, lookup_dict);
                  @@ -5367,6 +5437,18 @@
                  return convert_dl(obj, tv, pyseq_to_tv, lookup_dict);
                  else if (PyMapping_Check(obj))
                  return convert_dl(obj, tv, pymap_to_tv, lookup_dict);
                  + else if (PyNumber_Check(obj))
                  + {
                  + PyObject *num;
                  +
                  + if (!(num = PyNumber_Long(obj)))
                  + return -1;
                  +
                  + tv->v_type = VAR_NUMBER;
                  + tv->vval.v_number = (varnumber_T) PyLong_AsLong(num);
                  +
                  + Py_DECREF(num);
                  + }
                  else
                  {
                  PyErr_FORMAT(PyExc_TypeError,
                  diff -r 81c6385adb92 -r 55671c8e2205 src/if_python.c
                  --- a/src/if_python.c Sun Jun 16 13:43:18 2013 +0400
                  +++ b/src/if_python.c Sun Jun 16 13:16:14 2013 +0400
                  @@ -220,6 +220,7 @@
                  # define PyObject_CallFunctionObjArgs dll_PyObject_CallFunctionObjArgs
                  # define PyObject_CallFunction dll_PyObject_CallFunction
                  # define PyObject_Call dll_PyObject_Call
                  +# define PyObject_Repr dll_PyObject_Repr
                  # define PyString_AsString dll_PyString_AsString
                  # define PyString_AsStringAndSize dll_PyString_AsStringAndSize
                  # define PyString_FromString dll_PyString_FromString
                  @@ -233,6 +234,8 @@
                  # define PyFloat_AsDouble dll_PyFloat_AsDouble
                  # define PyFloat_FromDouble dll_PyFloat_FromDouble
                  # define PyFloat_Type (*dll_PyFloat_Type)
                  +# define PyNumber_Check dll_PyNumber_Check
                  +# define PyNumber_Long dll_PyNumber_Long
                  # define PyImport_AddModule (*dll_PyImport_AddModule)
                  # define PySys_SetObject dll_PySys_SetObject
                  # define PySys_GetObject dll_PySys_GetObject
                  @@ -360,6 +363,7 @@
                  static PyObject* (*dll_PyObject_CallFunctionObjArgs)(PyObject *, ...);
                  static PyObject* (*dll_PyObject_CallFunction)(PyObject *, char *, ...);
                  static PyObject* (*dll_PyObject_Call)(PyObject *, PyObject *, PyObject *);
                  +static PyObject* (*dll_PyObject_Repr)(PyObject *);
                  static char*(*dll_PyString_AsString)(PyObject *);
                  static int(*dll_PyString_AsStringAndSize)(PyObject *, char **, int *);
                  static PyObject*(*dll_PyString_FromString)(const char *);
                  @@ -372,6 +376,8 @@
                  static double(*dll_PyFloat_AsDouble)(PyObject *);
                  static PyObject*(*dll_PyFloat_FromDouble)(double);
                  static PyTypeObject* dll_PyFloat_Type;
                  +static int(*dll_PyNumber_Check)(PyObject *);
                  +static PyObject*(*dll_PyNumber_Long)(PyObject *);
                  static int(*dll_PySys_SetObject)(char *, PyObject *);
                  static PyObject *(*dll_PySys_GetObject)(char *);
                  static int(*dll_PySys_SetArgv)(int, char **);
                  @@ -440,6 +446,7 @@
                  static PyObject *imp_PyExc_ValueError;
                  static PyObject *imp_PyExc_RuntimeError;
                  static PyObject *imp_PyExc_ImportError;
                  +static PyObject *imp_PyExc_OverflowError;

                  # define PyExc_AttributeError imp_PyExc_AttributeError
                  # define PyExc_IndexError imp_PyExc_IndexError
                  @@ -449,6 +456,7 @@
                  # define PyExc_ValueError imp_PyExc_ValueError
                  # define PyExc_RuntimeError imp_PyExc_RuntimeError
                  # define PyExc_ImportError imp_PyExc_ImportError
                  +# define PyExc_OverflowError imp_PyExc_OverflowError

                  /*
                  * Table of name to function pointer of python.
                  @@ -533,6 +541,7 @@
                  {"PyObject_CallFunctionObjArgs", (PYTHON_PROC*)&dll_PyObject_CallFunctionObjArgs},
                  {"PyObject_CallFunction", (PYTHON_PROC*)&dll_PyObject_CallFunction},
                  {"PyObject_Call", (PYTHON_PROC*)&dll_PyObject_Call},
                  + {"PyObject_Repr", (PYTHON_PROC*)&dll_PyObject_Repr},
                  {"PyString_AsString", (PYTHON_PROC*)&dll_PyString_AsString},
                  {"PyString_AsStringAndSize", (PYTHON_PROC*)&dll_PyString_AsStringAndSize},
                  {"PyString_FromString", (PYTHON_PROC*)&dll_PyString_FromString},
                  @@ -545,6 +554,8 @@
                  {"PyFloat_AsDouble", (PYTHON_PROC*)&dll_PyFloat_AsDouble},
                  {"PyFloat_FromDouble", (PYTHON_PROC*)&dll_PyFloat_FromDouble},
                  {"PyImport_AddModule", (PYTHON_PROC*)&dll_PyImport_AddModule},
                  + {"PyNumber_Check", (PYTHON_PROC*)&dll_PyNumber_Check},
                  + {"PyNumber_Long", (PYTHON_PROC*)&dll_PyNumber_Long},
                  {"PySys_SetObject", (PYTHON_PROC*)&dll_PySys_SetObject},
                  {"PySys_GetObject", (PYTHON_PROC*)&dll_PySys_GetObject},
                  {"PySys_SetArgv", (PYTHON_PROC*)&dll_PySys_SetArgv},
                  @@ -722,6 +733,7 @@
                  imp_PyExc_ValueError = PyDict_GetItemString(exdict, "ValueError");
                  imp_PyExc_RuntimeError = PyDict_GetItemString(exdict, "RuntimeError");
                  imp_PyExc_ImportError = PyDict_GetItemString(exdict, "ImportError");
                  + imp_PyExc_OverflowError = PyDict_GetItemString(exdict, "OverflowError");
                  Py_XINCREF(imp_PyExc_AttributeError);
                  Py_XINCREF(imp_PyExc_IndexError);
                  Py_XINCREF(imp_PyExc_KeyError);
                  @@ -730,6 +742,7 @@
                  Py_XINCREF(imp_PyExc_ValueError);
                  Py_XINCREF(imp_PyExc_RuntimeError);
                  Py_XINCREF(imp_PyExc_ImportError);
                  + Py_XINCREF(imp_PyExc_OverflowError);
                  Py_XDECREF(exmod);
                  }
                  #endif /* DYNAMIC_PYTHON */
                  diff -r 81c6385adb92 -r 55671c8e2205 src/if_python3.c
                  --- a/src/if_python3.c Sun Jun 16 13:43:18 2013 +0400
                  +++ b/src/if_python3.c Sun Jun 16 13:16:14 2013 +0400
                  @@ -160,6 +160,7 @@
                  # define PyMapping_Keys py3_PyMapping_Keys
                  # define PyIter_Next py3_PyIter_Next
                  # define PyObject_GetIter py3_PyObject_GetIter
                  +# define PyObject_Repr py3_PyObject_Repr
                  # define PyObject_GetItem py3_PyObject_GetItem
                  # define PyObject_IsTrue py3_PyObject_IsTrue
                  # define PyModule_GetDict py3_PyModule_GetDict
                  @@ -211,6 +212,8 @@
                  # define PyType_Type (*py3_PyType_Type)
                  # define PySlice_Type (*py3_PySlice_Type)
                  # define PyFloat_Type (*py3_PyFloat_Type)
                  +# define PyNumber_Check (*py3_PyNumber_Check)
                  +# define PyNumber_Long (*py3_PyNumber_Long)
                  # define PyBool_Type (*py3_PyBool_Type)
                  # define PyErr_NewException py3_PyErr_NewException
                  # ifdef Py_DEBUG
                  @@ -310,6 +313,7 @@
                  static PyObject* (*py3_PyDict_New)(void);
                  static PyObject* (*py3_PyIter_Next)(PyObject *);
                  static PyObject* (*py3_PyObject_GetIter)(PyObject *);
                  +static PyObject* (*py3_PyObject_Repr)(PyObject *);
                  static PyObject* (*py3_PyObject_GetItem)(PyObject *, PyObject *);
                  static int (*py3_PyObject_IsTrue)(PyObject *);
                  static PyObject* (*py3_Py_BuildValue)(char *, ...);
                  @@ -365,6 +369,8 @@
                  static PyTypeObject* py3_PySlice_Type;
                  static PyTypeObject* py3_PyFloat_Type;
                  static PyTypeObject* py3_PyBool_Type;
                  +static int (*py3_PyNumber_Check)(PyObject *);
                  +static PyObject* (*py3_PyNumber_Long)(PyObject *);
                  static PyObject* (*py3_PyErr_NewException)(char *name, PyObject *base, PyObject *dict);
                  static PyObject* (*py3_PyCapsule_New)(void *, char *, PyCapsule_Destructor);
                  static void* (*py3_PyCapsule_GetPointer)(PyObject *, char *);
                  @@ -399,6 +405,7 @@
                  static PyObject *p3imp_PyExc_ValueError;
                  static PyObject *p3imp_PyExc_RuntimeError;
                  static PyObject *p3imp_PyExc_ImportError;
                  +static PyObject *p3imp_PyExc_OverflowError;

                  # define PyExc_AttributeError p3imp_PyExc_AttributeError
                  # define PyExc_IndexError p3imp_PyExc_IndexError
                  @@ -408,6 +415,7 @@
                  # define PyExc_ValueError p3imp_PyExc_ValueError
                  # define PyExc_RuntimeError p3imp_PyExc_RuntimeError
                  # define PyExc_ImportError p3imp_PyExc_ImportError
                  +# define PyExc_OverflowError p3imp_PyExc_OverflowError

                  /*
                  * Table of name to function pointer of python.
                  @@ -469,6 +477,7 @@
                  {"PyMapping_Keys", (PYTHON_PROC*)&py3_PyMapping_Keys},
                  {"PyIter_Next", (PYTHON_PROC*)&py3_PyIter_Next},
                  {"PyObject_GetIter", (PYTHON_PROC*)&py3_PyObject_GetIter},
                  + {"PyObject_Repr", (PYTHON_PROC*)&py3_PyObject_Repr},
                  {"PyObject_GetItem", (PYTHON_PROC*)&py3_PyObject_GetItem},
                  {"PyObject_IsTrue", (PYTHON_PROC*)&py3_PyObject_IsTrue},
                  {"PyLong_FromLong", (PYTHON_PROC*)&py3_PyLong_FromLong},
                  @@ -518,6 +527,8 @@
                  {"PySlice_Type", (PYTHON_PROC*)&py3_PySlice_Type},
                  {"PyFloat_Type", (PYTHON_PROC*)&py3_PyFloat_Type},
                  {"PyBool_Type", (PYTHON_PROC*)&py3_PyBool_Type},
                  + {"PyNumber_Check", (PYTHON_PROC*)&py3_PyNumber_Check},
                  + {"PyNumber_Long", (PYTHON_PROC*)&py3_PyNumber_Long},
                  {"PyErr_NewException", (PYTHON_PROC*)&py3_PyErr_NewException},
                  # ifdef Py_DEBUG
                  {"_Py_NegativeRefcount", (PYTHON_PROC*)&py3__Py_NegativeRefcount},
                  @@ -672,6 +683,7 @@
                  p3imp_PyExc_ValueError = PyDict_GetItemString(exdict, "ValueError");
                  p3imp_PyExc_RuntimeError = PyDict_GetItemString(exdict, "RuntimeError");
                  p3imp_PyExc_ImportError = PyDict_GetItemString(exdict, "ImportError");
                  + p3imp_PyExc_OverflowError = PyDict_GetItemString(exdict, "OverflowError");
                  Py_XINCREF(p3imp_PyExc_AttributeError);
                  Py_XINCREF(p3imp_PyExc_IndexError);
                  Py_XINCREF(p3imp_PyExc_KeyError);
                  @@ -680,6 +692,7 @@
                  Py_XINCREF(p3imp_PyExc_ValueError);
                  Py_XINCREF(p3imp_PyExc_RuntimeError);
                  Py_XINCREF(p3imp_PyExc_ImportError);
                  + Py_XINCREF(p3imp_PyExc_OverflowError);
                  Py_XDECREF(exmod);
                  }
                  #endif /* DYNAMIC_PYTHON3 */
                  diff -r 81c6385adb92 -r 55671c8e2205 src/testdir/test86.ok
                  --- a/src/testdir/test86.ok Sun Jun 16 13:43:18 2013 +0400
                  +++ b/src/testdir/test86.ok Sun Jun 16 13:16:14 2013 +0400
                  @@ -438,7 +438,7 @@
                  > Output
                  >> OutputSetattr
                  del sys.stdout.softspace:AttributeError:("can't delete OutputObject attributes",)
                  -sys.stdout.softspace = []:TypeError:('softspace must be an integer',)
                  +sys.stdout.softspace = []:TypeError:('expected int(), long() or something supporting coercing to long(), but got list',)
                  sys.stdout.attr = None:AttributeError:('invalid attribute: attr',)
                  >> OutputWrite
                  sys.stdout.write(None):TypeError:('coercing to Unicode: need string or buffer, NoneType found',)
                  @@ -1037,8 +1037,8 @@
                  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 = "abc":TypeError:('an integer is required',)
                  -vim.current.window.width = "abc":TypeError:('an integer is required',)
                  +vim.current.window.height = "abc":TypeError:('expected int(), long() or something supporting coercing to long(), but got str',)
                  +vim.current.window.width = "abc":TypeError:('expected int(), long() or something supporting coercing to long(), but got str',)
                  vim.current.window.xxxxxx = True:AttributeError:('xxxxxx',)
                  > WinList
                  >> WinListItem
                  @@ -1072,7 +1072,7 @@
                  vim.current.buffer.range(1, 2, 3):TypeError:('function takes exactly 2 arguments (3 given)',)
                  > BufMap
                  >> BufMapItem
                  -vim.buffers[None]:TypeError:('key must be integer',)
                  +vim.buffers[None]:TypeError:('expected int(), long() or something supporting coercing to long(), but got NoneType',)
                  vim.buffers[100000000]:KeyError:(100000000,)
                  > Current
                  >> CurrentGetattr
                  diff -r 81c6385adb92 -r 55671c8e2205 src/testdir/test87.ok
                  --- a/src/testdir/test87.ok Sun Jun 16 13:43:18 2013 +0400
                  +++ b/src/testdir/test87.ok Sun Jun 16 13:16:14 2013 +0400
                  @@ -427,7 +427,7 @@
                  > Output
                  >> OutputSetattr
                  del sys.stdout.softspace:(<class 'AttributeError'>, AttributeError("can't delete OutputObject attributes",))
                  -sys.stdout.softspace = []:(<class 'TypeError'>, TypeError('softspace must be an integer',))
                  +sys.stdout.softspace = []:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got list',))
                  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",))
                  @@ -1046,8 +1046,8 @@
                  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 = "abc":(<class 'TypeError'>, TypeError('an integer is required',))
                  -vim.current.window.width = "abc":(<class 'TypeError'>, TypeError('an integer is required',))
                  +vim.current.window.height = "abc":(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got str',))
                  +vim.current.window.width = "abc":(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got str',))
                  vim.current.window.xxxxxx = True:(<class 'AttributeError'>, AttributeError('xxxxxx',))
                  > WinList
                  >> WinListItem
                  @@ -1081,7 +1081,7 @@
                  vim.current.buffer.range(1, 2, 3):(<class 'TypeError'>, TypeError('function takes exactly 2 arguments (3 given)',))
                  > BufMap
                  >> BufMapItem
                  -vim.buffers[None]:(<class 'TypeError'>, TypeError('key must be integer',))
                  +vim.buffers[None]:(<class 'TypeError'>, TypeError('expected int() or something supporting coercing to int(), but got NoneType',))
                  vim.buffers[100000000]:(<class 'KeyError'>, KeyError(100000000,))
                  > Current
                  >> CurrentGetattr

                  --
                  --
                  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 1371395827 -14400 # Sun Jun 16 19:17:07 2013 +0400 # Branch python-fixes # Node ID
                  Message 8 of 25 , Jun 16, 2013
                  • 0 Attachment
                    # HG changeset patch
                    # User ZyX <kp-pav@...>
                    # Date 1371395827 -14400
                    # Sun Jun 16 19:17:07 2013 +0400
                    # Branch python-fixes
                    # Node ID e4cfe82588f5203b9dfd71e1d8668f2f1900f72a
                    # Parent 55671c8e22056cd070287fc271e1f0aba731ec58
                    Some variable renamings and more tabs in variable declarations

                    diff -r 55671c8e2205 -r e4cfe82588f5 src/eval.c
                    --- a/src/eval.c Sun Jun 16 13:16:14 2013 +0400
                    +++ b/src/eval.c Sun Jun 16 19:17:07 2013 +0400
                    @@ -3226,7 +3226,7 @@
                    void *fi_void;
                    char_u *arg;
                    {
                    - forinfo_T *fi = (forinfo_T *)fi_void;
                    + forinfo_T *fi = (forinfo_T *)fi_void;
                    int result;
                    listitem_T *item;

                    diff -r 55671c8e2205 -r e4cfe82588f5 src/if_py_both.h
                    --- a/src/if_py_both.h Sun Jun 16 13:16:14 2013 +0400
                    +++ b/src/if_py_both.h Sun Jun 16 19:17:07 2013 +0400
                    @@ -107,28 +107,28 @@
                    * Use Py_XDECREF to decrement reference count.
                    */
                    static char_u *
                    -StringToChars(PyObject *object, PyObject **todecref)
                    -{
                    - char_u *p;
                    -
                    - if (PyBytes_Check(object))
                    - {
                    -
                    - if (PyBytes_AsStringAndSize(object, (char **) &p, NULL) == -1
                    - || p == NULL)
                    +StringToChars(PyObject *obj, PyObject **todecref)
                    +{
                    + char_u *str;
                    +
                    + if (PyBytes_Check(obj))
                    + {
                    +
                    + if (PyBytes_AsStringAndSize(obj, (char **) &str, NULL) == -1
                    + || str == NULL)
                    return NULL;

                    *todecref = NULL;
                    }
                    - else if (PyUnicode_Check(object))
                    + else if (PyUnicode_Check(obj))
                    {
                    PyObject *bytes;

                    - if (!(bytes = PyUnicode_AsEncodedString(object, ENC_OPT, NULL)))
                    + if (!(bytes = PyUnicode_AsEncodedString(obj, ENC_OPT, NULL)))
                    return NULL;

                    - if(PyBytes_AsStringAndSize(bytes, (char **) &p, NULL) == -1
                    - || p == NULL)
                    + if(PyBytes_AsStringAndSize(bytes, (char **) &str, NULL) == -1
                    + || str == NULL)
                    {
                    Py_DECREF(bytes);
                    return NULL;
                    @@ -144,11 +144,11 @@
                    #else
                    "expected bytes() or str() instance, but got %s"
                    #endif
                    - , Py_TYPE_NAME(object));
                    + , Py_TYPE_NAME(obj));
                    return NULL;
                    }

                    - return (char_u *) p;
                    + return (char_u *) str;
                    }

                    #define NUMBER_LONG 1
                    @@ -263,35 +263,35 @@
                    {
                    PyMethodDef *method;
                    char **attr;
                    - PyObject *r;
                    -
                    - if (!(r = PyList_New(0)))
                    + PyObject *ret;
                    +
                    + if (!(ret = PyList_New(0)))
                    return NULL;

                    if (self)
                    for (method = self->ob_type->tp_methods ; method->ml_name != NULL ; ++method)
                    - if (add_string(r, (char *) method->ml_name))
                    + if (add_string(ret, (char *) method->ml_name))
                    {
                    - Py_DECREF(r);
                    + Py_DECREF(ret);
                    return NULL;
                    }

                    for (attr = attributes ; *attr ; ++attr)
                    - if (add_string(r, *attr))
                    + if (add_string(ret, *attr))
                    {
                    - Py_DECREF(r);
                    + Py_DECREF(ret);
                    return NULL;
                    }

                    #if PY_MAJOR_VERSION < 3
                    - if (add_string(r, "__members__"))
                    - {
                    - Py_DECREF(r);
                    + if (add_string(ret, "__members__"))
                    + {
                    + Py_DECREF(ret);
                    return NULL;
                    }
                    #endif

                    - return r;
                    + return ret;
                    }

                    /* Output buffer management
                    @@ -321,9 +321,9 @@
                    }

                    static int
                    -OutputSetattr(OutputObject *self, char *name, PyObject *val)
                    -{
                    - if (val == NULL)
                    +OutputSetattr(OutputObject *self, char *name, PyObject *valObject)
                    +{
                    + if (valObject == NULL)
                    {
                    PyErr_SET_STRING(PyExc_AttributeError,
                    "can't delete OutputObject attributes");
                    @@ -332,7 +332,7 @@

                    if (strcmp(name, "softspace") == 0)
                    {
                    - if (NumberToLong(val, &(self->softspace), NUMBER_UNSIGNED))
                    + if (NumberToLong(valObject, &(self->softspace), NUMBER_UNSIGNED))
                    return -1;
                    return 0;
                    }
                    @@ -519,10 +519,10 @@
                    static PyObject *
                    LoaderLoadModule(LoaderObject *self, PyObject *args UNUSED)
                    {
                    - PyObject *r = self->module;
                    -
                    - Py_INCREF(r);
                    - return r;
                    + PyObject *ret = self->module;
                    +
                    + Py_INCREF(ret);
                    + return ret;
                    }

                    static struct PyMethodDef LoaderMethods[] = {
                    @@ -580,7 +580,7 @@
                    VimCommand(PyObject *self UNUSED, PyObject *string)
                    {
                    char_u *cmd;
                    - PyObject *result;
                    + PyObject *ret;
                    PyObject *todecref;

                    if (!(cmd = StringToChars(string, &todecref)))
                    @@ -597,13 +597,13 @@
                    Py_END_ALLOW_THREADS

                    if (VimTryEnd())
                    - result = NULL;
                    + ret = NULL;
                    else
                    - result = Py_None;
                    -
                    - Py_XINCREF(result);
                    + ret = Py_None;
                    +
                    + Py_XINCREF(ret);
                    Py_XDECREF(todecref);
                    - return result;
                    + return ret;
                    }

                    /*
                    @@ -616,7 +616,7 @@
                    static PyObject *
                    VimToPython(typval_T *our_tv, int depth, PyObject *lookup_dict)
                    {
                    - PyObject *result;
                    + PyObject *ret;
                    PyObject *newObj;
                    char ptrBuf[sizeof(void *) * 2 + 3];

                    @@ -624,8 +624,8 @@
                    if (depth > 100)
                    {
                    Py_INCREF(Py_None);
                    - result = Py_None;
                    - return result;
                    + ret = Py_None;
                    + return ret;
                    }

                    /* Check if we run into a recursive loop. The item must be in lookup_dict
                    @@ -637,15 +637,15 @@
                    our_tv->v_type == VAR_LIST ? (void *)our_tv->vval.v_list
                    : (void *)our_tv->vval.v_dict);

                    - if ((result = PyDict_GetItemString(lookup_dict, ptrBuf)))
                    + if ((ret = PyDict_GetItemString(lookup_dict, ptrBuf)))
                    {
                    - Py_INCREF(result);
                    - return result;
                    + Py_INCREF(ret);
                    + return ret;
                    }
                    }

                    if (our_tv->v_type == VAR_STRING)
                    - result = PyString_FromString(our_tv->vval.v_string == NULL
                    + ret = PyString_FromString(our_tv->vval.v_string == NULL
                    ? "" : (char *)our_tv->vval.v_string);
                    else if (our_tv->v_type == VAR_NUMBER)
                    {
                    @@ -653,7 +653,7 @@

                    /* For backwards compatibility numbers are stored as strings. */
                    sprintf(buf, "%ld", (long)our_tv->vval.v_number);
                    - result = PyString_FromString((char *) buf);
                    + ret = PyString_FromString((char *) buf);
                    }
                    # ifdef FEAT_FLOAT
                    else if (our_tv->v_type == VAR_FLOAT)
                    @@ -661,7 +661,7 @@
                    char buf[NUMBUFLEN];

                    sprintf(buf, "%f", our_tv->vval.v_float);
                    - result = PyString_FromString((char *) buf);
                    + ret = PyString_FromString((char *) buf);
                    }
                    # endif
                    else if (our_tv->v_type == VAR_LIST)
                    @@ -672,12 +672,12 @@
                    if (list == NULL)
                    return NULL;

                    - if (!(result = PyList_New(0)))
                    + if (!(ret = PyList_New(0)))
                    return NULL;

                    - if (PyDict_SetItemString(lookup_dict, ptrBuf, result))
                    + if (PyDict_SetItemString(lookup_dict, ptrBuf, ret))
                    {
                    - Py_DECREF(result);
                    + Py_DECREF(ret);
                    return NULL;
                    }

                    @@ -685,13 +685,13 @@
                    {
                    if (!(newObj = VimToPython(&curr->li_tv, depth + 1, lookup_dict)))
                    {
                    - Py_DECREF(result);
                    + Py_DECREF(ret);
                    return NULL;
                    }
                    - if (PyList_Append(result, newObj))
                    + if (PyList_Append(ret, newObj))
                    {
                    Py_DECREF(newObj);
                    - Py_DECREF(result);
                    + Py_DECREF(ret);
                    return NULL;
                    }
                    Py_DECREF(newObj);
                    @@ -707,12 +707,12 @@
                    if (our_tv->vval.v_dict == NULL)
                    return NULL;

                    - if (!(result = PyDict_New()))
                    + if (!(ret = PyDict_New()))
                    return NULL;

                    - if (PyDict_SetItemString(lookup_dict, ptrBuf, result))
                    + if (PyDict_SetItemString(lookup_dict, ptrBuf, ret))
                    {
                    - Py_DECREF(result);
                    + Py_DECREF(ret);
                    return NULL;
                    }

                    @@ -725,12 +725,12 @@
                    di = dict_lookup(hi);
                    if (!(newObj = VimToPython(&di->di_tv, depth + 1, lookup_dict)))
                    {
                    - Py_DECREF(result);
                    + Py_DECREF(ret);
                    return NULL;
                    }
                    - if (PyDict_SetItemString(result, (char *)hi->hi_key, newObj))
                    + if (PyDict_SetItemString(ret, (char *)hi->hi_key, newObj))
                    {
                    - Py_DECREF(result);
                    + Py_DECREF(ret);
                    Py_DECREF(newObj);
                    return NULL;
                    }
                    @@ -740,10 +740,10 @@
                    else
                    {
                    Py_INCREF(Py_None);
                    - result = Py_None;
                    - }
                    -
                    - return result;
                    + ret = Py_None;
                    + }
                    +
                    + return ret;
                    }

                    static PyObject *
                    @@ -753,7 +753,7 @@
                    typval_T *our_tv;
                    PyObject *string;
                    PyObject *todecref;
                    - PyObject *result;
                    + PyObject *ret;
                    PyObject *lookup_dict;

                    if (!PyArg_ParseTuple(args, "O", &string))
                    @@ -783,10 +783,10 @@
                    /* Convert the Vim type into a Python type. Create a dictionary that's
                    * used to check for recursive loops. */
                    if (!(lookup_dict = PyDict_New()))
                    - result = NULL;
                    + ret = NULL;
                    else
                    {
                    - result = VimToPython(our_tv, 1, lookup_dict);
                    + ret = VimToPython(our_tv, 1, lookup_dict);
                    Py_DECREF(lookup_dict);
                    }

                    @@ -797,7 +797,7 @@
                    Python_Release_Vim();
                    Py_END_ALLOW_THREADS

                    - return result;
                    + return ret;
                    }

                    static PyObject *ConvertToPyObject(typval_T *);
                    @@ -806,7 +806,7 @@
                    VimEvalPy(PyObject *self UNUSED, PyObject *string)
                    {
                    typval_T *our_tv;
                    - PyObject *result;
                    + PyObject *ret;
                    char_u *expr;
                    PyObject *todecref;

                    @@ -831,14 +831,14 @@
                    return NULL;
                    }

                    - result = ConvertToPyObject(our_tv);
                    + ret = ConvertToPyObject(our_tv);
                    Py_BEGIN_ALLOW_THREADS
                    Python_Lock_Vim();
                    free_tv(our_tv);
                    Python_Release_Vim();
                    Py_END_ALLOW_THREADS

                    - return result;
                    + return ret;
                    }

                    static PyObject *
                    @@ -846,44 +846,44 @@
                    {
                    char_u *str;
                    PyObject *todecref;
                    - int result;
                    + int len;

                    if (!(str = StringToChars(string, &todecref)))
                    return NULL;

                    #ifdef FEAT_MBYTE
                    - result = mb_string2cells(str, (int)STRLEN(str));
                    + len = mb_string2cells(str, (int)STRLEN(str));
                    #else
                    - result = STRLEN(str);
                    + len = STRLEN(str);
                    #endif

                    Py_XDECREF(todecref);

                    - return PyLong_FromLong(result);
                    + return PyLong_FromLong(len);
                    }

                    static PyObject *
                    _VimChdir(PyObject *_chdir, PyObject *args, PyObject *kwargs)
                    {
                    - PyObject *r;
                    + PyObject *ret;
                    PyObject *newwd;
                    PyObject *todecref;
                    char_u *new_dir;

                    if (_chdir == NULL)
                    return NULL;
                    - if (!(r = PyObject_Call(_chdir, args, kwargs)))
                    + if (!(ret = PyObject_Call(_chdir, args, kwargs)))
                    return NULL;

                    if (!(newwd = PyObject_CallFunctionObjArgs(py_getcwd, NULL)))
                    {
                    - Py_DECREF(r);
                    + Py_DECREF(ret);
                    return NULL;
                    }

                    if (!(new_dir = StringToChars(newwd, &todecref)))
                    {
                    - Py_DECREF(r);
                    + Py_DECREF(ret);
                    Py_DECREF(newwd);
                    return NULL;
                    }
                    @@ -892,7 +892,7 @@

                    if (vim_chdir(new_dir))
                    {
                    - Py_DECREF(r);
                    + Py_DECREF(ret);
                    Py_DECREF(newwd);
                    Py_XDECREF(todecref);

                    @@ -910,11 +910,11 @@

                    if (VimTryEnd())
                    {
                    - Py_DECREF(r);
                    + Py_DECREF(ret);
                    return NULL;
                    }

                    - return r;
                    + return ret;
                    }

                    static PyObject *
                    @@ -1053,20 +1053,20 @@
                    static PyObject *
                    Vim_GetPaths(PyObject *self UNUSED)
                    {
                    - PyObject *r;
                    -
                    - if (!(r = PyList_New(0)))
                    + PyObject *ret;
                    +
                    + if (!(ret = PyList_New(0)))
                    return NULL;

                    - do_in_runtimepath(NULL, FALSE, &map_finder_callback, r);
                    + do_in_runtimepath(NULL, FALSE, &map_finder_callback, ret);

                    if (PyErr_Occurred())
                    {
                    - Py_DECREF(r);
                    + Py_DECREF(ret);
                    return NULL;
                    }

                    - return r;
                    + return ret;
                    }

                    static PyObject *
                    @@ -1401,16 +1401,16 @@
                    static dict_T *
                    py_dict_alloc(void)
                    {
                    - dict_T *r;
                    -
                    - if (!(r = dict_alloc()))
                    + dict_T *ret;
                    +
                    + if (!(ret = dict_alloc()))
                    {
                    PyErr_NoMemory();
                    return NULL;
                    }
                    - ++r->dv_refcount;
                    -
                    - return r;
                    + ++ret->dv_refcount;
                    +
                    + return ret;
                    }

                    static PyObject *
                    @@ -1462,9 +1462,9 @@
                    }

                    static int
                    -DictionarySetattr(DictionaryObject *self, char *name, PyObject *val)
                    -{
                    - if (val == NULL)
                    +DictionarySetattr(DictionaryObject *self, char *name, PyObject *valObject)
                    +{
                    + if (valObject == NULL)
                    {
                    PyErr_SET_STRING(PyExc_AttributeError,
                    "cannot delete vim.Dictionary attributes");
                    @@ -1480,7 +1480,7 @@
                    }
                    else
                    {
                    - int istrue = PyObject_IsTrue(val);
                    + int istrue = PyObject_IsTrue(valObject);
                    if (istrue == -1)
                    return -1;
                    else if (istrue)
                    @@ -1514,7 +1514,7 @@
                    {
                    PyObject *keyObject;
                    PyObject *defObject = ((flags & DICT_FLAG_NONE_DEFAULT)? Py_None : NULL);
                    - PyObject *r;
                    + PyObject *ret;
                    char_u *key;
                    dictitem_T *di;
                    dict_T *dict = self->dict;
                    @@ -1567,7 +1567,7 @@

                    di = dict_lookup(hi);

                    - if (!(r = ConvertToPyObject(&di->di_tv)))
                    + if (!(ret = ConvertToPyObject(&di->di_tv)))
                    return NULL;

                    if (flags & DICT_FLAG_POP)
                    @@ -1575,7 +1575,7 @@
                    if (dict->dv_lock)
                    {
                    RAISE_LOCKED_DICTIONARY;
                    - Py_DECREF(r);
                    + Py_DECREF(ret);
                    return NULL;
                    }

                    @@ -1583,7 +1583,7 @@
                    dictitem_free(di);
                    }

                    - return r;
                    + return ret;
                    }

                    static PyObject *
                    @@ -1596,13 +1596,13 @@
                    DictionaryContains(DictionaryObject *self, PyObject *keyObject)
                    {
                    PyObject *rObj = _DictionaryItem(self, keyObject, DICT_FLAG_RETURN_BOOL);
                    - int r;
                    -
                    - r = (rObj == Py_True);
                    + int ret;
                    +
                    + ret = (rObj == Py_True);

                    Py_DECREF(Py_True);

                    - return r;
                    + return ret;
                    }

                    typedef struct
                    @@ -1617,7 +1617,7 @@
                    static PyObject *
                    DictionaryIterNext(dictiterinfo_T **dii)
                    {
                    - PyObject *r;
                    + PyObject *ret;

                    if (!(*dii)->todo)
                    return NULL;
                    @@ -1635,10 +1635,10 @@

                    --((*dii)->todo);

                    - if (!(r = PyBytes_FromString((char *) (*dii)->hi->hi_key)))
                    + if (!(ret = PyBytes_FromString((char *) (*dii)->hi->hi_key)))
                    return NULL;

                    - return r;
                    + return ret;
                    }

                    static PyObject *
                    @@ -1754,26 +1754,26 @@
                    dict_T *dict = self->dict;
                    long_u todo = dict->dv_hashtab.ht_used;
                    Py_ssize_t i = 0;
                    - PyObject *r;
                    + PyObject *ret;
                    hashitem_T *hi;
                    PyObject *newObj;

                    - r = PyList_New(todo);
                    + ret = PyList_New(todo);
                    for (hi = dict->dv_hashtab.ht_array; todo > 0; ++hi)
                    {
                    if (!HASHITEM_EMPTY(hi))
                    {
                    if (!(newObj = hiconvert(hi)))
                    {
                    - Py_DECREF(r);
                    + Py_DECREF(ret);
                    return NULL;
                    }
                    - PyList_SET_ITEM(r, i, newObj);
                    + PyList_SET_ITEM(ret, i, newObj);
                    --todo;
                    ++i;
                    }
                    }
                    - return r;
                    + return ret;
                    }

                    static PyObject *
                    @@ -1808,7 +1808,7 @@
                    {
                    PyObject *keyObject;
                    PyObject *valObject;
                    - PyObject *r;
                    + PyObject *ret;

                    if (!(keyObject = dict_key(hi)))
                    return NULL;
                    @@ -1819,12 +1819,12 @@
                    return NULL;
                    }

                    - r = Py_BuildValue("(OO)", keyObject, valObject);
                    + ret = Py_BuildValue("(OO)", keyObject, valObject);

                    Py_DECREF(keyObject);
                    Py_DECREF(valObject);

                    - return r;
                    + return ret;
                    }

                    static PyObject *
                    @@ -1859,19 +1859,19 @@
                    }
                    else
                    {
                    - PyObject *object;
                    -
                    - if (!PyArg_ParseTuple(args, "O", &object))
                    + PyObject *obj;
                    +
                    + if (!PyArg_ParseTuple(args, "O", &obj))
                    return NULL;

                    - if (PyObject_HasAttrString(object, "keys"))
                    - return DictionaryUpdate(self, NULL, object);
                    + if (PyObject_HasAttrString(obj, "keys"))
                    + return DictionaryUpdate(self, NULL, obj);
                    else
                    {
                    PyObject *iterator;
                    PyObject *item;

                    - if (!(iterator = PyObject_GetIter(object)))
                    + if (!(iterator = PyObject_GetIter(obj)))
                    return NULL;

                    while ((item = PyIter_Next(iterator)))
                    @@ -1975,7 +1975,7 @@
                    DictionaryPopItem(DictionaryObject *self)
                    {
                    hashitem_T *hi;
                    - PyObject *r;
                    + PyObject *ret;
                    PyObject *valObject;
                    dictitem_T *di;

                    @@ -1994,7 +1994,7 @@
                    if (!(valObject = ConvertToPyObject(&di->di_tv)))
                    return NULL;

                    - if (!(r = Py_BuildValue("(" Py_bytes_fmt "O)", hi->hi_key, valObject)))
                    + if (!(ret = Py_BuildValue("(" Py_bytes_fmt "O)", hi->hi_key, valObject)))
                    {
                    Py_DECREF(valObject);
                    return NULL;
                    @@ -2003,7 +2003,7 @@
                    hash_remove(&self->dict->dv_hashtab, hi);
                    dictitem_free(di);

                    - return r;
                    + return ret;
                    }

                    static PyObject *
                    @@ -2076,16 +2076,16 @@
                    static list_T *
                    py_list_alloc()
                    {
                    - list_T *r;
                    -
                    - if (!(r = list_alloc()))
                    + list_T *ret;
                    +
                    + if (!(ret = list_alloc()))
                    {
                    PyErr_NoMemory();
                    return NULL;
                    }
                    - ++r->lv_refcount;
                    -
                    - return r;
                    + ++ret->lv_refcount;
                    +
                    + return ret;
                    }

                    static int
                    @@ -2273,17 +2273,17 @@
                    static PyObject *
                    ListIterNext(listiterinfo_T **lii)
                    {
                    - PyObject *r;
                    + PyObject *ret;

                    if (!((*lii)->lw.lw_item))
                    return NULL;

                    - if (!(r = ConvertToPyObject(&((*lii)->lw.lw_item->li_tv))))
                    + if (!(ret = ConvertToPyObject(&((*lii)->lw.lw_item->li_tv))))
                    return NULL;

                    (*lii)->lw.lw_item = (*lii)->lw.lw_item->li_next;

                    - return r;
                    + return ret;
                    }

                    static PyObject *
                    @@ -2320,7 +2320,7 @@
                    RAISE_LOCKED_LIST;
                    return -1;
                    }
                    - if (index>length || (index==length && obj==NULL))
                    + if (index > length || (index == length && obj == NULL))
                    {
                    PyErr_SET_STRING(PyExc_IndexError, "list index out of range");
                    return -1;
                    @@ -2464,9 +2464,9 @@
                    }

                    static int
                    -ListSetattr(ListObject *self, char *name, PyObject *val)
                    -{
                    - if (val == NULL)
                    +ListSetattr(ListObject *self, char *name, PyObject *valObject)
                    +{
                    + if (valObject == NULL)
                    {
                    PyErr_SET_STRING(PyExc_AttributeError,
                    "cannot delete vim.List attributes");
                    @@ -2482,7 +2482,7 @@
                    }
                    else
                    {
                    - int istrue = PyObject_IsTrue(val);
                    + int istrue = PyObject_IsTrue(valObject);
                    if (istrue == -1)
                    return -1;
                    else if (istrue)
                    @@ -2600,7 +2600,7 @@
                    typval_T rettv;
                    dict_T *selfdict = NULL;
                    PyObject *selfdictObject;
                    - PyObject *result;
                    + PyObject *ret;
                    int error;

                    if (ConvertFromPyObject(argsObject, &args) == -1)
                    @@ -2630,21 +2630,21 @@
                    Py_END_ALLOW_THREADS

                    if (VimTryEnd())
                    - result = NULL;
                    + ret = NULL;
                    else if (error != OK)
                    {
                    - result = NULL;
                    + ret = NULL;
                    PyErr_VIM_FORMAT("failed to run function %s", (char *)name);
                    }
                    else
                    - result = ConvertToPyObject(&rettv);
                    + ret = ConvertToPyObject(&rettv);

                    clear_tv(&args);
                    clear_tv(&rettv);
                    if (selfdict != NULL)
                    clear_tv(&selfdicttv);

                    - return result;
                    + return ret;
                    }

                    static PyObject *
                    @@ -2762,10 +2762,10 @@
                    }
                    else if (flags & SOPT_BOOL)
                    {
                    - PyObject *r;
                    - r = numval ? Py_True : Py_False;
                    - Py_INCREF(r);
                    - return r;
                    + PyObject *ret;
                    + ret = numval ? Py_True : Py_False;
                    + Py_INCREF(ret);
                    + return ret;
                    }
                    else if (flags & SOPT_NUM)
                    return PyInt_FromLong(numval);
                    @@ -2773,9 +2773,9 @@
                    {
                    if (stringval)
                    {
                    - PyObject *r = PyBytes_FromString((char *) stringval);
                    + PyObject *ret = PyBytes_FromString((char *) stringval);
                    vim_free(stringval);
                    - return r;
                    + return ret;
                    }
                    else
                    {
                    @@ -2818,7 +2818,7 @@
                    win_T *save_curwin = NULL;
                    tabpage_T *save_curtab = NULL;
                    buf_T *save_curbuf = NULL;
                    - int r = 0;
                    + int set_ret = 0;

                    VimTryStart();
                    switch (opt_type)
                    @@ -2832,24 +2832,20 @@
                    PyErr_SET_VIM("problem while switching windows");
                    return -1;
                    }
                    - r = set_option_value_err(key, numval, stringval, opt_flags);
                    - restore_win(save_curwin, save_curtab, FALSE);
                    - if (r == FAIL)
                    - return -1;
                    + set_ret = set_option_value_err(key, numval, stringval, opt_flags);
                    + restore_win(save_curwin, save_curtab, TRUE);
                    break;
                    case SREQ_BUF:
                    switch_buffer(&save_curbuf, (buf_T *)from);
                    - r = set_option_value_err(key, numval, stringval, opt_flags);
                    + set_ret = set_option_value_err(key, numval, stringval, opt_flags);
                    restore_buffer(save_curbuf);
                    - if (r == FAIL)
                    - return -1;
                    break;
                    case SREQ_GLOBAL:
                    - r = set_option_value_err(key, numval, stringval, opt_flags);
                    - if (r == FAIL)
                    - return -1;
                    + set_ret = set_option_value_err(key, numval, stringval, opt_flags);
                    break;
                    }
                    + if (set_ret == FAIL)
                    + return -1;
                    return VimTryEnd();
                    }

                    @@ -2859,7 +2855,7 @@
                    char_u *key;
                    int flags;
                    int opt_flags;
                    - int r = 0;
                    + int ret = 0;
                    PyObject *todecref;

                    if (self->Check(self->from))
                    @@ -2917,9 +2913,9 @@
                    int istrue = PyObject_IsTrue(valObject);

                    if (istrue == -1)
                    - r = -1;
                    + ret = -1;
                    else
                    - r = set_option_value_for(key, istrue, NULL,
                    + ret = set_option_value_for(key, istrue, NULL,
                    opt_flags, self->opt_type, self->from);
                    }
                    else if (flags & SOPT_NUM)
                    @@ -2932,24 +2928,24 @@
                    return -1;
                    }

                    - r = set_option_value_for(key, (int) val, NULL, opt_flags,
                    + ret = set_option_value_for(key, (int) val, NULL, opt_flags,
                    self->opt_type, self->from);
                    }
                    else
                    {
                    - char_u *val;
                    + char_u *val;
                    PyObject *todecref;

                    if ((val = StringToChars(valObject, &todecref)))
                    - r = set_option_value_for(key, 0, val, opt_flags,
                    + ret = set_option_value_for(key, 0, val, opt_flags,
                    self->opt_type, self->from);
                    else
                    - r = -1;
                    + ret = -1;
                    }

                    Py_XDECREF(todecref);

                    - return r;
                    + return ret;
                    }

                    static PyMappingMethods OptionsAsMapping = {
                    @@ -3028,14 +3024,14 @@
                    static PyObject *
                    TabPageAttrValid(TabPageObject *self, char *name)
                    {
                    - PyObject *r;
                    + PyObject *ret;

                    if (strcmp(name, "valid") != 0)
                    return NULL;

                    - r = ((self->tab == INVALID_TABPAGE_VALUE) ? Py_False : Py_True);
                    - Py_INCREF(r);
                    - return r;
                    + ret = ((self->tab == INVALID_TABPAGE_VALUE) ? Py_False : Py_True);
                    + Py_INCREF(ret);
                    + return ret;
                    }

                    static PyObject *
                    @@ -3243,14 +3239,14 @@
                    static PyObject *
                    WindowAttrValid(WindowObject *self, char *name)
                    {
                    - PyObject *r;
                    + PyObject *ret;

                    if (strcmp(name, "valid") != 0)
                    return NULL;

                    - r = ((self->win == INVALID_WINDOW_VALUE) ? Py_False : Py_True);
                    - Py_INCREF(r);
                    - return r;
                    + ret = ((self->win == INVALID_WINDOW_VALUE) ? Py_False : Py_True);
                    + Py_INCREF(ret);
                    + return ret;
                    }

                    static PyObject *
                    @@ -3300,7 +3296,7 @@
                    }

                    static int
                    -WindowSetattr(WindowObject *self, char *name, PyObject *val)
                    +WindowSetattr(WindowObject *self, char *name, PyObject *valObject)
                    {
                    if (CheckWindow(self))
                    return -1;
                    @@ -3315,7 +3311,7 @@
                    long lnum;
                    long col;

                    - if (!PyArg_Parse(val, "(ll)", &lnum, &col))
                    + if (!PyArg_Parse(valObject, "(ll)", &lnum, &col))
                    return -1;

                    if (lnum <= 0 || lnum > self->win->w_buffer->b_ml.ml_line_count)
                    @@ -3344,7 +3340,7 @@
                    long height;
                    win_T *savewin;

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

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

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

                    #ifdef FEAT_GUI
                    @@ -3584,25 +3580,26 @@
                    static PyObject *
                    GetBufferLineList(buf_T *buf, PyInt lo, PyInt hi)
                    {
                    - PyInt i;
                    - PyInt n = hi - lo;
                    - PyObject *list = PyList_New(n);
                    + PyInt i;
                    + PyInt n = hi - lo;
                    + PyObject *list = PyList_New(n);

                    if (list == NULL)
                    return NULL;

                    for (i = 0; i < n; ++i)
                    {
                    - PyObject *str = LineToString((char *)ml_get_buf(buf, (linenr_T)(lo+i), FALSE));
                    + PyObject *string = LineToString(
                    + (char *)ml_get_buf(buf, (linenr_T)(lo+i), FALSE));

                    /* Error check - was the Python string creation OK? */
                    - if (str == NULL)
                    + if (string == NULL)
                    {
                    Py_DECREF(list);
                    return NULL;
                    }

                    - PyList_SET_ITEM(list, i, str);
                    + PyList_SET_ITEM(list, i, string);
                    }

                    /* The ownership of the Python list is passed to the caller (ie,
                    @@ -3662,7 +3659,7 @@
                    */
                    if (line == Py_None || line == NULL)
                    {
                    - buf_T *savebuf;
                    + buf_T *savebuf;

                    PyErr_Clear();
                    switch_buffer(&savebuf, buf);
                    @@ -3747,7 +3744,12 @@
                    * is set to the change in the buffer length.
                    */
                    static int
                    -SetBufferLineList(buf_T *buf, PyInt lo, PyInt hi, PyObject *list, PyInt *len_change)
                    +SetBufferLineList(
                    + buf_T *buf,
                    + PyInt lo,
                    + PyInt hi,
                    + PyObject *list,
                    + PyInt *len_change)
                    {
                    /* First of all, we check the type of the supplied Python object.
                    * There are three cases:
                    @@ -4124,7 +4126,13 @@
                    }

                    static PyInt
                    -RBAsItem(BufferObject *self, PyInt n, PyObject *val, PyInt start, PyInt end, PyInt *new_end)
                    +RBAsItem(
                    + BufferObject *self,
                    + PyInt n,
                    + PyObject *valObject,
                    + PyInt start,
                    + PyInt end,
                    + PyInt *new_end)
                    {
                    PyInt len_change;

                    @@ -4143,7 +4151,7 @@
                    return -1;
                    }

                    - if (SetBufferLine(self->buf, n+start, val, &len_change) == FAIL)
                    + if (SetBufferLine(self->buf, n+start, valObject, &len_change) == FAIL)
                    return -1;

                    if (new_end)
                    @@ -4153,7 +4161,14 @@
                    }

                    static PyInt
                    -RBAsSlice(BufferObject *self, PyInt lo, PyInt hi, PyObject *val, PyInt start, PyInt end, PyInt *new_end)
                    +RBAsSlice(
                    + BufferObject *self,
                    + PyInt lo,
                    + PyInt hi,
                    + PyObject *valObject,
                    + PyInt start,
                    + PyInt end,
                    + PyInt *new_end)
                    {
                    PyInt size;
                    PyInt len_change;
                    @@ -4180,7 +4195,7 @@
                    hi = size;

                    if (SetBufferLineList(self->buf, lo + start, hi + start,
                    - val, &len_change) == FAIL)
                    + valObject, &len_change) == FAIL)
                    return -1;

                    if (new_end)
                    @@ -4191,7 +4206,12 @@


                    static PyObject *
                    -RBAppend(BufferObject *self, PyObject *args, PyInt start, PyInt end, PyInt *new_end)
                    +RBAppend(
                    + BufferObject *self,
                    + PyObject *args,
                    + PyInt start,
                    + PyInt end,
                    + PyInt *new_end)
                    {
                    PyObject *lines;
                    PyInt len_change;
                    @@ -4438,14 +4458,14 @@
                    static PyObject *
                    BufferAttrValid(BufferObject *self, char *name)
                    {
                    - PyObject *r;
                    + PyObject *ret;

                    if (strcmp(name, "valid") != 0)
                    return NULL;

                    - r = ((self->buf == INVALID_BUFFER_VALUE) ? Py_False : Py_True);
                    - Py_INCREF(r);
                    - return r;
                    + ret = ((self->buf == INVALID_BUFFER_VALUE) ? Py_False : Py_True);
                    + Py_INCREF(ret);
                    + return ret;
                    }

                    static PyObject *
                    @@ -4475,9 +4495,9 @@

                    if (strcmp(name, "name") == 0)
                    {
                    - char_u *val;
                    + char_u *val;
                    aco_save_T aco;
                    - int r;
                    + int ren_ret;
                    PyObject *todecref;

                    if (!(val = StringToChars(valObject, &todecref)))
                    @@ -4486,13 +4506,13 @@
                    VimTryStart();
                    /* Using aucmd_*: autocommands will be executed by rename_buffer */
                    aucmd_prepbuf(&aco, self->buf);
                    - r = rename_buffer(val);
                    + ren_ret = rename_buffer(val);
                    aucmd_restbuf(&aco);
                    Py_XDECREF(todecref);
                    if (VimTryEnd())
                    return -1;

                    - if (r == FAIL)
                    + if (ren_ret == FAIL)
                    {
                    PyErr_SET_VIM("failed to rename buffer");
                    return -1;
                    @@ -4677,27 +4697,27 @@
                    BufMapIterNext(PyObject **buffer)
                    {
                    PyObject *next;
                    - PyObject *r;
                    + PyObject *ret;

                    if (!*buffer)
                    return NULL;

                    - r = *buffer;
                    -
                    - if (CheckBuffer((BufferObject *)(r)))
                    + ret = *buffer;
                    +
                    + if (CheckBuffer((BufferObject *)(ret)))
                    {
                    *buffer = NULL;
                    return NULL;
                    }

                    - if (!((BufferObject *)(r))->buf->b_next)
                    + if (!((BufferObject *)(ret))->buf->b_next)
                    next = NULL;
                    - else if (!(next = BufferNew(((BufferObject *)(r))->buf->b_next)))
                    + else if (!(next = BufferNew(((BufferObject *)(ret))->buf->b_next)))
                    return NULL;
                    *buffer = next;
                    /* Do not increment reference: we no longer hold it (decref), but whoever
                    * on other side will hold (incref). Decref+incref = nothing. */
                    - return r;
                    + return ret;
                    }

                    static PyObject *
                    @@ -4755,11 +4775,12 @@
                    }

                    static int
                    -CurrentSetattr(PyObject *self UNUSED, char *name, PyObject *value)
                    +CurrentSetattr(PyObject *self UNUSED, char *name, PyObject *valObject)
                    {
                    if (strcmp(name, "line") == 0)
                    {
                    - if (SetBufferLine(curbuf, (PyInt)curwin->w_cursor.lnum, value, NULL) == FAIL)
                    + if (SetBufferLine(curbuf, (PyInt)curwin->w_cursor.lnum, valObject,
                    + NULL) == FAIL)
                    return -1;

                    return 0;
                    @@ -4768,17 +4789,17 @@
                    {
                    int count;

                    - if (value->ob_type != &BufferType)
                    + if (valObject->ob_type != &BufferType)
                    {
                    PyErr_FORMAT(PyExc_TypeError,
                    "expected vim.Buffer object, but got %s",
                    - Py_TYPE_NAME(value));
                    + Py_TYPE_NAME(valObject));
                    return -1;
                    }

                    - if (CheckBuffer((BufferObject *)(value)))
                    + if (CheckBuffer((BufferObject *)(valObject)))
                    return -1;
                    - count = ((BufferObject *)(value))->buf->b_fnum;
                    + count = ((BufferObject *)(valObject))->buf->b_fnum;

                    VimTryStart();
                    if (do_buffer(DOBUF_GOTO, DOBUF_FIRST, FORWARD, count, 0) == FAIL)
                    @@ -4795,17 +4816,17 @@
                    {
                    int count;

                    - if (value->ob_type != &WindowType)
                    + if (valObject->ob_type != &WindowType)
                    {
                    PyErr_FORMAT(PyExc_TypeError,
                    "expected vim.Window object, but got %s",
                    - Py_TYPE_NAME(value));
                    + Py_TYPE_NAME(valObject));
                    return -1;
                    }

                    - if (CheckWindow((WindowObject *)(value)))
                    + if (CheckWindow((WindowObject *)(valObject)))
                    return -1;
                    - count = get_win_number(((WindowObject *)(value))->win, firstwin);
                    + count = get_win_number(((WindowObject *)(valObject))->win, firstwin);

                    if (!count)
                    {
                    @@ -4815,8 +4836,8 @@
                    }

                    VimTryStart();
                    - win_goto(((WindowObject *)(value))->win);
                    - if (((WindowObject *)(value))->win != curwin)
                    + win_goto(((WindowObject *)(valObject))->win);
                    + if (((WindowObject *)(valObject))->win != curwin)
                    {
                    if (VimTryEnd())
                    return -1;
                    @@ -4829,20 +4850,20 @@
                    }
                    else if (strcmp(name, "tabpage") == 0)
                    {
                    - if (value->ob_type != &TabPageType)
                    + if (valObject->ob_type != &TabPageType)
                    {
                    PyErr_FORMAT(PyExc_TypeError,
                    "expected vim.TabPage object, but got %s",
                    - Py_TYPE_NAME(value));
                    + Py_TYPE_NAME(valObject));
                    return -1;
                    }

                    - if (CheckTabPage((TabPageObject *)(value)))
                    + if (CheckTabPage((TabPageObject *)(valObject)))
                    return -1;

                    VimTryStart();
                    - goto_tabpage_tp(((TabPageObject *)(value))->tab, TRUE, TRUE);
                    - if (((TabPageObject *)(value))->tab != curtab)
                    + goto_tabpage_tp(((TabPageObject *)(valObject))->tab, TRUE, TRUE);
                    + if (((TabPageObject *)(valObject))->tab != curtab)
                    {
                    if (VimTryEnd())
                    return -1;
                    @@ -4934,7 +4955,9 @@

                    for (lnum = RangeStart; lnum <= RangeEnd; ++lnum)
                    {
                    - PyObject *line, *linenr, *ret;
                    + PyObject *line;
                    + PyObject *linenr;
                    + PyObject *ret;

                    #ifdef PY_CAN_RECURSE
                    *pygilstate = PyGILState_Ensure();
                    @@ -4990,10 +5013,10 @@
                    #endif
                    )
                    {
                    - PyObject *r;
                    -
                    - r = PyRun_String((char *) cmd, Py_eval_input, globals, globals);
                    - if (r == NULL)
                    + PyObject *run_ret;
                    +
                    + run_ret = PyRun_String((char *) cmd, Py_eval_input, globals, globals);
                    + if (run_ret == NULL)
                    {
                    if (PyErr_Occurred() && !msg_silent)
                    PyErr_PrintEx(0);
                    @@ -5001,9 +5024,9 @@
                    }
                    else
                    {
                    - if (ConvertFromPyObject(r, rettv) == -1)
                    + if (ConvertFromPyObject(run_ret, rettv) == -1)
                    EMSG(_("E859: Failed to convert returned python object to vim value"));
                    - Py_DECREF(r);
                    + Py_DECREF(run_ret);
                    }
                    PyErr_Clear();
                    }
                    @@ -5306,7 +5329,7 @@
                    ConvertFromPyMapping(PyObject *obj, typval_T *tv)
                    {
                    PyObject *lookup_dict;
                    - int r;
                    + int ret;

                    if (!(lookup_dict = PyDict_New()))
                    return -1;
                    @@ -5316,34 +5339,34 @@
                    tv->v_type = VAR_DICT;
                    tv->vval.v_dict = (((DictionaryObject *)(obj))->dict);
                    ++tv->vval.v_dict->dv_refcount;
                    - r = 0;
                    + ret = 0;
                    }
                    else if (PyDict_Check(obj))
                    - r = convert_dl(obj, tv, pydict_to_tv, lookup_dict);
                    + ret = convert_dl(obj, tv, pydict_to_tv, lookup_dict);
                    else if (PyMapping_Check(obj))
                    - r = convert_dl(obj, tv, pymap_to_tv, lookup_dict);
                    + ret = convert_dl(obj, tv, pymap_to_tv, lookup_dict);
                    else
                    {
                    PyErr_FORMAT(PyExc_TypeError,
                    "unable to convert %s to vim dictionary",
                    Py_TYPE_NAME(obj));
                    - r = -1;
                    + ret = -1;
                    }
                    Py_DECREF(lookup_dict);
                    - return r;
                    + return ret;
                    }

                    static int
                    ConvertFromPyObject(PyObject *obj, typval_T *tv)
                    {
                    PyObject *lookup_dict;
                    - int r;
                    + int ret;

                    if (!(lookup_dict = PyDict_New()))
                    return -1;
                    - r = _ConvertFromPyObject(obj, tv, lookup_dict);
                    + ret = _ConvertFromPyObject(obj, tv, lookup_dict);
                    Py_DECREF(lookup_dict);
                    - return r;
                    + return ret;
                    }

                    static int
                    @@ -5371,14 +5394,14 @@
                    }
                    else if (PyBytes_Check(obj))
                    {
                    - char_u *result;
                    -
                    - if (PyBytes_AsStringAndSize(obj, (char **) &result, NULL) == -1)
                    + char_u *str;
                    +
                    + if (PyBytes_AsStringAndSize(obj, (char **) &str, NULL) == -1)
                    return -1;
                    - if (result == NULL)
                    + if (str == NULL)
                    return -1;

                    - if (set_string_copy(result, tv) == -1)
                    + if (set_string_copy(str, tv) == -1)
                    return -1;

                    tv->v_type = VAR_STRING;
                    @@ -5386,18 +5409,18 @@
                    else if (PyUnicode_Check(obj))
                    {
                    PyObject *bytes;
                    - char_u *result;
                    + char_u *str;

                    bytes = PyUnicode_AsEncodedString(obj, ENC_OPT, NULL);
                    if (bytes == NULL)
                    return -1;

                    - if(PyBytes_AsStringAndSize(bytes, (char **) &result, NULL) == -1)
                    + if(PyBytes_AsStringAndSize(bytes, (char **) &str, NULL) == -1)
                    return -1;
                    - if (result == NULL)
                    + if (str == NULL)
                    return -1;

                    - if (set_string_copy(result, tv))
                    + if (set_string_copy(str, tv))
                    {
                    Py_XDECREF(bytes);
                    return -1;
                    @@ -5852,7 +5875,7 @@

                    static struct numeric_constant {
                    char *name;
                    - int value;
                    + int val;
                    } numeric_constants[] = {
                    {"VAR_LOCKED", VAR_LOCKED},
                    {"VAR_FIXED", VAR_FIXED},
                    @@ -5862,7 +5885,7 @@

                    static struct object_constant {
                    char *name;
                    - PyObject *value;
                    + PyObject *valObject;
                    } object_constants[] = {
                    {"buffers", (PyObject *)(void *)&TheBufferMap},
                    {"windows", (PyObject *)(void *)&TheWindowList},
                    @@ -5889,10 +5912,10 @@

                    #define ADD_CHECKED_OBJECT(m, name, obj) \
                    { \
                    - PyObject *value = obj; \
                    - if (!value) \
                    + PyObject *valObject = obj; \
                    + if (!valObject) \
                    return -1; \
                    - ADD_OBJECT(m, name, value); \
                    + ADD_OBJECT(m, name, valObject); \
                    }

                    static int
                    @@ -5907,17 +5930,17 @@
                    / sizeof(struct numeric_constant));
                    ++i)
                    ADD_CHECKED_OBJECT(m, numeric_constants[i].name,
                    - PyInt_FromLong(numeric_constants[i].value));
                    + PyInt_FromLong(numeric_constants[i].val));

                    for (i = 0; i < (int)(sizeof(object_constants)
                    / sizeof(struct object_constant));
                    ++i)
                    {
                    - PyObject *value;
                    -
                    - value = object_constants[i].value;
                    - Py_INCREF(value);
                    - ADD_OBJECT(m, object_constants[i].name, value);
                    + PyObject *valObject;
                    +
                    + valObject = object_constants[i].valObject;
                    + Py_INCREF(valObject);
                    + ADD_OBJECT(m, object_constants[i].name, valObject);
                    }

                    if (!(VimError = PyErr_NewException("vim.error", NULL, 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.
                  • ZyX
                    # HG changeset patch # User ZyX # Date 1371407889 -14400 # Sun Jun 16 22:38:09 2013 +0400 # Branch python-fixes # Node ID
                    Message 9 of 25 , Jun 16, 2013
                    • 0 Attachment
                      # HG changeset patch
                      # User ZyX <kp-pav@...>
                      # Date 1371407889 -14400
                      # Sun Jun 16 22:38:09 2013 +0400
                      # Branch python-fixes
                      # Node ID 4a00cd941a883917f6d740f9f06aca7baadcb45e
                      # Parent e4cfe82588f5203b9dfd71e1d8668f2f1900f72a
                      Some fixes:

                      - Fixed VimTryEnd: it used to stop processing of the subsequent lines if E***
                      error messages were thrown
                      - Fixed crash with debug build and PYTHONDUMPREFS=1: for some reason self->name
                      in function may be NULL
                      - Fixed two memory leaks in StringToLine (in case string contains newlines and
                      in case there is no memory left)
                      - Fixed memory leak in BufferMark (in case argument is not a single character)
                      - Fixed memory leak in convert_dl (always when complex structure encountered)

                      - Made tests run 10 times in case PYTHONDUMPREFS=1 is set (I have not checked
                      though whether tests succeed in this case: always launched them without make)
                      - Made tests delete variables just after they are no longer used
                      - Made tests use abc{C} in place of just abc: helps to determine exactly which
                      abc did leak

                      - Made ConvertFromPyObject also treat subclasses of vim.Function and vim.List
                      type as the types themselves like it already does with vim.Dictionary

                      diff -r e4cfe82588f5 -r 4a00cd941a88 src/if_py_both.h
                      --- a/src/if_py_both.h Sun Jun 16 19:17:07 2013 +0400
                      +++ b/src/if_py_both.h Sun Jun 16 22:38:09 2013 +0400
                      @@ -545,20 +545,30 @@
                      VimTryEnd(void)
                      {
                      --trylevel;
                      + /* Without this it stops processing all subsequent VimL commands and
                      + * generates strange error messages if I e.g. try calling Test() in a cycle */
                      + did_emsg = FALSE;
                      + /* Keyboard interrupt should be preferred over anything else */
                      if (got_int)
                      {
                      + did_throw = got_int = FALSE;
                      PyErr_SetNone(PyExc_KeyboardInterrupt);
                      - return 1;
                      + return -1;
                      }
                      else if (!did_throw)
                      - return 0;
                      + return (PyErr_Occurred() ? -1 : 0);
                      + /* Python exception is preferred over vim one; unlikely to occur though */
                      else if (PyErr_Occurred())
                      - return 1;
                      + {
                      + did_throw = FALSE;
                      + return -1;
                      + }
                      + /* Finally transform VimL exception to python one */
                      else
                      {
                      PyErr_SetVim((char *) current_exception->value);
                      discard_current_exception();
                      - return 1;
                      + return -1;
                      }
                      }

                      @@ -2650,7 +2660,14 @@
                      static PyObject *
                      FunctionRepr(FunctionObject *self)
                      {
                      - return PyString_FromFormat("<vim.Function '%s'>", self->name);
                      +#ifdef Py_TRACE_REFS
                      + /* For unknown reason self->name may be NULL after calling
                      + * Finalize */
                      + return PyString_FromFormat("<vim.Function '%s'>",
                      + (self->name == NULL ? "<NULL>" : (char *) self->name));
                      +#else
                      + return PyString_FromFormat("<vim.Function '%s'>", (char *) self->name);
                      +#endif
                      }

                      static struct PyMethodDef FunctionMethods[] = {
                      @@ -3534,6 +3551,7 @@
                      else
                      {
                      PyErr_SET_VIM("string cannot contain newlines");
                      + Py_XDECREF(bytes);
                      return NULL;
                      }
                      }
                      @@ -3545,6 +3563,7 @@
                      if (save == NULL)
                      {
                      PyErr_NoMemory();
                      + Py_XDECREF(bytes);
                      return NULL;
                      }

                      @@ -4551,6 +4570,7 @@
                      {
                      PyErr_SET_STRING(PyExc_ValueError,
                      "mark name must be a single character");
                      + Py_XDECREF(todecref);
                      return NULL;
                      }

                      @@ -5298,6 +5318,9 @@
                      tv->v_type = VAR_UNKNOWN;
                      return -1;
                      }
                      +
                      + Py_DECREF(capsule);
                      +
                      if (py_to_tv(obj, tv, lookup_dict) == -1)
                      {
                      tv->v_type = VAR_UNKNOWN;
                      @@ -5378,13 +5401,13 @@
                      tv->vval.v_dict = (((DictionaryObject *)(obj))->dict);
                      ++tv->vval.v_dict->dv_refcount;
                      }
                      - else if (obj->ob_type == &ListType)
                      + else if (PyType_IsSubtype(obj->ob_type, &ListType))
                      {
                      tv->v_type = VAR_LIST;
                      tv->vval.v_list = (((ListObject *)(obj))->list);
                      ++tv->vval.v_list->lv_refcount;
                      }
                      - else if (obj->ob_type == &FunctionType)
                      + else if (PyType_IsSubtype(obj->ob_type, &FunctionType))
                      {
                      if (set_string_copy(((FunctionObject *) (obj))->name, tv) == -1)
                      return -1;
                      diff -r e4cfe82588f5 -r 4a00cd941a88 src/testdir/test86.in
                      --- a/src/testdir/test86.in Sun Jun 16 19:17:07 2013 +0400
                      +++ b/src/testdir/test86.in Sun Jun 16 22:38:09 2013 +0400
                      @@ -11,8 +11,8 @@
                      :set noswapfile
                      :if !has('python') | e! test.ok | wq! test.out | endif
                      :lang C
                      +:fun Test()
                      :py import vim
                      -:fun Test()
                      :let l = []
                      :py l=vim.bindeval('l')
                      :py f=vim.bindeval('function("strlen")')
                      @@ -58,6 +58,9 @@
                      : $put =string(key) . ' : ' . string(Val)
                      : unlet key Val
                      :endfor
                      +:py del dk
                      +:py del di
                      +:py del dv
                      :"
                      :" removing items with del
                      :py del l[2]
                      @@ -176,12 +179,12 @@
                      :unlockvar! l
                      :"
                      :" Function calls
                      -:function New(...)
                      -:return ['NewStart']+a:000+['NewEnd']
                      -:endfunction
                      -:function DictNew(...) dict
                      -:return ['DictNewStart']+a:000+['DictNewEnd', self]
                      -:endfunction
                      +:fun New(...)
                      +: return ['NewStart']+a:000+['NewEnd']
                      +:endfun
                      +:fun DictNew(...) dict
                      +: return ['DictNewStart']+a:000+['DictNewEnd', self]
                      +:endfun
                      :let l=[function('New'), function('DictNew')]
                      :py l=vim.bindeval('l')
                      :py l.extend(list(l[0](1, 2, 3)))
                      @@ -211,6 +214,7 @@
                      : $put ='[0.0, 0.0]'
                      :endif
                      :let messages=[]
                      +:delfunction DictNew
                      py <<EOF
                      d=vim.bindeval('{}')
                      m=vim.bindeval('messages')
                      @@ -220,15 +224,17 @@
                      except:
                      m.extend([sys.exc_type.__name__])

                      -em('d["abc"]')
                      -em('d["abc"]="\\0"')
                      -em('d["abc"]=vim')
                      +em('d["abc1"]')
                      +em('d["abc1"]="\\0"')
                      +em('d["abc1"]=vim')
                      em('d[""]=1')
                      em('d["a\\0b"]=1')
                      em('d[u"a\\0b"]=1')

                      -em('d.pop("abc")')
                      +em('d.pop("abc1")')
                      em('d.popitem()')
                      +del em
                      +del m
                      EOF
                      :$put =messages
                      :unlet messages
                      @@ -240,8 +246,8 @@
                      : let toput=s.' : '.join(map(['locked', 'scope'], 'v:val.":".pyeval(name.".".v:val)'), ';')
                      : $put =toput
                      :endfor
                      -:silent! let d.abc=1
                      -:silent! let dl.abc=1
                      +:silent! let d.abc2=1
                      +:silent! let dl.abc3=1
                      :py d.locked=True
                      :py dl.locked=False
                      :silent! let d.def=1
                      @@ -307,12 +313,15 @@
                      time.sleep(0.1)

                      t = T()
                      +del T
                      t.start()
                      EOF
                      :sleep 1
                      :py t.running = False
                      :py t.join()
                      :py l[0] = t.t > 8 # check if the background thread is working
                      +:py del time
                      +:py del threading
                      :$put =string(l)
                      :"
                      :" settrace
                      @@ -333,6 +342,8 @@
                      EOF
                      :py sys.settrace(traceit)
                      :py trace_main()
                      +:py del traceit
                      +:py del trace_main
                      :py sys.settrace(None)
                      :$put =string(l)
                      :"
                      @@ -363,7 +374,7 @@
                      :"
                      :" Vars
                      :let g:foo = 'bac'
                      -:let w:abc = 'def'
                      +:let w:abc3 = 'def'
                      :let b:baz = 'bar'
                      :let t:bar = 'jkl'
                      :try
                      @@ -372,7 +383,7 @@
                      : put =pyeval('vim.vvars[''exception'']')
                      :endtry
                      :put =pyeval('vim.vars[''foo'']')
                      -:put =pyeval('vim.current.window.vars[''abc'']')
                      +:put =pyeval('vim.current.window.vars[''abc3'']')
                      :put =pyeval('vim.current.buffer.vars[''baz'']')
                      :put =pyeval('vim.current.tabpage.vars[''bar'']')
                      :"
                      @@ -420,16 +431,16 @@
                      vim.command('let exc=' + repr(sys.exc_type.__name__))
                      return 0
                      EOF
                      -:function E(s)
                      +:fun E(s)
                      : python e(vim.eval('a:s'))
                      -:endfunction
                      -:function Ev(s)
                      +:endfun
                      +:fun Ev(s)
                      : let r=pyeval('ev(vim.eval("a:s"))')
                      : if exists('exc')
                      : throw exc
                      : endif
                      : return r
                      -:endfunction
                      +:endfun
                      :py gopts1=vim.options
                      :py wopts1=vim.windows[2].options
                      :py wopts2=vim.windows[0].options
                      @@ -444,7 +455,7 @@
                      :let lst+=[['operatorfunc', 'A', 'B', 'C', 2, 0, 1, 0 ]]
                      :let lst+=[['number', 0, 1, 1, 0, 1, 0, 1 ]]
                      :let lst+=[['numberwidth', 2, 3, 5, -100, 0, 0, 1 ]]
                      -:let lst+=[['colorcolumn', '+1', '+2', '+3', 'abc', 0, 0, 1 ]]
                      +:let lst+=[['colorcolumn', '+1', '+2', '+3', 'abc4', 0, 0, 1 ]]
                      :let lst+=[['statusline', '1', '2', '4', 0, 0, 1, 1 ]]
                      :let lst+=[['autoindent', 0, 1, 1, 2, 1, 0, 2 ]]
                      :let lst+=[['shiftwidth', 0, 2, 1, 3, 0, 0, 2 ]]
                      @@ -494,10 +505,27 @@
                      : endfor
                      : call RecVars(oname)
                      :endfor
                      +:delfunction RecVars
                      +:delfunction E
                      +:delfunction Ev
                      +:py del ev
                      +:py del e
                      :only
                      :for buf in g:bufs[1:]
                      : execute 'bwipeout!' buf
                      :endfor
                      +:py del gopts1
                      +:py del wopts1
                      +:py del wopts2
                      +:py del wopts3
                      +:py del bopts1
                      +:py del bopts2
                      +:py del bopts3
                      +:py del oval1
                      +:py del oval2
                      +:py del oval3
                      +:py del oname
                      +:py del invval
                      :"
                      :" Test buffer object
                      :vnew
                      @@ -517,7 +545,7 @@
                      # Tests BufferAppend and BufferItem
                      cb.append(b[0])
                      # Tests BufferSlice and BufferAssSlice
                      -cb.append('abc') # Will be overwritten
                      +cb.append('abc5') # Will be overwritten
                      cb[-1:] = b[:-2]
                      # Test BufferLength and BufferAssSlice
                      cb.append('def') # Will not be overwritten
                      @@ -541,13 +569,14 @@
                      cb.append(b.name[-11:].replace(os.path.sep, '/'))
                      cb.name = old_name
                      cb.append(cb.name[-17:].replace(os.path.sep, '/'))
                      +del old_name
                      # Test CheckBuffer
                      for _b in vim.buffers:
                      if _b is not cb:
                      vim.command('bwipeout! ' + str(_b.number))
                      del _b
                      cb.append('valid: b:%s, cb:%s' % (repr(b.valid), repr(cb.valid)))
                      -for expr in ('b[1]','b[:] = ["A", "B"]','b[:]','b.append("abc")', 'b.name = "!"'):
                      +for expr in ('b[1]','b[:] = ["A", "B"]','b[:]','b.append("abc6")', 'b.name = "!"'):
                      try:
                      exec(expr)
                      except vim.error:
                      @@ -557,6 +586,7 @@
                      # Should not happen in any case
                      cb.append('No exception for ' + expr)
                      vim.command('cd .')
                      +del b
                      EOF
                      :augroup BUFS
                      : autocmd!
                      @@ -598,6 +628,7 @@
                      # Check indexing: vim.buffers[number].number == number
                      cb.append(str(b.number) + ':' + repr(vim.buffers[b.number]) + '=' + repr(b))
                      prevnum = b.number
                      +del prevnum

                      cb.append(str(len(vim.buffers)))

                      @@ -621,6 +652,8 @@
                      next(i4)
                      except StopIteration:
                      cb.append('StopIteration')
                      +del i4
                      +del bnums
                      EOF
                      :"
                      :" Test vim.{tabpage,window}list and vim.{tabpage,window} objects
                      @@ -663,7 +696,11 @@
                      raise ValueError
                      except Exception:
                      cb.append('!!!!!! Error while getting attribute ' + attr + ': ' + sys.exc_type.__name__)
                      + del aval
                      + del attr
                      w.cursor = (len(w.buffer), 0)
                      +del W
                      +del Cursor
                      cb.append('Number of windows in current tab page: ' + str(len(vim.windows)))
                      if list(vim.windows) != list(vim.current.tabpage.windows):
                      cb.append('!!!!!! Windows differ')
                      @@ -676,6 +713,7 @@
                      cb.append('Current tab page: ' + repr(vim.current.tabpage))
                      cb.append('Current window: ' + repr(vim.current.window) + ': ' + H(vim.current.window) + ' is ' + H(vim.current.tabpage.window))
                      cb.append('Current buffer: ' + repr(vim.current.buffer) + ': ' + H(vim.current.buffer) + ' is ' + H(vim.current.window.buffer)+ ' is ' + H(vim.current.tabpage.window.buffer))
                      +del H
                      # Assigning: fails
                      try:
                      vim.current.window = vim.tabpages[0].window
                      @@ -687,6 +725,7 @@
                      setattr(vim.current, attr, None)
                      except TypeError:
                      cb.append('Type error at assigning None to vim.current.' + attr)
                      +del attr

                      # Assigning: success
                      vim.current.tabpage = vim.tabpages[-2]
                      @@ -702,8 +741,13 @@
                      for b in vim.buffers:
                      if b is not cb:
                      vim.command('bwipeout! ' + str(b.number))
                      +del b
                      cb.append('w.valid: ' + repr([w.valid for w in ws]))
                      cb.append('t.valid: ' + repr([t.valid for t in ts]))
                      +del w
                      +del t
                      +del ts
                      +del ws
                      EOF
                      :tabonly!
                      :only!
                      @@ -722,6 +766,8 @@
                      ('vim.current.tabpage', 'TabPage'),
                      ):
                      cb.append(expr + ':' + attr + ':' + repr(type(eval(expr)) is getattr(vim, attr)))
                      +del expr
                      +del attr
                      EOF
                      :"
                      :" Test __dir__() method
                      @@ -747,15 +793,15 @@
                      :$put =string(pyeval('vim.Dictionary(a=1)'))
                      :$put =string(pyeval('vim.Dictionary(((''a'', 1),))'))
                      :$put =string(pyeval('vim.List()'))
                      -:$put =string(pyeval('vim.List(iter(''abc''))'))
                      +:$put =string(pyeval('vim.List(iter(''abc7''))'))
                      :$put =string(pyeval('vim.Function(''tr'')'))
                      :"
                      :" Test stdout/stderr
                      :redir => messages
                      -:py sys.stdout.write('abc') ; sys.stdout.write('def')
                      -:py sys.stderr.write('abc') ; sys.stderr.write('def')
                      -:py sys.stdout.writelines(iter('abc'))
                      -:py sys.stderr.writelines(iter('abc'))
                      +:py sys.stdout.write('abc8') ; sys.stdout.write('def')
                      +:py sys.stderr.write('abc9') ; sys.stderr.write('def')
                      +:py sys.stdout.writelines(iter('abcA'))
                      +:py sys.stderr.writelines(iter('abcB'))
                      :redir END
                      :$put =string(substitute(messages, '\d\+', '', 'g'))
                      :" Test subclassing
                      @@ -776,7 +822,7 @@
                      return [super(DupList, self).__getitem__(idx)] * 2

                      dl = DupList()
                      -dl2 = DupList(iter('abc'))
                      +dl2 = DupList(iter('abcC'))
                      dl.extend(dl2[0])

                      class DupFun(vim.Function):
                      @@ -789,6 +835,19 @@
                      :$put =string(pyeval('dl'))
                      :$put =string(pyeval('dl2'))
                      :$put =string(pyeval('df(2)'))
                      +:$put =string(pyeval('dl') is# pyeval('dl'))
                      +:$put =string(pyeval('dd') is# pyeval('dd'))
                      +:$put =string(pyeval('df'))
                      +:delfunction Put
                      +py << EOF
                      +del DupDict
                      +del DupList
                      +del DupFun
                      +del dd
                      +del dl
                      +del dl2
                      +del df
                      +EOF
                      :"
                      :" Test chdir
                      py << EOF
                      @@ -802,6 +861,7 @@
                      os.chdir('testdir')
                      cb.append(fnamemodify('.', ':p:h:t'))
                      cb.append(vim.eval('@%'))
                      +del fnamemodify
                      EOF
                      :"
                      :" Test errors
                      @@ -828,11 +888,11 @@
                      else:
                      cb.append(expr + ':NOT FAILED')
                      d = vim.Dictionary()
                      -ned = vim.Dictionary(foo='bar', baz='abc')
                      +ned = vim.Dictionary(foo='bar', baz='abcD')
                      dl = vim.Dictionary(a=1)
                      dl.locked = True
                      l = vim.List()
                      -ll = vim.List('abc')
                      +ll = vim.List('abcE')
                      ll.locked = True
                      f = vim.Function('string')
                      fd = vim.Function('F')
                      @@ -869,11 +929,11 @@
                      # pydict_to_tv
                      stringtochars_test(expr % '{%s : 1}')
                      if recurse:
                      - convertfrompyobject_test(expr % '{"abc" : %s}', False)
                      + convertfrompyobject_test(expr % '{"abcF" : %s}', False)
                      # pymap_to_tv
                      stringtochars_test(expr % 'Mapping({%s : 1})')
                      if recurse:
                      - convertfrompyobject_test(expr % 'Mapping({"abc" : %s})', False)
                      + convertfrompyobject_test(expr % 'Mapping({"abcG" : %s})', False)
                      # pyseq_to_tv
                      iter_test(expr)
                      return subexpr_test(expr, 'ConvertFromPyObject', (
                      @@ -916,7 +976,7 @@
                      raise NotImplementedError

                      def keys(self):
                      - return list("abc")
                      + return list("abcH")

                      class FailingMapping(object):
                      def __getitem__(self):
                      @@ -958,7 +1018,7 @@
                      ee('vim.strwidth(1)')
                      cb.append("> Dictionary")
                      cb.append(">> DictionaryConstructor")
                      -ee('vim.Dictionary("abc")')
                      +ee('vim.Dictionary("abcI")')
                      ##! Not checked: py_dict_alloc failure
                      cb.append(">> DictionarySetattr")
                      ee('del d.locked')
                      @@ -973,6 +1033,7 @@
                      ee('dl.pop("a")')
                      cb.append(">> DictionaryIterNext")
                      ee('for i in ned: ned["a"] = 1')
                      +del i
                      cb.append(">> DictionaryAssItem")
                      ee('dl["b"] = 1')
                      stringtochars_test('d[%s] = 1')
                      @@ -1002,7 +1063,7 @@
                      ee('ll[1] = 2')
                      ee('l[1000] = 3')
                      cb.append(">> ListAssSlice")
                      -ee('ll[1:100] = "abc"')
                      +ee('ll[1:100] = "abcJ"')
                      #iter_test('l[:] = %s')
                      convertfrompyobject_test('l[:] = [%s]')
                      cb.append(">> ListConcatInPlace")
                      @@ -1033,8 +1094,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 = "abc"')
                      -ee('vim.current.window.width = "abc"')
                      +ee('vim.current.window.height = "abcK"')
                      +ee('vim.current.window.width = "abcL"')
                      ee('vim.current.window.xxxxxx = True')
                      cb.append("> WinList")
                      cb.append(">> WinListItem")
                      @@ -1044,7 +1105,7 @@
                      ee('vim.current.buffer[0] = "\\na"')
                      cb.append(">> SetBufferLine (indirect)")
                      ee('vim.current.buffer[0] = True')
                      -cb.append(">> SetBufferLines (indirect)")
                      +cb.append(">> SetBufferLineList (indirect)")
                      ee('vim.current.buffer[:] = True')
                      ee('vim.current.buffer[:] = ["\\na", "bc"]')
                      cb.append(">> InsertBufferLines (indirect)")
                      @@ -1062,7 +1123,7 @@
                      ee('vim.current.buffer.xxx = True')
                      cb.append(">> BufferMark")
                      ee('vim.current.buffer.mark(0)')
                      -ee('vim.current.buffer.mark("abc")')
                      +ee('vim.current.buffer.mark("abcM")')
                      ee('vim.current.buffer.mark("!")')
                      cb.append(">> BufferRange")
                      ee('vim.current.buffer.range(1, 2, 3)')
                      @@ -1079,7 +1140,28 @@
                      ee('vim.current.window = True')
                      ee('vim.current.tabpage = True')
                      ee('vim.current.xxx = True')
                      +del d
                      +del ned
                      +del dl
                      +del l
                      +del ll
                      +del f
                      +del fd
                      +del fdel
                      +del subexpr_test
                      +del stringtochars_test
                      +del Mapping
                      +del convertfrompyobject_test
                      +del convertfrompymapping_test
                      +del iter_test
                      +del FailingTrue
                      +del FailingIter
                      +del FailingIterNext
                      +del FailingMapping
                      +del FailingMappingKey
                      +del FailingList
                      EOF
                      +:delfunction F
                      :"
                      :" Test import
                      py << EOF
                      @@ -1093,6 +1175,10 @@
                      cb.append(before.dir)
                      import after
                      cb.append(after.dir)
                      +del before
                      +del after
                      +del d
                      +del ddir
                      EOF
                      :"
                      :" Test exceptions
                      @@ -1101,18 +1187,48 @@
                      :endfun
                      py << EOF
                      Exe = vim.bindeval('function("Exe")')
                      -ee('vim.command("throw \'abc\'")')
                      +ee('vim.command("throw \'abcN\'")')
                      ee('Exe("throw \'def\'")')
                      ee('vim.eval("Exe(\'throw \'\'ghi\'\'\')")')
                      ee('vim.eval("Exe(\'echoerr \'\'jkl\'\'\')")')
                      ee('vim.eval("Exe(\'xxx_non_existent_command_xxx\')")')
                      ee('vim.bindeval("Exe(\'xxx_non_existent_command_xxx\')")')
                      +del Exe
                      +EOF
                      +:delfunction Exe
                      +:"
                      +:" Cleanup
                      +py << EOF
                      +del cb
                      +del ee
                      +del sys
                      +del os
                      +del vim
                      EOF
                      :endfun
                      :"
                      -:call Test()
                      +:fun RunTest()
                      +:let checkrefs = !empty($PYTHONDUMPREFS)
                      +:let start = getline(1, '$')
                      +:for i in range(checkrefs ? 10 : 1)
                      +: if i != 0
                      +: %d _
                      +: call setline(1, start)
                      +: endif
                      +: call Test()
                      +: if i == 0
                      +: let result = getline(1, '$')
                      +: endif
                      +:endfor
                      +:if checkrefs
                      +: %d _
                      +: call setline(1, result)
                      +:endif
                      +:endfun
                      :"
                      -:delfunc Test
                      +:call RunTest()
                      +:delfunction RunTest
                      +:delfunction Test
                      :call garbagecollect(1)
                      :"
                      :/^start:/,$wq! test.out
                      diff -r e4cfe82588f5 -r 4a00cd941a88 src/testdir/test86.ok
                      --- a/src/testdir/test86.ok Sun Jun 16 19:17:07 2013 +0400
                      +++ b/src/testdir/test86.ok Sun Jun 16 22:38:09 2013 +0400
                      @@ -68,7 +68,7 @@
                      dl : locked:1;scope:0
                      v: : locked:2;scope:1
                      g: : locked:0;scope:2
                      -d:{'abc': 1}
                      +d:{'abc2': 1}
                      dl:{'def': 1}
                      l : locked:0
                      ll : locked:1
                      @@ -202,12 +202,12 @@
                      B: 1:3 2:5 3:2 4:8
                      >>> colorcolumn
                      p/gopts1! KeyError
                      - inv: 'abc'! KeyError
                      + inv: 'abc4'! KeyError
                      gopts1! KeyError
                      p/wopts1: ''
                      - inv: 'abc'! error
                      + inv: 'abc4'! error
                      p/bopts1! KeyError
                      - inv: 'abc'! KeyError
                      + inv: 'abc4'! KeyError
                      bopts1! KeyError
                      bopts2! KeyError
                      bopts3! KeyError
                      @@ -415,20 +415,23 @@
                      {'a': 1}
                      {'a': 1}
                      []
                      -['a', 'b', 'c']
                      +['a', 'b', 'c', '7']
                      function('tr')
                      '
                      abcdef
                      line :
                      abcdef
                      -abc
                      +abcA
                      line :
                      -abc'
                      +abcB'
                      ['a', 'dup_a']
                      ['a', 'a']
                      -['a', 'b', 'c']
                      +['a', 'b', 'c', 'C']
                      [2, 2]
                      [2, 2]
                      +1
                      +1
                      +function('Put')
                      testdir
                      test86.in
                      src
                      @@ -456,7 +459,7 @@
                      vim.strwidth(1):TypeError:('expected str() or unicode() instance, but got int',)
                      > Dictionary
                      >> DictionaryConstructor
                      -vim.Dictionary("abc"):ValueError:('expected sequence element of size 2, but got sequence of size 1',)
                      +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:()
                      @@ -486,52 +489,52 @@
                      d["a"] = {u"\0" : 1}:TypeError:('expected string without null bytes',)
                      d["a"] = {"\0" : 1}:TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing StringToChars using d["a"] = {"abc" : {%s : 1}}
                      -d["a"] = {"abc" : {1 : 1}}:TypeError:('expected str() or unicode() instance, but got int',)
                      -d["a"] = {"abc" : {u"\0" : 1}}:TypeError:('expected string without null bytes',)
                      -d["a"] = {"abc" : {"\0" : 1}}:TypeError:('expected string without null bytes',)
                      +>>> Testing StringToChars using d["a"] = {"abcF" : {%s : 1}}
                      +d["a"] = {"abcF" : {1 : 1}}:TypeError:('expected str() or unicode() instance, but got int',)
                      +d["a"] = {"abcF" : {u"\0" : 1}}:TypeError:('expected string without null bytes',)
                      +d["a"] = {"abcF" : {"\0" : 1}}:TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing StringToChars using d["a"] = {"abc" : Mapping({%s : 1})}
                      -d["a"] = {"abc" : Mapping({1 : 1})}:TypeError:('expected str() or unicode() instance, but got int',)
                      -d["a"] = {"abc" : Mapping({u"\0" : 1})}:TypeError:('expected string without null bytes',)
                      -d["a"] = {"abc" : Mapping({"\0" : 1})}:TypeError:('expected string without null bytes',)
                      +>>> Testing StringToChars using d["a"] = {"abcF" : Mapping({%s : 1})}
                      +d["a"] = {"abcF" : Mapping({1 : 1})}:TypeError:('expected str() or unicode() instance, but got int',)
                      +d["a"] = {"abcF" : Mapping({u"\0" : 1})}:TypeError:('expected string without null bytes',)
                      +d["a"] = {"abcF" : Mapping({"\0" : 1})}:TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing *Iter* using d["a"] = {"abc" : %s}
                      -d["a"] = {"abc" : FailingIter()}:TypeError:('unable to convert FailingIter to vim structure',)
                      -d["a"] = {"abc" : FailingIterNext()}:NotImplementedError:()
                      +>>> Testing *Iter* using d["a"] = {"abcF" : %s}
                      +d["a"] = {"abcF" : FailingIter()}:TypeError:('unable to convert FailingIter to vim structure',)
                      +d["a"] = {"abcF" : FailingIterNext()}:NotImplementedError:()
                      <<< Finished
                      ->>> Testing ConvertFromPyObject using d["a"] = {"abc" : %s}
                      -d["a"] = {"abc" : None}:TypeError:('unable to convert NoneType to vim structure',)
                      -d["a"] = {"abc" : {"": 1}}:ValueError:('empty keys are not allowed',)
                      -d["a"] = {"abc" : {u"": 1}}:ValueError:('empty keys are not allowed',)
                      -d["a"] = {"abc" : FailingMapping()}:NotImplementedError:()
                      -d["a"] = {"abc" : FailingMappingKey()}:NotImplementedError:()
                      +>>> 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:()
                      <<< Finished
                      >>> Testing StringToChars using d["a"] = Mapping({%s : 1})
                      d["a"] = Mapping({1 : 1}):TypeError:('expected str() or unicode() instance, but got int',)
                      d["a"] = Mapping({u"\0" : 1}):TypeError:('expected string without null bytes',)
                      d["a"] = Mapping({"\0" : 1}):TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing StringToChars using d["a"] = Mapping({"abc" : {%s : 1}})
                      -d["a"] = Mapping({"abc" : {1 : 1}}):TypeError:('expected str() or unicode() instance, but got int',)
                      -d["a"] = Mapping({"abc" : {u"\0" : 1}}):TypeError:('expected string without null bytes',)
                      -d["a"] = Mapping({"abc" : {"\0" : 1}}):TypeError:('expected string without null bytes',)
                      +>>> Testing StringToChars using d["a"] = Mapping({"abcG" : {%s : 1}})
                      +d["a"] = Mapping({"abcG" : {1 : 1}}):TypeError:('expected str() or unicode() instance, but got int',)
                      +d["a"] = Mapping({"abcG" : {u"\0" : 1}}):TypeError:('expected string without null bytes',)
                      +d["a"] = Mapping({"abcG" : {"\0" : 1}}):TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing StringToChars using d["a"] = Mapping({"abc" : Mapping({%s : 1})})
                      -d["a"] = Mapping({"abc" : Mapping({1 : 1})}):TypeError:('expected str() or unicode() instance, but got int',)
                      -d["a"] = Mapping({"abc" : Mapping({u"\0" : 1})}):TypeError:('expected string without null bytes',)
                      -d["a"] = Mapping({"abc" : Mapping({"\0" : 1})}):TypeError:('expected string without null bytes',)
                      +>>> Testing StringToChars using d["a"] = Mapping({"abcG" : Mapping({%s : 1})})
                      +d["a"] = Mapping({"abcG" : Mapping({1 : 1})}):TypeError:('expected str() or unicode() instance, but got int',)
                      +d["a"] = Mapping({"abcG" : Mapping({u"\0" : 1})}):TypeError:('expected string without null bytes',)
                      +d["a"] = Mapping({"abcG" : Mapping({"\0" : 1})}):TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing *Iter* using d["a"] = Mapping({"abc" : %s})
                      -d["a"] = Mapping({"abc" : FailingIter()}):TypeError:('unable to convert FailingIter to vim structure',)
                      -d["a"] = Mapping({"abc" : FailingIterNext()}):NotImplementedError:()
                      +>>> 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:()
                      <<< Finished
                      ->>> Testing ConvertFromPyObject using d["a"] = Mapping({"abc" : %s})
                      -d["a"] = Mapping({"abc" : None}):TypeError:('unable to convert NoneType to vim structure',)
                      -d["a"] = Mapping({"abc" : {"": 1}}):ValueError:('empty keys are not allowed',)
                      -d["a"] = Mapping({"abc" : {u"": 1}}):ValueError:('empty keys are not allowed',)
                      -d["a"] = Mapping({"abc" : FailingMapping()}):NotImplementedError:()
                      -d["a"] = Mapping({"abc" : FailingMappingKey()}):NotImplementedError:()
                      +>>> 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:()
                      <<< Finished
                      >>> Testing *Iter* using d["a"] = %s
                      d["a"] = FailingIter():TypeError:('unable to convert FailingIter to vim structure',)
                      @@ -554,52 +557,52 @@
                      d.update({u"\0" : 1}):TypeError:('expected string without null bytes',)
                      d.update({"\0" : 1}):TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing StringToChars using d.update({"abc" : {%s : 1}})
                      -d.update({"abc" : {1 : 1}}):TypeError:('expected str() or unicode() instance, but got int',)
                      -d.update({"abc" : {u"\0" : 1}}):TypeError:('expected string without null bytes',)
                      -d.update({"abc" : {"\0" : 1}}):TypeError:('expected string without null bytes',)
                      +>>> Testing StringToChars using d.update({"abcF" : {%s : 1}})
                      +d.update({"abcF" : {1 : 1}}):TypeError:('expected str() or unicode() instance, but got int',)
                      +d.update({"abcF" : {u"\0" : 1}}):TypeError:('expected string without null bytes',)
                      +d.update({"abcF" : {"\0" : 1}}):TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing StringToChars using d.update({"abc" : Mapping({%s : 1})})
                      -d.update({"abc" : Mapping({1 : 1})}):TypeError:('expected str() or unicode() instance, but got int',)
                      -d.update({"abc" : Mapping({u"\0" : 1})}):TypeError:('expected string without null bytes',)
                      -d.update({"abc" : Mapping({"\0" : 1})}):TypeError:('expected string without null bytes',)
                      +>>> Testing StringToChars using d.update({"abcF" : Mapping({%s : 1})})
                      +d.update({"abcF" : Mapping({1 : 1})}):TypeError:('expected str() or unicode() instance, but got int',)
                      +d.update({"abcF" : Mapping({u"\0" : 1})}):TypeError:('expected string without null bytes',)
                      +d.update({"abcF" : Mapping({"\0" : 1})}):TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing *Iter* using d.update({"abc" : %s})
                      -d.update({"abc" : FailingIter()}):TypeError:('unable to convert FailingIter to vim structure',)
                      -d.update({"abc" : FailingIterNext()}):NotImplementedError:()
                      +>>> Testing *Iter* using d.update({"abcF" : %s})
                      +d.update({"abcF" : FailingIter()}):TypeError:('unable to convert FailingIter to vim structure',)
                      +d.update({"abcF" : FailingIterNext()}):NotImplementedError:()
                      <<< Finished
                      ->>> Testing ConvertFromPyObject using d.update({"abc" : %s})
                      -d.update({"abc" : None}):TypeError:('unable to convert NoneType to vim structure',)
                      -d.update({"abc" : {"": 1}}):ValueError:('empty keys are not allowed',)
                      -d.update({"abc" : {u"": 1}}):ValueError:('empty keys are not allowed',)
                      -d.update({"abc" : FailingMapping()}):NotImplementedError:()
                      -d.update({"abc" : FailingMappingKey()}):NotImplementedError:()
                      +>>> 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:()
                      <<< Finished
                      >>> Testing StringToChars using d.update(Mapping({%s : 1}))
                      d.update(Mapping({1 : 1})):TypeError:('expected str() or unicode() instance, but got int',)
                      d.update(Mapping({u"\0" : 1})):TypeError:('expected string without null bytes',)
                      d.update(Mapping({"\0" : 1})):TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing StringToChars using d.update(Mapping({"abc" : {%s : 1}}))
                      -d.update(Mapping({"abc" : {1 : 1}})):TypeError:('expected str() or unicode() instance, but got int',)
                      -d.update(Mapping({"abc" : {u"\0" : 1}})):TypeError:('expected string without null bytes',)
                      -d.update(Mapping({"abc" : {"\0" : 1}})):TypeError:('expected string without null bytes',)
                      +>>> Testing StringToChars using d.update(Mapping({"abcG" : {%s : 1}}))
                      +d.update(Mapping({"abcG" : {1 : 1}})):TypeError:('expected str() or unicode() instance, but got int',)
                      +d.update(Mapping({"abcG" : {u"\0" : 1}})):TypeError:('expected string without null bytes',)
                      +d.update(Mapping({"abcG" : {"\0" : 1}})):TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing StringToChars using d.update(Mapping({"abc" : Mapping({%s : 1})}))
                      -d.update(Mapping({"abc" : Mapping({1 : 1})})):TypeError:('expected str() or unicode() instance, but got int',)
                      -d.update(Mapping({"abc" : Mapping({u"\0" : 1})})):TypeError:('expected string without null bytes',)
                      -d.update(Mapping({"abc" : Mapping({"\0" : 1})})):TypeError:('expected string without null bytes',)
                      +>>> Testing StringToChars using d.update(Mapping({"abcG" : Mapping({%s : 1})}))
                      +d.update(Mapping({"abcG" : Mapping({1 : 1})})):TypeError:('expected str() or unicode() instance, but got int',)
                      +d.update(Mapping({"abcG" : Mapping({u"\0" : 1})})):TypeError:('expected string without null bytes',)
                      +d.update(Mapping({"abcG" : Mapping({"\0" : 1})})):TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing *Iter* using d.update(Mapping({"abc" : %s}))
                      -d.update(Mapping({"abc" : FailingIter()})):TypeError:('unable to convert FailingIter to vim structure',)
                      -d.update(Mapping({"abc" : FailingIterNext()})):NotImplementedError:()
                      +>>> 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:()
                      <<< Finished
                      ->>> Testing ConvertFromPyObject using d.update(Mapping({"abc" : %s}))
                      -d.update(Mapping({"abc" : None})):TypeError:('unable to convert NoneType to vim structure',)
                      -d.update(Mapping({"abc" : {"": 1}})):ValueError:('empty keys are not allowed',)
                      -d.update(Mapping({"abc" : {u"": 1}})):ValueError:('empty keys are not allowed',)
                      -d.update(Mapping({"abc" : FailingMapping()})):NotImplementedError:()
                      -d.update(Mapping({"abc" : FailingMappingKey()})):NotImplementedError:()
                      +>>> 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:()
                      <<< Finished
                      >>> Testing *Iter* using d.update(%s)
                      d.update(FailingIter()):NotImplementedError:()
                      @@ -622,52 +625,52 @@
                      d.update((("a", {u"\0" : 1}),)):TypeError:('expected string without null bytes',)
                      d.update((("a", {"\0" : 1}),)):TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing StringToChars using d.update((("a", {"abc" : {%s : 1}}),))
                      -d.update((("a", {"abc" : {1 : 1}}),)):TypeError:('expected str() or unicode() instance, but got int',)
                      -d.update((("a", {"abc" : {u"\0" : 1}}),)):TypeError:('expected string without null bytes',)
                      -d.update((("a", {"abc" : {"\0" : 1}}),)):TypeError:('expected string without null bytes',)
                      +>>> Testing StringToChars using d.update((("a", {"abcF" : {%s : 1}}),))
                      +d.update((("a", {"abcF" : {1 : 1}}),)):TypeError:('expected str() or unicode() instance, but got int',)
                      +d.update((("a", {"abcF" : {u"\0" : 1}}),)):TypeError:('expected string without null bytes',)
                      +d.update((("a", {"abcF" : {"\0" : 1}}),)):TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing StringToChars using d.update((("a", {"abc" : Mapping({%s : 1})}),))
                      -d.update((("a", {"abc" : Mapping({1 : 1})}),)):TypeError:('expected str() or unicode() instance, but got int',)
                      -d.update((("a", {"abc" : Mapping({u"\0" : 1})}),)):TypeError:('expected string without null bytes',)
                      -d.update((("a", {"abc" : Mapping({"\0" : 1})}),)):TypeError:('expected string without null bytes',)
                      +>>> Testing StringToChars using d.update((("a", {"abcF" : Mapping({%s : 1})}),))
                      +d.update((("a", {"abcF" : Mapping({1 : 1})}),)):TypeError:('expected str() or unicode() instance, but got int',)
                      +d.update((("a", {"abcF" : Mapping({u"\0" : 1})}),)):TypeError:('expected string without null bytes',)
                      +d.update((("a", {"abcF" : Mapping({"\0" : 1})}),)):TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing *Iter* using d.update((("a", {"abc" : %s}),))
                      -d.update((("a", {"abc" : FailingIter()}),)):TypeError:('unable to convert FailingIter to vim structure',)
                      -d.update((("a", {"abc" : FailingIterNext()}),)):NotImplementedError:()
                      +>>> 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:()
                      <<< Finished
                      ->>> Testing ConvertFromPyObject using d.update((("a", {"abc" : %s}),))
                      -d.update((("a", {"abc" : None}),)):TypeError:('unable to convert NoneType to vim structure',)
                      -d.update((("a", {"abc" : {"": 1}}),)):ValueError:('empty keys are not allowed',)
                      -d.update((("a", {"abc" : {u"": 1}}),)):ValueError:('empty keys are not allowed',)
                      -d.update((("a", {"abc" : FailingMapping()}),)):NotImplementedError:()
                      -d.update((("a", {"abc" : FailingMappingKey()}),)):NotImplementedError:()
                      +>>> 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:()
                      <<< 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',)
                      d.update((("a", Mapping({u"\0" : 1})),)):TypeError:('expected string without null bytes',)
                      d.update((("a", Mapping({"\0" : 1})),)):TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing StringToChars using d.update((("a", Mapping({"abc" : {%s : 1}})),))
                      -d.update((("a", Mapping({"abc" : {1 : 1}})),)):TypeError:('expected str() or unicode() instance, but got int',)
                      -d.update((("a", Mapping({"abc" : {u"\0" : 1}})),)):TypeError:('expected string without null bytes',)
                      -d.update((("a", Mapping({"abc" : {"\0" : 1}})),)):TypeError:('expected string without null bytes',)
                      +>>> Testing StringToChars using d.update((("a", Mapping({"abcG" : {%s : 1}})),))
                      +d.update((("a", Mapping({"abcG" : {1 : 1}})),)):TypeError:('expected str() or unicode() instance, but got int',)
                      +d.update((("a", Mapping({"abcG" : {u"\0" : 1}})),)):TypeError:('expected string without null bytes',)
                      +d.update((("a", Mapping({"abcG" : {"\0" : 1}})),)):TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing StringToChars using d.update((("a", Mapping({"abc" : Mapping({%s : 1})})),))
                      -d.update((("a", Mapping({"abc" : Mapping({1 : 1})})),)):TypeError:('expected str() or unicode() instance, but got int',)
                      -d.update((("a", Mapping({"abc" : Mapping({u"\0" : 1})})),)):TypeError:('expected string without null bytes',)
                      -d.update((("a", Mapping({"abc" : Mapping({"\0" : 1})})),)):TypeError:('expected string without null bytes',)
                      +>>> Testing StringToChars using d.update((("a", Mapping({"abcG" : Mapping({%s : 1})})),))
                      +d.update((("a", Mapping({"abcG" : Mapping({1 : 1})})),)):TypeError:('expected str() or unicode() instance, but got int',)
                      +d.update((("a", Mapping({"abcG" : Mapping({u"\0" : 1})})),)):TypeError:('expected string without null bytes',)
                      +d.update((("a", Mapping({"abcG" : Mapping({"\0" : 1})})),)):TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing *Iter* using d.update((("a", Mapping({"abc" : %s})),))
                      -d.update((("a", Mapping({"abc" : FailingIter()})),)):TypeError:('unable to convert FailingIter to vim structure',)
                      -d.update((("a", Mapping({"abc" : FailingIterNext()})),)):NotImplementedError:()
                      +>>> 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:()
                      <<< Finished
                      ->>> Testing ConvertFromPyObject using d.update((("a", Mapping({"abc" : %s})),))
                      -d.update((("a", Mapping({"abc" : None})),)):TypeError:('unable to convert NoneType to vim structure',)
                      -d.update((("a", Mapping({"abc" : {"": 1}})),)):ValueError:('empty keys are not allowed',)
                      -d.update((("a", Mapping({"abc" : {u"": 1}})),)):ValueError:('empty keys are not allowed',)
                      -d.update((("a", Mapping({"abc" : FailingMapping()})),)):NotImplementedError:()
                      -d.update((("a", Mapping({"abc" : FailingMappingKey()})),)):NotImplementedError:()
                      +>>> 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:()
                      <<< Finished
                      >>> Testing *Iter* using d.update((("a", %s),))
                      d.update((("a", FailingIter()),)):TypeError:('unable to convert FailingIter to vim structure',)
                      @@ -693,52 +696,52 @@
                      vim.List([{u"\0" : 1}]):TypeError:('expected string without null bytes',)
                      vim.List([{"\0" : 1}]):TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing StringToChars using vim.List([{"abc" : {%s : 1}}])
                      -vim.List([{"abc" : {1 : 1}}]):TypeError:('expected str() or unicode() instance, but got int',)
                      -vim.List([{"abc" : {u"\0" : 1}}]):TypeError:('expected string without null bytes',)
                      -vim.List([{"abc" : {"\0" : 1}}]):TypeError:('expected string without null bytes',)
                      +>>> Testing StringToChars using vim.List([{"abcF" : {%s : 1}}])
                      +vim.List([{"abcF" : {1 : 1}}]):TypeError:('expected str() or unicode() instance, but got int',)
                      +vim.List([{"abcF" : {u"\0" : 1}}]):TypeError:('expected string without null bytes',)
                      +vim.List([{"abcF" : {"\0" : 1}}]):TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing StringToChars using vim.List([{"abc" : Mapping({%s : 1})}])
                      -vim.List([{"abc" : Mapping({1 : 1})}]):TypeError:('expected str() or unicode() instance, but got int',)
                      -vim.List([{"abc" : Mapping({u"\0" : 1})}]):TypeError:('expected string without null bytes',)
                      -vim.List([{"abc" : Mapping({"\0" : 1})}]):TypeError:('expected string without null bytes',)
                      +>>> Testing StringToChars using vim.List([{"abcF" : Mapping({%s : 1})}])
                      +vim.List([{"abcF" : Mapping({1 : 1})}]):TypeError:('expected str() or unicode() instance, but got int',)
                      +vim.List([{"abcF" : Mapping({u"\0" : 1})}]):TypeError:('expected string without null bytes',)
                      +vim.List([{"abcF" : Mapping({"\0" : 1})}]):TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing *Iter* using vim.List([{"abc" : %s}])
                      -vim.List([{"abc" : FailingIter()}]):TypeError:('unable to convert FailingIter to vim structure',)
                      -vim.List([{"abc" : FailingIterNext()}]):NotImplementedError:()
                      +>>> Testing *Iter* using vim.List([{"abcF" : %s}])
                      +vim.List([{"abcF" : FailingIter()}]):TypeError:('unable to convert FailingIter to vim structure',)
                      +vim.List([{"abcF" : FailingIterNext()}]):NotImplementedError:()
                      <<< Finished
                      ->>> Testing ConvertFromPyObject using vim.List([{"abc" : %s}])
                      -vim.List([{"abc" : None}]):TypeError:('unable to convert NoneType to vim structure',)
                      -vim.List([{"abc" : {"": 1}}]):ValueError:('empty keys are not allowed',)
                      -vim.List([{"abc" : {u"": 1}}]):ValueError:('empty keys are not allowed',)
                      -vim.List([{"abc" : FailingMapping()}]):NotImplementedError:()
                      -vim.List([{"abc" : FailingMappingKey()}]):NotImplementedError:()
                      +>>> 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:()
                      <<< Finished
                      >>> Testing StringToChars using vim.List([Mapping({%s : 1})])
                      vim.List([Mapping({1 : 1})]):TypeError:('expected str() or unicode() instance, but got int',)
                      vim.List([Mapping({u"\0" : 1})]):TypeError:('expected string without null bytes',)
                      vim.List([Mapping({"\0" : 1})]):TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing StringToChars using vim.List([Mapping({"abc" : {%s : 1}})])
                      -vim.List([Mapping({"abc" : {1 : 1}})]):TypeError:('expected str() or unicode() instance, but got int',)
                      -vim.List([Mapping({"abc" : {u"\0" : 1}})]):TypeError:('expected string without null bytes',)
                      -vim.List([Mapping({"abc" : {"\0" : 1}})]):TypeError:('expected string without null bytes',)
                      +>>> Testing StringToChars using vim.List([Mapping({"abcG" : {%s : 1}})])
                      +vim.List([Mapping({"abcG" : {1 : 1}})]):TypeError:('expected str() or unicode() instance, but got int',)
                      +vim.List([Mapping({"abcG" : {u"\0" : 1}})]):TypeError:('expected string without null bytes',)
                      +vim.List([Mapping({"abcG" : {"\0" : 1}})]):TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing StringToChars using vim.List([Mapping({"abc" : Mapping({%s : 1})})])
                      -vim.List([Mapping({"abc" : Mapping({1 : 1})})]):TypeError:('expected str() or unicode() instance, but got int',)
                      -vim.List([Mapping({"abc" : Mapping({u"\0" : 1})})]):TypeError:('expected string without null bytes',)
                      -vim.List([Mapping({"abc" : Mapping({"\0" : 1})})]):TypeError:('expected string without null bytes',)
                      +>>> Testing StringToChars using vim.List([Mapping({"abcG" : Mapping({%s : 1})})])
                      +vim.List([Mapping({"abcG" : Mapping({1 : 1})})]):TypeError:('expected str() or unicode() instance, but got int',)
                      +vim.List([Mapping({"abcG" : Mapping({u"\0" : 1})})]):TypeError:('expected string without null bytes',)
                      +vim.List([Mapping({"abcG" : Mapping({"\0" : 1})})]):TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing *Iter* using vim.List([Mapping({"abc" : %s})])
                      -vim.List([Mapping({"abc" : FailingIter()})]):TypeError:('unable to convert FailingIter to vim structure',)
                      -vim.List([Mapping({"abc" : FailingIterNext()})]):NotImplementedError:()
                      +>>> 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:()
                      <<< Finished
                      ->>> Testing ConvertFromPyObject using vim.List([Mapping({"abc" : %s})])
                      -vim.List([Mapping({"abc" : None})]):TypeError:('unable to convert NoneType to vim structure',)
                      -vim.List([Mapping({"abc" : {"": 1}})]):ValueError:('empty keys are not allowed',)
                      -vim.List([Mapping({"abc" : {u"": 1}})]):ValueError:('empty keys are not allowed',)
                      -vim.List([Mapping({"abc" : FailingMapping()})]):NotImplementedError:()
                      -vim.List([Mapping({"abc" : FailingMappingKey()})]):NotImplementedError:()
                      +>>> 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:()
                      <<< Finished
                      >>> Testing *Iter* using vim.List([%s])
                      vim.List([FailingIter()]):TypeError:('unable to convert FailingIter to vim structure',)
                      @@ -757,58 +760,58 @@
                      ll[1] = 2:error:('list is locked',)
                      l[1000] = 3:IndexError:('list index out of range',)
                      >> ListAssSlice
                      -ll[1:100] = "abc":error:('list is locked',)
                      +ll[1:100] = "abcJ":error:('list is locked',)
                      >>> 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[:] = [{"abc" : {%s : 1}}]
                      -l[:] = [{"abc" : {1 : 1}}]:TypeError:('expected str() or unicode() instance, but got int',)
                      -l[:] = [{"abc" : {u"\0" : 1}}]:TypeError:('expected string without null bytes',)
                      -l[:] = [{"abc" : {"\0" : 1}}]:TypeError:('expected string without null bytes',)
                      +>>> 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',)
                      <<< Finished
                      ->>> Testing StringToChars using l[:] = [{"abc" : Mapping({%s : 1})}]
                      -l[:] = [{"abc" : Mapping({1 : 1})}]:TypeError:('expected str() or unicode() instance, but got int',)
                      -l[:] = [{"abc" : Mapping({u"\0" : 1})}]:TypeError:('expected string without null bytes',)
                      -l[:] = [{"abc" : Mapping({"\0" : 1})}]:TypeError:('expected string without null bytes',)
                      +>>> Testing StringToChars using l[:] = [{"abcF" : Mapping({%s : 1})}]
                      +l[:] = [{"abcF" : Mapping({1 : 1})}]:TypeError:('expected str() or unicode() instance, but got int',)
                      +l[:] = [{"abcF" : Mapping({u"\0" : 1})}]:TypeError:('expected string without null bytes',)
                      +l[:] = [{"abcF" : Mapping({"\0" : 1})}]:TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing *Iter* using l[:] = [{"abc" : %s}]
                      -l[:] = [{"abc" : FailingIter()}]:TypeError:('unable to convert FailingIter to vim structure',)
                      -l[:] = [{"abc" : FailingIterNext()}]:NotImplementedError:()
                      +>>> Testing *Iter* using l[:] = [{"abcF" : %s}]
                      +l[:] = [{"abcF" : FailingIter()}]:TypeError:('unable to convert FailingIter to vim structure',)
                      +l[:] = [{"abcF" : FailingIterNext()}]:NotImplementedError:()
                      <<< Finished
                      ->>> Testing ConvertFromPyObject using l[:] = [{"abc" : %s}]
                      -l[:] = [{"abc" : None}]:TypeError:('unable to convert NoneType to vim structure',)
                      -l[:] = [{"abc" : {"": 1}}]:ValueError:('empty keys are not allowed',)
                      -l[:] = [{"abc" : {u"": 1}}]:ValueError:('empty keys are not allowed',)
                      -l[:] = [{"abc" : FailingMapping()}]:NotImplementedError:()
                      -l[:] = [{"abc" : FailingMappingKey()}]:NotImplementedError:()
                      +>>> 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:()
                      <<< Finished
                      >>> Testing StringToChars using l[:] = [Mapping({%s : 1})]
                      l[:] = [Mapping({1 : 1})]:TypeError:('expected str() or unicode() instance, but got int',)
                      l[:] = [Mapping({u"\0" : 1})]:TypeError:('expected string without null bytes',)
                      l[:] = [Mapping({"\0" : 1})]:TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing StringToChars using l[:] = [Mapping({"abc" : {%s : 1}})]
                      -l[:] = [Mapping({"abc" : {1 : 1}})]:TypeError:('expected str() or unicode() instance, but got int',)
                      -l[:] = [Mapping({"abc" : {u"\0" : 1}})]:TypeError:('expected string without null bytes',)
                      -l[:] = [Mapping({"abc" : {"\0" : 1}})]:TypeError:('expected string without null bytes',)
                      +>>> Testing StringToChars using l[:] = [Mapping({"abcG" : {%s : 1}})]
                      +l[:] = [Mapping({"abcG" : {1 : 1}})]:TypeError:('expected str() or unicode() instance, but got int',)
                      +l[:] = [Mapping({"abcG" : {u"\0" : 1}})]:TypeError:('expected string without null bytes',)
                      +l[:] = [Mapping({"abcG" : {"\0" : 1}})]:TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing StringToChars using l[:] = [Mapping({"abc" : Mapping({%s : 1})})]
                      -l[:] = [Mapping({"abc" : Mapping({1 : 1})})]:TypeError:('expected str() or unicode() instance, but got int',)
                      -l[:] = [Mapping({"abc" : Mapping({u"\0" : 1})})]:TypeError:('expected string without null bytes',)
                      -l[:] = [Mapping({"abc" : Mapping({"\0" : 1})})]:TypeError:('expected string without null bytes',)
                      +>>> Testing StringToChars using l[:] = [Mapping({"abcG" : Mapping({%s : 1})})]
                      +l[:] = [Mapping({"abcG" : Mapping({1 : 1})})]:TypeError:('expected str() or unicode() instance, but got int',)
                      +l[:] = [Mapping({"abcG" : Mapping({u"\0" : 1})})]:TypeError:('expected string without null bytes',)
                      +l[:] = [Mapping({"abcG" : Mapping({"\0" : 1})})]:TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing *Iter* using l[:] = [Mapping({"abc" : %s})]
                      -l[:] = [Mapping({"abc" : FailingIter()})]:TypeError:('unable to convert FailingIter to vim structure',)
                      -l[:] = [Mapping({"abc" : FailingIterNext()})]:NotImplementedError:()
                      +>>> Testing *Iter* using l[:] = [Mapping({"abcG" : %s})]
                      +l[:] = [Mapping({"abcG" : FailingIter()})]:TypeError:('unable to convert FailingIter to vim structure',)
                      +l[:] = [Mapping({"abcG" : FailingIterNext()})]:NotImplementedError:()
                      <<< Finished
                      ->>> Testing ConvertFromPyObject using l[:] = [Mapping({"abc" : %s})]
                      -l[:] = [Mapping({"abc" : None})]:TypeError:('unable to convert NoneType to vim structure',)
                      -l[:] = [Mapping({"abc" : {"": 1}})]:ValueError:('empty keys are not allowed',)
                      -l[:] = [Mapping({"abc" : {u"": 1}})]:ValueError:('empty keys are not allowed',)
                      -l[:] = [Mapping({"abc" : FailingMapping()})]:NotImplementedError:()
                      -l[:] = [Mapping({"abc" : FailingMappingKey()})]:NotImplementedError:()
                      +>>> 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:()
                      <<< Finished
                      >>> Testing *Iter* using l[:] = [%s]
                      l[:] = [FailingIter()]:TypeError:('unable to convert FailingIter to vim structure',)
                      @@ -827,52 +830,52 @@
                      l.extend([{u"\0" : 1}]):TypeError:('expected string without null bytes',)
                      l.extend([{"\0" : 1}]):TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing StringToChars using l.extend([{"abc" : {%s : 1}}])
                      -l.extend([{"abc" : {1 : 1}}]):TypeError:('expected str() or unicode() instance, but got int',)
                      -l.extend([{"abc" : {u"\0" : 1}}]):TypeError:('expected string without null bytes',)
                      -l.extend([{"abc" : {"\0" : 1}}]):TypeError:('expected string without null bytes',)
                      +>>> Testing StringToChars using l.extend([{"abcF" : {%s : 1}}])
                      +l.extend([{"abcF" : {1 : 1}}]):TypeError:('expected str() or unicode() instance, but got int',)
                      +l.extend([{"abcF" : {u"\0" : 1}}]):TypeError:('expected string without null bytes',)
                      +l.extend([{"abcF" : {"\0" : 1}}]):TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing StringToChars using l.extend([{"abc" : Mapping({%s : 1})}])
                      -l.extend([{"abc" : Mapping({1 : 1})}]):TypeError:('expected str() or unicode() instance, but got int',)
                      -l.extend([{"abc" : Mapping({u"\0" : 1})}]):TypeError:('expected string without null bytes',)
                      -l.extend([{"abc" : Mapping({"\0" : 1})}]):TypeError:('expected string without null bytes',)
                      +>>> Testing StringToChars using l.extend([{"abcF" : Mapping({%s : 1})}])
                      +l.extend([{"abcF" : Mapping({1 : 1})}]):TypeError:('expected str() or unicode() instance, but got int',)
                      +l.extend([{"abcF" : Mapping({u"\0" : 1})}]):TypeError:('expected string without null bytes',)
                      +l.extend([{"abcF" : Mapping({"\0" : 1})}]):TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing *Iter* using l.extend([{"abc" : %s}])
                      -l.extend([{"abc" : FailingIter()}]):TypeError:('unable to convert FailingIter to vim structure',)
                      -l.extend([{"abc" : FailingIterNext()}]):NotImplementedError:()
                      +>>> Testing *Iter* using l.extend([{"abcF" : %s}])
                      +l.extend([{"abcF" : FailingIter()}]):TypeError:('unable to convert FailingIter to vim structure',)
                      +l.extend([{"abcF" : FailingIterNext()}]):NotImplementedError:()
                      <<< Finished
                      ->>> Testing ConvertFromPyObject using l.extend([{"abc" : %s}])
                      -l.extend([{"abc" : None}]):TypeError:('unable to convert NoneType to vim structure',)
                      -l.extend([{"abc" : {"": 1}}]):ValueError:('empty keys are not allowed',)
                      -l.extend([{"abc" : {u"": 1}}]):ValueError:('empty keys are not allowed',)
                      -l.extend([{"abc" : FailingMapping()}]):NotImplementedError:()
                      -l.extend([{"abc" : FailingMappingKey()}]):NotImplementedError:()
                      +>>> 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:()
                      <<< Finished
                      >>> Testing StringToChars using l.extend([Mapping({%s : 1})])
                      l.extend([Mapping({1 : 1})]):TypeError:('expected str() or unicode() instance, but got int',)
                      l.extend([Mapping({u"\0" : 1})]):TypeError:('expected string without null bytes',)
                      l.extend([Mapping({"\0" : 1})]):TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing StringToChars using l.extend([Mapping({"abc" : {%s : 1}})])
                      -l.extend([Mapping({"abc" : {1 : 1}})]):TypeError:('expected str() or unicode() instance, but got int',)
                      -l.extend([Mapping({"abc" : {u"\0" : 1}})]):TypeError:('expected string without null bytes',)
                      -l.extend([Mapping({"abc" : {"\0" : 1}})]):TypeError:('expected string without null bytes',)
                      +>>> Testing StringToChars using l.extend([Mapping({"abcG" : {%s : 1}})])
                      +l.extend([Mapping({"abcG" : {1 : 1}})]):TypeError:('expected str() or unicode() instance, but got int',)
                      +l.extend([Mapping({"abcG" : {u"\0" : 1}})]):TypeError:('expected string without null bytes',)
                      +l.extend([Mapping({"abcG" : {"\0" : 1}})]):TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing StringToChars using l.extend([Mapping({"abc" : Mapping({%s : 1})})])
                      -l.extend([Mapping({"abc" : Mapping({1 : 1})})]):TypeError:('expected str() or unicode() instance, but got int',)
                      -l.extend([Mapping({"abc" : Mapping({u"\0" : 1})})]):TypeError:('expected string without null bytes',)
                      -l.extend([Mapping({"abc" : Mapping({"\0" : 1})})]):TypeError:('expected string without null bytes',)
                      +>>> Testing StringToChars using l.extend([Mapping({"abcG" : Mapping({%s : 1})})])
                      +l.extend([Mapping({"abcG" : Mapping({1 : 1})})]):TypeError:('expected str() or unicode() instance, but got int',)
                      +l.extend([Mapping({"abcG" : Mapping({u"\0" : 1})})]):TypeError:('expected string without null bytes',)
                      +l.extend([Mapping({"abcG" : Mapping({"\0" : 1})})]):TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing *Iter* using l.extend([Mapping({"abc" : %s})])
                      -l.extend([Mapping({"abc" : FailingIter()})]):TypeError:('unable to convert FailingIter to vim structure',)
                      -l.extend([Mapping({"abc" : FailingIterNext()})]):NotImplementedError:()
                      +>>> 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:()
                      <<< Finished
                      ->>> Testing ConvertFromPyObject using l.extend([Mapping({"abc" : %s})])
                      -l.extend([Mapping({"abc" : None})]):TypeError:('unable to convert NoneType to vim structure',)
                      -l.extend([Mapping({"abc" : {"": 1}})]):ValueError:('empty keys are not allowed',)
                      -l.extend([Mapping({"abc" : {u"": 1}})]):ValueError:('empty keys are not allowed',)
                      -l.extend([Mapping({"abc" : FailingMapping()})]):NotImplementedError:()
                      -l.extend([Mapping({"abc" : FailingMappingKey()})]):NotImplementedError:()
                      +>>> 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:()
                      <<< Finished
                      >>> Testing *Iter* using l.extend([%s])
                      l.extend([FailingIter()]):TypeError:('unable to convert FailingIter to vim structure',)
                      @@ -900,52 +903,52 @@
                      f({u"\0" : 1}):TypeError:('expected string without null bytes',)
                      f({"\0" : 1}):TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing StringToChars using f({"abc" : {%s : 1}})
                      -f({"abc" : {1 : 1}}):TypeError:('expected str() or unicode() instance, but got int',)
                      -f({"abc" : {u"\0" : 1}}):TypeError:('expected string without null bytes',)
                      -f({"abc" : {"\0" : 1}}):TypeError:('expected string without null bytes',)
                      +>>> Testing StringToChars using f({"abcF" : {%s : 1}})
                      +f({"abcF" : {1 : 1}}):TypeError:('expected str() or unicode() instance, but got int',)
                      +f({"abcF" : {u"\0" : 1}}):TypeError:('expected string without null bytes',)
                      +f({"abcF" : {"\0" : 1}}):TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing StringToChars using f({"abc" : Mapping({%s : 1})})
                      -f({"abc" : Mapping({1 : 1})}):TypeError:('expected str() or unicode() instance, but got int',)
                      -f({"abc" : Mapping({u"\0" : 1})}):TypeError:('expected string without null bytes',)
                      -f({"abc" : Mapping({"\0" : 1})}):TypeError:('expected string without null bytes',)
                      +>>> Testing StringToChars using f({"abcF" : Mapping({%s : 1})})
                      +f({"abcF" : Mapping({1 : 1})}):TypeError:('expected str() or unicode() instance, but got int',)
                      +f({"abcF" : Mapping({u"\0" : 1})}):TypeError:('expected string without null bytes',)
                      +f({"abcF" : Mapping({"\0" : 1})}):TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing *Iter* using f({"abc" : %s})
                      -f({"abc" : FailingIter()}):TypeError:('unable to convert FailingIter to vim structure',)
                      -f({"abc" : FailingIterNext()}):NotImplementedError:()
                      +>>> Testing *Iter* using f({"abcF" : %s})
                      +f({"abcF" : FailingIter()}):TypeError:('unable to convert FailingIter to vim structure',)
                      +f({"abcF" : FailingIterNext()}):NotImplementedError:()
                      <<< Finished
                      ->>> Testing ConvertFromPyObject using f({"abc" : %s})
                      -f({"abc" : None}):TypeError:('unable to convert NoneType to vim structure',)
                      -f({"abc" : {"": 1}}):ValueError:('empty keys are not allowed',)
                      -f({"abc" : {u"": 1}}):ValueError:('empty keys are not allowed',)
                      -f({"abc" : FailingMapping()}):NotImplementedError:()
                      -f({"abc" : FailingMappingKey()}):NotImplementedError:()
                      +>>> 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:()
                      <<< Finished
                      >>> Testing StringToChars using f(Mapping({%s : 1}))
                      f(Mapping({1 : 1})):TypeError:('expected str() or unicode() instance, but got int',)
                      f(Mapping({u"\0" : 1})):TypeError:('expected string without null bytes',)
                      f(Mapping({"\0" : 1})):TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing StringToChars using f(Mapping({"abc" : {%s : 1}}))
                      -f(Mapping({"abc" : {1 : 1}})):TypeError:('expected str() or unicode() instance, but got int',)
                      -f(Mapping({"abc" : {u"\0" : 1}})):TypeError:('expected string without null bytes',)
                      -f(Mapping({"abc" : {"\0" : 1}})):TypeError:('expected string without null bytes',)
                      +>>> Testing StringToChars using f(Mapping({"abcG" : {%s : 1}}))
                      +f(Mapping({"abcG" : {1 : 1}})):TypeError:('expected str() or unicode() instance, but got int',)
                      +f(Mapping({"abcG" : {u"\0" : 1}})):TypeError:('expected string without null bytes',)
                      +f(Mapping({"abcG" : {"\0" : 1}})):TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing StringToChars using f(Mapping({"abc" : Mapping({%s : 1})}))
                      -f(Mapping({"abc" : Mapping({1 : 1})})):TypeError:('expected str() or unicode() instance, but got int',)
                      -f(Mapping({"abc" : Mapping({u"\0" : 1})})):TypeError:('expected string without null bytes',)
                      -f(Mapping({"abc" : Mapping({"\0" : 1})})):TypeError:('expected string without null bytes',)
                      +>>> Testing StringToChars using f(Mapping({"abcG" : Mapping({%s : 1})}))
                      +f(Mapping({"abcG" : Mapping({1 : 1})})):TypeError:('expected str() or unicode() instance, but got int',)
                      +f(Mapping({"abcG" : Mapping({u"\0" : 1})})):TypeError:('expected string without null bytes',)
                      +f(Mapping({"abcG" : Mapping({"\0" : 1})})):TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing *Iter* using f(Mapping({"abc" : %s}))
                      -f(Mapping({"abc" : FailingIter()})):TypeError:('unable to convert FailingIter to vim structure',)
                      -f(Mapping({"abc" : FailingIterNext()})):NotImplementedError:()
                      +>>> Testing *Iter* using f(Mapping({"abcG" : %s}))
                      +f(Mapping({"abcG" : FailingIter()})):TypeError:('unable to convert FailingIter to vim structure',)
                      +f(Mapping({"abcG" : FailingIterNext()})):NotImplementedError:()
                      <<< Finished
                      ->>> Testing ConvertFromPyObject using f(Mapping({"abc" : %s}))
                      -f(Mapping({"abc" : None})):TypeError:('unable to convert NoneType to vim structure',)
                      -f(Mapping({"abc" : {"": 1}})):ValueError:('empty keys are not allowed',)
                      -f(Mapping({"abc" : {u"": 1}})):ValueError:('empty keys are not allowed',)
                      -f(Mapping({"abc" : FailingMapping()})):NotImplementedError:()
                      -f(Mapping({"abc" : FailingMappingKey()})):NotImplementedError:()
                      +>>> 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:()
                      <<< Finished
                      >>> Testing *Iter* using f(%s)
                      f(FailingIter()):TypeError:('unable to convert FailingIter to vim structure',)
                      @@ -963,52 +966,52 @@
                      fd(self={u"\0" : 1}):TypeError:('expected string without null bytes',)
                      fd(self={"\0" : 1}):TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing StringToChars using fd(self={"abc" : {%s : 1}})
                      -fd(self={"abc" : {1 : 1}}):TypeError:('expected str() or unicode() instance, but got int',)
                      -fd(self={"abc" : {u"\0" : 1}}):TypeError:('expected string without null bytes',)
                      -fd(self={"abc" : {"\0" : 1}}):TypeError:('expected string without null bytes',)
                      +>>> Testing StringToChars using fd(self={"abcF" : {%s : 1}})
                      +fd(self={"abcF" : {1 : 1}}):TypeError:('expected str() or unicode() instance, but got int',)
                      +fd(self={"abcF" : {u"\0" : 1}}):TypeError:('expected string without null bytes',)
                      +fd(self={"abcF" : {"\0" : 1}}):TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing StringToChars using fd(self={"abc" : Mapping({%s : 1})})
                      -fd(self={"abc" : Mapping({1 : 1})}):TypeError:('expected str() or unicode() instance, but got int',)
                      -fd(self={"abc" : Mapping({u"\0" : 1})}):TypeError:('expected string without null bytes',)
                      -fd(self={"abc" : Mapping({"\0" : 1})}):TypeError:('expected string without null bytes',)
                      +>>> Testing StringToChars using fd(self={"abcF" : Mapping({%s : 1})})
                      +fd(self={"abcF" : Mapping({1 : 1})}):TypeError:('expected str() or unicode() instance, but got int',)
                      +fd(self={"abcF" : Mapping({u"\0" : 1})}):TypeError:('expected string without null bytes',)
                      +fd(self={"abcF" : Mapping({"\0" : 1})}):TypeError:('expected string without null bytes',)
                      <<< Finished
                      ->>> Testing *Iter* using fd(self={"abc" : %s})
                      -fd(self={"abc" : FailingIter()}):TypeError:('unable to convert FailingIter to vim structure',)
                      -fd(self={"abc" : FailingIterNext()}):NotImplementedError:()
                      +>>> Testing *Iter* using fd(self={"abcF" : %s})
                      +fd(self={"abcF" :<br/><br/>(Message over 64 KB, truncated)
                    • ZyX
                      Note: posting here regardless of the Note: below in the commit message because the child of this changeset may (most likely may not, but change is at the code
                      Message 10 of 25 , Jun 19, 2013
                      • 0 Attachment
                        Note: posting here regardless of the Note: below in the commit message because the child of this changeset may (most likely may not, but change is at the code that shows the error) solve problem with test86/test87 (will come next patch). Have not actually checked though (I mean, have not actually checked whether it does solve this problem), but it indeed does solve another problem I found out.

                        # 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 -r 4a00cd941a88 -r 42e166b5c6ff src/if_py_both.h
                        --- a/src/if_py_both.h Sun Jun 16 22:38:09 2013 +0400
                        +++ b/src/if_py_both.h Mon Jun 17 07:54:07 2013 +0400
                        @@ -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 -r 4a00cd941a88 -r 42e166b5c6ff src/testdir/pythonx/failing.py
                        --- /dev/null Thu Jan 01 00:00:00 1970 +0000
                        +++ b/src/testdir/pythonx/failing.py Mon Jun 17 07:54:07 2013 +0400
                        @@ -0,0 +1,1 @@
                        +raise NotImplementedError
                        diff -r 4a00cd941a88 -r 42e166b5c6ff src/testdir/pythonx/failing_import.py
                        --- /dev/null Thu Jan 01 00:00:00 1970 +0000
                        +++ b/src/testdir/pythonx/failing_import.py Mon Jun 17 07:54:07 2013 +0400
                        @@ -0,0 +1,1 @@
                        +raise ImportError
                        diff -r 4a00cd941a88 -r 42e166b5c6ff src/testdir/test86.in
                        --- a/src/testdir/test86.in Sun Jun 16 22:38:09 2013 +0400
                        +++ b/src/testdir/test86.in Mon Jun 17 07:54:07 2013 +0400
                        @@ -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 -r 4a00cd941a88 -r 42e166b5c6ff src/testdir/test86.ok
                        --- a/src/testdir/test86.ok Sun Jun 16 22:38:09 2013 +0400
                        +++ b/src/testdir/test86.ok Mon Jun 17 07:54:07 2013 +0400
                        @@ -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 -r 4a00cd941a88 -r 42e166b5c6ff src/testdir/test87.in
                        --- a/src/testdir/test87.in Sun Jun 16 22:38:09 2013 +0400
                        +++ b/src/testdir/test87.in Mon Jun 17 07:54:07 2013 +0400
                        @@ -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 -r 4a00cd941a88 -r 42e166b5c6ff src/testdir/test87.ok
                        --- a/src/testdir/test87.ok Sun Jun 16 22:38:09 2013 +0400
                        +++ b/src/testdir/test87.ok Mon Jun 17 07:54:07 2013 +0400
                        @@ -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.
                      • ZyX
                        “XXX undetected error” fix is the change described in the previous message. # HG changeset patch # User ZyX # Date 1371669021 -14400 #
                        Message 11 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 12 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 13 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 14 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 15 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 16 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 17 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 18 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 19 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 20 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 21 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 22 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 23 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 24 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 25 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.