From 0d48a4494fc60d350ed1b10a88edc8b06f716d65 Mon Sep 17 00:00:00 2001 From: jeremy Date: Wed, 29 Jan 2025 20:41:39 -0500 Subject: [PATCH 1/2] relax pydantic, pydantic-settings, and uvicorn --- pyproject.toml | 6 ++-- tests/server/fastmcp/test_func_metadata.py | 42 +++++++++++++++++++++- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 31a54944e..05494d85f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,11 +25,11 @@ dependencies = [ "anyio>=4.5", "httpx>=0.27", "httpx-sse>=0.4", - "pydantic>=2.10.1,<3.0.0", + "pydantic>=2.7.2,<3.0.0", "starlette>=0.27", "sse-starlette>=1.6.1", - "pydantic-settings>=2.6.1", - "uvicorn>=0.30", + "pydantic-settings>=2.5.2", + "uvicorn>=0.23.1", ] [project.optional-dependencies] diff --git a/tests/server/fastmcp/test_func_metadata.py b/tests/server/fastmcp/test_func_metadata.py index 7173b43b2..79922799e 100644 --- a/tests/server/fastmcp/test_func_metadata.py +++ b/tests/server/fastmcp/test_func_metadata.py @@ -235,8 +235,48 @@ async def check_call(args): def test_complex_function_json_schema(): + """Test JSON schema generation for complex function arguments. + + Note: This test accepts two equivalent JSON Schema formats for models with defaults: + 1. Pre-pydantic 2.7.2: + { + "$ref": "#/$defs/Model", + "default": {} + } + + 2. Pydantic 2.7.2+: + { + "allOf": [ + { + "$ref": "#/$defs/Model" + } + ], + "default": {} + } + + Both formats are valid JSON Schema and represent the same validation rules. + The newer format using allOf is more correct according to the JSON Schema spec + as it properly composes the reference with additional properties. + + This change in format does not affect runtime behavior since: + 1. Both schemas validate the same way + 2. The actual model classes and validation logic are unchanged + 3. func_metadata uses model_validate/model_dump, not the schema directly + """ meta = func_metadata(complex_arguments_fn) - assert meta.arg_model.model_json_schema() == { + actual_schema = meta.arg_model.model_json_schema() + + # Create a copy of the actual schema to normalize + normalized_schema = actual_schema.copy() + + # Normalize the my_model_a_with_default field to handle both pydantic formats + if 'allOf' in actual_schema['properties']['my_model_a_with_default']: + normalized_schema['properties']['my_model_a_with_default'] = { + '$ref': '#/$defs/SomeInputModelA', + 'default': {} + } + + assert normalized_schema == { "$defs": { "InnerModel": { "properties": {"x": {"title": "X", "type": "integer"}}, From defd52b2d691cd7694efaf20e1e02bfe7712302b Mon Sep 17 00:00:00 2001 From: jeremy Date: Thu, 30 Jan 2025 10:21:03 -0500 Subject: [PATCH 2/2] Fix comment about pydantic versioning --- tests/server/fastmcp/test_func_metadata.py | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/tests/server/fastmcp/test_func_metadata.py b/tests/server/fastmcp/test_func_metadata.py index 79922799e..b68fb9025 100644 --- a/tests/server/fastmcp/test_func_metadata.py +++ b/tests/server/fastmcp/test_func_metadata.py @@ -237,26 +237,23 @@ async def check_call(args): def test_complex_function_json_schema(): """Test JSON schema generation for complex function arguments. - Note: This test accepts two equivalent JSON Schema formats for models with defaults: - 1. Pre-pydantic 2.7.2: + Note: Different versions of pydantic output slightly different + JSON Schema formats for model fields with defaults. The format changed in 2.9.0: + + 1. Before 2.9.0: { - "$ref": "#/$defs/Model", + "allOf": [{"$ref": "#/$defs/Model"}], "default": {} } - 2. Pydantic 2.7.2+: + 2. Since 2.9.0: { - "allOf": [ - { - "$ref": "#/$defs/Model" - } - ], + "$ref": "#/$defs/Model", "default": {} } - Both formats are valid JSON Schema and represent the same validation rules. - The newer format using allOf is more correct according to the JSON Schema spec - as it properly composes the reference with additional properties. + Both formats are valid and functionally equivalent. This test accepts either format + to ensure compatibility across our supported pydantic versions. This change in format does not affect runtime behavior since: 1. Both schemas validate the same way