From afe55bba33a20f87a58f940186359237064b428f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20v=2E=20L=C3=B6wis?= Date: Sun, 9 Oct 2011 10:38:36 +0200 Subject: [PATCH] =?UTF-8?q?Add=20API=20for=20static=20strings,=20primarily?= =?UTF-8?q?=20good=20for=20identifiers.=20Thanks=20to=20Konrad=20Sch=C3=B6?= =?UTF-8?q?bel=20and=20Jasper=20Schulz=20for=20helping=20with=20the=20mass?= =?UTF-8?q?-editing.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Include/abstract.h | 12 ++++ Include/object.h | 4 ++ Include/unicodeobject.h | 34 +++++++++ Misc/NEWS | 2 + Modules/_bisectmodule.c | 8 ++- Modules/_collectionsmodule.c | 4 +- Modules/_ctypes/_ctypes.c | 4 +- Modules/_ctypes/callproc.c | 6 +- Modules/_cursesmodule.c | 7 +- Modules/_datetimemodule.c | 77 +++++++++++++------- Modules/_elementtree.c | 33 +++++---- Modules/_io/_iomodule.c | 7 +- Modules/_io/bufferedio.c | 47 +++++++----- Modules/_io/fileio.c | 5 +- Modules/_io/iobase.c | 27 ++++--- Modules/_io/textio.c | 103 +++++++++++++++----------- Modules/_pickle.c | 14 ++-- Modules/_posixsubprocess.c | 11 ++- Modules/_sqlite/connection.c | 15 ++-- Modules/_sqlite/cursor.c | 3 +- Modules/_sqlite/microprotocols.c | 8 ++- Modules/_sqlite/module.c | 3 +- Modules/arraymodule.c | 7 +- Modules/cjkcodecs/multibytecodec.c | 7 +- Modules/faulthandler.c | 9 ++- Modules/gcmodule.c | 4 +- Modules/itertoolsmodule.c | 4 +- Modules/mmapmodule.c | 4 +- Modules/ossaudiodev.c | 4 +- Modules/socketmodule.c | 4 +- Modules/timemodule.c | 5 +- Objects/abstract.c | 111 +++++++++++++++++++---------- Objects/descrobject.c | 15 ++-- Objects/dictobject.c | 12 +++- Objects/fileobject.c | 3 +- Objects/object.c | 36 ++++++++++ Objects/typeobject.c | 9 ++- Objects/unicodeobject.c | 31 ++++++++ Objects/weakrefobject.c | 5 +- PC/_msi.c | 8 ++- Parser/tokenizer.c | 3 +- Python/_warnings.c | 3 +- Python/ast.c | 3 +- Python/bltinmodule.c | 13 ++-- Python/ceval.c | 3 +- Python/import.c | 11 +-- Python/marshal.c | 11 ++- Python/pythonrun.c | 30 ++++---- Python/sysmodule.c | 3 +- Python/traceback.c | 12 ++-- 50 files changed, 571 insertions(+), 233 deletions(-) diff --git a/Include/abstract.h b/Include/abstract.h index 0fe0956b14f724..3946ec5b388cf7 100644 --- a/Include/abstract.h +++ b/Include/abstract.h @@ -7,6 +7,7 @@ extern "C" { #ifdef PY_SSIZE_T_CLEAN #define PyObject_CallFunction _PyObject_CallFunction_SizeT #define PyObject_CallMethod _PyObject_CallMethod_SizeT +#define _PyObject_CallMethodId _PyObject_CallMethodId_SizeT #endif /* Abstract Object Interface (many thanks to Jim Fulton) */ @@ -307,11 +308,22 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/ Python expression: o.method(args). */ + PyAPI_FUNC(PyObject *) _PyObject_CallMethodId(PyObject *o, _Py_Identifier *method, + char *format, ...); + + /* + Like PyObject_CallMethod, but expect a _Py_Identifier* as the + method name. + */ + PyAPI_FUNC(PyObject *) _PyObject_CallFunction_SizeT(PyObject *callable, char *format, ...); PyAPI_FUNC(PyObject *) _PyObject_CallMethod_SizeT(PyObject *o, char *name, char *format, ...); + PyAPI_FUNC(PyObject *) _PyObject_CallMethodId_SizeT(PyObject *o, + _Py_Identifier *name, + char *format, ...); PyAPI_FUNC(PyObject *) PyObject_CallFunctionObjArgs(PyObject *callable, ...); diff --git a/Include/object.h b/Include/object.h index e0c68c133d6e33..cf231aff371d95 100644 --- a/Include/object.h +++ b/Include/object.h @@ -454,6 +454,7 @@ PyAPI_FUNC(unsigned int) PyType_ClearCache(void); PyAPI_FUNC(void) PyType_Modified(PyTypeObject *); /* Generic operations on objects */ +struct _Py_Identifier; #ifndef Py_LIMITED_API PyAPI_FUNC(int) PyObject_Print(PyObject *, FILE *, int); PyAPI_FUNC(void) _Py_BreakPoint(void); @@ -471,6 +472,9 @@ PyAPI_FUNC(int) PyObject_HasAttrString(PyObject *, const char *); PyAPI_FUNC(PyObject *) PyObject_GetAttr(PyObject *, PyObject *); PyAPI_FUNC(int) PyObject_SetAttr(PyObject *, PyObject *, PyObject *); PyAPI_FUNC(int) PyObject_HasAttr(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) _PyObject_GetAttrId(PyObject *, struct _Py_Identifier *); +PyAPI_FUNC(int) _PyObject_SetAttrId(PyObject *, struct _Py_Identifier *, PyObject *); +PyAPI_FUNC(int) _PyObject_HasAttrId(PyObject *, struct _Py_Identifier *); #ifndef Py_LIMITED_API PyAPI_FUNC(PyObject **) _PyObject_GetDictPtr(PyObject *); #endif diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h index 51442341775846..f90e0bd867a3f8 100644 --- a/Include/unicodeobject.h +++ b/Include/unicodeobject.h @@ -2024,6 +2024,40 @@ 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 new 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. */ +PyAPI_FUNC(void) _PyUnicode_ClearStaticStrings(void); + #ifdef __cplusplus } #endif diff --git a/Misc/NEWS b/Misc/NEWS index 26a98f4bc8b958..b4dbd6ed562ef3 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,8 @@ What's New in Python 3.3 Alpha 1? Core and Builtins ----------------- +- Add internal API for static strings (_Py_identifier et.al.). + - Issue #13063: the Windows error ERROR_NO_DATA (numbered 232 and described as "The pipe is being closed") is now mapped to POSIX errno EPIPE (previously EINVAL). diff --git a/Modules/_bisectmodule.c b/Modules/_bisectmodule.c index 7fecfc6937b808..9da255e14861ec 100644 --- a/Modules/_bisectmodule.c +++ b/Modules/_bisectmodule.c @@ -86,7 +86,9 @@ insort_right(PyObject *self, PyObject *args, PyObject *kw) if (PyList_Insert(list, index, item) < 0) return NULL; } else { - result = PyObject_CallMethod(list, "insert", "nO", index, item); + _Py_identifier(insert); + + result = _PyObject_CallMethodId(list, &PyId_insert, "nO", index, item); if (result == NULL) return NULL; Py_DECREF(result); @@ -186,7 +188,9 @@ insort_left(PyObject *self, PyObject *args, PyObject *kw) if (PyList_Insert(list, index, item) < 0) return NULL; } else { - result = PyObject_CallMethod(list, "insert", "iO", index, item); + _Py_identifier(insert); + + result = _PyObject_CallMethodId(list, &PyId_insert, "iO", index, item); if (result == NULL) return NULL; Py_DECREF(result); diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c index 156ad1863cd326..40e253d39086f5 100644 --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -1334,13 +1334,15 @@ defdict_reduce(defdictobject *dd) PyObject *items; PyObject *iter; PyObject *result; + _Py_identifier(items); + if (dd->default_factory == NULL || dd->default_factory == Py_None) args = PyTuple_New(0); else args = PyTuple_Pack(1, dd->default_factory); if (args == NULL) return NULL; - items = PyObject_CallMethod((PyObject *)dd, "items", "()"); + items = _PyObject_CallMethodId((PyObject *)dd, &PyId_items, "()"); if (items == NULL) { Py_DECREF(args); return NULL; diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index e2905bc277f20f..1d7cf94137b5bf 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -3679,8 +3679,10 @@ _build_result(PyObject *result, PyObject *callargs, PyTuple_SET_ITEM(tup, index, v); index++; } else if (bit & outmask) { + _Py_identifier(__ctypes_from_outparam__); + v = PyTuple_GET_ITEM(callargs, i); - v = PyObject_CallMethod(v, "__ctypes_from_outparam__", NULL); + v = _PyObject_CallMethodId(v, &PyId___ctypes_from_outparam__, NULL); if (v == NULL || numretvals == 1) { Py_DECREF(callargs); return v; diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index 60d59c878a5916..adc28703216c53 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -1687,13 +1687,15 @@ unpickle(PyObject *self, PyObject *args) PyObject *state; PyObject *result; PyObject *tmp; + _Py_identifier(__new__); + _Py_identifier(__setstate__); if (!PyArg_ParseTuple(args, "OO", &typ, &state)) return NULL; - result = PyObject_CallMethod(typ, "__new__", "O", typ); + result = _PyObject_CallMethodId(typ, &PyId___new__, "O", typ); if (result == NULL) return NULL; - tmp = PyObject_CallMethod(result, "__setstate__", "O", state); + tmp = _PyObject_CallMethodId(result, &PyId___setstate__, "O", state); if (tmp == NULL) { Py_DECREF(result); return NULL; diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c index 191d53fff2f365..ead38d371e33fb 100644 --- a/Modules/_cursesmodule.c +++ b/Modules/_cursesmodule.c @@ -1418,10 +1418,12 @@ PyCursesWindow_PutWin(PyCursesWindowObject *self, PyObject *stream) while (1) { char buf[BUFSIZ]; Py_ssize_t n = fread(buf, 1, BUFSIZ, fp); + _Py_identifier(write); + if (n <= 0) break; Py_DECREF(res); - res = PyObject_CallMethod(stream, "write", "y#", buf, n); + res = _PyObject_CallMethodId(stream, &PyId_write, "y#", buf, n); if (res == NULL) break; } @@ -1911,6 +1913,7 @@ PyCurses_GetWin(PyCursesWindowObject *self, PyObject *stream) WINDOW *win; PyCursesInitialised; + _Py_identifier(read); strcpy(fn, "/tmp/py.curses.getwin.XXXXXX"); fd = mkstemp(fn); @@ -1922,7 +1925,7 @@ PyCurses_GetWin(PyCursesWindowObject *self, PyObject *stream) remove(fn); return PyErr_SetFromErrnoWithFilename(PyExc_IOError, fn); } - data = PyObject_CallMethod(stream, "read", ""); + data = _PyObject_CallMethodId(stream, &PyId_read, ""); if (data == NULL) { fclose(fp); remove(fn); diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index a7156a46523051..eb6998f0fa4a76 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -946,6 +946,7 @@ static PyObject * call_tzname(PyObject *tzinfo, PyObject *tzinfoarg) { PyObject *result; + _Py_identifier(tzname); assert(tzinfo != NULL); assert(check_tzinfo_subclass(tzinfo) >= 0); @@ -954,7 +955,7 @@ call_tzname(PyObject *tzinfo, PyObject *tzinfoarg) if (tzinfo == Py_None) Py_RETURN_NONE; - result = PyObject_CallMethod(tzinfo, "tzname", "O", tzinfoarg); + result = _PyObject_CallMethodId(tzinfo, &PyId_tzname, "O", tzinfoarg); if (result == NULL || result == Py_None) return result; @@ -1078,6 +1079,8 @@ make_Zreplacement(PyObject *object, PyObject *tzinfoarg) PyObject *temp; PyObject *tzinfo = get_tzinfo_member(object); PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0); + _Py_identifier(replace); + if (Zreplacement == NULL) return NULL; if (tzinfo == Py_None || tzinfo == NULL) @@ -1098,7 +1101,7 @@ make_Zreplacement(PyObject *object, PyObject *tzinfoarg) * strftime doesn't treat them as format codes. */ Py_DECREF(Zreplacement); - Zreplacement = PyObject_CallMethod(temp, "replace", "ss", "%", "%%"); + Zreplacement = _PyObject_CallMethodId(temp, &PyId_replace, "ss", "%", "%%"); Py_DECREF(temp); if (Zreplacement == NULL) return NULL; @@ -1281,12 +1284,15 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple, { PyObject *format; PyObject *time = PyImport_ImportModuleNoBlock("time"); + if (time == NULL) goto Done; format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt)); if (format != NULL) { - result = PyObject_CallMethod(time, "strftime", "OO", - format, timetuple, NULL); + _Py_identifier(strftime); + + result = _PyObject_CallMethodId(time, &PyId_strftime, "OO", + format, timetuple, NULL); Py_DECREF(format); } Py_DECREF(time); @@ -1312,7 +1318,9 @@ time_time(void) PyObject *time = PyImport_ImportModuleNoBlock("time"); if (time != NULL) { - result = PyObject_CallMethod(time, "time", "()"); + _Py_identifier(time); + + result = _PyObject_CallMethodId(time, &PyId_time, "()"); Py_DECREF(time); } return result; @@ -1329,13 +1337,15 @@ build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag) time = PyImport_ImportModuleNoBlock("time"); if (time != NULL) { - result = PyObject_CallMethod(time, "struct_time", - "((iiiiiiiii))", - y, m, d, - hh, mm, ss, - weekday(y, m, d), - days_before_month(y, m) + d, - dstflag); + _Py_identifier(struct_time); + + result = _PyObject_CallMethodId(time, &PyId_struct_time, + "((iiiiiiiii))", + y, m, d, + hh, mm, ss, + weekday(y, m, d), + days_before_month(y, m) + d, + dstflag); Py_DECREF(time); } return result; @@ -1568,11 +1578,12 @@ multiply_float_timedelta(PyObject *floatobj, PyDateTime_Delta *delta) PyObject *result = NULL; PyObject *pyus_in = NULL, *temp, *pyus_out; PyObject *ratio = NULL; + _Py_identifier(as_integer_ratio); pyus_in = delta_to_microseconds(delta); if (pyus_in == NULL) return NULL; - ratio = PyObject_CallMethod(floatobj, "as_integer_ratio", NULL); + ratio = _PyObject_CallMethodId(floatobj, &PyId_as_integer_ratio, NULL); if (ratio == NULL) goto error; temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 0)); @@ -1666,11 +1677,12 @@ truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *f) PyObject *result = NULL; PyObject *pyus_in = NULL, *temp, *pyus_out; PyObject *ratio = NULL; + _Py_identifier(as_integer_ratio); pyus_in = delta_to_microseconds(delta); if (pyus_in == NULL) return NULL; - ratio = PyObject_CallMethod(f, "as_integer_ratio", NULL); + ratio = _PyObject_CallMethodId(f, &PyId_as_integer_ratio, NULL); if (ratio == NULL) goto error; temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 1)); @@ -2461,6 +2473,7 @@ date_today(PyObject *cls, PyObject *dummy) { PyObject *time; PyObject *result; + _Py_identifier(fromtimestamp); time = time_time(); if (time == NULL) @@ -2472,7 +2485,7 @@ date_today(PyObject *cls, PyObject *dummy) * time.time() delivers; if someone were gonzo about optimization, * date.today() could get away with plain C time(). */ - result = PyObject_CallMethod(cls, "fromtimestamp", "O", time); + result = _PyObject_CallMethodId(cls, &PyId_fromtimestamp, "O", time); Py_DECREF(time); return result; } @@ -2613,7 +2626,9 @@ date_isoformat(PyDateTime_Date *self) static PyObject * date_str(PyDateTime_Date *self) { - return PyObject_CallMethod((PyObject *)self, "isoformat", "()"); + _Py_identifier(isoformat); + + return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "()"); } @@ -2632,13 +2647,14 @@ date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw) PyObject *result; PyObject *tuple; PyObject *format; + _Py_identifier(timetuple); static char *keywords[] = {"format", NULL}; if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords, &format)) return NULL; - tuple = PyObject_CallMethod((PyObject *)self, "timetuple", "()"); + tuple = _PyObject_CallMethodId((PyObject *)self, &PyId_timetuple, "()"); if (tuple == NULL) return NULL; result = wrap_strftime((PyObject *)self, format, tuple, @@ -2651,6 +2667,7 @@ static PyObject * date_format(PyDateTime_Date *self, PyObject *args) { PyObject *format; + _Py_identifier(strftime); if (!PyArg_ParseTuple(args, "U:__format__", &format)) return NULL; @@ -2659,7 +2676,7 @@ date_format(PyDateTime_Date *self, PyObject *args) if (PyUnicode_GetSize(format) == 0) return PyObject_Str((PyObject *)self); - return PyObject_CallMethod((PyObject *)self, "strftime", "O", format); + return _PyObject_CallMethodId((PyObject *)self, &PyId_strftime, "O", format); } /* ISO methods. */ @@ -3573,7 +3590,9 @@ time_repr(PyDateTime_Time *self) static PyObject * time_str(PyDateTime_Time *self) { - return PyObject_CallMethod((PyObject *)self, "isoformat", "()"); + _Py_identifier(isoformat); + + return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "()"); } static PyObject * @@ -4152,7 +4171,9 @@ datetime_now(PyObject *cls, PyObject *args, PyObject *kw) if (self != NULL && tzinfo != Py_None) { /* Convert UTC to tzinfo's zone. */ PyObject *temp = self; - self = PyObject_CallMethod(tzinfo, "fromutc", "O", self); + _Py_identifier(fromutc); + + self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "O", self); Py_DECREF(temp); } return self; @@ -4189,7 +4210,9 @@ datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw) if (self != NULL && tzinfo != Py_None) { /* Convert UTC to tzinfo's zone. */ PyObject *temp = self; - self = PyObject_CallMethod(tzinfo, "fromutc", "O", self); + _Py_identifier(fromutc); + + self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "O", self); Py_DECREF(temp); } return self; @@ -4214,6 +4237,7 @@ datetime_strptime(PyObject *cls, PyObject *args) { static PyObject *module = NULL; PyObject *string, *format; + _Py_identifier(_strptime_datetime); if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format)) return NULL; @@ -4223,8 +4247,8 @@ datetime_strptime(PyObject *cls, PyObject *args) if (module == NULL) return NULL; } - return PyObject_CallMethod(module, "_strptime_datetime", "OOO", - cls, string, format); + return _PyObject_CallMethodId(module, &PyId__strptime_datetime, "OOO", + cls, string, format); } /* Return new datetime from date/datetime and time arguments. */ @@ -4469,7 +4493,9 @@ datetime_repr(PyDateTime_DateTime *self) static PyObject * datetime_str(PyDateTime_DateTime *self) { - return PyObject_CallMethod((PyObject *)self, "isoformat", "(s)", " "); + _Py_identifier(isoformat); + + return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "(s)", " "); } static PyObject * @@ -4676,6 +4702,7 @@ datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw) PyObject *offset; PyObject *temp; PyObject *tzinfo; + _Py_identifier(fromutc); static char *keywords[] = {"tz", NULL}; if (! PyArg_ParseTupleAndKeywords(args, kw, "O!:astimezone", keywords, @@ -4717,7 +4744,7 @@ datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw) Py_DECREF(temp); temp = result; - result = PyObject_CallMethod(tzinfo, "fromutc", "O", temp); + result = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "O", temp); Py_DECREF(temp); return result; diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index 0c64dd5d4b87c5..fcd12716e30a47 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -790,16 +790,18 @@ static PyObject* element_find(ElementObject* self, PyObject* args) { int i; - PyObject* tag; PyObject* namespaces = Py_None; + if (!PyArg_ParseTuple(args, "O|O:find", &tag, &namespaces)) return NULL; - if (checkpath(tag) || namespaces != Py_None) - return PyObject_CallMethod( - elementpath_obj, "find", "OOO", self, tag, namespaces + if (checkpath(tag) || namespaces != Py_None) { + _Py_identifier(find); + return _PyObject_CallMethodId( + elementpath_obj, &PyId_find, "OOO", self, tag, namespaces ); + } if (!self->extra) Py_RETURN_NONE; @@ -820,16 +822,17 @@ static PyObject* element_findtext(ElementObject* self, PyObject* args) { int i; - PyObject* tag; PyObject* default_value = Py_None; PyObject* namespaces = Py_None; + _Py_identifier(findtext); + if (!PyArg_ParseTuple(args, "O|OO:findtext", &tag, &default_value, &namespaces)) return NULL; if (checkpath(tag) || namespaces != Py_None) - return PyObject_CallMethod( - elementpath_obj, "findtext", "OOOO", self, tag, default_value, namespaces + return _PyObject_CallMethodId( + elementpath_obj, &PyId_findtext, "OOOO", self, tag, default_value, namespaces ); if (!self->extra) { @@ -858,16 +861,18 @@ element_findall(ElementObject* self, PyObject* args) { int i; PyObject* out; - PyObject* tag; PyObject* namespaces = Py_None; + if (!PyArg_ParseTuple(args, "O|O:findall", &tag, &namespaces)) return NULL; - if (checkpath(tag) || namespaces != Py_None) - return PyObject_CallMethod( - elementpath_obj, "findall", "OOO", self, tag, namespaces + if (checkpath(tag) || namespaces != Py_None) { + _Py_identifier(findall); + return _PyObject_CallMethodId( + elementpath_obj, &PyId_findall, "OOO", self, tag, namespaces ); + } out = PyList_New(0); if (!out) @@ -895,11 +900,13 @@ element_iterfind(ElementObject* self, PyObject* args) { PyObject* tag; PyObject* namespaces = Py_None; + _Py_identifier(iterfind); + if (!PyArg_ParseTuple(args, "O|O:iterfind", &tag, &namespaces)) return NULL; - return PyObject_CallMethod( - elementpath_obj, "iterfind", "OOO", self, tag, namespaces + return _PyObject_CallMethodId( + elementpath_obj, &PyId_iterfind, "OOO", self, tag, namespaces ); } diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c index 6f5bd48780c02c..f264756f3d3532 100644 --- a/Modules/_io/_iomodule.c +++ b/Modules/_io/_iomodule.c @@ -308,6 +308,9 @@ io_open(PyObject *self, PyObject *args, PyObject *kwds) PyObject *raw, *modeobj = NULL, *buffer = NULL, *wrapper = NULL; + _Py_identifier(isatty); + _Py_identifier(fileno); + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|sizzzi:open", kwlist, &file, &mode, &buffering, &encoding, &errors, &newline, @@ -421,7 +424,7 @@ io_open(PyObject *self, PyObject *args, PyObject *kwds) /* buffering */ { - PyObject *res = PyObject_CallMethod(raw, "isatty", NULL); + PyObject *res = _PyObject_CallMethodId(raw, &PyId_isatty, NULL); if (res == NULL) goto error; isatty = PyLong_AsLong(res); @@ -443,7 +446,7 @@ io_open(PyObject *self, PyObject *args, PyObject *kwds) { struct stat st; long fileno; - PyObject *res = PyObject_CallMethod(raw, "fileno", NULL); + PyObject *res = _PyObject_CallMethodId(raw, &PyId_fileno, NULL); if (res == NULL) goto error; diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index 86f7412c26e566..6ef2c206a239d9 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -13,6 +13,18 @@ #include "pythread.h" #include "_iomodule.h" +_Py_identifier(close); +_Py_identifier(_dealloc_warn); +_Py_identifier(flush); +_Py_identifier(isatty); +_Py_identifier(peek); +_Py_identifier(read); +_Py_identifier(read1); +_Py_identifier(readable); +_Py_identifier(readinto); +_Py_identifier(writable); +_Py_identifier(write); + /* * BufferedIOBase class, inherits from IOBase. */ @@ -38,12 +50,13 @@ bufferediobase_readinto(PyObject *self, PyObject *args) Py_buffer buf; Py_ssize_t len; PyObject *data; + _Py_identifier(read); if (!PyArg_ParseTuple(args, "w*:readinto", &buf)) { return NULL; } - data = PyObject_CallMethod(self, "read", "n", buf.len); + data = _PyObject_CallMethodId(self, &PyId_read, "n", buf.len); if (data == NULL) goto error; @@ -410,7 +423,7 @@ buffered_dealloc_warn(buffered *self, PyObject *source) { if (self->ok && self->raw) { PyObject *r; - r = PyObject_CallMethod(self->raw, "_dealloc_warn", "O", source); + r = _PyObject_CallMethodId(self->raw, &PyId__dealloc_warn, "O", source); if (r) Py_DECREF(r); else @@ -2216,13 +2229,13 @@ bufferedrwpair_dealloc(rwpair *self) } static PyObject * -_forward_call(buffered *self, const char *name, PyObject *args) +_forward_call(buffered *self, _Py_Identifier *name, PyObject *args) { - PyObject *func = PyObject_GetAttrString((PyObject *)self, name); + PyObject *func = _PyObject_GetAttrId((PyObject *)self, name); PyObject *ret; if (func == NULL) { - PyErr_SetString(PyExc_AttributeError, name); + PyErr_SetString(PyExc_AttributeError, name->string); return NULL; } @@ -2234,66 +2247,66 @@ _forward_call(buffered *self, const char *name, PyObject *args) static PyObject * bufferedrwpair_read(rwpair *self, PyObject *args) { - return _forward_call(self->reader, "read", args); + return _forward_call(self->reader, &PyId_read, args); } static PyObject * bufferedrwpair_peek(rwpair *self, PyObject *args) { - return _forward_call(self->reader, "peek", args); + return _forward_call(self->reader, &PyId_peek, args); } static PyObject * bufferedrwpair_read1(rwpair *self, PyObject *args) { - return _forward_call(self->reader, "read1", args); + return _forward_call(self->reader, &PyId_read1, args); } static PyObject * bufferedrwpair_readinto(rwpair *self, PyObject *args) { - return _forward_call(self->reader, "readinto", args); + return _forward_call(self->reader, &PyId_readinto, args); } static PyObject * bufferedrwpair_write(rwpair *self, PyObject *args) { - return _forward_call(self->writer, "write", args); + return _forward_call(self->writer, &PyId_write, args); } static PyObject * bufferedrwpair_flush(rwpair *self, PyObject *args) { - return _forward_call(self->writer, "flush", args); + return _forward_call(self->writer, &PyId_flush, args); } static PyObject * bufferedrwpair_readable(rwpair *self, PyObject *args) { - return _forward_call(self->reader, "readable", args); + return _forward_call(self->reader, &PyId_readable, args); } static PyObject * bufferedrwpair_writable(rwpair *self, PyObject *args) { - return _forward_call(self->writer, "writable", args); + return _forward_call(self->writer, &PyId_writable, args); } static PyObject * bufferedrwpair_close(rwpair *self, PyObject *args) { - PyObject *ret = _forward_call(self->writer, "close", args); + PyObject *ret = _forward_call(self->writer, &PyId_close, args); if (ret == NULL) return NULL; Py_DECREF(ret); - return _forward_call(self->reader, "close", args); + return _forward_call(self->reader, &PyId_close, args); } static PyObject * bufferedrwpair_isatty(rwpair *self, PyObject *args) { - PyObject *ret = _forward_call(self->writer, "isatty", args); + PyObject *ret = _forward_call(self->writer, &PyId_isatty, args); if (ret != Py_False) { /* either True or exception */ @@ -2301,7 +2314,7 @@ bufferedrwpair_isatty(rwpair *self, PyObject *args) } Py_DECREF(ret); - return _forward_call(self->reader, "isatty", args); + return _forward_call(self->reader, &PyId_isatty, args); } static PyObject * diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c index 2bf8933b57beb0..a16d13cc60cf94 100644 --- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@ -128,6 +128,7 @@ internal_close(fileio *self) static PyObject * fileio_close(fileio *self) { + _Py_identifier(close); if (!self->closefd) { self->fd = -1; Py_RETURN_NONE; @@ -143,8 +144,8 @@ fileio_close(fileio *self) if (errno < 0) return NULL; - return PyObject_CallMethod((PyObject*)&PyRawIOBase_Type, - "close", "O", self); + return _PyObject_CallMethodId((PyObject*)&PyRawIOBase_Type, + &PyId_close, "O", self); } static PyObject * diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c index 35c7cdd480dccf..6a94a04f4eb1ca 100644 --- a/Modules/_io/iobase.c +++ b/Modules/_io/iobase.c @@ -97,7 +97,9 @@ PyDoc_STRVAR(iobase_tell_doc, static PyObject * iobase_tell(PyObject *self, PyObject *args) { - return PyObject_CallMethod(self, "seek", "ii", 0, 1); + _Py_identifier(seek); + + return _PyObject_CallMethodId(self, &PyId_seek, "ii", 0, 1); } PyDoc_STRVAR(iobase_truncate_doc, @@ -464,6 +466,7 @@ iobase_readline(PyObject *self, PyObject *args) int has_peek = 0; PyObject *buffer, *result; Py_ssize_t old_size = -1; + _Py_identifier(read); if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit)) { return NULL; @@ -481,7 +484,9 @@ iobase_readline(PyObject *self, PyObject *args) PyObject *b; if (has_peek) { - PyObject *readahead = PyObject_CallMethod(self, "peek", "i", 1); + _Py_identifier(peek); + PyObject *readahead = _PyObject_CallMethodId(self, &PyId_peek, "i", 1); + if (readahead == NULL) goto fail; if (!PyBytes_Check(readahead)) { @@ -515,7 +520,7 @@ iobase_readline(PyObject *self, PyObject *args) Py_DECREF(readahead); } - b = PyObject_CallMethod(self, "read", "n", nreadahead); + b = _PyObject_CallMethodId(self, &PyId_read, "n", nreadahead); if (b == NULL) goto fail; if (!PyBytes_Check(b)) { @@ -601,7 +606,9 @@ iobase_readlines(PyObject *self, PyObject *args) /* XXX special-casing this made sense in the Python version in order to remove the bytecode interpretation overhead, but it could probably be removed here. */ - PyObject *ret = PyObject_CallMethod(result, "extend", "O", self); + _Py_identifier(extend); + PyObject *ret = _PyObject_CallMethodId(result, &PyId_extend, "O", self); + if (ret == NULL) { Py_DECREF(result); return NULL; @@ -781,8 +788,11 @@ rawiobase_read(PyObject *self, PyObject *args) return NULL; } - if (n < 0) - return PyObject_CallMethod(self, "readall", NULL); + if (n < 0) { + _Py_identifier(readall); + + return _PyObject_CallMethodId(self, &PyId_readall, NULL); + } /* TODO: allocate a bytes object directly instead and manually construct a writable memoryview pointing to it. */ @@ -823,8 +833,9 @@ rawiobase_readall(PyObject *self, PyObject *args) return NULL; while (1) { - PyObject *data = PyObject_CallMethod(self, "read", - "i", DEFAULT_BUFFER_SIZE); + _Py_identifier(read); + PyObject *data = _PyObject_CallMethodId(self, &PyId_read, + "i", DEFAULT_BUFFER_SIZE); if (!data) { Py_DECREF(chunks); return NULL; diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index aa29ffb4136dca..2ded719e9c70b5 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -11,6 +11,24 @@ #include "structmember.h" #include "_iomodule.h" +_Py_identifier(close); +_Py_identifier(_dealloc_warn); +_Py_identifier(decode); +_Py_identifier(device_encoding); +_Py_identifier(fileno); +_Py_identifier(flush); +_Py_identifier(getpreferredencoding); +_Py_identifier(isatty); +_Py_identifier(read); +_Py_identifier(readable); +_Py_identifier(replace); +_Py_identifier(reset); +_Py_identifier(seek); +_Py_identifier(seekable); +_Py_identifier(setstate); +_Py_identifier(tell); +_Py_identifier(writable); + /* TextIOBase */ PyDoc_STRVAR(textiobase_doc, @@ -501,8 +519,8 @@ incrementalnewlinedecoder_setstate(nldecoder_object *self, PyObject *state) flag >>= 1; if (self->decoder != Py_None) - return PyObject_CallMethod(self->decoder, - "setstate", "((OK))", buffer, flag); + return _PyObject_CallMethodId(self->decoder, + &PyId_setstate, "((OK))", buffer, flag); else Py_RETURN_NONE; } @@ -842,7 +860,7 @@ textiowrapper_init(textio *self, PyObject *args, PyObject *kwds) if (encoding == NULL) { /* Try os.device_encoding(fileno) */ PyObject *fileno; - fileno = PyObject_CallMethod(buffer, "fileno", NULL); + fileno = _PyObject_CallMethodId(buffer, &PyId_fileno, NULL); /* Ignore only AttributeError and UnsupportedOperation */ if (fileno == NULL) { if (PyErr_ExceptionMatches(PyExc_AttributeError) || @@ -854,9 +872,9 @@ textiowrapper_init(textio *self, PyObject *args, PyObject *kwds) } } else { - self->encoding = PyObject_CallMethod(state->os_module, - "device_encoding", - "N", fileno); + self->encoding = _PyObject_CallMethodId(state->os_module, + &PyId_device_encoding, + "N", fileno); if (self->encoding == NULL) goto error; else if (!PyUnicode_Check(self->encoding)) @@ -873,8 +891,8 @@ textiowrapper_init(textio *self, PyObject *args, PyObject *kwds) } else { use_locale: - self->encoding = PyObject_CallMethod( - state->locale_module, "getpreferredencoding", NULL); + self->encoding = _PyObject_CallMethodId( + state->locale_module, &PyId_getpreferredencoding, NULL); if (self->encoding == NULL) { catch_ImportError: /* @@ -939,7 +957,7 @@ textiowrapper_init(textio *self, PyObject *args, PyObject *kwds) #endif /* Build the decoder object */ - res = PyObject_CallMethod(buffer, "readable", NULL); + res = _PyObject_CallMethodId(buffer, &PyId_readable, NULL); if (res == NULL) goto error; r = PyObject_IsTrue(res); @@ -964,7 +982,7 @@ textiowrapper_init(textio *self, PyObject *args, PyObject *kwds) } /* Build the encoder object */ - res = PyObject_CallMethod(buffer, "writable", NULL); + res = _PyObject_CallMethodId(buffer, &PyId_writable, NULL); if (res == NULL) goto error; r = PyObject_IsTrue(res); @@ -1022,7 +1040,7 @@ textiowrapper_init(textio *self, PyObject *args, PyObject *kwds) Py_DECREF(raw); } - res = PyObject_CallMethod(buffer, "seekable", NULL); + res = _PyObject_CallMethodId(buffer, &PyId_seekable, NULL); if (res == NULL) goto error; self->seekable = self->telling = PyObject_IsTrue(res); @@ -1255,8 +1273,8 @@ textiowrapper_write(textio *self, PyObject *args) haslf = 1; if (haslf && self->writetranslate && self->writenl != NULL) { - PyObject *newtext = PyObject_CallMethod( - text, "replace", "ss", "\n", self->writenl); + PyObject *newtext = _PyObject_CallMethodId( + text, &PyId_replace, "ss", "\n", self->writenl); Py_DECREF(text); if (newtext == NULL) return NULL; @@ -1311,7 +1329,7 @@ textiowrapper_write(textio *self, PyObject *args) Py_CLEAR(self->snapshot); if (self->decoder) { - ret = PyObject_CallMethod(self->decoder, "reset", NULL); + ret = _PyObject_CallMethodId(self->decoder, &PyId_reset, NULL); if (ret == NULL) return NULL; Py_DECREF(ret); @@ -1490,7 +1508,7 @@ textiowrapper_read(textio *self, PyObject *args) if (n < 0) { /* Read everything */ - PyObject *bytes = PyObject_CallMethod(self->buffer, "read", NULL); + PyObject *bytes = _PyObject_CallMethodId(self->buffer, &PyId_read, NULL); PyObject *decoded; if (bytes == NULL) goto fail; @@ -1940,8 +1958,8 @@ _textiowrapper_decoder_setstate(textio *self, cookie_type *cookie) if (cookie->start_pos == 0 && cookie->dec_flags == 0) res = PyObject_CallMethodObjArgs(self->decoder, _PyIO_str_reset, NULL); else - res = PyObject_CallMethod(self->decoder, "setstate", - "((yi))", "", cookie->dec_flags); + res = _PyObject_CallMethodId(self->decoder, &PyId_setstate, + "((yi))", "", cookie->dec_flags); if (res == NULL) return -1; Py_DECREF(res); @@ -2005,13 +2023,12 @@ textiowrapper_seek(textio *self, PyObject *args) * sync the underlying buffer with the current position. */ Py_DECREF(cookieObj); - cookieObj = PyObject_CallMethod((PyObject *)self, "tell", NULL); + cookieObj = _PyObject_CallMethodId((PyObject *)self, &PyId_tell, NULL); if (cookieObj == NULL) goto fail; } else if (whence == 2) { /* seek relative to end of file */ - cmp = PyObject_RichCompareBool(cookieObj, _PyIO_zero, Py_EQ); if (cmp < 0) goto fail; @@ -2021,7 +2038,7 @@ textiowrapper_seek(textio *self, PyObject *args) goto fail; } - res = PyObject_CallMethod((PyObject *)self, "flush", NULL); + res = _PyObject_CallMethodId((PyObject *)self, &PyId_flush, NULL); if (res == NULL) goto fail; Py_DECREF(res); @@ -2029,13 +2046,13 @@ textiowrapper_seek(textio *self, PyObject *args) textiowrapper_set_decoded_chars(self, NULL); Py_CLEAR(self->snapshot); if (self->decoder) { - res = PyObject_CallMethod(self->decoder, "reset", NULL); + res = _PyObject_CallMethodId(self->decoder, &PyId_reset, NULL); if (res == NULL) goto fail; Py_DECREF(res); } - res = PyObject_CallMethod(self->buffer, "seek", "ii", 0, 2); + res = _PyObject_CallMethodId(self->buffer, &PyId_seek, "ii", 0, 2); Py_XDECREF(cookieObj); return res; } @@ -2088,8 +2105,8 @@ textiowrapper_seek(textio *self, PyObject *args) if (cookie.chars_to_skip) { /* Just like _read_chunk, feed the decoder and save a snapshot. */ - PyObject *input_chunk = PyObject_CallMethod( - self->buffer, "read", "i", cookie.bytes_to_feed); + PyObject *input_chunk = _PyObject_CallMethodId( + self->buffer, &PyId_read, "i", cookie.bytes_to_feed); PyObject *decoded; if (input_chunk == NULL) @@ -2103,8 +2120,8 @@ textiowrapper_seek(textio *self, PyObject *args) goto fail; } - decoded = PyObject_CallMethod(self->decoder, "decode", - "Oi", input_chunk, (int)cookie.need_eof); + decoded = _PyObject_CallMethodId(self->decoder, &PyId_decode, + "Oi", input_chunk, (int)cookie.need_eof); if (decoded == NULL) goto fail; @@ -2170,12 +2187,12 @@ textiowrapper_tell(textio *self, PyObject *args) if (_textiowrapper_writeflush(self) < 0) return NULL; - res = PyObject_CallMethod((PyObject *)self, "flush", NULL); + res = _PyObject_CallMethodId((PyObject *)self, &PyId_flush, NULL); if (res == NULL) goto fail; Py_DECREF(res); - posobj = PyObject_CallMethod(self->buffer, "tell", NULL); + posobj = _PyObject_CallMethodId(self->buffer, &PyId_tell, NULL); if (posobj == NULL) goto fail; @@ -2229,8 +2246,8 @@ textiowrapper_tell(textio *self, PyObject *args) /* TODO: replace assert with exception */ #define DECODER_DECODE(start, len, res) do { \ - PyObject *_decoded = PyObject_CallMethod( \ - self->decoder, "decode", "y#", start, len); \ + PyObject *_decoded = _PyObject_CallMethodId( \ + self->decoder, &PyId_decode, "y#", start, len); \ if (_decoded == NULL) \ goto fail; \ assert (PyUnicode_Check(_decoded)); \ @@ -2312,8 +2329,8 @@ textiowrapper_tell(textio *self, PyObject *args) } if (input == input_end) { /* We didn't get enough decoded data; signal EOF to get more. */ - PyObject *decoded = PyObject_CallMethod( - self->decoder, "decode", "yi", "", /* final = */ 1); + PyObject *decoded = _PyObject_CallMethodId( + self->decoder, &PyId_decode, "yi", "", /* final = */ 1); if (decoded == NULL) goto fail; assert (PyUnicode_Check(decoded)); @@ -2329,7 +2346,7 @@ textiowrapper_tell(textio *self, PyObject *args) } finally: - res = PyObject_CallMethod(self->decoder, "setstate", "(O)", saved_state); + res = _PyObject_CallMethodId(self->decoder, &PyId_setstate, "(O)", saved_state); Py_DECREF(saved_state); if (res == NULL) return NULL; @@ -2344,7 +2361,7 @@ textiowrapper_tell(textio *self, PyObject *args) PyObject *type, *value, *traceback; PyErr_Fetch(&type, &value, &traceback); - res = PyObject_CallMethod(self->decoder, "setstate", "(O)", saved_state); + res = _PyObject_CallMethodId(self->decoder, &PyId_setstate, "(O)", saved_state); Py_DECREF(saved_state); if (res == NULL) return NULL; @@ -2432,35 +2449,35 @@ static PyObject * textiowrapper_fileno(textio *self, PyObject *args) { CHECK_INITIALIZED(self); - return PyObject_CallMethod(self->buffer, "fileno", NULL); + return _PyObject_CallMethodId(self->buffer, &PyId_fileno, NULL); } static PyObject * textiowrapper_seekable(textio *self, PyObject *args) { CHECK_INITIALIZED(self); - return PyObject_CallMethod(self->buffer, "seekable", NULL); + return _PyObject_CallMethodId(self->buffer, &PyId_seekable, NULL); } static PyObject * textiowrapper_readable(textio *self, PyObject *args) { CHECK_INITIALIZED(self); - return PyObject_CallMethod(self->buffer, "readable", NULL); + return _PyObject_CallMethodId(self->buffer, &PyId_readable, NULL); } static PyObject * textiowrapper_writable(textio *self, PyObject *args) { CHECK_INITIALIZED(self); - return PyObject_CallMethod(self->buffer, "writable", NULL); + return _PyObject_CallMethodId(self->buffer, &PyId_writable, NULL); } static PyObject * textiowrapper_isatty(textio *self, PyObject *args) { CHECK_INITIALIZED(self); - return PyObject_CallMethod(self->buffer, "isatty", NULL); + return _PyObject_CallMethodId(self->buffer, &PyId_isatty, NULL); } static PyObject * @@ -2479,7 +2496,7 @@ textiowrapper_flush(textio *self, PyObject *args) self->telling = self->seekable; if (_textiowrapper_writeflush(self) < 0) return NULL; - return PyObject_CallMethod(self->buffer, "flush", NULL); + return _PyObject_CallMethodId(self->buffer, &PyId_flush, NULL); } static PyObject * @@ -2502,20 +2519,20 @@ textiowrapper_close(textio *self, PyObject *args) } else { if (self->deallocating) { - res = PyObject_CallMethod(self->buffer, "_dealloc_warn", "O", self); + res = _PyObject_CallMethodId(self->buffer, &PyId__dealloc_warn, "O", self); if (res) Py_DECREF(res); else PyErr_Clear(); } - res = PyObject_CallMethod((PyObject *)self, "flush", NULL); + res = _PyObject_CallMethodId((PyObject *)self, &PyId_flush, NULL); if (res == NULL) { return NULL; } else Py_DECREF(res); - return PyObject_CallMethod(self->buffer, "close", NULL); + return _PyObject_CallMethodId(self->buffer, &PyId_close, NULL); } } diff --git a/Modules/_pickle.c b/Modules/_pickle.c index 0b10009334ffb5..e53abc888e12a4 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -2488,7 +2488,9 @@ save_dict(PicklerObject *self, PyObject *obj) status = batch_dict_exact(self, obj); Py_LeaveRecursiveCall(); } else { - items = PyObject_CallMethod(obj, "items", "()"); + _Py_identifier(items); + + items = _PyObject_CallMethodId(obj, &PyId_items, "()"); if (items == NULL) goto error; iter = PyObject_GetIter(items); @@ -3774,8 +3776,10 @@ static PyTypeObject Pickler_Type = { static PyObject * find_class(UnpicklerObject *self, PyObject *module_name, PyObject *global_name) { - return PyObject_CallMethod((PyObject *)self, "find_class", "OO", - module_name, global_name); + _Py_identifier(find_class); + + return _PyObject_CallMethodId((PyObject *)self, &PyId_find_class, "OO", + module_name, global_name); } static Py_ssize_t @@ -4388,7 +4392,9 @@ instantiate(PyObject *cls, PyObject *args) result = PyObject_CallObject(cls, args); } else { - result = PyObject_CallMethod(cls, "__new__", "O", cls); + _Py_identifier(__new__); + + result = _PyObject_CallMethodId(cls, &PyId___new__, "O", cls); } return result; } diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c index bc2f72c7a76b3c..e6a9283c0a4e34 100644 --- a/Modules/_posixsubprocess.c +++ b/Modules/_posixsubprocess.c @@ -18,7 +18,9 @@ static long max_fd; static int _enable_gc(PyObject *gc_module) { PyObject *result; - result = PyObject_CallMethod(gc_module, "enable", NULL); + _Py_identifier(enable); + + result = _PyObject_CallMethodId(gc_module, &PyId_enable, NULL); if (result == NULL) return 1; Py_DECREF(result); @@ -249,10 +251,13 @@ subprocess_fork_exec(PyObject* self, PyObject *args) /* We need to call gc.disable() when we'll be calling preexec_fn */ if (preexec_fn != Py_None) { PyObject *result; + _Py_identifier(isenabled); + _Py_identifier(disable); + gc_module = PyImport_ImportModule("gc"); if (gc_module == NULL) return NULL; - result = PyObject_CallMethod(gc_module, "isenabled", NULL); + result = _PyObject_CallMethodId(gc_module, &PyId_isenabled, NULL); if (result == NULL) { Py_DECREF(gc_module); return NULL; @@ -263,7 +268,7 @@ subprocess_fork_exec(PyObject* self, PyObject *args) Py_DECREF(gc_module); return NULL; } - result = PyObject_CallMethod(gc_module, "disable", NULL); + result = _PyObject_CallMethodId(gc_module, &PyId_disable, NULL); if (result == NULL) { Py_DECREF(gc_module); return NULL; diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 310a27c42a2a3a..c2f218f17f3280 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -675,6 +675,7 @@ void _pysqlite_final_callback(sqlite3_context* context) { PyObject* function_result = NULL; PyObject** aggregate_instance; + _Py_identifier(finalize); #ifdef WITH_THREAD PyGILState_STATE threadstate; @@ -690,7 +691,7 @@ void _pysqlite_final_callback(sqlite3_context* context) goto error; } - function_result = PyObject_CallMethod(*aggregate_instance, "finalize", ""); + function_result = _PyObject_CallMethodId(*aggregate_instance, &PyId_finalize, ""); if (!function_result) { if (_enable_callback_tracebacks) { PyErr_Print(); @@ -1230,8 +1231,9 @@ PyObject* pysqlite_connection_execute(pysqlite_Connection* self, PyObject* args, PyObject* cursor = 0; PyObject* result = 0; PyObject* method = 0; + _Py_identifier(cursor); - cursor = PyObject_CallMethod((PyObject*)self, "cursor", ""); + cursor = _PyObject_CallMethodId((PyObject*)self, &PyId_cursor, ""); if (!cursor) { goto error; } @@ -1259,8 +1261,9 @@ PyObject* pysqlite_connection_executemany(pysqlite_Connection* self, PyObject* a PyObject* cursor = 0; PyObject* result = 0; PyObject* method = 0; + _Py_identifier(cursor); - cursor = PyObject_CallMethod((PyObject*)self, "cursor", ""); + cursor = _PyObject_CallMethodId((PyObject*)self, &PyId_cursor, ""); if (!cursor) { goto error; } @@ -1288,8 +1291,9 @@ PyObject* pysqlite_connection_executescript(pysqlite_Connection* self, PyObject* PyObject* cursor = 0; PyObject* result = 0; PyObject* method = 0; + _Py_identifier(cursor); - cursor = PyObject_CallMethod((PyObject*)self, "cursor", ""); + cursor = _PyObject_CallMethodId((PyObject*)self, &PyId_cursor, ""); if (!cursor) { goto error; } @@ -1437,6 +1441,7 @@ pysqlite_connection_create_collation(pysqlite_Connection* self, PyObject* args) PyObject* name; PyObject* retval; Py_ssize_t i, len; + _Py_identifier(upper); char *uppercase_name_str; int rc; unsigned int kind; @@ -1450,7 +1455,7 @@ pysqlite_connection_create_collation(pysqlite_Connection* self, PyObject* args) goto finally; } - uppercase_name = PyObject_CallMethod(name, "upper", ""); + uppercase_name = _PyObject_CallMethodId(name, &PyId_upper, ""); if (!uppercase_name) { goto finally; } diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 264ae451ad5b4d..b47fed4ccb0cd0 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -150,8 +150,9 @@ PyObject* _pysqlite_get_converter(PyObject* key) { PyObject* upcase_key; PyObject* retval; + _Py_identifier(upper); - upcase_key = PyObject_CallMethod(key, "upper", ""); + upcase_key = _PyObject_CallMethodId(key, &PyId_upper, ""); if (!upcase_key) { return NULL; } diff --git a/Modules/_sqlite/microprotocols.c b/Modules/_sqlite/microprotocols.c index c730afa7bd7ad3..c0f5e224f2b4e6 100644 --- a/Modules/_sqlite/microprotocols.c +++ b/Modules/_sqlite/microprotocols.c @@ -95,7 +95,9 @@ pysqlite_microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt) /* try to have the protocol adapt this object*/ if (PyObject_HasAttrString(proto, "__adapt__")) { - PyObject *adapted = PyObject_CallMethod(proto, "__adapt__", "O", obj); + _Py_identifier(__adapt__); + PyObject *adapted = _PyObject_CallMethodId(proto, &PyId___adapt__, "O", obj); + if (adapted) { if (adapted != Py_None) { return adapted; @@ -110,7 +112,9 @@ pysqlite_microprotocols_adapt(PyObject *obj, PyObject *proto, PyObject *alt) /* and finally try to have the object adapt itself */ if (PyObject_HasAttrString(obj, "__conform__")) { - PyObject *adapted = PyObject_CallMethod(obj, "__conform__","O", proto); + _Py_identifier(__conform__); + PyObject *adapted = _PyObject_CallMethodId(obj, &PyId___conform__,"O", proto); + if (adapted) { if (adapted != Py_None) { return adapted; diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c index cbc3b8e90bea2b..20e1ec72aa2e38 100644 --- a/Modules/_sqlite/module.c +++ b/Modules/_sqlite/module.c @@ -179,13 +179,14 @@ static PyObject* module_register_converter(PyObject* self, PyObject* args) PyObject* name = NULL; PyObject* callable; PyObject* retval = NULL; + _Py_identifier(upper); if (!PyArg_ParseTuple(args, "UO", &orig_name, &callable)) { return NULL; } /* convert the name to upper case */ - name = PyObject_CallMethod(orig_name, "upper", ""); + name = _PyObject_CallMethodId(orig_name, &PyId_upper, ""); if (!name) { goto error; } diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index 00325940b7e7ae..6cedee4ef2c3ce 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -1253,6 +1253,7 @@ array_fromfile(arrayobject *self, PyObject *args) PyObject *f, *b, *res; Py_ssize_t itemsize = self->ob_descr->itemsize; Py_ssize_t n, nbytes; + _Py_identifier(read); int not_enough_bytes; if (!PyArg_ParseTuple(args, "On:fromfile", &f, &n)) @@ -1264,7 +1265,7 @@ array_fromfile(arrayobject *self, PyObject *args) return NULL; } - b = PyObject_CallMethod(f, "read", "n", nbytes); + b = _PyObject_CallMethodId(f, &PyId_read, "n", nbytes); if (b == NULL) return NULL; @@ -1321,12 +1322,14 @@ array_tofile(arrayobject *self, PyObject *f) char* ptr = self->ob_item + i*BLOCKSIZE; Py_ssize_t size = BLOCKSIZE; PyObject *bytes, *res; + _Py_identifier(write); + if (i*BLOCKSIZE + size > nbytes) size = nbytes - i*BLOCKSIZE; bytes = PyBytes_FromStringAndSize(ptr, size); if (bytes == NULL) return NULL; - res = PyObject_CallMethod(f, "write", "O", bytes); + res = _PyObject_CallMethodId(f, &PyId_write, "O", bytes); Py_DECREF(bytes); if (res == NULL) return NULL; diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c index 1b37845285f2ce..8635a568b43c50 100644 --- a/Modules/cjkcodecs/multibytecodec.c +++ b/Modules/cjkcodecs/multibytecodec.c @@ -1579,12 +1579,13 @@ mbstreamwriter_iwrite(MultibyteStreamWriterObject *self, PyObject *unistr) { PyObject *str, *wr; + _Py_identifier(write); str = encoder_encode_stateful(STATEFUL_ECTX(self), unistr, 0); if (str == NULL) return -1; - wr = PyObject_CallMethod(self->stream, "write", "O", str); + wr = _PyObject_CallMethodId(self->stream, &PyId_write, "O", str); Py_DECREF(str); if (wr == NULL) return -1; @@ -1650,7 +1651,9 @@ mbstreamwriter_reset(MultibyteStreamWriterObject *self) assert(PyBytes_Check(pwrt)); if (PyBytes_Size(pwrt) > 0) { PyObject *wr; - wr = PyObject_CallMethod(self->stream, "write", "O", pwrt); + _Py_identifier(write); + + wr = _PyObject_CallMethodId(self->stream, &PyId_write, "O", pwrt); if (wr == NULL) { Py_DECREF(pwrt); return NULL; diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c index 06f7f2e8c3a381..11d534000425f7 100644 --- a/Modules/faulthandler.c +++ b/Modules/faulthandler.c @@ -146,6 +146,8 @@ static PyObject* faulthandler_get_fileno(PyObject *file, int *p_fd) { PyObject *result; + _Py_identifier(fileno); + _Py_identifier(flush); long fd_long; int fd; @@ -157,7 +159,7 @@ faulthandler_get_fileno(PyObject *file, int *p_fd) } } - result = PyObject_CallMethod(file, "fileno", ""); + result = _PyObject_CallMethodId(file, &PyId_fileno, ""); if (result == NULL) return NULL; @@ -175,7 +177,7 @@ faulthandler_get_fileno(PyObject *file, int *p_fd) return NULL; } - result = PyObject_CallMethod(file, "flush", ""); + result = _PyObject_CallMethodId(file, &PyId_flush, ""); if (result != NULL) Py_DECREF(result); else { @@ -1197,6 +1199,7 @@ static int faulthandler_env_options(void) { PyObject *xoptions, *key, *module, *res; + _Py_identifier(enable); if (!Py_GETENV("PYTHONFAULTHANDLER")) { int has_key; @@ -1219,7 +1222,7 @@ faulthandler_env_options(void) if (module == NULL) { return -1; } - res = PyObject_CallMethod(module, "enable", ""); + res = _PyObject_CallMethodId(module, &PyId_enable, ""); Py_DECREF(module); if (res == NULL) return -1; diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index b05675c84a76d1..2533de61a28465 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -769,7 +769,9 @@ get_time(void) { double result = 0; if (tmod != NULL) { - PyObject *f = PyObject_CallMethod(tmod, "time", NULL); + _Py_identifier(time); + + PyObject *f = _PyObject_CallMethodId(tmod, &PyId_time, NULL); if (f == NULL) { PyErr_Clear(); } diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index d0897c3eb956f3..4f81fe29d23fbb 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -654,7 +654,9 @@ tee(PyObject *self, PyObject *args) copyable = it; PyTuple_SET_ITEM(result, 0, copyable); for (i=1 ; istring); + return 0; } - else - args = PyTuple_New(0); - retval = call_function_tail(func, args); + va_start(va, format); + retval = callmethod(func, format, va, 0); + va_end(va); + return retval; +} - exit: - /* args gets consumed in call_function_tail */ - Py_XDECREF(func); +PyObject * +_PyObject_CallMethod_SizeT(PyObject *o, char *name, char *format, ...) +{ + va_list va; + PyObject *func = NULL; + PyObject *retval; + + if (o == NULL || name == NULL) + return null_error(); + func = PyObject_GetAttrString(o, name); + if (func == NULL) { + PyErr_SetString(PyExc_AttributeError, name); + return 0; + } + va_start(va, format); + retval = callmethod(func, format, va, 1); + va_end(va); return retval; } +PyObject * +_PyObject_CallMethodId_SizeT(PyObject *o, _Py_Identifier *name, char *format, ...) +{ + va_list va; + PyObject *func = NULL; + PyObject *retval; + + if (o == NULL || name == NULL) + return null_error(); + + func = _PyObject_GetAttrId(o, name); + if (func == NULL) { + PyErr_SetString(PyExc_AttributeError, name->string); + return NULL; + } + va_start(va, format); + retval = callmethod(func, format, va, 1); + va_end(va); + return retval; +} static PyObject * objargs_mktuple(va_list va) diff --git a/Objects/descrobject.c b/Objects/descrobject.c index a786bae14343c1..046eebdaf312a0 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -703,34 +703,39 @@ static PyObject * proxy_get(proxyobject *pp, PyObject *args) { PyObject *key, *def = Py_None; + _Py_identifier(get); if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &def)) return NULL; - return PyObject_CallMethod(pp->dict, "get", "(OO)", key, def); + return _PyObject_CallMethodId(pp->dict, &PyId_get, "(OO)", key, def); } static PyObject * proxy_keys(proxyobject *pp) { - return PyObject_CallMethod(pp->dict, "keys", NULL); + _Py_identifier(keys); + return _PyObject_CallMethodId(pp->dict, &PyId_keys, NULL); } static PyObject * proxy_values(proxyobject *pp) { - return PyObject_CallMethod(pp->dict, "values", NULL); + _Py_identifier(values); + return _PyObject_CallMethodId(pp->dict, &PyId_values, NULL); } static PyObject * proxy_items(proxyobject *pp) { - return PyObject_CallMethod(pp->dict, "items", NULL); + _Py_identifier(items); + return _PyObject_CallMethodId(pp->dict, &PyId_items, NULL); } static PyObject * proxy_copy(proxyobject *pp) { - return PyObject_CallMethod(pp->dict, "copy", NULL); + _Py_identifier(copy); + return _PyObject_CallMethodId(pp->dict, &PyId_copy, NULL); } static PyMethodDef proxy_methods[] = { diff --git a/Objects/dictobject.c b/Objects/dictobject.c index c4265da769e671..220e621f077d48 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -2707,10 +2707,12 @@ dictviews_sub(PyObject* self, PyObject *other) { PyObject *result = PySet_New(self); PyObject *tmp; + _Py_identifier(difference_update); + if (result == NULL) return NULL; - tmp = PyObject_CallMethod(result, "difference_update", "O", other); + tmp = _PyObject_CallMethodId(result, &PyId_difference_update, "O", other); if (tmp == NULL) { Py_DECREF(result); return NULL; @@ -2725,10 +2727,12 @@ dictviews_and(PyObject* self, PyObject *other) { PyObject *result = PySet_New(self); PyObject *tmp; + _Py_identifier(intersection_update); + if (result == NULL) return NULL; - tmp = PyObject_CallMethod(result, "intersection_update", "O", other); + tmp = _PyObject_CallMethodId(result, &PyId_intersection_update, "O", other); if (tmp == NULL) { Py_DECREF(result); return NULL; @@ -2761,10 +2765,12 @@ dictviews_xor(PyObject* self, PyObject *other) { PyObject *result = PySet_New(self); PyObject *tmp; + _Py_identifier(symmetric_difference_update); + if (result == NULL) return NULL; - tmp = PyObject_CallMethod(result, "symmetric_difference_update", "O", + tmp = _PyObject_CallMethodId(result, &PyId_symmetric_difference_update, "O", other); if (tmp == NULL) { Py_DECREF(result); diff --git a/Objects/fileobject.c b/Objects/fileobject.c index 64215430c5ac47..f3006d0fb5db91 100644 --- a/Objects/fileobject.c +++ b/Objects/fileobject.c @@ -30,11 +30,12 @@ PyFile_FromFd(int fd, char *name, char *mode, int buffering, char *encoding, char *errors, char *newline, int closefd) { PyObject *io, *stream; + _Py_identifier(open); io = PyImport_ImportModule("io"); if (io == NULL) return NULL; - stream = PyObject_CallMethod(io, "open", "isisssi", fd, mode, + stream = _PyObject_CallMethodId(io, &PyId_open, "isisssi", fd, mode, buffering, encoding, errors, newline, closefd); Py_DECREF(io); diff --git a/Objects/object.c b/Objects/object.c index aeaa4b5fa438c1..7db60f313130f0 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -810,6 +810,42 @@ PyObject_SetAttrString(PyObject *v, const char *name, PyObject *w) return res; } +PyObject * +_PyObject_GetAttrId(PyObject *v, _Py_Identifier *name) +{ + PyObject *result; + PyObject *oname = _PyUnicode_FromId(name); + if (!oname) + return NULL; + result = PyObject_GetAttr(v, oname); + Py_DECREF(oname); + return result; +} + +int +_PyObject_HasAttrId(PyObject *v, _Py_Identifier *name) +{ + int result; + PyObject *oname = _PyUnicode_FromId(name); + if (!oname) + return -1; + result = PyObject_HasAttr(v, oname); + Py_DECREF(oname); + return result; +} + +int +_PyObject_SetAttrId(PyObject *v, _Py_Identifier *name, PyObject *w) +{ + int result; + PyObject *oname = _PyUnicode_FromId(name); + if (!oname) + return -1; + result = PyObject_SetAttr(v, oname, w); + Py_DECREF(oname); + return result; +} + PyObject * PyObject_GetAttr(PyObject *v, PyObject *name) { diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 2e6eb0af465f07..f94dfbf94ef658 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2897,6 +2897,7 @@ object_new(PyTypeObject *type, PyObject *args, PyObject *kwds) PyObject *sorted; PyObject *sorted_methods = NULL; PyObject *joined = NULL; + _Py_identifier(join); /* Compute ", ".join(sorted(type.__abstractmethods__)) into joined. */ @@ -2919,7 +2920,7 @@ object_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (comma == NULL) goto error; } - joined = PyObject_CallMethod(comma, "join", + joined = _PyObject_CallMethodId(comma, &PyId_join, "O", sorted_methods); if (joined == NULL) goto error; @@ -3184,6 +3185,7 @@ slotnames(PyObject *cls) PyObject *copyreg; PyObject *slotnames; static PyObject *str_slotnames; + _Py_identifier(_slotnames); if (str_slotnames == NULL) { str_slotnames = PyUnicode_InternFromString("__slotnames__"); @@ -3202,7 +3204,7 @@ slotnames(PyObject *cls) if (copyreg == NULL) return NULL; - slotnames = PyObject_CallMethod(copyreg, "_slotnames", "O", cls); + slotnames = _PyObject_CallMethodId(copyreg, &PyId__slotnames, "O", cls); Py_DECREF(copyreg); if (slotnames != NULL && slotnames != Py_None && @@ -3323,7 +3325,8 @@ reduce_2(PyObject *obj) Py_INCREF(dictitems); } else { - PyObject *items = PyObject_CallMethod(obj, "items", ""); + _Py_identifier(items); + PyObject *items = _PyObject_CallMethodId(obj, &PyId_items, ""); if (items == NULL) goto end; dictitems = PyObject_GetIter(items); diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index e904b6ea9819b3..af923685155f53 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -201,6 +201,9 @@ static PyObject *interned; /* The empty Unicode object is shared to improve performance. */ static PyObject *unicode_empty; +/* List of static strings. */ +static _Py_Identifier *static_strings; + /* Single character Unicode strings in the Latin-1 range are being shared as well. */ static PyObject *unicode_latin1[256]; @@ -1609,6 +1612,33 @@ PyUnicode_FromString(const char *u) return PyUnicode_FromStringAndSize(u, size); } +PyObject * +_PyUnicode_FromId(_Py_Identifier *id) +{ + if (!id->object) { + id->object = PyUnicode_FromString(id->string); + if (!id->object) + return NULL; + PyUnicode_InternInPlace(&id->object); + assert(!id->next); + id->next = static_strings; + static_strings = id; + } + Py_INCREF(id->object); + return id->object; +} + +void +_PyUnicode_ClearStaticStrings() +{ + _Py_Identifier *i; + for (i = static_strings; i; i = i->next) { + Py_DECREF(i->object); + i->object = NULL; + i->next = NULL; + } +} + static PyObject* unicode_fromascii(const unsigned char* s, Py_ssize_t size) { @@ -13523,6 +13553,7 @@ _PyUnicode_Fini(void) unicode_latin1[i] = NULL; } } + _PyUnicode_ClearStaticStrings(); (void)PyUnicode_ClearFreeList(); } diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c index c99f6ba1b6f125..594f0ea4d3dc86 100644 --- a/Objects/weakrefobject.c +++ b/Objects/weakrefobject.c @@ -440,8 +440,9 @@ proxy_checkref(PyWeakReference *proxy) #define WRAP_METHOD(method, special) \ static PyObject * \ method(PyObject *proxy) { \ + _Py_identifier(special); \ UNWRAP(proxy); \ - return PyObject_CallMethod(proxy, special, ""); \ + return _PyObject_CallMethodId(proxy, &PyId_##special, ""); \ } @@ -584,7 +585,7 @@ proxy_iternext(PyWeakReference *proxy) } -WRAP_METHOD(proxy_bytes, "__bytes__") +WRAP_METHOD(proxy_bytes, __bytes__) static PyMethodDef proxy_methods[] = { diff --git a/PC/_msi.c b/PC/_msi.c index d4d8483115f464..54406dfc468f63 100644 --- a/PC/_msi.c +++ b/PC/_msi.c @@ -122,7 +122,9 @@ static FNFCIGETTEMPFILE(cb_gettempfile) static FNFCISTATUS(cb_status) { if (pv) { - PyObject *result = PyObject_CallMethod(pv, "status", "iii", typeStatus, cb1, cb2); + _Py_identifier(status); + + PyObject *result = _PyObject_CallMethodId(pv, &PyId_status, "iii", typeStatus, cb1, cb2); if (result == NULL) return -1; Py_DECREF(result); @@ -133,7 +135,9 @@ static FNFCISTATUS(cb_status) static FNFCIGETNEXTCABINET(cb_getnextcabinet) { if (pv) { - PyObject *result = PyObject_CallMethod(pv, "getnextcabinet", "i", pccab->iCab); + _Py_identifier(getnextcabinet); + + PyObject *result = _PyObject_CallMethodId(pv, &PyId_getnextcabinet, "i", pccab->iCab); if (result == NULL) return -1; if (!PyBytes_Check(result)) { diff --git a/Parser/tokenizer.c b/Parser/tokenizer.c index a0a3a67063dcf3..23ea2eb6baaeca 100644 --- a/Parser/tokenizer.c +++ b/Parser/tokenizer.c @@ -462,6 +462,7 @@ static int fp_setreadl(struct tok_state *tok, const char* enc) { PyObject *readline = NULL, *stream = NULL, *io = NULL; + _Py_identifier(open); int fd; io = PyImport_ImportModuleNoBlock("io"); @@ -474,7 +475,7 @@ fp_setreadl(struct tok_state *tok, const char* enc) goto cleanup; } - stream = PyObject_CallMethod(io, "open", "isisOOO", + stream = _PyObject_CallMethodId(io, &PyId_open, "isisOOO", fd, "r", -1, enc, Py_None, Py_None, Py_False); if (stream == NULL) goto cleanup; diff --git a/Python/_warnings.c b/Python/_warnings.c index 792e3ed6df12f7..e5631079a96737 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -18,11 +18,12 @@ static int check_matched(PyObject *obj, PyObject *arg) { PyObject *result; + _Py_identifier(match); int rc; if (obj == Py_None) return 1; - result = PyObject_CallMethod(obj, "match", "O", arg); + result = _PyObject_CallMethodId(obj, &PyId_match, "O", arg); if (result == NULL) return -1; diff --git a/Python/ast.c b/Python/ast.c index a52fd093e6743c..987297924ebba2 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -527,6 +527,7 @@ static PyObject *parsestrplus(struct compiling *, const node *n, static identifier new_identifier(const char* n, PyArena *arena) { + _Py_identifier(normalize); PyObject* id = PyUnicode_DecodeUTF8(n, strlen(n), NULL); if (!id || PyUnicode_READY(id) == -1) return NULL; @@ -537,7 +538,7 @@ new_identifier(const char* n, PyArena *arena) PyObject *id2; if (!m) return NULL; - id2 = PyObject_CallMethod(m, "normalize", "sO", "NFKC", id); + id2 = _PyObject_CallMethodId(m, &PyId_normalize, "sO", "NFKC", id); Py_DECREF(m); if (!id2) return NULL; diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 04f5231891dd47..c174e9d5ef2021 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -32,6 +32,9 @@ const char *Py_FileSystemDefaultEncoding = NULL; /* set by initfsencoding() */ int Py_HasFileSystemDefaultEncoding = 0; #endif +_Py_identifier(fileno); +_Py_identifier(flush); + static PyObject * builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds) { @@ -1567,7 +1570,7 @@ builtin_input(PyObject *self, PyObject *args) } /* First of all, flush stderr */ - tmp = PyObject_CallMethod(ferr, "flush", ""); + tmp = _PyObject_CallMethodId(ferr, &PyId_flush, ""); if (tmp == NULL) PyErr_Clear(); else @@ -1576,7 +1579,7 @@ builtin_input(PyObject *self, PyObject *args) /* We should only use (GNU) readline if Python's sys.stdin and sys.stdout are the same as C's stdin and stdout, because we need to pass it those. */ - tmp = PyObject_CallMethod(fin, "fileno", ""); + tmp = _PyObject_CallMethodId(fin, &PyId_fileno, ""); if (tmp == NULL) { PyErr_Clear(); tty = 0; @@ -1589,7 +1592,7 @@ builtin_input(PyObject *self, PyObject *args) tty = fd == fileno(stdin) && isatty(fd); } if (tty) { - tmp = PyObject_CallMethod(fout, "fileno", ""); + tmp = _PyObject_CallMethodId(fout, &PyId_fileno, ""); if (tmp == NULL) PyErr_Clear(); else { @@ -1621,7 +1624,7 @@ builtin_input(PyObject *self, PyObject *args) Py_DECREF(stdin_encoding); return NULL; } - tmp = PyObject_CallMethod(fout, "flush", ""); + tmp = _PyObject_CallMethodId(fout, &PyId_flush, ""); if (tmp == NULL) PyErr_Clear(); else @@ -1703,7 +1706,7 @@ builtin_input(PyObject *self, PyObject *args) if (PyFile_WriteObject(promptarg, fout, Py_PRINT_RAW) != 0) return NULL; } - tmp = PyObject_CallMethod(fout, "flush", ""); + tmp = _PyObject_CallMethodId(fout, &PyId_flush, ""); if (tmp == NULL) PyErr_Clear(); else diff --git a/Python/ceval.c b/Python/ceval.c index 686a54dafe2f8d..04d3df1500269f 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -372,6 +372,7 @@ PyEval_ReleaseThread(PyThreadState *tstate) void PyEval_ReInitThreads(void) { + _Py_identifier(_after_fork); PyObject *threading, *result; PyThreadState *tstate = PyThreadState_GET(); @@ -392,7 +393,7 @@ PyEval_ReInitThreads(void) PyErr_Clear(); return; } - result = PyObject_CallMethod(threading, "_after_fork", NULL); + result = _PyObject_CallMethodId(threading, &PyId__after_fork, NULL); if (result == NULL) PyErr_WriteUnraisable(threading); else diff --git a/Python/import.c b/Python/import.c index 5f84ac2f745a7a..6eca90a0f799e2 100644 --- a/Python/import.c +++ b/Python/import.c @@ -1801,6 +1801,7 @@ find_module_path(PyObject *fullname, PyObject *name, PyObject *path, /* sys.path_hooks import hook */ if (p_loader != NULL) { + _Py_identifier(find_module); PyObject *importer; importer = get_path_importer(path_importer_cache, @@ -1811,8 +1812,8 @@ find_module_path(PyObject *fullname, PyObject *name, PyObject *path, /* Note: importer is a borrowed reference */ if (importer != Py_None) { PyObject *loader; - loader = PyObject_CallMethod(importer, - "find_module", "O", fullname); + loader = _PyObject_CallMethodId(importer, + &PyId_find_module, "O", fullname); if (loader == NULL) return -1; /* error */ if (loader != Py_None) { @@ -2030,6 +2031,7 @@ find_module(PyObject *fullname, PyObject *name, PyObject *search_path_list, /* sys.meta_path import hook */ if (p_loader != NULL) { + _Py_identifier(find_module); PyObject *meta_path; meta_path = PySys_GetObject("meta_path"); @@ -2044,7 +2046,7 @@ find_module(PyObject *fullname, PyObject *name, PyObject *search_path_list, for (i = 0; i < npath; i++) { PyObject *loader; PyObject *hook = PyList_GetItem(meta_path, i); - loader = PyObject_CallMethod(hook, "find_module", + loader = _PyObject_CallMethodId(hook, &PyId_find_module, "OO", fullname, search_path_list != NULL ? search_path_list : Py_None); @@ -2454,12 +2456,13 @@ load_module(PyObject *name, FILE *fp, PyObject *pathname, int type, PyObject *lo break; case IMP_HOOK: { + _Py_identifier(load_module); if (loader == NULL) { PyErr_SetString(PyExc_ImportError, "import hook without loader"); return NULL; } - m = PyObject_CallMethod(loader, "load_module", "O", name); + m = _PyObject_CallMethodId(loader, &PyId_load_module, "O", name); break; } diff --git a/Python/marshal.c b/Python/marshal.c index 31fe66b08f95c3..b8288d0c1a9609 100644 --- a/Python/marshal.c +++ b/Python/marshal.c @@ -480,7 +480,9 @@ r_string(char *s, int n, RFILE *p) } } else { - PyObject *data = PyObject_CallMethod(p->readable, "read", "i", n); + _Py_identifier(read); + + PyObject *data = _PyObject_CallMethodId(p->readable, &PyId_read, "i", n); read = 0; if (data != NULL) { if (!PyBytes_Check(data)) { @@ -1290,12 +1292,14 @@ marshal_dump(PyObject *self, PyObject *args) int version = Py_MARSHAL_VERSION; PyObject *s; PyObject *res; + _Py_identifier(write); + if (!PyArg_ParseTuple(args, "OO|i:dump", &x, &f, &version)) return NULL; s = PyMarshal_WriteObjectToString(x, version); if (s == NULL) return NULL; - res = PyObject_CallMethod(f, "write", "O", s); + res = _PyObject_CallMethodId(f, &PyId_write, "O", s); Py_DECREF(s); return res; } @@ -1317,6 +1321,7 @@ static PyObject * marshal_load(PyObject *self, PyObject *f) { PyObject *data, *result; + _Py_identifier(read); RFILE rf; /* @@ -1324,7 +1329,7 @@ marshal_load(PyObject *self, PyObject *f) * This is to ensure that the object passed in at least * has a read method which returns bytes. */ - data = PyObject_CallMethod(f, "read", "i", 0); + data = _PyObject_CallMethodId(f, &PyId_read, "i", 0); if (data == NULL) return NULL; if (!PyBytes_Check(data)) { diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 1888fba9b97681..0ef36bbb8cb776 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -352,9 +352,10 @@ flush_std_files(void) PyObject *fout = PySys_GetObject("stdout"); PyObject *ferr = PySys_GetObject("stderr"); PyObject *tmp; + _Py_identifier(flush); if (fout != NULL && fout != Py_None) { - tmp = PyObject_CallMethod(fout, "flush", ""); + tmp = _PyObject_CallMethodId(fout, &PyId_flush, ""); if (tmp == NULL) PyErr_WriteUnraisable(fout); else @@ -362,7 +363,7 @@ flush_std_files(void) } if (ferr != NULL && ferr != Py_None) { - tmp = PyObject_CallMethod(ferr, "flush", ""); + tmp = _PyObject_CallMethodId(ferr, &PyId_flush, ""); if (tmp == NULL) PyErr_Clear(); else @@ -805,6 +806,9 @@ create_stdio(PyObject* io, const char* newline; PyObject *line_buffering; int buffering, isatty; + _Py_identifier(open); + _Py_identifier(isatty); + _Py_identifier(TextIOWrapper); /* stdin is always opened in buffered mode, first because it shouldn't make a difference in common use cases, second because TextIOWrapper @@ -819,9 +823,9 @@ create_stdio(PyObject* io, mode = "wb"; else mode = "rb"; - buf = PyObject_CallMethod(io, "open", "isiOOOi", - fd, mode, buffering, - Py_None, Py_None, Py_None, 0); + buf = _PyObject_CallMethodId(io, &PyId_open, "isiOOOi", + fd, mode, buffering, + Py_None, Py_None, Py_None, 0); if (buf == NULL) goto error; @@ -838,7 +842,7 @@ create_stdio(PyObject* io, text = PyUnicode_FromString(name); if (text == NULL || PyObject_SetAttrString(raw, "name", text) < 0) goto error; - res = PyObject_CallMethod(raw, "isatty", ""); + res = _PyObject_CallMethodId(raw, &PyId_isatty, ""); if (res == NULL) goto error; isatty = PyObject_IsTrue(res); @@ -861,9 +865,9 @@ create_stdio(PyObject* io, } #endif - stream = PyObject_CallMethod(io, "TextIOWrapper", "OsssO", - buf, encoding, errors, - newline, line_buffering); + stream = _PyObject_CallMethodId(io, &PyId_TextIOWrapper, "OsssO", + buf, encoding, errors, + newline, line_buffering); Py_CLEAR(buf); if (stream == NULL) goto error; @@ -1759,13 +1763,14 @@ flush_io(void) { PyObject *f, *r; PyObject *type, *value, *traceback; + _Py_identifier(flush); /* Save the current exception */ PyErr_Fetch(&type, &value, &traceback); f = PySys_GetObject("stderr"); if (f != NULL) { - r = PyObject_CallMethod(f, "flush", ""); + r = _PyObject_CallMethodId(f, &PyId_flush, ""); if (r) Py_DECREF(r); else @@ -1773,7 +1778,7 @@ flush_io(void) } f = PySys_GetObject("stdout"); if (f != NULL) { - r = PyObject_CallMethod(f, "flush", ""); + r = _PyObject_CallMethodId(f, &PyId_flush, ""); if (r) Py_DECREF(r); else @@ -2205,6 +2210,7 @@ static void wait_for_thread_shutdown(void) { #ifdef WITH_THREAD + _Py_identifier(_shutdown); PyObject *result; PyThreadState *tstate = PyThreadState_GET(); PyObject *threading = PyMapping_GetItemString(tstate->interp->modules, @@ -2214,7 +2220,7 @@ wait_for_thread_shutdown(void) PyErr_Clear(); return; } - result = PyObject_CallMethod(threading, "_shutdown", ""); + result = _PyObject_CallMethodId(threading, &PyId__shutdown, ""); if (result == NULL) { PyErr_WriteUnraisable(threading); } diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 3576cedf63f9a3..f0aceada5f096f 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -99,7 +99,8 @@ sys_displayhook_unencodable(PyObject *outf, PyObject *o) buffer = PyObject_GetAttrString(outf, "buffer"); if (buffer) { - result = PyObject_CallMethod(buffer, "write", "(O)", encoded); + _Py_identifier(write); + result = _PyObject_CallMethodId(buffer, &PyId_write, "(O)", encoded); Py_DECREF(buffer); Py_DECREF(encoded); if (result == NULL) diff --git a/Python/traceback.c b/Python/traceback.c index b66c96cda676fc..551f9d6228e7af 100644 --- a/Python/traceback.c +++ b/Python/traceback.c @@ -152,6 +152,7 @@ _Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject * const char* filepath; Py_ssize_t len; PyObject* result; + _Py_identifier(open); filebytes = PyUnicode_EncodeFSDefault(filename); if (filebytes == NULL) { @@ -199,7 +200,7 @@ _Py_FindSourceFile(PyObject *filename, char* namebuf, size_t namelen, PyObject * namebuf[len++] = SEP; strcpy(namebuf+len, tail); - binary = PyObject_CallMethod(io, "open", "ss", namebuf, "rb"); + binary = _PyObject_CallMethodId(io, &PyId_open, "ss", namebuf, "rb"); if (binary != NULL) { result = binary; goto finally; @@ -231,6 +232,9 @@ _Py_DisplaySourceLine(PyObject *f, PyObject *filename, int lineno, int indent) char buf[MAXPATHLEN+1]; int kind; void *data; + _Py_identifier(close); + _Py_identifier(open); + _Py_identifier(TextIOWrapper); /* open the file */ if (filename == NULL) @@ -239,7 +243,7 @@ _Py_DisplaySourceLine(PyObject *f, PyObject *filename, int lineno, int indent) io = PyImport_ImportModuleNoBlock("io"); if (io == NULL) return -1; - binary = PyObject_CallMethod(io, "open", "Os", filename, "rb"); + binary = _PyObject_CallMethodId(io, &PyId_open, "Os", filename, "rb"); if (binary == NULL) { binary = _Py_FindSourceFile(filename, buf, sizeof(buf), io); @@ -254,7 +258,7 @@ _Py_DisplaySourceLine(PyObject *f, PyObject *filename, int lineno, int indent) found_encoding = PyTokenizer_FindEncodingFilename(fd, filename); encoding = (found_encoding != NULL) ? found_encoding : "utf-8"; lseek(fd, 0, 0); /* Reset position */ - fob = PyObject_CallMethod(io, "TextIOWrapper", "Os", binary, encoding); + fob = _PyObject_CallMethodId(io, &PyId_TextIOWrapper, "Os", binary, encoding); Py_DECREF(io); Py_DECREF(binary); PyMem_FREE(found_encoding); @@ -273,7 +277,7 @@ _Py_DisplaySourceLine(PyObject *f, PyObject *filename, int lineno, int indent) break; } } - res = PyObject_CallMethod(fob, "close", ""); + res = _PyObject_CallMethodId(fob, &PyId_close, ""); if (res) Py_DECREF(res); else