mirror of
https://github.com/python/cpython.git
synced 2025-07-28 13:44:43 +00:00
Modified PyImport_Import and PyImport_ImportModule to always use absolute imports by calling __import__ with an explicit level of 0
Added a new API function PyImport_ImportModuleNoBlock. It solves the problem with dead locks when mixing threads and imports
This commit is contained in:
parent
0a83d79268
commit
000a074c95
19 changed files with 135 additions and 63 deletions
|
@ -183,7 +183,8 @@ Importing Modules
|
||||||
single: __all__ (package variable)
|
single: __all__ (package variable)
|
||||||
|
|
||||||
This is a simplified interface to :cfunc:`PyImport_ImportModuleEx` below,
|
This is a simplified interface to :cfunc:`PyImport_ImportModuleEx` below,
|
||||||
leaving the *globals* and *locals* arguments set to *NULL*. When the *name*
|
leaving the *globals* and *locals* arguments set to *NULL* and *level* set
|
||||||
|
to 0. When the *name*
|
||||||
argument contains a dot (when it specifies a submodule of a package), the
|
argument contains a dot (when it specifies a submodule of a package), the
|
||||||
*fromlist* argument is set to the list ``['*']`` so that the return value is the
|
*fromlist* argument is set to the list ``['*']`` so that the return value is the
|
||||||
named module rather than the top-level package containing it as would otherwise
|
named module rather than the top-level package containing it as would otherwise
|
||||||
|
@ -198,9 +199,28 @@ Importing Modules
|
||||||
.. versionchanged:: 2.4
|
.. versionchanged:: 2.4
|
||||||
failing imports remove incomplete module objects.
|
failing imports remove incomplete module objects.
|
||||||
|
|
||||||
|
.. versionchanged:: 2.6
|
||||||
|
always use absolute imports
|
||||||
|
|
||||||
.. index:: single: modules (in module sys)
|
.. index:: single: modules (in module sys)
|
||||||
|
|
||||||
|
|
||||||
|
.. cfunction:: PyObject* PyImport_ImportModuleNoBlock(const char *name)
|
||||||
|
|
||||||
|
.. index::
|
||||||
|
single: `cfunc:PyImport_ImportModule`
|
||||||
|
|
||||||
|
This version of `cfunc:PyImport_ImportModule` does not block. It's intended
|
||||||
|
to be used in C function which import other modules to execute a function.
|
||||||
|
The import may block if another thread holds the import lock. The function
|
||||||
|
`cfunc:PyImport_ImportModuleNoBlock` doesn't block. It first tries to fetch
|
||||||
|
the module from sys.modules and falls back to `cfunc:PyImport_ImportModule`
|
||||||
|
unless the the lock is hold. In the latter case the function raises an
|
||||||
|
ImportError.
|
||||||
|
|
||||||
|
.. versionadded:: 2.6
|
||||||
|
|
||||||
|
|
||||||
.. cfunction:: PyObject* PyImport_ImportModuleEx(char *name, PyObject *globals, PyObject *locals, PyObject *fromlist)
|
.. cfunction:: PyObject* PyImport_ImportModuleEx(char *name, PyObject *globals, PyObject *locals, PyObject *fromlist)
|
||||||
|
|
||||||
.. index:: builtin: __import__
|
.. index:: builtin: __import__
|
||||||
|
@ -218,6 +238,24 @@ Importing Modules
|
||||||
.. versionchanged:: 2.4
|
.. versionchanged:: 2.4
|
||||||
failing imports remove incomplete module objects.
|
failing imports remove incomplete module objects.
|
||||||
|
|
||||||
|
.. versionchanged:: 2.6
|
||||||
|
The function is an alias for `cfunc:PyImport_ImportModuleLevel` with
|
||||||
|
-1 as level, meaning relative import.
|
||||||
|
|
||||||
|
|
||||||
|
.. cfunction:: PyObject* PyImport_ImportModuleLevel(char *name, PyObject *globals, PyObject *locals, PyObject *fromlist, int level)
|
||||||
|
|
||||||
|
Import a module. This is best described by referring to the built-in Python
|
||||||
|
function :func:`__import__`, as the standard :func:`__import__` function calls
|
||||||
|
this function directly.
|
||||||
|
|
||||||
|
The return value is a new reference to the imported module or top-level package,
|
||||||
|
or *NULL* with an exception set on failure. Like for :func:`__import__`,
|
||||||
|
the return value when a submodule of a package was requested is normally the
|
||||||
|
top-level package, unless a non-empty *fromlist* was given.
|
||||||
|
|
||||||
|
..versionadded:: 2.5
|
||||||
|
|
||||||
|
|
||||||
.. cfunction:: PyObject* PyImport_Import(PyObject *name)
|
.. cfunction:: PyObject* PyImport_Import(PyObject *name)
|
||||||
|
|
||||||
|
@ -230,6 +268,9 @@ Importing Modules
|
||||||
current globals. This means that the import is done using whatever import hooks
|
current globals. This means that the import is done using whatever import hooks
|
||||||
are installed in the current environment, e.g. by :mod:`rexec` or :mod:`ihooks`.
|
are installed in the current environment, e.g. by :mod:`rexec` or :mod:`ihooks`.
|
||||||
|
|
||||||
|
.. versionchanged:: 2.6
|
||||||
|
always use absolute imports
|
||||||
|
|
||||||
|
|
||||||
.. cfunction:: PyObject* PyImport_ReloadModule(PyObject *m)
|
.. cfunction:: PyObject* PyImport_ReloadModule(PyObject *m)
|
||||||
|
|
||||||
|
|
|
@ -14,13 +14,10 @@ PyAPI_FUNC(PyObject *) PyImport_ExecCodeModuleEx(
|
||||||
PyAPI_FUNC(PyObject *) PyImport_GetModuleDict(void);
|
PyAPI_FUNC(PyObject *) PyImport_GetModuleDict(void);
|
||||||
PyAPI_FUNC(PyObject *) PyImport_AddModule(const char *name);
|
PyAPI_FUNC(PyObject *) PyImport_AddModule(const char *name);
|
||||||
PyAPI_FUNC(PyObject *) PyImport_ImportModule(const char *name);
|
PyAPI_FUNC(PyObject *) PyImport_ImportModule(const char *name);
|
||||||
|
PyAPI_FUNC(PyObject *) PyImport_ImportModuleNoBlock(const char *);
|
||||||
PyAPI_FUNC(PyObject *) PyImport_ImportModuleLevel(char *name,
|
PyAPI_FUNC(PyObject *) PyImport_ImportModuleLevel(char *name,
|
||||||
PyObject *globals, PyObject *locals, PyObject *fromlist, int level);
|
PyObject *globals, PyObject *locals, PyObject *fromlist, int level);
|
||||||
|
|
||||||
/* For DLL compatibility */
|
|
||||||
#undef PyImport_ImportModuleEx
|
|
||||||
PyAPI_FUNC(PyObject *) PyImport_ImportModuleEx(
|
|
||||||
char *name, PyObject *globals, PyObject *locals, PyObject *fromlist);
|
|
||||||
#define PyImport_ImportModuleEx(n, g, l, f) \
|
#define PyImport_ImportModuleEx(n, g, l, f) \
|
||||||
PyImport_ImportModuleLevel(n, g, l, f, -1)
|
PyImport_ImportModuleLevel(n, g, l, f, -1)
|
||||||
|
|
||||||
|
|
|
@ -90,7 +90,7 @@ static void **PyCurses_API;
|
||||||
|
|
||||||
#define import_curses() \
|
#define import_curses() \
|
||||||
{ \
|
{ \
|
||||||
PyObject *module = PyImport_ImportModule("_curses"); \
|
PyObject *module = PyImport_ImportModuleNoBlock("_curses"); \
|
||||||
if (module != NULL) { \
|
if (module != NULL) { \
|
||||||
PyObject *module_dict = PyModule_GetDict(module); \
|
PyObject *module_dict = PyModule_GetDict(module); \
|
||||||
PyObject *c_api_object = PyDict_GetItemString(module_dict, "_C_API"); \
|
PyObject *c_api_object = PyDict_GetItemString(module_dict, "_C_API"); \
|
||||||
|
|
|
@ -357,7 +357,7 @@ MacOS_GetErrorString(PyObject *self, PyObject *args)
|
||||||
PyObject *m, *rv;
|
PyObject *m, *rv;
|
||||||
errors_loaded = 1;
|
errors_loaded = 1;
|
||||||
|
|
||||||
m = PyImport_ImportModule("macresource");
|
m = PyImport_ImportModuleNoBlock("macresource");
|
||||||
if (!m) {
|
if (!m) {
|
||||||
if (Py_VerboseFlag)
|
if (Py_VerboseFlag)
|
||||||
PyErr_Print();
|
PyErr_Print();
|
||||||
|
|
36
Misc/NEWS
36
Misc/NEWS
|
@ -14,25 +14,10 @@ Core and builtins
|
||||||
|
|
||||||
- Issue #1640: Added math.isinf() and math.isnan() functions.
|
- Issue #1640: Added math.isinf() and math.isnan() functions.
|
||||||
|
|
||||||
- Issue #1726: Remove Python/atof.c from PCBuild/pythoncore.vcproj
|
|
||||||
|
|
||||||
- Removed PCbuild8/ directory and added a new build directory for VS 2005
|
|
||||||
based on the VS 2008 build directory to PC/VS8.0. The script
|
|
||||||
PCbuild/vs8to9.py was added to sync changes from PCbuild to PC/VS8.0.
|
|
||||||
|
|
||||||
- Moved PCbuild/ directory for VS 2003 to PC/VS7.1 and renamed PCBuild9/
|
|
||||||
directory to PCBuild/.
|
|
||||||
|
|
||||||
- Issue #1629: Renamed Py_Size, Py_Type and Py_Refcnt to Py_SIZE, Py_TYPE
|
|
||||||
and Py_REFCNT.
|
|
||||||
|
|
||||||
- Issue #1635: Platform independent creation and representation of NaN
|
- Issue #1635: Platform independent creation and representation of NaN
|
||||||
and INF. float("nan"), float("inf") and float("-inf") now work on every
|
and INF. float("nan"), float("inf") and float("-inf") now work on every
|
||||||
platform with IEEE 754 semantics.
|
platform with IEEE 754 semantics.
|
||||||
|
|
||||||
- Added case insensitive comparsion methods ``PyOS_stricmp(char*, char*)``
|
|
||||||
and ``PyOS_strnicmp(char*, char*, Py_ssize_t)``.
|
|
||||||
|
|
||||||
- Compiler now generates simpler and faster code for dictionary literals.
|
- Compiler now generates simpler and faster code for dictionary literals.
|
||||||
The oparg for BUILD_MAP now indicates an estimated dictionary size.
|
The oparg for BUILD_MAP now indicates an estimated dictionary size.
|
||||||
There is a new opcode, STORE_MAP, for adding entries to the dictionary.
|
There is a new opcode, STORE_MAP, for adding entries to the dictionary.
|
||||||
|
@ -1165,6 +1150,15 @@ Tools/Demos
|
||||||
Build
|
Build
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
- Issue #1726: Remove Python/atof.c from PCBuild/pythoncore.vcproj
|
||||||
|
|
||||||
|
- Removed PCbuild8/ directory and added a new build directory for VS 2005
|
||||||
|
based on the VS 2008 build directory to PC/VS8.0. The script
|
||||||
|
PCbuild/vs8to9.py was added to sync changes from PCbuild to PC/VS8.0.
|
||||||
|
|
||||||
|
- Moved PCbuild/ directory for VS 2003 to PC/VS7.1 and renamed PCBuild9/
|
||||||
|
directory to PCBuild/.
|
||||||
|
|
||||||
- Bug #1699: Define _BSD_SOURCE only on OpenBSD.
|
- Bug #1699: Define _BSD_SOURCE only on OpenBSD.
|
||||||
|
|
||||||
- Bug #1608: use -fwrapv when GCC supports it. This is important,
|
- Bug #1608: use -fwrapv when GCC supports it. This is important,
|
||||||
|
@ -1225,6 +1219,18 @@ Build
|
||||||
C API
|
C API
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
- Added a new API function ``PyImport_ImportModuleNoBlock``.
|
||||||
|
|
||||||
|
- ``PyImport_Import`` and ``PyImport_ImportModule`` now always do absolute
|
||||||
|
imports. In earlier versions they might have used relative imports under
|
||||||
|
some conditions.
|
||||||
|
|
||||||
|
- Issue #1629: Renamed Py_Size, Py_Type and Py_Refcnt to Py_SIZE, Py_TYPE
|
||||||
|
and Py_REFCNT.
|
||||||
|
|
||||||
|
- Added case insensitive comparsion methods ``PyOS_stricmp(char*, char*)``
|
||||||
|
and ``PyOS_strnicmp(char*, char*, Py_ssize_t)``.
|
||||||
|
|
||||||
- Bug #1542693: remove semi-colon at end of PyImport_ImportModuleEx macro
|
- Bug #1542693: remove semi-colon at end of PyImport_ImportModuleEx macro
|
||||||
so it can be used as an expression.
|
so it can be used as an expression.
|
||||||
|
|
||||||
|
|
|
@ -370,7 +370,7 @@ long Call_GetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
|
||||||
if (context == NULL)
|
if (context == NULL)
|
||||||
context = PyString_FromString("_ctypes.DllGetClassObject");
|
context = PyString_FromString("_ctypes.DllGetClassObject");
|
||||||
|
|
||||||
mod = PyImport_ImportModule("ctypes");
|
mod = PyImport_ImportModuleNoBlock("ctypes");
|
||||||
if (!mod) {
|
if (!mod) {
|
||||||
PyErr_WriteUnraisable(context ? context : Py_None);
|
PyErr_WriteUnraisable(context ? context : Py_None);
|
||||||
/* There has been a warning before about this already */
|
/* There has been a warning before about this already */
|
||||||
|
@ -449,7 +449,7 @@ long Call_CanUnloadNow(void)
|
||||||
if (context == NULL)
|
if (context == NULL)
|
||||||
context = PyString_FromString("_ctypes.DllCanUnloadNow");
|
context = PyString_FromString("_ctypes.DllCanUnloadNow");
|
||||||
|
|
||||||
mod = PyImport_ImportModule("ctypes");
|
mod = PyImport_ImportModuleNoBlock("ctypes");
|
||||||
if (!mod) {
|
if (!mod) {
|
||||||
/* OutputDebugString("Could not import ctypes"); */
|
/* OutputDebugString("Could not import ctypes"); */
|
||||||
/* We assume that this error can only occur when shutting
|
/* We assume that this error can only occur when shutting
|
||||||
|
|
|
@ -2255,7 +2255,7 @@ static int
|
||||||
update_lines_cols(void)
|
update_lines_cols(void)
|
||||||
{
|
{
|
||||||
PyObject *o;
|
PyObject *o;
|
||||||
PyObject *m = PyImport_ImportModule("curses");
|
PyObject *m = PyImport_ImportModuleNoBlock("curses");
|
||||||
|
|
||||||
if (!m)
|
if (!m)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -245,7 +245,7 @@ getmultibytecodec(void)
|
||||||
static PyObject *cofunc = NULL;
|
static PyObject *cofunc = NULL;
|
||||||
|
|
||||||
if (cofunc == NULL) {
|
if (cofunc == NULL) {
|
||||||
PyObject *mod = PyImport_ImportModule("_multibytecodec");
|
PyObject *mod = PyImport_ImportModuleNoBlock("_multibytecodec");
|
||||||
if (mod == NULL)
|
if (mod == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
cofunc = PyObject_GetAttrString(mod, "__create_codec");
|
cofunc = PyObject_GetAttrString(mod, "__create_codec");
|
||||||
|
|
|
@ -1305,7 +1305,7 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
|
||||||
if (_PyString_Resize(&newfmt, usednew) < 0)
|
if (_PyString_Resize(&newfmt, usednew) < 0)
|
||||||
goto Done;
|
goto Done;
|
||||||
{
|
{
|
||||||
PyObject *time = PyImport_ImportModule("time");
|
PyObject *time = PyImport_ImportModuleNoBlock("time");
|
||||||
if (time == NULL)
|
if (time == NULL)
|
||||||
goto Done;
|
goto Done;
|
||||||
result = PyObject_CallMethod(time, "strftime", "OO",
|
result = PyObject_CallMethod(time, "strftime", "OO",
|
||||||
|
@ -1353,7 +1353,7 @@ static PyObject *
|
||||||
time_time(void)
|
time_time(void)
|
||||||
{
|
{
|
||||||
PyObject *result = NULL;
|
PyObject *result = NULL;
|
||||||
PyObject *time = PyImport_ImportModule("time");
|
PyObject *time = PyImport_ImportModuleNoBlock("time");
|
||||||
|
|
||||||
if (time != NULL) {
|
if (time != NULL) {
|
||||||
result = PyObject_CallMethod(time, "time", "()");
|
result = PyObject_CallMethod(time, "time", "()");
|
||||||
|
@ -1371,7 +1371,7 @@ build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag)
|
||||||
PyObject *time;
|
PyObject *time;
|
||||||
PyObject *result = NULL;
|
PyObject *result = NULL;
|
||||||
|
|
||||||
time = PyImport_ImportModule("time");
|
time = PyImport_ImportModuleNoBlock("time");
|
||||||
if (time != NULL) {
|
if (time != NULL) {
|
||||||
result = PyObject_CallMethod(time, "struct_time",
|
result = PyObject_CallMethod(time, "struct_time",
|
||||||
"((iiiiiiiii))",
|
"((iiiiiiiii))",
|
||||||
|
@ -3827,7 +3827,7 @@ datetime_strptime(PyObject *cls, PyObject *args)
|
||||||
if (!PyArg_ParseTuple(args, "ss:strptime", &string, &format))
|
if (!PyArg_ParseTuple(args, "ss:strptime", &string, &format))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if ((module = PyImport_ImportModule("time")) == NULL)
|
if ((module = PyImport_ImportModuleNoBlock("time")) == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
obj = PyObject_CallMethod(module, "strptime", "ss", string, format);
|
obj = PyObject_CallMethod(module, "strptime", "ss", string, format);
|
||||||
Py_DECREF(module);
|
Py_DECREF(module);
|
||||||
|
|
|
@ -1236,7 +1236,7 @@ initgc(void)
|
||||||
* the import and triggers an assertion.
|
* the import and triggers an assertion.
|
||||||
*/
|
*/
|
||||||
if (tmod == NULL) {
|
if (tmod == NULL) {
|
||||||
tmod = PyImport_ImportModule("time");
|
tmod = PyImport_ImportModuleNoBlock("time");
|
||||||
if (tmod == NULL)
|
if (tmod == NULL)
|
||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
}
|
}
|
||||||
|
|
|
@ -3269,7 +3269,7 @@ initparser(void)
|
||||||
* If this fails, the import of this module will fail because an
|
* If this fails, the import of this module will fail because an
|
||||||
* exception will be raised here; should we clear the exception?
|
* exception will be raised here; should we clear the exception?
|
||||||
*/
|
*/
|
||||||
copyreg = PyImport_ImportModule("copy_reg");
|
copyreg = PyImport_ImportModuleNoBlock("copy_reg");
|
||||||
if (copyreg != NULL) {
|
if (copyreg != NULL) {
|
||||||
PyObject *func, *pickler;
|
PyObject *func, *pickler;
|
||||||
|
|
||||||
|
|
|
@ -5651,7 +5651,7 @@ wait_helper(int pid, int status, struct rusage *ru)
|
||||||
return posix_error();
|
return posix_error();
|
||||||
|
|
||||||
if (struct_rusage == NULL) {
|
if (struct_rusage == NULL) {
|
||||||
PyObject *m = PyImport_ImportModule("resource");
|
PyObject *m = PyImport_ImportModuleNoBlock("resource");
|
||||||
if (m == NULL)
|
if (m == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
|
struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
|
||||||
|
|
|
@ -222,7 +222,7 @@ int PySocketModule_ImportModuleAndAPI(void)
|
||||||
void *api;
|
void *api;
|
||||||
|
|
||||||
DPRINTF("Importing the %s C API...\n", apimodule);
|
DPRINTF("Importing the %s C API...\n", apimodule);
|
||||||
mod = PyImport_ImportModule(apimodule);
|
mod = PyImport_ImportModuleNoBlock(apimodule);
|
||||||
if (mod == NULL)
|
if (mod == NULL)
|
||||||
goto onError;
|
goto onError;
|
||||||
DPRINTF(" %s package found\n", apimodule);
|
DPRINTF(" %s package found\n", apimodule);
|
||||||
|
|
|
@ -515,7 +515,7 @@ is not present, current time as returned by localtime() is used.");
|
||||||
static PyObject *
|
static PyObject *
|
||||||
time_strptime(PyObject *self, PyObject *args)
|
time_strptime(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
PyObject *strptime_module = PyImport_ImportModule("_strptime");
|
PyObject *strptime_module = PyImport_ImportModuleNoBlock("_strptime");
|
||||||
PyObject *strptime_result;
|
PyObject *strptime_result;
|
||||||
|
|
||||||
if (!strptime_module)
|
if (!strptime_module)
|
||||||
|
@ -627,7 +627,7 @@ time_tzset(PyObject *self, PyObject *unused)
|
||||||
{
|
{
|
||||||
PyObject* m;
|
PyObject* m;
|
||||||
|
|
||||||
m = PyImport_ImportModule("time");
|
m = PyImport_ImportModuleNoBlock("time");
|
||||||
if (m == NULL) {
|
if (m == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -776,7 +776,7 @@ get_decompress_func(void)
|
||||||
let's avoid a stack overflow. */
|
let's avoid a stack overflow. */
|
||||||
return NULL;
|
return NULL;
|
||||||
importing_zlib = 1;
|
importing_zlib = 1;
|
||||||
zlib = PyImport_ImportModule("zlib"); /* import zlib */
|
zlib = PyImport_ImportModuleNoBlock("zlib");
|
||||||
importing_zlib = 0;
|
importing_zlib = 0;
|
||||||
if (zlib != NULL) {
|
if (zlib != NULL) {
|
||||||
decompress = PyObject_GetAttrString(zlib,
|
decompress = PyObject_GetAttrString(zlib,
|
||||||
|
|
|
@ -2216,7 +2216,7 @@ PyObject *PyUnicode_DecodeUnicodeEscape(const char *s,
|
||||||
if (ucnhash_CAPI == NULL) {
|
if (ucnhash_CAPI == NULL) {
|
||||||
/* load the unicode data module */
|
/* load the unicode data module */
|
||||||
PyObject *m, *api;
|
PyObject *m, *api;
|
||||||
m = PyImport_ImportModule("unicodedata");
|
m = PyImport_ImportModuleNoBlock("unicodedata");
|
||||||
if (m == NULL)
|
if (m == NULL)
|
||||||
goto ucnhashError;
|
goto ucnhashError;
|
||||||
api = PyObject_GetAttrString(m, "ucnhash_CAPI");
|
api = PyObject_GetAttrString(m, "ucnhash_CAPI");
|
||||||
|
|
|
@ -690,7 +690,7 @@ PyErr_WarnExplicit(PyObject *category, const char *message,
|
||||||
{
|
{
|
||||||
PyObject *mod, *dict, *func = NULL;
|
PyObject *mod, *dict, *func = NULL;
|
||||||
|
|
||||||
mod = PyImport_ImportModule("warnings");
|
mod = PyImport_ImportModuleNoBlock("warnings");
|
||||||
if (mod != NULL) {
|
if (mod != NULL) {
|
||||||
dict = PyModule_GetDict(mod);
|
dict = PyModule_GetDict(mod);
|
||||||
func = PyDict_GetItemString(dict, "warn_explicit");
|
func = PyDict_GetItemString(dict, "warn_explicit");
|
||||||
|
|
|
@ -1985,6 +1985,53 @@ PyImport_ImportModule(const char *name)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Import a module without blocking
|
||||||
|
*
|
||||||
|
* At first it tries to fetch the module from sys.modules. If the module was
|
||||||
|
* never loaded before it loads it with PyImport_ImportModule() unless another
|
||||||
|
* thread holds the import lock. In the latter case the function raises an
|
||||||
|
* ImportError instead of blocking.
|
||||||
|
*
|
||||||
|
* Returns the module object with incremented ref count.
|
||||||
|
*/
|
||||||
|
PyObject *
|
||||||
|
PyImport_ImportModuleNoBlock(const char *name)
|
||||||
|
{
|
||||||
|
PyObject *result;
|
||||||
|
PyObject *modules;
|
||||||
|
long me;
|
||||||
|
|
||||||
|
/* Try to get the module from sys.modules[name] */
|
||||||
|
modules = PyImport_GetModuleDict();
|
||||||
|
if (modules == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
result = PyDict_GetItemString(modules, name);
|
||||||
|
if (result != NULL) {
|
||||||
|
Py_INCREF(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check the import lock
|
||||||
|
* me might be -1 but I ignore the error here, the lock function
|
||||||
|
* takes care of the problem */
|
||||||
|
me = PyThread_get_thread_ident();
|
||||||
|
if (import_lock_thread == -1 || import_lock_thread == me) {
|
||||||
|
/* no thread or me is holding the lock */
|
||||||
|
return PyImport_ImportModule(name);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PyErr_Format(PyExc_ImportError,
|
||||||
|
"Failed to import %.200s because the import lock"
|
||||||
|
"is held by another thread.",
|
||||||
|
name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Forward declarations for helper routines */
|
/* Forward declarations for helper routines */
|
||||||
static PyObject *get_parent(PyObject *globals, char *buf,
|
static PyObject *get_parent(PyObject *globals, char *buf,
|
||||||
Py_ssize_t *p_buflen, int level);
|
Py_ssize_t *p_buflen, int level);
|
||||||
|
@ -2054,26 +2101,6 @@ import_module_level(char *name, PyObject *globals, PyObject *locals,
|
||||||
return tail;
|
return tail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For DLL compatibility */
|
|
||||||
#undef PyImport_ImportModuleEx
|
|
||||||
PyObject *
|
|
||||||
PyImport_ImportModuleEx(char *name, PyObject *globals, PyObject *locals,
|
|
||||||
PyObject *fromlist)
|
|
||||||
{
|
|
||||||
PyObject *result;
|
|
||||||
lock_import();
|
|
||||||
result = import_module_level(name, globals, locals, fromlist, -1);
|
|
||||||
if (unlock_import() < 0) {
|
|
||||||
Py_XDECREF(result);
|
|
||||||
PyErr_SetString(PyExc_RuntimeError,
|
|
||||||
"not holding the import lock");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
#define PyImport_ImportModuleEx(n, g, l, f) \
|
|
||||||
PyImport_ImportModuleLevel(n, g, l, f, -1);
|
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyImport_ImportModuleLevel(char *name, PyObject *globals, PyObject *locals,
|
PyImport_ImportModuleLevel(char *name, PyObject *globals, PyObject *locals,
|
||||||
PyObject *fromlist, int level)
|
PyObject *fromlist, int level)
|
||||||
|
@ -2646,9 +2673,10 @@ PyImport_Import(PyObject *module_name)
|
||||||
if (import == NULL)
|
if (import == NULL)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
/* Call the __import__ function with the proper argument list */
|
/* Call the __import__ function with the proper argument list
|
||||||
r = PyObject_CallFunctionObjArgs(import, module_name, globals,
|
* Always use absolute import here. */
|
||||||
globals, silly_list, NULL);
|
r = PyObject_CallFunction(import, "OOOOi", module_name, globals,
|
||||||
|
globals, silly_list, 0, NULL);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
Py_XDECREF(globals);
|
Py_XDECREF(globals);
|
||||||
|
|
|
@ -36,7 +36,7 @@ PyMac_StrError(int err)
|
||||||
PyObject *m;
|
PyObject *m;
|
||||||
PyObject *rv;
|
PyObject *rv;
|
||||||
|
|
||||||
m = PyImport_ImportModule("MacOS");
|
m = PyImport_ImportModuleNoBlock("MacOS");
|
||||||
if (!m) {
|
if (!m) {
|
||||||
if (Py_VerboseFlag)
|
if (Py_VerboseFlag)
|
||||||
PyErr_Print();
|
PyErr_Print();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue