diff --git a/apischema/json_schema/schema.py b/apischema/json_schema/schema.py index 3c327918..ac1aeef7 100644 --- a/apischema/json_schema/schema.py +++ b/apischema/json_schema/schema.py @@ -217,8 +217,8 @@ def mapping( with context_setter(self): self._ignore_first_ref = True key = self.visit(key_type) - if key["type"] != JsonType.STRING: - raise ValueError("Mapping types must string-convertible key") + if "type" not in key or key["type"] != JsonType.STRING: + raise ValueError("Mapping types must have string-convertible keys") value = self.visit(value_type) if "pattern" in key: return json_schema( diff --git a/tests/integration/test_deserialize_with_coercion.py b/tests/integration/test_deserialize_with_coercion.py index 0eea512f..61c954a3 100644 --- a/tests/integration/test_deserialize_with_coercion.py +++ b/tests/integration/test_deserialize_with_coercion.py @@ -23,11 +23,7 @@ def test_coerce_json(): key = "test" value = 2 ret = deserialize( - MyClass, - { - "my_property": f'{{"{key}": {value}}}', - }, - coerce=_coerce_json, + MyClass, {"my_property": f'{{"{key}": {value}}}'}, coerce=_coerce_json ) assert isinstance(ret, MyClass) assert isinstance(ret.my_property, dict) and ret.my_property[key] == value diff --git a/tests/integration/test_typed_dict.py b/tests/integration/test_dict.py similarity index 81% rename from tests/integration/test_typed_dict.py rename to tests/integration/test_dict.py index 76fa6b48..6d1a3791 100644 --- a/tests/integration/test_typed_dict.py +++ b/tests/integration/test_dict.py @@ -1,4 +1,5 @@ from datetime import date +from typing import Any, Dict, Mapping import pytest @@ -8,6 +9,20 @@ from apischema.typing import Annotated, TypedDict +class MyDict(dict): + pass + + +@pytest.mark.parametrize( + "tp", [dict, Dict[int, Any], pytest.param(MyDict, marks=pytest.mark.xfail), Mapping] +) +def test_dict(tp): + with pytest.raises(ValueError, match="string-convertible keys"): + deserialization_schema(tp) + with pytest.raises(ValueError, match="string-convertible keys"): + serialization_schema(tp) + + class TD1(TypedDict, total=False): key1: str