From d3a80f0ecd2c24c9d849a907ffe4680933a76b68 Mon Sep 17 00:00:00 2001 From: Robert Collins Date: Wed, 18 May 2016 18:54:35 +1200 Subject: Handle import cycles. --- extras/__init__.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'extras/__init__.py') diff --git a/extras/__init__.py b/extras/__init__.py index 2d34b52..29d2230 100644 --- a/extras/__init__.py +++ b/extras/__init__.py @@ -40,13 +40,17 @@ def try_import(name, alternative=None, error_callback=None): """ module_segments = name.split('.') last_error = None + remainder = [] + # module_name will be what successfully imports. We cannot walk from the + # __import__ result because in import loops (A imports A.B, which imports + # C, which calls try_import("A.B")) A.B will not yet be set. while module_segments: module_name = '.'.join(module_segments) try: - module = __import__(module_name) + __import__(module_name) except ImportError: last_error = sys.exc_info()[1] - module_segments.pop() + remainder.append(module_segments.pop()) continue else: break @@ -54,8 +58,9 @@ def try_import(name, alternative=None, error_callback=None): if last_error is not None and error_callback is not None: error_callback(last_error) return alternative + module = sys.modules[module_name] nonexistent = object() - for segment in name.split('.')[1:]: + for segment in reversed(remainder): module = getattr(module, segment, nonexistent) if module is nonexistent: if last_error is not None and error_callback is not None: -- cgit v1.2.1