pytest-dev/pytest · error · ValueError
invalid type for ini option {name!r}: {type_!r} (expected on
Error message
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) What it means
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.
Source
Thrown at src/_pytest/config/argparsing.py:74
#: ``int | str``).
IniType: TypeAlias = _IniTypeTag | _IniLiteral | tuple[_IniTypeTag | _IniLiteral, ...]
#: Maps each string tag or plain Python type accepted by :meth:`Parser.addini`
#: for its ``type`` argument to the normalized string tag.
_INI_TYPES: dict[object, _IniTypeTag] = {tag: tag for tag in get_args(_IniTypeTag)} | {
str: "string",
bool: "bool",
int: "int",
float: "float",
}
def _ini_type_to_tag(name: str, type_: object) -> _IniTypeTag:
"""Normalize one member of an `addini(type=...)` argument to a string tag."""
try:
return _INI_TYPES[type_]
except (KeyError, TypeError): # TypeError: unhashable type_
raise ValueError(
f"invalid type for ini option {name!r}: {type_!r} (expected one of "
f"{', '.join(repr(tag) for tag in get_args(_IniTypeTag))}, one of "
"the types str, bool, int, float, a union of these types such as "
"`int | str`, or a `Literal` of strings)"
) from None
def _ini_type_to_member(name: str, type_: object) -> _IniTypeTag | _IniLiteral:
"""Normalize one member of an `addini(type=...)` argument."""
if get_origin(type_) is Literal:
choices = get_args(type_)
if not all(isinstance(choice, str) for choice in choices):
raise ValueError(
f"invalid type for ini option {name!r}: Literal choices "
f"must be strings, got {choices!r}"
)
return _IniLiteral(choices)
return _ini_type_to_tag(name, type_)View on GitHub (pinned to 98b357f69e)
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().
Example fix
# before
def pytest_addoption(parser):
parser.addini('myopt', type=list, help='...')
# after
def pytest_addoption(parser):
parser.addini('myopt', type='linelist', help='...') Defensive patterns
Strategy: type-guard
Validate before calling
from typing import get_args, Literal
_VALID_TAGS = set(get_args(Literal['string','paths','pathlist','args','linelist','bool','int','float']))
_VALID_TYPES = {str, bool, int, float}
def validate_ini_type(type_: object) -> None:
if type_ is None or type_ in _VALID_TAGS or type_ in _VALID_TYPES:
return
raise ValueError(f'unsupported ini type {type_!r}; use one of {_VALID_TAGS} or { _VALID_TYPES}') Type guard
from typing import get_args, Literal, get_origin, Union, types
_VALID_TAGS = set(get_args(Literal['string','paths','pathlist','args','linelist','bool','int','float']))
_VALID_PY = {str, bool, int, float}
def is_valid_ini_type(type_: object) -> bool:
if type_ is None or type_ in _VALID_TAGS or type_ in _VALID_PY:
return True
if get_origin(type_) in (Union, types.UnionType):
return all(is_valid_ini_type(m) for m in type_.__args__)
if get_origin(type_) is Literal:
return all(isinstance(c, str) for c in type_.__args__)
return False Prevention
- 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.
When it happens
Trigger: 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).
Common situations: 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).
Related errors
- invalid type for ini option {name!r}: Literal choices must b
- ini option {name!r} has a {kind} type, which has no implicit
- alias {alias!r} conflicts with existing configuration option
- {alias!r} is already an alias of {already!r}
- help argument cannot be None for {name}
AI-assisted analysis of pytest-dev/pytest@98b357f69e (2026-08-04).
Data as JSON: /data/errors/cf8335de787324a3.json.
Report an issue: GitHub.