misc.py 5.4 KB

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