If Python is initialized multiple times, :c:func:`PyImport_AppendInittab` or
:c:func:`PyImport_ExtendInittab` must be called before each Python
initialization.
+
+
+.. c:function:: PyObject* PyImport_ImportModuleAttr(PyObject *mod_name, PyObject *attr_name)
+
+ Import the module *mod_name* and get its attribute *attr_name*.
+
+ Names must be Python :class:`str` objects.
+
+ Helper function combining :c:func:`PyImport_Import` and
+ :c:func:`PyObject_GetAttr`. For example, it can raise :exc:`ImportError` if
+ the module is not found, and :exc:`AttributeError` if the attribute doesn't
+ exist.
+
+ .. versionadded:: 3.14
+
+.. c:function:: PyObject* PyImport_ImportModuleAttrString(const char *mod_name, const char *attr_name)
+
+ Similar to :c:func:`PyImport_ImportModuleAttr`, but names are UTF-8 encoded
+ strings instead of Python :class:`str` objects.
+
+ .. versionadded:: 3.14
_Py_c_sum:Py_complex:::
_Py_c_sum:Py_complex:left::
_Py_c_sum:Py_complex:right::
+
+PyImport_ImportModuleAttr:PyObject*::+1:
+PyImport_ImportModuleAttr:PyObject*:mod_name:0:
+PyImport_ImportModuleAttr:PyObject*:attr_name:0:
+
+PyImport_ImportModuleAttrString:PyObject*::+1:
+PyImport_ImportModuleAttrString:const char *:mod_name::
+PyImport_ImportModuleAttrString:const char *:attr_name::
* Add :c:func:`PyUnstable_IsImmortal` for determining whether an object is :term:`immortal`,
for debugging purposes.
+* Add :c:func:`PyImport_ImportModuleAttr` and
+ :c:func:`PyImport_ImportModuleAttrString` helper functions to import a module
+ and get an attribute of the module.
+ (Contributed by Victor Stinner in :gh:`128911`.)
+
Limited C API changes
---------------------
collection of frozen modules: */
PyAPI_DATA(const struct _frozen *) PyImport_FrozenModules;
+
+PyAPI_FUNC(PyObject*) PyImport_ImportModuleAttr(
+ PyObject *mod_name,
+ PyObject *attr_name);
+PyAPI_FUNC(PyObject*) PyImport_ImportModuleAttrString(
+ const char *mod_name,
+ const char *attr_name);
PyObject *modules
);
-// Export for many shared extensions, like '_json'
-PyAPI_FUNC(PyObject*) _PyImport_GetModuleAttr(PyObject *, PyObject *);
-
-// Export for many shared extensions, like '_datetime'
-PyAPI_FUNC(PyObject*) _PyImport_GetModuleAttrString(const char *, const char *);
-
struct _import_runtime_state {
/* The builtin modules (defined in config.c). */
from test.support import import_helper
from test.support.warnings_helper import check_warnings
+_testcapi = import_helper.import_module('_testcapi')
_testlimitedcapi = import_helper.import_module('_testlimitedcapi')
NULL = None
try:
self.assertEqual(import_frozen_module('zipimport'), 1)
- # import zipimport again
+ # import zipimport again
self.assertEqual(import_frozen_module('zipimport'), 1)
finally:
sys.modules['zipimport'] = old_zipimport
# CRASHES execute_code_func(NULL, code, NULL, NULL)
# CRASHES execute_code_func(name, NULL, NULL, NULL)
+ def check_importmoduleattr(self, importmoduleattr):
+ self.assertIs(importmoduleattr('sys', 'argv'), sys.argv)
+ self.assertIs(importmoduleattr('types', 'ModuleType'), types.ModuleType)
+
+ # module name containing a dot
+ attr = importmoduleattr('email.message', 'Message')
+ from email.message import Message
+ self.assertIs(attr, Message)
+
+ with self.assertRaises(ImportError):
+ # nonexistent module
+ importmoduleattr('nonexistentmodule', 'attr')
+ with self.assertRaises(AttributeError):
+ # nonexistent attribute
+ importmoduleattr('sys', 'nonexistentattr')
+ with self.assertRaises(AttributeError):
+ # attribute name containing a dot
+ importmoduleattr('sys', 'implementation.name')
+
+ def test_importmoduleattr(self):
+ # Test PyImport_ImportModuleAttr()
+ importmoduleattr = _testcapi.PyImport_ImportModuleAttr
+ self.check_importmoduleattr(importmoduleattr)
+
+ # Invalid module name type
+ for mod_name in (object(), 123, b'bytes'):
+ with self.subTest(mod_name=mod_name):
+ with self.assertRaises(TypeError):
+ importmoduleattr(mod_name, "attr")
+
+ # Invalid attribute name type
+ for attr_name in (object(), 123, b'bytes'):
+ with self.subTest(attr_name=attr_name):
+ with self.assertRaises(TypeError):
+ importmoduleattr("sys", attr_name)
+
+ with self.assertRaises(SystemError):
+ importmoduleattr(NULL, "argv")
+ # CRASHES importmoduleattr("sys", NULL)
+
+ def test_importmoduleattrstring(self):
+ # Test PyImport_ImportModuleAttrString()
+ importmoduleattr = _testcapi.PyImport_ImportModuleAttrString
+ self.check_importmoduleattr(importmoduleattr)
+
+ with self.assertRaises(UnicodeDecodeError):
+ importmoduleattr(b"sys\xff", "argv")
+ with self.assertRaises(UnicodeDecodeError):
+ importmoduleattr("sys", b"argv\xff")
+
+ # CRASHES importmoduleattr(NULL, "argv")
+ # CRASHES importmoduleattr("sys", NULL)
+
# TODO: test PyImport_GetImporter()
# TODO: test PyImport_ReloadModule()
# TODO: test PyImport_ExtendInittab()
--- /dev/null
+Add :c:func:`PyImport_ImportModuleAttr` and :c:func:`PyImport_ImportModuleAttrString`
+helper functions to import a module and get an attribute of the module. Patch
+by Victor Stinner.
@MODULE__XXTESTFUZZ_TRUE@_xxtestfuzz _xxtestfuzz/_xxtestfuzz.c _xxtestfuzz/fuzzer.c
@MODULE__TESTBUFFER_TRUE@_testbuffer _testbuffer.c
@MODULE__TESTINTERNALCAPI_TRUE@_testinternalcapi _testinternalcapi.c _testinternalcapi/test_lock.c _testinternalcapi/pytime.c _testinternalcapi/set.c _testinternalcapi/test_critical_sections.c
-@MODULE__TESTCAPI_TRUE@_testcapi _testcapimodule.c _testcapi/vectorcall.c _testcapi/heaptype.c _testcapi/abstract.c _testcapi/unicode.c _testcapi/dict.c _testcapi/set.c _testcapi/list.c _testcapi/tuple.c _testcapi/getargs.c _testcapi/datetime.c _testcapi/docstring.c _testcapi/mem.c _testcapi/watchers.c _testcapi/long.c _testcapi/float.c _testcapi/complex.c _testcapi/numbers.c _testcapi/structmember.c _testcapi/exceptions.c _testcapi/code.c _testcapi/buffer.c _testcapi/pyatomic.c _testcapi/run.c _testcapi/file.c _testcapi/codec.c _testcapi/immortal.c _testcapi/gc.c _testcapi/hash.c _testcapi/time.c _testcapi/bytes.c _testcapi/object.c _testcapi/monitoring.c _testcapi/config.c
+@MODULE__TESTCAPI_TRUE@_testcapi _testcapimodule.c _testcapi/vectorcall.c _testcapi/heaptype.c _testcapi/abstract.c _testcapi/unicode.c _testcapi/dict.c _testcapi/set.c _testcapi/list.c _testcapi/tuple.c _testcapi/getargs.c _testcapi/datetime.c _testcapi/docstring.c _testcapi/mem.c _testcapi/watchers.c _testcapi/long.c _testcapi/float.c _testcapi/complex.c _testcapi/numbers.c _testcapi/structmember.c _testcapi/exceptions.c _testcapi/code.c _testcapi/buffer.c _testcapi/pyatomic.c _testcapi/run.c _testcapi/file.c _testcapi/codec.c _testcapi/immortal.c _testcapi/gc.c _testcapi/hash.c _testcapi/time.c _testcapi/bytes.c _testcapi/object.c _testcapi/monitoring.c _testcapi/config.c _testcapi/import.c
@MODULE__TESTLIMITEDCAPI_TRUE@_testlimitedcapi _testlimitedcapi.c _testlimitedcapi/abstract.c _testlimitedcapi/bytearray.c _testlimitedcapi/bytes.c _testlimitedcapi/codec.c _testlimitedcapi/complex.c _testlimitedcapi/dict.c _testlimitedcapi/eval.c _testlimitedcapi/float.c _testlimitedcapi/heaptype_relative.c _testlimitedcapi/import.c _testlimitedcapi/list.c _testlimitedcapi/long.c _testlimitedcapi/object.c _testlimitedcapi/pyos.c _testlimitedcapi/set.c _testlimitedcapi/sys.c _testlimitedcapi/tuple.c _testlimitedcapi/unicode.c _testlimitedcapi/vectorcall_limited.c _testlimitedcapi/version.c
@MODULE__TESTCLINIC_TRUE@_testclinic _testclinic.c
@MODULE__TESTCLINIC_LIMITED_TRUE@_testclinic_limited _testclinic_limited.c
if (context == NULL)
context = PyUnicode_InternFromString("_ctypes.DllGetClassObject");
- func = _PyImport_GetModuleAttrString("ctypes", "DllGetClassObject");
+ func = PyImport_ImportModuleAttrString("ctypes", "DllGetClassObject");
if (!func) {
PyErr_WriteUnraisable(context ? context : Py_None);
/* There has been a warning before about this already */
goto error;
}
- PyObject *layout_func = _PyImport_GetModuleAttrString("ctypes._layout",
+ PyObject *layout_func = PyImport_ImportModuleAttrString("ctypes._layout",
"get_layout");
if (!layout_func) {
goto error;
if (called == TRUE) {
return 1;
}
- PyObject *exc = _PyImport_GetModuleAttrString("_curses", "error");
+ PyObject *exc = PyImport_ImportModuleAttrString("_curses", "error");
if (exc != NULL) {
PyErr_Format(exc, "must call %s() first", funcname);
Py_DECREF(exc);
assert(object && format && timetuple);
assert(PyUnicode_Check(format));
- PyObject *strftime = _PyImport_GetModuleAttrString("time", "strftime");
+ PyObject *strftime = PyImport_ImportModuleAttrString("time", "strftime");
if (strftime == NULL) {
return NULL;
}
time_time(void)
{
PyObject *result = NULL;
- PyObject *time = _PyImport_GetModuleAttrString("time", "time");
+ PyObject *time = PyImport_ImportModuleAttrString("time", "time");
if (time != NULL) {
result = PyObject_CallNoArgs(time);
PyObject *struct_time;
PyObject *result;
- struct_time = _PyImport_GetModuleAttrString("time", "struct_time");
+ struct_time = PyImport_ImportModuleAttrString("time", "struct_time");
if (struct_time == NULL) {
return NULL;
}
PyObject *u;
if (state->PyDecimal == NULL) {
- state->PyDecimal = _PyImport_GetModuleAttrString("_pydecimal", "Decimal");
+ state->PyDecimal = PyImport_ImportModuleAttrString("_pydecimal", "Decimal");
if (state->PyDecimal == NULL) {
return NULL;
}
#endif
#include "Python.h"
-#include "pycore_import.h" // _PyImport_GetModuleAttrString()
#include "pycore_pyhash.h" // _Py_HashSecret
#include <stddef.h> // offsetof()
CREATE_TYPE(m, st->Element_Type, &element_spec);
CREATE_TYPE(m, st->XMLParser_Type, &xmlparser_spec);
- st->deepcopy_obj = _PyImport_GetModuleAttrString("copy", "deepcopy");
+ st->deepcopy_obj = PyImport_ImportModuleAttrString("copy", "deepcopy");
if (st->deepcopy_obj == NULL) {
goto error;
}
goto error;
/* link against pyexpat */
- if (!(st->expat_capsule = _PyImport_GetModuleAttrString("pyexpat", "expat_CAPI")))
+ if (!(st->expat_capsule = PyImport_ImportModuleAttrString("pyexpat", "expat_CAPI")))
goto error;
if (!(st->expat_capi = PyCapsule_GetPointer(st->expat_capsule, PyExpat_CAPSULE_NAME)))
goto error;
/* Use JSONDecodeError exception to raise a nice looking ValueError subclass */
_Py_DECLARE_STR(json_decoder, "json.decoder");
PyObject *JSONDecodeError =
- _PyImport_GetModuleAttr(&_Py_STR(json_decoder), &_Py_ID(JSONDecodeError));
+ PyImport_ImportModuleAttr(&_Py_STR(json_decoder), &_Py_ID(JSONDecodeError));
if (JSONDecodeError == NULL) {
return;
}
return NULL;
}
- PyObject* monitoring = _PyImport_GetModuleAttrString("sys", "monitoring");
+ PyObject* monitoring = PyImport_ImportModuleAttrString("sys", "monitoring");
if (!monitoring) {
return NULL;
}
}
if (self->flags & POF_ENABLED) {
PyObject* result = NULL;
- PyObject* monitoring = _PyImport_GetModuleAttrString("sys", "monitoring");
+ PyObject* monitoring = PyImport_ImportModuleAttrString("sys", "monitoring");
if (!monitoring) {
return NULL;
Py_XSETREF(self->externalTimer, Py_XNewRef(timer));
self->tool_id = PY_MONITORING_PROFILER_ID;
- PyObject* monitoring = _PyImport_GetModuleAttrString("sys", "monitoring");
+ PyObject* monitoring = PyImport_ImportModuleAttrString("sys", "monitoring");
if (!monitoring) {
return -1;
}
PyObject *constructor;
PyObject *newargs[2];
- partial = _PyImport_GetModuleAttrString("functools", "partial");
+ partial = PyImport_ImportModuleAttrString("functools", "partial");
if (!partial)
return NULL;
}
Py_CLEAR(compat_pickle);
- st->codecs_encode = _PyImport_GetModuleAttrString("codecs", "encode");
+ st->codecs_encode = PyImport_ImportModuleAttrString("codecs", "encode");
if (st->codecs_encode == NULL) {
goto error;
}
goto error;
}
- st->partial = _PyImport_GetModuleAttrString("functools", "partial");
+ st->partial = PyImport_ImportModuleAttrString("functools", "partial");
if (!st->partial)
goto error;
#include "prepare_protocol.h"
#include "util.h"
-#include "pycore_import.h" // _PyImport_GetModuleAttrString()
#include "pycore_modsupport.h" // _PyArg_NoKeywords()
#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1()
#include "pycore_pylifecycle.h" // _Py_IsInterpreterFinalizing()
return NULL;
}
- PyObject *iterdump = _PyImport_GetModuleAttrString(MODULE_NAME ".dump", "_iterdump");
+ PyObject *iterdump = PyImport_ImportModuleAttrString(MODULE_NAME ".dump", "_iterdump");
if (!iterdump) {
if (!PyErr_Occurred()) {
PyErr_SetString(self->OperationalError,
#include "row.h"
#include "blob.h"
-#include "pycore_import.h" // _PyImport_GetModuleAttrString()
-
#if SQLITE_VERSION_NUMBER < 3015002
#error "SQLite 3.15.2 or higher required"
#endif
load_functools_lru_cache(PyObject *module)
{
pysqlite_state *state = pysqlite_get_state(module);
- state->lru_cache = _PyImport_GetModuleAttrString("functools", "lru_cache");
+ state->lru_cache = PyImport_ImportModuleAttrString("functools", "lru_cache");
if (state->lru_cache == NULL) {
return -1;
}
/* delegate to Python code */
PyObject *func = module_state->compile_template;
if (func == NULL) {
- func = _PyImport_GetModuleAttrString("re", "_compile_template");
+ func = PyImport_ImportModuleAttrString("re", "_compile_template");
if (func == NULL) {
return NULL;
}
--- /dev/null
+#include "parts.h"
+#include "util.h"
+
+// Test PyImport_ImportModuleAttr()
+static PyObject *
+pyimport_importmoduleattr(PyObject *self, PyObject *args)
+{
+ PyObject *mod_name, *attr_name;
+ if (!PyArg_ParseTuple(args, "OO", &mod_name, &attr_name)) {
+ return NULL;
+ }
+ NULLABLE(mod_name);
+ NULLABLE(attr_name);
+
+ return PyImport_ImportModuleAttr(mod_name, attr_name);
+}
+
+
+// Test PyImport_ImportModuleAttrString()
+static PyObject *
+pyimport_importmoduleattrstring(PyObject *self, PyObject *args)
+{
+ const char *mod_name, *attr_name;
+ Py_ssize_t len;
+ if (!PyArg_ParseTuple(args, "z#z#", &mod_name, &len, &attr_name, &len)) {
+ return NULL;
+ }
+
+ return PyImport_ImportModuleAttrString(mod_name, attr_name);
+}
+
+
+static PyMethodDef test_methods[] = {
+ {"PyImport_ImportModuleAttr", pyimport_importmoduleattr, METH_VARARGS},
+ {"PyImport_ImportModuleAttrString", pyimport_importmoduleattrstring, METH_VARARGS},
+ {NULL},
+};
+
+int
+_PyTestCapi_Init_Import(PyObject *m)
+{
+ return PyModule_AddFunctions(m, test_methods);
+}
+
int _PyTestCapi_Init_Monitoring(PyObject *module);
int _PyTestCapi_Init_Object(PyObject *module);
int _PyTestCapi_Init_Config(PyObject *mod);
+int _PyTestCapi_Init_Import(PyObject *mod);
#endif // Py_TESTCAPI_PARTS_H
if (_PyTestCapi_Init_Config(m) < 0) {
return NULL;
}
+ if (_PyTestCapi_Init_Import(m) < 0) {
+ return NULL;
+ }
PyState_AddModule(m, &_testcapimodule);
return m;
if (self->source == SOURCE_FILE) {
// Objects constructed from files cannot be pickled.
PyObject *pickle_error =
- _PyImport_GetModuleAttrString("pickle", "PicklingError");
+ PyImport_ImportModuleAttrString("pickle", "PicklingError");
if (pickle_error == NULL) {
return NULL;
}
new_weak_cache(void)
{
PyObject *WeakValueDictionary =
- _PyImport_GetModuleAttrString("weakref", "WeakValueDictionary");
+ PyImport_ImportModuleAttrString("weakref", "WeakValueDictionary");
if (WeakValueDictionary == NULL) {
return NULL;
}
/* Populate imports */
state->_tzpath_find_tzfile =
- _PyImport_GetModuleAttrString("zoneinfo._tzpath", "find_tzfile");
+ PyImport_ImportModuleAttrString("zoneinfo._tzpath", "find_tzfile");
if (state->_tzpath_find_tzfile == NULL) {
goto error;
}
- state->io_open = _PyImport_GetModuleAttrString("io", "open");
+ state->io_open = PyImport_ImportModuleAttrString("io", "open");
if (state->io_open == NULL) {
goto error;
}
assert(state != NULL);
if (state->array_reconstructor == NULL) {
- state->array_reconstructor = _PyImport_GetModuleAttrString(
+ state->array_reconstructor = PyImport_ImportModuleAttrString(
"array", "_array_reconstructor");
if (state->array_reconstructor == NULL) {
return NULL;
return -1;
}
- PyObject *mutablesequence = _PyImport_GetModuleAttrString(
+ PyObject *mutablesequence = PyImport_ImportModuleAttrString(
"collections.abc", "MutableSequence");
if (!mutablesequence) {
Py_DECREF((PyObject *)state->ArrayType);
#include "Python.h"
#include "multibytecodec.h"
-#include "pycore_import.h" // _PyImport_GetModuleAttrString()
/* a unicode "undefined" code point */
static PyObject *
getmultibytecodec(void)
{
- return _PyImport_GetModuleAttrString("_multibytecodec", "__create_codec");
+ return PyImport_ImportModuleAttrString("_multibytecodec", "__create_codec");
}
static void
static int
faulthandler_init_enable(void)
{
- PyObject *enable = _PyImport_GetModuleAttrString("faulthandler", "enable");
+ PyObject *enable = PyImport_ImportModuleAttrString("faulthandler", "enable");
if (enable == NULL) {
return -1;
}
memset(ru, 0, sizeof(*ru));
}
- struct_rusage = _PyImport_GetModuleAttrString("resource", "struct_rusage");
+ struct_rusage = PyImport_ImportModuleAttrString("resource", "struct_rusage");
if (struct_rusage == NULL)
return NULL;
#include "Python.h"
#include "pycore_fileutils.h" // _Py_set_inheritable()
-#include "pycore_import.h" // _PyImport_GetModuleAttrString()
#include "pycore_time.h" // _PyTime_FromSecondsObject()
#include <stdbool.h>
// Register a callback to invalidate kqueues with open fds after fork.
PyObject *register_at_fork = NULL, *cb = NULL, *args = NULL,
*kwargs = NULL, *result = NULL;
- register_at_fork = _PyImport_GetModuleAttrString("posix",
+ register_at_fork = PyImport_ImportModuleAttrString("posix",
"register_at_fork");
if (register_at_fork == NULL) {
goto finally;
{
PyObject *func, *result;
- func = _PyImport_GetModuleAttrString("_strptime", "_strptime_time");
+ func = PyImport_ImportModuleAttrString("_strptime", "_strptime_time");
if (!func) {
return NULL;
}
PyObject *fmt = NULL;
Py_ssize_t itemsize = -1;
- calcsize = _PyImport_GetModuleAttrString("struct", "calcsize");
+ calcsize = PyImport_ImportModuleAttrString("struct", "calcsize");
if (calcsize == NULL) {
goto done;
}
PyObject *open, *stream;
/* import _io in case we are being used to open io.py */
- open = _PyImport_GetModuleAttrString("_io", "open");
+ open = PyImport_ImportModuleAttrString("_io", "open");
if (open == NULL)
return NULL;
stream = PyObject_CallFunction(open, "isisssO", fd, mode,
if (hook) {
f = hook(path, _PyRuntime.open_code_userdata);
} else {
- PyObject *open = _PyImport_GetModuleAttrString("_io", "open");
+ PyObject *open = PyImport_ImportModuleAttrString("_io", "open");
if (open) {
f = PyObject_CallFunction(open, "Os", path, "rb");
Py_DECREF(open);
PyObject *format = NULL;
struct unpacker *x = NULL;
- Struct = _PyImport_GetModuleAttrString("struct", "Struct");
+ Struct = PyImport_ImportModuleAttrString("struct", "Struct");
if (Struct == NULL)
return NULL;
<ClCompile Include="..\Modules\_testcapi\run.c" />
<ClCompile Include="..\Modules\_testcapi\monitoring.c" />
<ClCompile Include="..\Modules\_testcapi\config.c" />
+ <ClCompile Include="..\Modules\_testcapi\import.c" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\PC\python_nt.rc" />
<ClCompile Include="..\Modules\_testcapi\config.c">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="..\Modules\_testcapi\import.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\PC\python_nt.rc">
if (p->normalize) {
return 1;
}
- p->normalize = _PyImport_GetModuleAttrString("unicodedata", "normalize");
+ p->normalize = PyImport_ImportModuleAttrString("unicodedata", "normalize");
if (!p->normalize)
{
return 0;
return 0;
}
- open = _PyImport_GetModuleAttrString("io", "open");
+ open = PyImport_ImportModuleAttrString("io", "open");
if (open == NULL) {
return 0;
}
PySys_WriteStderr("# installing zipimport hook\n");
}
- PyObject *zipimporter = _PyImport_GetModuleAttrString("zipimport", "zipimporter");
+ PyObject *zipimporter = PyImport_ImportModuleAttrString("zipimport", "zipimporter");
if (zipimporter == NULL) {
_PyErr_Clear(tstate); /* No zipimporter object -- okay */
if (verbose) {
/******************/
PyObject *
-_PyImport_GetModuleAttr(PyObject *modname, PyObject *attrname)
+PyImport_ImportModuleAttr(PyObject *modname, PyObject *attrname)
{
PyObject *mod = PyImport_Import(modname);
if (mod == NULL) {
}
PyObject *
-_PyImport_GetModuleAttrString(const char *modname, const char *attrname)
+PyImport_ImportModuleAttrString(const char *modname, const char *attrname)
{
PyObject *pmodname = PyUnicode_FromString(modname);
if (pmodname == NULL) {
Py_DECREF(pmodname);
return NULL;
}
- PyObject *result = _PyImport_GetModuleAttr(pmodname, pattrname);
+ PyObject *result = PyImport_ImportModuleAttr(pmodname, pattrname);
Py_DECREF(pattrname);
Py_DECREF(pmodname);
return result;
#ifdef HAVE_WINDOWS_CONSOLE_IO
/* Windows console IO is always UTF-8 encoded */
- PyTypeObject *winconsoleio_type = (PyTypeObject *)_PyImport_GetModuleAttr(
+ PyTypeObject *winconsoleio_type = (PyTypeObject *)PyImport_ImportModuleAttr(
&_Py_ID(_io), &_Py_ID(_WindowsConsoleIO));
if (winconsoleio_type == NULL) {
goto error;
goto error;
}
- if (!(wrapper = _PyImport_GetModuleAttrString("io", "open"))) {
+ if (!(wrapper = PyImport_ImportModuleAttrString("io", "open"))) {
goto error;
}