From 435159e7ced029447ccdaecb0ea635cab0d8e429 Mon Sep 17 00:00:00 2001 From: DominicPrince2003 <99886601+DominicPrince2003@users.noreply.github.com> Date: Sun, 6 Jul 2025 14:18:21 +0530 Subject: [PATCH 1/3] [5895] added code to raise error in sleep if invalid value --- Lib/test/test_time.py | 10 ++++++++++ vm/src/stdlib/time.rs | 35 ++++++++++++++++++++++++++++++----- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py index 3886aae934..9543bd5514 100644 --- a/Lib/test/test_time.py +++ b/Lib/test/test_time.py @@ -155,7 +155,17 @@ def test_conversions(self): def test_sleep(self): self.assertRaises(ValueError, time.sleep, -2) self.assertRaises(ValueError, time.sleep, -1) + self.assertRaises(ValueError, time.sleep, float('nan')) + self.assertRaises(ValueError, time.sleep, float('inf')) + self.assertRaises(ValueError, time.sleep, -float('inf')) + self.assertRaises(ValueError, time.sleep, 1e100) + time.sleep(0) + time.sleep(0.000001) + time.sleep(1e-9) + time.sleep(0.5) time.sleep(1.2) + time.sleep(2) + # TODO: RUSTPYTHON @unittest.expectedFailure diff --git a/vm/src/stdlib/time.rs b/vm/src/stdlib/time.rs index 12a47fca87..4680b07ba8 100644 --- a/vm/src/stdlib/time.rs +++ b/vm/src/stdlib/time.rs @@ -90,8 +90,22 @@ mod decl { #[cfg(not(unix))] #[pyfunction] - fn sleep(dur: Duration) { - std::thread::sleep(dur); + fn sleep(secs: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { + // Try to get as float first, if that fails try as integer + let secs = if let Ok(float_val) = f64::try_from_object(vm, secs.clone()) { + float_val + } else if let Ok(int_val) = i64::try_from_object(vm, secs) { + int_val as f64 + } else { + return Err(vm.new_type_error("sleep() argument must be a number")); + }; + if !secs.is_finite() || secs < 0.0 || secs > u64::MAX as f64 { + return Err(vm.new_value_error("sleep length must be a non-negative finite number")); + } + + let duration = Duration::from_secs_f64(secs); + std::thread::sleep(duration); + Ok(()) } #[cfg(not(target_os = "wasi"))] @@ -527,7 +541,7 @@ mod platform { use crate::{ PyObject, PyRef, PyResult, TryFromBorrowedObject, VirtualMachine, builtins::{PyNamespace, PyStrRef}, - convert::IntoPyException, + convert::{IntoPyException,TryFromObject}, }; use nix::{sys::time::TimeSpec, time::ClockId}; use std::time::Duration; @@ -691,9 +705,20 @@ mod platform { } #[pyfunction] - fn sleep(dur: Duration, vm: &VirtualMachine) -> PyResult<()> { + fn sleep(secs: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { // this is basically std::thread::sleep, but that catches interrupts and we don't want to; - + // Try to get as float first, if that fails try as integer + let secs = if let Ok(float_val) = f64::try_from_object(vm, secs.clone()) { + float_val + } else if let Ok(int_val) = i64::try_from_object(vm, secs) { + int_val as f64 + } else { + return Err(vm.new_type_error("sleep() argument must be a number")); + }; + if !secs.is_finite() || secs < 0.0 || secs > u64::MAX as f64 { + return Err(vm.new_value_error("sleep length must be a non-negative finite number")); + } + let dur = Duration::from_secs_f64(secs); let ts = TimeSpec::from(dur); let res = unsafe { libc::nanosleep(ts.as_ref(), std::ptr::null_mut()) }; let interrupted = res == -1 && nix::Error::last_raw() == libc::EINTR; From cdff22fc76766aeb57032eba713a0c0cad1e9fab Mon Sep 17 00:00:00 2001 From: DominicPrince2003 <99886601+DominicPrince2003@users.noreply.github.com> Date: Sun, 6 Jul 2025 17:17:11 +0530 Subject: [PATCH 2/3] Update vm/src/stdlib/time.rs Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- vm/src/stdlib/time.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vm/src/stdlib/time.rs b/vm/src/stdlib/time.rs index 4680b07ba8..1c36c18c37 100644 --- a/vm/src/stdlib/time.rs +++ b/vm/src/stdlib/time.rs @@ -715,9 +715,9 @@ mod platform { } else { return Err(vm.new_type_error("sleep() argument must be a number")); }; - if !secs.is_finite() || secs < 0.0 || secs > u64::MAX as f64 { - return Err(vm.new_value_error("sleep length must be a non-negative finite number")); - } + if !secs.is_finite() || secs < 0.0 || secs > u64::MAX as f64 { + return Err(vm.new_value_error("sleep length must be a non-negative finite number")); + } let dur = Duration::from_secs_f64(secs); let ts = TimeSpec::from(dur); let res = unsafe { libc::nanosleep(ts.as_ref(), std::ptr::null_mut()) }; From a9f152c2160dc0819e5e3861d3acf2777c284eb6 Mon Sep 17 00:00:00 2001 From: DominicPrince2003 <99886601+DominicPrince2003@users.noreply.github.com> Date: Sun, 6 Jul 2025 17:22:20 +0530 Subject: [PATCH 3/3] changed max sleep for not unix systems --- vm/src/stdlib/time.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vm/src/stdlib/time.rs b/vm/src/stdlib/time.rs index 1c36c18c37..92d35a1cc0 100644 --- a/vm/src/stdlib/time.rs +++ b/vm/src/stdlib/time.rs @@ -99,7 +99,7 @@ mod decl { } else { return Err(vm.new_type_error("sleep() argument must be a number")); }; - if !secs.is_finite() || secs < 0.0 || secs > u64::MAX as f64 { + if !secs.is_finite() || secs < 0.0 || secs > (u32::MAX / 1000) as f64 { return Err(vm.new_value_error("sleep length must be a non-negative finite number")); }