{"id":"cf8335de787324a3","repo":"pytest-dev/pytest","slug":"invalid-type-for-ini-option-name-r-type-r-e","errorCode":null,"errorMessage":"invalid type for ini option {name!r}: {type_!r} (expected one of {tags}, one of the types str, bool, int, float, a union of these types such as `int | str`, or a `Literal` of strings)","messagePattern":"invalid type for ini option (.+?): (.+?) \\(expected one of (.+?), one of the types str, bool, int, float, a union of these types such as `int \\| str`, or a `Literal` of strings\\)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/_pytest/config/argparsing.py","lineNumber":74,"sourceCode":"#: ``int | str``).\nIniType: TypeAlias = _IniTypeTag | _IniLiteral | tuple[_IniTypeTag | _IniLiteral, ...]\n\n#: Maps each string tag or plain Python type accepted by :meth:`Parser.addini`\n#: for its ``type`` argument to the normalized string tag.\n_INI_TYPES: dict[object, _IniTypeTag] = {tag: tag for tag in get_args(_IniTypeTag)} | {\n    str: \"string\",\n    bool: \"bool\",\n    int: \"int\",\n    float: \"float\",\n}\n\n\ndef _ini_type_to_tag(name: str, type_: object) -> _IniTypeTag:\n    \"\"\"Normalize one member of an `addini(type=...)` argument to a string tag.\"\"\"\n    try:\n        return _INI_TYPES[type_]\n    except (KeyError, TypeError):  # TypeError: unhashable type_\n        raise ValueError(\n            f\"invalid type for ini option {name!r}: {type_!r} (expected one of \"\n            f\"{', '.join(repr(tag) for tag in get_args(_IniTypeTag))}, one of \"\n            \"the types str, bool, int, float, a union of these types such as \"\n            \"`int | str`, or a `Literal` of strings)\"\n        ) from None\n\n\ndef _ini_type_to_member(name: str, type_: object) -> _IniTypeTag | _IniLiteral:\n    \"\"\"Normalize one member of an `addini(type=...)` argument.\"\"\"\n    if get_origin(type_) is Literal:\n        choices = get_args(type_)\n        if not all(isinstance(choice, str) for choice in choices):\n            raise ValueError(\n                f\"invalid type for ini option {name!r}: Literal choices \"\n                f\"must be strings, got {choices!r}\"\n            )\n        return _IniLiteral(choices)\n    return _ini_type_to_tag(name, type_)","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/pytest-dev/pytest/blob/98b357f69e380da908740a212288d73b2ee06687/src/_pytest/config/argparsing.py#L56-L92","documentation":"Raised by Parser.addini() when the type= argument is not one of the accepted forms: a string tag ('string','paths','pathlist','args','linelist','bool','int','float'), one of the Python types str/bool/int/float, a union of these (e.g. int | str), or a typing.Literal of strings. Any other value triggers this ValueError at plugin registration time.","triggerScenarios":"Calling parser.addini('myopt', type='datetime'), type=list, type=dict, type=float-or-str (a custom type), or passing a class that isn't str/bool/int/float. The _ini_type_to_tag lookup in _INI_TYPES fails with KeyError or TypeError (unhashable).","commonSituations":"Plugin authors passing an unsupported type to addini; migrating a plugin from an older pytest that tolerated looser types; attempting to use a custom callable as the type (which argparse allows but pytest's ini system does not).","solutions":["Use one of the supported string tags: 'string', 'paths', 'pathlist', 'args', 'linelist', 'bool', 'int', 'float'.","For multiple accepted types use a union like `int | str` or `str | bool`.","For enumerated string values use Literal['a','b','c'].","For complex parsing, use type='string' and post-process the value in a pytest_load_initial_conftests hook or config.getvalue()."],"exampleFix":"# before\ndef pytest_addoption(parser):\n    parser.addini('myopt', type=list, help='...')\n\n# after\ndef pytest_addoption(parser):\n    parser.addini('myopt', type='linelist', help='...')","handlingStrategy":"type-guard","validationCode":"from typing import get_args, Literal\n_VALID_TAGS = set(get_args(Literal['string','paths','pathlist','args','linelist','bool','int','float']))\n_VALID_TYPES = {str, bool, int, float}\ndef validate_ini_type(type_: object) -> None:\n    if type_ is None or type_ in _VALID_TAGS or type_ in _VALID_TYPES:\n        return\n    raise ValueError(f'unsupported ini type {type_!r}; use one of {_VALID_TAGS} or { _VALID_TYPES}')","typeGuard":"from typing import get_args, Literal, get_origin, Union, types\n_VALID_TAGS = set(get_args(Literal['string','paths','pathlist','args','linelist','bool','int','float']))\n_VALID_PY = {str, bool, int, float}\ndef is_valid_ini_type(type_: object) -> bool:\n    if type_ is None or type_ in _VALID_TAGS or type_ in _VALID_PY:\n        return True\n    if get_origin(type_) in (Union, types.UnionType):\n        return all(is_valid_ini_type(m) for m in type_.__args__)\n    if get_origin(type_) is Literal:\n        return all(isinstance(c, str) for c in type_.__args__)\n    return False","tryCatchPattern":null,"preventionTips":["Restrict addini type= to documented tags and str/bool/int/float.","Write a smoke test that loads your plugin to catch registration-time errors.","Use Literal['a','b'] for enumerated string options."],"tags":["pytest","plugin","config","addini","type-check","api-misuse"],"analyzedSha":"98b357f69e380da908740a212288d73b2ee06687","analyzedAt":"2026-08-04T20:26:34.442Z","schemaVersion":2}