python / python/mypy

Unsatisfyable descriptors: mark defintion, not usage

Aperta
#9,373 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

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

Descrizione

🚀 Improvement

After #2266 merged, mypy is understanding and checking the usage of the descriptor protocol. However, the validity of the types of a descriptor are only checked when the descriptor is used, not when it is declared: So you can define a descriptor that can never be accessed, as access to the descriptor will always result in a type error (see example below)

Versions

mypy 0.782
python 3.7.8

Pitch

Giving a error for unusable descriptors would help to find mistakes early on.

Furthermore, with the current error message when using such a descriptor, it is quite hard find the source of the problem, which is the descriptor instance itself, not the code where the descriptor is accessed.

Example


S = TypeVar('S', bound='Spec')
from __future__ import annotations
from typing import TypeVar, Type, overload, Generic

S = TypeVar("S", bound='Spec')

class Spec:
    def __init__(self, name):
        self.name = name

    @overload
    def __get__(self: S, obj: None, typ: Type[Service[S]]) -> S: ...
    @overload
    def __get__(self: S, obj: Service[S], typ: Type[Service[S]]) -> Service[S]: ...

    def __get__(self, obj, typ):
        if obj is None:
            self
        else:
            service.push(S)
            return obj.service

class Int(Spec):
    pass

class String(Spec):
    pass

class Service(Generic[S]):
    def push(self, S):
        ...

class IntService(Service[Int]):
    a = Int('a')
    b = Int('b')
    c = String('c')  # offending descriptor: obj in __get__ will be a Service[Int], but Service[String] is expected for String

def usage(ints: IntService):
    ints.a
    ints.c  # only this line will cause a typing issue and it has no indication to the offending definition 4 lines abouve

Only the last line currently is reporting an error: Argument 1 to "__get__" of "Spec" has incompatible type "IntService"; expected "Service[String]", the offending descriptor is silently ignored and it is quite hard to find that line from this error.

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

Non vengono indicati file sorgente o test. Inizia riproducendo l'esempio di descrittore con mypy 0.782 e traccia il modo in cui i tipi dei descrittori vengono controllati durante la dichiarazione rispetto all'accesso. Il lavoro è completato quando il descrittore incompatibile viene segnalato nella sua definizione, con una diagnosi attuabile, invece che solo in ints.c.

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

Valutazione

Stack tecnologico
python
Ambito
compilers
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.