Mercurial > hg
annotate mercurial/demandimport.py @ 30317:3fd53cc1aad8
profiling: make statprof the default profiler (BC)
The statprof sampling profiler runs with significantly less overhead.
Its data is therefore more useful. Furthermore, its default output
shows the hotpath by default, which I've found to be way more useful
than the default profiler's function time table.
There is one behavioral regression with this change worth noting:
the statprof profiler currently doesn't profile individual hgweb
requests like lsprof does. This is because the current implementation
of statprof only profiles the thread that started profiling.
The ability for lsprof to profile individual hgweb requests is
relatively new and likely not widely used. Furthermore, I have plans
to modify statprof to support profiling multiple threads. I expect
that change to go through several iterations. I'm submitting this
patch first so there is more time to test statprof. Perfect is the
enemy of good.
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Fri, 04 Nov 2016 21:44:25 -0700 |
parents | 75c71c533977 |
children | 1914db1b7d9e |
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 |
3beed01daff9
demandimport: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25937
diff
changeset
|
29 import contextlib |
3beed01daff9
demandimport: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25937
diff
changeset
|
30 import os |
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 |
5d0847cd1587
demandimport: support importing builtins for Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25673
diff
changeset
|
33 # __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
|
34 try: |
5d0847cd1587
demandimport: support importing builtins for Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25673
diff
changeset
|
35 import __builtin__ as builtins |
5d0847cd1587
demandimport: support importing builtins for Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25673
diff
changeset
|
36 except ImportError: |
5d0847cd1587
demandimport: support importing builtins for Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25673
diff
changeset
|
37 import builtins |
25327
2e7804110b14
demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
23643
diff
changeset
|
38 |
25943
3beed01daff9
demandimport: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25937
diff
changeset
|
39 contextmanager = contextlib.contextmanager |
3beed01daff9
demandimport: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25937
diff
changeset
|
40 |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
41 _origimport = __import__ |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
42 |
14977
1dbd42a02153
demandimport: use getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents:
14976
diff
changeset
|
43 nothing = object() |
1dbd42a02153
demandimport: use getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents:
14976
diff
changeset
|
44 |
25933
1fc6c02782ab
demandimport: remove support for Python < 2.5
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25674
diff
changeset
|
45 # Python 3 doesn't have relative imports nor level -1. |
1fc6c02782ab
demandimport: remove support for Python < 2.5
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25674
diff
changeset
|
46 level = -1 |
1fc6c02782ab
demandimport: remove support for Python < 2.5
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25674
diff
changeset
|
47 if sys.version_info[0] >= 3: |
1fc6c02782ab
demandimport: remove support for Python < 2.5
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25674
diff
changeset
|
48 level = 0 |
1fc6c02782ab
demandimport: remove support for Python < 2.5
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25674
diff
changeset
|
49 _import = _origimport |
15096
868282fa29d8
demandimport: determine at load time if __import__ has level argument
Simon Heimberg <simohe@besonet.ch>
parents:
14977
diff
changeset
|
50 |
25936
f90bb2002bcf
demandimport: support keyword arguments on _hgextimport
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25935
diff
changeset
|
51 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
|
52 try: |
25936
f90bb2002bcf
demandimport: support keyword arguments on _hgextimport
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25935
diff
changeset
|
53 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
|
54 except ImportError: |
621a26eb3a99
demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
19932
diff
changeset
|
55 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
|
56 raise |
621a26eb3a99
demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
19932
diff
changeset
|
57 # 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
|
58 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
|
59 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
|
60 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
|
61 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
|
62 raise |
621a26eb3a99
demandimport: allow extensions to import own modules by absolute name
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
19932
diff
changeset
|
63 # retry to import with "hgext_" prefix |
25936
f90bb2002bcf
demandimport: support keyword arguments on _hgextimport
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25935
diff
changeset
|
64 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
|
65 |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
66 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
|
67 """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
|
68 |
ae9a4d6a8d51
demandimport: omit default value of "level" at construction of _demandmod
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29736
diff
changeset
|
69 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
|
70 relatively. |
ae9a4d6a8d51
demandimport: omit default value of "level" at construction of _demandmod
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29736
diff
changeset
|
71 """ |
ae9a4d6a8d51
demandimport: omit default value of "level" at construction of _demandmod
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29736
diff
changeset
|
72 def __init__(self, name, globals, locals, level): |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
73 if '.' in name: |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
74 head, rest = name.split('.', 1) |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
75 after = [rest] |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
76 else: |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
77 head = name |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
78 after = [] |
19932
e3a5922e18c3
demandimport: support "absolute_import" for external libraries (issue4029)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15096
diff
changeset
|
79 object.__setattr__(self, "_data", |
26457
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
80 (head, globals, locals, after, level, set())) |
3896
3b628b5da9e9
use parent.__setattr__ instead of __dict__
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3877
diff
changeset
|
81 object.__setattr__(self, "_module", None) |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
82 def _extend(self, name): |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
83 """add to the list of submodules to load""" |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
84 self._data[3].append(name) |
26457
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 def _addref(self, name): |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
87 """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
|
88 |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
89 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
|
90 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
|
91 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
|
92 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
|
93 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
|
94 """ |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
95 self._data[5].add(name) |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
96 |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
97 def _load(self): |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
98 if not self._module: |
26457
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
99 head, globals, locals, after, level, modrefs = 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
|
100 mod = _hgextimport(_import, 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
|
101 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
|
102 # 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
|
103 # _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
|
104 # 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
|
105 # 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
|
106 # |
8960fcb76ca4
demandimport: avoid infinite recursion at actual module importing (issue5304)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29375
diff
changeset
|
107 # 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
|
108 # 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
|
109 # 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
|
110 # 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
|
111 # 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
|
112 # 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
|
113 # 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
|
114 mod = self._module |
8960fcb76ca4
demandimport: avoid infinite recursion at actual module importing (issue5304)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29375
diff
changeset
|
115 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
|
116 return |
8960fcb76ca4
demandimport: avoid infinite recursion at actual module importing (issue5304)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29375
diff
changeset
|
117 |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
118 # 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
|
119 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
|
120 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
|
121 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
|
122 h, t = p.split('.', 1) |
14977
1dbd42a02153
demandimport: use getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents:
14976
diff
changeset
|
123 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
|
124 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
|
125 level=1)) |
3926
de6ae8f016af
demandimport: handle already-loaded nested modules in subload
Brendan Cully <brendan@kublai.com>
parents:
3921
diff
changeset
|
126 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
|
127 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
|
128 |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
129 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
|
130 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
|
131 |
26457
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
132 # Replace references to this proxy instance with the actual module. |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
133 if locals and locals.get(head) == self: |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
134 locals[head] = mod |
26457
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
135 |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
136 for modname in modrefs: |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
137 modref = sys.modules.get(modname, None) |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
138 if modref and getattr(modref, head, None) == self: |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
139 setattr(modref, head, mod) |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
140 |
3896
3b628b5da9e9
use parent.__setattr__ instead of __dict__
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
3877
diff
changeset
|
141 object.__setattr__(self, "_module", mod) |
4631
e3afa670e484
demandimport: fix issue579 and add a test
Matt Mackall <mpm@selenic.com>
parents:
4626
diff
changeset
|
142 |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
143 def __repr__(self): |
4631
e3afa670e484
demandimport: fix issue579 and add a test
Matt Mackall <mpm@selenic.com>
parents:
4626
diff
changeset
|
144 if self._module: |
e3afa670e484
demandimport: fix issue579 and add a test
Matt Mackall <mpm@selenic.com>
parents:
4626
diff
changeset
|
145 return "<proxied module '%s'>" % self._data[0] |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
146 return "<unloaded module '%s'>" % self._data[0] |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
147 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
|
148 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
|
149 def __getattribute__(self, attr): |
26457
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
150 if attr in ('_data', '_extend', '_load', '_module', '_addref'): |
3903
f9136599700f
Make demandimport pass all tests on python2.5.
Brendan Cully <brendan@kublai.com>
parents:
3898
diff
changeset
|
151 return object.__getattribute__(self, attr) |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
152 self._load() |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
153 return getattr(self._module, attr) |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
154 def __setattr__(self, attr, val): |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
155 self._load() |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
156 setattr(self._module, attr, val) |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
157 |
27536
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
158 _pypy = '__pypy__' in sys.builtin_module_names |
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
159 |
21290
74be3fb1e3b8
demandimport: pass proper level to __import__ in Python 3
Gregory Szorc <gregory.szorc@gmail.com>
parents:
21025
diff
changeset
|
160 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
|
161 if not locals or name in ignore or fromlist == ('*',): |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
162 # 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
|
163 return _hgextimport(_import, name, globals, locals, fromlist, level) |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
164 elif not fromlist: |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
165 # import a [as b] |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
166 if '.' in name: # a.b |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
167 base, rest = name.split('.', 1) |
3903
f9136599700f
Make demandimport pass all tests on python2.5.
Brendan Cully <brendan@kublai.com>
parents:
3898
diff
changeset
|
168 # email.__init__ loading email.mime |
f9136599700f
Make demandimport pass all tests on python2.5.
Brendan Cully <brendan@kublai.com>
parents:
3898
diff
changeset
|
169 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
|
170 return _import(name, globals, locals, fromlist, level) |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
171 # 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
|
172 if base in locals: |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
173 if isinstance(locals[base], _demandmod): |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
174 locals[base]._extend(rest) |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
175 return locals[base] |
19932
e3a5922e18c3
demandimport: support "absolute_import" for external libraries (issue4029)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
15096
diff
changeset
|
176 return _demandmod(name, globals, locals, level) |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
177 else: |
25935
49dd4fd3f283
demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25934
diff
changeset
|
178 # There is a fromlist. |
49dd4fd3f283
demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25934
diff
changeset
|
179 # from a import b,c,d |
49dd4fd3f283
demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25934
diff
changeset
|
180 # from . import b,c,d |
49dd4fd3f283
demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25934
diff
changeset
|
181 # from .a import b,c,d |
49dd4fd3f283
demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25934
diff
changeset
|
182 |
49dd4fd3f283
demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25934
diff
changeset
|
183 # 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
|
184 # 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
|
185 # 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
|
186 # 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
|
187 |
26457
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
188 # 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
|
189 globalname = globals.get('__name__') |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
190 |
26873
78d05778907b
demandimport: fix level passed to loader of sub-modules
Yuya Nishihara <yuya@tcha.org>
parents:
26830
diff
changeset
|
191 def processfromitem(mod, attr): |
26455
f2bf76d3d567
demandimport: consolidate code for processing items in fromlist
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25943
diff
changeset
|
192 """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
|
193 |
30022
26a4e46af2bc
demandimport: error out early on missing attribute of non package (issue5373)
Yuya Nishihara <yuya@tcha.org>
parents:
30021
diff
changeset
|
194 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
|
195 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
|
196 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
|
197 """ |
26456
86fc4a2863ff
demandimport: refactor processfromitem
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26455
diff
changeset
|
198 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
|
199 nonpkg = getattr(mod, '__path__', nothing) is nothing |
26456
86fc4a2863ff
demandimport: refactor processfromitem
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26455
diff
changeset
|
200 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
|
201 if nonpkg: |
26a4e46af2bc
demandimport: error out early on missing attribute of non package (issue5373)
Yuya Nishihara <yuya@tcha.org>
parents:
30021
diff
changeset
|
202 # do not try relative import, which would raise ValueError |
26a4e46af2bc
demandimport: error out early on missing attribute of non package (issue5373)
Yuya Nishihara <yuya@tcha.org>
parents:
30021
diff
changeset
|
203 raise ImportError('cannot import name %s' % attr) |
28175
c25e3fd38ff1
demandimport: enforce ignore list while processing modules in fromlist
Yuya Nishihara <yuya@tcha.org>
parents:
27537
diff
changeset
|
204 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
|
205 if mn in ignore: |
c25e3fd38ff1
demandimport: enforce ignore list while processing modules in fromlist
Yuya Nishihara <yuya@tcha.org>
parents:
27537
diff
changeset
|
206 importfunc = _origimport |
c25e3fd38ff1
demandimport: enforce ignore list while processing modules in fromlist
Yuya Nishihara <yuya@tcha.org>
parents:
27537
diff
changeset
|
207 else: |
c25e3fd38ff1
demandimport: enforce ignore list while processing modules in fromlist
Yuya Nishihara <yuya@tcha.org>
parents:
27537
diff
changeset
|
208 importfunc = _demandmod |
c25e3fd38ff1
demandimport: enforce ignore list while processing modules in fromlist
Yuya Nishihara <yuya@tcha.org>
parents:
27537
diff
changeset
|
209 symbol = importfunc(attr, mod.__dict__, locals, level=1) |
26456
86fc4a2863ff
demandimport: refactor processfromitem
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26455
diff
changeset
|
210 setattr(mod, attr, symbol) |
26455
f2bf76d3d567
demandimport: consolidate code for processing items in fromlist
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25943
diff
changeset
|
211 |
26457
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
212 # 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
|
213 # 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
|
214 # time. |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
215 if globalname and isinstance(symbol, _demandmod): |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
216 symbol._addref(globalname) |
7e81305092a0
demandimport: replace more references to _demandmod instances
Gregory Szorc <gregory.szorc@gmail.com>
parents:
26456
diff
changeset
|
217 |
29375
fcaf20175b1b
demandimport: delay loading for "from a import b" with absolute_import
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
28286
diff
changeset
|
218 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
|
219 # 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
|
220 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
|
221 for comp in modname.split('.')[1:]: |
fcaf20175b1b
demandimport: delay loading for "from a import b" with absolute_import
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
28286
diff
changeset
|
222 if getattr(mod, comp, nothing) is nothing: |
29736
14f077f7519a
demandimport: import sub-module relatively as expected (issue5208)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29642
diff
changeset
|
223 setattr(mod, comp, _demandmod(comp, mod.__dict__, |
14f077f7519a
demandimport: import sub-module relatively as expected (issue5208)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
29642
diff
changeset
|
224 mod.__dict__, level=1)) |
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 mod = getattr(mod, comp) |
fcaf20175b1b
demandimport: delay loading for "from a import b" with absolute_import
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents:
28286
diff
changeset
|
226 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
|
227 |
25935
49dd4fd3f283
demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25934
diff
changeset
|
228 if level >= 0: |
25937
4f1144c3c72b
demandimport: support lazy loading for absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25936
diff
changeset
|
229 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
|
230 # "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
|
231 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
|
232 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
|
233 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
|
234 elif _pypy: |
27536
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
235 # PyPy's __import__ throws an exception if invoked |
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
236 # 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
|
237 # desired behaviour by hand. |
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
238 mn = globalname |
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
239 mod = sys.modules[mn] |
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
240 if getattr(mod, '__path__', nothing) is nothing: |
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
241 mn = mn.rsplit('.', 1)[0] |
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
242 mod = sys.modules[mn] |
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
243 if level > 1: |
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
244 mn = mn.rsplit('.', level - 1)[0] |
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
245 mod = sys.modules[mn] |
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
246 else: |
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
247 mod = _hgextimport(_origimport, name, globals, locals, |
f7d890bc5e01
demandimport: add support for PyPy
Bryan O'Sullivan <bos@serpentine.com>
parents:
27069
diff
changeset
|
248 level=level) |
26455
f2bf76d3d567
demandimport: consolidate code for processing items in fromlist
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25943
diff
changeset
|
249 |
25937
4f1144c3c72b
demandimport: support lazy loading for absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25936
diff
changeset
|
250 for x in fromlist: |
26873
78d05778907b
demandimport: fix level passed to loader of sub-modules
Yuya Nishihara <yuya@tcha.org>
parents:
26830
diff
changeset
|
251 processfromitem(mod, x) |
25937
4f1144c3c72b
demandimport: support lazy loading for absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25936
diff
changeset
|
252 |
4f1144c3c72b
demandimport: support lazy loading for absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25936
diff
changeset
|
253 return mod |
25935
49dd4fd3f283
demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25934
diff
changeset
|
254 |
49dd4fd3f283
demandimport: refactor logic and add documentation
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25934
diff
changeset
|
255 # 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
|
256 # 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
|
257 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
|
258 mod = chainmodules(mod, name) |
26455
f2bf76d3d567
demandimport: consolidate code for processing items in fromlist
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25943
diff
changeset
|
259 |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
260 for x in fromlist: |
26455
f2bf76d3d567
demandimport: consolidate code for processing items in fromlist
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25943
diff
changeset
|
261 processfromitem(mod, x) |
f2bf76d3d567
demandimport: consolidate code for processing items in fromlist
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25943
diff
changeset
|
262 |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
263 return mod |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
264 |
5098
0bbd86b847dd
demandimport: ignore resource module, not available under Windows.
Patrick Mezard <pmezard@gmail.com>
parents:
5097
diff
changeset
|
265 ignore = [ |
25934
e283c5d922db
demandimport: add __future__ to ignore list
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25933
diff
changeset
|
266 '__future__', |
5098
0bbd86b847dd
demandimport: ignore resource module, not available under Windows.
Patrick Mezard <pmezard@gmail.com>
parents:
5097
diff
changeset
|
267 '_hashlib', |
28252
f5b2b358b8b7
demandimport: add _imp to ignore list
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27537
diff
changeset
|
268 # ImportError during pkg_resources/__init__.py:fixup_namespace_package |
f5b2b358b8b7
demandimport: add _imp to ignore list
Gregory Szorc <gregory.szorc@gmail.com>
parents:
27537
diff
changeset
|
269 '_imp', |
5098
0bbd86b847dd
demandimport: ignore resource module, not available under Windows.
Patrick Mezard <pmezard@gmail.com>
parents:
5097
diff
changeset
|
270 '_xmlplus', |
0bbd86b847dd
demandimport: ignore resource module, not available under Windows.
Patrick Mezard <pmezard@gmail.com>
parents:
5097
diff
changeset
|
271 'fcntl', |
30021
16a09ae318b4
demandimport: add 'nt' to ignore list (issue5373)
Yuya Nishihara <yuya@tcha.org>
parents:
30020
diff
changeset
|
272 'nt', # pathlib2 tests the existence of built-in 'nt' module |
5098
0bbd86b847dd
demandimport: ignore resource module, not available under Windows.
Patrick Mezard <pmezard@gmail.com>
parents:
5097
diff
changeset
|
273 'win32com.gen_py', |
10242
ecd0a5c8bbe5
demandimport: ignore _winreg (used in python-2.7 mimetypes)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
9458
diff
changeset
|
274 '_winreg', # 2.7 mimetypes needs immediate ImportError |
7861
2bc14da14992
demandimport: blacklist pythoncom
Steve Borho <steve@borho.org>
parents:
7727
diff
changeset
|
275 'pythoncom', |
5098
0bbd86b847dd
demandimport: ignore resource module, not available under Windows.
Patrick Mezard <pmezard@gmail.com>
parents:
5097
diff
changeset
|
276 # 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
|
277 'pwd', |
0bbd86b847dd
demandimport: ignore resource module, not available under Windows.
Patrick Mezard <pmezard@gmail.com>
parents:
5097
diff
changeset
|
278 'grp', |
0bbd86b847dd
demandimport: ignore resource module, not available under Windows.
Patrick Mezard <pmezard@gmail.com>
parents:
5097
diff
changeset
|
279 # 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
|
280 # not available under Windows |
0bbd86b847dd
demandimport: ignore resource module, not available under Windows.
Patrick Mezard <pmezard@gmail.com>
parents:
5097
diff
changeset
|
281 'resource', |
9458 | 282 # this trips up many extension authors |
283 'gtk', | |
10598
1037bd445768
demandimport: add __main__ to the blacklist (because of setuptools)
Greg Ward <greg-hg@gerg.ca>
parents:
10263
diff
changeset
|
284 # 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
|
285 # 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
|
286 '__main__', |
10612
30553ac3e355
demandimport: blacklist _ssl (issue1964)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
10598
diff
changeset
|
287 '_ssl', # conditional imports in the stdlib, issue1964 |
26830
65387a30430e
demandimport: fix TypeError when importing Python regex library (issue4920)
Gábor Stefanik <gabor.stefanik@nng.com>
parents:
26457
diff
changeset
|
288 '_sre', # issue4920 |
14976
04a950b1c2ad
demandimport: blacklist rfc822 and mimetools to prevent spurious warnings
Augie Fackler <durin42@gmail.com>
parents:
13082
diff
changeset
|
289 'rfc822', |
04a950b1c2ad
demandimport: blacklist rfc822 and mimetools to prevent spurious warnings
Augie Fackler <durin42@gmail.com>
parents:
13082
diff
changeset
|
290 'mimetools', |
28176
9ff7261cc0f5
demandimport: blacklist sqlalchemy.events as it has side effects (issue5085)
Yuya Nishihara <yuya@tcha.org>
parents:
28175
diff
changeset
|
291 'sqlalchemy.events', # has import-time side effects (issue5085) |
23643
2205d00b6d2b
demandimport: blacklist distutils.msvc9compiler (issue4475)
Augie Fackler <raf@durin42.com>
parents:
21290
diff
changeset
|
292 # setuptools 8 expects this module to explode early when not on windows |
29980
11b3a59e7435
demandimport: add trailing comma
timeless <timeless@mozdev.org>
parents:
29737
diff
changeset
|
293 'distutils.msvc9compiler', |
30156
75c71c533977
demandimport: disable lazy import of __builtin__
Mads Kiilerich <madski@unity3d.com>
parents:
30022
diff
changeset
|
294 '__builtin__', |
75c71c533977
demandimport: disable lazy import of __builtin__
Mads Kiilerich <madski@unity3d.com>
parents:
30022
diff
changeset
|
295 'builtins', |
5098
0bbd86b847dd
demandimport: ignore resource module, not available under Windows.
Patrick Mezard <pmezard@gmail.com>
parents:
5097
diff
changeset
|
296 ] |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
297 |
30020
bf94fe556f16
demandimport: add '_ctypes.pointer' to ignore list on PyPy
Yuya Nishihara <yuya@tcha.org>
parents:
29980
diff
changeset
|
298 if _pypy: |
bf94fe556f16
demandimport: add '_ctypes.pointer' to ignore list on PyPy
Yuya Nishihara <yuya@tcha.org>
parents:
29980
diff
changeset
|
299 ignore.extend([ |
bf94fe556f16
demandimport: add '_ctypes.pointer' to ignore list on PyPy
Yuya Nishihara <yuya@tcha.org>
parents:
29980
diff
changeset
|
300 # _ctypes.pointer is shadowed by "from ... import pointer" (PyPy 5) |
bf94fe556f16
demandimport: add '_ctypes.pointer' to ignore list on PyPy
Yuya Nishihara <yuya@tcha.org>
parents:
29980
diff
changeset
|
301 '_ctypes.pointer', |
bf94fe556f16
demandimport: add '_ctypes.pointer' to ignore list on PyPy
Yuya Nishihara <yuya@tcha.org>
parents:
29980
diff
changeset
|
302 ]) |
bf94fe556f16
demandimport: add '_ctypes.pointer' to ignore list on PyPy
Yuya Nishihara <yuya@tcha.org>
parents:
29980
diff
changeset
|
303 |
20422
aac87f70f38e
hooks: only disable/re-enable demandimport when it's already enabled
Brodie Rao <brodie@sf.io>
parents:
19933
diff
changeset
|
304 def isenabled(): |
25673
fa1f04529775
demandimport: alias __builtin__ as builtins
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25327
diff
changeset
|
305 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
|
306 |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
307 def enable(): |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
308 "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
|
309 if os.environ.get('HGDEMANDIMPORT') != 'disable': |
25673
fa1f04529775
demandimport: alias __builtin__ as builtins
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25327
diff
changeset
|
310 builtins.__import__ = _demandimport |
3877
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
311 |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
312 def disable(): |
abaee83ce0a6
Replace demandload with new demandimport
Matt Mackall <mpm@selenic.com>
parents:
diff
changeset
|
313 "disable global demand-loading of modules" |
25673
fa1f04529775
demandimport: alias __builtin__ as builtins
Gregory Szorc <gregory.szorc@gmail.com>
parents:
25327
diff
changeset
|
314 builtins.__import__ = _origimport |
25327
2e7804110b14
demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
23643
diff
changeset
|
315 |
2e7804110b14
demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
23643
diff
changeset
|
316 @contextmanager |
2e7804110b14
demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
23643
diff
changeset
|
317 def deactivated(): |
2e7804110b14
demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
23643
diff
changeset
|
318 "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
|
319 demandenabled = isenabled() |
2e7804110b14
demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
23643
diff
changeset
|
320 if demandenabled: |
2e7804110b14
demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
23643
diff
changeset
|
321 disable() |
2e7804110b14
demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
23643
diff
changeset
|
322 |
2e7804110b14
demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
23643
diff
changeset
|
323 try: |
2e7804110b14
demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
23643
diff
changeset
|
324 yield |
2e7804110b14
demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
23643
diff
changeset
|
325 finally: |
2e7804110b14
demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
23643
diff
changeset
|
326 if demandenabled: |
2e7804110b14
demandimport: define a `deactivated` context manager
Jordi Gutiérrez Hermoso <jordigh@octave.org>
parents:
23643
diff
changeset
|
327 enable() |