overload + decorator to transform callable into class protocol w/ attribute does not see the attribute
Nessuno ha ancora preso questa issue.
- Lingua principale
- Python
- Stelle
- 20.6k
- Fork
- 3.3k
- Metriche di merge delle PR
- Metriche PR in attesa
Descrizione
Bug Report
Trying to combine function attributes (a la #2087) where we add the attribute with a decorator fails to apply the decorator and the attribute is dropped on the ground.
To Reproduce
from __future__ import annotations
from typing import overload, Callable, TypeVar, Protocol
from typing_extensions import ParamSpec, reveal_type
P = ParamSpec("P")
R = TypeVar("R", covariant=True)
class WithExtra(Protocol[P, R]):
extra: str
def __call__(self, *args: P.args, **kwargs: P.kwargs) -> R: ...
def add_extra(func: Callable[P, R]) -> WithExtra[P, R]:
func.extra = "added" # type: ignore
return func # type: ignore
@overload
@add_extra
def foo(x: int) -> str: ...
@overload
@add_extra
def foo(x: str) -> str: ...
@add_extra
def foo(x: int | str) -> str:
return str(x)
assert foo.extra # type: ignore[attr-defined]
reveal_type(foo) # Revealed type is "Overload(def (x: builtins.int) -> builtins.str, def (x: builtins.str) -> builtins.str)"
This works in pyright.
I feel like it should be possible to work around it with a callable class, but I've yet to figure out the proper incantation.
Real-life use: https://github.com/pytest-dev/pytest/blob/b0caf3d7adc45f773177424593431869fd2f82d8/src/_pytest/python_api.py#L1025
Your Environment
- Mypy version used: 1.14.1
- Mypy command-line flags: none
- Mypy configuration options from
mypy.ini(and other config files): none - Python version used: python 3.13.1
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Direzione di ricerca
Inizia eseguendo la riproduzione fornita con mypy 1.14.1 e verifica il tipo di overload rivelato e l'attributo aggiuntivo mancante. Traccia quindi i percorsi di analisi dei tipi di overload e decorator per identificare dove vengono perse le informazioni sul protocollo callable, poi aggiungi un test di regressione che mostri il risultato atteso consapevole degli attributi.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- python
- Ambito
- devtools
- Tipo di issue
- Bug
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Stato di attività
- Ferma
- Chiarezza
- Abbastanza chiara
- Idoneità per principianti
- 42/100