_interop.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. # Copyright (C) 2009-2011 Wander Lairson Costa
  2. #
  3. # The following terms apply to all files associated
  4. # with the software unless explicitly disclaimed in individual files.
  5. #
  6. # The authors hereby grant permission to use, copy, modify, distribute,
  7. # and license this software and its documentation for any purpose, provided
  8. # that existing copyright notices are retained in all copies and that this
  9. # notice is included verbatim in any distributions. No written agreement,
  10. # license, or royalty fee is required for any of the authorized uses.
  11. # Modifications to this software may be copyrighted by their authors
  12. # and need not follow the licensing terms described here, provided that
  13. # the new terms are clearly indicated on the first page of each file where
  14. # they apply.
  15. #
  16. # IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
  17. # FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
  18. # ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
  19. # DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
  20. # POSSIBILITY OF SUCH DAMAGE.
  21. #
  22. # THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
  23. # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
  24. # FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
  25. # IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
  26. # NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
  27. # MODIFICATIONS.
  28. # All the hacks necessary to assure compatibility across all
  29. # supported versions come here.
  30. # Please, note that there is one version check for each
  31. # hack we need to do, this makes maintenance easier... ^^
  32. import sys
  33. import array
  34. __all__ = ['_reduce', '_set', '_next', '_groupby', '_sorted', '_update_wrapper']
  35. # we support Python >= 2.3
  36. assert sys.hexversion >= 0x020300f0
  37. # On Python 3, reduce became a functools module function
  38. try:
  39. import functools
  40. _reduce = functools.reduce
  41. except (ImportError, AttributeError):
  42. _reduce = reduce
  43. # we only have the builtin set type since 2.5 version
  44. try:
  45. _set = set
  46. except NameError:
  47. import sets
  48. _set = sets.Set
  49. # On Python >= 2.6, we have the builtin next() function
  50. # On Python 2.5 and before, we have to call the iterator method next()
  51. def _next(iter):
  52. try:
  53. return next(iter)
  54. except NameError:
  55. return iter.next()
  56. # groupby is available only since 2.4 version
  57. try:
  58. import itertools
  59. _groupby = itertools.groupby
  60. except (ImportError, AttributeError):
  61. # stolen from Python docs
  62. class _groupby(object):
  63. # [k for k, g in groupby('AAAABBBCCDAABBB')] --> A B C D A B
  64. # [list(g) for k, g in groupby('AAAABBBCCD')] --> AAAA BBB CC D
  65. def __init__(self, iterable, key=None):
  66. if key is None:
  67. key = lambda x: x
  68. self.keyfunc = key
  69. self.it = iter(iterable)
  70. self.tgtkey = self.currkey = self.currvalue = object()
  71. def __iter__(self):
  72. return self
  73. def next(self):
  74. while self.currkey == self.tgtkey:
  75. self.currvalue = _next(self.it) # Exit on StopIteration
  76. self.currkey = self.keyfunc(self.currvalue)
  77. self.tgtkey = self.currkey
  78. return (self.currkey, self._grouper(self.tgtkey))
  79. def _grouper(self, tgtkey):
  80. while self.currkey == tgtkey:
  81. yield self.currvalue
  82. self.currvalue = _next(self.it) # Exit on StopIteration
  83. self.currkey = self.keyfunc(self.currvalue)
  84. # builtin sorted function is only availale since 2.4 version
  85. try:
  86. _sorted = sorted
  87. except NameError:
  88. def _sorted(l, key=None, reverse=False):
  89. # sort function on Python 2.3 does not
  90. # support 'key' parameter
  91. class KeyToCmp(object):
  92. def __init__(self, K):
  93. self.key = K
  94. def __call__(self, x, y):
  95. kx = self.key(x)
  96. ky = self.key(y)
  97. if kx < ky:
  98. return reverse and 1 or -1
  99. elif kx > ky:
  100. return reverse and -1 or 1
  101. else:
  102. return 0
  103. tmp = list(l)
  104. tmp.sort(KeyToCmp(key))
  105. return tmp
  106. try:
  107. import functools
  108. _update_wrapper = functools.update_wrapper
  109. except (ImportError, AttributeError):
  110. def _update_wrapper(wrapper, wrapped):
  111. wrapper.__name__ = wrapped.__name__
  112. wrapper.__module__ = wrapped.__module__
  113. wrapper.__doc__ = wrapped.__doc__
  114. wrapper.__dict__ = wrapped.__dict__
  115. def as_array(data=None):
  116. if data is None:
  117. return array.array('B')
  118. try:
  119. return array.array('B', data)
  120. except TypeError:
  121. # When you pass a unicode string, you got a TypeError
  122. # if first parameter is not 'u'
  123. return array.array('u', data)