@@ -34,7 +34,7 @@ unsafe extern "C" {
3434#[ pymodule( name = "time" , with( platform) ) ]
3535mod decl {
3636 use crate :: {
37- PyObjectRef , PyResult , TryFromObject , VirtualMachine ,
37+ AsObject , PyObjectRef , PyResult , TryFromObject , VirtualMachine ,
3838 builtins:: { PyStrRef , PyTypeRef } ,
3939 function:: { Either , FuncArgs , OptionalArg } ,
4040 types:: PyStructSequence ,
@@ -88,10 +88,37 @@ mod decl {
8888 duration_since_system_now ( vm)
8989 }
9090
91- #[ cfg( not( unix) ) ]
9291 #[ pyfunction]
93- fn sleep ( dur : Duration ) {
94- std:: thread:: sleep ( dur) ;
92+ fn sleep ( seconds : PyObjectRef , vm : & VirtualMachine ) -> PyResult < ( ) > {
93+ let dur = seconds. try_into_value :: < Duration > ( vm) . map_err ( |e| {
94+ if e. class ( ) . is ( vm. ctx . exceptions . value_error ) {
95+ if let Some ( s) = e. args ( ) . first ( ) . and_then ( |arg| arg. str ( vm) . ok ( ) ) {
96+ if s. as_str ( ) == "negative duration" {
97+ return vm. new_value_error ( "sleep length must be non-negative" ) ;
98+ }
99+ }
100+ }
101+ e
102+ } ) ?;
103+
104+ #[ cfg( unix) ]
105+ {
106+ // this is basically std::thread::sleep, but that catches interrupts and we don't want to;
107+ let ts = nix:: sys:: time:: TimeSpec :: from ( dur) ;
108+ let res = unsafe { libc:: nanosleep ( ts. as_ref ( ) , std:: ptr:: null_mut ( ) ) } ;
109+ let interrupted = res == -1 && nix:: Error :: last_raw ( ) == libc:: EINTR ;
110+
111+ if interrupted {
112+ vm. check_signals ( ) ?;
113+ }
114+ }
115+
116+ #[ cfg( not( unix) ) ]
117+ {
118+ std:: thread:: sleep ( dur) ;
119+ }
120+
121+ Ok ( ( ) )
95122 }
96123
97124 #[ cfg( not( target_os = "wasi" ) ) ]
@@ -690,21 +717,6 @@ mod platform {
690717 get_clock_time ( ClockId :: CLOCK_MONOTONIC , vm)
691718 }
692719
693- #[ pyfunction]
694- fn sleep ( dur : Duration , vm : & VirtualMachine ) -> PyResult < ( ) > {
695- // this is basically std::thread::sleep, but that catches interrupts and we don't want to;
696-
697- let ts = TimeSpec :: from ( dur) ;
698- let res = unsafe { libc:: nanosleep ( ts. as_ref ( ) , std:: ptr:: null_mut ( ) ) } ;
699- let interrupted = res == -1 && nix:: Error :: last_raw ( ) == libc:: EINTR ;
700-
701- if interrupted {
702- vm. check_signals ( ) ?;
703- }
704-
705- Ok ( ( ) )
706- }
707-
708720 #[ cfg( not( any(
709721 target_os = "illumos" ,
710722 target_os = "netbsd" ,
0 commit comments