python / python/mypy

`--extra-checks` is too strict when using `Concatenate` within a `Protocol`

Aperta
#17,122 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

bug topic-paramspec
Lingua principale
Python
Stelle
20.6k
Fork
3.3k
Metriche di merge delle PR
Metriche PR in attesa

Descrizione

Bug Report

This is admittedly a fairly niche use-case, but this came up when adding more precise type hints to itsdangerous and trying to write a Protocol that accepts any object that has a loads and dumps method where dumps can take arbitrary extra keyword arguments.

The docs for --extra-checks state that uses of Concatenate will force positional-only for equality, but this seems incorrect to me in the specific case of a property on a Protocol, since we're performing a structural match against methods there. *args: Any, **kwargs: Any doesn't really work, because it will only be recognized as a gradual extension of the method by some type checkers and not consistently, it's also not part of the typing spec, unless I'm mistaken. So Concatenate with ... is the only way to spell this.

To Reproduce
mypy Playground

import typing as t
import typing_extensions as te

class _PDataSerializer(t.Protocol[t.AnyStr]):
    def loads(self, payload: t.AnyStr, /) -> t.Any: ...
    @property
    def dumps(self) -> t.Callable[te.Concatenate[t.Any, ...], t.AnyStr]: ...
    
class MySerializer:
    def loads(self, payload: bytes) -> t.Any: ...
    def dumps(self, obj: object, *, some_required_option: bool) -> bytes:
        return NotImplemented
    
foo: _PDataSerializer[bytes] = MySerializer()

Expected Behavior

I would expect MySerializer to match the Protocol in my example. As soon as I change the payload argument to positional-only it does. It also does if I disable --extra-checks.

Actual Behavior

It is rejected based on the first argument not being positional-only.

Your Environment

  • Mypy version used: 1.9.0
  • Mypy command-line flags: --strict
  • Mypy configuration options from mypy.ini (and other config files):
  • Python version used: 3.8-3.12

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 collegata di mypy Playground con --strict e confronta il comportamento con --extra-checks disabilitato. Analizza la gestione di Concatenate e la corrispondenza strutturale dei metodi di Protocol; il lavoro è completato quando l’assegnazione mostrata di MySerializer viene accettata senza richiedere che il primo argomento sia positional-only.

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
35/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.