1 """
2 Operator Interface
3
4 This module exports a set of functions corresponding to the intrinsic
5 operators of Python. For example, operator.add(x, y) is equivalent
6 to the expression x+y. The function names are those used for special
7 methods; variants without leading and trailing '__' are also provided
8 for convenience.
9
10 This is the pure Python implementation of the module.
11 """
12
13 __all__ = ['abs', 'add', 'and_', 'attrgetter', 'call', 'concat', 'contains', 'countOf',
14 'delitem', 'eq', 'floordiv', 'ge', 'getitem', 'gt', 'iadd', 'iand',
15 'iconcat', 'ifloordiv', 'ilshift', 'imatmul', 'imod', 'imul',
16 'index', 'indexOf', 'inv', 'invert', 'ior', 'ipow', 'irshift',
17 'is_', 'is_not', 'isub', 'itemgetter', 'itruediv', 'ixor', 'le',
18 'length_hint', 'lshift', 'lt', 'matmul', 'methodcaller', 'mod',
19 'mul', 'ne', 'neg', 'not_', 'or_', 'pos', 'pow', 'rshift',
20 'setitem', 'sub', 'truediv', 'truth', 'xor']
21
22 from builtins import abs as _abs
23
24
25 # Comparison Operations *******************************************************#
26
27 def lt(a, b):
28 "Same as a < b."
29 return a < b
30
31 def le(a, b):
32 "Same as a <= b."
33 return a <= b
34
35 def eq(a, b):
36 "Same as a == b."
37 return a == b
38
39 def ne(a, b):
40 "Same as a != b."
41 return a != b
42
43 def ge(a, b):
44 "Same as a >= b."
45 return a >= b
46
47 def gt(a, b):
48 "Same as a > b."
49 return a > b
50
51 # Logical Operations **********************************************************#
52
53 def not_(a):
54 "Same as not a."
55 return not a
56
57 def truth(a):
58 "Return True if a is true, False otherwise."
59 return True if a else False
60
61 def is_(a, b):
62 "Same as a is b."
63 return a is b
64
65 def is_not(a, b):
66 "Same as a is not b."
67 return a is not b
68
69 # Mathematical/Bitwise Operations *********************************************#
70
71 def abs(a):
72 "Same as abs(a)."
73 return _abs(a)
74
75 def add(a, b):
76 "Same as a + b."
77 return a + b
78
79 def and_(a, b):
80 "Same as a & b."
81 return a & b
82
83 def floordiv(a, b):
84 "Same as a // b."
85 return a // b
86
87 def index(a):
88 "Same as a.__index__()."
89 return a.__index__()
90
91 def inv(a):
92 "Same as ~a."
93 return ~a
94 invert = inv
95
96 def lshift(a, b):
97 "Same as a << b."
98 return a << b
99
100 def mod(a, b):
101 "Same as a % b."
102 return a % b
103
104 def mul(a, b):
105 "Same as a * b."
106 return a * b
107
108 def matmul(a, b):
109 "Same as a @ b."
110 return a @ b
111
112 def neg(a):
113 "Same as -a."
114 return -a
115
116 def or_(a, b):
117 "Same as a | b."
118 return a | b
119
120 def pos(a):
121 "Same as +a."
122 return +a
123
124 def pow(a, b):
125 "Same as a ** b."
126 return a ** b
127
128 def rshift(a, b):
129 "Same as a >> b."
130 return a >> b
131
132 def sub(a, b):
133 "Same as a - b."
134 return a - b
135
136 def truediv(a, b):
137 "Same as a / b."
138 return a / b
139
140 def xor(a, b):
141 "Same as a ^ b."
142 return a ^ b
143
144 # Sequence Operations *********************************************************#
145
146 def 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
153 def contains(a, b):
154 "Same as b in a (note reversed operands)."
155 return b in a
156
157 def countOf(a, b):
158 "Return the number of items in a which are, or which equal, b."
159 count = 0
160 for i in a:
161 if i is b or i == b:
162 count += 1
163 return count
164
165 def delitem(a, b):
166 "Same as del a[b]."
167 del a[b]
168
169 def getitem(a, b):
170 "Same as a[b]."
171 return a[b]
172
173 def indexOf(a, b):
174 "Return the first index of b in a."
175 for i, j in enumerate(a):
176 if j is b or j == b:
177 return i
178 else:
179 raise ValueError('sequence.index(x): x not in sequence')
180
181 def setitem(a, b, c):
182 "Same as a[b] = c."
183 a[b] = c
184
185 def 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 # Other Operations ************************************************************#
225
226 def call(obj, /, *args, **kwargs):
227 """Same as obj(*args, **kwargs)."""
228 return obj(*args, **kwargs)
229
230 # Generalized Lookup Objects **************************************************#
231
232 class ESC[4;38;5;81mattrgetter:
233 """
234 Return a callable object that fetches the given attribute(s) from its operand.
235 After f = attrgetter('name'), the call f(r) returns r.name.
236 After g = attrgetter('name', 'date'), the call g(r) returns (r.name, r.date).
237 After h = attrgetter('name.first', 'name.last'), the call h(r) returns
238 (r.name.first, r.name.last).
239 """
240 __slots__ = ('_attrs', '_call')
241
242 def __init__(self, attr, *attrs):
243 if not attrs:
244 if not isinstance(attr, str):
245 raise TypeError('attribute name must be a string')
246 self._attrs = (attr,)
247 names = attr.split('.')
248 def func(obj):
249 for name in names:
250 obj = getattr(obj, name)
251 return obj
252 self._call = func
253 else:
254 self._attrs = (attr,) + attrs
255 getters = tuple(map(attrgetter, self._attrs))
256 def func(obj):
257 return tuple(getter(obj) for getter in getters)
258 self._call = func
259
260 def __call__(self, obj):
261 return self._call(obj)
262
263 def __repr__(self):
264 return '%s.%s(%s)' % (self.__class__.__module__,
265 self.__class__.__qualname__,
266 ', '.join(map(repr, self._attrs)))
267
268 def __reduce__(self):
269 return self.__class__, self._attrs
270
271 class ESC[4;38;5;81mitemgetter:
272 """
273 Return a callable object that fetches the given item(s) from its operand.
274 After f = itemgetter(2), the call f(r) returns r[2].
275 After g = itemgetter(2, 5, 3), the call g(r) returns (r[2], r[5], r[3])
276 """
277 __slots__ = ('_items', '_call')
278
279 def __init__(self, item, *items):
280 if not items:
281 self._items = (item,)
282 def func(obj):
283 return obj[item]
284 self._call = func
285 else:
286 self._items = items = (item,) + items
287 def func(obj):
288 return tuple(obj[i] for i in items)
289 self._call = func
290
291 def __call__(self, obj):
292 return self._call(obj)
293
294 def __repr__(self):
295 return '%s.%s(%s)' % (self.__class__.__module__,
296 self.__class__.__name__,
297 ', '.join(map(repr, self._items)))
298
299 def __reduce__(self):
300 return self.__class__, self._items
301
302 class ESC[4;38;5;81mmethodcaller:
303 """
304 Return a callable object that calls the given method on its operand.
305 After f = methodcaller('name'), the call f(r) returns r.name().
306 After g = methodcaller('name', 'date', foo=1), the call g(r) returns
307 r.name('date', foo=1).
308 """
309 __slots__ = ('_name', '_args', '_kwargs')
310
311 def __init__(self, name, /, *args, **kwargs):
312 self._name = name
313 if not isinstance(self._name, str):
314 raise TypeError('method name must be a string')
315 self._args = args
316 self._kwargs = kwargs
317
318 def __call__(self, obj):
319 return getattr(obj, self._name)(*self._args, **self._kwargs)
320
321 def __repr__(self):
322 args = [repr(self._name)]
323 args.extend(map(repr, self._args))
324 args.extend('%s=%r' % (k, v) for k, v in self._kwargs.items())
325 return '%s.%s(%s)' % (self.__class__.__module__,
326 self.__class__.__name__,
327 ', '.join(args))
328
329 def __reduce__(self):
330 if not self._kwargs:
331 return self.__class__, (self._name,) + self._args
332 else:
333 from functools import partial
334 return partial(self.__class__, self._name, **self._kwargs), self._args
335
336
337 # In-place Operations *********************************************************#
338
339 def iadd(a, b):
340 "Same as a += b."
341 a += b
342 return a
343
344 def iand(a, b):
345 "Same as a &= b."
346 a &= b
347 return a
348
349 def iconcat(a, b):
350 "Same as a += b, for a and b sequences."
351 if not hasattr(a, '__getitem__'):
352 msg = "'%s' object can't be concatenated" % type(a).__name__
353 raise TypeError(msg)
354 a += b
355 return a
356
357 def ifloordiv(a, b):
358 "Same as a //= b."
359 a //= b
360 return a
361
362 def ilshift(a, b):
363 "Same as a <<= b."
364 a <<= b
365 return a
366
367 def imod(a, b):
368 "Same as a %= b."
369 a %= b
370 return a
371
372 def imul(a, b):
373 "Same as a *= b."
374 a *= b
375 return a
376
377 def imatmul(a, b):
378 "Same as a @= b."
379 a @= b
380 return a
381
382 def ior(a, b):
383 "Same as a |= b."
384 a |= b
385 return a
386
387 def ipow(a, b):
388 "Same as a **= b."
389 a **=b
390 return a
391
392 def irshift(a, b):
393 "Same as a >>= b."
394 a >>= b
395 return a
396
397 def isub(a, b):
398 "Same as a -= b."
399 a -= b
400 return a
401
402 def itruediv(a, b):
403 "Same as a /= b."
404 a /= b
405 return a
406
407 def ixor(a, b):
408 "Same as a ^= b."
409 a ^= b
410 return a
411
412
413 try:
414 from _operator import *
415 except ImportError:
416 pass
417 else:
418 from _operator import __doc__
419
420 # All of these "__func__ = func" assignments have to happen after importing
421 # from _operator to make sure they're set to the right function
422 __lt__ = lt
423 __le__ = le
424 __eq__ = eq
425 __ne__ = ne
426 __ge__ = ge
427 __gt__ = gt
428 __not__ = not_
429 __abs__ = abs
430 __add__ = add
431 __and__ = and_
432 __call__ = call
433 __floordiv__ = floordiv
434 __index__ = index
435 __inv__ = inv
436 __invert__ = invert
437 __lshift__ = lshift
438 __mod__ = mod
439 __mul__ = mul
440 __matmul__ = matmul
441 __neg__ = neg
442 __or__ = or_
443 __pos__ = pos
444 __pow__ = pow
445 __rshift__ = rshift
446 __sub__ = sub
447 __truediv__ = truediv
448 __xor__ = xor
449 __concat__ = concat
450 __contains__ = contains
451 __delitem__ = delitem
452 __getitem__ = getitem
453 __setitem__ = setitem
454 __iadd__ = iadd
455 __iand__ = iand
456 __iconcat__ = iconcat
457 __ifloordiv__ = ifloordiv
458 __ilshift__ = ilshift
459 __imod__ = imod
460 __imul__ = imul
461 __imatmul__ = imatmul
462 __ior__ = ior
463 __ipow__ = ipow
464 __irshift__ = irshift
465 __isub__ = isub
466 __itruediv__ = itruediv
467 __ixor__ = ixor