This repo contains code to mirror other repos. It also contains the code that is getting mirrored.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

242 lines
6.1 KiB

  1. import sys
  2. from collections import deque
  3. class fzset(frozenset):
  4. def __repr__(self):
  5. return '{%s}' % ', '.join(map(repr, self))
  6. def classify_bool(seq, pred):
  7. true_elems = []
  8. false_elems = []
  9. for elem in seq:
  10. if pred(elem):
  11. true_elems.append(elem)
  12. else:
  13. false_elems.append(elem)
  14. return true_elems, false_elems
  15. def bfs(initial, expand):
  16. open_q = deque(list(initial))
  17. visited = set(open_q)
  18. while open_q:
  19. node = open_q.popleft()
  20. yield node
  21. for next_node in expand(node):
  22. if next_node not in visited:
  23. visited.add(next_node)
  24. open_q.append(next_node)
  25. def _serialize(value, memo):
  26. # if memo and memo.in_types(value):
  27. # return {'__memo__': memo.memoized.get(value)}
  28. if isinstance(value, Serialize):
  29. return value.serialize(memo)
  30. elif isinstance(value, list):
  31. return [_serialize(elem, memo) for elem in value]
  32. elif isinstance(value, frozenset):
  33. return list(value) # TODO reversible?
  34. elif isinstance(value, dict):
  35. return {key:_serialize(elem, memo) for key, elem in value.items()}
  36. return value
  37. ###{standalone
  38. def classify(seq, key=None, value=None):
  39. d = {}
  40. for item in seq:
  41. k = key(item) if (key is not None) else item
  42. v = value(item) if (value is not None) else item
  43. if k in d:
  44. d[k].append(v)
  45. else:
  46. d[k] = [v]
  47. return d
  48. def _deserialize(data, namespace, memo):
  49. if isinstance(data, dict):
  50. if '__type__' in data: # Object
  51. class_ = namespace[data['__type__']]
  52. return class_.deserialize(data, memo)
  53. elif '@' in data:
  54. return memo[data['@']]
  55. return {key:_deserialize(value, namespace, memo) for key, value in data.items()}
  56. elif isinstance(data, list):
  57. return [_deserialize(value, namespace, memo) for value in data]
  58. return data
  59. class Serialize(object):
  60. def memo_serialize(self, types_to_memoize):
  61. memo = SerializeMemoizer(types_to_memoize)
  62. return self.serialize(memo), memo.serialize()
  63. def serialize(self, memo=None):
  64. if memo and memo.in_types(self):
  65. return {'@': memo.memoized.get(self)}
  66. fields = getattr(self, '__serialize_fields__')
  67. res = {f: _serialize(getattr(self, f), memo) for f in fields}
  68. res['__type__'] = type(self).__name__
  69. postprocess = getattr(self, '_serialize', None)
  70. if postprocess:
  71. postprocess(res, memo)
  72. return res
  73. @classmethod
  74. def deserialize(cls, data, memo):
  75. namespace = getattr(cls, '__serialize_namespace__', {})
  76. namespace = {c.__name__:c for c in namespace}
  77. fields = getattr(cls, '__serialize_fields__')
  78. if '@' in data:
  79. return memo[data['@']]
  80. inst = cls.__new__(cls)
  81. for f in fields:
  82. try:
  83. setattr(inst, f, _deserialize(data[f], namespace, memo))
  84. except KeyError as e:
  85. raise KeyError("Cannot find key for class", cls, e)
  86. postprocess = getattr(inst, '_deserialize', None)
  87. if postprocess:
  88. postprocess()
  89. return inst
  90. class SerializeMemoizer(Serialize):
  91. __serialize_fields__ = 'memoized',
  92. def __init__(self, types_to_memoize):
  93. self.types_to_memoize = tuple(types_to_memoize)
  94. self.memoized = Enumerator()
  95. def in_types(self, value):
  96. return isinstance(value, self.types_to_memoize)
  97. def serialize(self):
  98. return _serialize(self.memoized.reversed(), None)
  99. @classmethod
  100. def deserialize(cls, data, namespace, memo):
  101. return _deserialize(data, namespace, memo)
  102. try:
  103. STRING_TYPE = basestring
  104. except NameError: # Python 3
  105. STRING_TYPE = str
  106. import types
  107. from functools import wraps, partial
  108. from contextlib import contextmanager
  109. Str = type(u'')
  110. try:
  111. classtype = types.ClassType # Python2
  112. except AttributeError:
  113. classtype = type # Python3
  114. def smart_decorator(f, create_decorator):
  115. if isinstance(f, types.FunctionType):
  116. return wraps(f)(create_decorator(f, True))
  117. elif isinstance(f, (classtype, type, types.BuiltinFunctionType)):
  118. return wraps(f)(create_decorator(f, False))
  119. elif isinstance(f, types.MethodType):
  120. return wraps(f)(create_decorator(f.__func__, True))
  121. elif isinstance(f, partial):
  122. # wraps does not work for partials in 2.7: https://bugs.python.org/issue3445
  123. return wraps(f.func)(create_decorator(lambda *args, **kw: f(*args[1:], **kw), True))
  124. else:
  125. return create_decorator(f.__func__.__call__, True)
  126. import sys, re
  127. Py36 = (sys.version_info[:2] >= (3, 6))
  128. import sre_parse
  129. import sre_constants
  130. def get_regexp_width(regexp):
  131. try:
  132. return [int(x) for x in sre_parse.parse(regexp).getwidth()]
  133. except sre_constants.error:
  134. raise ValueError(regexp)
  135. ###}
  136. def dedup_list(l):
  137. """Given a list (l) will removing duplicates from the list,
  138. preserving the original order of the list. Assumes that
  139. the list entrie are hashable."""
  140. dedup = set()
  141. return [ x for x in l if not (x in dedup or dedup.add(x))]
  142. try:
  143. from contextlib import suppress # Python 3
  144. except ImportError:
  145. @contextmanager
  146. def suppress(*excs):
  147. '''Catch and dismiss the provided exception
  148. >>> x = 'hello'
  149. >>> with suppress(IndexError):
  150. ... x = x[10]
  151. >>> x
  152. 'hello'
  153. '''
  154. try:
  155. yield
  156. except excs:
  157. pass
  158. try:
  159. compare = cmp
  160. except NameError:
  161. def compare(a, b):
  162. if a == b:
  163. return 0
  164. elif a > b:
  165. return 1
  166. return -1
  167. class Enumerator(Serialize):
  168. def __init__(self):
  169. self.enums = {}
  170. def get(self, item):
  171. if item not in self.enums:
  172. self.enums[item] = len(self.enums)
  173. return self.enums[item]
  174. def __len__(self):
  175. return len(self.enums)
  176. def reversed(self):
  177. r = {v: k for k, v in self.enums.items()}
  178. assert len(r) == len(self.enums)
  179. return r