Skip to content

Commit

Permalink
refactor(regex): use regex
Browse files Browse the repository at this point in the history
  • Loading branch information
JeanArhancet committed Dec 23, 2021
1 parent dda3a11 commit c49de2e
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 14 deletions.
19 changes: 10 additions & 9 deletions pydantic/datetime_parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@
r'$'
)

# Support scientific notation
scientific_notation = re.compile(r'^(?P<sign>[-+]?)' r'(?P<scientific_notation>\d+(.\d+)?[eE][+\-]?\d+)?' r'$')

EPOCH = datetime(1970, 1, 1)
# if greater than this, the number is in ms, if less than or equal it's in seconds
# (in seconds this is 11th October 2603, in ms it's 20th August 1970)
Expand Down Expand Up @@ -226,16 +229,11 @@ def parse_duration(value: StrBytesIntFloat) -> timedelta:
value = str(value)
elif isinstance(value, bytes):
value = value.decode()

if isinstance(value, (str)):
try:
#scientific notation
value = f"{float(value):.6f}"
except ValueError:
pass


try:
match = standard_duration_re.match(value) or iso8601_duration_re.match(value)
match = (
standard_duration_re.match(value) or iso8601_duration_re.match(value) or scientific_notation.match(value)
)
except TypeError:
raise TypeError('invalid type; expected timedelta, string, bytes, int or float')

Expand All @@ -250,6 +248,9 @@ def parse_duration(value: StrBytesIntFloat) -> timedelta:
if kw.get('seconds') and kw.get('microseconds') and kw['seconds'].startswith('-'):
kw['microseconds'] = '-' + kw['microseconds']

if kw.get('scientific_notation'):
kw['seconds'] = ("%.17s" % kw.pop('scientific_notation')).rstrip('0').rstrip('.')

kw_ = {k: float(v) for k, v in kw.items() if v is not None}

return sign * timedelta(**kw_) # type: ignore
10 changes: 5 additions & 5 deletions tests/test_datetime_parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ def test_datetime_parsing(value, result):
timedelta(days=-4, minutes=15, seconds=30), # negative durations
timedelta(minutes=15, seconds=30), # minute & seconds
timedelta(seconds=30), # seconds
timedelta(microseconds=99) # microseconds
timedelta(microseconds=99), # microseconds
],
)
def test_parse_python_format(delta):
Expand Down Expand Up @@ -212,14 +212,14 @@ def test_parse_python_format(delta):
('PT0.000005S', timedelta(microseconds=5)),
(b'PT0.000005S', timedelta(microseconds=5)),
# Scientific Notation
('+0003', timedelta(seconds=3)),
('+0003', errors.DurationError),
(9.9e-05, timedelta(microseconds=99)),
('9.9e-05', timedelta(microseconds=99)),
(9.9e05, timedelta(days=11, seconds=39600)),
(+3, timedelta(seconds=3)),
(-4.70e+9, timedelta(days=-54399, seconds=73600)),
(-.2E-4, timedelta(days=-1, seconds=86399, microseconds=999980)),
(-7.6603, timedelta(days=-1, seconds=86392, microseconds=339700))
(-4.70e9, timedelta(days=-54399, seconds=73600)),
(-0.2e-4, timedelta(days=-1, seconds=86399, microseconds=999980)),
(-7.6603, timedelta(days=-1, seconds=86392, microseconds=339700)),
],
)
def test_parse_durations(value, result):
Expand Down

0 comments on commit c49de2e

Please sign in to comment.