py3compat.py 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. # -*- coding: utf-8 -*-
  2. #
  3. # Copyright © 2012-2013 Pierre Raybaut
  4. # Licensed under the terms of the MIT License
  5. # (see spyderlib/__init__.py for details)
  6. """
  7. spyderlib.py3compat
  8. -------------------
  9. Transitional module providing compatibility functions intended to help
  10. migrating from Python 2 to Python 3.
  11. This module should be fully compatible with:
  12. * Python >=v2.6
  13. * Python 3
  14. """
  15. from __future__ import print_function
  16. import sys
  17. import os
  18. PY2 = sys.version[0] == '2'
  19. PY3 = sys.version[0] == '3'
  20. # ==============================================================================
  21. # Data types
  22. # ==============================================================================
  23. if PY2:
  24. # Python 2
  25. TEXT_TYPES = (str, unicode)
  26. INT_TYPES = (int, long)
  27. else:
  28. # Python 3
  29. TEXT_TYPES = (str,)
  30. INT_TYPES = (int,)
  31. NUMERIC_TYPES = tuple(list(INT_TYPES) + [float, complex])
  32. # ==============================================================================
  33. # Renamed/Reorganized modules
  34. # ==============================================================================
  35. if PY2:
  36. # Python 2
  37. import __builtin__ as builtins
  38. import ConfigParser as configparser
  39. try:
  40. import _winreg as winreg
  41. except ImportError:
  42. pass
  43. from sys import maxint as maxsize
  44. try:
  45. import CStringIO as io
  46. except ImportError:
  47. import StringIO as io
  48. try:
  49. import cPickle as pickle
  50. except ImportError:
  51. import pickle
  52. from UserDict import DictMixin as MutableMapping
  53. import thread as _thread
  54. import repr as reprlib
  55. else:
  56. # Python 3
  57. import builtins
  58. import configparser
  59. try:
  60. import winreg
  61. except ImportError:
  62. pass
  63. from sys import maxsize
  64. import io
  65. import pickle
  66. try: # Python 3.8 and more
  67. from collections.abc import MutableMapping
  68. except ImportError:
  69. from collections import MutableMapping
  70. import _thread
  71. import reprlib
  72. # ==============================================================================
  73. # Strings
  74. # ==============================================================================
  75. if PY2:
  76. # Python 2
  77. import codecs
  78. def u(obj):
  79. """Make unicode object"""
  80. return codecs.unicode_escape_decode(obj)[0]
  81. else:
  82. # Python 3
  83. def u(obj):
  84. """Return string as it is"""
  85. return obj
  86. def is_text_string(obj):
  87. """Return True if `obj` is a text string, False if it is anything else,
  88. like binary data (Python 3) or QString (Python 2, PyQt API #1)"""
  89. if PY2:
  90. # Python 2
  91. return isinstance(obj, basestring)
  92. else:
  93. # Python 3
  94. return isinstance(obj, str)
  95. def is_binary_string(obj):
  96. """Return True if `obj` is a binary string, False if it is anything else"""
  97. if PY2:
  98. # Python 2
  99. return isinstance(obj, str)
  100. else:
  101. # Python 3
  102. return isinstance(obj, bytes)
  103. def is_string(obj):
  104. """Return True if `obj` is a text or binary Python string object,
  105. False if it is anything else, like a QString (Python 2, PyQt API #1)"""
  106. return is_text_string(obj) or is_binary_string(obj)
  107. def is_unicode(obj):
  108. """Return True if `obj` is unicode"""
  109. if PY2:
  110. # Python 2
  111. return isinstance(obj, unicode)
  112. else:
  113. # Python 3
  114. return isinstance(obj, str)
  115. def to_text_string(obj, encoding=None):
  116. """Convert `obj` to (unicode) text string"""
  117. if PY2:
  118. # Python 2
  119. if encoding is None:
  120. return unicode(obj)
  121. else:
  122. return unicode(obj, encoding)
  123. else:
  124. # Python 3
  125. if encoding is None:
  126. return str(obj)
  127. elif isinstance(obj, str):
  128. # In case this function is not used properly, this could happen
  129. return obj
  130. else:
  131. return str(obj, encoding)
  132. def to_binary_string(obj, encoding=None):
  133. """Convert `obj` to binary string (bytes in Python 3, str in Python 2)"""
  134. if PY2:
  135. # Python 2
  136. if encoding is None:
  137. return str(obj)
  138. else:
  139. return obj.encode(encoding)
  140. else:
  141. # Python 3
  142. return bytes(
  143. obj, 'utf-8' if encoding is None else encoding
  144. )
  145. # ==============================================================================
  146. # Function attributes
  147. # ==============================================================================
  148. def get_func_code(func):
  149. """Return function code object"""
  150. if PY2:
  151. # Python 2
  152. return func.func_code
  153. else:
  154. # Python 3
  155. return func.__code__
  156. def get_func_name(func):
  157. """Return function name"""
  158. if PY2:
  159. # Python 2
  160. return func.func_name
  161. else:
  162. # Python 3
  163. return func.__name__
  164. def get_func_defaults(func):
  165. """Return function default argument values"""
  166. if PY2:
  167. # Python 2
  168. return func.func_defaults
  169. else:
  170. # Python 3
  171. return func.__defaults__
  172. # ==============================================================================
  173. # Special method attributes
  174. # ==============================================================================
  175. def get_meth_func(obj):
  176. """Return method function object"""
  177. if PY2:
  178. # Python 2
  179. return obj.im_func
  180. else:
  181. # Python 3
  182. return obj.__func__
  183. def get_meth_class_inst(obj):
  184. """Return method class instance"""
  185. if PY2:
  186. # Python 2
  187. return obj.im_self
  188. else:
  189. # Python 3
  190. return obj.__self__
  191. def get_meth_class(obj):
  192. """Return method class"""
  193. if PY2:
  194. # Python 2
  195. return obj.im_class
  196. else:
  197. # Python 3
  198. return obj.__self__.__class__
  199. # ==============================================================================
  200. # Misc.
  201. # ==============================================================================
  202. if PY2:
  203. # Python 2
  204. input = raw_input
  205. getcwd = os.getcwdu
  206. cmp = cmp
  207. import string
  208. str_lower = string.lower
  209. from itertools import izip_longest as zip_longest
  210. else:
  211. # Python 3
  212. input = input
  213. getcwd = os.getcwd
  214. def cmp(a, b):
  215. return (a > b) - (a < b)
  216. str_lower = str.lower
  217. from itertools import zip_longest
  218. def qbytearray_to_str(qba):
  219. """Convert QByteArray object to str in a way compatible with Python 2/3"""
  220. return str(bytes(qba.toHex().data()).decode())
  221. if __name__ == '__main__':
  222. pass