Skip to content

Commit 22d34a7

Browse files
authored
Coerce 'time' schema constraints (#1720)
1 parent e43c144 commit 22d34a7

File tree

3 files changed

+22
-8
lines changed

3 files changed

+22
-8
lines changed

src/input/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ mod shared;
1313
pub use datetime::TzInfo;
1414
pub(crate) use datetime::{
1515
duration_as_pytimedelta, pydate_as_date, pydatetime_as_datetime, pytime_as_time, EitherDate, EitherDateTime,
16-
EitherTime, EitherTimedelta,
16+
EitherTimedelta,
1717
};
1818
pub(crate) use input_abstract::{
1919
Arguments, BorrowInput, ConsumeIterator, Input, InputType, KeywordArgs, PositionalArgs, ValidatedDict,

src/validators/time.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1+
use pyo3::exceptions::PyValueError;
12
use pyo3::intern;
23
use pyo3::prelude::*;
34
use pyo3::types::{PyDict, PyString};
45

56
use pyo3::IntoPyObjectExt;
6-
use speedate::Time;
7+
use speedate::{MicrosecondsPrecisionOverflowBehavior, Time};
78

89
use crate::build_tools::is_strict;
910
use crate::errors::{ErrorType, ValError, ValResult};
10-
use crate::input::{EitherTime, Input};
11-
use crate::tools::SchemaDict;
11+
use crate::input::Input;
1212

1313
use super::datetime::extract_microseconds_precision;
1414
use super::datetime::TZConstraint;
@@ -18,7 +18,7 @@ use super::{BuildValidator, CombinedValidator, DefinitionsBuilder, ValidationSta
1818
pub struct TimeValidator {
1919
strict: bool,
2020
constraints: Option<TimeConstraints>,
21-
microseconds_precision: speedate::MicrosecondsPrecisionOverflowBehavior,
21+
microseconds_precision: MicrosecondsPrecisionOverflowBehavior,
2222
}
2323

2424
impl BuildValidator for TimeValidator {
@@ -86,9 +86,14 @@ impl Validator for TimeValidator {
8686
}
8787
}
8888

89-
fn convert_pytime(schema: &Bound<'_, PyDict>, field: &Bound<'_, PyString>) -> PyResult<Option<Time>> {
90-
match schema.get_as(field)? {
91-
Some(date) => Ok(Some(EitherTime::Py(date).as_raw()?)),
89+
fn convert_pytime(schema: &Bound<'_, PyDict>, key: &Bound<'_, PyString>) -> PyResult<Option<Time>> {
90+
match schema.get_item(key)? {
91+
Some(value) => match value.validate_time(false, MicrosecondsPrecisionOverflowBehavior::default()) {
92+
Ok(v) => Ok(Some(v.into_inner().as_raw()?)),
93+
Err(_) => Err(PyValueError::new_err(format!(
94+
"'{key}' must be coercible to a time instance",
95+
))),
96+
},
9297
None => Ok(None),
9398
}
9499
}

tests/validators/test_time.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@
1010
from ..conftest import Err, PyAndJson
1111

1212

13+
@pytest.mark.parametrize(
14+
'constraint',
15+
['le', 'lt', 'ge', 'gt'],
16+
)
17+
def test_constraints_schema_validation_error(constraint: str) -> None:
18+
with pytest.raises(SchemaError, match=f"'{constraint}' must be coercible to a time instance"):
19+
SchemaValidator(core_schema.time_schema(**{constraint: 'bad_value'}))
20+
21+
1322
@pytest.mark.parametrize(
1423
'input_value,expected',
1524
[

0 commit comments

Comments
 (0)