pytest-dev / pytest-dev/pytest-xdist

Allow other plugins to completely disable pytest-xdist output

Open
#928 6 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
1.9k
Forks
287
Avg merge
9h 30m
Merged PRs (30d)
2

Description

When creating the DSession object, pytest-xdist checks to see if the terminalreporter plugin is registered with pytest, and if so, creates a TerminalDistReporter object and registers it as a pytest plugin named terminaldistreporter.

pytest-tap tries to disable all terminal output (since it interferes with the tap output). This works by removing the terminalreporter plugin. If you have xdist and pytest_tap both installed as site packages, this approach works fine — but only because the pytest_tap configure hook happens to run first.

If you try to do the same thing from your own conftest.py, though, you fall over fast. It's difficult to arrange for your configure hook to be called after terminalreporter has been created but before xdist checks for it. No worries — our conftest.py can run last and also remove the terminaldistreporter plugin. Great!

Unfortunately, this doesn't work. In addition to registering the plugin, the DSession takes a reference on it:

self.terminal = config.pluginmanager.getplugin("terminalreporter")
if self.terminal:
    self.trdist = TerminalDistReporter(config)
    config.pluginmanager.register(self.trdist, "terminaldistreporter")

and uses this trdist later, from worker_collectionfinish:

if self.terminal:
    self.trdist.setstatus(
        node.gateway.spec, WorkerStatus.CollectionDone, tests_collected=len(ids)
    )

and

if self.terminal and not self.sched.has_pending:
    self.trdist.ensure_show_status()
    self.terminal.write_line("")

It would be nice if there was a better way to silence pytest-xdist entirely. The "big hammer", of course, is to redirect sys.stdout entirely, but I'd prefer to avoid that if possible.

So some alternatives:

  • provide a simple mechanism to disable all output without playing around with unregistering plugins
  • defer creation of the TerminalDistReporter until after the config step is done, making it more sensitive to changes in the terminalwriter plugin
  • turn the .setstatus() and .ensure_show_status() APIs into hooks and call them that way. If the plugin gets unloaded then they won't be called — not harm done. That would also allow dropping the extra self.terminal check (although there are some direct uses of those, as well, that would need to be fixed up).
  • provide some official API on pytest-xdist to disable output. For now, I'm getting the dsession plugin and manually setting terminal to None, but this doesn't really feel great...

If any of these approaches are acceptable, I'm happy to write a patch.

Thanks!

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing DSession's terminal and trdist references, including TerminalDistReporter registration and the worker_collectionfinish paths shown in the issue. Compare the proposed disabling mechanisms and existing plugin behavior; done means pytest-xdist output can be disabled through a supported mechanism without unregistering plugins or breaking distributed test reporting.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
testing-qa
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.