pytest-dev/pytest · error · RuntimeError

function definitions are not supposed to be run as tests

Error message

function definitions are not supposed to be run as tests

What it means

Raised by FunctionDefinition.runtest (and its alias setup) when pytest attempts to execute a FunctionDefinition node as a test. FunctionDefinition is a placeholder node representing a function *definition* collected for introspection (e.g. a non-test function or a fixture-bearing function) that must never be run. Seeing this means the collection tree is misconfigured such that a definition node reached the runtest phase.

Source

Thrown at src/_pytest/python.py:1833

        return excinfo.traceback

    # TODO: Type ignored -- breaks Liskov Substitution.
    def repr_failure(  # type: ignore[override]
        self,
        excinfo: ExceptionInfo[BaseException],
    ) -> str | TerminalRepr:
        style = self.config.getoption("tbstyle", "auto")
        if style == "auto":
            style = "long"
        return self._repr_failure_py(excinfo, style=style)


class FunctionDefinition(Function):
    """This class is a stop gap solution until we evolve to have actual function
    definition nodes and manage to get rid of ``metafunc``."""

    def runtest(self) -> None:
        raise RuntimeError("function definitions are not supposed to be run as tests")

    setup = runtest


def __getattr__(name: str) -> object:
    if name == "CallSpec2":
        warnings.warn(CALLSPEC2_RENAMED, stacklevel=2)
        return CallSpec
    raise AttributeError(f"module {__name__!r} has no attribute {name!r}")

View on GitHub (pinned to 98b357f69e)

Solutions

  1. Do not call runtest() on FunctionDefinition nodes; only runtest concrete Function test items.
  2. Check item.__class__ is Function (not FunctionDefinition) before invoking runtest in plugin code.
  3. Update the custom collection plugin to produce proper test Function nodes.
  4. Report a bug to the plugin if it forces execution of definition nodes.

Example fix

// before
for item in session.items:
    item.runtest()  # may include FunctionDefinition
// after
from _pytest.python import Function
for item in session.items:
    if isinstance(item, Function):
        item.runtest()
Defensive patterns

Strategy: type-guard

Validate before calling

from _pytest.python import Function, FunctionDefinition

def is_runnable(item) -> bool:
    return isinstance(item, Function) and not isinstance(item, FunctionDefinition)

for item in items:
    if is_runnable(item):
        item.runtest()

Type guard

from _pytest.python import Function, FunctionDefinition

def is_test_function(item) -> bool:
    return isinstance(item, Function) and not isinstance(item, FunctionDefinition)

Prevention

When it happens

Trigger: A plugin or hook that forces runtest on a FunctionDefinition; manually invoking item.runtest() on a FunctionDefinition item; an internal collection inconsistency where a def-only node is treated as a test item.

Common situations: Custom collection plugins that subclass Function incorrectly; calling pytest internals directly in a test; a stale plugin incompatible with the current pytest version where FunctionDefinition semantics changed.

Related errors


AI-assisted analysis of pytest-dev/pytest@98b357f69e (2026-08-04). Data as JSON: /data/errors/122c9a5fe1b0fe1d.json. Report an issue: GitHub.