diff --git a/quaddtype/numpy_quaddtype/_quaddtype_main.pyi b/quaddtype/numpy_quaddtype/_quaddtype_main.pyi index f5e8d680..eab36b39 100644 --- a/quaddtype/numpy_quaddtype/_quaddtype_main.pyi +++ b/quaddtype/numpy_quaddtype/_quaddtype_main.pyi @@ -4,8 +4,14 @@ import numpy as np from typing_extensions import Never, Self, override _Backend: TypeAlias = Literal["sleef", "longdouble"] -_IntoQuad: TypeAlias = QuadPrecision | float | str -_CastsQuad: TypeAlias = _IntoQuad | np.floating[Any] | np.integer[Any] | np.bool_ +_IntoQuad: TypeAlias = ( + QuadPrecision + | float + | str + | np.floating[Any] + | np.integer[Any] + | np.bool_ +) # fmt: skip @final class QuadPrecDType(np.dtype[QuadPrecision]): # type: ignore[misc, type-var] # pyright: ignore[reportGeneralTypeIssues, reportInvalidTypeArguments] @@ -64,8 +70,15 @@ class QuadPrecDType(np.dtype[QuadPrecision]): # type: ignore[misc, type-var] # @override def __getitem__(self, key: Never, /) -> Self: ... # type: ignore[override] +# NOTE: Until `QuadPrecision` will become a subclass of `np.generic`, this class cannot +# be considered "type-safe". @final -class QuadPrecision: # NOTE: It doesn't inherit from `np.generic` which is type-unsafe +class QuadPrecision: + # NOTE: At runtime this constructor also accepts array-likes, for which it returns + # `np.ndarray` instances with `dtype=QuadPrecDType()`. + # But because of mypy limitations, it is currently impossible to annotate + # constructors that do no return instances of their class (or a subclass thereof). + # See https://github.com/python/mypy/issues/18343#issuecomment-2571784915 def __new__(cls, /, value: _IntoQuad, backend: _Backend = "sleef") -> Self: ... # Rich comparison operators @@ -80,16 +93,16 @@ class QuadPrecision: # NOTE: It doesn't inherit from `np.generic` which is type def __ge__(self, other: _IntoQuad, /) -> bool: ... # Binary operators - def __add__(self, other: _CastsQuad, /) -> Self: ... - def __radd__(self, other: _CastsQuad, /) -> Self: ... - def __sub__(self, other: _CastsQuad, /) -> Self: ... - def __rsub__(self, other: _CastsQuad, /) -> Self: ... - def __mul__(self, other: _CastsQuad, /) -> Self: ... - def __rmul__(self, other: _CastsQuad, /) -> Self: ... - def __pow__(self, other: _CastsQuad, mod: None = None, /) -> Self: ... - def __rpow__(self, other: _CastsQuad, mod: None = None, /) -> Self: ... - def __truediv__(self, other: _CastsQuad, /) -> Self: ... - def __rtruediv__(self, other: _CastsQuad, /) -> Self: ... + def __add__(self, other: _IntoQuad, /) -> Self: ... + def __radd__(self, other: _IntoQuad, /) -> Self: ... + def __sub__(self, other: _IntoQuad, /) -> Self: ... + def __rsub__(self, other: _IntoQuad, /) -> Self: ... + def __mul__(self, other: _IntoQuad, /) -> Self: ... + def __rmul__(self, other: _IntoQuad, /) -> Self: ... + def __pow__(self, other: _IntoQuad, mod: None = None, /) -> Self: ... + def __rpow__(self, other: _IntoQuad, mod: None = None, /) -> Self: ... + def __truediv__(self, other: _IntoQuad, /) -> Self: ... + def __rtruediv__(self, other: _IntoQuad, /) -> Self: ... # Unary operators def __neg__(self, /) -> Self: ...