]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
updated for version 7.3.1062 v7.3.1062
authorBram Moolenaar <Bram@vim.org>
Thu, 30 May 2013 11:05:58 +0000 (13:05 +0200)
committerBram Moolenaar <Bram@vim.org>
Thu, 30 May 2013 11:05:58 +0000 (13:05 +0200)
Problem:    Python: List is not standard.
Solution:   Python patch 21: Add standard methods and fields. (ZyX)

src/if_py_both.h
src/testdir/test86.in
src/testdir/test86.ok
src/testdir/test87.in
src/testdir/test87.ok
src/version.c

index e669d84099a16ab5b85a31b3623b291389a14e1b..bf7110d5ebfb58f4964e3a48a4100796b46563f3 100644 (file)
@@ -1530,12 +1530,14 @@ typedef struct
     pylinkedlist_T     ref;
 } ListObject;
 
+#define NEW_LIST(list) ListNew(&ListType, list)
+
     static PyObject *
-ListNew(list_T *list)
+ListNew(PyTypeObject *subtype, list_T *list)
 {
     ListObject *self;
 
-    self = PyObject_NEW(ListObject, &ListType);
+    self = (ListObject *) subtype->tp_alloc(subtype, 0);
     if (self == NULL)
        return NULL;
     self->list = list;
@@ -1546,44 +1548,116 @@ ListNew(list_T *list)
     return (PyObject *)(self);
 }
 
-    static void
-ListDestructor(ListObject *self)
+    static list_T *
+py_list_alloc()
 {
-    pyll_remove(&self->ref, &lastlist);
-    list_unref(self->list);
+    list_T     *r;
 
-    DESTRUCTOR_FINISH(self);
+    if (!(r = list_alloc()))
+    {
+       PyErr_NoMemory();
+       return NULL;
+    }
+    ++r->lv_refcount;
+
+    return r;
 }
 
     static int
 list_py_concat(list_T *l, PyObject *obj, PyObject *lookup_dict)
 {
-    Py_ssize_t i;
-    Py_ssize_t lsize = PySequence_Size(obj);
-    PyObject   *litem;
+    PyObject   *iterator;
+    PyObject   *item;
     listitem_T *li;
 
-    for(i=0; i<lsize; i++)
+    if (!(iterator = PyObject_GetIter(obj)))
+       return -1;
+
+    while ((item = PyIter_Next(iterator)))
     {
-       li = listitem_alloc();
-       if (li == NULL)
+       if (!(li = listitem_alloc()))
        {
            PyErr_NoMemory();
+           Py_DECREF(item);
+           Py_DECREF(iterator);
            return -1;
        }
        li->li_tv.v_lock = 0;
+       li->li_tv.v_type = VAR_UNKNOWN;
 
-       litem = PySequence_GetItem(obj, i);
-       if (litem == NULL)
-           return -1;
-       if (_ConvertFromPyObject(litem, &li->li_tv, lookup_dict) == -1)
+       if (_ConvertFromPyObject(item, &li->li_tv, lookup_dict) == -1)
+       {
+           Py_DECREF(item);
+           Py_DECREF(iterator);
+           listitem_free(li);
            return -1;
+       }
+
+       Py_DECREF(item);
 
        list_append(l, li);
     }
+
+    Py_DECREF(iterator);
+
+    /* Iterator may have finished due to an exception */
+    if (PyErr_Occurred())
+       return -1;
+
     return 0;
 }
 
+    static PyObject *
+ListConstructor(PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
+{
+    list_T     *list;
+    PyObject   *obj = NULL;
+
+    if (kwargs)
+    {
+       PyErr_SetString(PyExc_TypeError,
+               _("list constructor does not accept keyword arguments"));
+       return NULL;
+    }
+
+    if (!PyArg_ParseTuple(args, "|O", &obj))
+       return NULL;
+
+    if (!(list = py_list_alloc()))
+       return NULL;
+
+    if (obj)
+    {
+       PyObject        *lookup_dict;
+
+       if (!(lookup_dict = PyDict_New()))
+       {
+           list_unref(list);
+           return NULL;
+       }
+
+       if (list_py_concat(list, obj, lookup_dict) == -1)
+       {
+           Py_DECREF(lookup_dict);
+           list_unref(list);
+           return NULL;
+       }
+
+       Py_DECREF(lookup_dict);
+    }
+
+    return ListNew(subtype, list);
+}
+
+    static void
+ListDestructor(ListObject *self)
+{
+    pyll_remove(&self->ref, &lastlist);
+    list_unref(self->list);
+
+    DESTRUCTOR_FINISH(self);
+}
+
     static PyInt
 ListLength(ListObject *self)
 {
@@ -1747,7 +1821,7 @@ ListAssItem(ListObject *self, Py_ssize_t index, PyObject *obj)
        if (list_append_tv(l, &tv) == FAIL)
        {
            clear_tv(&tv);
-           PyErr_SetVim(_("Failed to add item to list"));
+           PyErr_SetVim(_("failed to add item to list"));
            return -1;
        }
     }
@@ -1765,13 +1839,13 @@ ListAssItem(ListObject *self, Py_ssize_t index, PyObject *obj)
 ListAssSlice(ListObject *self, Py_ssize_t first, Py_ssize_t last, PyObject *obj)
 {
     PyInt      size = ListLength(self);
-    Py_ssize_t i;
-    Py_ssize_t lsize;
-    PyObject   *litem;
+    PyObject   *iterator;
+    PyObject   *item;
     listitem_T *li;
     listitem_T *next;
     typval_T   v;
     list_T     *l = self->list;
+    PyInt      i;
 
     if (l->lv_lock)
     {
@@ -1806,21 +1880,18 @@ ListAssSlice(ListObject *self, Py_ssize_t first, Py_ssize_t last, PyObject *obj)
     if (obj == NULL)
        return 0;
 
-    if (!PyList_Check(obj))
-    {
-       PyErr_SetString(PyExc_TypeError, _("can only assign lists to slice"));
+    if (!(iterator = PyObject_GetIter(obj)))
        return -1;
-    }
 
-    lsize = PyList_Size(obj);
-
-    for(i=0; i<lsize; i++)
+    while ((item = PyIter_Next(iterator)))
     {
-       litem = PyList_GetItem(obj, i);
-       if (litem == NULL)
-           return -1;
-       if (ConvertFromPyObject(litem, &v) == -1)
+       if (ConvertFromPyObject(item, &v) == -1)
+       {
+           Py_DECREF(iterator);
+           Py_DECREF(item);
            return -1;
+       }
+       Py_DECREF(item);
        if (list_insert_tv(l, &v, li) == FAIL)
        {
            clear_tv(&v);
@@ -1829,6 +1900,7 @@ ListAssSlice(ListObject *self, Py_ssize_t first, Py_ssize_t last, PyObject *obj)
        }
        clear_tv(&v);
     }
+    Py_DECREF(iterator);
     return 0;
 }
 
@@ -1844,12 +1916,6 @@ ListConcatInPlace(ListObject *self, PyObject *obj)
        return NULL;
     }
 
-    if (!PySequence_Check(obj))
-    {
-       PyErr_SetString(PyExc_TypeError, _("can only concatenate with lists"));
-       return NULL;
-    }
-
     if (!(lookup_dict = PyDict_New()))
        return NULL;
 
@@ -1881,7 +1947,7 @@ ListSetattr(ListObject *self, char *name, PyObject *val)
     if (val == NULL)
     {
        PyErr_SetString(PyExc_AttributeError,
-               _("cannot delete vim.dictionary attributes"));
+               _("cannot delete vim.List attributes"));
        return -1;
     }
 
@@ -4591,21 +4657,6 @@ pymap_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
     return 0;
 }
 
-    static list_T *
-py_list_alloc()
-{
-    list_T     *r;
-
-    if (!(r = list_alloc()))
-    {
-       PyErr_NoMemory();
-       return NULL;
-    }
-    ++r->lv_refcount;
-
-    return r;
-}
-
     static int
 pyseq_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
 {
@@ -4627,65 +4678,6 @@ pyseq_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
     return 0;
 }
 
-    static int
-pyiter_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
-{
-    PyObject   *iterator;
-    PyObject   *item;
-    list_T     *l;
-    listitem_T *li;
-
-    if (!(l = py_list_alloc()))
-       return -1;
-
-    tv->vval.v_list = l;
-    tv->v_type = VAR_LIST;
-
-    if (!(iterator = PyObject_GetIter(obj)))
-    {
-       list_unref(l);
-       return -1;
-    }
-
-    while ((item = PyIter_Next(iterator)))
-    {
-       li = listitem_alloc();
-       if (li == NULL)
-       {
-           list_unref(l);
-           Py_DECREF(iterator);
-           PyErr_NoMemory();
-           return -1;
-       }
-       li->li_tv.v_lock = 0;
-
-       if (_ConvertFromPyObject(item, &li->li_tv, lookup_dict) == -1)
-       {
-           list_unref(l);
-           listitem_free(li);
-           Py_DECREF(item);
-           Py_DECREF(iterator);
-           return -1;
-       }
-
-       list_append(l, li);
-
-       Py_DECREF(item);
-    }
-
-    Py_DECREF(iterator);
-
-    /* Iterator may have finished due to an exception */
-    if (PyErr_Occurred())
-    {
-       list_unref(l);
-       return -1;
-    }
-
-    --l->lv_refcount;
-    return 0;
-}
-
 typedef int (*pytotvfunc)(PyObject *, typval_T *, PyObject *);
 
     static int
@@ -4866,9 +4858,7 @@ _ConvertFromPyObject(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
        tv->vval.v_float = (float_T) PyFloat_AsDouble(obj);
     }
 #endif
-    else if (PyIter_Check(obj))
-       return convert_dl(obj, tv, pyiter_to_tv, lookup_dict);
-    else if (PySequence_Check(obj))
+    else if (PyIter_Check(obj) || PySequence_Check(obj))
        return convert_dl(obj, tv, pyseq_to_tv, lookup_dict);
     else if (PyMapping_Check(obj))
        return convert_dl(obj, tv, pymap_to_tv, lookup_dict);
@@ -4901,7 +4891,7 @@ ConvertToPyObject(typval_T *tv)
            return PyFloat_FromDouble((double) tv->vval.v_float);
 #endif
        case VAR_LIST:
-           return ListNew(tv->vval.v_list);
+           return NEW_LIST(tv->vval.v_list);
        case VAR_DICT:
            return NEW_DICTIONARY(tv->vval.v_dict);
        case VAR_FUNC:
@@ -5096,10 +5086,12 @@ init_structs(void)
     ListType.tp_basicsize = sizeof(ListObject);
     ListType.tp_as_sequence = &ListAsSeq;
     ListType.tp_as_mapping = &ListAsMapping;
-    ListType.tp_flags = Py_TPFLAGS_DEFAULT;
+    ListType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE;
     ListType.tp_doc = "list pushing modifications to vim structure";
     ListType.tp_methods = ListMethods;
     ListType.tp_iter = (getiterfunc)ListIter;
+    ListType.tp_new = (newfunc)ListConstructor;
+    ListType.tp_alloc = (allocfunc)PyType_GenericAlloc;
 #if PY_MAJOR_VERSION >= 3
     ListType.tp_getattro = (getattrofunc)ListGetattro;
     ListType.tp_setattro = (setattrofunc)ListSetattro;
index 28adb709d6e9c941e7d38e939a1240261311f3e9..dfba65de9b6065bebcded185f537f6aa2fad10fa 100644 (file)
@@ -735,6 +735,8 @@ EOF
 :$put =string(pyeval('vim.Dictionary({})'))
 :$put =string(pyeval('vim.Dictionary(a=1)'))
 :$put =string(pyeval('vim.Dictionary(((''a'', 1),))'))
+:$put =string(pyeval('vim.List()'))
+:$put =string(pyeval('vim.List(iter(''abc''))'))
 :"
 :" Test stdout/stderr
 :redir => messages
@@ -752,8 +754,18 @@ class DupDict(vim.Dictionary):
         super(DupDict, self).__setitem__('dup_' + key, value)
 dd = DupDict()
 dd['a'] = 'b'
+
+class DupList(vim.List):
+    def __getitem__(self, idx):
+        return [super(DupList, self).__getitem__(idx)] * 2
+
+dl = DupList()
+dl2 = DupList(iter('abc'))
+dl.extend(dl2[0])
 EOF
 :$put =string(sort(keys(pyeval('dd'))))
+:$put =string(pyeval('dl'))
+:$put =string(pyeval('dl2'))
 :"
 :" Test exceptions
 :fun Exe(e)
index 200af0489fa4e9aeebd938c565031464e6ac930c..b484ec62e2da4d91022aab3f06a6a644edc258f5 100644 (file)
@@ -412,6 +412,8 @@ output:__dir__,__members__,flush,softspace,write,writelines
 {}
 {'a': 1}
 {'a': 1}
+[]
+['a', 'b', 'c']
 '
 abcdef
 line  :
@@ -420,6 +422,8 @@ abc
 line  :
 abc'
 ['a', 'dup_a']
+['a', 'a']
+['a', 'b', 'c']
 (<class 'vim.error'>, error('abc',))
 (<class 'vim.error'>, error('def',))
 (<class 'vim.error'>, error('ghi',))
index 20f616fdb8b5a1f7b819d28ac93d4e123655d89c..82edc8badecd2d96129ccb41edc7d5623f60de1e 100644 (file)
@@ -692,10 +692,12 @@ del name
 del o
 EOF
 :"
-:" Test vim.Dictionary.__new__
+:" Test vim.*.__new__
 :$put =string(py3eval('vim.Dictionary({})'))
 :$put =string(py3eval('vim.Dictionary(a=1)'))
 :$put =string(py3eval('vim.Dictionary(((''a'', 1),))'))
+:$put =string(py3eval('vim.List()'))
+:$put =string(py3eval('vim.List(iter(''abc''))'))
 :"
 :" Test stdout/stderr
 :redir => messages
@@ -713,8 +715,18 @@ class DupDict(vim.Dictionary):
         super(DupDict, self).__setitem__('dup_' + key, value)
 dd = DupDict()
 dd['a'] = 'b'
+
+class DupList(vim.List):
+    def __getitem__(self, idx):
+        return [super(DupList, self).__getitem__(idx)] * 2
+
+dl = DupList()
+dl2 = DupList(iter('abc'))
+dl.extend(dl2[0])
 EOF
 :$put =string(sort(keys(py3eval('dd'))))
+:$put =string(py3eval('dl'))
+:$put =string(py3eval('dl2'))
 :"
 :" Test exceptions
 :fun Exe(e)
index b92d65cfff0c96dc145304a3ca5da2fc7df76519..0945396d6cf6619c7e72e28e04e323191eb005e1 100644 (file)
@@ -401,6 +401,8 @@ output:__dir__,flush,softspace,write,writelines
 {}
 {'a': 1}
 {'a': 1}
+[]
+['a', 'b', 'c']
 '
 abcdef
 line  :
@@ -409,6 +411,8 @@ abc
 line  :
 abc'
 ['a', 'dup_a']
+['a', 'a']
+['a', 'b', 'c']
 (<class 'vim.error'>, error('abc',))
 (<class 'vim.error'>, error('def',))
 (<class 'vim.error'>, error('ghi',))
index 0a20a72a11d2296c7c40c30d4e5c6636eef4489a..fa27fade52d897abe359830a9c2f4ea106a55d8e 100644 (file)
@@ -728,6 +728,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1062,
 /**/
     1061,
 /**/