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

Enum issue #6381

Closed
Fapso opened this issue Sep 11, 2024 · 6 comments
Closed

Enum issue #6381

Fapso opened this issue Sep 11, 2024 · 6 comments
Assignees
Labels
needs repro Issue has not been reproduced yet

Comments

@Fapso
Copy link

Fapso commented Sep 11, 2024

image

Environment data

  • Pylance version: v2024.9.1
  • OS and version: Windows 10
  • Python version: 3.9.4

Code Snippet

from enum import IntFlag

class Test(IntFlag):
    """"""
    Onet = 1
    Two = 2
    Three = 3
    Four = 4


for k in Test:
    print(k.name.lower())
3.9.4

Expected behavior

I excepected .name to always return a string, especially since all Enum's class members are hard-coded.

Actual behavior

As you can see, it claims, whatever is returned cannot get the .lower() treatment, because it might be a None.

@github-actions github-actions bot added the needs repro Issue has not been reproduced yet label Sep 11, 2024
@Fapso
Copy link
Author

Fapso commented Sep 11, 2024

image

Pylance v2024.8.1 did not have such an issue.

@erictraut
Copy link
Contributor

erictraut commented Sep 11, 2024

This behavior is intended. Instances of of Flag (which is the parent class for IntFlag) can be combined to produce new (nameless) enum values. For this reason, the type definition for Flag.name in the typeshed stubs indicates that name can be None.

I'm guessing that this was recently changed in the typeshed stubs, which would explain why you didn't see this error in older versions of pylance.

@erictraut
Copy link
Contributor

Actually, it looks like a name is synthesized at runtime for combinations.

x: Test = Test.Two | Test.Four
print(x.name.lower()) # prints "two|four"

So this might be a bug in the typeshed stubs. If you'd like to pursue that, you can file a bug report or PR in the typeshed proejct. All of the major type checkers (including pyright, which pylance is built upon) make use of these stubs.

@luanft
Copy link

luanft commented Sep 12, 2024

The same issue on Id attribute of Django models. Also on ManyToMany, ForeignKey fields

@Fapso
Copy link
Author

Fapso commented Sep 12, 2024

Trusting: https://github.com/python/cpython/blob/cbfeb6a7fe89101e24ba7f61b5d42e12b79f1c9d/Lib/enum.py#L1492, it is possible for a FlagInt to have name None under this condition:

            if not combined_value:
                pseudo_member._name_ = None

Seems that Pylance is doing this thing correctly, or I'm being mistaken here.

Changed FlagInt to IntEnum and the problem disappeared.

Thank you, Erictraut, for pushing me in the right direction.

The same issue on Id attribute of Django models. Also on ManyToMany, ForeignKey fields

Luanft, indeed I have the same issue happening, but shouldn't it be a different 'bug'?

image

@heejaechang
Copy link
Contributor

going to close it as by design. for the other issue, please open new issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs repro Issue has not been reproduced yet
Projects
None yet
Development

No branches or pull requests

4 participants