11from typing import Any , Literal , TypeAlias , final , overload
22
33import numpy as np
4+ from numpy ._typing import _128Bit # pyright: ignore[reportPrivateUsage]
45from typing_extensions import Never , Self , override
56
67_Backend : TypeAlias = Literal ["sleef" , "longdouble" ]
@@ -12,9 +13,10 @@ _IntoQuad: TypeAlias = (
1213 | np .integer [Any ]
1314 | np .bool_
1415) # fmt: skip
16+ _ScalarItemArg : TypeAlias = Literal [0 , - 1 ] | tuple [Literal [0 , - 1 ]] | tuple [()]
1517
1618@final
17- class QuadPrecDType (np .dtype [QuadPrecision ]): # type: ignore[misc, type-var ] # pyright: ignore[reportGeneralTypeIssues, reportInvalidTypeArguments ]
19+ class QuadPrecDType (np .dtype [QuadPrecision ]): # type: ignore[misc] # pyright: ignore[reportGeneralTypeIssues]
1820 def __new__ (cls , / , backend : _Backend = "sleef" ) -> Self : ...
1921
2022 # `numpy.dtype` overrides
@@ -70,61 +72,94 @@ class QuadPrecDType(np.dtype[QuadPrecision]): # type: ignore[misc, type-var] #
7072 @override
7173 def __getitem__ (self , key : Never , / ) -> Self : ... # type: ignore[override]
7274
73- # NOTE: Until `QuadPrecision` will become a subclass of `np.generic`, this class cannot
74- # be considered "type-safe".
7575@final
76- class QuadPrecision :
76+ class QuadPrecision ( np . floating [ _128Bit ]) :
7777 # NOTE: At runtime this constructor also accepts array-likes, for which it returns
7878 # `np.ndarray` instances with `dtype=QuadPrecDType()`.
7979 # But because of mypy limitations, it is currently impossible to annotate
8080 # constructors that do no return instances of their class (or a subclass thereof).
8181 # See https://github.com/python/mypy/issues/18343#issuecomment-2571784915
82+ @override
8283 def __new__ (cls , / , value : _IntoQuad , backend : _Backend = "sleef" ) -> Self : ...
8384
84- # Attributes
85+ # numpy.floating property overrides
86+
8587 @property
88+ @override
89+ def dtype (self ) -> QuadPrecDType : ...
90+ @property
91+ @override
8692 def real (self ) -> Self : ...
8793 @property
94+ @override
8895 def imag (self ) -> Self : ...
8996
90- # Rich comparison operators
91- # NOTE: Unlike other numpy scalars, these return `builtins.bool`, not `np.bool`.
97+ # numpy.floating method overrides
98+
99+ @override
100+ def item (self , arg0 : _ScalarItemArg = ..., / ) -> Self : ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride]
101+ @override
102+ def tolist (self , / ) -> Self : ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride]
103+
104+ # Equality operators
92105 @override
93106 def __eq__ (self , other : object , / ) -> bool : ...
94107 @override
95108 def __ne__ (self , other : object , / ) -> bool : ...
96- def __lt__ (self , other : _IntoQuad , / ) -> bool : ...
97- def __le__ (self , other : _IntoQuad , / ) -> bool : ...
98- def __gt__ (self , other : _IntoQuad , / ) -> bool : ...
99- def __ge__ (self , other : _IntoQuad , / ) -> bool : ...
100-
101- # Binary operators
102- def __add__ (self , other : _IntoQuad , / ) -> Self : ...
103- def __radd__ (self , other : _IntoQuad , / ) -> Self : ...
104- def __sub__ (self , other : _IntoQuad , / ) -> Self : ...
105- def __rsub__ (self , other : _IntoQuad , / ) -> Self : ...
106- def __mul__ (self , other : _IntoQuad , / ) -> Self : ...
107- def __rmul__ (self , other : _IntoQuad , / ) -> Self : ...
108- def __pow__ (self , other : _IntoQuad , mod : None = None , / ) -> Self : ...
109- def __rpow__ (self , other : _IntoQuad , mod : None = None , / ) -> Self : ...
110- def __truediv__ (self , other : _IntoQuad , / ) -> Self : ...
111- def __rtruediv__ (self , other : _IntoQuad , / ) -> Self : ...
112-
113- # Unary operators
114- def __neg__ (self , / ) -> Self : ...
115- def __pos__ (self , / ) -> Self : ...
116- def __abs__ (self , / ) -> Self : ...
117-
118- # Conversion methods
119- def __bool__ (self , / ) -> bool : ...
120- def __int__ (self , / ) -> int : ...
121- def __float__ (self , / ) -> float : ...
122-
123- # String representation
124- @override
125- def __repr__ (self , / ) -> str : ...
126- @override
127- def __str__ (self , / ) -> str : ...
109+
110+ # Rich comparison operators
111+ # NOTE: Unlike other numpy scalars, these return `builtins.bool`, not `np.bool`.
112+ @override
113+ def __lt__ (self , other : _IntoQuad , / ) -> bool : ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride]
114+ @override
115+ def __le__ (self , other : _IntoQuad , / ) -> bool : ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride]
116+ @override
117+ def __gt__ (self , other : _IntoQuad , / ) -> bool : ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride]
118+ @override
119+ def __ge__ (self , other : _IntoQuad , / ) -> bool : ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride]
120+
121+ # Binary arithmetic operators
122+ @override
123+ def __add__ (self , other : _IntoQuad , / ) -> Self : ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride]
124+ @override
125+ def __radd__ (self , other : _IntoQuad , / ) -> Self : ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride]
126+ @override
127+ def __sub__ (self , other : _IntoQuad , / ) -> Self : ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride]
128+ @override
129+ def __rsub__ (self , other : _IntoQuad , / ) -> Self : ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride]
130+ @override
131+ def __mul__ (self , other : _IntoQuad , / ) -> Self : ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride]
132+ @override
133+ def __rmul__ (self , other : _IntoQuad , / ) -> Self : ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride]
134+ @override
135+ def __pow__ (self , other : _IntoQuad , mod : None = None , / ) -> Self : ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride]
136+ @override
137+ def __rpow__ (self , other : _IntoQuad , mod : None = None , / ) -> Self : ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride]
138+ @override
139+ def __truediv__ (self , other : _IntoQuad , / ) -> Self : ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride]
140+ @override
141+ def __rtruediv__ (self , other : _IntoQuad , / ) -> Self : ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride]
142+
143+ # Binary modulo operators
144+ @override
145+ def __floordiv__ (self , other : _IntoQuad , / ) -> Self : ...
146+ @override
147+ def __rfloordiv__ (self , other : _IntoQuad , / ) -> Self : ...
148+ @override
149+ def __mod__ (self , other : _IntoQuad , / ) -> Self : ...
150+ @override
151+ def __rmod__ (self , other : _IntoQuad , / ) -> Self : ...
152+ @override
153+ def __divmod__ (self , other : _IntoQuad , / ) -> tuple [Self , Self ]: ...
154+ @override
155+ def __rdivmod__ (self , other : _IntoQuad , / ) -> tuple [Self , Self ]: ...
156+
157+ # NOTE: is_integer() and as_integer_ratio() are defined on numpy.floating in the
158+ # stubs, but don't exist at runtime. And because QuadPrecision does not have
159+ # implement them, we use this hacky workaround to emulate their abscence.
160+ # TODO: Remove after https://github.com/numpy/numpy-user-dtypes/issues/216
161+ is_integer : Never # pyright: ignore[reportIncompatibleMethodOverride]
162+ as_integer_ratio : Never # pyright: ignore[reportIncompatibleMethodOverride]
128163
129164#
130165def is_longdouble_128 () -> bool : ...
0 commit comments