py3compat.py 6.3 KB

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