coveragepy icon indicating copy to clipboard operation
coveragepy copied to clipboard

`Erase` fails with local plugins due to incorrect path

Open kdickerson opened this issue 2 years ago • 0 comments

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.

  1. mkdir sandbox && cd sandbox
  2. pipenv install coverage
  3. 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())
    
  4. Create a file to run:
    # ./app.py
    
    print('The App')
    
  5. Create coverage config file:
    # ./setup.cfg
    
    [coverage:run]
    omit = plugins/*
    source = .
    plugins = plugins.ExamplePlugin
    
  6. pipenv run coverage run app.py
  7. 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.

kdickerson avatar Jan 02 '24 22:01 kdickerson