Skip to content

Commit

Permalink
fix: don't warn about already imported files for namespace packages #888
Browse files Browse the repository at this point in the history


Ignore namespace packages in the already-imported check. #888
  • Loading branch information
nedbat committed Oct 31, 2021
1 parent 7589066 commit 1a6844a
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 4 deletions.
10 changes: 8 additions & 2 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,16 @@ This list is detailed and covers changes in each pre-release version.
Unreleased
----------

- Fix: the sticky header on the HTML report didn't work unless you had branch
coverage enabled. This is now fixed, the sticky header works for everyone.
- Fix: The sticky header on the HTML report didn't work unless you had branch
coverage enabled. This is now fixed: the sticky header works for everyone.
(Do people still use coverage without branch measurement!? j/k)

- Fix: When using explicitly declared namespace packages, the "already imported
a file that will be measured" warning would be issued (`issue 888`_). This
is now fixed.

.. _issue 888: https://github.com/nedbat/coveragepy/issues/888


.. _changes_61:

Expand Down
4 changes: 4 additions & 0 deletions coverage/inorout.py
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,10 @@ def warn_already_imported_files(self):
if filename in warned:
continue

if len(getattr(mod, "__path__", ())) > 1:
# A namespace package, which confuses this code, so ignore it.
continue

disp = self.should_trace(filename)
if disp.has_dynamic_filename:
# A plugin with dynamic filenames: the Python file
Expand Down
6 changes: 6 additions & 0 deletions lab/treetopy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Turn a tree of Python files into a series of make_file calls.
for f in **/*.py; do
echo 'make_file("'$1$f'", """\\'
sed -e 's/^/ /' <$f
echo ' """)'
done
54 changes: 52 additions & 2 deletions tests/test_venv.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ def fifth(x):
def sixth(x):
return 6 * x
""")
# The setup.py to install everything.
make_file("another_pkg/setup.py", """\
import setuptools
setuptools.setup(
Expand All @@ -93,9 +92,52 @@ def sixth(x):
)
""")

# Bug888 code.
make_file("bug888/app/setup.py", """\
from setuptools import setup
setup(
name='testcov',
packages=['testcov'],
namespace_packages=['testcov'],
)
""")
make_file("bug888/app/testcov/__init__.py", """\
try: # pragma: no cover
__import__('pkg_resources').declare_namespace(__name__)
except ImportError: # pragma: no cover
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)
""")
make_file("bug888/app/testcov/main.py", """\
import pkg_resources
for entry_point in pkg_resources.iter_entry_points('plugins'):
entry_point.load()()
""")
make_file("bug888/plugin/setup.py", """\
from setuptools import setup
setup(
name='testcov-plugin',
packages=['testcov'],
namespace_packages=['testcov'],
entry_points={'plugins': ['testp = testcov.plugin:testp']},
)
""")
make_file("bug888/plugin/testcov/__init__.py", """\
try: # pragma: no cover
__import__('pkg_resources').declare_namespace(__name__)
except ImportError: # pragma: no cover
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)
""")
make_file("bug888/plugin/testcov/plugin.py", """\
def testp():
print("Plugin here")
""")

# Install the third-party packages.
run_in_venv("python -m pip install --no-index ./third_pkg")
run_in_venv("python -m pip install --no-index -e ./another_pkg")
run_in_venv("python -m pip install --no-index -e ./bug888/app -e ./bug888/plugin")
shutil.rmtree("third_pkg")

# Install coverage.
Expand Down Expand Up @@ -141,7 +183,7 @@ def in_venv_world_fixture(self, venv_world):
yield

for fname in os.listdir("."):
if fname not in {"venv", "another_pkg"}:
if fname not in {"venv", "another_pkg", "bug888"}:
os.remove(fname)

def get_trace_output(self):
Expand Down Expand Up @@ -274,3 +316,11 @@ def test_installed_namespace_packages(self, coverage_command):
assert "colorsys" not in out
assert "fifth" in out
assert "sixth" in out

def test_bug888(self, coverage_command):
out = run_in_venv(
coverage_command +
" run --source=bug888/app,bug888/plugin bug888/app/testcov/main.py"
)
# When the test fails, the output includes "Already imported a file that will be measured"
assert out == "Plugin here\n"

0 comments on commit 1a6844a

Please sign in to comment.