blob: b60349fe4c9ddddd44d099b1693fc2ee6c147ec3 [file] [log] [blame]
Antoine Pitroua85017f2013-04-20 19:21:44 +02001"""
2Operator Interface
3
4This module exports a set of functions corresponding to the intrinsic
5operators of Python. For example, operator.add(x, y) is equivalent
6to the expression x+y. The function names are those used for special
7methods; variants without leading and trailing '__' are also provided
8for convenience.
9
10This is the pure Python implementation of the module.
11"""
12
13__all__ = ['abs', 'add', 'and_', 'attrgetter', 'concat', 'contains', 'countOf',
14 'delitem', 'eq', 'floordiv', 'ge', 'getitem', 'gt', 'iadd', 'iand',
15 'iconcat', 'ifloordiv', 'ilshift', 'imod', 'imul', 'index',
16 'indexOf', 'inv', 'invert', 'ior', 'ipow', 'irshift', 'is_',
17 'is_not', 'isub', 'itemgetter', 'itruediv', 'ixor', 'le',
18 'length_hint', 'lshift', 'lt', 'methodcaller', 'mod', 'mul', 'ne',
19 'neg', 'not_', 'or_', 'pos', 'pow', 'rshift', 'setitem', 'sub',
20 'truediv', 'truth', 'xor']
21
22from builtins import abs as _abs
23
24
25# Comparison Operations *******************************************************#
26
27def lt(a, b):
28 "Same as a < b."
29 return a < b
30
31def le(a, b):
32 "Same as a <= b."
33 return a <= b
34
35def eq(a, b):
36 "Same as a == b."
37 return a == b
38
39def ne(a, b):
40 "Same as a != b."
41 return a != b
42
43def ge(a, b):
44 "Same as a >= b."
45 return a >= b
46
47def gt(a, b):
48 "Same as a > b."
49 return a > b
50
51# Logical Operations **********************************************************#
52
53def not_(a):
54 "Same as not a."
55 return not a
56
57def truth(a):
58 "Return True if a is true, False otherwise."
59 return True if a else False
60
61def is_(a, b):
62 "Same as a is b."
63 return a is b
64
65def is_not(a, b):
66 "Same as a is not b."
67 return a is not b
68
69# Mathematical/Bitwise Operations *********************************************#
70
71def abs(a):
72 "Same as abs(a)."
73 return _abs(a)
74
75def add(a, b):
76 "Same as a + b."
77 return a + b
78
79def and_(a, b):
80 "Same as a & b."
81 return a & b
82
83def floordiv(a, b):
84 "Same as a // b."
85 return a // b
86
87def index(a):
88 "Same as a.__index__()."
89 return a.__index__()
90
91def inv(a):
92 "Same as ~a."
93 return ~a
94invert = inv
95
96def lshift(a, b):
97 "Same as a << b."
98 return a << b
99
100def mod(a, b):
101 "Same as a % b."
102 return a % b
103
104def mul(a, b):
105 "Same as a * b."
106 return a * b
107
108def neg(a):
109 "Same as -a."
110 return -a
111
112def or_(a, b):
113 "Same as a | b."
114 return a | b
115
116def pos(a):
117 "Same as +a."
118 return +a
119
120def pow(a, b):
121 "Same as a ** b."
122 return a ** b
123
124def rshift(a, b):
125 "Same as a >> b."
126 return a >> b
127
128def sub(a, b):
129 "Same as a - b."
130 return a - b
131
132def truediv(a, b):
133 "Same as a / b."
134 return a / b
135
136def xor(a, b):
137 "Same as a ^ b."
138 return a ^ b
139
140# Sequence Operations *********************************************************#
141
142def concat(a, b):
143 "Same as a + b, for a and b sequences."
144 if not hasattr(a, '__getitem__'):
145 msg = "'%s' object can't be concatenated" % type(a).__name__
146 raise TypeError(msg)
147 return a + b
148
149def contains(a, b):
150 "Same as b in a (note reversed operands)."
151 return b in a
152
153def countOf(a, b):
154 "Return the number of times b occurs in a."
155 count = 0
156 for i in a:
157 if i == b:
158 count += 1
159 return count
160
161def delitem(a, b):
162 "Same as del a[b]."
163 del a[b]
164
165def getitem(a, b):
166 "Same as a[b]."
167 return a[b]
168
169def indexOf(a, b):
170 "Return the first index of b in a."
171 for i, j in enumerate(a):
172 if j == b:
173 return i
174 else:
175 raise ValueError('sequence.index(x): x not in sequence')
176
177def setitem(a, b, c):
178 "Same as a[b] = c."
179 a[b] = c
180
181def length_hint(obj, default=0):
182 """
183 Return an estimate of the number of items in obj.
184 This is useful for presizing containers when building from an iterable.
185
186 If the object supports len(), the result will be exact. Otherwise, it may
187 over- or under-estimate by an arbitrary amount. The result will be an
188 integer >= 0.
189 """
190 if not isinstance(default, int):
191 msg = ("'%s' object cannot be interpreted as an integer" %
192 type(default).__name__)
193 raise TypeError(msg)
194
195 try:
196 return len(obj)
197 except TypeError:
198 pass
199
200 try:
201 hint = type(obj).__length_hint__
202 except AttributeError:
203 return default
204
205 try:
206 val = hint(obj)
207 except TypeError:
208 return default
209 if val is NotImplemented:
210 return default
211 if not isinstance(val, int):
212 msg = ('__length_hint__ must be integer, not %s' %
213 type(val).__name__)
214 raise TypeError(msg)
215 if val < 0:
216 msg = '__length_hint__() should return >= 0'
217 raise ValueError(msg)
218 return val
219
220# Generalized Lookup Objects **************************************************#
221
222class attrgetter:
223 """
224 Return a callable object that fetches the given attribute(s) from its operand.
Ezio Melotti0fbdf262013-05-08 10:56:32 +0300225 After f = attrgetter('name'), the call f(r) returns r.name.
226 After g = attrgetter('name', 'date'), the call g(r) returns (r.name, r.date).
227 After h = attrgetter('name.first', 'name.last'), the call h(r) returns
Antoine Pitroua85017f2013-04-20 19:21:44 +0200228 (r.name.first, r.name.last).
229 """
230 def __init__(self, attr, *attrs):
231 if not attrs:
232 if not isinstance(attr, str):
233 raise TypeError('attribute name must be a string')
234 names = attr.split('.')
235 def func(obj):
236 for name in names:
237 obj = getattr(obj, name)
238 return obj
239 self._call = func
240 else:
241 getters = tuple(map(attrgetter, (attr,) + attrs))
242 def func(obj):
243 return tuple(getter(obj) for getter in getters)
244 self._call = func
245
246 def __call__(self, obj):
247 return self._call(obj)
248
249class itemgetter:
250 """
251 Return a callable object that fetches the given item(s) from its operand.
Ezio Melotti0fbdf262013-05-08 10:56:32 +0300252 After f = itemgetter(2), the call f(r) returns r[2].
253 After g = itemgetter(2, 5, 3), the call g(r) returns (r[2], r[5], r[3])
Antoine Pitroua85017f2013-04-20 19:21:44 +0200254 """
255 def __init__(self, item, *items):
256 if not items:
257 def func(obj):
258 return obj[item]
259 self._call = func
260 else:
261 items = (item,) + items
262 def func(obj):
263 return tuple(obj[i] for i in items)
264 self._call = func
265
266 def __call__(self, obj):
267 return self._call(obj)
268
269class methodcaller:
270 """
271 Return a callable object that calls the given method on its operand.
272 After f = methodcaller('name'), the call f(r) returns r.name().
273 After g = methodcaller('name', 'date', foo=1), the call g(r) returns
274 r.name('date', foo=1).
275 """
276
277 def __init__(*args, **kwargs):
278 if len(args) < 2:
279 msg = "methodcaller needs at least one argument, the method name"
280 raise TypeError(msg)
281 self = args[0]
282 self._name = args[1]
283 self._args = args[2:]
284 self._kwargs = kwargs
285
286 def __call__(self, obj):
287 return getattr(obj, self._name)(*self._args, **self._kwargs)
288
289# In-place Operations *********************************************************#
290
291def iadd(a, b):
292 "Same as a += b."
293 a += b
294 return a
295
296def iand(a, b):
297 "Same as a &= b."
298 a &= b
299 return a
300
301def iconcat(a, b):
302 "Same as a += b, for a and b sequences."
303 if not hasattr(a, '__getitem__'):
304 msg = "'%s' object can't be concatenated" % type(a).__name__
305 raise TypeError(msg)
306 a += b
307 return a
308
309def ifloordiv(a, b):
310 "Same as a //= b."
311 a //= b
312 return a
313
314def ilshift(a, b):
315 "Same as a <<= b."
316 a <<= b
317 return a
318
319def imod(a, b):
320 "Same as a %= b."
321 a %= b
322 return a
323
324def imul(a, b):
325 "Same as a *= b."
326 a *= b
327 return a
328
329def ior(a, b):
330 "Same as a |= b."
331 a |= b
332 return a
333
334def ipow(a, b):
335 "Same as a **= b."
336 a **=b
337 return a
338
339def irshift(a, b):
340 "Same as a >>= b."
341 a >>= b
342 return a
343
344def isub(a, b):
345 "Same as a -= b."
346 a -= b
347 return a
348
349def itruediv(a, b):
350 "Same as a /= b."
351 a /= b
352 return a
353
354def ixor(a, b):
355 "Same as a ^= b."
356 a ^= b
357 return a
358
359
360try:
361 from _operator import *
Brett Cannoncd171c82013-07-04 17:43:24 -0400362except ImportError:
Antoine Pitroua85017f2013-04-20 19:21:44 +0200363 pass
364else:
365 from _operator import __doc__
366
367# All of these "__func__ = func" assignments have to happen after importing
368# from _operator to make sure they're set to the right function
369__lt__ = lt
370__le__ = le
371__eq__ = eq
372__ne__ = ne
373__ge__ = ge
374__gt__ = gt
375__not__ = not_
376__abs__ = abs
377__add__ = add
378__and__ = and_
379__floordiv__ = floordiv
380__index__ = index
381__inv__ = inv
382__invert__ = invert
383__lshift__ = lshift
384__mod__ = mod
385__mul__ = mul
386__neg__ = neg
387__or__ = or_
388__pos__ = pos
389__pow__ = pow
390__rshift__ = rshift
391__sub__ = sub
392__truediv__ = truediv
393__xor__ = xor
394__concat__ = concat
395__contains__ = contains
396__delitem__ = delitem
397__getitem__ = getitem
398__setitem__ = setitem
399__iadd__ = iadd
400__iand__ = iand
401__iconcat__ = iconcat
402__ifloordiv__ = ifloordiv
403__ilshift__ = ilshift
404__imod__ = imod
405__imul__ = imul
406__ior__ = ior
407__ipow__ = ipow
408__irshift__ = irshift
409__isub__ = isub
410__itruediv__ = itruediv
411__ixor__ = ixor