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