python/cpython · error · TypeError

strptime() argument {} must be str, not {}

Error message

strptime() argument {} must be str, not {}

What it means

_strptime type-checks both of its arguments up front: for index, arg in enumerate([data_string, format]) it requires str. This TypeError is raised when the data string (index 0) or the format (index 1) is not a str — e.g. bytes, int, None. The message reports the argument position and the offending type.

Source

Thrown at Lib/_strptime.py:543

    # the same as that specified by %U or %W).
    week_0_length = (7 - first_weekday) % 7
    if week_of_year == 0:
        return 1 + day_of_week - first_weekday
    else:
        days_to_week = week_0_length + (7 * (week_of_year - 1))
        return 1 + days_to_week + day_of_week


def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
    """Return a 3-tuple consisting of a tuple with time components,
    an int containing the number of microseconds, and an int
    containing the microseconds part of the GMT offset, based on the
    input string and the format string."""

    for index, arg in enumerate([data_string, format]):
        if not isinstance(arg, str):
            msg = "strptime() argument {} must be str, not {}"
            raise TypeError(msg.format(index, type(arg)))

    global _TimeRE_cache, _regex_cache
    with _cache_lock:
        locale_time = _TimeRE_cache.locale_time
        if (_getlang() != locale_time.lang or
            time.tzname != locale_time.tzname or
            time.daylight != locale_time.daylight):
            _TimeRE_cache = TimeRE()
            _regex_cache.clear()
            locale_time = _TimeRE_cache.locale_time
        if len(_regex_cache) > _CACHE_MAX_SIZE:
            _regex_cache.clear()
        format_regex = _regex_cache.get(format)
        if not format_regex:
            try:
                format_regex = _TimeRE_cache.compile(format)
            # KeyError raised when a bad format is found; can be specified as
            # \\, in which case it was a stray % but with a space after it

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. Decode bytes to str before parsing: time.strptime(data.decode('utf-8'), fmt)
  2. If you have a timestamp number, use datetime.fromtimestamp(ts) instead of strptime
  3. If you have a date/datetime object, call .strftime(fmt) — strptime is only for strings

Example fix

# before
>>> datetime.strptime(b'2020-01-01', '%Y-%m-%d')
TypeError: strptime() argument 0 must be str, not <class 'bytes'>

# after
>>> datetime.strptime(b'2020-01-01'.decode(), '%Y-%m-%d')
datetime.datetime(2020, 1, 1, 0, 0)
Defensive patterns

Strategy: type-guard

Validate before calling

if not isinstance(data_string, str):
    data_string = data_string.decode('utf-8') if isinstance(data_string, bytes) else str(data_string)
if not isinstance(fmt, str):
    raise TypeError('fmt must be str')

Type guard

def is_strptime_args(*args) -> bool:
    return all(isinstance(a, str) for a in args)

Try / catch

try:
    dt = datetime.strptime(s, fmt)
except TypeError:
    dt = datetime.strptime(s.decode() if isinstance(s, bytes) else str(s), fmt)

Prevention

When it happens

Trigger: Calling time.strptime() or datetime.datetime.strptime() with bytes (b'2020-01-01'), an int/float timestamp, None, or a non-str format argument.

Common situations: Reading data from files/network opened in binary mode and passing bytes directly; passing a datetime.date object instead of its string form; forgetting that strptime (parse) is the inverse of strftime (format).

Related errors


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