| To: vim_dev@googlegroups.com |
| Subject: Patch 7.3.672 |
| Fcc: outbox |
| From: Bram Moolenaar <Bram@moolenaar.net> |
| 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 |
| |
| |
| |
| |
| |
| *** 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|. |
| |
| |
| |
| |
| |
| *** 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 } |
| |
| |
| |
| *** 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); |
| } |
| |
| |
| |
| |
| *** 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; |
| |
| |
| |
| *** 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: |
| |
| |
| |
| *** 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] |
| |
| |
| |
| *** 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]') |
| |
| |
| |
| *** 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] |
| |
| |
| |
| *** 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 /// |