To: vim_dev@googlegroups.com Subject: Patch 7.4.1731 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 7.4.1731 Problem: Python: turns partial into simple funcref. Solution: Use partials like partials. (Nikolai Pavlov, closes #734) Files: runtime/doc/if_pyth.txt, src/eval.c, src/if_py_both.h, src/if_python.c, src/if_python3.c, src/proto/eval.pro, src/testdir/test86.in, src/testdir/test86.ok, src/testdir/test87.in, src/testdir/test87.ok *** ../vim-7.4.1730/runtime/doc/if_pyth.txt 2015-11-02 15:27:03.434325554 +0100 --- runtime/doc/if_pyth.txt 2016-04-14 15:48:56.037753928 +0200 *************** *** 653,662 **** class List(vim.List): # Subclassing vim.Function object *python-Function* ! Function-like object, acting like vim |Funcref| object. Supports `.name` ! attribute and is callable. Accepts special keyword argument `self`, see ! |Dictionary-function|. You can also use `vim.Function(name)` constructor, ! it is the same as `vim.bindeval('function(%s)'%json.dumps(name))`. Examples: > f = vim.Function('tr') # Constructor --- 653,677 ---- class List(vim.List): # Subclassing vim.Function object *python-Function* ! Function-like object, acting like vim |Funcref| object. Accepts special ! keyword argument `self`, see |Dictionary-function|. You can also use ! `vim.Function(name)` constructor, it is the same as ! `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. ! ! Constructor additionally accepts `args` and `self` keywords. If any of ! them is given then it constructs a partial, see |function()|. Examples: > f = vim.Function('tr') # Constructor *************** *** 670,675 **** --- 685,695 ---- print f(self={}) # Like call('DictFun', [], {}) print isinstance(f, vim.Function) # True + p = vim.Function('DictFun', self={}) + print f() + p = vim.Function('tr', args=['abc', 'a']) + print f('b') + ============================================================================== 8. pyeval() and py3eval() Vim functions *python-pyeval* *************** *** 686,703 **** when needed. When you don't use the Python interface you don't need it, thus you can use Vim without this file. ! On MS-Windows to use the Python interface the Python DLL must be in your search ! path. In a console window type "path" to see what directories are used. The name of the DLL must match the Python version Vim was compiled with. Currently the name is "python24.dll". That is for Python 2.4. To know for sure edit "gvim.exe" and search for "python\d*.dll\c". ! On Unix the 'pythondll' or 'python3dll' option can be used to specify the ! Python shared library file instead of DYNAMIC_PYTHON_DLL or ! DYNAMIC_PYTHON3_DLL file what were specified at compile time. The version of ! the shared library must match the Python 2.x or Python 3 version Vim was ! compiled with. ============================================================================== 10. Python 3 *python3* --- 706,729 ---- when needed. When you don't use the Python interface you don't need it, thus you can use Vim without this file. ! ! MS-Windows ~ ! ! To use the Python interface the Python DLL must be in your search path. In a ! console window type "path" to see what directories are used. The 'pythondll' ! or 'pythonthreedll' option can be also used to specify the Python DLL. The name of the DLL must match the Python version Vim was compiled with. Currently the name is "python24.dll". That is for Python 2.4. To know for sure edit "gvim.exe" and search for "python\d*.dll\c". ! ! Unix ~ ! ! The 'pythondll' or 'pythonthreedll' option can be used to specify the Python ! shared library file instead of DYNAMIC_PYTHON_DLL or DYNAMIC_PYTHON3_DLL file ! what were specified at compile time. The version of the shared library must ! match the Python 2.x or Python 3 version Vim was compiled with. ============================================================================== 10. Python 3 *python3* *** ../vim-7.4.1730/src/eval.c 2016-04-14 15:13:41.755917075 +0200 --- src/eval.c 2016-04-14 15:48:56.045753843 +0200 *************** *** 453,459 **** static char_u *dict2string(typval_T *tv, int copyID); static int get_dict_tv(char_u **arg, typval_T *rettv, int evaluate); static char_u *echo_string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID); - static char_u *tv2string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID); static char_u *string_quote(char_u *str, int function); static int get_env_tv(char_u **arg, typval_T *rettv, int evaluate); static int find_internal_func(char_u *name); --- 453,458 ---- *************** *** 8153,8159 **** * Puts quotes around strings, so that they can be parsed back by eval(). * May return NULL. */ ! static char_u * tv2string( typval_T *tv, char_u **tofree, --- 8152,8158 ---- * Puts quotes around strings, so that they can be parsed back by eval(). * May return NULL. */ ! char_u * tv2string( typval_T *tv, char_u **tofree, *** ../vim-7.4.1730/src/if_py_both.h 2016-03-24 21:58:06.940204253 +0100 --- src/if_py_both.h 2016-04-14 15:53:14.955034304 +0200 *************** *** 72,77 **** --- 72,78 ---- static int ConvertFromPyObject(PyObject *, typval_T *); static int _ConvertFromPyObject(PyObject *, typval_T *, PyObject *); static int ConvertFromPyMapping(PyObject *, typval_T *); + static int ConvertFromPySequence(PyObject *, typval_T *); static PyObject *WindowNew(win_T *, tabpage_T *); static PyObject *BufferNew (buf_T *); static PyObject *LineToString(const char *); *************** *** 1433,1438 **** --- 1434,1440 ---- static pylinkedlist_T *lastdict = NULL; static pylinkedlist_T *lastlist = NULL; + static pylinkedlist_T *lastfunc = NULL; static void pyll_remove(pylinkedlist_T *ref, pylinkedlist_T **last) *************** *** 2828,2841 **** { PyObject_HEAD char_u *name; } FunctionObject; static PyTypeObject FunctionType; ! #define NEW_FUNCTION(name) FunctionNew(&FunctionType, name) static PyObject * ! FunctionNew(PyTypeObject *subtype, char_u *name) { FunctionObject *self; --- 2830,2849 ---- { PyObject_HEAD char_u *name; + int argc; + typval_T *argv; + dict_T *self; + pylinkedlist_T ref; } FunctionObject; static PyTypeObject FunctionType; ! #define NEW_FUNCTION(name, argc, argv, self) \ ! FunctionNew(&FunctionType, name, argc, argv, self) static PyObject * ! FunctionNew(PyTypeObject *subtype, char_u *name, int argc, typval_T *argv, ! dict_T *selfdict) { FunctionObject *self; *************** *** 2865,2870 **** --- 2873,2885 ---- return NULL; } + self->argc = argc; + self->argv = argv; + self->self = selfdict; + + if (self->argv || self->self) + pyll_add((PyObject *)(self), &self->ref, &lastfunc); + return (PyObject *)(self); } *************** *** 2872,2890 **** FunctionConstructor(PyTypeObject *subtype, PyObject *args, PyObject *kwargs) { PyObject *self; char_u *name; ! if (kwargs) { ! PyErr_SET_STRING(PyExc_TypeError, ! N_("function constructor does not accept keyword arguments")); ! return NULL; } if (!PyArg_ParseTuple(args, "et", "ascii", &name)) return NULL; ! self = FunctionNew(subtype, name); PyMem_Free(name); --- 2887,2945 ---- FunctionConstructor(PyTypeObject *subtype, PyObject *args, PyObject *kwargs) { PyObject *self; + PyObject *selfdictObject; + PyObject *argsObject = NULL; char_u *name; + typval_T selfdicttv; + typval_T argstv; + list_T *argslist = NULL; + dict_T *selfdict = NULL; + int argc = 0; + typval_T *argv = NULL; + typval_T *curtv; + listitem_T *li; ! if (kwargs != NULL) { ! selfdictObject = PyDict_GetItemString(kwargs, "self"); ! if (selfdictObject != NULL) ! { ! if (ConvertFromPyMapping(selfdictObject, &selfdicttv) == -1) ! return NULL; ! selfdict = selfdicttv.vval.v_dict; ! } ! argsObject = PyDict_GetItemString(kwargs, "args"); ! if (argsObject != NULL) ! { ! if (ConvertFromPySequence(argsObject, &argstv) == -1) ! { ! dict_unref(selfdict); ! return NULL; ! } ! argslist = argstv.vval.v_list; ! ! argc = argslist->lv_len; ! if (argc != 0) ! { ! argv = PyMem_New(typval_T, (size_t) argc); ! curtv = argv; ! for (li = argslist->lv_first; li != NULL; li = li->li_next) ! copy_tv(&li->li_tv, curtv++); ! } ! list_unref(argslist); ! } } if (!PyArg_ParseTuple(args, "et", "ascii", &name)) + { + dict_unref(selfdict); + while (argc--) + clear_tv(&argv[argc]); + PyMem_Free(argv); return NULL; + } ! self = FunctionNew(subtype, name, argc, argv, selfdict); PyMem_Free(name); *************** *** 2894,2907 **** static void FunctionDestructor(FunctionObject *self) { func_unref(self->name); vim_free(self->name); DESTRUCTOR_FINISH(self); } static char *FunctionAttrs[] = { ! "softspace", NULL }; --- 2949,2969 ---- static void FunctionDestructor(FunctionObject *self) { + int i; func_unref(self->name); vim_free(self->name); + for (i = 0; i < self->argc; ++i) + clear_tv(&self->argv[i]); + PyMem_Free(self->argv); + dict_unref(self->self); + if (self->argv || self->self) + pyll_remove(&self->ref, &lastfunc); DESTRUCTOR_FINISH(self); } static char *FunctionAttrs[] = { ! "softspace", "args", "self", NULL }; *************** *** 2912,2917 **** --- 2974,3042 ---- } static PyObject * + FunctionAttr(FunctionObject *self, char *name) + { + list_T *list; + int i; + if (strcmp(name, "name") == 0) + return PyString_FromString((char *)(self->name)); + else if (strcmp(name, "args") == 0) + { + if (self->argv == NULL) + return AlwaysNone(NULL); + list = list_alloc(); + for (i = 0; i < self->argc; ++i) + list_append_tv(list, &self->argv[i]); + return NEW_LIST(list); + } + else if (strcmp(name, "self") == 0) + return self->self == NULL + ? AlwaysNone(NULL) + : NEW_DICTIONARY(self->self); + else if (strcmp(name, "__members__") == 0) + return ObjectDir(NULL, FunctionAttrs); + return NULL; + } + + /* Populate partial_T given function object. + * + * "exported" should be set to true when it is needed to construct a partial + * that may be stored in a variable (i.e. may be freed by Vim). + */ + static void + set_partial(FunctionObject *self, partial_T *pt, int exported) + { + typval_T *curtv; + int i; + + pt->pt_name = self->name; + if (self->argv) + { + pt->pt_argc = self->argc; + if (exported) + { + pt->pt_argv = (typval_T *)alloc_clear( + sizeof(typval_T) * self->argc); + for (i = 0; i < pt->pt_argc; ++i) + copy_tv(&self->argv[i], &pt->pt_argv[i]); + } + else + pt->pt_argv = self->argv; + } + else + { + pt->pt_argc = 0; + pt->pt_argv = NULL; + } + pt->pt_dict = self->self; + if (exported && self->self) + ++pt->pt_dict->dv_refcount; + if (exported) + pt->pt_name = vim_strsave(pt->pt_name); + pt->pt_refcount = 1; + } + + static PyObject * FunctionCall(FunctionObject *self, PyObject *argsObject, PyObject *kwargs) { char_u *name = self->name; *************** *** 2922,2929 **** PyObject *selfdictObject; PyObject *ret; int error; ! if (ConvertFromPyObject(argsObject, &args) == -1) return NULL; if (kwargs != NULL) --- 3047,3056 ---- PyObject *selfdictObject; PyObject *ret; int error; + partial_T pt; + partial_T *pt_ptr = NULL; ! if (ConvertFromPySequence(argsObject, &args) == -1) return NULL; if (kwargs != NULL) *************** *** 2940,2950 **** } } Py_BEGIN_ALLOW_THREADS Python_Lock_Vim(); VimTryStart(); ! error = func_call(name, &args, NULL, selfdict, &rettv); Python_Release_Vim(); Py_END_ALLOW_THREADS --- 3067,3083 ---- } } + if (self->argv || self->self) + { + set_partial(self, &pt, FALSE); + pt_ptr = &pt; + } + Py_BEGIN_ALLOW_THREADS Python_Lock_Vim(); VimTryStart(); ! error = func_call(name, &args, pt_ptr, selfdict, &rettv); Python_Release_Vim(); Py_END_ALLOW_THREADS *************** *** 2970,2983 **** static PyObject * FunctionRepr(FunctionObject *self) { ! #ifdef Py_TRACE_REFS ! /* For unknown reason self->name may be NULL after calling ! * Finalize */ ! return PyString_FromFormat("", ! (self->name == NULL ? "" : (char *)self->name)); ! #else ! return PyString_FromFormat("", (char *)self->name); ! #endif } static struct PyMethodDef FunctionMethods[] = { --- 3103,3151 ---- static PyObject * FunctionRepr(FunctionObject *self) { ! PyObject *ret; ! garray_T repr_ga; ! int i; ! char_u *tofree = NULL; ! typval_T tv; ! char_u numbuf[NUMBUFLEN]; ! ! ga_init2(&repr_ga, (int)sizeof(char), 70); ! ga_concat(&repr_ga, (char_u *)"name) ! ga_concat(&repr_ga, self->name); ! else ! ga_concat(&repr_ga, (char_u *)""); ! ga_append(&repr_ga, '\''); ! if (self->argv) ! { ! ga_concat(&repr_ga, (char_u *)", args=["); ! ++emsg_silent; ! for (i = 0; i < self->argc; i++) ! { ! if (i != 0) ! ga_concat(&repr_ga, (char_u *)", "); ! ga_concat(&repr_ga, tv2string(&self->argv[i], &tofree, numbuf, ! get_copyID())); ! vim_free(tofree); ! } ! --emsg_silent; ! ga_append(&repr_ga, ']'); ! } ! if (self->self) ! { ! ga_concat(&repr_ga, (char_u *)", self="); ! tv.v_type = VAR_DICT; ! tv.vval.v_dict = self->self; ! ++emsg_silent; ! ga_concat(&repr_ga, tv2string(&tv, &tofree, numbuf, get_copyID())); ! --emsg_silent; ! vim_free(tofree); ! } ! ga_append(&repr_ga, '>'); ! ret = PyString_FromString((char *)repr_ga.ga_data); ! ga_clear(&repr_ga); ! return ret; } static struct PyMethodDef FunctionMethods[] = { *************** *** 5551,5561 **** pylinkedlist_T *cur; dict_T *dd; list_T *ll; int abort = FALSE; if (lastdict != NULL) { ! for(cur = lastdict ; !abort && cur != NULL ; cur = cur->pll_prev) { dd = ((DictionaryObject *) (cur->pll_obj))->dict; if (dd->dv_copyID != copyID) --- 5719,5731 ---- pylinkedlist_T *cur; dict_T *dd; list_T *ll; + int i; int abort = FALSE; + FunctionObject *func; if (lastdict != NULL) { ! for (cur = lastdict ; !abort && cur != NULL ; cur = cur->pll_prev) { dd = ((DictionaryObject *) (cur->pll_obj))->dict; if (dd->dv_copyID != copyID) *************** *** 5568,5574 **** if (lastlist != NULL) { ! for(cur = lastlist ; !abort && cur != NULL ; cur = cur->pll_prev) { ll = ((ListObject *) (cur->pll_obj))->list; if (ll->lv_copyID != copyID) --- 5738,5744 ---- if (lastlist != NULL) { ! for (cur = lastlist ; !abort && cur != NULL ; cur = cur->pll_prev) { ll = ((ListObject *) (cur->pll_obj))->list; if (ll->lv_copyID != copyID) *************** *** 5579,5584 **** --- 5749,5772 ---- } } + if (lastfunc != NULL) + { + for (cur = lastfunc ; !abort && cur != NULL ; cur = cur->pll_prev) + { + func = (FunctionObject *) cur->pll_obj; + if (func->self != NULL && func->self->dv_copyID != copyID) + { + func->self->dv_copyID = copyID; + abort = abort || set_ref_in_ht( + &func->self->dv_hashtab, copyID, NULL); + } + if (func->argc) + for (i = 0; !abort && i < func->argc; ++i) + abort = abort + || set_ref_in_item(&func->argv[i], copyID, NULL, NULL); + } + } + return abort; } *************** *** 5880,5885 **** --- 6068,6101 ---- } static int + ConvertFromPySequence(PyObject *obj, typval_T *tv) + { + PyObject *lookup_dict; + int ret; + + if (!(lookup_dict = PyDict_New())) + return -1; + + if (PyType_IsSubtype(obj->ob_type, &ListType)) + { + tv->v_type = VAR_LIST; + tv->vval.v_list = (((ListObject *)(obj))->list); + ++tv->vval.v_list->lv_refcount; + } + else if (PyIter_Check(obj) || PySequence_Check(obj)) + return convert_dl(obj, tv, pyseq_to_tv, lookup_dict); + else + { + PyErr_FORMAT(PyExc_TypeError, + N_("unable to convert %s to vim list"), + Py_TYPE_NAME(obj)); + ret = -1; + } + Py_DECREF(lookup_dict); + return ret; + } + + static int ConvertFromPyObject(PyObject *obj, typval_T *tv) { PyObject *lookup_dict; *************** *** 5909,5919 **** } else if (PyType_IsSubtype(obj->ob_type, &FunctionType)) { ! if (set_string_copy(((FunctionObject *) (obj))->name, tv) == -1) ! return -1; ! tv->v_type = VAR_FUNC; ! func_ref(tv->vval.v_string); } else if (PyBytes_Check(obj)) { --- 6125,6146 ---- } else if (PyType_IsSubtype(obj->ob_type, &FunctionType)) { ! FunctionObject *func = (FunctionObject *) obj; ! if (func->self != NULL || func->argv != NULL) ! { ! partial_T *pt = (partial_T *)alloc_clear(sizeof(partial_T)); ! set_partial(func, pt, TRUE); ! tv->vval.v_partial = pt; ! tv->v_type = VAR_PARTIAL; ! } ! else ! { ! if (set_string_copy(func->name, tv) == -1) ! return -1; ! tv->v_type = VAR_FUNC; ! } ! func_ref(func->name); } else if (PyBytes_Check(obj)) { *************** *** 6009,6014 **** --- 6236,6243 ---- static PyObject * ConvertToPyObject(typval_T *tv) { + typval_T *argv; + int i; if (tv == NULL) { PyErr_SET_VIM(N_("internal error: NULL reference passed")); *************** *** 6031,6040 **** return NEW_DICTIONARY(tv->vval.v_dict); case VAR_FUNC: return NEW_FUNCTION(tv->vval.v_string == NULL ! ? (char_u *)"" : tv->vval.v_string); case VAR_PARTIAL: return NEW_FUNCTION(tv->vval.v_partial == NULL ! ? (char_u *)"" : tv->vval.v_partial->pt_name); case VAR_UNKNOWN: case VAR_CHANNEL: case VAR_JOB: --- 6260,6282 ---- return NEW_DICTIONARY(tv->vval.v_dict); case VAR_FUNC: return NEW_FUNCTION(tv->vval.v_string == NULL ! ? (char_u *)"" : tv->vval.v_string, ! 0, NULL, NULL); case VAR_PARTIAL: + if (tv->vval.v_partial->pt_argc) + { + argv = PyMem_New(typval_T, (size_t)tv->vval.v_partial->pt_argc); + for (i = 0; i < tv->vval.v_partial->pt_argc; i++) + copy_tv(&tv->vval.v_partial->pt_argv[i], &argv[i]); + } + else + argv = NULL; + if (tv->vval.v_partial->pt_dict != NULL) + tv->vval.v_partial->pt_dict->dv_refcount++; 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); case VAR_UNKNOWN: case VAR_CHANNEL: case VAR_JOB: *** ../vim-7.4.1730/src/if_python.c 2016-03-14 23:04:49.698923062 +0100 --- src/if_python.c 2016-04-14 15:48:56.045753843 +0200 *************** *** 1539,1550 **** static PyObject * FunctionGetattr(PyObject *self, char *name) { ! FunctionObject *this = (FunctionObject *)(self); ! if (strcmp(name, "name") == 0) ! return PyString_FromString((char *)(this->name)); ! else if (strcmp(name, "__members__") == 0) ! return ObjectDir(NULL, FunctionAttrs); else return Py_FindMethod(FunctionMethods, self, name); } --- 1539,1550 ---- static PyObject * FunctionGetattr(PyObject *self, char *name) { ! PyObject *r; ! r = FunctionAttr((FunctionObject *)(self), name); ! ! if (r || PyErr_Occurred()) ! return r; else return Py_FindMethod(FunctionMethods, self, name); } *** ../vim-7.4.1730/src/if_python3.c 2016-03-14 23:04:49.698923062 +0100 --- src/if_python3.c 2016-04-14 15:48:56.045753843 +0200 *************** *** 1528,1541 **** static PyObject * FunctionGetattro(PyObject *self, PyObject *nameobj) { FunctionObject *this = (FunctionObject *)(self); GET_ATTR_STRING(name, nameobj); ! if (strcmp(name, "name") == 0) ! return PyUnicode_FromString((char *)(this->name)); ! ! return PyObject_GenericGetAttr(self, nameobj); } /* External interface --- 1528,1543 ---- static PyObject * FunctionGetattro(PyObject *self, PyObject *nameobj) { + PyObject *r; FunctionObject *this = (FunctionObject *)(self); GET_ATTR_STRING(name, nameobj); ! r = FunctionAttr(this, name); ! if (r || PyErr_Occurred()) ! return r; ! else ! return PyObject_GenericGetAttr(self, nameobj); } /* External interface *** ../vim-7.4.1730/src/proto/eval.pro 2016-04-14 12:46:33.620678603 +0200 --- src/proto/eval.pro 2016-04-14 15:48:56.045753843 +0200 *************** *** 150,153 **** --- 150,154 ---- void reset_v_option_vars(void); int modify_fname(char_u *src, int *usedlen, char_u **fnamep, char_u **bufp, int *fnamelen); char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub, char_u *flags); + char_u *tv2string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID); /* vim: set ft=c : */ *** ../vim-7.4.1730/src/testdir/test86.in 2016-01-17 22:36:56.017417164 +0100 --- src/testdir/test86.in 2016-04-14 15:48:56.045753843 +0200 *************** *** 13,18 **** --- 13,19 ---- :lang C :fun Test() :py import vim + :py cb = vim.current.buffer :let l = [] :py l=vim.bindeval('l') :py f=vim.bindeval('function("strlen")') *************** *** 207,213 **** :let l = [0, 1, 2, 3] :py l=vim.bindeval('l') :lockvar! l ! :py l[2]='i' :$put =string(l) :unlockvar! l :" --- 208,222 ---- :let l = [0, 1, 2, 3] :py l=vim.bindeval('l') :lockvar! l ! py << EOF ! def emsg(ei): ! return ei[0].__name__ + ':' + repr(ei[1].args) ! ! try: ! l[2]='i' ! except vim.error: ! cb.append('l[2] threw vim.error: ' + emsg(sys.exc_info())) ! EOF :$put =string(l) :unlockvar! l :" *************** *** 219,225 **** exec(expr, g, l) except: ei = sys.exc_info() ! msg = sys.exc_info()[0].__name__ + ':' + repr(sys.exc_info()[1].args) msg = msg.replace('TypeError:(\'argument 1 ', 'TypeError:(\'') if expr.find('None') > -1: msg = msg.replace('TypeError:(\'iteration over non-sequence\',)', --- 228,234 ---- exec(expr, g, l) except: ei = sys.exc_info() ! msg = emsg(ei) msg = msg.replace('TypeError:(\'argument 1 ', 'TypeError:(\'') if expr.find('None') > -1: msg = msg.replace('TypeError:(\'iteration over non-sequence\',)', *************** *** 611,617 **** : autocmd BufFilePre * python cb.append(vim.eval('expand("")') + ':BufFilePre:' + vim.eval('bufnr("%")')) :augroup END py << EOF - cb = vim.current.buffer # Tests BufferAppend and BufferItem cb.append(b[0]) # Tests BufferSlice and BufferAssSlice --- 620,625 ---- *************** *** 865,870 **** --- 873,1047 ---- :$put =string(pyeval('vim.List()')) :$put =string(pyeval('vim.List(iter(''abc7''))')) :$put =string(pyeval('vim.Function(''tr'')')) + :$put =string(pyeval('vim.Function(''tr'', args=[123, 3, 4])')) + :$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={})')) + :" + :" Test vim.Function + :function Args(...) + : return a:000 + :endfunction + :function SelfArgs(...) dict + : return [a:000, self] + :endfunction + :" The following four lines should not crash + :let Pt = function('tr', [[]], {'l': []}) + :py Pt = vim.bindeval('Pt') + :unlet Pt + :py del Pt + py << EOF + def ecall(out_prefix, func, *args, **kwargs): + line = out_prefix + ': ' + try: + ret = func(*args, **kwargs) + except Exception: + line += '!exception: ' + emsg(sys.exc_info()) + else: + line += '!result: ' + vim.Function('string')(ret) + cb.append(line) + a = vim.Function('Args') + pa1 = vim.Function('Args', args=['abcArgsPA1']) + pa2 = vim.Function('Args', args=[]) + pa3 = vim.Function('Args', args=['abcArgsPA3'], self={'abcSelfPA3': 'abcSelfPA3Val'}) + pa4 = vim.Function('Args', self={'abcSelfPA4': 'abcSelfPA4Val'}) + cb.append('a: ' + repr(a)) + cb.append('pa1: ' + repr(pa1)) + cb.append('pa2: ' + repr(pa2)) + cb.append('pa3: ' + repr(pa3)) + cb.append('pa4: ' + repr(pa4)) + sa = vim.Function('SelfArgs') + psa1 = vim.Function('SelfArgs', args=['abcArgsPSA1']) + psa2 = vim.Function('SelfArgs', args=[]) + psa3 = vim.Function('SelfArgs', args=['abcArgsPSA3'], self={'abcSelfPSA3': 'abcSelfPSA3Val'}) + psa4 = vim.Function('SelfArgs', self={'abcSelfPSA4': 'abcSelfPSA4Val'}) + 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)) + + psar = vim.Function('SelfArgs', args=[{'abcArgsPSAr': 'abcArgsPSArVal'}], self={'abcSelfPSAr': 'abcSelfPSArVal'}) + psar.args[0]['abcArgsPSAr2'] = [psar.self, psar.args[0]] + psar.self['rec'] = psar + psar.self['self'] = psar.self + psar.self['args'] = psar.args + + try: + cb.append('psar: ' + repr(psar)) + except Exception: + cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info())) + EOF + :$put ='s(a): '.string(pyeval('a')) + :$put ='s(pa1): '.string(pyeval('pa1')) + :$put ='s(pa2): '.string(pyeval('pa2')) + :$put ='s(pa3): '.string(pyeval('pa3')) + :$put ='s(pa4): '.string(pyeval('pa4')) + :$put ='s(sa): '.string(pyeval('sa')) + :$put ='s(psa1): '.string(pyeval('psa1')) + :$put ='s(psa2): '.string(pyeval('psa2')) + :$put ='s(psa3): '.string(pyeval('psa3')) + :$put ='s(psa4): '.string(pyeval('psa4')) + : + :py ecall('a()', a, ) + :py ecall('pa1()', pa1, ) + :py ecall('pa2()', pa2, ) + :py ecall('pa3()', pa3, ) + :py ecall('pa4()', pa4, ) + :py ecall('sa()', sa, ) + :py ecall('psa1()', psa1, ) + :py ecall('psa2()', psa2, ) + :py ecall('psa3()', psa3, ) + :py ecall('psa4()', psa4, ) + : + :py ecall('a(42, 43)', a, 42, 43) + :py ecall('pa1(42, 43)', pa1, 42, 43) + :py ecall('pa2(42, 43)', pa2, 42, 43) + :py ecall('pa3(42, 43)', pa3, 42, 43) + :py ecall('pa4(42, 43)', pa4, 42, 43) + :py ecall('sa(42, 43)', sa, 42, 43) + :py ecall('psa1(42, 43)', psa1, 42, 43) + :py ecall('psa2(42, 43)', psa2, 42, 43) + :py ecall('psa3(42, 43)', psa3, 42, 43) + :py ecall('psa4(42, 43)', psa4, 42, 43) + : + :py ecall('a(42, self={"20": 1})', a, 42, self={'20': 1}) + :py ecall('pa1(42, self={"20": 1})', pa1, 42, self={'20': 1}) + :py ecall('pa2(42, self={"20": 1})', pa2, 42, self={'20': 1}) + :py ecall('pa3(42, self={"20": 1})', pa3, 42, self={'20': 1}) + :py ecall('pa4(42, self={"20": 1})', pa4, 42, self={'20': 1}) + :py ecall('sa(42, self={"20": 1})', sa, 42, self={'20': 1}) + :py ecall('psa1(42, self={"20": 1})', psa1, 42, self={'20': 1}) + :py ecall('psa2(42, self={"20": 1})', psa2, 42, self={'20': 1}) + :py ecall('psa3(42, self={"20": 1})', psa3, 42, self={'20': 1}) + :py ecall('psa4(42, self={"20": 1})', psa4, 42, self={'20': 1}) + : + :py ecall('a(self={"20": 1})', a, self={'20': 1}) + :py ecall('pa1(self={"20": 1})', pa1, self={'20': 1}) + :py ecall('pa2(self={"20": 1})', pa2, self={'20': 1}) + :py ecall('pa3(self={"20": 1})', pa3, self={'20': 1}) + :py ecall('pa4(self={"20": 1})', pa4, self={'20': 1}) + :py ecall('sa(self={"20": 1})', sa, self={'20': 1}) + :py ecall('psa1(self={"20": 1})', psa1, self={'20': 1}) + :py ecall('psa2(self={"20": 1})', psa2, self={'20': 1}) + :py ecall('psa3(self={"20": 1})', psa3, self={'20': 1}) + :py ecall('psa4(self={"20": 1})', psa4, self={'20': 1}) + py << EOF + def s(v): + if v is None: + return repr(v) + else: + return vim.Function('string')(v) + + cb.append('a.args: ' + s(a.args)) + cb.append('pa1.args: ' + s(pa1.args)) + cb.append('pa2.args: ' + s(pa2.args)) + cb.append('pa3.args: ' + s(pa3.args)) + cb.append('pa4.args: ' + s(pa4.args)) + cb.append('sa.args: ' + s(sa.args)) + cb.append('psa1.args: ' + s(psa1.args)) + cb.append('psa2.args: ' + s(psa2.args)) + cb.append('psa3.args: ' + s(psa3.args)) + cb.append('psa4.args: ' + s(psa4.args)) + + cb.append('a.self: ' + s(a.self)) + cb.append('pa1.self: ' + s(pa1.self)) + cb.append('pa2.self: ' + s(pa2.self)) + cb.append('pa3.self: ' + s(pa3.self)) + cb.append('pa4.self: ' + s(pa4.self)) + cb.append('sa.self: ' + s(sa.self)) + cb.append('psa1.self: ' + s(psa1.self)) + cb.append('psa2.self: ' + s(psa2.self)) + cb.append('psa3.self: ' + s(psa3.self)) + cb.append('psa4.self: ' + s(psa4.self)) + + cb.append('a.name: ' + s(a.name)) + cb.append('pa1.name: ' + s(pa1.name)) + cb.append('pa2.name: ' + s(pa2.name)) + cb.append('pa3.name: ' + s(pa3.name)) + cb.append('pa4.name: ' + s(pa4.name)) + cb.append('sa.name: ' + s(sa.name)) + cb.append('psa1.name: ' + s(psa1.name)) + cb.append('psa2.name: ' + s(psa2.name)) + cb.append('psa3.name: ' + s(psa3.name)) + cb.append('psa4.name: ' + s(psa4.name)) + + del s + + del a + del pa1 + del pa2 + del pa3 + del pa4 + del sa + del psa1 + del psa2 + del psa3 + del psa4 + del psar + + del ecall + EOF :" :" Test stdout/stderr :redir => messages *************** *** 1140,1146 **** ee('vim.foreach_rtp(int, 2)') cb.append('> import') old_rtp = vim.options['rtp'] ! vim.options['rtp'] = os.getcwd().replace(',', '\\,').replace('\\', '\\\\') ee('import xxx_no_such_module_xxx') ee('import failing_import') ee('import failing') --- 1317,1323 ---- ee('vim.foreach_rtp(int, 2)') cb.append('> import') old_rtp = vim.options['rtp'] ! vim.options['rtp'] = os.getcwd().replace('\\', '\\\\').replace(',', '\\,') ee('import xxx_no_such_module_xxx') ee('import failing_import') ee('import failing') *************** *** 1224,1232 **** --- 1401,1420 ---- ee('l.xxx = True') cb.append("> Function") cb.append(">> FunctionConstructor") + cb.append(">>> FunctionConstructor") ee('vim.Function("123")') ee('vim.Function("xxx_non_existent_function_xxx")') ee('vim.Function("xxx#non#existent#function#xxx")') + ee('vim.Function("xxx_non_existent_function_xxx2", args=[])') + ee('vim.Function("xxx_non_existent_function_xxx3", self={})') + ee('vim.Function("xxx_non_existent_function_xxx4", args=[], self={})') + cb.append(">>> FunctionNew") + ee('vim.Function("tr", self="abcFuncSelf")') + ee('vim.Function("tr", args=427423)') + ee('vim.Function("tr", self="abcFuncSelf2", args="abcFuncArgs2")') + ee('vim.Function(self="abcFuncSelf2", args="abcFuncArgs2")') + ee('vim.Function("tr", "", self="abcFuncSelf2", args="abcFuncArgs2")') + ee('vim.Function("tr", "")') cb.append(">> FunctionCall") convertfrompyobject_test('f(%s)') convertfrompymapping_test('fd(self=%s)') *************** *** 1381,1387 **** except KeyboardInterrupt: cb.append('Caught KeyboardInterrupt') except Exception: ! cb.append('!!!!!!!! Caught exception: ' + repr(sys.exc_info)) else: cb.append('!!!!!!!! No exception') try: --- 1569,1575 ---- except KeyboardInterrupt: cb.append('Caught KeyboardInterrupt') except Exception: ! cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info())) else: cb.append('!!!!!!!! No exception') try: *************** *** 1389,1395 **** except KeyboardInterrupt: cb.append('!!!!!!!! Caught KeyboardInterrupt') except Exception: ! cb.append('!!!!!!!! Caught exception: ' + repr(sys.exc_info)) else: cb.append('No exception') EOF --- 1577,1583 ---- except KeyboardInterrupt: cb.append('!!!!!!!! Caught KeyboardInterrupt') except Exception: ! cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info())) else: cb.append('No exception') EOF *************** *** 1409,1414 **** --- 1597,1603 ---- py << EOF del cb del ee + del emsg del sys del os del vim *************** *** 1441,1447 **** :" :/^start:/,$wq! test.out :" vim: et ts=4 isk-=\: ! :call getchar() ENDTEST start: --- 1630,1636 ---- :" :/^start:/,$wq! test.out :" vim: et ts=4 isk-=\: ! :while getchar(0) isnot 0|endwhile ENDTEST start: *** ../vim-7.4.1730/src/testdir/test86.ok 2016-01-17 22:36:56.017417164 +0100 --- src/testdir/test86.ok 2016-04-14 15:48:56.045753843 +0200 *************** *** 57,62 **** --- 57,63 ---- [0, 1, 2, 3, 4, 5, 6, 7] [0, 1, 2, 3, 4, 5, 6, 7] [0, 1, 2, 3, 4, 5, 6, 7] + l[2] threw vim.error: error:('list is locked',) [0, 1, 2, 3] [function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd'] [function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd', 'DictNewStart', 1, 2, 3, 'DictNewEnd', {'a': 'b'}] *************** *** 447,453 **** 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__,softspace output:__dir__,__members__,close,flush,isatty,readable,seekable,softspace,writable,write,writelines {} {'a': 1} --- 448,454 ---- 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 output:__dir__,__members__,close,flush,isatty,readable,seekable,softspace,writable,write,writelines {} {'a': 1} *************** *** 455,466 **** [] ['a', 'b', 'c', '7'] function('tr') ' abcdef ! line : abcdef abcA ! line : abcB' ['a', 'dup_a'] ['a', 'a'] --- 456,563 ---- [] ['a', 'b', 'c', '7'] function('tr') + function('tr', [123, 3, 4]) + function('tr') + function('tr', {}) + function('tr', [123, 3, 4], {}) + a: + pa1: + pa2: + pa3: + pa4: + sa: + psa1: + psa2: + psa3: + psa4: + psar: + s(a): function('Args') + s(pa1): function('Args', ['abcArgsPA1']) + s(pa2): function('Args') + s(pa3): function('Args', ['abcArgsPA3'], {'abcSelfPA3': 'abcSelfPA3Val'}) + s(pa4): function('Args', {'abcSelfPA4': 'abcSelfPA4Val'}) + s(sa): function('SelfArgs') + s(psa1): function('SelfArgs', ['abcArgsPSA1']) + s(psa2): function('SelfArgs') + s(psa3): function('SelfArgs', ['abcArgsPSA3'], {'abcSelfPSA3': 'abcSelfPSA3Val'}) + s(psa4): function('SelfArgs', {'abcSelfPSA4': 'abcSelfPSA4Val'}) + a(): !result: [] + pa1(): !result: ['abcArgsPA1'] + pa2(): !result: [] + pa3(): !result: ['abcArgsPA3'] + pa4(): !result: [] + sa(): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',) + psa1(): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',) + psa2(): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',) + psa3(): !result: [['abcArgsPSA3'], {'abcSelfPSA3': 'abcSelfPSA3Val'}] + psa4(): !result: [[], {'abcSelfPSA4': 'abcSelfPSA4Val'}] + a(42, 43): !result: [42, 43] + pa1(42, 43): !result: ['abcArgsPA1', 42, 43] + pa2(42, 43): !result: [42, 43] + pa3(42, 43): !result: ['abcArgsPA3', 42, 43] + pa4(42, 43): !result: [42, 43] + sa(42, 43): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',) + psa1(42, 43): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',) + psa2(42, 43): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',) + psa3(42, 43): !result: [['abcArgsPSA3', 42, 43], {'abcSelfPSA3': 'abcSelfPSA3Val'}] + psa4(42, 43): !result: [[42, 43], {'abcSelfPSA4': 'abcSelfPSA4Val'}] + a(42, self={"20": 1}): !result: [42] + pa1(42, self={"20": 1}): !result: ['abcArgsPA1', 42] + pa2(42, self={"20": 1}): !result: [42] + pa3(42, self={"20": 1}): !result: ['abcArgsPA3', 42] + pa4(42, self={"20": 1}): !result: [42] + sa(42, self={"20": 1}): !result: [[42], {'20': 1}] + psa1(42, self={"20": 1}): !result: [['abcArgsPSA1', 42], {'20': 1}] + psa2(42, self={"20": 1}): !result: [[42], {'20': 1}] + psa3(42, self={"20": 1}): !result: [['abcArgsPSA3', 42], {'20': 1}] + psa4(42, self={"20": 1}): !result: [[42], {'20': 1}] + a(self={"20": 1}): !result: [] + pa1(self={"20": 1}): !result: ['abcArgsPA1'] + pa2(self={"20": 1}): !result: [] + pa3(self={"20": 1}): !result: ['abcArgsPA3'] + pa4(self={"20": 1}): !result: [] + sa(self={"20": 1}): !result: [[], {'20': 1}] + psa1(self={"20": 1}): !result: [['abcArgsPSA1'], {'20': 1}] + psa2(self={"20": 1}): !result: [[], {'20': 1}] + psa3(self={"20": 1}): !result: [['abcArgsPSA3'], {'20': 1}] + psa4(self={"20": 1}): !result: [[], {'20': 1}] + a.args: None + pa1.args: ['abcArgsPA1'] + pa2.args: None + pa3.args: ['abcArgsPA3'] + pa4.args: None + sa.args: None + psa1.args: ['abcArgsPSA1'] + psa2.args: None + psa3.args: ['abcArgsPSA3'] + psa4.args: None + a.self: None + pa1.self: None + pa2.self: None + pa3.self: {'abcSelfPA3': 'abcSelfPA3Val'} + pa4.self: {'abcSelfPA4': 'abcSelfPA4Val'} + sa.self: None + psa1.self: None + psa2.self: None + psa3.self: {'abcSelfPSA3': 'abcSelfPSA3Val'} + psa4.self: {'abcSelfPSA4': 'abcSelfPSA4Val'} + a.name: 'Args' + pa1.name: 'Args' + pa2.name: 'Args' + pa3.name: 'Args' + pa4.name: 'Args' + sa.name: 'SelfArgs' + psa1.name: 'SelfArgs' + psa2.name: 'SelfArgs' + psa3.name: 'SelfArgs' + psa4.name: 'SelfArgs' ' abcdef ! Error detected while processing function RunTest[]..Test: ! line : abcdef abcA ! line : abcB' ['a', 'dup_a'] ['a', 'a'] *************** *** 1046,1054 **** --- 1143,1162 ---- l.xxx = True:AttributeError:('cannot set attribute xxx',) > Function >> FunctionConstructor + >>> FunctionConstructor vim.Function("123"):ValueError:('unnamed function 123 does not exist',) vim.Function("xxx_non_existent_function_xxx"):ValueError:('function xxx_non_existent_function_xxx does not exist',) vim.Function("xxx#non#existent#function#xxx"):NOT FAILED + vim.Function("xxx_non_existent_function_xxx2", args=[]):ValueError:('function xxx_non_existent_function_xxx2 does not exist',) + vim.Function("xxx_non_existent_function_xxx3", self={}):ValueError:('function xxx_non_existent_function_xxx3 does not exist',) + vim.Function("xxx_non_existent_function_xxx4", args=[], self={}):ValueError:('function xxx_non_existent_function_xxx4 does not exist',) + >>> FunctionNew + vim.Function("tr", self="abcFuncSelf"):TypeError:('unable to convert str to vim dictionary',) + vim.Function("tr", args=427423):TypeError:('unable to convert int to vim list',) + vim.Function("tr", self="abcFuncSelf2", args="abcFuncArgs2"):TypeError:('unable to convert str to vim dictionary',) + vim.Function(self="abcFuncSelf2", args="abcFuncArgs2"):TypeError:('unable to convert str to vim dictionary',) + vim.Function("tr", "", self="abcFuncSelf2", args="abcFuncArgs2"):TypeError:('unable to convert str to vim dictionary',) + vim.Function("tr", ""):TypeError:('function takes exactly 1 argument (2 given)',) >> FunctionCall >>> Testing StringToChars using f({%s : 1}) f({1 : 1}):TypeError:('expected str() or unicode() instance, but got int',) *** ../vim-7.4.1730/src/testdir/test87.in 2016-02-28 20:13:14.237733718 +0100 --- src/testdir/test87.in 2016-04-14 15:48:56.049753799 +0200 *************** *** 7,12 **** --- 7,13 ---- :lang C :fun Test() :py3 import vim + :py3 cb = vim.current.buffer :let l = [] :py3 l=vim.bindeval('l') :py3 f=vim.bindeval('function("strlen")') *************** *** 200,206 **** :let l = [0, 1, 2, 3] :py3 l=vim.bindeval('l') :lockvar! l ! :py3 l[2]='i' :$put =string(l) :unlockvar! l :" --- 201,215 ---- :let l = [0, 1, 2, 3] :py3 l=vim.bindeval('l') :lockvar! l ! py3 << EOF ! def emsg(ei): ! return ei[0].__name__ + ':' + repr(ei[1].args) ! ! try: ! l[2]='i' ! except vim.error: ! cb.append('l[2] threw vim.error: ' + emsg(sys.exc_info())) ! EOF :$put =string(l) :unlockvar! l :" *************** *** 614,620 **** : autocmd BufFilePre * python3 cb.append(vim.eval('expand("")') + ':BufFilePre:' + vim.eval('bufnr("%")')) :augroup END py3 << EOF - cb = vim.current.buffer # Tests BufferAppend and BufferItem cb.append(b[0]) # Tests BufferSlice and BufferAssSlice --- 623,628 ---- *************** *** 859,864 **** --- 867,1041 ---- :$put =string(py3eval('vim.List()')) :$put =string(py3eval('vim.List(iter(''abc7''))')) :$put =string(py3eval('vim.Function(''tr'')')) + :$put =string(py3eval('vim.Function(''tr'', args=[123, 3, 4])')) + :$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={})')) + :" + :" Test vim.Function + :function Args(...) + : return a:000 + :endfunction + :function SelfArgs(...) dict + : return [a:000, self] + :endfunction + :" The following four lines should not crash + :let Pt = function('tr', [[]], {'l': []}) + :py3 Pt = vim.bindeval('Pt') + :unlet Pt + :py3 del Pt + py3 << EOF + def ecall(out_prefix, func, *args, **kwargs): + line = out_prefix + ': ' + try: + ret = func(*args, **kwargs) + except Exception: + line += '!exception: ' + emsg(sys.exc_info()) + else: + line += '!result: ' + str(vim.Function('string')(ret), 'utf-8') + cb.append(line) + a = vim.Function('Args') + pa1 = vim.Function('Args', args=['abcArgsPA1']) + pa2 = vim.Function('Args', args=[]) + pa3 = vim.Function('Args', args=['abcArgsPA3'], self={'abcSelfPA3': 'abcSelfPA3Val'}) + pa4 = vim.Function('Args', self={'abcSelfPA4': 'abcSelfPA4Val'}) + cb.append('a: ' + repr(a)) + cb.append('pa1: ' + repr(pa1)) + cb.append('pa2: ' + repr(pa2)) + cb.append('pa3: ' + repr(pa3)) + cb.append('pa4: ' + repr(pa4)) + sa = vim.Function('SelfArgs') + psa1 = vim.Function('SelfArgs', args=['abcArgsPSA1']) + psa2 = vim.Function('SelfArgs', args=[]) + psa3 = vim.Function('SelfArgs', args=['abcArgsPSA3'], self={'abcSelfPSA3': 'abcSelfPSA3Val'}) + psa4 = vim.Function('SelfArgs', self={'abcSelfPSA4': 'abcSelfPSA4Val'}) + 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)) + + psar = vim.Function('SelfArgs', args=[{'abcArgsPSAr': 'abcArgsPSArVal'}], self={'abcSelfPSAr': 'abcSelfPSArVal'}) + psar.args[0]['abcArgsPSAr2'] = [psar.self, psar.args[0]] + psar.self['rec'] = psar + psar.self['self'] = psar.self + psar.self['args'] = psar.args + + try: + cb.append('psar: ' + repr(psar)) + except Exception: + cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info())) + EOF + :$put ='s(a): '.string(py3eval('a')) + :$put ='s(pa1): '.string(py3eval('pa1')) + :$put ='s(pa2): '.string(py3eval('pa2')) + :$put ='s(pa3): '.string(py3eval('pa3')) + :$put ='s(pa4): '.string(py3eval('pa4')) + :$put ='s(sa): '.string(py3eval('sa')) + :$put ='s(psa1): '.string(py3eval('psa1')) + :$put ='s(psa2): '.string(py3eval('psa2')) + :$put ='s(psa3): '.string(py3eval('psa3')) + :$put ='s(psa4): '.string(py3eval('psa4')) + : + :py3 ecall('a()', a, ) + :py3 ecall('pa1()', pa1, ) + :py3 ecall('pa2()', pa2, ) + :py3 ecall('pa3()', pa3, ) + :py3 ecall('pa4()', pa4, ) + :py3 ecall('sa()', sa, ) + :py3 ecall('psa1()', psa1, ) + :py3 ecall('psa2()', psa2, ) + :py3 ecall('psa3()', psa3, ) + :py3 ecall('psa4()', psa4, ) + : + :py3 ecall('a(42, 43)', a, 42, 43) + :py3 ecall('pa1(42, 43)', pa1, 42, 43) + :py3 ecall('pa2(42, 43)', pa2, 42, 43) + :py3 ecall('pa3(42, 43)', pa3, 42, 43) + :py3 ecall('pa4(42, 43)', pa4, 42, 43) + :py3 ecall('sa(42, 43)', sa, 42, 43) + :py3 ecall('psa1(42, 43)', psa1, 42, 43) + :py3 ecall('psa2(42, 43)', psa2, 42, 43) + :py3 ecall('psa3(42, 43)', psa3, 42, 43) + :py3 ecall('psa4(42, 43)', psa4, 42, 43) + : + :py3 ecall('a(42, self={"20": 1})', a, 42, self={'20': 1}) + :py3 ecall('pa1(42, self={"20": 1})', pa1, 42, self={'20': 1}) + :py3 ecall('pa2(42, self={"20": 1})', pa2, 42, self={'20': 1}) + :py3 ecall('pa3(42, self={"20": 1})', pa3, 42, self={'20': 1}) + :py3 ecall('pa4(42, self={"20": 1})', pa4, 42, self={'20': 1}) + :py3 ecall('sa(42, self={"20": 1})', sa, 42, self={'20': 1}) + :py3 ecall('psa1(42, self={"20": 1})', psa1, 42, self={'20': 1}) + :py3 ecall('psa2(42, self={"20": 1})', psa2, 42, self={'20': 1}) + :py3 ecall('psa3(42, self={"20": 1})', psa3, 42, self={'20': 1}) + :py3 ecall('psa4(42, self={"20": 1})', psa4, 42, self={'20': 1}) + : + :py3 ecall('a(self={"20": 1})', a, self={'20': 1}) + :py3 ecall('pa1(self={"20": 1})', pa1, self={'20': 1}) + :py3 ecall('pa2(self={"20": 1})', pa2, self={'20': 1}) + :py3 ecall('pa3(self={"20": 1})', pa3, self={'20': 1}) + :py3 ecall('pa4(self={"20": 1})', pa4, self={'20': 1}) + :py3 ecall('sa(self={"20": 1})', sa, self={'20': 1}) + :py3 ecall('psa1(self={"20": 1})', psa1, self={'20': 1}) + :py3 ecall('psa2(self={"20": 1})', psa2, self={'20': 1}) + :py3 ecall('psa3(self={"20": 1})', psa3, self={'20': 1}) + :py3 ecall('psa4(self={"20": 1})', psa4, self={'20': 1}) + py3 << EOF + def s(v): + if v is None: + return repr(v) + else: + return str(vim.Function('string')(v), 'utf-8') + + cb.append('a.args: ' + s(a.args)) + cb.append('pa1.args: ' + s(pa1.args)) + cb.append('pa2.args: ' + s(pa2.args)) + cb.append('pa3.args: ' + s(pa3.args)) + cb.append('pa4.args: ' + s(pa4.args)) + cb.append('sa.args: ' + s(sa.args)) + cb.append('psa1.args: ' + s(psa1.args)) + cb.append('psa2.args: ' + s(psa2.args)) + cb.append('psa3.args: ' + s(psa3.args)) + cb.append('psa4.args: ' + s(psa4.args)) + + cb.append('a.self: ' + s(a.self)) + cb.append('pa1.self: ' + s(pa1.self)) + cb.append('pa2.self: ' + s(pa2.self)) + cb.append('pa3.self: ' + s(pa3.self)) + cb.append('pa4.self: ' + s(pa4.self)) + cb.append('sa.self: ' + s(sa.self)) + cb.append('psa1.self: ' + s(psa1.self)) + cb.append('psa2.self: ' + s(psa2.self)) + cb.append('psa3.self: ' + s(psa3.self)) + cb.append('psa4.self: ' + s(psa4.self)) + + cb.append('a.name: ' + s(a.name)) + cb.append('pa1.name: ' + s(pa1.name)) + cb.append('pa2.name: ' + s(pa2.name)) + cb.append('pa3.name: ' + s(pa3.name)) + cb.append('pa4.name: ' + s(pa4.name)) + cb.append('sa.name: ' + s(sa.name)) + cb.append('psa1.name: ' + s(psa1.name)) + cb.append('psa2.name: ' + s(psa2.name)) + cb.append('psa3.name: ' + s(psa3.name)) + cb.append('psa4.name: ' + s(psa4.name)) + + del s + + del a + del pa1 + del pa2 + del pa3 + del pa4 + del sa + del psa1 + del psa2 + del psa3 + del psa4 + del psar + + del ecall + EOF :" :" Test stdout/stderr :redir => messages *************** *** 1134,1140 **** ee('vim.foreach_rtp(int, 2)') cb.append('> import') old_rtp = vim.options['rtp'] ! vim.options['rtp'] = os.getcwd().replace(',', '\\,').replace('\\', '\\\\') ee('import xxx_no_such_module_xxx') ee('import failing_import') ee('import failing') --- 1311,1317 ---- ee('vim.foreach_rtp(int, 2)') cb.append('> import') old_rtp = vim.options['rtp'] ! vim.options['rtp'] = os.getcwd().replace('\\', '\\\\').replace(',', '\\,') ee('import xxx_no_such_module_xxx') ee('import failing_import') ee('import failing') *************** *** 1218,1226 **** --- 1395,1414 ---- ee('l.xxx = True') cb.append("> Function") cb.append(">> FunctionConstructor") + cb.append(">>> FunctionConstructor") ee('vim.Function("123")') ee('vim.Function("xxx_non_existent_function_xxx")') ee('vim.Function("xxx#non#existent#function#xxx")') + ee('vim.Function("xxx_non_existent_function_xxx2", args=[])') + ee('vim.Function("xxx_non_existent_function_xxx3", self={})') + ee('vim.Function("xxx_non_existent_function_xxx4", args=[], self={})') + cb.append(">>> FunctionNew") + ee('vim.Function("tr", self="abcFuncSelf")') + ee('vim.Function("tr", args=427423)') + ee('vim.Function("tr", self="abcFuncSelf2", args="abcFuncArgs2")') + ee('vim.Function(self="abcFuncSelf2", args="abcFuncArgs2")') + ee('vim.Function("tr", "", self="abcFuncSelf2", args="abcFuncArgs2")') + ee('vim.Function("tr", "")') cb.append(">> FunctionCall") convertfrompyobject_test('f(%s)') convertfrompymapping_test('fd(self=%s)') *************** *** 1374,1389 **** vim.command('while 1 | endwhile') except KeyboardInterrupt: cb.append('Caught KeyboardInterrupt') ! except Exception as e: ! cb.append('!!!!!!!! Caught exception: ' + repr(e)) else: cb.append('!!!!!!!! No exception') try: vim.command('$ put =\'Running :put\'') except KeyboardInterrupt: cb.append('!!!!!!!! Caught KeyboardInterrupt') ! except Exception as e: ! cb.append('!!!!!!!! Caught exception: ' + repr(e)) else: cb.append('No exception') EOF --- 1562,1577 ---- vim.command('while 1 | endwhile') except KeyboardInterrupt: cb.append('Caught KeyboardInterrupt') ! except Exception: ! cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info())) else: cb.append('!!!!!!!! No exception') try: vim.command('$ put =\'Running :put\'') except KeyboardInterrupt: cb.append('!!!!!!!! Caught KeyboardInterrupt') ! except Exception: ! cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info())) else: cb.append('No exception') EOF *************** *** 1403,1408 **** --- 1591,1597 ---- py3 << EOF del cb del ee + del emsg del sys del os del vim *************** *** 1434,1441 **** :call garbagecollect(1) :" :/^start:/,$wq! test.out :" vim: et ts=4 isk-=\: ! :call getchar() ENDTEST start: --- 1623,1631 ---- :call garbagecollect(1) :" :/^start:/,$wq! test.out + :/^start:/,$w! test.out :" vim: et ts=4 isk-=\: ! :while getchar(0) isnot 0|endwhile ENDTEST start: *** ../vim-7.4.1730/src/testdir/test87.ok 2016-01-17 22:36:56.017417164 +0100 --- src/testdir/test87.ok 2016-04-14 15:48:56.049753799 +0200 *************** *** 57,62 **** --- 57,63 ---- [0, 1, 2, 3, 4, 5, 6, 7] [0, 1, 2, 3, 4, 5, 6, 7] [0, 1, 2, 3, 4, 5, 6, 7] + l[2] threw vim.error: error:('list is locked',) [0, 1, 2, 3] [function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd'] [function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd', 'DictNewStart', 1, 2, 3, 'DictNewEnd', {'a': 'b'}] *************** *** 447,453 **** range:__dir__,append,end,start dictionary:__dir__,get,has_key,items,keys,locked,pop,popitem,scope,update,values list:__dir__,extend,locked ! function:__dir__,softspace output:__dir__,close,flush,isatty,readable,seekable,softspace,writable,write,writelines {} {'a': 1} --- 448,454 ---- 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 output:__dir__,close,flush,isatty,readable,seekable,softspace,writable,write,writelines {} {'a': 1} *************** *** 455,466 **** [] ['a', 'b', 'c', '7'] function('tr') ' abcdef ! line : abcdef abcA ! line : abcB' ['a', 'dup_a'] ['a', 'a'] --- 456,563 ---- [] ['a', 'b', 'c', '7'] function('tr') + function('tr', [123, 3, 4]) + function('tr') + function('tr', {}) + function('tr', [123, 3, 4], {}) + a: + pa1: + pa2: + pa3: + pa4: + sa: + psa1: + psa2: + psa3: + psa4: + psar: + s(a): function('Args') + s(pa1): function('Args', ['abcArgsPA1']) + s(pa2): function('Args') + s(pa3): function('Args', ['abcArgsPA3'], {'abcSelfPA3': 'abcSelfPA3Val'}) + s(pa4): function('Args', {'abcSelfPA4': 'abcSelfPA4Val'}) + s(sa): function('SelfArgs') + s(psa1): function('SelfArgs', ['abcArgsPSA1']) + s(psa2): function('SelfArgs') + s(psa3): function('SelfArgs', ['abcArgsPSA3'], {'abcSelfPSA3': 'abcSelfPSA3Val'}) + s(psa4): function('SelfArgs', {'abcSelfPSA4': 'abcSelfPSA4Val'}) + a(): !result: [] + pa1(): !result: ['abcArgsPA1'] + pa2(): !result: [] + pa3(): !result: ['abcArgsPA3'] + pa4(): !result: [] + sa(): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',) + psa1(): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',) + psa2(): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',) + psa3(): !result: [['abcArgsPSA3'], {'abcSelfPSA3': 'abcSelfPSA3Val'}] + psa4(): !result: [[], {'abcSelfPSA4': 'abcSelfPSA4Val'}] + a(42, 43): !result: [42, 43] + pa1(42, 43): !result: ['abcArgsPA1', 42, 43] + pa2(42, 43): !result: [42, 43] + pa3(42, 43): !result: ['abcArgsPA3', 42, 43] + pa4(42, 43): !result: [42, 43] + sa(42, 43): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',) + psa1(42, 43): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',) + psa2(42, 43): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',) + psa3(42, 43): !result: [['abcArgsPSA3', 42, 43], {'abcSelfPSA3': 'abcSelfPSA3Val'}] + psa4(42, 43): !result: [[42, 43], {'abcSelfPSA4': 'abcSelfPSA4Val'}] + a(42, self={"20": 1}): !result: [42] + pa1(42, self={"20": 1}): !result: ['abcArgsPA1', 42] + pa2(42, self={"20": 1}): !result: [42] + pa3(42, self={"20": 1}): !result: ['abcArgsPA3', 42] + pa4(42, self={"20": 1}): !result: [42] + sa(42, self={"20": 1}): !result: [[42], {'20': 1}] + psa1(42, self={"20": 1}): !result: [['abcArgsPSA1', 42], {'20': 1}] + psa2(42, self={"20": 1}): !result: [[42], {'20': 1}] + psa3(42, self={"20": 1}): !result: [['abcArgsPSA3', 42], {'20': 1}] + psa4(42, self={"20": 1}): !result: [[42], {'20': 1}] + a(self={"20": 1}): !result: [] + pa1(self={"20": 1}): !result: ['abcArgsPA1'] + pa2(self={"20": 1}): !result: [] + pa3(self={"20": 1}): !result: ['abcArgsPA3'] + pa4(self={"20": 1}): !result: [] + sa(self={"20": 1}): !result: [[], {'20': 1}] + psa1(self={"20": 1}): !result: [['abcArgsPSA1'], {'20': 1}] + psa2(self={"20": 1}): !result: [[], {'20': 1}] + psa3(self={"20": 1}): !result: [['abcArgsPSA3'], {'20': 1}] + psa4(self={"20": 1}): !result: [[], {'20': 1}] + a.args: None + pa1.args: ['abcArgsPA1'] + pa2.args: None + pa3.args: ['abcArgsPA3'] + pa4.args: None + sa.args: None + psa1.args: ['abcArgsPSA1'] + psa2.args: None + psa3.args: ['abcArgsPSA3'] + psa4.args: None + a.self: None + pa1.self: None + pa2.self: None + pa3.self: {'abcSelfPA3': 'abcSelfPA3Val'} + pa4.self: {'abcSelfPA4': 'abcSelfPA4Val'} + sa.self: None + psa1.self: None + psa2.self: None + psa3.self: {'abcSelfPSA3': 'abcSelfPSA3Val'} + psa4.self: {'abcSelfPSA4': 'abcSelfPSA4Val'} + a.name: 'Args' + pa1.name: 'Args' + pa2.name: 'Args' + pa3.name: 'Args' + pa4.name: 'Args' + sa.name: 'SelfArgs' + psa1.name: 'SelfArgs' + psa2.name: 'SelfArgs' + psa3.name: 'SelfArgs' + psa4.name: 'SelfArgs' ' abcdef ! Error detected while processing function RunTest[]..Test: ! line : abcdef abcA ! line : abcB' ['a', 'dup_a'] ['a', 'a'] *************** *** 1046,1054 **** --- 1143,1162 ---- l.xxx = True:(, AttributeError('cannot set attribute xxx',)) > Function >> FunctionConstructor + >>> FunctionConstructor vim.Function("123"):(, ValueError('unnamed function 123 does not exist',)) vim.Function("xxx_non_existent_function_xxx"):(, ValueError('function xxx_non_existent_function_xxx does not exist',)) vim.Function("xxx#non#existent#function#xxx"):NOT FAILED + vim.Function("xxx_non_existent_function_xxx2", args=[]):(, ValueError('function xxx_non_existent_function_xxx2 does not exist',)) + vim.Function("xxx_non_existent_function_xxx3", self={}):(, ValueError('function xxx_non_existent_function_xxx3 does not exist',)) + vim.Function("xxx_non_existent_function_xxx4", args=[], self={}):(, ValueError('function xxx_non_existent_function_xxx4 does not exist',)) + >>> FunctionNew + vim.Function("tr", self="abcFuncSelf"):(, AttributeError('keys',)) + vim.Function("tr", args=427423):(, TypeError('unable to convert int to vim list',)) + vim.Function("tr", self="abcFuncSelf2", args="abcFuncArgs2"):(, AttributeError('keys',)) + vim.Function(self="abcFuncSelf2", args="abcFuncArgs2"):(, AttributeError('keys',)) + vim.Function("tr", "", self="abcFuncSelf2", args="abcFuncArgs2"):(, AttributeError('keys',)) + vim.Function("tr", ""):(, TypeError('function takes exactly 1 argument (2 given)',)) >> FunctionCall >>> Testing StringToChars using f({%s : 1}) f({1 : 1}):(, TypeError('expected bytes() or str() instance, but got int',)) *** ../vim-7.4.1730/src/version.c 2016-04-14 15:13:41.755917075 +0200 --- src/version.c 2016-04-14 15:49:55.705121421 +0200 *************** *** 750,751 **** --- 750,753 ---- { /* Add new patch number below this line */ + /**/ + 1731, /**/ -- ARTHUR: (as the MAN next to him is squashed by a sheep) Knights! Run away! Midst echoing shouts of "run away" the KNIGHTS retreat to cover with the odd cow or goose hitting them still. The KNIGHTS crouch down under cover. "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD /// 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 ///