bpo-35444: Unify and optimize the helper for getting a builtin object. (GH-11047)
This speeds up pickling of some iterators. This fixes also error handling in pickling methods when fail to look up builtin "getattr".
This commit is contained in:
parent
7cf3d8e251
commit
bb86bf4c4e
|
@ -48,10 +48,12 @@ PyAPI_FUNC(PyObject *) PyEval_GetGlobals(void);
|
||||||
PyAPI_FUNC(PyObject *) PyEval_GetLocals(void);
|
PyAPI_FUNC(PyObject *) PyEval_GetLocals(void);
|
||||||
PyAPI_FUNC(struct _frame *) PyEval_GetFrame(void);
|
PyAPI_FUNC(struct _frame *) PyEval_GetFrame(void);
|
||||||
|
|
||||||
|
#ifndef Py_LIMITED_API
|
||||||
|
/* Helper to look up a builtin object */
|
||||||
|
PyAPI_FUNC(PyObject *) _PyEval_GetBuiltinId(_Py_Identifier *);
|
||||||
/* Look at the current frame's (if any) code's co_flags, and turn on
|
/* Look at the current frame's (if any) code's co_flags, and turn on
|
||||||
the corresponding compiler flags in cf->cf_flags. Return 1 if any
|
the corresponding compiler flags in cf->cf_flags. Return 1 if any
|
||||||
flag was set, else return 0. */
|
flag was set, else return 0. */
|
||||||
#ifndef Py_LIMITED_API
|
|
||||||
PyAPI_FUNC(int) PyEval_MergeCompilerFlags(PyCompilerFlags *cf);
|
PyAPI_FUNC(int) PyEval_MergeCompilerFlags(PyCompilerFlags *cf);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -330,9 +330,6 @@ PyAPI_FUNC(int)
|
||||||
_PyObject_GenericSetAttrWithDict(PyObject *, PyObject *,
|
_PyObject_GenericSetAttrWithDict(PyObject *, PyObject *,
|
||||||
PyObject *, PyObject *);
|
PyObject *, PyObject *);
|
||||||
|
|
||||||
/* Helper to look up a builtin object */
|
|
||||||
PyAPI_FUNC(PyObject *) _PyObject_GetBuiltin(const char *name);
|
|
||||||
|
|
||||||
#define PyType_HasFeature(t,f) (((t)->tp_flags & (f)) != 0)
|
#define PyType_HasFeature(t,f) (((t)->tp_flags & (f)) != 0)
|
||||||
|
|
||||||
static inline void _Py_Dealloc_inline(PyObject *op)
|
static inline void _Py_Dealloc_inline(PyObject *op)
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Fixed error handling in pickling methods when fail to look up builtin
|
||||||
|
"getattr". Sped up pickling iterators.
|
|
@ -209,19 +209,15 @@ _Pickle_ClearState(PickleState *st)
|
||||||
static int
|
static int
|
||||||
_Pickle_InitState(PickleState *st)
|
_Pickle_InitState(PickleState *st)
|
||||||
{
|
{
|
||||||
PyObject *builtins;
|
|
||||||
PyObject *copyreg = NULL;
|
PyObject *copyreg = NULL;
|
||||||
PyObject *compat_pickle = NULL;
|
PyObject *compat_pickle = NULL;
|
||||||
PyObject *codecs = NULL;
|
PyObject *codecs = NULL;
|
||||||
PyObject *functools = NULL;
|
PyObject *functools = NULL;
|
||||||
|
_Py_IDENTIFIER(getattr);
|
||||||
|
|
||||||
builtins = PyEval_GetBuiltins();
|
st->getattr = _PyEval_GetBuiltinId(&PyId_getattr);
|
||||||
if (builtins == NULL)
|
|
||||||
goto error;
|
|
||||||
st->getattr = PyDict_GetItemString(builtins, "getattr");
|
|
||||||
if (st->getattr == NULL)
|
if (st->getattr == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
Py_INCREF(st->getattr);
|
|
||||||
|
|
||||||
copyreg = PyImport_ImportModule("copyreg");
|
copyreg = PyImport_ImportModule("copyreg");
|
||||||
if (!copyreg)
|
if (!copyreg)
|
||||||
|
|
|
@ -2943,7 +2943,8 @@ static PyObject *
|
||||||
array_arrayiterator___reduce___impl(arrayiterobject *self)
|
array_arrayiterator___reduce___impl(arrayiterobject *self)
|
||||||
/*[clinic end generated code: output=7898a52e8e66e016 input=a062ea1e9951417a]*/
|
/*[clinic end generated code: output=7898a52e8e66e016 input=a062ea1e9951417a]*/
|
||||||
{
|
{
|
||||||
PyObject *func = _PyObject_GetBuiltin("iter");
|
_Py_IDENTIFIER(iter);
|
||||||
|
PyObject *func = _PyEval_GetBuiltinId(&PyId_iter);
|
||||||
if (self->ao == NULL) {
|
if (self->ao == NULL) {
|
||||||
return Py_BuildValue("N(())", func);
|
return Py_BuildValue("N(())", func);
|
||||||
}
|
}
|
||||||
|
|
|
@ -368,8 +368,9 @@ _grouper_next(_grouperobject *igo)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
_grouper_reduce(_grouperobject *lz, PyObject *Py_UNUSED(ignored))
|
_grouper_reduce(_grouperobject *lz, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
|
_Py_IDENTIFIER(iter);
|
||||||
if (((groupbyobject *)lz->parent)->currgrouper != lz) {
|
if (((groupbyobject *)lz->parent)->currgrouper != lz) {
|
||||||
return Py_BuildValue("N(())", _PyObject_GetBuiltin("iter"));
|
return Py_BuildValue("N(())", _PyEval_GetBuiltinId(&PyId_iter));
|
||||||
}
|
}
|
||||||
return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->parent, lz->tgtkey);
|
return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->parent, lz->tgtkey);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2358,11 +2358,12 @@ PyDoc_STRVAR(length_hint_doc,
|
||||||
static PyObject *
|
static PyObject *
|
||||||
bytearrayiter_reduce(bytesiterobject *it, PyObject *Py_UNUSED(ignored))
|
bytearrayiter_reduce(bytesiterobject *it, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
|
_Py_IDENTIFIER(iter);
|
||||||
if (it->it_seq != NULL) {
|
if (it->it_seq != NULL) {
|
||||||
return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"),
|
return Py_BuildValue("N(O)n", _PyEval_GetBuiltinId(&PyId_iter),
|
||||||
it->it_seq, it->it_index);
|
it->it_seq, it->it_index);
|
||||||
} else {
|
} else {
|
||||||
return Py_BuildValue("N(())", _PyObject_GetBuiltin("iter"));
|
return Py_BuildValue("N(())", _PyEval_GetBuiltinId(&PyId_iter));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3089,11 +3089,12 @@ PyDoc_STRVAR(length_hint_doc,
|
||||||
static PyObject *
|
static PyObject *
|
||||||
striter_reduce(striterobject *it, PyObject *Py_UNUSED(ignored))
|
striter_reduce(striterobject *it, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
|
_Py_IDENTIFIER(iter);
|
||||||
if (it->it_seq != NULL) {
|
if (it->it_seq != NULL) {
|
||||||
return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"),
|
return Py_BuildValue("N(O)n", _PyEval_GetBuiltinId(&PyId_iter),
|
||||||
it->it_seq, it->it_index);
|
it->it_seq, it->it_index);
|
||||||
} else {
|
} else {
|
||||||
return Py_BuildValue("N(())", _PyObject_GetBuiltin("iter"));
|
return Py_BuildValue("N(())", _PyEval_GetBuiltinId(&PyId_iter));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,8 +78,6 @@ method_reduce(PyMethodObject *im, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
PyObject *self = PyMethod_GET_SELF(im);
|
PyObject *self = PyMethod_GET_SELF(im);
|
||||||
PyObject *func = PyMethod_GET_FUNCTION(im);
|
PyObject *func = PyMethod_GET_FUNCTION(im);
|
||||||
PyObject *builtins;
|
|
||||||
PyObject *getattr;
|
|
||||||
PyObject *funcname;
|
PyObject *funcname;
|
||||||
_Py_IDENTIFIER(getattr);
|
_Py_IDENTIFIER(getattr);
|
||||||
|
|
||||||
|
@ -87,9 +85,8 @@ method_reduce(PyMethodObject *im, PyObject *Py_UNUSED(ignored))
|
||||||
if (funcname == NULL) {
|
if (funcname == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
builtins = PyEval_GetBuiltins();
|
return Py_BuildValue("N(ON)", _PyEval_GetBuiltinId(&PyId_getattr),
|
||||||
getattr = _PyDict_GetItemId(builtins, &PyId_getattr);
|
self, funcname);
|
||||||
return Py_BuildValue("O(ON)", getattr, self, funcname);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyMethodDef method_methods[] = {
|
static PyMethodDef method_methods[] = {
|
||||||
|
|
|
@ -452,14 +452,9 @@ descr_get_qualname(PyDescrObject *descr, void *Py_UNUSED(ignored))
|
||||||
static PyObject *
|
static PyObject *
|
||||||
descr_reduce(PyDescrObject *descr, PyObject *Py_UNUSED(ignored))
|
descr_reduce(PyDescrObject *descr, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
PyObject *builtins;
|
|
||||||
PyObject *getattr;
|
|
||||||
_Py_IDENTIFIER(getattr);
|
_Py_IDENTIFIER(getattr);
|
||||||
|
return Py_BuildValue("N(OO)", _PyEval_GetBuiltinId(&PyId_getattr),
|
||||||
builtins = PyEval_GetBuiltins();
|
PyDescr_TYPE(descr), PyDescr_NAME(descr));
|
||||||
getattr = _PyDict_GetItemId(builtins, &PyId_getattr);
|
|
||||||
return Py_BuildValue("O(OO)", getattr, PyDescr_TYPE(descr),
|
|
||||||
PyDescr_NAME(descr));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyMethodDef descr_methods[] = {
|
static PyMethodDef descr_methods[] = {
|
||||||
|
@ -1087,13 +1082,9 @@ wrapper_repr(wrapperobject *wp)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
wrapper_reduce(wrapperobject *wp, PyObject *Py_UNUSED(ignored))
|
wrapper_reduce(wrapperobject *wp, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
PyObject *builtins;
|
|
||||||
PyObject *getattr;
|
|
||||||
_Py_IDENTIFIER(getattr);
|
_Py_IDENTIFIER(getattr);
|
||||||
|
return Py_BuildValue("N(OO)", _PyEval_GetBuiltinId(&PyId_getattr),
|
||||||
builtins = PyEval_GetBuiltins();
|
wp->self, PyDescr_NAME(wp->descr));
|
||||||
getattr = _PyDict_GetItemId(builtins, &PyId_getattr);
|
|
||||||
return Py_BuildValue("O(OO)", getattr, wp->self, PyDescr_NAME(wp->descr));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyMethodDef wrapper_methods[] = {
|
static PyMethodDef wrapper_methods[] = {
|
||||||
|
|
|
@ -3810,6 +3810,7 @@ dict___reversed___impl(PyDictObject *self)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
dictiter_reduce(dictiterobject *di, PyObject *Py_UNUSED(ignored))
|
dictiter_reduce(dictiterobject *di, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
|
_Py_IDENTIFIER(iter);
|
||||||
/* copy the iterator state */
|
/* copy the iterator state */
|
||||||
dictiterobject tmp = *di;
|
dictiterobject tmp = *di;
|
||||||
Py_XINCREF(tmp.di_dict);
|
Py_XINCREF(tmp.di_dict);
|
||||||
|
@ -3819,7 +3820,7 @@ dictiter_reduce(dictiterobject *di, PyObject *Py_UNUSED(ignored))
|
||||||
if (list == NULL) {
|
if (list == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), list);
|
return Py_BuildValue("N(N)", _PyEval_GetBuiltinId(&PyId_iter), list);
|
||||||
}
|
}
|
||||||
|
|
||||||
PyTypeObject PyDictRevIterItem_Type = {
|
PyTypeObject PyDictRevIterItem_Type = {
|
||||||
|
|
|
@ -104,11 +104,12 @@ PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(
|
||||||
static PyObject *
|
static PyObject *
|
||||||
iter_reduce(seqiterobject *it, PyObject *Py_UNUSED(ignored))
|
iter_reduce(seqiterobject *it, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
|
_Py_IDENTIFIER(iter);
|
||||||
if (it->it_seq != NULL)
|
if (it->it_seq != NULL)
|
||||||
return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"),
|
return Py_BuildValue("N(O)n", _PyEval_GetBuiltinId(&PyId_iter),
|
||||||
it->it_seq, it->it_index);
|
it->it_seq, it->it_index);
|
||||||
else
|
else
|
||||||
return Py_BuildValue("N(())", _PyObject_GetBuiltin("iter"));
|
return Py_BuildValue("N(())", _PyEval_GetBuiltinId(&PyId_iter));
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
|
PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
|
||||||
|
@ -243,11 +244,12 @@ calliter_iternext(calliterobject *it)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
calliter_reduce(calliterobject *it, PyObject *Py_UNUSED(ignored))
|
calliter_reduce(calliterobject *it, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
|
_Py_IDENTIFIER(iter);
|
||||||
if (it->it_callable != NULL && it->it_sentinel != NULL)
|
if (it->it_callable != NULL && it->it_sentinel != NULL)
|
||||||
return Py_BuildValue("N(OO)", _PyObject_GetBuiltin("iter"),
|
return Py_BuildValue("N(OO)", _PyEval_GetBuiltinId(&PyId_iter),
|
||||||
it->it_callable, it->it_sentinel);
|
it->it_callable, it->it_sentinel);
|
||||||
else
|
else
|
||||||
return Py_BuildValue("N(())", _PyObject_GetBuiltin("iter"));
|
return Py_BuildValue("N(())", _PyEval_GetBuiltinId(&PyId_iter));
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyMethodDef calliter_methods[] = {
|
static PyMethodDef calliter_methods[] = {
|
||||||
|
|
|
@ -3356,23 +3356,25 @@ listreviter_setstate(listreviterobject *it, PyObject *state)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
listiter_reduce_general(void *_it, int forward)
|
listiter_reduce_general(void *_it, int forward)
|
||||||
{
|
{
|
||||||
|
_Py_IDENTIFIER(iter);
|
||||||
|
_Py_IDENTIFIER(reversed);
|
||||||
PyObject *list;
|
PyObject *list;
|
||||||
|
|
||||||
/* the objects are not the same, index is of different types! */
|
/* the objects are not the same, index is of different types! */
|
||||||
if (forward) {
|
if (forward) {
|
||||||
listiterobject *it = (listiterobject *)_it;
|
listiterobject *it = (listiterobject *)_it;
|
||||||
if (it->it_seq)
|
if (it->it_seq)
|
||||||
return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"),
|
return Py_BuildValue("N(O)n", _PyEval_GetBuiltinId(&PyId_iter),
|
||||||
it->it_seq, it->it_index);
|
it->it_seq, it->it_index);
|
||||||
} else {
|
} else {
|
||||||
listreviterobject *it = (listreviterobject *)_it;
|
listreviterobject *it = (listreviterobject *)_it;
|
||||||
if (it->it_seq)
|
if (it->it_seq)
|
||||||
return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("reversed"),
|
return Py_BuildValue("N(O)n", _PyEval_GetBuiltinId(&PyId_reversed),
|
||||||
it->it_seq, it->it_index);
|
it->it_seq, it->it_index);
|
||||||
}
|
}
|
||||||
/* empty iterator, create an empty list */
|
/* empty iterator, create an empty list */
|
||||||
list = PyList_New(0);
|
list = PyList_New(0);
|
||||||
if (list == NULL)
|
if (list == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), list);
|
return Py_BuildValue("N(N)", _PyEval_GetBuiltinId(&PyId_iter), list);
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,16 +104,13 @@ meth_dealloc(PyCFunctionObject *m)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
meth_reduce(PyCFunctionObject *m, PyObject *Py_UNUSED(ignored))
|
meth_reduce(PyCFunctionObject *m, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
PyObject *builtins;
|
|
||||||
PyObject *getattr;
|
|
||||||
_Py_IDENTIFIER(getattr);
|
_Py_IDENTIFIER(getattr);
|
||||||
|
|
||||||
if (m->m_self == NULL || PyModule_Check(m->m_self))
|
if (m->m_self == NULL || PyModule_Check(m->m_self))
|
||||||
return PyUnicode_FromString(m->m_ml->ml_name);
|
return PyUnicode_FromString(m->m_ml->ml_name);
|
||||||
|
|
||||||
builtins = PyEval_GetBuiltins();
|
return Py_BuildValue("N(Os)", _PyEval_GetBuiltinId(&PyId_getattr),
|
||||||
getattr = _PyDict_GetItemId(builtins, &PyId_getattr);
|
m->m_self, m->m_ml->ml_name);
|
||||||
return Py_BuildValue("O(Os)", getattr, m->m_self, m->m_ml->ml_name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyMethodDef meth_methods[] = {
|
static PyMethodDef meth_methods[] = {
|
||||||
|
|
|
@ -1080,23 +1080,6 @@ PyObject_SelfIter(PyObject *obj)
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convenience function to get a builtin from its name */
|
|
||||||
PyObject *
|
|
||||||
_PyObject_GetBuiltin(const char *name)
|
|
||||||
{
|
|
||||||
PyObject *mod_name, *mod, *attr;
|
|
||||||
|
|
||||||
mod_name = _PyUnicode_FromId(&PyId_builtins); /* borrowed */
|
|
||||||
if (mod_name == NULL)
|
|
||||||
return NULL;
|
|
||||||
mod = PyImport_Import(mod_name);
|
|
||||||
if (mod == NULL)
|
|
||||||
return NULL;
|
|
||||||
attr = PyObject_GetAttrString(mod, name);
|
|
||||||
Py_DECREF(mod);
|
|
||||||
return attr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Helper used when the __next__ method is removed from a type:
|
/* Helper used when the __next__ method is removed from a type:
|
||||||
tp_iternext is never NULL and can be safely called without checking
|
tp_iternext is never NULL and can be safely called without checking
|
||||||
on every iteration.
|
on every iteration.
|
||||||
|
|
|
@ -1806,6 +1806,7 @@ PyDoc_STRVAR(reduce_doc, "Return state information for pickling");
|
||||||
static PyObject *
|
static PyObject *
|
||||||
odictiter_reduce(odictiterobject *di, PyObject *Py_UNUSED(ignored))
|
odictiter_reduce(odictiterobject *di, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
|
_Py_IDENTIFIER(iter);
|
||||||
/* copy the iterator state */
|
/* copy the iterator state */
|
||||||
odictiterobject tmp = *di;
|
odictiterobject tmp = *di;
|
||||||
Py_XINCREF(tmp.di_odict);
|
Py_XINCREF(tmp.di_odict);
|
||||||
|
@ -1818,7 +1819,7 @@ odictiter_reduce(odictiterobject *di, PyObject *Py_UNUSED(ignored))
|
||||||
if (list == NULL) {
|
if (list == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), list);
|
return Py_BuildValue("N(N)", _PyEval_GetBuiltinId(&PyId_iter), list);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyMethodDef odictiter_methods[] = {
|
static PyMethodDef odictiter_methods[] = {
|
||||||
|
|
|
@ -742,6 +742,7 @@ PyDoc_STRVAR(length_hint_doc,
|
||||||
static PyObject *
|
static PyObject *
|
||||||
rangeiter_reduce(rangeiterobject *r, PyObject *Py_UNUSED(ignored))
|
rangeiter_reduce(rangeiterobject *r, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
|
_Py_IDENTIFIER(iter);
|
||||||
PyObject *start=NULL, *stop=NULL, *step=NULL;
|
PyObject *start=NULL, *stop=NULL, *step=NULL;
|
||||||
PyObject *range;
|
PyObject *range;
|
||||||
|
|
||||||
|
@ -760,7 +761,8 @@ rangeiter_reduce(rangeiterobject *r, PyObject *Py_UNUSED(ignored))
|
||||||
if (range == NULL)
|
if (range == NULL)
|
||||||
goto err;
|
goto err;
|
||||||
/* return the result */
|
/* return the result */
|
||||||
return Py_BuildValue("N(N)i", _PyObject_GetBuiltin("iter"), range, r->index);
|
return Py_BuildValue("N(N)i", _PyEval_GetBuiltinId(&PyId_iter),
|
||||||
|
range, r->index);
|
||||||
err:
|
err:
|
||||||
Py_XDECREF(start);
|
Py_XDECREF(start);
|
||||||
Py_XDECREF(stop);
|
Py_XDECREF(stop);
|
||||||
|
@ -898,6 +900,7 @@ longrangeiter_len(longrangeiterobject *r, PyObject *no_args)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
longrangeiter_reduce(longrangeiterobject *r, PyObject *Py_UNUSED(ignored))
|
longrangeiter_reduce(longrangeiterobject *r, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
|
_Py_IDENTIFIER(iter);
|
||||||
PyObject *product, *stop=NULL;
|
PyObject *product, *stop=NULL;
|
||||||
PyObject *range;
|
PyObject *range;
|
||||||
|
|
||||||
|
@ -921,7 +924,8 @@ longrangeiter_reduce(longrangeiterobject *r, PyObject *Py_UNUSED(ignored))
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return the result */
|
/* return the result */
|
||||||
return Py_BuildValue("N(N)O", _PyObject_GetBuiltin("iter"), range, r->index);
|
return Py_BuildValue("N(N)O", _PyEval_GetBuiltinId(&PyId_iter),
|
||||||
|
range, r->index);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
|
|
@ -842,6 +842,7 @@ static PyObject *setiter_iternext(setiterobject *si);
|
||||||
static PyObject *
|
static PyObject *
|
||||||
setiter_reduce(setiterobject *si, PyObject *Py_UNUSED(ignored))
|
setiter_reduce(setiterobject *si, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
|
_Py_IDENTIFIER(iter);
|
||||||
/* copy the iterator state */
|
/* copy the iterator state */
|
||||||
setiterobject tmp = *si;
|
setiterobject tmp = *si;
|
||||||
Py_XINCREF(tmp.si_set);
|
Py_XINCREF(tmp.si_set);
|
||||||
|
@ -852,7 +853,7 @@ setiter_reduce(setiterobject *si, PyObject *Py_UNUSED(ignored))
|
||||||
if (list == NULL) {
|
if (list == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), list);
|
return Py_BuildValue("N(N)", _PyEval_GetBuiltinId(&PyId_iter), list);
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
|
PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
|
||||||
|
|
|
@ -1024,11 +1024,12 @@ PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(
|
||||||
static PyObject *
|
static PyObject *
|
||||||
tupleiter_reduce(tupleiterobject *it, PyObject *Py_UNUSED(ignored))
|
tupleiter_reduce(tupleiterobject *it, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
|
_Py_IDENTIFIER(iter);
|
||||||
if (it->it_seq)
|
if (it->it_seq)
|
||||||
return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"),
|
return Py_BuildValue("N(O)n", _PyEval_GetBuiltinId(&PyId_iter),
|
||||||
it->it_seq, it->it_index);
|
it->it_seq, it->it_index);
|
||||||
else
|
else
|
||||||
return Py_BuildValue("N(())", _PyObject_GetBuiltin("iter"));
|
return Py_BuildValue("N(())", _PyEval_GetBuiltinId(&PyId_iter));
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
|
|
@ -15444,14 +15444,15 @@ PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(
|
||||||
static PyObject *
|
static PyObject *
|
||||||
unicodeiter_reduce(unicodeiterobject *it, PyObject *Py_UNUSED(ignored))
|
unicodeiter_reduce(unicodeiterobject *it, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
|
_Py_IDENTIFIER(iter);
|
||||||
if (it->it_seq != NULL) {
|
if (it->it_seq != NULL) {
|
||||||
return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"),
|
return Py_BuildValue("N(O)n", _PyEval_GetBuiltinId(&PyId_iter),
|
||||||
it->it_seq, it->it_index);
|
it->it_seq, it->it_index);
|
||||||
} else {
|
} else {
|
||||||
PyObject *u = (PyObject *)_PyUnicode_New(0);
|
PyObject *u = (PyObject *)_PyUnicode_New(0);
|
||||||
if (u == NULL)
|
if (u == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), u);
|
return Py_BuildValue("N(N)", _PyEval_GetBuiltinId(&PyId_iter), u);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4437,6 +4437,20 @@ PyEval_GetBuiltins(void)
|
||||||
return current_frame->f_builtins;
|
return current_frame->f_builtins;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Convenience function to get a builtin from its name */
|
||||||
|
PyObject *
|
||||||
|
_PyEval_GetBuiltinId(_Py_Identifier *name)
|
||||||
|
{
|
||||||
|
PyObject *attr = _PyDict_GetItemIdWithError(PyEval_GetBuiltins(), name);
|
||||||
|
if (attr) {
|
||||||
|
Py_INCREF(attr);
|
||||||
|
}
|
||||||
|
else if (!PyErr_Occurred()) {
|
||||||
|
PyErr_SetObject(PyExc_AttributeError, _PyUnicode_FromId(name));
|
||||||
|
}
|
||||||
|
return attr;
|
||||||
|
}
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyEval_GetLocals(void)
|
PyEval_GetLocals(void)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue