]> granicus.if.org Git - vim/commitdiff
patch 8.1.0627: Python cannot handle function name of script-local function v8.1.0627
authorBram Moolenaar <Bram@vim.org>
Sat, 22 Dec 2018 17:59:06 +0000 (18:59 +0100)
committerBram Moolenaar <Bram@vim.org>
Sat, 22 Dec 2018 17:59:06 +0000 (18:59 +0100)
Problem:    Python cannot handle function name of script-local function.
Solution:   Use <SNR> instead of the special byte code. (Ozaki Kiichi, closes
            #3681)

src/if_py_both.h
src/testdir/test_python2.vim
src/testdir/test_python3.vim
src/version.c

index cdd7460191ddf2cb1b7e1cb7f9aea970b28039bb..1a4ef462ef12c8d46e20f311ee03d06d79e00423 100644 (file)
@@ -2922,8 +2922,7 @@ FunctionNew(PyTypeObject *subtype, char_u *name, int argc, typval_T *argv,
 {
     FunctionObject     *self;
 
-    self = (FunctionObject *) subtype->tp_alloc(subtype, 0);
-
+    self = (FunctionObject *)subtype->tp_alloc(subtype, 0);
     if (self == NULL)
        return NULL;
 
@@ -2938,15 +2937,36 @@ FunctionNew(PyTypeObject *subtype, char_u *name, int argc, typval_T *argv,
        self->name = vim_strsave(name);
     }
     else
-       if ((self->name = get_expanded_name(name,
-                                   vim_strchr(name, AUTOLOAD_CHAR) == NULL))
-               == NULL)
+    {
+       char_u *p;
+
+       if ((p = get_expanded_name(name,
+                           vim_strchr(name, AUTOLOAD_CHAR) == NULL)) == NULL)
        {
            PyErr_FORMAT(PyExc_ValueError,
                    N_("function %s does not exist"), name);
            return NULL;
        }
 
+       if (p[0] == K_SPECIAL && p[1] == KS_EXTRA && p[2] == (int)KE_SNR)
+       {
+           char_u *np;
+           size_t len = STRLEN(p) + 1;
+
+           if ((np = alloc(len + 2)) == NULL)
+           {
+               vim_free(p);
+               return NULL;
+           }
+           mch_memmove(np, "<SNR>", 5);
+           mch_memmove(np + 5, p + 3, len - 3);
+           vim_free(p);
+           self->name = np;
+       }
+       else
+           self->name = p;
+    }
+
     func_ref(self->name);
     self->argc = argc;
     self->argv = argv;
index c438ba04158d20521bbd00443043a98c15052832..d79400de714b55f8c0128a762ca44ac4b481891e 100644 (file)
@@ -36,3 +36,30 @@ func Test_set_cursor()
   normal j
   call assert_equal([2, 6], [line('.'), col('.')])
 endfunc
+
+func Test_vim_function()
+  " Check creating vim.Function object
+  py import vim
+
+  func s:foo()
+    return matchstr(expand('<sfile>'), '<SNR>\zs\d\+_foo$')
+  endfunc
+  let name = '<SNR>' . s:foo()
+
+  try
+    py f = vim.bindeval('function("s:foo")')
+    call assert_equal(name, pyeval('f.name'))
+  catch
+    call assert_false(v:exception)
+  endtry
+
+  try
+    py f = vim.Function('\x80\xfdR' + vim.eval('s:foo()'))
+    call assert_equal(name, pyeval('f.name'))
+  catch
+    call assert_false(v:exception)
+  endtry
+
+  py del f
+  delfunc s:foo
+endfunc
index 69ad8021316172d0cd9509877344bf04553be792..344034af0049434141ef71a2a6aa0e0f11b21092 100644 (file)
@@ -36,3 +36,30 @@ func Test_set_cursor()
   normal j
   call assert_equal([2, 6], [line('.'), col('.')])
 endfunc
+
+func Test_vim_function()
+  " Check creating vim.Function object
+  py3 import vim
+
+  func s:foo()
+    return matchstr(expand('<sfile>'), '<SNR>\zs\d\+_foo$')
+  endfunc
+  let name = '<SNR>' . s:foo()
+
+  try
+    py3 f = vim.bindeval('function("s:foo")')
+    call assert_equal(name, py3eval('f.name'))
+  catch
+    call assert_false(v:exception)
+  endtry
+
+  try
+    py3 f = vim.Function(b'\x80\xfdR' + vim.eval('s:foo()').encode())
+    call assert_equal(name, py3eval('f.name'))
+  catch
+    call assert_false(v:exception)
+  endtry
+
+  py3 del f
+  delfunc s:foo
+endfunc
index 4d39dde9d3824436bee1b37bea3cf4d233e05f32..101d7864d12e22532079b73a1034f7d0cf3e1922 100644 (file)
@@ -799,6 +799,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    627,
 /**/
     626,
 /**/