python / python/mypy

overload + decorator to transform callable into class protocol w/ attribute does not see the attribute

Aperta
#18,715 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

bug topic-overloads
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

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

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.