mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 02:39:12 +00:00
Fix member lookup for unions & intersections ignoring policy (#17066)
## Summary A quick fix for how union/intersection member search ins performed in Knot. ## Test Plan * Added a dunder method call test for Union, which exhibits the error * Also added an intersection error, but it is not triggering currently due to `call` logic not being fully implemented for intersections. --------- Co-authored-by: David Peter <mail@david-peter.de>
This commit is contained in:
parent
5f83a32553
commit
5c1fab0661
2 changed files with 30 additions and 2 deletions
|
@ -204,6 +204,28 @@ def _(flag: bool):
|
|||
reveal_type(d[0]) # revealed: str | bytes
|
||||
```
|
||||
|
||||
## Calling a union of types without dunder methods
|
||||
|
||||
We add instance attributes here to make sure that we don't treat the implicit dunder calls here like
|
||||
regular method calls.
|
||||
|
||||
```py
|
||||
def external_getitem(instance, key: int) -> str:
|
||||
return str(key)
|
||||
|
||||
class NotSubscriptable1:
|
||||
def __init__(self, value: int):
|
||||
self.__getitem__ = external_getitem
|
||||
|
||||
class NotSubscriptable2:
|
||||
def __init__(self, value: int):
|
||||
self.__getitem__ = external_getitem
|
||||
|
||||
def _(union: NotSubscriptable1 | NotSubscriptable2):
|
||||
# error: [non-subscriptable]
|
||||
union[0]
|
||||
```
|
||||
|
||||
## Calling a possibly-unbound dunder method
|
||||
|
||||
```py
|
||||
|
|
|
@ -1963,11 +1963,17 @@ impl<'db> Type<'db> {
|
|||
|
||||
match self {
|
||||
Type::Union(union) => union
|
||||
.map_with_boundness(db, |elem| elem.member(db, &name).symbol)
|
||||
.map_with_boundness(db, |elem| {
|
||||
elem.member_lookup_with_policy(db, name_str.into(), policy)
|
||||
.symbol
|
||||
})
|
||||
.into(),
|
||||
|
||||
Type::Intersection(intersection) => intersection
|
||||
.map_with_boundness(db, |elem| elem.member(db, &name).symbol)
|
||||
.map_with_boundness(db, |elem| {
|
||||
elem.member_lookup_with_policy(db, name_str.into(), policy)
|
||||
.symbol
|
||||
})
|
||||
.into(),
|
||||
|
||||
Type::Dynamic(..) | Type::Never => Symbol::bound(self).into(),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue