Mercurial > hg
annotate hgdemandimport/demandimportpy2.py @ 33761:f5fc54e7e467
encoding: drop circular import by proxying through '<policy>.charencode'
I decided not to split charencode.c to new C extension module because it
would duplicate binary codes unnecessarily.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Mon, 31 Jul 2017 23:13:47 +0900 |
parents | 9cbbf9118c6c |
children | 8fb5212652ec |
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 os |
3beed01daff9
demandimport: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25937
diff
changeset
|
32 import sys |
25674
5d0847cd1587
demandimport: support importing builtins for Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25673
diff
changeset
|
33 |
25943
3beed01daff9
demandimport: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25937
diff
changeset
|
34 contextmanager = contextlib.contextmanager |
3beed01daff9
demandimport: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25937
diff
changeset
|
35 |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
36 _origimport = __import__ |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
37 |
14977
1dbd42a02153
demandimport: use getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents:
14976
diff
changeset
|
38 nothing = object() |
1dbd42a02153
demandimport: use getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents:
14976
diff
changeset
|
39 |
25936
f90bb2002bcf
demandimport: support keyword arguments on _hgextimport
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25935
diff
changeset
|
40 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
|
41 try: |
25936
f90bb2002bcf
demandimport: support keyword arguments on _hgextimport
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25935
diff
changeset
|
42 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
|
43 except ImportError: |
621a26eb3a99
demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
19932
diff
changeset
|
44 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
|
45 raise |
621a26eb3a99
demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
19932
diff
changeset
|
46 # 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
|
47 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
|
48 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
|
49 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
|
50 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
|
51 raise |
621a26eb3a99
demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
19932
diff
changeset
|
52 # retry to import with "hgext_" prefix |
25936
f90bb2002bcf
demandimport: support keyword arguments on _hgextimport
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25935
diff
changeset
|
53 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
|
54 |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
55 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
|
56 """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
|
57 |
ae9a4d6a8d51
demandimport: omit default value of "level" at construction of _demandmod
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29736
diff
changeset
|
58 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
|
59 relatively. |
ae9a4d6a8d51
demandimport: omit default value of "level" at construction of _demandmod
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29736
diff
changeset
|
60 """ |
32446
63365e9621d6
demandimport: insert empty line per method
Yuya Nishihara <yuya@tcha.org>
parents:
32445
diff
changeset
|
61 |
29737
ae9a4d6a8d51
demandimport: omit default value of "level" at construction of _demandmod
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29736
diff
changeset
|
62 def __init__(self, name, globals, locals, level): |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
63 if '.' in name: |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
64 head, rest = name.split('.', 1) |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
65 after = [rest] |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
66 else: |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
67 head = name |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
68 after = [] |
31644
f80d9ddc40f3
py3: abuse r'' to preserve str-ness of literals passed to __setattr__()
Yuya Nishihara <yuya@tcha.org>
parents:
30647
diff
changeset
|
69 object.__setattr__(self, r"_data", |
26457
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
70 (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
|
71 object.__setattr__(self, r"_module", None) |
32446
63365e9621d6
demandimport: insert empty line per method
Yuya Nishihara <yuya@tcha.org>
parents:
32445
diff
changeset
|
72 |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
73 def _extend(self, name): |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
74 """add to the list of submodules to load""" |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
75 self._data[3].append(name) |
26457
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
76 |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
77 def _addref(self, name): |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
78 """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
|
79 |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
80 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
|
81 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
|
82 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
|
83 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
|
84 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
|
85 """ |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
86 self._data[5].add(name) |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
87 |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
88 def _load(self): |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
89 if not self._module: |
26457
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
90 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
|
91 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
|
92 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
|
93 # 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
|
94 # _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
|
95 # 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
|
96 # 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
|
97 # |
8960fcb76ca4
demandimport: avoid infinite recursion at actual module importing (issue5304)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29375
diff
changeset
|
98 # 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
|
99 # 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
|
100 # 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
|
101 # 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
|
102 # 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
|
103 # 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
|
104 # 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
|
105 mod = self._module |
8960fcb76ca4
demandimport: avoid infinite recursion at actual module importing (issue5304)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29375
diff
changeset
|
106 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
|
107 return |
8960fcb76ca4
demandimport: avoid infinite recursion at actual module importing (issue5304)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29375
diff
changeset
|
108 |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
109 # 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
|
110 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
|
111 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
|
112 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
|
113 h, t = p.split('.', 1) |
14977
1dbd42a02153
demandimport: use getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents:
14976
diff
changeset
|
114 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
|
115 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
|
116 level=1)) |
3926
de6ae8f016af
demandimport: handle already-loaded nested modules in subload
Brendan Cully <brendan@kublai.com>
parents:
3921
diff
changeset
|
117 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
|
118 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
|
119 |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
120 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
|
121 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
|
122 |
26457
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
123 # 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
|
124 if locals: |
252d2260c74e
demandimport: look for 'mod' suffix as alternative name for module reference
Yuya Nishihara <yuya@tcha.org>
parents:
32446
diff
changeset
|
125 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
|
126 locals[head] = mod |
252d2260c74e
demandimport: look for 'mod' suffix as alternative name for module reference
Yuya Nishihara <yuya@tcha.org>
parents:
32446
diff
changeset
|
127 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
|
128 locals[head + r'mod'] = mod |
26457
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
129 |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
130 for modname in modrefs: |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
131 modref = sys.modules.get(modname, None) |
32445
847233374434
demandimport: strictly compare identity of proxy object
Yuya Nishihara <yuya@tcha.org>
parents:
32422
diff
changeset
|
132 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
|
133 setattr(modref, head, mod) |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
134 |
31644
f80d9ddc40f3
py3: abuse r'' to preserve str-ness of literals passed to __setattr__()
Yuya Nishihara <yuya@tcha.org>
parents:
30647
diff
changeset
|
135 object.__setattr__(self, r"_module", mod) |
4631
e3afa670e484
demandimport: fix issue579 and add a test
Matt Mackall <mpm@selenic.com>
parents:
4626
diff
changeset
|
136 |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
137 def __repr__(self): |
4631
e3afa670e484
demandimport: fix issue579 and add a test
Matt Mackall <mpm@selenic.com>
parents:
4626
diff
changeset
|
138 if self._module: |
e3afa670e484
demandimport: fix issue579 and add a test
Matt Mackall <mpm@selenic.com>
parents:
4626
diff
changeset
|
139 return "<proxied module '%s'>" % self._data[0] |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
140 return "<unloaded module '%s'>" % self._data[0] |
32446
63365e9621d6
demandimport: insert empty line per method
Yuya Nishihara <yuya@tcha.org>
parents:
32445
diff
changeset
|
141 |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
142 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
|
143 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
|
144 |
32448
91a2ec8e7fa0
demandimport: stop overriding __getattribute__()
Yuya Nishihara <yuya@tcha.org>
parents:
32447
diff
changeset
|
145 def __getattr__(self, attr): |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
146 self._load() |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
147 return getattr(self._module, attr) |
32446
63365e9621d6
demandimport: insert empty line per method
Yuya Nishihara <yuya@tcha.org>
parents:
32445
diff
changeset
|
148 |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
149 def __setattr__(self, attr, val): |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
150 self._load() |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
151 setattr(self._module, attr, val) |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
152 |
32448
91a2ec8e7fa0
demandimport: stop overriding __getattribute__()
Yuya Nishihara <yuya@tcha.org>
parents:
32447
diff
changeset
|
153 @property |
91a2ec8e7fa0
demandimport: stop overriding __getattribute__()
Yuya Nishihara <yuya@tcha.org>
parents:
32447
diff
changeset
|
154 def __dict__(self): |
91a2ec8e7fa0
demandimport: stop overriding __getattribute__()
Yuya Nishihara <yuya@tcha.org>
parents:
32447
diff
changeset
|
155 self._load() |
91a2ec8e7fa0
demandimport: stop overriding __getattribute__()
Yuya Nishihara <yuya@tcha.org>
parents:
32447
diff
changeset
|
156 return self._module.__dict__ |
91a2ec8e7fa0
demandimport: stop overriding __getattribute__()
Yuya Nishihara <yuya@tcha.org>
parents:
32447
diff
changeset
|
157 |
91a2ec8e7fa0
demandimport: stop overriding __getattribute__()
Yuya Nishihara <yuya@tcha.org>
parents:
32447
diff
changeset
|
158 @property |
91a2ec8e7fa0
demandimport: stop overriding __getattribute__()
Yuya Nishihara <yuya@tcha.org>
parents:
32447
diff
changeset
|
159 def __doc__(self): |
91a2ec8e7fa0
demandimport: stop overriding __getattribute__()
Yuya Nishihara <yuya@tcha.org>
parents:
32447
diff
changeset
|
160 self._load() |
91a2ec8e7fa0
demandimport: stop overriding __getattribute__()
Yuya Nishihara <yuya@tcha.org>
parents:
32447
diff
changeset
|
161 return self._module.__doc__ |
91a2ec8e7fa0
demandimport: stop overriding __getattribute__()
Yuya Nishihara <yuya@tcha.org>
parents:
32447
diff
changeset
|
162 |
27536
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
163 _pypy = '__pypy__' in sys.builtin_module_names |
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
164 |
33530
05e3fa254b6b
demandimport: drop Py3 workarounds from Py2 implementation
Yuya Nishihara <yuya@tcha.org>
parents:
33529
diff
changeset
|
165 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
|
166 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
|
167 # 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
|
168 return _hgextimport(_origimport, name, globals, locals, fromlist, level) |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
169 elif not fromlist: |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
170 # import a [as b] |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
171 if '.' in name: # a.b |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
172 base, rest = name.split('.', 1) |
3903
f9136599700f
Make demandimport pass all tests on python2.5.
Brendan Cully <brendan@kublai.com>
parents:
3898
diff
changeset
|
173 # email.__init__ loading email.mime |
f9136599700f
Make demandimport pass all tests on python2.5.
Brendan Cully <brendan@kublai.com>
parents:
3898
diff
changeset
|
174 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
|
175 return _origimport(name, globals, locals, fromlist, level) |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
176 # 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
|
177 if base in locals: |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
178 if isinstance(locals[base], _demandmod): |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
179 locals[base]._extend(rest) |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
180 return locals[base] |
19932
e3a5922e18c3
demandimport: support "absolute_import" for external libraries (issue4029)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15096
diff
changeset
|
181 return _demandmod(name, globals, locals, level) |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
182 else: |
25935
49dd4fd3f283
demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25934
diff
changeset
|
183 # There is a fromlist. |
49dd4fd3f283
demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25934
diff
changeset
|
184 # from a import b,c,d |
49dd4fd3f283
demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25934
diff
changeset
|
185 # from . import b,c,d |
49dd4fd3f283
demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25934
diff
changeset
|
186 # from .a import b,c,d |
49dd4fd3f283
demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25934
diff
changeset
|
187 |
49dd4fd3f283
demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25934
diff
changeset
|
188 # 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
|
189 # 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
|
190 # 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
|
191 # 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
|
192 |
26457
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
193 # 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
|
194 globalname = globals.get('__name__') |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
195 |
26873
78d05778907b
demandimport: fix level passed to loader of sub-modules
Yuya Nishihara <yuya@tcha.org>
parents:
26830
diff
changeset
|
196 def processfromitem(mod, attr): |
26455
f2bf76d3d567
demandimport: consolidate code for processing items in fromlist
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25943
diff
changeset
|
197 """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
|
198 |
30022
26a4e46af2bc
demandimport: error out early on missing attribute of non package (issue5373)
Yuya Nishihara <yuya@tcha.org>
parents:
30021
diff
changeset
|
199 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
|
200 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
|
201 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
|
202 """ |
26456
86fc4a2863ff
demandimport: refactor processfromitem
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26455
diff
changeset
|
203 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
|
204 nonpkg = getattr(mod, '__path__', nothing) is nothing |
26456
86fc4a2863ff
demandimport: refactor processfromitem
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26455
diff
changeset
|
205 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
|
206 if nonpkg: |
30647
1914db1b7d9e
demandimport: do not raise ImportError for unknown item in fromlist
Yuya Nishihara <yuya@tcha.org>
parents:
30156
diff
changeset
|
207 # 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
|
208 # 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
|
209 # 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
|
210 # 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
|
211 return |
28175
c25e3fd38ff1
demandimport: enforce ignore list while processing modules in fromlist
Yuya Nishihara <yuya@tcha.org>
parents:
27537
diff
changeset
|
212 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
|
213 if mn in ignore: |
c25e3fd38ff1
demandimport: enforce ignore list while processing modules in fromlist
Yuya Nishihara <yuya@tcha.org>
parents:
27537
diff
changeset
|
214 importfunc = _origimport |
c25e3fd38ff1
demandimport: enforce ignore list while processing modules in fromlist
Yuya Nishihara <yuya@tcha.org>
parents:
27537
diff
changeset
|
215 else: |
c25e3fd38ff1
demandimport: enforce ignore list while processing modules in fromlist
Yuya Nishihara <yuya@tcha.org>
parents:
27537
diff
changeset
|
216 importfunc = _demandmod |
c25e3fd38ff1
demandimport: enforce ignore list while processing modules in fromlist
Yuya Nishihara <yuya@tcha.org>
parents:
27537
diff
changeset
|
217 symbol = importfunc(attr, mod.__dict__, locals, level=1) |
26456
86fc4a2863ff
demandimport: refactor processfromitem
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26455
diff
changeset
|
218 setattr(mod, attr, symbol) |
26455
f2bf76d3d567
demandimport: consolidate code for processing items in fromlist
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25943
diff
changeset
|
219 |
26457
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
220 # 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
|
221 # 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
|
222 # time. |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
223 if globalname and isinstance(symbol, _demandmod): |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
224 symbol._addref(globalname) |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
225 |
29375
fcaf20175b1b
demandimport: delay loading for "from a import b" with absolute_import
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
28286
diff
changeset
|
226 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
|
227 # 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
|
228 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
|
229 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
|
230 obj = getattr(mod, comp, nothing) |
9cbbf9118c6c
demandimport: prefer loaded module over package attribute (issue5617)
Yuya Nishihara <yuya@tcha.org>
parents:
33530
diff
changeset
|
231 if obj is nothing: |
9cbbf9118c6c
demandimport: prefer loaded module over package attribute (issue5617)
Yuya Nishihara <yuya@tcha.org>
parents:
33530
diff
changeset
|
232 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
|
233 setattr(mod, comp, obj) |
9cbbf9118c6c
demandimport: prefer loaded module over package attribute (issue5617)
Yuya Nishihara <yuya@tcha.org>
parents:
33530
diff
changeset
|
234 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
|
235 # prefer loaded module over attribute (issue5617) |
9cbbf9118c6c
demandimport: prefer loaded module over package attribute (issue5617)
Yuya Nishihara <yuya@tcha.org>
parents:
33530
diff
changeset
|
236 obj = sys.modules[mod.__name__ + '.' + comp] |
9cbbf9118c6c
demandimport: prefer loaded module over package attribute (issue5617)
Yuya Nishihara <yuya@tcha.org>
parents:
33530
diff
changeset
|
237 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
|
238 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
|
239 |
25935
49dd4fd3f283
demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25934
diff
changeset
|
240 if level >= 0: |
25937
4f1144c3c72b
demandimport: support lazy loading for absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25936
diff
changeset
|
241 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
|
242 # "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
|
243 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
|
244 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
|
245 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
|
246 elif _pypy: |
27536
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
247 # PyPy's __import__ throws an exception if invoked |
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
248 # 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
|
249 # desired behaviour by hand. |
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
250 mn = globalname |
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
251 mod = sys.modules[mn] |
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
252 if getattr(mod, '__path__', nothing) is nothing: |
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
253 mn = mn.rsplit('.', 1)[0] |
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
254 mod = sys.modules[mn] |
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
255 if level > 1: |
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
256 mn = mn.rsplit('.', level - 1)[0] |
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
257 mod = sys.modules[mn] |
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
258 else: |
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
259 mod = _hgextimport(_origimport, name, globals, locals, |
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
260 level=level) |
26455
f2bf76d3d567
demandimport: consolidate code for processing items in fromlist
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25943
diff
changeset
|
261 |
25937
4f1144c3c72b
demandimport: support lazy loading for absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25936
diff
changeset
|
262 for x in fromlist: |
26873
78d05778907b
demandimport: fix level passed to loader of sub-modules
Yuya Nishihara <yuya@tcha.org>
parents:
26830
diff
changeset
|
263 processfromitem(mod, x) |
25937
4f1144c3c72b
demandimport: support lazy loading for absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25936
diff
changeset
|
264 |
4f1144c3c72b
demandimport: support lazy loading for absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25936
diff
changeset
|
265 return mod |
25935
49dd4fd3f283
demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25934
diff
changeset
|
266 |
49dd4fd3f283
demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25934
diff
changeset
|
267 # 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
|
268 # 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
|
269 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
|
270 mod = chainmodules(mod, name) |
26455
f2bf76d3d567
demandimport: consolidate code for processing items in fromlist
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25943
diff
changeset
|
271 |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
272 for x in fromlist: |
26455
f2bf76d3d567
demandimport: consolidate code for processing items in fromlist
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25943
diff
changeset
|
273 processfromitem(mod, x) |
f2bf76d3d567
demandimport: consolidate code for processing items in fromlist
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25943
diff
changeset
|
274 |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
275 return mod |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
276 |
32422
f37f9499fea8
demandimport: move ignore list to __init__.py
Siddharth Agarwal <sid0@fb.com>
parents:
32420
diff
changeset
|
277 ignore = [] |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
278 |
32422
f37f9499fea8
demandimport: move ignore list to __init__.py
Siddharth Agarwal <sid0@fb.com>
parents:
32420
diff
changeset
|
279 def init(ignorelist): |
f37f9499fea8
demandimport: move ignore list to __init__.py
Siddharth Agarwal <sid0@fb.com>
parents:
32420
diff
changeset
|
280 global ignore |
f37f9499fea8
demandimport: move ignore list to __init__.py
Siddharth Agarwal <sid0@fb.com>
parents:
32420
diff
changeset
|
281 ignore = ignorelist |
30020
bf94fe556f16
demandimport: add '_ctypes.pointer' to ignore list on PyPy
Yuya Nishihara <yuya@tcha.org>
parents:
29980
diff
changeset
|
282 |
20422
aac87f70f38e
hooks: only disable/re-enable demandimport when it's already enabled
Brodie Rao <brodie@sf.io>
parents:
19933
diff
changeset
|
283 def isenabled(): |
25673
fa1f04529775
demandimport: alias __builtin__ as builtins
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25327
diff
changeset
|
284 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
|
285 |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
286 def enable(): |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
287 "enable global demand-loading of modules" |
21025
54af51c18c4c
demandimport: make it possible to disable by setting HGDEMANDIMPORT=disable
Mads Kiilerich <madski@unity3d.com>
parents:
20422
diff
changeset
|
288 if os.environ.get('HGDEMANDIMPORT') != 'disable': |
25673
fa1f04529775
demandimport: alias __builtin__ as builtins
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25327
diff
changeset
|
289 builtins.__import__ = _demandimport |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
290 |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
291 def disable(): |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
292 "disable global demand-loading of modules" |
25673
fa1f04529775
demandimport: alias __builtin__ as builtins
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25327
diff
changeset
|
293 builtins.__import__ = _origimport |
25327
2e7804110b14
demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
23643
diff
changeset
|
294 |
2e7804110b14
demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
23643
diff
changeset
|
295 @contextmanager |
2e7804110b14
demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
23643
diff
changeset
|
296 def deactivated(): |
2e7804110b14
demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
23643
diff
changeset
|
297 "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
|
298 demandenabled = isenabled() |
2e7804110b14
demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
23643
diff
changeset
|
299 if demandenabled: |
2e7804110b14
demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
23643
diff
changeset
|
300 disable() |
2e7804110b14
demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
23643
diff
changeset
|
301 |
2e7804110b14
demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
23643
diff
changeset
|
302 try: |
2e7804110b14
demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
23643
diff
changeset
|
303 yield |
2e7804110b14
demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
23643
diff
changeset
|
304 finally: |
2e7804110b14
demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
23643
diff
changeset
|
305 if demandenabled: |
2e7804110b14
demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
23643
diff
changeset
|
306 enable() |