Mercurial > public > mercurial-scm > hg
annotate hgdemandimport/demandimportpy3.py @ 49778:48e38b179106 stable
demandimport: fix a crash in LazyFinder.__delattr__
I was tinkering with `with hgdemandimport.deactivated()` wrapped around loading
the keyring module, and got spew that seemed to be confirmed by PyCharm. But I
can't believe we haven't seen this before (and phabricator uses the same
pattern):
** Unknown exception encountered with possibly-broken third-party extension "mercurial_keyring" 1.4.3 (keyring 23.11.0, backend unknown)
** which supports versions unknown of Mercurial.
** Please disable "mercurial_keyring" and try your action again.
** If that fixes the bug please report it to https://foss.heptapod.net/mercurial/mercurial_keyring/issues
** Python 3.9.15 (main, Oct 13 2022, 04:28:25) [GCC 7.5.0]
** Mercurial Distributed SCM (version 6.3.1)
** Extensions loaded: absorb, attorc 20220315, blackbox, eol, extdiff, fastannotate, lfs, mercurial_keyring 1.4.3 (keyring 23.11.0, backend unknown), phabblocker 20220315, phabricator 20220315, purge, rebase, schemes, share, show, strip, uncommit
Traceback (most recent call last):
File "/usr/local/bin/hg", line 59, in <module>
dispatch.run()
File "/usr/local/lib/python3.9/site-packages/mercurial/dispatch.py", line 143, in run
status = dispatch(req)
File "/usr/local/lib/python3.9/site-packages/mercurial/dispatch.py", line 232, in dispatch
status = _rundispatch(req)
File "/usr/local/lib/python3.9/site-packages/mercurial/dispatch.py", line 276, in _rundispatch
ret = _runcatch(req) or 0
File "/usr/local/lib/python3.9/site-packages/mercurial/dispatch.py", line 451, in _runcatch
return _callcatch(ui, _runcatchfunc)
File "/usr/local/lib/python3.9/site-packages/mercurial/dispatch.py", line 461, in _callcatch
return scmutil.callcatch(ui, func)
File "/usr/local/lib/python3.9/site-packages/mercurial/scmutil.py", line 153, in callcatch
return func()
File "/usr/local/lib/python3.9/site-packages/mercurial/dispatch.py", line 441, in _runcatchfunc
return _dispatch(req)
File "/usr/local/lib/python3.9/site-packages/mercurial/dispatch.py", line 1265, in _dispatch
return runcommand(
File "/usr/local/lib/python3.9/site-packages/mercurial/dispatch.py", line 899, in runcommand
ret = _runcommand(ui, options, cmd, d)
File "/usr/local/lib/python3.9/site-packages/mercurial/dispatch.py", line 1277, in _runcommand
return cmdfunc()
File "/usr/local/lib/python3.9/site-packages/mercurial/dispatch.py", line 1263, in <lambda>
d = lambda: util.checksignature(func)(ui, *args, **strcmdopt)
File "/usr/local/lib/python3.9/site-packages/mercurial/util.py", line 1880, in check
return func(*args, **kwargs)
File "/root/mercurial_keyring/mercurial_keyring/mercurial_keyring.py", line 962, in cmd_keyring_check
user, pwd, source, final_url = handler.get_credentials(
File "/root/mercurial_keyring/mercurial_keyring/mercurial_keyring.py", line 497, in get_credentials
keyring_pwd = password_store.get_http_password(keyring_url, actual_user)
File "/root/mercurial_keyring/mercurial_keyring/mercurial_keyring.py", line 287, in get_http_password
return self._read_password_from_keyring(
File "/root/mercurial_keyring/mercurial_keyring/mercurial_keyring.py", line 335, in _read_password_from_keyring
keyring = import_keyring()
>> `with hgdemandimport.deactivated()` inserted here
File "/root/mercurial_keyring/mercurial_keyring/mercurial_keyring.py", line 120, in import_keyring
return _import_keyring()
File "/root/mercurial_keyring/mercurial_keyring/mercurial_keyring.py", line 133, in _import_keyring
mod, was_imported_now = meu.direct_import_ext(
File "/usr/lib/python3.9/site-packages/mercurial_extension_utils.py", line 1381, in direct_import_ext
__import__(module_name)
File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
File "/usr/local/lib/python3.9/site-packages/hgdemandimport/demandimportpy3.py", line 46, in exec_module
self.loader.exec_module(module)
File "/usr/lib/python3.9/site-packages/keyring/__init__.py", line 1, in <module>
from .core import (
File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
File "/usr/local/lib/python3.9/site-packages/hgdemandimport/demandimportpy3.py", line 46, in exec_module
self.loader.exec_module(module)
File "/usr/lib/python3.9/site-packages/keyring/core.py", line 11, in <module>
from . import backend, credentials
File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
File "/usr/local/lib/python3.9/site-packages/hgdemandimport/demandimportpy3.py", line 46, in exec_module
self.loader.exec_module(module)
File "/usr/lib/python3.9/site-packages/keyring/backend.py", line 13, in <module>
from .py312compat import metadata
File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
File "/usr/local/lib/python3.9/site-packages/hgdemandimport/demandimportpy3.py", line 46, in exec_module
self.loader.exec_module(module)
File "/usr/lib/python3.9/site-packages/keyring/py312compat.py", line 10, in <module>
import importlib_metadata as metadata # type: ignore
File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
File "/usr/local/lib/python3.9/site-packages/hgdemandimport/demandimportpy3.py", line 46, in exec_module
self.loader.exec_module(module)
File "/usr/lib/python3.9/site-packages/importlib_metadata/__init__.py", line 715, in <module>
class MetadataPathFinder(NullFinder, DistributionFinder):
File "/usr/lib/python3.9/site-packages/importlib_metadata/_compat.py", line 24, in install
disable_stdlib_finder()
File "/usr/lib/python3.9/site-packages/importlib_metadata/_compat.py", line 43, in disable_stdlib_finder
del finder.find_distributions
File "/usr/local/lib/python3.9/site-packages/hgdemandimport/demandimportpy3.py", line 88, in __delattr__
return delattr(object.__getattribute__(self, "_finder"))
TypeError: delattr expected 2 arguments, got 1
author | Matt Harbison <matt_harbison@yahoo.com> |
---|---|
date | Thu, 08 Dec 2022 21:45:47 -0500 |
parents | b8eb29ab3906 |
children | e0c0545e2e55 |
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 |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
28 import contextlib |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
29 import importlib.util |
33898
3595e4e0ae57
demandimportpy3: update to pass import checker
Augie Fackler <raf@durin42.com>
parents:
33859
diff
changeset
|
30 import sys |
32423
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
31 |
42474
adb636392b3f
demandimport: add tracing coverage for Python 3
Augie Fackler <augie@google.com>
parents:
37843
diff
changeset
|
32 from . import tracing |
adb636392b3f
demandimport: add tracing coverage for Python 3
Augie Fackler <augie@google.com>
parents:
37843
diff
changeset
|
33 |
32423
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
34 _deactivated = False |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
35 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42474
diff
changeset
|
36 |
32423
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
37 class _lazyloaderex(importlib.util.LazyLoader): |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
38 """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
|
39 the ignore list. |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
40 """ |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42474
diff
changeset
|
41 |
32423
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
42 def exec_module(self, module): |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
43 """Make the module load lazily.""" |
42474
adb636392b3f
demandimport: add tracing coverage for Python 3
Augie Fackler <augie@google.com>
parents:
37843
diff
changeset
|
44 with tracing.log('demandimport %s', module): |
adb636392b3f
demandimport: add tracing coverage for Python 3
Augie Fackler <augie@google.com>
parents:
37843
diff
changeset
|
45 if _deactivated or module.__name__ in ignores: |
adb636392b3f
demandimport: add tracing coverage for Python 3
Augie Fackler <augie@google.com>
parents:
37843
diff
changeset
|
46 self.loader.exec_module(module) |
adb636392b3f
demandimport: add tracing coverage for Python 3
Augie Fackler <augie@google.com>
parents:
37843
diff
changeset
|
47 else: |
adb636392b3f
demandimport: add tracing coverage for Python 3
Augie Fackler <augie@google.com>
parents:
37843
diff
changeset
|
48 super().exec_module(module) |
32423
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
49 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42474
diff
changeset
|
50 |
48946
642e31cb55f0
py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents:
48875
diff
changeset
|
51 class LazyFinder: |
44118
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
52 """A wrapper around a ``MetaPathFinder`` that makes loaders lazy. |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
53 |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
54 ``sys.meta_path`` finders have their ``find_spec()`` called to locate a |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
55 module. This returns a ``ModuleSpec`` if found or ``None``. The |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
56 ``ModuleSpec`` has a ``loader`` attribute, which is called to actually |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
57 load a module. |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
58 |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
59 Our class wraps an existing finder and overloads its ``find_spec()`` to |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
60 replace the ``loader`` with our lazy loader proxy. |
32423
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
61 |
44118
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
62 We have to use __getattribute__ to proxy the instance because some meta |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
63 path finders don't support monkeypatching. |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
64 """ |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
65 |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
66 __slots__ = ("_finder",) |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
67 |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
68 def __init__(self, finder): |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
69 object.__setattr__(self, "_finder", finder) |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
70 |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
71 def __repr__(self): |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
72 return "<LazyFinder for %r>" % object.__getattribute__(self, "_finder") |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
73 |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
74 # __bool__ is canonical Python 3. But check-code insists on __nonzero__ being |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
75 # defined via `def`. |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
76 def __nonzero__(self): |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
77 return bool(object.__getattribute__(self, "_finder")) |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42474
diff
changeset
|
78 |
44118
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
79 __bool__ = __nonzero__ |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
80 |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
81 def __getattribute__(self, name): |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
82 if name in ("_finder", "find_spec"): |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
83 return object.__getattribute__(self, name) |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
84 |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
85 return getattr(object.__getattribute__(self, "_finder"), name) |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
86 |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
87 def __delattr__(self, name): |
49778
48e38b179106
demandimport: fix a crash in LazyFinder.__delattr__
Matt Harbison <matt_harbison@yahoo.com>
parents:
48958
diff
changeset
|
88 return delattr(object.__getattribute__(self, "_finder"), name) |
44118
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
89 |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
90 def __setattr__(self, name, value): |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
91 return setattr(object.__getattribute__(self, "_finder"), name, value) |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
92 |
44819
a6e12d477595
demandimport: fix compatibility with meta path finders w/o find_spec() method
Manuel Jacob <me@manueljacob.de>
parents:
44118
diff
changeset
|
93 def find_spec(self, fullname, path, target=None): |
44118
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
94 finder = object.__getattribute__(self, "_finder") |
44819
a6e12d477595
demandimport: fix compatibility with meta path finders w/o find_spec() method
Manuel Jacob <me@manueljacob.de>
parents:
44118
diff
changeset
|
95 try: |
a6e12d477595
demandimport: fix compatibility with meta path finders w/o find_spec() method
Manuel Jacob <me@manueljacob.de>
parents:
44118
diff
changeset
|
96 find_spec = finder.find_spec |
a6e12d477595
demandimport: fix compatibility with meta path finders w/o find_spec() method
Manuel Jacob <me@manueljacob.de>
parents:
44118
diff
changeset
|
97 except AttributeError: |
a6e12d477595
demandimport: fix compatibility with meta path finders w/o find_spec() method
Manuel Jacob <me@manueljacob.de>
parents:
44118
diff
changeset
|
98 loader = finder.find_module(fullname, path) |
a6e12d477595
demandimport: fix compatibility with meta path finders w/o find_spec() method
Manuel Jacob <me@manueljacob.de>
parents:
44118
diff
changeset
|
99 if loader is None: |
a6e12d477595
demandimport: fix compatibility with meta path finders w/o find_spec() method
Manuel Jacob <me@manueljacob.de>
parents:
44118
diff
changeset
|
100 spec = None |
a6e12d477595
demandimport: fix compatibility with meta path finders w/o find_spec() method
Manuel Jacob <me@manueljacob.de>
parents:
44118
diff
changeset
|
101 else: |
a6e12d477595
demandimport: fix compatibility with meta path finders w/o find_spec() method
Manuel Jacob <me@manueljacob.de>
parents:
44118
diff
changeset
|
102 spec = importlib.util.spec_from_loader(fullname, loader) |
a6e12d477595
demandimport: fix compatibility with meta path finders w/o find_spec() method
Manuel Jacob <me@manueljacob.de>
parents:
44118
diff
changeset
|
103 else: |
a6e12d477595
demandimport: fix compatibility with meta path finders w/o find_spec() method
Manuel Jacob <me@manueljacob.de>
parents:
44118
diff
changeset
|
104 spec = find_spec(fullname, path, target) |
44118
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
105 |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
106 # Lazy loader requires exec_module(). |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
107 if ( |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
108 spec is not None |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
109 and spec.loader is not None |
45755
8ed69bd42f10
demandimport: don't raise AttributeError if `exec_module` is missing
Matt Harbison <matt_harbison@yahoo.com>
parents:
44819
diff
changeset
|
110 and getattr(spec.loader, "exec_module", None) |
44118
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
111 ): |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
112 spec.loader = _lazyloaderex(spec.loader) |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
113 |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
114 return spec |
32423
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
115 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42474
diff
changeset
|
116 |
37843
670eb4fa1b86
demandimport: make module ignores a set (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35524
diff
changeset
|
117 ignores = set() |
32423
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
118 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42474
diff
changeset
|
119 |
37843
670eb4fa1b86
demandimport: make module ignores a set (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35524
diff
changeset
|
120 def init(ignoreset): |
670eb4fa1b86
demandimport: make module ignores a set (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35524
diff
changeset
|
121 global ignores |
670eb4fa1b86
demandimport: make module ignores a set (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents:
35524
diff
changeset
|
122 ignores = ignoreset |
32423
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
123 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42474
diff
changeset
|
124 |
32423
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
125 def isenabled(): |
44118
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
126 return not _deactivated and any( |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
127 isinstance(finder, LazyFinder) for finder in sys.meta_path |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
128 ) |
32423
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
129 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42474
diff
changeset
|
130 |
32423
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
131 def disable(): |
44118
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
132 new_finders = [] |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
133 for finder in sys.meta_path: |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
134 new_finders.append( |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
135 finder._finder if isinstance(finder, LazyFinder) else finder |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
136 ) |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
137 sys.meta_path[:] = new_finders |
32423
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
138 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42474
diff
changeset
|
139 |
32423
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
140 def enable(): |
44118
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
141 new_finders = [] |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
142 for finder in sys.meta_path: |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
143 new_finders.append( |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
144 LazyFinder(finder) if not isinstance(finder, LazyFinder) else finder |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
145 ) |
f81c17ec303c
hgdemandimport: apply lazy module loading to sys.meta_path finders
Gregory Szorc <gregory.szorc@gmail.com>
parents:
44117
diff
changeset
|
146 sys.meta_path[:] = new_finders |
32423
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
147 |
43076
2372284d9457
formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents:
42474
diff
changeset
|
148 |
32423
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
149 @contextlib.contextmanager |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
150 def deactivated(): |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
151 # 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
|
152 # 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
|
153 # 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
|
154 # If we do that, in situations like: |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
155 # |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
156 # demandimport.enable() |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
157 # ... |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
158 # from foo.bar import mod1 |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
159 # with demandimport.deactivated(): |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
160 # from foo.bar import mod2 |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
161 # |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
162 # 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
|
163 # first gets cached will be used.) |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
164 # |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
165 # Instead, have a global flag the LazyLoader can use. |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
166 global _deactivated |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
167 demandenabled = isenabled() |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
168 if demandenabled: |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
169 _deactivated = True |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
170 try: |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
171 yield |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
172 finally: |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
173 if demandenabled: |
859496bb6db3
demandimport: add python 3 implementation
Siddharth Agarwal <sid0@fb.com>
parents:
diff
changeset
|
174 _deactivated = False |