{"id":"31d2059140956d23","repo":"pytest-dev/pytest","slug":"plugins-may-be-specified-as-a-sequence-or-a-se","errorCode":null,"errorMessage":"Plugins may be specified as a sequence or a ','-separated string of plugin names. Got: {specs!r}","messagePattern":"Plugins may be specified as a sequence or a ','-separated string of plugin names\\. Got: (.+?)","errorType":"validation","errorClass":"UsageError","httpStatus":null,"severity":"error","filePath":"src/_pytest/config/__init__.py","lineNumber":953,"sourceCode":"\n\ndef _get_plugin_specs_as_list(\n    specs: types.ModuleType | str | Sequence[str] | None,\n) -> list[str]:\n    \"\"\"Parse a plugins specification into a list of plugin names.\"\"\"\n    # None means empty.\n    if specs is None:\n        return []\n    # Workaround for #3899 - a submodule which happens to be called \"pytest_plugins\".\n    if isinstance(specs, types.ModuleType):\n        return []\n    # Comma-separated list.\n    if isinstance(specs, str):\n        return specs.split(\",\") if specs else []\n    # Direct specification.\n    if isinstance(specs, collections.abc.Sequence):\n        return list(specs)\n    raise UsageError(\n        f\"Plugins may be specified as a sequence or a ','-separated string of plugin names. Got: {specs!r}\"\n    )\n\n\ndef _iter_rewritable_modules(package_files: Iterable[str]) -> Iterator[str]:\n    \"\"\"Given an iterable of file names in a source distribution, return the \"names\" that should\n    be marked for assertion rewrite.\n\n    For example the package \"pytest_mock/__init__.py\" should be added as \"pytest_mock\" in\n    the assertion rewrite mechanism.\n\n    This function has to deal with dist-info based distributions and egg based distributions\n    (which are still very much in use for \"editable\" installs).\n\n    Here are the file names as seen in a dist-info based distribution:\n\n        pytest_mock/__init__.py\n        pytest_mock/_version.py","sourceCodeStart":935,"sourceCodeEnd":971,"githubUrl":"https://github.com/pytest-dev/pytest/blob/98b357f69e380da908740a212288d73b2ee06687/src/_pytest/config/__init__.py#L935-L971","documentation":"The _get_plugin_specs_as_list function parses plugin specifications from PYTEST_PLUGINS or pytest_plugins in conftest. It accepts None, a module object (treated as empty), a comma-separated string, or a Sequence of strings. If the value is any other type (e.g., a dict, int, or set), pytest raises UsageError. This guards against misconfigured plugin declarations.","triggerScenarios":"Setting pytest_plugins = {'a', 'b'} (a set/dict) in conftest.py, or setting PYTEST_PLUGINS to a non-string env value. The isinstance checks for None, ModuleType, str, and Sequence all fail, triggering the UsageError.","commonSituations":"Writing pytest_plugins = ('plugin1', 'plugin2') as a tuple works (Sequence), but using a set or dict does not. Also, dynamically computing pytest_plugins with a buggy expression that yields an unexpected type.","solutions":["Ensure pytest_plugins is a list, tuple, or comma-separated string of plugin names.","If using a set, convert to a list: pytest_plugins = list(my_set).","If setting PYTEST_PLUGINS in env, use a comma-separated string: PYTEST_PLUGINS='a,b'."],"exampleFix":"# before (conftest.py)\npytest_plugins = {'plugin_a', 'plugin_b'}  # set, not allowed\n\n# after (conftest.py)\npytest_plugins = ['plugin_a', 'plugin_b']","handlingStrategy":"type-guard","validationCode":"from collections.abc import Sequence\nimport types\n\ndef validate_plugin_specs(specs) -> list[str]:\n    if specs is None:\n        return []\n    if isinstance(specs, types.ModuleType):\n        return []\n    if isinstance(specs, str):\n        return specs.split(',') if specs else []\n    if isinstance(specs, Sequence):\n        return [str(s) for s in specs]\n    raise TypeError(f'Invalid plugin specs type: {type(specs).__name__}. Use a list, tuple, or comma-separated string.')","typeGuard":"from collections.abc import Sequence\nimport types\n\ndef is_valid_plugin_specs(specs) -> bool:\n    return specs is None or isinstance(specs, (types.ModuleType, str, Sequence))","tryCatchPattern":null,"preventionTips":["Always declare pytest_plugins as a list or tuple of strings in conftest.py.","When setting PYTEST_PLUGINS in env, use comma-separated string format.","Avoid dynamically constructing pytest_plugins with set/dict comprehensions."],"tags":["config","plugins","type-error","usage-error"],"analyzedSha":"98b357f69e380da908740a212288d73b2ee06687","analyzedAt":"2026-08-04T20:26:34.442Z","schemaVersion":2}