def bool_and(self_ty, other_ty): self_ty, other_ty = _astype(self_ty), _astype(other_ty) if self_ty is bool and other_ty is bool: return bool if all(issubclass(ty, (bool, int)) for ty in (self_ty, other_ty)): return int raise TypeError
def _oez_like(a, dtype, order, subok, shape): if not issubclass(a, NDArray): raise TypeError if dtype is _Cst[None]: dtype = a.__args__[0] if issubclass(dtype, _Ty): dtype = dtype.__args__[0] if not issubclass(dtype, (_np.number, int, float, complex)): raise TypeError if not issubclass(_astype(order), str): raise TypeError if not issubclass(_astype(subok), bool): raise TypeError if shape is _Cst[None]: shape = a.__args__[1] if shape is int or issubclass(shape, _Cst): shape = _Tuple[shape] # there's currently no child class of ndarray anyway :-) if subok is _Cst[True]: return a.__base__[dtype, shape] else: return NDArray[dtype, shape]
def rbinop(self, value): self, value = _astype(self), _astype(value) if not issubclass(self, dtype): raise TypeError if issubclass(value, (_np.generic, int, float, complex)): return type(operator(value(1), self(1))) else: raise TypeError
def dtype_pow(self, value, mod=_Cst[None]): self, value = _astype(self), _astype(value) if mod is not _Cst[None]: raise TypeError if issubclass(self, dtype) and issubclass(value, dtype): return dtype else: raise TypeError
def dtype_rdivmod(self, value): self, value = _astype(self), _astype(value) if not issubclass(self, dtype): raise TypeError if issubclass(value, (_np.generic, int, float, complex)): tmp = divmod(value(1), self(1)) return _Tuple[type(tmp[0]), type(tmp[1])] else: raise TypeError
def divmod_(self_ty, other_ty): from penty.penty import Types self_ty, other_ty = _astype(self_ty), _astype(other_ty) try: return Types[self_ty]['__divmod__'](self_ty, other_ty) except TypeError: if '__rdivmod__' in Types[other_ty]: return Types[other_ty]['__rdivmod__'](other_ty, self_ty) raise
def binop(self_ty, other_ty): self_ty, other_ty = _astype(self_ty), _astype(other_ty) if not issubclass(self_ty, complex): raise TypeError if not issubclass(other_ty, (int, float, complex)): raise TypeError return complex
def dict_setdefault(self_ty, key_ty, default_ty=None): if default_ty is None: default_ty = _Cst[None] else: default_ty = _astype(default_ty) self_ty.__args__[0].add(_astype(key_ty)) self_ty.__args__[1].add(default_ty) return dict_get(self_ty, key_ty, default_ty)
def dtype_rpow(self, value, mod=_Cst[None]): self, value = _astype(self), _astype(value) if mod is not _Cst[None] and not issubclass(mod, dtype): raise TypeError if not issubclass(self, dtype): raise TypeError if issubclass(value, (_np.generic, int, float, complex)): return type(pow(value(1), self(1))) else: raise TypeError
def binop(self, value): self, value = _astype(self), _astype(value) if not issubclass(self, dtype): raise TypeError if issubclass(value, (_np.generic, int)): try: return type(operator(self(1), value(1))) except TypeError: raise TypeError # FIXME: for a better message else: raise TypeError
def dtype_pow(self, value, mod=_Cst[None]): self, value = _astype(self), _astype(value) if not issubclass(self, dtype): raise TypeError if mod is not _Cst[None]: if issubclass(mod, (int, _np.integer)): return type(pow(dtype(), value(), mod())) else: raise TypeError if issubclass(value, (int, _np.integer)): return type(pow(dtype(), value())) else: raise TypeError
def ndarray_getitem(self, key_ty): dtype_ty, shape_ty = self.__args__ if _astype(key_ty) is int: if len(shape_ty.__args__) == 1: return dtype_ty else: return NDArray[dtype_ty, _Tuple[shape_ty.__args__[1:]]] if _astype(key_ty) is slice: return ndarray_getitem(self, _Tuple[key_ty]) if issubclass(_astype(key_ty), tuple): if len(shape_ty.__args__) < len(key_ty.__args__): raise TypeError new_shape = () padded_indices_dims = itertools.zip_longest(key_ty.__args__, shape_ty.__args__, fillvalue=slice) for index, dim in padded_indices_dims: if index is int: continue if index is slice: new_shape += _astype(dim), continue if issubclass(index, _Cst): index = index.__args__[0] if isinstance(index, int): continue if isinstance(index, slice): if issubclass(dim, _Cst): dim_v = dim.__args__[0] new_shape += _Cst[len([0] * dim_v)[index]] elif index.stop is None or index.stop < 0: new_shape += int, else: start = 0 if index.start is None else index.start step = 1 if index.step is None else index.step if start < 0: new_shape += int, else: new_shape += _Cst[(index.stop - start) // step], continue raise TypeError raise TypeError if new_shape: return NDArray[dtype_ty, _Tuple[new_shape]] else: return dtype_ty raise TypeError(key_ty)
def _floating_round(self, ndigits=None): if not issubclass(self, _np.floating): raise TypeError if ndigits is None: return type(self(1).__round__()) ndigits = _astype(ndigits) if not issubclass(ndigits, (_np.integer, int)): raise TypeError return type(self(1).__round__(ndigits(1)))
def complex_init(real_ty, imag_ty=None): from penty.penty import Types real_ty = _astype(real_ty) if imag_ty is None: if issubclass(real_ty, complex): return complex Types[real_ty]['__float__'](real_ty) return complex # interestingly, if the real part is a complex, everything is fine (!) imag_ty = _astype(imag_ty) if issubclass(real_ty, complex): if issubclass(imag_ty, complex): return complex Types[imag_ty]['__float__'](imag_ty) return complex Types[real_ty]['__float__'](real_ty) if issubclass(imag_ty, complex): return complex Types[imag_ty]['__float__'](imag_ty) return complex
def binop(self, value): from penty.penty import Types dtype_ty, shape_ty = self.__args__ value = _astype(value) if value in (bool, int, float): new_dtype_ty = Types[_Module['operator']][op](dtype_ty, value) return NDArray[new_dtype_ty, shape_ty] if issubclass(value, NDArray): other_dtype_ty, other_shape_ty = value.__args__ new_dtype_ty = Types[_Module['operator']][op](dtype_ty, other_dtype_ty) return NDArray[new_dtype_ty, _broadcast_shape(shape_ty, other_shape_ty)] raise TypeError
def ndarray_matmul(self, value): from penty.penty import Types dtype_ty, shape_ty = self.__args__ value = _astype(value) if value in (bool, int, float): raise TypeError if issubclass(value, NDArray): other_dtype_ty, other_shape_ty = value.__args__ # using mul instead of matmul for type inference as matmul is not # defined for some scalars, including int new_dtype_ty = Types[_Module['operator']]['__mul__'](dtype_ty, other_dtype_ty) return NDArray[new_dtype_ty, _broadcast_shape(shape_ty, other_shape_ty)] raise TypeError
def _oez(shape, dtype, order): if issubclass(dtype, _Ty): dtype = dtype.__args__[0] if not issubclass(dtype, (_np.number, int, float, complex)): raise TypeError if not issubclass(_astype(order), str): raise TypeError if shape is int or issubclass(shape, _Cst): return NDArray[dtype, _Tuple[shape]] if issubclass(shape, _Tuple): return NDArray[dtype, shape] raise NotImplementedError
def binop(self_ty, other_ty): from penty.penty import Types dtype_ty, shape_ty = self_ty.__args__ if dtype_ty not in (bool, int): raise TypeError other_ty = _astype(other_ty) if other_ty in (bool, int): new_dtype_ty = Types[_Module['operator']][op](dtype_ty, other_ty) return NDArray[new_dtype_ty, shape_ty] if issubclass(other_ty, NDArray): other_dtype_ty, other_shape_ty = other_ty.__args__ if other_dtype_ty not in (bool, int): raise TypeError new_dtype_ty = Types[_Module['operator']][op](dtype_ty, other_dtype_ty) return NDArray[new_dtype_ty, _broadcast_shape(shape_ty, other_shape_ty)] raise TypeError
def dtype_ne(self, value): self = _astype(self) if not issubclass(self, dtype): raise TypeError return bool
def str_iter(self_ty): if _astype(self_ty) is str: return str_iterator else: raise TypeError
def int_truediv(self_ty, other_ty): self_ty, other_ty = _astype(self_ty), _astype(other_ty) if issubclass(self_ty, int) and issubclass(other_ty, int): return float else: raise TypeError
def list_append(self_ty, value_ty): self_ty.__args__[0].add(_astype(value_ty)) return _Cst[None]
def binop(self_ty, other_ty): self_ty, other_ty = _astype(self_ty), _astype(other_ty) if issubclass(self_ty, int) and issubclass(other_ty, int): return int else: raise TypeError
def boolop(self_ty, other_ty): self_ty, other_ty = _astype(self_ty), _astype(other_ty) if self_ty is float and other_ty in (bool, int, float): return bool else: raise TypeError
def bool_init(value_ty): from penty.penty import Types return Types[_astype(value_ty)]['__bool__'](value_ty)
def type_(self_ty, node=None): if node is None: return _Ty[_astype(self_ty)] else: return _TypeOf[_astype(self_ty), node.id]
def set_add(self_ty, value_ty): if not issubclass(self_ty, set): raise TypeError self_ty.__args__[0].add(_astype(value_ty)) return _Cst[None]
def bytes_(int_ty): int_ty = _astype(int_ty) if int_ty is int: return str else: raise NotImplementedError