Skip to content

Unsatisfyable descriptors: mark defintion, not usage #9373

Open
@wabu

Description

@wabu

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions