Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ce79852

Browse files
committed
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.
1 parent cd89912 commit ce79852

11 files changed

Lines changed: 153 additions & 164 deletions

File tree

Include/object.h

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,35 @@ typedef struct {
117117
#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
118118
#define Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size)
119119

120+
/********************* String Literals ****************************************/
121+
/* This structure helps managing static strings. The basic usage goes like this:
122+
Instead of doing
123+
124+
r = PyObject_CallMethod(o, "foo", "args", ...);
125+
126+
do
127+
128+
_Py_IDENTIFIER(foo);
129+
...
130+
r = _PyObject_CallMethodId(o, &PyId_foo, "args", ...);
131+
132+
PyId_foo is a static variable, either on block level or file level. On first
133+
usage, the string "foo" is interned, and the structures are linked. On interpreter
134+
shutdown, all strings are released (through _PyUnicode_ClearStaticStrings).
135+
136+
Alternatively, _Py_static_string allows to choose the variable name.
137+
_PyUnicode_FromId returns a borrowed reference to the interned string.
138+
_PyObject_{Get,Set,Has}AttrId are __getattr__ versions using _Py_Identifier*.
139+
*/
140+
typedef struct _Py_Identifier {
141+
struct _Py_Identifier *next;
142+
const char* string;
143+
PyObject *object;
144+
} _Py_Identifier;
145+
146+
#define _Py_static_string(varname, value) static _Py_Identifier varname = { 0, value, 0 }
147+
#define _Py_IDENTIFIER(varname) _Py_static_string(PyId_##varname, #varname)
148+
120149
/*
121150
Type objects contain a string containing the type name (to help somewhat
122151
in debugging), the allocation parameters (see PyObject_New() and
@@ -448,7 +477,7 @@ PyAPI_FUNC(PyObject *) PyType_GenericNew(PyTypeObject *,
448477
PyObject *, PyObject *);
449478
#ifndef Py_LIMITED_API
450479
PyAPI_FUNC(PyObject *) _PyType_Lookup(PyTypeObject *, PyObject *);
451-
PyAPI_FUNC(PyObject *) _PyObject_LookupSpecial(PyObject *, char *, PyObject **);
480+
PyAPI_FUNC(PyObject *) _PyObject_LookupSpecial(PyObject *, _Py_Identifier *);
452481
PyAPI_FUNC(PyTypeObject *) _PyType_CalculateMetaclass(PyTypeObject *, PyObject *);
453482
#endif
454483
PyAPI_FUNC(unsigned int) PyType_ClearCache(void);

Include/unicodeobject.h

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2120,35 +2120,6 @@ PyAPI_FUNC(int) _PyUnicode_CheckConsistency(
21202120
int check_content);
21212121
#endif
21222122

2123-
/********************* String Literals ****************************************/
2124-
/* This structure helps managing static strings. The basic usage goes like this:
2125-
Instead of doing
2126-
2127-
r = PyObject_CallMethod(o, "foo", "args", ...);
2128-
2129-
do
2130-
2131-
_Py_IDENTIFIER(foo);
2132-
...
2133-
r = _PyObject_CallMethodId(o, &PyId_foo, "args", ...);
2134-
2135-
PyId_foo is a static variable, either on block level or file level. On first
2136-
usage, the string "foo" is interned, and the structures are linked. On interpreter
2137-
shutdown, all strings are released (through _PyUnicode_ClearStaticStrings).
2138-
2139-
Alternatively, _Py_static_string allows to choose the variable name.
2140-
_PyUnicode_FromId returns a borrowed reference to the interned string.
2141-
_PyObject_{Get,Set,Has}AttrId are __getattr__ versions using _Py_Identifier*.
2142-
*/
2143-
typedef struct _Py_Identifier {
2144-
struct _Py_Identifier *next;
2145-
const char* string;
2146-
PyObject *object;
2147-
} _Py_Identifier;
2148-
2149-
#define _Py_static_string(varname, value) static _Py_Identifier varname = { 0, value, 0 }
2150-
#define _Py_IDENTIFIER(varname) _Py_static_string(PyId_##varname, #varname)
2151-
21522123
/* Return an interned Unicode object for an Identifier; may fail if there is no memory.*/
21532124
PyAPI_FUNC(PyObject*) _PyUnicode_FromId(_Py_Identifier*);
21542125
/* Clear all static strings. */

Modules/mathmodule.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -887,10 +887,10 @@ FUNC1(atanh, m_atanh, 0,
887887
"atanh(x)\n\nReturn the hyperbolic arc tangent (measured in radians) of x.")
888888

889889
static PyObject * math_ceil(PyObject *self, PyObject *number) {
890-
static PyObject *ceil_str = NULL;
890+
_Py_IDENTIFIER(__ceil__);
891891
PyObject *method, *result;
892892

893-
method = _PyObject_LookupSpecial(number, "__ceil__", &ceil_str);
893+
method = _PyObject_LookupSpecial(number, &PyId___ceil__);
894894
if (method == NULL) {
895895
if (PyErr_Occurred())
896896
return NULL;
@@ -925,10 +925,10 @@ FUNC1(fabs, fabs, 0,
925925
"fabs(x)\n\nReturn the absolute value of the float x.")
926926

927927
static PyObject * math_floor(PyObject *self, PyObject *number) {
928-
static PyObject *floor_str = NULL;
928+
_Py_IDENTIFIER(__floor__);
929929
PyObject *method, *result;
930930

931-
method = _PyObject_LookupSpecial(number, "__floor__", &floor_str);
931+
method = _PyObject_LookupSpecial(number, &PyId___floor__);
932932
if (method == NULL) {
933933
if (PyErr_Occurred())
934934
return NULL;
@@ -1462,15 +1462,15 @@ PyDoc_STRVAR(math_factorial_doc,
14621462
static PyObject *
14631463
math_trunc(PyObject *self, PyObject *number)
14641464
{
1465-
static PyObject *trunc_str = NULL;
1465+
_Py_IDENTIFIER(__trunc__);
14661466
PyObject *trunc, *result;
14671467

14681468
if (Py_TYPE(number)->tp_dict == NULL) {
14691469
if (PyType_Ready(Py_TYPE(number)) < 0)
14701470
return NULL;
14711471
}
14721472

1473-
trunc = _PyObject_LookupSpecial(number, "__trunc__", &trunc_str);
1473+
trunc = _PyObject_LookupSpecial(number, &PyId___trunc__);
14741474
if (trunc == NULL) {
14751475
if (!PyErr_Occurred())
14761476
PyErr_Format(PyExc_TypeError,

Objects/abstract.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ PyObject_Length(PyObject *o)
7474
Py_ssize_t
7575
_PyObject_LengthHint(PyObject *o, Py_ssize_t defaultvalue)
7676
{
77-
static PyObject *hintstrobj = NULL;
77+
_Py_IDENTIFIER(__length_hint__);
7878
PyObject *ro, *hintmeth;
7979
Py_ssize_t rv;
8080

@@ -89,7 +89,7 @@ _PyObject_LengthHint(PyObject *o, Py_ssize_t defaultvalue)
8989
}
9090

9191
/* try o.__length_hint__() */
92-
hintmeth = _PyObject_LookupSpecial(o, "__length_hint__", &hintstrobj);
92+
hintmeth = _PyObject_LookupSpecial(o, &PyId___length_hint__);
9393
if (hintmeth == NULL) {
9494
if (PyErr_Occurred())
9595
return -1;
@@ -697,7 +697,7 @@ PyObject_Format(PyObject *obj, PyObject *format_spec)
697697
PyObject *meth;
698698
PyObject *empty = NULL;
699699
PyObject *result = NULL;
700-
static PyObject *format_cache = NULL;
700+
_Py_IDENTIFIER(__format__);
701701

702702
/* If no format_spec is provided, use an empty string */
703703
if (format_spec == NULL) {
@@ -706,7 +706,7 @@ PyObject_Format(PyObject *obj, PyObject *format_spec)
706706
}
707707

708708
/* Find the (unbound!) __format__ method (a borrowed reference) */
709-
meth = _PyObject_LookupSpecial(obj, "__format__", &format_cache);
709+
meth = _PyObject_LookupSpecial(obj, &PyId___format__);
710710
if (meth == NULL) {
711711
if (!PyErr_Occurred())
712712
PyErr_Format(PyExc_TypeError,
@@ -2571,7 +2571,7 @@ recursive_isinstance(PyObject *inst, PyObject *cls)
25712571
int
25722572
PyObject_IsInstance(PyObject *inst, PyObject *cls)
25732573
{
2574-
static PyObject *name = NULL;
2574+
_Py_IDENTIFIER(__instancecheck__);
25752575
PyObject *checker;
25762576

25772577
/* Quick test for an exact match */
@@ -2597,7 +2597,7 @@ PyObject_IsInstance(PyObject *inst, PyObject *cls)
25972597
return r;
25982598
}
25992599

2600-
checker = _PyObject_LookupSpecial(cls, "__instancecheck__", &name);
2600+
checker = _PyObject_LookupSpecial(cls, &PyId___instancecheck__);
26012601
if (checker != NULL) {
26022602
PyObject *res;
26032603
int ok = -1;
@@ -2640,7 +2640,7 @@ recursive_issubclass(PyObject *derived, PyObject *cls)
26402640
int
26412641
PyObject_IsSubclass(PyObject *derived, PyObject *cls)
26422642
{
2643-
static PyObject *name = NULL;
2643+
_Py_IDENTIFIER(__subclasscheck__);
26442644
PyObject *checker;
26452645

26462646
if (PyTuple_Check(cls)) {
@@ -2662,7 +2662,7 @@ PyObject_IsSubclass(PyObject *derived, PyObject *cls)
26622662
return r;
26632663
}
26642664

2665-
checker = _PyObject_LookupSpecial(cls, "__subclasscheck__", &name);
2665+
checker = _PyObject_LookupSpecial(cls, &PyId___subclasscheck__);
26662666
if (checker != NULL) {
26672667
PyObject *res;
26682668
int ok = -1;

Objects/complexobject.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,9 +265,9 @@ PyComplex_ImagAsDouble(PyObject *op)
265265
static PyObject *
266266
try_complex_special_method(PyObject *op) {
267267
PyObject *f;
268-
static PyObject *complexstr;
268+
_Py_IDENTIFIER(__complex__);
269269

270-
f = _PyObject_LookupSpecial(op, "__complex__", &complexstr);
270+
f = _PyObject_LookupSpecial(op, &PyId___complex__);
271271
if (f) {
272272
PyObject *res = PyObject_CallFunctionObjArgs(f, NULL);
273273
Py_DECREF(f);

Objects/dictobject.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1142,10 +1142,8 @@ dict_subscript(PyDictObject *mp, register PyObject *key)
11421142
if (!PyDict_CheckExact(mp)) {
11431143
/* Look up __missing__ method if we're a subclass. */
11441144
PyObject *missing, *res;
1145-
static PyObject *missing_str = NULL;
1146-
missing = _PyObject_LookupSpecial((PyObject *)mp,
1147-
"__missing__",
1148-
&missing_str);
1145+
_Py_IDENTIFIER(__missing__);
1146+
missing = _PyObject_LookupSpecial((PyObject *)mp, &PyId___missing__);
11491147
if (missing != NULL) {
11501148
res = PyObject_CallFunctionObjArgs(missing,
11511149
key, NULL);

Objects/enumobject.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,16 +224,16 @@ reversed_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
224224
{
225225
Py_ssize_t n;
226226
PyObject *seq, *reversed_meth;
227-
static PyObject *reversed_cache = NULL;
228227
reversedobject *ro;
228+
_Py_IDENTIFIER(__reversed__);
229229

230230
if (type == &PyReversed_Type && !_PyArg_NoKeywords("reversed()", kwds))
231231
return NULL;
232232

233233
if (!PyArg_UnpackTuple(args, "reversed", 1, 1, &seq) )
234234
return NULL;
235235

236-
reversed_meth = _PyObject_LookupSpecial(seq, "__reversed__", &reversed_cache);
236+
reversed_meth = _PyObject_LookupSpecial(seq, &PyId___reversed__);
237237
if (reversed_meth != NULL) {
238238
PyObject *res = PyObject_CallFunctionObjArgs(reversed_meth, NULL);
239239
Py_DECREF(reversed_meth);

Objects/object.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,7 @@ PyObject *
470470
PyObject_Bytes(PyObject *v)
471471
{
472472
PyObject *result, *func;
473-
static PyObject *bytesstring = NULL;
473+
_Py_IDENTIFIER(__bytes__);
474474

475475
if (v == NULL)
476476
return PyBytes_FromString("<NULL>");
@@ -480,7 +480,7 @@ PyObject_Bytes(PyObject *v)
480480
return v;
481481
}
482482

483-
func = _PyObject_LookupSpecial(v, "__bytes__", &bytesstring);
483+
func = _PyObject_LookupSpecial(v, &PyId___bytes__);
484484
if (func != NULL) {
485485
result = PyObject_CallFunctionObjArgs(func, NULL);
486486
Py_DECREF(func);
@@ -1298,8 +1298,8 @@ static PyObject *
12981298
_dir_object(PyObject *obj)
12991299
{
13001300
PyObject *result, *sorted;
1301-
static PyObject *dir_str = NULL;
1302-
PyObject *dirfunc = _PyObject_LookupSpecial(obj, "__dir__", &dir_str);
1301+
_Py_IDENTIFIER(__dir__);
1302+
PyObject *dirfunc = _PyObject_LookupSpecial(obj, &PyId___dir__);
13031303

13041304
assert(obj);
13051305
if (dirfunc == NULL) {

0 commit comments

Comments
 (0)