Skip to content

Commit 65982a1

Browse files
authored
[ty] Use 'unknown' specialization for upper bound on Self (#20325)
## Summary closes astral-sh/ty#1156 ## Test Plan Added a regression test
1 parent 57d1f71 commit 65982a1

File tree

2 files changed

+19
-4
lines changed

2 files changed

+19
-4
lines changed

crates/ty_python_semantic/resources/mdtest/annotations/self.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
```toml
44
[environment]
5-
python-version = "3.11"
5+
python-version = "3.13"
66
```
77

88
`Self` is treated as if it were a `TypeVar` bound to the class it's being used on.
@@ -147,6 +147,23 @@ class Shape:
147147
return self
148148
```
149149

150+
## `Self` for classes with a default value for their generic parameter
151+
152+
This is a regression test for <https://github.com/astral-sh/ty/issues/1156>.
153+
154+
```py
155+
from typing import Self
156+
157+
class Container[T = bytes]:
158+
def __init__(self: Self, data: T | None = None) -> None:
159+
self.data = data
160+
161+
reveal_type(Container()) # revealed: Container[bytes]
162+
reveal_type(Container(1)) # revealed: Container[int]
163+
reveal_type(Container("a")) # revealed: Container[str]
164+
reveal_type(Container(b"a")) # revealed: Container[bytes]
165+
```
166+
150167
## Invalid Usage
151168

152169
`Self` cannot be used in the signature of a function or variable.

crates/ty_python_semantic/src/types.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5711,9 +5711,7 @@ impl<'db> Type<'db> {
57115711
],
57125712
});
57135713
};
5714-
let instance = Type::ClassLiteral(class).to_instance(db).expect(
5715-
"nearest_enclosing_class must return type that can be instantiated",
5716-
);
5714+
let instance = Type::instance(db, class.unknown_specialization(db));
57175715
let class_definition = class.definition(db);
57185716
let typevar = TypeVarInstance::new(
57195717
db,

0 commit comments

Comments
 (0)