py3k.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. """
  2. Python 3.X compatibility tools.
  3. While this file was originally intended for Python 2 -> 3 transition,
  4. it is now used to create a compatibility layer between different
  5. minor versions of Python 3.
  6. While the active version of numpy may not support a given version of python, we
  7. allow downstream libraries to continue to use these shims for forward
  8. compatibility with numpy while they transition their code to newer versions of
  9. Python.
  10. """
  11. __all__ = ['bytes', 'asbytes', 'isfileobj', 'getexception', 'strchar',
  12. 'unicode', 'asunicode', 'asbytes_nested', 'asunicode_nested',
  13. 'asstr', 'open_latin1', 'long', 'basestring', 'sixu',
  14. 'integer_types', 'is_pathlib_path', 'npy_load_module', 'Path',
  15. 'pickle', 'contextlib_nullcontext', 'os_fspath', 'os_PathLike']
  16. import sys
  17. import os
  18. from pathlib import Path
  19. import io
  20. try:
  21. import pickle5 as pickle
  22. except ImportError:
  23. import pickle
  24. long = int
  25. integer_types = (int,)
  26. basestring = str
  27. unicode = str
  28. bytes = bytes
  29. def asunicode(s):
  30. if isinstance(s, bytes):
  31. return s.decode('latin1')
  32. return str(s)
  33. def asbytes(s):
  34. if isinstance(s, bytes):
  35. return s
  36. return str(s).encode('latin1')
  37. def asstr(s):
  38. if isinstance(s, bytes):
  39. return s.decode('latin1')
  40. return str(s)
  41. def isfileobj(f):
  42. if not isinstance(f, (io.FileIO, io.BufferedReader, io.BufferedWriter)):
  43. return False
  44. try:
  45. # BufferedReader/Writer may raise OSError when
  46. # fetching `fileno()` (e.g. when wrapping BytesIO).
  47. f.fileno()
  48. return True
  49. except OSError:
  50. return False
  51. def open_latin1(filename, mode='r'):
  52. return open(filename, mode=mode, encoding='iso-8859-1')
  53. def sixu(s):
  54. return s
  55. strchar = 'U'
  56. def getexception():
  57. return sys.exc_info()[1]
  58. def asbytes_nested(x):
  59. if hasattr(x, '__iter__') and not isinstance(x, (bytes, unicode)):
  60. return [asbytes_nested(y) for y in x]
  61. else:
  62. return asbytes(x)
  63. def asunicode_nested(x):
  64. if hasattr(x, '__iter__') and not isinstance(x, (bytes, unicode)):
  65. return [asunicode_nested(y) for y in x]
  66. else:
  67. return asunicode(x)
  68. def is_pathlib_path(obj):
  69. """
  70. Check whether obj is a `pathlib.Path` object.
  71. Prefer using ``isinstance(obj, os.PathLike)`` instead of this function.
  72. """
  73. return isinstance(obj, Path)
  74. # from Python 3.7
  75. class contextlib_nullcontext:
  76. """Context manager that does no additional processing.
  77. Used as a stand-in for a normal context manager, when a particular
  78. block of code is only sometimes used with a normal context manager:
  79. cm = optional_cm if condition else nullcontext()
  80. with cm:
  81. # Perform operation, using optional_cm if condition is True
  82. .. note::
  83. Prefer using `contextlib.nullcontext` instead of this context manager.
  84. """
  85. def __init__(self, enter_result=None):
  86. self.enter_result = enter_result
  87. def __enter__(self):
  88. return self.enter_result
  89. def __exit__(self, *excinfo):
  90. pass
  91. def npy_load_module(name, fn, info=None):
  92. """
  93. Load a module. Uses ``load_module`` which will be deprecated in python
  94. 3.12. An alternative that uses ``exec_module`` is in
  95. numpy.distutils.misc_util.exec_mod_from_location
  96. .. versionadded:: 1.11.2
  97. Parameters
  98. ----------
  99. name : str
  100. Full module name.
  101. fn : str
  102. Path to module file.
  103. info : tuple, optional
  104. Only here for backward compatibility with Python 2.*.
  105. Returns
  106. -------
  107. mod : module
  108. """
  109. # Explicitly lazy import this to avoid paying the cost
  110. # of importing importlib at startup
  111. from importlib.machinery import SourceFileLoader
  112. return SourceFileLoader(name, fn).load_module()
  113. os_fspath = os.fspath
  114. os_PathLike = os.PathLike