Skip to content

Commit 59cedd2

Browse files
qingshi163youknowone
authored andcommitted
deprecated warnings for int
1 parent 20632ed commit 59cedd2

File tree

5 files changed

+71
-30
lines changed

5 files changed

+71
-30
lines changed

Lib/test/test_int.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -458,8 +458,6 @@ def __int__(self):
458458
self.assertEqual(my_int, 7)
459459
self.assertRaises(TypeError, int, my_int)
460460

461-
# TODO: RUSTPYTHON
462-
@unittest.expectedFailure
463461
def test_int_returns_int_subclass(self):
464462
class BadIndex:
465463
def __index__(self):

vm/src/protocol/number.rs

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::{
44
builtins::{int, PyByteArray, PyBytes, PyComplex, PyFloat, PyInt, PyIntRef, PyStr},
55
common::lock::OnceCell,
66
function::ArgBytesLike,
7+
stdlib::warnings,
78
AsObject, PyObject, PyPayload, PyRef, PyResult, TryFromBorrowedObject, VirtualMachine,
89
};
910

@@ -119,15 +120,34 @@ impl PyNumber<'_> {
119120
}
120121

121122
if self.obj.class().is(PyInt::class(vm)) {
122-
Ok(unsafe { self.obj.downcast_unchecked_ref::<PyInt>() }.to_owned())
123+
Ok(unsafe { self.obj.to_owned().downcast_unchecked::<PyInt>() })
123124
} else if let Some(f) = self.methods(vm).int {
124-
f(self, vm)
125-
} else if let Some(f) = self.methods(vm).index {
126-
f(self, vm)
125+
let ret = f(self, vm)?;
126+
if !ret.class().is(PyInt::class(vm)) {
127+
warnings::warn(
128+
vm.ctx.exceptions.deprecation_warning.clone(),
129+
format!("__int__ returned non-int (type {})", ret.class()),
130+
1,
131+
vm,
132+
)?
133+
}
134+
Ok(ret)
135+
} else if self.methods(vm).index.is_some() {
136+
self.index(vm)
127137
} else if let Ok(Ok(f)) = vm.get_special_method(self.obj.to_owned(), "__trunc__") {
128-
let r = f.invoke((), vm)?;
129-
PyNumber::from(r.as_ref()).index(vm).map_err(|_| {
130-
vm.new_type_error("__trunc__ returned non-Integral (type NonIntegral)".to_string())
138+
// TODO: Deprecate in 3.11
139+
// warnings::warn(
140+
// vm.ctx.exceptions.deprecation_warning.clone(),
141+
// "The delegation of int() to __trunc__ is deprecated.".to_owned(),
142+
// 1,
143+
// vm,
144+
// )?;
145+
let ret = f.invoke((), vm)?;
146+
PyNumber::from(ret.as_ref()).index(vm).map_err(|_| {
147+
vm.new_type_error(format!(
148+
"__trunc__ returned non-Integral (type {})",
149+
ret.class()
150+
))
131151
})
132152
} else if let Some(s) = self.obj.payload::<PyStr>() {
133153
try_convert(self.obj, s.as_str().as_bytes(), vm)
@@ -148,9 +168,18 @@ impl PyNumber<'_> {
148168

149169
pub fn index(&self, vm: &VirtualMachine) -> PyResult<PyIntRef> {
150170
if self.obj.class().is(PyInt::class(vm)) {
151-
Ok(unsafe { self.obj.downcast_unchecked_ref::<PyInt>() }.to_owned())
171+
Ok(unsafe { self.obj.to_owned().downcast_unchecked::<PyInt>() })
152172
} else if let Some(f) = self.methods(vm).index {
153-
f(self, vm)
173+
let ret = f(self, vm)?;
174+
if !ret.class().is(PyInt::class(vm)) {
175+
warnings::warn(
176+
vm.ctx.exceptions.deprecation_warning.clone(),
177+
format!("__index__ returned non-int (type {})", ret.class()),
178+
1,
179+
vm,
180+
)?
181+
}
182+
Ok(ret)
154183
} else {
155184
Err(vm.new_type_error(format!(
156185
"'{}' object cannot be interpreted as an integer",

vm/src/stdlib/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ mod sysconfigdata;
2121
#[cfg(feature = "threading")]
2222
mod thread;
2323
pub mod time;
24-
mod warnings;
24+
pub mod warnings;
2525
mod weakref;
2626

2727
#[cfg(any(not(target_arch = "wasm32"), target_os = "wasi"))]

vm/src/stdlib/warnings.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,25 @@
11
pub(crate) use _warnings::make_module;
22

3+
use crate::{builtins::PyTypeRef, PyResult, VirtualMachine};
4+
5+
pub fn warn(
6+
category: PyTypeRef,
7+
message: String,
8+
stack_level: usize,
9+
vm: &VirtualMachine,
10+
) -> PyResult<()> {
11+
// let module = vm.import("warnings", None, 0)?;
12+
// let func = module.get_attr("warn", vm)?;
13+
// vm.invoke(&func, (message, category, stack_level))?;
14+
// TODO
15+
if let Ok(module) = vm.import("warnings", None, 0) {
16+
if let Ok(func) = module.get_attr("warn", vm) {
17+
let _ = vm.invoke(&func, (message, category, stack_level));
18+
}
19+
}
20+
Ok(())
21+
}
22+
323
#[pymodule]
424
mod _warnings {
525
use crate::{

vm/src/types/slot.rs

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -344,30 +344,24 @@ fn as_number_wrapper(zelf: &PyObject, _vm: &VirtualMachine) -> Cow<'static, PyNu
344344
Cow::Owned(PyNumberMethods {
345345
int: then_some_closure!(zelf.class().has_attr("__int__"), |num, vm| {
346346
let ret = vm.call_special_method(num.obj.to_owned(), "__int__", ())?;
347-
if let Some(i) = ret.downcast_ref::<PyInt>() {
348-
Ok(i.to_owned())
349-
} else {
350-
// TODO
351-
Err(vm.new_type_error("".to_string()))
352-
}
347+
ret.downcast::<PyInt>().map_err(|obj| {
348+
vm.new_type_error(format!("__int__ returned non-int (type {})", obj.class()))
349+
})
353350
}),
354351
float: then_some_closure!(zelf.class().has_attr("__float__"), |num, vm| {
355352
let ret = vm.call_special_method(num.obj.to_owned(), "__float__", ())?;
356-
if let Some(f) = ret.downcast_ref::<PyFloat>() {
357-
Ok(f.to_owned())
358-
} else {
359-
// TODO
360-
Err(vm.new_type_error("".to_string()))
361-
}
353+
ret.downcast::<PyFloat>().map_err(|obj| {
354+
vm.new_type_error(format!(
355+
"__float__ returned non-float (type {})",
356+
obj.class()
357+
))
358+
})
362359
}),
363360
index: then_some_closure!(zelf.class().has_attr("__index__"), |num, vm| {
364361
let ret = vm.call_special_method(num.obj.to_owned(), "__index__", ())?;
365-
if let Some(i) = ret.downcast_ref::<PyInt>() {
366-
Ok(i.to_owned())
367-
} else {
368-
// TODO
369-
Err(vm.new_type_error("".to_string()))
370-
}
362+
ret.downcast::<PyInt>().map_err(|obj| {
363+
vm.new_type_error(format!("__index__ returned non-int (type {})", obj.class()))
364+
})
371365
}),
372366
..*PyNumberMethods::not_implemented()
373367
})

0 commit comments

Comments
 (0)