Skip to content

Commit d56c5fb

Browse files
fix: ClassTypeHint.recurse_bases() now parameterizes type parameters.
1 parent b059fae commit d56c5fb

File tree

3 files changed

+54
-2
lines changed

3 files changed

+54
-2
lines changed

.changelog/_unreleased.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[[entries]]
2+
id = "984c08a5-3fa1-40d7-baa7-3886f8fd2548"
3+
type = "fix"
4+
description = "`ClassTypeHint.recurse_bases()` now parameterizes type parameters."
5+
author = "@NiklasRosenstein"

src/typeapi/typehint.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,10 @@ def recurse_bases(
320320
if response == "skip":
321321
continue
322322

323-
current_bases = cast(List[ClassTypeHint], [TypeHint(x, current.type).evaluate() for x in current.bases])
323+
current_bases = cast(
324+
List[ClassTypeHint],
325+
[TypeHint(x, current.type).evaluate().parameterize(current.get_parameter_map()) for x in current.bases],
326+
)
324327

325328
if order == "bfs":
326329
bases.extend(current_bases)

src/typeapi/typehint_test.py

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ def test__TypeHint__repeated() -> None:
502502
assert hint.repeated
503503

504504

505-
def test__ClassTypeHint__iter_all_bases() -> None:
505+
def test__ClassTypeHint__recurse_bases_generic() -> None:
506506
class A:
507507
pass
508508

@@ -512,6 +512,9 @@ class B(A, int):
512512
class C(B, Generic[T]):
513513
pass
514514

515+
class D(C[T]):
516+
pass
517+
515518
hint = TypeHint(C)
516519
assert isinstance(hint, ClassTypeHint)
517520
assert hint.type is C
@@ -536,3 +539,44 @@ class C(B, Generic[T]):
536539
TypeHint(Generic[T]),
537540
TypeHint(object),
538541
]
542+
543+
hint = TypeHint(D[int])
544+
assert isinstance(hint, ClassTypeHint)
545+
assert hint.type is D
546+
assert hint.bases == (C[T],)
547+
assert list(hint.recurse_bases("bfs")) == [
548+
TypeHint(D[int]),
549+
TypeHint(C[int]),
550+
TypeHint(B),
551+
TypeHint(Generic[T]),
552+
TypeHint(A),
553+
TypeHint(int),
554+
TypeHint(object),
555+
TypeHint(object),
556+
TypeHint(object),
557+
]
558+
559+
560+
def test__ClassTypeHint__recurse_bases_for_list_subclass() -> None:
561+
class CustomList(List[T]):
562+
pass
563+
564+
hint = TypeHint(CustomList)
565+
assert isinstance(hint, ClassTypeHint)
566+
assert hint.type is CustomList
567+
assert hint.bases == (List[T],)
568+
assert list(hint.recurse_bases("bfs")) == [
569+
TypeHint(CustomList),
570+
TypeHint(List[T]),
571+
TypeHint(object),
572+
]
573+
574+
hint = TypeHint(CustomList[int])
575+
assert isinstance(hint, ClassTypeHint)
576+
assert hint.type is CustomList
577+
assert hint.bases == (List[T],)
578+
assert list(hint.recurse_bases("bfs")) == [
579+
TypeHint(CustomList[int]),
580+
TypeHint(List[int]),
581+
TypeHint(object),
582+
]

0 commit comments

Comments
 (0)