pytest-dev/pytest · error · UsageError
Plugins may be specified as a sequence or a ','-separated…
Error message
Plugins may be specified as a sequence or a ','-separated string of plugin names. Got: {specs!r} What it means
Raised by _get_plugin_specs_as_list() (src/_pytest/config/__init__.py:953) when the pytest_plugins variable in a conftest.py is not None, not a str, not a Sequence, and not a module (config/__init__.py:942-952 cover those cases). The final raise at capture.py:953-955 surfaces the bad value via UsageError so the user sees a clear message rather than a confusing AttributeError later.
Solutions
- Make pytest_plugins a string or a tuple/list of strings: `pytest_plugins = ('a', 'b')`
- If you must compute it dynamically, ensure the expression yields str or Sequence[str]
- Use None or omit the variable to disable plugin specs entirely
Example fix
// before
# conftest.py
pytest_plugins = {'foo': 'plugin_foo'}
// after
pytest_plugins = ('plugin_foo',) Defensive patterns
Strategy: type-guard
Validate before calling
import collections.abc, types
ok = specs is None or isinstance(specs, (str, collections.abc.Sequence, types.ModuleType))
if not ok:
raise TypeError('pytest_plugins must be None/str/Sequence/module') Type guard
import collections.abc, types
def valid_plugin_specs(s) -> bool:
return s is None or isinstance(s, (str, collections.abc.Sequence, types.ModuleType)) Prevention
- Use a tuple literal for pytest_plugins in conftest.py
- Avoid dict/set/dict-values - only str, tuple, list, or None
- Lint conftest.py for unusual pytest_plugins assignments
When it happens
Trigger: Setting `pytest_plugins = 42` or `pytest_plugins = {'name': 'plugin'}` (a dict) in a conftest.py. None, str, list, tuple, and module types are accepted; anything else falls through to config/__init__.py:953.
Common situations: Typos in conftest.py; copying a dict-style config from another tool; assigning the result of a function call that returns a non-sequence; using a set literal `{...}` instead of a tuple `(...)`.
Related errors
- Blocking conftest files using -p is not supported: -p no
- Missing required plugins
- plugin cannot be disabled
- : (from )
- Error importing plugin
AI-assisted analysis of pytest-dev/pytest@0d6fbdeffa (2026-08-11).
Data as JSON: /api/errors/31d2059140956d23.
Report an issue: GitHub.
Appendix: source
Thrown at src/_pytest/config/__init__.py:953
def _get_plugin_specs_as_list(
specs: types.ModuleType | str | Sequence[str] | None,
) -> list[str]:
"""Parse a plugins specification into a list of plugin names."""
# None means empty.
if specs is None:
return []
# Workaround for #3899 - a submodule which happens to be called "pytest_plugins".
if isinstance(specs, types.ModuleType):
return []
# Comma-separated list.
if isinstance(specs, str):
return specs.split(",") if specs else []
# Direct specification.
if isinstance(specs, collections.abc.Sequence):
return list(specs)
raise UsageError(
f"Plugins may be specified as a sequence or a ','-separated string of plugin names. Got: {specs!r}"
)
def _iter_rewritable_modules(package_files: Iterable[str]) -> Iterator[str]:
"""Given an iterable of file names in a source distribution, return the "names" that should
be marked for assertion rewrite.
For example the package "pytest_mock/__init__.py" should be added as "pytest_mock" in
the assertion rewrite mechanism.
This function has to deal with dist-info based distributions and egg based distributions
(which are still very much in use for "editable" installs).
Here are the file names as seen in a dist-info based distribution:
pytest_mock/__init__.py
pytest_mock/_version.pyView on GitHub (pinned to 0d6fbdeffa)