{"record":{"id":"ae3a7bee8bfc951b","repo":"python/cpython","slug":"argument-must-be-an-ascii-str","errorCode":null,"errorMessage":"Argument must be an ASCII str","messagePattern":"Argument must be an ASCII str","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"Lib/_pydatetime.py","lineNumber":1057,"sourceCode":"    @classmethod\n    def fromordinal(cls, n):\n        \"\"\"Construct a date from a proleptic Gregorian ordinal.\n\n        January 1 of year 1 is day 1.  Only the year, month and day are\n        non-zero in the result.\n        \"\"\"\n        y, m, d = _ord2ymd(n)\n        return cls(y, m, d)\n\n    @classmethod\n    def fromisoformat(cls, date_string):\n        \"\"\"Construct a date from a string in ISO 8601 format.\"\"\"\n\n        if not isinstance(date_string, str):\n            raise TypeError('Argument must be a str')\n\n        if not date_string.isascii():\n            raise ValueError('Argument must be an ASCII str')\n\n        if len(date_string) not in (7, 8, 10):\n            raise ValueError(f'Invalid isoformat string: {date_string!r}')\n\n        try:\n            return cls(*_parse_isoformat_date(date_string))\n        except Exception:\n            raise ValueError(f'Invalid isoformat string: {date_string!r}')\n\n    @classmethod\n    def fromisocalendar(cls, year, week, day):\n        \"\"\"Construct a date from the ISO year, week number and weekday.\n\n        This is the inverse of the date.isocalendar() function\"\"\"\n        return cls(*_isoweek_to_gregorian(year, week, day))\n\n    @classmethod\n    def strptime(cls, date_string, format):","sourceCodeStart":1039,"sourceCodeEnd":1075,"githubUrl":"https://github.com/python/cpython/blob/bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6/Lib/_pydatetime.py#L1039-L1075","documentation":"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 '２０２４' or look-alike Unicode dashes) is rejected with ValueError before length/format checks run.","triggerScenarios":"date.fromisoformat('２０２４-０１-０１') (full-width digits); strings pasted from word processors with typographic hyphens (U+2010/2012 instead of '-'); user input via IME producing Unicode digits.","commonSituations":"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.","solutions":["Normalize input before parsing: s.encode('ascii', 'ignore').decode() or unicodedata.normalize('NFKC', s)","Reject non-ASCII at form validation with a clear message","Use unicodedata.digit() mapping or a strict regex [0-9]{4}-[0-9]{2}-[0-9]{2} pre-check"],"exampleFix":"# before\nd = date.fromisoformat(user_input)  # contains full-width digits\n# after\nimport unicodedata\nd = date.fromisoformat(unicodedata.normalize('NFKC', user_input))","handlingStrategy":"validation","validationCode":"import unicodedata\n\ns = unicodedata.normalize('NFKC', s)\nif not s.isascii():\n    raise ValueError('date string must be ASCII')\nd = date.fromisoformat(s)","typeGuard":"def is_ascii_date_str(s: str) -> bool:\n    return isinstance(s, str) and s.isascii()","tryCatchPattern":null,"preventionTips":["NFKC-normalize pasted/IME input to fold full-width digits to ASCII","Reject non-ASCII early in form validation with an actionable message"],"tags":["datetime","valueerror","iso-8601","unicode","parsing"],"backgroundTag":null,"analyzedSha":"bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6","analyzedAt":"2026-08-14T22:01:13.976Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}