Home | History | Annotate | Download | only in Lib
      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', '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 times b occurs in a."
    159     count = 0
    160     for i in a:
    161         if 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 == 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 # Generalized Lookup Objects **************************************************#
    225 
    226 class attrgetter:
    227     """
    228     Return a callable object that fetches the given attribute(s) from its operand.
    229     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
    232     (r.name.first, r.name.last).
    233     """
    234     __slots__ = ('_attrs', '_call')
    235 
    236     def __init__(self, attr, *attrs):
    237         if not attrs:
    238             if not isinstance(attr, str):
    239                 raise TypeError('attribute name must be a string')
    240             self._attrs = (attr,)
    241             names = attr.split('.')
    242             def func(obj):
    243                 for name in names:
    244                     obj = getattr(obj, name)
    245                 return obj
    246             self._call = func
    247         else:
    248             self._attrs = (attr,) + attrs
    249             getters = tuple(map(attrgetter, self._attrs))
    250             def func(obj):
    251                 return tuple(getter(obj) for getter in getters)
    252             self._call = func
    253 
    254     def __call__(self, obj):
    255         return self._call(obj)
    256 
    257     def __repr__(self):
    258         return '%s.%s(%s)' % (self.__class__.__module__,
    259                               self.__class__.__qualname__,
    260                               ', '.join(map(repr, self._attrs)))
    261 
    262     def __reduce__(self):
    263         return self.__class__, self._attrs
    264 
    265 class itemgetter:
    266     """
    267     Return a callable object that fetches the given item(s) from its operand.
    268     After f = itemgetter(2), the call f(r) returns r[2].
    269     After g = itemgetter(2, 5, 3), the call g(r) returns (r[2], r[5], r[3])
    270     """
    271     __slots__ = ('_items', '_call')
    272 
    273     def __init__(self, item, *items):
    274         if not items:
    275             self._items = (item,)
    276             def func(obj):
    277                 return obj[item]
    278             self._call = func
    279         else:
    280             self._items = items = (item,) + items
    281             def func(obj):
    282                 return tuple(obj[i] for i in items)
    283             self._call = func
    284 
    285     def __call__(self, obj):
    286         return self._call(obj)
    287 
    288     def __repr__(self):
    289         return '%s.%s(%s)' % (self.__class__.__module__,
    290                               self.__class__.__name__,
    291                               ', '.join(map(repr, self._items)))
    292 
    293     def __reduce__(self):
    294         return self.__class__, self._items
    295 
    296 class methodcaller:
    297     """
    298     Return a callable object that calls the given method on its operand.
    299     After f = methodcaller('name'), the call f(r) returns r.name().
    300     After g = methodcaller('name', 'date', foo=1), the call g(r) returns
    301     r.name('date', foo=1).
    302     """
    303     __slots__ = ('_name', '_args', '_kwargs')
    304 
    305     def __init__(*args, **kwargs):
    306         if len(args) < 2:
    307             msg = "methodcaller needs at least one argument, the method name"
    308             raise TypeError(msg)
    309         self = args[0]
    310         self._name = args[1]
    311         if not isinstance(self._name, str):
    312             raise TypeError('method name must be a string')
    313         self._args = args[2:]
    314         self._kwargs = kwargs
    315 
    316     def __call__(self, obj):
    317         return getattr(obj, self._name)(*self._args, **self._kwargs)
    318 
    319     def __repr__(self):
    320         args = [repr(self._name)]
    321         args.extend(map(repr, self._args))
    322         args.extend('%s=%r' % (k, v) for k, v in self._kwargs.items())
    323         return '%s.%s(%s)' % (self.__class__.__module__,
    324                               self.__class__.__name__,
    325                               ', '.join(args))
    326 
    327     def __reduce__(self):
    328         if not self._kwargs:
    329             return self.__class__, (self._name,) + self._args
    330         else:
    331             from functools import partial
    332             return partial(self.__class__, self._name, **self._kwargs), self._args
    333 
    334 
    335 # In-place Operations *********************************************************#
    336 
    337 def iadd(a, b):
    338     "Same as a += b."
    339     a += b
    340     return a
    341 
    342 def iand(a, b):
    343     "Same as a &= b."
    344     a &= b
    345     return a
    346 
    347 def iconcat(a, b):
    348     "Same as a += b, for a and b sequences."
    349     if not hasattr(a, '__getitem__'):
    350         msg = "'%s' object can't be concatenated" % type(a).__name__
    351         raise TypeError(msg)
    352     a += b
    353     return a
    354 
    355 def ifloordiv(a, b):
    356     "Same as a //= b."
    357     a //= b
    358     return a
    359 
    360 def ilshift(a, b):
    361     "Same as a <<= b."
    362     a <<= b
    363     return a
    364 
    365 def imod(a, b):
    366     "Same as a %= b."
    367     a %= b
    368     return a
    369 
    370 def imul(a, b):
    371     "Same as a *= b."
    372     a *= b
    373     return a
    374 
    375 def imatmul(a, b):
    376     "Same as a @= b."
    377     a @= b
    378     return a
    379 
    380 def ior(a, b):
    381     "Same as a |= b."
    382     a |= b
    383     return a
    384 
    385 def ipow(a, b):
    386     "Same as a **= b."
    387     a **=b
    388     return a
    389 
    390 def irshift(a, b):
    391     "Same as a >>= b."
    392     a >>= b
    393     return a
    394 
    395 def isub(a, b):
    396     "Same as a -= b."
    397     a -= b
    398     return a
    399 
    400 def itruediv(a, b):
    401     "Same as a /= b."
    402     a /= b
    403     return a
    404 
    405 def ixor(a, b):
    406     "Same as a ^= b."
    407     a ^= b
    408     return a
    409 
    410 
    411 try:
    412     from _operator import *
    413 except ImportError:
    414     pass
    415 else:
    416     from _operator import __doc__
    417 
    418 # All of these "__func__ = func" assignments have to happen after importing
    419 # from _operator to make sure they're set to the right function
    420 __lt__ = lt
    421 __le__ = le
    422 __eq__ = eq
    423 __ne__ = ne
    424 __ge__ = ge
    425 __gt__ = gt
    426 __not__ = not_
    427 __abs__ = abs
    428 __add__ = add
    429 __and__ = and_
    430 __floordiv__ = floordiv
    431 __index__ = index
    432 __inv__ = inv
    433 __invert__ = invert
    434 __lshift__ = lshift
    435 __mod__ = mod
    436 __mul__ = mul
    437 __matmul__ = matmul
    438 __neg__ = neg
    439 __or__ = or_
    440 __pos__ = pos
    441 __pow__ = pow
    442 __rshift__ = rshift
    443 __sub__ = sub
    444 __truediv__ = truediv
    445 __xor__ = xor
    446 __concat__ = concat
    447 __contains__ = contains
    448 __delitem__ = delitem
    449 __getitem__ = getitem
    450 __setitem__ = setitem
    451 __iadd__ = iadd
    452 __iand__ = iand
    453 __iconcat__ = iconcat
    454 __ifloordiv__ = ifloordiv
    455 __ilshift__ = ilshift
    456 __imod__ = imod
    457 __imul__ = imul
    458 __imatmul__ = imatmul
    459 __ior__ = ior
    460 __ipow__ = ipow
    461 __irshift__ = irshift
    462 __isub__ = isub
    463 __itruediv__ = itruediv
    464 __ixor__ = ixor
    465