mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-02 06:41:23 +00:00
[red-knot] Fix descriptor __get__
call on class objects (#16304)
## Summary I spotted a minor mistake in my descriptor protocol implementation where `C.descriptor` would pass the meta type (`type`) of the type of `C` (`Literal[C]`) as the owner argument to `__get__`, instead of passing `Literal[C]` directly. ## Test Plan New test.
This commit is contained in:
parent
4dae09ecff
commit
3aa7ba31b1
2 changed files with 26 additions and 1 deletions
|
@ -285,6 +285,31 @@ C.descriptor = "something else"
|
||||||
reveal_type(C.descriptor) # revealed: Unknown | int
|
reveal_type(C.descriptor) # revealed: Unknown | int
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## `__get__` is called with correct arguments
|
||||||
|
|
||||||
|
```py
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
class TailoredForClassObjectAccess:
|
||||||
|
def __get__(self, instance: None, owner: type[C]) -> int:
|
||||||
|
return 1
|
||||||
|
|
||||||
|
class TailoredForInstanceAccess:
|
||||||
|
def __get__(self, instance: C, owner: type[C] | None = None) -> str:
|
||||||
|
return "a"
|
||||||
|
|
||||||
|
class C:
|
||||||
|
class_object_access: TailoredForClassObjectAccess = TailoredForClassObjectAccess()
|
||||||
|
instance_access: TailoredForInstanceAccess = TailoredForInstanceAccess()
|
||||||
|
|
||||||
|
reveal_type(C.class_object_access) # revealed: int
|
||||||
|
reveal_type(C().instance_access) # revealed: str
|
||||||
|
|
||||||
|
# TODO: These should emit a diagnostic
|
||||||
|
reveal_type(C().class_object_access) # revealed: TailoredForClassObjectAccess
|
||||||
|
reveal_type(C.instance_access) # revealed: TailoredForInstanceAccess
|
||||||
|
```
|
||||||
|
|
||||||
## Descriptors with incorrect `__get__` signature
|
## Descriptors with incorrect `__get__` signature
|
||||||
|
|
||||||
```py
|
```py
|
||||||
|
|
|
@ -1663,7 +1663,7 @@ impl<'db> Type<'db> {
|
||||||
let member = self.static_member(db, name);
|
let member = self.static_member(db, name);
|
||||||
|
|
||||||
let instance = None;
|
let instance = None;
|
||||||
let owner = self.to_meta_type(db);
|
let owner = *self;
|
||||||
|
|
||||||
// TODO: Handle `__get__` call errors (see above).
|
// TODO: Handle `__get__` call errors (see above).
|
||||||
member.map_type(|ty| ty.try_call_dunder_get(db, instance, owner).unwrap_or(ty))
|
member.map_type(|ty| ty.try_call_dunder_get(db, instance, owner).unwrap_or(ty))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue