Skip to content
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

isoparse: Fail with inconsistent time separators #1125

Merged
merged 2 commits into from Jul 2, 2021
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/1125.bugfix.rst
@@ -0,0 +1 @@
Make `isoparse` raise when trying to parse times with inconsistent use of `:` separator. Reported and fixed by @mariocj89 (gh pr #1125).
13 changes: 9 additions & 4 deletions dateutil/parser/isoparser.py
Expand Up @@ -336,7 +336,7 @@ def _parse_isotime(self, timestr):
if len(timestr) < 2:
raise ValueError('ISO time too short')

has_sep = len_str >= 3 and timestr[2:3] == self._TIME_SEP
has_sep = False

while pos < len_str and comp < 5:
comp += 1
Expand All @@ -347,13 +347,18 @@ def _parse_isotime(self, timestr):
pos = len_str
break

if comp == 1 and timestr[pos:pos+1] == self._TIME_SEP:
has_sep = True
pos += 1
elif comp == 2 and has_sep:
if timestr[pos:pos+1] != self._TIME_SEP:
raise ValueError('Inconsistent use of colon separator')
pos += 1

if comp < 3:
# Hour, minute, second
components[comp] = int(timestr[pos:pos + 2])
pos += 2
if (has_sep and pos < len_str and
timestr[pos:pos + 1] == self._TIME_SEP):
pos += 1

if comp == 3:
# Fraction of a second
Expand Down
25 changes: 3 additions & 22 deletions dateutil/test/test_isoparser.py
Expand Up @@ -244,6 +244,8 @@ def test_bytes(isostr, dt):
('2012-0425', ValueError), # Inconsistent date separators
('201204-25', ValueError), # Inconsistent date separators
('20120425T0120:00', ValueError), # Inconsistent time separators
('20120425T01:2000', ValueError), # Inconsistent time separators
('14:3015', ValueError), # Inconsistent time separator
('20120425T012500-334', ValueError), # Wrong microsecond separator
('2001-1', ValueError), # YYYY-M not valid
('2012-04-9', ValueError), # YYYY-MM-D not valid
Expand Down Expand Up @@ -286,17 +288,6 @@ def test_iso_with_sep_raises(sep_act, valid_sep, exception):
parser.isoparse(isostr)


@pytest.mark.xfail()
@pytest.mark.parametrize('isostr,exception', [ # pragma: nocover
('20120425T01:2000', ValueError), # Inconsistent time separators
])
def test_iso_raises_failing(isostr, exception):
# These are test cases where the current implementation is too lenient
# and need to be fixed
with pytest.raises(exception):
isoparse(isostr)


###
# Test ISOParser constructor
@pytest.mark.parametrize('sep', [' ', '9', '🍛'])
Expand Down Expand Up @@ -397,6 +388,7 @@ def test_parse_isodate(d, dt_fmt, as_bytes):
('2013-02-29', ValueError), # Not a leap year
('2014/12/03', ValueError), # Wrong separators
('2014-04-19T', ValueError), # Unknown components
('201202', ValueError), # Invalid format
])
def test_isodate_raises(isostr, exception):
with pytest.raises(exception):
Expand Down Expand Up @@ -503,14 +495,3 @@ def test_isotime_raises(isostr, exception):
iparser = isoparser()
with pytest.raises(exception):
iparser.parse_isotime(isostr)


@pytest.mark.xfail()
@pytest.mark.parametrize('isostr,exception', [ # pragma: nocover
('14:3015', ValueError), # Inconsistent separator use
('201202', ValueError) # Invalid ISO format
])
def test_isotime_raises_xfail(isostr, exception):
iparser = isoparser()
with pytest.raises(exception):
iparser.parse_isotime(isostr)