| 74 | |
| 75 | |
| 76 | class ufunc: |
| 77 | _forward_attrs = { |
| 78 | "nin", |
| 79 | "nargs", |
| 80 | "nout", |
| 81 | "ntypes", |
| 82 | "identity", |
| 83 | "signature", |
| 84 | "types", |
| 85 | } |
| 86 | |
| 87 | def __init__(self, ufunc): |
| 88 | if not isinstance(ufunc, (np.ufunc, da_frompyfunc)): |
| 89 | raise TypeError( |
| 90 | "must be an instance of `ufunc` or " |
| 91 | "`da_frompyfunc`, got `%s" % type(ufunc).__name__ |
| 92 | ) |
| 93 | self._ufunc = ufunc |
| 94 | self.__name__ = ufunc.__name__ |
| 95 | if isinstance(ufunc, np.ufunc): |
| 96 | derived_from(np)(self) |
| 97 | |
| 98 | def __dask_tokenize__(self): |
| 99 | return self.__name__, normalize_token(self._ufunc) |
| 100 | |
| 101 | def __getattr__(self, key): |
| 102 | if key in self._forward_attrs: |
| 103 | return getattr(self._ufunc, key) |
| 104 | raise AttributeError(f"{type(self).__name__!r} object has no attribute {key!r}") |
| 105 | |
| 106 | def __dir__(self): |
| 107 | return list(self._forward_attrs.union(dir(type(self)), self.__dict__)) |
| 108 | |
| 109 | def __repr__(self): |
| 110 | return repr(self._ufunc) |
| 111 | |
| 112 | def __call__(self, *args, **kwargs): |
| 113 | dsks = [arg for arg in args if hasattr(arg, "_elemwise")] |
| 114 | if len(dsks) > 0: |
| 115 | for dsk in dsks: |
| 116 | result = dsk._elemwise(self._ufunc, *args, **kwargs) |
| 117 | if type(result) != type(NotImplemented): |
| 118 | return result |
| 119 | raise TypeError( |
| 120 | "Parameters of such types are not supported by " + self.__name__ |
| 121 | ) |
| 122 | else: |
| 123 | return self._ufunc(*args, **kwargs) |
| 124 | |
| 125 | @derived_from(np.ufunc) |
| 126 | def outer(self, A, B, **kwargs): |
| 127 | if self.nin != 2: |
| 128 | raise ValueError("outer product only supported for binary functions") |
| 129 | if "out" in kwargs: |
| 130 | raise ValueError("`out` kwarg not supported") |
| 131 | |
| 132 | A_is_dask = is_dask_collection(A) |
| 133 | B_is_dask = is_dask_collection(B) |
no outgoing calls
no test coverage detected