Skip to content

Commit e951039

Browse files
committed
Fix problem with np.array related to type[T]
1 parent d85469e commit e951039

File tree

2 files changed

+28
-12
lines changed

2 files changed

+28
-12
lines changed

crates/ty_python_semantic/resources/mdtest/implicit_type_aliases.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,14 +500,27 @@ def _(
500500
A generic implicit type alias can also be used in another generic implicit type alias:
501501

502502
```py
503+
from typing_extensions import Any
504+
505+
B = TypeVar("B", bound=int)
506+
503507
MyOtherList = MyList[T]
508+
MyOtherType = MyType[T]
509+
TypeOrList = MyType[B] | MyList[B]
504510

505511
reveal_type(MyOtherList) # revealed: <class 'list[T@MyOtherList]'>
512+
reveal_type(MyOtherType) # revealed: GenericAlias
513+
reveal_type(TypeOrList) # revealed: types.UnionType
506514

507515
def _(
508516
list_of_ints: MyOtherList[int],
517+
subclass_of_int: MyOtherType[int],
518+
type_or_list: TypeOrList[Any],
509519
):
510520
reveal_type(list_of_ints) # revealed: list[int]
521+
reveal_type(subclass_of_int) # revealed: type[int]
522+
# TODO: Should be `type[Any] | list[Any]`
523+
reveal_type(type_or_list) # revealed: @Todo(type[T]) | list[Any]
511524
```
512525

513526
If a generic implicit type alias is used unspecialized in a type expression, we treat it as an
@@ -1456,3 +1469,14 @@ def _(
14561469
reveal_type(recursive_dict3) # revealed: dict[Divergent, int]
14571470
reveal_type(recursive_dict4) # revealed: dict[Divergent, int]
14581471
```
1472+
1473+
### Self-referential generic implicit type aliases
1474+
1475+
<!-- expect-panic: execute: too many cycle iterations -->
1476+
1477+
```py
1478+
from typing import TypeVar
1479+
1480+
T = TypeVar("T")
1481+
NestedDict = dict[str, "NestedDict[T] | T"]
1482+
```

crates/ty_python_semantic/src/types.rs

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6799,7 +6799,7 @@ impl<'db> Type<'db> {
67996799
}
68006800
KnownInstanceType::Literal(ty) => Ok(ty.inner(db)),
68016801
KnownInstanceType::Annotated(ty) => Ok(ty.inner(db)),
6802-
KnownInstanceType::TypeGenericAlias(ty) => {
6802+
KnownInstanceType::TypeGenericAlias(instance) => {
68036803
// When `type[…]` appears in a value position (e.g. in an implicit type alias),
68046804
// we infer its argument as a type expression. This ensures that we can emit
68056805
// diagnostics for invalid type expressions, and more importantly, that we can
@@ -6808,7 +6808,7 @@ impl<'db> Type<'db> {
68086808
// (`int` -> instance of `int` -> subclass of `int`) can be lossy, but it is
68096809
// okay for all valid arguments to `type[…]`.
68106810

6811-
Ok(ty.inner(db).to_meta_type(db))
6811+
Ok(instance.inner(db).to_meta_type(db))
68126812
}
68136813
KnownInstanceType::Callable(instance) => {
68146814
Ok(Type::Callable(instance.callable_type(db)))
@@ -7046,16 +7046,8 @@ impl<'db> Type<'db> {
70467046
}
70477047
Type::Callable(_) | Type::DataclassTransformer(_) => KnownClass::Type.to_instance(db),
70487048
Type::ModuleLiteral(_) => KnownClass::ModuleType.to_class_literal(db),
7049-
Type::TypeVar(bound_typevar) => {
7050-
match bound_typevar.typevar(db).bound_or_constraints(db) {
7051-
None => KnownClass::Type.to_instance(db),
7052-
Some(TypeVarBoundOrConstraints::UpperBound(bound)) => bound.to_meta_type(db),
7053-
Some(TypeVarBoundOrConstraints::Constraints(constraints)) => {
7054-
// TODO: If we add a proper `OneOf` connector, we should use that here instead
7055-
// of union. (Using a union here doesn't break anything, but it is imprecise.)
7056-
constraints.map(db, |constraint| constraint.to_meta_type(db))
7057-
}
7058-
}
7049+
Type::TypeVar(_) => {
7050+
todo_type!("type[T]")
70597051
}
70607052

70617053
Type::ClassLiteral(class) => class.metaclass(db),

0 commit comments

Comments
 (0)