@@ -259,6 +259,42 @@ def test_output_type_deserialization_legacy_ellipsis_literal():
259259 assert deserialize_type ("typing.Callable[Ellipsis, int]" ) == Callable [..., int ]
260260
261261
262+ def test_output_type_serialization_callable_with_parameter_list ():
263+ # `Callable[[X, Y], R]` returns its parameter list from `typing.get_args` as a Python list ([X, Y]),
264+ # not as a type. It must be serialized as "[X, Y]" so the parameters survive the round-trip.
265+ assert serialize_type (Callable [[int , str ], bool ]) == "typing.Callable[[int, str], bool]"
266+ assert serialize_type (Callable [[], int ]) == "typing.Callable[[], int]"
267+ assert serialize_type (Callable [[int ], List [str ]]) == "typing.Callable[[int], typing.List[str]]"
268+ assert serialize_type (Callable [[Union [str , int ]], bool ]) == "typing.Callable[[typing.Union[str, int]], bool]"
269+
270+
271+ def test_output_type_deserialization_callable_with_parameter_list ():
272+ assert deserialize_type ("typing.Callable[[int, str], bool]" ) == Callable [[int , str ], bool ]
273+ assert deserialize_type ("typing.Callable[[], int]" ) == Callable [[], int ]
274+ assert deserialize_type ("typing.Callable[[int], typing.List[str]]" ) == Callable [[int ], List [str ]]
275+ assert deserialize_type ("typing.Callable[[typing.Union[str, int]], bool]" ) == Callable [[Union [str , int ]], bool ]
276+
277+
278+ def test_output_type_round_trip_callable_with_parameter_list ():
279+ for type_ in [
280+ Callable [[int , str ], bool ],
281+ Callable [[], int ],
282+ Callable [[int ], List [str ]],
283+ Callable [[Dict [str , int ], str ], List [bool ]],
284+ Callable [[Union [str , int ]], bool ],
285+ List [Callable [[int ], str ]],
286+ Dict [str , Callable [[int , str ], bool ]],
287+ Optional [Callable [[int ], str ]],
288+ Callable [[Callable [[int ], str ]], bool ],
289+ # The Ellipsis form (no parameter list) must still round-trip unaffected by the parameter-list
290+ # handling above: `_serialize_type_arg`/`_deserialize_type_arg` only special-case a `list` argument,
291+ # so `...` still falls through to the existing Ellipsis handling in serialize_type/deserialize_type.
292+ Callable [..., int ],
293+ Callable [[int ], Callable [..., str ]],
294+ ]:
295+ assert deserialize_type (serialize_type (type_ )) == type_
296+
297+
262298def test_output_type_serialization_haystack_dataclasses ():
263299 # typing
264300 # Answer
0 commit comments