{"record":{"id":"062ec39c70320360","repo":"python/cpython","slug":"name-must-be-a-string","errorCode":null,"errorMessage":"name must be a string","messagePattern":"name must be a string","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"Lib/_pydatetime.py","lineNumber":2460,"sourceCode":"    return week1monday\n\n\nclass timezone(tzinfo):\n    \"\"\"Fixed offset from UTC implementation of tzinfo.\"\"\"\n\n    __slots__ = '_offset', '_name'\n\n    # Sentinel value to disallow None\n    _Omitted = object()\n    def __new__(cls, offset, name=_Omitted):\n        if not isinstance(offset, timedelta):\n            raise TypeError(\"offset must be a timedelta\")\n        if name is cls._Omitted:\n            if not offset:\n                return cls.utc\n            name = None\n        elif not isinstance(name, str):\n            raise TypeError(\"name must be a string\")\n        if not cls._minoffset <= offset <= cls._maxoffset:\n            raise ValueError(\"offset must be a timedelta \"\n                             \"strictly between -timedelta(hours=24) and \"\n                             f\"timedelta(hours=24), not {offset!r}\")\n        return cls._create(offset, name)\n\n    def __init_subclass__(cls):\n        raise TypeError(\"type 'datetime.timezone' is not an acceptable base type\")\n\n    @classmethod\n    def _create(cls, offset, name=None):\n        self = tzinfo.__new__(cls)\n        self._offset = offset\n        self._name = name\n        return self\n\n    def __getinitargs__(self):\n        \"\"\"pickle support\"\"\"","sourceCodeStart":2442,"sourceCodeEnd":2478,"githubUrl":"https://github.com/python/cpython/blob/bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6/Lib/_pydatetime.py#L2442-L2478","documentation":"When the optional name argument to timezone() is supplied (i.e. not the _Omitted sentinel), it must be a str used as the tzname() display label. Any non-string name — bytes, int, None — raises TypeError. Note None is only legal internally when name was omitted.","triggerScenarios":"timezone(timedelta(hours=-5), b'EST'); timezone(offset, None) explicitly passing None to 'clear' the name; names read from binary config or env vars not decoded.","commonSituations":"Config keys read as bytes (e.g. os.environb); passing name=None intending auto-generated names — omit the argument instead; copying examples where the name came from a non-str source.","solutions":["Pass a str: timezone(timedelta(hours=-5), 'EST')","To get an auto-derived name (like 'UTC-05:00'), omit the argument entirely","Decode bytes names: name.decode('ascii') before passing","For full IANA names use ZoneInfo('America/New_York')"],"exampleFix":"// before\ntz = timezone(timedelta(hours=-5), None)\n\n# after\ntz = timezone(timedelta(hours=-5))  # name auto-derived","handlingStrategy":"type-guard","validationCode":"from datetime import timedelta, timezone\n\ndef make_timezone(offset: timedelta, name=None) -> timezone:\n    if name is None:\n        return timezone(offset)      # omit -> auto-derived name\n    if isinstance(name, bytes):\n        name = name.decode('ascii')\n    return timezone(offset, name)","typeGuard":"def is_valid_tz_name(name) -> bool:\n    return name is None or isinstance(name, str)","tryCatchPattern":null,"preventionTips":["Omit the name argument for auto-derived labels","Decode bytes config values once at load","Pass only str names, never None explicitly"],"tags":["python","datetime","timezone","type-error"],"backgroundTag":null,"analyzedSha":"bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6","analyzedAt":"2026-08-14T22:01:13.976Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}