python / python/mypy

should mypy recognize pep-681 @dataclass_transform on a method as well as a function?

Offen
#19,824 2 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

feature needs discussion topic-dataclass-transform
Vorherrschende Sprache
Python
Sterne
20.6k
Forks
3.3k
PR-Merge-Kennzahlen
PR-Kennzahlen ausstehend

Beschreibung

Just noticed that trying to make an object method provide @dataclass_transform functionality is not recognized by mypy as a pep-681 use of @dataclass_transform (it does not complain either, just silently ignores it):

from typing import dataclass_transform

class SomeClassThing:
    @dataclass_transform()
    def make_a_dataclass(self, cls: type) -> type:
        return cls

sct = SomeClassThing()

@sct.make_a_dataclass
class MyClass:
    x: int
    y: str

m1 = MyClass(x=5, y="y")

mypy:

test4.py:16: error: Unexpected keyword argument "x" for "MyClass"  [call-arg]
test4.py:16: error: Unexpected keyword argument "y" for "MyClass"  [call-arg]
Found 2 errors in 1 file (checked 1 source file)

the above would need to be reorganized like this:

from typing import Callable
from typing import dataclass_transform

class SomeClassThing:
    pass

@dataclass_transform()
def make_a_dataclass(sct: SomeClassThing) -> Callable[[type], type]:
    def decorate(cls: type) -> type:
        return cls
    return decorate

sct = SomeClassThing()

@make_a_dataclass(sct)
class MyClass:
    x: int
    y: str

m1 = MyClass(x=5, y="y")

where mypy is happy:

Success: no issues found in 1 source file

SQLAlchemy has a pep-681 feature that mostly uses the superclass approach, however we also offer a decorator that looks like @mapper_registry.mapped_as_dataclass(), and I just noticed that while pyright has always accepted this, mypy does not. So I'm adding an alternative decorator of the above form @mapped_as_dataclass(mapper_registry). Took a look at pep-681 and it discusses @dataclass_transform applied to a function or a class, not a method. So I'm out of luck. but it seems ....like it should work? pyright does it....

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne mit dem methodenbasierten Reproduzierer im Issue und lies die Regeln von PEP 681 dazu, wo @dataclass_transform angewendet werden darf. Vergleiche das Verhalten mit dem funktionsbasierten Beispiel und pyright und bestimme dann, ob Methodenunterstützung spezifiziert ist; fertig ist die Aufgabe, wenn mypy den Decorator konsistent verarbeitet oder die nicht unterstützte Form eindeutig ablehnt.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
python
Bereich
devtools
Issue-Typ
Feature
Schwierigkeit
5/5
Geschätzter Aufwand
Über eine Woche
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
35/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.