Statistics
| Branch: | Tag: | Revision:

root / lib / compat.py @ 808cb0ee

History | View | Annotate | Download (5.2 kB)

1 cea881e5 Michael Hanselmann
#
2 cea881e5 Michael Hanselmann
#
3 cea881e5 Michael Hanselmann
4 eb62069e Iustin Pop
# Copyright (C) 2010, 2011 Google Inc.
5 cea881e5 Michael Hanselmann
#
6 cea881e5 Michael Hanselmann
# This program is free software; you can redistribute it and/or modify
7 cea881e5 Michael Hanselmann
# it under the terms of the GNU General Public License as published by
8 cea881e5 Michael Hanselmann
# the Free Software Foundation; either version 2 of the License, or
9 cea881e5 Michael Hanselmann
# (at your option) any later version.
10 cea881e5 Michael Hanselmann
#
11 cea881e5 Michael Hanselmann
# This program is distributed in the hope that it will be useful, but
12 cea881e5 Michael Hanselmann
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 cea881e5 Michael Hanselmann
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 cea881e5 Michael Hanselmann
# General Public License for more details.
15 cea881e5 Michael Hanselmann
#
16 cea881e5 Michael Hanselmann
# You should have received a copy of the GNU General Public License
17 cea881e5 Michael Hanselmann
# along with this program; if not, write to the Free Software
18 cea881e5 Michael Hanselmann
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 cea881e5 Michael Hanselmann
# 02110-1301, USA.
20 cea881e5 Michael Hanselmann
21 cea881e5 Michael Hanselmann
22 cea881e5 Michael Hanselmann
"""Module containing backported language/library functionality.
23 cea881e5 Michael Hanselmann

24 cea881e5 Michael Hanselmann
"""
25 cea881e5 Michael Hanselmann
26 cea881e5 Michael Hanselmann
import itertools
27 eb62069e Iustin Pop
import operator
28 cea881e5 Michael Hanselmann
29 cea881e5 Michael Hanselmann
try:
30 b459a848 Andrea Spadaccini
  # pylint: disable=F0401
31 cea881e5 Michael Hanselmann
  import functools
32 cea881e5 Michael Hanselmann
except ImportError:
33 cea881e5 Michael Hanselmann
  functools = None
34 cea881e5 Michael Hanselmann
35 6396164f Guido Trotter
try:
36 b459a848 Andrea Spadaccini
  # pylint: disable=F0401
37 6396164f Guido Trotter
  import roman
38 6396164f Guido Trotter
except ImportError:
39 6396164f Guido Trotter
  roman = None
40 6396164f Guido Trotter
41 cea881e5 Michael Hanselmann
42 716a32cb Guido Trotter
# compat.md5_hash and compat.sha1_hash can be called to generate and md5 and a
43 716a32cb Guido Trotter
# sha1 hashing modules, under python 2.4, 2.5 and 2.6, even though some changes
44 716a32cb Guido Trotter
# went on. compat.sha1 is python-version specific and is used for python
45 716a32cb Guido Trotter
# modules (hmac, for example) which have changed their behavior as well from
46 716a32cb Guido Trotter
# one version to the other.
47 716a32cb Guido Trotter
try:
48 1dd64393 Guido Trotter
  # Yes, these don't always exist, that's why we're testing
49 716a32cb Guido Trotter
  # Yes, we're not using the imports in this module.
50 1dd64393 Guido Trotter
  from hashlib import md5 as md5_hash # pylint: disable=W0611,E0611,F0401
51 1dd64393 Guido Trotter
  from hashlib import sha1 as sha1_hash # pylint: disable=W0611,E0611,F0401
52 716a32cb Guido Trotter
  # this additional version is needed for compatibility with the hmac module
53 716a32cb Guido Trotter
  sha1 = sha1_hash
54 716a32cb Guido Trotter
except ImportError:
55 716a32cb Guido Trotter
  from md5 import new as md5_hash
56 716a32cb Guido Trotter
  import sha
57 716a32cb Guido Trotter
  sha1 = sha
58 716a32cb Guido Trotter
  sha1_hash = sha.new
59 716a32cb Guido Trotter
60 716a32cb Guido Trotter
61 403f5172 Guido Trotter
def _all(seq):
62 403f5172 Guido Trotter
  """Returns True if all elements in the iterable are True.
63 cea881e5 Michael Hanselmann

64 cea881e5 Michael Hanselmann
  """
65 403f5172 Guido Trotter
  for _ in itertools.ifilterfalse(bool, seq):
66 cea881e5 Michael Hanselmann
    return False
67 cea881e5 Michael Hanselmann
  return True
68 cea881e5 Michael Hanselmann
69 e687ec01 Michael Hanselmann
70 403f5172 Guido Trotter
def _any(seq):
71 403f5172 Guido Trotter
  """Returns True if any element of the iterable are True.
72 cea881e5 Michael Hanselmann

73 cea881e5 Michael Hanselmann
  """
74 403f5172 Guido Trotter
  for _ in itertools.ifilter(bool, seq):
75 cea881e5 Michael Hanselmann
    return True
76 cea881e5 Michael Hanselmann
  return False
77 cea881e5 Michael Hanselmann
78 e687ec01 Michael Hanselmann
79 403f5172 Guido Trotter
try:
80 b459a848 Andrea Spadaccini
  # pylint: disable=E0601
81 b459a848 Andrea Spadaccini
  # pylint: disable=W0622
82 23e0ef8c Guido Trotter
  all = all
83 403f5172 Guido Trotter
except NameError:
84 403f5172 Guido Trotter
  all = _all
85 403f5172 Guido Trotter
86 403f5172 Guido Trotter
try:
87 b459a848 Andrea Spadaccini
  # pylint: disable=E0601
88 b459a848 Andrea Spadaccini
  # pylint: disable=W0622
89 23e0ef8c Guido Trotter
  any = any
90 403f5172 Guido Trotter
except NameError:
91 403f5172 Guido Trotter
  any = _any
92 cea881e5 Michael Hanselmann
93 e687ec01 Michael Hanselmann
94 b459a848 Andrea Spadaccini
def partition(seq, pred=bool): # pylint: disable=W0622
95 cea881e5 Michael Hanselmann
  """Partition a list in two, based on the given predicate.
96 cea881e5 Michael Hanselmann

97 cea881e5 Michael Hanselmann
  """
98 cea881e5 Michael Hanselmann
  return (list(itertools.ifilter(pred, seq)),
99 cea881e5 Michael Hanselmann
          list(itertools.ifilterfalse(pred, seq)))
100 cea881e5 Michael Hanselmann
101 cea881e5 Michael Hanselmann
102 cea881e5 Michael Hanselmann
# Even though we're using Python's built-in "partial" function if available,
103 cea881e5 Michael Hanselmann
# this one is always defined for testing.
104 b459a848 Andrea Spadaccini
def _partial(func, *args, **keywords): # pylint: disable=W0622
105 cea881e5 Michael Hanselmann
  """Decorator with partial application of arguments and keywords.
106 cea881e5 Michael Hanselmann

107 cea881e5 Michael Hanselmann
  This function was copied from Python's documentation.
108 cea881e5 Michael Hanselmann

109 cea881e5 Michael Hanselmann
  """
110 cea881e5 Michael Hanselmann
  def newfunc(*fargs, **fkeywords):
111 cea881e5 Michael Hanselmann
    newkeywords = keywords.copy()
112 cea881e5 Michael Hanselmann
    newkeywords.update(fkeywords)
113 b459a848 Andrea Spadaccini
    return func(*(args + fargs), **newkeywords) # pylint: disable=W0142
114 cea881e5 Michael Hanselmann
115 cea881e5 Michael Hanselmann
  newfunc.func = func
116 cea881e5 Michael Hanselmann
  newfunc.args = args
117 cea881e5 Michael Hanselmann
  newfunc.keywords = keywords
118 cea881e5 Michael Hanselmann
  return newfunc
119 cea881e5 Michael Hanselmann
120 cea881e5 Michael Hanselmann
121 403f5172 Guido Trotter
if functools is None:
122 403f5172 Guido Trotter
  partial = _partial
123 403f5172 Guido Trotter
else:
124 403f5172 Guido Trotter
  partial = functools.partial
125 403f5172 Guido Trotter
126 403f5172 Guido Trotter
127 47d2185e Michele Tartara
def RomanOrRounded(value, rounding, convert=True):
128 47d2185e Michele Tartara
  """Try to round the value to the closest integer and return it as a roman
129 47d2185e Michele Tartara
  numeral. If the conversion is disabled, or if the roman module could not be
130 47d2185e Michele Tartara
  loaded, round the value to the specified level and return it.
131 47d2185e Michele Tartara

132 47d2185e Michele Tartara
  @type value: number
133 47d2185e Michele Tartara
  @param value: value to convert
134 47d2185e Michele Tartara
  @type rounding: integer
135 47d2185e Michele Tartara
  @param rounding: how many decimal digits the number should be rounded to
136 47d2185e Michele Tartara
  @type convert: boolean
137 47d2185e Michele Tartara
  @param convert: if False, don't try conversion at all
138 47d2185e Michele Tartara
  @rtype: string
139 47d2185e Michele Tartara
  @return: roman numeral for val, or formatted string representing val if
140 47d2185e Michele Tartara
           conversion didn't succeed
141 47d2185e Michele Tartara

142 47d2185e Michele Tartara
  """
143 47d2185e Michele Tartara
  def _FormatOutput(val, r):
144 47d2185e Michele Tartara
    format_string = "%0." + str(r) + "f"
145 47d2185e Michele Tartara
    return format_string % val
146 47d2185e Michele Tartara
147 47d2185e Michele Tartara
  if roman is not None and convert:
148 47d2185e Michele Tartara
    try:
149 47d2185e Michele Tartara
      return roman.toRoman(round(value, 0))
150 47d2185e Michele Tartara
    except roman.RomanError:
151 47d2185e Michele Tartara
      return _FormatOutput(value, rounding)
152 47d2185e Michele Tartara
  return _FormatOutput(value, rounding)
153 47d2185e Michele Tartara
154 47d2185e Michele Tartara
155 6396164f Guido Trotter
def TryToRoman(val, convert=True):
156 6396164f Guido Trotter
  """Try to convert a value to roman numerals
157 6396164f Guido Trotter

158 6396164f Guido Trotter
  If the roman module could be loaded convert the given value to a roman
159 6396164f Guido Trotter
  numeral. Gracefully fail back to leaving the value untouched.
160 6396164f Guido Trotter

161 6396164f Guido Trotter
  @type val: integer
162 6396164f Guido Trotter
  @param val: value to convert
163 6396164f Guido Trotter
  @type convert: boolean
164 6396164f Guido Trotter
  @param convert: if False, don't try conversion at all
165 6396164f Guido Trotter
  @rtype: string or typeof(val)
166 6396164f Guido Trotter
  @return: roman numeral for val, or val if conversion didn't succeed
167 6396164f Guido Trotter

168 6396164f Guido Trotter
  """
169 6396164f Guido Trotter
  if roman is not None and convert:
170 6396164f Guido Trotter
    try:
171 6396164f Guido Trotter
      return roman.toRoman(val)
172 6396164f Guido Trotter
    except roman.RomanError:
173 6396164f Guido Trotter
      return val
174 6396164f Guido Trotter
  else:
175 6396164f Guido Trotter
    return val
176 6396164f Guido Trotter
177 4a3dd52d Michael Hanselmann
178 4a3dd52d Michael Hanselmann
def UniqueFrozenset(seq):
179 4a3dd52d Michael Hanselmann
  """Makes C{frozenset} from sequence after checking for duplicate elements.
180 4a3dd52d Michael Hanselmann

181 4a3dd52d Michael Hanselmann
  @raise ValueError: When there are duplicate elements
182 4a3dd52d Michael Hanselmann

183 4a3dd52d Michael Hanselmann
  """
184 4a3dd52d Michael Hanselmann
  if isinstance(seq, (list, tuple)):
185 4a3dd52d Michael Hanselmann
    items = seq
186 4a3dd52d Michael Hanselmann
  else:
187 4a3dd52d Michael Hanselmann
    items = list(seq)
188 4a3dd52d Michael Hanselmann
189 4a3dd52d Michael Hanselmann
  result = frozenset(items)
190 4a3dd52d Michael Hanselmann
191 4a3dd52d Michael Hanselmann
  if len(items) != len(result):
192 4a3dd52d Michael Hanselmann
    raise ValueError("Duplicate values found")
193 4a3dd52d Michael Hanselmann
194 4a3dd52d Michael Hanselmann
  return result
195 4a3dd52d Michael Hanselmann
196 4a3dd52d Michael Hanselmann
197 eb62069e Iustin Pop
#: returns the first element of a list-like value
198 eb62069e Iustin Pop
fst = operator.itemgetter(0)
199 eb62069e Iustin Pop
200 eb62069e Iustin Pop
#: returns the second element of a list-like value
201 eb62069e Iustin Pop
snd = operator.itemgetter(1)