changeset 9119:39cc63e8df7c v7.4.1843

commit https://github.com/vim/vim/commit/2177f9fe18a927ef65ccebb0856722a28dc00252 Author: Bram Moolenaar <Bram@vim.org> Date: Wed May 25 20:39:09 2016 +0200 patch 7.4.1843 Problem: Tests involving Python are flaky. Solution: Set the pt_auto field. Add tests. (Nikolai Pavlov)
author Christian Brabandt <cb@256bit.org>
date Wed, 25 May 2016 20:45:06 +0200
parents c35c9121c72b
children 2d179e86d3c0
files runtime/doc/if_pyth.txt src/if_py_both.h src/testdir/test86.in src/testdir/test86.ok src/testdir/test87.in src/testdir/test87.ok src/version.c
diffstat 7 files changed, 293 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/runtime/doc/if_pyth.txt
+++ b/runtime/doc/if_pyth.txt
@@ -659,19 +659,31 @@ vim.Function object				*python-Function*
     `vim.bindeval('function(%s)'%json.dumps(name))`.
 
     Attributes (read-only):
-        Attribute  Description ~
-        name       Function name.
-        args       `None` or a |python-List| object with arguments.  Note that 
-                   this is a copy of the arguments list, constructed each time 
-                   you request this attribute. Modifications made to the list 
-                   will be ignored (but not to the containers inside argument 
-                   list: this is like |copy()| and not |deepcopy()|).
-        self       `None` or a |python-Dictionary| object with self 
-                   dictionary. Note that explicit `self` keyword used when 
-                   calling resulting object overrides this attribute.
+        Attribute    Description ~
+        name         Function name.
+        args         `None` or a |python-List| object with arguments.  Note 
+                     that this is a copy of the arguments list, constructed 
+                     each time you request this attribute. Modifications made 
+                     to the list will be ignored (but not to the containers 
+                     inside argument list: this is like |copy()| and not 
+                     |deepcopy()|).
+        self         `None` or a |python-Dictionary| object with self 
+                     dictionary. Note that explicit `self` keyword used when 
+                     calling resulting object overrides this attribute.
+        auto_rebind  Boolean. True if partial created from this Python object 
+                     and stored in the VimL dictionary should be automatically 
+                     rebound to the dictionary it is stored in when this 
+                     dictionary is indexed. Exposes Vim internal difference 
+                     between `dict.func` (auto_rebind=True) and 
+                     `function(dict.func,dict)` (auto_rebind=False). This 
+                     attribute makes no sense if `self` attribute is `None`.
 
-    Constructor additionally accepts `args` and `self` keywords.  If any of 
-    them is given then it constructs a partial, see |function()|.
+    Constructor additionally accepts `args`, `self` and `auto_rebind` 
+    keywords.  If `args` and/or `self` argument is given then it constructs 
+    a partial, see |function()|.  `auto_rebind` is only used when `self` 
+    argument is given, otherwise it is assumed to be `True` regardless of 
+    whether it was given or not.  If `self` is given then it defaults to 
+    `False`.
 
     Examples: >
         f = vim.Function('tr')			# Constructor
--- a/src/if_py_both.h
+++ b/src/if_py_both.h
@@ -2835,16 +2835,17 @@ typedef struct
     typval_T	*argv;
     dict_T	*self;
     pylinkedlist_T	ref;
+    int		auto_rebind;
 } FunctionObject;
 
 static PyTypeObject FunctionType;
 
-#define NEW_FUNCTION(name, argc, argv, self) \
-    FunctionNew(&FunctionType, name, argc, argv, self)
+#define NEW_FUNCTION(name, argc, argv, self, pt_auto) \
+    FunctionNew(&FunctionType, (name), (argc), (argv), (self), (pt_auto))
 
     static PyObject *
 FunctionNew(PyTypeObject *subtype, char_u *name, int argc, typval_T *argv,
-	dict_T *selfdict)
+	dict_T *selfdict, int auto_rebind)
 {
     FunctionObject	*self;
 
@@ -2877,6 +2878,7 @@ FunctionNew(PyTypeObject *subtype, char_
     self->argc = argc;
     self->argv = argv;
     self->self = selfdict;
+    self->auto_rebind = selfdict == NULL ? TRUE : auto_rebind;
 
     if (self->argv || self->self)
 	pyll_add((PyObject *)(self), &self->ref, &lastfunc);
@@ -2889,6 +2891,7 @@ FunctionConstructor(PyTypeObject *subtyp
 {
     PyObject	*self;
     PyObject	*selfdictObject;
+    PyObject	*autoRebindObject;
     PyObject	*argsObject = NULL;
     char_u	*name;
     typval_T	selfdicttv;
@@ -2896,6 +2899,7 @@ FunctionConstructor(PyTypeObject *subtyp
     list_T	*argslist = NULL;
     dict_T	*selfdict = NULL;
     int		argc = 0;
+    int		auto_rebind = TRUE;
     typval_T	*argv = NULL;
     typval_T	*curtv;
     listitem_T	*li;
@@ -2936,6 +2940,21 @@ FunctionConstructor(PyTypeObject *subtyp
 	    }
 	    list_unref(argslist);
 	}
+	if (selfdict != NULL)
+	{
+	    auto_rebind = FALSE;
+	    autoRebindObject = PyDict_GetItemString(kwargs, "auto_rebind");
+	    if (autoRebindObject != NULL)
+	    {
+		auto_rebind = PyObject_IsTrue(autoRebindObject);
+		if (auto_rebind == -1)
+		{
+		    dict_unref(selfdict);
+		    list_unref(argslist);
+		    return NULL;
+		}
+	    }
+	}
     }
 
     if (!PyArg_ParseTuple(args, "et", "ascii", &name))
@@ -2947,7 +2966,7 @@ FunctionConstructor(PyTypeObject *subtyp
 	return NULL;
     }
 
-    self = FunctionNew(subtype, name, argc, argv, selfdict);
+    self = FunctionNew(subtype, name, argc, argv, selfdict, auto_rebind);
 
     PyMem_Free(name);
 
@@ -2971,7 +2990,7 @@ FunctionDestructor(FunctionObject *self)
 }
 
 static char *FunctionAttrs[] = {
-    "softspace", "args", "self",
+    "softspace", "args", "self", "auto_rebind",
     NULL
 };
 
@@ -3001,6 +3020,10 @@ FunctionAttr(FunctionObject *self, char 
 	return self->self == NULL
 	    ? AlwaysNone(NULL)
 	    : NEW_DICTIONARY(self->self);
+    else if (strcmp(name, "auto_rebind") == 0)
+	return self->auto_rebind
+	    ? AlwaysTrue(NULL)
+	    : AlwaysFalse(NULL);
     else if (strcmp(name, "__members__") == 0)
 	return ObjectDir(NULL, FunctionAttrs);
     return NULL;
@@ -3035,6 +3058,7 @@ set_partial(FunctionObject *self, partia
 	pt->pt_argc = 0;
 	pt->pt_argv = NULL;
     }
+    pt->pt_auto = self->auto_rebind || !exported;
     pt->pt_dict = self->self;
     if (exported && self->self)
 	++pt->pt_dict->dv_refcount;
@@ -3076,6 +3100,7 @@ FunctionCall(FunctionObject *self, PyObj
 
     if (self->argv || self->self)
     {
+	vim_memset(&pt, 0, sizeof(partial_T));
 	set_partial(self, &pt, FALSE);
 	pt_ptr = &pt;
     }
@@ -3148,6 +3173,8 @@ FunctionRepr(FunctionObject *self)
 	ga_concat(&repr_ga, tv2string(&tv, &tofree, numbuf, get_copyID()));
 	--emsg_silent;
 	vim_free(tofree);
+	if (self->auto_rebind)
+	    ga_concat(&repr_ga, (char_u *)", auto_rebind=True");
     }
     ga_append(&repr_ga, '>');
     ret = PyString_FromString((char *)repr_ga.ga_data);
@@ -6269,7 +6296,7 @@ ConvertToPyObject(typval_T *tv)
 	case VAR_FUNC:
 	    return NEW_FUNCTION(tv->vval.v_string == NULL
 					  ? (char_u *)"" : tv->vval.v_string,
-					  0, NULL, NULL);
+					  0, NULL, NULL, TRUE);
 	case VAR_PARTIAL:
 	    if (tv->vval.v_partial->pt_argc)
 	    {
@@ -6284,7 +6311,8 @@ ConvertToPyObject(typval_T *tv)
 	    return NEW_FUNCTION(tv->vval.v_partial == NULL
 				? (char_u *)"" : tv->vval.v_partial->pt_name,
 				tv->vval.v_partial->pt_argc, argv,
-				tv->vval.v_partial->pt_dict);
+				tv->vval.v_partial->pt_dict,
+				tv->vval.v_partial->pt_auto);
 	case VAR_UNKNOWN:
 	case VAR_CHANNEL:
 	case VAR_JOB:
--- a/src/testdir/test86.in
+++ b/src/testdir/test86.in
@@ -877,6 +877,12 @@ EOF
 :$put =string(pyeval('vim.Function(''tr'', args=[])'))
 :$put =string(pyeval('vim.Function(''tr'', self={})'))
 :$put =string(pyeval('vim.Function(''tr'', args=[123, 3, 4], self={})'))
+:$put ='auto_rebind'
+:$put =string(pyeval('vim.Function(''tr'', auto_rebind=False)'))
+:$put =string(pyeval('vim.Function(''tr'', args=[123, 3, 4], auto_rebind=False)'))
+:$put =string(pyeval('vim.Function(''tr'', args=[], auto_rebind=False)'))
+:$put =string(pyeval('vim.Function(''tr'', self={}, auto_rebind=False)'))
+:$put =string(pyeval('vim.Function(''tr'', args=[123, 3, 4], self={}, auto_rebind=False)'))
 :"
 :" Test vim.Function
 :function Args(...)
@@ -915,11 +921,27 @@ psa1 = vim.Function('SelfArgs', args=['a
 psa2 = vim.Function('SelfArgs', args=[])
 psa3 = vim.Function('SelfArgs', args=['abcArgsPSA3'], self={'abcSelfPSA3': 'abcSelfPSA3Val'})
 psa4 = vim.Function('SelfArgs', self={'abcSelfPSA4': 'abcSelfPSA4Val'})
+psa5 = vim.Function('SelfArgs', self={'abcSelfPSA5': 'abcSelfPSA5Val'}, auto_rebind=0)
+psa6 = vim.Function('SelfArgs', args=['abcArgsPSA6'], self={'abcSelfPSA6': 'abcSelfPSA6Val'}, auto_rebind=())
+psa7 = vim.Function('SelfArgs', args=['abcArgsPSA7'], auto_rebind=[])
+psa8 = vim.Function('SelfArgs', auto_rebind=False)
+psa9 = vim.Function('SelfArgs', self={'abcSelfPSA9': 'abcSelfPSA9Val'}, auto_rebind=True)
+psaA = vim.Function('SelfArgs', args=['abcArgsPSAA'], self={'abcSelfPSAA': 'abcSelfPSAAVal'}, auto_rebind=1)
+psaB = vim.Function('SelfArgs', args=['abcArgsPSAB'], auto_rebind={'abcARPSAB': 'abcARPSABVal'})
+psaC = vim.Function('SelfArgs', auto_rebind=['abcARPSAC'])
 cb.append('sa: ' + repr(sa))
 cb.append('psa1: ' + repr(psa1))
 cb.append('psa2: ' + repr(psa2))
 cb.append('psa3: ' + repr(psa3))
 cb.append('psa4: ' + repr(psa4))
+cb.append('psa5: ' + repr(psa5))
+cb.append('psa6: ' + repr(psa6))
+cb.append('psa7: ' + repr(psa7))
+cb.append('psa8: ' + repr(psa8))
+cb.append('psa9: ' + repr(psa9))
+cb.append('psaA: ' + repr(psaA))
+cb.append('psaB: ' + repr(psaB))
+cb.append('psaC: ' + repr(psaC))
 
 psar = vim.Function('SelfArgs', args=[{'abcArgsPSAr': 'abcArgsPSArVal'}], self={'abcSelfPSAr': 'abcSelfPSArVal'})
 psar.args[0]['abcArgsPSAr2'] = [psar.self, psar.args[0]]
@@ -942,6 +964,19 @@ EOF
 :$put ='s(psa2): '.string(pyeval('psa2'))
 :$put ='s(psa3): '.string(pyeval('psa3'))
 :$put ='s(psa4): '.string(pyeval('psa4'))
+:$put ='s(psa5): '.string(pyeval('psa5'))
+:$put ='s(psa6): '.string(pyeval('psa6'))
+:$put ='s(psa7): '.string(pyeval('psa7'))
+:$put ='s(psa8): '.string(pyeval('psa8'))
+:$put ='s(psa9): '.string(pyeval('psa9'))
+:$put ='s(psaA): '.string(pyeval('psaA'))
+:$put ='s(psaB): '.string(pyeval('psaB'))
+:$put ='s(psaC): '.string(pyeval('psaC'))
+:
+:for v in ['sa', 'psa1', 'psa2', 'psa3', 'psa4', 'psa5', 'psa6', 'psa7', 'psa8', 'psa9', 'psaA', 'psaB', 'psaC']
+:   let d = {'f': pyeval(v)}
+:   $put ='d.'.v.'(): '.string(d.f())
+:endfor
 :
 :py ecall('a()', a, )
 :py ecall('pa1()', pa1, )
@@ -1026,6 +1061,25 @@ cb.append('psa2.name: ' + s(psa2.name))
 cb.append('psa3.name: ' + s(psa3.name))
 cb.append('psa4.name: ' + s(psa4.name))
 
+cb.append('a.auto_rebind: ' + s(a.auto_rebind))
+cb.append('pa1.auto_rebind: ' + s(pa1.auto_rebind))
+cb.append('pa2.auto_rebind: ' + s(pa2.auto_rebind))
+cb.append('pa3.auto_rebind: ' + s(pa3.auto_rebind))
+cb.append('pa4.auto_rebind: ' + s(pa4.auto_rebind))
+cb.append('sa.auto_rebind: ' + s(sa.auto_rebind))
+cb.append('psa1.auto_rebind: ' + s(psa1.auto_rebind))
+cb.append('psa2.auto_rebind: ' + s(psa2.auto_rebind))
+cb.append('psa3.auto_rebind: ' + s(psa3.auto_rebind))
+cb.append('psa4.auto_rebind: ' + s(psa4.auto_rebind))
+cb.append('psa5.auto_rebind: ' + s(psa5.auto_rebind))
+cb.append('psa6.auto_rebind: ' + s(psa6.auto_rebind))
+cb.append('psa7.auto_rebind: ' + s(psa7.auto_rebind))
+cb.append('psa8.auto_rebind: ' + s(psa8.auto_rebind))
+cb.append('psa9.auto_rebind: ' + s(psa9.auto_rebind))
+cb.append('psaA.auto_rebind: ' + s(psaA.auto_rebind))
+cb.append('psaB.auto_rebind: ' + s(psaB.auto_rebind))
+cb.append('psaC.auto_rebind: ' + s(psaC.auto_rebind))
+
 del s
 
 del a
@@ -1038,6 +1092,14 @@ del psa1
 del psa2
 del psa3
 del psa4
+del psa5
+del psa6
+del psa7
+del psa8
+del psa9
+del psaA
+del psaB
+del psaC
 del psar
 
 del ecall
--- a/src/testdir/test86.ok
+++ b/src/testdir/test86.ok
@@ -448,7 +448,7 @@ tabpage:__dir__,__members__,number,valid
 range:__dir__,__members__,append,end,start
 dictionary:__dir__,__members__,get,has_key,items,keys,locked,pop,popitem,scope,update,values
 list:__dir__,__members__,extend,locked
-function:__dir__,__members__,args,self,softspace
+function:__dir__,__members__,args,auto_rebind,self,softspace
 output:__dir__,__members__,close,closed,flush,isatty,readable,seekable,softspace,writable,write,writelines
 {}
 {'a': 1}
@@ -460,6 +460,12 @@ function('tr', [123, 3, 4])
 function('tr')
 function('tr', {})
 function('tr', [123, 3, 4], {})
+auto_rebind
+function('tr')
+function('tr', [123, 3, 4])
+function('tr')
+function('tr', {})
+function('tr', [123, 3, 4], {})
 a: <vim.Function 'Args'>
 pa1: <vim.Function 'Args', args=['abcArgsPA1']>
 pa2: <vim.Function 'Args'>
@@ -470,6 +476,14 @@ psa1: <vim.Function 'SelfArgs', args=['a
 psa2: <vim.Function 'SelfArgs'>
 psa3: <vim.Function 'SelfArgs', args=['abcArgsPSA3'], self={'abcSelfPSA3': 'abcSelfPSA3Val'}>
 psa4: <vim.Function 'SelfArgs', self={'abcSelfPSA4': 'abcSelfPSA4Val'}>
+psa5: <vim.Function 'SelfArgs', self={'abcSelfPSA5': 'abcSelfPSA5Val'}>
+psa6: <vim.Function 'SelfArgs', args=['abcArgsPSA6'], self={'abcSelfPSA6': 'abcSelfPSA6Val'}>
+psa7: <vim.Function 'SelfArgs', args=['abcArgsPSA7']>
+psa8: <vim.Function 'SelfArgs'>
+psa9: <vim.Function 'SelfArgs', self={'abcSelfPSA9': 'abcSelfPSA9Val'}, auto_rebind=True>
+psaA: <vim.Function 'SelfArgs', args=['abcArgsPSAA'], self={'abcSelfPSAA': 'abcSelfPSAAVal'}, auto_rebind=True>
+psaB: <vim.Function 'SelfArgs', args=['abcArgsPSAB']>
+psaC: <vim.Function 'SelfArgs'>
 psar: <vim.Function 'SelfArgs', args=[{'abcArgsPSAr2': [{'rec': function('SelfArgs', [{...}], {...}), 'self': {...}, 'abcSelfPSAr': 'abcSelfPSArVal', 'args': [{...}]}, {...}], 'abcArgsPSAr': 'abcArgsPSArVal'}], self={'rec': function('SelfArgs', [{'abcArgsPSAr2': [{...}, {...}], 'abcArgsPSAr': 'abcArgsPSArVal'}], {...}), 'self': {...}, 'abcSelfPSAr': 'abcSelfPSArVal', 'args': [{...}]}>
 s(a): function('Args')
 s(pa1): function('Args', ['abcArgsPA1'])
@@ -481,6 +495,27 @@ s(psa1): function('SelfArgs', ['abcArgsP
 s(psa2): function('SelfArgs')
 s(psa3): function('SelfArgs', ['abcArgsPSA3'], {'abcSelfPSA3': 'abcSelfPSA3Val'})
 s(psa4): function('SelfArgs', {'abcSelfPSA4': 'abcSelfPSA4Val'})
+s(psa5): function('SelfArgs', {'abcSelfPSA5': 'abcSelfPSA5Val'})
+s(psa6): function('SelfArgs', ['abcArgsPSA6'], {'abcSelfPSA6': 'abcSelfPSA6Val'})
+s(psa7): function('SelfArgs', ['abcArgsPSA7'])
+s(psa8): function('SelfArgs')
+s(psa9): function('SelfArgs', {'abcSelfPSA9': 'abcSelfPSA9Val'})
+s(psaA): function('SelfArgs', ['abcArgsPSAA'], {'abcSelfPSAA': 'abcSelfPSAAVal'})
+s(psaB): function('SelfArgs', ['abcArgsPSAB'])
+s(psaC): function('SelfArgs')
+d.sa(): [[], {'f': function('SelfArgs')}]
+d.psa1(): [['abcArgsPSA1'], {'f': function('SelfArgs', ['abcArgsPSA1'])}]
+d.psa2(): [[], {'f': function('SelfArgs')}]
+d.psa3(): [['abcArgsPSA3'], {'abcSelfPSA3': 'abcSelfPSA3Val'}]
+d.psa4(): [[], {'abcSelfPSA4': 'abcSelfPSA4Val'}]
+d.psa5(): [[], {'abcSelfPSA5': 'abcSelfPSA5Val'}]
+d.psa6(): [['abcArgsPSA6'], {'abcSelfPSA6': 'abcSelfPSA6Val'}]
+d.psa7(): [['abcArgsPSA7'], {'f': function('SelfArgs', ['abcArgsPSA7'])}]
+d.psa8(): [[], {'f': function('SelfArgs')}]
+d.psa9(): [[], {'f': function('SelfArgs', {'abcSelfPSA9': 'abcSelfPSA9Val'})}]
+d.psaA(): [['abcArgsPSAA'], {'f': function('SelfArgs', ['abcArgsPSAA'], {'abcSelfPSAA': 'abcSelfPSAAVal'})}]
+d.psaB(): [['abcArgsPSAB'], {'f': function('SelfArgs', ['abcArgsPSAB'])}]
+d.psaC(): [[], {'f': function('SelfArgs')}]
 a(): !result: []
 pa1(): !result: ['abcArgsPA1']
 pa2(): !result: []
@@ -551,6 +586,24 @@ psa1.name: 'SelfArgs'
 psa2.name: 'SelfArgs'
 psa3.name: 'SelfArgs'
 psa4.name: 'SelfArgs'
+a.auto_rebind: 1
+pa1.auto_rebind: 1
+pa2.auto_rebind: 1
+pa3.auto_rebind: 0
+pa4.auto_rebind: 0
+sa.auto_rebind: 1
+psa1.auto_rebind: 1
+psa2.auto_rebind: 1
+psa3.auto_rebind: 0
+psa4.auto_rebind: 0
+psa5.auto_rebind: 0
+psa6.auto_rebind: 0
+psa7.auto_rebind: 1
+psa8.auto_rebind: 1
+psa9.auto_rebind: 1
+psaA.auto_rebind: 1
+psaB.auto_rebind: 1
+psaC.auto_rebind: 1
 '
 abcdef
 Error detected while processing function RunTest[]..Test:
--- a/src/testdir/test87.in
+++ b/src/testdir/test87.in
@@ -871,6 +871,12 @@ EOF
 :$put =string(py3eval('vim.Function(''tr'', args=[])'))
 :$put =string(py3eval('vim.Function(''tr'', self={})'))
 :$put =string(py3eval('vim.Function(''tr'', args=[123, 3, 4], self={})'))
+:$put ='auto_rebind'
+:$put =string(py3eval('vim.Function(''tr'', auto_rebind=False)'))
+:$put =string(py3eval('vim.Function(''tr'', args=[123, 3, 4], auto_rebind=False)'))
+:$put =string(py3eval('vim.Function(''tr'', args=[], auto_rebind=False)'))
+:$put =string(py3eval('vim.Function(''tr'', self={}, auto_rebind=False)'))
+:$put =string(py3eval('vim.Function(''tr'', args=[123, 3, 4], self={}, auto_rebind=False)'))
 :"
 :" Test vim.Function
 :function Args(...)
@@ -909,11 +915,27 @@ psa1 = vim.Function('SelfArgs', args=['a
 psa2 = vim.Function('SelfArgs', args=[])
 psa3 = vim.Function('SelfArgs', args=['abcArgsPSA3'], self={'abcSelfPSA3': 'abcSelfPSA3Val'})
 psa4 = vim.Function('SelfArgs', self={'abcSelfPSA4': 'abcSelfPSA4Val'})
+psa5 = vim.Function('SelfArgs', self={'abcSelfPSA5': 'abcSelfPSA5Val'}, auto_rebind=0)
+psa6 = vim.Function('SelfArgs', args=['abcArgsPSA6'], self={'abcSelfPSA6': 'abcSelfPSA6Val'}, auto_rebind=())
+psa7 = vim.Function('SelfArgs', args=['abcArgsPSA7'], auto_rebind=[])
+psa8 = vim.Function('SelfArgs', auto_rebind=False)
+psa9 = vim.Function('SelfArgs', self={'abcSelfPSA9': 'abcSelfPSA9Val'}, auto_rebind=True)
+psaA = vim.Function('SelfArgs', args=['abcArgsPSAA'], self={'abcSelfPSAA': 'abcSelfPSAAVal'}, auto_rebind=1)
+psaB = vim.Function('SelfArgs', args=['abcArgsPSAB'], auto_rebind={'abcARPSAB': 'abcARPSABVal'})
+psaC = vim.Function('SelfArgs', auto_rebind=['abcARPSAC'])
 cb.append('sa: ' + repr(sa))
 cb.append('psa1: ' + repr(psa1))
 cb.append('psa2: ' + repr(psa2))
 cb.append('psa3: ' + repr(psa3))
 cb.append('psa4: ' + repr(psa4))
+cb.append('psa5: ' + repr(psa5))
+cb.append('psa6: ' + repr(psa6))
+cb.append('psa7: ' + repr(psa7))
+cb.append('psa8: ' + repr(psa8))
+cb.append('psa9: ' + repr(psa9))
+cb.append('psaA: ' + repr(psaA))
+cb.append('psaB: ' + repr(psaB))
+cb.append('psaC: ' + repr(psaC))
 
 psar = vim.Function('SelfArgs', args=[{'abcArgsPSAr': 'abcArgsPSArVal'}], self={'abcSelfPSAr': 'abcSelfPSArVal'})
 psar.args[0]['abcArgsPSAr2'] = [psar.self, psar.args[0]]
@@ -936,6 +958,19 @@ EOF
 :$put ='s(psa2): '.string(py3eval('psa2'))
 :$put ='s(psa3): '.string(py3eval('psa3'))
 :$put ='s(psa4): '.string(py3eval('psa4'))
+:$put ='s(psa5): '.string(py3eval('psa5'))
+:$put ='s(psa6): '.string(py3eval('psa6'))
+:$put ='s(psa7): '.string(py3eval('psa7'))
+:$put ='s(psa8): '.string(py3eval('psa8'))
+:$put ='s(psa9): '.string(py3eval('psa9'))
+:$put ='s(psaA): '.string(py3eval('psaA'))
+:$put ='s(psaB): '.string(py3eval('psaB'))
+:$put ='s(psaC): '.string(py3eval('psaC'))
+:
+:for v in ['sa', 'psa1', 'psa2', 'psa3', 'psa4', 'psa5', 'psa6', 'psa7', 'psa8', 'psa9', 'psaA', 'psaB', 'psaC']
+:   let d = {'f': py3eval(v)}
+:   $put ='d.'.v.'(): '.string(d.f())
+:endfor
 :
 :py3 ecall('a()', a, )
 :py3 ecall('pa1()', pa1, )
@@ -1020,6 +1055,25 @@ cb.append('psa2.name: ' + s(psa2.name))
 cb.append('psa3.name: ' + s(psa3.name))
 cb.append('psa4.name: ' + s(psa4.name))
 
+cb.append('a.auto_rebind: ' + s(a.auto_rebind))
+cb.append('pa1.auto_rebind: ' + s(pa1.auto_rebind))
+cb.append('pa2.auto_rebind: ' + s(pa2.auto_rebind))
+cb.append('pa3.auto_rebind: ' + s(pa3.auto_rebind))
+cb.append('pa4.auto_rebind: ' + s(pa4.auto_rebind))
+cb.append('sa.auto_rebind: ' + s(sa.auto_rebind))
+cb.append('psa1.auto_rebind: ' + s(psa1.auto_rebind))
+cb.append('psa2.auto_rebind: ' + s(psa2.auto_rebind))
+cb.append('psa3.auto_rebind: ' + s(psa3.auto_rebind))
+cb.append('psa4.auto_rebind: ' + s(psa4.auto_rebind))
+cb.append('psa5.auto_rebind: ' + s(psa5.auto_rebind))
+cb.append('psa6.auto_rebind: ' + s(psa6.auto_rebind))
+cb.append('psa7.auto_rebind: ' + s(psa7.auto_rebind))
+cb.append('psa8.auto_rebind: ' + s(psa8.auto_rebind))
+cb.append('psa9.auto_rebind: ' + s(psa9.auto_rebind))
+cb.append('psaA.auto_rebind: ' + s(psaA.auto_rebind))
+cb.append('psaB.auto_rebind: ' + s(psaB.auto_rebind))
+cb.append('psaC.auto_rebind: ' + s(psaC.auto_rebind))
+
 del s
 
 del a
@@ -1032,6 +1086,14 @@ del psa1
 del psa2
 del psa3
 del psa4
+del psa5
+del psa6
+del psa7
+del psa8
+del psa9
+del psaA
+del psaB
+del psaC
 del psar
 
 del ecall
--- a/src/testdir/test87.ok
+++ b/src/testdir/test87.ok
@@ -448,7 +448,7 @@ tabpage:__dir__,number,valid,vars,window
 range:__dir__,append,end,start
 dictionary:__dir__,get,has_key,items,keys,locked,pop,popitem,scope,update,values
 list:__dir__,extend,locked
-function:__dir__,args,self,softspace
+function:__dir__,args,auto_rebind,self,softspace
 output:__dir__,close,closed,flush,isatty,readable,seekable,softspace,writable,write,writelines
 {}
 {'a': 1}
@@ -460,6 +460,12 @@ function('tr', [123, 3, 4])
 function('tr')
 function('tr', {})
 function('tr', [123, 3, 4], {})
+auto_rebind
+function('tr')
+function('tr', [123, 3, 4])
+function('tr')
+function('tr', {})
+function('tr', [123, 3, 4], {})
 a: <vim.Function 'Args'>
 pa1: <vim.Function 'Args', args=['abcArgsPA1']>
 pa2: <vim.Function 'Args'>
@@ -470,6 +476,14 @@ psa1: <vim.Function 'SelfArgs', args=['a
 psa2: <vim.Function 'SelfArgs'>
 psa3: <vim.Function 'SelfArgs', args=['abcArgsPSA3'], self={'abcSelfPSA3': 'abcSelfPSA3Val'}>
 psa4: <vim.Function 'SelfArgs', self={'abcSelfPSA4': 'abcSelfPSA4Val'}>
+psa5: <vim.Function 'SelfArgs', self={'abcSelfPSA5': 'abcSelfPSA5Val'}>
+psa6: <vim.Function 'SelfArgs', args=['abcArgsPSA6'], self={'abcSelfPSA6': 'abcSelfPSA6Val'}>
+psa7: <vim.Function 'SelfArgs', args=['abcArgsPSA7']>
+psa8: <vim.Function 'SelfArgs'>
+psa9: <vim.Function 'SelfArgs', self={'abcSelfPSA9': 'abcSelfPSA9Val'}, auto_rebind=True>
+psaA: <vim.Function 'SelfArgs', args=['abcArgsPSAA'], self={'abcSelfPSAA': 'abcSelfPSAAVal'}, auto_rebind=True>
+psaB: <vim.Function 'SelfArgs', args=['abcArgsPSAB']>
+psaC: <vim.Function 'SelfArgs'>
 psar: <vim.Function 'SelfArgs', args=[{'abcArgsPSAr2': [{'rec': function('SelfArgs', [{...}], {...}), 'self': {...}, 'abcSelfPSAr': 'abcSelfPSArVal', 'args': [{...}]}, {...}], 'abcArgsPSAr': 'abcArgsPSArVal'}], self={'rec': function('SelfArgs', [{'abcArgsPSAr2': [{...}, {...}], 'abcArgsPSAr': 'abcArgsPSArVal'}], {...}), 'self': {...}, 'abcSelfPSAr': 'abcSelfPSArVal', 'args': [{...}]}>
 s(a): function('Args')
 s(pa1): function('Args', ['abcArgsPA1'])
@@ -481,6 +495,27 @@ s(psa1): function('SelfArgs', ['abcArgsP
 s(psa2): function('SelfArgs')
 s(psa3): function('SelfArgs', ['abcArgsPSA3'], {'abcSelfPSA3': 'abcSelfPSA3Val'})
 s(psa4): function('SelfArgs', {'abcSelfPSA4': 'abcSelfPSA4Val'})
+s(psa5): function('SelfArgs', {'abcSelfPSA5': 'abcSelfPSA5Val'})
+s(psa6): function('SelfArgs', ['abcArgsPSA6'], {'abcSelfPSA6': 'abcSelfPSA6Val'})
+s(psa7): function('SelfArgs', ['abcArgsPSA7'])
+s(psa8): function('SelfArgs')
+s(psa9): function('SelfArgs', {'abcSelfPSA9': 'abcSelfPSA9Val'})
+s(psaA): function('SelfArgs', ['abcArgsPSAA'], {'abcSelfPSAA': 'abcSelfPSAAVal'})
+s(psaB): function('SelfArgs', ['abcArgsPSAB'])
+s(psaC): function('SelfArgs')
+d.sa(): [[], {'f': function('SelfArgs')}]
+d.psa1(): [['abcArgsPSA1'], {'f': function('SelfArgs', ['abcArgsPSA1'])}]
+d.psa2(): [[], {'f': function('SelfArgs')}]
+d.psa3(): [['abcArgsPSA3'], {'abcSelfPSA3': 'abcSelfPSA3Val'}]
+d.psa4(): [[], {'abcSelfPSA4': 'abcSelfPSA4Val'}]
+d.psa5(): [[], {'abcSelfPSA5': 'abcSelfPSA5Val'}]
+d.psa6(): [['abcArgsPSA6'], {'abcSelfPSA6': 'abcSelfPSA6Val'}]
+d.psa7(): [['abcArgsPSA7'], {'f': function('SelfArgs', ['abcArgsPSA7'])}]
+d.psa8(): [[], {'f': function('SelfArgs')}]
+d.psa9(): [[], {'f': function('SelfArgs', {'abcSelfPSA9': 'abcSelfPSA9Val'})}]
+d.psaA(): [['abcArgsPSAA'], {'f': function('SelfArgs', ['abcArgsPSAA'], {'abcSelfPSAA': 'abcSelfPSAAVal'})}]
+d.psaB(): [['abcArgsPSAB'], {'f': function('SelfArgs', ['abcArgsPSAB'])}]
+d.psaC(): [[], {'f': function('SelfArgs')}]
 a(): !result: []
 pa1(): !result: ['abcArgsPA1']
 pa2(): !result: []
@@ -551,6 +586,24 @@ psa1.name: 'SelfArgs'
 psa2.name: 'SelfArgs'
 psa3.name: 'SelfArgs'
 psa4.name: 'SelfArgs'
+a.auto_rebind: 1
+pa1.auto_rebind: 1
+pa2.auto_rebind: 1
+pa3.auto_rebind: 0
+pa4.auto_rebind: 0
+sa.auto_rebind: 1
+psa1.auto_rebind: 1
+psa2.auto_rebind: 1
+psa3.auto_rebind: 0
+psa4.auto_rebind: 0
+psa5.auto_rebind: 0
+psa6.auto_rebind: 0
+psa7.auto_rebind: 1
+psa8.auto_rebind: 1
+psa9.auto_rebind: 1
+psaA.auto_rebind: 1
+psaB.auto_rebind: 1
+psaC.auto_rebind: 1
 '
 abcdef
 Error detected while processing function RunTest[]..Test:
--- a/src/version.c
+++ b/src/version.c
@@ -754,6 +754,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1843,
+/**/
     1842,
 /**/
     1841,