From 6fd4c8ec7740523bb81191c013118d9d6959bc9d Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 14 Jun 2022 07:15:26 +0300 Subject: [PATCH] gh-93741: Add private C API _PyImport_GetModuleAttrString() (GH-93742) It combines PyImport_ImportModule() and PyObject_GetAttrString() and saves 4-6 lines of code on every use. Add also _PyImport_GetModuleAttr() which takes Python strings as arguments. --- Include/cpython/import.h | 3 ++ Include/internal/pycore_global_strings.h | 4 -- Include/internal/pycore_runtime_init.h | 4 -- Modules/_ctypes/callbacks.c | 13 ++--- Modules/_datetimemodule.c | 34 ++++--------- Modules/_elementtree.c | 8 +-- Modules/_operator.c | 7 +-- Modules/_pickle.c | 16 +----- Modules/_sqlite/connection.c | 34 +++---------- Modules/_sqlite/module.c | 8 +-- Modules/_sre/sre.c | 12 +---- Modules/_zoneinfo.c | 35 +++---------- Modules/arraymodule.c | 21 ++------ Modules/cjkcodecs/cjkcodecs.h | 9 +--- Modules/faulthandler.c | 8 +-- Modules/posixmodule.c | 6 +-- Modules/timemodule.c | 9 +--- Objects/abstract.c | 9 +--- Objects/fileobject.c | 20 ++++---- Objects/memoryobject.c | 10 +--- Parser/pegen.c | 8 +-- Parser/tokenizer.c | 10 ++-- Python/import.c | 65 ++++++++++++++++-------- Python/pylifecycle.c | 9 +--- 24 files changed, 114 insertions(+), 248 deletions(-) diff --git a/Include/cpython/import.h b/Include/cpython/import.h index ef6be689468ee5..a69b4f34def342 100644 --- a/Include/cpython/import.h +++ b/Include/cpython/import.h @@ -40,3 +40,6 @@ struct _frozen { collection of frozen modules: */ PyAPI_DATA(const struct _frozen *) PyImport_FrozenModules; + +PyAPI_DATA(PyObject *) _PyImport_GetModuleAttr(PyObject *, PyObject *); +PyAPI_DATA(PyObject *) _PyImport_GetModuleAttrString(const char *, const char *); diff --git a/Include/internal/pycore_global_strings.h b/Include/internal/pycore_global_strings.h index af6c5ebaaf9def..2bf16c30e1bce2 100644 --- a/Include/internal/pycore_global_strings.h +++ b/Include/internal/pycore_global_strings.h @@ -226,7 +226,6 @@ struct _Py_global_strings { STRUCT_FOR_ID(_showwarnmsg) STRUCT_FOR_ID(_shutdown) STRUCT_FOR_ID(_slotnames) - STRUCT_FOR_ID(_strptime_time) STRUCT_FOR_ID(_uninitialized_submodules) STRUCT_FOR_ID(_warn_unawaited_coroutine) STRUCT_FOR_ID(_xoptions) @@ -252,7 +251,6 @@ struct _Py_global_strings { STRUCT_FOR_ID(difference_update) STRUCT_FOR_ID(dispatch_table) STRUCT_FOR_ID(displayhook) - STRUCT_FOR_ID(enable) STRUCT_FOR_ID(encode) STRUCT_FOR_ID(encoding) STRUCT_FOR_ID(end_lineno) @@ -311,7 +309,6 @@ struct _Py_global_strings { STRUCT_FOR_ID(opcode) STRUCT_FOR_ID(open) STRUCT_FOR_ID(parent) - STRUCT_FOR_ID(partial) STRUCT_FOR_ID(path) STRUCT_FOR_ID(peek) STRUCT_FOR_ID(persistent_id) @@ -357,7 +354,6 @@ struct _Py_global_strings { STRUCT_FOR_ID(warnoptions) STRUCT_FOR_ID(writable) STRUCT_FOR_ID(write) - STRUCT_FOR_ID(zipimporter) } identifiers; struct { PyASCIIObject _ascii; diff --git a/Include/internal/pycore_runtime_init.h b/Include/internal/pycore_runtime_init.h index 2420d81a8a238a..b4ce4e325a4d8e 100644 --- a/Include/internal/pycore_runtime_init.h +++ b/Include/internal/pycore_runtime_init.h @@ -848,7 +848,6 @@ extern "C" { INIT_ID(_showwarnmsg), \ INIT_ID(_shutdown), \ INIT_ID(_slotnames), \ - INIT_ID(_strptime_time), \ INIT_ID(_uninitialized_submodules), \ INIT_ID(_warn_unawaited_coroutine), \ INIT_ID(_xoptions), \ @@ -874,7 +873,6 @@ extern "C" { INIT_ID(difference_update), \ INIT_ID(dispatch_table), \ INIT_ID(displayhook), \ - INIT_ID(enable), \ INIT_ID(encode), \ INIT_ID(encoding), \ INIT_ID(end_lineno), \ @@ -933,7 +931,6 @@ extern "C" { INIT_ID(opcode), \ INIT_ID(open), \ INIT_ID(parent), \ - INIT_ID(partial), \ INIT_ID(path), \ INIT_ID(peek), \ INIT_ID(persistent_id), \ @@ -979,7 +976,6 @@ extern "C" { INIT_ID(warnoptions), \ INIT_ID(writable), \ INIT_ID(write), \ - INIT_ID(zipimporter), \ }, \ .ascii = { \ _PyASCIIObject_INIT("\x00"), \ diff --git a/Modules/_ctypes/callbacks.c b/Modules/_ctypes/callbacks.c index e1e0225f67b341..220b6120dac52a 100644 --- a/Modules/_ctypes/callbacks.c +++ b/Modules/_ctypes/callbacks.c @@ -472,24 +472,17 @@ static void LoadPython(void) long Call_GetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) { - PyObject *mod, *func, *result; + PyObject *func, *result; long retval; static PyObject *context; if (context == NULL) context = PyUnicode_InternFromString("_ctypes.DllGetClassObject"); - mod = PyImport_ImportModule("ctypes"); - if (!mod) { - PyErr_WriteUnraisable(context ? context : Py_None); - /* There has been a warning before about this already */ - return E_FAIL; - } - - func = PyObject_GetAttrString(mod, "DllGetClassObject"); - Py_DECREF(mod); + func = _PyImport_GetModuleAttrString("ctypes", "DllGetClassObject"); if (!func) { PyErr_WriteUnraisable(context ? context : Py_None); + /* There has been a warning before about this already */ return E_FAIL; } diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index 06dff8fdd9eed9..ba24e3c124846f 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -1718,17 +1718,17 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple, goto Done; { PyObject *format; - PyObject *time = PyImport_ImportModule("time"); + PyObject *strftime = _PyImport_GetModuleAttrString("time", "strftime"); - if (time == NULL) + if (strftime == NULL) goto Done; format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt)); if (format != NULL) { - result = _PyObject_CallMethodIdObjArgs(time, &PyId_strftime, + result = PyObject_CallFunctionObjArgs(strftime, format, timetuple, NULL); Py_DECREF(format); } - Py_DECREF(time); + Py_DECREF(strftime); } Done: Py_XDECREF(freplacement); @@ -1748,12 +1748,10 @@ static PyObject * time_time(void) { PyObject *result = NULL; - PyObject *time = PyImport_ImportModule("time"); + PyObject *time = _PyImport_GetModuleAttrString("time", "time"); if (time != NULL) { - _Py_IDENTIFIER(time); - - result = _PyObject_CallMethodIdNoArgs(time, &PyId_time); + result = PyObject_CallNoArgs(time); Py_DECREF(time); } return result; @@ -1765,31 +1763,21 @@ time_time(void) static PyObject * build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag) { - PyObject *time; + PyObject *struct_time; PyObject *result; - _Py_IDENTIFIER(struct_time); - PyObject *args; - - time = PyImport_ImportModule("time"); - if (time == NULL) { + struct_time = _PyImport_GetModuleAttrString("time", "struct_time"); + if (struct_time == NULL) { return NULL; } - args = Py_BuildValue("iiiiiiiii", + result = PyObject_CallFunction(struct_time, "((iiiiiiiii))", y, m, d, hh, mm, ss, weekday(y, m, d), days_before_month(y, m) + d, dstflag); - if (args == NULL) { - Py_DECREF(time); - return NULL; - } - - result = _PyObject_CallMethodIdOneArg(time, &PyId_struct_time, args); - Py_DECREF(time); - Py_DECREF(args); + Py_DECREF(struct_time); return result; } diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index 453e57a94f2c6b..87f18d6e671a63 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -4370,7 +4370,7 @@ static struct PyModuleDef elementtreemodule = { PyMODINIT_FUNC PyInit__elementtree(void) { - PyObject *m, *temp; + PyObject *m; elementtreestate *st; m = PyState_FindModule(&elementtreemodule); @@ -4394,11 +4394,7 @@ PyInit__elementtree(void) return NULL; st = get_elementtree_state(m); - if (!(temp = PyImport_ImportModule("copy"))) - return NULL; - st->deepcopy_obj = PyObject_GetAttrString(temp, "deepcopy"); - Py_XDECREF(temp); - + st->deepcopy_obj = _PyImport_GetModuleAttrString("copy", "deepcopy"); if (st->deepcopy_obj == NULL) { return NULL; } diff --git a/Modules/_operator.c b/Modules/_operator.c index 1af4a4feb7728a..e89451631ca1b2 100644 --- a/Modules/_operator.c +++ b/Modules/_operator.c @@ -1752,16 +1752,11 @@ methodcaller_reduce(methodcallerobject *mc, PyObject *Py_UNUSED(ignored)) return Py_BuildValue("ON", Py_TYPE(mc), newargs); } else { - PyObject *functools; PyObject *partial; PyObject *constructor; PyObject *newargs[2]; - functools = PyImport_ImportModule("functools"); - if (!functools) - return NULL; - partial = PyObject_GetAttr(functools, &_Py_ID(partial)); - Py_DECREF(functools); + partial = _PyImport_GetModuleAttrString("functools", "partial"); if (!partial) return NULL; diff --git a/Modules/_pickle.c b/Modules/_pickle.c index 753ac2fe892a1b..1c5de30b07d620 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -232,8 +232,6 @@ _Pickle_InitState(PickleState *st) { PyObject *copyreg = NULL; PyObject *compat_pickle = NULL; - PyObject *codecs = NULL; - PyObject *functools = NULL; st->getattr = _PyEval_GetBuiltin(&_Py_ID(getattr)); if (st->getattr == NULL) @@ -329,10 +327,7 @@ _Pickle_InitState(PickleState *st) } Py_CLEAR(compat_pickle); - codecs = PyImport_ImportModule("codecs"); - if (codecs == NULL) - goto error; - st->codecs_encode = PyObject_GetAttrString(codecs, "encode"); + st->codecs_encode = _PyImport_GetModuleAttrString("codecs", "encode"); if (st->codecs_encode == NULL) { goto error; } @@ -342,23 +337,16 @@ _Pickle_InitState(PickleState *st) Py_TYPE(st->codecs_encode)->tp_name); goto error; } - Py_CLEAR(codecs); - functools = PyImport_ImportModule("functools"); - if (!functools) - goto error; - st->partial = PyObject_GetAttrString(functools, "partial"); + st->partial = _PyImport_GetModuleAttrString("functools", "partial"); if (!st->partial) goto error; - Py_CLEAR(functools); return 0; error: Py_CLEAR(copyreg); Py_CLEAR(compat_pickle); - Py_CLEAR(codecs); - Py_CLEAR(functools); _Pickle_ClearState(st); return -1; } diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 4ac0078eb83c21..484af7a1771b06 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -1841,43 +1841,21 @@ static PyObject * pysqlite_connection_iterdump_impl(pysqlite_Connection *self) /*[clinic end generated code: output=586997aaf9808768 input=1911ca756066da89]*/ { - PyObject* retval = NULL; - PyObject* module = NULL; - PyObject* module_dict; - PyObject* pyfn_iterdump; - if (!pysqlite_check_connection(self)) { - goto finally; - } - - module = PyImport_ImportModule(MODULE_NAME ".dump"); - if (!module) { - goto finally; - } - - module_dict = PyModule_GetDict(module); - if (!module_dict) { - goto finally; + return NULL; } - PyObject *meth = PyUnicode_InternFromString("_iterdump"); - if (meth == NULL) { - goto finally; - } - pyfn_iterdump = PyDict_GetItemWithError(module_dict, meth); - Py_DECREF(meth); - if (!pyfn_iterdump) { + PyObject *iterdump = _PyImport_GetModuleAttrString(MODULE_NAME ".dump", "_iterdump"); + if (!iterdump) { if (!PyErr_Occurred()) { PyErr_SetString(self->OperationalError, "Failed to obtain _iterdump() reference"); } - goto finally; + return NULL; } - retval = PyObject_CallOneArg(pyfn_iterdump, (PyObject *)self); - -finally: - Py_XDECREF(module); + PyObject *retval = PyObject_CallOneArg(iterdump, (PyObject *)self); + Py_DECREF(iterdump); return retval; } diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c index 995d0946d9414c..dfb93015387b10 100644 --- a/Modules/_sqlite/module.c +++ b/Modules/_sqlite/module.c @@ -227,14 +227,8 @@ static int converters_init(PyObject* module) static int load_functools_lru_cache(PyObject *module) { - PyObject *functools = PyImport_ImportModule("functools"); - if (functools == NULL) { - return -1; - } - pysqlite_state *state = pysqlite_get_state(module); - state->lru_cache = PyObject_GetAttrString(functools, "lru_cache"); - Py_DECREF(functools); + state->lru_cache = _PyImport_GetModuleAttrString("functools", "lru_cache"); if (state->lru_cache == NULL) { return -1; } diff --git a/Modules/_sre/sre.c b/Modules/_sre/sre.c index 491734f243849b..a1da180892fb4a 100644 --- a/Modules/_sre/sre.c +++ b/Modules/_sre/sre.c @@ -771,22 +771,12 @@ _sre_SRE_Pattern_search_impl(PatternObject *self, PyTypeObject *cls, static PyObject* call(const char* module, const char* function, PyObject* args) { - PyObject* name; - PyObject* mod; PyObject* func; PyObject* result; if (!args) return NULL; - name = PyUnicode_FromString(module); - if (!name) - return NULL; - mod = PyImport_Import(name); - Py_DECREF(name); - if (!mod) - return NULL; - func = PyObject_GetAttrString(mod, function); - Py_DECREF(mod); + func = _PyImport_GetModuleAttrString(module, function); if (!func) return NULL; result = PyObject_CallObject(func, args); diff --git a/Modules/_zoneinfo.c b/Modules/_zoneinfo.c index 1535721b026d1f..207340adec152f 100644 --- a/Modules/_zoneinfo.c +++ b/Modules/_zoneinfo.c @@ -659,14 +659,8 @@ zoneinfo_reduce(PyObject *obj_self, PyObject *unused) PyZoneInfo_ZoneInfo *self = (PyZoneInfo_ZoneInfo *)obj_self; if (self->source == SOURCE_FILE) { // Objects constructed from files cannot be pickled. - PyObject *pickle = PyImport_ImportModule("pickle"); - if (pickle == NULL) { - return NULL; - } - PyObject *pickle_error = - PyObject_GetAttrString(pickle, "PicklingError"); - Py_DECREF(pickle); + _PyImport_GetModuleAttrString("pickle", "PicklingError"); if (pickle_error == NULL) { return NULL; } @@ -2492,14 +2486,13 @@ clear_strong_cache(const PyTypeObject *const type) static PyObject * new_weak_cache(void) { - PyObject *weakref_module = PyImport_ImportModule("weakref"); - if (weakref_module == NULL) { + PyObject *WeakValueDictionary = + _PyImport_GetModuleAttrString("weakref", "WeakValueDictionary"); + if (WeakValueDictionary == NULL) { return NULL; } - - PyObject *weak_cache = - PyObject_CallMethod(weakref_module, "WeakValueDictionary", ""); - Py_DECREF(weakref_module); + PyObject *weak_cache = PyObject_CallNoArgs(WeakValueDictionary); + Py_DECREF(WeakValueDictionary); return weak_cache; } @@ -2656,25 +2649,13 @@ zoneinfomodule_exec(PyObject *m) PyModule_AddObject(m, "ZoneInfo", (PyObject *)&PyZoneInfo_ZoneInfoType); /* Populate imports */ - PyObject *_tzpath_module = PyImport_ImportModule("zoneinfo._tzpath"); - if (_tzpath_module == NULL) { - goto error; - } - _tzpath_find_tzfile = - PyObject_GetAttrString(_tzpath_module, "find_tzfile"); - Py_DECREF(_tzpath_module); + _PyImport_GetModuleAttrString("zoneinfo._tzpath", "find_tzfile"); if (_tzpath_find_tzfile == NULL) { goto error; } - PyObject *io_module = PyImport_ImportModule("io"); - if (io_module == NULL) { - goto error; - } - - io_open = PyObject_GetAttrString(io_module, "open"); - Py_DECREF(io_module); + io_open = _PyImport_GetModuleAttrString("io", "open"); if (io_open == NULL) { goto error; } diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index a04e6a4e070d9e..924fbf29bfb889 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -60,7 +60,6 @@ typedef struct { PyObject *str_read; PyObject *str_write; - PyObject *str__array_reconstructor; PyObject *str___dict__; PyObject *str_iter; } array_state; @@ -2199,13 +2198,8 @@ array_array___reduce_ex___impl(arrayobject *self, PyTypeObject *cls, assert(state != NULL); if (array_reconstructor == NULL) { - PyObject *array_module = PyImport_ImportModule("array"); - if (array_module == NULL) - return NULL; - array_reconstructor = PyObject_GetAttr( - array_module, - state->str__array_reconstructor); - Py_DECREF(array_module); + array_reconstructor = _PyImport_GetModuleAttrString( + "array", "_array_reconstructor"); if (array_reconstructor == NULL) return NULL; } @@ -3029,7 +3023,6 @@ array_clear(PyObject *module) Py_CLEAR(state->ArrayIterType); Py_CLEAR(state->str_read); Py_CLEAR(state->str_write); - Py_CLEAR(state->str__array_reconstructor); Py_CLEAR(state->str___dict__); Py_CLEAR(state->str_iter); return 0; @@ -3075,7 +3068,6 @@ array_modexec(PyObject *m) /* Add interned strings */ ADD_INTERNED(state, read); ADD_INTERNED(state, write); - ADD_INTERNED(state, _array_reconstructor); ADD_INTERNED(state, __dict__); ADD_INTERNED(state, iter); @@ -3089,13 +3081,8 @@ array_modexec(PyObject *m) return -1; } - PyObject *abc_mod = PyImport_ImportModule("collections.abc"); - if (!abc_mod) { - Py_DECREF((PyObject *)state->ArrayType); - return -1; - } - PyObject *mutablesequence = PyObject_GetAttrString(abc_mod, "MutableSequence"); - Py_DECREF(abc_mod); + PyObject *mutablesequence = _PyImport_GetModuleAttrString( + "collections.abc", "MutableSequence"); if (!mutablesequence) { Py_DECREF((PyObject *)state->ArrayType); return -1; diff --git a/Modules/cjkcodecs/cjkcodecs.h b/Modules/cjkcodecs/cjkcodecs.h index ba8fad26055a8b..d9aeec2ff40b08 100644 --- a/Modules/cjkcodecs/cjkcodecs.h +++ b/Modules/cjkcodecs/cjkcodecs.h @@ -245,14 +245,7 @@ static const struct dbcs_map *mapping_list; static PyObject * getmultibytecodec(void) { - PyObject *mod = PyImport_ImportModuleNoBlock("_multibytecodec"); - if (mod == NULL) { - return NULL; - } - - PyObject *cofunc = PyObject_GetAttrString(mod, "__create_codec"); - Py_DECREF(mod); - return cofunc; + return _PyImport_GetModuleAttrString("_multibytecodec", "__create_codec"); } static PyObject * diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c index 08c40834c45f20..d33cd58333ec10 100644 --- a/Modules/faulthandler.c +++ b/Modules/faulthandler.c @@ -1340,13 +1340,13 @@ PyInit_faulthandler(void) static int faulthandler_init_enable(void) { - PyObject *module = PyImport_ImportModule("faulthandler"); - if (module == NULL) { + PyObject *enable = _PyImport_GetModuleAttrString("faulthandler", "enable"); + if (enable == NULL) { return -1; } - PyObject *res = PyObject_CallMethodNoArgs(module, &_Py_ID(enable)); - Py_DECREF(module); + PyObject *res = PyObject_CallNoArgs(enable); + Py_DECREF(enable); if (res == NULL) { return -1; } diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index d41e19e6527147..40229bce0f4033 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -8279,11 +8279,7 @@ wait_helper(PyObject *module, pid_t pid, int status, struct rusage *ru) memset(ru, 0, sizeof(*ru)); } - PyObject *m = PyImport_ImportModule("resource"); - if (m == NULL) - return NULL; - struct_rusage = PyObject_GetAttr(m, get_posix_state(module)->struct_rusage); - Py_DECREF(m); + struct_rusage = _PyImport_GetModuleAttrString("resource", "struct_rusage"); if (struct_rusage == NULL) return NULL; diff --git a/Modules/timemodule.c b/Modules/timemodule.c index 18f9ddb909c028..11c888af03e82d 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -910,14 +910,9 @@ is not present, current time as returned by localtime() is used.\n\ static PyObject * time_strptime(PyObject *self, PyObject *args) { - PyObject *module, *func, *result; + PyObject *func, *result; - module = PyImport_ImportModule("_strptime"); - if (!module) - return NULL; - - func = PyObject_GetAttr(module, &_Py_ID(_strptime_time)); - Py_DECREF(module); + func = _PyImport_GetModuleAttrString("_strptime", "_strptime_time"); if (!func) { return NULL; } diff --git a/Objects/abstract.c b/Objects/abstract.c index 93987c201b5e25..5d50491b2dd347 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -526,18 +526,12 @@ _Py_add_one_to_index_C(int nd, Py_ssize_t *index, const Py_ssize_t *shape) Py_ssize_t PyBuffer_SizeFromFormat(const char *format) { - PyObject *structmodule = NULL; PyObject *calcsize = NULL; PyObject *res = NULL; PyObject *fmt = NULL; Py_ssize_t itemsize = -1; - structmodule = PyImport_ImportModule("struct"); - if (structmodule == NULL) { - return itemsize; - } - - calcsize = PyObject_GetAttrString(structmodule, "calcsize"); + calcsize = _PyImport_GetModuleAttrString("struct", "calcsize"); if (calcsize == NULL) { goto done; } @@ -558,7 +552,6 @@ PyBuffer_SizeFromFormat(const char *format) } done: - Py_DECREF(structmodule); Py_XDECREF(calcsize); Py_XDECREF(fmt); Py_XDECREF(res); diff --git a/Objects/fileobject.c b/Objects/fileobject.c index 8dba5b9aea6db1..cbc57412134d3e 100644 --- a/Objects/fileobject.c +++ b/Objects/fileobject.c @@ -32,16 +32,16 @@ PyObject * PyFile_FromFd(int fd, const char *name, const char *mode, int buffering, const char *encoding, const char *errors, const char *newline, int closefd) { - PyObject *io, *stream; + PyObject *open, *stream; /* import _io in case we are being used to open io.py */ - io = PyImport_ImportModule("_io"); - if (io == NULL) + open = _PyImport_GetModuleAttrString("_io", "open"); + if (open == NULL) return NULL; - stream = _PyObject_CallMethod(io, &_Py_ID(open), "isisssO", fd, mode, + stream = PyObject_CallFunction(open, "isisssO", fd, mode, buffering, encoding, errors, newline, closefd ? Py_True : Py_False); - Py_DECREF(io); + Py_DECREF(open); if (stream == NULL) return NULL; /* ignore name attribute because the name attribute of _BufferedIOMixin @@ -490,7 +490,7 @@ PyFile_SetOpenCodeHook(Py_OpenCodeHookFunction hook, void *userData) { PyObject * PyFile_OpenCodeObject(PyObject *path) { - PyObject *iomod, *f = NULL; + PyObject *f = NULL; if (!PyUnicode_Check(path)) { PyErr_Format(PyExc_TypeError, "'path' must be 'str', not '%.200s'", @@ -502,10 +502,10 @@ PyFile_OpenCodeObject(PyObject *path) if (hook) { f = hook(path, _PyRuntime.open_code_userdata); } else { - iomod = PyImport_ImportModule("_io"); - if (iomod) { - f = _PyObject_CallMethod(iomod, &_Py_ID(open), "Os", path, "rb"); - Py_DECREF(iomod); + PyObject *open = _PyImport_GetModuleAttrString("_io", "open"); + if (open) { + f = PyObject_CallFunction(open, "Os", path, "rb"); + Py_DECREF(open); } } diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c index 8c269168824471..c833c0bef65f39 100644 --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -1950,18 +1950,12 @@ unpacker_free(struct unpacker *x) static struct unpacker * struct_get_unpacker(const char *fmt, Py_ssize_t itemsize) { - PyObject *structmodule; /* XXX cache these two */ - PyObject *Struct = NULL; /* XXX in globals? */ + PyObject *Struct = NULL; /* XXX cache it in globals? */ PyObject *structobj = NULL; PyObject *format = NULL; struct unpacker *x = NULL; - structmodule = PyImport_ImportModule("struct"); - if (structmodule == NULL) - return NULL; - - Struct = PyObject_GetAttrString(structmodule, "Struct"); - Py_DECREF(structmodule); + Struct = _PyImport_GetModuleAttrString("struct", "Struct"); if (Struct == NULL) return NULL; diff --git a/Parser/pegen.c b/Parser/pegen.c index ec4fee3fc4b712..dbf105aedcf427 100644 --- a/Parser/pegen.c +++ b/Parser/pegen.c @@ -77,13 +77,7 @@ init_normalization(Parser *p) if (p->normalize) { return 1; } - PyObject *m = PyImport_ImportModule("unicodedata"); - if (!m) - { - return 0; - } - p->normalize = PyObject_GetAttrString(m, "normalize"); - Py_DECREF(m); + p->normalize = _PyImport_GetModuleAttrString("unicodedata", "normalize"); if (!p->normalize) { return 0; diff --git a/Parser/tokenizer.c b/Parser/tokenizer.c index d5b549c8706ce5..952265eb923f9d 100644 --- a/Parser/tokenizer.c +++ b/Parser/tokenizer.c @@ -421,7 +421,7 @@ tok_readline_recode(struct tok_state *tok) { static int fp_setreadl(struct tok_state *tok, const char* enc) { - PyObject *readline, *io, *stream; + PyObject *readline, *open, *stream; int fd; long pos; @@ -438,13 +438,13 @@ fp_setreadl(struct tok_state *tok, const char* enc) return 0; } - io = PyImport_ImportModule("io"); - if (io == NULL) { + open = _PyImport_GetModuleAttrString("io", "open"); + if (open == NULL) { return 0; } - stream = _PyObject_CallMethod(io, &_Py_ID(open), "isisOOO", + stream = PyObject_CallFunction(open, "isisOOO", fd, "r", -1, enc, Py_None, Py_None, Py_False); - Py_DECREF(io); + Py_DECREF(open); if (stream == NULL) { return 0; } diff --git a/Python/import.c b/Python/import.c index 4b6d6d16821a94..54c21fa4a56aa9 100644 --- a/Python/import.c +++ b/Python/import.c @@ -48,7 +48,7 @@ module _imp PyStatus _PyImportZip_Init(PyThreadState *tstate) { - PyObject *path_hooks, *zipimport; + PyObject *path_hooks; int err = 0; path_hooks = PySys_GetObject("path_hooks"); @@ -63,32 +63,22 @@ _PyImportZip_Init(PyThreadState *tstate) PySys_WriteStderr("# installing zipimport hook\n"); } - zipimport = PyImport_ImportModule("zipimport"); - if (zipimport == NULL) { - _PyErr_Clear(tstate); /* No zip import module -- okay */ + PyObject *zipimporter = _PyImport_GetModuleAttrString("zipimport", "zipimporter"); + if (zipimporter == NULL) { + _PyErr_Clear(tstate); /* No zipimporter object -- okay */ if (verbose) { - PySys_WriteStderr("# can't import zipimport\n"); + PySys_WriteStderr("# can't import zipimport.zipimporter\n"); } } else { - PyObject *zipimporter = PyObject_GetAttr(zipimport, &_Py_ID(zipimporter)); - Py_DECREF(zipimport); - if (zipimporter == NULL) { - _PyErr_Clear(tstate); /* No zipimporter object -- okay */ - if (verbose) { - PySys_WriteStderr("# can't import zipimport.zipimporter\n"); - } + /* sys.path_hooks.insert(0, zipimporter) */ + err = PyList_Insert(path_hooks, 0, zipimporter); + Py_DECREF(zipimporter); + if (err < 0) { + goto error; } - else { - /* sys.path_hooks.insert(0, zipimporter) */ - err = PyList_Insert(path_hooks, 0, zipimporter); - Py_DECREF(zipimporter); - if (err < 0) { - goto error; - } - if (verbose) { - PySys_WriteStderr("# installed zipimport hook\n"); - } + if (verbose) { + PySys_WriteStderr("# installed zipimport hook\n"); } } @@ -2632,6 +2622,37 @@ PyImport_AppendInittab(const char *name, PyObject* (*initfunc)(void)) return PyImport_ExtendInittab(newtab); } + +PyObject * +_PyImport_GetModuleAttr(PyObject *modname, PyObject *attrname) +{ + PyObject *mod = PyImport_Import(modname); + if (mod == NULL) { + return NULL; + } + PyObject *result = PyObject_GetAttr(mod, attrname); + Py_DECREF(mod); + return result; +} + +PyObject * +_PyImport_GetModuleAttrString(const char *modname, const char *attrname) +{ + PyObject *pmodname = PyUnicode_FromString(modname); + if (pmodname == NULL) { + return NULL; + } + PyObject *pattrname = PyUnicode_FromString(attrname); + if (pattrname == NULL) { + Py_DECREF(pmodname); + return NULL; + } + PyObject *result = _PyImport_GetModuleAttr(pmodname, pattrname); + Py_DECREF(pattrname); + Py_DECREF(pmodname); + return result; +} + #ifdef __cplusplus } #endif diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 31a358fe80de2e..0937cce5c38f30 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -2342,19 +2342,15 @@ create_stdio(const PyConfig *config, PyObject* io, static PyStatus init_set_builtins_open(void) { - PyObject *iomod = NULL, *wrapper; + PyObject *wrapper; PyObject *bimod = NULL; PyStatus res = _PyStatus_OK(); - if (!(iomod = PyImport_ImportModule("io"))) { - goto error; - } - if (!(bimod = PyImport_ImportModule("builtins"))) { goto error; } - if (!(wrapper = PyObject_GetAttrString(iomod, "open"))) { + if (!(wrapper = _PyImport_GetModuleAttrString("io", "open"))) { goto error; } @@ -2371,7 +2367,6 @@ init_set_builtins_open(void) done: Py_XDECREF(bimod); - Py_XDECREF(iomod); return res; }