`Erase` fails with local plugins due to incorrect path
Describe the bug
When executing run, PyRunner monkey-patches the path so that the directory of the file being run is the first entry in the path instead of the directory of the coverage script. This change allows for plugins to be imported from the local directory structure. When executing erase this monkey-patching doesn't happen and any local plugins fail to load and erase exits due to a ModuleNotFoundError when trying to import the plugin module.
To Reproduce
Python/Coverage versions 3.8/6.3.2 & 3.10/7.4.0.
Empty virtual environment (I happen to be using Pipenv, but see nothing specific to Pipenv related to this issue) with only coverage installed.
-
mkdir sandbox && cd sandbox -
pipenv install coverage - Create a Coverage Plugin in the local directory structure:
# ./plugins/ExamplePlugin.py import coverage class ExamplePlugin(coverage.CoveragePlugin): def configure(self, config): print('Do Nothing') def coverage_init(reg, options): reg.add_configurer(ExamplePlugin()) - Create a file to run:
# ./app.py print('The App') - Create coverage config file:
# ./setup.cfg [coverage:run] omit = plugins/* source = . plugins = plugins.ExamplePlugin -
pipenv run coverage run app.py -
pipenv run coverage erase
Results in:
Traceback (most recent call last):
File "/home/kdickerson/.local/share/virtualenvs/sandbox-ErqkbyCg/bin/coverage", line 8, in <module>
sys.exit(main())
File "/home/kdickerson/.local/share/virtualenvs/sandbox-ErqkbyCg/lib/python3.10/site-packages/coverage/cmdline.py", line 970, in main
status = CoverageScript().command_line(argv)
File "/home/kdickerson/.local/share/virtualenvs/sandbox-ErqkbyCg/lib/python3.10/site-packages/coverage/cmdline.py", line 677, in command_line
self.coverage.erase()
File "/home/kdickerson/.local/share/virtualenvs/sandbox-ErqkbyCg/lib/python3.10/site-packages/coverage/control.py", line 701, in erase
self._init()
File "/home/kdickerson/.local/share/virtualenvs/sandbox-ErqkbyCg/lib/python3.10/site-packages/coverage/control.py", line 341, in _init
self._plugins = Plugins.load_plugins(self.config.plugins, self.config, self._debug)
File "/home/kdickerson/.local/share/virtualenvs/sandbox-ErqkbyCg/lib/python3.10/site-packages/coverage/plugin_support.py", line 55, in load_plugins
__import__(module)
ModuleNotFoundError: No module named 'plugins'
Expected behavior
erase should run as expected and remove the data file(s).
Additional context
It works if you perform the same monkey-patching before erase runs by changing CoverageScript.command_line in cmdline.py:L676-678 from:
elif options.action == "erase":
self.coverage.erase()
return OK
to
elif options.action == "erase":
runner = PyRunner(['dummy.txt'], as_module=bool(options.module))
runner.prepare()
self.coverage.erase()
return OK
But I'm highly doubtful that's the right solution.