Skip to content

Commit 4bc5181

Browse files
committed
Apply suggestions
* Update tests * Add test cases for missing colons * Check missing colons
1 parent fa4d19c commit 4bc5181

File tree

2 files changed

+48
-34
lines changed

2 files changed

+48
-34
lines changed

Lib/_strptime.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -557,8 +557,17 @@ def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
557557
raise ValueError("time data %r does not match format %r" %
558558
(data_string, format))
559559
if len(data_string) != found.end():
560-
raise ValueError("unconverted data remains: %s" %
561-
data_string[found.end():])
560+
rest = data_string[found.end():]
561+
# Specific check for '%:z' directive
562+
if (
563+
"colon_z" in found.re.groupindex
564+
and found.group("colon_z") is not None
565+
and rest[0] != ":"
566+
):
567+
raise ValueError(
568+
f"Missing colon in %:z before '{rest}', got '{data_string}'"
569+
)
570+
raise ValueError("unconverted data remains: %s" % rest)
562571

563572
iso_year = year = None
564573
month = day = 1

Lib/test/test_strptime.py

Lines changed: 37 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -406,45 +406,50 @@ def test_offset(self):
406406
(*_, offset), _, offset_fraction = _strptime._strptime("-013030.000001", "%z")
407407
self.assertEqual(offset, -(one_hour + half_hour + half_minute))
408408
self.assertEqual(offset_fraction, -1)
409+
410+
cases = [
411+
("+01:00", one_hour, 0),
412+
("-01:30", -(one_hour + half_hour), 0),
413+
("-01:30:30", -(one_hour + half_hour + half_minute), 0),
414+
("-01:30:30.000001", -(one_hour + half_hour + half_minute), -1),
415+
("+01:30:30.001", +(one_hour + half_hour + half_minute), 1000),
416+
("Z", 0, 0),
417+
]
409418
for directive in ("%z", "%:z"):
410-
(*_, offset), _, offset_fraction = _strptime._strptime("+01:00",
411-
directive)
412-
self.assertEqual(offset, one_hour)
413-
self.assertEqual(offset_fraction, 0)
414-
(*_, offset), _, offset_fraction = _strptime._strptime("-01:30",
415-
directive)
416-
self.assertEqual(offset, -(one_hour + half_hour))
417-
self.assertEqual(offset_fraction, 0)
418-
(*_, offset), _, offset_fraction = _strptime._strptime("-01:30:30",
419-
directive)
420-
self.assertEqual(offset, -(one_hour + half_hour + half_minute))
421-
self.assertEqual(offset_fraction, 0)
422-
(*_, offset), _, offset_fraction = _strptime._strptime("-01:30:30.000001",
423-
directive)
424-
self.assertEqual(offset, -(one_hour + half_hour + half_minute))
425-
self.assertEqual(offset_fraction, -1)
426-
(*_, offset), _, offset_fraction = _strptime._strptime("+01:30:30.001",
427-
directive)
428-
self.assertEqual(offset, one_hour + half_hour + half_minute)
429-
self.assertEqual(offset_fraction, 1000)
430-
(*_, offset), _, offset_fraction = _strptime._strptime("Z",
431-
directive)
432-
self.assertEqual(offset, 0)
433-
self.assertEqual(offset_fraction, 0)
419+
for offset_str, expected_offset, expected_fraction in cases:
420+
with self.subTest(offset_str=offset_str, directive=directive):
421+
(*_, offset), _, offset_fraction = _strptime._strptime(
422+
offset_str, directive
423+
)
424+
self.assertEqual(offset, expected_offset)
425+
self.assertEqual(offset_fraction, expected_fraction)
434426

435427
def test_bad_offset(self):
428+
error_cases_any_z = [
429+
"-01:30:30.", # Decimal point not followed with digits
430+
"-01:30:30.1234567", # Too many digits after decimal point
431+
"-01:30:30:123456", # Colon as decimal separator
432+
"-0130:30", # Incorrect use of colons
433+
]
436434
for directive in ("%z", "%:z"):
437-
with self.assertRaises(ValueError):
438-
_strptime._strptime("-01:30:30.", directive)
439-
with self.assertRaises(ValueError):
440-
_strptime._strptime("-01:30:30.1234567", directive)
441-
with self.assertRaises(ValueError):
442-
_strptime._strptime("-01:30:30:123456", directive)
443-
with self.assertRaises(ValueError):
444-
_strptime._strptime("-0130:30", "%z")
435+
for timestr in error_cases_any_z:
436+
with self.subTest(timestr=timestr, directive=directive):
437+
with self.assertRaises(ValueError):
438+
_strptime._strptime(timestr, directive)
439+
440+
required_colons_cases = ["-013030", "+0130", "-01:3030.123456"]
441+
for timestr in required_colons_cases:
442+
with self.subTest(timestr=timestr):
443+
with self.assertRaises(ValueError):
444+
_strptime._strptime(timestr, "%:z")
445+
445446
with self.assertRaises(ValueError) as err:
446447
_strptime._strptime("-01:3030", "%z")
447448
self.assertEqual("Inconsistent use of : in -01:3030", str(err.exception))
449+
with self.assertRaises(ValueError) as err:
450+
_strptime._strptime("-01:3030", "%:z")
451+
self.assertEqual("Missing colon in %:z before '30', got '-01:3030'",
452+
str(err.exception))
448453

449454
@skip_if_buggy_ucrt_strfptime
450455
def test_timezone(self):

0 commit comments

Comments
 (0)