Example:

    :let d = {'a': 99, 'b': 100}
    :lockvar 1 d
    :call extend(d, {'a': 123})
        E741: Value is locked: extend() argument
    :let d.a = 123
    :let d
        d                     {'a': 123, 'b': 100}

The dictionary is locked, but the 'a' item is not, so extend() on 'a'
should succeed in the same way as the 'let' does. According to ':he
lockvar', a dictionary lock protects against item deletion and addition,
but not against changing an existing item.

BTW, protection against item deletion and addition works:

    :call extend(d, {'x': 'new'})
        E741: Value is locked: extend() argument


diff -r 18d84ed365a5 src/eval.c
--- a/src/eval.c        Wed Apr 22 22:18:22 2015 +0200
+++ b/src/eval.c        Thu Apr 30 09:09:37 2015 +0200
@@ -10524,6 +10524,8 @@ dict_extend(d1, d2, action)
            }
            if (di1 == NULL)
            {
+               if (tv_check_lock(d1->dv_lock, arg_errmsg, TRUE))
+                   break;
                di1 = dictitem_copy(HI2DI(hi2));
                if (di1 != NULL && dict_add(d1, di1) == FAIL)
                    dictitem_free(di1);
@@ -10601,8 +10603,7 @@ f_extend(argvars, rettv)
 
        d1 = argvars[0].vval.v_dict;
        d2 = argvars[1].vval.v_dict;
-       if (d1 != NULL && !tv_check_lock(d1->dv_lock, arg_errmsg, TRUE)
-               && d2 != NULL)
+       if (d1 != NULL && d2 != NULL)
        {
            /* Check the third argument. */
            if (argvars[2].v_type != VAR_UNKNOWN)
diff -r 18d84ed365a5 src/testdir/test55.in
--- a/src/testdir/test55.in     Wed Apr 22 22:18:22 2015 +0200
+++ b/src/testdir/test55.in     Thu Apr 30 09:09:37 2015 +0200
@@ -408,6 +408,20 @@ let l = [0, 1, 2, 3]
 :endtry
 :$put =string(d)
 :"
+:$put ='extend() after lock on dict (existing: yes, new: no):'
+:unlet! d
+:let d = {'a': 99, 'b': 100}
+:lockvar 1 d
+:try
+:  $put =string(extend(d, {'a': 123}))
+:  $put ='did extend() existing item'
+:  $put =string(extend(d, {'x': 'new'}))
+:  $put ='did extend() with new item'
+:catch
+:  $put =v:exception[:14]
+:endtry
+:$put =string(d)
+:"
 :$put ='No remove() of write-protected scope-level variable:'
 :fun! Tfunc(this_is_a_loooooooooong_parameter_name)
 :  try
diff -r 18d84ed365a5 src/testdir/test55.ok
--- a/src/testdir/test55.ok     Wed Apr 22 22:18:22 2015 +0200
+++ b/src/testdir/test55.ok     Thu Apr 30 09:09:37 2015 +0200
@@ -138,6 +138,10 @@ did map()
 No extend() after lock on dict item:
 Vim(put):E741: 
 {'a': 99, 'b': 100}
+extend() after lock on dict (existing: yes, new: no):
+did extend() existing item
+Vim(put):E741: 
+{'a': 123, 'b': 100}
 No remove() of write-protected scope-level variable:
 Vim(put):E795: 
 No extend() of write-protected scope-level variable:

-- 
Olaf Dabrunz (oda <at> fctrace.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.

Reply via email to