@@ -90,8 +90,22 @@ mod decl {
9090
9191 #[ cfg( not( unix) ) ]
9292 #[ pyfunction]
93- fn sleep ( dur : Duration ) {
94- std:: thread:: sleep ( dur) ;
93+ fn sleep ( secs : PyObjectRef , vm : & VirtualMachine ) -> PyResult < ( ) > {
94+ // Try to get as float first, if that fails try as integer
95+ let secs = if let Ok ( float_val) = f64:: try_from_object ( vm, secs. clone ( ) ) {
96+ float_val
97+ } else if let Ok ( int_val) = i64:: try_from_object ( vm, secs) {
98+ int_val as f64
99+ } else {
100+ return Err ( vm. new_type_error ( "sleep() argument must be a number" ) ) ;
101+ } ;
102+ if !secs. is_finite ( ) || secs < 0.0 || secs > u64:: MAX as f64 {
103+ return Err ( vm. new_value_error ( "sleep length must be a non-negative finite number" ) ) ;
104+ }
105+
106+ let duration = Duration :: from_secs_f64 ( secs) ;
107+ std:: thread:: sleep ( duration) ;
108+ Ok ( ( ) )
95109 }
96110
97111 #[ cfg( not( target_os = "wasi" ) ) ]
@@ -527,7 +541,7 @@ mod platform {
527541 use crate :: {
528542 PyObject , PyRef , PyResult , TryFromBorrowedObject , VirtualMachine ,
529543 builtins:: { PyNamespace , PyStrRef } ,
530- convert:: IntoPyException ,
544+ convert:: { IntoPyException , TryFromObject } ,
531545 } ;
532546 use nix:: { sys:: time:: TimeSpec , time:: ClockId } ;
533547 use std:: time:: Duration ;
@@ -691,9 +705,20 @@ mod platform {
691705 }
692706
693707 #[ pyfunction]
694- fn sleep ( dur : Duration , vm : & VirtualMachine ) -> PyResult < ( ) > {
708+ fn sleep ( secs : PyObjectRef , vm : & VirtualMachine ) -> PyResult < ( ) > {
695709 // this is basically std::thread::sleep, but that catches interrupts and we don't want to;
696-
710+ // Try to get as float first, if that fails try as integer
711+ let secs = if let Ok ( float_val) = f64:: try_from_object ( vm, secs. clone ( ) ) {
712+ float_val
713+ } else if let Ok ( int_val) = i64:: try_from_object ( vm, secs) {
714+ int_val as f64
715+ } else {
716+ return Err ( vm. new_type_error ( "sleep() argument must be a number" ) ) ;
717+ } ;
718+ if !secs. is_finite ( ) || secs < 0.0 || secs > u64:: MAX as f64 {
719+ return Err ( vm. new_value_error ( "sleep length must be a non-negative finite number" ) ) ;
720+ }
721+ let dur = Duration :: from_secs_f64 ( secs) ;
697722 let ts = TimeSpec :: from ( dur) ;
698723 let res = unsafe { libc:: nanosleep ( ts. as_ref ( ) , std:: ptr:: null_mut ( ) ) } ;
699724 let interrupted = res == -1 && nix:: Error :: last_raw ( ) == libc:: EINTR ;
0 commit comments