mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-30 13:51:16 +00:00
[ty] Use fully qualified names to distinguish ambiguous protocols in diagnostics (#20627)
This commit is contained in:
parent
803d61e21f
commit
1cf19732b9
2 changed files with 39 additions and 2 deletions
|
@ -170,6 +170,36 @@ class Container(Generic[T]):
|
||||||
|
|
||||||
## Protocols
|
## Protocols
|
||||||
|
|
||||||
|
### Differing members
|
||||||
|
|
||||||
|
`bad.py`:
|
||||||
|
|
||||||
|
```py
|
||||||
|
from typing import Protocol, TypeVar
|
||||||
|
|
||||||
|
T_co = TypeVar("T_co", covariant=True)
|
||||||
|
|
||||||
|
class Iterator(Protocol[T_co]):
|
||||||
|
def __nexxt__(self) -> T_co: ...
|
||||||
|
|
||||||
|
def bad() -> Iterator[str]:
|
||||||
|
raise NotImplementedError
|
||||||
|
```
|
||||||
|
|
||||||
|
`main.py`:
|
||||||
|
|
||||||
|
```py
|
||||||
|
from typing import Iterator
|
||||||
|
|
||||||
|
def f() -> Iterator[str]:
|
||||||
|
import bad
|
||||||
|
|
||||||
|
# error: [invalid-return-type] "Return type does not match returned value: expected `typing.Iterator[str]`, found `bad.Iterator[str]"
|
||||||
|
return bad.bad()
|
||||||
|
```
|
||||||
|
|
||||||
|
### Same members but with different types
|
||||||
|
|
||||||
```py
|
```py
|
||||||
from typing import Protocol
|
from typing import Protocol
|
||||||
import proto_a
|
import proto_a
|
||||||
|
|
|
@ -22,8 +22,8 @@ use crate::types::tuple::TupleSpec;
|
||||||
use crate::types::visitor::TypeVisitor;
|
use crate::types::visitor::TypeVisitor;
|
||||||
use crate::types::{
|
use crate::types::{
|
||||||
BoundTypeVarInstance, CallableType, IntersectionType, KnownBoundMethodType, KnownClass,
|
BoundTypeVarInstance, CallableType, IntersectionType, KnownBoundMethodType, KnownClass,
|
||||||
MaterializationKind, Protocol, StringLiteralType, SubclassOfInner, Type, UnionType,
|
MaterializationKind, Protocol, ProtocolInstanceType, StringLiteralType, SubclassOfInner, Type,
|
||||||
WrapperDescriptorKind, visitor,
|
UnionType, WrapperDescriptorKind, visitor,
|
||||||
};
|
};
|
||||||
use ruff_db::parsed::parsed_module;
|
use ruff_db::parsed::parsed_module;
|
||||||
|
|
||||||
|
@ -128,6 +128,13 @@ impl<'db> super::visitor::TypeVisitor<'db> for AmbiguousClassCollector<'db> {
|
||||||
Type::ClassLiteral(class) => self.record_class(db, class),
|
Type::ClassLiteral(class) => self.record_class(db, class),
|
||||||
Type::EnumLiteral(literal) => self.record_class(db, literal.enum_class(db)),
|
Type::EnumLiteral(literal) => self.record_class(db, literal.enum_class(db)),
|
||||||
Type::GenericAlias(alias) => self.record_class(db, alias.origin(db)),
|
Type::GenericAlias(alias) => self.record_class(db, alias.origin(db)),
|
||||||
|
// Visit the class (as if it were a nominal-instance type)
|
||||||
|
// rather than the protocol members, if it is a class-based protocol.
|
||||||
|
// (For the purposes of displaying the type, we'll use the class name.)
|
||||||
|
Type::ProtocolInstance(ProtocolInstanceType {
|
||||||
|
inner: Protocol::FromClass(class),
|
||||||
|
..
|
||||||
|
}) => return self.visit_type(db, Type::from(class)),
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue