On Thu, Dec 27, 2012 at 5:33 PM, Gnarlodious <gnarlodi...@gmail.com> wrote: > Graham Dumpleton has informed me that the the relevant bug reports are: > > http://bugs.python.org/issue8098 > http://bugs.python.org/issue9260 > > To quote: > > All the problems derive from a stupid function in Python internals called > PyImport_ImportModuleNoBlock(). It was designed to avoid lockups of the > import machinery but just causes other problems because a module import can > fail if the import lock is held by a different thread. This faulty magic > fairy dust was sprinkled on the time.strptime() function which internally > loads _strptime module. If you access time.strptime() when another thread > holds the import lock, the call will fail because of a failed import. > > So there. As more people update to Python 3.3.0 hopefully this magic fairy > dust workaround will see some daylight.
Thanks for the context, but that actually seems to be describing the situation from Python 3.2. Python 3.3 introduced module-level import locking with improved deadlock detection that looks for actual cycles and is supposed to fix the unnecessary ImportErrors described in #8098, rendering the PyImport_ImportModuleNoBlock "fairy dust" unnecessary -- in 3.3, I understand that PyImport_ImportModuleNoBlock is now just a synonym for PyImport_ImportModule. But you're reporting that you're still seeing issues with this in Python 3.3. Diving into the code, I think I start to understand why. Take a look at this function from Lib/importlib/_bootstrap.py: 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() try: lock.acquire() except _DeadlockError: # Concurrent circular import, we'll accept a partially initialized # module object. pass else: lock.release() Normally, it just acquires and releases the module lock to ensure that the module has been completely initialized. If a deadlock is detected, however, then it skips that step and instead of raising an ImportError (which would seem to me to be the right thing to do here) it allows the importing code to simply proceed with a module that may not be fully imported yet. Since your error message concerned missing module-level attributes within the _strptime module, that seems to be what you're running into. The time.strptime function attempts to import _strptime, which is already being imported by another thread; for some unknown reason it detects a cyclical deadlock as a result of this; it then white-washes the deadlock and tries to use the _strptime module anyway, causing a different error to occur. The question then is how you're managing to get an import cycle by using strptime. -- http://mail.python.org/mailman/listinfo/python-list