Mercurial > hg
annotate hgdemandimport/demandimportpy3.py @ 33349:28f75a1695fb
histedit: pass multiple nodes to strip (BC)
Previously, histedit.cleanupnode pass root nodes one by one. Since
repair.strip takes multiple nodes and can handle them just fine, pass all
strip roots at once.
This is BC because the number of strip backup files may change from N to 1.
author | Jun Wu <quark@fb.com> |
---|---|
date | Sat, 08 Jul 2017 16:50:31 -0700 |
parents | 859496bb6db3 |
children | 8fb5212652ec |
rev | line source |
---|---|
32423
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
1 # demandimportpy3 - global demand-loading of modules for Mercurial |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
2 # |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
3 # Copyright 2017 Facebook Inc. |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
4 # |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
5 # This software may be used and distributed according to the terms of the |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
6 # GNU General Public License version 2 or any later version. |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
7 |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
8 """Lazy loading for Python 3.6 and above. |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
9 |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
10 This uses the new importlib finder/loader functionality available in Python 3.5 |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
11 and up. The code reuses most of the mechanics implemented inside importlib.util, |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
12 but with a few additions: |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
13 |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
14 * Allow excluding certain modules from lazy imports. |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
15 * Expose an interface that's substantially the same as demandimport for |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
16 Python 2. |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
17 |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
18 This also has some limitations compared to the Python 2 implementation: |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
19 |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
20 * Much of the logic is per-package, not per-module, so any packages loaded |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
21 before demandimport is enabled will not be lazily imported in the future. In |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
22 practice, we only expect builtins to be loaded before demandimport is |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
23 enabled. |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
24 """ |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
25 |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
26 # This line is unnecessary, but it satisfies test-check-py3-compat.t. |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
27 from __future__ import absolute_import |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
28 |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
29 import contextlib |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
30 import os |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
31 import sys |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
32 |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
33 import importlib.abc |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
34 import importlib.machinery |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
35 import importlib.util |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
36 |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
37 _deactivated = False |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
38 |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
39 class _lazyloaderex(importlib.util.LazyLoader): |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
40 """This is a LazyLoader except it also follows the _deactivated global and |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
41 the ignore list. |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
42 """ |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
43 def exec_module(self, module): |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
44 """Make the module load lazily.""" |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
45 if _deactivated or module.__name__ in ignore: |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
46 self.loader.exec_module(module) |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
47 else: |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
48 super().exec_module(module) |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
49 |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
50 # This is 3.6+ because with Python 3.5 it isn't possible to lazily load |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
51 # extensions. See the discussion in https://python.org/sf/26186 for more. |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
52 _extensions_loader = _lazyloaderex.factory( |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
53 importlib.machinery.ExtensionFileLoader) |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
54 _bytecode_loader = _lazyloaderex.factory( |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
55 importlib.machinery.SourcelessFileLoader) |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
56 _source_loader = _lazyloaderex.factory(importlib.machinery.SourceFileLoader) |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
57 |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
58 def _makefinder(path): |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
59 return importlib.machinery.FileFinder( |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
60 path, |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
61 # This is the order in which loaders are passed in in core Python. |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
62 (_extensions_loader, importlib.machinery.EXTENSION_SUFFIXES), |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
63 (_source_loader, importlib.machinery.SOURCE_SUFFIXES), |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
64 (_bytecode_loader, importlib.machinery.BYTECODE_SUFFIXES), |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
65 ) |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
66 |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
67 ignore = [] |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
68 |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
69 def init(ignorelist): |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
70 global ignore |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
71 ignore = ignorelist |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
72 |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
73 def isenabled(): |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
74 return _makefinder in sys.path_hooks and not _deactivated |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
75 |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
76 def disable(): |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
77 try: |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
78 while True: |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
79 sys.path_hooks.remove(_makefinder) |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
80 except ValueError: |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
81 pass |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
82 |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
83 def enable(): |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
84 if os.environ.get('HGDEMANDIMPORT') != 'disable': |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
85 sys.path_hooks.insert(0, _makefinder) |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
86 |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
87 @contextlib.contextmanager |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
88 def deactivated(): |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
89 # This implementation is a bit different from Python 2's. Python 3 |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
90 # maintains a per-package finder cache in sys.path_importer_cache (see |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
91 # PEP 302). This means that we can't just call disable + enable. |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
92 # If we do that, in situations like: |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
93 # |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
94 # demandimport.enable() |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
95 # ... |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
96 # from foo.bar import mod1 |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
97 # with demandimport.deactivated(): |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
98 # from foo.bar import mod2 |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
99 # |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
100 # mod2 will be imported lazily. (The converse also holds -- whatever finder |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
101 # first gets cached will be used.) |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
102 # |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
103 # Instead, have a global flag the LazyLoader can use. |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
104 global _deactivated |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
105 demandenabled = isenabled() |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
106 if demandenabled: |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
107 _deactivated = True |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
108 try: |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
109 yield |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
110 finally: |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
111 if demandenabled: |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
112 _deactivated = False |