python / python/mypy

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

Aperta
#19,824 2 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

feature needs discussion topic-dataclass-transform
Lingua principale
Python
Stelle
20.6k
Fork
3.3k
Metriche di merge delle PR
Metriche PR in attesa

Descrizione

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

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia con il riproduttore basato sul metodo nell’issue e leggi le regole di PEP 681 su dove può essere applicato @dataclass_transform. Confronta il comportamento con l’esempio basato sulla funzione e con pyright, quindi determina se il supporto dei metodi è specificato; il lavoro è completato quando mypy gestisce il decoratore in modo coerente o rifiuta chiaramente la forma non supportata.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
python
Ambito
devtools
Tipo di issue
Funzionalità
Difficoltà
5/5
Tempo stimato
Più di una settimana
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
35/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.