Mercurial > hg
annotate hgdemandimport/demandimportpy2.py @ 34535:78590585c0db
templater: add dot operator to easily access a sub item
This and the next patch will allow us to access a deeply-nested item
by foo.bar.baz syntax.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sat, 09 Sep 2017 19:32:56 +0900 |
parents | 8fb5212652ec |
children | 670eb4fa1b86 |
rev | line source |
---|---|
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
1 # demandimport.py - global demand-loading of modules for Mercurial |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
2 # |
4635
63b9d2deed48
Updated copyright notices and add "and others" to "hg version"
Thomas Arendsen Hein <thomas@intevation.de>
parents:
4631
diff
changeset
|
3 # Copyright 2006, 2007 Matt Mackall <mpm@selenic.com> |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
4 # |
8225
46293a0c7e9f
updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents:
7861
diff
changeset
|
5 # This software may be used and distributed according to the terms of the |
10263 | 6 # GNU General Public License version 2 or any later version. |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
7 |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
8 ''' |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
9 demandimport - automatic demandloading of modules |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
10 |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
11 To enable this module, do: |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
12 |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
13 import demandimport; demandimport.enable() |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
14 |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
15 Imports of the following forms will be demand-loaded: |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
16 |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
17 import a, b.c |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
18 import a.b as c |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
19 from a import b,c # a will be loaded immediately |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
20 |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
21 These imports will not be delayed: |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
22 |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
23 from a import * |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
24 b = __import__(a) |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
25 ''' |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
26 |
25943
3beed01daff9
demandimport: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25937
diff
changeset
|
27 from __future__ import absolute_import |
3beed01daff9
demandimport: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25937
diff
changeset
|
28 |
33530
05e3fa254b6b
demandimport: drop Py3 workarounds from Py2 implementation
Yuya Nishihara <yuya@tcha.org>
parents:
33529
diff
changeset
|
29 import __builtin__ as builtins |
25943
3beed01daff9
demandimport: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25937
diff
changeset
|
30 import contextlib |
3beed01daff9
demandimport: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25937
diff
changeset
|
31 import sys |
25674
5d0847cd1587
demandimport: support importing builtins for Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25673
diff
changeset
|
32 |
25943
3beed01daff9
demandimport: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25937
diff
changeset
|
33 contextmanager = contextlib.contextmanager |
3beed01daff9
demandimport: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25937
diff
changeset
|
34 |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
35 _origimport = __import__ |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
36 |
14977
1dbd42a02153
demandimport: use getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents:
14976
diff
changeset
|
37 nothing = object() |
1dbd42a02153
demandimport: use getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents:
14976
diff
changeset
|
38 |
25936
f90bb2002bcf
demandimport: support keyword arguments on _hgextimport
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25935
diff
changeset
|
39 def _hgextimport(importfunc, name, globals, *args, **kwargs): |
19933
621a26eb3a99
demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
19932
diff
changeset
|
40 try: |
25936
f90bb2002bcf
demandimport: support keyword arguments on _hgextimport
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25935
diff
changeset
|
41 return importfunc(name, globals, *args, **kwargs) |
19933
621a26eb3a99
demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
19932
diff
changeset
|
42 except ImportError: |
621a26eb3a99
demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
19932
diff
changeset
|
43 if not globals: |
621a26eb3a99
demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
19932
diff
changeset
|
44 raise |
621a26eb3a99
demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
19932
diff
changeset
|
45 # extensions are loaded with "hgext_" prefix |
621a26eb3a99
demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
19932
diff
changeset
|
46 hgextname = 'hgext_%s' % name |
621a26eb3a99
demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
19932
diff
changeset
|
47 nameroot = hgextname.split('.', 1)[0] |
621a26eb3a99
demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
19932
diff
changeset
|
48 contextroot = globals.get('__name__', '').split('.', 1)[0] |
621a26eb3a99
demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
19932
diff
changeset
|
49 if nameroot != contextroot: |
621a26eb3a99
demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
19932
diff
changeset
|
50 raise |
621a26eb3a99
demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
19932
diff
changeset
|
51 # retry to import with "hgext_" prefix |
25936
f90bb2002bcf
demandimport: support keyword arguments on _hgextimport
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25935
diff
changeset
|
52 return importfunc(hgextname, globals, *args, **kwargs) |
19933
621a26eb3a99
demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
19932
diff
changeset
|
53 |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
54 class _demandmod(object): |
29737
ae9a4d6a8d51
demandimport: omit default value of "level" at construction of _demandmod
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29736
diff
changeset
|
55 """module demand-loader and proxy |
ae9a4d6a8d51
demandimport: omit default value of "level" at construction of _demandmod
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29736
diff
changeset
|
56 |
ae9a4d6a8d51
demandimport: omit default value of "level" at construction of _demandmod
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29736
diff
changeset
|
57 Specify 1 as 'level' argument at construction, to import module |
ae9a4d6a8d51
demandimport: omit default value of "level" at construction of _demandmod
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29736
diff
changeset
|
58 relatively. |
ae9a4d6a8d51
demandimport: omit default value of "level" at construction of _demandmod
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29736
diff
changeset
|
59 """ |
32446
63365e9621d6
demandimport: insert empty line per method
Yuya Nishihara <yuya@tcha.org>
parents:
32445
diff
changeset
|
60 |
29737
ae9a4d6a8d51
demandimport: omit default value of "level" at construction of _demandmod
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29736
diff
changeset
|
61 def __init__(self, name, globals, locals, level): |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
62 if '.' in name: |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
63 head, rest = name.split('.', 1) |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
64 after = [rest] |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
65 else: |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
66 head = name |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
67 after = [] |
31644
f80d9ddc40f3
py3: abuse r'' to preserve str-ness of literals passed to __setattr__()
Yuya Nishihara <yuya@tcha.org>
parents:
30647
diff
changeset
|
68 object.__setattr__(self, r"_data", |
26457
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
69 (head, globals, locals, after, level, set())) |
31644
f80d9ddc40f3
py3: abuse r'' to preserve str-ness of literals passed to __setattr__()
Yuya Nishihara <yuya@tcha.org>
parents:
30647
diff
changeset
|
70 object.__setattr__(self, r"_module", None) |
32446
63365e9621d6
demandimport: insert empty line per method
Yuya Nishihara <yuya@tcha.org>
parents:
32445
diff
changeset
|
71 |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
72 def _extend(self, name): |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
73 """add to the list of submodules to load""" |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
74 self._data[3].append(name) |
26457
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
75 |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
76 def _addref(self, name): |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
77 """Record that the named module ``name`` imports this module. |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
78 |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
79 References to this proxy class having the name of this module will be |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
80 replaced at module load time. We assume the symbol inside the importing |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
81 module is identical to the "head" name of this module. We don't |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
82 actually know if "as X" syntax is being used to change the symbol name |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
83 because this information isn't exposed to __import__. |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
84 """ |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
85 self._data[5].add(name) |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
86 |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
87 def _load(self): |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
88 if not self._module: |
26457
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
89 head, globals, locals, after, level, modrefs = self._data |
33529
ded3ebae8779
demandimport: drop hack for old Pythons which had no level argument
Yuya Nishihara <yuya@tcha.org>
parents:
32448
diff
changeset
|
90 mod = _hgextimport(_origimport, head, globals, locals, None, level) |
29642
8960fcb76ca4
demandimport: avoid infinite recursion at actual module importing (issue5304)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29375
diff
changeset
|
91 if mod is self: |
8960fcb76ca4
demandimport: avoid infinite recursion at actual module importing (issue5304)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29375
diff
changeset
|
92 # In this case, _hgextimport() above should imply |
8960fcb76ca4
demandimport: avoid infinite recursion at actual module importing (issue5304)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29375
diff
changeset
|
93 # _demandimport(). Otherwise, _hgextimport() never |
8960fcb76ca4
demandimport: avoid infinite recursion at actual module importing (issue5304)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29375
diff
changeset
|
94 # returns _demandmod. This isn't intentional behavior, |
8960fcb76ca4
demandimport: avoid infinite recursion at actual module importing (issue5304)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29375
diff
changeset
|
95 # in fact. (see also issue5304 for detail) |
8960fcb76ca4
demandimport: avoid infinite recursion at actual module importing (issue5304)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29375
diff
changeset
|
96 # |
8960fcb76ca4
demandimport: avoid infinite recursion at actual module importing (issue5304)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29375
diff
changeset
|
97 # If self._module is already bound at this point, self |
8960fcb76ca4
demandimport: avoid infinite recursion at actual module importing (issue5304)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29375
diff
changeset
|
98 # should be already _load()-ed while _hgextimport(). |
8960fcb76ca4
demandimport: avoid infinite recursion at actual module importing (issue5304)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29375
diff
changeset
|
99 # Otherwise, there is no way to import actual module |
8960fcb76ca4
demandimport: avoid infinite recursion at actual module importing (issue5304)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29375
diff
changeset
|
100 # as expected, because (re-)invoking _hgextimport() |
8960fcb76ca4
demandimport: avoid infinite recursion at actual module importing (issue5304)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29375
diff
changeset
|
101 # should cause same result. |
8960fcb76ca4
demandimport: avoid infinite recursion at actual module importing (issue5304)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29375
diff
changeset
|
102 # This is reason why _load() returns without any more |
8960fcb76ca4
demandimport: avoid infinite recursion at actual module importing (issue5304)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29375
diff
changeset
|
103 # setup but assumes self to be already bound. |
8960fcb76ca4
demandimport: avoid infinite recursion at actual module importing (issue5304)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29375
diff
changeset
|
104 mod = self._module |
8960fcb76ca4
demandimport: avoid infinite recursion at actual module importing (issue5304)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29375
diff
changeset
|
105 assert mod and mod is not self, "%s, %s" % (self, mod) |
8960fcb76ca4
demandimport: avoid infinite recursion at actual module importing (issue5304)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29375
diff
changeset
|
106 return |
8960fcb76ca4
demandimport: avoid infinite recursion at actual module importing (issue5304)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29375
diff
changeset
|
107 |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
108 # load submodules |
3921
6d0d025e125a
demandimport: fix import x.y.z as a when x.y is already imported.
Matt Mackall <mpm@selenic.com>
parents:
3903
diff
changeset
|
109 def subload(mod, p): |
6d0d025e125a
demandimport: fix import x.y.z as a when x.y is already imported.
Matt Mackall <mpm@selenic.com>
parents:
3903
diff
changeset
|
110 h, t = p, None |
6d0d025e125a
demandimport: fix import x.y.z as a when x.y is already imported.
Matt Mackall <mpm@selenic.com>
parents:
3903
diff
changeset
|
111 if '.' in p: |
6d0d025e125a
demandimport: fix import x.y.z as a when x.y is already imported.
Matt Mackall <mpm@selenic.com>
parents:
3903
diff
changeset
|
112 h, t = p.split('.', 1) |
14977
1dbd42a02153
demandimport: use getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents:
14976
diff
changeset
|
113 if getattr(mod, h, nothing) is nothing: |
29736
14f077f7519a
demandimport: import sub-module relatively as expected (issue5208)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29642
diff
changeset
|
114 setattr(mod, h, _demandmod(p, mod.__dict__, mod.__dict__, |
14f077f7519a
demandimport: import sub-module relatively as expected (issue5208)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29642
diff
changeset
|
115 level=1)) |
3926
de6ae8f016af
demandimport: handle already-loaded nested modules in subload
Brendan Cully <brendan@kublai.com>
parents:
3921
diff
changeset
|
116 elif t: |
3921
6d0d025e125a
demandimport: fix import x.y.z as a when x.y is already imported.
Matt Mackall <mpm@selenic.com>
parents:
3903
diff
changeset
|
117 subload(getattr(mod, h), t) |
6d0d025e125a
demandimport: fix import x.y.z as a when x.y is already imported.
Matt Mackall <mpm@selenic.com>
parents:
3903
diff
changeset
|
118 |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
119 for x in after: |
3921
6d0d025e125a
demandimport: fix import x.y.z as a when x.y is already imported.
Matt Mackall <mpm@selenic.com>
parents:
3903
diff
changeset
|
120 subload(mod, x) |
6d0d025e125a
demandimport: fix import x.y.z as a when x.y is already imported.
Matt Mackall <mpm@selenic.com>
parents:
3903
diff
changeset
|
121 |
26457
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
122 # Replace references to this proxy instance with the actual module. |
32447
252d2260c74e
demandimport: look for 'mod' suffix as alternative name for module reference
Yuya Nishihara <yuya@tcha.org>
parents:
32446
diff
changeset
|
123 if locals: |
252d2260c74e
demandimport: look for 'mod' suffix as alternative name for module reference
Yuya Nishihara <yuya@tcha.org>
parents:
32446
diff
changeset
|
124 if locals.get(head) is self: |
252d2260c74e
demandimport: look for 'mod' suffix as alternative name for module reference
Yuya Nishihara <yuya@tcha.org>
parents:
32446
diff
changeset
|
125 locals[head] = mod |
252d2260c74e
demandimport: look for 'mod' suffix as alternative name for module reference
Yuya Nishihara <yuya@tcha.org>
parents:
32446
diff
changeset
|
126 elif locals.get(head + r'mod') is self: |
252d2260c74e
demandimport: look for 'mod' suffix as alternative name for module reference
Yuya Nishihara <yuya@tcha.org>
parents:
32446
diff
changeset
|
127 locals[head + r'mod'] = mod |
26457
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
128 |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
129 for modname in modrefs: |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
130 modref = sys.modules.get(modname, None) |
32445
847233374434
demandimport: strictly compare identity of proxy object
Yuya Nishihara <yuya@tcha.org>
parents:
32422
diff
changeset
|
131 if modref and getattr(modref, head, None) is self: |
26457
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
132 setattr(modref, head, mod) |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
133 |
31644
f80d9ddc40f3
py3: abuse r'' to preserve str-ness of literals passed to __setattr__()
Yuya Nishihara <yuya@tcha.org>
parents:
30647
diff
changeset
|
134 object.__setattr__(self, r"_module", mod) |
4631
e3afa670e484
demandimport: fix issue579 and add a test
Matt Mackall <mpm@selenic.com>
parents:
4626
diff
changeset
|
135 |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
136 def __repr__(self): |
4631
e3afa670e484
demandimport: fix issue579 and add a test
Matt Mackall <mpm@selenic.com>
parents:
4626
diff
changeset
|
137 if self._module: |
e3afa670e484
demandimport: fix issue579 and add a test
Matt Mackall <mpm@selenic.com>
parents:
4626
diff
changeset
|
138 return "<proxied module '%s'>" % self._data[0] |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
139 return "<unloaded module '%s'>" % self._data[0] |
32446
63365e9621d6
demandimport: insert empty line per method
Yuya Nishihara <yuya@tcha.org>
parents:
32445
diff
changeset
|
140 |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
141 def __call__(self, *args, **kwargs): |
5639
7dd5cf9d1e09
demandload: give better diagnostic for call of an unloaded module
Matt Mackall <mpm@selenic.com>
parents:
5098
diff
changeset
|
142 raise TypeError("%s object is not callable" % repr(self)) |
32446
63365e9621d6
demandimport: insert empty line per method
Yuya Nishihara <yuya@tcha.org>
parents:
32445
diff
changeset
|
143 |
32448
91a2ec8e7fa0
demandimport: stop overriding __getattribute__()
Yuya Nishihara <yuya@tcha.org>
parents:
32447
diff
changeset
|
144 def __getattr__(self, attr): |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
145 self._load() |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
146 return getattr(self._module, attr) |
32446
63365e9621d6
demandimport: insert empty line per method
Yuya Nishihara <yuya@tcha.org>
parents:
32445
diff
changeset
|
147 |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
148 def __setattr__(self, attr, val): |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
149 self._load() |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
150 setattr(self._module, attr, val) |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
151 |
32448
91a2ec8e7fa0
demandimport: stop overriding __getattribute__()
Yuya Nishihara <yuya@tcha.org>
parents:
32447
diff
changeset
|
152 @property |
91a2ec8e7fa0
demandimport: stop overriding __getattribute__()
Yuya Nishihara <yuya@tcha.org>
parents:
32447
diff
changeset
|
153 def __dict__(self): |
91a2ec8e7fa0
demandimport: stop overriding __getattribute__()
Yuya Nishihara <yuya@tcha.org>
parents:
32447
diff
changeset
|
154 self._load() |
91a2ec8e7fa0
demandimport: stop overriding __getattribute__()
Yuya Nishihara <yuya@tcha.org>
parents:
32447
diff
changeset
|
155 return self._module.__dict__ |
91a2ec8e7fa0
demandimport: stop overriding __getattribute__()
Yuya Nishihara <yuya@tcha.org>
parents:
32447
diff
changeset
|
156 |
91a2ec8e7fa0
demandimport: stop overriding __getattribute__()
Yuya Nishihara <yuya@tcha.org>
parents:
32447
diff
changeset
|
157 @property |
91a2ec8e7fa0
demandimport: stop overriding __getattribute__()
Yuya Nishihara <yuya@tcha.org>
parents:
32447
diff
changeset
|
158 def __doc__(self): |
91a2ec8e7fa0
demandimport: stop overriding __getattribute__()
Yuya Nishihara <yuya@tcha.org>
parents:
32447
diff
changeset
|
159 self._load() |
91a2ec8e7fa0
demandimport: stop overriding __getattribute__()
Yuya Nishihara <yuya@tcha.org>
parents:
32447
diff
changeset
|
160 return self._module.__doc__ |
91a2ec8e7fa0
demandimport: stop overriding __getattribute__()
Yuya Nishihara <yuya@tcha.org>
parents:
32447
diff
changeset
|
161 |
27536
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
162 _pypy = '__pypy__' in sys.builtin_module_names |
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
163 |
33530
05e3fa254b6b
demandimport: drop Py3 workarounds from Py2 implementation
Yuya Nishihara <yuya@tcha.org>
parents:
33529
diff
changeset
|
164 def _demandimport(name, globals=None, locals=None, fromlist=None, level=-1): |
32365
b2b5605285ec
demandimport: strictly check missing locals argument
Yuya Nishihara <yuya@tcha.org>
parents:
32173
diff
changeset
|
165 if locals is None or name in ignore or fromlist == ('*',): |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
166 # these cases we can't really delay |
33529
ded3ebae8779
demandimport: drop hack for old Pythons which had no level argument
Yuya Nishihara <yuya@tcha.org>
parents:
32448
diff
changeset
|
167 return _hgextimport(_origimport, name, globals, locals, fromlist, level) |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
168 elif not fromlist: |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
169 # import a [as b] |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
170 if '.' in name: # a.b |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
171 base, rest = name.split('.', 1) |
3903
f9136599700f
Make demandimport pass all tests on python2.5.
Brendan Cully <brendan@kublai.com>
parents:
3898
diff
changeset
|
172 # email.__init__ loading email.mime |
f9136599700f
Make demandimport pass all tests on python2.5.
Brendan Cully <brendan@kublai.com>
parents:
3898
diff
changeset
|
173 if globals and globals.get('__name__', None) == base: |
33529
ded3ebae8779
demandimport: drop hack for old Pythons which had no level argument
Yuya Nishihara <yuya@tcha.org>
parents:
32448
diff
changeset
|
174 return _origimport(name, globals, locals, fromlist, level) |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
175 # if a is already demand-loaded, add b to its submodule list |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
176 if base in locals: |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
177 if isinstance(locals[base], _demandmod): |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
178 locals[base]._extend(rest) |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
179 return locals[base] |
19932
e3a5922e18c3
demandimport: support "absolute_import" for external libraries (issue4029)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15096
diff
changeset
|
180 return _demandmod(name, globals, locals, level) |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
181 else: |
25935
49dd4fd3f283
demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25934
diff
changeset
|
182 # There is a fromlist. |
49dd4fd3f283
demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25934
diff
changeset
|
183 # from a import b,c,d |
49dd4fd3f283
demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25934
diff
changeset
|
184 # from . import b,c,d |
49dd4fd3f283
demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25934
diff
changeset
|
185 # from .a import b,c,d |
49dd4fd3f283
demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25934
diff
changeset
|
186 |
49dd4fd3f283
demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25934
diff
changeset
|
187 # level == -1: relative and absolute attempted (Python 2 only). |
49dd4fd3f283
demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25934
diff
changeset
|
188 # level >= 0: absolute only (Python 2 w/ absolute_import and Python 3). |
49dd4fd3f283
demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25934
diff
changeset
|
189 # The modern Mercurial convention is to use absolute_import everywhere, |
49dd4fd3f283
demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25934
diff
changeset
|
190 # so modern Mercurial code will have level >= 0. |
49dd4fd3f283
demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25934
diff
changeset
|
191 |
26457
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
192 # The name of the module the import statement is located in. |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
193 globalname = globals.get('__name__') |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
194 |
26873
78d05778907b
demandimport: fix level passed to loader of sub-modules
Yuya Nishihara <yuya@tcha.org>
parents:
26830
diff
changeset
|
195 def processfromitem(mod, attr): |
26455
f2bf76d3d567
demandimport: consolidate code for processing items in fromlist
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25943
diff
changeset
|
196 """Process an imported symbol in the import statement. |
f2bf76d3d567
demandimport: consolidate code for processing items in fromlist
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25943
diff
changeset
|
197 |
30022
26a4e46af2bc
demandimport: error out early on missing attribute of non package (issue5373)
Yuya Nishihara <yuya@tcha.org>
parents:
30021
diff
changeset
|
198 If the symbol doesn't exist in the parent module, and if the |
26a4e46af2bc
demandimport: error out early on missing attribute of non package (issue5373)
Yuya Nishihara <yuya@tcha.org>
parents:
30021
diff
changeset
|
199 parent module is a package, it must be a module. We set missing |
26a4e46af2bc
demandimport: error out early on missing attribute of non package (issue5373)
Yuya Nishihara <yuya@tcha.org>
parents:
30021
diff
changeset
|
200 modules up as _demandmod instances. |
26455
f2bf76d3d567
demandimport: consolidate code for processing items in fromlist
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25943
diff
changeset
|
201 """ |
26456
86fc4a2863ff
demandimport: refactor processfromitem
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26455
diff
changeset
|
202 symbol = getattr(mod, attr, nothing) |
30022
26a4e46af2bc
demandimport: error out early on missing attribute of non package (issue5373)
Yuya Nishihara <yuya@tcha.org>
parents:
30021
diff
changeset
|
203 nonpkg = getattr(mod, '__path__', nothing) is nothing |
26456
86fc4a2863ff
demandimport: refactor processfromitem
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26455
diff
changeset
|
204 if symbol is nothing: |
30022
26a4e46af2bc
demandimport: error out early on missing attribute of non package (issue5373)
Yuya Nishihara <yuya@tcha.org>
parents:
30021
diff
changeset
|
205 if nonpkg: |
30647
1914db1b7d9e
demandimport: do not raise ImportError for unknown item in fromlist
Yuya Nishihara <yuya@tcha.org>
parents:
30156
diff
changeset
|
206 # do not try relative import, which would raise ValueError, |
1914db1b7d9e
demandimport: do not raise ImportError for unknown item in fromlist
Yuya Nishihara <yuya@tcha.org>
parents:
30156
diff
changeset
|
207 # and leave unknown attribute as the default __import__() |
1914db1b7d9e
demandimport: do not raise ImportError for unknown item in fromlist
Yuya Nishihara <yuya@tcha.org>
parents:
30156
diff
changeset
|
208 # would do. the missing attribute will be detected later |
1914db1b7d9e
demandimport: do not raise ImportError for unknown item in fromlist
Yuya Nishihara <yuya@tcha.org>
parents:
30156
diff
changeset
|
209 # while processing the import statement. |
1914db1b7d9e
demandimport: do not raise ImportError for unknown item in fromlist
Yuya Nishihara <yuya@tcha.org>
parents:
30156
diff
changeset
|
210 return |
28175
c25e3fd38ff1
demandimport: enforce ignore list while processing modules in fromlist
Yuya Nishihara <yuya@tcha.org>
parents:
27537
diff
changeset
|
211 mn = '%s.%s' % (mod.__name__, attr) |
c25e3fd38ff1
demandimport: enforce ignore list while processing modules in fromlist
Yuya Nishihara <yuya@tcha.org>
parents:
27537
diff
changeset
|
212 if mn in ignore: |
c25e3fd38ff1
demandimport: enforce ignore list while processing modules in fromlist
Yuya Nishihara <yuya@tcha.org>
parents:
27537
diff
changeset
|
213 importfunc = _origimport |
c25e3fd38ff1
demandimport: enforce ignore list while processing modules in fromlist
Yuya Nishihara <yuya@tcha.org>
parents:
27537
diff
changeset
|
214 else: |
c25e3fd38ff1
demandimport: enforce ignore list while processing modules in fromlist
Yuya Nishihara <yuya@tcha.org>
parents:
27537
diff
changeset
|
215 importfunc = _demandmod |
c25e3fd38ff1
demandimport: enforce ignore list while processing modules in fromlist
Yuya Nishihara <yuya@tcha.org>
parents:
27537
diff
changeset
|
216 symbol = importfunc(attr, mod.__dict__, locals, level=1) |
26456
86fc4a2863ff
demandimport: refactor processfromitem
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26455
diff
changeset
|
217 setattr(mod, attr, symbol) |
26455
f2bf76d3d567
demandimport: consolidate code for processing items in fromlist
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25943
diff
changeset
|
218 |
26457
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
219 # Record the importing module references this symbol so we can |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
220 # replace the symbol with the actual module instance at load |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
221 # time. |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
222 if globalname and isinstance(symbol, _demandmod): |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
223 symbol._addref(globalname) |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
224 |
29375
fcaf20175b1b
demandimport: delay loading for "from a import b" with absolute_import
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
28286
diff
changeset
|
225 def chainmodules(rootmod, modname): |
fcaf20175b1b
demandimport: delay loading for "from a import b" with absolute_import
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
28286
diff
changeset
|
226 # recurse down the module chain, and return the leaf module |
fcaf20175b1b
demandimport: delay loading for "from a import b" with absolute_import
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
28286
diff
changeset
|
227 mod = rootmod |
fcaf20175b1b
demandimport: delay loading for "from a import b" with absolute_import
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
28286
diff
changeset
|
228 for comp in modname.split('.')[1:]: |
33531
9cbbf9118c6c
demandimport: prefer loaded module over package attribute (issue5617)
Yuya Nishihara <yuya@tcha.org>
parents:
33530
diff
changeset
|
229 obj = getattr(mod, comp, nothing) |
9cbbf9118c6c
demandimport: prefer loaded module over package attribute (issue5617)
Yuya Nishihara <yuya@tcha.org>
parents:
33530
diff
changeset
|
230 if obj is nothing: |
9cbbf9118c6c
demandimport: prefer loaded module over package attribute (issue5617)
Yuya Nishihara <yuya@tcha.org>
parents:
33530
diff
changeset
|
231 obj = _demandmod(comp, mod.__dict__, mod.__dict__, level=1) |
9cbbf9118c6c
demandimport: prefer loaded module over package attribute (issue5617)
Yuya Nishihara <yuya@tcha.org>
parents:
33530
diff
changeset
|
232 setattr(mod, comp, obj) |
9cbbf9118c6c
demandimport: prefer loaded module over package attribute (issue5617)
Yuya Nishihara <yuya@tcha.org>
parents:
33530
diff
changeset
|
233 elif mod.__name__ + '.' + comp in sys.modules: |
9cbbf9118c6c
demandimport: prefer loaded module over package attribute (issue5617)
Yuya Nishihara <yuya@tcha.org>
parents:
33530
diff
changeset
|
234 # prefer loaded module over attribute (issue5617) |
9cbbf9118c6c
demandimport: prefer loaded module over package attribute (issue5617)
Yuya Nishihara <yuya@tcha.org>
parents:
33530
diff
changeset
|
235 obj = sys.modules[mod.__name__ + '.' + comp] |
9cbbf9118c6c
demandimport: prefer loaded module over package attribute (issue5617)
Yuya Nishihara <yuya@tcha.org>
parents:
33530
diff
changeset
|
236 mod = obj |
29375
fcaf20175b1b
demandimport: delay loading for "from a import b" with absolute_import
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
28286
diff
changeset
|
237 return mod |
fcaf20175b1b
demandimport: delay loading for "from a import b" with absolute_import
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
28286
diff
changeset
|
238 |
25935
49dd4fd3f283
demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25934
diff
changeset
|
239 if level >= 0: |
25937
4f1144c3c72b
demandimport: support lazy loading for absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25936
diff
changeset
|
240 if name: |
29375
fcaf20175b1b
demandimport: delay loading for "from a import b" with absolute_import
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
28286
diff
changeset
|
241 # "from a import b" or "from .a import b" style |
fcaf20175b1b
demandimport: delay loading for "from a import b" with absolute_import
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
28286
diff
changeset
|
242 rootmod = _hgextimport(_origimport, name, globals, locals, |
fcaf20175b1b
demandimport: delay loading for "from a import b" with absolute_import
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
28286
diff
changeset
|
243 level=level) |
fcaf20175b1b
demandimport: delay loading for "from a import b" with absolute_import
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
28286
diff
changeset
|
244 mod = chainmodules(rootmod, name) |
fcaf20175b1b
demandimport: delay loading for "from a import b" with absolute_import
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
28286
diff
changeset
|
245 elif _pypy: |
27536
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
246 # PyPy's __import__ throws an exception if invoked |
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
247 # with an empty name and no fromlist. Recreate the |
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
248 # desired behaviour by hand. |
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
249 mn = globalname |
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
250 mod = sys.modules[mn] |
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
251 if getattr(mod, '__path__', nothing) is nothing: |
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
252 mn = mn.rsplit('.', 1)[0] |
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
253 mod = sys.modules[mn] |
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
254 if level > 1: |
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
255 mn = mn.rsplit('.', level - 1)[0] |
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
256 mod = sys.modules[mn] |
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
257 else: |
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
258 mod = _hgextimport(_origimport, name, globals, locals, |
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
259 level=level) |
26455
f2bf76d3d567
demandimport: consolidate code for processing items in fromlist
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25943
diff
changeset
|
260 |
25937
4f1144c3c72b
demandimport: support lazy loading for absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25936
diff
changeset
|
261 for x in fromlist: |
26873
78d05778907b
demandimport: fix level passed to loader of sub-modules
Yuya Nishihara <yuya@tcha.org>
parents:
26830
diff
changeset
|
262 processfromitem(mod, x) |
25937
4f1144c3c72b
demandimport: support lazy loading for absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25936
diff
changeset
|
263 |
4f1144c3c72b
demandimport: support lazy loading for absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25936
diff
changeset
|
264 return mod |
25935
49dd4fd3f283
demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25934
diff
changeset
|
265 |
49dd4fd3f283
demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25934
diff
changeset
|
266 # But, we still need to support lazy loading of standard library and 3rd |
49dd4fd3f283
demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25934
diff
changeset
|
267 # party modules. So handle level == -1. |
19933
621a26eb3a99
demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
19932
diff
changeset
|
268 mod = _hgextimport(_origimport, name, globals, locals) |
29375
fcaf20175b1b
demandimport: delay loading for "from a import b" with absolute_import
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
28286
diff
changeset
|
269 mod = chainmodules(mod, name) |
26455
f2bf76d3d567
demandimport: consolidate code for processing items in fromlist
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25943
diff
changeset
|
270 |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
271 for x in fromlist: |
26455
f2bf76d3d567
demandimport: consolidate code for processing items in fromlist
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25943
diff
changeset
|
272 processfromitem(mod, x) |
f2bf76d3d567
demandimport: consolidate code for processing items in fromlist
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25943
diff
changeset
|
273 |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
274 return mod |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
275 |
32422
f37f9499fea8
demandimport: move ignore list to __init__.py
Siddharth Agarwal <sid0@fb.com>
parents:
32420
diff
changeset
|
276 ignore = [] |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
277 |
32422
f37f9499fea8
demandimport: move ignore list to __init__.py
Siddharth Agarwal <sid0@fb.com>
parents:
32420
diff
changeset
|
278 def init(ignorelist): |
f37f9499fea8
demandimport: move ignore list to __init__.py
Siddharth Agarwal <sid0@fb.com>
parents:
32420
diff
changeset
|
279 global ignore |
f37f9499fea8
demandimport: move ignore list to __init__.py
Siddharth Agarwal <sid0@fb.com>
parents:
32420
diff
changeset
|
280 ignore = ignorelist |
30020
bf94fe556f16
demandimport: add '_ctypes.pointer' to ignore list on PyPy
Yuya Nishihara <yuya@tcha.org>
parents:
29980
diff
changeset
|
281 |
20422
aac87f70f38e
hooks: only disable/re-enable demandimport when it's already enabled
Brodie Rao <brodie@sf.io>
parents:
19933
diff
changeset
|
282 def isenabled(): |
25673
fa1f04529775
demandimport: alias __builtin__ as builtins
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25327
diff
changeset
|
283 return builtins.__import__ == _demandimport |
20422
aac87f70f38e
hooks: only disable/re-enable demandimport when it's already enabled
Brodie Rao <brodie@sf.io>
parents:
19933
diff
changeset
|
284 |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
285 def enable(): |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
286 "enable global demand-loading of modules" |
33859
8fb5212652ec
demandimport: move HGDEMANDIMPORT test to __init__.py
Jun Wu <quark@fb.com>
parents:
33531
diff
changeset
|
287 builtins.__import__ = _demandimport |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
288 |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
289 def disable(): |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
290 "disable global demand-loading of modules" |
25673
fa1f04529775
demandimport: alias __builtin__ as builtins
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25327
diff
changeset
|
291 builtins.__import__ = _origimport |
25327
2e7804110b14
demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
23643
diff
changeset
|
292 |
2e7804110b14
demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
23643
diff
changeset
|
293 @contextmanager |
2e7804110b14
demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
23643
diff
changeset
|
294 def deactivated(): |
2e7804110b14
demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
23643
diff
changeset
|
295 "context manager for disabling demandimport in 'with' blocks" |
2e7804110b14
demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
23643
diff
changeset
|
296 demandenabled = isenabled() |
2e7804110b14
demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
23643
diff
changeset
|
297 if demandenabled: |
2e7804110b14
demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
23643
diff
changeset
|
298 disable() |
2e7804110b14
demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
23643
diff
changeset
|
299 |
2e7804110b14
demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
23643
diff
changeset
|
300 try: |
2e7804110b14
demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
23643
diff
changeset
|
301 yield |
2e7804110b14
demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
23643
diff
changeset
|
302 finally: |
2e7804110b14
demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
23643
diff
changeset
|
303 if demandenabled: |
2e7804110b14
demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
23643
diff
changeset
|
304 enable() |