ef3136f8d2a13c3d251e146d8d754e21c3ed1c38
[SubU] /
1 import sys
2 import platform
3
4
5 __all__ = ['install', 'NullFinder', 'Protocol']
6
7
8 try:
9     from typing import Protocol
10 except ImportError:  # pragma: no cover
11     from ..typing_extensions import Protocol  # type: ignore
12
13
14 def install(cls):
15     """
16     Class decorator for installation on sys.meta_path.
17
18     Adds the backport DistributionFinder to sys.meta_path and
19     attempts to disable the finder functionality of the stdlib
20     DistributionFinder.
21     """
22     sys.meta_path.append(cls())
23     disable_stdlib_finder()
24     return cls
25
26
27 def disable_stdlib_finder():
28     """
29     Give the backport primacy for discovering path-based distributions
30     by monkey-patching the stdlib O_O.
31
32     See #91 for more background for rationale on this sketchy
33     behavior.
34     """
35
36     def matches(finder):
37         return getattr(
38             finder, '__module__', None
39         ) == '_frozen_importlib_external' and hasattr(finder, 'find_distributions')
40
41     for finder in filter(matches, sys.meta_path):  # pragma: nocover
42         del finder.find_distributions
43
44
45 class NullFinder:
46     """
47     A "Finder" (aka "MetaClassFinder") that never finds any modules,
48     but may find distributions.
49     """
50
51     @staticmethod
52     def find_spec(*args, **kwargs):
53         return None
54
55     # In Python 2, the import system requires finders
56     # to have a find_module() method, but this usage
57     # is deprecated in Python 3 in favor of find_spec().
58     # For the purposes of this finder (i.e. being present
59     # on sys.meta_path but having no other import
60     # system functionality), the two methods are identical.
61     find_module = find_spec
62
63
64 def pypy_partial(val):
65     """
66     Adjust for variable stacklevel on partial under PyPy.
67
68     Workaround for #327.
69     """
70     is_pypy = platform.python_implementation() == 'PyPy'
71     return val + is_pypy