annotate mercurial/demandimport.py @ 25783:1f6878c87c25

templater: introduce one-pass parsing of nested template strings Instead of re-parsing quoted strings as templates, the tokenizer can delegate the parsing of nested template strings to the parser. It has two benefits: 1. syntax errors can be reported with absolute positions 2. nested template can use quotes just like shell: "{"{rev}"}" It doesn't sound nice that the tokenizer recurses into the parser. We could instead make the tokenize itself recursive, but it would be much more complicated because we would have to adjust binding strengths carefully and put dummy infix operators to concatenate template fragments. Now "string" token without r"" never appears. It will be removed by the next patch.
author Yuya Nishihara <yuya@tcha.org>
date Mon, 15 Jun 2015 23:11:35 +0900
parents 5d0847cd1587
children 1fc6c02782ab
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 10242
diff changeset
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
25673
fa1f04529775 demandimport: alias __builtin__ as builtins
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25327
diff changeset
27 import os, sys
25327
2e7804110b14 demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 23643
diff changeset
28 from contextlib import contextmanager
25674
5d0847cd1587 demandimport: support importing builtins for Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25673
diff changeset
29
5d0847cd1587 demandimport: support importing builtins for Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25673
diff changeset
30 # __builtin__ in Python 2, builtins in Python 3.
5d0847cd1587 demandimport: support importing builtins for Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25673
diff changeset
31 try:
5d0847cd1587 demandimport: support importing builtins for Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25673
diff changeset
32 import __builtin__ as builtins
5d0847cd1587 demandimport: support importing builtins for Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25673
diff changeset
33 except ImportError:
5d0847cd1587 demandimport: support importing builtins for Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25673
diff changeset
34 import builtins
25327
2e7804110b14 demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 23643
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
15096
868282fa29d8 demandimport: determine at load time if __import__ has level argument
Simon Heimberg <simohe@besonet.ch>
parents: 14977
diff changeset
40 try:
21290
74be3fb1e3b8 demandimport: pass proper level to __import__ in Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21025
diff changeset
41 # Python 3 doesn't have relative imports nor level -1.
74be3fb1e3b8 demandimport: pass proper level to __import__ in Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21025
diff changeset
42 level = -1
74be3fb1e3b8 demandimport: pass proper level to __import__ in Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21025
diff changeset
43 if sys.version_info[0] >= 3:
74be3fb1e3b8 demandimport: pass proper level to __import__ in Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21025
diff changeset
44 level = 0
25673
fa1f04529775 demandimport: alias __builtin__ as builtins
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25327
diff changeset
45 _origimport(builtins.__name__, {}, {}, None, level)
15096
868282fa29d8 demandimport: determine at load time if __import__ has level argument
Simon Heimberg <simohe@besonet.ch>
parents: 14977
diff changeset
46 except TypeError: # no level argument
868282fa29d8 demandimport: determine at load time if __import__ has level argument
Simon Heimberg <simohe@besonet.ch>
parents: 14977
diff changeset
47 def _import(name, globals, locals, fromlist, level):
868282fa29d8 demandimport: determine at load time if __import__ has level argument
Simon Heimberg <simohe@besonet.ch>
parents: 14977
diff changeset
48 "call _origimport with no level argument"
868282fa29d8 demandimport: determine at load time if __import__ has level argument
Simon Heimberg <simohe@besonet.ch>
parents: 14977
diff changeset
49 return _origimport(name, globals, locals, fromlist)
868282fa29d8 demandimport: determine at load time if __import__ has level argument
Simon Heimberg <simohe@besonet.ch>
parents: 14977
diff changeset
50 else:
868282fa29d8 demandimport: determine at load time if __import__ has level argument
Simon Heimberg <simohe@besonet.ch>
parents: 14977
diff changeset
51 _import = _origimport
868282fa29d8 demandimport: determine at load time if __import__ has level argument
Simon Heimberg <simohe@besonet.ch>
parents: 14977
diff changeset
52
19933
621a26eb3a99 demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19932
diff changeset
53 def _hgextimport(importfunc, name, globals, *args):
621a26eb3a99 demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19932
diff changeset
54 try:
621a26eb3a99 demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19932
diff changeset
55 return importfunc(name, globals, *args)
621a26eb3a99 demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19932
diff changeset
56 except ImportError:
621a26eb3a99 demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19932
diff changeset
57 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
58 raise
621a26eb3a99 demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19932
diff changeset
59 # 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
60 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
61 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
62 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
63 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
64 raise
621a26eb3a99 demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19932
diff changeset
65 # retry to import 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
66 return importfunc(hgextname, globals, *args)
621a26eb3a99 demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19932
diff changeset
67
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
68 class _demandmod(object):
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
69 """module demand-loader and proxy"""
21290
74be3fb1e3b8 demandimport: pass proper level to __import__ in Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21025
diff changeset
70 def __init__(self, name, globals, locals, level=level):
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
71 if '.' in name:
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
72 head, rest = name.split('.', 1)
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
73 after = [rest]
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
74 else:
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
75 head = name
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
76 after = []
19932
e3a5922e18c3 demandimport: support "absolute_import" for external libraries (issue4029)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15096
diff changeset
77 object.__setattr__(self, "_data",
e3a5922e18c3 demandimport: support "absolute_import" for external libraries (issue4029)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15096
diff changeset
78 (head, globals, locals, after, level))
3896
3b628b5da9e9 use parent.__setattr__ instead of __dict__
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3877
diff changeset
79 object.__setattr__(self, "_module", None)
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
80 def _extend(self, name):
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
81 """add to the list of submodules to load"""
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
82 self._data[3].append(name)
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
83 def _load(self):
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
84 if not self._module:
19932
e3a5922e18c3 demandimport: support "absolute_import" for external libraries (issue4029)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15096
diff changeset
85 head, globals, locals, after, level = self._data
19933
621a26eb3a99 demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19932
diff changeset
86 mod = _hgextimport(_import, head, globals, locals, None, level)
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
87 # 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
88 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
89 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
90 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
91 h, t = p.split('.', 1)
14977
1dbd42a02153 demandimport: use getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14976
diff changeset
92 if getattr(mod, h, nothing) is nothing:
12894
bc91a79fa3d0 demandimport: back out 50a4e55aa278 (issue2467)
Matt Mackall <mpm@selenic.com>
parents: 12801
diff changeset
93 setattr(mod, h, _demandmod(p, mod.__dict__, mod.__dict__))
3926
de6ae8f016af demandimport: handle already-loaded nested modules in subload
Brendan Cully <brendan@kublai.com>
parents: 3921
diff changeset
94 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
95 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
96
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
97 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
98 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
99
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
100 # are we in the locals dictionary still?
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
101 if locals and locals.get(head) == self:
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
102 locals[head] = mod
3896
3b628b5da9e9 use parent.__setattr__ instead of __dict__
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3877
diff changeset
103 object.__setattr__(self, "_module", mod)
4631
e3afa670e484 demandimport: fix issue579 and add a test
Matt Mackall <mpm@selenic.com>
parents: 4626
diff changeset
104
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
105 def __repr__(self):
4631
e3afa670e484 demandimport: fix issue579 and add a test
Matt Mackall <mpm@selenic.com>
parents: 4626
diff changeset
106 if self._module:
e3afa670e484 demandimport: fix issue579 and add a test
Matt Mackall <mpm@selenic.com>
parents: 4626
diff changeset
107 return "<proxied module '%s'>" % self._data[0]
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
108 return "<unloaded module '%s'>" % self._data[0]
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
109 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
110 raise TypeError("%s object is not callable" % repr(self))
3903
f9136599700f Make demandimport pass all tests on python2.5.
Brendan Cully <brendan@kublai.com>
parents: 3898
diff changeset
111 def __getattribute__(self, attr):
f9136599700f Make demandimport pass all tests on python2.5.
Brendan Cully <brendan@kublai.com>
parents: 3898
diff changeset
112 if attr in ('_data', '_extend', '_load', '_module'):
f9136599700f Make demandimport pass all tests on python2.5.
Brendan Cully <brendan@kublai.com>
parents: 3898
diff changeset
113 return object.__getattribute__(self, attr)
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
114 self._load()
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
115 return getattr(self._module, attr)
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
116 def __setattr__(self, attr, val):
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
117 self._load()
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
118 setattr(self._module, attr, val)
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
119
21290
74be3fb1e3b8 demandimport: pass proper level to __import__ in Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21025
diff changeset
120 def _demandimport(name, globals=None, locals=None, fromlist=None, level=level):
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
121 if not locals or name in ignore or fromlist == ('*',):
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
122 # these cases we can't really delay
19933
621a26eb3a99 demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19932
diff changeset
123 return _hgextimport(_import, name, globals, locals, fromlist, level)
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
124 elif not fromlist:
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
125 # import a [as b]
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
126 if '.' in name: # a.b
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
127 base, rest = name.split('.', 1)
3903
f9136599700f Make demandimport pass all tests on python2.5.
Brendan Cully <brendan@kublai.com>
parents: 3898
diff changeset
128 # email.__init__ loading email.mime
f9136599700f Make demandimport pass all tests on python2.5.
Brendan Cully <brendan@kublai.com>
parents: 3898
diff changeset
129 if globals and globals.get('__name__', None) == base:
15096
868282fa29d8 demandimport: determine at load time if __import__ has level argument
Simon Heimberg <simohe@besonet.ch>
parents: 14977
diff changeset
130 return _import(name, globals, locals, fromlist, level)
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
131 # 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
132 if base in locals:
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
133 if isinstance(locals[base], _demandmod):
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
134 locals[base]._extend(rest)
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
135 return locals[base]
19932
e3a5922e18c3 demandimport: support "absolute_import" for external libraries (issue4029)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 15096
diff changeset
136 return _demandmod(name, globals, locals, level)
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
137 else:
13082
4db5bfea1b07 demandimport: change default for level from None to -1
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 12964
diff changeset
138 if level != -1:
12894
bc91a79fa3d0 demandimport: back out 50a4e55aa278 (issue2467)
Matt Mackall <mpm@selenic.com>
parents: 12801
diff changeset
139 # from . import b,c,d or from .a import b,c,d
bc91a79fa3d0 demandimport: back out 50a4e55aa278 (issue2467)
Matt Mackall <mpm@selenic.com>
parents: 12801
diff changeset
140 return _origimport(name, globals, locals, fromlist, level)
bc91a79fa3d0 demandimport: back out 50a4e55aa278 (issue2467)
Matt Mackall <mpm@selenic.com>
parents: 12801
diff changeset
141 # from a import b,c,d
19933
621a26eb3a99 demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19932
diff changeset
142 mod = _hgextimport(_origimport, name, globals, locals)
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
143 # recurse down the module chain
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
144 for comp in name.split('.')[1:]:
14977
1dbd42a02153 demandimport: use getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14976
diff changeset
145 if getattr(mod, comp, nothing) is nothing:
12894
bc91a79fa3d0 demandimport: back out 50a4e55aa278 (issue2467)
Matt Mackall <mpm@selenic.com>
parents: 12801
diff changeset
146 setattr(mod, comp, _demandmod(comp, mod.__dict__, mod.__dict__))
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
147 mod = getattr(mod, comp)
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
148 for x in fromlist:
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
149 # set requested submodules for demand load
14977
1dbd42a02153 demandimport: use getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14976
diff changeset
150 if getattr(mod, x, nothing) is nothing:
12894
bc91a79fa3d0 demandimport: back out 50a4e55aa278 (issue2467)
Matt Mackall <mpm@selenic.com>
parents: 12801
diff changeset
151 setattr(mod, x, _demandmod(x, mod.__dict__, locals))
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
152 return mod
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
153
5098
0bbd86b847dd demandimport: ignore resource module, not available under Windows.
Patrick Mezard <pmezard@gmail.com>
parents: 5097
diff changeset
154 ignore = [
0bbd86b847dd demandimport: ignore resource module, not available under Windows.
Patrick Mezard <pmezard@gmail.com>
parents: 5097
diff changeset
155 '_hashlib',
0bbd86b847dd demandimport: ignore resource module, not available under Windows.
Patrick Mezard <pmezard@gmail.com>
parents: 5097
diff changeset
156 '_xmlplus',
0bbd86b847dd demandimport: ignore resource module, not available under Windows.
Patrick Mezard <pmezard@gmail.com>
parents: 5097
diff changeset
157 'fcntl',
0bbd86b847dd demandimport: ignore resource module, not available under Windows.
Patrick Mezard <pmezard@gmail.com>
parents: 5097
diff changeset
158 'win32com.gen_py',
10242
ecd0a5c8bbe5 demandimport: ignore _winreg (used in python-2.7 mimetypes)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9458
diff changeset
159 '_winreg', # 2.7 mimetypes needs immediate ImportError
7861
2bc14da14992 demandimport: blacklist pythoncom
Steve Borho <steve@borho.org>
parents: 7727
diff changeset
160 'pythoncom',
5098
0bbd86b847dd demandimport: ignore resource module, not available under Windows.
Patrick Mezard <pmezard@gmail.com>
parents: 5097
diff changeset
161 # imported by tarfile, not available under Windows
0bbd86b847dd demandimport: ignore resource module, not available under Windows.
Patrick Mezard <pmezard@gmail.com>
parents: 5097
diff changeset
162 'pwd',
0bbd86b847dd demandimport: ignore resource module, not available under Windows.
Patrick Mezard <pmezard@gmail.com>
parents: 5097
diff changeset
163 'grp',
0bbd86b847dd demandimport: ignore resource module, not available under Windows.
Patrick Mezard <pmezard@gmail.com>
parents: 5097
diff changeset
164 # imported by profile, itself imported by hotshot.stats,
0bbd86b847dd demandimport: ignore resource module, not available under Windows.
Patrick Mezard <pmezard@gmail.com>
parents: 5097
diff changeset
165 # not available under Windows
0bbd86b847dd demandimport: ignore resource module, not available under Windows.
Patrick Mezard <pmezard@gmail.com>
parents: 5097
diff changeset
166 'resource',
9458
ffeaf5ba25d8 demandimport: blacklist gtk
Steve Borho <steve@borho.org>
parents: 9315
diff changeset
167 # this trips up many extension authors
ffeaf5ba25d8 demandimport: blacklist gtk
Steve Borho <steve@borho.org>
parents: 9315
diff changeset
168 'gtk',
10598
1037bd445768 demandimport: add __main__ to the blacklist (because of setuptools)
Greg Ward <greg-hg@gerg.ca>
parents: 10263
diff changeset
169 # setuptools' pkg_resources.py expects "from __main__ import x" to
1037bd445768 demandimport: add __main__ to the blacklist (because of setuptools)
Greg Ward <greg-hg@gerg.ca>
parents: 10263
diff changeset
170 # raise ImportError if x not defined
1037bd445768 demandimport: add __main__ to the blacklist (because of setuptools)
Greg Ward <greg-hg@gerg.ca>
parents: 10263
diff changeset
171 '__main__',
10612
30553ac3e355 demandimport: blacklist _ssl (issue1964)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10598
diff changeset
172 '_ssl', # conditional imports in the stdlib, issue1964
14976
04a950b1c2ad demandimport: blacklist rfc822 and mimetools to prevent spurious warnings
Augie Fackler <durin42@gmail.com>
parents: 13082
diff changeset
173 'rfc822',
04a950b1c2ad demandimport: blacklist rfc822 and mimetools to prevent spurious warnings
Augie Fackler <durin42@gmail.com>
parents: 13082
diff changeset
174 'mimetools',
23643
2205d00b6d2b demandimport: blacklist distutils.msvc9compiler (issue4475)
Augie Fackler <raf@durin42.com>
parents: 21290
diff changeset
175 # setuptools 8 expects this module to explode early when not on windows
2205d00b6d2b demandimport: blacklist distutils.msvc9compiler (issue4475)
Augie Fackler <raf@durin42.com>
parents: 21290
diff changeset
176 'distutils.msvc9compiler'
5098
0bbd86b847dd demandimport: ignore resource module, not available under Windows.
Patrick Mezard <pmezard@gmail.com>
parents: 5097
diff changeset
177 ]
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
178
20422
aac87f70f38e hooks: only disable/re-enable demandimport when it's already enabled
Brodie Rao <brodie@sf.io>
parents: 19933
diff changeset
179 def isenabled():
25673
fa1f04529775 demandimport: alias __builtin__ as builtins
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25327
diff changeset
180 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
181
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
182 def enable():
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
183 "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
184 if os.environ.get('HGDEMANDIMPORT') != 'disable':
25673
fa1f04529775 demandimport: alias __builtin__ as builtins
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25327
diff changeset
185 builtins.__import__ = _demandimport
3877
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
186
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
187 def disable():
abaee83ce0a6 Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
188 "disable global demand-loading of modules"
25673
fa1f04529775 demandimport: alias __builtin__ as builtins
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25327
diff changeset
189 builtins.__import__ = _origimport
25327
2e7804110b14 demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 23643
diff changeset
190
2e7804110b14 demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 23643
diff changeset
191 @contextmanager
2e7804110b14 demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 23643
diff changeset
192 def deactivated():
2e7804110b14 demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 23643
diff changeset
193 "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
194 demandenabled = isenabled()
2e7804110b14 demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 23643
diff changeset
195 if demandenabled:
2e7804110b14 demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 23643
diff changeset
196 disable()
2e7804110b14 demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 23643
diff changeset
197
2e7804110b14 demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 23643
diff changeset
198 try:
2e7804110b14 demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 23643
diff changeset
199 yield
2e7804110b14 demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 23643
diff changeset
200 finally:
2e7804110b14 demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 23643
diff changeset
201 if demandenabled:
2e7804110b14 demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents: 23643
diff changeset
202 enable()