Patchwork [stable] demandimport: fix compatibility with meta path finders w/o find_spec() method

login
register
mail settings
Submitter Manuel Jacob
Date May 11, 2020, 11:07 p.m.
Message ID <fb5fffb2dbddef1ba6dd.1589238435@tmp>
Download mbox | patch
Permalink /patch/46300/
State Accepted
Headers show

Comments

Manuel Jacob - May 11, 2020, 11:07 p.m.
# HG changeset patch
# User Manuel Jacob <me@manueljacob.de>
# Date 1589238192 -7200
#      Tue May 12 01:03:12 2020 +0200
# Branch stable
# Node ID fb5fffb2dbddef1ba6dd07cb0f9a95637d7802ad
# Parent  a50f33f1ff24466d6d721685cc65a732cb4c522c
demandimport: fix compatibility with meta path finders w/o find_spec() method

Meta path finders got a find_spec() method in Python version 3.4. The
sys.meta_path documentation says that the deprecated find_module() method is
used as a fallback.

Setuptool’s VendorImporter still doesn’t have the find_spec() method,
which resulted in a crash e.g. within a virtual environment. For reference, I
opened an issue for that: https://github.com/pypa/setuptools/issues/2104.

An alternative implementation would have been to implement a wrapper for
find_module() itself and raise an AttributeError when accessing find_spec() if
the wrapped finder doesn’t have it.
Yuya Nishihara - May 12, 2020, 12:52 p.m.
On Tue, 12 May 2020 01:07:15 +0200, Manuel Jacob wrote:
> # HG changeset patch
> # User Manuel Jacob <me@manueljacob.de>
> # Date 1589238192 -7200
> #      Tue May 12 01:03:12 2020 +0200
> # Branch stable
> # Node ID fb5fffb2dbddef1ba6dd07cb0f9a95637d7802ad
> # Parent  a50f33f1ff24466d6d721685cc65a732cb4c522c
> demandimport: fix compatibility with meta path finders w/o find_spec() method

Queued for stable, thanks.

Patch

diff --git a/hgdemandimport/demandimportpy3.py b/hgdemandimport/demandimportpy3.py
--- a/hgdemandimport/demandimportpy3.py
+++ b/hgdemandimport/demandimportpy3.py
@@ -97,9 +97,18 @@ 
     def __setattr__(self, name, value):
         return setattr(object.__getattribute__(self, "_finder"), name, value)
 
-    def find_spec(self, *args, **kwargs):
+    def find_spec(self, fullname, path, target=None):
         finder = object.__getattribute__(self, "_finder")
-        spec = finder.find_spec(*args, **kwargs)
+        try:
+            find_spec = finder.find_spec
+        except AttributeError:
+            loader = finder.find_module(fullname, path)
+            if loader is None:
+                spec = None
+            else:
+                spec = importlib.util.spec_from_loader(fullname, loader)
+        else:
+            spec = find_spec(fullname, path, target)
 
         # Lazy loader requires exec_module().
         if (