From 2f20cc44aea8ad3bdd1723bf9a6807f7b010d5c9 Mon Sep 17 00:00:00 2001 From: Oliver Tosky <42260747+otosky@users.noreply.github.com> Date: Sat, 28 Dec 2024 07:45:31 -0500 Subject: [PATCH] fix: unravel Optional to inner generic arg from instance (#2172) * fix: unravel Optional to inner generic arg from instance * test: remove dependency on Incremental in common * refactor: use extract_inner_type * refactor: remove redundant conditional --- dlt/common/typing.py | 3 +-- tests/common/test_typing.py | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/dlt/common/typing.py b/dlt/common/typing.py index a0322fe01e..9866b72ed1 100644 --- a/dlt/common/typing.py +++ b/dlt/common/typing.py @@ -438,8 +438,7 @@ def get_generic_type_argument_from_instance( """ orig_param_type = Any if cls_ := getattr(instance, "__orig_class__", None): - # instance of generic class - pass + cls_ = extract_inner_type(cls_) elif bases_ := get_original_bases(instance.__class__): # instance of class deriving from generic cls_ = bases_[0] diff --git a/tests/common/test_typing.py b/tests/common/test_typing.py index e81c3e7fa2..a298e7d50c 100644 --- a/tests/common/test_typing.py +++ b/tests/common/test_typing.py @@ -1,3 +1,5 @@ +from types import SimpleNamespace + import pytest from dataclasses import dataclass from typing import ( @@ -5,6 +7,7 @@ Callable, ClassVar, Final, + Generic, List, Literal, Mapping, @@ -44,6 +47,7 @@ is_annotated, is_callable_type, add_value_to_literal, + get_generic_type_argument_from_instance, ) @@ -310,3 +314,22 @@ def test_add_value_to_literal() -> None: add_value_to_literal(TestSingleLiteral, "green") add_value_to_literal(TestSingleLiteral, "blue") assert get_args(TestSingleLiteral) == ("red", "green", "blue") + + +def test_get_generic_type_argument_from_instance() -> None: + T = TypeVar("T") + + class Foo(Generic[T]): + pass + + # generic contains hint + instance = SimpleNamespace(__orig_class__=Foo[str]) + assert get_generic_type_argument_from_instance(instance) is str + instance = SimpleNamespace(__orig_class__=Optional[Foo[str]]) + assert get_generic_type_argument_from_instance(instance) is str + + # with sample values + instance = SimpleNamespace(__orig_class__=Foo[Any]) + assert get_generic_type_argument_from_instance(instance, 1) is int + instance = SimpleNamespace(__orig_class__=Optional[Foo[Any]]) + assert get_generic_type_argument_from_instance(instance, 1) is int