Mercurial > repos > guerler > springsuite
comparison planemo/lib/python3.7/site-packages/future/utils/__init__.py @ 0:d30785e31577 draft
"planemo upload commit 6eee67778febed82ddd413c3ca40b3183a3898f1"
| author | guerler |
|---|---|
| date | Fri, 31 Jul 2020 00:18:57 -0400 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:d30785e31577 |
|---|---|
| 1 """ | |
| 2 A selection of cross-compatible functions for Python 2 and 3. | |
| 3 | |
| 4 This module exports useful functions for 2/3 compatible code: | |
| 5 | |
| 6 * bind_method: binds functions to classes | |
| 7 * ``native_str_to_bytes`` and ``bytes_to_native_str`` | |
| 8 * ``native_str``: always equal to the native platform string object (because | |
| 9 this may be shadowed by imports from future.builtins) | |
| 10 * lists: lrange(), lmap(), lzip(), lfilter() | |
| 11 * iterable method compatibility: | |
| 12 - iteritems, iterkeys, itervalues | |
| 13 - viewitems, viewkeys, viewvalues | |
| 14 | |
| 15 These use the original method if available, otherwise they use items, | |
| 16 keys, values. | |
| 17 | |
| 18 * types: | |
| 19 | |
| 20 * text_type: unicode in Python 2, str in Python 3 | |
| 21 * string_types: basestring in Python 2, str in Python 3 | |
| 22 * binary_type: str in Python 2, bytes in Python 3 | |
| 23 * integer_types: (int, long) in Python 2, int in Python 3 | |
| 24 * class_types: (type, types.ClassType) in Python 2, type in Python 3 | |
| 25 | |
| 26 * bchr(c): | |
| 27 Take an integer and make a 1-character byte string | |
| 28 * bord(c) | |
| 29 Take the result of indexing on a byte string and make an integer | |
| 30 * tobytes(s) | |
| 31 Take a text string, a byte string, or a sequence of characters taken | |
| 32 from a byte string, and make a byte string. | |
| 33 | |
| 34 * raise_from() | |
| 35 * raise_with_traceback() | |
| 36 | |
| 37 This module also defines these decorators: | |
| 38 | |
| 39 * ``python_2_unicode_compatible`` | |
| 40 * ``with_metaclass`` | |
| 41 * ``implements_iterator`` | |
| 42 | |
| 43 Some of the functions in this module come from the following sources: | |
| 44 | |
| 45 * Jinja2 (BSD licensed: see | |
| 46 https://github.com/mitsuhiko/jinja2/blob/master/LICENSE) | |
| 47 * Pandas compatibility module pandas.compat | |
| 48 * six.py by Benjamin Peterson | |
| 49 * Django | |
| 50 """ | |
| 51 | |
| 52 import types | |
| 53 import sys | |
| 54 import numbers | |
| 55 import functools | |
| 56 import copy | |
| 57 import inspect | |
| 58 | |
| 59 | |
| 60 PY3 = sys.version_info[0] >= 3 | |
| 61 PY34_PLUS = sys.version_info[0:2] >= (3, 4) | |
| 62 PY35_PLUS = sys.version_info[0:2] >= (3, 5) | |
| 63 PY36_PLUS = sys.version_info[0:2] >= (3, 6) | |
| 64 PY2 = sys.version_info[0] == 2 | |
| 65 PY26 = sys.version_info[0:2] == (2, 6) | |
| 66 PY27 = sys.version_info[0:2] == (2, 7) | |
| 67 PYPY = hasattr(sys, 'pypy_translation_info') | |
| 68 | |
| 69 | |
| 70 def python_2_unicode_compatible(cls): | |
| 71 """ | |
| 72 A decorator that defines __unicode__ and __str__ methods under Python | |
| 73 2. Under Python 3, this decorator is a no-op. | |
| 74 | |
| 75 To support Python 2 and 3 with a single code base, define a __str__ | |
| 76 method returning unicode text and apply this decorator to the class, like | |
| 77 this:: | |
| 78 | |
| 79 >>> from future.utils import python_2_unicode_compatible | |
| 80 | |
| 81 >>> @python_2_unicode_compatible | |
| 82 ... class MyClass(object): | |
| 83 ... def __str__(self): | |
| 84 ... return u'Unicode string: \u5b54\u5b50' | |
| 85 | |
| 86 >>> a = MyClass() | |
| 87 | |
| 88 Then, after this import: | |
| 89 | |
| 90 >>> from future.builtins import str | |
| 91 | |
| 92 the following is ``True`` on both Python 3 and 2:: | |
| 93 | |
| 94 >>> str(a) == a.encode('utf-8').decode('utf-8') | |
| 95 True | |
| 96 | |
| 97 and, on a Unicode-enabled terminal with the right fonts, these both print the | |
| 98 Chinese characters for Confucius:: | |
| 99 | |
| 100 >>> print(a) | |
| 101 >>> print(str(a)) | |
| 102 | |
| 103 The implementation comes from django.utils.encoding. | |
| 104 """ | |
| 105 if not PY3: | |
| 106 cls.__unicode__ = cls.__str__ | |
| 107 cls.__str__ = lambda self: self.__unicode__().encode('utf-8') | |
| 108 return cls | |
| 109 | |
| 110 | |
| 111 def with_metaclass(meta, *bases): | |
| 112 """ | |
| 113 Function from jinja2/_compat.py. License: BSD. | |
| 114 | |
| 115 Use it like this:: | |
| 116 | |
| 117 class BaseForm(object): | |
| 118 pass | |
| 119 | |
| 120 class FormType(type): | |
| 121 pass | |
| 122 | |
| 123 class Form(with_metaclass(FormType, BaseForm)): | |
| 124 pass | |
| 125 | |
| 126 This requires a bit of explanation: the basic idea is to make a | |
| 127 dummy metaclass for one level of class instantiation that replaces | |
| 128 itself with the actual metaclass. Because of internal type checks | |
| 129 we also need to make sure that we downgrade the custom metaclass | |
| 130 for one level to something closer to type (that's why __call__ and | |
| 131 __init__ comes back from type etc.). | |
| 132 | |
| 133 This has the advantage over six.with_metaclass of not introducing | |
| 134 dummy classes into the final MRO. | |
| 135 """ | |
| 136 class metaclass(meta): | |
| 137 __call__ = type.__call__ | |
| 138 __init__ = type.__init__ | |
| 139 def __new__(cls, name, this_bases, d): | |
| 140 if this_bases is None: | |
| 141 return type.__new__(cls, name, (), d) | |
| 142 return meta(name, bases, d) | |
| 143 return metaclass('temporary_class', None, {}) | |
| 144 | |
| 145 | |
| 146 # Definitions from pandas.compat and six.py follow: | |
| 147 if PY3: | |
| 148 def bchr(s): | |
| 149 return bytes([s]) | |
| 150 def bstr(s): | |
| 151 if isinstance(s, str): | |
| 152 return bytes(s, 'latin-1') | |
| 153 else: | |
| 154 return bytes(s) | |
| 155 def bord(s): | |
| 156 return s | |
| 157 | |
| 158 string_types = str, | |
| 159 integer_types = int, | |
| 160 class_types = type, | |
| 161 text_type = str | |
| 162 binary_type = bytes | |
| 163 | |
| 164 else: | |
| 165 # Python 2 | |
| 166 def bchr(s): | |
| 167 return chr(s) | |
| 168 def bstr(s): | |
| 169 return str(s) | |
| 170 def bord(s): | |
| 171 return ord(s) | |
| 172 | |
| 173 string_types = basestring, | |
| 174 integer_types = (int, long) | |
| 175 class_types = (type, types.ClassType) | |
| 176 text_type = unicode | |
| 177 binary_type = str | |
| 178 | |
| 179 ### | |
| 180 | |
| 181 if PY3: | |
| 182 def tobytes(s): | |
| 183 if isinstance(s, bytes): | |
| 184 return s | |
| 185 else: | |
| 186 if isinstance(s, str): | |
| 187 return s.encode('latin-1') | |
| 188 else: | |
| 189 return bytes(s) | |
| 190 else: | |
| 191 # Python 2 | |
| 192 def tobytes(s): | |
| 193 if isinstance(s, unicode): | |
| 194 return s.encode('latin-1') | |
| 195 else: | |
| 196 return ''.join(s) | |
| 197 | |
| 198 tobytes.__doc__ = """ | |
| 199 Encodes to latin-1 (where the first 256 chars are the same as | |
| 200 ASCII.) | |
| 201 """ | |
| 202 | |
| 203 if PY3: | |
| 204 def native_str_to_bytes(s, encoding='utf-8'): | |
| 205 return s.encode(encoding) | |
| 206 | |
| 207 def bytes_to_native_str(b, encoding='utf-8'): | |
| 208 return b.decode(encoding) | |
| 209 | |
| 210 def text_to_native_str(t, encoding=None): | |
| 211 return t | |
| 212 else: | |
| 213 # Python 2 | |
| 214 def native_str_to_bytes(s, encoding=None): | |
| 215 from future.types import newbytes # to avoid a circular import | |
| 216 return newbytes(s) | |
| 217 | |
| 218 def bytes_to_native_str(b, encoding=None): | |
| 219 return native(b) | |
| 220 | |
| 221 def text_to_native_str(t, encoding='ascii'): | |
| 222 """ | |
| 223 Use this to create a Py2 native string when "from __future__ import | |
| 224 unicode_literals" is in effect. | |
| 225 """ | |
| 226 return unicode(t).encode(encoding) | |
| 227 | |
| 228 native_str_to_bytes.__doc__ = """ | |
| 229 On Py3, returns an encoded string. | |
| 230 On Py2, returns a newbytes type, ignoring the ``encoding`` argument. | |
| 231 """ | |
| 232 | |
| 233 if PY3: | |
| 234 # list-producing versions of the major Python iterating functions | |
| 235 def lrange(*args, **kwargs): | |
| 236 return list(range(*args, **kwargs)) | |
| 237 | |
| 238 def lzip(*args, **kwargs): | |
| 239 return list(zip(*args, **kwargs)) | |
| 240 | |
| 241 def lmap(*args, **kwargs): | |
| 242 return list(map(*args, **kwargs)) | |
| 243 | |
| 244 def lfilter(*args, **kwargs): | |
| 245 return list(filter(*args, **kwargs)) | |
| 246 else: | |
| 247 import __builtin__ | |
| 248 # Python 2-builtin ranges produce lists | |
| 249 lrange = __builtin__.range | |
| 250 lzip = __builtin__.zip | |
| 251 lmap = __builtin__.map | |
| 252 lfilter = __builtin__.filter | |
| 253 | |
| 254 | |
| 255 def isidentifier(s, dotted=False): | |
| 256 ''' | |
| 257 A function equivalent to the str.isidentifier method on Py3 | |
| 258 ''' | |
| 259 if dotted: | |
| 260 return all(isidentifier(a) for a in s.split('.')) | |
| 261 if PY3: | |
| 262 return s.isidentifier() | |
| 263 else: | |
| 264 import re | |
| 265 _name_re = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*$") | |
| 266 return bool(_name_re.match(s)) | |
| 267 | |
| 268 | |
| 269 def viewitems(obj, **kwargs): | |
| 270 """ | |
| 271 Function for iterating over dictionary items with the same set-like | |
| 272 behaviour on Py2.7 as on Py3. | |
| 273 | |
| 274 Passes kwargs to method.""" | |
| 275 func = getattr(obj, "viewitems", None) | |
| 276 if not func: | |
| 277 func = obj.items | |
| 278 return func(**kwargs) | |
| 279 | |
| 280 | |
| 281 def viewkeys(obj, **kwargs): | |
| 282 """ | |
| 283 Function for iterating over dictionary keys with the same set-like | |
| 284 behaviour on Py2.7 as on Py3. | |
| 285 | |
| 286 Passes kwargs to method.""" | |
| 287 func = getattr(obj, "viewkeys", None) | |
| 288 if not func: | |
| 289 func = obj.keys | |
| 290 return func(**kwargs) | |
| 291 | |
| 292 | |
| 293 def viewvalues(obj, **kwargs): | |
| 294 """ | |
| 295 Function for iterating over dictionary values with the same set-like | |
| 296 behaviour on Py2.7 as on Py3. | |
| 297 | |
| 298 Passes kwargs to method.""" | |
| 299 func = getattr(obj, "viewvalues", None) | |
| 300 if not func: | |
| 301 func = obj.values | |
| 302 return func(**kwargs) | |
| 303 | |
| 304 | |
| 305 def iteritems(obj, **kwargs): | |
| 306 """Use this only if compatibility with Python versions before 2.7 is | |
| 307 required. Otherwise, prefer viewitems(). | |
| 308 """ | |
| 309 func = getattr(obj, "iteritems", None) | |
| 310 if not func: | |
| 311 func = obj.items | |
| 312 return func(**kwargs) | |
| 313 | |
| 314 | |
| 315 def iterkeys(obj, **kwargs): | |
| 316 """Use this only if compatibility with Python versions before 2.7 is | |
| 317 required. Otherwise, prefer viewkeys(). | |
| 318 """ | |
| 319 func = getattr(obj, "iterkeys", None) | |
| 320 if not func: | |
| 321 func = obj.keys | |
| 322 return func(**kwargs) | |
| 323 | |
| 324 | |
| 325 def itervalues(obj, **kwargs): | |
| 326 """Use this only if compatibility with Python versions before 2.7 is | |
| 327 required. Otherwise, prefer viewvalues(). | |
| 328 """ | |
| 329 func = getattr(obj, "itervalues", None) | |
| 330 if not func: | |
| 331 func = obj.values | |
| 332 return func(**kwargs) | |
| 333 | |
| 334 | |
| 335 def bind_method(cls, name, func): | |
| 336 """Bind a method to class, python 2 and python 3 compatible. | |
| 337 | |
| 338 Parameters | |
| 339 ---------- | |
| 340 | |
| 341 cls : type | |
| 342 class to receive bound method | |
| 343 name : basestring | |
| 344 name of method on class instance | |
| 345 func : function | |
| 346 function to be bound as method | |
| 347 | |
| 348 Returns | |
| 349 ------- | |
| 350 None | |
| 351 """ | |
| 352 # only python 2 has an issue with bound/unbound methods | |
| 353 if not PY3: | |
| 354 setattr(cls, name, types.MethodType(func, None, cls)) | |
| 355 else: | |
| 356 setattr(cls, name, func) | |
| 357 | |
| 358 | |
| 359 def getexception(): | |
| 360 return sys.exc_info()[1] | |
| 361 | |
| 362 | |
| 363 def _get_caller_globals_and_locals(): | |
| 364 """ | |
| 365 Returns the globals and locals of the calling frame. | |
| 366 | |
| 367 Is there an alternative to frame hacking here? | |
| 368 """ | |
| 369 caller_frame = inspect.stack()[2] | |
| 370 myglobals = caller_frame[0].f_globals | |
| 371 mylocals = caller_frame[0].f_locals | |
| 372 return myglobals, mylocals | |
| 373 | |
| 374 | |
| 375 def _repr_strip(mystring): | |
| 376 """ | |
| 377 Returns the string without any initial or final quotes. | |
| 378 """ | |
| 379 r = repr(mystring) | |
| 380 if r.startswith("'") and r.endswith("'"): | |
| 381 return r[1:-1] | |
| 382 else: | |
| 383 return r | |
| 384 | |
| 385 | |
| 386 if PY3: | |
| 387 def raise_from(exc, cause): | |
| 388 """ | |
| 389 Equivalent to: | |
| 390 | |
| 391 raise EXCEPTION from CAUSE | |
| 392 | |
| 393 on Python 3. (See PEP 3134). | |
| 394 """ | |
| 395 myglobals, mylocals = _get_caller_globals_and_locals() | |
| 396 | |
| 397 # We pass the exception and cause along with other globals | |
| 398 # when we exec(): | |
| 399 myglobals = myglobals.copy() | |
| 400 myglobals['__python_future_raise_from_exc'] = exc | |
| 401 myglobals['__python_future_raise_from_cause'] = cause | |
| 402 execstr = "raise __python_future_raise_from_exc from __python_future_raise_from_cause" | |
| 403 exec(execstr, myglobals, mylocals) | |
| 404 | |
| 405 def raise_(tp, value=None, tb=None): | |
| 406 """ | |
| 407 A function that matches the Python 2.x ``raise`` statement. This | |
| 408 allows re-raising exceptions with the cls value and traceback on | |
| 409 Python 2 and 3. | |
| 410 """ | |
| 411 if isinstance(tp, BaseException): | |
| 412 # If the first object is an instance, the type of the exception | |
| 413 # is the class of the instance, the instance itself is the value, | |
| 414 # and the second object must be None. | |
| 415 if value is not None: | |
| 416 raise TypeError("instance exception may not have a separate value") | |
| 417 exc = tp | |
| 418 elif isinstance(tp, type) and not issubclass(tp, BaseException): | |
| 419 # If the first object is a class, it becomes the type of the | |
| 420 # exception. | |
| 421 raise TypeError("class must derive from BaseException, not %s" % tp.__name__) | |
| 422 else: | |
| 423 # The second object is used to determine the exception value: If it | |
| 424 # is an instance of the class, the instance becomes the exception | |
| 425 # value. If the second object is a tuple, it is used as the argument | |
| 426 # list for the class constructor; if it is None, an empty argument | |
| 427 # list is used, and any other object is treated as a single argument | |
| 428 # to the constructor. The instance so created by calling the | |
| 429 # constructor is used as the exception value. | |
| 430 if isinstance(value, tp): | |
| 431 exc = value | |
| 432 elif isinstance(value, tuple): | |
| 433 exc = tp(*value) | |
| 434 elif value is None: | |
| 435 exc = tp() | |
| 436 else: | |
| 437 exc = tp(value) | |
| 438 | |
| 439 if exc.__traceback__ is not tb: | |
| 440 raise exc.with_traceback(tb) | |
| 441 raise exc | |
| 442 | |
| 443 def raise_with_traceback(exc, traceback=Ellipsis): | |
| 444 if traceback == Ellipsis: | |
| 445 _, _, traceback = sys.exc_info() | |
| 446 raise exc.with_traceback(traceback) | |
| 447 | |
| 448 else: | |
| 449 def raise_from(exc, cause): | |
| 450 """ | |
| 451 Equivalent to: | |
| 452 | |
| 453 raise EXCEPTION from CAUSE | |
| 454 | |
| 455 on Python 3. (See PEP 3134). | |
| 456 """ | |
| 457 # Is either arg an exception class (e.g. IndexError) rather than | |
| 458 # instance (e.g. IndexError('my message here')? If so, pass the | |
| 459 # name of the class undisturbed through to "raise ... from ...". | |
| 460 if isinstance(exc, type) and issubclass(exc, Exception): | |
| 461 e = exc() | |
| 462 # exc = exc.__name__ | |
| 463 # execstr = "e = " + _repr_strip(exc) + "()" | |
| 464 # myglobals, mylocals = _get_caller_globals_and_locals() | |
| 465 # exec(execstr, myglobals, mylocals) | |
| 466 else: | |
| 467 e = exc | |
| 468 e.__suppress_context__ = False | |
| 469 if isinstance(cause, type) and issubclass(cause, Exception): | |
| 470 e.__cause__ = cause() | |
| 471 e.__cause__.__traceback__ = sys.exc_info()[2] | |
| 472 e.__suppress_context__ = True | |
| 473 elif cause is None: | |
| 474 e.__cause__ = None | |
| 475 e.__suppress_context__ = True | |
| 476 elif isinstance(cause, BaseException): | |
| 477 e.__cause__ = cause | |
| 478 object.__setattr__(e.__cause__, '__traceback__', sys.exc_info()[2]) | |
| 479 e.__suppress_context__ = True | |
| 480 else: | |
| 481 raise TypeError("exception causes must derive from BaseException") | |
| 482 e.__context__ = sys.exc_info()[1] | |
| 483 raise e | |
| 484 | |
| 485 exec(''' | |
| 486 def raise_(tp, value=None, tb=None): | |
| 487 raise tp, value, tb | |
| 488 | |
| 489 def raise_with_traceback(exc, traceback=Ellipsis): | |
| 490 if traceback == Ellipsis: | |
| 491 _, _, traceback = sys.exc_info() | |
| 492 raise exc, None, traceback | |
| 493 '''.strip()) | |
| 494 | |
| 495 | |
| 496 raise_with_traceback.__doc__ = ( | |
| 497 """Raise exception with existing traceback. | |
| 498 If traceback is not passed, uses sys.exc_info() to get traceback.""" | |
| 499 ) | |
| 500 | |
| 501 | |
| 502 # Deprecated alias for backward compatibility with ``future`` versions < 0.11: | |
| 503 reraise = raise_ | |
| 504 | |
| 505 | |
| 506 def implements_iterator(cls): | |
| 507 ''' | |
| 508 From jinja2/_compat.py. License: BSD. | |
| 509 | |
| 510 Use as a decorator like this:: | |
| 511 | |
| 512 @implements_iterator | |
| 513 class UppercasingIterator(object): | |
| 514 def __init__(self, iterable): | |
| 515 self._iter = iter(iterable) | |
| 516 def __iter__(self): | |
| 517 return self | |
| 518 def __next__(self): | |
| 519 return next(self._iter).upper() | |
| 520 | |
| 521 ''' | |
| 522 if PY3: | |
| 523 return cls | |
| 524 else: | |
| 525 cls.next = cls.__next__ | |
| 526 del cls.__next__ | |
| 527 return cls | |
| 528 | |
| 529 if PY3: | |
| 530 get_next = lambda x: x.next | |
| 531 else: | |
| 532 get_next = lambda x: x.__next__ | |
| 533 | |
| 534 | |
| 535 def encode_filename(filename): | |
| 536 if PY3: | |
| 537 return filename | |
| 538 else: | |
| 539 if isinstance(filename, unicode): | |
| 540 return filename.encode('utf-8') | |
| 541 return filename | |
| 542 | |
| 543 | |
| 544 def is_new_style(cls): | |
| 545 """ | |
| 546 Python 2.7 has both new-style and old-style classes. Old-style classes can | |
| 547 be pesky in some circumstances, such as when using inheritance. Use this | |
| 548 function to test for whether a class is new-style. (Python 3 only has | |
| 549 new-style classes.) | |
| 550 """ | |
| 551 return hasattr(cls, '__class__') and ('__dict__' in dir(cls) | |
| 552 or hasattr(cls, '__slots__')) | |
| 553 | |
| 554 # The native platform string and bytes types. Useful because ``str`` and | |
| 555 # ``bytes`` are redefined on Py2 by ``from future.builtins import *``. | |
| 556 native_str = str | |
| 557 native_bytes = bytes | |
| 558 | |
| 559 | |
| 560 def istext(obj): | |
| 561 """ | |
| 562 Deprecated. Use:: | |
| 563 >>> isinstance(obj, str) | |
| 564 after this import: | |
| 565 >>> from future.builtins import str | |
| 566 """ | |
| 567 return isinstance(obj, type(u'')) | |
| 568 | |
| 569 | |
| 570 def isbytes(obj): | |
| 571 """ | |
| 572 Deprecated. Use:: | |
| 573 >>> isinstance(obj, bytes) | |
| 574 after this import: | |
| 575 >>> from future.builtins import bytes | |
| 576 """ | |
| 577 return isinstance(obj, type(b'')) | |
| 578 | |
| 579 | |
| 580 def isnewbytes(obj): | |
| 581 """ | |
| 582 Equivalent to the result of ``type(obj) == type(newbytes)`` | |
| 583 in other words, it is REALLY a newbytes instance, not a Py2 native str | |
| 584 object? | |
| 585 | |
| 586 Note that this does not cover subclasses of newbytes, and it is not | |
| 587 equivalent to ininstance(obj, newbytes) | |
| 588 """ | |
| 589 return type(obj).__name__ == 'newbytes' | |
| 590 | |
| 591 | |
| 592 def isint(obj): | |
| 593 """ | |
| 594 Deprecated. Tests whether an object is a Py3 ``int`` or either a Py2 ``int`` or | |
| 595 ``long``. | |
| 596 | |
| 597 Instead of using this function, you can use: | |
| 598 | |
| 599 >>> from future.builtins import int | |
| 600 >>> isinstance(obj, int) | |
| 601 | |
| 602 The following idiom is equivalent: | |
| 603 | |
| 604 >>> from numbers import Integral | |
| 605 >>> isinstance(obj, Integral) | |
| 606 """ | |
| 607 | |
| 608 return isinstance(obj, numbers.Integral) | |
| 609 | |
| 610 | |
| 611 def native(obj): | |
| 612 """ | |
| 613 On Py3, this is a no-op: native(obj) -> obj | |
| 614 | |
| 615 On Py2, returns the corresponding native Py2 types that are | |
| 616 superclasses for backported objects from Py3: | |
| 617 | |
| 618 >>> from builtins import str, bytes, int | |
| 619 | |
| 620 >>> native(str(u'ABC')) | |
| 621 u'ABC' | |
| 622 >>> type(native(str(u'ABC'))) | |
| 623 unicode | |
| 624 | |
| 625 >>> native(bytes(b'ABC')) | |
| 626 b'ABC' | |
| 627 >>> type(native(bytes(b'ABC'))) | |
| 628 bytes | |
| 629 | |
| 630 >>> native(int(10**20)) | |
| 631 100000000000000000000L | |
| 632 >>> type(native(int(10**20))) | |
| 633 long | |
| 634 | |
| 635 Existing native types on Py2 will be returned unchanged: | |
| 636 | |
| 637 >>> type(native(u'ABC')) | |
| 638 unicode | |
| 639 """ | |
| 640 if hasattr(obj, '__native__'): | |
| 641 return obj.__native__() | |
| 642 else: | |
| 643 return obj | |
| 644 | |
| 645 | |
| 646 # Implementation of exec_ is from ``six``: | |
| 647 if PY3: | |
| 648 import builtins | |
| 649 exec_ = getattr(builtins, "exec") | |
| 650 else: | |
| 651 def exec_(code, globs=None, locs=None): | |
| 652 """Execute code in a namespace.""" | |
| 653 if globs is None: | |
| 654 frame = sys._getframe(1) | |
| 655 globs = frame.f_globals | |
| 656 if locs is None: | |
| 657 locs = frame.f_locals | |
| 658 del frame | |
| 659 elif locs is None: | |
| 660 locs = globs | |
| 661 exec("""exec code in globs, locs""") | |
| 662 | |
| 663 | |
| 664 # Defined here for backward compatibility: | |
| 665 def old_div(a, b): | |
| 666 """ | |
| 667 DEPRECATED: import ``old_div`` from ``past.utils`` instead. | |
| 668 | |
| 669 Equivalent to ``a / b`` on Python 2 without ``from __future__ import | |
| 670 division``. | |
| 671 | |
| 672 TODO: generalize this to other objects (like arrays etc.) | |
| 673 """ | |
| 674 if isinstance(a, numbers.Integral) and isinstance(b, numbers.Integral): | |
| 675 return a // b | |
| 676 else: | |
| 677 return a / b | |
| 678 | |
| 679 | |
| 680 def as_native_str(encoding='utf-8'): | |
| 681 ''' | |
| 682 A decorator to turn a function or method call that returns text, i.e. | |
| 683 unicode, into one that returns a native platform str. | |
| 684 | |
| 685 Use it as a decorator like this:: | |
| 686 | |
| 687 from __future__ import unicode_literals | |
| 688 | |
| 689 class MyClass(object): | |
| 690 @as_native_str(encoding='ascii') | |
| 691 def __repr__(self): | |
| 692 return next(self._iter).upper() | |
| 693 ''' | |
| 694 if PY3: | |
| 695 return lambda f: f | |
| 696 else: | |
| 697 def encoder(f): | |
| 698 @functools.wraps(f) | |
| 699 def wrapper(*args, **kwargs): | |
| 700 return f(*args, **kwargs).encode(encoding=encoding) | |
| 701 return wrapper | |
| 702 return encoder | |
| 703 | |
| 704 # listvalues and listitems definitions from Nick Coghlan's (withdrawn) | |
| 705 # PEP 496: | |
| 706 try: | |
| 707 dict.iteritems | |
| 708 except AttributeError: | |
| 709 # Python 3 | |
| 710 def listvalues(d): | |
| 711 return list(d.values()) | |
| 712 def listitems(d): | |
| 713 return list(d.items()) | |
| 714 else: | |
| 715 # Python 2 | |
| 716 def listvalues(d): | |
| 717 return d.values() | |
| 718 def listitems(d): | |
| 719 return d.items() | |
| 720 | |
| 721 if PY3: | |
| 722 def ensure_new_type(obj): | |
| 723 return obj | |
| 724 else: | |
| 725 def ensure_new_type(obj): | |
| 726 from future.types.newbytes import newbytes | |
| 727 from future.types.newstr import newstr | |
| 728 from future.types.newint import newint | |
| 729 from future.types.newdict import newdict | |
| 730 | |
| 731 native_type = type(native(obj)) | |
| 732 | |
| 733 # Upcast only if the type is already a native (non-future) type | |
| 734 if issubclass(native_type, type(obj)): | |
| 735 # Upcast | |
| 736 if native_type == str: # i.e. Py2 8-bit str | |
| 737 return newbytes(obj) | |
| 738 elif native_type == unicode: | |
| 739 return newstr(obj) | |
| 740 elif native_type == int: | |
| 741 return newint(obj) | |
| 742 elif native_type == long: | |
| 743 return newint(obj) | |
| 744 elif native_type == dict: | |
| 745 return newdict(obj) | |
| 746 else: | |
| 747 return obj | |
| 748 else: | |
| 749 # Already a new type | |
| 750 assert type(obj) in [newbytes, newstr] | |
| 751 return obj | |
| 752 | |
| 753 | |
| 754 __all__ = ['PY2', 'PY26', 'PY3', 'PYPY', | |
| 755 'as_native_str', 'binary_type', 'bind_method', 'bord', 'bstr', | |
| 756 'bytes_to_native_str', 'class_types', 'encode_filename', | |
| 757 'ensure_new_type', 'exec_', 'get_next', 'getexception', | |
| 758 'implements_iterator', 'integer_types', 'is_new_style', 'isbytes', | |
| 759 'isidentifier', 'isint', 'isnewbytes', 'istext', 'iteritems', | |
| 760 'iterkeys', 'itervalues', 'lfilter', 'listitems', 'listvalues', | |
| 761 'lmap', 'lrange', 'lzip', 'native', 'native_bytes', 'native_str', | |
| 762 'native_str_to_bytes', 'old_div', | |
| 763 'python_2_unicode_compatible', 'raise_', | |
| 764 'raise_with_traceback', 'reraise', 'string_types', | |
| 765 'text_to_native_str', 'text_type', 'tobytes', 'viewitems', | |
| 766 'viewkeys', 'viewvalues', 'with_metaclass' | |
| 767 ] |
