codekingpro/portable-devtools
114k
1"""2Operator Interface3 4This module exports a set of functions corresponding to the intrinsic5operators of Python. For example, operator.add(x, y) is equivalent6to the expression x+y. The function names are those used for special7methods; variants without leading and trailing '__' are also provided8for convenience.9 10This 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_none', 'is_not', 'is_not_none', 'isub', 'itemgetter', 'itruediv',18 'ixor', 'le', 'length_hint', 'lshift', 'lt', 'matmul', 'methodcaller', 'mod',19 'mul', 'ne', 'neg', 'not_', 'or_', 'pos', 'pow', 'rshift',20 'setitem', 'sub', 'truediv', 'truth', 'xor']21 22from builtins import abs as _abs23 24 25# Comparison Operations *******************************************************#26 27def lt(a, b):28 "Same as a < b."29 return a < b30 31def le(a, b):32 "Same as a <= b."33 return a <= b34 35def eq(a, b):36 "Same as a == b."37 return a == b38 39def ne(a, b):40 "Same as a != b."41 return a != b42 43def ge(a, b):44 "Same as a >= b."45 return a >= b46 47def gt(a, b):48 "Same as a > b."49 return a > b50 51# Logical Operations **********************************************************#52 53def not_(a):54 "Same as not a."55 return not a56 57def truth(a):58 "Return True if a is true, False otherwise."59 return True if a else False60 61def is_(a, b):62 "Same as a is b."63 return a is b64 65def is_not(a, b):66 "Same as a is not b."67 return a is not b68 69def is_none(a):70 "Same as a is None."71 return a is None72 73def is_not_none(a):74 "Same as a is not None."75 return a is not None76 77# Mathematical/Bitwise Operations *********************************************#78 79def abs(a):80 "Same as abs(a)."81 return _abs(a)82 83def add(a, b):84 "Same as a + b."85 return a + b86 87def and_(a, b):88 "Same as a & b."89 return a & b90 91def floordiv(a, b):92 "Same as a // b."93 return a // b94 95def index(a):96 "Same as a.__index__()."97 return a.__index__()98 99def inv(a):100 "Same as ~a."101 return ~a102invert = inv103 104def lshift(a, b):105 "Same as a << b."106 return a << b107 108def mod(a, b):109 "Same as a % b."110 return a % b111 112def mul(a, b):113 "Same as a * b."114 return a * b115 116def matmul(a, b):117 "Same as a @ b."118 return a @ b119 120def neg(a):121 "Same as -a."122 return -a123 124def or_(a, b):125 "Same as a | b."126 return a | b127 128def pos(a):129 "Same as +a."130 return +a131 132def pow(a, b):133 "Same as a ** b."134 return a ** b135 136def rshift(a, b):137 "Same as a >> b."138 return a >> b139 140def sub(a, b):141 "Same as a - b."142 return a - b143 144def truediv(a, b):145 "Same as a / b."146 return a / b147 148def xor(a, b):149 "Same as a ^ b."150 return a ^ b151 152# Sequence Operations *********************************************************#153 154def concat(a, b):155 "Same as a + b, for a and b sequences."156 if not hasattr(a, '__getitem__'):157 msg = "'%s' object can't be concatenated" % type(a).__name__158 raise TypeError(msg)159 return a + b160 161def contains(a, b):162 "Same as b in a (note reversed operands)."163 return b in a164 165def countOf(a, b):166 "Return the number of items in a which are, or which equal, b."167 count = 0168 for i in a:169 if i is b or i == b:170 count += 1171 return count172 173def delitem(a, b):174 "Same as del a[b]."175 del a[b]176 177def getitem(a, b):178 "Same as a[b]."179 return a[b]180 181def indexOf(a, b):182 "Return the first index of b in a."183 for i, j in enumerate(a):184 if j is b or j == b:185 return i186 else:187 raise ValueError('sequence.index(x): x not in sequence')188 189def setitem(a, b, c):190 "Same as a[b] = c."191 a[b] = c192 193def length_hint(obj, default=0):194 """195 Return an estimate of the number of items in obj.196 This is useful for presizing containers when building from an iterable.197 198 If the object supports len(), the result will be exact. Otherwise, it may199 over- or under-estimate by an arbitrary amount. The result will be an200 integer >= 0.201 """202 if not isinstance(default, int):203 msg = ("'%s' object cannot be interpreted as an integer" %204 type(default).__name__)205 raise TypeError(msg)206 207 try:208 return len(obj)209 except TypeError:210 pass211 212 try:213 hint = type(obj).__length_hint__214 except AttributeError:215 return default216 217 try:218 val = hint(obj)219 except TypeError:220 return default221 if val is NotImplemented:222 return default223 if not isinstance(val, int):224 msg = ('__length_hint__ must be integer, not %s' %225 type(val).__name__)226 raise TypeError(msg)227 if val < 0:228 msg = '__length_hint__() should return >= 0'229 raise ValueError(msg)230 return val231 232# Other Operations ************************************************************#233 234def call(obj, /, *args, **kwargs):235 """Same as obj(*args, **kwargs)."""236 return obj(*args, **kwargs)237 238# Generalized Lookup Objects **************************************************#239 240class attrgetter:241 """242 Return a callable object that fetches the given attribute(s) from its operand.243 After f = attrgetter('name'), the call f(r) returns r.name.244 After g = attrgetter('name', 'date'), the call g(r) returns (r.name, r.date).245 After h = attrgetter('name.first', 'name.last'), the call h(r) returns246 (r.name.first, r.name.last).247 """248 __slots__ = ('_attrs', '_call')249 250 def __init__(self, attr, /, *attrs):251 if not attrs:252 if not isinstance(attr, str):253 raise TypeError('attribute name must be a string')254 self._attrs = (attr,)255 names = attr.split('.')256 def func(obj):257 for name in names:258 obj = getattr(obj, name)259 return obj260 self._call = func261 else:262 self._attrs = (attr,) + attrs263 getters = tuple(map(attrgetter, self._attrs))264 def func(obj):265 return tuple(getter(obj) for getter in getters)266 self._call = func267 268 def __call__(self, obj, /):269 return self._call(obj)270 271 def __repr__(self):272 return '%s.%s(%s)' % (self.__class__.__module__,273 self.__class__.__qualname__,274 ', '.join(map(repr, self._attrs)))275 276 def __reduce__(self):277 return self.__class__, self._attrs278 279class itemgetter:280 """281 Return a callable object that fetches the given item(s) from its operand.282 After f = itemgetter(2), the call f(r) returns r[2].283 After g = itemgetter(2, 5, 3), the call g(r) returns (r[2], r[5], r[3])284 """285 __slots__ = ('_items', '_call')286 287 def __init__(self, item, /, *items):288 if not items:289 self._items = (item,)290 def func(obj):291 return obj[item]292 self._call = func293 else:294 self._items = items = (item,) + items295 def func(obj):296 return tuple(obj[i] for i in items)297 self._call = func298 299 def __call__(self, obj, /):300 return self._call(obj)301 302 def __repr__(self):303 return '%s.%s(%s)' % (self.__class__.__module__,304 self.__class__.__name__,305 ', '.join(map(repr, self._items)))306 307 def __reduce__(self):308 return self.__class__, self._items309 310class methodcaller:311 """312 Return a callable object that calls the given method on its operand.313 After f = methodcaller('name'), the call f(r) returns r.name().314 After g = methodcaller('name', 'date', foo=1), the call g(r) returns315 r.name('date', foo=1).316 """317 __slots__ = ('_name', '_args', '_kwargs')318 319 def __init__(self, name, /, *args, **kwargs):320 self._name = name321 if not isinstance(self._name, str):322 raise TypeError('method name must be a string')323 self._args = args324 self._kwargs = kwargs325 326 def __call__(self, obj, /):327 return getattr(obj, self._name)(*self._args, **self._kwargs)328 329 def __repr__(self):330 args = [repr(self._name)]331 args.extend(map(repr, self._args))332 args.extend('%s=%r' % (k, v) for k, v in self._kwargs.items())333 return '%s.%s(%s)' % (self.__class__.__module__,334 self.__class__.__name__,335 ', '.join(args))336 337 def __reduce__(self):338 if not self._kwargs:339 return self.__class__, (self._name,) + self._args340 else:341 from functools import partial342 return partial(self.__class__, self._name, **self._kwargs), self._args343 344 345# In-place Operations *********************************************************#346 347def iadd(a, b):348 "Same as a += b."349 a += b350 return a351 352def iand(a, b):353 "Same as a &= b."354 a &= b355 return a356 357def iconcat(a, b):358 "Same as a += b, for a and b sequences."359 if not hasattr(a, '__getitem__'):360 msg = "'%s' object can't be concatenated" % type(a).__name__361 raise TypeError(msg)362 a += b363 return a364 365def ifloordiv(a, b):366 "Same as a //= b."367 a //= b368 return a369 370def ilshift(a, b):371 "Same as a <<= b."372 a <<= b373 return a374 375def imod(a, b):376 "Same as a %= b."377 a %= b378 return a379 380def imul(a, b):381 "Same as a *= b."382 a *= b383 return a384 385def imatmul(a, b):386 "Same as a @= b."387 a @= b388 return a389 390def ior(a, b):391 "Same as a |= b."392 a |= b393 return a394 395def ipow(a, b):396 "Same as a **= b."397 a **=b398 return a399 400def irshift(a, b):401 "Same as a >>= b."402 a >>= b403 return a404 405def isub(a, b):406 "Same as a -= b."407 a -= b408 return a409 410def itruediv(a, b):411 "Same as a /= b."412 a /= b413 return a414 415def ixor(a, b):416 "Same as a ^= b."417 a ^= b418 return a419 420 421try:422 from _operator import *423except ImportError:424 pass425else:426 from _operator import __doc__ # noqa: F401427 428# All of these "__func__ = func" assignments have to happen after importing429# from _operator to make sure they're set to the right function430__lt__ = lt431__le__ = le432__eq__ = eq433__ne__ = ne434__ge__ = ge435__gt__ = gt436__not__ = not_437__abs__ = abs438__add__ = add439__and__ = and_440__call__ = call441__floordiv__ = floordiv442__index__ = index443__inv__ = inv444__invert__ = invert445__lshift__ = lshift446__mod__ = mod447__mul__ = mul448__matmul__ = matmul449__neg__ = neg450__or__ = or_451__pos__ = pos452__pow__ = pow453__rshift__ = rshift454__sub__ = sub455__truediv__ = truediv456__xor__ = xor457__concat__ = concat458__contains__ = contains459__delitem__ = delitem460__getitem__ = getitem461__setitem__ = setitem462__iadd__ = iadd463__iand__ = iand464__iconcat__ = iconcat465__ifloordiv__ = ifloordiv466__ilshift__ = ilshift467__imod__ = imod468__imul__ = imul469__imatmul__ = imatmul470__ior__ = ior471__ipow__ = ipow472__irshift__ = irshift473__isub__ = isub474__itruediv__ = itruediv475__ixor__ = ixor476 