]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
ok forget it, that approach didn't really cover every base, so
authorMike Bayer <mike_mp@zzzcomputing.com>
Sun, 4 Aug 2013 20:21:37 +0000 (16:21 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sun, 4 Aug 2013 20:21:37 +0000 (16:21 -0400)
we are pretty much back to the beginning, nothing to see here

lib/sqlalchemy/__init__.py
lib/sqlalchemy/orm/__init__.py
lib/sqlalchemy/util/langhelpers.py

index 61892e02ed2403562bb40a6e46ccadaf37ee4408..06c597877bbbf1424377c0fadeae920e8295769f 100644 (file)
@@ -124,3 +124,5 @@ __version__ = '0.9.0'
 
 del _inspect, sys
 
+from . import util as _sa_util
+_sa_util.importlater.resolve_all()
\ No newline at end of file
index 797569ce8e25015b89863a3b0bcffda4edaa0195..0bfaf72c9b1c7fa2ae1ac1649cfb3a4d8afa3e8a 100644 (file)
@@ -1782,3 +1782,6 @@ def undefer_group(name):
     """
     return strategies.UndeferGroupOption(name)
 
+
+from .. import util as _sa_util
+_sa_util.importlater.resolve_all()
\ No newline at end of file
index 430c630a85e91c8c65eb48d41ce159f68a374e07..d8e469a2b5af89c837282c835c3ae91e7163321e 100644 (file)
@@ -688,15 +688,25 @@ class importlater(object):
 
     except evaluted upon attribute access to "somesubmod".
 
-    importlater() relies on sys.modules being populated with the
-    target package, and the target package containing the target module,
-    by time the attribute is evaulated.
+    importlater() currently requires that resolve_all() be
+    called, typically at the bottom of a package's __init__.py.
+    This is so that __import__ still called only at
+    module import time, and not potentially within
+    a non-main thread later on.
 
     """
 
+    _unresolved = set()
+
     def __init__(self, path, addtl):
         self._il_path = path
         self._il_addtl = addtl
+        importlater._unresolved.add(self)
+
+    @classmethod
+    def resolve_all(cls):
+        for m in list(importlater._unresolved):
+            m._resolve()
 
     @property
     def _full_path(self):
@@ -704,20 +714,24 @@ class importlater(object):
 
     @memoized_property
     def module(self):
-        try:
-            m = sys.modules[self._il_path]
-        except KeyError:
-            raise KeyError("Module %s hasn't been installed" % self._il_path)
-        else:
-            try:
-                return getattr(m, self._il_addtl)
-            except AttributeError:
-                raise KeyError(
-                        "Module %s hasn't been installed into %s" %
-                        (self._il_addtl, self._il_path)
-                    )
+        if self in importlater._unresolved:
+            raise ImportError(
+                    "importlater.resolve_all() hasn't "
+                    "been called (this is %s %s)"
+                    % (self._il_path, self._il_addtl))
+
+        return getattr(self._initial_import, self._il_addtl)
+
+    def _resolve(self):
+        importlater._unresolved.discard(self)
+        self._initial_import = compat.import_(
+                            self._il_path, globals(), locals(),
+                            [self._il_addtl])
 
     def __getattr__(self, key):
+        if key == 'module':
+            raise ImportError("Could not resolve module %s"
+                                % self._full_path)
         try:
             attr = getattr(self.module, key)
         except AttributeError:
@@ -728,7 +742,6 @@ class importlater(object):
         self.__dict__[key] = attr
         return attr
 
-
 # from paste.deploy.converters
 def asbool(obj):
     if isinstance(obj, compat.string_types):