OLD | NEW |
(Empty) | |
| 1 """ |
| 2 Various non-built-in utility functions and definitions for Py2 |
| 3 compatibility in Py3. |
| 4 |
| 5 For example: |
| 6 |
| 7 >>> # The old_div() function behaves like Python 2's / operator |
| 8 >>> # without "from __future__ import division" |
| 9 >>> from past.utils import old_div |
| 10 >>> old_div(3, 2) # like 3/2 in Py2 |
| 11 0 |
| 12 >>> old_div(3, 2.0) # like 3/2.0 in Py2 |
| 13 1.5 |
| 14 """ |
| 15 |
| 16 import sys |
| 17 import numbers |
| 18 |
| 19 PY3 = sys.version_info[0] == 3 |
| 20 PY2 = sys.version_info[0] == 2 |
| 21 PYPY = hasattr(sys, 'pypy_translation_info') |
| 22 |
| 23 |
| 24 def with_metaclass(meta, *bases): |
| 25 """ |
| 26 Function from jinja2/_compat.py. License: BSD. |
| 27 |
| 28 Use it like this:: |
| 29 |
| 30 class BaseForm(object): |
| 31 pass |
| 32 |
| 33 class FormType(type): |
| 34 pass |
| 35 |
| 36 class Form(with_metaclass(FormType, BaseForm)): |
| 37 pass |
| 38 |
| 39 This requires a bit of explanation: the basic idea is to make a |
| 40 dummy metaclass for one level of class instantiation that replaces |
| 41 itself with the actual metaclass. Because of internal type checks |
| 42 we also need to make sure that we downgrade the custom metaclass |
| 43 for one level to something closer to type (that's why __call__ and |
| 44 __init__ comes back from type etc.). |
| 45 |
| 46 This has the advantage over six.with_metaclass of not introducing |
| 47 dummy classes into the final MRO. |
| 48 """ |
| 49 class metaclass(meta): |
| 50 __call__ = type.__call__ |
| 51 __init__ = type.__init__ |
| 52 def __new__(cls, name, this_bases, d): |
| 53 if this_bases is None: |
| 54 return type.__new__(cls, name, (), d) |
| 55 return meta(name, bases, d) |
| 56 return metaclass('temporary_class', None, {}) |
| 57 |
| 58 |
| 59 def native(obj): |
| 60 """ |
| 61 On Py2, this is a no-op: native(obj) -> obj |
| 62 |
| 63 On Py3, returns the corresponding native Py3 types that are |
| 64 superclasses for forward-ported objects from Py2: |
| 65 |
| 66 >>> from past.builtins import str, dict |
| 67 |
| 68 >>> native(str(b'ABC')) # Output on Py3 follows. On Py2, output is 'ABC' |
| 69 b'ABC' |
| 70 >>> type(native(str(b'ABC'))) |
| 71 bytes |
| 72 |
| 73 Existing native types on Py3 will be returned unchanged: |
| 74 |
| 75 >>> type(native(b'ABC')) |
| 76 bytes |
| 77 """ |
| 78 if hasattr(obj, '__native__'): |
| 79 return obj.__native__() |
| 80 else: |
| 81 return obj |
| 82 |
| 83 |
| 84 # An alias for future.utils.old_div(): |
| 85 def old_div(a, b): |
| 86 """ |
| 87 Equivalent to ``a / b`` on Python 2 without ``from __future__ import |
| 88 division``. |
| 89 |
| 90 TODO: generalize this to other objects (like arrays etc.) |
| 91 """ |
| 92 if isinstance(a, numbers.Integral) and isinstance(b, numbers.Integral): |
| 93 return a // b |
| 94 else: |
| 95 return a / b |
| 96 |
| 97 __all__ = ['PY3', 'PY2', 'PYPY', 'with_metaclass', 'native', 'old_div'] |
OLD | NEW |