[PATCH 5 of 5 V2] demandimport: support lazy loading for absolute_import

Gregory Szorc gregory.szorc at gmail.com
Sat Aug 8 20:17:07 CDT 2015


# HG changeset patch
# User Gregory Szorc <gregory.szorc at gmail.com>
# Date 1439075607 25200
#      Sat Aug 08 16:13:27 2015 -0700
# Node ID f09df3346da5b601735035bbd7310b64bf15a410
# Parent  09b65b56301a659ca42d470458c6c535c20b4517
demandimport: support lazy loading for absolute_import

Before, we didn't support lazy loading if absolute_import was in
effect and a fromlist was used. This meant that "from . import X"
wasn't lazy and performance could suffer as a result.

With this patch, we now support lazy loading for this scenario.
As part of developing this, I discovered issues when module names
are defined. Since the enforced import style only allows
"from X import Y" or "from .X import Y" in very few scenarios
when absolute_import is enabled - scenarios where Y is not a
module and thus there is nothing to lazy load - I decided to drop
support for this case instead of chasing down the errors. I don't
think much harm will come from this. But I'd like to take another
look once all modules are using absolute_import and I can see the
full extent of what is using names in absolute_import mode.

diff --git a/mercurial/demandimport.py b/mercurial/demandimport.py
--- a/mercurial/demandimport.py
+++ b/mercurial/demandimport.py
@@ -138,9 +138,26 @@ def _demandimport(name, globals=None, lo
         # The modern Mercurial convention is to use absolute_import everywhere,
         # so modern Mercurial code will have level >= 0.
 
         if level >= 0:
-            return _origimport(name, globals, locals, fromlist, level)
+            # Mercurial's enforced import style does not use
+            # "from a import b,c,d" or "from .a import b,c,d" syntax. In
+            # addition, this appears to be giving errors with some modules
+            # for unknown reasons. Since we shouldn't be using this syntax
+            # much, work around the problems.
+            if name:
+                return _hgextimport(_origimport, name, globals, locals,
+                                    fromlist, level)
+
+            mod = _hgextimport(_origimport, name, globals, locals, level=level)
+            for x in fromlist:
+                # Missing symbols mean they weren't defined in the module
+                # itself which means they are sub-modules.
+                if getattr(mod, x, nothing) is nothing:
+                    setattr(mod, x,
+                            _demandmod(x, mod.__dict__, locals, level=level))
+
+            return mod
 
         # But, we still need to support lazy loading of standard library and 3rd
         # party modules. So handle level == -1.
         mod = _hgextimport(_origimport, name, globals, locals)


More information about the Mercurial-devel mailing list