8000 bpo-39728: enum with invalid value results in ValueError twice by dorosch · Pull Request #18641 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

bpo-39728: enum with invalid value results in ValueError twice #18641

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

Closed

Conversation

dorosch
Copy link
Contributor
@dorosch dorosch commented Feb 24, 2020

Color('error out')
except ZeroDivisionError as exc:
self.assertTrue(isinstance(exc.__context__, ValueError))

Choose a reason for hiding this comment

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

Hm, I hadn't noticed but this test would (still) be affected by the fix. And it seems reasonable to keep : \

Instead of changing when context is added to the exception, could the default implementation of _missing be changed to return None? Or would that break something?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think that would break logic because None might be as value of enum:

from enum import Enum

class Color(Enum):
    BLUE = 'blue'
    RED = 'red'
    UNDEFINED = None

Copy link
@jonasmalacofilho jonasmalacofilho Feb 24, 2020

Choose a reason for hiding this comment

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

But in that example _missing_ would need to return cls.UNDEFINED instead of None, because it has to return an instance of cls.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Maybe you're right) I will try it

Copy link
Member

Choose a reason for hiding this comment

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

The original verification here should be kept. It's checking that if using _missing_ explodes when searching for a value, the final result is the ValueError (of the bad value) and the ZeroDivisionError (of the internal problem).

@dorosch dorosch force-pushed the bpo-39728-enum-valuerrror-twice branch from de44c06 to 72eb2c4 Compare February 24, 2020 10:45
@@ -1776,7 +1776,8 @@ def _missing_(cls, item):
# trigger not found
return None
self.assertIs(Color('three'), Color.blue)
self.assertRaises(ValueError, Color, 7)
with self.assertRaises(ValueError):
Copy link
Contributor

Choose a reason for hiding this comment

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

This statement passes on the old code as well. Is it possible to specifically assert that a ValueError has been raised, but without the second ValueError being raised in the process?

Copy link
Member

Choose a reason for hiding this comment

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

Yes, that can (and should) be tested, with something like this:

        with self.assertRaises(ValueError) as cm:
            Color(7)
        self.assertIsNone(cm.exception.__context__)

Copy link
Member
@facundobatista facundobatista left a comment

Choose a reason for hiding this comment

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

Thanks for this work!

Probably the fix is not good, as one test is changed but it shouldn't. In the process, other test can be improved, see conversation.

All that said, note that one test is missing, which would be the one that verifies that in the simple case of value not being found, the exception is simple and not chained (which is what describes the original bug, which was not using the _missing_ feature).

Thanks again!

@@ -1776,7 +1776,8 @@ def _missing_(cls, item):
# trigger not found
return None
self.assertIs(Color('three'), Color.blue)
self.assertRaises(ValueError, Color, 7)
with self.assertRaises(ValueError):
Copy link
Member

Choose a reason for hiding this comment

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

Yes, that can (and should) be tested, with something like this:

        with self.assertRaises(ValueError) as cm:
            Color(7)
        self.assertIsNone(cm.exception.__context__)

Color('error out')
except ZeroDivisionError as exc:
self.assertTrue(isinstance(exc.__context__, ValueError))
Copy link
Member

Choose a reason for hiding this comment

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

The original verification here should be kept. It's checking that if using _missing_ explodes when searching for a value, the final result is the ValueError (of the bad value) and the ZeroDivisionError (of the internal problem).

@bedevere-bot
Copy link

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

@python python deleted a comment from codecov bot Sep 16, 2020
@ethanfurman ethanfurman self-assigned this Sep 16, 2020
@ethanfurman
Copy link
Member

dorosch, thank you for your efforts. The source of the problem was actually in the default _missing_ method. I was unable to push my changes to this PR, so I opened #22277.

farazs-github pushed a commit to MediaTek-Labs/cpython that referenced this pull request Nov 12, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants
0