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', '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 times b occurs in a." 159 count = 0 160 for i in a: 161 if 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 == 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# Generalized Lookup Objects **************************************************# 225 226class 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 265class 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 296class 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__(self, name, /, *args, **kwargs): 306 self._name = name 307 if not isinstance(self._name, str): 308 raise TypeError('method name must be a string') 309 self._args = args 310 self._kwargs = kwargs 311 312 def __call__(self, obj): 313 return getattr(obj, self._name)(*self._args, **self._kwargs) 314 315 def __repr__(self): 316 args = [repr(self._name)] 317 args.extend(map(repr, self._args)) 318 args.extend('%s=%r' % (k, v) for k, v in self._kwargs.items()) 319 return '%s.%s(%s)' % (self.__class__.__module__, 320 self.__class__.__name__, 321 ', '.join(args)) 322 323 def __reduce__(self): 324 if not self._kwargs: 325 return self.__class__, (self._name,) + self._args 326 else: 327 from functools import partial 328 return partial(self.__class__, self._name, **self._kwargs), self._args 329 330 331# In-place Operations *********************************************************# 332 333def iadd(a, b): 334 "Same as a += b." 335 a += b 336 return a 337 338def iand(a, b): 339 "Same as a &= b." 340 a &= b 341 return a 342 343def iconcat(a, b): 344 "Same as a += b, for a and b sequences." 345 if not hasattr(a, '__getitem__'): 346 msg = "'%s' object can't be concatenated" % type(a).__name__ 347 raise TypeError(msg) 348 a += b 349 return a 350 351def ifloordiv(a, b): 352 "Same as a //= b." 353 a //= b 354 return a 355 356def ilshift(a, b): 357 "Same as a <<= b." 358 a <<= b 359 return a 360 361def imod(a, b): 362 "Same as a %= b." 363 a %= b 364 return a 365 366def imul(a, b): 367 "Same as a *= b." 368 a *= b 369 return a 370 371def imatmul(a, b): 372 "Same as a @= b." 373 a @= b 374 return a 375 376def ior(a, b): 377 "Same as a |= b." 378 a |= b 379 return a 380 381def ipow(a, b): 382 "Same as a **= b." 383 a **=b 384 return a 385 386def irshift(a, b): 387 "Same as a >>= b." 388 a >>= b 389 return a 390 391def isub(a, b): 392 "Same as a -= b." 393 a -= b 394 return a 395 396def itruediv(a, b): 397 "Same as a /= b." 398 a /= b 399 return a 400 401def ixor(a, b): 402 "Same as a ^= b." 403 a ^= b 404 return a 405 406 407try: 408 from _operator import * 409except ImportError: 410 pass 411else: 412 from _operator import __doc__ 413 414# All of these "__func__ = func" assignments have to happen after importing 415# from _operator to make sure they're set to the right function 416__lt__ = lt 417__le__ = le 418__eq__ = eq 419__ne__ = ne 420__ge__ = ge 421__gt__ = gt 422__not__ = not_ 423__abs__ = abs 424__add__ = add 425__and__ = and_ 426__floordiv__ = floordiv 427__index__ = index 428__inv__ = inv 429__invert__ = invert 430__lshift__ = lshift 431__mod__ = mod 432__mul__ = mul 433__matmul__ = matmul 434__neg__ = neg 435__or__ = or_ 436__pos__ = pos 437__pow__ = pow 438__rshift__ = rshift 439__sub__ = sub 440__truediv__ = truediv 441__xor__ = xor 442__concat__ = concat 443__contains__ = contains 444__delitem__ = delitem 445__getitem__ = getitem 446__setitem__ = setitem 447__iadd__ = iadd 448__iand__ = iand 449__iconcat__ = iconcat 450__ifloordiv__ = ifloordiv 451__ilshift__ = ilshift 452__imod__ = imod 453__imul__ = imul 454__imatmul__ = imatmul 455__ior__ = ior 456__ipow__ = ipow 457__irshift__ = irshift 458__isub__ = isub 459__itruediv__ = itruediv 460__ixor__ = ixor 461