/PyInstaller/lib/altgraph/compat.py

https://bitbucket.org/pyinstaller/pyinstaller-cleanup
Python | 189 lines | 142 code | 28 blank | 19 comment | 37 complexity | 32c78d900af29ff950eef1d642f7bae6 MD5 | raw file
  1. """
  2. Python 2.4-like compatibility library for Python 2.3
  3. """
  4. from itertools import izip, imap
  5. try:
  6. from itertools import tee, groupby
  7. except ImportError:
  8. pass
  9. #
  10. # builtins from 2.4
  11. #
  12. try:
  13. set, frozenset
  14. except NameError:
  15. from sets import Set as set, ImmutableSet as frozenset
  16. try:
  17. sorted
  18. except NameError:
  19. def sorted(iterable, cmp=None, key=None, reverse=False):
  20. if key is not None:
  21. a, b = tee(iterable)
  22. iterable = izip(imap(key, iterable), iterable)
  23. if cmp is not None:
  24. iterable = list(iterable)
  25. iterable.sort(cmp)
  26. else:
  27. iterable = isorted(iterable)
  28. if key is not None:
  29. iterable = [v for (k,v) in iterable]
  30. if type(iterable) is not list:
  31. iterable = list(iterable)
  32. if reverse:
  33. iterable.reverse()
  34. return iterable
  35. try:
  36. reversed
  37. except NameError:
  38. def reversed(iterable):
  39. lst = list(iterable)
  40. pop = lst.pop
  41. while lst:
  42. yield pop()
  43. #
  44. # itertools functions from 2.4
  45. #
  46. try:
  47. tee
  48. except NameError:
  49. def tee(iterable, n=2):
  50. def gen(next, data={}, cnt=[0]):
  51. for i in count():
  52. if i == cnt[0]:
  53. item = data[i] = next()
  54. cnt[0] += 1
  55. else:
  56. item = data.pop(i)
  57. yield item
  58. return tuple(imap(gen, repeat(iter(iterable), n)))
  59. try:
  60. groupby
  61. except NameError:
  62. class groupby(object):
  63. def __init__(self, iterable, key=None):
  64. if key is None:
  65. key = lambda x: x
  66. self.keyfunc = key
  67. self.it = iter(iterable)
  68. self.tgtkey = self.currkey = self.currvalue = xrange(0)
  69. def __iter__(self):
  70. return self
  71. def next(self):
  72. while self.currkey == self.tgtkey:
  73. self.currvalue = self.it.next() # Exit on StopIteration
  74. self.currkey = self.keyfunc(self.currvalue)
  75. self.tgtkey = self.currkey
  76. return (self.currkey, self._grouper(self.tgtkey))
  77. def _grouper(self, tgtkey):
  78. while self.currkey == tgtkey:
  79. yield self.currvalue
  80. self.currvalue = self.it.next() # Exit on StopIteration
  81. self.currkey = self.keyfunc(self.currvalue)
  82. #
  83. # operators from 2.4
  84. #
  85. try:
  86. from operator import attrgetter, itemgetter
  87. except ImportError:
  88. def attrgetter(attr):
  89. def attrgetter(obj):
  90. return getattr(obj, attr)
  91. return attrgetter
  92. def itemgetter(item):
  93. def itemgetter(obj):
  94. return obj[item]
  95. return itemgetter
  96. #
  97. # deque from 2.4's collections
  98. # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/259179/
  99. #
  100. try:
  101. from collections import deque
  102. except ImportError:
  103. class deque(object):
  104. def __init__(self, iterable=()):
  105. self.data = dict(enumerate(iterable))
  106. self.left = 0
  107. self.right = len(self.data)
  108. def append(self, x):
  109. self.data[self.right] = x
  110. self.right += 1
  111. def appendleft(self, x):
  112. self.left -= 1
  113. self.data[self.left] = x
  114. def pop(self):
  115. if self.left == self.right:
  116. raise IndexError('cannot pop from empty deque')
  117. self.right -= 1
  118. return self.data[self.right]
  119. def popleft(self):
  120. if self.left == self.right:
  121. raise IndexError('cannot pop from empty deque')
  122. x = self.data[self.left]
  123. self.left += 1
  124. return x
  125. def __len__(self):
  126. return self.right - self.left
  127. def __iter__(self):
  128. return imap(self.data.__getitem__, xrange(self.left, self.right))
  129. def __repr__(self):
  130. return 'deque(%r)' % (list(self),)
  131. def __getstate__(self):
  132. return (tuple(self),)
  133. def __setstate__(self, s):
  134. self.__init__(s[0])
  135. def __hash__(self):
  136. raise TypeError
  137. def __copy__(self):
  138. return self.__class__(self)
  139. def __deepcopy__(self, memo={}):
  140. from copy import deepcopy
  141. result = self.__class__()
  142. memo[id(self)] = result
  143. result.__init__(deepcopy(tuple(self), memo))
  144. return result
  145. #
  146. # new functions
  147. #
  148. import heapq as _heapq
  149. def isorted(iterable):
  150. lst = list(iterable)
  151. _heapq.heapify(lst)
  152. pop = _heapq.heappop
  153. while lst:
  154. yield pop(lst)
  155. def ireversed(iterable):
  156. if isinstance(iterable, (list, tuple)):
  157. for i in xrange(len(iterable)-1, -1, -1):
  158. yield iterable[i]
  159. else:
  160. for obj in reversed(iterable):
  161. yield obj