Skip to content

AttributeError with import-mode importlib and doctest modules #12194

Closed
@jaraco

Description

@jaraco

Likely related to #12112, discovered in jaraco/keyring#676, a new regression appears in pytest 8.1 relating to collection. Consider this minimal example:

 draft @ cat > test_something.py
import foo
from foo.bar import baz
foo.bar.baz
 draft @ mkdir -p foo/bar/baz
 draft @ touch foo/__init__.py
 draft @ touch foo/bar/__init__.py
 draft @ touch foo/bar/baz/__init__.py
 draft @ pip-run pytest -- -m pytest --import-mode importlib --doctest-modules
============================================================== test session starts ===============================================================
platform darwin -- Python 3.12.2, pytest-8.1.1, pluggy-1.4.0
rootdir: /Users/jaraco/draft
collected 0 items / 1 error                                                                                                                      

===================================================================== ERRORS =====================================================================
_______________________________________________________ ERROR collecting test_something.py _______________________________________________________
test_something.py:3: in <module>
    foo.bar.baz
E   AttributeError: module 'foo' has no attribute 'bar'
============================================================ short test summary info =============================================================
ERROR test_something.py - AttributeError: module 'foo' has no attribute 'bar'
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
================================================================ 1 error in 0.03s ================================================================

It seems that once the foo/bar/__init__.py has been collected for doctesting, the collection of the tests in test_something will start to fail when foo has no attribute bar. Any of the following tweaks will bypass the failure:

  • disable doctests
  • pin to pytest<8.1
  • use a different import-mode

Something about the pytest discovery and import machinery is breaking the Python convention that importing a submodule causes the submodule to be added as an attribute of the parent module.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions