Skip to content

Commit d790468

Browse files
authored
Call JSON type converters recursively (#304)
Fixes #289
1 parent cd8cbf9 commit d790468

File tree

4 files changed

+27
-9
lines changed

4 files changed

+27
-9
lines changed

.github/workflows/build-binaries.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,10 @@ jobs:
5151
working-directory: temporalio/bridge
5252

5353
# Prepare
54-
- run: python -m pip install --upgrade wheel poetry poethepoet
54+
# Using fixed Poetry version until
55+
# https://github.com/python-poetry/poetry/issues/7611 and
56+
# https://github.com/python-poetry/poetry/pull/7694 are fixed
57+
- run: python -m pip install --upgrade wheel "poetry==1.3.2" poethepoet
5558
- run: poetry install --no-root -E opentelemetry
5659

5760
# Add the source dist only for Linux x64 for now

.github/workflows/ci.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,10 @@ jobs:
4545
uses: deadsnakes/action@v2.1.1
4646
with:
4747
python-version: ${{ matrix.python }}
48-
- run: python -m pip install --upgrade wheel poetry poethepoet
48+
# Using fixed Poetry version until
49+
# https://github.com/python-poetry/poetry/issues/7611 and
50+
# https://github.com/python-poetry/poetry/pull/7694 are fixed
51+
- run: python -m pip install --upgrade wheel "poetry==1.3.2" poethepoet
4952
- run: poetry install --no-root -E opentelemetry
5053
- run: poe lint
5154
- run: poe build-develop

temporalio/converter.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1209,7 +1209,7 @@ def value_to_type(
12091209
# of a supertype.
12101210
supertype = getattr(hint, "__supertype__", None)
12111211
if supertype:
1212-
return value_to_type(supertype, value)
1212+
return value_to_type(supertype, value, custom_converters)
12131213

12141214
# Load origin for other checks
12151215
origin = getattr(hint, "__origin__", hint)
@@ -1230,7 +1230,7 @@ def value_to_type(
12301230
# Try each one. Note, Optional is just a union w/ none.
12311231
for arg in type_args:
12321232
try:
1233-
return value_to_type(arg, value)
1233+
return value_to_type(arg, value, custom_converters)
12341234
except Exception:
12351235
pass
12361236
raise TypeError(f"Failed converting to {hint} from {value}")
@@ -1265,7 +1265,7 @@ def value_to_type(
12651265
for key, value in value.items():
12661266
if key_type:
12671267
try:
1268-
key = value_to_type(key_type, key)
1268+
key = value_to_type(key_type, key, custom_converters)
12691269
except Exception as err:
12701270
raise TypeError(f"Failed converting key {key} on {hint}") from err
12711271
# If there are per-key types, use it instead of single type
@@ -1275,7 +1275,7 @@ def value_to_type(
12751275
this_value_type = per_key_types.get(key)
12761276
if this_value_type:
12771277
try:
1278-
value = value_to_type(this_value_type, value)
1278+
value = value_to_type(this_value_type, value, custom_converters)
12791279
except Exception as err:
12801280
raise TypeError(
12811281
f"Failed converting value for key {key} on {hint}"
@@ -1307,7 +1307,7 @@ def value_to_type(
13071307
if field_value is not dataclasses.MISSING:
13081308
try:
13091309
field_values[field.name] = value_to_type(
1310-
field_hints[field.name], field_value
1310+
field_hints[field.name], field_value, custom_converters
13111311
)
13121312
except Exception as err:
13131313
raise TypeError(
@@ -1379,7 +1379,7 @@ def value_to_type(
13791379
f"Type {hint} only expecting {len(type_args)} values, got at least {i + 1}"
13801380
)
13811381
try:
1382-
ret_list.append(value_to_type(arg_type, item))
1382+
ret_list.append(value_to_type(arg_type, item, custom_converters))
13831383
except Exception as err:
13841384
raise TypeError(f"Failed converting {hint} index {i}") from err
13851385
# If tuple, set, or deque convert back to that type

tests/test_converter.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import annotations
22

33
import dataclasses
4+
import inspect
45
import ipaddress
56
import logging
67
import sys
@@ -551,7 +552,7 @@ class IPv4AddressJSONTypeConverter(JSONTypeConverter):
551552
def to_typed_value(
552553
self, hint: Type, value: Any
553554
) -> Union[Optional[Any], _JSONTypeConverterUnhandled]:
554-
if issubclass(hint, ipaddress.IPv4Address):
555+
if inspect.isclass(hint) and issubclass(hint, ipaddress.IPv4Address):
555556
return ipaddress.IPv4Address(value)
556557
return JSONTypeConverter.Unhandled
557558

@@ -565,14 +566,25 @@ async def test_json_type_converter():
565566
# Fails to encode with default
566567
with pytest.raises(TypeError):
567568
await DataConverter.default.encode([addr])
569+
with pytest.raises(TypeError):
570+
await DataConverter.default.encode([[addr, addr]])
568571

569572
# But encodes with custom
570573
payload = (await custom_conv.encode([addr]))[0]
571574
assert '"1.2.3.4"' == payload.data.decode()
575+
list_payload = (await custom_conv.encode([[addr, addr]]))[0]
576+
assert '["1.2.3.4","1.2.3.4"]' == list_payload.data.decode()
572577

573578
# Fails to decode with default
574579
with pytest.raises(TypeError):
575580
await DataConverter.default.decode([payload], [ipaddress.IPv4Address])
581+
with pytest.raises(TypeError):
582+
await DataConverter.default.decode(
583+
[list_payload], [List[ipaddress.IPv4Address]]
584+
)
576585

577586
# But decodes with custom
578587
assert addr == (await custom_conv.decode([payload], [ipaddress.IPv4Address]))[0]
588+
assert [addr, addr] == (
589+
await custom_conv.decode([list_payload], [List[ipaddress.IPv4Address]])
590+
)[0]

0 commit comments

Comments
 (0)