Skip to content

Stubgen generates __mypy-replace method for @dataclass_transform #18081

Closed

Description

@KapJI

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

Activity

  1. hamdanal commented on Nov 2, 2024

    @hamdanal
    Collaborator

    Another problem is that stubgen swallows the @dataclass_transform decorator

  2. self-assigned this
    on Nov 2, 2024
  3. KapJI commented on Nov 5, 2024

    @KapJI
    ContributorAuthor

    @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.

  4. hamdanal commented on Nov 9, 2024

    @hamdanal
    Collaborator

    @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.

  5. bramstroker commented on Nov 9, 2024

    @bramstroker

    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.

  6. JelleZijlstra commented on Nov 9, 2024

    @JelleZijlstra
    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.

  7. hamdanal commented on Jan 25, 2025

    @hamdanal
    Collaborator

    Fixed by #18137 and #18418

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions