_compat.py 1.5 KB

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