coveragepy icon indicating copy to clipboard operation
coveragepy copied to clipboard

Support reporting filenames relative to PYTHONPATH

Open allisonkarlitskaya opened this issue 3 years ago • 4 comments

Is your feature request related to a problem? Please describe.

I run coverage on pytest under tox in my project, and I'm trying to move to a src layout. That means that a simple import of my package will no longer find it in the current directory, but rather in the venv where tox installed it.

When I do that, then suddenly, I start getting really long filenames in the coverage report:

.tox/site/lib/python3.10/site-packages/systemd_ctypes/bus.py                126     11    91%   141-144, 181-185, 188-190
.tox/site/lib/python3.10/site-packages/systemd_ctypes/event.py               42      2    95%   67, 74
...

and so on.

Describe the solution you'd like

I want the first part of the path to be stripped off, leaving only the module name.

Something like

systemd_ctypes/bus.py                126     11    91%   141-144, 181-185, 188-190
systemd_ctypes/event.py               42      2    95%   67, 74
...

I don't understand why that doesn't work already. It seems that the PythonFileReporter tries to generate a name based on the module's __name__:

        if hasattr(morf, '__name__'):
            name = morf.__name__.replace(".", os.sep)
            if os.path.basename(filename).startswith('__init__.'):
                name += os.sep + "__init__"
            name += ".py"

but for some reason, this code doesn't engage for me, and I just end up with the long path name.

Describe alternatives you've considered

I thought that maybe relative_files = true would help here, but a quick read through the source seems to indicate that this is about making filenames relative to the current working directory (which is as they get reported, indeed).

Additional context

Here's some relevant pyproject.toml fragments:

...

[tool.coverage.run]
source_pkgs = ["systemd_ctypes"]
relative_files = true

[tool.coverage.report]
fail_under = 85
show_missing = true
skip_covered = true

[tool.tox]
legacy_tox_ini = """
...
commands =
  python3 -m coverage erase
  python3 -m coverage run --module pytest {posargs}
  python3 -m coverage report
...

allisonkarlitskaya avatar Jul 01 '22 11:07 allisonkarlitskaya

Hi, sorry it's taken me so long to get to this.

I'm making some improvements (described in #991, which isn't really about slash direction) that might make this easier. I have a project using src layout (scriv). It's coverage measurement includes this [paths] setting:

[coverage:paths]
source =
    src
    */site-packages

others =
    .
    */scriv

Do you use coverage combine? Have you tried configuring the [paths]? The latest version of coverage.py has a coverage combine --debug=pathmap option that can show what is being considered during combining.

nedbat avatar Oct 10 '22 19:10 nedbat

Thanks for your reply! It helped a lot.

As things are, I don't use coverage combine in my project.

In response to your suggestion, I've added the following to my pyproject.toml:

[tool.coverage.paths]
source = ["src", "*/site-packages"]   

and adjusted my coverage setup to invoke run with -p and add a separate combine step.

python3 -m coverage erase
python3 -m coverage run --parallel-mode --source systemd_ctypes --module pytest {posargs}
python3 -m coverage combine
python3 -m coverage report --skip-covered  --fail-under=85 --show-missing

The result is that the reported paths now look like the following:

src/systemd_ctypes/bus.py                398     40    90%   265, 271-273, 316, 328-333, 459, 546-547, 558-559, 584, 672, 674, 677, 681, 688, 700-702, 705-710, 713-714, 790, 803, 808-809, 833, 856-857
src/systemd_ctypes/event.py               58     10    83%   68, 90-101, 106

which I consider to be acceptable.

That's with python3-coverage-6.4.2-2.fc37.x86_64 (ie: standard coverage package from Fedora) installed, so it doesn't depend on any fancy new feature, either.

So this is at least a partial solution to my problem, and I'd be happy enough to take it for now. Some things which might make it nicer:

  • have this work without having to use the combine tool, since this isn't really what it was made for
  • mapping site-packages/* to some standard prefix might be a nice default

allisonkarlitskaya avatar Oct 12 '22 12:10 allisonkarlitskaya

In case anyone else stumbles upon this: I just discovered the existence of pytest-cov, which makes this all quite a bit nicer.

It basically allows to replace the separate commands with a single pytest --cov invocation, and the paths merging works properly with this, as well (although it still needs to be explicitly given in the coverage config).

allisonkarlitskaya avatar Oct 28 '22 08:10 allisonkarlitskaya

Just found this after reporting #1674, which is slightly more general compared to this request, namely: Support reporting filenames relative to any configured base directory, and/or support applying arbitrary transformations to paths in a final post-processing step.

jab avatar Aug 25 '23 14:08 jab