__init__.py 2.6 KB

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