1# -*- coding: utf-8 -*- 2# 3# Copyright © Spyder Project Contributors 4# Licensed under the terms of the MIT License 5# (see spyder/__init__.py for details) 6 7""" 8spyder.py3compat 9---------------- 10 11Transitional module providing compatibility functions intended to help 12migrating from Python 2 to Python 3. 13 14This module should be fully compatible with: 15 * Python >=v2.6 16 * Python 3 17""" 18 19from __future__ import print_function 20 21import operator 22import os 23import sys 24 25PY2 = sys.version[0] == '2' 26PY3 = sys.version[0] == '3' 27 28#============================================================================== 29# Data types 30#============================================================================== 31if PY2: 32 # Python 2 33 TEXT_TYPES = (str, unicode) 34 INT_TYPES = (int, long) 35else: 36 # Python 3 37 TEXT_TYPES = (str,) 38 INT_TYPES = (int,) 39NUMERIC_TYPES = tuple(list(INT_TYPES) + [float, complex]) 40 41 42#============================================================================== 43# Renamed/Reorganized modules 44#============================================================================== 45if PY2: 46 # Python 2 47 import __builtin__ as builtins 48 import ConfigParser as configparser 49 try: 50 import _winreg as winreg 51 except ImportError: 52 pass 53 from sys import maxint as maxsize 54 try: 55 import CStringIO as io 56 except ImportError: 57 import StringIO as io 58 try: 59 import cPickle as pickle 60 except ImportError: 61 import pickle 62 from UserDict import DictMixin as MutableMapping 63 import thread as _thread 64 import repr as reprlib 65 import Queue 66else: 67 # Python 3 68 import builtins 69 import configparser 70 try: 71 import winreg 72 except ImportError: 73 pass 74 from sys import maxsize 75 import io 76 import pickle 77 from collections import MutableMapping 78 import _thread 79 import reprlib 80 import queue as Queue 81 82 83#============================================================================== 84# Strings 85#============================================================================== 86def is_type_text_string(obj): 87 """Return True if `obj` is type text string, False if it is anything else, 88 like an instance of a class that extends the basestring class.""" 89 if PY2: 90 # Python 2 91 return type(obj) in [str, unicode] 92 else: 93 # Python 3 94 return type(obj) in [str, bytes] 95 96def is_text_string(obj): 97 """Return True if `obj` is a text string, False if it is anything else, 98 like binary data (Python 3) or QString (Python 2, PyQt API #1)""" 99 if PY2: 100 # Python 2 101 return isinstance(obj, basestring) 102 else: 103 # Python 3 104 return isinstance(obj, str) 105 106def is_binary_string(obj): 107 """Return True if `obj` is a binary string, False if it is anything else""" 108 if PY2: 109 # Python 2 110 return isinstance(obj, str) 111 else: 112 # Python 3 113 return isinstance(obj, bytes) 114 115def is_string(obj): 116 """Return True if `obj` is a text or binary Python string object, 117 False if it is anything else, like a QString (Python 2, PyQt API #1)""" 118 return is_text_string(obj) or is_binary_string(obj) 119 120def is_unicode(obj): 121 """Return True if `obj` is unicode""" 122 if PY2: 123 # Python 2 124 return isinstance(obj, unicode) 125 else: 126 # Python 3 127 return isinstance(obj, str) 128 129def to_text_string(obj, encoding=None): 130 """Convert `obj` to (unicode) text string""" 131 if PY2: 132 # Python 2 133 if encoding is None: 134 return unicode(obj) 135 else: 136 return unicode(obj, encoding) 137 else: 138 # Python 3 139 if encoding is None: 140 return str(obj) 141 elif isinstance(obj, str): 142 # In case this function is not used properly, this could happen 143 return obj 144 else: 145 return str(obj, encoding) 146 147def to_binary_string(obj, encoding=None): 148 """Convert `obj` to binary string (bytes in Python 3, str in Python 2)""" 149 if PY2: 150 # Python 2 151 if encoding is None: 152 return str(obj) 153 else: 154 return obj.encode(encoding) 155 else: 156 # Python 3 157 return bytes(obj, 'utf-8' if encoding is None else encoding) 158 159 160#============================================================================== 161# Function attributes 162#============================================================================== 163def get_func_code(func): 164 """Return function code object""" 165 if PY2: 166 # Python 2 167 return func.func_code 168 else: 169 # Python 3 170 return func.__code__ 171 172def get_func_name(func): 173 """Return function name""" 174 if PY2: 175 # Python 2 176 return func.func_name 177 else: 178 # Python 3 179 return func.__name__ 180 181def get_func_defaults(func): 182 """Return function default argument values""" 183 if PY2: 184 # Python 2 185 return func.func_defaults 186 else: 187 # Python 3 188 return func.__defaults__ 189 190 191#============================================================================== 192# Special method attributes 193#============================================================================== 194def get_meth_func(obj): 195 """Return method function object""" 196 if PY2: 197 # Python 2 198 return obj.im_func 199 else: 200 # Python 3 201 return obj.__func__ 202 203def get_meth_class_inst(obj): 204 """Return method class instance""" 205 if PY2: 206 # Python 2 207 return obj.im_self 208 else: 209 # Python 3 210 return obj.__self__ 211 212def get_meth_class(obj): 213 """Return method class""" 214 if PY2: 215 # Python 2 216 return obj.im_class 217 else: 218 # Python 3 219 return obj.__self__.__class__ 220 221 222#============================================================================== 223# Misc. 224#============================================================================== 225if PY2: 226 # Python 2 227 input = raw_input 228 getcwd = os.getcwdu 229 cmp = cmp 230 import string 231 str_lower = string.lower 232 from itertools import izip_longest as zip_longest 233else: 234 # Python 3 235 input = input 236 getcwd = os.getcwd 237 def cmp(a, b): 238 return (a > b) - (a < b) 239 str_lower = str.lower 240 from itertools import zip_longest 241 242def qbytearray_to_str(qba): 243 """Convert QByteArray object to str in a way compatible with Python 2/3""" 244 return str(bytes(qba.toHex().data()).decode()) 245 246# ============================================================================= 247# Dict funcs 248# ============================================================================= 249if PY3: 250 def iterkeys(d, **kw): 251 return iter(d.keys(**kw)) 252 253 def itervalues(d, **kw): 254 return iter(d.values(**kw)) 255 256 def iteritems(d, **kw): 257 return iter(d.items(**kw)) 258 259 def iterlists(d, **kw): 260 return iter(d.lists(**kw)) 261 262 viewkeys = operator.methodcaller("keys") 263 264 viewvalues = operator.methodcaller("values") 265 266 viewitems = operator.methodcaller("items") 267else: 268 def iterkeys(d, **kw): 269 return d.iterkeys(**kw) 270 271 def itervalues(d, **kw): 272 return d.itervalues(**kw) 273 274 def iteritems(d, **kw): 275 return d.iteritems(**kw) 276 277 def iterlists(d, **kw): 278 return d.iterlists(**kw) 279 280 viewkeys = operator.methodcaller("viewkeys") 281 282 viewvalues = operator.methodcaller("viewvalues") 283 284 viewitems = operator.methodcaller("viewitems") 285 286 287if __name__ == '__main__': 288 pass 289