Coverage 7.10 has some significant new features that have solved some long-standing problems.
Years ago I greeted a friend returning from vacation and asked how it had been. She answered, “It was good, I got a lot done!” I understand that feeling. I just had a long vacation myself, and used the time to clean up some old issues and add some new features in coverage.py v7.10.
The major new feature is a configuration option,
[run] patch
. With it, you specify named
patches that coverage can use to monkey-patch some behavior that gets in the way
of coverage measurement.
The first is subprocess
. Coverage works great when you start your
program with coverage measurement, but has long had the problem of how to also
measure the coverage of sub-processes that your program created. The existing
solution had been a complicated two-step process of creating obscure .pth files
and setting environment variables. Whole projects appeared on PyPI to handle
this for you.
Now, patch = subprocess
will do this for you automatically, and clean
itself up when the program ends. It handles sub-processes created by the
subprocess module, the
os.system() function, and any of the
execv or spawnv families of
functions.
This alone has spurred one user to exclaim,
The latest release of Coverage feels like a Christmas present! The native support for Python subprocesses is so good!
Another patch is _exit
. This patches
os._exit() so that coverage saves its data before
exiting. The os._exit() function is an immediate and abrupt termination of the
program, skipping all kinds of registered clean up code. This patch makes it
possible to collect coverage data from programs that end this way.
The third patch is execv
. The execv functions
end the current program and replace it with a new program in the same process.
The execv
patch arranges for coverage to save its data before the
current program is ended.
Now that these patches are available, it seems silly that it’s taken so long. They (mostly) weren’t difficult. I guess it took looking at the old issues, realizing the friction they caused, and thinking up a new way to let users control the patching. Monkey-patching is a bit invasive, so I’ve never wanted to do it implicitly. The patch option gives the user an explicit way to request what they need without having to get into the dirty details themselves.
Another process-oriented feature was contributed by Arkady Gilinsky: with
--save-signal=USR1
you can specify a user signal that coverage will
attend to. When you send the signal to your running coverage process, it will
save the collected data to disk. This gives a way to measure coverage in a
long-running process without having to end the process.
There were some other fixes and features along the way, like better HTML
coloring of multi-line statements, and more default exclusions
(if TYPE_CHECKING:
and ...
).
It feels good to finally address some of these pain points. I also closed some stale issues and pull requests. There is more to do, always more to do, but this feels like a real step forward. Give coverage 7.10.0 a try and let me know how it works for you.
Comments
This is a great set of changes! Nice work, Ned.
Add a comment: