class xnd_gumath(xnd):
def __new__(cls, *args, **kwargs):
ops = {
'add': 'add', 'sub': 'subtract', 'mul': 'multiply',
'div': 'divide', 'floordiv': 'divide', 'truediv': 'divide',
}
map_types = {
'int': 'int32',
'float': 'float64'
}
def gen_fn(op, reversed_op=False):
def _target(*args):
l_args = list(args)
for i, v in enumerate(args):
if not isinstance(v, xnd):
_type = type(v)
_type_name = (
_type.__name__ if _type.__name__ not in map_types else
map_types[_type.__name__]
)
l_args[i] = xnd(v, type=_type_name)
if reversed_op:
l_args = l_args[::-1]
if any([not v.type.isscalar() for v in l_args]):
for i, v in enumerate(l_args):
if v.type.isscalar():
_type = '1 * {}'.format(str(v.type))
l_args[i] = xnd_gumath([v.value], type=_type)
return getattr(fn, op)(*tuple(l_args))
return _target
for py_op, gumath_op in ops.items():
setattr(cls, '__{}__'.format(py_op), gen_fn(gumath_op))
setattr(cls, '__r{}__'.format(py_op), gen_fn(gumath_op, reversed_op=True))
for op in fn.__dir__():
if op.startswith('__'):
continue
setattr(cls, op, gen_fn(op))
return super().__new__(cls, *args, **kwargs)