diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py --- a/Lib/importlib/_bootstrap.py +++ b/Lib/importlib/_bootstrap.py @@ -159,6 +159,101 @@ def new_module(name): return type(_io)(name) +# Module-level locking ######################################################## + +# A dict mapping module names to weakrefs of _ModuleLock instances +_module_locks = {} +# A dict mapping thread ids to _ModuleLock instances +_blocking_on = {} + +class _ModuleLock: + """A recursive lock implementation which is able to detect deadlocks + (e.g. thread 1 trying to take locks A then B, and thread 2 trying to + take locks B then A). + """ + + def __init__(self, name): + self.lock = _thread.allocate_lock() + self.wakeup = _thread.allocate_lock() + self.name = name + self.owner = None + self.count = 0 + self.waiters = 0 + + def has_deadlock(self): + # Deadlock avoidance for concurrent circular imports. + me = _thread.get_ident() + tid = self.owner + while True: + lock = _blocking_on.get(tid) + if lock is None: + return False + tid = lock.owner + if tid == me: + return True + + def acquire(self, avoid_deadlocks=False): + tid = _thread.get_ident() + _blocking_on[tid] = self + try: + while True: + with self.lock: + if self.count == 0 or self.owner == tid: + self.owner = tid + self.count += 1 + return True + if avoid_deadlocks and self.has_deadlock(): + return False + if self.wakeup.acquire(False): + self.waiters += 1 + self.wakeup.acquire() + self.wakeup.release() + finally: + del _blocking_on[tid] + + def release(self): + tid = _thread.get_ident() + with self.lock: + assert self.owner == tid + assert self.count > 0 + self.count -= 1 + if self.count == 0: + self.owner = None + if self.waiters: + self.waiters -= 1 + self.wakeup.release() + + def __repr__(self): + return "_ModuleLock(%r) at %d" % (self.name, id(self)) + + +def _get_module_lock(name): + """Get or create the module lock for a given module name. + + Should only be called with the import lock taken.""" + lock = None + if name in _module_locks: + lock = _module_locks[name]() + if lock is None: + lock = _ModuleLock(name) + def cb(_): + del _module_locks[name] + _module_locks[name] = _weakref.ref(lock, cb) + return lock + +def _lock_unlock_module(name): + """Release the global import lock, and acquires then release the + module lock for a given module name. + This is used to ensure a module is completely initialized, in the + event it is being imported by another thread. + + Should only be called with the import lock taken.""" + lock = _get_module_lock(name) + _imp.release_lock() + if lock.acquire(avoid_deadlocks=True): + lock.release() + + # Finder/loader utility code ################################################## _PYCACHE = '__pycache__' @@ -258,12 +353,15 @@ def module_for_loader(fxn): else: module.__package__ = fullname.rpartition('.')[0] try: + module.__initializing__ = True # If __package__ was not set above, __import__() will do it later. return fxn(self, module, *args, **kwargs) except: if not is_reload: del sys.modules[fullname] raise + finally: + module.__initializing__ = False _wrap(module_for_loader_wrapper, fxn) return module_for_loader_wrapper @@ -922,7 +1020,8 @@ def _find_module(name, path): if not sys.meta_path: _warnings.warn('sys.meta_path is empty', ImportWarning) for finder in sys.meta_path: - loader = finder.find_module(name, path) + with _ImportLockContext(): + loader = finder.find_module(name, path) if loader is not None: # The parent import may have already imported this module. if name not in sys.modules: @@ -952,8 +1051,7 @@ def _sanity_check(name, package, level): _ERR_MSG = 'No module named {!r}' -def _find_and_load(name, import_): - """Find and load the module.""" +def _find_and_load_unlocked(name, import_): path = None parent = name.rpartition('.')[0] if parent: @@ -999,6 +1097,19 @@ def _find_and_load(name, import_): return module +def _find_and_load(name, import_): + """Find and load the module, and release the import lock.""" + try: + lock = _get_module_lock(name) + finally: + _imp.release_lock() + lock.acquire() + try: + return _find_and_load_unlocked(name, import_) + finally: + lock.release() + + def _gcd_import(name, package=None, level=0): """Import and return the module based on its name, the package the call is being made from, and the level adjustment. @@ -1011,17 +1122,17 @@ def _gcd_import(name, package=None, leve _sanity_check(name, package, level) if level > 0: name = _resolve_name(name, package, level) - with _ImportLockContext(): - try: - module = sys.modules[name] - if module is None: - message = ("import of {} halted; " - "None in sys.modules".format(name)) - raise ImportError(message, name=name) - return module - except KeyError: - pass # Don't want to chain the exception + _imp.acquire_lock() + if name not in sys.modules: return _find_and_load(name, _gcd_import) + module = sys.modules[name] + if module is None: + _imp.release_lock() + message = ("import of {} halted; " + "None in sys.modules".format(name)) + raise ImportError(message, name=name) + _lock_unlock_module(name) + return module def _handle_fromlist(module, fromlist, import_): @@ -1139,7 +1250,17 @@ def _setup(sys_module, _imp_module): continue else: raise ImportError('importlib requires posix or nt') + + try: + thread_module = BuiltinImporter.load_module('_thread') + except ImportError: + # Python was built without threads + thread_module = None + weakref_module = BuiltinImporter.load_module('_weakref') + setattr(self_module, '_os', os_module) + setattr(self_module, '_thread', thread_module) + setattr(self_module, '_weakref', weakref_module) setattr(self_module, 'path_sep', path_sep) setattr(self_module, 'path_separators', set(path_separators)) # Constants diff --git a/Lib/pydoc.py b/Lib/pydoc.py --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -166,7 +166,7 @@ def visiblename(name, all=None, obj=None if name in {'__builtins__', '__doc__', '__file__', '__path__', '__module__', '__name__', '__slots__', '__package__', '__cached__', '__author__', '__credits__', '__date__', - '__version__', '__qualname__'}: + '__version__', '__qualname__', '__initializing__'}: return 0 # Private names are hidden, but special names are displayed. if name.startswith('__') and name.endswith('__'): return 1 diff --git a/Lib/test/test_pkg.py b/Lib/test/test_pkg.py --- a/Lib/test/test_pkg.py +++ b/Lib/test/test_pkg.py @@ -23,6 +23,8 @@ def cleanout(root): def fixdir(lst): if "__builtins__" in lst: lst.remove("__builtins__") + if "__initializing__" in lst: + lst.remove("__initializing__") return lst diff --git a/Lib/test/test_threaded_import.py b/Lib/test/test_threaded_import.py --- a/Lib/test/test_threaded_import.py +++ b/Lib/test/test_threaded_import.py @@ -12,7 +12,7 @@ import time import shutil import unittest from test.support import ( - verbose, import_module, run_unittest, TESTFN, reap_threads) + verbose, import_module, run_unittest, TESTFN, reap_threads, forget) threading = import_module('threading') def task(N, done, done_tasks, errors): @@ -187,7 +187,7 @@ class ThreadedImportTests(unittest.TestC contents = contents % {'delay': delay} with open(os.path.join(TESTFN, name + ".py"), "wb") as f: f.write(contents.encode('utf-8')) - self.addCleanup(sys.modules.pop, name, None) + self.addCleanup(forget, name) results = [] def import_ab(): @@ -204,6 +204,21 @@ class ThreadedImportTests(unittest.TestC t2.join() self.assertEqual(set(results), {'a', 'b'}) + def test_side_effect_import(self): + code = """if 1: + import threading + def target(): + import random + t = threading.Thread(target=target) + t.start() + t.join()""" + sys.path.insert(0, os.curdir) + self.addCleanup(sys.path.remove, os.curdir) + with open(TESTFN + ".py", "wb") as f: + f.write(code.encode('utf-8')) + self.addCleanup(forget, TESTFN) + __import__(TESTFN) + @reap_threads def test_main(): diff --git a/Lib/token.py b/Lib/token.py --- a/Lib/token.py +++ b/Lib/token.py @@ -70,7 +70,7 @@ NT_OFFSET = 256 tok_name = {value: name for name, value in globals().items() - if isinstance(value, int)} + if isinstance(value, int) and not name.startswith('_')} __all__.extend(tok_name.values()) def ISTERMINAL(x): diff --git a/Python/import.c b/Python/import.c --- a/Python/import.c +++ b/Python/import.c @@ -1370,47 +1370,7 @@ PyImport_ImportModule(const char *name) PyObject * PyImport_ImportModuleNoBlock(const char *name) { - PyObject *nameobj, *modules, *result; -#ifdef WITH_THREAD - long me; -#endif - - /* Try to get the module from sys.modules[name] */ - modules = PyImport_GetModuleDict(); - if (modules == NULL) - return NULL; - - nameobj = PyUnicode_FromString(name); - if (nameobj == NULL) - return NULL; - result = PyDict_GetItem(modules, nameobj); - if (result != NULL) { - Py_DECREF(nameobj); - Py_INCREF(result); - return result; - } - PyErr_Clear(); -#ifdef WITH_THREAD - /* 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 */ - result = PyImport_Import(nameobj); - } - else { - PyErr_Format(PyExc_ImportError, - "Failed to import %R because the import lock" - "is held by another thread.", - nameobj); - result = NULL; - } -#else - result = PyImport_Import(nameobj); -#endif - Py_DECREF(nameobj); - return result; + return PyImport_ImportModule(name); } @@ -1420,11 +1380,13 @@ PyImport_ImportModuleLevelObject(PyObjec int level) { _Py_IDENTIFIER(__import__); + _Py_IDENTIFIER(__initializing__); _Py_IDENTIFIER(__package__); _Py_IDENTIFIER(__path__); _Py_IDENTIFIER(__name__); _Py_IDENTIFIER(_find_and_load); _Py_IDENTIFIER(_handle_fromlist); + _Py_IDENTIFIER(_lock_unlock_module); _Py_static_string(single_dot, "."); PyObject *abs_name = NULL; PyObject *builtins_import = NULL; @@ -1607,16 +1569,48 @@ PyImport_ImportModuleLevelObject(PyObjec goto error_with_unlock; } else if (mod != NULL) { + PyObject *value; + int initializing = 0; + Py_INCREF(mod); + /* Only call _bootstrap._lock_unlock_module() if __initializing__ is true. */ + value = _PyObject_GetAttrId(mod, &PyId___initializing__); + if (value == NULL) + PyErr_Clear(); + else { + initializing = PyObject_IsTrue(value); + Py_DECREF(value); + if (initializing == -1) + PyErr_Clear(); + } + if (initializing > 0) { + /* _bootstrap._lock_unlock_module() releases the import lock */ + value = _PyObject_CallMethodObjIdArgs(interp->importlib, + &PyId__lock_unlock_module, abs_name, + NULL); + if (value == NULL) + goto error; + Py_DECREF(value); + } + else { +#ifdef WITH_THREAD + if (_PyImport_ReleaseLock() < 0) { + PyErr_SetString(PyExc_RuntimeError, "not holding the import lock"); + goto error; + } +#endif + } } else { + /* _bootstrap._find_and_load() releases the import lock */ mod = _PyObject_CallMethodObjIdArgs(interp->importlib, &PyId__find_and_load, abs_name, builtins_import, NULL); if (mod == NULL) { - goto error_with_unlock; + goto error; } } + /* From now on we don't hold the import lock anymore. */ if (PyObject_Not(fromlist)) { if (level == 0 || PyUnicode_GET_LENGTH(name) > 0) { @@ -1625,12 +1619,12 @@ PyImport_ImportModuleLevelObject(PyObjec PyObject *borrowed_dot = _PyUnicode_FromId(&single_dot); if (borrowed_dot == NULL) { - goto error_with_unlock; + goto error; } partition = PyUnicode_Partition(name, borrowed_dot); if (partition == NULL) { - goto error_with_unlock; + goto error; } front = PyTuple_GET_ITEM(partition, 0); @@ -1656,7 +1650,7 @@ PyImport_ImportModuleLevelObject(PyObjec abs_name_len - cut_off); Py_DECREF(front); if (to_return == NULL) { - goto error_with_unlock; + goto error; } final_mod = PyDict_GetItem(interp->modules, to_return); @@ -1682,6 +1676,8 @@ PyImport_ImportModuleLevelObject(PyObjec fromlist, builtins_import, NULL); } + goto error; + error_with_unlock: #ifdef WITH_THREAD if (_PyImport_ReleaseLock() < 0) { diff --git a/Python/importlib.h b/Python/importlib.h index 292308fc78123e9fa10c7131bb110c47559975dd..bfcb1752442ac8dacfa8f7d48b779305c62fd8da GIT binary patch literal 178469 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 P_y6;6|HE&8`B(oxhfIOP