141 # level == -1: relative and absolute attempted (Python 2 only). |
141 # level == -1: relative and absolute attempted (Python 2 only). |
142 # level >= 0: absolute only (Python 2 w/ absolute_import and Python 3). |
142 # level >= 0: absolute only (Python 2 w/ absolute_import and Python 3). |
143 # The modern Mercurial convention is to use absolute_import everywhere, |
143 # The modern Mercurial convention is to use absolute_import everywhere, |
144 # so modern Mercurial code will have level >= 0. |
144 # so modern Mercurial code will have level >= 0. |
145 |
145 |
|
146 def processfromitem(mod, attr, **kwargs): |
|
147 """Process an imported symbol in the import statement. |
|
148 |
|
149 If the symbol doesn't exist in the parent module, it must be a |
|
150 module. We set missing modules up as _demandmod instances. |
|
151 """ |
|
152 if getattr(mod, attr, nothing) is nothing: |
|
153 setattr(mod, attr, |
|
154 _demandmod(attr, mod.__dict__, locals, **kwargs)) |
|
155 |
146 if level >= 0: |
156 if level >= 0: |
147 # Mercurial's enforced import style does not use |
157 # Mercurial's enforced import style does not use |
148 # "from a import b,c,d" or "from .a import b,c,d" syntax. In |
158 # "from a import b,c,d" or "from .a import b,c,d" syntax. In |
149 # addition, this appears to be giving errors with some modules |
159 # addition, this appears to be giving errors with some modules |
150 # for unknown reasons. Since we shouldn't be using this syntax |
160 # for unknown reasons. Since we shouldn't be using this syntax |
152 if name: |
162 if name: |
153 return _hgextimport(_origimport, name, globals, locals, |
163 return _hgextimport(_origimport, name, globals, locals, |
154 fromlist, level) |
164 fromlist, level) |
155 |
165 |
156 mod = _hgextimport(_origimport, name, globals, locals, level=level) |
166 mod = _hgextimport(_origimport, name, globals, locals, level=level) |
|
167 |
157 for x in fromlist: |
168 for x in fromlist: |
158 # Missing symbols mean they weren't defined in the module |
169 processfromitem(mod, x, level=level) |
159 # itself which means they are sub-modules. |
|
160 if getattr(mod, x, nothing) is nothing: |
|
161 setattr(mod, x, |
|
162 _demandmod(x, mod.__dict__, locals, level=level)) |
|
163 |
170 |
164 return mod |
171 return mod |
165 |
172 |
166 # But, we still need to support lazy loading of standard library and 3rd |
173 # But, we still need to support lazy loading of standard library and 3rd |
167 # party modules. So handle level == -1. |
174 # party modules. So handle level == -1. |
170 for comp in name.split('.')[1:]: |
177 for comp in name.split('.')[1:]: |
171 if getattr(mod, comp, nothing) is nothing: |
178 if getattr(mod, comp, nothing) is nothing: |
172 setattr(mod, comp, |
179 setattr(mod, comp, |
173 _demandmod(comp, mod.__dict__, mod.__dict__)) |
180 _demandmod(comp, mod.__dict__, mod.__dict__)) |
174 mod = getattr(mod, comp) |
181 mod = getattr(mod, comp) |
|
182 |
175 for x in fromlist: |
183 for x in fromlist: |
176 # set requested submodules for demand load |
184 processfromitem(mod, x) |
177 if getattr(mod, x, nothing) is nothing: |
185 |
178 setattr(mod, x, _demandmod(x, mod.__dict__, locals)) |
|
179 return mod |
186 return mod |
180 |
187 |
181 ignore = [ |
188 ignore = [ |
182 '__future__', |
189 '__future__', |
183 '_hashlib', |
190 '_hashlib', |