From d90bcc8569bdcd94899de66520bdc509cdc24d9a Mon Sep 17 00:00:00 2001 From: Yurii Motov Date: Thu, 5 Feb 2026 15:15:00 +0100 Subject: [PATCH] Remove xfail for defaul_factory in openapi --- .../test_body/test_nullable_and_defaults.py | 40 +++++++++---------- .../test_file/test_nullable_and_defaults.py | 1 - .../test_form/test_nullable_and_defaults.py | 34 ++++++++-------- .../test_header/test_nullable_and_defaults.py | 27 ++++++++----- .../test_query/test_nullable_and_defaults.py | 33 +++++++-------- 5 files changed, 71 insertions(+), 64 deletions(-) diff --git a/tests/test_request_params/test_body/test_nullable_and_defaults.py b/tests/test_request_params/test_body/test_nullable_and_defaults.py index 7696f765fd..3f0afd5cad 100644 --- a/tests/test_request_params/test_body/test_nullable_and_defaults.py +++ b/tests/test_request_params/test_body/test_nullable_and_defaults.py @@ -2,7 +2,7 @@ from typing import Annotated, Any, Union from unittest.mock import Mock, patch import pytest -from dirty_equals import IsList, IsOneOf +from dirty_equals import IsList, IsOneOf, IsPartialDict from fastapi import Body, FastAPI from fastapi.testclient import TestClient from pydantic import BaseModel, BeforeValidator, field_validator @@ -811,20 +811,16 @@ async def read_nullable_with_non_null_default_no_embed_list( @pytest.mark.parametrize( "path", [ - pytest.param( - "/nullable-with-non-null-default", - marks=pytest.mark.xfail( - reason="`default_factory` is not reflected in OpenAPI schema" - ), - ), + "/nullable-with-non-null-default", "/model-nullable-with-non-null-default", ], ) def test_nullable_with_non_null_default_schema(path: str): openapi = app.openapi() body_model_name = get_body_model_name(openapi, path) + body_model = app.openapi()["components"]["schemas"][body_model_name] - assert app.openapi()["components"]["schemas"][body_model_name] == { + assert body_model == { "properties": { "int_val": { "title": "Int Val", @@ -836,19 +832,25 @@ def test_nullable_with_non_null_default_schema(path: str): "anyOf": [{"type": "string"}, {"type": "null"}], "default": "default", }, - "list_val": { - "title": "List Val", - "anyOf": [ - {"type": "array", "items": {"type": "integer"}}, - {"type": "null"}, - ], - "default": [0], # default_factory is not reflected in OpenAPI schema - }, + "list_val": IsPartialDict( + { + "title": "List Val", + "anyOf": [ + {"type": "array", "items": {"type": "integer"}}, + {"type": "null"}, + ], + }, + ), }, "title": body_model_name, "type": "object", } + if path == "/model-nullable-with-non-null-default": + # Check default value for list_val param for model-based Body parameters only. + # default_factory is not reflected in OpenAPI schema + assert body_model["properties"]["list_val"]["default"] == [0] + @pytest.mark.parametrize( ("path", "schema"), @@ -869,7 +871,7 @@ def test_nullable_with_non_null_default_schema(path: str): "default": -1, }, ), - pytest.param( + ( "/nullable-with-non-null-default-list", { "anyOf": [ @@ -877,11 +879,7 @@ def test_nullable_with_non_null_default_schema(path: str): {"type": "null"}, ], "title": "List Val", - "default": [0], # default_factory is not reflected in OpenAPI schema }, - marks=pytest.mark.xfail( - reason="`default_factory` is not reflected in OpenAPI schema" - ), ), ], ) diff --git a/tests/test_request_params/test_file/test_nullable_and_defaults.py b/tests/test_request_params/test_file/test_nullable_and_defaults.py index 5602aa6e53..ce862dc465 100644 --- a/tests/test_request_params/test_file/test_nullable_and_defaults.py +++ b/tests/test_request_params/test_file/test_nullable_and_defaults.py @@ -393,7 +393,6 @@ def test_nullable_with_non_null_default_schema(path: str): {"type": "array", "items": {"type": "string", "format": "binary"}}, {"type": "null"}, ], - # "default": None, # default_factory is not reflected in OpenAPI schema }, }, "title": body_model_name, diff --git a/tests/test_request_params/test_form/test_nullable_and_defaults.py b/tests/test_request_params/test_form/test_nullable_and_defaults.py index 2679da309a..6b9ac4c300 100644 --- a/tests/test_request_params/test_form/test_nullable_and_defaults.py +++ b/tests/test_request_params/test_form/test_nullable_and_defaults.py @@ -2,7 +2,7 @@ from typing import Annotated, Any, Union from unittest.mock import Mock, patch import pytest -from dirty_equals import IsList, IsOneOf +from dirty_equals import IsList, IsOneOf, IsPartialDict from fastapi import FastAPI, Form from fastapi.testclient import TestClient from pydantic import BaseModel, BeforeValidator, field_validator @@ -462,20 +462,16 @@ async def read_model_nullable_with_non_null_default( @pytest.mark.parametrize( "path", [ - pytest.param( - "/nullable-with-non-null-default", - marks=pytest.mark.xfail( - reason="`default_factory` is not reflected in OpenAPI schema" - ), - ), + "/nullable-with-non-null-default", "/model-nullable-with-non-null-default", ], ) def test_nullable_with_non_null_default_schema(path: str): openapi = app.openapi() body_model_name = get_body_model_name(openapi, path) + body_model = app.openapi()["components"]["schemas"][body_model_name] - assert app.openapi()["components"]["schemas"][body_model_name] == { + assert body_model == { "properties": { "int_val": { "title": "Int Val", @@ -487,19 +483,25 @@ def test_nullable_with_non_null_default_schema(path: str): "anyOf": [{"type": "string"}, {"type": "null"}], "default": "default", }, - "list_val": { - "title": "List Val", - "anyOf": [ - {"type": "array", "items": {"type": "integer"}}, - {"type": "null"}, - ], - "default": [0], # default_factory is not reflected in OpenAPI schema - }, + "list_val": IsPartialDict( + { + "title": "List Val", + "anyOf": [ + {"type": "array", "items": {"type": "integer"}}, + {"type": "null"}, + ], + } + ), }, "title": body_model_name, "type": "object", } + if path == "/model-nullable-with-non-null-default": + # Check default value for list_val param for model-based Body parameters only. + # default_factory is not reflected in OpenAPI schema + assert body_model["properties"]["list_val"]["default"] == [0] + @pytest.mark.parametrize( "path", diff --git a/tests/test_request_params/test_header/test_nullable_and_defaults.py b/tests/test_request_params/test_header/test_nullable_and_defaults.py index c871bbaeea..6cb555f374 100644 --- a/tests/test_request_params/test_header/test_nullable_and_defaults.py +++ b/tests/test_request_params/test_header/test_nullable_and_defaults.py @@ -2,7 +2,7 @@ from typing import Annotated, Any, Union from unittest.mock import Mock, patch import pytest -from dirty_equals import AnyThing, IsList, IsOneOf +from dirty_equals import AnyThing, IsList, IsOneOf, IsPartialDict from fastapi import FastAPI, Header from fastapi.testclient import TestClient from pydantic import BaseModel, BeforeValidator, field_validator @@ -420,7 +420,8 @@ async def read_model_nullable_with_non_null_default( ], ) def test_nullable_with_non_null_default_schema(path: str): - assert app.openapi()["paths"][path]["get"]["parameters"] == [ + parameters = app.openapi()["paths"][path]["get"]["parameters"] + assert parameters == [ { "required": False, "schema": { @@ -443,19 +444,25 @@ def test_nullable_with_non_null_default_schema(path: str): }, { "required": False, - "schema": { - "title": "List Val", - "anyOf": [ - {"type": "array", "items": {"type": "integer"}}, - {"type": "null"}, - ], - "default": [0], - }, + "schema": IsPartialDict( + { + "title": "List Val", + "anyOf": [ + {"type": "array", "items": {"type": "integer"}}, + {"type": "null"}, + ], + } + ), "name": "list-val", "in": "header", }, ] + if path == "/model-nullable-with-non-null-default": + # Check default value for list_val param for model-based Body parameters only. + # default_factory is not reflected in OpenAPI schema + assert parameters[2]["schema"]["default"] == [0] + @pytest.mark.parametrize( "path", diff --git a/tests/test_request_params/test_query/test_nullable_and_defaults.py b/tests/test_request_params/test_query/test_nullable_and_defaults.py index bca69444d0..f329e08886 100644 --- a/tests/test_request_params/test_query/test_nullable_and_defaults.py +++ b/tests/test_request_params/test_query/test_nullable_and_defaults.py @@ -2,7 +2,7 @@ from typing import Annotated, Any, Union from unittest.mock import Mock, patch import pytest -from dirty_equals import IsList, IsOneOf +from dirty_equals import IsList, IsOneOf, IsPartialDict from fastapi import FastAPI, Query from fastapi.testclient import TestClient from pydantic import BaseModel, BeforeValidator, field_validator @@ -378,17 +378,13 @@ async def read_model_nullable_with_non_null_default( @pytest.mark.parametrize( "path", [ - pytest.param( - "/nullable-with-non-null-default", - marks=pytest.mark.xfail( - reason="`default_factory` is not reflected in OpenAPI schema" - ), - ), + "/nullable-with-non-null-default", "/model-nullable-with-non-null-default", ], ) def test_nullable_with_non_null_default_schema(path: str): - assert app.openapi()["paths"][path]["get"]["parameters"] == [ + parameters = app.openapi()["paths"][path]["get"]["parameters"] + assert parameters == [ { "required": False, "schema": { @@ -413,17 +409,22 @@ def test_nullable_with_non_null_default_schema(path: str): "in": "query", "name": "list_val", "required": False, - "schema": { - "anyOf": [ - {"items": {"type": "integer"}, "type": "array"}, - {"type": "null"}, - ], - "title": "List Val", - "default": [0], # `default_factory` is not reflected in OpenAPI schema - }, + "schema": IsPartialDict( + { + "anyOf": [ + {"items": {"type": "integer"}, "type": "array"}, + {"type": "null"}, + ], + "title": "List Val", + } + ), }, ] + if path == "/model-nullable-with-non-null-default": + # Check default value for list_val param for model-based Body parameters only. + # default_factory is not reflected in OpenAPI schema + assert parameters[2]["schema"]["default"] == [0] @pytest.mark.parametrize( "path",