##// END OF EJS Templates
demandimport: replace more references to _demandmod instances...
Gregory Szorc -
r26457:7e813050 default
parent child Browse files
Show More
@@ -73,14 +73,26 b' class _demandmod(object):'
73 73 head = name
74 74 after = []
75 75 object.__setattr__(self, "_data",
76 (head, globals, locals, after, level))
76 (head, globals, locals, after, level, set()))
77 77 object.__setattr__(self, "_module", None)
78 78 def _extend(self, name):
79 79 """add to the list of submodules to load"""
80 80 self._data[3].append(name)
81
82 def _addref(self, name):
83 """Record that the named module ``name`` imports this module.
84
85 References to this proxy class having the name of this module will be
86 replaced at module load time. We assume the symbol inside the importing
87 module is identical to the "head" name of this module. We don't
88 actually know if "as X" syntax is being used to change the symbol name
89 because this information isn't exposed to __import__.
90 """
91 self._data[5].add(name)
92
81 93 def _load(self):
82 94 if not self._module:
83 head, globals, locals, after, level = self._data
95 head, globals, locals, after, level, modrefs = self._data
84 96 mod = _hgextimport(_import, head, globals, locals, None, level)
85 97 # load submodules
86 98 def subload(mod, p):
@@ -95,9 +107,15 b' class _demandmod(object):'
95 107 for x in after:
96 108 subload(mod, x)
97 109
98 # are we in the locals dictionary still?
110 # Replace references to this proxy instance with the actual module.
99 111 if locals and locals.get(head) == self:
100 112 locals[head] = mod
113
114 for modname in modrefs:
115 modref = sys.modules.get(modname, None)
116 if modref and getattr(modref, head, None) == self:
117 setattr(modref, head, mod)
118
101 119 object.__setattr__(self, "_module", mod)
102 120
103 121 def __repr__(self):
@@ -107,7 +125,7 b' class _demandmod(object):'
107 125 def __call__(self, *args, **kwargs):
108 126 raise TypeError("%s object is not callable" % repr(self))
109 127 def __getattribute__(self, attr):
110 if attr in ('_data', '_extend', '_load', '_module'):
128 if attr in ('_data', '_extend', '_load', '_module', '_addref'):
111 129 return object.__getattribute__(self, attr)
112 130 self._load()
113 131 return getattr(self._module, attr)
@@ -143,6 +161,9 b' def _demandimport(name, globals=None, lo'
143 161 # The modern Mercurial convention is to use absolute_import everywhere,
144 162 # so modern Mercurial code will have level >= 0.
145 163
164 # The name of the module the import statement is located in.
165 globalname = globals.get('__name__')
166
146 167 def processfromitem(mod, attr, **kwargs):
147 168 """Process an imported symbol in the import statement.
148 169
@@ -154,6 +175,12 b' def _demandimport(name, globals=None, lo'
154 175 symbol = _demandmod(attr, mod.__dict__, locals, **kwargs)
155 176 setattr(mod, attr, symbol)
156 177
178 # Record the importing module references this symbol so we can
179 # replace the symbol with the actual module instance at load
180 # time.
181 if globalname and isinstance(symbol, _demandmod):
182 symbol._addref(globalname)
183
157 184 if level >= 0:
158 185 # Mercurial's enforced import style does not use
159 186 # "from a import b,c,d" or "from .a import b,c,d" syntax. In
General Comments 0
You need to be logged in to leave comments. Login now