@@ -20,6 +20,7 @@ use pyo3::types::PyAny;
20
20
use pyo3:: types:: PyBytes ;
21
21
use pyo3:: types:: PyInt ;
22
22
use pyo3:: types:: PyType ;
23
+ use pyo3:: FromPy ;
23
24
use pyo3:: PyNativeType ;
24
25
use pyo3:: PyNumberProtocol ;
25
26
use pyo3:: PyObjectProtocol ;
@@ -51,6 +52,12 @@ impl ToPyObject for PyBigInt {
51
52
}
52
53
}
53
54
55
+ impl FromPy < PyBigInt > for PyObject {
56
+ fn from_py ( value : PyBigInt , py : Python ) -> Self {
57
+ value. to_object ( py)
58
+ }
59
+ }
60
+
54
61
impl FromPyObject < ' _ > for PyBigInt {
55
62
fn extract ( ob : & PyAny ) -> PyResult < Self > {
56
63
let value = ob. downcast_ref :: < PyInt > ( ) ?;
@@ -97,17 +104,69 @@ impl FromPyObject<'_> for RealAlgebraicNumberPy {
97
104
#[ pymethods( PyObjectProtocol , PyNumberProtocol ) ]
98
105
impl RealAlgebraicNumberPy {
99
106
#[ new]
100
- fn pynew ( obj : & PyRawObject , value : RealAlgebraicNumberPy ) -> PyResult < ( ) > {
101
- obj. init ( value) ;
102
- Ok ( ( ) )
107
+ fn pynew ( obj : & PyRawObject , value : Option < RealAlgebraicNumberPy > ) {
108
+ obj. init ( value. unwrap_or_else ( || RealAlgebraicNumberPy {
109
+ value : RealAlgebraicNumber :: zero ( ) . into ( ) ,
110
+ } ) ) ;
111
+ }
112
+ fn __trunc__ ( & self ) -> PyBigInt {
113
+ let gil = Python :: acquire_gil ( ) ;
114
+ let py = gil. python ( ) ;
115
+ py. allow_threads ( || PyBigInt ( self . value . to_integer_trunc ( ) ) )
116
+ }
117
+ fn __floor__ ( & self ) -> PyBigInt {
118
+ let gil = Python :: acquire_gil ( ) ;
119
+ let py = gil. python ( ) ;
120
+ py. allow_threads ( || PyBigInt ( self . value . to_integer_floor ( ) ) )
121
+ }
122
+ fn __ceil__ ( & self ) -> PyBigInt {
123
+ let gil = Python :: acquire_gil ( ) ;
124
+ let py = gil. python ( ) ;
125
+ py. allow_threads ( || PyBigInt ( self . value . to_integer_ceil ( ) ) )
126
+ }
127
+ fn to_integer ( & self ) -> Option < PyBigInt > {
128
+ self . value . to_integer ( ) . map ( PyBigInt )
129
+ }
130
+ fn to_rational ( & self ) -> Option < ( PyBigInt , PyBigInt ) > {
131
+ self . value . to_rational ( ) . map ( |value| {
132
+ let ( numer, denom) = value. into ( ) ;
133
+ ( PyBigInt ( numer) , PyBigInt ( denom) )
134
+ } )
135
+ }
136
+ #[ getter]
137
+ fn minimal_polynomial ( & self ) -> Vec < PyBigInt > {
138
+ self . value
139
+ . minimal_polynomial ( )
140
+ . iter ( )
141
+ . map ( PyBigInt )
142
+ . collect ( )
143
+ }
144
+ #[ getter]
145
+ fn degree ( & self ) -> usize {
146
+ self . value . degree ( )
147
+ }
148
+ fn is_rational ( & self ) -> bool {
149
+ self . value . is_rational ( )
150
+ }
151
+ fn is_integer ( & self ) -> bool {
152
+ self . value . is_integer ( )
153
+ }
154
+ fn recip ( & self ) -> PyResult < RealAlgebraicNumberPy > {
155
+ Python :: acquire_gil ( )
156
+ . python ( )
157
+ . allow_threads ( || {
158
+ Some ( RealAlgebraicNumberPy {
159
+ value : self . value . checked_recip ( ) ?. into ( ) ,
160
+ } )
161
+ } )
162
+ . ok_or_else ( get_div_by_zero_error)
103
163
}
104
- // FIXME: implement rest of methods
105
164
}
106
165
107
166
#[ pyproto]
108
167
impl PyObjectProtocol for RealAlgebraicNumberPy {
109
168
fn __repr__ ( & self ) -> PyResult < String > {
110
- Ok ( format ! ( "{:?}" , self . value) )
169
+ Ok ( format ! ( "< {:?}> " , self . value) )
111
170
}
112
171
fn __richcmp__ ( & self , other : & PyAny , op : CompareOp ) -> PyResult < bool > {
113
172
let py = other. py ( ) ;
@@ -123,6 +182,10 @@ impl PyObjectProtocol for RealAlgebraicNumberPy {
123
182
}
124
183
}
125
184
185
+ fn get_div_by_zero_error ( ) -> PyErr {
186
+ ZeroDivisionError :: py_err ( "can't divide RealAlgebraicNumber by zero" )
187
+ }
188
+
126
189
#[ pyproto]
127
190
impl PyNumberProtocol for RealAlgebraicNumberPy {
128
191
fn __add__ ( lhs : & PyAny , rhs : RealAlgebraicNumberPy ) -> PyResult < RealAlgebraicNumberPy > {
@@ -156,7 +219,7 @@ impl PyNumberProtocol for RealAlgebraicNumberPy {
156
219
Arc :: make_mut ( & mut lhs. value ) . checked_exact_div_assign ( & * rhs. value ) ?;
157
220
Ok ( lhs)
158
221
} )
159
- . map_err ( |( ) | ZeroDivisionError :: py_err ( "can't divide RealAlgebraicNumber by zero" ) )
222
+ . map_err ( |( ) | get_div_by_zero_error ( ) )
160
223
}
161
224
fn __pow__ (
162
225
lhs : RealAlgebraicNumberPy ,
@@ -204,7 +267,6 @@ impl PyNumberProtocol for RealAlgebraicNumberPy {
204
267
205
268
#[ pymodule]
206
269
fn algebraics ( _py : Python , m : & PyModule ) -> PyResult < ( ) > {
207
- // FIXME: add module members
208
270
m. add_class :: < RealAlgebraicNumberPy > ( ) ?;
209
271
Ok ( ( ) )
210
272
}
0 commit comments