Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Catch exceptions in other Qt threads #11

Closed
jdreaver opened this issue May 29, 2014 · 8 comments
Closed

Catch exceptions in other Qt threads #11

jdreaver opened this issue May 29, 2014 · 8 comments

Comments

@jdreaver
Copy link
Member

I recently switched to pytest-qt, and I love it so far. Before, I used my own pytest fixture to create a QApplication. I found a way to catch exceptions on all threads by overriding sys.excepthook in the fixture and checking for errors:

caught_exceptions = []


@pytest.yield_fixture
def qtbot_(request, qtbot):
    # Set excepthook to catch pyside errors in other threads.
    global caught_exceptions
    caught_exceptions = []

    def pytest_excepthook(type_, value, tback):
        global caught_exceptions
        caught_exceptions.append(''.join(traceback.format_tb(tback)) + "\n" +
                                 str(type_.__name__) + ": " + str(value))
        sys.__excepthook__(type_, value, tback)
    sys.excepthook = pytest_excepthook

    yield qtbot

    sys.excepthook = sys.__excepthook__
    if caught_exceptions:
        pytest.fail("Caught qt exceptions:\n{}".format(
            "\n".join(caught_exceptions)))

I created this so I can see when my table model methods fail. Without this, if an error happens in the data() or header() methods of a table model, like when a table view is being populated using the model, the test will not fail.

I think something similar to this would be a nice feature of pytest-qt, but a better, less hacky implementation would probably be better.

@nicoddemus
Copy link
Member

Done in 1.1.1, if you have a change to try it out let me know what you think. Cheers!

@jdreaver
Copy link
Member Author

Wow, great implementation!

One thing I would consider doing: move the new the context manager outside of the QtBot class, and define it as its own top-level definition. It doesn't seem to require a QtBot class instance for anything. That's just a style opinion I suppose.

Thanks!

EDIT: I didn't even notice you already made the new 1.1.1 release too. I'll start using this immediately to help test it out.

@jdreaver
Copy link
Member Author

It works great!

As a sidenote, I wish using pytest.fail() in a fixture caused the test to be marked as a failure, instead of an error. Oh well!

@nicoddemus
Copy link
Member

Excellent!

Yes, I noticed that about pytest.fail() too, but that's how pytest works it seems.

Thanks again!

@nicoddemus
Copy link
Member

Thanks for the suggestion about changing the context manager into a function. That allows me to test the code formatting code (see this commit if you want to check it out).

Cheers!

@jdreaver
Copy link
Member Author

Nice! I like the formatting refactoring as well. It keeps the main fixture definition very clear.

@patrickkidd
Copy link

FWIW, it is probably more accurate to report these as "Exceptions caught in Qt event loop" rather than "Qt exceptions in virtual methods." This is because these exceptions can also be raised in a pyqt slot.

nicoddemus added a commit to nicoddemus/pytest-qt that referenced this issue Feb 27, 2019
nicoddemus added a commit to nicoddemus/pytest-qt that referenced this issue Feb 27, 2019
@nicoddemus
Copy link
Member

@patrickkidd good point, thanks. Implemented it in #255.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants