_compat.py 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. from __future__ import absolute_import
  2. import io
  3. import abc
  4. import sys
  5. import email
  6. if sys.version_info > (3,): # pragma: nocover
  7. import builtins
  8. from configparser import ConfigParser
  9. from contextlib import suppress
  10. FileNotFoundError = builtins.FileNotFoundError
  11. IsADirectoryError = builtins.IsADirectoryError
  12. NotADirectoryError = builtins.NotADirectoryError
  13. PermissionError = builtins.PermissionError
  14. map = builtins.map
  15. else: # pragma: nocover
  16. from backports.configparser import ConfigParser
  17. from itertools import imap as map # type: ignore
  18. from contextlib2 import suppress # noqa
  19. FileNotFoundError = IOError, OSError
  20. IsADirectoryError = IOError, OSError
  21. NotADirectoryError = IOError, OSError
  22. PermissionError = IOError, OSError
  23. if sys.version_info > (3, 5): # pragma: nocover
  24. import pathlib
  25. else: # pragma: nocover
  26. import pathlib2 as pathlib
  27. try:
  28. ModuleNotFoundError = builtins.FileNotFoundError
  29. except (NameError, AttributeError): # pragma: nocover
  30. ModuleNotFoundError = ImportError # type: ignore
  31. if sys.version_info >= (3,): # pragma: nocover
  32. from importlib.abc import MetaPathFinder
  33. else: # pragma: nocover
  34. class MetaPathFinder(object):
  35. __metaclass__ = abc.ABCMeta
  36. __metaclass__ = type
  37. __all__ = [
  38. 'install', 'NullFinder', 'MetaPathFinder', 'ModuleNotFoundError',
  39. 'pathlib', 'ConfigParser', 'map', 'suppress', 'FileNotFoundError',
  40. 'NotADirectoryError', 'email_message_from_string',
  41. ]
  42. def install(cls):
  43. """Class decorator for installation on sys.meta_path."""
  44. sys.meta_path.append(cls())
  45. return cls
  46. class NullFinder:
  47. """
  48. A "Finder" (aka "MetaClassFinder") that never finds any modules,
  49. but may find distributions.
  50. """
  51. @staticmethod
  52. def find_spec(*args, **kwargs):
  53. return None
  54. # In Python 2, the import system requires finders
  55. # to have a find_module() method, but this usage
  56. # is deprecated in Python 3 in favor of find_spec().
  57. # For the purposes of this finder (i.e. being present
  58. # on sys.meta_path but having no other import
  59. # system functionality), the two methods are identical.
  60. find_module = find_spec
  61. def py2_message_from_string(text): # nocoverpy3
  62. # Work around https://bugs.python.org/issue25545 where
  63. # email.message_from_string cannot handle Unicode on Python 2.
  64. io_buffer = io.StringIO(text)
  65. return email.message_from_file(io_buffer)
  66. email_message_from_string = (
  67. py2_message_from_string
  68. if sys.version_info < (3,) else
  69. email.message_from_string
  70. )
  71. # https://bitbucket.org/pypy/pypy/issues/3021/ioopen-directory-leaks-a-file-descriptor
  72. PYPY_OPEN_BUG = getattr(sys, 'pypy_version_info', (9, 9, 9))[:3] <= (7, 1, 1)