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

Understand the self-destructing nature of Enum._ignore_ #12128

Merged
merged 5 commits into from
Feb 16, 2022

Conversation

kstauffer
Copy link
Contributor

@kstauffer kstauffer commented Feb 4, 2022

Similar to _order_ (which mypy already handles), _ignore_ is deleted by EnumMeta. Currently, (#12121) mypy thinks it's an error to set _ignore_ in an Enum subclass because 'Cannot override writable attribute "_ignore_" with a final one.' This PR both:

  1. Makes mypy ok with setting _ignore_ in the class body; and
  2. Makes it an error to later access the (deleted) _ignore_ attribute ('Type[E] has no attribute "_ignore_"')

The PR adds a test that accessing _ignore_ after the class definition is flagged as an error. I wanted to test that (1) above has been fixed, but I couldn't figure out how to make a failing test. So I went "out of band" from the unit test themselves; I created a simple test file:

from enum import Enum
class E(Enum):
    _ignore_ = '' # how to assert that old mypy "Cannot override writable"
E._ignore_

And checked that before this PR, mypy raised an error on line 3 but not line 4, and after this PR line 3 was ok but line 4 was now in error.

This PR does not cause mypy itself to ignore the attributes. That is, after this definition:

from enum import Enum
class E(Enum):
    _ignore_ = "X"
    X = 1

mypy still thinks E.X exists. I suppose mypy could parse the value of _ignore_ when it's a literal , but I don't have plans to look into that.

@sobolevn sobolevn self-requested a review February 5, 2022 12:30
Copy link
Member

@sobolevn sobolevn left a comment

Choose a reason for hiding this comment

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

Thank you!

Blocking

  • Let's add a constant

Non-blocking

I think if we are adding _ignore_ support, we must be sure that this case works correctly:

class Some(Enum):
   a = 1
   b = 2
   _ignore_ = ('a',)

reveal_type(Some.a)
reveal_type(Some.b)

However, I think that it can be addressed in a separate PR.
But, we need at least an new issue for it.

mypy/typeops.py Outdated Show resolved Hide resolved
mypy/typeops.py Outdated Show resolved Hide resolved
@github-actions

This comment has been minimized.

@kstauffer
Copy link
Contributor Author

kstauffer commented Feb 11, 2022

However, I think that it can be addressed in a separate PR. But, we need at least an new issue for it.

Created issue #12157.

@github-actions
Copy link
Contributor

According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉

Copy link
Member

@sobolevn sobolevn left a comment

Choose a reason for hiding this comment

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

Thank you!

@kstauffer
Copy link
Contributor Author

kstauffer commented Feb 11, 2022 via email

Copy link
Collaborator

@hauntsaninja hauntsaninja left a comment

Choose a reason for hiding this comment

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

Looks good, thank you for this!

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.

4 participants