Skip to content

datetime.fromisoformat() hits a debug-build assertion on an out-of-range month combined with a 24:00 time #151770

@tonghuaroot

Description

@tonghuaroot

Bug report

datetime.fromisoformat() reaches days_in_month() with month == 0 when the string combines an out-of-range (below 1) month with a 24:00 time, tripping a debug-build assertion. On a release build the same input raises ValueError, so the behaviour is inconsistent between build configurations.

Reproduction

>>> from datetime import datetime
>>> datetime.fromisoformat("2009-00-01T24:00:00")

On a --with-pydebug build (C implementation):

Assertion failed: (month >= 1), function days_in_month, file Modules/_datetimemodule.c, line 441.

(SIGABRT). The pure-Python implementation in Lib/_pydatetime.py raises AssertionError on the same input. On a release / -DNDEBUG build, both implementations correctly raise ValueError: month must be in 1..12, not 0.

Root cause

The 24:00 midnight-rollover guard validates the upper month bound but not the lower one before calling days_in_month():

  • Modules/_datetimemodule.c, datetime_datetime_fromisoformat_impl: if ((hour == 24) && (month <= 12))
  • Lib/_pydatetime.py, datetime.fromisoformat: if month <= 12 and day <= (days_in_month := _days_in_month(year, month))

The parser does not range-check the month before this point, so month == 0 flows into days_in_month(year, 0) and hits assert(month >= 1). The matching upper-bound input "2009-13-01T24:00:00" is already rejected by the month <= 12 check; only the lower bound is missing.

Suggested fix

Add the month >= 1 lower bound to the guard in both implementations (mirroring check_date_args's existing month < 1 || month > 12 validation), so the 24:00 path is only taken for an in-range month and the normal ValueError is raised otherwise. I'll open a PR.

This was found while adding a fuzz harness for fromisoformat.

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    extension-modulesC modules in the Modules dirstdlibStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or error
    No fields configured for issues without a type.

    Projects

    Status
    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions