Skip to content

Commit fb1717e

Browse files
Add a unit test for the expected behaviour when inheriting from an unparameterized generic base class (#40)
* Add a unit test for the expected behaviour when inheriting from an unparaemterized generic base class * update changelog * update test * fix mypy
1 parent 2f0c8a7 commit fb1717e

File tree

2 files changed

+49
-0
lines changed

2 files changed

+49
-0
lines changed

.changelog/_unreleased.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,11 @@ id = "0285c33d-85e6-4d72-bf09-7f8812b75e36"
33
type = "fix"
44
description = "Fix star import from `typeapi`"
55
author = "@NiklasRosenstein"
6+
pr = "https://github.com/NiklasRosenstein/python-typeapi/pull/39"
7+
8+
[[entries]]
9+
id = "233e97d3-9e6c-4330-ac8d-fe4a9ad8e3a5"
10+
type = "tests"
11+
description = "Add a unit test for the expected behaviour when inheriting from an unparameterized generic base class"
12+
author = "@NiklasRosenstein"
13+
pr = "https://github.com/NiklasRosenstein/python-typeapi/pull/40"

src/typeapi/typehint_test.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,47 @@ def test__TypeHint__from_newtype() -> None:
274274
assert hint.hint is MyInt
275275

276276

277+
def test__TypeHint__from_generic_with_unbound_typevar() -> None:
278+
"""
279+
Inheriting from a generic base class without parameterizing it is not valid and databind cannot handle the
280+
case correctly. The `TypeHint.bases` will appear as the bases' bases (that is because `__orig_bases__` is not
281+
set on the new subclass and instead it reads the attribute from the parent).
282+
"""
283+
284+
T = TypeVar("T")
285+
U = TypeVar("U")
286+
287+
class Base(Generic[T]):
288+
a: int
289+
290+
class Incorrect(Base): # type: ignore[type-arg]
291+
b: str
292+
293+
class Correct(Base[U]):
294+
b: str
295+
296+
hint = TypeHint(Base)
297+
assert isinstance(hint, ClassTypeHint)
298+
assert hint.type == Base
299+
assert hint.bases == (Generic[T],)
300+
assert hint.origin is None
301+
assert "__orig_bases__" in vars(Base)
302+
303+
hint = TypeHint(Incorrect)
304+
assert isinstance(hint, ClassTypeHint)
305+
assert hint.type == Incorrect
306+
assert hint.bases == (Generic[T],) # Note how this is not (Base,)
307+
assert hint.origin is None
308+
assert "__orig_bases__" not in vars(Incorrect)
309+
310+
hint = TypeHint(Correct)
311+
assert isinstance(hint, ClassTypeHint)
312+
assert hint.type == Correct
313+
assert hint.bases == (Base[U],) # type: ignore[valid-type]
314+
assert hint.origin is None
315+
assert "__orig_bases__" in vars(Correct)
316+
317+
277318
def test__ClassTypeHint__parametrize() -> None:
278319
"""This method tests the infusion of type parameters into other types.
279320

0 commit comments

Comments
 (0)