@@ -34,7 +34,7 @@ unsafe extern "C" {
34
34
#[ pymodule( name = "time" , with( platform) ) ]
35
35
mod decl {
36
36
use crate :: {
37
- PyObjectRef , PyResult , TryFromObject , VirtualMachine ,
37
+ AsObject , PyObjectRef , PyResult , TryFromObject , VirtualMachine ,
38
38
builtins:: { PyStrRef , PyTypeRef } ,
39
39
function:: { Either , FuncArgs , OptionalArg } ,
40
40
types:: PyStructSequence ,
@@ -88,10 +88,37 @@ mod decl {
88
88
duration_since_system_now ( vm)
89
89
}
90
90
91
- #[ cfg( not( unix) ) ]
92
91
#[ 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 ( ( ) )
95
122
}
96
123
97
124
#[ cfg( not( target_os = "wasi" ) ) ]
@@ -690,21 +717,6 @@ mod platform {
690
717
get_clock_time ( ClockId :: CLOCK_MONOTONIC , vm)
691
718
}
692
719
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
-
708
720
#[ cfg( not( any(
709
721
target_os = "illumos" ,
710
722
target_os = "netbsd" ,
0 commit comments