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

Fix unguarded == comparison in fixtures. #6541

Merged

Conversation

kohr-h
Copy link
Contributor

@kohr-h kohr-h commented Jan 22, 2020

Here's an attempt to fix the equality checking issue in fixtures.

To do:

  • AUTHORS file
  • Tests for the fix

Closes: #6497

try:
cache_valid = bool(my_cache_key == cache_key)
except (TypeError, ValueError):
pass
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should warn that a fragile cache key was used,
pytest should at some point require parameters to be reasonably stable/hash-able
accidentally and strangely modifiable parameters have led to many horrendous errors as aftermath of accidential modification

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I'll add a warning.
Regarding the TypeError case, is that even desirable? Classes have to actively disallow ==, if unimplemented it defaults to is, which would be okay. Should we consider a class that raises TypeError on __eq__ as pathological? Besides, AttributeError would also be an option.

Copy link
Member

@nicoddemus nicoddemus Jan 24, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps we should straight out error out instead? Warnings have a tendency to get ignored, and we should avoid letting users running test suites with problematic setups.

So I suggest we raise an appropriate error pointing to the problematic node id instead.

Regarding the TypeError case

We should actually handle any exception I think (using Exception)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for clarity, @nicoddemus do you mean to also error out in the NumPy array case? After thinking about it for a second, I agree that's the most reasonable solution. Besides brittleness, another reason is that every == operation with an array computes a new boolean array, so with large arrays as parameters, the comparisons can get quite expensive.
I suggest to include a hint in the error message to use scope='function' for NumPy arrays or other types where if a == b: can raise an exception. The docs would ideally also mention that case.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for clarity, @nicoddemus do you mean to also error out in the NumPy array case? After thinking about it for a second, I agree that's the most reasonable solution. Besides brittleness, another reason is that every == operation with an array computes a new boolean array, so with large arrays as parameters, the comparisons can get quite expensive.

Yes that's my reasoning as well: we should straight out discourage parametrization using types that don't have standard/buggy == operators.

I suggest to include a hint in the error message to use scope='function' for NumPy arrays or other types where if a == b: can raise an exception. The docs would ideally also mention that case.

Not sure, this problem is not related to scoping at all, I'm afraid. We could however add a link in the exception message to a section in the docs where this is explained, probably using numpy arrays as example and possible workarounds.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @RonnyPfannschmidt those are good points.

I'm still leaning towards just breaking it in the next feature release though (don't think this will affect many users), but I'm also OK about deprecating it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw, please get the final word then so @kohr-h can finish the PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what if we did something more clever with request.param below in def cache_key -- I think we could probably use object identity (id(...)) for request.param

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we remove support for them it breaks test-suites that are technically working

Hm, with the current release test suites are already broken, so the question is whether you prefer to add a (somewhat dirty) workaround or rather keep failing, but with a better error message. Or would it make sense to re-enable a broken feature and deprecate it at the same time?

@asottile You mean replace == with is basically?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quick testing shows that is instead of == could work. I'll do a push and see how the test suite does.

@kohr-h kohr-h force-pushed the issue_6487__unguarded_eq_in_fixture branch from fb3975f to f0fd818 Compare January 25, 2020 19:29
@kohr-h
Copy link
Contributor Author

kohr-h commented Jan 25, 2020

Works with is, at least the existing tests. What do you think?
And what would be a good place for a test case for this issue?

@kohr-h
Copy link
Contributor Author

kohr-h commented Jan 25, 2020

And what would be a good place for a test case for this issue?

Maybe around here?

def test_funcarg_parametrized_and_used_twice(self, testdir):

@kohr-h
Copy link
Contributor Author

kohr-h commented Jan 25, 2020

Now with test.

Copy link
Member

@nicoddemus nicoddemus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @kohr-h!

Pushed minor improvements and fixed linting.

As we only use the comparison for caching, I don't think this will have any adverse effects. 👍

Copy link
Contributor

@blueyed blueyed left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, looks good.
Please squash it though (@nicoddemus can do it).

@nicoddemus
Copy link
Member

Please squash it though (@nicoddemus can do it).

Just did, thanks for catching it.

Copy link
Member

@asottile asottile left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

@blueyed blueyed left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please squash it though (@nicoddemus can do it).
Just did, thanks for catching it.

Has not been done/pushed?

JFI: I'm out of here (given the animated GIF).

@nicoddemus nicoddemus force-pushed the issue_6487__unguarded_eq_in_fixture branch from 4de0aa6 to 80d4dd6 Compare January 28, 2020 21:23
@nicoddemus
Copy link
Member

Has not been done/pushed?

My bad, done. 😅

@nicoddemus nicoddemus merged commit d282424 into pytest-dev:master Jan 28, 2020
@kohr-h kohr-h deleted the issue_6487__unguarded_eq_in_fixture branch January 31, 2020 16:34
@kohr-h
Copy link
Contributor Author

kohr-h commented Jan 31, 2020

Ah, just saw that this is merged, 👍 -- and that the conversation took a funny turn..

0xDEC0DE pushed a commit to 0xDEC0DE/pytest that referenced this pull request Jul 11, 2024
The fix for Issue pytest-dev#6541 caused regression where cache hits became
cache misses, unexpectedly.  Attempt to restore the previous behavior,
while also retaining the fix for the bug.

Fixes: Issue pytest-dev#6962
0xDEC0DE pushed a commit to 0xDEC0DE/pytest that referenced this pull request Jul 11, 2024
The fix for Issue pytest-dev#6541 caused regression where cache hits became
cache misses, unexpectedly.  Attempt to restore the previous behavior,
while also retaining the fix for the bug.

Fixes: Issue pytest-dev#6962
0xDEC0DE pushed a commit to 0xDEC0DE/pytest that referenced this pull request Jul 11, 2024
The fix for Issue pytest-dev#6541 caused regression where cache hits became
cache misses, unexpectedly.  Attempt to restore the previous behavior,
while also retaining the fix for the bug.

Fixes: Issue pytest-dev#6962
0xDEC0DE pushed a commit to 0xDEC0DE/pytest that referenced this pull request Jul 11, 2024
The fix for Issue pytest-dev#6541 caused regression where cache hits became
cache misses, unexpectedly.  Attempt to restore the previous behavior,
while also retaining the fix for the bug.

Fixes: Issue pytest-dev#6962
0xDEC0DE pushed a commit to 0xDEC0DE/pytest that referenced this pull request Jul 12, 2024
The fix for Issue pytest-dev#6541 caused regression where cache hits became
cache misses, unexpectedly.  Attempt to restore the previous behavior,
while also retaining the fix for the bug.

Fixes: Issue pytest-dev#6962
nicoddemus pushed a commit to 0xDEC0DE/pytest that referenced this pull request Jul 17, 2024
The fix for Issue pytest-dev#6541 caused regression where cache hits became
cache misses, unexpectedly.  Attempt to restore the previous behavior,
while also retaining the fix for the bug.

Fixes: Issue pytest-dev#6962
nicoddemus added a commit that referenced this pull request Jul 17, 2024
The fix for Issue #6541 caused regression where cache hits became cache misses, unexpectedly.  

Fixes #6962

---------

Co-authored-by: Nicolas Simonds <[email protected]>
Co-authored-by: Bruno Oliveira <[email protected]>
Co-authored-by: Ran Benita <[email protected]>
0xDEC0DE added a commit to 0xDEC0DE/pytest that referenced this pull request Jul 17, 2024
The fix for Issue pytest-dev#6541 caused regression where cache hits became cache misses, unexpectedly.  

Fixes pytest-dev#6962

---------

Co-authored-by: Nicolas Simonds <[email protected]>
Co-authored-by: Bruno Oliveira <[email protected]>
Co-authored-by: Ran Benita <[email protected]>
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

Successfully merging this pull request may close these issues.

Fixture fails with "module" scope and numpy array as value
5 participants