Unsatisfyable descriptors: mark defintion, not usage
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 20.6k
- Forks
- 3.3k
- PR merge metrics
- PR metrics pending
Description
🚀 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.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
No source files or tests are named. Start by reproducing the descriptor example with mypy 0.782 and trace how descriptor types are checked at declaration versus access. Done means the incompatible descriptor is reported at its definition, with an actionable diagnostic, rather than only at ints.c.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100