Patch 7.4.1836

67 views
Skip to first unread message

Bram Moolenaar

unread,
May 24, 2016, 9:44:37 AM5/24/16
to vim...@googlegroups.com

Patch 7.4.1836
Problem: When using a partial on a dictionary it always gets bound to that
dictionary.
Solution: Make a difference between binding a function to a dictionary
explicitly or automatically.
Files: src/structs.h, src/eval.c, src/testdir/test_partial.vim,
runtime/doc/eval.txt


*** ../vim-7.4.1835/src/structs.h 2016-05-09 17:57:59.810722519 +0200
--- src/structs.h 2016-05-24 13:13:50.267420387 +0200
***************
*** 1261,1266 ****
--- 1261,1268 ----
{
int pt_refcount; /* reference count */
char_u *pt_name; /* function name */
+ int pt_auto; /* when TRUE the partial was created for using
+ dict.member in handle_subscript() */
int pt_argc; /* number of arguments */
typval_T *pt_argv; /* arguments in allocated array */
dict_T *pt_dict; /* dict for "self" */
*** ../vim-7.4.1835/src/eval.c 2016-05-15 18:00:11.510811069 +0200
--- src/eval.c 2016-05-24 15:37:25.719301875 +0200
***************
*** 9069,9082 ****

if (partial != NULL)
{
! if (partial->pt_dict != NULL)
! {
! /* When the function has a partial with a dict and there is a dict
! * argument, use the dict argument. That is backwards compatible.
! */
! if (selfdict_in == NULL)
! selfdict = partial->pt_dict;
! }
if (error == ERROR_NONE && partial->pt_argc > 0)
{
for (argv_clear = 0; argv_clear < partial->pt_argc; ++argv_clear)
--- 9069,9080 ----

if (partial != NULL)
{
! /* When the function has a partial with a dict and there is a dict
! * argument, use the dict argument. That is backwards compatible.
! * When the dict was bound explicitly use the one from the partial. */
! if (partial->pt_dict != NULL
! && (selfdict_in == NULL || !partial->pt_auto))
! selfdict = partial->pt_dict;
if (error == ERROR_NONE && partial->pt_argc > 0)
{
for (argv_clear = 0; argv_clear < partial->pt_argc; ++argv_clear)
***************
*** 12330,12341 ****
--- 12328,12343 ----
* use "dict". That is backwards compatible. */
if (dict_idx > 0)
{
+ /* The dict is bound explicitly, pt_auto is FALSE. */
pt->pt_dict = argvars[dict_idx].vval.v_dict;
++pt->pt_dict->dv_refcount;
}
else if (arg_pt != NULL)
{
+ /* If the dict was bound automatically the result is also
+ * bound automatically. */
pt->pt_dict = arg_pt->pt_dict;
+ pt->pt_auto = arg_pt->pt_auto;
if (pt->pt_dict != NULL)
++pt->pt_dict->dv_refcount;
}
***************
*** 22279,22286 ****
}
}

! if ((rettv->v_type == VAR_FUNC || rettv->v_type == VAR_PARTIAL)
! && selfdict != NULL)
{
char_u *fname = rettv->v_type == VAR_FUNC ? rettv->vval.v_string
: rettv->vval.v_partial->pt_name;
--- 22281,22294 ----
}
}

! /* Turn "dict.Func" into a partial for "Func" bound to "dict".
! * Don't do this when "Func" is already a partial that was bound
! * explicitly (pt_auto is FALSE). */
! if (selfdict != NULL
! && (rettv->v_type == VAR_FUNC
! || (rettv->v_type == VAR_PARTIAL
! && (rettv->vval.v_partial->pt_auto
! || rettv->vval.v_partial->pt_dict == NULL))))
{
char_u *fname = rettv->v_type == VAR_FUNC ? rettv->vval.v_string
: rettv->vval.v_partial->pt_name;
***************
*** 22294,22300 ****
fp = find_func(fname);
vim_free(tofree);

- /* Turn "dict.Func" into a partial for "Func" with "dict". */
if (fp != NULL && (fp->uf_flags & FC_DICT))
{
partial_T *pt = (partial_T *)alloc_clear(sizeof(partial_T));
--- 22302,22307 ----
***************
*** 22303,22308 ****
--- 22310,22316 ----
{
pt->pt_refcount = 1;
pt->pt_dict = selfdict;
+ pt->pt_auto = TRUE;
selfdict = NULL;
if (rettv->v_type == VAR_FUNC)
{
*** ../vim-7.4.1835/src/testdir/test_partial.vim 2016-04-08 17:25:15.198702510 +0200
--- src/testdir/test_partial.vim 2016-05-24 15:41:07.923298818 +0200
***************
*** 257,259 ****
--- 257,281 ----
call job_setoptions(g:ref_job, {'exit_cb': function('string', [], d)})
endif
endfunc
+
+ func Test_auto_partial_rebind()
+ let dict1 = {'name': 'dict1'}
+ func! dict1.f1()
+ return self.name
+ endfunc
+ let dict1.f2 = function(dict1.f1, dict1)
+
+ call assert_equal('dict1', dict1.f1())
+ call assert_equal('dict1', dict1['f1']())
+ call assert_equal('dict1', dict1.f2())
+ call assert_equal('dict1', dict1['f2']())
+
+ let dict2 = {'name': 'dict2'}
+ let dict2.f1 = dict1.f1
+ let dict2.f2 = dict1.f2
+
+ call assert_equal('dict2', dict2.f1())
+ call assert_equal('dict2', dict2['f1']())
+ call assert_equal('dict1', dict2.f2())
+ call assert_equal('dict1', dict2['f2']())
+ endfunc
*** ../vim-7.4.1835/runtime/doc/eval.txt 2016-04-14 13:51:16.211410903 +0200
--- runtime/doc/eval.txt 2016-05-24 12:46:44.923442745 +0200
***************
*** 61,72 ****

Funcref A reference to a function |Funcref|.
Example: function("strlen")

Special |v:false|, |v:true|, |v:none| and |v:null|. *Special*

! Job Used for a job, see |job_start()|. *Job*

! Channel Used for a channel, see |ch_open()|. *Channel*

The Number and String types are converted automatically, depending on how they
are used.
--- 59,73 ----

Funcref A reference to a function |Funcref|.
Example: function("strlen")
+ It can be bound to a dictionary and arguments, it then works
+ like a Partial.
+ Example: function("Callback", [arg], myDict)

Special |v:false|, |v:true|, |v:none| and |v:null|. *Special*

! Job Used for a job, see |job_start()|. *Job* *Jobs*

! Channel Used for a channel, see |ch_open()|. *Channel* *Channels*

The Number and String types are converted automatically, depending on how they
are used.
***************
*** 150,159 ****
You can use |call()| to invoke a Funcref and use a list variable for the
arguments: >
:let r = call(Fn, mylist)


1.3 Lists ~
! *List* *Lists* *E686*
A List is an ordered sequence of items. An item can be of any type. Items
can be accessed by their index number. Items can be added and removed at any
position in the sequence.
--- 153,199 ----
You can use |call()| to invoke a Funcref and use a list variable for the
arguments: >
:let r = call(Fn, mylist)
+ <
+ *Partial*
+ A Funcref optionally binds a Dictionary and/or arguments. This is also called
+ a Partial. This is created by passing the Dictionary and/or arguments to
+ function(). When calling the function the Dictionary and/or arguments will be
+ passed to the function. Example: >
+
+ let Cb = function('Callback', ['foo'], myDict)
+ call Cb()
+
+ This will invoke the function as if using: >
+ call myDict.Callback('foo')
+
+ This is very useful when passing a function around, e.g. in the arguments of
+ |ch_open()|.
+
+ Note that binding a function to a Dictionary also happens when the function is
+ a member of the Dictionary: >
+
+ let myDict.myFunction = MyFunction
+ call myDict.myFunction()
+
+ Here MyFunction() will get myDict passed as "self". This happens when the
+ "myFunction" member is accessed. When making assigning "myFunction" to
+ otherDict and calling it, it will be bound to otherDict: >
+
+ let otherDict.myFunction = myDict.myFunction
+ call otherDict.myFunction()
+
+ Now "self" will be "otherDict". But when the dictionary was bound explicitly
+ this won't happen: >
+
+ let myDict.myFunction = function(MyFunction, myDict)
+ let otherDict.myFunction = myDict.myFunction
+ call otherDict.myFunction()
+
+ Here "self" will be "myDict", because it was bound explitly.


1.3 Lists ~
! *list* *List* *Lists* *E686*
A List is an ordered sequence of items. An item can be of any type. Items
can be accessed by their index number. Items can be added and removed at any
position in the sequence.
*** ../vim-7.4.1835/src/version.c 2016-05-24 11:31:10.523505120 +0200
--- src/version.c 2016-05-24 15:41:19.031298666 +0200
***************
*** 755,756 ****
--- 755,758 ----
{ /* Add new patch number below this line */
+ /**/
+ 1836,
/**/

--
It's totally unfair to suggest - as many have - that engineers are socially
inept. Engineers simply have different objectives when it comes to social
interaction.
(Scott Adams - The Dilbert principle)

/// Bram Moolenaar -- Br...@Moolenaar.net -- 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 ///

Bram Moolenaar

unread,
May 24, 2016, 11:50:49 AM5/24/16
to Bram Moolenaar, vim...@googlegroups.com

I wrote:

> Patch 7.4.1836
> Problem: When using a partial on a dictionary it always gets bound to that
> dictionary.
> Solution: Make a difference between binding a function to a dictionary
> explicitly or automatically.
> Files: src/structs.h, src/eval.c, src/testdir/test_partial.vim,
> runtime/doc/eval.txt

I hope this doesn't break anything. At least code that was written
before Partials were introduced.

I hope it's not too difficult to understand:
- When using dict.member the dict is bound automatically to member
- When using function() to bind a dict that dict is kept and not change
by automatic binding.

It might be useful to add some more explanation in the documentation.
Let me know if you have a suggestion.

--
The process for understanding customers primarily involves sitting around with
other marketing people and talking about what you would to if you were dumb
enough to be a customer.

Christian Brabandt

unread,
May 24, 2016, 4:14:09 PM5/24/16
to vim...@googlegroups.com
Hi Bram!

On Di, 24 Mai 2016, Bram Moolenaar wrote:

>
> Patch 7.4.1836
> Problem: When using a partial on a dictionary it always gets bound to that
> dictionary.
> Solution: Make a difference between binding a function to a dictionary
> explicitly or automatically.
> Files: src/structs.h, src/eval.c, src/testdir/test_partial.vim,
> runtime/doc/eval.txt

Starting with this patch, I see sporadic failures on appveyor:
https://ci.appveyor.com/project/chrisbra/vim/build/1234/job/wlpgqc4vnyvrdgqo
https://ci.appveyor.com/project/chrisbra/vim/build/1239/job/2p6y8dru0sv216dv#L2073
https://ci.appveyor.com/project/chrisbra/vim/build/1238/job/q4e5huq9x6opj6id#L2073


test86:
..\gvim -u dos.vim -U NONE --noplugin --not-a-term "+set ff=unix|f
test.out|wq" dostmp\test86.out
522c522
< psa3(self={"20": 1}): !result: [['abcArgsPSA3'], {'abcSelfPSA3':
'abcSelfPSA3Val'}]
---
> psa3(self={"20": 1}): !result: [['abcArgsPSA3'], {'20': 1}


Best,
Christian
--
Was ist das Allgemeine?
Der einzelne Fall.
Was ist das Besondere?
Millionen Fälle.
-- Goethe, Maximen und Reflektionen, Nr. 875

Bram Moolenaar

unread,
May 24, 2016, 5:17:46 PM5/24/16
to Christian Brabandt, vim...@googlegroups.com

Christian Brabandt wrote:

> On Di, 24 Mai 2016, Bram Moolenaar wrote:
>
> >
> > Patch 7.4.1836
> > Problem: When using a partial on a dictionary it always gets bound to that
> > dictionary.
> > Solution: Make a difference between binding a function to a dictionary
> > explicitly or automatically.
> > Files: src/structs.h, src/eval.c, src/testdir/test_partial.vim,
> > runtime/doc/eval.txt
>
> Starting with this patch, I see sporadic failures on appveyor:
> https://ci.appveyor.com/project/chrisbra/vim/build/1234/job/wlpgqc4vnyvrdgqo
> https://ci.appveyor.com/project/chrisbra/vim/build/1239/job/2p6y8dru0sv216dv#L2073
> https://ci.appveyor.com/project/chrisbra/vim/build/1238/job/q4e5huq9x6opj6id#L2073
>
>
> test86:
> ..\gvim -u dos.vim -U NONE --noplugin --not-a-term "+set ff=unix|f
> test.out|wq" dostmp\test86.out
> 522c522
> < psa3(self={"20": 1}): !result: [['abcArgsPSA3'], {'abcSelfPSA3':
> 'abcSelfPSA3Val'}]
> ---
> > psa3(self={"20": 1}): !result: [['abcArgsPSA3'], {'20': 1}

I noticed. It's strange that it only fails sometimes.
This is an old style test without any comments, it's hard to see what
it's doing. I believe Nikolai wrote this, hopefully he knows.

--
A)bort, R)etry, B)ang it with a large hammer

Nikolay Aleksandrovich Pavlov

unread,
May 24, 2016, 5:58:34 PM5/24/16
to vim_dev
2016-05-24 23:14 GMT+03:00 Christian Brabandt <cbl...@256bit.org>:
> Hi Bram!
>
> On Di, 24 Mai 2016, Bram Moolenaar wrote:
>
>>
>> Patch 7.4.1836
>> Problem: When using a partial on a dictionary it always gets bound to that
>> dictionary.
>> Solution: Make a difference between binding a function to a dictionary
>> explicitly or automatically.
>> Files: src/structs.h, src/eval.c, src/testdir/test_partial.vim,
>> runtime/doc/eval.txt
>
> Starting with this patch, I see sporadic failures on appveyor:
> https://ci.appveyor.com/project/chrisbra/vim/build/1234/job/wlpgqc4vnyvrdgqo
> https://ci.appveyor.com/project/chrisbra/vim/build/1239/job/2p6y8dru0sv216dv#L2073
> https://ci.appveyor.com/project/chrisbra/vim/build/1238/job/q4e5huq9x6opj6id#L2073
>
>
> test86:
> ..\gvim -u dos.vim -U NONE --noplugin --not-a-term "+set ff=unix|f
> test.out|wq" dostmp\test86.out
> 522c522
> < psa3(self={"20": 1}): !result: [['abcArgsPSA3'], {'abcSelfPSA3':
> 'abcSelfPSA3Val'}]
> ---
>> psa3(self={"20": 1}): !result: [['abcArgsPSA3'], {'20': 1}

Uninitialized memory: set_partial() in if_py_both.h is not setting new
attribute.

diff -r c35c9121c72b runtime/doc/if_pyth.txt
--- a/runtime/doc/if_pyth.txt Tue May 24 22:30:07 2016 +0200
+++ b/runtime/doc/if_pyth.txt Wed May 25 01:14:35 2016 +0300
@@ -659,19 +659,31 @@
`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
diff -r c35c9121c72b src/if_py_both.h
--- a/src/if_py_both.h Tue May 24 22:30:07 2016 +0200
+++ b/src/if_py_both.h Wed May 25 01:14:35 2016 +0300
@@ -2835,16 +2835,17 @@
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 @@
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 @@
{
PyObject *self;
PyObject *selfdictObject;
+ PyObject *autoRebindObject;
PyObject *argsObject = NULL;
char_u *name;
typval_T selfdicttv;
@@ -2896,6 +2899,7 @@
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 @@
}
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 @@
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 @@
}

static char *FunctionAttrs[] = {
- "softspace", "args", "self",
+ "softspace", "args", "self", "auto_rebind",
NULL
};

@@ -3001,6 +3020,10 @@
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 @@
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;
@@ -3148,6 +3172,8 @@
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 +6295,7 @@
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 +6310,8 @@
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:
diff -r c35c9121c72b src/testdir/test86.in
--- a/src/testdir/test86.in Tue May 24 22:30:07 2016 +0200
+++ b/src/testdir/test86.in Wed May 25 01:14:35 2016 +0300
@@ -877,6 +877,12 @@
:$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 @@
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 @@
:$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('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 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
diff -r c35c9121c72b src/testdir/test86.ok
--- a/src/testdir/test86.ok Tue May 24 22:30:07 2016 +0200
+++ b/src/testdir/test86.ok Wed May 25 01:14:35 2016 +0300
@@ -448,7 +448,7 @@
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')
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 @@
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(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 @@
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:
diff -r c35c9121c72b src/testdir/test87.in
--- a/src/testdir/test87.in Tue May 24 22:30:07 2016 +0200
+++ b/src/testdir/test87.in Wed May 25 01:14:35 2016 +0300
@@ -871,6 +871,12 @@
:$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 @@
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 @@
:$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('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 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
diff -r c35c9121c72b src/testdir/test87.ok
--- a/src/testdir/test87.ok Tue May 24 22:30:07 2016 +0200
+++ b/src/testdir/test87.ok Wed May 25 01:14:35 2016 +0300
@@ -448,7 +448,7 @@
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')
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 @@
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(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 @@
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:


>
>
> Best,
> Christian
> --
> Was ist das Allgemeine?
> Der einzelne Fall.
> Was ist das Besondere?
> Millionen Fälle.
> -- Goethe, Maximen und Reflektionen, Nr. 875
>
> --
> --
> 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+u...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
c.diff

Bram Moolenaar

unread,
May 25, 2016, 2:39:56 PM5/25/16
to Nikolay Aleksandrovich Pavlov, vim_dev
Ah, that's much more work than I expected. Thanks!

To avoid this flaky behavior I'll clear the partial_T in FunctionCall().
Would be nice to have a test fail when adding another field, but that
isn't possible. I only noticed valgrind errors when running the test,
but they didn't pinpoint the problem.

--
hundred-and-one symptoms of being an internet addict:
1. You actually wore a blue ribbon to protest the Communications Decency Act.
Reply all
Reply to author
Forward
0 new messages