blob: 856036ddf12c35b38991beee477c50fd805fc1c4 [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
Benjamin Petersond51374e2014-04-09 23:55:56 -0400108def matmul(a, b):
109 "Same as a @ b."
110 return a @ b
111
Antoine Pitroua85017f2013-04-20 19:21:44 +0200112def neg(a):
113 "Same as -a."
114 return -a
115
116def or_(a, b):
117 "Same as a | b."
118 return a | b
119
120def pos(a):
121 "Same as +a."
122 return +a
123
124def pow(a, b):
125 "Same as a ** b."
126 return a ** b
127
128def rshift(a, b):
129 "Same as a >> b."
130 return a >> b
131
132def sub(a, b):
133 "Same as a - b."
134 return a - b
135
136def truediv(a, b):
137 "Same as a / b."
138 return a / b
139
140def xor(a, b):
141 "Same as a ^ b."
142 return a ^ b
143
144# Sequence Operations *********************************************************#
145
146def concat(a, b):
147 "Same as a + b, for a and b sequences."
148 if not hasattr(a, '__getitem__'):
149 msg = "'%s' object can't be concatenated" % type(a).__name__
150 raise TypeError(msg)
151 return a + b
152
153def contains(a, b):
154 "Same as b in a (note reversed operands)."
155 return b in a
156
157def countOf(a, b):
158 "Return the number of times b occurs in a."
159 count = 0
160 for i in a:
161 if i == b:
162 count += 1
163 return count
164
165def delitem(a, b):
166 "Same as del a[b]."
167 del a[b]
168
169def getitem(a, b):
170 "Same as a[b]."
171 return a[b]
172
173def indexOf(a, b):
174 "Return the first index of b in a."
175 for i, j in enumerate(a):
176 if j == b:
177 return i
178 else:
179 raise ValueError('sequence.index(x): x not in sequence')
180
181def setitem(a, b, c):
182 "Same as a[b] = c."
183 a[b] = c
184
185def length_hint(obj, default=0):
186 """
187 Return an estimate of the number of items in obj.
188 This is useful for presizing containers when building from an iterable.
189
190 If the object supports len(), the result will be exact. Otherwise, it may
191 over- or under-estimate by an arbitrary amount. The result will be an
192 integer >= 0.
193 """
194 if not isinstance(default, int):
195 msg = ("'%s' object cannot be interpreted as an integer" %
196 type(default).__name__)
197 raise TypeError(msg)
198
199 try:
200 return len(obj)
201 except TypeError:
202 pass
203
204 try:
205 hint = type(obj).__length_hint__
206 except AttributeError:
207 return default
208
209 try:
210 val = hint(obj)
211 except TypeError:
212 return default
213 if val is NotImplemented:
214 return default
215 if not isinstance(val, int):
216 msg = ('__length_hint__ must be integer, not %s' %
217 type(val).__name__)
218 raise TypeError(msg)
219 if val < 0:
220 msg = '__length_hint__() should return >= 0'
221 raise ValueError(msg)
222 return val
223
224# Generalized Lookup Objects **************************************************#
225
226class attrgetter:
227 """
228 Return a callable object that fetches the given attribute(s) from its operand.
Ezio Melotti0fbdf262013-05-08 10:56:32 +0300229 After f = attrgetter('name'), the call f(r) returns r.name.
230 After g = attrgetter('name', 'date'), the call g(r) returns (r.name, r.date).
231 After h = attrgetter('name.first', 'name.last'), the call h(r) returns
Antoine Pitroua85017f2013-04-20 19:21:44 +0200232 (r.name.first, r.name.last).
233 """
234 def __init__(self, attr, *attrs):
235 if not attrs:
236 if not isinstance(attr, str):
237 raise TypeError('attribute name must be a string')
238 names = attr.split('.')
239 def func(obj):
240 for name in names:
241 obj = getattr(obj, name)
242 return obj
243 self._call = func
244 else:
245 getters = tuple(map(attrgetter, (attr,) + attrs))
246 def func(obj):
247 return tuple(getter(obj) for getter in getters)
248 self._call = func
249
250 def __call__(self, obj):
251 return self._call(obj)
252
253class itemgetter:
254 """
255 Return a callable object that fetches the given item(s) from its operand.
Ezio Melotti0fbdf262013-05-08 10:56:32 +0300256 After f = itemgetter(2), the call f(r) returns r[2].
257 After g = itemgetter(2, 5, 3), the call g(r) returns (r[2], r[5], r[3])
Antoine Pitroua85017f2013-04-20 19:21:44 +0200258 """
259 def __init__(self, item, *items):
260 if not items:
261 def func(obj):
262 return obj[item]
263 self._call = func
264 else:
265 items = (item,) + items
266 def func(obj):
267 return tuple(obj[i] for i in items)
268 self._call = func
269
270 def __call__(self, obj):
271 return self._call(obj)
272
273class methodcaller:
274 """
275 Return a callable object that calls the given method on its operand.
276 After f = methodcaller('name'), the call f(r) returns r.name().
277 After g = methodcaller('name', 'date', foo=1), the call g(r) returns
278 r.name('date', foo=1).
279 """
280
281 def __init__(*args, **kwargs):
282 if len(args) < 2:
283 msg = "methodcaller needs at least one argument, the method name"
284 raise TypeError(msg)
285 self = args[0]
286 self._name = args[1]
287 self._args = args[2:]
288 self._kwargs = kwargs
289
290 def __call__(self, obj):
291 return getattr(obj, self._name)(*self._args, **self._kwargs)
292
293# In-place Operations *********************************************************#
294
295def iadd(a, b):
296 "Same as a += b."
297 a += b
298 return a
299
300def iand(a, b):
301 "Same as a &= b."
302 a &= b
303 return a
304
305def iconcat(a, b):
306 "Same as a += b, for a and b sequences."
307 if not hasattr(a, '__getitem__'):
308 msg = "'%s' object can't be concatenated" % type(a).__name__
309 raise TypeError(msg)
310 a += b
311 return a
312
313def ifloordiv(a, b):
314 "Same as a //= b."
315 a //= b
316 return a
317
318def ilshift(a, b):
319 "Same as a <<= b."
320 a <<= b
321 return a
322
323def imod(a, b):
324 "Same as a %= b."
325 a %= b
326 return a
327
328def imul(a, b):
329 "Same as a *= b."
330 a *= b
331 return a
332
Benjamin Petersond51374e2014-04-09 23:55:56 -0400333def imatmul(a, b):
334 "Same as a @= b."
335 a @= b
336 return a
337
Antoine Pitroua85017f2013-04-20 19:21:44 +0200338def ior(a, b):
339 "Same as a |= b."
340 a |= b
341 return a
342
343def ipow(a, b):
344 "Same as a **= b."
345 a **=b
346 return a
347
348def irshift(a, b):
349 "Same as a >>= b."
350 a >>= b
351 return a
352
353def isub(a, b):
354 "Same as a -= b."
355 a -= b
356 return a
357
358def itruediv(a, b):
359 "Same as a /= b."
360 a /= b
361 return a
362
363def ixor(a, b):
364 "Same as a ^= b."
365 a ^= b
366 return a
367
368
369try:
370 from _operator import *
Brett Cannoncd171c82013-07-04 17:43:24 -0400371except ImportError:
Antoine Pitroua85017f2013-04-20 19:21:44 +0200372 pass
373else:
374 from _operator import __doc__
375
376# All of these "__func__ = func" assignments have to happen after importing
377# from _operator to make sure they're set to the right function
378__lt__ = lt
379__le__ = le
380__eq__ = eq
381__ne__ = ne
382__ge__ = ge
383__gt__ = gt
384__not__ = not_
385__abs__ = abs
386__add__ = add
387__and__ = and_
388__floordiv__ = floordiv
389__index__ = index
390__inv__ = inv
391__invert__ = invert
392__lshift__ = lshift
393__mod__ = mod
394__mul__ = mul
Benjamin Petersond51374e2014-04-09 23:55:56 -0400395__matmul__ = matmul
Antoine Pitroua85017f2013-04-20 19:21:44 +0200396__neg__ = neg
397__or__ = or_
398__pos__ = pos
399__pow__ = pow
400__rshift__ = rshift
401__sub__ = sub
402__truediv__ = truediv
403__xor__ = xor
404__concat__ = concat
405__contains__ = contains
406__delitem__ = delitem
407__getitem__ = getitem
408__setitem__ = setitem
409__iadd__ = iadd
410__iand__ = iand
411__iconcat__ = iconcat
412__ifloordiv__ = ifloordiv
413__ilshift__ = ilshift
414__imod__ = imod
415__imul__ = imul
Benjamin Petersond51374e2014-04-09 23:55:56 -0400416__imatmul__ = imatmul
Antoine Pitroua85017f2013-04-20 19:21:44 +0200417__ior__ = ior
418__ipow__ = ipow
419__irshift__ = irshift
420__isub__ = isub
421__itruediv__ = itruediv
422__ixor__ = ixor