From ce798520778e9cb41adfdc4f0a3cb5085a0b11be Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sun, 22 Jan 2012 11:24:29 -0500 Subject: [PATCH] use the static identifier api for looking up special methods I had to move the static identifier code from unicodeobject.h to object.h in order for this to work. --- Include/object.h | 31 ++++++- Include/unicodeobject.h | 29 ------- Modules/mathmodule.c | 12 +-- Objects/abstract.c | 16 ++-- Objects/complexobject.c | 4 +- Objects/dictobject.c | 6 +- Objects/enumobject.c | 4 +- Objects/object.c | 8 +- Objects/typeobject.c | 186 +++++++++++++++++++--------------------- Python/ceval.c | 15 ++-- Python/sysmodule.c | 6 +- 11 files changed, 153 insertions(+), 164 deletions(-) diff --git a/Include/object.h b/Include/object.h index 16662714b7d..6907a4464c2 100644 --- a/Include/object.h +++ b/Include/object.h @@ -117,6 +117,35 @@ typedef struct { #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) #define Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size) +/********************* String Literals ****************************************/ +/* This structure helps managing static strings. The basic usage goes like this: + Instead of doing + + r = PyObject_CallMethod(o, "foo", "args", ...); + + do + + _Py_IDENTIFIER(foo); + ... + r = _PyObject_CallMethodId(o, &PyId_foo, "args", ...); + + PyId_foo is a static variable, either on block level or file level. On first + usage, the string "foo" is interned, and the structures are linked. On interpreter + shutdown, all strings are released (through _PyUnicode_ClearStaticStrings). + + Alternatively, _Py_static_string allows to choose the variable name. + _PyUnicode_FromId returns a borrowed reference to the interned string. + _PyObject_{Get,Set,Has}AttrId are __getattr__ versions using _Py_Identifier*. +*/ +typedef struct _Py_Identifier { + struct _Py_Identifier *next; + const char* string; + PyObject *object; +} _Py_Identifier; + +#define _Py_static_string(varname, value) static _Py_Identifier varname = { 0, value, 0 } +#define _Py_IDENTIFIER(varname) _Py_static_string(PyId_##varname, #varname) + /* Type objects contain a string containing the type name (to help somewhat in debugging), the allocation parameters (see PyObject_New() and @@ -448,7 +477,7 @@ PyAPI_FUNC(PyObject *) PyType_GenericNew(PyTypeObject *, PyObject *, PyObject *); #ifndef Py_LIMITED_API PyAPI_FUNC(PyObject *) _PyType_Lookup(PyTypeObject *, PyObject *); -PyAPI_FUNC(PyObject *) _PyObject_LookupSpecial(PyObject *, char *, PyObject **); +PyAPI_FUNC(PyObject *) _PyObject_LookupSpecial(PyObject *, _Py_Identifier *); PyAPI_FUNC(PyTypeObject *) _PyType_CalculateMetaclass(PyTypeObject *, PyObject *); #endif PyAPI_FUNC(unsigned int) PyType_ClearCache(void); diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h index 29d927ff7d7..a1e5e35b3a9 100644 --- a/Include/unicodeobject.h +++ b/Include/unicodeobject.h @@ -2120,35 +2120,6 @@ PyAPI_FUNC(int) _PyUnicode_CheckConsistency( int check_content); #endif -/********************* String Literals ****************************************/ -/* This structure helps managing static strings. The basic usage goes like this: - Instead of doing - - r = PyObject_CallMethod(o, "foo", "args", ...); - - do - - _Py_IDENTIFIER(foo); - ... - r = _PyObject_CallMethodId(o, &PyId_foo, "args", ...); - - PyId_foo is a static variable, either on block level or file level. On first - usage, the string "foo" is interned, and the structures are linked. On interpreter - shutdown, all strings are released (through _PyUnicode_ClearStaticStrings). - - Alternatively, _Py_static_string allows to choose the variable name. - _PyUnicode_FromId returns a borrowed reference to the interned string. - _PyObject_{Get,Set,Has}AttrId are __getattr__ versions using _Py_Identifier*. -*/ -typedef struct _Py_Identifier { - struct _Py_Identifier *next; - const char* string; - PyObject *object; -} _Py_Identifier; - -#define _Py_static_string(varname, value) static _Py_Identifier varname = { 0, value, 0 } -#define _Py_IDENTIFIER(varname) _Py_static_string(PyId_##varname, #varname) - /* Return an interned Unicode object for an Identifier; may fail if there is no memory.*/ PyAPI_FUNC(PyObject*) _PyUnicode_FromId(_Py_Identifier*); /* Clear all static strings. */ diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index c4cc46ebc61..04f8f66c4f5 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -887,10 +887,10 @@ FUNC1(atanh, m_atanh, 0, "atanh(x)\n\nReturn the hyperbolic arc tangent (measured in radians) of x.") static PyObject * math_ceil(PyObject *self, PyObject *number) { - static PyObject *ceil_str = NULL; + _Py_IDENTIFIER(__ceil__); PyObject *method, *result; - method = _PyObject_LookupSpecial(number, "__ceil__", &ceil_str); + method = _PyObject_LookupSpecial(number, &PyId___ceil__); if (method == NULL) { if (PyErr_Occurred()) return NULL; @@ -925,10 +925,10 @@ FUNC1(fabs, fabs, 0, "fabs(x)\n\nReturn the absolute value of the float x.") static PyObject * math_floor(PyObject *self, PyObject *number) { - static PyObject *floor_str = NULL; + _Py_IDENTIFIER(__floor__); PyObject *method, *result; - method = _PyObject_LookupSpecial(number, "__floor__", &floor_str); + method = _PyObject_LookupSpecial(number, &PyId___floor__); if (method == NULL) { if (PyErr_Occurred()) return NULL; @@ -1462,7 +1462,7 @@ PyDoc_STRVAR(math_factorial_doc, static PyObject * math_trunc(PyObject *self, PyObject *number) { - static PyObject *trunc_str = NULL; + _Py_IDENTIFIER(__trunc__); PyObject *trunc, *result; if (Py_TYPE(number)->tp_dict == NULL) { @@ -1470,7 +1470,7 @@ math_trunc(PyObject *self, PyObject *number) return NULL; } - trunc = _PyObject_LookupSpecial(number, "__trunc__", &trunc_str); + trunc = _PyObject_LookupSpecial(number, &PyId___trunc__); if (trunc == NULL) { if (!PyErr_Occurred()) PyErr_Format(PyExc_TypeError, diff --git a/Objects/abstract.c b/Objects/abstract.c index be568c695a9..47010d60e50 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -74,7 +74,7 @@ PyObject_Length(PyObject *o) Py_ssize_t _PyObject_LengthHint(PyObject *o, Py_ssize_t defaultvalue) { - static PyObject *hintstrobj = NULL; + _Py_IDENTIFIER(__length_hint__); PyObject *ro, *hintmeth; Py_ssize_t rv; @@ -89,7 +89,7 @@ _PyObject_LengthHint(PyObject *o, Py_ssize_t defaultvalue) } /* try o.__length_hint__() */ - hintmeth = _PyObject_LookupSpecial(o, "__length_hint__", &hintstrobj); + hintmeth = _PyObject_LookupSpecial(o, &PyId___length_hint__); if (hintmeth == NULL) { if (PyErr_Occurred()) return -1; @@ -697,7 +697,7 @@ PyObject_Format(PyObject *obj, PyObject *format_spec) PyObject *meth; PyObject *empty = NULL; PyObject *result = NULL; - static PyObject *format_cache = NULL; + _Py_IDENTIFIER(__format__); /* If no format_spec is provided, use an empty string */ if (format_spec == NULL) { @@ -706,7 +706,7 @@ PyObject_Format(PyObject *obj, PyObject *format_spec) } /* Find the (unbound!) __format__ method (a borrowed reference) */ - meth = _PyObject_LookupSpecial(obj, "__format__", &format_cache); + meth = _PyObject_LookupSpecial(obj, &PyId___format__); if (meth == NULL) { if (!PyErr_Occurred()) PyErr_Format(PyExc_TypeError, @@ -2571,7 +2571,7 @@ recursive_isinstance(PyObject *inst, PyObject *cls) int PyObject_IsInstance(PyObject *inst, PyObject *cls) { - static PyObject *name = NULL; + _Py_IDENTIFIER(__instancecheck__); PyObject *checker; /* Quick test for an exact match */ @@ -2597,7 +2597,7 @@ PyObject_IsInstance(PyObject *inst, PyObject *cls) return r; } - checker = _PyObject_LookupSpecial(cls, "__instancecheck__", &name); + checker = _PyObject_LookupSpecial(cls, &PyId___instancecheck__); if (checker != NULL) { PyObject *res; int ok = -1; @@ -2640,7 +2640,7 @@ recursive_issubclass(PyObject *derived, PyObject *cls) int PyObject_IsSubclass(PyObject *derived, PyObject *cls) { - static PyObject *name = NULL; + _Py_IDENTIFIER(__subclasscheck__); PyObject *checker; if (PyTuple_Check(cls)) { @@ -2662,7 +2662,7 @@ PyObject_IsSubclass(PyObject *derived, PyObject *cls) return r; } - checker = _PyObject_LookupSpecial(cls, "__subclasscheck__", &name); + checker = _PyObject_LookupSpecial(cls, &PyId___subclasscheck__); if (checker != NULL) { PyObject *res; int ok = -1; diff --git a/Objects/complexobject.c b/Objects/complexobject.c index 1e61b967cef..b73dc4b9112 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -265,9 +265,9 @@ PyComplex_ImagAsDouble(PyObject *op) static PyObject * try_complex_special_method(PyObject *op) { PyObject *f; - static PyObject *complexstr; + _Py_IDENTIFIER(__complex__); - f = _PyObject_LookupSpecial(op, "__complex__", &complexstr); + f = _PyObject_LookupSpecial(op, &PyId___complex__); if (f) { PyObject *res = PyObject_CallFunctionObjArgs(f, NULL); Py_DECREF(f); diff --git a/Objects/dictobject.c b/Objects/dictobject.c index b799a0a5f0c..5a8a8a7a09a 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -1142,10 +1142,8 @@ dict_subscript(PyDictObject *mp, register PyObject *key) if (!PyDict_CheckExact(mp)) { /* Look up __missing__ method if we're a subclass. */ PyObject *missing, *res; - static PyObject *missing_str = NULL; - missing = _PyObject_LookupSpecial((PyObject *)mp, - "__missing__", - &missing_str); + _Py_IDENTIFIER(__missing__); + missing = _PyObject_LookupSpecial((PyObject *)mp, &PyId___missing__); if (missing != NULL) { res = PyObject_CallFunctionObjArgs(missing, key, NULL); diff --git a/Objects/enumobject.c b/Objects/enumobject.c index 00a33463cd6..23b38084961 100644 --- a/Objects/enumobject.c +++ b/Objects/enumobject.c @@ -224,8 +224,8 @@ reversed_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { Py_ssize_t n; PyObject *seq, *reversed_meth; - static PyObject *reversed_cache = NULL; reversedobject *ro; + _Py_IDENTIFIER(__reversed__); if (type == &PyReversed_Type && !_PyArg_NoKeywords("reversed()", kwds)) return NULL; @@ -233,7 +233,7 @@ reversed_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (!PyArg_UnpackTuple(args, "reversed", 1, 1, &seq) ) return NULL; - reversed_meth = _PyObject_LookupSpecial(seq, "__reversed__", &reversed_cache); + reversed_meth = _PyObject_LookupSpecial(seq, &PyId___reversed__); if (reversed_meth != NULL) { PyObject *res = PyObject_CallFunctionObjArgs(reversed_meth, NULL); Py_DECREF(reversed_meth); diff --git a/Objects/object.c b/Objects/object.c index 441068d1e35..86f5e1b7a4b 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -470,7 +470,7 @@ PyObject * PyObject_Bytes(PyObject *v) { PyObject *result, *func; - static PyObject *bytesstring = NULL; + _Py_IDENTIFIER(__bytes__); if (v == NULL) return PyBytes_FromString(""); @@ -480,7 +480,7 @@ PyObject_Bytes(PyObject *v) return v; } - func = _PyObject_LookupSpecial(v, "__bytes__", &bytesstring); + func = _PyObject_LookupSpecial(v, &PyId___bytes__); if (func != NULL) { result = PyObject_CallFunctionObjArgs(func, NULL); Py_DECREF(func); @@ -1298,8 +1298,8 @@ static PyObject * _dir_object(PyObject *obj) { PyObject *result, *sorted; - static PyObject *dir_str = NULL; - PyObject *dirfunc = _PyObject_LookupSpecial(obj, "__dir__", &dir_str); + _Py_IDENTIFIER(__dir__); + PyObject *dirfunc = _PyObject_LookupSpecial(obj, &PyId___dir__); assert(obj); if (dirfunc == NULL) { diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 508e35c4d25..2c6ac426f19 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -1157,16 +1157,14 @@ PyType_IsSubtype(PyTypeObject *a, PyTypeObject *b) */ static PyObject * -lookup_maybe(PyObject *self, char *attrstr, PyObject **attrobj) +lookup_maybe(PyObject *self, _Py_Identifier *attrid) { - PyObject *res; + PyObject *attr, *res; - if (*attrobj == NULL) { - *attrobj = PyUnicode_InternFromString(attrstr); - if (*attrobj == NULL) - return NULL; - } - res = _PyType_Lookup(Py_TYPE(self), *attrobj); + attr = _PyUnicode_FromId(attrid); + if (attr == NULL) + return NULL; + res = _PyType_Lookup(Py_TYPE(self), attr); if (res != NULL) { descrgetfunc f; if ((f = Py_TYPE(res)->tp_descr_get) == NULL) @@ -1178,18 +1176,18 @@ lookup_maybe(PyObject *self, char *attrstr, PyObject **attrobj) } static PyObject * -lookup_method(PyObject *self, char *attrstr, PyObject **attrobj) +lookup_method(PyObject *self, _Py_Identifier *attrid) { - PyObject *res = lookup_maybe(self, attrstr, attrobj); + PyObject *res = lookup_maybe(self, attrid); if (res == NULL && !PyErr_Occurred()) - PyErr_SetObject(PyExc_AttributeError, *attrobj); + PyErr_SetObject(PyExc_AttributeError, attrid->object); return res; } PyObject * -_PyObject_LookupSpecial(PyObject *self, char *attrstr, PyObject **attrobj) +_PyObject_LookupSpecial(PyObject *self, _Py_Identifier *attrid) { - return lookup_maybe(self, attrstr, attrobj); + return lookup_maybe(self, attrid); } /* A variation of PyObject_CallMethod that uses lookup_method() @@ -1197,17 +1195,17 @@ _PyObject_LookupSpecial(PyObject *self, char *attrstr, PyObject **attrobj) as lookup_method to cache the interned name string object. */ static PyObject * -call_method(PyObject *o, char *name, PyObject **nameobj, char *format, ...) +call_method(PyObject *o, _Py_Identifier *nameid, char *format, ...) { va_list va; PyObject *args, *func = 0, *retval; va_start(va, format); - func = lookup_maybe(o, name, nameobj); + func = lookup_maybe(o, nameid); if (func == NULL) { va_end(va); if (!PyErr_Occurred()) - PyErr_SetObject(PyExc_AttributeError, *nameobj); + PyErr_SetObject(PyExc_AttributeError, nameid->object); return NULL; } @@ -1233,13 +1231,13 @@ call_method(PyObject *o, char *name, PyObject **nameobj, char *format, ...) /* Clone of call_method() that returns NotImplemented when the lookup fails. */ static PyObject * -call_maybe(PyObject *o, char *name, PyObject **nameobj, char *format, ...) +call_maybe(PyObject *o, _Py_Identifier *nameid, char *format, ...) { va_list va; PyObject *args, *func = 0, *retval; va_start(va, format); - func = lookup_maybe(o, name, nameobj); + func = lookup_maybe(o, nameid); if (func == NULL) { va_end(va); if (!PyErr_Occurred()) @@ -1565,9 +1563,9 @@ mro_internal(PyTypeObject *type) result = mro_implementation(type); } else { - static PyObject *mro_str; + _Py_IDENTIFIER(mro); checkit = 1; - mro = lookup_method((PyObject *)type, "mro", &mro_str); + mro = lookup_method((PyObject *)type, &PyId_mro); if (mro == NULL) return -1; result = PyObject_CallObject(mro, NULL); @@ -4819,16 +4817,16 @@ add_tp_new_wrapper(PyTypeObject *type) static PyObject * \ FUNCNAME(PyObject *self) \ { \ - static PyObject *cache_str; \ - return call_method(self, OPSTR, &cache_str, "()"); \ + _Py_static_string(id, OPSTR); \ + return call_method(self, &id, "()"); \ } #define SLOT1(FUNCNAME, OPSTR, ARG1TYPE, ARGCODES) \ static PyObject * \ FUNCNAME(PyObject *self, ARG1TYPE arg1) \ { \ - static PyObject *cache_str; \ - return call_method(self, OPSTR, &cache_str, "(" ARGCODES ")", arg1); \ + _Py_static_string(id, OPSTR); \ + return call_method(self, &id, "(" ARGCODES ")", arg1); \ } /* Boolean helper for SLOT1BINFULL(). @@ -4870,7 +4868,8 @@ method_is_overloaded(PyObject *left, PyObject *right, char *name) static PyObject * \ FUNCNAME(PyObject *self, PyObject *other) \ { \ - static PyObject *cache_str, *rcache_str; \ + _Py_static_string(op_id, OPSTR); \ + _Py_static_string(rop_id, ROPSTR); \ int do_other = Py_TYPE(self) != Py_TYPE(other) && \ Py_TYPE(other)->tp_as_number != NULL && \ Py_TYPE(other)->tp_as_number->SLOTNAME == TESTFUNC; \ @@ -4880,23 +4879,20 @@ FUNCNAME(PyObject *self, PyObject *other) \ if (do_other && \ PyType_IsSubtype(Py_TYPE(other), Py_TYPE(self)) && \ method_is_overloaded(self, other, ROPSTR)) { \ - r = call_maybe( \ - other, ROPSTR, &rcache_str, "(O)", self); \ + r = call_maybe(other, &rop_id, "(O)", self); \ if (r != Py_NotImplemented) \ return r; \ Py_DECREF(r); \ do_other = 0; \ } \ - r = call_maybe( \ - self, OPSTR, &cache_str, "(O)", other); \ + r = call_maybe(self, &op_id, "(O)", other); \ if (r != Py_NotImplemented || \ Py_TYPE(other) == Py_TYPE(self)) \ return r; \ Py_DECREF(r); \ } \ if (do_other) { \ - return call_maybe( \ - other, ROPSTR, &rcache_str, "(O)", self); \ + return call_maybe(other, &rop_id, "(O)", self); \ } \ Py_RETURN_NOTIMPLEMENTED; \ } @@ -4908,16 +4904,15 @@ FUNCNAME(PyObject *self, PyObject *other) \ static PyObject * \ FUNCNAME(PyObject *self, ARG1TYPE arg1, ARG2TYPE arg2) \ { \ - static PyObject *cache_str; \ - return call_method(self, OPSTR, &cache_str, \ - "(" ARGCODES ")", arg1, arg2); \ + _Py_static_string(id, #OPSTR); \ + return call_method(self, &id, "(" ARGCODES ")", arg1, arg2); \ } static Py_ssize_t slot_sq_length(PyObject *self) { - static PyObject *len_str; - PyObject *res = call_method(self, "__len__", &len_str, "()"); + _Py_IDENTIFIER(__len__); + PyObject *res = call_method(self, &PyId___len__, "()"); Py_ssize_t len; if (res == NULL) @@ -4982,14 +4977,13 @@ static int slot_sq_ass_item(PyObject *self, Py_ssize_t index, PyObject *value) { PyObject *res; - static PyObject *delitem_str, *setitem_str; + _Py_IDENTIFIER(__delitem__); + _Py_IDENTIFIER(__setitem__); if (value == NULL) - res = call_method(self, "__delitem__", &delitem_str, - "(n)", index); + res = call_method(self, &PyId___delitem__, "(n)", index); else - res = call_method(self, "__setitem__", &setitem_str, - "(nO)", index, value); + res = call_method(self, &PyId___setitem__, "(nO)", index, value); if (res == NULL) return -1; Py_DECREF(res); @@ -5001,10 +4995,9 @@ slot_sq_contains(PyObject *self, PyObject *value) { PyObject *func, *res, *args; int result = -1; + _Py_IDENTIFIER(__contains__); - static PyObject *contains_str; - - func = lookup_maybe(self, "__contains__", &contains_str); + func = lookup_maybe(self, &PyId___contains__); if (func != NULL) { args = PyTuple_Pack(1, value); if (args == NULL) @@ -5035,14 +5028,14 @@ static int slot_mp_ass_subscript(PyObject *self, PyObject *key, PyObject *value) { PyObject *res; - static PyObject *delitem_str, *setitem_str; + _Py_IDENTIFIER(__delitem__); + _Py_IDENTIFIER(__setitem__); if (value == NULL) - res = call_method(self, "__delitem__", &delitem_str, - "(O)", key); + res = call_method(self, &PyId___delitem__, "(O)", key); else - res = call_method(self, "__setitem__", &setitem_str, - "(OO)", key, value); + res = call_method(self, &PyId___setitem__, "(OO)", key, value); + if (res == NULL) return -1; Py_DECREF(res); @@ -5063,7 +5056,7 @@ SLOT1BINFULL(slot_nb_power_binary, slot_nb_power, static PyObject * slot_nb_power(PyObject *self, PyObject *other, PyObject *modulus) { - static PyObject *pow_str; + _Py_IDENTIFIER(__pow__); if (modulus == Py_None) return slot_nb_power_binary(self, other); @@ -5072,8 +5065,7 @@ slot_nb_power(PyObject *self, PyObject *other, PyObject *modulus) slot_nb_power, so check before calling self.__pow__. */ if (Py_TYPE(self)->tp_as_number != NULL && Py_TYPE(self)->tp_as_number->nb_power == slot_nb_power) { - return call_method(self, "__pow__", &pow_str, - "(OO)", other, modulus); + return call_method(self, &PyId___pow__, "(OO)", other, modulus); } Py_RETURN_NOTIMPLEMENTED; } @@ -5086,15 +5078,16 @@ static int slot_nb_bool(PyObject *self) { PyObject *func, *args; - static PyObject *bool_str, *len_str; int result = -1; int using_len = 0; + _Py_IDENTIFIER(__len__); + _Py_IDENTIFIER(__bool__); - func = lookup_maybe(self, "__bool__", &bool_str); + func = lookup_maybe(self, &PyId___bool__); if (func == NULL) { if (PyErr_Occurred()) return -1; - func = lookup_maybe(self, "__len__", &len_str); + func = lookup_maybe(self, &PyId___len__); if (func == NULL) return PyErr_Occurred() ? -1 : 1; using_len = 1; @@ -5129,8 +5122,8 @@ slot_nb_bool(PyObject *self) static PyObject * slot_nb_index(PyObject *self) { - static PyObject *index_str; - return call_method(self, "__index__", &index_str, "()"); + _Py_IDENTIFIER(__index__); + return call_method(self, &PyId___index__, "()"); } @@ -5151,8 +5144,8 @@ SLOT1(slot_nb_inplace_remainder, "__imod__", PyObject *, "O") static PyObject * slot_nb_inplace_power(PyObject *self, PyObject * arg1, PyObject *arg2) { - static PyObject *cache_str; - return call_method(self, "__ipow__", &cache_str, "(" "O" ")", arg1); + _Py_IDENTIFIER(__ipow__); + return call_method(self, &PyId___ipow__, "(" "O" ")", arg1); } SLOT1(slot_nb_inplace_lshift, "__ilshift__", PyObject *, "O") SLOT1(slot_nb_inplace_rshift, "__irshift__", PyObject *, "O") @@ -5169,9 +5162,9 @@ static PyObject * slot_tp_repr(PyObject *self) { PyObject *func, *res; - static PyObject *repr_str; + _Py_IDENTIFIER(__repr__); - func = lookup_method(self, "__repr__", &repr_str); + func = lookup_method(self, &PyId___repr__); if (func != NULL) { res = PyEval_CallObject(func, NULL); Py_DECREF(func); @@ -5186,9 +5179,9 @@ static PyObject * slot_tp_str(PyObject *self) { PyObject *func, *res; - static PyObject *str_str; + _Py_IDENTIFIER(__str__); - func = lookup_method(self, "__str__", &str_str); + func = lookup_method(self, &PyId___str__); if (func != NULL) { res = PyEval_CallObject(func, NULL); Py_DECREF(func); @@ -5217,10 +5210,10 @@ static Py_hash_t slot_tp_hash(PyObject *self) { PyObject *func, *res; - static PyObject *hash_str; Py_ssize_t h; + _Py_IDENTIFIER(__hash__); - func = lookup_method(self, "__hash__", &hash_str); + func = lookup_method(self, &PyId___hash__); if (func == Py_None) { Py_DECREF(func); @@ -5264,8 +5257,8 @@ slot_tp_hash(PyObject *self) static PyObject * slot_tp_call(PyObject *self, PyObject *args, PyObject *kwds) { - static PyObject *call_str; - PyObject *meth = lookup_method(self, "__call__", &call_str); + _Py_IDENTIFIER(__call__); + PyObject *meth = lookup_method(self, &PyId___call__); PyObject *res; if (meth == NULL) @@ -5291,9 +5284,8 @@ slot_tp_call(PyObject *self, PyObject *args, PyObject *kwds) static PyObject * slot_tp_getattro(PyObject *self, PyObject *name) { - static PyObject *getattribute_str = NULL; - return call_method(self, "__getattribute__", &getattribute_str, - "(O)", name); + _Py_IDENTIFIER(__getattribute__); + return call_method(self, &PyId___getattribute__, "(O)", name); } static PyObject * @@ -5373,36 +5365,34 @@ static int slot_tp_setattro(PyObject *self, PyObject *name, PyObject *value) { PyObject *res; - static PyObject *delattr_str, *setattr_str; + _Py_IDENTIFIER(__delattr__); + _Py_IDENTIFIER(__setattr__); if (value == NULL) - res = call_method(self, "__delattr__", &delattr_str, - "(O)", name); + res = call_method(self, &PyId___delattr__, "(O)", name); else - res = call_method(self, "__setattr__", &setattr_str, - "(OO)", name, value); + res = call_method(self, &PyId___setattr__, "(OO)", name, value); if (res == NULL) return -1; Py_DECREF(res); return 0; } -static char *name_op[] = { - "__lt__", - "__le__", - "__eq__", - "__ne__", - "__gt__", - "__ge__", +static _Py_Identifier name_op[] = { + {0, "__lt__", 0}, + {0, "__le__", 0}, + {0, "__eq__", 0}, + {0, "__ne__", 0}, + {0, "__gt__", 0}, + {0, "__ge__", 0} }; static PyObject * slot_tp_richcompare(PyObject *self, PyObject *other, int op) { PyObject *func, *args, *res; - static PyObject *op_str[6]; - func = lookup_method(self, name_op[op], &op_str[op]); + func = lookup_method(self, &name_op[op]); if (func == NULL) { PyErr_Clear(); Py_RETURN_NOTIMPLEMENTED; @@ -5422,9 +5412,10 @@ static PyObject * slot_tp_iter(PyObject *self) { PyObject *func, *res; - static PyObject *iter_str, *getitem_str; + _Py_IDENTIFIER(__iter__); + _Py_IDENTIFIER(__getitem__); - func = lookup_method(self, "__iter__", &iter_str); + func = lookup_method(self, &PyId___iter__); if (func != NULL) { PyObject *args; args = res = PyTuple_New(0); @@ -5436,7 +5427,7 @@ slot_tp_iter(PyObject *self) return res; } PyErr_Clear(); - func = lookup_method(self, "__getitem__", &getitem_str); + func = lookup_method(self, &PyId___getitem__); if (func == NULL) { PyErr_Format(PyExc_TypeError, "'%.200s' object is not iterable", @@ -5450,8 +5441,8 @@ slot_tp_iter(PyObject *self) static PyObject * slot_tp_iternext(PyObject *self) { - static PyObject *next_str; - return call_method(self, "__next__", &next_str, "()"); + _Py_IDENTIFIER(__next__); + return call_method(self, &PyId___next__, "()"); } static PyObject * @@ -5485,14 +5476,13 @@ static int slot_tp_descr_set(PyObject *self, PyObject *target, PyObject *value) { PyObject *res; - static PyObject *del_str, *set_str; + _Py_IDENTIFIER(__delete__); + _Py_IDENTIFIER(__set__); if (value == NULL) - res = call_method(self, "__delete__", &del_str, - "(O)", target); + res = call_method(self, &PyId___delete__, "(O)", target); else - res = call_method(self, "__set__", &set_str, - "(OO)", target, value); + res = call_method(self, &PyId___set__, "(OO)", target, value); if (res == NULL) return -1; Py_DECREF(res); @@ -5502,8 +5492,8 @@ slot_tp_descr_set(PyObject *self, PyObject *target, PyObject *value) static int slot_tp_init(PyObject *self, PyObject *args, PyObject *kwds) { - static PyObject *init_str; - PyObject *meth = lookup_method(self, "__init__", &init_str); + _Py_IDENTIFIER(__init__); + PyObject *meth = lookup_method(self, &PyId___init__); PyObject *res; if (meth == NULL) @@ -5560,7 +5550,7 @@ slot_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds) static void slot_tp_del(PyObject *self) { - static PyObject *del_str = NULL; + _Py_IDENTIFIER(__del__); PyObject *del, *res; PyObject *error_type, *error_value, *error_traceback; @@ -5572,7 +5562,7 @@ slot_tp_del(PyObject *self) PyErr_Fetch(&error_type, &error_value, &error_traceback); /* Execute __del__ method, if any. */ - del = lookup_maybe(self, "__del__", &del_str); + del = lookup_maybe(self, &PyId___del__); if (del != NULL) { res = PyEval_CallObject(del, NULL); if (res == NULL) diff --git a/Python/ceval.c b/Python/ceval.c index e2d96c5c442..06bff4c1690 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -138,7 +138,7 @@ static void format_exc_check_arg(PyObject *, const char *, PyObject *); static void format_exc_unbound(PyCodeObject *co, int oparg); static PyObject * unicode_concatenate(PyObject *, PyObject *, PyFrameObject *, unsigned char *); -static PyObject * special_lookup(PyObject *, char *, PyObject **); +static PyObject * special_lookup(PyObject *, _Py_Identifier *); #define NAME_ERROR_MSG \ "name '%.200s' is not defined" @@ -2540,13 +2540,14 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) TARGET(SETUP_WITH) { - static PyObject *exit, *enter; + _Py_IDENTIFIER(__exit__); + _Py_IDENTIFIER(__enter__); w = TOP(); - x = special_lookup(w, "__exit__", &exit); + x = special_lookup(w, &PyId___exit__); if (!x) break; SET_TOP(x); - u = special_lookup(w, "__enter__", &enter); + u = special_lookup(w, &PyId___enter__); Py_DECREF(w); if (!u) { x = NULL; @@ -3440,12 +3441,12 @@ fail: /* Jump here from prelude on failure */ static PyObject * -special_lookup(PyObject *o, char *meth, PyObject **cache) +special_lookup(PyObject *o, _Py_Identifier *id) { PyObject *res; - res = _PyObject_LookupSpecial(o, meth, cache); + res = _PyObject_LookupSpecial(o, id); if (res == NULL && !PyErr_Occurred()) { - PyErr_SetObject(PyExc_AttributeError, *cache); + PyErr_SetObject(PyExc_AttributeError, id->object); return NULL; } return res; diff --git a/Python/sysmodule.c b/Python/sysmodule.c index ab0008e44cc..d1517d33f6c 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -814,10 +814,11 @@ static PyObject * sys_getsizeof(PyObject *self, PyObject *args, PyObject *kwds) { PyObject *res = NULL; - static PyObject *str__sizeof__ = NULL, *gc_head_size = NULL; + static PyObject *gc_head_size = NULL; static char *kwlist[] = {"object", "default", 0}; PyObject *o, *dflt = NULL; PyObject *method; + _Py_IDENTIFIER(__sizeof__); if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:getsizeof", kwlist, &o, &dflt)) @@ -834,8 +835,7 @@ sys_getsizeof(PyObject *self, PyObject *args, PyObject *kwds) if (PyType_Ready(Py_TYPE(o)) < 0) return NULL; - method = _PyObject_LookupSpecial(o, "__sizeof__", - &str__sizeof__); + method = _PyObject_LookupSpecial(o, &PyId___sizeof__); if (method == NULL) { if (!PyErr_Occurred()) PyErr_Format(PyExc_TypeError,