To: vim_dev@googlegroups.com Subject: Patch 7.3.672 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 7.3.672 Problem: Not possible to lock/unlock lists in Python interface. Solution: Add .locked and .scope attributes. (ZyX) Files: runtime/doc/if_pyth.txt, src/if_py_both.h, src/if_python.c, src/if_python3.c, src/testdir/test86.in, src/testdir/test86.ok, src/testdir/test87.in, src/testdir/test87.ok *** ../vim-7.3.671/runtime/doc/if_pyth.txt 2012-06-29 12:54:32.000000000 +0200 --- runtime/doc/if_pyth.txt 2012-09-21 13:49:14.000000000 +0200 *************** *** 27,33 **** *:python* *:py* *E205* *E263* *E264* :[range]py[thon] {stmt} ! Execute Python statement {stmt}. :[range]py[thon] << {endmarker} {script} --- 27,35 ---- *:python* *:py* *E205* *E263* *E264* :[range]py[thon] {stmt} ! Execute Python statement {stmt}. A simple check if ! the `:python` command is working: > ! :python print "Hello" :[range]py[thon] << {endmarker} {script} *************** *** 157,162 **** --- 159,184 ---- vimlist or vimdictionary python type that are connected to original list or dictionary. Thus modifications to these objects imply modifications of the original. + + Additionally, vimlist and vimdictionary type have read-write + `.locked` attribute that returns + Value Meaning ~ + zero Variable is not locked + vim.VAR_LOCKED Variable is locked, but can be unlocked + vim.VAR_FIXED Variable is locked and can’t be unlocked + integer constants. If variable is not fixed, you can do + `var.locked=True` to lock it and `var.locked=False` to unlock. + There is no recursive locking like |:lockvar|! does. There is also + no way to lock a specific key or check whether it is locked (in any + case these locks are ignored by anything except |:let|: |extend()| + does not care, neither does python interface). + + Vimdictionary type also supports `.scope` attribute which is one of + Value Meaning ~ + zero Dictionary is not a scope one + vim.VAR_DEF_SCOPE Function-local or global scope dictionary + vim.VAR_SCOPE Other scope dictionary + 2. if expression evaluates to a function reference, then it returns callable vimfunction object. Use self keyword argument to assign |self| object for dictionary functions. *************** *** 362,369 **** 8. Python 3 *python3* *:py3* *:python3* ! The |:py3| and |:python3| commands work similar to |:python|. ! *:py3file* The |:py3file| command works similar to |:pyfile|. --- 384,393 ---- 8. Python 3 *python3* *:py3* *:python3* ! The |:py3| and |:python3| commands work similar to |:python|. A simple check ! if the `:py3` command is wrong: > ! :py3 print("Hello") ! < *:py3file* The |:py3file| command works similar to |:pyfile|. *** ../vim-7.3.671/src/if_py_both.h 2012-09-21 13:45:57.000000000 +0200 --- src/if_py_both.h 2012-09-21 13:49:14.000000000 +0200 *************** *** 808,813 **** --- 808,851 ---- } static PyInt + DictionarySetattr(DictionaryObject *self, char *name, PyObject *val) + { + if (val == NULL) + { + PyErr_SetString(PyExc_AttributeError, _("Cannot delete DictionaryObject attributes")); + return -1; + } + + if (strcmp(name, "locked") == 0) + { + if (self->dict->dv_lock == VAR_FIXED) + { + PyErr_SetString(PyExc_TypeError, _("Cannot modify fixed dictionary")); + return -1; + } + else + { + if (!PyBool_Check(val)) + { + PyErr_SetString(PyExc_TypeError, _("Only boolean objects are allowed")); + return -1; + } + + if (val == Py_True) + self->dict->dv_lock = VAR_LOCKED; + else + self->dict->dv_lock = 0; + } + return 0; + } + else + { + PyErr_SetString(PyExc_AttributeError, _("Cannot set this attribute")); + return -1; + } + } + + static PyInt DictionaryLength(PyObject *self) { return ((PyInt) ((((DictionaryObject *)(self))->dict->dv_hashtab.ht_used))); *************** *** 1271,1276 **** --- 1309,1352 ---- return self; } + static int + ListSetattr(ListObject *self, char *name, PyObject *val) + { + if (val == NULL) + { + PyErr_SetString(PyExc_AttributeError, _("Cannot delete DictionaryObject attributes")); + return -1; + } + + if (strcmp(name, "locked") == 0) + { + if (self->list->lv_lock == VAR_FIXED) + { + PyErr_SetString(PyExc_TypeError, _("Cannot modify fixed list")); + return -1; + } + else + { + if (!PyBool_Check(val)) + { + PyErr_SetString(PyExc_TypeError, _("Only boolean objects are allowed")); + return -1; + } + + if (val == Py_True) + self->list->lv_lock = VAR_LOCKED; + else + self->list->lv_lock = 0; + } + return 0; + } + else + { + PyErr_SetString(PyExc_AttributeError, _("Cannot set this attribute")); + return -1; + } + } + static struct PyMethodDef ListMethods[] = { {"extend", (PyCFunction)ListConcatInPlace, METH_O, ""}, { NULL, NULL, 0, NULL } *** ../vim-7.3.671/src/if_python.c 2012-09-21 13:45:57.000000000 +0200 --- src/if_python.c 2012-09-21 13:49:14.000000000 +0200 *************** *** 163,168 **** --- 163,169 ---- # define PyInt_FromLong dll_PyInt_FromLong # define PyLong_AsLong dll_PyLong_AsLong # define PyLong_FromLong dll_PyLong_FromLong + # define PyBool_Type (*dll_PyBool_Type) # define PyInt_Type (*dll_PyInt_Type) # define PyLong_Type (*dll_PyLong_Type) # define PyList_GetItem dll_PyList_GetItem *************** *** 221,226 **** --- 222,229 ---- # define _PyObject_NextNotImplemented (*dll__PyObject_NextNotImplemented) # endif # define _Py_NoneStruct (*dll__Py_NoneStruct) + # define _Py_ZeroStruct (*dll__Py_ZeroStruct) + # define _Py_TrueStruct (*dll__Py_TrueStruct) # define PyObject_Init dll__PyObject_Init # define PyObject_GetIter dll_PyObject_GetIter # if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02020000 *************** *** 263,268 **** --- 266,272 ---- static PyObject*(*dll_PyInt_FromLong)(long); static long(*dll_PyLong_AsLong)(PyObject *); static PyObject*(*dll_PyLong_FromLong)(long); + static PyTypeObject* dll_PyBool_Type; static PyTypeObject* dll_PyInt_Type; static PyTypeObject* dll_PyLong_Type; static PyObject*(*dll_PyList_GetItem)(PyObject *, PyInt); *************** *** 320,325 **** --- 324,331 ---- static iternextfunc dll__PyObject_NextNotImplemented; # endif static PyObject* dll__Py_NoneStruct; + static PyObject* _Py_ZeroStruct; + static PyObject* dll__Py_TrueStruct; # if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02020000 static int (*dll_PyType_IsSubtype)(PyTypeObject *, PyTypeObject *); # endif *************** *** 389,394 **** --- 395,401 ---- {"PyInt_FromLong", (PYTHON_PROC*)&dll_PyInt_FromLong}, {"PyLong_AsLong", (PYTHON_PROC*)&dll_PyLong_AsLong}, {"PyLong_FromLong", (PYTHON_PROC*)&dll_PyLong_FromLong}, + {"PyBool_Type", (PYTHON_PROC*)&dll_PyBool_Type}, {"PyInt_Type", (PYTHON_PROC*)&dll_PyInt_Type}, {"PyLong_Type", (PYTHON_PROC*)&dll_PyLong_Type}, {"PyList_GetItem", (PYTHON_PROC*)&dll_PyList_GetItem}, *************** *** 449,454 **** --- 456,463 ---- {"_PyObject_NextNotImplemented", (PYTHON_PROC*)&dll__PyObject_NextNotImplemented}, # endif {"_Py_NoneStruct", (PYTHON_PROC*)&dll__Py_NoneStruct}, + {"_Py_ZeroStruct", (PYTHON_PROC*)&dll__Py_ZeroStruct}, + {"_Py_TrueStruct", (PYTHON_PROC*)&dll__Py_TrueStruct}, # if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02020000 {"PyType_IsSubtype", (PYTHON_PROC*)&dll_PyType_IsSubtype}, # endif *************** *** 1563,1568 **** --- 1572,1581 ---- PyDict_SetItemString(dict, "buffers", (PyObject *)(void *)&TheBufferList); PyDict_SetItemString(dict, "current", (PyObject *)(void *)&TheCurrent); PyDict_SetItemString(dict, "windows", (PyObject *)(void *)&TheWindowList); + PyDict_SetItemString(dict, "VAR_LOCKED", PyInt_FromLong(VAR_LOCKED)); + PyDict_SetItemString(dict, "VAR_FIXED", PyInt_FromLong(VAR_FIXED)); + PyDict_SetItemString(dict, "VAR_SCOPE", PyInt_FromLong(VAR_SCOPE)); + PyDict_SetItemString(dict, "VAR_DEF_SCOPE", PyInt_FromLong(VAR_DEF_SCOPE)); if (PyErr_Occurred()) return -1; *************** *** 1629,1635 **** (destructor) DictionaryDestructor, (printfunc) 0, (getattrfunc) DictionaryGetattr, ! (setattrfunc) 0, (cmpfunc) 0, (reprfunc) 0, --- 1642,1648 ---- (destructor) DictionaryDestructor, (printfunc) 0, (getattrfunc) DictionaryGetattr, ! (setattrfunc) DictionarySetattr, (cmpfunc) 0, (reprfunc) 0, *************** *** 1656,1661 **** --- 1669,1681 ---- static PyObject * DictionaryGetattr(PyObject *self, char *name) { + DictionaryObject *this = ((DictionaryObject *) (self)); + + if (strcmp(name, "locked") == 0) + return PyInt_FromLong(this->dict->dv_lock); + else if (strcmp(name, "scope") == 0) + return PyInt_FromLong(this->dict->dv_scope); + return Py_FindMethod(DictionaryMethods, self, name); } *************** *** 1687,1693 **** (destructor) ListDestructor, (printfunc) 0, (getattrfunc) ListGetattr, ! (setattrfunc) 0, (cmpfunc) 0, (reprfunc) 0, --- 1707,1713 ---- (destructor) ListDestructor, (printfunc) 0, (getattrfunc) ListGetattr, ! (setattrfunc) ListSetattr, (cmpfunc) 0, (reprfunc) 0, *************** *** 1714,1719 **** --- 1734,1742 ---- static PyObject * ListGetattr(PyObject *self, char *name) { + if (strcmp(name, "locked") == 0) + return PyInt_FromLong(((ListObject *)(self))->list->lv_lock); + return Py_FindMethod(ListMethods, self, name); } *** ../vim-7.3.671/src/if_python3.c 2012-09-21 13:45:57.000000000 +0200 --- src/if_python3.c 2012-09-21 13:49:14.000000000 +0200 *************** *** 161,167 **** # define PyRun_String py3_PyRun_String # define PySys_SetObject py3_PySys_SetObject # define PySys_SetArgv py3_PySys_SetArgv - # define PyType_Type (*py3_PyType_Type) # define PyType_Ready py3_PyType_Ready #undef Py_BuildValue # define Py_BuildValue py3_Py_BuildValue --- 161,166 ---- *************** *** 170,175 **** --- 169,176 ---- # define Py_Finalize py3_Py_Finalize # define Py_IsInitialized py3_Py_IsInitialized # define _Py_NoneStruct (*py3__Py_NoneStruct) + # define _Py_FalseStruct (*py3__Py_FalseStruct) + # define _Py_TrueStruct (*py3__Py_TrueStruct) # define _PyObject_NextNotImplemented (*py3__PyObject_NextNotImplemented) # define PyModule_AddObject py3_PyModule_AddObject # define PyImport_AppendInittab py3_PyImport_AppendInittab *************** *** 184,191 **** --- 185,194 ---- # define PyFloat_FromDouble py3_PyFloat_FromDouble # define PyFloat_AsDouble py3_PyFloat_AsDouble # define PyObject_GenericGetAttr py3_PyObject_GenericGetAttr + # define PyType_Type (*py3_PyType_Type) # define PySlice_Type (*py3_PySlice_Type) # define PyFloat_Type (*py3_PyFloat_Type) + # define PyBool_Type (*py3_PyBool_Type) # define PyErr_NewException py3_PyErr_NewException # ifdef Py_DEBUG # define _Py_NegativeRefcount py3__Py_NegativeRefcount *************** *** 245,251 **** static PyObject* (*py3_PyImport_ImportModule)(const char *); static PyObject* (*py3_PyImport_AddModule)(const char *); static int (*py3_PyErr_BadArgument)(void); - static PyTypeObject* py3_PyType_Type; static PyObject* (*py3_PyErr_Occurred)(void); static PyObject* (*py3_PyModule_GetDict)(PyObject *); static int (*py3_PyList_SetItem)(PyObject *, Py_ssize_t, PyObject *); --- 248,253 ---- *************** *** 275,280 **** --- 277,284 ---- static PyObject*(*py3__PyObject_Init)(PyObject *, PyTypeObject *); static iternextfunc py3__PyObject_NextNotImplemented; static PyObject* py3__Py_NoneStruct; + static PyObject* py3__Py_FalseStruct; + static PyObject* py3__Py_TrueStruct; static int (*py3_PyModule_AddObject)(PyObject *m, const char *name, PyObject *o); static int (*py3_PyImport_AppendInittab)(const char *name, PyObject* (*initfunc)(void)); static char* (*py3__PyUnicode_AsString)(PyObject *unicode); *************** *** 288,295 **** --- 292,301 ---- static PyObject* (*py3_PyModule_Create2)(struct PyModuleDef* module, int module_api_version); static PyObject* (*py3_PyType_GenericAlloc)(PyTypeObject *type, Py_ssize_t nitems); static PyObject* (*py3_PyType_GenericNew)(PyTypeObject *type, PyObject *args, PyObject *kwds); + static PyTypeObject* py3_PyType_Type; static PyTypeObject* py3_PySlice_Type; static PyTypeObject* py3_PyFloat_Type; + static PyTypeObject* py3_PyBool_Type; static PyObject* (*py3_PyErr_NewException)(char *name, PyObject *base, PyObject *dict); static PyObject* (*py3_PyCapsule_New)(void *, char *, PyCapsule_Destructor); static void* (*py3_PyCapsule_GetPointer)(PyObject *, char *); *************** *** 363,369 **** {"PyImport_ImportModule", (PYTHON_PROC*)&py3_PyImport_ImportModule}, {"PyImport_AddModule", (PYTHON_PROC*)&py3_PyImport_AddModule}, {"PyErr_BadArgument", (PYTHON_PROC*)&py3_PyErr_BadArgument}, - {"PyType_Type", (PYTHON_PROC*)&py3_PyType_Type}, {"PyErr_Occurred", (PYTHON_PROC*)&py3_PyErr_Occurred}, {"PyModule_GetDict", (PYTHON_PROC*)&py3_PyModule_GetDict}, {"PyList_SetItem", (PYTHON_PROC*)&py3_PyList_SetItem}, --- 369,374 ---- *************** *** 386,391 **** --- 391,398 ---- {"Py_IsInitialized", (PYTHON_PROC*)&py3_Py_IsInitialized}, {"_PyObject_NextNotImplemented", (PYTHON_PROC*)&py3__PyObject_NextNotImplemented}, {"_Py_NoneStruct", (PYTHON_PROC*)&py3__Py_NoneStruct}, + {"_Py_FalseStruct", (PYTHON_PROC*)&py3__Py_FalseStruct}, + {"_Py_TrueStruct", (PYTHON_PROC*)&py3__Py_TrueStruct}, {"PyErr_Clear", (PYTHON_PROC*)&py3_PyErr_Clear}, {"PyObject_Init", (PYTHON_PROC*)&py3__PyObject_Init}, {"PyModule_AddObject", (PYTHON_PROC*)&py3_PyModule_AddObject}, *************** *** 400,407 **** --- 407,416 ---- {"PyModule_Create2", (PYTHON_PROC*)&py3_PyModule_Create2}, {"PyType_GenericAlloc", (PYTHON_PROC*)&py3_PyType_GenericAlloc}, {"PyType_GenericNew", (PYTHON_PROC*)&py3_PyType_GenericNew}, + {"PyType_Type", (PYTHON_PROC*)&py3_PyType_Type}, {"PySlice_Type", (PYTHON_PROC*)&py3_PySlice_Type}, {"PyFloat_Type", (PYTHON_PROC*)&py3_PyFloat_Type}, + {"PyBool_Type", (PYTHON_PROC*)&py3_PyBool_Type}, {"PyErr_NewException", (PYTHON_PROC*)&py3_PyErr_NewException}, # ifdef Py_DEBUG {"_Py_NegativeRefcount", (PYTHON_PROC*)&py3__Py_NegativeRefcount}, *************** *** 1534,1539 **** --- 1543,1570 ---- /* mp_ass_subscript */ (objobjargproc) DictionaryAssItem, }; + static PyObject * + DictionaryGetattro(PyObject *self, PyObject *nameobj) + { + DictionaryObject *this = ((DictionaryObject *) (self)); + + GET_ATTR_STRING(name, nameobj); + + if (strcmp(name, "locked") == 0) + return PyLong_FromLong(this->dict->dv_lock); + else if (strcmp(name, "scope") == 0) + return PyLong_FromLong(this->dict->dv_scope); + + return PyObject_GenericGetAttr(self, nameobj); + } + + static int + DictionarySetattro(PyObject *self, PyObject *nameobj, PyObject *val) + { + GET_ATTR_STRING(name, nameobj); + return DictionarySetattr((DictionaryObject *) self, name, val); + } + static PyTypeObject DictionaryType; static void *************** *** 1625,1630 **** --- 1656,1679 ---- } } + static PyObject * + ListGetattro(PyObject *self, PyObject *nameobj) + { + GET_ATTR_STRING(name, nameobj); + + if (strcmp(name, "locked") == 0) + return PyLong_FromLong(((ListObject *) (self))->list->lv_lock); + + return PyObject_GenericGetAttr(self, nameobj); + } + + static int + ListSetattro(PyObject *self, PyObject *nameobj, PyObject *val) + { + GET_ATTR_STRING(name, nameobj); + return ListSetattr((ListObject *) self, name, val); + } + static void ListDestructor(PyObject *self) { *************** *** 1713,1718 **** --- 1762,1768 ---- PyMODINIT_FUNC Py3Init_vim(void) { PyObject *mod; + PyObject *tmp; /* The special value is removed from sys.path in Python3_Init(). */ static wchar_t *(argv[2]) = {L"/must>not&exist/foo", NULL}; *************** *** 1744,1749 **** --- 1794,1809 ---- Py_INCREF((PyObject *)(void *)&TheWindowList); PyModule_AddObject(mod, "windows", (PyObject *)(void *)&TheWindowList); + #define ADD_INT_CONSTANT(name, value) \ + tmp = PyLong_FromLong(value); \ + Py_INCREF(tmp); \ + PyModule_AddObject(mod, name, tmp) + + ADD_INT_CONSTANT("VAR_LOCKED", VAR_LOCKED); + ADD_INT_CONSTANT("VAR_FIXED", VAR_FIXED); + ADD_INT_CONSTANT("VAR_SCOPE", VAR_SCOPE); + ADD_INT_CONSTANT("VAR_DEF_SCOPE", VAR_DEF_SCOPE); + if (PyErr_Occurred()) return NULL; *************** *** 1899,1904 **** --- 1959,1966 ---- vim_memset(&DictionaryType, 0, sizeof(DictionaryType)); DictionaryType.tp_name = "vim.dictionary"; DictionaryType.tp_basicsize = sizeof(DictionaryObject); + DictionaryType.tp_getattro = DictionaryGetattro; + DictionaryType.tp_setattro = DictionarySetattro; DictionaryType.tp_dealloc = DictionaryDestructor; DictionaryType.tp_as_mapping = &DictionaryAsMapping; DictionaryType.tp_flags = Py_TPFLAGS_DEFAULT; *************** *** 1909,1914 **** --- 1971,1978 ---- ListType.tp_name = "vim.list"; ListType.tp_dealloc = ListDestructor; ListType.tp_basicsize = sizeof(ListObject); + ListType.tp_getattro = ListGetattro; + ListType.tp_setattro = ListSetattro; ListType.tp_as_sequence = &ListAsSeq; ListType.tp_as_mapping = &ListAsMapping; ListType.tp_flags = Py_TPFLAGS_DEFAULT; *** ../vim-7.3.671/src/testdir/test86.in 2012-09-05 19:17:37.000000000 +0200 --- src/testdir/test86.in 2012-09-21 13:49:14.000000000 +0200 *************** *** 211,216 **** --- 211,251 ---- m.extend([e.__class__.__name__]) EOF :$put =messages + :unlet messages + :" locked and scope attributes + :let d={} | let dl={} | lockvar dl + :for s in split("d dl v: g:") + : let name=tr(s, ':', 's') + : execute 'py '.name.'=vim.bindeval("'.s.'")' + : let toput=s.' : '.join(map(['locked', 'scope'], 'v:val.":".pyeval(name.".".v:val)'), ';') + : $put =toput + :endfor + :silent! let d.abc=1 + :silent! let dl.abc=1 + :py d.locked=True + :py dl.locked=False + :silent! let d.def=1 + :silent! let dl.def=1 + :put ='d:'.string(d) + :put ='dl:'.string(dl) + :unlet d dl + : + :let l=[] | let ll=[] | lockvar ll + :for s in split("l ll") + : let name=tr(s, ':', 's') + : execute 'py '.name.'=vim.bindeval("'.s.'")' + : let toput=s.' : locked:'.pyeval(name.'.locked') + : $put =toput + :endfor + :silent! call extend(l, [0]) + :silent! call extend(ll, [0]) + :py l.locked=True + :py ll.locked=False + :silent! call extend(l, [1]) + :silent! call extend(ll, [1]) + :put ='l:'.string(l) + :put ='ll:'.string(ll) + :unlet l ll :" :" pyeval() :let l=pyeval('range(3)') *************** *** 240,245 **** --- 275,281 ---- :call garbagecollect(1) :" :/^start:/,$wq! test.out + :call getchar() ENDTEST start: *** ../vim-7.3.671/src/testdir/test86.ok 2012-09-05 19:17:37.000000000 +0200 --- src/testdir/test86.ok 2012-09-21 13:49:14.000000000 +0200 *************** *** 44,49 **** --- 44,59 ---- ValueError TypeError TypeError + d : locked:0;scope:0 + dl : locked:1;scope:0 + v: : locked:2;scope:1 + g: : locked:0;scope:2 + d:{'abc': 1} + dl:{'def': 1} + l : locked:0 + ll : locked:1 + l:[0] + ll:[1] [0, 1, 2] ['a', 'b'] ['c', 1] *** ../vim-7.3.671/src/testdir/test87.in 2012-09-05 19:17:37.000000000 +0200 --- src/testdir/test87.in 2012-09-21 13:49:14.000000000 +0200 *************** *** 211,216 **** --- 211,251 ---- m.extend([e.__class__.__name__]) EOF :$put =messages + :unlet messages + :" locked and scope attributes + :let d={} | let dl={} | lockvar dl + :for s in split("d dl v: g:") + : let name=tr(s, ':', 's') + : execute 'py3 '.name.'=vim.bindeval("'.s.'")' + : let toput=s.' : '.join(map(['locked', 'scope'], 'v:val.":".py3eval(name.".".v:val)'), ';') + : $put =toput + :endfor + :silent! let d.abc=1 + :silent! let dl.abc=1 + :py3 d.locked=True + :py3 dl.locked=False + :silent! let d.def=1 + :silent! let dl.def=1 + :put ='d:'.string(d) + :put ='dl:'.string(dl) + :unlet d dl + : + :let l=[] | let ll=[] | lockvar ll + :for s in split("l ll") + : let name=tr(s, ':', 's') + : execute 'py3 '.name.'=vim.bindeval("'.s.'")' + : let toput=s.' : locked:'.py3eval(name.'.locked') + : $put =toput + :endfor + :silent! call extend(l, [0]) + :silent! call extend(ll, [0]) + :py3 l.locked=True + :py3 ll.locked=False + :silent! call extend(l, [1]) + :silent! call extend(ll, [1]) + :put ='l:'.string(l) + :put ='ll:'.string(ll) + :unlet l ll :" :" py3eval() :let l=py3eval('[0, 1, 2]') *** ../vim-7.3.671/src/testdir/test87.ok 2012-09-05 19:17:37.000000000 +0200 --- src/testdir/test87.ok 2012-09-21 13:49:14.000000000 +0200 *************** *** 44,49 **** --- 44,59 ---- ValueError TypeError TypeError + d : locked:0;scope:0 + dl : locked:1;scope:0 + v: : locked:2;scope:1 + g: : locked:0;scope:2 + d:{'abc': 1} + dl:{'def': 1} + l : locked:0 + ll : locked:1 + l:[0] + ll:[1] [0, 1, 2] ['a', 'b'] ['c', 1] *** ../vim-7.3.671/src/version.c 2012-09-21 13:45:57.000000000 +0200 --- src/version.c 2012-09-21 13:48:18.000000000 +0200 *************** *** 721,722 **** --- 721,724 ---- { /* Add new patch number below this line */ + /**/ + 672, /**/ -- Vi beats Emacs to death, and then again! http://linuxtoday.com/stories/5764.html /// Bram Moolenaar -- Bram@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 ///