Mercurial > cpython-lru_cache-weakref
annotate Lib/importlib/util.py @ 87690:66c1c9f32567 default tip
Add use_weakref option to functools.lru_cache
The use_weakref option makes lru_cache create weak references to the function
arguments when creating the cache key, which prevents them from staying in the
memory forever even after all other references to them are gone.
This is a proof of concept for http://bugs.python.org/issue19859
| author | Radomir Dopieralski <devel@sheep.art.pl> |
|---|---|
| date | Tue, 03 Dec 2013 16:02:48 +0100 |
| parents | 07229c6104b1 |
| children |
| rev | line source |
|---|---|
|
51681
147fcebacb5b
Implement the more specific PEP 302 semantics for loaders and what happens upon
Brett Cannon <bcannon@gmail.com>
parents:
diff
changeset
|
1 """Utility code for constructing importers, etc.""" |
| 60648 | 2 |
|
84128
5619bc2d8207
Issue #18192: Introduce importlib.util.MAGIC_NUMBER and document the
Brett Cannon <brett@python.org>
parents:
84002
diff
changeset
|
3 from ._bootstrap import MAGIC_NUMBER |
|
84134
9cacdb9d0c59
Issue #17907: touch up the code for imp.new_module().
Brett Cannon <brett@python.org>
parents:
84128
diff
changeset
|
4 from ._bootstrap import cache_from_source |
|
84173
bdd60bedf933
Issue #18076: Introduce imoportlib.util.decode_source().
Brett Cannon <brett@python.org>
parents:
84134
diff
changeset
|
5 from ._bootstrap import decode_source |
|
84134
9cacdb9d0c59
Issue #17907: touch up the code for imp.new_module().
Brett Cannon <brett@python.org>
parents:
84128
diff
changeset
|
6 from ._bootstrap import source_from_cache |
|
87347
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
7 from ._bootstrap import spec_from_loader |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
8 from ._bootstrap import spec_from_file_location |
|
76905
767503ba72e7
Add importlib.util.resolve_name().
Brett Cannon <brett@python.org>
parents:
60648
diff
changeset
|
9 from ._bootstrap import _resolve_name |
|
767503ba72e7
Add importlib.util.resolve_name().
Brett Cannon <brett@python.org>
parents:
60648
diff
changeset
|
10 |
|
87347
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
11 from contextlib import contextmanager |
|
84001
e873f2e67353
Issues #18088, 18089: Introduce
Brett Cannon <brett@python.org>
parents:
83988
diff
changeset
|
12 import functools |
|
87347
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
13 import sys |
|
84001
e873f2e67353
Issues #18088, 18089: Introduce
Brett Cannon <brett@python.org>
parents:
83988
diff
changeset
|
14 import warnings |
|
e873f2e67353
Issues #18088, 18089: Introduce
Brett Cannon <brett@python.org>
parents:
83988
diff
changeset
|
15 |
|
76905
767503ba72e7
Add importlib.util.resolve_name().
Brett Cannon <brett@python.org>
parents:
60648
diff
changeset
|
16 |
|
767503ba72e7
Add importlib.util.resolve_name().
Brett Cannon <brett@python.org>
parents:
60648
diff
changeset
|
17 def resolve_name(name, package): |
|
767503ba72e7
Add importlib.util.resolve_name().
Brett Cannon <brett@python.org>
parents:
60648
diff
changeset
|
18 """Resolve a relative module name to an absolute one.""" |
|
767503ba72e7
Add importlib.util.resolve_name().
Brett Cannon <brett@python.org>
parents:
60648
diff
changeset
|
19 if not name.startswith('.'): |
|
767503ba72e7
Add importlib.util.resolve_name().
Brett Cannon <brett@python.org>
parents:
60648
diff
changeset
|
20 return name |
|
767503ba72e7
Add importlib.util.resolve_name().
Brett Cannon <brett@python.org>
parents:
60648
diff
changeset
|
21 elif not package: |
|
767503ba72e7
Add importlib.util.resolve_name().
Brett Cannon <brett@python.org>
parents:
60648
diff
changeset
|
22 raise ValueError('{!r} is not a relative name ' |
|
767503ba72e7
Add importlib.util.resolve_name().
Brett Cannon <brett@python.org>
parents:
60648
diff
changeset
|
23 '(no leading dot)'.format(name)) |
|
767503ba72e7
Add importlib.util.resolve_name().
Brett Cannon <brett@python.org>
parents:
60648
diff
changeset
|
24 level = 0 |
|
767503ba72e7
Add importlib.util.resolve_name().
Brett Cannon <brett@python.org>
parents:
60648
diff
changeset
|
25 for character in name: |
|
767503ba72e7
Add importlib.util.resolve_name().
Brett Cannon <brett@python.org>
parents:
60648
diff
changeset
|
26 if character != '.': |
|
767503ba72e7
Add importlib.util.resolve_name().
Brett Cannon <brett@python.org>
parents:
60648
diff
changeset
|
27 break |
|
767503ba72e7
Add importlib.util.resolve_name().
Brett Cannon <brett@python.org>
parents:
60648
diff
changeset
|
28 level += 1 |
|
767503ba72e7
Add importlib.util.resolve_name().
Brett Cannon <brett@python.org>
parents:
60648
diff
changeset
|
29 return _resolve_name(name[level:], package, level) |
|
84001
e873f2e67353
Issues #18088, 18089: Introduce
Brett Cannon <brett@python.org>
parents:
83988
diff
changeset
|
30 |
|
e873f2e67353
Issues #18088, 18089: Introduce
Brett Cannon <brett@python.org>
parents:
83988
diff
changeset
|
31 |
|
87347
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
32 @contextmanager |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
33 def _module_to_load(name): |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
34 is_reload = name in sys.modules |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
35 |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
36 module = sys.modules.get(name) |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
37 if not is_reload: |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
38 # This must be done before open() is called as the 'io' module |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
39 # implicitly imports 'locale' and would otherwise trigger an |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
40 # infinite loop. |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
41 module = type(sys)(name) |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
42 # This must be done before putting the module in sys.modules |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
43 # (otherwise an optimization shortcut in import.c becomes wrong) |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
44 module.__initializing__ = True |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
45 sys.modules[name] = module |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
46 try: |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
47 yield module |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
48 except Exception: |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
49 if not is_reload: |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
50 try: |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
51 del sys.modules[name] |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
52 except KeyError: |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
53 pass |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
54 finally: |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
55 module.__initializing__ = False |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
56 |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
57 |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
58 # XXX deprecate |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
59 def set_package(fxn): |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
60 """Set __package__ on the returned module.""" |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
61 @functools.wraps(fxn) |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
62 def set_package_wrapper(*args, **kwargs): |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
63 module = fxn(*args, **kwargs) |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
64 if getattr(module, '__package__', None) is None: |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
65 module.__package__ = module.__name__ |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
66 if not hasattr(module, '__path__'): |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
67 module.__package__ = module.__package__.rpartition('.')[0] |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
68 return module |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
69 return set_package_wrapper |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
70 |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
71 |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
72 # XXX deprecate |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
73 def set_loader(fxn): |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
74 """Set __loader__ on the returned module.""" |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
75 @functools.wraps(fxn) |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
76 def set_loader_wrapper(self, *args, **kwargs): |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
77 module = fxn(self, *args, **kwargs) |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
78 if getattr(module, '__loader__', None) is None: |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
79 module.__loader__ = self |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
80 return module |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
81 return set_loader_wrapper |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
82 |
|
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
83 |
|
84001
e873f2e67353
Issues #18088, 18089: Introduce
Brett Cannon <brett@python.org>
parents:
83988
diff
changeset
|
84 def module_for_loader(fxn): |
|
e873f2e67353
Issues #18088, 18089: Introduce
Brett Cannon <brett@python.org>
parents:
83988
diff
changeset
|
85 """Decorator to handle selecting the proper module for loaders. |
|
e873f2e67353
Issues #18088, 18089: Introduce
Brett Cannon <brett@python.org>
parents:
83988
diff
changeset
|
86 |
|
e873f2e67353
Issues #18088, 18089: Introduce
Brett Cannon <brett@python.org>
parents:
83988
diff
changeset
|
87 The decorated function is passed the module to use instead of the module |
|
e873f2e67353
Issues #18088, 18089: Introduce
Brett Cannon <brett@python.org>
parents:
83988
diff
changeset
|
88 name. The module passed in to the function is either from sys.modules if |
|
e873f2e67353
Issues #18088, 18089: Introduce
Brett Cannon <brett@python.org>
parents:
83988
diff
changeset
|
89 it already exists or is a new module. If the module is new, then __name__ |
|
e873f2e67353
Issues #18088, 18089: Introduce
Brett Cannon <brett@python.org>
parents:
83988
diff
changeset
|
90 is set the first argument to the method, __loader__ is set to self, and |
|
e873f2e67353
Issues #18088, 18089: Introduce
Brett Cannon <brett@python.org>
parents:
83988
diff
changeset
|
91 __package__ is set accordingly (if self.is_package() is defined) will be set |
|
e873f2e67353
Issues #18088, 18089: Introduce
Brett Cannon <brett@python.org>
parents:
83988
diff
changeset
|
92 before it is passed to the decorated function (if self.is_package() does |
|
e873f2e67353
Issues #18088, 18089: Introduce
Brett Cannon <brett@python.org>
parents:
83988
diff
changeset
|
93 not work for the module it will be set post-load). |
|
e873f2e67353
Issues #18088, 18089: Introduce
Brett Cannon <brett@python.org>
parents:
83988
diff
changeset
|
94 |
|
e873f2e67353
Issues #18088, 18089: Introduce
Brett Cannon <brett@python.org>
parents:
83988
diff
changeset
|
95 If an exception is raised and the decorator created the module it is |
|
e873f2e67353
Issues #18088, 18089: Introduce
Brett Cannon <brett@python.org>
parents:
83988
diff
changeset
|
96 subsequently removed from sys.modules. |
|
e873f2e67353
Issues #18088, 18089: Introduce
Brett Cannon <brett@python.org>
parents:
83988
diff
changeset
|
97 |
|
e873f2e67353
Issues #18088, 18089: Introduce
Brett Cannon <brett@python.org>
parents:
83988
diff
changeset
|
98 The decorator assumes that the decorated function takes the module name as |
|
e873f2e67353
Issues #18088, 18089: Introduce
Brett Cannon <brett@python.org>
parents:
83988
diff
changeset
|
99 the second argument. |
|
e873f2e67353
Issues #18088, 18089: Introduce
Brett Cannon <brett@python.org>
parents:
83988
diff
changeset
|
100 |
|
e873f2e67353
Issues #18088, 18089: Introduce
Brett Cannon <brett@python.org>
parents:
83988
diff
changeset
|
101 """ |
|
87347
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
102 warnings.warn('The import system now takes care of this automatically.', |
|
84001
e873f2e67353
Issues #18088, 18089: Introduce
Brett Cannon <brett@python.org>
parents:
83988
diff
changeset
|
103 PendingDeprecationWarning, stacklevel=2) |
|
e873f2e67353
Issues #18088, 18089: Introduce
Brett Cannon <brett@python.org>
parents:
83988
diff
changeset
|
104 @functools.wraps(fxn) |
|
e873f2e67353
Issues #18088, 18089: Introduce
Brett Cannon <brett@python.org>
parents:
83988
diff
changeset
|
105 def module_for_loader_wrapper(self, fullname, *args, **kwargs): |
|
87347
07229c6104b1
Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents:
84173
diff
changeset
|
106 with _module_to_load(fullname) as module: |
|
84001
e873f2e67353
Issues #18088, 18089: Introduce
Brett Cannon <brett@python.org>
parents:
83988
diff
changeset
|
107 module.__loader__ = self |
|
e873f2e67353
Issues #18088, 18089: Introduce
Brett Cannon <brett@python.org>
parents:
83988
diff
changeset
|
108 try: |
|
e873f2e67353
Issues #18088, 18089: Introduce
Brett Cannon <brett@python.org>
parents:
83988
diff
changeset
|
109 is_package = self.is_package(fullname) |
|
e873f2e67353
Issues #18088, 18089: Introduce
Brett Cannon <brett@python.org>
parents:
83988
diff
changeset
|
110 except (ImportError, AttributeError): |
|
e873f2e67353
Issues #18088, 18089: Introduce
Brett Cannon <brett@python.org>
parents:
83988
diff
changeset
|
111 pass |
|
e873f2e67353
Issues #18088, 18089: Introduce
Brett Cannon <brett@python.org>
parents:
83988
diff
changeset
|
112 else: |
|
e873f2e67353
Issues #18088, 18089: Introduce
Brett Cannon <brett@python.org>
parents:
83988
diff
changeset
|
113 if is_package: |
|
e873f2e67353
Issues #18088, 18089: Introduce
Brett Cannon <brett@python.org>
parents:
83988
diff
changeset
|
114 module.__package__ = fullname |
|
e873f2e67353
Issues #18088, 18089: Introduce
Brett Cannon <brett@python.org>
parents:
83988
diff
changeset
|
115 else: |
|
e873f2e67353
Issues #18088, 18089: Introduce
Brett Cannon <brett@python.org>
parents:
83988
diff
changeset
|
116 module.__package__ = fullname.rpartition('.')[0] |
|
e873f2e67353
Issues #18088, 18089: Introduce
Brett Cannon <brett@python.org>
parents:
83988
diff
changeset
|
117 # If __package__ was not set above, __import__() will do it later. |
|
e873f2e67353
Issues #18088, 18089: Introduce
Brett Cannon <brett@python.org>
parents:
83988
diff
changeset
|
118 return fxn(self, module, *args, **kwargs) |
|
e873f2e67353
Issues #18088, 18089: Introduce
Brett Cannon <brett@python.org>
parents:
83988
diff
changeset
|
119 |
| 84002 | 120 return module_for_loader_wrapper |
