RustPython/RustPython · error · ValueError

Inconsistent use of dash separator

Error message

Inconsistent use of dash separator

What it means

_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.

Source

Thrown at Lib/_pydatetime.py:375

def _parse_isoformat_date(dtstr):
    # It is assumed that this is an ASCII-only string of lengths 7, 8 or 10,
    # see the comment on Modules/_datetimemodule.c:_find_isoformat_datetime_separator
    assert len(dtstr) in (7, 8, 10)
    year = int(dtstr[0:4])
    has_sep = dtstr[4] == '-'

    pos = 4 + has_sep
    if dtstr[pos:pos + 1] == "W":
        # YYYY-?Www-?D?
        pos += 1
        weekno = int(dtstr[pos:pos + 2])
        pos += 2

        dayno = 1
        if len(dtstr) > pos:
            if (dtstr[pos:pos + 1] == '-') != has_sep:
                raise ValueError("Inconsistent use of dash separator")

            pos += has_sep

            dayno = int(dtstr[pos:pos + 1])

        return list(_isoweek_to_gregorian(year, weekno, dayno))
    else:
        month = int(dtstr[pos:pos + 2])
        pos += 2
        if (dtstr[pos:pos + 1] == "-") != has_sep:
            raise ValueError("Inconsistent use of dash separator")

        pos += has_sep
        day = int(dtstr[pos:pos + 2])

        return [year, month, day]

View on GitHub (pinned to aaeab4f754)

Solutions

  1. Pick one form for the whole date: '2019-W01-1' or '2019W011'
  2. Normalize the string before parsing: strip all dashes or insert them at fixed positions
  3. Validate with a single regex that fixes the convention, e.g. ^\d{4}-W\d{2}-\d$

Example fix

# before
date.fromisoformat('2019W01-1')  # Inconsistent use of dash separator

# after
date.fromisoformat('2019-W01-1')  # or '2019W011'
Defensive patterns

Strategy: validation

Validate before calling

import re
SEPARATED_WEEK = re.compile(r'^\d{4}-W\d{2}-\d$')
COMPACT_WEEK = re.compile(r'^\d{4}W\d{2}\d$')
if not (SEPARATED_WEEK.match(s) or COMPACT_WEEK.match(s)):
    raise ValueError(f'inconsistent ISO week date separators: {s!r}')
d = date.fromisoformat(s)

Try / catch

try:
    d = date.fromisoformat(s)
except ValueError as e:
    if 'dash separator' in str(e):
        d = date.fromisoformat(s.replace('-', ''))  # normalize to compact and retry once
    else:
        raise

Prevention

When it happens

Trigger: date.fromisoformat('2019W01-1') (compact year-week, separated day) or '2019-W011' (separated year-week, compact day).

Common situations: 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.

Related errors


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