{"record":{"id":"0430fed9a2a85a69","repo":"RustPython/RustPython","slug":"inconsistent-use-of-dash-separator","errorCode":null,"errorMessage":"Inconsistent use of dash separator","messagePattern":"Inconsistent use of dash separator","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"Lib/_pydatetime.py","lineNumber":375,"sourceCode":"\ndef _parse_isoformat_date(dtstr):\n    # It is assumed that this is an ASCII-only string of lengths 7, 8 or 10,\n    # see the comment on Modules/_datetimemodule.c:_find_isoformat_datetime_separator\n    assert len(dtstr) in (7, 8, 10)\n    year = int(dtstr[0:4])\n    has_sep = dtstr[4] == '-'\n\n    pos = 4 + has_sep\n    if dtstr[pos:pos + 1] == \"W\":\n        # YYYY-?Www-?D?\n        pos += 1\n        weekno = int(dtstr[pos:pos + 2])\n        pos += 2\n\n        dayno = 1\n        if len(dtstr) > pos:\n            if (dtstr[pos:pos + 1] == '-') != has_sep:\n                raise ValueError(\"Inconsistent use of dash separator\")\n\n            pos += has_sep\n\n            dayno = int(dtstr[pos:pos + 1])\n\n        return list(_isoweek_to_gregorian(year, weekno, dayno))\n    else:\n        month = int(dtstr[pos:pos + 2])\n        pos += 2\n        if (dtstr[pos:pos + 1] == \"-\") != has_sep:\n            raise ValueError(\"Inconsistent use of dash separator\")\n\n        pos += has_sep\n        day = int(dtstr[pos:pos + 2])\n\n        return [year, month, day]\n\n","sourceCodeStart":357,"sourceCodeEnd":393,"githubUrl":"https://github.com/RustPython/RustPython/blob/aaeab4f754b4f40efc0c8ab39cf7c4a3c35a8cfd/Lib/_pydatetime.py#L357-L393","documentation":"_parse_isoformat_date requires the week-date form to be consistent: either fully dash-separated ('2019-W01-1') or fully compact ('2019W011'). It records has_sep from position 4, and when the separator before the day digit disagrees with that choice it raises ValueError('Inconsistent use of dash separator') before reading the day.","triggerScenarios":"date.fromisoformat('2019W01-1') (compact year-week, separated day) or '2019-W011' (separated year-week, compact day).","commonSituations":"String templates that conditionally insert dashes in only one place; data cleaned by replacing some dashes but not others; copy-paste between compact and separated conventions.","solutions":["Pick one form for the whole date: '2019-W01-1' or '2019W011'","Normalize the string before parsing: strip all dashes or insert them at fixed positions","Validate with a single regex that fixes the convention, e.g. ^\\d{4}-W\\d{2}-\\d$"],"exampleFix":"# before\ndate.fromisoformat('2019W01-1')  # Inconsistent use of dash separator\n\n# after\ndate.fromisoformat('2019-W01-1')  # or '2019W011'","handlingStrategy":"validation","validationCode":"import re\nSEPARATED_WEEK = re.compile(r'^\\d{4}-W\\d{2}-\\d$')\nCOMPACT_WEEK = re.compile(r'^\\d{4}W\\d{2}\\d$')\nif not (SEPARATED_WEEK.match(s) or COMPACT_WEEK.match(s)):\n    raise ValueError(f'inconsistent ISO week date separators: {s!r}')\nd = date.fromisoformat(s)","typeGuard":null,"tryCatchPattern":"try:\n    d = date.fromisoformat(s)\nexcept ValueError as e:\n    if 'dash separator' in str(e):\n        d = date.fromisoformat(s.replace('-', ''))  # normalize to compact and retry once\n    else:\n        raise","preventionTips":["Choose one dash convention per codebase for ISO week dates and lint for it","Assemble week dates with a single template, e.g. f'{y}-W{w:02d}-{day}'","Reject mixed-separator input at the boundary instead of repairing deep in the parser"],"tags":["datetime","iso8601","fromisoformat","valueerror","parse-error","separator-mismatch"],"backgroundTag":"iso8601-parse-error","analyzedSha":"aaeab4f754b4f40efc0c8ab39cf7c4a3c35a8cfd","analyzedAt":"2026-08-17T00:37:52.100Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}