[Python-checkins] cpython: use the static identifier api for looking up special methods

benjamin.peterson python-checkins at python.org
Sun Jan 22 17:24:37 CET 2012


http://hg.python.org/cpython/rev/7d96679c5d46
changeset:   74578:7d96679c5d46
user:        Benjamin Peterson <benjamin at python.org>
date:        Sun Jan 22 11:24:29 2012 -0500
summary:
  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.

files:
  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    |  208 +++++++++++++--------------
  Python/ceval.c          |   15 +-
  Python/sysmodule.c      |    6 +-
  11 files changed, 164 insertions(+), 175 deletions(-)


diff --git a/Include/object.h b/Include/object.h
--- a/Include/object.h
+++ b/Include/object.h
@@ -117,6 +117,35 @@
 #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 @@
                                                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
--- a/Include/unicodeobject.h
+++ b/Include/unicodeobject.h
@@ -2120,35 +2120,6 @@
     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
--- a/Modules/mathmodule.c
+++ b/Modules/mathmodule.c
@@ -887,10 +887,10 @@
       "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 @@
       "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 @@
 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 @@
             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
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -74,7 +74,7 @@
 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 @@
     }
 
     /* 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 *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 @@
     }
 
     /* 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 @@
 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 @@
         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 @@
 int
 PyObject_IsSubclass(PyObject *derived, PyObject *cls)
 {
-    static PyObject *name = NULL;
+    _Py_IDENTIFIER(__subclasscheck__);
     PyObject *checker;
 
     if (PyTuple_Check(cls)) {
@@ -2662,7 +2662,7 @@
         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
--- a/Objects/complexobject.c
+++ b/Objects/complexobject.c
@@ -265,9 +265,9 @@
 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
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -1142,10 +1142,8 @@
         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
--- a/Objects/enumobject.c
+++ b/Objects/enumobject.c
@@ -224,8 +224,8 @@
 {
     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 @@
     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
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -470,7 +470,7 @@
 PyObject_Bytes(PyObject *v)
 {
     PyObject *result, *func;
-    static PyObject *bytesstring = NULL;
+    _Py_IDENTIFIER(__bytes__);
 
     if (v == NULL)
         return PyBytes_FromString("<NULL>");
@@ -480,7 +480,7 @@
         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 @@
 _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
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -1157,16 +1157,14 @@
 */
 
 static PyObject *
-lookup_maybe(PyObject *self, char *attrstr, PyObject **attrobj)
-{
-    PyObject *res;
-
-    if (*attrobj == NULL) {
-        *attrobj = PyUnicode_InternFromString(attrstr);
-        if (*attrobj == NULL)
-            return NULL;
-    }
-    res = _PyType_Lookup(Py_TYPE(self), *attrobj);
+lookup_maybe(PyObject *self, _Py_Identifier *attrid)
+{
+    PyObject *attr, *res;
+
+    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 @@
 }
 
 static PyObject *
-lookup_method(PyObject *self, char *attrstr, PyObject **attrobj)
-{
-    PyObject *res = lookup_maybe(self, attrstr, attrobj);
+lookup_method(PyObject *self, _Py_Identifier *attrid)
+{
+    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)
-{
-    return lookup_maybe(self, attrstr, attrobj);
+_PyObject_LookupSpecial(PyObject *self, _Py_Identifier *attrid)
+{
+    return lookup_maybe(self, attrid);
 }
 
 /* A variation of PyObject_CallMethod that uses lookup_method()
@@ -1197,17 +1195,17 @@
    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 @@
 /* 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 @@
         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 @@
 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 @@
 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 @@
         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 @@
 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 @@
 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 @@
 {
     PyObject *func, *res, *args;
     int result = -1;
-
-    static PyObject *contains_str;
-
-    func = lookup_maybe(self, "__contains__", &contains_str);
+    _Py_IDENTIFIER(__contains__);
+
+    func = lookup_maybe(self, &PyId___contains__);
     if (func != NULL) {
         args = PyTuple_Pack(1, value);
         if (args == NULL)
@@ -5035,14 +5028,14 @@
 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 @@
 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, 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 @@
 slot_nb_bool(PyObject *self)
 {
     PyObject *func, *args;
-    static PyObject *bool_str, *len_str;
     int result = -1;
     int using_len = 0;
-
-    func = lookup_maybe(self, "__bool__", &bool_str);
+    _Py_IDENTIFIER(__len__);
+    _Py_IDENTIFIER(__bool__);
+
+    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 @@
 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 @@
 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 @@
 slot_tp_repr(PyObject *self)
 {
     PyObject *func, *res;
-    static PyObject *repr_str;
-
-    func = lookup_method(self, "__repr__", &repr_str);
+    _Py_IDENTIFIER(__repr__);
+
+    func = lookup_method(self, &PyId___repr__);
     if (func != NULL) {
         res = PyEval_CallObject(func, NULL);
         Py_DECREF(func);
@@ -5186,9 +5179,9 @@
 slot_tp_str(PyObject *self)
 {
     PyObject *func, *res;
-    static PyObject *str_str;
-
-    func = lookup_method(self, "__str__", &str_str);
+    _Py_IDENTIFIER(__str__);
+
+    func = lookup_method(self, &PyId___str__);
     if (func != NULL) {
         res = PyEval_CallObject(func, NULL);
         Py_DECREF(func);
@@ -5217,10 +5210,10 @@
 slot_tp_hash(PyObject *self)
 {
     PyObject *func, *res;
-    static PyObject *hash_str;
     Py_ssize_t h;
-
-    func = lookup_method(self, "__hash__", &hash_str);
+    _Py_IDENTIFIER(__hash__);
+
+    func = lookup_method(self, &PyId___hash__);
 
     if (func == Py_None) {
         Py_DECREF(func);
@@ -5264,8 +5257,8 @@
 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 @@
 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 @@
 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 @@
 slot_tp_iter(PyObject *self)
 {
     PyObject *func, *res;
-    static PyObject *iter_str, *getitem_str;
-
-    func = lookup_method(self, "__iter__", &iter_str);
+    _Py_IDENTIFIER(__iter__);
+    _Py_IDENTIFIER(__getitem__);
+
+    func = lookup_method(self, &PyId___iter__);
     if (func != NULL) {
         PyObject *args;
         args = res = PyTuple_New(0);
@@ -5436,7 +5427,7 @@
         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 @@
 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 @@
 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 @@
 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 @@
 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 @@
     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
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -138,7 +138,7 @@
 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 @@
 
         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 @@
 
 
 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
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -814,10 +814,11 @@
 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 @@
     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,

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list