Does the requests module play a part in pytest or pytest-qt?

134 Views Asked by At

This has cropped up in the course of some tests. I've tried to reproduce the problem in an MRE to isolate the problem but without success.

I have a test like this (simplified, but this simplified version manifests the same problem):

def test_if_index_already_exists_should_be_deleted(request, qtbot):
    response = requests.delete(f'http://localhost:9200/some_index')

... adding these 2 lines and running pytest results in a series of unexpected fails and errors. I'm using pytest-random-order, so they vary. The errors are the dreaded

RuntimeError: wrapped C/C++ object of type QTextEdit has been deleted

... but if I comment out the requests.delete line nothing happens: all tests pass fine with multiple random order runs.

Whether or not the index exists shouldn't be an issue (or indeed whether Elasticsearch is running). I'm a bit baffled.

A QTextEdit is present in my GUI, and a signal is used to update it. The trace info from pytest looks like this:

   File "/media/mike/software projects/EclipseWorkspace/doc_indexer/src/core/indexing_task_class.py", line 72, in set_extra_text
    self.extra_info_text_edit.setText(msg)
RuntimeError: wrapped C/C++ object of type QTextEdit has been deleted

This shows that a signal to update this GUI element is being fired when these tests fail. In response I have removed the signal and all references to it in the app and test code. After this the tests all pass OK.

Why could calling a command requests.delete cause what seems to be a spurious signal firing (apparently during teardown)? Does pytest-qt use requests in its internals perhaps?

PS deleting the qtbot fixture above does not solve the problem.

Edit

If I put traceback.print_stack() in the slot which gets fired I get this:

...
  File "/media/apps/Python/virtual_envs/doc_indexer/lib/python3.10/site-packages/pytestqt/plugin.py", line 142, in pytest_runtest_setup
    _process_events()
  File "/media/apps/Python/virtual_envs/doc_indexer/lib/python3.10/site-packages/pytestqt/plugin.py", line 182, in _process_events
    app.processEvents()
  File "/media/mike/software projects/EclipseWorkspace/doc_indexer/src/core/indexing_task_class.py", line 71, in set_extra_text
    traceback.print_stack()
Exceptions caught in Qt event loop:
________________________________________________________________________________
Traceback (most recent call last):
  File "/media/mike/software projects/EclipseWorkspace/doc_indexer/src/core/indexing_task_class.py", line 72, in set_extra_text
    self.extra_info_text_edit.setText(msg)
RuntimeError: wrapped C/C++ object of type QTextEdit has been deleted

From the above it can be seen that the thing firing the signal is something inside pytestqt:

... /site-packages/pytestqt/plugin.py", line 182, in _process_events

That method looks like this:

def _process_events():
    """Calls app.processEvents() while taking care of capturing exceptions
    or not based on the given item's configuration.
    """
    app = qt_api.QtWidgets.QApplication.instance()
    if app is not None:
        app.processEvents()
1

There are 1 best solutions below

0
mike rodent On

I think... this sort of error is almost always caused by failing to include the pytest-qt qtbot fixture when it needs to be included.

From my experiments, this is quite an insidious error, in the sense that test suites can pass many times without any error occurring... and then suddenly one appears to occur without any real clue from any console (or logging) output about what test method is the issue.

In particular, I am using the moddule pytest-random-order, but I've also created a little script so I can do runs any number of times with a CLI switch. Typically therefore I may do the full test run 5 or so times so I can see when phenomena are occurring "intermittently". (In fact these turn out not to be intermittent: if I use the same --random-order-seed value I get the same horrible error: but using pytest-random-order obviously runs each run with a different seed, and therefore runs the test files in random order, and all the tests within them in random order).

The way I've had to identify this error is, then, by commenting out all my tests and gradually adding them back. More than once I've now found that it's a fairly new method which I added, without the qtbot fixture, which turned out to be the culprit.