@@ -1471,22 +1471,39 @@ def value_to_type(
1471
1471
)
1472
1472
# Convert each key/value
1473
1473
for key , value in value .items ():
1474
- if key_type :
1475
- try :
1476
- key = value_to_type (key_type , key , custom_converters )
1477
- except Exception as err :
1478
- raise TypeError (f"Failed converting key { key } on { hint } " ) from err
1479
- # If there are per-key types, use it instead of single type
1480
1474
this_value_type = value_type
1481
1475
if per_key_types :
1482
1476
# TODO(cretz): Strict mode would fail an unknown key
1483
1477
this_value_type = per_key_types .get (key )
1478
+
1479
+ if key_type :
1480
+ # This function is used only by JSONPlainPayloadConverter. When
1481
+ # serializing to JSON, Python supports key types str, int, float, bool,
1482
+ # and None, serializing all to string representations. We now attempt to
1483
+ # use the provided type annotation to recover the original value with its
1484
+ # original type.
1485
+ try :
1486
+ if isinstance (key , str ):
1487
+ if key_type is int or key_type is float :
1488
+ key = key_type (key )
1489
+ elif key_type is bool :
1490
+ key = {"true" : True , "false" : False }[key ]
1491
+ elif key_type is type (None ):
1492
+ key = {"null" : None }[key ]
1493
+
1494
+ if not isinstance (key , key_type ):
1495
+ key = value_to_type (key_type , key , custom_converters )
1496
+ except Exception as err :
1497
+ raise TypeError (
1498
+ f"Failed converting key { repr (key )} to type { key_type } in mapping { hint } "
1499
+ ) from err
1500
+
1484
1501
if this_value_type :
1485
1502
try :
1486
1503
value = value_to_type (this_value_type , value , custom_converters )
1487
1504
except Exception as err :
1488
1505
raise TypeError (
1489
- f"Failed converting value for key { key } on { hint } "
1506
+ f"Failed converting value for key { repr ( key ) } in mapping { hint } "
1490
1507
) from err
1491
1508
ret_dict [key ] = value
1492
1509
# If there are per-key types, it's a typed dict and we want to attempt
0 commit comments