{"id":"e6162192eb1b3b71","repo":"pytest-dev/pytest","slug":"specifying-plugins-as-objects-is-not-supported-in","errorCode":null,"errorMessage":"Specifying plugins as objects is not supported in pytester subprocess mode; specify by name instead: {plugin}","messagePattern":"Specifying plugins as objects is not supported in pytester subprocess mode; specify by name instead: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/_pytest/pytester.py","lineNumber":1515,"sourceCode":"        ``-p`` command line option.  Additionally ``--basetemp`` is used to put\n        any temporary files and directories in a numbered directory prefixed\n        with \"runpytest-\" to not conflict with the normal numbered pytest\n        location for temporary files and directories.\n\n        :param args:\n            The sequence of arguments to pass to the pytest subprocess.\n        :param timeout:\n            The period in seconds after which to timeout and raise\n            :py:class:`Pytester.TimeoutExpired`.\n        :returns:\n            The result.\n        \"\"\"\n        __tracebackhide__ = True\n        p = make_numbered_dir(root=self.path, prefix=\"runpytest-\", mode=0o700)\n        args = (f\"--basetemp={p}\", *args)\n        for plugin in self.plugins:\n            if not isinstance(plugin, str):\n                raise ValueError(\n                    f\"Specifying plugins as objects is not supported in pytester subprocess mode; \"\n                    f\"specify by name instead: {plugin}\"\n                )\n            args = (\"-p\", plugin, *args)\n        args = self._getpytestargs() + args\n        return self.run(*args, timeout=timeout)\n\n    def spawn_pytest(self, string: str, expect_timeout: float = 10.0) -> pexpect.spawn:\n        \"\"\"Run pytest using pexpect.\n\n        This makes sure to use the right pytest and sets up the temporary\n        directory locations.\n\n        The pexpect child is returned.\n        \"\"\"\n        basetemp = self.path / \"temp-pexpect\"\n        basetemp.mkdir(mode=0o700)\n        invoke = \" \".join(map(str, self._getpytestargs()))","sourceCodeStart":1497,"sourceCodeEnd":1533,"githubUrl":"https://github.com/pytest-dev/pytest/blob/98b357f69e380da908740a212288d73b2ee06687/src/_pytest/pytester.py#L1497-L1533","documentation":"Raised by Pytester.runpytest_subprocess when any entry in self.plugins is not a string. Subprocess mode launches a fresh Python interpreter and can only activate plugins by importable name (passed as '-p name'); it cannot serialize live plugin objects across the process boundary. Object plugins are only supported by the inprocess runner.","triggerScenarios":"Passing a plugin class or module instance to the pytester fixture (pytester_factory plugins=[MyPlugin()]) and then calling runpytest_subprocess or runpytest with method='subprocess'.","commonSituations":"Writing a pytester test that needs a fixture-providing plugin object and switching the run to subprocess mode (e.g. to test import-time behavior); forgetting that the default method can be flipped globally via --runpytest=subprocess.","solutions":["Register the plugin by its entry-point/module name string instead of the object when using subprocess mode.","Use runpytest_inprocess() for the runs that need object plugins.","Make the plugin installable/importable and pass its module name (e.g. 'mypkg.plugin')."],"exampleFix":"// before\npytester.makepyfile(\"def test(x): assert x==1\")\npytester.runpytest_subprocess(MyPlugin())  # object not allowed\n// after\n# register plugin by name and use inprocess for object plugins\npytester.runpytest_inprocess(MyPlugin())\n# or install plugin and pass name for subprocess\npytester.runpytest_subprocess(\"-p\", \"myplugin\")","handlingStrategy":"validation","validationCode":"def plugins_for_mode(plugins, method: str):\n    if method == \"subprocess\":\n        bad = [p for p in plugins if not isinstance(p, str)]\n        if bad:\n            raise ValueError(f\"these plugins must be passed by name in subprocess mode: {bad}\")\n    return plugins","typeGuard":"def all_str(plugins) -> bool:\n    return all(isinstance(p, str) for p in plugins)","tryCatchPattern":"try:\n    pytester.runpytest_subprocess(*plugins)\nexcept ValueError:\n    # fall back to inprocess for object plugins\n    pytester.runpytest_inprocess(*plugins)","preventionTips":["Pass plugins by importable name string for subprocess runs.","Reserve object plugins for runpytest_inprocess.","Make custom plugins installable so they have a name."],"tags":["pytester","subprocess","plugins"],"analyzedSha":"98b357f69e380da908740a212288d73b2ee06687","analyzedAt":"2026-08-04T20:26:34.442Z","schemaVersion":2}