{"id":"5ebbfd321fedd03c","repo":"pytest-dev/pytest","slug":"module-name-r-has-no-attribute-name-r","errorCode":null,"errorMessage":"module {__name__!r} has no attribute {name!r}","messagePattern":"module (.+?) has no attribute (.+?)","errorType":"exception","errorClass":"AttributeError","httpStatus":null,"severity":"error","filePath":"src/_pytest/python.py","lineNumber":1842,"sourceCode":"            style = \"long\"\n        return self._repr_failure_py(excinfo, style=style)\n\n\nclass FunctionDefinition(Function):\n    \"\"\"This class is a stop gap solution until we evolve to have actual function\n    definition nodes and manage to get rid of ``metafunc``.\"\"\"\n\n    def runtest(self) -> None:\n        raise RuntimeError(\"function definitions are not supposed to be run as tests\")\n\n    setup = runtest\n\n\ndef __getattr__(name: str) -> object:\n    if name == \"CallSpec2\":\n        warnings.warn(CALLSPEC2_RENAMED, stacklevel=2)\n        return CallSpec\n    raise AttributeError(f\"module {__name__!r} has no attribute {name!r}\")\n","sourceCodeStart":1824,"sourceCodeEnd":1843,"githubUrl":"https://github.com/pytest-dev/pytest/blob/98b357f69e380da908740a212288d73b2ee06687/src/_pytest/python.py#L1824-L1843","documentation":"Raised by the module-level __getattr__ in _pytest.python when code accesses an attribute that does not exist on the module. It is the standard AttributeError produced for any unknown name on the _pytest.python module. Historically this also handles the deprecated CallSpec2 alias (emitting a warning then returning CallSpec); all other names raise this error.","triggerScenarios":"Doing `from _pytest.python import SomeName` or `_pytest.python.SomeName` where SomeName is not defined in the module (and is not the deprecated CallSpec2).","commonSituations":"Importing a private/internal name that was renamed or removed across pytest versions; typo in an import; depending on _pytest internals that are not part of the public API.","solutions":["Check the installed pytest version's _pytest/python.py for the actual exported names.","Use the public pytest.* API instead of _pytest.python internals where possible.","If importing CallSpec2, migrate to CallSpec (the alias emits a deprecation warning).","Correct the typo in the import statement."],"exampleFix":"// before\nfrom _pytest.python import CallSpec2  # deprecated/removed in future\n// after\nfrom _pytest.python import CallSpec","handlingStrategy":"validation","validationCode":"import _pytest.python as pm\nname = \"CallSpec2\"\nif not hasattr(pm, name) and name != \"CallSpec2\":\n    raise AttributeError(f\"_pytest.python has no attribute {name!r}\")\n# for CallSpec2, prefer CallSpec directly\nfrom _pytest.python import CallSpec","typeGuard":"import _pytest.python as pm\n\ndef module_has(name: str) -> bool:\n    return hasattr(pm, name)","tryCatchPattern":"try:\n    from _pytest.python import CallSpec2  # deprecated\nexcept (ImportError, AttributeError):\n    from _pytest.python import CallSpec as CallSpec2","preventionTips":["Prefer the public pytest.* API over _pytest internals.","Migrate off CallSpec2 to CallSpec.","Verify internal names exist after upgrading pytest."],"tags":["internal","import","attribute-access"],"analyzedSha":"98b357f69e380da908740a212288d73b2ee06687","analyzedAt":"2026-08-04T20:26:34.442Z","schemaVersion":2}