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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
7b69e630d237 PEP 3147
Barry Warsaw <barry@python.org>
parents: 52115
diff changeset
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
6a90817fb437 fix whitespace
Brett Cannon <brett@python.org>
parents: 84001
diff changeset
120 return module_for_loader_wrapper