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