@@ -1471,22 +1471,39 @@ def value_to_type(
14711471 )
14721472 # Convert each key/value
14731473 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
14801474 this_value_type = value_type
14811475 if per_key_types :
14821476 # TODO(cretz): Strict mode would fail an unknown key
14831477 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+
14841501 if this_value_type :
14851502 try :
14861503 value = value_to_type (this_value_type , value , custom_converters )
14871504 except Exception as err :
14881505 raise TypeError (
1489- f"Failed converting value for key { key } on { hint } "
1506+ f"Failed converting value for key { repr ( key ) } in mapping { hint } "
14901507 ) from err
14911508 ret_dict [key ] = value
14921509 # If there are per-key types, it's a typed dict and we want to attempt
0 commit comments