RustPython/RustPython · error · ValueError

Invalid isoformat string: {date_string!r}

Error message

Invalid isoformat string: {date_string!r}

What it means

date.fromisoformat only accepts date-only ISO strings whose length is exactly 7 (YYYY-DDD ordinal), 8 (YYYYMMDD), or 10 (YYYY-MM-DD); any other length raises ValueError('Invalid isoformat string: ...'). Full timestamps, week dates with extra fields, and strings carrying offsets belong to datetime.fromisoformat, not date.fromisoformat.

Source

Thrown at Lib/_pydatetime.py:1050

        January 1 of year 1 is day 1.  Only the year, month and day are
        non-zero in the result.
        """
        y, m, d = _ord2ymd(n)
        return cls(y, m, d)

    @classmethod
    def fromisoformat(cls, date_string):
        """Construct a date from a string in ISO 8601 format."""

        if not isinstance(date_string, str):
            raise TypeError('Argument must be a str')

        if not date_string.isascii():
            raise ValueError('Argument must be an ASCII str')

        if len(date_string) not in (7, 8, 10):
            raise ValueError(f'Invalid isoformat string: {date_string!r}')

        try:
            return cls(*_parse_isoformat_date(date_string))
        except Exception:
            raise ValueError(f'Invalid isoformat string: {date_string!r}')

    @classmethod
    def fromisocalendar(cls, year, week, day):
        """Construct a date from the ISO year, week number and weekday.

        This is the inverse of the date.isocalendar() function"""
        return cls(*_isoweek_to_gregorian(year, week, day))

    @classmethod
    def strptime(cls, date_string, format):
        """Parse a date string according to the given format (like time.strptime())."""
        import _strptime
        return _strptime._strptime_datetime_date(cls, date_string, format)

View on GitHub (pinned to aaeab4f754)

Solutions

  1. For full timestamps use datetime.datetime.fromisoformat(s).date()
  2. When the format is fixed, slice the date part: date.fromisoformat(s[:10])
  3. Pre-validate len(s) in (7, 8, 10) and emit your own descriptive error

Example fix

// before
d = date.fromisoformat(iso_ts)   # iso_ts == '2020-01-01T12:00:00+02:00'

// after
import datetime as dt
d = dt.datetime.fromisoformat(iso_ts).date()
Defensive patterns

Strategy: validation

Validate before calling

if len(s) not in (7, 8, 10):
    raise ValueError(f'{s!r} is not a date-only ISO string (YYYY-DDD, YYYYMMDD, or YYYY-MM-DD); use datetime.fromisoformat for timestamps')

Prevention

When it happens

Trigger: date.fromisoformat('2020-01-01T00:00:00') (19 chars); '2020-01-01T00:00' (16); truncated '2020-0' or '2020-01-0'; strings with 'Z' or '+02:00' appended (13+ chars).

Common situations: Feeding API timestamp strings into date.fromisoformat instead of datetime.fromisoformat; assuming 'YYYY-MM' or 'YYYY-Www' alone is supported; keeping UTC offsets attached when only the date is wanted.

Related errors


AI-assisted analysis of RustPython/RustPython@aaeab4f754 (2026-08-17). Data as JSON: /api/errors/782dc5af31126c20. Report an issue: GitHub.