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

Stubgen generates __mypy-replace method for @dataclass_transform #18081

Open
KapJI opened this issue Oct 31, 2024 · 5 comments
Open

Stubgen generates __mypy-replace method for @dataclass_transform #18081

KapJI opened this issue Oct 31, 2024 · 5 comments
Assignees
Labels

Comments

@KapJI
Copy link
Contributor

KapJI commented Oct 31, 2024

Bug Report

Stubgen generates mypy-replace method which makes .pyi file invalid.

To Reproduce

Minimum example, truncated from Home Assistant codebase:

from typing import dataclass_transform

@dataclass_transform(
    field_specifiers=(),
)
class FrozenOrThawed(type):
    ...

class EntityDescription(metaclass=FrozenOrThawed):
    key: str
$ stubgen --include-private test.py

Without --include-private this method is not generated.

Expected Behavior

Stubgen produces .pyi file with valid syntax, without mypy-replace. Probably with __replace__ method:

class FrozenOrThawed(type): ...

class EntityDescription(metaclass=FrozenOrThawed):
    key: str
    def __init__(self, key) -> None: ...
    def __replace__(self, *, key) -> None: ...

Actual Behavior

Stubgen on master generates:

class FrozenOrThawed(type): ...

class EntityDescription(metaclass=FrozenOrThawed):
    key: str
    def __init__(self, key) -> None: ...
    def __mypy-replace(*, key) -> None: ...

Stubgen 1.13.0 generates __replace__ method as well:

class FrozenOrThawed(type): ...

class EntityDescription(metaclass=FrozenOrThawed):
    key: str
    def __init__(self, key) -> None: ...
    def __mypy-replace(*, key) -> None: ...
    def __replace__(self, *, key) -> None: ...

Your Environment

  • Stubgen version used: master 06a566b and released 1.13.0.
  • Stubgen command-line flags: --include-private
  • Python version used: 3.12.6 on MacOS
@KapJI KapJI added the bug mypy got something wrong label Oct 31, 2024
@hamdanal
Copy link
Collaborator

hamdanal commented Nov 2, 2024

Another problem is that stubgen swallows the @dataclass_transform decorator

@hamdanal hamdanal self-assigned this Nov 2, 2024
@KapJI
Copy link
Contributor Author

KapJI commented Nov 5, 2024

@hamdanal This is unrelated to this bug but do you think it's possible to make stubgen preserve arbitrary decorators?

E.g. home assistant uses @cached_property from propcache extensively, stubgen swallows it and then mypy emits error on code that uses generated stubs:

number.py:91: error: Signature of "native_value" incompatible with supertype "NumberEntity"  [override]
number.py:91: note:      Superclass:
number.py:91: note:          def native_value(self) -> float | None
number.py:91: note:      Subclass:
number.py:91: note:          float | None

Here def native_value(self) is decorated with @property or @cached_property from either functools or propcache, none of these work.

Mypy passes if I remove decorators in number.py but that changes code behaviour.

In original home assistant code base mypy accepts methods decorated with @property when superclass method is decorated with @propcache.cached_property.

@hamdanal
Copy link
Collaborator

hamdanal commented Nov 9, 2024

@hamdanal This is unrelated to this bug but do you think it's possible to make stubgen preserve arbitrary decorators?

The decision to ignore unknown decorators predates my contributions to stubgen. I suggest you open a new issue asking for this to be supported.

@bramstroker
Copy link

E.g. home assistant uses @cached_property from propcache extensively, stubgen swallows it and then mypy emits error on code that uses generated stubs:

number.py:91: error: Signature of "native_value" incompatible with supertype "NumberEntity"  [override]
number.py:91: note:      Superclass:
number.py:91: note:          def native_value(self) -> float | None
number.py:91: note:      Subclass:
number.py:91: note:          float | None

Thanks for raising this issue. I'm hit with the same bug on my project and was bumping my head.
Would be nice if support for arbitrary decorators would be added, as these are part of the method signature and mypy fails when signature is not the same. Not sure what would be the reason to drop unknown decorators from the stubs generated, as that renders the whole stub useless.

@JelleZijlstra
Copy link
Member

Please leave discussion of unrelated problems out of this issue. Feel free to open a new issue (or look for an existing one) if you have feedback that isn't related to this __mypy-replace method.

hauntsaninja pushed a commit that referenced this issue Nov 14, 2024
Addresses part of #18081

stubgen still does not handle dataclass transforms correctly but with
this change we make sure to never include private mypy generated symbols
in the stubs.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants