Skip to content

Conversation

@hauntsaninja
Copy link
Collaborator

if t.type.is_final or t.type.is_enum:
return UninhabitedType(line=t.line)
elif isinstance(t, LiteralType) and t.is_enum_literal():
return UninhabitedType(line=t.line)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

metaclasses are a red herring, enums are just effectively final, so this is safe to do

Copy link
Contributor

Choose a reason for hiding this comment

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

Are you sure it's not about the order of operations? I.e. first __bool__ gets checked, then __len__ and then the same thing happens for the metaclass.

But here __bool__ gets checked and then immediately it goes to the metaclass.

I think falling back to the metaclass is correct, it just happens too early.

Copy link
Contributor

Choose a reason for hiding this comment

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

Alright I had a read of the blog post, maybe metaclasses aren't involved in truthiness after all and it just so happens that the default is to return True if you have neither a __bool__ or __len__, although I'm a little confused about the purpose of __bool__ on EnumMeta, when that is the default truthiness anyways.

Copy link
Contributor

@Daverball Daverball Dec 30, 2024

Choose a reason for hiding this comment

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

I double checked, looks like the metaclass does matter, but only for the truthiness of type[Enum], not the instances.

>>> from enum import EnumMeta
>>> EnumMeta.__bool__ = lambda self: False
>>> from enum import Enum                                                                   
>>> bool(Enum)
False
>>> class Foo(Enum):
...     a = "a"
...     
>>> bool(Foo.a)                                                                             
True
>>> 

Copy link
Collaborator Author

@hauntsaninja hauntsaninja Dec 30, 2024

Choose a reason for hiding this comment

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

That's right. It would also affect bool(Foo)

... continuing from your monkey patch ...
>>> bool(Foo)
False
>>> type(Foo.a).__mro__
(<enum 'Foo'>, <enum 'Enum'>, <class 'object'>)
>>> type(Foo).__mro__
(<class 'enum.EnumType'>, <class 'type'>, <class 'object'>)

@github-actions
Copy link
Contributor

According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅

Copy link
Collaborator

@JukkaL JukkaL 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 the fix!

@JukkaL JukkaL merged commit e139a0d into python:master Dec 30, 2024
18 checks passed
@hauntsaninja hauntsaninja deleted the fix-enum branch December 30, 2024 19:10
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.

[1.14 regression] truthy check for enums

3 participants