pytest icon indicating copy to clipboard operation
pytest copied to clipboard

Exclude variable from showlocals output

Open richardjharris opened this issue 4 years ago • 12 comments

What's the problem this feature will solve?

I have a test which uses a large dictionary of words. With showlocals on (which is generally really useful and I have it globally enabled) this huge dictionary gets printed for any test failure.

This is distinct from the case of credentials, as my data is not private and I don't care if something prints it, I just don't want --showlocals to print it.

Describe the solution you'd like

A way of excluding variables from output, attached to either the test function via annotation, or a @pytest.fixture (in my case the dictionary is a fixture)

There must be other cases where large test data objects make the test output more difficult to read.

Alternative Solutions

Can disable showlocals and go back to normal debugging.

Can wrap the object in a class with a custom __repr__ and __str__ implementation. However this is clumsy, has too wide a scope, and is error prone (for example not implementing __eq__ may lead to test failures for string-like objects).

Additional context

I'm mostly looking for workarounds, I understand this is a niche request and might not be productive to be added into pytest itself.

richardjharris avatar Aug 03 '21 10:08 richardjharris

This would be less annoying if there was a way to override --showlocals e.g. --showlocals=false to disable the global configuration.

richardjharris avatar Aug 03 '21 10:08 richardjharris

This would be less annoying if there was a way to override --showlocals e.g. --showlocals=false to disable the global configuration.

Not sure I follow, can you elaborate on that?

nicoddemus avatar Aug 06 '21 12:08 nicoddemus

Alternative Solutions

One way to customize tracebacks currently is __tracebackhide__ = True, which if present in locals, will hide that from when rendering the traceback.

Here it seems this should follow the same rationale of using a local variable to customize this behavior, because the customization is usually closely attached to the locals in the frame.

One idea that comes to mind is create a new special variable to customize traceback rendering:

__traceback_options__ = pytest.TracebackOptions(hide=True, hide_locals=["large_dict"])

This would then eventually replace __tracebackhide__, as it is more flexible.

nicoddemus avatar Aug 06 '21 12:08 nicoddemus

This would be less annoying if there was a way to override --showlocals e.g. --showlocals=false to disable the global configuration.

Not sure I follow, can you elaborate on that?

I would like to keep showlocals on by default (via addopts in pytest.ini) but if the output is too noisy, disable it for particular invocations. Afaict there is no way to override the setting once it's set.

richardjharris avatar Aug 06 '21 17:08 richardjharris

Filters for the locals should be a hook

Also we should ensure its not dependent on the traceback objects we copied from pylib

RonnyPfannschmidt avatar Aug 06 '21 17:08 RonnyPfannschmidt

Filters for the locals should be a hook

Not sure, often I have a bunch of utility code which I know will be used for testing and want to exclude frames containing implementation details. I wouldn't like to implement a hook for that.

EDIT: unless you mean to have hooks in addition to some form of local customization, in which case I think it would be fine.

nicoddemus avatar Aug 06 '21 18:08 nicoddemus

This would be less annoying if there was a way to override --showlocals e.g. --showlocals=false

This just bit me on pytest 7.1.2. I can't override the default addopts. It feels like a bug.

Since this issue is very broadly scoped (hiding individual variables are a possibility), I created https://github.com/pytest-dev/pytest/issues/10381

tony avatar Oct 13 '22 18:10 tony

Is there still not a way to exclude one specific variable name?

siddhpant avatar May 15 '25 09:05 siddhpant

Indeed there isn't, hence why this issue is open.

The-Compiler avatar May 15 '25 09:05 The-Compiler

Given that important frameworks and toolkits adapted secret strings im inclined to close this with a reference to them as they apply more general

RonnyPfannschmidt avatar May 15 '25 10:05 RonnyPfannschmidt

Perhaps it wouldn't be simple enough to allow a local variable to exclude locals similar to tracebackhide for globals

Its still going to be a pain if they pass into multiple places

RonnyPfannschmidt avatar May 15 '25 10:05 RonnyPfannschmidt

Given that important frameworks and toolkits adapted secret strings im inclined to close this with a reference to them as they apply more general

How would a secret string apply in this case (where a huge dictionary is provided)?

siddhpant avatar May 16 '25 04:05 siddhpant