From e68fd017bad00c1cd2e85d2616881b67417c5fcd Mon Sep 17 00:00:00 2001 From: Sviatoslav Sydorenko Date: Thu, 8 Apr 2021 19:58:24 +0200 Subject: [PATCH] Implement `find_spec` in vendored module importers This change makes the import warning emitted by Python 3.10 disappear but implementing the hook that is supposed to replace the old import mechanism. Refs: * https://bugs.python.org/issue42134 * https://bugs.python.org/issue43540 * https://github.com/pypa/setuptools/issues/2632#issuecomment-815701078 Fixes #2632 --- pkg_resources/extern/__init__.py | 20 ++++++++++++++------ setuptools/extern/__init__.py | 20 ++++++++++++++------ 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/pkg_resources/extern/__init__.py b/pkg_resources/extern/__init__.py index 1fbb4fcc896..962802fdc19 100644 --- a/pkg_resources/extern/__init__.py +++ b/pkg_resources/extern/__init__.py @@ -20,17 +20,18 @@ def search_path(self): yield self.vendor_pkg + '.' yield '' + def _module_matches_namespace(self, fullname): + """Figure out if the target module is vendored.""" + root, base, target = fullname.partition(self.root_name + '.') + return not root and any(map(target.startswith, self.vendored_names)) + def find_module(self, fullname, path=None): """ Return self when fullname starts with root_name and the target module is one vendored through this importer. """ - root, base, target = fullname.partition(self.root_name + '.') - if root: - return - if not any(map(target.startswith, self.vendored_names)): - return - return self + spec = self.find_spec(fullname, path) + return spec.loader if spec is not None else None def load_module(self, fullname): """ @@ -60,6 +61,13 @@ def create_module(self, spec): def exec_module(self, module): pass + def find_spec(self, fullname, path=None, target=None): + """Produce a registered namespace matching module spec.""" + return ( + importlib.machinery.ModuleSpec(fullname, self) + if self._module_matches_namespace(fullname) else None + ) + def install(self): """ Install this importer into sys.meta_path if not already present. diff --git a/setuptools/extern/__init__.py b/setuptools/extern/__init__.py index 399701a044e..94b6ddd6134 100644 --- a/setuptools/extern/__init__.py +++ b/setuptools/extern/__init__.py @@ -20,17 +20,18 @@ def search_path(self): yield self.vendor_pkg + '.' yield '' + def _module_matches_namespace(self, fullname): + """Figure out if the target module is vendored.""" + root, base, target = fullname.partition(self.root_name + '.') + return not root and any(map(target.startswith, self.vendored_names)) + def find_module(self, fullname, path=None): """ Return self when fullname starts with root_name and the target module is one vendored through this importer. """ - root, base, target = fullname.partition(self.root_name + '.') - if root: - return - if not any(map(target.startswith, self.vendored_names)): - return - return self + spec = self.find_spec(fullname, path) + return spec.loader if spec is not None else None def load_module(self, fullname): """ @@ -60,6 +61,13 @@ def create_module(self, spec): def exec_module(self, module): pass + def find_spec(self, fullname, path=None, target=None): + """Produce a registered namespace matching module spec.""" + return ( + importlib.machinery.ModuleSpec(fullname, self) + if self._module_matches_namespace(fullname) else None + ) + def install(self): """ Install this importer into sys.meta_path if not already present.