summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2010-08-03 20:42:36 -0700
committerZac Medico <zmedico@gentoo.org>2010-08-03 20:42:36 -0700
commit47b5490fe3f36afee860ecd62fb3052ee2a3b6d4 (patch)
tree9f6af4c425637b041ff1d8e5c86af606e22722d8
parent7d2026628046cf3849fce81f58567e27788450d6 (diff)
downloadportage-47b5490fe3f36afee860ecd62fb3052ee2a3b6d4.tar.gz
portage-47b5490fe3f36afee860ecd62fb3052ee2a3b6d4.tar.bz2
portage-47b5490fe3f36afee860ecd62fb3052ee2a3b6d4.zip
Bug #330645 - Make _unregister_module_proxy() detect partially imported
modules (indicated when an AttributeError is caught) and handle them appropriately.
-rw-r--r--pym/portage/proxy/lazyimport.py29
1 files changed, 17 insertions, 12 deletions
diff --git a/pym/portage/proxy/lazyimport.py b/pym/portage/proxy/lazyimport.py
index 56591c037..c9147caea 100644
--- a/pym/portage/proxy/lazyimport.py
+++ b/pym/portage/proxy/lazyimport.py
@@ -53,19 +53,13 @@ def _unregister_module_proxy(name):
Destroy all proxies that reference the give module name. Also, check
for other proxies referenced by modules that have been imported and
destroy those proxies too. This way, destruction of a single proxy
- can trigger destruction of all the rest.
+ can trigger destruction of all the rest. If the a target module appears
+ to be partially imported (indicated when an AttributeError is caught),
+ this function will leave in place proxies that reference it.
"""
_module_proxies_lock.acquire()
try:
- proxy_list = _module_proxies.get(name)
- if proxy_list is not None:
- # First delete this name from the dict so that
- # if this same thread reenters below, it won't
- # enter this path again.
- del _module_proxies[name]
- for proxy in proxy_list:
- object.__getattribute__(proxy, '_get_target')()
-
+ if name in _module_proxies:
modules = sys.modules
for name, proxy_list in list(_module_proxies.items()):
if name not in modules:
@@ -74,8 +68,16 @@ def _unregister_module_proxy(name):
# if this same thread reenters below, it won't
# enter this path again.
del _module_proxies[name]
- for proxy in proxy_list:
- object.__getattribute__(proxy, '_get_target')()
+ try:
+ while proxy_list:
+ proxy = proxy_list.pop()
+ object.__getattribute__(proxy, '_get_target')()
+ except AttributeError:
+ # Apparently the target module is only partially
+ # imported, so proxies that reference it cannot
+ # be destroyed yet.
+ proxy_list.append(proxy)
+ _module_proxies[name] = proxy_list
finally:
_module_proxies_lock.release()
@@ -120,6 +122,9 @@ class _LazyImportFrom(_LazyImport):
name = object.__getattribute__(self, '_name')
attr_name = object.__getattribute__(self, '_attr_name')
__import__(name)
+ # If called by _unregister_module_proxy() and the target module is
+ # partially imported, then the following getattr call may raise an
+ # AttributeError for _unregister_module_proxy() to handle.
target = getattr(sys.modules[name], attr_name)
object.__setattr__(self, '_target', target)
object.__getattribute__(self, '_scope')[