pytest-dev/pytest · warning · AttributeError

module has no attribute

Error message

module {__name__!r} has no attribute {name!r}

What it means

Thrown by the module-level __getattr__ in _pytest/python.py for any attribute access not special-cased. Currently only 'CallSpec2' is special-cased (deprecated alias); everything else falls through to this generic AttributeError.

Solutions

  1. Import the name from the public pytest namespace instead of _pytest.python.
  2. Check the pytest version's source for the correct name; it may have been renamed.
  3. Avoid relying on private _pytest.* modules in external plugins.

Example fix

// before
from _pytest.python import CallSpec2  # deprecated, will warn
// after
from _pytest.python import CallSpec
Defensive patterns

Strategy: validation

Validate before calling

import importlib
mod = importlib.import_module('_pytest.python')
if not hasattr(mod, name):
    raise AttributeError(f'_pytest.python has no {name!r}; check for renames')

Type guard

def module_has_attr(module, name: str) -> bool:
    return hasattr(module, name)

Prevention

When it happens

Trigger: Doing from _pytest.python import SomeName where SomeName doesn't exist; accessing _pytest.python.CallSpec2 (deprecated warning then redirect, but other names error); typos in internal imports by plugins.

Common situations: Plugins reaching into _pytest.python internals; renamed/removed private names across pytest versions; IDE auto-import suggestions for non-existent names.

Related errors


AI-assisted analysis of pytest-dev/pytest@0d6fbdeffa (2026-08-11). Data as JSON: /api/errors/5ebbfd321fedd03c. Report an issue: GitHub.

Appendix: source

Thrown at src/_pytest/python.py:1842

            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 0d6fbdeffa)