misc.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. from __future__ import unicode_literals
  2. import inspect
  3. import sys
  4. import math
  5. import numbers
  6. from future.utils import PY2, PY3, exec_
  7. if PY2:
  8. from collections import Mapping
  9. else:
  10. from collections.abc import Mapping
  11. if PY3:
  12. import builtins
  13. from collections.abc import Mapping
  14. def apply(f, *args, **kw):
  15. return f(*args, **kw)
  16. from past.builtins import str as oldstr
  17. def chr(i):
  18. """
  19. Return a byte-string of one character with ordinal i; 0 <= i <= 256
  20. """
  21. return oldstr(bytes((i,)))
  22. def cmp(x, y):
  23. """
  24. cmp(x, y) -> integer
  25. Return negative if x<y, zero if x==y, positive if x>y.
  26. Python2 had looser comparison allowing cmp None and non Numerical types and collections.
  27. Try to match the old behavior
  28. """
  29. if isinstance(x, set) and isinstance(y, set):
  30. raise TypeError('cannot compare sets using cmp()',)
  31. try:
  32. if isinstance(x, numbers.Number) and math.isnan(x):
  33. if not isinstance(y, numbers.Number):
  34. raise TypeError('cannot compare float("nan"), {type_y} with cmp'.format(type_y=type(y)))
  35. if isinstance(y, int):
  36. return 1
  37. else:
  38. return -1
  39. if isinstance(y, numbers.Number) and math.isnan(y):
  40. if not isinstance(x, numbers.Number):
  41. raise TypeError('cannot compare {type_x}, float("nan") with cmp'.format(type_x=type(x)))
  42. if isinstance(x, int):
  43. return -1
  44. else:
  45. return 1
  46. return (x > y) - (x < y)
  47. except TypeError:
  48. if x == y:
  49. return 0
  50. type_order = [
  51. type(None),
  52. numbers.Number,
  53. dict, list,
  54. set,
  55. (str, bytes),
  56. ]
  57. x_type_index = y_type_index = None
  58. for i, type_match in enumerate(type_order):
  59. if isinstance(x, type_match):
  60. x_type_index = i
  61. if isinstance(y, type_match):
  62. y_type_index = i
  63. if cmp(x_type_index, y_type_index) == 0:
  64. if isinstance(x, bytes) and isinstance(y, str):
  65. return cmp(x.decode('ascii'), y)
  66. if isinstance(y, bytes) and isinstance(x, str):
  67. return cmp(x, y.decode('ascii'))
  68. elif isinstance(x, list):
  69. # if both arguments are lists take the comparison of the first non equal value
  70. for x_elem, y_elem in zip(x, y):
  71. elem_cmp_val = cmp(x_elem, y_elem)
  72. if elem_cmp_val != 0:
  73. return elem_cmp_val
  74. # if all elements are equal, return equal/0
  75. return 0
  76. elif isinstance(x, dict):
  77. if len(x) != len(y):
  78. return cmp(len(x), len(y))
  79. else:
  80. x_key = min(a for a in x if a not in y or x[a] != y[a])
  81. y_key = min(b for b in y if b not in x or x[b] != y[b])
  82. if x_key != y_key:
  83. return cmp(x_key, y_key)
  84. else:
  85. return cmp(x[x_key], y[y_key])
  86. return cmp(x_type_index, y_type_index)
  87. from sys import intern
  88. def oct(number):
  89. """oct(number) -> string
  90. Return the octal representation of an integer
  91. """
  92. return '0' + builtins.oct(number)[2:]
  93. raw_input = input
  94. # imp was deprecated in python 3.6
  95. if sys.version_info >= (3, 6):
  96. from importlib import reload
  97. else:
  98. # for python2, python3 <= 3.4
  99. from imp import reload
  100. unicode = str
  101. unichr = chr
  102. xrange = range
  103. else:
  104. import __builtin__
  105. from collections import Mapping
  106. apply = __builtin__.apply
  107. chr = __builtin__.chr
  108. cmp = __builtin__.cmp
  109. execfile = __builtin__.execfile
  110. intern = __builtin__.intern
  111. oct = __builtin__.oct
  112. raw_input = __builtin__.raw_input
  113. reload = __builtin__.reload
  114. unicode = __builtin__.unicode
  115. unichr = __builtin__.unichr
  116. xrange = __builtin__.xrange
  117. if PY3:
  118. def execfile(filename, myglobals=None, mylocals=None):
  119. """
  120. Read and execute a Python script from a file in the given namespaces.
  121. The globals and locals are dictionaries, defaulting to the current
  122. globals and locals. If only globals is given, locals defaults to it.
  123. """
  124. if myglobals is None:
  125. # There seems to be no alternative to frame hacking here.
  126. caller_frame = inspect.stack()[1]
  127. myglobals = caller_frame[0].f_globals
  128. mylocals = caller_frame[0].f_locals
  129. elif mylocals is None:
  130. # Only if myglobals is given do we set mylocals to it.
  131. mylocals = myglobals
  132. if not isinstance(myglobals, Mapping):
  133. raise TypeError('globals must be a mapping')
  134. if not isinstance(mylocals, Mapping):
  135. raise TypeError('locals must be a mapping')
  136. with open(filename, "rb") as fin:
  137. source = fin.read()
  138. code = compile(source, filename, "exec")
  139. exec_(code, myglobals, mylocals)
  140. if PY3:
  141. __all__ = ['apply', 'chr', 'cmp', 'execfile', 'intern', 'raw_input',
  142. 'reload', 'unichr', 'unicode', 'xrange']
  143. else:
  144. __all__ = []