python/cpython · error · ValueError

Argument must be an ASCII str

Error message

Argument must be an ASCII str

What it means

Raised by date.fromisoformat() when the argument is a str but contains non-ASCII characters. The fast ISO parser operates on ASCII only, so any multi-byte content (e.g. full-width digits '2024' or look-alike Unicode dashes) is rejected with ValueError before length/format checks run.

Source

Thrown at Lib/_pydatetime.py:1057

    @classmethod
    def fromordinal(cls, n):
        """Construct a date from a proleptic Gregorian ordinal.

        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):

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. Normalize input before parsing: s.encode('ascii', 'ignore').decode() or unicodedata.normalize('NFKC', s)
  2. Reject non-ASCII at form validation with a clear message
  3. Use unicodedata.digit() mapping or a strict regex [0-9]{4}-[0-9]{2}-[0-9]{2} pre-check

Example fix

# before
d = date.fromisoformat(user_input)  # contains full-width digits
# after
import unicodedata
d = date.fromisoformat(unicodedata.normalize('NFKC', user_input))
Defensive patterns

Strategy: validation

Validate before calling

import unicodedata

s = unicodedata.normalize('NFKC', s)
if not s.isascii():
    raise ValueError('date string must be ASCII')
d = date.fromisoformat(s)

Type guard

def is_ascii_date_str(s: str) -> bool:
    return isinstance(s, str) and s.isascii()

Prevention

When it happens

Trigger: date.fromisoformat('2024-01-01') (full-width digits); strings pasted from word processors with typographic hyphens (U+2010/2012 instead of '-'); user input via IME producing Unicode digits.

Common situations: Copy-pasted dates from rich-text documents/chat apps; locales where input methods emit full-width digits; data cleaning pipelines that normalize ASCII but miss Unicode digit variants.

Related errors


AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14). Data as JSON: /api/errors/ae3a7bee8bfc951b. Report an issue: GitHub.