1""" 2Operator Interface 3 4This module exports a set of functions corresponding to the intrinsic 5operators of Python. For example, operator.add(x, y) is equivalent 6to the expression x+y. The function names are those used for special 7methods; variants without leading and trailing '__' are also provided 8for 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_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 22from builtins import abs as _abs 23 24 25# Comparison Operations *******************************************************# 26 27def lt(a, b): 28 "Same as a < b." 29 return a < b 30 31def le(a, b): 32 "Same as a <= b." 33 return a <= b 34 35def eq(a, b): 36 "Same as a == b." 37 return a == b 38 39def ne(a, b): 40 "Same as a != b." 41 return a != b 42 43def ge(a, b): 44 "Same as a >= b." 45 return a >= b 46 47def gt(a, b): 48 "Same as a > b." 49 return a > b 50 51# Logical Operations **********************************************************# 52 53def not_(a): 54 "Same as not a." 55 return not a 56 57def truth(a): 58 "Return True if a is true, False otherwise." 59 return True if a else False 60 61def is_(a, b): 62 "Same as a is b." 63 return a is b 64 65def is_not(a, b): 66 "Same as a is not b." 67 return a is not b 68 69# Mathematical/Bitwise Operations *********************************************# 70 71def abs(a): 72 "Same as abs(a)." 73 return _abs(a) 74 75def add(a, b): 76 "Same as a + b." 77 return a + b 78 79def and_(a, b): 80 "Same as a & b." 81 return a & b 82 83def floordiv(a, b): 84 "Same as a // b." 85 return a // b 86 87def index(a): 88 "Same as a.__index__()." 89 return a.__index__() 90 91def inv(a): 92 "Same as ~a." 93 return ~a 94invert = inv 95 96def lshift(a, b): 97 "Same as a << b." 98 return a << b 99 100def mod(a, b): 101 "Same as a % b." 102 return a % b 103 104def mul(a, b): 105 "Same as a * b." 106 return a * b 107 108def matmul(a, b): 109 "Same as a @ b." 110 return a @ b 111 112def neg(a): 113 "Same as -a." 114 return -a 115 116def or_(a, b): 117 "Same as a | b." 118 return a | b 119 120def pos(a): 121 "Same as +a." 122 return +a 123 124def pow(a, b): 125 "Same as a ** b." 126 return a ** b 127 128def rshift(a, b): 129 "Same as a >> b." 130 return a >> b 131 132def sub(a, b): 133 "Same as a - b." 134 return a - b 135 136def truediv(a, b): 137 "Same as a / b." 138 return a / b 139 140def xor(a, b): 141 "Same as a ^ b." 142 return a ^ b 143 144# Sequence Operations *********************************************************# 145 146def 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 153def contains(a, b): 154 "Same as b in a (note reversed operands)." 155 return b in a 156 157def 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 165def delitem(a, b): 166 "Same as del a[b]." 167 del a[b] 168 169def getitem(a, b): 170 "Same as a[b]." 171 return a[b] 172 173def 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 181def setitem(a, b, c): 182 "Same as a[b] = c." 183 a[b] = c 184 185def 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 226def call(obj, /, *args, **kwargs): 227 """Same as obj(*args, **kwargs).""" 228 return obj(*args, **kwargs) 229 230# Generalized Lookup Objects **************************************************# 231 232class attrgetter: 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 271class itemgetter: 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 302class methodcaller: 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 339def iadd(a, b): 340 "Same as a += b." 341 a += b 342 return a 343 344def iand(a, b): 345 "Same as a &= b." 346 a &= b 347 return a 348 349def 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 357def ifloordiv(a, b): 358 "Same as a //= b." 359 a //= b 360 return a 361 362def ilshift(a, b): 363 "Same as a <<= b." 364 a <<= b 365 return a 366 367def imod(a, b): 368 "Same as a %= b." 369 a %= b 370 return a 371 372def imul(a, b): 373 "Same as a *= b." 374 a *= b 375 return a 376 377def imatmul(a, b): 378 "Same as a @= b." 379 a @= b 380 return a 381 382def ior(a, b): 383 "Same as a |= b." 384 a |= b 385 return a 386 387def ipow(a, b): 388 "Same as a **= b." 389 a **=b 390 return a 391 392def irshift(a, b): 393 "Same as a >>= b." 394 a >>= b 395 return a 396 397def isub(a, b): 398 "Same as a -= b." 399 a -= b 400 return a 401 402def itruediv(a, b): 403 "Same as a /= b." 404 a /= b 405 return a 406 407def ixor(a, b): 408 "Same as a ^= b." 409 a ^= b 410 return a 411 412 413try: 414 from _operator import * 415except ImportError: 416 pass 417else: 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 468