diff options
-rw-r--r-- | Doc/c-api/utilities.rst | 43 | ||||
-rw-r--r-- | Include/import.h | 5 | ||||
-rw-r--r-- | Include/py_curses.h | 2 | ||||
-rw-r--r-- | Mac/Modules/MacOS.c | 2 | ||||
-rw-r--r-- | Misc/NEWS | 36 | ||||
-rw-r--r-- | Modules/_ctypes/callbacks.c | 4 | ||||
-rw-r--r-- | Modules/_cursesmodule.c | 2 | ||||
-rw-r--r-- | Modules/cjkcodecs/cjkcodecs.h | 2 | ||||
-rw-r--r-- | Modules/datetimemodule.c | 8 | ||||
-rw-r--r-- | Modules/gcmodule.c | 2 | ||||
-rw-r--r-- | Modules/parsermodule.c | 2 | ||||
-rw-r--r-- | Modules/posixmodule.c | 2 | ||||
-rw-r--r-- | Modules/socketmodule.h | 2 | ||||
-rw-r--r-- | Modules/timemodule.c | 4 | ||||
-rw-r--r-- | Modules/zipimport.c | 2 | ||||
-rw-r--r-- | Objects/unicodeobject.c | 2 | ||||
-rw-r--r-- | Python/errors.c | 2 | ||||
-rw-r--r-- | Python/import.c | 74 | ||||
-rw-r--r-- | Python/mactoolboxglue.c | 2 |
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(); @@ -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(); |