pytest-dev / py

Python development support library (note: maintenance only)
MIT License
67 stars 106 forks source link

[WIP] Extract ExceptionContext from pytest.python_api.RaisesContext. #181

Closed jaraco closed 6 years ago

jaraco commented 6 years ago

I occasionally wish I had the interfaces that pytest.raises provides without the assertion logic - just the ability to test if an exception occurred and if so retains the details of that exception.

This PR extracts that functionality from pytest.

After pytest can depend on this new functionality, its implementation can be pared down to:

class RaisesContext(_py._code.ExceptionContext):
    def __init__(self, expected_exception, message, match_expr):
        super(RaisesContext, self).__init__(expected_exception)
        self.message = message
        self.match_expr = match_expr

    def __exit__(self, *tp):
        __tracebackhide__ = True
        if tp[0] is None:
            fail(self.message)
        suppress_exception = super(RaisesContext, self).__exit__(*tp)
        if self.match_expr and suppress_exception:
            self.excinfo.match(self.match_expr)
        return suppress_exception

This approach provides greater separation of responsibility and allows for greater code re-use by making the ExceptionContext available for broader use (outside of testing frameworks).

This implementation would largely if not wholly obviate jaraco.context.ExceptionTrap. In fact, I wonder if it should be named ExceptionTrap here.

I present this as a work in progress to get your initial reaction and advice on how to proceed. Is the approach attractive and viable? Do you want tests? Documentation? Changelog?

RonnyPfannschmidt commented 6 years ago

pytest no longer uses py.code, as such this extraction is unfortunately misplaced

i like the idea behind the abstraction tho and would like to figure how to integrate it with the current situation

nicoddemus commented 6 years ago

I just noticed that this is very similar to contextlib.suppress, it is just a shame that you can't obtain details of the exception after that context manager executes.

jaraco commented 6 years ago

I created python 33146 to consider adding this functionality to the stdlib (and presumably backported by contextlib2).

jaraco commented 6 years ago

pytest no longer uses py.code

The code begs to differ.

RonnyPfannschmidt commented 6 years ago

@jaraco thats _pytest._code not py.code - see pytest-dev/pytest#1199

jaraco commented 6 years ago

So if I wanted to extract/present this functionality elsewhere, where would that be?

RonnyPfannschmidt commented 6 years ago

Oft Hand thats unclear, pylib is maintenance only and pytest will stop using it long term

nicoddemus commented 6 years ago

@jaraco perhaps https://github.com/mahmoud/boltons would be a good place for it? Your request seems to me much like a contextlib.supress with additional functionality, which fits the philosophy of the library.

cc @mahmoud

jaraco commented 6 years ago

Thanks for the tip. I'll have to check out boltons. Unfortunately, that only creates yet another home for this functionality, which already has a home at jaraco.context. My main goal with this PR was to consolidate functionality - for pytest to share the functionality from a common source. But it sounds like pytest has no intention of presenting this functionality except in the context of a test runner, so I'll just rely on jaraco.context.

RonnyPfannschmidt commented 6 years ago

@jaraco thing is - pylib is in maintenance mode and pytest aims to stop using it altogether - so for pytest to move functonality into pylib is not a path forward