mirror of
https://github.com/python/cpython.git
synced 2025-08-22 01:35:16 +00:00
bpo-45020: Identify which frozen modules are actually aliases. (gh-28655)
In the list of generated frozen modules at the top of Tools/scripts/freeze_modules.py, you will find that some of the modules have a different name than the module (or .py file) that is actually frozen. Let's call each case an "alias". Aliases do not come into play until we get to the (generated) list of modules in Python/frozen.c. (The tool for freezing modules, Programs/_freeze_module, is only concerned with the source file, not the module it will be used for.) Knowledge of which frozen modules are aliases (and the identity of the original module) normally isn't important. However, this information is valuable when we go to set __file__ on frozen stdlib modules. This change updates Tools/scripts/freeze_modules.py to map aliases to the original module name (or None if not a stdlib module) in Python/frozen.c. We also add a helper function in Python/import.c to look up a frozen module's alias and add the result of that function to the frozen info returned from find_frozen(). https://bugs.python.org/issue45020
This commit is contained in:
parent
444429142c
commit
08285d563e
10 changed files with 225 additions and 37 deletions
|
@ -824,16 +824,39 @@ class FrozenImporter:
|
|||
"slated for removal in Python 3.12", DeprecationWarning)
|
||||
return '<module {!r} ({})>'.format(m.__name__, FrozenImporter._ORIGIN)
|
||||
|
||||
@classmethod
|
||||
def _setup_module(cls, module):
|
||||
assert not hasattr(module, '__file__'), module.__file__
|
||||
ispkg = hasattr(module, '__path__')
|
||||
assert not ispkg or not module.__path__, module.__path__
|
||||
spec = module.__spec__
|
||||
assert not ispkg or not spec.submodule_search_locations
|
||||
|
||||
if spec.loader_state is None:
|
||||
spec.loader_state = type(sys.implementation)(
|
||||
data=None,
|
||||
origname=None,
|
||||
)
|
||||
elif not hasattr(spec.loader_state, 'data'):
|
||||
spec.loader_state.data = None
|
||||
if not getattr(spec.loader_state, 'origname', None):
|
||||
origname = vars(module).pop('__origname__', None)
|
||||
assert origname, 'see PyImport_ImportFrozenModuleObject()'
|
||||
spec.loader_state.origname = origname
|
||||
|
||||
@classmethod
|
||||
def find_spec(cls, fullname, path=None, target=None):
|
||||
info = _call_with_frames_removed(_imp.find_frozen, fullname)
|
||||
if info is None:
|
||||
return None
|
||||
data, ispkg = info
|
||||
data, ispkg, origname = info
|
||||
spec = spec_from_loader(fullname, cls,
|
||||
origin=cls._ORIGIN,
|
||||
is_package=ispkg)
|
||||
spec.loader_state = data
|
||||
spec.loader_state = type(sys.implementation)(
|
||||
data=data,
|
||||
origname=origname,
|
||||
)
|
||||
return spec
|
||||
|
||||
@classmethod
|
||||
|
@ -857,7 +880,7 @@ class FrozenImporter:
|
|||
spec = module.__spec__
|
||||
name = spec.name
|
||||
try:
|
||||
data = spec.loader_state
|
||||
data = spec.loader_state.data
|
||||
except AttributeError:
|
||||
if not _imp.is_frozen(name):
|
||||
raise ImportError('{!r} is not a frozen module'.format(name),
|
||||
|
@ -868,7 +891,7 @@ class FrozenImporter:
|
|||
# Note that if this method is called again (e.g. by
|
||||
# importlib.reload()) then _imp.get_frozen_object() will notice
|
||||
# no data was provided and will look it up.
|
||||
spec.loader_state = None
|
||||
spec.loader_state.data = None
|
||||
code = _call_with_frames_removed(_imp.get_frozen_object, name, data)
|
||||
exec(code, module.__dict__)
|
||||
|
||||
|
@ -1220,6 +1243,8 @@ def _setup(sys_module, _imp_module):
|
|||
continue
|
||||
spec = _spec_from_module(module, loader)
|
||||
_init_module_attrs(spec, module)
|
||||
if loader is FrozenImporter:
|
||||
loader._setup_module(module)
|
||||
|
||||
# Directly load built-in modules needed during bootstrap.
|
||||
self_module = sys.modules[__name__]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue