diff --git a/.changeset/array_without_items_is_list_of_any.md b/.changeset/array_without_items_is_list_of_any.md new file mode 100644 index 000000000..f9c1d8a0e --- /dev/null +++ b/.changeset/array_without_items_is_list_of_any.md @@ -0,0 +1,11 @@ +--- +default: patch +--- + +# Treat `type: array` without `items` as a list of Any + +An array schema with neither `items` nor `prefixItems` is valid in JSON Schema +2020-12 (OpenAPI 3.1) and means "array of any type". Previously the generator +failed such schemas with a `PropertyError` ("type array must have items or +prefixItems defined"), silently skipping the property or `anyOf` branch. It now +generates a `list[Any]`, equivalent to `items: {}`. diff --git a/openapi_python_client/parser/properties/list_property.py b/openapi_python_client/parser/properties/list_property.py index e331cddb4..3175e59b9 100644 --- a/openapi_python_client/parser/properties/list_property.py +++ b/openapi_python_client/parser/properties/list_property.py @@ -58,20 +58,17 @@ def build( """ from . import property_from_data # noqa: PLC0415 - if data.items is None and not data.prefixItems: - return ( - PropertyError( - data=data, - detail="type array must have items or prefixItems defined", - ), - schemas, - ) - items = data.prefixItems or [] if data.items: items.append(data.items) - if len(items) == 1: + if not items: + # An array with neither `items` nor `prefixItems` is valid in JSON + # Schema 2020-12 (OpenAPI 3.1) and means "array of any type". Treat + # it as equivalent to `items: {}` and generate a list of Any rather + # than failing. See issue #1435. + inner_schema: oai.Schema | oai.Reference = oai.Schema() + elif len(items) == 1: inner_schema = items[0] else: inner_schema = oai.Schema(anyOf=items) diff --git a/tests/test_parser/test_properties/test_init.py b/tests/test_parser/test_properties/test_init.py index 09446414f..181973c4a 100644 --- a/tests/test_parser/test_properties/test_init.py +++ b/tests/test_parser/test_properties/test_init.py @@ -3,7 +3,9 @@ import openapi_python_client.schema as oai from openapi_python_client.parser.errors import PropertyError from openapi_python_client.parser.properties import ( + AnyProperty, Class, + ListProperty, ReferencePath, Schemas, _propogate_removal, @@ -323,3 +325,23 @@ def test_propogate_removal_ref_path_already_removed(self): assert schemas.classes_by_name == {class_name: None} assert schemas.classes_by_reference == {ref_path: None} assert not error.detail + + +class TestArrayWithoutItems: + def test_array_without_items_becomes_list_of_any(self, config): + """Issue #1435: `{"type": "array"}` with no `items`/`prefixItems` is + valid in OpenAPI 3.1 (JSON Schema 2020-12) and means "array of any". It + must generate a list of Any instead of failing with a PropertyError.""" + data = oai.Schema(type="array", description="anything") + prop, _ = property_from_data( + name=UntrustedString("metrics"), + required=True, + data=data, + schemas=Schemas(), + parent_name="parent", + config=config, + ) + + assert isinstance(prop, ListProperty) + assert isinstance(prop.inner_property, AnyProperty) + assert prop.get_base_type_string().as_unembedded_code() == "list[Any]"