Summary
dateutil.parser.parse truncates fractional-second digits beyond 6 in the generic parser path:
# dateutil/parser/_parser.py (_parsems)
return int(i), int(f.ljust(6, "0")[:6])
>>> from dateutil import parser
>>> parser.parse("2020-01-01 00:00:00.1234567").microsecond
123456 # correct rounding = 123457; the 7th digit is silently dropped
Same family as the isoparse report (#1545); this is the generic/most-used API (parser.parse), a distinct sink (_parsems). ISO-8601 permits arbitrary fraction precision; a silent wrong instant is returned with no error.
Suggested fix
Round to the nearest microsecond (Decimal / ROUND_HALF_EVEN) instead of truncating, and handle the carry when a rounded value reaches 1_000_000us. Alternatively reject >6 digits (matching datetime.fromisoformat). Happy to adjust to maintainer preference; caught by the exterminator sweep, four-gated.
Summary
dateutil.parser.parsetruncates fractional-second digits beyond 6 in the generic parser path:Same family as the isoparse report (#1545); this is the generic/most-used API (
parser.parse), a distinct sink (_parsems). ISO-8601 permits arbitrary fraction precision; a silent wrong instant is returned with no error.Suggested fix
Round to the nearest microsecond (Decimal / ROUND_HALF_EVEN) instead of truncating, and handle the carry when a rounded value reaches 1_000_000us. Alternatively reject >6 digits (matching
datetime.fromisoformat). Happy to adjust to maintainer preference; caught by the exterminator sweep, four-gated.