Skip to content

Implicit namespace submodules not discovered #1024

Closed
@adamchainz

Description

@adamchainz

Describe the bug

If an implicit namespace package (directory without __init__.py) exists within a source module and is not imported, coverage won't discover it or report it as uncovered.

I discovered this on Django project where an app had an idiomatic management.commands submodule without intermediate __init__.py files. This had two levels of implicit namespace packages, but it also happens with just one (what would be just management).

To Reproduce

Worked example:

$ coverage --version
Coverage.py, version 5.2.1 with C extension
Full documentation is at https://coverage.readthedocs.io
$ python --version
Python 3.8.3
$ tree example
example
├── management
│   └── submodule2.py
└── submodule.py

1 directory, 2 files
$ cat example/submodule.py
x = 1
$ cat example/management/submodule2.py
y = 2
$ cat test.py
import example.submodule
$ coverage erase && coverage run --source example -m test && coverage report
Name                   Stmts   Miss  Cover
------------------------------------------
example/submodule.py       1      0   100%

Expected behavior

I'd expect example/management/submodule2.py to be discovered as uncovered. Adding an __init__.py to management makes coverage discover it:

$ touch example/management/__init__.py
$ coverage erase && coverage run --source example -m test && coverage report
Name                               Stmts   Miss  Cover
------------------------------------------------------
example/management/__init__.py         0      0   100%
example/management/submodule2.py       1      1     0%
example/submodule.py                   1      0   100%
------------------------------------------------------
TOTAL                                  2      1    50%

Additional context

Implicit namespace packages "just work" with Python 3, and many new developers create them on purpose or accidentally.

Django itself has moved to, and then back from, implicit namespace packages for management commands: https://groups.google.com/g/django-developers/c/GVHMH2ciAnk/m/7RzvMIzyAQAJ . So there are at least some users who believe "__init__.py files are no longer needed".

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingduplicateThis issue or pull request already existsfixed

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions