mirror of
https://github.com/python/cpython.git
synced 2024-11-27 11:55:13 +08:00
8f8ec92de8
requires them. Disable executable bits and shebang lines in test and benchmark files in order to prevent using a random system python, and in source files of modules which don't provide command line interface. Fixed shebang lines in the unittestgui and checkpip scripts.
412 lines
9.0 KiB
Python
412 lines
9.0 KiB
Python
"""
|
|
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.
|
|
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
|
|
(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.
|
|
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])
|
|
"""
|
|
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 *
|
|
except ImportError:
|
|
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
|