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