github.com/grumpyhome/grumpy@v0.3.1-0.20201208125205-7b775405bdf1/grumpy-runtime-src/third_party/ouroboros/operator.py (about)

     1  """
     2  Operator Interface
     3  This module exports a set of functions corresponding to the intrinsic
     4  operators of Python.  For example, operator.add(x, y) is equivalent
     5  to the expression x+y.  The function names are those used for special
     6  methods; variants without leading and trailing '__' are also provided
     7  for convenience.
     8  This is the pure Python implementation of the module.
     9  """
    10  
    11  __all__ = ['abs', 'add', 'and_', 'attrgetter', 'concat', 'contains', 'countOf',
    12             'delitem', 'eq', 'floordiv', 'ge', 'getitem', 'gt', 'iadd', 'iand',
    13             'iconcat', 'ifloordiv', 'ilshift', 'imod', 'imul', 'index',
    14             'indexOf', 'inv', 'invert', 'ior', 'ipow', 'irshift', 'is_',
    15             'is_not', 'isub', 'itemgetter', 'itruediv', 'ixor', 'le',
    16             'length_hint', 'lshift', 'lt', 'methodcaller', 'mod', 'mul', 'ne',
    17             'neg', 'not_', 'or_', 'pos', 'pow', 'rshift', 'setitem', 'sub',
    18             'truediv', 'truth', 'xor']
    19  
    20  from '__go__/math' import Abs as _abs
    21  
    22  
    23  # Comparison Operations *******************************************************#
    24  
    25  def lt(a, b):
    26      "Same as a < b."
    27      return a < b
    28  
    29  def le(a, b):
    30      "Same as a <= b."
    31      return a <= b
    32  
    33  def eq(a, b):
    34      "Same as a == b."
    35      return a == b
    36  
    37  def ne(a, b):
    38      "Same as a != b."
    39      return a != b
    40  
    41  def ge(a, b):
    42      "Same as a >= b."
    43      return a >= b
    44  
    45  def gt(a, b):
    46      "Same as a > b."
    47      return a > b
    48  
    49  # Logical Operations **********************************************************#
    50  
    51  def not_(a):
    52      "Same as not a."
    53      return not a
    54  
    55  def truth(a):
    56      "Return True if a is true, False otherwise."
    57      return True if a else False
    58  
    59  def is_(a, b):
    60      "Same as a is b."
    61      return a is b
    62  
    63  def is_not(a, b):
    64      "Same as a is not b."
    65      return a is not b
    66  
    67  # Mathematical/Bitwise Operations *********************************************#
    68  
    69  def abs(a):
    70      "Same as abs(a)."
    71      return _abs(a)
    72  
    73  def add(a, b):
    74      "Same as a + b."
    75      return a + b
    76  
    77  def and_(a, b):
    78      "Same as a & b."
    79      return a & b
    80  
    81  def floordiv(a, b):
    82      "Same as a // b."
    83      return a // b
    84  
    85  def index(a):
    86      "Same as a.__index__()."
    87      return a.__index__()
    88  
    89  def inv(a):
    90      "Same as ~a."
    91      return ~a
    92  invert = inv
    93  
    94  def lshift(a, b):
    95      "Same as a << b."
    96      return a << b
    97  
    98  def mod(a, b):
    99      "Same as a % b."
   100      return a % b
   101  
   102  def mul(a, b):
   103      "Same as a * b."
   104      return a * b
   105  
   106  def neg(a):
   107      "Same as -a."
   108      return -a
   109  
   110  def or_(a, b):
   111      "Same as a | b."
   112      return a | b
   113  
   114  def pos(a):
   115      "Same as +a."
   116      return +a
   117  
   118  def pow(a, b):
   119      "Same as a ** b."
   120      return a**b
   121  
   122  def rshift(a, b):
   123      "Same as a >> b."
   124      return a >> b
   125  
   126  def sub(a, b):
   127      "Same as a - b."
   128      return a - b
   129  
   130  def truediv(a, b):
   131      "Same as a / b."
   132      if type(a) == int or type(a) == long:
   133          a = float(a)
   134      return a / b
   135  
   136  def xor(a, b):
   137      "Same as a ^ b."
   138      return a ^ b
   139  
   140  # Sequence Operations *********************************************************#
   141  
   142  def concat(a, b):
   143      "Same as a + b, for a and b sequences."
   144      if not hasattr(a, '__getitem__'):
   145          msg = "'%s' object can't be concatenated" % type(a).__name__
   146          raise TypeError(msg)
   147      return a + b
   148  
   149  def contains(a, b):
   150      "Same as b in a (note reversed operands)."
   151      return b in a
   152  
   153  def countOf(a, b):
   154      "Return the number of times b occurs in a."
   155      count = 0
   156      for i in a:
   157          if i == b:
   158              count += 1
   159      return count
   160  
   161  def delitem(a, b):
   162      "Same as del a[b]."
   163      del a[b]
   164  
   165  def getitem(a, b):
   166      "Same as a[b]."
   167      return a[b]
   168  
   169  def indexOf(a, b):
   170      "Return the first index of b in a."
   171      for i, j in enumerate(a):
   172          if j == b:
   173              return i
   174      else:
   175          raise ValueError('sequence.index(x): x not in sequence')
   176  
   177  def setitem(a, b, c):
   178      "Same as a[b] = c."
   179      a[b] = c
   180  
   181  def length_hint(obj, default=0):
   182      """
   183      Return an estimate of the number of items in obj.
   184      This is useful for presizing containers when building from an iterable.
   185      If the object supports len(), the result will be exact. Otherwise, it may
   186      over- or under-estimate by an arbitrary amount. The result will be an
   187      integer >= 0.
   188      """
   189      if not isinstance(default, int):
   190          msg = ("'%s' object cannot be interpreted as an integer" %
   191                 type(default).__name__)
   192          raise TypeError(msg)
   193  
   194      try:
   195          return len(obj)
   196      except TypeError:
   197          pass
   198  
   199      try:
   200          hint = type(obj).__length_hint__
   201      except AttributeError:
   202          return default
   203  
   204      try:
   205          val = hint(obj)
   206      except TypeError:
   207          return default
   208      if val is NotImplemented:
   209          return default
   210      if not isinstance(val, int):
   211          msg = ('__length_hint__ must be integer, not %s' %
   212                 type(val).__name__)
   213          raise TypeError(msg)
   214      if val < 0:
   215          msg = '__length_hint__() should return >= 0'
   216          raise ValueError(msg)
   217      return val
   218  
   219  # Generalized Lookup Objects **************************************************#
   220  
   221  # TODO: class attrgetter:
   222  class attrgetter(object):
   223      """
   224      Return a callable object that fetches the given attribute(s) from its operand.
   225      After f = attrgetter('name'), the call f(r) returns r.name.
   226      After g = attrgetter('name', 'date'), the call g(r) returns (r.name, r.date).
   227      After h = attrgetter('name.first', 'name.last'), the call h(r) returns
   228      (r.name.first, r.name.last).
   229      """
   230      def __init__(self, attr, *attrs):
   231          if not attrs:
   232              if not isinstance(attr, str):
   233                  raise TypeError('attribute name must be a string')
   234              names = attr.split('.')
   235              def func(obj):
   236                  for name in names:
   237                      obj = getattr(obj, name)
   238                  return obj
   239              self._call = func
   240          else:
   241              getters = tuple(map(attrgetter, (attr,) + attrs))
   242              def func(obj):
   243                  return tuple(getter(obj) for getter in getters)
   244              self._call = func
   245  
   246      def __call__(self, obj):
   247          return self._call(obj)
   248  
   249  # TODO: class itemgetter:
   250  class itemgetter(object):
   251      """
   252      Return a callable object that fetches the given item(s) from its operand.
   253      After f = itemgetter(2), the call f(r) returns r[2].
   254      After g = itemgetter(2, 5, 3), the call g(r) returns (r[2], r[5], r[3])
   255      """
   256      def __init__(self, item, *items):
   257          if not items:
   258              def func(obj):
   259                  return obj[item]
   260              self._call = func
   261          else:
   262              items = (item,) + items
   263              def func(obj):
   264                  return tuple(obj[i] for i in items)
   265              self._call = func
   266  
   267      def __call__(self, obj):
   268          return self._call(obj)
   269  
   270  # TODO: class methodcaller:
   271  class methodcaller(object):
   272      """
   273      Return a callable object that calls the given method on its operand.
   274      After f = methodcaller('name'), the call f(r) returns r.name().
   275      After g = methodcaller('name', 'date', foo=1), the call g(r) returns
   276      r.name('date', foo=1).
   277      """
   278  
   279      def __init__(*args, **kwargs):
   280          if len(args) < 2:
   281              msg = "methodcaller needs at least one argument, the method name"
   282              raise TypeError(msg)
   283          self = args[0]
   284          self._name = args[1]
   285          self._args = args[2:]
   286          self._kwargs = kwargs
   287  
   288      def __call__(self, obj):
   289          return getattr(obj, self._name)(*self._args, **self._kwargs)
   290  
   291  # In-place Operations *********************************************************#
   292  
   293  def iadd(a, b):
   294      "Same as a += b."
   295      a += b
   296      return a
   297  
   298  def iand(a, b):
   299      "Same as a &= b."
   300      a &= b
   301      return a
   302  
   303  def iconcat(a, b):
   304      "Same as a += b, for a and b sequences."
   305      if not hasattr(a, '__getitem__'):
   306          msg = "'%s' object can't be concatenated" % type(a).__name__
   307          raise TypeError(msg)
   308      a += b
   309      return a
   310  
   311  def ifloordiv(a, b):
   312      "Same as a //= b."
   313      a //= b
   314      return a
   315  
   316  def ilshift(a, b):
   317      "Same as a <<= b."
   318      a <<= b
   319      return a
   320  
   321  def imod(a, b):
   322      "Same as a %= b."
   323      a %= b
   324      return a
   325  
   326  def imul(a, b):
   327      "Same as a *= b."
   328      a *= b
   329      return a
   330  
   331  def ior(a, b):
   332      "Same as a |= b."
   333      a |= b
   334      return a
   335  
   336  def ipow(a, b):
   337      "Same as a **= b."
   338      a **= b
   339      return a
   340  
   341  def irshift(a, b):
   342      "Same as a >>= b."
   343      a >>= b
   344      return a
   345  
   346  def isub(a, b):
   347      "Same as a -= b."
   348      a -= b
   349      return a
   350  
   351  def itruediv(a, b):
   352      "Same as a /= b."
   353      if type(a) == int or type(a) == long:
   354          a = float(a)
   355      a /= b
   356      return a
   357  
   358  def ixor(a, b):
   359      "Same as a ^= b."
   360      a ^= b
   361      return a
   362  
   363  # TODO: https://github.com/google/grumpy/pull/263
   364  #try:
   365  #    from _operator import *
   366  #except ImportError:
   367  #    pass
   368  #else:
   369  #    from _operator import __doc__
   370  
   371  # All of these "__func__ = func" assignments have to happen after importing
   372  # from _operator to make sure they're set to the right function
   373  __lt__ = lt
   374  __le__ = le
   375  __eq__ = eq
   376  __ne__ = ne
   377  __ge__ = ge
   378  __gt__ = gt
   379  __not__ = not_
   380  __abs__ = abs
   381  __add__ = add
   382  __and__ = and_
   383  __floordiv__ = floordiv
   384  __index__ = index
   385  __inv__ = inv
   386  __invert__ = invert
   387  __lshift__ = lshift
   388  __mod__ = mod
   389  __mul__ = mul
   390  __neg__ = neg
   391  __or__ = or_
   392  __pos__ = pos
   393  __pow__ = pow
   394  __rshift__ = rshift
   395  __sub__ = sub
   396  __truediv__ = truediv
   397  __xor__ = xor
   398  __concat__ = concat
   399  __contains__ = contains
   400  __delitem__ = delitem
   401  __getitem__ = getitem
   402  __setitem__ = setitem
   403  __iadd__ = iadd
   404  __iand__ = iand
   405  __iconcat__ = iconcat
   406  __ifloordiv__ = ifloordiv
   407  __ilshift__ = ilshift
   408  __imod__ = imod
   409  __imul__ = imul
   410  __ior__ = ior
   411  __ipow__ = ipow
   412  __irshift__ = irshift
   413  __isub__ = isub
   414  __itruediv__ = itruediv
   415  __ixor__ = ixor