[PATCH 3 of 3] demandimport: support lazy loading for absolute_import

Gregory Szorc gregory.szorc at gmail.com
Sat Aug 8 23:31:43 UTC 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 32a1478c09258281f31319577493d538c9e83eb8
# Parent  5266b5af74f60da97b52335ea2414835d0ca3006
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
@@ -151,9 +151,24 @@ def _demandimport(name, globals=None, lo
                 if getattr(mod, x, nothing) is nothing:
                     setattr(mod, x, _demandmod(x, mod.__dict__, locals))
             return mod
 
-        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 branch much, work around the problems.
+        if name:
+            return _hgextimport(_origimport, name, globals, locals, fromlist,
+                                level)
+
+        mod = _hgextimport(_origimport, name, globals, locals)
+        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))
+
+        return mod
 
 ignore = [
     '_hashlib',
     '_xmlplus',



More information about the Mercurial-devel mailing list