Skip to content

Commit 898031f

Browse files
committed
Fix error message to match original datetime lib and enabled more unit tests
1 parent 4e7900b commit 898031f

File tree

2 files changed

+37
-26
lines changed

2 files changed

+37
-26
lines changed

adafruit_datetime.py

+35-22
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@
6363
)
6464
_DAYNAMES = (None, "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun")
6565

66+
_INVALID_ISO_ERROR = "Invalid isoformat string: '{}'"
67+
6668
# Utility functions - universal
6769
def _cmp(obj_x, obj_y):
6870
return 0 if obj_x == obj_y else 1 if obj_x > obj_y else -1
@@ -670,7 +672,7 @@ def fromisoformat(cls, date_string):
670672
if match:
671673
y, m, d = int(match.group(1)), int(match.group(2)), int(match.group(3))
672674
return cls(y, m, d)
673-
raise ValueError("Invalid isoformat string")
675+
raise ValueError(_INVALID_ISO_ERROR.format(date_string))
674676

675677
@classmethod
676678
def today(cls):
@@ -926,16 +928,17 @@ def tzinfo(self):
926928
def _parse_iso_string(string_to_parse, segments):
927929
results = []
928930

931+
remaining_string = string_to_parse
929932
for regex in segments:
930-
match = _re.match(regex, string_to_parse)
933+
match = _re.match(regex, remaining_string)
931934
if match:
932935
for grp in range(regex.count("(")):
933936
results.append(int(match.group(grp + 1)))
934-
string_to_parse = string_to_parse[len(match.group(0)) :]
935-
elif string_to_parse: # Only raise an error if we're not done yet
936-
raise ValueError("Invalid isoformat string")
937-
if string_to_parse:
938-
raise ValueError("Invalid isoformat string")
937+
remaining_string = remaining_string[len(match.group(0)) :]
938+
elif remaining_string: # Only raise an error if we're not done yet
939+
raise ValueError()
940+
if remaining_string:
941+
raise ValueError()
939942
return results
940943

941944
# pylint: disable=too-many-locals
@@ -945,6 +948,8 @@ def fromisoformat(cls, time_string):
945948
Valid format is ``HH[:MM[:SS[.fff[fff]]]][+HH:MM[:SS[.ffffff]]]``
946949
947950
"""
951+
# Store the original string in an error message
952+
original_string = time_string
948953
match = _re.match(r"(.*)[\-\+]", time_string)
949954
offset_string = None
950955
if match:
@@ -964,13 +969,16 @@ def fromisoformat(cls, time_string):
964969
r"\.([0-9][0-9][0-9][0-9][0-9][0-9])",
965970
)
966971

967-
results = cls._parse_iso_string(time_string, time_segments)
968-
if len(results) < 1:
969-
raise ValueError("Invalid isoformat string")
970-
if len(results) < len(time_segments):
971-
results += [None] * (len(time_segments) - len(results))
972-
if offset_string:
973-
results += cls._parse_iso_string(offset_string, offset_segments)
972+
try:
973+
results = cls._parse_iso_string(time_string, time_segments)
974+
if len(results) < 1:
975+
raise ValueError(_INVALID_ISO_ERROR.format(original_string))
976+
if len(results) < len(time_segments):
977+
results += [None] * (len(time_segments) - len(results))
978+
if offset_string:
979+
results += cls._parse_iso_string(offset_string, offset_segments)
980+
except ValueError as error:
981+
raise ValueError(_INVALID_ISO_ERROR.format(original_string)) from error
974982

975983
hh = results[0]
976984
mm = results[1] if len(results) >= 2 and results[1] is not None else 0
@@ -1316,15 +1324,20 @@ def fromisoformat(cls, date_string):
13161324
Valid format is ``YYYY-MM-DD[*HH[:MM[:SS[.fff[fff]]]][+HH:MM[:SS[.ffffff]]]]``
13171325
13181326
"""
1327+
original_string = date_string
1328+
13191329
time_string = None
1320-
if len(date_string) > 10:
1321-
time_string = date_string[11:]
1322-
date_string = date_string[:10]
1323-
dateval = date.fromisoformat(date_string)
1324-
timeval = time.fromisoformat(time_string)
1325-
else:
1326-
dateval = date.fromisoformat(date_string)
1327-
timeval = time()
1330+
try:
1331+
if len(date_string) > 10:
1332+
time_string = date_string[11:]
1333+
date_string = date_string[:10]
1334+
dateval = date.fromisoformat(date_string)
1335+
timeval = time.fromisoformat(time_string)
1336+
else:
1337+
dateval = date.fromisoformat(date_string)
1338+
timeval = time()
1339+
except ValueError as error:
1340+
raise ValueError(_INVALID_ISO_ERROR.format(original_string)) from error
13281341

13291342
return cls.combine(dateval, timeval)
13301343

tests/test_datetime.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -1128,7 +1128,7 @@ def test_fromisoformat_ambiguous(self):
11281128
self.assertEqual(dt, dt_rt)
11291129

11301130
# TODO
1131-
@unittest.skip("fromisoformat not implemented")
1131+
@unittest.skip("_format_time not fully implemented")
11321132
def test_fromisoformat_timespecs(self):
11331133
datetime_bases = [(2009, 12, 4, 8, 17, 45, 123456), (2009, 12, 4, 8, 17, 45, 0)]
11341134

@@ -1193,14 +1193,12 @@ def test_fromisoformat_fails_datetime(self):
11931193
with self.assertRaises(ValueError):
11941194
self.theclass.fromisoformat(bad_str)
11951195

1196-
# TODO
1197-
@unittest.skip("fromisoformat not implemented")
11981196
def test_fromisoformat_fails_surrogate(self):
11991197
# Test that when fromisoformat() fails with a surrogate character as
12001198
# the separator, the error message contains the original string
12011199
dtstr = "2018-01-03\ud80001:0113"
12021200

1203-
with self.assertRaisesRegex(ValueError, re.escape(repr(dtstr))):
1201+
with self.assertRaisesRegex(ValueError, repr(dtstr)):
12041202
self.theclass.fromisoformat(dtstr)
12051203

12061204
# TODO

0 commit comments

Comments
 (0)