@@ -9,6 +9,7 @@ use crate::{
9
9
} ,
10
10
identifier,
11
11
protocol:: PyNumberMethods ,
12
+ stdlib:: warnings,
12
13
types:: { AsNumber , Comparable , Constructor , Hashable , PyComparisonOp , Representable } ,
13
14
AsObject , Context , Py , PyObject , PyObjectRef , PyPayload , PyRef , PyResult , VirtualMachine ,
14
15
} ;
@@ -59,14 +60,31 @@ impl PyObjectRef {
59
60
}
60
61
if let Some ( method) = vm. get_method ( self . clone ( ) , identifier ! ( vm, __complex__) ) {
61
62
let result = method?. call ( ( ) , vm)
8000
span>?;
62
- // TODO: returning strict subclasses of complex in __complex__ is deprecated
63
- return match result. payload :: < PyComplex > ( ) {
64
- Some ( complex_obj) => Ok ( Some ( ( complex_obj. value , true ) ) ) ,
65
- None => Err ( vm. new_type_error ( format ! (
66
- "__complex__ returned non-complex (type '{}')" ,
67
- result. class( ) . name( )
68
- ) ) ) ,
69
- } ;
63
+
64
+ let ret_class = result. class ( ) . to_owned ( ) ;
65
+ if let Some ( ret) = result. downcast_ref :: < PyComplex > ( ) {
66
+ warnings:: warn (
67
+ vm. ctx . exceptions . deprecation_warning ,
68
+ format ! (
69
+ "__complex__ returned non-complex (type {}). \
70
+ The ability to return an instance of a strict subclass of complex \
71
+ is deprecated, and may be removed in a future version of Python.",
72
+ ret_class
73
+ ) ,
74
+ 1 ,
75
+ vm,
76
+ ) ?;
77
+
78
+ return Ok ( Some ( ( ret. value , true ) ) ) ;
79
+ } else {
80
+ return match result. payload :: < PyComplex > ( ) {
81
+ Some ( complex_obj) => Ok ( Some ( ( complex_obj. value , true ) ) ) ,
82
+ None => Err ( vm. new_type_error ( format ! (
83
+ "__complex__ returned non-complex (type '{}')" ,
84
+ result. class( ) . name( )
85
+ ) ) ) ,
86
+ } ;
87
+ }
70
88
}
71
89
// `complex` does not have a `__complex__` by default, so subclasses might not either,
72
90
// use the actual stored value in this case
0 commit comments