| 
									
										
										
										
											2013-04-20 19:21:44 +02:00
										 |  |  | #!/usr/bin/env python3 | 
					
						
							|  |  |  | """
 | 
					
						
							|  |  |  | Operator Interface | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This module exports a set of functions corresponding to the intrinsic | 
					
						
							|  |  |  | operators of Python.  For example, operator.add(x, y) is equivalent | 
					
						
							|  |  |  | to the expression x+y.  The function names are those used for special | 
					
						
							|  |  |  | methods; variants without leading and trailing '__' are also provided | 
					
						
							|  |  |  | for convenience. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This is the pure Python implementation of the module. | 
					
						
							|  |  |  | """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | __all__ = ['abs', 'add', 'and_', 'attrgetter', 'concat', 'contains', 'countOf', | 
					
						
							|  |  |  |            'delitem', 'eq', 'floordiv', 'ge', 'getitem', 'gt', 'iadd', 'iand', | 
					
						
							|  |  |  |            'iconcat', 'ifloordiv', 'ilshift', 'imod', 'imul', 'index', | 
					
						
							|  |  |  |            'indexOf', 'inv', 'invert', 'ior', 'ipow', 'irshift', 'is_', | 
					
						
							|  |  |  |            'is_not', 'isub', 'itemgetter', 'itruediv', 'ixor', 'le', | 
					
						
							|  |  |  |            'length_hint', 'lshift', 'lt', 'methodcaller', 'mod', 'mul', 'ne', | 
					
						
							|  |  |  |            'neg', 'not_', 'or_', 'pos', 'pow', 'rshift', 'setitem', 'sub', | 
					
						
							|  |  |  |            'truediv', 'truth', 'xor'] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from builtins import abs as _abs | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Comparison Operations *******************************************************# | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def lt(a, b): | 
					
						
							|  |  |  |     "Same as a < b." | 
					
						
							|  |  |  |     return a < b | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def le(a, b): | 
					
						
							|  |  |  |     "Same as a <= b." | 
					
						
							|  |  |  |     return a <= b | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def eq(a, b): | 
					
						
							|  |  |  |     "Same as a == b." | 
					
						
							|  |  |  |     return a == b | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def ne(a, b): | 
					
						
							|  |  |  |     "Same as a != b." | 
					
						
							|  |  |  |     return a != b | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def ge(a, b): | 
					
						
							|  |  |  |     "Same as a >= b." | 
					
						
							|  |  |  |     return a >= b | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def gt(a, b): | 
					
						
							|  |  |  |     "Same as a > b." | 
					
						
							|  |  |  |     return a > b | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Logical Operations **********************************************************# | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def not_(a): | 
					
						
							|  |  |  |     "Same as not a." | 
					
						
							|  |  |  |     return not a | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def truth(a): | 
					
						
							|  |  |  |     "Return True if a is true, False otherwise." | 
					
						
							|  |  |  |     return True if a else False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def is_(a, b): | 
					
						
							|  |  |  |     "Same as a is b." | 
					
						
							|  |  |  |     return a is b | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def is_not(a, b): | 
					
						
							|  |  |  |     "Same as a is not b." | 
					
						
							|  |  |  |     return a is not b | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Mathematical/Bitwise Operations *********************************************# | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def abs(a): | 
					
						
							|  |  |  |     "Same as abs(a)." | 
					
						
							|  |  |  |     return _abs(a) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def add(a, b): | 
					
						
							|  |  |  |     "Same as a + b." | 
					
						
							|  |  |  |     return a + b | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def and_(a, b): | 
					
						
							|  |  |  |     "Same as a & b." | 
					
						
							|  |  |  |     return a & b | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def floordiv(a, b): | 
					
						
							|  |  |  |     "Same as a // b." | 
					
						
							|  |  |  |     return a // b | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def index(a): | 
					
						
							|  |  |  |     "Same as a.__index__()." | 
					
						
							|  |  |  |     return a.__index__() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def inv(a): | 
					
						
							|  |  |  |     "Same as ~a." | 
					
						
							|  |  |  |     return ~a | 
					
						
							|  |  |  | invert = inv | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def lshift(a, b): | 
					
						
							|  |  |  |     "Same as a << b." | 
					
						
							|  |  |  |     return a << b | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def mod(a, b): | 
					
						
							|  |  |  |     "Same as a % b." | 
					
						
							|  |  |  |     return a % b | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def mul(a, b): | 
					
						
							|  |  |  |     "Same as a * b." | 
					
						
							|  |  |  |     return a * b | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def neg(a): | 
					
						
							|  |  |  |     "Same as -a." | 
					
						
							|  |  |  |     return -a | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def or_(a, b): | 
					
						
							|  |  |  |     "Same as a | b." | 
					
						
							|  |  |  |     return a | b | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def pos(a): | 
					
						
							|  |  |  |     "Same as +a." | 
					
						
							|  |  |  |     return +a | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def pow(a, b): | 
					
						
							|  |  |  |     "Same as a ** b." | 
					
						
							|  |  |  |     return a ** b | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def rshift(a, b): | 
					
						
							|  |  |  |     "Same as a >> b." | 
					
						
							|  |  |  |     return a >> b | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def sub(a, b): | 
					
						
							|  |  |  |     "Same as a - b." | 
					
						
							|  |  |  |     return a - b | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def truediv(a, b): | 
					
						
							|  |  |  |     "Same as a / b." | 
					
						
							|  |  |  |     return a / b | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def xor(a, b): | 
					
						
							|  |  |  |     "Same as a ^ b." | 
					
						
							|  |  |  |     return a ^ b | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Sequence Operations *********************************************************# | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def concat(a, b): | 
					
						
							|  |  |  |     "Same as a + b, for a and b sequences." | 
					
						
							|  |  |  |     if not hasattr(a, '__getitem__'): | 
					
						
							|  |  |  |         msg = "'%s' object can't be concatenated" % type(a).__name__ | 
					
						
							|  |  |  |         raise TypeError(msg) | 
					
						
							|  |  |  |     return a + b | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def contains(a, b): | 
					
						
							|  |  |  |     "Same as b in a (note reversed operands)." | 
					
						
							|  |  |  |     return b in a | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def countOf(a, b): | 
					
						
							|  |  |  |     "Return the number of times b occurs in a." | 
					
						
							|  |  |  |     count = 0 | 
					
						
							|  |  |  |     for i in a: | 
					
						
							|  |  |  |         if i == b: | 
					
						
							|  |  |  |             count += 1 | 
					
						
							|  |  |  |     return count | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def delitem(a, b): | 
					
						
							|  |  |  |     "Same as del a[b]." | 
					
						
							|  |  |  |     del a[b] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def getitem(a, b): | 
					
						
							|  |  |  |     "Same as a[b]." | 
					
						
							|  |  |  |     return a[b] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def indexOf(a, b): | 
					
						
							|  |  |  |     "Return the first index of b in a." | 
					
						
							|  |  |  |     for i, j in enumerate(a): | 
					
						
							|  |  |  |         if j == b: | 
					
						
							|  |  |  |             return i | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         raise ValueError('sequence.index(x): x not in sequence') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def setitem(a, b, c): | 
					
						
							|  |  |  |     "Same as a[b] = c." | 
					
						
							|  |  |  |     a[b] = c | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def length_hint(obj, default=0): | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     Return an estimate of the number of items in obj. | 
					
						
							|  |  |  |     This is useful for presizing containers when building from an iterable. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     If the object supports len(), the result will be exact. Otherwise, it may | 
					
						
							|  |  |  |     over- or under-estimate by an arbitrary amount. The result will be an | 
					
						
							|  |  |  |     integer >= 0. | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     if not isinstance(default, int): | 
					
						
							|  |  |  |         msg = ("'%s' object cannot be interpreted as an integer" % | 
					
						
							|  |  |  |                type(default).__name__) | 
					
						
							|  |  |  |         raise TypeError(msg) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         return len(obj) | 
					
						
							|  |  |  |     except TypeError: | 
					
						
							|  |  |  |         pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         hint = type(obj).__length_hint__ | 
					
						
							|  |  |  |     except AttributeError: | 
					
						
							|  |  |  |         return default | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         val = hint(obj) | 
					
						
							|  |  |  |     except TypeError: | 
					
						
							|  |  |  |         return default | 
					
						
							|  |  |  |     if val is NotImplemented: | 
					
						
							|  |  |  |         return default | 
					
						
							|  |  |  |     if not isinstance(val, int): | 
					
						
							|  |  |  |         msg = ('__length_hint__ must be integer, not %s' % | 
					
						
							|  |  |  |                type(val).__name__) | 
					
						
							|  |  |  |         raise TypeError(msg) | 
					
						
							|  |  |  |     if val < 0: | 
					
						
							|  |  |  |         msg = '__length_hint__() should return >= 0' | 
					
						
							|  |  |  |         raise ValueError(msg) | 
					
						
							|  |  |  |     return val | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Generalized Lookup Objects **************************************************# | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class attrgetter: | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     Return a callable object that fetches the given attribute(s) from its operand. | 
					
						
							| 
									
										
										
										
											2013-05-08 10:56:32 +03:00
										 |  |  |     After f = attrgetter('name'), the call f(r) returns r.name. | 
					
						
							|  |  |  |     After g = attrgetter('name', 'date'), the call g(r) returns (r.name, r.date). | 
					
						
							|  |  |  |     After h = attrgetter('name.first', 'name.last'), the call h(r) returns | 
					
						
							| 
									
										
										
										
											2013-04-20 19:21:44 +02:00
										 |  |  |     (r.name.first, r.name.last). | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     def __init__(self, attr, *attrs): | 
					
						
							|  |  |  |         if not attrs: | 
					
						
							|  |  |  |             if not isinstance(attr, str): | 
					
						
							|  |  |  |                 raise TypeError('attribute name must be a string') | 
					
						
							|  |  |  |             names = attr.split('.') | 
					
						
							|  |  |  |             def func(obj): | 
					
						
							|  |  |  |                 for name in names: | 
					
						
							|  |  |  |                     obj = getattr(obj, name) | 
					
						
							|  |  |  |                 return obj | 
					
						
							|  |  |  |             self._call = func | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             getters = tuple(map(attrgetter, (attr,) + attrs)) | 
					
						
							|  |  |  |             def func(obj): | 
					
						
							|  |  |  |                 return tuple(getter(obj) for getter in getters) | 
					
						
							|  |  |  |             self._call = func | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __call__(self, obj): | 
					
						
							|  |  |  |         return self._call(obj) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class itemgetter: | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     Return a callable object that fetches the given item(s) from its operand. | 
					
						
							| 
									
										
										
										
											2013-05-08 10:56:32 +03:00
										 |  |  |     After f = itemgetter(2), the call f(r) returns r[2]. | 
					
						
							|  |  |  |     After g = itemgetter(2, 5, 3), the call g(r) returns (r[2], r[5], r[3]) | 
					
						
							| 
									
										
										
										
											2013-04-20 19:21:44 +02:00
										 |  |  |     """
 | 
					
						
							|  |  |  |     def __init__(self, item, *items): | 
					
						
							|  |  |  |         if not items: | 
					
						
							|  |  |  |             def func(obj): | 
					
						
							|  |  |  |                 return obj[item] | 
					
						
							|  |  |  |             self._call = func | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             items = (item,) + items | 
					
						
							|  |  |  |             def func(obj): | 
					
						
							|  |  |  |                 return tuple(obj[i] for i in items) | 
					
						
							|  |  |  |             self._call = func | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __call__(self, obj): | 
					
						
							|  |  |  |         return self._call(obj) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class methodcaller: | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |     Return a callable object that calls the given method on its operand. | 
					
						
							|  |  |  |     After f = methodcaller('name'), the call f(r) returns r.name(). | 
					
						
							|  |  |  |     After g = methodcaller('name', 'date', foo=1), the call g(r) returns | 
					
						
							|  |  |  |     r.name('date', foo=1). | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(*args, **kwargs): | 
					
						
							|  |  |  |         if len(args) < 2: | 
					
						
							|  |  |  |             msg = "methodcaller needs at least one argument, the method name" | 
					
						
							|  |  |  |             raise TypeError(msg) | 
					
						
							|  |  |  |         self = args[0] | 
					
						
							|  |  |  |         self._name = args[1] | 
					
						
							|  |  |  |         self._args = args[2:] | 
					
						
							|  |  |  |         self._kwargs = kwargs | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __call__(self, obj): | 
					
						
							|  |  |  |         return getattr(obj, self._name)(*self._args, **self._kwargs) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # In-place Operations *********************************************************# | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def iadd(a, b): | 
					
						
							|  |  |  |     "Same as a += b." | 
					
						
							|  |  |  |     a += b | 
					
						
							|  |  |  |     return a | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def iand(a, b): | 
					
						
							|  |  |  |     "Same as a &= b." | 
					
						
							|  |  |  |     a &= b | 
					
						
							|  |  |  |     return a | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def iconcat(a, b): | 
					
						
							|  |  |  |     "Same as a += b, for a and b sequences." | 
					
						
							|  |  |  |     if not hasattr(a, '__getitem__'): | 
					
						
							|  |  |  |         msg = "'%s' object can't be concatenated" % type(a).__name__ | 
					
						
							|  |  |  |         raise TypeError(msg) | 
					
						
							|  |  |  |     a += b | 
					
						
							|  |  |  |     return a | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def ifloordiv(a, b): | 
					
						
							|  |  |  |     "Same as a //= b." | 
					
						
							|  |  |  |     a //= b | 
					
						
							|  |  |  |     return a | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def ilshift(a, b): | 
					
						
							|  |  |  |     "Same as a <<= b." | 
					
						
							|  |  |  |     a <<= b | 
					
						
							|  |  |  |     return a | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def imod(a, b): | 
					
						
							|  |  |  |     "Same as a %= b." | 
					
						
							|  |  |  |     a %= b | 
					
						
							|  |  |  |     return a | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def imul(a, b): | 
					
						
							|  |  |  |     "Same as a *= b." | 
					
						
							|  |  |  |     a *= b | 
					
						
							|  |  |  |     return a | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def ior(a, b): | 
					
						
							|  |  |  |     "Same as a |= b." | 
					
						
							|  |  |  |     a |= b | 
					
						
							|  |  |  |     return a | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def ipow(a, b): | 
					
						
							|  |  |  |     "Same as a **= b." | 
					
						
							|  |  |  |     a **=b | 
					
						
							|  |  |  |     return a | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def irshift(a, b): | 
					
						
							|  |  |  |     "Same as a >>= b." | 
					
						
							|  |  |  |     a >>= b | 
					
						
							|  |  |  |     return a | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def isub(a, b): | 
					
						
							|  |  |  |     "Same as a -= b." | 
					
						
							|  |  |  |     a -= b | 
					
						
							|  |  |  |     return a | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def itruediv(a, b): | 
					
						
							|  |  |  |     "Same as a /= b." | 
					
						
							|  |  |  |     a /= b | 
					
						
							|  |  |  |     return a | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def ixor(a, b): | 
					
						
							|  |  |  |     "Same as a ^= b." | 
					
						
							|  |  |  |     a ^= b | 
					
						
							|  |  |  |     return a | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | try: | 
					
						
							|  |  |  |     from _operator import * | 
					
						
							| 
									
										
										
										
											2013-07-04 17:43:24 -04:00
										 |  |  | except ImportError: | 
					
						
							| 
									
										
										
										
											2013-04-20 19:21:44 +02:00
										 |  |  |     pass | 
					
						
							|  |  |  | else: | 
					
						
							|  |  |  |     from _operator import __doc__ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # All of these "__func__ = func" assignments have to happen after importing | 
					
						
							|  |  |  | # from _operator to make sure they're set to the right function | 
					
						
							|  |  |  | __lt__ = lt | 
					
						
							|  |  |  | __le__ = le | 
					
						
							|  |  |  | __eq__ = eq | 
					
						
							|  |  |  | __ne__ = ne | 
					
						
							|  |  |  | __ge__ = ge | 
					
						
							|  |  |  | __gt__ = gt | 
					
						
							|  |  |  | __not__ = not_ | 
					
						
							|  |  |  | __abs__ = abs | 
					
						
							|  |  |  | __add__ = add | 
					
						
							|  |  |  | __and__ = and_ | 
					
						
							|  |  |  | __floordiv__ = floordiv | 
					
						
							|  |  |  | __index__ = index | 
					
						
							|  |  |  | __inv__ = inv | 
					
						
							|  |  |  | __invert__ = invert | 
					
						
							|  |  |  | __lshift__ = lshift | 
					
						
							|  |  |  | __mod__ = mod | 
					
						
							|  |  |  | __mul__ = mul | 
					
						
							|  |  |  | __neg__ = neg | 
					
						
							|  |  |  | __or__ = or_ | 
					
						
							|  |  |  | __pos__ = pos | 
					
						
							|  |  |  | __pow__ = pow | 
					
						
							|  |  |  | __rshift__ = rshift | 
					
						
							|  |  |  | __sub__ = sub | 
					
						
							|  |  |  | __truediv__ = truediv | 
					
						
							|  |  |  | __xor__ = xor | 
					
						
							|  |  |  | __concat__ = concat | 
					
						
							|  |  |  | __contains__ = contains | 
					
						
							|  |  |  | __delitem__ = delitem | 
					
						
							|  |  |  | __getitem__ = getitem | 
					
						
							|  |  |  | __setitem__ = setitem | 
					
						
							|  |  |  | __iadd__ = iadd | 
					
						
							|  |  |  | __iand__ = iand | 
					
						
							|  |  |  | __iconcat__ = iconcat | 
					
						
							|  |  |  | __ifloordiv__ = ifloordiv | 
					
						
							|  |  |  | __ilshift__ = ilshift | 
					
						
							|  |  |  | __imod__ = imod | 
					
						
							|  |  |  | __imul__ = imul | 
					
						
							|  |  |  | __ior__ = ior | 
					
						
							|  |  |  | __ipow__ = ipow | 
					
						
							|  |  |  | __irshift__ = irshift | 
					
						
							|  |  |  | __isub__ = isub | 
					
						
							|  |  |  | __itruediv__ = itruediv | 
					
						
							|  |  |  | __ixor__ = ixor |