summaryrefslogtreecommitdiffstats
path: root/Lib/zipimport.py
diff options
context:
space:
mode:
authorBrett Cannon <brett@python.org>2020-11-13 23:14:58 (GMT)
committerGitHub <noreply@github.com>2020-11-13 23:14:58 (GMT)
commitd2e94bb0848e04a90efa51be401f0ce8a9e252f2 (patch)
tree241cec2ab4a3037fee4406acc2cd502db1d8bf1c /Lib/zipimport.py
parent9b6934230c35e24d8582ea8c58456fa8eab72ae2 (diff)
downloadcpython-d2e94bb0848e04a90efa51be401f0ce8a9e252f2.zip
cpython-d2e94bb0848e04a90efa51be401f0ce8a9e252f2.tar.gz
cpython-d2e94bb0848e04a90efa51be401f0ce8a9e252f2.tar.bz2
bpo-42131: Add PEP 451-related methods to zipimport (GH-23187)
Specifically, find_spec(), create_module(), and exec_module(). Co-authored-by: Nick Coghlan <ncoghlan@gmail.com>
Diffstat (limited to 'Lib/zipimport.py')
-rw-r--r--Lib/zipimport.py34
1 files changed, 33 insertions, 1 deletions
diff --git a/Lib/zipimport.py b/Lib/zipimport.py
index 080e0c4..2e5188a 100644
--- a/Lib/zipimport.py
+++ b/Lib/zipimport.py
@@ -42,7 +42,7 @@ END_CENTRAL_DIR_SIZE = 22
STRING_END_ARCHIVE = b'PK\x05\x06'
MAX_COMMENT_LEN = (1 << 16) - 1
-class zipimporter:
+class zipimporter(_bootstrap_external._LoaderBasics):
"""zipimporter(archivepath) -> zipimporter object
Create a new zipimporter instance. 'archivepath' must be a path to
@@ -115,6 +115,8 @@ class zipimporter:
full path name if it's possibly a portion of a namespace package,
or None otherwise. The optional 'path' argument is ignored -- it's
there for compatibility with the importer protocol.
+
+ Deprecated since Python 3.10. Use find_spec() instead.
"""
mi = _get_module_info(self, fullname)
if mi is not None:
@@ -146,9 +148,37 @@ class zipimporter:
instance itself if the module was found, or None if it wasn't.
The optional 'path' argument is ignored -- it's there for compatibility
with the importer protocol.
+
+ Deprecated since Python 3.10. Use find_spec() instead.
"""
return self.find_loader(fullname, path)[0]
+ def find_spec(self, fullname, target=None):
+ """Create a ModuleSpec for the specified module.
+
+ Returns None if the module cannot be found.
+ """
+ module_info = _get_module_info(self, fullname)
+ if module_info is not None:
+ return _bootstrap.spec_from_loader(fullname, self, is_package=module_info)
+ else:
+ # Not a module or regular package. See if this is a directory, and
+ # therefore possibly a portion of a namespace package.
+
+ # We're only interested in the last path component of fullname
+ # earlier components are recorded in self.prefix.
+ modpath = _get_module_path(self, fullname)
+ if _is_dir(self, modpath):
+ # This is possibly a portion of a namespace
+ # package. Return the string representing its path,
+ # without a trailing separator.
+ path = f'{self.archive}{path_sep}{modpath}'
+ spec = _bootstrap.ModuleSpec(name=fullname, loader=None,
+ is_package=True)
+ spec.submodule_search_locations.append(path)
+ return spec
+ else:
+ return None
def get_code(self, fullname):
"""get_code(fullname) -> code object.
@@ -237,6 +267,8 @@ class zipimporter:
Load the module specified by 'fullname'. 'fullname' must be the
fully qualified (dotted) module name. It returns the imported
module, or raises ZipImportError if it wasn't found.
+
+ Deprecated since Python 3.10. use exec_module() instead.
"""
code, ispackage, modpath = _get_module_code(self, fullname)
mod = sys.modules.get(fullname)