1import platform
2import sys
3
4__all__ = ['install', 'NullFinder']
5
6
7def install(cls):
8 """
9 Class decorator for installation on sys.meta_path.
10
11 Adds the backport DistributionFinder to sys.meta_path and
12 attempts to disable the finder functionality of the stdlib
13 DistributionFinder.
14 """
15 sys.meta_path.append(cls())
16 disable_stdlib_finder()
17 return cls
18
19
20def disable_stdlib_finder():
21 """
22 Give the backport primacy for discovering path-based distributions
23 by monkey-patching the stdlib O_O.
24
25 See #91 for more background for rationale on this sketchy
26 behavior.
27 """
28
29 def matches(finder):
30 return getattr(
31 finder, '__module__', None
32 ) == '_frozen_importlib_external' and hasattr(finder, 'find_distributions')
33
34 for finder in filter(matches, sys.meta_path): # pragma: nocover
35 del finder.find_distributions
36
37
38class NullFinder:
39 """
40 A "Finder" (aka "MetaPathFinder") that never finds any modules,
41 but may find distributions.
42 """
43
44 @staticmethod
45 def find_spec(*args, **kwargs):
46 return None
47
48
49def pypy_partial(val):
50 """
51 Adjust for variable stacklevel on partial under PyPy.
52
53 Workaround for #327.
54 """
55 is_pypy = platform.python_implementation() == 'PyPy'
56 return val + is_pypy