diff --git a/tests/snippets/tuple.py b/tests/snippets/tuple.py index 0f4306fa61..fd59e90609 100644 --- a/tests/snippets/tuple.py +++ b/tests/snippets/tuple.py @@ -44,7 +44,7 @@ def __eq__(self, x): b = (55, *a) assert b == (55, 1, 2, 3, 1) -assert () is () +assert () is () # noqa a = () b = () diff --git a/vm/src/stdlib/time_module.rs b/vm/src/stdlib/time_module.rs index a807535522..f697d4a49c 100644 --- a/vm/src/stdlib/time_module.rs +++ b/vm/src/stdlib/time_module.rs @@ -70,32 +70,41 @@ fn time_monotonic(_vm: &VirtualMachine) -> f64 { } } -fn pyobj_to_naive_date_time(value: Either) -> NaiveDateTime { - match value { +fn pyobj_to_naive_date_time( + value: Either, + vm: &VirtualMachine, +) -> PyResult { + let timestamp = match value { Either::A(float) => { let secs = float.trunc() as i64; let nsecs = (float.fract() * 1e9) as u32; - NaiveDateTime::from_timestamp(secs, nsecs) + NaiveDateTime::from_timestamp_opt(secs, nsecs) } - Either::B(int) => NaiveDateTime::from_timestamp(int, 0), - } + Either::B(int) => NaiveDateTime::from_timestamp_opt(int, 0), + }; + timestamp.ok_or_else(|| { + vm.new_overflow_error("timestamp out of range for platform time_t".to_owned()) + }) } /// https://docs.python.org/3/library/time.html?highlight=gmtime#time.gmtime -fn time_gmtime(secs: OptionalArg>, vm: &VirtualMachine) -> PyObjectRef { +fn time_gmtime(secs: OptionalArg>, vm: &VirtualMachine) -> PyResult { let default = chrono::offset::Utc::now().naive_utc(); let instant = match secs { - OptionalArg::Present(secs) => pyobj_to_naive_date_time(secs), + OptionalArg::Present(secs) => pyobj_to_naive_date_time(secs, vm)?, OptionalArg::Missing => default, }; - PyStructTime::new(vm, instant, 0).into_obj(vm) + Ok(PyStructTime::new(vm, instant, 0).into_obj(vm)) } -fn time_localtime(secs: OptionalArg>, vm: &VirtualMachine) -> PyObjectRef { - let instant = optional_or_localtime(secs); +fn time_localtime( + secs: OptionalArg>, + vm: &VirtualMachine, +) -> PyResult { + let instant = optional_or_localtime(secs, vm)?; // TODO: isdst flag must be valid value here // https://docs.python.org/3/library/time.html#time.localtime - PyStructTime::new(vm, instant, -1).into_obj(vm) + Ok(PyStructTime::new(vm, instant, -1).into_obj(vm)) } fn time_mktime(t: PyStructTime, vm: &VirtualMachine) -> PyResult { @@ -105,12 +114,15 @@ fn time_mktime(t: PyStructTime, vm: &VirtualMachine) -> PyResult { } /// Construct a localtime from the optional seconds, or get the current local time. -fn optional_or_localtime(secs: OptionalArg>) -> NaiveDateTime { +fn optional_or_localtime( + secs: OptionalArg>, + vm: &VirtualMachine, +) -> PyResult { let default = chrono::offset::Local::now().naive_local(); - match secs { - OptionalArg::Present(secs) => pyobj_to_naive_date_time(secs), + Ok(match secs { + OptionalArg::Present(secs) => pyobj_to_naive_date_time(secs, vm)?, OptionalArg::Missing => default, - } + }) } const CFMT: &str = "%a %b %e %H:%M:%S %Y"; @@ -125,9 +137,9 @@ fn time_asctime(t: OptionalArg, vm: &VirtualMachine) -> PyResult { Ok(vm.ctx.new_str(formatted_time)) } -fn time_ctime(secs: OptionalArg>) -> String { - let instant = optional_or_localtime(secs); - instant.format(&CFMT).to_string() +fn time_ctime(secs: OptionalArg>, vm: &VirtualMachine) -> PyResult { + let instant = optional_or_localtime(secs, vm)?; + Ok(instant.format(&CFMT).to_string()) } fn time_strftime(