mirror of https://github.com/python/cpython
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.
This commit is contained in:
parent
cd8991255c
commit
ce79852077
|
@ -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);
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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("<NULL>");
|
||||
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
attr = _PyUnicode_FromId(attrid);
|
||||
if (attr == NULL)
|
||||
return NULL;
|
||||
}
|
||||
res = _PyType_Lookup(Py_TYPE(self), *attrobj);
|
||||
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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue