[pytest-dev] No traceback filtering with __tracebackhide__ attribute using custom pytest plugin
Ringo De Smet
ringo.de.smet at ontoforce.com
Fri Mar 16 04:18:18 EDT 2018
On Thu, Mar 15, 2018 at 11:19 PM, Bruno Oliveira <nicoddemus at gmail.com>
> You are right, pytest_runtest_makereport creates a longrepr instance
> depending on excinfo attribute of the call object:
> To do that it calls item.repr_failure(excinfo), which calls
> _repr_failure_py in python.py which ends up calling _prunetraceback which
> filters the traceback here:
> .filter() is declared here:
> And the default value uses a lambda where ishidden() checks for
> __tracebackhide__ attribute in the function’s locals.
You definitely pointed me in the right direction by mentioning that the
filtering passes via an item object. So thanks a lot for this info.
Checking the class hierarchy, I found this (simplified):
class Node(object) # nodes.py
repr_failure = _repr_failure_py
*pass* # No basic filtering here
class Item(Node) # nodes.py
... # no overriden methods here
class Function(FunctionMixin, Item) # python.py
def _prunetraceback # Whole filtering mechanism is triggered here!
And here is my code:
# no overridden methods here
I think it's clear now why it doesn't work. Since I provide instances of
SpecExample to the pytest runner, the filtering defined in FunctionMixin is
not triggered. As a solution I overridden _prunetraceback:
def _prunetraceback(self, excinfo):
filtered_traceback = excinfo.traceback.filter(filter_traceback)
filtered_traceback = filtered_traceback.filter()
excinfo.traceback = filtered_traceback
With this in place, my stack trace becomes this now:
============================= test session starts
platform darwin -- Python 3.6.4, pytest-3.4.2, py-1.5.2, pluggy-0.6.0
collected 6 items
../python-mamba/pytest_mamba/plugin.py:135: in runtest
../../venv/lib/python3.6/site-packages/mamba/example.py:43: in _execute_test
action_base_spec.py:44: in 00000007__it is ok--
E expected: 'value' to equal 'value2'
Now this is a bit dirty as I have code duplication from what you have in
FunctionMixin. Let's look at pytest from 2 different angles:
- pytest as a test runner (nodes.py, runner.py)
- pytest as the test implementation framework (python.py/unittest.py)
I would expect the basic traceback filtering to work via the runner,
irrespective of which custom tests a thirdparty plugin provides. What do I
consider basic filtering? Filtering out the traceback entries of the runner
as defined in python.py:filter_traceback function (pluggy, etc.) as well as
the default filter function regarding __tracebackhide__. This is exactly
what I activated via my custom _prunetraceback method.
May I suggest to push this basic filtering higher in that class hierarchy?
You will probably know better where that is/should be, but I guess in class
Item would be a good fit. Should I file this as an improvement on Github?
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the pytest-dev