Re: Patch 7.4.1836

2016-05-25 Fir de Conversatie Bram Moolenaar

Nikolay Pavlov wrote:

> 2016-05-24 23:14 GMT+03:00 Christian Brabandt :
> > 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.

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.

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

-- 
-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Patch 7.4.1836

2016-05-24 Fir de Conversatie Nikolay Aleksandrovich Pavlov
2016-05-24 23:14 GMT+03:00 Christian Brabandt :
> 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.
+AttributeDescription ~
+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->

Re: Patch 7.4.1836

2016-05-24 Fir de Conversatie Bram Moolenaar

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

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

-- 
-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Patch 7.4.1836

2016-05-24 Fir de Conversatie Christian Brabandt
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

-- 
-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Patch 7.4.1836

2016-05-24 Fir de Conversatie Bram Moolenaar

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.
(Scott Adams - The Dilbert principle)

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

-- 
-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Patch 7.4.1836

2016-05-24 Fir de Conversatie Bram Moolenaar

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.vim2016-04-08 
17:25:15.198702510 +0200
-