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