From df4317333dba6d8cd21eb8b5ae87d8cb79d544ea Mon Sep 17 00:00:00 2001 From: Bruno Date: Sun, 26 Oct 2025 09:28:16 -0700 Subject: [PATCH 1/3] Fix: Resolve TypeError in value_to_type on Python 3.13 (issue #1188) --- temporalio/converter.py | 6 +++++- tests/test_converter.py | 26 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/temporalio/converter.py b/temporalio/converter.py index 29eb35566..ce5c5f2fd 100644 --- a/temporalio/converter.py +++ b/temporalio/converter.py @@ -1766,7 +1766,11 @@ def value_to_type( # Can't call isinstance if key_type is a newtype is_newtype = getattr(key_type, "__supertype__", None) - if is_newtype or not isinstance(key, key_type): + if ( + is_newtype + or not isinstance(key_type, type) + or not isinstance(key, key_type) + ): key = value_to_type(key_type, key, custom_converters) except Exception as err: raise TypeError( diff --git a/tests/test_converter.py b/tests/test_converter.py index e274b10d9..47e7c7f04 100644 --- a/tests/test_converter.py +++ b/tests/test_converter.py @@ -671,3 +671,29 @@ async def test_json_type_converter(): assert [addr, addr] == ( await custom_conv.decode([list_payload], [List[ipaddress.IPv4Address]]) )[0] + + +def test_value_to_type_literal_key(): + # The type for the dictionary's *key*: + KeyHint = Literal[ + "Key1", + "Key2", + ] + + # The type for the dictionary's *value* (the inner dict): + InnerKeyHint = Literal[ + "Inner1", + "Inner2", + ] + InnerValueHint = str | int | float | None + ValueHint = dict[InnerKeyHint, InnerValueHint] + + # The full type hint for the mapping: + hint_with_bug = dict[KeyHint, ValueHint] + + # A value that uses one of the literal keys: + value_to_convert = {"Key1": {"Inner1": 123.45, "Inner2": 10}} + custom_converters = [] + + # Function executes without error + value_to_type(hint_with_bug, value_to_convert, custom_converters) From 7f8b90ce235cf91d5faaf0de242c599c1c3e0d9b Mon Sep 17 00:00:00 2001 From: Bruno Date: Wed, 29 Oct 2025 16:39:20 -0700 Subject: [PATCH 2/3] fix poe linting --- tests/test_converter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_converter.py b/tests/test_converter.py index 47e7c7f04..a6a292dff 100644 --- a/tests/test_converter.py +++ b/tests/test_converter.py @@ -693,7 +693,7 @@ def test_value_to_type_literal_key(): # A value that uses one of the literal keys: value_to_convert = {"Key1": {"Inner1": 123.45, "Inner2": 10}} - custom_converters = [] + custom_converters: Sequence[JSONTypeConverter] = [] # Function executes without error value_to_type(hint_with_bug, value_to_convert, custom_converters) From fe5069b6168362f51745fed0a4598c48fd56f9c9 Mon Sep 17 00:00:00 2001 From: Bruno Date: Wed, 29 Oct 2025 16:45:57 -0700 Subject: [PATCH 3/3] replace newtype check 'https://github.com/temporalio/sdk-python/pull/1189#discussion_r2465951696' --- temporalio/converter.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/temporalio/converter.py b/temporalio/converter.py index ce5c5f2fd..92a5d72e2 100644 --- a/temporalio/converter.py +++ b/temporalio/converter.py @@ -1764,13 +1764,7 @@ def value_to_type( elif key_type is type(None): key = {"null": None}[key] - # Can't call isinstance if key_type is a newtype - is_newtype = getattr(key_type, "__supertype__", None) - if ( - is_newtype - or not isinstance(key_type, type) - or not isinstance(key, key_type) - ): + if not isinstance(key_type, type) or not isinstance(key, key_type): key = value_to_type(key_type, key, custom_converters) except Exception as err: raise TypeError(