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