summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/c-api/utilities.rst43
-rw-r--r--Include/import.h5
-rw-r--r--Include/py_curses.h2
-rw-r--r--Mac/Modules/MacOS.c2
-rw-r--r--Misc/NEWS36
-rw-r--r--Modules/_ctypes/callbacks.c4
-rw-r--r--Modules/_cursesmodule.c2
-rw-r--r--Modules/cjkcodecs/cjkcodecs.h2
-rw-r--r--Modules/datetimemodule.c8
-rw-r--r--Modules/gcmodule.c2
-rw-r--r--Modules/parsermodule.c2
-rw-r--r--Modules/posixmodule.c2
-rw-r--r--Modules/socketmodule.h2
-rw-r--r--Modules/timemodule.c4
-rw-r--r--Modules/zipimport.c2
-rw-r--r--Objects/unicodeobject.c2
-rw-r--r--Python/errors.c2
-rw-r--r--Python/import.c74
-rw-r--r--Python/mactoolboxglue.c2
19 files changed, 135 insertions, 63 deletions
diff --git a/Doc/c-api/utilities.rst b/Doc/c-api/utilities.rst
index eab33a3..d9e85b0 100644
--- a/Doc/c-api/utilities.rst
+++ b/Doc/c-api/utilities.rst
@@ -183,7 +183,8 @@ Importing Modules
single: __all__ (package variable)
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
*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
@@ -198,9 +199,28 @@ Importing Modules
.. versionchanged:: 2.4
failing imports remove incomplete module objects.
+ .. versionchanged:: 2.6
+ always use absolute imports
+
.. 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)
.. index:: builtin: __import__
@@ -218,6 +238,24 @@ Importing Modules
.. versionchanged:: 2.4
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)
@@ -230,6 +268,9 @@ Importing Modules
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`.
+ .. versionchanged:: 2.6
+ always use absolute imports
+
.. cfunction:: PyObject* PyImport_ReloadModule(PyObject *m)
diff --git a/Include/import.h b/Include/import.h
index af9f339..05ad7f0 100644
--- a/Include/import.h
+++ b/Include/import.h
@@ -14,13 +14,10 @@ PyAPI_FUNC(PyObject *) PyImport_ExecCodeModuleEx(
PyAPI_FUNC(PyObject *) PyImport_GetModuleDict(void);
PyAPI_FUNC(PyObject *) PyImport_AddModule(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,
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) \
PyImport_ImportModuleLevel(n, g, l, f, -1)
diff --git a/Include/py_curses.h b/Include/py_curses.h
index b045a59..f38f765 100644
--- a/Include/py_curses.h
+++ b/Include/py_curses.h
@@ -90,7 +90,7 @@ static void **PyCurses_API;
#define import_curses() \
{ \
- PyObject *module = PyImport_ImportModule("_curses"); \
+ PyObject *module = PyImport_ImportModuleNoBlock("_curses"); \
if (module != NULL) { \
PyObject *module_dict = PyModule_GetDict(module); \
PyObject *c_api_object = PyDict_GetItemString(module_dict, "_C_API"); \
diff --git a/Mac/Modules/MacOS.c b/Mac/Modules/MacOS.c
index 4eabb39..3fe6e0d 100644
--- a/Mac/Modules/MacOS.c
+++ b/Mac/Modules/MacOS.c
@@ -357,7 +357,7 @@ MacOS_GetErrorString(PyObject *self, PyObject *args)
PyObject *m, *rv;
errors_loaded = 1;
- m = PyImport_ImportModule("macresource");
+ m = PyImport_ImportModuleNoBlock("macresource");
if (!m) {
if (Py_VerboseFlag)
PyErr_Print();
diff --git a/Misc/NEWS b/Misc/NEWS
index 95845b6..ee0bec2 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -14,25 +14,10 @@ Core and builtins
- 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
and INF. float("nan"), float("inf") and float("-inf") now work on every
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.
The oparg for BUILD_MAP now indicates an estimated dictionary size.
There is a new opcode, STORE_MAP, for adding entries to the dictionary.
@@ -1165,6 +1150,15 @@ Tools/Demos
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 #1608: use -fwrapv when GCC supports it. This is important,
@@ -1225,6 +1219,18 @@ Build
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
so it can be used as an expression.
diff --git a/Modules/_ctypes/callbacks.c b/Modules/_ctypes/callbacks.c
index 18af288..5362584 100644
--- a/Modules/_ctypes/callbacks.c
+++ b/Modules/_ctypes/callbacks.c
@@ -370,7 +370,7 @@ long Call_GetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
if (context == NULL)
context = PyString_FromString("_ctypes.DllGetClassObject");
- mod = PyImport_ImportModule("ctypes");
+ mod = PyImport_ImportModuleNoBlock("ctypes");
if (!mod) {
PyErr_WriteUnraisable(context ? context : Py_None);
/* There has been a warning before about this already */
@@ -449,7 +449,7 @@ long Call_CanUnloadNow(void)
if (context == NULL)
context = PyString_FromString("_ctypes.DllCanUnloadNow");
- mod = PyImport_ImportModule("ctypes");
+ mod = PyImport_ImportModuleNoBlock("ctypes");
if (!mod) {
/* OutputDebugString("Could not import ctypes"); */
/* We assume that this error can only occur when shutting
diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c
index e7c4bc1..a805b2d 100644
--- a/Modules/_cursesmodule.c
+++ b/Modules/_cursesmodule.c
@@ -2255,7 +2255,7 @@ static int
update_lines_cols(void)
{
PyObject *o;
- PyObject *m = PyImport_ImportModule("curses");
+ PyObject *m = PyImport_ImportModuleNoBlock("curses");
if (!m)
return 0;
diff --git a/Modules/cjkcodecs/cjkcodecs.h b/Modules/cjkcodecs/cjkcodecs.h
index 71c54f0..4005bcf 100644
--- a/Modules/cjkcodecs/cjkcodecs.h
+++ b/Modules/cjkcodecs/cjkcodecs.h
@@ -245,7 +245,7 @@ getmultibytecodec(void)
static PyObject *cofunc = NULL;
if (cofunc == NULL) {
- PyObject *mod = PyImport_ImportModule("_multibytecodec");
+ PyObject *mod = PyImport_ImportModuleNoBlock("_multibytecodec");
if (mod == NULL)
return NULL;
cofunc = PyObject_GetAttrString(mod, "__create_codec");
diff --git a/Modules/datetimemodule.c b/Modules/datetimemodule.c
index b94812b..83e547e 100644
--- a/Modules/datetimemodule.c
+++ b/Modules/datetimemodule.c
@@ -1305,7 +1305,7 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple,
if (_PyString_Resize(&newfmt, usednew) < 0)
goto Done;
{
- PyObject *time = PyImport_ImportModule("time");
+ PyObject *time = PyImport_ImportModuleNoBlock("time");
if (time == NULL)
goto Done;
result = PyObject_CallMethod(time, "strftime", "OO",
@@ -1353,7 +1353,7 @@ static PyObject *
time_time(void)
{
PyObject *result = NULL;
- PyObject *time = PyImport_ImportModule("time");
+ PyObject *time = PyImport_ImportModuleNoBlock("time");
if (time != NULL) {
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 *result = NULL;
- time = PyImport_ImportModule("time");
+ time = PyImport_ImportModuleNoBlock("time");
if (time != NULL) {
result = PyObject_CallMethod(time, "struct_time",
"((iiiiiiiii))",
@@ -3827,7 +3827,7 @@ datetime_strptime(PyObject *cls, PyObject *args)
if (!PyArg_ParseTuple(args, "ss:strptime", &string, &format))
return NULL;
- if ((module = PyImport_ImportModule("time")) == NULL)
+ if ((module = PyImport_ImportModuleNoBlock("time")) == NULL)
return NULL;
obj = PyObject_CallMethod(module, "strptime", "ss", string, format);
Py_DECREF(module);
diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c
index 0edf523..522cc89 100644
--- a/Modules/gcmodule.c
+++ b/Modules/gcmodule.c
@@ -1236,7 +1236,7 @@ initgc(void)
* the import and triggers an assertion.
*/
if (tmod == NULL) {
- tmod = PyImport_ImportModule("time");
+ tmod = PyImport_ImportModuleNoBlock("time");
if (tmod == NULL)
PyErr_Clear();
}
diff --git a/Modules/parsermodule.c b/Modules/parsermodule.c
index 6c4a6ad..5764c24 100644
--- a/Modules/parsermodule.c
+++ b/Modules/parsermodule.c
@@ -3269,7 +3269,7 @@ initparser(void)
* If this fails, the import of this module will fail because an
* exception will be raised here; should we clear the exception?
*/
- copyreg = PyImport_ImportModule("copy_reg");
+ copyreg = PyImport_ImportModuleNoBlock("copy_reg");
if (copyreg != NULL) {
PyObject *func, *pickler;
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index 85725f4..696df0d 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -5651,7 +5651,7 @@ wait_helper(int pid, int status, struct rusage *ru)
return posix_error();
if (struct_rusage == NULL) {
- PyObject *m = PyImport_ImportModule("resource");
+ PyObject *m = PyImport_ImportModuleNoBlock("resource");
if (m == NULL)
return NULL;
struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
diff --git a/Modules/socketmodule.h b/Modules/socketmodule.h
index a4382ab..fb9ec67 100644
--- a/Modules/socketmodule.h
+++ b/Modules/socketmodule.h
@@ -222,7 +222,7 @@ int PySocketModule_ImportModuleAndAPI(void)
void *api;
DPRINTF("Importing the %s C API...\n", apimodule);
- mod = PyImport_ImportModule(apimodule);
+ mod = PyImport_ImportModuleNoBlock(apimodule);
if (mod == NULL)
goto onError;
DPRINTF(" %s package found\n", apimodule);
diff --git a/Modules/timemodule.c b/Modules/timemodule.c
index 842ce94..5b4d210 100644
--- a/Modules/timemodule.c
+++ b/Modules/timemodule.c
@@ -515,7 +515,7 @@ is not present, current time as returned by localtime() is used.");
static PyObject *
time_strptime(PyObject *self, PyObject *args)
{
- PyObject *strptime_module = PyImport_ImportModule("_strptime");
+ PyObject *strptime_module = PyImport_ImportModuleNoBlock("_strptime");
PyObject *strptime_result;
if (!strptime_module)
@@ -627,7 +627,7 @@ time_tzset(PyObject *self, PyObject *unused)
{
PyObject* m;
- m = PyImport_ImportModule("time");
+ m = PyImport_ImportModuleNoBlock("time");
if (m == NULL) {
return NULL;
}
diff --git a/Modules/zipimport.c b/Modules/zipimport.c
index fe5e1b0..dec6091 100644
--- a/Modules/zipimport.c
+++ b/Modules/zipimport.c
@@ -776,7 +776,7 @@ get_decompress_func(void)
let's avoid a stack overflow. */
return NULL;
importing_zlib = 1;
- zlib = PyImport_ImportModule("zlib"); /* import zlib */
+ zlib = PyImport_ImportModuleNoBlock("zlib");
importing_zlib = 0;
if (zlib != NULL) {
decompress = PyObject_GetAttrString(zlib,
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 4241fe9..e3fc71a 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -2216,7 +2216,7 @@ PyObject *PyUnicode_DecodeUnicodeEscape(const char *s,
if (ucnhash_CAPI == NULL) {
/* load the unicode data module */
PyObject *m, *api;
- m = PyImport_ImportModule("unicodedata");
+ m = PyImport_ImportModuleNoBlock("unicodedata");
if (m == NULL)
goto ucnhashError;
api = PyObject_GetAttrString(m, "ucnhash_CAPI");
diff --git a/Python/errors.c b/Python/errors.c
index 63acf33..1c29160 100644
--- a/Python/errors.c
+++ b/Python/errors.c
@@ -690,7 +690,7 @@ PyErr_WarnExplicit(PyObject *category, const char *message,
{
PyObject *mod, *dict, *func = NULL;
- mod = PyImport_ImportModule("warnings");
+ mod = PyImport_ImportModuleNoBlock("warnings");
if (mod != NULL) {
dict = PyModule_GetDict(mod);
func = PyDict_GetItemString(dict, "warn_explicit");
diff --git a/Python/import.c b/Python/import.c
index bcae9b2..e191bd5 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -1985,6 +1985,53 @@ PyImport_ImportModule(const char *name)
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 */
static PyObject *get_parent(PyObject *globals, char *buf,
Py_ssize_t *p_buflen, int level);
@@ -2054,26 +2101,6 @@ import_module_level(char *name, PyObject *globals, PyObject *locals,
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 *
PyImport_ImportModuleLevel(char *name, PyObject *globals, PyObject *locals,
PyObject *fromlist, int level)
@@ -2646,9 +2673,10 @@ PyImport_Import(PyObject *module_name)
if (import == NULL)
goto err;
- /* Call the __import__ function with the proper argument list */
- r = PyObject_CallFunctionObjArgs(import, module_name, globals,
- globals, silly_list, NULL);
+ /* Call the __import__ function with the proper argument list
+ * Always use absolute import here. */
+ r = PyObject_CallFunction(import, "OOOOi", module_name, globals,
+ globals, silly_list, 0, NULL);
err:
Py_XDECREF(globals);
diff --git a/Python/mactoolboxglue.c b/Python/mactoolboxglue.c
index 26a1308..8ad0d6d 100644
--- a/Python/mactoolboxglue.c
+++ b/Python/mactoolboxglue.c
@@ -36,7 +36,7 @@ PyMac_StrError(int err)
PyObject *m;
PyObject *rv;
- m = PyImport_ImportModule("MacOS");
+ m = PyImport_ImportModuleNoBlock("MacOS");
if (!m) {
if (Py_VerboseFlag)
PyErr_Print();