-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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
Enum private attributes are not enum members #17182
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1425,6 +1425,10 @@ from enum import Enum | |
class Correct(Enum): | ||
x = 'y' | ||
y = 'x' | ||
class Correct2(Enum): | ||
x = 'y' | ||
__z = 'y' | ||
__z = 'x' | ||
class Foo(Enum): | ||
A = 1 | ||
A = 'a' # E: Attempted to reuse member name "A" in Enum definition "Foo" \ | ||
|
@@ -2105,3 +2109,31 @@ class AllPartialList(Enum): | |
|
||
def check(self) -> None: | ||
reveal_type(self.value) # N: Revealed type is "builtins.list[Any]" | ||
|
||
[case testEnumPrivateAttributeNotMember] | ||
from enum import Enum | ||
|
||
class MyEnum(Enum): | ||
A = 1 | ||
B = 2 | ||
__my_dict = {A: "ham", B: "spam"} | ||
|
||
x: MyEnum = MyEnum.__my_dict # E: Incompatible types in assignment (expression has type "Dict[int, str]", variable has type "MyEnum") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, I'm not sure this is correct? The name is mangled at runtime, so this attempted attribute access fails with an exception unless you use the mangled name: >>> from enum import Enum
>>> class Foo(Enum):
... __x = 'y'
... y = 'z'
...
>>> Foo.__x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: type object 'Foo' has no attribute '__x'
>>> Foo._Foo__x
'y' This PR definitely improves the handling of mangled names in enum class namespaces, but really mypy should be warning that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
It isn't :D, but mypy doesn't understand name mangling yet and it is out of scope here. You are right however, there should be a comment. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oof, we don't understand name mangling in any context? 😬
Thanks! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We don't: https://mypy-play.net/?mypy=latest&python=3.12&gist=13d2e1e6e60b8e3828129fc44b336381 but there is already an issue for that #8267 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh and a PR #16715 |
||
|
||
[case testEnumWithPrivateAttributeReachability] | ||
# flags: --warn-unreachable | ||
from enum import Enum | ||
|
||
class MyEnum(Enum): | ||
A = 1 | ||
B = 2 | ||
__my_dict = {A: "ham", B: "spam"} | ||
|
||
e: MyEnum | ||
if e == MyEnum.A: | ||
reveal_type(e) # N: Revealed type is "Literal[__main__.MyEnum.A]" | ||
elif e == MyEnum.B: | ||
reveal_type(e) # N: Revealed type is "Literal[__main__.MyEnum.B]" | ||
else: | ||
reveal_type(e) # E: Statement is unreachable | ||
[builtins fixtures/dict.pyi] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I would call any name that starts with a single underscore a "private" (by convention) name, and any name that starts with two underscores a "mangled" name
(There's several other places in this PR where you also refer to them as "private" names; I'd change those too, personally)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I used the same terminology used by the enum docs: https://docs.python.org/3/howto/enum.html#private-names
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough... though I sorta think the docs there are using the wrong terminology... but hey :P