Skip to content

Update speedate to 0.11.0 #769

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ enum_dispatch = "0.3.8"
serde = { version = "1.0.147", features = ["derive"] }
# disabled for benchmarks since it makes microbenchmark performance more flakey
mimalloc = { version = "0.1.30", optional = true, default-features = false, features = ["local_dynamic_tls"] }
speedate = "0.10.0"
speedate = "0.11.0"
ahash = "0.8.0"
url = "2.3.1"
# idna is already required by url, added here to be explicit
Expand Down
30 changes: 23 additions & 7 deletions src/input/datetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ use speedate::{Date, DateTime, Duration, ParseError, Time, TimeConfig};
use std::borrow::Cow;
use strum::EnumMessage;

use crate::errors::{ErrorType, ValError, ValResult};

use super::Input;
use crate::errors::{ErrorType, ValError, ValResult};

#[cfg_attr(debug_assertions, derive(Debug))]
pub enum EitherDate<'a> {
Expand Down Expand Up @@ -272,8 +271,9 @@ pub fn bytes_as_time<'a>(
) -> ValResult<'a, EitherTime<'a>> {
match Time::parse_bytes_with_config(
bytes,
TimeConfig {
&TimeConfig {
microseconds_precision_overflow_behavior: microseconds_overflow_behavior,
unix_timestamp_offset: Some(0),
},
) {
Ok(date) => Ok(date.into()),
Expand All @@ -293,8 +293,9 @@ pub fn bytes_as_datetime<'a, 'b>(
) -> ValResult<'a, EitherDateTime<'a>> {
match DateTime::parse_bytes_with_config(
bytes,
TimeConfig {
&TimeConfig {
microseconds_precision_overflow_behavior: microseconds_overflow_behavior,
unix_timestamp_offset: Some(0),
},
) {
Ok(dt) => Ok(dt.into()),
Expand All @@ -312,7 +313,14 @@ pub fn int_as_datetime<'a>(
timestamp: i64,
timestamp_microseconds: u32,
) -> ValResult<EitherDateTime> {
match DateTime::from_timestamp(timestamp, timestamp_microseconds) {
match DateTime::from_timestamp_with_config(
timestamp,
timestamp_microseconds,
&TimeConfig {
unix_timestamp_offset: Some(0),
..Default::default()
},
) {
Ok(dt) => Ok(dt.into()),
Err(err) => Err(ValError::new(
ErrorType::DatetimeParsing {
Expand Down Expand Up @@ -381,7 +389,14 @@ pub fn int_as_time<'a>(
// ok
t => t as u32,
};
match Time::from_timestamp(time_timestamp, timestamp_microseconds) {
match Time::from_timestamp_with_config(
time_timestamp,
timestamp_microseconds,
&TimeConfig {
unix_timestamp_offset: Some(0),
..Default::default()
},
) {
Ok(dt) => Ok(dt.into()),
Err(err) => Err(ValError::new(
ErrorType::TimeParsing {
Expand Down Expand Up @@ -415,8 +430,9 @@ pub fn bytes_as_timedelta<'a, 'b>(
) -> ValResult<'a, EitherTimedelta<'a>> {
match Duration::parse_bytes_with_config(
bytes,
TimeConfig {
&TimeConfig {
microseconds_precision_overflow_behavior: microseconds_overflow_behavior,
unix_timestamp_offset: Some(0),
},
) {
Ok(dt) => Ok(dt.into()),
Expand Down
2 changes: 1 addition & 1 deletion src/validators/date.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ fn date_from_datetime<'data>(
minute: 0,
second: 0,
microsecond: 0,
tz_offset: None,
tz_offset: dt.time.tz_offset,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@samuelcolvin what are your thoughts on this? It means that we allow datetime(2023, 7, 13, 0, 0, 0, tzinfo=timezone.utc) -> date(2023, 7, 13). We need it because when we parse a unix timestamp to a date it goes through a datetime first. I can try to work around it but maybe it's reasonable as is.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it seems fine.

Simpler might be to just do dt.time.hour == 0 && ... && dt.time.microsecond == 0?

};
if dt.time == zero_time {
Ok(EitherDate::Raw(dt.date))
Expand Down
2 changes: 1 addition & 1 deletion tests/test_hypothesis.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def test_datetime_int(datetime_schema, data):
except OverflowError:
pytest.skip('OverflowError, see pyodide/pyodide#2841, this can happen on 32-bit systems')
else:
assert datetime_schema.validate_python(data) == expected, data
assert datetime_schema.validate_python(data).replace(tzinfo=None) == expected, data


@given(strategies.binary())
Expand Down
22 changes: 11 additions & 11 deletions tests/validators/test_datetime.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,17 @@
(datetime(2022, 6, 8, 12, 13, 14), datetime(2022, 6, 8, 12, 13, 14)),
(date(2022, 6, 8), datetime(2022, 6, 8)),
('2022-06-08T12:13:14', datetime(2022, 6, 8, 12, 13, 14)),
('1000000000000', datetime(2001, 9, 9, 1, 46, 40)),
('1000000000000', datetime(2001, 9, 9, 1, 46, 40, tzinfo=timezone.utc)),
(b'2022-06-08T12:13:14', datetime(2022, 6, 8, 12, 13, 14)),
(b'2022-06-08T12:13:14Z', datetime(2022, 6, 8, 12, 13, 14, tzinfo=timezone.utc)),
((1,), Err('Input should be a valid datetime [type=datetime_type')),
(time(1, 2, 3), Err('Input should be a valid datetime [type=datetime_type')),
(Decimal('1654646400'), datetime(2022, 6, 8)),
('1654646400', datetime(2022, 6, 8)),
(Decimal('1654646400.123456'), datetime(2022, 6, 8, 0, 0, 0, 123456)),
(Decimal('1654646400.1234564'), datetime(2022, 6, 8, 0, 0, 0, 123456)),
(Decimal('1654646400.1234568'), datetime(2022, 6, 8, 0, 0, 0, 123457)),
('1654646400.1234568', datetime(2022, 6, 8, 0, 0, 0, 123457)),
(Decimal('1654646400'), datetime(2022, 6, 8, tzinfo=timezone.utc)),
('1654646400', datetime(2022, 6, 8, tzinfo=timezone.utc)),
(Decimal('1654646400.123456'), datetime(2022, 6, 8, 0, 0, 0, 123456, tzinfo=timezone.utc)),
(Decimal('1654646400.1234564'), datetime(2022, 6, 8, 0, 0, 0, 123456, tzinfo=timezone.utc)),
(Decimal('1654646400.1234568'), datetime(2022, 6, 8, 0, 0, 0, 123457, tzinfo=timezone.utc)),
('1654646400.1234568', datetime(2022, 6, 8, 0, 0, 0, 123457, tzinfo=timezone.utc)),
(253_402_300_800_000, Err('should be a valid datetime, dates after 9999 are not supported as unix timestamps')),
(-20_000_000_000, Err('should be a valid datetime, dates before 1600 are not supported as unix timestamps')),
(float('nan'), Err('Input should be a valid datetime, NaN values not permitted [type=datetime_parsing,')),
Expand Down Expand Up @@ -112,8 +112,8 @@ def test_keep_tz_bound():
'2022-06-08T12:13:14+23:59',
datetime(2022, 6, 8, 12, 13, 14, tzinfo=timezone(timedelta(hours=23, minutes=59))),
),
(1655205632, datetime(2022, 6, 14, 11, 20, 32)),
(1655205632.331557, datetime(2022, 6, 14, 11, 20, 32, microsecond=331557)),
(1655205632, datetime(2022, 6, 14, 11, 20, 32, tzinfo=timezone.utc)),
(1655205632.331557, datetime(2022, 6, 14, 11, 20, 32, microsecond=331557, tzinfo=timezone.utc)),
(
'2022-06-08T12:13:14+24:00',
Err('Input should be a valid datetime, timezone offset must be less than 24 hours [type=datetime_parsing,'),
Expand Down Expand Up @@ -290,7 +290,7 @@ def test_invalid_constraint():
[
('2022-06-08T12:13:14', datetime(2022, 6, 8, 12, 13, 14)),
('2022-06-08T12:13:14Z', datetime(2022, 6, 8, 12, 13, 14, tzinfo=timezone.utc)),
(1655205632, datetime(2022, 6, 14, 11, 20, 32)),
(1655205632, datetime(2022, 6, 14, 11, 20, 32, tzinfo=timezone.utc)),
('2068-06-08T12:13:14', Err('Input should be in the past [type=datetime_past,')),
(3105730800, Err('Input should be in the past [type=datetime_past,')),
],
Expand Down Expand Up @@ -333,7 +333,7 @@ def test_datetime_past_timezone():
[
('2068-06-08T12:13:14', datetime(2068, 6, 8, 12, 13, 14)),
('2068-06-08T12:13:14Z', datetime(2068, 6, 8, 12, 13, 14, tzinfo=timezone.utc)),
(3105730800, datetime(2068, 5, 31, 23, 0)),
(3105730800, datetime(2068, 5, 31, 23, 0, tzinfo=timezone.utc)),
('2022-06-08T12:13:14', Err('Input should be in the future [type=datetime_future,')),
(1655205632, Err('Input should be in the future [type=datetime_future,')),
],
Expand Down
18 changes: 9 additions & 9 deletions tests/validators/test_time.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@
pytest.param((1,), Err('Input should be a valid time [type=time_type'), id='tuple'),
pytest.param(date(2022, 6, 8), Err('Input should be a valid time [type=time_type'), id='date'),
pytest.param(datetime(2022, 6, 8), Err('Input should be a valid time [type=time_type'), id='datetime'),
pytest.param(123, time(0, 2, 3), id='int'),
pytest.param(123, time(0, 2, 3, tzinfo=timezone.utc), id='int'),
pytest.param(float('nan'), Err('valid time format, NaN values not permitted [type=time_parsing,'), id='nan'),
pytest.param(float('inf'), Err('valid time format, numeric times may not exceed 86,399 seconds'), id='inf'),
pytest.param(float('-inf'), Err('valid time format, time in seconds should be positive'), id='-inf'),
pytest.param(Decimal('123'), time(0, 2, 3), id='decimal'),
pytest.param(Decimal('123.123456'), time(0, 2, 3, 123456), id='decimal-6dig'),
pytest.param(Decimal('123.1234562'), time(0, 2, 3, 123456), id='decimal-7dig-up'),
pytest.param(Decimal('123.1234568'), time(0, 2, 3, 123457), id='decimal-7dig-down'),
pytest.param(Decimal('123'), time(0, 2, 3, tzinfo=timezone.utc), id='decimal'),
pytest.param(Decimal('123.123456'), time(0, 2, 3, 123456, tzinfo=timezone.utc), id='decimal-6dig'),
pytest.param(Decimal('123.1234562'), time(0, 2, 3, 123456, tzinfo=timezone.utc), id='decimal-7dig-up'),
pytest.param(Decimal('123.1234568'), time(0, 2, 3, 123457, tzinfo=timezone.utc), id='decimal-7dig-down'),
],
)
def test_time(input_value, expected):
Expand All @@ -50,10 +50,10 @@ def test_time(input_value, expected):
pytest.param('12:13:14.123456', time(12, 13, 14, 123_456), id='str-micro-6dig'),
pytest.param('12:13:14.123456', time(12, 13, 14, 123_456), id='str-micro-6dig'),
pytest.param('12:13:14.1234561', time(12, 13, 14, 123_456), id='str-micro-7dig'),
pytest.param(123, time(0, 2, 3), id='int'),
pytest.param(123.4, time(0, 2, 3, 400_000), id='float'),
pytest.param(123.0, time(0, 2, 3), id='float.0'),
pytest.param(0, time(0), id='int-zero'),
pytest.param(123, time(0, 2, 3, tzinfo=timezone.utc), id='int'),
pytest.param(123.4, time(0, 2, 3, 400_000, tzinfo=timezone.utc), id='float'),
pytest.param(123.0, time(0, 2, 3, tzinfo=timezone.utc), id='float.0'),
pytest.param(0, time(0, tzinfo=timezone.utc), id='int-zero'),
pytest.param(
86400,
Err(
Expand Down