I have seen this line of code in some functions
__traceback_hide__ = True
What does it do? It seems like its trying to suppress the error traceback. In what situations should the traceback be hidden?
__tracebackhide__
can be set to hide a function from the traceback when using PyTest. __traceback_hide__
appears to be used in the Python Paste package for the same purpose.
Here's what the paste.exceptions.collector documentation has to say about it:
If set and true, this indicates that the frame should be hidden from abbreviated tracebacks. This way you can hide some of the complexity of the larger framework and let the user focus on their own errors.
By setting it to 'before', all frames before this one will be thrown away. By setting it to 'after' then all frames after this will be thrown away until 'reset' is found. In each case the frame where it is set is included, unless you append '_and_this' to the value (e.g., 'before_and_this').
Note that formatters will ignore this entirely if the frame that contains the error wouldn’t normally be shown according to these rules.
And the PyTest documentation on its similar __tracebackhide__
:
If you have a test helper function called from a test you can use the pytest.fail marker to fail a test with a certain message. The test support function will not show up in the traceback if you set the __tracebackhide__ option somewhere in the helper function.
So basically, they are to avoid cluttering your tracebacks with test helper functions or other functions that you know aren't part of the problem that you are trying to debug.
Googling for "python __traceback_hide__", I learn that it's intended to let a complicated framework hide part of its inner workings by suppressing some stack frames from the exception printout, so that the user does not become confused lots of irrelevant output.
Looks like this is mostly a convenience for web frameworks (Sentry, werkzeug, Paste, Django) to make it so framework functions aren't included in the high level exception reporting features of the frameworks.
The exact behavior likely differs by framework, for example, for Paste specifically, it's documented as:
If set and true, this indicates that the frame should be hidden from abbreviated tracebacks. This way you can hide some of the complexity of the larger framework and let the user focus on their own errors.
By setting it to 'before', all frames before this one will be thrown away. By setting it to 'after' then all frames after this will be thrown away until 'reset' is found. In each case the frame where it is set is included, unless you append '_and_this' to the value (e.g., 'before_and_this').
Note that formatters will ignore this entirely if the frame that contains the error wouldn’t normally be shown according to these rules.
It's not a standard variable, and the core Python interpreter provides no support for it.
Hiding the traceback can give you more comprehensible test output.
Consider testing that a web API endpoint /running
returns the JSON response {"running": true}
:
import pytest
import json
def test_running(client):
action_response = client.get('/running')
assert parse_as_json(action_response) == {'running': True}
def parse_as_json(response):
__tracebackhide__ = True # <---- Point of interest
try:
return json.loads(response.data)
except json.decoder.JSONDecodeError:
pass
pytest.fail(f'Expected JSON, but got {response.data}')
If the test fails (because the JSON is malformed), then the failure will be displayed as
__________________________ test_running _________________________
client = <FlaskClient <Flask 'webapi'>>
def test_running(client):
action_res = client.get('/running')
> assert parse_as_json(action_res) == {'running': True}
E Failed: Expected JSON, but got b'ok'
webapi_test.py:22: Failed
=============== 1 failed, 1 passed in 0.15 seconds ===============
whereas, without the __tracebackhide__ = True
, the output will be
__________________________ test_running _________________________
client = <FlaskClient <Flask 'webapi'>>
def test_running(client):
action_res = client.get('/running')
> assert parse_as_json(action_res) == {'running': True}
webapi_test.py:22:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
client = <FlaskClient <Flask 'webapi'>>
def test_running(client):
action_res = client.get('/running')
> assert parse_as_json(action_res) == {'running': True}
E Failed: Expected JSON, but got b'ok'
webapi_test.py:22: Failed
=============== 1 failed, 1 passed in 0.17 seconds ===============
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With