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

Default value for Generic self is erased by @dataclass #14382

Closed
zmievsa opened this issue Jan 3, 2023 · 6 comments
Closed

Default value for Generic self is erased by @dataclass #14382

zmievsa opened this issue Jan 3, 2023 · 6 comments
Labels
bug mypy got something wrong

Comments

@zmievsa
Copy link

zmievsa commented Jan 3, 2023

Note that pyright has a similar behavior so I am not sure whether it is a bug per se but I do believe that it is an incorrect behavior.

Bug Report

It is possible to specify the default value for a generic self using __init__ parameter type hint or __new__ return type hint. However, when a @dataclass decorator is applied to the class and when it generates __init__, the __new__ definition gets erased.

To Reproduce

https://mypy-play.net/?mypy=latest&python=3.11&gist=13b4e50085788299b532d56cf70c3eb8

Expected Behavior
Mypy must show:

main.py:22: note: Revealed type is "__main__.User[Literal['NotLoggedIn']]"

And it does show it if the @dataclass gets commented out, init=False is passed to the dataclass, or if the following __init__ is added to the class:

def __init__(self: "User[Literal['NotLoggedIn']]", name: str) -> None:
    self.name = name

Actual Behavior

main.py:21: error: Need type annotation for "f"  [var-annotated]
main.py:22: note: Revealed type is "__main__.User[Any]"

Your Environment

  • Mypy version used: 0.991
  • Python version used: 3.11

Relevant links

#4236

@erictraut
Copy link

FWIW, I closed this issue in the pyright issue tracker because I don't consider this a bug in pyright. The mechanism by which a constructor's specialized type is influenced by an annotated self parameter within an __init__ mechanism has never been specified or documented. If this is something that we want to officially support in the Python type system, someone should write a PEP, and we should specify and discuss how it should work in detail. Until then, I consider this a narrowly-scoped hack that works around a very specific issue.

@zmievsa
Copy link
Author

zmievsa commented Jan 3, 2023

@erictraut do I understand correctly that your work with @JelleZijlstra on PEP 696 is supposed to solve this issue in its entirety?

@erictraut
Copy link

@Ovsyanka83, no, this issue has nothing to do with PEP 696 (or PEP 695).

@zmievsa
Copy link
Author

zmievsa commented Jan 3, 2023

@erictraut I decided to go back and check whether I'll be able to use typevardefaults with the latest pyright and succeeded.

And it does solve my problem in its entirety. Take a look at the modified code that reveals the expected type:

from dataclasses import dataclass
from typing import Generic, TypeVar, cast

from typing_extensions import TYPE_CHECKING, Literal

if TYPE_CHECKING:
    T = TypeVar("T", bound=Literal["LoggedIn", "NotLoggedIn"], default=Literal["NotLoggedIn"])


@dataclass
class User(Generic[T]):
    name: str

    def log_in(self) -> "User[Literal['LoggedIn']]":
        return cast(User[Literal["LoggedIn"]], self)

    def scream(self: "User[Literal['LoggedIn']]") -> None:
        print(f"{self.name} screams!")


f = User("admin")
reveal_type(f)

I apologize for disturbing you and I am really grateful for your work on PEP 696 in pyright.

@JelleZijlstra
Copy link
Member

(Also, to be clear, PEP 696 is @Gobot1234's work, not mine; I am just the PEP sponsor.)

@hauntsaninja hauntsaninja closed this as not planned Won't fix, can't repro, duplicate, stale Jan 3, 2023
@hauntsaninja
Copy link
Collaborator

Closing in favour of whatever issue is tracking 696

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong
Projects
None yet
Development

No branches or pull requests

4 participants