# HG changeset patch
# User ZyX <[email protected]>
# 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 [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


diff -crN vim.d0320d1f7ff2/src/if_py_both.h vim.c40e953fe936/src/if_py_both.h
*** vim.d0320d1f7ff2/src/if_py_both.h	2013-06-16 19:23:28.554049066 +0400
--- vim.c40e953fe936/src/if_py_both.h	2013-06-16 19:23:28.566048951 +0400
***************
*** 467,487 ****
   */
  
      static PyObject *
! VimCommand(PyObject *self UNUSED, PyObject *args)
  {
!     char *cmd;
!     PyObject *result;
  
!     if (!PyArg_ParseTuple(args, "s", &cmd))
  	return NULL;
  
-     PyErr_Clear();
- 
      Py_BEGIN_ALLOW_THREADS
      Python_Lock_Vim();
  
      VimTryStart();
!     do_cmdline_cmd((char_u *)cmd);
      update_screen(VALID);
  
      Python_Release_Vim();
--- 467,486 ----
   */
  
      static PyObject *
! VimCommand(PyObject *self UNUSED, PyObject *string)
  {
!     char_u	*cmd;
!     PyObject	*result;
!     PyObject	*todecref;
  
!     if (!(cmd = StringToChars(string, &todecref)))
  	return NULL;
  
      Py_BEGIN_ALLOW_THREADS
      Python_Lock_Vim();
  
      VimTryStart();
!     do_cmdline_cmd(cmd);
      update_screen(VALID);
  
      Python_Release_Vim();
***************
*** 492,499 ****
      else
  	result = Py_None;
  
- 
      Py_XINCREF(result);
      return result;
  }
  
--- 491,498 ----
      else
  	result = Py_None;
  
      Py_XINCREF(result);
+     Py_XDECREF(todecref);
      return result;
  }
  
***************
*** 642,662 ****
      static PyObject *
  VimEval(PyObject *self UNUSED, PyObject *args)
  {
!     char	*expr;
      typval_T	*our_tv;
      PyObject	*result;
!     PyObject    *lookup_dict;
  
!     if (!PyArg_ParseTuple(args, "s", &expr))
  	return NULL;
  
      Py_BEGIN_ALLOW_THREADS
      Python_Lock_Vim();
      VimTryStart();
!     our_tv = eval_expr((char_u *)expr, NULL);
      Python_Release_Vim();
      Py_END_ALLOW_THREADS
  
      if (VimTryEnd())
  	return NULL;
  
--- 641,668 ----
      static PyObject *
  VimEval(PyObject *self UNUSED, PyObject *args)
  {
!     char_u	*expr;
      typval_T	*our_tv;
+     PyObject	*string;
+     PyObject	*todecref;
      PyObject	*result;
!     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(expr, NULL);
      Python_Release_Vim();
      Py_END_ALLOW_THREADS
  
+     Py_XDECREF(todecref);
+ 
      if (VimTryEnd())
  	return NULL;
  
***************
*** 689,710 ****
  static PyObject *ConvertToPyObject(typval_T *);
  
      static PyObject *
! VimEvalPy(PyObject *self UNUSED, PyObject *args)
  {
-     char	*expr;
      typval_T	*our_tv;
      PyObject	*result;
  
!     if (!PyArg_ParseTuple(args, "s", &expr))
  	return NULL;
  
      Py_BEGIN_ALLOW_THREADS
      Python_Lock_Vim();
      VimTryStart();
!     our_tv = eval_expr((char_u *)expr, NULL);
      Python_Release_Vim();
      Py_END_ALLOW_THREADS
  
      if (VimTryEnd())
  	return NULL;
  
--- 695,719 ----
  static PyObject *ConvertToPyObject(typval_T *);
  
      static PyObject *
! VimEvalPy(PyObject *self UNUSED, PyObject *string)
  {
      typval_T	*our_tv;
      PyObject	*result;
+     char_u	*expr;
+     PyObject	*todecref;
  
!     if (!(expr = StringToChars(string, &todecref)))
  	return NULL;
  
      Py_BEGIN_ALLOW_THREADS
      Python_Lock_Vim();
      VimTryStart();
!     our_tv = eval_expr(expr, NULL);
      Python_Release_Vim();
      Py_END_ALLOW_THREADS
  
+     Py_XDECREF(todecref);
+ 
      if (VimTryEnd())
  	return NULL;
  
***************
*** 725,744 ****
  }
  
      static PyObject *
! VimStrwidth(PyObject *self UNUSED, PyObject *args)
  {
!     char	*expr;
  
!     if (!PyArg_ParseTuple(args, "s", &expr))
  	return NULL;
  
-     return PyLong_FromLong(
  #ifdef FEAT_MBYTE
! 	    mb_string2cells((char_u *)expr, (int)STRLEN(expr))
  #else
! 	    STRLEN(expr)
  #endif
! 	    );
  }
  
      static PyObject *
--- 734,757 ----
  }
  
      static PyObject *
! VimStrwidth(PyObject *self UNUSED, PyObject *string)
  {
!     char_u	*str;
!     PyObject	*todecref;
!     int		result;
  
!     if (!(str = StringToChars(string, &todecref)))
  	return NULL;
  
  #ifdef FEAT_MBYTE
!     result = mb_string2cells(str, (int)STRLEN(str));
  #else
!     result = STRLEN(str);
  #endif
! 
!     Py_XDECREF(todecref);
! 
!     return PyLong_FromLong(result);
  }
  
      static PyObject *
***************
*** 841,853 ****
  }
  
      static PyObject *
! VimForeachRTP(PyObject *self UNUSED, PyObject *args)
  {
      map_rtp_data	data;
  
!     if (!PyArg_ParseTuple(args, "O", &data.callable))
! 	return NULL;
! 
      data.result = NULL;
  
      do_in_runtimepath(NULL, FALSE, &map_rtp_callback, &data);
--- 854,864 ----
  }
  
      static PyObject *
! VimForeachRTP(PyObject *self UNUSED, PyObject *callable)
  {
      map_rtp_data	data;
  
!     data.callable = callable;
      data.result = NULL;
  
      do_in_runtimepath(NULL, FALSE, &map_rtp_callback, &data);
***************
*** 1100,1112 ****
  
  static struct PyMethodDef VimMethods[] = {
      /* name,	    function,			calling,			documentation */
!     {"command",	    VimCommand,			METH_VARARGS,			"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"},
      {"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"},
      {"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"},
--- 1111,1123 ----
  
  static struct PyMethodDef VimMethods[] = {
      /* name,	    function,			calling,			documentation */
!     {"command",	    VimCommand,			METH_O,				"Execute a Vim ex-mode command" },
      {"eval",	    VimEval,			METH_VARARGS,			"Evaluate an expression using Vim evaluator" },
!     {"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_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,1740 ****
      {
  	PyObject	*object;
  
! 	if (!PyArg_Parse(args, "(O)", &object))
  	    return NULL;
  
  	if (PyObject_HasAttrString(object, "keys"))
--- 1745,1751 ----
      {
  	PyObject	*object;
  
! 	if (!PyArg_ParseTuple(args, "O", &object))
  	    return NULL;
  
  	if (PyObject_HasAttrString(object, "keys"))
***************
*** 1878,1890 ****
  }
  
      static PyObject *
! DictionaryHasKey(DictionaryObject *self, PyObject *args)
  {
-     PyObject	*keyObject;
- 
-     if (!PyArg_ParseTuple(args, "O", &keyObject))
- 	return NULL;
- 
      return _DictionaryItem(self, keyObject, DICT_FLAG_RETURN_BOOL);
  }
  
--- 1889,1896 ----
  }
  
      static PyObject *
! DictionaryHasKey(DictionaryObject *self, PyObject *keyObject)
  {
      return _DictionaryItem(self, keyObject, DICT_FLAG_RETURN_BOOL);
  }
  
***************
*** 1915,1921 ****
      {"get",	(PyCFunction)DictionaryGet,		METH_VARARGS,	""},
      {"pop",	(PyCFunction)DictionaryPop,		METH_VARARGS,	""},
      {"popitem",	(PyCFunction)DictionaryPopItem,		METH_NOARGS,	""},
!     {"has_key",	(PyCFunction)DictionaryHasKey,		METH_VARARGS,	""},
      {"__dir__",	(PyCFunction)DictionaryDir,		METH_NOARGS,	""},
      { NULL,	NULL,					0,		NULL}
  };
--- 1921,1927 ----
      {"get",	(PyCFunction)DictionaryGet,		METH_VARARGS,	""},
      {"pop",	(PyCFunction)DictionaryPop,		METH_VARARGS,	""},
      {"popitem",	(PyCFunction)DictionaryPopItem,		METH_NOARGS,	""},
!     {"has_key",	(PyCFunction)DictionaryHasKey,		METH_O,		""},
      {"__dir__",	(PyCFunction)DictionaryDir,		METH_NOARGS,	""},
      { NULL,	NULL,					0,		NULL}
  };
***************
*** 2435,2445 ****
  	return NULL;
      }
  
!     if (!PyArg_ParseTuple(args, "s", &name))
  	return NULL;
  
      self = FunctionNew(subtype, name);
  
      return self;
  }
  
--- 2441,2453 ----
  	return NULL;
      }
  
!     if (!PyArg_ParseTuple(args, "et", "ascii", &name))
  	return NULL;
  
      self = FunctionNew(subtype, name);
  
+     PyMem_Free(name);
+ 
      return self;
  }
  
***************
*** 4383,4402 ****
  }
  
      static PyObject *
! BufferMark(BufferObject *self, PyObject *args)
  {
      pos_T	*posp;
!     char	*pmark;
!     char	mark;
      buf_T	*savebuf;
  
      if (CheckBuffer(self))
  	return NULL;
  
!     if (!PyArg_ParseTuple(args, "s", &pmark))
  	return NULL;
  
!     if (STRLEN(pmark) != 1)
      {
  	PyErr_SetString(PyExc_ValueError,
  		_("mark name must be a single character"));
--- 4391,4411 ----
  }
  
      static PyObject *
! BufferMark(BufferObject *self, PyObject *pmarkObject)
  {
      pos_T	*posp;
!     char_u	*pmark;
!     char_u	mark;
      buf_T	*savebuf;
+     PyObject	*todecref;
  
      if (CheckBuffer(self))
  	return NULL;
  
!     if (!(pmark = StringToChars(pmarkObject, &todecref)))
  	return NULL;
  
!     if (pmark[0] == '\0' || pmark[1] != '\0')
      {
  	PyErr_SetString(PyExc_ValueError,
  		_("mark name must be a single character"));
***************
*** 4404,4409 ****
--- 4413,4421 ----
      }
  
      mark = *pmark;
+ 
+     Py_XDECREF(todecref);
+ 
      VimTryStart();
      switch_buffer(&savebuf, self->buf);
      posp = getmark(mark, FALSE);
***************
*** 4461,4467 ****
  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" },
      {"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}
--- 4473,4479 ----
  static struct PyMethodDef BufferMethods[] = {
      /* name,	    function,			calling,	documentation */
      {"append",	    (PyCFunction)BufferAppend,	METH_VARARGS,	"Append data to Vim buffer" },
!     {"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 -crN vim.d0320d1f7ff2/src/testdir/test86.ok vim.c40e953fe936/src/testdir/test86.ok
*** vim.d0320d1f7ff2/src/testdir/test86.ok	2013-06-16 19:23:28.545049153 +0400
--- vim.c40e953fe936/src/testdir/test86.ok	2013-06-16 19:23:28.556049047 +0400
***************
*** 446,459 ****
  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',)
  > VimToPython
  > VimEval
! vim.eval(1):TypeError:('must be string, not int',)
  > VimEvalPy
! vim.bindeval(1):TypeError:('must be string, not int',)
  > VimStrwidth
! vim.strwidth(1):TypeError:('must be string, not int',)
  > Dictionary
  >> DictionaryConstructor
  vim.Dictionary("abc"):ValueError:('expected sequence element of size 2',)
--- 446,459 ----
  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',)
  > VimToPython
  > VimEval
! vim.eval(1):TypeError:('object must be string',)
  > VimEvalPy
! vim.bindeval(1):TypeError:('object must be string',)
  > VimStrwidth
! vim.strwidth(1):TypeError:('object must be string',)
  > Dictionary
  >> DictionaryConstructor
  vim.Dictionary("abc"):ValueError:('expected sequence element of size 2',)
***************
*** 683,689 ****
  >> DictionaryPopItem
  d.popitem(1, 2):TypeError:('popitem() takes no arguments (2 given)',)
  >> DictionaryHasKey
! d.has_key():TypeError:('function takes exactly 1 argument (0 given)',)
  > List
  >> ListConstructor
  vim.List(1, 2):TypeError:('function takes at most 1 argument (2 given)',)
--- 683,689 ----
  >> DictionaryPopItem
  d.popitem(1, 2):TypeError:('popitem() takes no arguments (2 given)',)
  >> DictionaryHasKey
! 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,1071 ****
  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("abc"):ValueError:('mark name must be a single character',)
  vim.current.buffer.mark("!"):error:('invalid mark name',)
  >> BufferRange
--- 1065,1071 ----
  vim.current.buffer.name = True:TypeError:('object must be string',)
  vim.current.buffer.xxx = True:AttributeError:('xxx',)
  >> BufferMark
! 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 -crN vim.d0320d1f7ff2/src/testdir/test87.ok vim.c40e953fe936/src/testdir/test87.ok
*** vim.d0320d1f7ff2/src/testdir/test87.ok	2013-06-16 19:23:28.546049143 +0400
--- vim.c40e953fe936/src/testdir/test87.ok	2013-06-16 19:23:28.558049028 +0400
***************
*** 439,452 ****
  sys.stdout.writelines(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError())
  <<< Finished
  > VimCommand
! vim.command(1):(<class 'TypeError'>, TypeError('must be str, not int',))
  > VimToPython
  > VimEval
! vim.eval(1):(<class 'TypeError'>, TypeError('must be str, not int',))
  > VimEvalPy
! vim.bindeval(1):(<class 'TypeError'>, TypeError('must be str, not int',))
  > VimStrwidth
! vim.strwidth(1):(<class 'TypeError'>, TypeError('must be str, not int',))
  > Dictionary
  >> DictionaryConstructor
  vim.Dictionary("abc"):(<class 'ValueError'>, ValueError('expected sequence element of size 2',))
--- 439,452 ----
  sys.stdout.writelines(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError())
  <<< Finished
  > VimCommand
! vim.command(1):(<class 'TypeError'>, TypeError('object must be string',))
  > VimToPython
  > VimEval
! vim.eval(1):(<class 'TypeError'>, TypeError('object must be string',))
  > VimEvalPy
! vim.bindeval(1):(<class 'TypeError'>, TypeError('object must be string',))
  > VimStrwidth
! 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,686 ****
  >> 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)',))
  > List
  >> ListConstructor
  vim.List(1, 2):(<class 'TypeError'>, TypeError('function takes at most 1 argument (2 given)',))
--- 680,686 ----
  >> DictionaryPopItem
  d.popitem(1, 2):(<class 'TypeError'>, TypeError('popitem() takes no arguments (2 given)',))
  >> DictionaryHasKey
! 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,1080 ****
  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("abc"):(<class 'ValueError'>, ValueError('mark name must be a single character',))
  vim.current.buffer.mark("!"):(<class 'vim.error'>, error('invalid mark name',))
  >> BufferRange
--- 1074,1080 ----
  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('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

Raspunde prin e-mail lui