Mercurial > hg
annotate hgdemandimport/demandimportpy2.py @ 36806:69b2d0900cd7
hgweb: parse WSGI request into a data structure
Currently, our WSGI applications (hgweb_mod and hgwebdir_mod) process
the raw WSGI request instance themselves. This means they have to
talk in terms of system strings. And they need to know details
about what's in the WSGI request. And in the case of hgweb_mod, it
is doing some very funky things with URL parsing to impact
dispatching. The code is difficult to read and maintain.
This commit introduces parsing of the WSGI request into a higher-level
and easier-to-reason-about data structure.
To prove it works, we hook it up to hgweb_mod and use it for populating
the relative URL on the request instance.
We hold off on using it in more places because the logic in hgweb_mod
is crazy and I don't want to involve those changes with review of
the parsing code.
The URL construction code has variations that use the HTTP: Host header
(the canonical WSGI way of reconstructing the URL) and with the use
of SERVER_NAME. We need to differentiate because hgweb is currently
using SERVER_NAME for URL construction.
Differential Revision: https://phab.mercurial-scm.org/D2734
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Sat, 10 Mar 2018 10:20:51 -0800 |
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() |