Ignore:
Timestamp:
Mar 19, 2014, 11:31:01 PM (11 years ago)
Author:
dmik
Message:

python: Merge vendor 2.7.6 to trunk.

Location:
python/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • python/trunk

  • python/trunk/Modules/_functoolsmodule.c

    r2 r391  
    33#include "structmember.h"
    44
    5 /* _functools module written and maintained 
     5/* _functools module written and maintained
    66   by Hye-Shik Chang <perky@FreeBSD.org>
    77   with adaptations by Raymond Hettinger <python@rcn.com>
     
    1515functools_reduce(PyObject *self, PyObject *args)
    1616{
    17         PyObject *seq, *func, *result = NULL, *it;
    18 
    19         if (!PyArg_UnpackTuple(args, "reduce", 2, 3, &func, &seq, &result))
    20                 return NULL;
    21         if (result != NULL)
    22                 Py_INCREF(result);
    23 
    24         it = PyObject_GetIter(seq);
    25         if (it == NULL) {
    26                 PyErr_SetString(PyExc_TypeError,
    27                     "reduce() arg 2 must support iteration");
    28                 Py_XDECREF(result);
    29                 return NULL;
    30         }
    31 
    32         if ((args = PyTuple_New(2)) == NULL)
    33                 goto Fail;
    34 
    35         for (;;) {
    36                 PyObject *op2;
    37 
    38                 if (args->ob_refcnt > 1) {
    39                         Py_DECREF(args);
    40                         if ((args = PyTuple_New(2)) == NULL)
    41                                 goto Fail;
    42                 }
    43 
    44                 op2 = PyIter_Next(it);
    45                 if (op2 == NULL) {
    46                         if (PyErr_Occurred())
    47                                 goto Fail;
    48                         break;
    49                 }
    50 
    51                 if (result == NULL)
    52                         result = op2;
    53                 else {
    54                         PyTuple_SetItem(args, 0, result);
    55                         PyTuple_SetItem(args, 1, op2);
    56                         if ((result = PyEval_CallObject(func, args)) == NULL)
    57                                 goto Fail;
    58                 }
    59         }
    60 
    61         Py_DECREF(args);
    62 
    63         if (result == NULL)
    64                 PyErr_SetString(PyExc_TypeError,
    65                            "reduce() of empty sequence with no initial value");
    66 
    67         Py_DECREF(it);
    68         return result;
     17    PyObject *seq, *func, *result = NULL, *it;
     18
     19    if (!PyArg_UnpackTuple(args, "reduce", 2, 3, &func, &seq, &result))
     20        return NULL;
     21    if (result != NULL)
     22        Py_INCREF(result);
     23
     24    it = PyObject_GetIter(seq);
     25    if (it == NULL) {
     26        PyErr_SetString(PyExc_TypeError,
     27            "reduce() arg 2 must support iteration");
     28        Py_XDECREF(result);
     29        return NULL;
     30    }
     31
     32    if ((args = PyTuple_New(2)) == NULL)
     33        goto Fail;
     34
     35    for (;;) {
     36        PyObject *op2;
     37
     38        if (args->ob_refcnt > 1) {
     39            Py_DECREF(args);
     40            if ((args = PyTuple_New(2)) == NULL)
     41                goto Fail;
     42        }
     43
     44        op2 = PyIter_Next(it);
     45        if (op2 == NULL) {
     46            if (PyErr_Occurred())
     47                goto Fail;
     48            break;
     49        }
     50
     51        if (result == NULL)
     52            result = op2;
     53        else {
     54            PyTuple_SetItem(args, 0, result);
     55            PyTuple_SetItem(args, 1, op2);
     56            if ((result = PyEval_CallObject(func, args)) == NULL)
     57                goto Fail;
     58        }
     59    }
     60
     61    Py_DECREF(args);
     62
     63    if (result == NULL)
     64        PyErr_SetString(PyExc_TypeError,
     65                   "reduce() of empty sequence with no initial value");
     66
     67    Py_DECREF(it);
     68    return result;
    6969
    7070Fail:
    71         Py_XDECREF(args);
    72         Py_XDECREF(result);
    73         Py_DECREF(it);
    74         return NULL;
     71    Py_XDECREF(args);
     72    Py_XDECREF(result);
     73    Py_DECREF(it);
     74    return NULL;
    7575}
    7676
     
    9191
    9292typedef struct {
    93         PyObject_HEAD
    94         PyObject *fn;
    95         PyObject *args;
    96         PyObject *kw;
    97         PyObject *dict;
    98         PyObject *weakreflist; /* List of weak references */
     93    PyObject_HEAD
     94    PyObject *fn;
     95    PyObject *args;
     96    PyObject *kw;
     97    PyObject *dict;
     98    PyObject *weakreflist; /* List of weak references */
    9999} partialobject;
    100100
     
    104104partial_new(PyTypeObject *type, PyObject *args, PyObject *kw)
    105105{
    106         PyObject *func;
    107         partialobject *pto;
    108 
    109         if (PyTuple_GET_SIZE(args) < 1) {
    110                 PyErr_SetString(PyExc_TypeError,
    111                                 "type 'partial' takes at least one argument");
    112                 return NULL;
    113         }
    114 
    115         func = PyTuple_GET_ITEM(args, 0);
    116         if (!PyCallable_Check(func)) {
    117                 PyErr_SetString(PyExc_TypeError,
    118                                 "the first argument must be callable");
    119                 return NULL;
    120         }
    121 
    122         /* create partialobject structure */
    123         pto = (partialobject *)type->tp_alloc(type, 0);
    124         if (pto == NULL)
    125                 return NULL;
    126 
    127         pto->fn = func;
    128         Py_INCREF(func);
    129         pto->args = PyTuple_GetSlice(args, 1, PY_SSIZE_T_MAX);
    130         if (pto->args == NULL) {
    131                 pto->kw = NULL;
    132                 Py_DECREF(pto);
    133                 return NULL;
    134         }
    135         if (kw != NULL) {
    136                 pto->kw = PyDict_Copy(kw);
    137                 if (pto->kw == NULL) {
    138                         Py_DECREF(pto);
    139                         return NULL;
    140                 }
    141         } else {
    142                 pto->kw = Py_None;
    143                 Py_INCREF(Py_None);
    144         }
    145 
    146         pto->weakreflist = NULL;
    147         pto->dict = NULL;
    148 
    149         return (PyObject *)pto;
     106    PyObject *func;
     107    partialobject *pto;
     108
     109    if (PyTuple_GET_SIZE(args) < 1) {
     110        PyErr_SetString(PyExc_TypeError,
     111                        "type 'partial' takes at least one argument");
     112        return NULL;
     113    }
     114
     115    func = PyTuple_GET_ITEM(args, 0);
     116    if (!PyCallable_Check(func)) {
     117        PyErr_SetString(PyExc_TypeError,
     118                        "the first argument must be callable");
     119        return NULL;
     120    }
     121
     122    /* create partialobject structure */
     123    pto = (partialobject *)type->tp_alloc(type, 0);
     124    if (pto == NULL)
     125        return NULL;
     126
     127    pto->fn = func;
     128    Py_INCREF(func);
     129    pto->args = PyTuple_GetSlice(args, 1, PY_SSIZE_T_MAX);
     130    if (pto->args == NULL) {
     131        pto->kw = NULL;
     132        Py_DECREF(pto);
     133        return NULL;
     134    }
     135    if (kw != NULL) {
     136        pto->kw = PyDict_Copy(kw);
     137        if (pto->kw == NULL) {
     138            Py_DECREF(pto);
     139            return NULL;
     140        }
     141    } else {
     142        pto->kw = Py_None;
     143        Py_INCREF(Py_None);
     144    }
     145
     146    pto->weakreflist = NULL;
     147    pto->dict = NULL;
     148
     149    return (PyObject *)pto;
    150150}
    151151
     
    153153partial_dealloc(partialobject *pto)
    154154{
    155         PyObject_GC_UnTrack(pto);
    156         if (pto->weakreflist != NULL)
    157                 PyObject_ClearWeakRefs((PyObject *) pto);
    158         Py_XDECREF(pto->fn);
    159         Py_XDECREF(pto->args);
    160         Py_XDECREF(pto->kw);
    161         Py_XDECREF(pto->dict);
    162         Py_TYPE(pto)->tp_free(pto);
     155    PyObject_GC_UnTrack(pto);
     156    if (pto->weakreflist != NULL)
     157        PyObject_ClearWeakRefs((PyObject *) pto);
     158    Py_XDECREF(pto->fn);
     159    Py_XDECREF(pto->args);
     160    Py_XDECREF(pto->kw);
     161    Py_XDECREF(pto->dict);
     162    Py_TYPE(pto)->tp_free(pto);
    163163}
    164164
     
    166166partial_call(partialobject *pto, PyObject *args, PyObject *kw)
    167167{
    168         PyObject *ret;
    169         PyObject *argappl = NULL, *kwappl = NULL;
    170 
    171         assert (PyCallable_Check(pto->fn));
    172         assert (PyTuple_Check(pto->args));
    173         assert (pto->kw == Py_None  ||  PyDict_Check(pto->kw));
    174 
    175         if (PyTuple_GET_SIZE(pto->args) == 0) {
    176                 argappl = args;
    177                 Py_INCREF(args);
    178         } else if (PyTuple_GET_SIZE(args) == 0) {
    179                 argappl = pto->args;
    180                 Py_INCREF(pto->args);
    181         } else {
    182                 argappl = PySequence_Concat(pto->args, args);
    183                 if (argappl == NULL)
    184                         return NULL;
    185         }
    186 
    187         if (pto->kw == Py_None) {
    188                 kwappl = kw;
    189                 Py_XINCREF(kw);
    190         } else {
    191                 kwappl = PyDict_Copy(pto->kw);
    192                 if (kwappl == NULL) {
    193                         Py_DECREF(argappl);
    194                         return NULL;
    195                 }
    196                 if (kw != NULL) {
    197                         if (PyDict_Merge(kwappl, kw, 1) != 0) {
    198                                 Py_DECREF(argappl);
    199                                 Py_DECREF(kwappl);
    200                                 return NULL;
    201                         }
    202                 }
    203         }
    204 
    205         ret = PyObject_Call(pto->fn, argappl, kwappl);
    206         Py_DECREF(argappl);
    207         Py_XDECREF(kwappl);
    208         return ret;
     168    PyObject *ret;
     169    PyObject *argappl = NULL, *kwappl = NULL;
     170
     171    assert (PyCallable_Check(pto->fn));
     172    assert (PyTuple_Check(pto->args));
     173    assert (pto->kw == Py_None  ||  PyDict_Check(pto->kw));
     174
     175    if (PyTuple_GET_SIZE(pto->args) == 0) {
     176        argappl = args;
     177        Py_INCREF(args);
     178    } else if (PyTuple_GET_SIZE(args) == 0) {
     179        argappl = pto->args;
     180        Py_INCREF(pto->args);
     181    } else {
     182        argappl = PySequence_Concat(pto->args, args);
     183        if (argappl == NULL)
     184            return NULL;
     185    }
     186
     187    if (pto->kw == Py_None) {
     188        kwappl = kw;
     189        Py_XINCREF(kw);
     190    } else {
     191        kwappl = PyDict_Copy(pto->kw);
     192        if (kwappl == NULL) {
     193            Py_DECREF(argappl);
     194            return NULL;
     195        }
     196        if (kw != NULL) {
     197            if (PyDict_Merge(kwappl, kw, 1) != 0) {
     198                Py_DECREF(argappl);
     199                Py_DECREF(kwappl);
     200                return NULL;
     201            }
     202        }
     203    }
     204
     205    ret = PyObject_Call(pto->fn, argappl, kwappl);
     206    Py_DECREF(argappl);
     207    Py_XDECREF(kwappl);
     208    return ret;
    209209}
    210210
     
    212212partial_traverse(partialobject *pto, visitproc visit, void *arg)
    213213{
    214         Py_VISIT(pto->fn);
    215         Py_VISIT(pto->args);
    216         Py_VISIT(pto->kw);
    217         Py_VISIT(pto->dict);
    218         return 0;
     214    Py_VISIT(pto->fn);
     215    Py_VISIT(pto->args);
     216    Py_VISIT(pto->kw);
     217    Py_VISIT(pto->dict);
     218    return 0;
    219219}
    220220
    221221PyDoc_STRVAR(partial_doc,
    222222"partial(func, *args, **keywords) - new function with partial application\n\
    223         of the given arguments and keywords.\n");
     223    of the given arguments and keywords.\n");
    224224
    225225#define OFF(x) offsetof(partialobject, x)
    226226static PyMemberDef partial_memberlist[] = {
    227         {"func",        T_OBJECT,       OFF(fn),        READONLY,
    228         "function object to use in future partial calls"},
    229         {"args",        T_OBJECT,       OFF(args),      READONLY,
    230         "tuple of arguments to future partial calls"},
    231         {"keywords",    T_OBJECT,       OFF(kw),        READONLY,
    232         "dictionary of keyword arguments to future partial calls"},
    233         {NULL}  /* Sentinel */
     227    {"func",            T_OBJECT,       OFF(fn),        READONLY,
     228    "function object to use in future partial calls"},
     229    {"args",            T_OBJECT,       OFF(args),      READONLY,
     230    "tuple of arguments to future partial calls"},
     231    {"keywords",        T_OBJECT,       OFF(kw),        READONLY,
     232    "dictionary of keyword arguments to future partial calls"},
     233    {NULL}  /* Sentinel */
    234234};
    235235
     
    237237partial_get_dict(partialobject *pto)
    238238{
    239         if (pto->dict == NULL) {
    240                 pto->dict = PyDict_New();
    241                 if (pto->dict == NULL)
    242                         return NULL;
    243         }
    244         Py_INCREF(pto->dict);
    245         return pto->dict;
     239    if (pto->dict == NULL) {
     240        pto->dict = PyDict_New();
     241        if (pto->dict == NULL)
     242            return NULL;
     243    }
     244    Py_INCREF(pto->dict);
     245    return pto->dict;
    246246}
    247247
     
    249249partial_set_dict(partialobject *pto, PyObject *value)
    250250{
    251         PyObject *tmp;
    252 
    253         /* It is illegal to del p.__dict__ */
    254         if (value == NULL) {
    255                 PyErr_SetString(PyExc_TypeError,
    256                                 "a partial object's dictionary may not be deleted");
    257                 return -1;
    258         }
    259         /* Can only set __dict__ to a dictionary */
    260         if (!PyDict_Check(value)) {
    261                 PyErr_SetString(PyExc_TypeError,
    262                                 "setting partial object's dictionary to a non-dict");
    263                 return -1;
    264         }
    265         tmp = pto->dict;
    266         Py_INCREF(value);
    267         pto->dict = value;
    268         Py_XDECREF(tmp);
    269         return 0;
     251    PyObject *tmp;
     252
     253    /* It is illegal to del p.__dict__ */
     254    if (value == NULL) {
     255        PyErr_SetString(PyExc_TypeError,
     256                        "a partial object's dictionary may not be deleted");
     257        return -1;
     258    }
     259    /* Can only set __dict__ to a dictionary */
     260    if (!PyDict_Check(value)) {
     261        PyErr_SetString(PyExc_TypeError,
     262                        "setting partial object's dictionary to a non-dict");
     263        return -1;
     264    }
     265    tmp = pto->dict;
     266    Py_INCREF(value);
     267    pto->dict = value;
     268    Py_XDECREF(tmp);
     269    return 0;
    270270}
    271271
    272272static PyGetSetDef partial_getsetlist[] = {
    273         {"__dict__", (getter)partial_get_dict, (setter)partial_set_dict},
    274         {NULL} /* Sentinel */
     273    {"__dict__", (getter)partial_get_dict, (setter)partial_set_dict},
     274    {NULL} /* Sentinel */
    275275};
    276276
     277/* Pickle strategy:
     278   __reduce__ by itself doesn't support getting kwargs in the unpickle
     279   operation so we define a __setstate__ that replaces all the information
     280   about the partial.  If we only replaced part of it someone would use
     281   it as a hook to do strange things.
     282 */
     283
     284PyObject *
     285partial_reduce(partialobject *pto, PyObject *unused)
     286{
     287    return Py_BuildValue("O(O)(OOOO)", Py_TYPE(pto), pto->fn, pto->fn,
     288                         pto->args, pto->kw,
     289                         pto->dict ? pto->dict : Py_None);
     290}
     291
     292PyObject *
     293partial_setstate(partialobject *pto, PyObject *state)
     294{
     295    PyObject *fn, *fnargs, *kw, *dict;
     296    if (!PyArg_ParseTuple(state, "OOOO",
     297                          &fn, &fnargs, &kw, &dict))
     298        return NULL;
     299    Py_XDECREF(pto->fn);
     300    Py_XDECREF(pto->args);
     301    Py_XDECREF(pto->kw);
     302    Py_XDECREF(pto->dict);
     303    pto->fn = fn;
     304    pto->args = fnargs;
     305    pto->kw = kw;
     306    if (dict != Py_None) {
     307      pto->dict = dict;
     308      Py_INCREF(dict);
     309    } else {
     310      pto->dict = NULL;
     311    }
     312    Py_INCREF(fn);
     313    Py_INCREF(fnargs);
     314    Py_INCREF(kw);
     315    Py_RETURN_NONE;
     316}
     317
     318static PyMethodDef partial_methods[] = {
     319    {"__reduce__", (PyCFunction)partial_reduce, METH_NOARGS},
     320    {"__setstate__", (PyCFunction)partial_setstate, METH_O},
     321    {NULL,              NULL}           /* sentinel */
     322};
     323
    277324static PyTypeObject partial_type = {
    278         PyVarObject_HEAD_INIT(NULL, 0)
    279         "functools.partial",            /* tp_name */
    280         sizeof(partialobject),          /* tp_basicsize */
    281         0,                              /* tp_itemsize */
    282         /* methods */
    283         (destructor)partial_dealloc,    /* tp_dealloc */
    284         0,                              /* tp_print */
    285         0,                              /* tp_getattr */
    286         0,                              /* tp_setattr */
    287         0,                              /* tp_compare */
    288         0,                              /* tp_repr */
    289         0,                              /* tp_as_number */
    290         0,                              /* tp_as_sequence */
    291         0,                              /* tp_as_mapping */
    292         0,                              /* tp_hash */
    293         (ternaryfunc)partial_call,      /* tp_call */
    294         0,                              /* tp_str */
    295         PyObject_GenericGetAttr,        /* tp_getattro */
    296         PyObject_GenericSetAttr,        /* tp_setattro */
    297         0,                              /* tp_as_buffer */
    298         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
    299                 Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
    300         partial_doc,                    /* tp_doc */
    301         (traverseproc)partial_traverse, /* tp_traverse */
    302         0,                              /* tp_clear */
    303         0,                              /* tp_richcompare */
    304         offsetof(partialobject, weakreflist),   /* tp_weaklistoffset */
    305         0,                              /* tp_iter */
    306         0,                              /* tp_iternext */
    307         0,                              /* tp_methods */
    308         partial_memberlist,             /* tp_members */
    309         partial_getsetlist,             /* tp_getset */
    310         0,                              /* tp_base */
    311         0,                              /* tp_dict */
    312         0,                              /* tp_descr_get */
    313         0,                              /* tp_descr_set */
    314         offsetof(partialobject, dict),  /* tp_dictoffset */
    315         0,                              /* tp_init */
    316         0,                              /* tp_alloc */
    317         partial_new,                    /* tp_new */
    318         PyObject_GC_Del,                /* tp_free */
     325    PyVarObject_HEAD_INIT(NULL, 0)
     326    "functools.partial",                /* tp_name */
     327    sizeof(partialobject),              /* tp_basicsize */
     328    0,                                  /* tp_itemsize */
     329    /* methods */
     330    (destructor)partial_dealloc,        /* tp_dealloc */
     331    0,                                  /* tp_print */
     332    0,                                  /* tp_getattr */
     333    0,                                  /* tp_setattr */
     334    0,                                  /* tp_compare */
     335    0,                                  /* tp_repr */
     336    0,                                  /* tp_as_number */
     337    0,                                  /* tp_as_sequence */
     338    0,                                  /* tp_as_mapping */
     339    0,                                  /* tp_hash */
     340    (ternaryfunc)partial_call,          /* tp_call */
     341    0,                                  /* tp_str */
     342    PyObject_GenericGetAttr,            /* tp_getattro */
     343    PyObject_GenericSetAttr,            /* tp_setattro */
     344    0,                                  /* tp_as_buffer */
     345    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
     346        Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS,         /* tp_flags */
     347    partial_doc,                        /* tp_doc */
     348    (traverseproc)partial_traverse,     /* tp_traverse */
     349    0,                                  /* tp_clear */
     350    0,                                  /* tp_richcompare */
     351    offsetof(partialobject, weakreflist),       /* tp_weaklistoffset */
     352    0,                                  /* tp_iter */
     353    0,                                  /* tp_iternext */
     354    partial_methods,                    /* tp_methods */
     355    partial_memberlist,                 /* tp_members */
     356    partial_getsetlist,                 /* tp_getset */
     357    0,                                  /* tp_base */
     358    0,                                  /* tp_dict */
     359    0,                                  /* tp_descr_get */
     360    0,                                  /* tp_descr_set */
     361    offsetof(partialobject, dict),      /* tp_dictoffset */
     362    0,                                  /* tp_init */
     363    0,                                  /* tp_alloc */
     364    partial_new,                        /* tp_new */
     365    PyObject_GC_Del,                    /* tp_free */
    319366};
    320367
     
    326373
    327374static PyMethodDef module_methods[] = {
    328         {"reduce",      functools_reduce,     METH_VARARGS, reduce_doc},
    329         {NULL,          NULL}           /* sentinel */
     375    {"reduce",          functools_reduce,     METH_VARARGS, reduce_doc},
     376    {NULL,              NULL}           /* sentinel */
    330377};
    331378
     
    333380init_functools(void)
    334381{
    335         int i;
    336         PyObject *m;
    337         char *name;
    338         PyTypeObject *typelist[] = {
    339                 &partial_type,
    340                 NULL
    341         };
    342 
    343         m = Py_InitModule3("_functools", module_methods, module_doc);
    344         if (m == NULL)
    345                 return;
    346 
    347         for (i=0 ; typelist[i] != NULL ; i++) {
    348                 if (PyType_Ready(typelist[i]) < 0)
    349                         return;
    350                 name = strchr(typelist[i]->tp_name, '.');
    351                 assert (name != NULL);
    352                 Py_INCREF(typelist[i]);
    353                 PyModule_AddObject(m, name+1, (PyObject *)typelist[i]);
    354         }
    355 }
     382    int i;
     383    PyObject *m;
     384    char *name;
     385    PyTypeObject *typelist[] = {
     386        &partial_type,
     387        NULL
     388    };
     389
     390    m = Py_InitModule3("_functools", module_methods, module_doc);
     391    if (m == NULL)
     392        return;
     393
     394    for (i=0 ; typelist[i] != NULL ; i++) {
     395        if (PyType_Ready(typelist[i]) < 0)
     396            return;
     397        name = strchr(typelist[i]->tp_name, '.');
     398        assert (name != NULL);
     399        Py_INCREF(typelist[i]);
     400        PyModule_AddObject(m, name+1, (PyObject *)typelist[i]);
     401    }
     402}
Note: See TracChangeset for help on using the changeset viewer.