]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
➖ Drop support for Pydantic v1, keeping short temporary support for Pydantic v2's...
authorSebastián Ramírez <tiangolo@gmail.com>
Sat, 20 Dec 2025 15:55:38 +0000 (07:55 -0800)
committerGitHub <noreply@github.com>
Sat, 20 Dec 2025 15:55:38 +0000 (16:55 +0100)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
138 files changed:
.github/workflows/test.yml
docs/en/docs/advanced/path-operation-advanced-configuration.md
docs/en/docs/advanced/settings.md
docs/en/docs/how-to/migrate-from-pydantic-v1-to-pydantic-v2.md
docs/en/docs/how-to/separate-openapi-schemas.md
docs/en/docs/tutorial/body-updates.md
docs/en/docs/tutorial/body.md
docs/en/docs/tutorial/extra-models.md
docs/en/docs/tutorial/query-params-str-validations.md
docs/en/docs/tutorial/response-model.md
docs/en/docs/tutorial/schema-extra-example.md
docs_src/body/tutorial002_py310.py
docs_src/body/tutorial002_py39.py
docs_src/body/tutorial003_py310.py
docs_src/body/tutorial003_py39.py
docs_src/body/tutorial004_py310.py
docs_src/body/tutorial004_py39.py
docs_src/body_updates/tutorial002_py310.py
docs_src/body_updates/tutorial002_py39.py
docs_src/cookie_param_models/tutorial002_pv1_an_py310.py [deleted file]
docs_src/cookie_param_models/tutorial002_pv1_an_py39.py [deleted file]
docs_src/cookie_param_models/tutorial002_pv1_py310.py [deleted file]
docs_src/cookie_param_models/tutorial002_pv1_py39.py [deleted file]
docs_src/extra_models/tutorial001_py310.py
docs_src/extra_models/tutorial001_py39.py
docs_src/extra_models/tutorial002_py310.py
docs_src/extra_models/tutorial002_py39.py
docs_src/header_param_models/tutorial002_pv1_an_py310.py [deleted file]
docs_src/header_param_models/tutorial002_pv1_an_py39.py [deleted file]
docs_src/header_param_models/tutorial002_pv1_py310.py [deleted file]
docs_src/header_param_models/tutorial002_pv1_py39.py [deleted file]
docs_src/path_operation_advanced_configuration/tutorial007_pv1_py39.py
docs_src/query_param_models/tutorial002_pv1_an_py310.py [deleted file]
docs_src/query_param_models/tutorial002_pv1_an_py39.py [deleted file]
docs_src/query_param_models/tutorial002_pv1_py310.py [deleted file]
docs_src/query_param_models/tutorial002_pv1_py39.py [deleted file]
docs_src/request_form_models/tutorial002_pv1_an_py39.py
docs_src/request_form_models/tutorial002_pv1_py39.py
docs_src/schema_extra_example/tutorial001_pv1_py310.py
docs_src/schema_extra_example/tutorial001_pv1_py39.py
docs_src/settings/app03_an_py39/config_pv1.py
docs_src/settings/app03_py39/config_pv1.py
docs_src/settings/tutorial001_pv1_py39.py
fastapi/_compat/__init__.py
fastapi/_compat/main.py
fastapi/_compat/may_v1.py
fastapi/_compat/v1.py
fastapi/_compat/v2.py
fastapi/datastructures.py
fastapi/dependencies/utils.py
fastapi/encoders.py
fastapi/openapi/models.py
fastapi/params.py
fastapi/routing.py
fastapi/temp_pydantic_v1_params.py
fastapi/utils.py
pyproject.toml
tests/test_additional_properties_bool.py
tests/test_ambiguous_params.py
tests/test_arbitrary_types.py
tests/test_compat.py
tests/test_compat_params_v1.py
tests/test_computed_fields.py
tests/test_custom_schema_fields.py
tests/test_datastructures.py
tests/test_datetime_custom_encoder.py
tests/test_filter_pydantic_sub_model/app_pv1.py
tests/test_filter_pydantic_sub_model/test_filter_pydantic_sub_model_pv1.py
tests/test_filter_pydantic_sub_model_pv2.py
tests/test_forms_single_model.py
tests/test_get_model_definitions_formfeed_escape.py
tests/test_inherited_custom_class.py
tests/test_jsonable_encoder.py
tests/test_no_schema_split.py
tests/test_openapi_separate_input_output_schemas.py
tests/test_pydantic_v1_v2_01.py
tests/test_pydantic_v1_v2_list.py
tests/test_pydantic_v1_v2_mixed.py
tests/test_pydantic_v1_v2_multifile/test_multifile.py
tests/test_pydantic_v1_v2_noneable.py
tests/test_query_cookie_header_model_extra_params.py
tests/test_read_with_orm_mode.py
tests/test_request_param_model_by_alias.py
tests/test_request_params/test_body/test_list.py
tests/test_request_params/test_body/test_optional_list.py
tests/test_request_params/test_body/test_optional_str.py
tests/test_request_params/test_body/test_required_str.py
tests/test_request_params/test_cookie/test_optional_str.py
tests/test_request_params/test_cookie/test_required_str.py
tests/test_request_params/test_file/test_list.py
tests/test_request_params/test_file/test_optional.py
tests/test_request_params/test_file/test_optional_list.py
tests/test_request_params/test_file/test_required.py
tests/test_request_params/test_form/test_list.py
tests/test_request_params/test_form/test_optional_list.py
tests/test_request_params/test_form/test_optional_str.py
tests/test_request_params/test_form/test_required_str.py
tests/test_request_params/test_header/test_list.py
tests/test_request_params/test_header/test_optional_list.py
tests/test_request_params/test_header/test_optional_str.py
tests/test_request_params/test_header/test_required_str.py
tests/test_request_params/test_path/test_required_str.py
tests/test_request_params/test_query/test_list.py
tests/test_request_params/test_query/test_optional_list.py
tests/test_request_params/test_query/test_optional_str.py
tests/test_request_params/test_query/test_required_str.py
tests/test_response_by_alias.py
tests/test_schema_compat_pydantic_v2.py
tests/test_schema_extra_examples.py
tests/test_schema_ref_pydantic_v2.py
tests/test_tutorial/test_body_updates/test_tutorial001.py
tests/test_tutorial/test_conditional_openapi/test_tutorial001.py
tests/test_tutorial/test_cookie_param_models/test_tutorial002.py
tests/test_tutorial/test_dataclasses/test_tutorial003.py
tests/test_tutorial/test_header_param_models/test_tutorial002.py
tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial004.py
tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial007.py
tests/test_tutorial/test_path_operation_configurations/test_tutorial005.py
tests/test_tutorial/test_pydantic_v1_in_v2/test_tutorial001.py
tests/test_tutorial/test_pydantic_v1_in_v2/test_tutorial002.py
tests/test_tutorial/test_pydantic_v1_in_v2/test_tutorial003.py
tests/test_tutorial/test_pydantic_v1_in_v2/test_tutorial004.py
tests/test_tutorial/test_query_param_models/test_tutorial002.py
tests/test_tutorial/test_query_params_str_validations/test_tutorial015.py
tests/test_tutorial/test_request_form_models/test_tutorial002.py
tests/test_tutorial/test_request_form_models/test_tutorial002_pv1.py
tests/test_tutorial/test_response_directly/test_tutorial001.py
tests/test_tutorial/test_schema_extra_example/test_tutorial001.py
tests/test_tutorial/test_schema_extra_example/test_tutorial001_pv1.py
tests/test_tutorial/test_separate_openapi_schemas/test_tutorial001.py
tests/test_tutorial/test_separate_openapi_schemas/test_tutorial002.py
tests/test_tutorial/test_settings/test_app02.py
tests/test_tutorial/test_settings/test_app03.py
tests/test_tutorial/test_settings/test_tutorial001.py
tests/test_union_body_discriminator.py
tests/test_union_body_discriminator_annotated.py
tests/test_validate_response_recursive/app.py
tests/utils.py

index cc906eaf6d4c45e7b92aa375a5450060410b2c65..eb2b6b64eea4b3e393aebea09bbae962733039a1 100644 (file)
@@ -44,35 +44,22 @@ jobs:
       matrix:
         os: [ windows-latest, macos-latest ]
         python-version: [ "3.14" ]
-        pydantic-version: [ "pydantic>=2.0.2,<3.0.0" ]
         include:
           - os: ubuntu-latest
             python-version: "3.9"
-            pydantic-version: "pydantic>=1.10.0,<2.0.0"
             coverage: coverage
           - os: macos-latest
             python-version: "3.10"
-            pydantic-version: "pydantic>=2.0.2,<3.0.0"
+            coverage: coverage
           - os: windows-latest
-            python-version: "3.11"
-            pydantic-version: "pydantic>=1.10.0,<2.0.0"
-          - os: ubuntu-latest
             python-version: "3.12"
-            pydantic-version: "pydantic>=2.0.2,<3.0.0"
-          - os: macos-latest
-            python-version: "3.13"
-            pydantic-version: "pydantic>=1.10.0,<2.0.0"
-          - os: windows-latest
-            python-version: "3.13"
-            pydantic-version: "pydantic>=2.0.2,<3.0.0"
             coverage: coverage
+          # Ubuntu with 3.13 needs coverage for CodSpeed benchmarks
           - os: ubuntu-latest
             python-version: "3.13"
-            pydantic-version: "pydantic>=2.0.2,<3.0.0"
             coverage: coverage
           - os: ubuntu-latest
             python-version: "3.14"
-            pydantic-version: "pydantic>=2.0.2,<3.0.0"
             coverage: coverage
       fail-fast: false
     runs-on: ${{ matrix.os }}
@@ -96,8 +83,6 @@ jobs:
             pyproject.toml
       - name: Install Dependencies
         run: uv pip install -r requirements-tests.txt
-      - name: Install Pydantic
-        run: uv pip install "${{ matrix.pydantic-version }}"
       - run: mkdir coverage
       - name: Test
         run: bash scripts/test.sh
@@ -105,7 +90,7 @@ jobs:
           COVERAGE_FILE: coverage/.coverage.${{ runner.os }}-py${{ matrix.python-version }}
           CONTEXT: ${{ runner.os }}-py${{ matrix.python-version }}
       - name: CodSpeed benchmarks
-        if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.13' && matrix.pydantic-version == 'pydantic>=2.0.2,<3.0.0'
+        if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.13'
         uses: CodSpeedHQ/action@v4
         env:
             COVERAGE_FILE: coverage/.coverage.${{ runner.os }}-py${{ matrix.python-version }}
index 01196af79e004b82580f96d3bdaf1975d4925a03..e0e3c96a0eab7cdb58cb05cb5b78a04b628a37d4 100644 (file)
@@ -153,48 +153,16 @@ And you could do this even if the data type in the request is not JSON.
 
 For example, in this application we don't use FastAPI's integrated functionality to extract the JSON Schema from Pydantic models nor the automatic validation for JSON. In fact, we are declaring the request content type as YAML, not JSON:
 
-//// tab | Pydantic v2
-
 {* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[15:20, 22] *}
 
-////
-
-//// tab | Pydantic v1
-
-{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1_py39.py hl[15:20, 22] *}
-
-////
-
-/// info
-
-In Pydantic version 1 the method to get the JSON Schema for a model was called `Item.schema()`, in Pydantic version 2, the method is called `Item.model_json_schema()`.
-
-///
-
 Nevertheless, although we are not using the default integrated functionality, we are still using a Pydantic model to manually generate the JSON Schema for the data that we want to receive in YAML.
 
 Then we use the request directly, and extract the body as `bytes`. This means that FastAPI won't even try to parse the request payload as JSON.
 
 And then in our code, we parse that YAML content directly, and then we are again using the same Pydantic model to validate the YAML content:
 
-//// tab | Pydantic v2
-
 {* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[24:31] *}
 
-////
-
-//// tab | Pydantic v1
-
-{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1_py39.py hl[24:31] *}
-
-////
-
-/// info
-
-In Pydantic version 1 the method to parse and validate an object was `Item.parse_obj()`, in Pydantic version 2, the method is called `Item.model_validate()`.
-
-///
-
 /// tip
 
 Here we reuse the same Pydantic model.
index 268983f1ef0da514fe07d6acb9264335fc9559c3..cded9b80b8e4e630bb3481f3a8c68ae0d4272658 100644 (file)
@@ -46,12 +46,6 @@ $ pip install "fastapi[all]"
 
 </div>
 
-/// info
-
-In Pydantic v1 it came included with the main package. Now it is distributed as this independent package so that you can choose to install it or not if you don't need that functionality.
-
-///
-
 ### Create the `Settings` object { #create-the-settings-object }
 
 Import `BaseSettings` from Pydantic and create a sub-class, very much like with a Pydantic model.
@@ -60,24 +54,8 @@ The same way as with Pydantic models, you declare class attributes with type ann
 
 You can use all the same validation features and tools you use for Pydantic models, like different data types and additional validations with `Field()`.
 
-//// tab | Pydantic v2
-
 {* ../../docs_src/settings/tutorial001_py39.py hl[2,5:8,11] *}
 
-////
-
-//// tab | Pydantic v1
-
-/// info
-
-In Pydantic v1 you would import `BaseSettings` directly from `pydantic` instead of from `pydantic_settings`.
-
-///
-
-{* ../../docs_src/settings/tutorial001_pv1_py39.py hl[2,5:8,11] *}
-
-////
-
 /// tip
 
 If you want something quick to copy and paste, don't use this example, use the last one below.
@@ -215,8 +193,6 @@ APP_NAME="ChimichangApp"
 
 And then update your `config.py` with:
 
-//// tab | Pydantic v2
-
 {* ../../docs_src/settings/app03_an_py39/config.py hl[9] *}
 
 /// tip
@@ -225,26 +201,6 @@ The `model_config` attribute is used just for Pydantic configuration. You can re
 
 ///
 
-////
-
-//// tab | Pydantic v1
-
-{* ../../docs_src/settings/app03_an_py39/config_pv1.py hl[9:10] *}
-
-/// tip
-
-The `Config` class is used just for Pydantic configuration. You can read more at <a href="https://docs.pydantic.dev/1.10/usage/model_config/" class="external-link" target="_blank">Pydantic Model Config</a>.
-
-///
-
-////
-
-/// info
-
-In Pydantic version 1 the configuration was done in an internal class `Config`, in Pydantic version 2 it's done in an attribute `model_config`. This attribute takes a `dict`, and to get autocompletion and inline errors you can import and use `SettingsConfigDict` to define that `dict`.
-
-///
-
 Here we define the config `env_file` inside of your Pydantic `Settings` class, and set the value to the filename with the dotenv file we want to use.
 
 ### Creating the `Settings` only once with `lru_cache` { #creating-the-settings-only-once-with-lru-cache }
index e85d122be8fa93d940fc309d2220258ce61a6c15..fc90220b89cd1bed67d22be8db7722973cd8e5d1 100644 (file)
@@ -2,21 +2,23 @@
 
 If you have an old FastAPI app, you might be using Pydantic version 1.
 
-FastAPI has had support for either Pydantic v1 or v2 since version 0.100.0.
+FastAPI version 0.100.0 had support for either Pydantic v1 or v2. It would use whichever you had installed.
 
-If you had installed Pydantic v2, it would use it. If instead you had Pydantic v1, it would use that.
+FastAPI version 0.119.0 introduced partial support for Pydantic v1 from inside of Pydantic v2 (as `pydantic.v1`), to facilitate the migration to v2.
 
-Pydantic v1 is now deprecated and support for it will be removed in the next versions of FastAPI, you should **migrate to Pydantic v2**. This way you will get the latest features, improvements, and fixes.
+FastAPI 0.126.0 dropped support for Pydantic v1, while still supporting `pydantic.v1` for a little while.
 
 /// warning
 
-Also, the Pydantic team stopped support for Pydantic v1 for the latest versions of Python, starting with **Python 3.14**.
+The Pydantic team stopped support for Pydantic v1 for the latest versions of Python, starting with **Python 3.14**.
+
+This includes `pydantic.v1`, which is no longer supported in Python 3.14 and above.
 
 If you want to use the latest features of Python, you will need to make sure you use Pydantic v2.
 
 ///
 
-If you have an old FastAPI app with Pydantic v1, here I'll show you how to migrate it to Pydantic v2, and the **new features in FastAPI 0.119.0** to help you with a gradual migration.
+If you have an old FastAPI app with Pydantic v1, here I'll show you how to migrate it to Pydantic v2, and the **features in FastAPI 0.119.0** to help you with a gradual migration.
 
 ## Official Guide { #official-guide }
 
@@ -44,7 +46,7 @@ After this, you can run the tests and check if everything works. If it does, you
 
 ## Pydantic v1 in v2 { #pydantic-v1-in-v2 }
 
-Pydantic v2 includes everything from Pydantic v1 as a submodule `pydantic.v1`.
+Pydantic v2 includes everything from Pydantic v1 as a submodule `pydantic.v1`. But this is no longer supported in versions above Python 3.13.
 
 This means that you can install the latest version of Pydantic v2 and import and use the old Pydantic v1 components from this submodule, as if you had the old Pydantic v1 installed.
 
index 3c78a56d36888543e0a3b46b8bf5e5807545ec2a..d790c600bba66cea90708f140d5fe9885216a35a 100644 (file)
@@ -1,6 +1,6 @@
 # Separate OpenAPI Schemas for Input and Output or Not { #separate-openapi-schemas-for-input-and-output-or-not }
 
-When using **Pydantic v2**, the generated OpenAPI is a bit more exact and **correct** than before. 😎
+Since **Pydantic v2** was released, the generated OpenAPI is a bit more exact and **correct** than before. 😎
 
 In fact, in some cases, it will even have **two JSON Schemas** in OpenAPI for the same Pydantic model, for input and output, depending on if they have **default values**.
 
@@ -100,5 +100,3 @@ And now there will be one single schema for input and output for the model, only
 <div class="screenshot">
 <img src="/img/tutorial/separate-openapi-schemas/image05.png">
 </div>
-
-This is the same behavior as in Pydantic v1. 🤓
index baeb53ec6f4d1a95a71db0be58453781cc7792d1..1b7fd70661dddad2e3a490cdd18f68257c4a2c6d 100644 (file)
@@ -50,14 +50,6 @@ If you want to receive partial updates, it's very useful to use the parameter `e
 
 Like `item.model_dump(exclude_unset=True)`.
 
-/// info
-
-In Pydantic v1 the method was called `.dict()`, it was deprecated (but still supported) in Pydantic v2, and renamed to `.model_dump()`.
-
-The examples here use `.dict()` for compatibility with Pydantic v1, but you should use `.model_dump()` instead if you can use Pydantic v2.
-
-///
-
 That would generate a `dict` with only the data that was set when creating the `item` model, excluding default values.
 
 Then you can use this to generate a `dict` with only the data that was set (sent in the request), omitting default values:
@@ -68,14 +60,6 @@ Then you can use this to generate a `dict` with only the data that was set (sent
 
 Now, you can create a copy of the existing model using `.model_copy()`, and pass the `update` parameter with a `dict` containing the data to update.
 
-/// info
-
-In Pydantic v1 the method was called `.copy()`, it was deprecated (but still supported) in Pydantic v2, and renamed to `.model_copy()`.
-
-The examples here use `.copy()` for compatibility with Pydantic v1, but you should use `.model_copy()` instead if you can use Pydantic v2.
-
-///
-
 Like `stored_item_model.model_copy(update=update_data)`:
 
 {* ../../docs_src/body_updates/tutorial002_py310.py hl[33] *}
index 25087b84062105e1f3d699a8593f7091272001c7..2d0dfcbb598bc54b5a928a301ae61768131c73be 100644 (file)
@@ -128,14 +128,6 @@ Inside of the function, you can access all the attributes of the model object di
 
 {* ../../docs_src/body/tutorial002_py310.py *}
 
-/// info
-
-In Pydantic v1 the method was called `.dict()`, it was deprecated (but still supported) in Pydantic v2, and renamed to `.model_dump()`.
-
-The examples here use `.dict()` for compatibility with Pydantic v1, but you should use `.model_dump()` instead if you can use Pydantic v2.
-
-///
-
 ## Request body + path parameters { #request-body-path-parameters }
 
 You can declare path parameters and request body at the same time.
index 7079bf73daf97fede600ae7449194b526490dab3..d82df561fa417cf4fd616671d090e3935b65ab76 100644 (file)
@@ -22,22 +22,13 @@ Here's a general idea of how the models could look like with their password fiel
 
 {* ../../docs_src/extra_models/tutorial001_py310.py hl[7,9,14,20,22,27:28,31:33,38:39] *}
 
+### About `**user_in.model_dump()` { #about-user-in-model-dump }
 
-/// info
-
-In Pydantic v1 the method was called `.dict()`, it was deprecated (but still supported) in Pydantic v2, and renamed to `.model_dump()`.
-
-The examples here use `.dict()` for compatibility with Pydantic v1, but you should use `.model_dump()` instead if you can use Pydantic v2.
-
-///
-
-### About `**user_in.dict()` { #about-user-in-dict }
-
-#### Pydantic's `.dict()` { #pydantics-dict }
+#### Pydantic's `.model_dump()` { #pydantics-model-dump }
 
 `user_in` is a Pydantic model of class `UserIn`.
 
-Pydantic models have a `.dict()` method that returns a `dict` with the model's data.
+Pydantic models have a `.model_dump()` method that returns a `dict` with the model's data.
 
 So, if we create a Pydantic object `user_in` like:
 
@@ -48,7 +39,7 @@ user_in = UserIn(username="john", password="secret", email="john.doe@example.com
 and then we call:
 
 ```Python
-user_dict = user_in.dict()
+user_dict = user_in.model_dump()
 ```
 
 we now have a `dict` with the data in the variable `user_dict` (it's a `dict` instead of a Pydantic model object).
@@ -104,20 +95,20 @@ UserInDB(
 
 #### A Pydantic model from the contents of another { #a-pydantic-model-from-the-contents-of-another }
 
-As in the example above we got `user_dict` from `user_in.dict()`, this code:
+As in the example above we got `user_dict` from `user_in.model_dump()`, this code:
 
 ```Python
-user_dict = user_in.dict()
+user_dict = user_in.model_dump()
 UserInDB(**user_dict)
 ```
 
 would be equivalent to:
 
 ```Python
-UserInDB(**user_in.dict())
+UserInDB(**user_in.model_dump())
 ```
 
-...because `user_in.dict()` is a `dict`, and then we make Python "unpack" it by passing it to `UserInDB` prefixed with `**`.
+...because `user_in.model_dump()` is a `dict`, and then we make Python "unpack" it by passing it to `UserInDB` prefixed with `**`.
 
 So, we get a Pydantic model from the data in another Pydantic model.
 
@@ -126,7 +117,7 @@ So, we get a Pydantic model from the data in another Pydantic model.
 And then adding the extra keyword argument `hashed_password=hashed_password`, like in:
 
 ```Python
-UserInDB(**user_in.dict(), hashed_password=hashed_password)
+UserInDB(**user_in.model_dump(), hashed_password=hashed_password)
 ```
 
 ...ends up being like:
@@ -181,7 +172,6 @@ When defining a <a href="https://docs.pydantic.dev/latest/concepts/types/#unions
 
 {* ../../docs_src/extra_models/tutorial003_py310.py hl[1,14:15,18:20,33] *}
 
-
 ### `Union` in Python 3.10 { #union-in-python-3-10 }
 
 In this example we pass `Union[PlaneItem, CarItem]` as the value of the argument `response_model`.
@@ -204,7 +194,6 @@ For that, use the standard Python `typing.List` (or just `list` in Python 3.9 an
 
 {* ../../docs_src/extra_models/tutorial004_py39.py hl[18] *}
 
-
 ## Response with arbitrary `dict` { #response-with-arbitrary-dict }
 
 You can also declare a response using a plain arbitrary `dict`, declaring just the type of the keys and values, without using a Pydantic model.
@@ -215,7 +204,6 @@ In this case, you can use `typing.Dict` (or just `dict` in Python 3.9 and above)
 
 {* ../../docs_src/extra_models/tutorial005_py39.py hl[6] *}
 
-
 ## Recap { #recap }
 
 Use multiple Pydantic models and inherit freely for each case.
index aba87a44849a20c58becea485a254fe0d2b114cf..4b8cc9d2979bfd9655b8baca70fe8071d0890056 100644 (file)
@@ -206,20 +206,6 @@ If you feel lost with all these **"regular expression"** ideas, don't worry. The
 
 Now you know that whenever you need them you can use them in **FastAPI**.
 
-### Pydantic v1 `regex` instead of `pattern` { #pydantic-v1-regex-instead-of-pattern }
-
-Before Pydantic version 2 and before FastAPI 0.100.0, the parameter was called `regex` instead of `pattern`, but it's now deprecated.
-
-You could still see some code using it:
-
-//// tab | Pydantic v1
-
-{* ../../docs_src/query_params_str_validations/tutorial004_regex_an_py310.py hl[11] *}
-
-////
-
-But know that this is deprecated and it should be updated to use the new parameter `pattern`. 🤓
-
 ## Default values { #default-values }
 
 You can, of course, use default values other than `None`.
index a38c610d4fff70b84474a7c4849c1ebb67c00704..b287cdf50abab04596ae5d78e1eb5d0ab3d14ee6 100644 (file)
@@ -252,20 +252,6 @@ So, if you send a request to that *path operation* for the item with ID `foo`, t
 
 /// info
 
-In Pydantic v1 the method was called `.dict()`, it was deprecated (but still supported) in Pydantic v2, and renamed to `.model_dump()`.
-
-The examples here use `.dict()` for compatibility with Pydantic v1, but you should use `.model_dump()` instead if you can use Pydantic v2.
-
-///
-
-/// info
-
-FastAPI uses Pydantic model's `.dict()` with <a href="https://docs.pydantic.dev/1.10/usage/exporting_models/#modeldict" class="external-link" target="_blank">its `exclude_unset` parameter</a> to achieve this.
-
-///
-
-/// info
-
 You can also use:
 
 * `response_model_exclude_defaults=True`
index f3ddaf36974b6257ee365066b56b99302e2fd40b..daaea73c87ba4f1f27948154f611b1d56b40b88a 100644 (file)
@@ -8,36 +8,14 @@ Here are several ways to do it.
 
 You can declare `examples` for a Pydantic model that will be added to the generated JSON Schema.
 
-//// tab | Pydantic v2
-
 {* ../../docs_src/schema_extra_example/tutorial001_py310.py hl[13:24] *}
 
-////
-
-//// tab | Pydantic v1
-
-{* ../../docs_src/schema_extra_example/tutorial001_pv1_py310.py hl[13:23] *}
-
-////
-
 That extra info will be added as-is to the output **JSON Schema** for that model, and it will be used in the API docs.
 
-//// tab | Pydantic v2
-
-In Pydantic version 2, you would use the attribute `model_config`, that takes a `dict` as described in <a href="https://docs.pydantic.dev/latest/api/config/" class="external-link" target="_blank">Pydantic's docs: Configuration</a>.
+You can use the attribute `model_config` that takes a `dict` as described in <a href="https://docs.pydantic.dev/latest/api/config/" class="external-link" target="_blank">Pydantic's docs: Configuration</a>.
 
 You can set `"json_schema_extra"` with a `dict` containing any additional data you would like to show up in the generated JSON Schema, including `examples`.
 
-////
-
-//// tab | Pydantic v1
-
-In Pydantic version 1, you would use an internal class `Config` and `schema_extra`, as described in <a href="https://docs.pydantic.dev/1.10/usage/schema/#schema-customization" class="external-link" target="_blank">Pydantic's docs: Schema customization</a>.
-
-You can set `schema_extra` with a `dict` containing any additional data you would like to show up in the generated JSON Schema, including `examples`.
-
-////
-
 /// tip
 
 You could use the same technique to extend the JSON Schema and add your own custom extra info.
index 454c45c886bd0365edf55192b47ee812413ae59c..a829a4dc9d60002397e86478c4cd6944ffebe07e 100644 (file)
@@ -14,7 +14,7 @@ app = FastAPI()
 
 @app.post("/items/")
 async def create_item(item: Item):
-    item_dict = item.dict()
+    item_dict = item.model_dump()
     if item.tax is not None:
         price_with_tax = item.price + item.tax
         item_dict.update({"price_with_tax": price_with_tax})
index 5cd86216b3904ce92542fef851d3d3e47b412a94..fb212e8e79e16de65e0d5999c1ddcab3ba9de63e 100644 (file)
@@ -16,7 +16,7 @@ app = FastAPI()
 
 @app.post("/items/")
 async def create_item(item: Item):
-    item_dict = item.dict()
+    item_dict = item.model_dump()
     if item.tax is not None:
         price_with_tax = item.price + item.tax
         item_dict.update({"price_with_tax": price_with_tax})
index 440b210e6b47a0dd183498e68a8da6f9bb57393c..51ac8aafac58a1c605accbf5b629c68a2f4ec47e 100644 (file)
@@ -14,4 +14,4 @@ app = FastAPI()
 
 @app.put("/items/{item_id}")
 async def update_item(item_id: int, item: Item):
-    return {"item_id": item_id, **item.dict()}
+    return {"item_id": item_id, **item.model_dump()}
index 2f33cc038969457726a564b4680944bf076b4dd1..636ba2275a31486c32b91d3b2f6fccf740b84de4 100644 (file)
@@ -16,4 +16,4 @@ app = FastAPI()
 
 @app.put("/items/{item_id}")
 async def update_item(item_id: int, item: Item):
-    return {"item_id": item_id, **item.dict()}
+    return {"item_id": item_id, **item.model_dump()}
index b352b70ab60109bd3a0d47e49c17c6dac0c821c6..53b10d97b60cdd8fd203913d03e44a92d9da8b97 100644 (file)
@@ -14,7 +14,7 @@ app = FastAPI()
 
 @app.put("/items/{item_id}")
 async def update_item(item_id: int, item: Item, q: str | None = None):
-    result = {"item_id": item_id, **item.dict()}
+    result = {"item_id": item_id, **item.model_dump()}
     if q:
         result.update({"q": q})
     return result
index 0671e0a278581fc29b336455d1c1a7fcff015b8e..2c157abfa193ab1ca3c4a053dcec160d4819deba 100644 (file)
@@ -16,7 +16,7 @@ app = FastAPI()
 
 @app.put("/items/{item_id}")
 async def update_item(item_id: int, item: Item, q: Union[str, None] = None):
-    result = {"item_id": item_id, **item.dict()}
+    result = {"item_id": item_id, **item.model_dump()}
     if q:
         result.update({"q": q})
     return result
index 3498414966dcb70c599d5691720c35aae60660d0..e5db711108001ec58b6ef362767e62eb3ce33ec4 100644 (file)
@@ -29,7 +29,7 @@ async def read_item(item_id: str):
 async def update_item(item_id: str, item: Item):
     stored_item_data = items[item_id]
     stored_item_model = Item(**stored_item_data)
-    update_data = item.dict(exclude_unset=True)
-    updated_item = stored_item_model.copy(update=update_data)
+    update_data = item.model_dump(exclude_unset=True)
+    updated_item = stored_item_model.model_copy(update=update_data)
     items[item_id] = jsonable_encoder(updated_item)
     return updated_item
index eb35b35215e8f751ae6725b5e1cf8f92775c9ebe..eddd7af716397fdec6f2c4dcd67f6162168db887 100644 (file)
@@ -31,7 +31,7 @@ async def read_item(item_id: str):
 async def update_item(item_id: str, item: Item):
     stored_item_data = items[item_id]
     stored_item_model = Item(**stored_item_data)
-    update_data = item.dict(exclude_unset=True)
-    updated_item = stored_item_model.copy(update=update_data)
+    update_data = item.model_dump(exclude_unset=True)
+    updated_item = stored_item_model.model_copy(update=update_data)
     items[item_id] = jsonable_encoder(updated_item)
     return updated_item
diff --git a/docs_src/cookie_param_models/tutorial002_pv1_an_py310.py b/docs_src/cookie_param_models/tutorial002_pv1_an_py310.py
deleted file mode 100644 (file)
index ac00360..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-from typing import Annotated
-
-from fastapi import Cookie, FastAPI
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Cookies(BaseModel):
-    class Config:
-        extra = "forbid"
-
-    session_id: str
-    fatebook_tracker: str | None = None
-    googall_tracker: str | None = None
-
-
-@app.get("/items/")
-async def read_items(cookies: Annotated[Cookies, Cookie()]):
-    return cookies
diff --git a/docs_src/cookie_param_models/tutorial002_pv1_an_py39.py b/docs_src/cookie_param_models/tutorial002_pv1_an_py39.py
deleted file mode 100644 (file)
index 573caea..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import Cookie, FastAPI
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Cookies(BaseModel):
-    class Config:
-        extra = "forbid"
-
-    session_id: str
-    fatebook_tracker: Union[str, None] = None
-    googall_tracker: Union[str, None] = None
-
-
-@app.get("/items/")
-async def read_items(cookies: Annotated[Cookies, Cookie()]):
-    return cookies
diff --git a/docs_src/cookie_param_models/tutorial002_pv1_py310.py b/docs_src/cookie_param_models/tutorial002_pv1_py310.py
deleted file mode 100644 (file)
index 2c59aad..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-from fastapi import Cookie, FastAPI
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Cookies(BaseModel):
-    class Config:
-        extra = "forbid"
-
-    session_id: str
-    fatebook_tracker: str | None = None
-    googall_tracker: str | None = None
-
-
-@app.get("/items/")
-async def read_items(cookies: Cookies = Cookie()):
-    return cookies
diff --git a/docs_src/cookie_param_models/tutorial002_pv1_py39.py b/docs_src/cookie_param_models/tutorial002_pv1_py39.py
deleted file mode 100644 (file)
index 13f78b8..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-from typing import Union
-
-from fastapi import Cookie, FastAPI
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Cookies(BaseModel):
-    class Config:
-        extra = "forbid"
-
-    session_id: str
-    fatebook_tracker: Union[str, None] = None
-    googall_tracker: Union[str, None] = None
-
-
-@app.get("/items/")
-async def read_items(cookies: Cookies = Cookie()):
-    return cookies
index 669386ae6ebd54314eb4dce72739abd9e577fd68..cf39142e4af848f8a60316e6b52f785800c67760 100644 (file)
@@ -30,7 +30,7 @@ def fake_password_hasher(raw_password: str):
 
 def fake_save_user(user_in: UserIn):
     hashed_password = fake_password_hasher(user_in.password)
-    user_in_db = UserInDB(**user_in.dict(), hashed_password=hashed_password)
+    user_in_db = UserInDB(**user_in.model_dump(), hashed_password=hashed_password)
     print("User saved! ..not really")
     return user_in_db
 
index 4be56cd2a744b4214ea715fcc31639489d9c6095..327ffcdf09611d1410db1f9262e95ba6d71b5d0a 100644 (file)
@@ -32,7 +32,7 @@ def fake_password_hasher(raw_password: str):
 
 def fake_save_user(user_in: UserIn):
     hashed_password = fake_password_hasher(user_in.password)
-    user_in_db = UserInDB(**user_in.dict(), hashed_password=hashed_password)
+    user_in_db = UserInDB(**user_in.model_dump(), hashed_password=hashed_password)
     print("User saved! ..not really")
     return user_in_db
 
index 5b8ed7de3dcd67515f1e5371b79db5e66e493753..e8a4f5f29bcb59e827442bf92e1521d20b8d0817 100644 (file)
@@ -28,7 +28,7 @@ def fake_password_hasher(raw_password: str):
 
 def fake_save_user(user_in: UserIn):
     hashed_password = fake_password_hasher(user_in.password)
-    user_in_db = UserInDB(**user_in.dict(), hashed_password=hashed_password)
+    user_in_db = UserInDB(**user_in.model_dump(), hashed_password=hashed_password)
     print("User saved! ..not really")
     return user_in_db
 
index 70fa16441d642ad70ce81e174de3d5344fae63f4..65437960159249671364ef7fcd56fdd7868a4119 100644 (file)
@@ -30,7 +30,7 @@ def fake_password_hasher(raw_password: str):
 
 def fake_save_user(user_in: UserIn):
     hashed_password = fake_password_hasher(user_in.password)
-    user_in_db = UserInDB(**user_in.dict(), hashed_password=hashed_password)
+    user_in_db = UserInDB(**user_in.model_dump(), hashed_password=hashed_password)
     print("User saved! ..not really")
     return user_in_db
 
diff --git a/docs_src/header_param_models/tutorial002_pv1_an_py310.py b/docs_src/header_param_models/tutorial002_pv1_an_py310.py
deleted file mode 100644 (file)
index e99e24e..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-from typing import Annotated
-
-from fastapi import FastAPI, Header
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class CommonHeaders(BaseModel):
-    class Config:
-        extra = "forbid"
-
-    host: str
-    save_data: bool
-    if_modified_since: str | None = None
-    traceparent: str | None = None
-    x_tag: list[str] = []
-
-
-@app.get("/items/")
-async def read_items(headers: Annotated[CommonHeaders, Header()]):
-    return headers
diff --git a/docs_src/header_param_models/tutorial002_pv1_an_py39.py b/docs_src/header_param_models/tutorial002_pv1_an_py39.py
deleted file mode 100644 (file)
index 18398b7..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import FastAPI, Header
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class CommonHeaders(BaseModel):
-    class Config:
-        extra = "forbid"
-
-    host: str
-    save_data: bool
-    if_modified_since: Union[str, None] = None
-    traceparent: Union[str, None] = None
-    x_tag: list[str] = []
-
-
-@app.get("/items/")
-async def read_items(headers: Annotated[CommonHeaders, Header()]):
-    return headers
diff --git a/docs_src/header_param_models/tutorial002_pv1_py310.py b/docs_src/header_param_models/tutorial002_pv1_py310.py
deleted file mode 100644 (file)
index 3dbff9d..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-from fastapi import FastAPI, Header
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class CommonHeaders(BaseModel):
-    class Config:
-        extra = "forbid"
-
-    host: str
-    save_data: bool
-    if_modified_since: str | None = None
-    traceparent: str | None = None
-    x_tag: list[str] = []
-
-
-@app.get("/items/")
-async def read_items(headers: CommonHeaders = Header()):
-    return headers
diff --git a/docs_src/header_param_models/tutorial002_pv1_py39.py b/docs_src/header_param_models/tutorial002_pv1_py39.py
deleted file mode 100644 (file)
index 86e19be..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI, Header
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class CommonHeaders(BaseModel):
-    class Config:
-        extra = "forbid"
-
-    host: str
-    save_data: bool
-    if_modified_since: Union[str, None] = None
-    traceparent: Union[str, None] = None
-    x_tag: list[str] = []
-
-
-@app.get("/items/")
-async def read_items(headers: CommonHeaders = Header()):
-    return headers
index 831966553fc66328af0b6cebcaaf6a6dc8175469..849f648e12535fd01e0165b622b8c130f1f71e57 100644 (file)
@@ -1,6 +1,6 @@
 import yaml
 from fastapi import FastAPI, HTTPException, Request
-from pydantic import BaseModel, ValidationError
+from pydantic.v1 import BaseModel, ValidationError
 
 app = FastAPI()
 
diff --git a/docs_src/query_param_models/tutorial002_pv1_an_py310.py b/docs_src/query_param_models/tutorial002_pv1_an_py310.py
deleted file mode 100644 (file)
index d635aae..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-from typing import Annotated, Literal
-
-from fastapi import FastAPI, Query
-from pydantic import BaseModel, Field
-
-app = FastAPI()
-
-
-class FilterParams(BaseModel):
-    class Config:
-        extra = "forbid"
-
-    limit: int = Field(100, gt=0, le=100)
-    offset: int = Field(0, ge=0)
-    order_by: Literal["created_at", "updated_at"] = "created_at"
-    tags: list[str] = []
-
-
-@app.get("/items/")
-async def read_items(filter_query: Annotated[FilterParams, Query()]):
-    return filter_query
diff --git a/docs_src/query_param_models/tutorial002_pv1_an_py39.py b/docs_src/query_param_models/tutorial002_pv1_an_py39.py
deleted file mode 100644 (file)
index d635aae..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-from typing import Annotated, Literal
-
-from fastapi import FastAPI, Query
-from pydantic import BaseModel, Field
-
-app = FastAPI()
-
-
-class FilterParams(BaseModel):
-    class Config:
-        extra = "forbid"
-
-    limit: int = Field(100, gt=0, le=100)
-    offset: int = Field(0, ge=0)
-    order_by: Literal["created_at", "updated_at"] = "created_at"
-    tags: list[str] = []
-
-
-@app.get("/items/")
-async def read_items(filter_query: Annotated[FilterParams, Query()]):
-    return filter_query
diff --git a/docs_src/query_param_models/tutorial002_pv1_py310.py b/docs_src/query_param_models/tutorial002_pv1_py310.py
deleted file mode 100644 (file)
index 9ffdeef..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-from typing import Literal
-
-from fastapi import FastAPI, Query
-from pydantic import BaseModel, Field
-
-app = FastAPI()
-
-
-class FilterParams(BaseModel):
-    class Config:
-        extra = "forbid"
-
-    limit: int = Field(100, gt=0, le=100)
-    offset: int = Field(0, ge=0)
-    order_by: Literal["created_at", "updated_at"] = "created_at"
-    tags: list[str] = []
-
-
-@app.get("/items/")
-async def read_items(filter_query: FilterParams = Query()):
-    return filter_query
diff --git a/docs_src/query_param_models/tutorial002_pv1_py39.py b/docs_src/query_param_models/tutorial002_pv1_py39.py
deleted file mode 100644 (file)
index 9ffdeef..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-from typing import Literal
-
-from fastapi import FastAPI, Query
-from pydantic import BaseModel, Field
-
-app = FastAPI()
-
-
-class FilterParams(BaseModel):
-    class Config:
-        extra = "forbid"
-
-    limit: int = Field(100, gt=0, le=100)
-    offset: int = Field(0, ge=0)
-    order_by: Literal["created_at", "updated_at"] = "created_at"
-    tags: list[str] = []
-
-
-@app.get("/items/")
-async def read_items(filter_query: FilterParams = Query()):
-    return filter_query
index 942d5d4118af96251d6e6d8275ca7f1b6a4a626e..392e6873cbdcae7f6c735d61997791de0cc75d50 100644 (file)
@@ -1,7 +1,8 @@
 from typing import Annotated
 
-from fastapi import FastAPI, Form
-from pydantic import BaseModel
+from fastapi import FastAPI
+from fastapi.temp_pydantic_v1_params import Form
+from pydantic.v1 import BaseModel
 
 app = FastAPI()
 
index d5f7db2a67ba48be55e33e4f2e27d0730f3337b8..da160b3a54706226e9582c7fac3aaa0c26d556f8 100644 (file)
@@ -1,5 +1,6 @@
-from fastapi import FastAPI, Form
-from pydantic import BaseModel
+from fastapi import FastAPI
+from fastapi.temp_pydantic_v1_params import Form
+from pydantic.v1 import BaseModel
 
 app = FastAPI()
 
index ec83f1112f20fb80798d67ff575e2e60f899bf7c..b13b8a8c2c810e578dde72f37463a0973de4b61d 100644 (file)
@@ -1,5 +1,5 @@
 from fastapi import FastAPI
-from pydantic import BaseModel
+from pydantic.v1 import BaseModel
 
 app = FastAPI()
 
index 6ab96ff859d0d9c3cd47ac01b9fed22a788e4f32..3240b35d6db343837908d5f9ae75043635282356 100644 (file)
@@ -1,7 +1,7 @@
 from typing import Union
 
 from fastapi import FastAPI
-from pydantic import BaseModel
+from pydantic.v1 import BaseModel
 
 app = FastAPI()
 
index e1c3ee30063b744f5ea4c0d0990ee6855219d419..7ae66ef77c9dcfc33242c7cd921af8efb89e037c 100644 (file)
@@ -1,4 +1,4 @@
-from pydantic import BaseSettings
+from pydantic.v1 import BaseSettings
 
 
 class Settings(BaseSettings):
index e1c3ee30063b744f5ea4c0d0990ee6855219d419..7ae66ef77c9dcfc33242c7cd921af8efb89e037c 100644 (file)
@@ -1,4 +1,4 @@
-from pydantic import BaseSettings
+from pydantic.v1 import BaseSettings
 
 
 class Settings(BaseSettings):
index 0cfd1b6632f0bad274578dd028a3b592f5cb8b02..20ad2bbf624e0441080267ef4ee096b213bde1dd 100644 (file)
@@ -1,5 +1,5 @@
 from fastapi import FastAPI
-from pydantic import BaseSettings
+from pydantic.v1 import BaseSettings
 
 
 class Settings(BaseSettings):
index 0aadd68de2c578b15a90ce6aa87bc71c81c655cb..fd1df8c6a780340389bcf7a6f9ef62d3570e6e38 100644 (file)
@@ -11,7 +11,6 @@ from .main import _is_model_class as _is_model_class
 from .main import _is_model_field as _is_model_field
 from .main import _is_undefined as _is_undefined
 from .main import _model_dump as _model_dump
-from .main import _model_rebuild as _model_rebuild
 from .main import copy_field_info as copy_field_info
 from .main import create_body_model as create_body_model
 from .main import evaluate_forwardref as evaluate_forwardref
index 2043a66781e981a5dd1301fbeb4987cae651eb30..95053a2374a69b0281aff02ec18af1f8ff31f450 100644 (file)
@@ -6,43 +6,26 @@ from typing import (
 )
 
 from fastapi._compat import may_v1
-from fastapi._compat.shared import PYDANTIC_V2, lenient_issubclass
+from fastapi._compat.shared import lenient_issubclass
 from fastapi.types import ModelNameMap
 from pydantic import BaseModel
 from typing_extensions import Literal
 
+from . import v2
 from .model_field import ModelField
-
-if PYDANTIC_V2:
-    from .v2 import BaseConfig as BaseConfig
-    from .v2 import FieldInfo as FieldInfo
-    from .v2 import PydanticSchemaGenerationError as PydanticSchemaGenerationError
-    from .v2 import RequiredParam as RequiredParam
-    from .v2 import Undefined as Undefined
-    from .v2 import UndefinedType as UndefinedType
-    from .v2 import Url as Url
-    from .v2 import Validator as Validator
-    from .v2 import evaluate_forwardref as evaluate_forwardref
-    from .v2 import get_missing_field_error as get_missing_field_error
-    from .v2 import (
-        with_info_plain_validator_function as with_info_plain_validator_function,
-    )
-else:
-    from .v1 import BaseConfig as BaseConfig  # type: ignore[assignment]
-    from .v1 import FieldInfo as FieldInfo
-    from .v1 import (  # type: ignore[assignment]
-        PydanticSchemaGenerationError as PydanticSchemaGenerationError,
-    )
-    from .v1 import RequiredParam as RequiredParam
-    from .v1 import Undefined as Undefined
-    from .v1 import UndefinedType as UndefinedType
-    from .v1 import Url as Url  # type: ignore[assignment]
-    from .v1 import Validator as Validator
-    from .v1 import evaluate_forwardref as evaluate_forwardref
-    from .v1 import get_missing_field_error as get_missing_field_error
-    from .v1 import (  # type: ignore[assignment]
-        with_info_plain_validator_function as with_info_plain_validator_function,
-    )
+from .v2 import BaseConfig as BaseConfig
+from .v2 import FieldInfo as FieldInfo
+from .v2 import PydanticSchemaGenerationError as PydanticSchemaGenerationError
+from .v2 import RequiredParam as RequiredParam
+from .v2 import Undefined as Undefined
+from .v2 import UndefinedType as UndefinedType
+from .v2 import Url as Url
+from .v2 import Validator as Validator
+from .v2 import evaluate_forwardref as evaluate_forwardref
+from .v2 import get_missing_field_error as get_missing_field_error
+from .v2 import (
+    with_info_plain_validator_function as with_info_plain_validator_function,
+)
 
 
 @lru_cache
@@ -50,7 +33,7 @@ def get_cached_model_fields(model: type[BaseModel]) -> list[ModelField]:
     if lenient_issubclass(model, may_v1.BaseModel):
         from fastapi._compat import v1
 
-        return v1.get_model_fields(model)
+        return v1.get_model_fields(model)  # type: ignore[arg-type,return-value]
     else:
         from . import v2
 
@@ -60,11 +43,8 @@ def get_cached_model_fields(model: type[BaseModel]) -> list[ModelField]:
 def _is_undefined(value: object) -> bool:
     if isinstance(value, may_v1.UndefinedType):
         return True
-    elif PYDANTIC_V2:
-        from . import v2
 
-        return isinstance(value, v2.UndefinedType)
-    return False
+    return isinstance(value, v2.UndefinedType)
 
 
 def _get_model_config(model: BaseModel) -> Any:
@@ -72,10 +52,8 @@ def _get_model_config(model: BaseModel) -> Any:
         from fastapi._compat import v1
 
         return v1._get_model_config(model)
-    elif PYDANTIC_V2:
-        from . import v2
 
-        return v2._get_model_config(model)
+    return v2._get_model_config(model)
 
 
 def _model_dump(
@@ -85,20 +63,15 @@ def _model_dump(
         from fastapi._compat import v1
 
         return v1._model_dump(model, mode=mode, **kwargs)
-    elif PYDANTIC_V2:
-        from . import v2
 
-        return v2._model_dump(model, mode=mode, **kwargs)
+    return v2._model_dump(model, mode=mode, **kwargs)
 
 
 def _is_error_wrapper(exc: Exception) -> bool:
     if isinstance(exc, may_v1.ErrorWrapper):
         return True
-    elif PYDANTIC_V2:
-        from . import v2
 
-        return isinstance(exc, v2.ErrorWrapper)
-    return False
+    return isinstance(exc, v2.ErrorWrapper)
 
 
 def copy_field_info(*, field_info: FieldInfo, annotation: Any) -> FieldInfo:
@@ -106,11 +79,8 @@ def copy_field_info(*, field_info: FieldInfo, annotation: Any) -> FieldInfo:
         from fastapi._compat import v1
 
         return v1.copy_field_info(field_info=field_info, annotation=annotation)
-    else:
-        assert PYDANTIC_V2
-        from . import v2
 
-        return v2.copy_field_info(field_info=field_info, annotation=annotation)
+    return v2.copy_field_info(field_info=field_info, annotation=annotation)
 
 
 def create_body_model(
@@ -120,11 +90,8 @@ def create_body_model(
         from fastapi._compat import v1
 
         return v1.create_body_model(fields=fields, model_name=model_name)
-    else:
-        assert PYDANTIC_V2
-        from . import v2
 
-        return v2.create_body_model(fields=fields, model_name=model_name)  # type: ignore[arg-type]
+    return v2.create_body_model(fields=fields, model_name=model_name)  # type: ignore[arg-type]
 
 
 def get_annotation_from_field_info(
@@ -136,13 +103,10 @@ def get_annotation_from_field_info(
         return v1.get_annotation_from_field_info(
             annotation=annotation, field_info=field_info, field_name=field_name
         )
-    else:
-        assert PYDANTIC_V2
-        from . import v2
 
-        return v2.get_annotation_from_field_info(
-            annotation=annotation, field_info=field_info, field_name=field_name
-        )
+    return v2.get_annotation_from_field_info(
+        annotation=annotation, field_info=field_info, field_name=field_name
+    )
 
 
 def is_bytes_field(field: ModelField) -> bool:
@@ -150,11 +114,8 @@ def is_bytes_field(field: ModelField) -> bool:
         from fastapi._compat import v1
 
         return v1.is_bytes_field(field)
-    else:
-        assert PYDANTIC_V2
-        from . import v2
 
-        return v2.is_bytes_field(field)  # type: ignore[arg-type]
+    return v2.is_bytes_field(field)  # type: ignore[arg-type]
 
 
 def is_bytes_sequence_field(field: ModelField) -> bool:
@@ -162,11 +123,8 @@ def is_bytes_sequence_field(field: ModelField) -> bool:
         from fastapi._compat import v1
 
         return v1.is_bytes_sequence_field(field)
-    else:
-        assert PYDANTIC_V2
-        from . import v2
 
-        return v2.is_bytes_sequence_field(field)  # type: ignore[arg-type]
+    return v2.is_bytes_sequence_field(field)  # type: ignore[arg-type]
 
 
 def is_scalar_field(field: ModelField) -> bool:
@@ -174,23 +132,12 @@ def is_scalar_field(field: ModelField) -> bool:
         from fastapi._compat import v1
 
         return v1.is_scalar_field(field)
-    else:
-        assert PYDANTIC_V2
-        from . import v2
 
-        return v2.is_scalar_field(field)  # type: ignore[arg-type]
+    return v2.is_scalar_field(field)  # type: ignore[arg-type]
 
 
 def is_scalar_sequence_field(field: ModelField) -> bool:
-    if isinstance(field, may_v1.ModelField):
-        from fastapi._compat import v1
-
-        return v1.is_scalar_sequence_field(field)
-    else:
-        assert PYDANTIC_V2
-        from . import v2
-
-        return v2.is_scalar_sequence_field(field)  # type: ignore[arg-type]
+    return v2.is_scalar_sequence_field(field)  # type: ignore[arg-type]
 
 
 def is_sequence_field(field: ModelField) -> bool:
@@ -198,11 +145,8 @@ def is_sequence_field(field: ModelField) -> bool:
         from fastapi._compat import v1
 
         return v1.is_sequence_field(field)
-    else:
-        assert PYDANTIC_V2
-        from . import v2
 
-        return v2.is_sequence_field(field)  # type: ignore[arg-type]
+    return v2.is_sequence_field(field)  # type: ignore[arg-type]
 
 
 def serialize_sequence_value(*, field: ModelField, value: Any) -> Sequence[Any]:
@@ -210,22 +154,8 @@ def serialize_sequence_value(*, field: ModelField, value: Any) -> Sequence[Any]:
         from fastapi._compat import v1
 
         return v1.serialize_sequence_value(field=field, value=value)
-    else:
-        assert PYDANTIC_V2
-        from . import v2
-
-        return v2.serialize_sequence_value(field=field, value=value)  # type: ignore[arg-type]
 
-
-def _model_rebuild(model: type[BaseModel]) -> None:
-    if lenient_issubclass(model, may_v1.BaseModel):
-        from fastapi._compat import v1
-
-        v1._model_rebuild(model)
-    elif PYDANTIC_V2:
-        from . import v2
-
-        v2._model_rebuild(model)
+    return v2.serialize_sequence_value(field=field, value=value)  # type: ignore[arg-type]
 
 
 def get_compat_model_name_map(fields: list[ModelField]) -> ModelNameMap:
@@ -236,27 +166,18 @@ def get_compat_model_name_map(fields: list[ModelField]) -> ModelNameMap:
         from fastapi._compat import v1
 
         v1_flat_models = v1.get_flat_models_from_fields(
-            v1_model_fields, known_models=set()
+            v1_model_fields,  # type: ignore[arg-type]
+            known_models=set(),
         )
         all_flat_models = v1_flat_models
     else:
         all_flat_models = set()
-    if PYDANTIC_V2:
-        from . import v2
 
-        v2_model_fields = [
-            field for field in fields if isinstance(field, v2.ModelField)
-        ]
-        v2_flat_models = v2.get_flat_models_from_fields(
-            v2_model_fields, known_models=set()
-        )
-        all_flat_models = all_flat_models.union(v2_flat_models)
+    v2_model_fields = [field for field in fields if isinstance(field, v2.ModelField)]
+    v2_flat_models = v2.get_flat_models_from_fields(v2_model_fields, known_models=set())
+    all_flat_models = all_flat_models.union(v2_flat_models)  # type: ignore[arg-type]
 
-        model_name_map = v2.get_model_name_map(all_flat_models)
-        return model_name_map
-    from fastapi._compat import v1
-
-    model_name_map = v1.get_model_name_map(all_flat_models)
+    model_name_map = v2.get_model_name_map(all_flat_models)  # type: ignore[arg-type]
     return model_name_map
 
 
@@ -275,29 +196,23 @@ def get_definitions(
     if sys.version_info < (3, 14):
         v1_fields = [field for field in fields if isinstance(field, may_v1.ModelField)]
         v1_field_maps, v1_definitions = may_v1.get_definitions(
-            fields=v1_fields,
+            fields=v1_fields,  # type: ignore[arg-type]
+            model_name_map=model_name_map,
+            separate_input_output_schemas=separate_input_output_schemas,
+        )
+
+        v2_fields = [field for field in fields if isinstance(field, v2.ModelField)]
+        v2_field_maps, v2_definitions = v2.get_definitions(
+            fields=v2_fields,
             model_name_map=model_name_map,
             separate_input_output_schemas=separate_input_output_schemas,
         )
-        if not PYDANTIC_V2:
-            return v1_field_maps, v1_definitions
-        else:
-            from . import v2
-
-            v2_fields = [field for field in fields if isinstance(field, v2.ModelField)]
-            v2_field_maps, v2_definitions = v2.get_definitions(
-                fields=v2_fields,
-                model_name_map=model_name_map,
-                separate_input_output_schemas=separate_input_output_schemas,
-            )
-            all_definitions = {**v1_definitions, **v2_definitions}
-            all_field_maps = {**v1_field_maps, **v2_field_maps}
-            return all_field_maps, all_definitions
+        all_definitions = {**v1_definitions, **v2_definitions}
+        all_field_maps = {**v1_field_maps, **v2_field_maps}  # type: ignore[misc]
+        return all_field_maps, all_definitions
 
     # Pydantic v1 is not supported since Python 3.14
     else:
-        from . import v2
-
         v2_fields = [field for field in fields if isinstance(field, v2.ModelField)]
         v2_field_maps, v2_definitions = v2.get_definitions(
             fields=v2_fields,
@@ -326,33 +241,24 @@ def get_schema_from_model_field(
             field_mapping=field_mapping,
             separate_input_output_schemas=separate_input_output_schemas,
         )
-    else:
-        assert PYDANTIC_V2
-        from . import v2
 
-        return v2.get_schema_from_model_field(
-            field=field,  # type: ignore[arg-type]
-            model_name_map=model_name_map,
-            field_mapping=field_mapping,  # type: ignore[arg-type]
-            separate_input_output_schemas=separate_input_output_schemas,
-        )
+    return v2.get_schema_from_model_field(
+        field=field,  # type: ignore[arg-type]
+        model_name_map=model_name_map,
+        field_mapping=field_mapping,  # type: ignore[arg-type]
+        separate_input_output_schemas=separate_input_output_schemas,
+    )
 
 
 def _is_model_field(value: Any) -> bool:
     if isinstance(value, may_v1.ModelField):
         return True
-    elif PYDANTIC_V2:
-        from . import v2
 
-        return isinstance(value, v2.ModelField)
-    return False
+    return isinstance(value, v2.ModelField)
 
 
 def _is_model_class(value: Any) -> bool:
     if lenient_issubclass(value, may_v1.BaseModel):
         return True
-    elif PYDANTIC_V2:
-        from . import v2
 
-        return lenient_issubclass(value, v2.BaseModel)  # type: ignore[attr-defined]
-    return False
+    return lenient_issubclass(value, v2.BaseModel)  # type: ignore[attr-defined]
index c7721622834b72394248a198f0c1d3a7f7f7f9f8..3ac86aa98bc4314339c3f172ff88c4b0d36c7f8b 100644 (file)
@@ -102,7 +102,7 @@ def _normalize_errors(errors: Sequence[Any]) -> list[dict[str, Any]]:
     use_errors: list[Any] = []
     for error in errors:
         if isinstance(error, ErrorWrapper):
-            new_errors = ValidationError(  # type: ignore[call-arg]
+            new_errors = ValidationError(
                 errors=[error], model=RequestErrorModel
             ).errors()
             use_errors.extend(new_errors)
index b29a61f7343e691735c088b115c601cb46780013..b0a9dd35f13667e4e26ab65132a9e102acfdb495 100644 (file)
@@ -11,6 +11,44 @@ from typing import (
 from fastapi._compat import shared
 from fastapi.openapi.constants import REF_PREFIX as REF_PREFIX
 from fastapi.types import ModelNameMap
+from pydantic.v1 import BaseConfig as BaseConfig
+from pydantic.v1 import BaseModel as BaseModel
+from pydantic.v1 import ValidationError as ValidationError
+from pydantic.v1 import create_model as create_model
+from pydantic.v1.class_validators import Validator as Validator
+from pydantic.v1.color import Color as Color
+from pydantic.v1.error_wrappers import ErrorWrapper as ErrorWrapper
+from pydantic.v1.fields import (
+    SHAPE_FROZENSET,
+    SHAPE_LIST,
+    SHAPE_SEQUENCE,
+    SHAPE_SET,
+    SHAPE_SINGLETON,
+    SHAPE_TUPLE,
+    SHAPE_TUPLE_ELLIPSIS,
+)
+from pydantic.v1.fields import FieldInfo as FieldInfo
+from pydantic.v1.fields import ModelField as ModelField
+from pydantic.v1.fields import Undefined as Undefined
+from pydantic.v1.fields import UndefinedType as UndefinedType
+from pydantic.v1.networks import AnyUrl as AnyUrl
+from pydantic.v1.networks import NameEmail as NameEmail
+from pydantic.v1.schema import TypeModelSet as TypeModelSet
+from pydantic.v1.schema import field_schema, model_process_schema
+from pydantic.v1.schema import (
+    get_annotation_from_field_info as get_annotation_from_field_info,
+)
+from pydantic.v1.schema import (
+    get_flat_models_from_field as get_flat_models_from_field,
+)
+from pydantic.v1.schema import (
+    get_flat_models_from_fields as get_flat_models_from_fields,
+)
+from pydantic.v1.schema import get_model_name_map as get_model_name_map
+from pydantic.v1.types import SecretBytes as SecretBytes
+from pydantic.v1.types import SecretStr as SecretStr
+from pydantic.v1.typing import evaluate_forwardref as evaluate_forwardref
+from pydantic.v1.utils import lenient_issubclass as lenient_issubclass
 from pydantic.version import VERSION as PYDANTIC_VERSION
 from typing_extensions import Literal
 
@@ -20,103 +58,6 @@ PYDANTIC_V2 = PYDANTIC_VERSION_MINOR_TUPLE[0] == 2
 # shadowing typing.Required.
 RequiredParam: Any = Ellipsis
 
-if not PYDANTIC_V2:
-    from pydantic import BaseConfig as BaseConfig
-    from pydantic import BaseModel as BaseModel
-    from pydantic import ValidationError as ValidationError
-    from pydantic import create_model as create_model
-    from pydantic.class_validators import Validator as Validator
-    from pydantic.color import Color as Color
-    from pydantic.error_wrappers import ErrorWrapper as ErrorWrapper
-    from pydantic.errors import MissingError
-    from pydantic.fields import (  # type: ignore[attr-defined]
-        SHAPE_FROZENSET,
-        SHAPE_LIST,
-        SHAPE_SEQUENCE,
-        SHAPE_SET,
-        SHAPE_SINGLETON,
-        SHAPE_TUPLE,
-        SHAPE_TUPLE_ELLIPSIS,
-    )
-    from pydantic.fields import FieldInfo as FieldInfo
-    from pydantic.fields import ModelField as ModelField  # type: ignore[attr-defined]
-    from pydantic.fields import Undefined as Undefined  # type: ignore[attr-defined]
-    from pydantic.fields import (  # type: ignore[attr-defined]
-        UndefinedType as UndefinedType,
-    )
-    from pydantic.networks import AnyUrl as AnyUrl
-    from pydantic.networks import NameEmail as NameEmail
-    from pydantic.schema import TypeModelSet as TypeModelSet
-    from pydantic.schema import (
-        field_schema,
-        model_process_schema,
-    )
-    from pydantic.schema import (
-        get_annotation_from_field_info as get_annotation_from_field_info,
-    )
-    from pydantic.schema import get_flat_models_from_field as get_flat_models_from_field
-    from pydantic.schema import (
-        get_flat_models_from_fields as get_flat_models_from_fields,
-    )
-    from pydantic.schema import get_model_name_map as get_model_name_map
-    from pydantic.types import SecretBytes as SecretBytes
-    from pydantic.types import SecretStr as SecretStr
-    from pydantic.typing import evaluate_forwardref as evaluate_forwardref
-    from pydantic.utils import lenient_issubclass as lenient_issubclass
-
-
-else:
-    from pydantic.v1 import BaseConfig as BaseConfig  # type: ignore[assignment]
-    from pydantic.v1 import BaseModel as BaseModel  # type: ignore[assignment]
-    from pydantic.v1 import (  # type: ignore[assignment]
-        ValidationError as ValidationError,
-    )
-    from pydantic.v1 import create_model as create_model  # type: ignore[no-redef]
-    from pydantic.v1.class_validators import Validator as Validator
-    from pydantic.v1.color import Color as Color  # type: ignore[assignment]
-    from pydantic.v1.error_wrappers import ErrorWrapper as ErrorWrapper
-    from pydantic.v1.errors import MissingError
-    from pydantic.v1.fields import (
-        SHAPE_FROZENSET,
-        SHAPE_LIST,
-        SHAPE_SEQUENCE,
-        SHAPE_SET,
-        SHAPE_SINGLETON,
-        SHAPE_TUPLE,
-        SHAPE_TUPLE_ELLIPSIS,
-    )
-    from pydantic.v1.fields import FieldInfo as FieldInfo  # type: ignore[assignment]
-    from pydantic.v1.fields import ModelField as ModelField
-    from pydantic.v1.fields import Undefined as Undefined
-    from pydantic.v1.fields import UndefinedType as UndefinedType
-    from pydantic.v1.networks import AnyUrl as AnyUrl
-    from pydantic.v1.networks import (  # type: ignore[assignment]
-        NameEmail as NameEmail,
-    )
-    from pydantic.v1.schema import TypeModelSet as TypeModelSet
-    from pydantic.v1.schema import (
-        field_schema,
-        model_process_schema,
-    )
-    from pydantic.v1.schema import (
-        get_annotation_from_field_info as get_annotation_from_field_info,
-    )
-    from pydantic.v1.schema import (
-        get_flat_models_from_field as get_flat_models_from_field,
-    )
-    from pydantic.v1.schema import (
-        get_flat_models_from_fields as get_flat_models_from_fields,
-    )
-    from pydantic.v1.schema import get_model_name_map as get_model_name_map
-    from pydantic.v1.types import (  # type: ignore[assignment]
-        SecretBytes as SecretBytes,
-    )
-    from pydantic.v1.types import (  # type: ignore[assignment]
-        SecretStr as SecretStr,
-    )
-    from pydantic.v1.typing import evaluate_forwardref as evaluate_forwardref
-    from pydantic.v1.utils import lenient_issubclass as lenient_issubclass
-
 
 GetJsonSchemaHandler = Any
 JsonSchemaValue = dict[str, Any]
@@ -200,24 +141,6 @@ def is_pv1_scalar_field(field: ModelField) -> bool:
     return True
 
 
-def is_pv1_scalar_sequence_field(field: ModelField) -> bool:
-    if (field.shape in sequence_shapes) and not lenient_issubclass(
-        field.type_, BaseModel
-    ):
-        if field.sub_fields is not None:
-            for sub_field in field.sub_fields:
-                if not is_pv1_scalar_field(sub_field):
-                    return False
-        return True
-    if shared._annotation_is_sequence(field.type_):
-        return True
-    return False
-
-
-def _model_rebuild(model: type[BaseModel]) -> None:
-    model.update_forward_refs()
-
-
 def _model_dump(
     model: BaseModel, mode: Literal["json", "python"] = "json", **kwargs: Any
 ) -> Any:
@@ -225,7 +148,7 @@ def _model_dump(
 
 
 def _get_model_config(model: BaseModel) -> Any:
-    return model.__config__  # type: ignore[attr-defined]
+    return model.__config__
 
 
 def get_schema_from_model_field(
@@ -237,8 +160,10 @@ def get_schema_from_model_field(
     ],
     separate_input_output_schemas: bool = True,
 ) -> dict[str, Any]:
-    return field_schema(  # type: ignore[no-any-return]
-        field, model_name_map=model_name_map, ref_prefix=REF_PREFIX
+    return field_schema(
+        field,
+        model_name_map=model_name_map,  # type: ignore[arg-type]
+        ref_prefix=REF_PREFIX,
     )[0]
 
 
@@ -257,7 +182,7 @@ def get_definitions(
     dict[str, dict[str, Any]],
 ]:
     models = get_flat_models_from_fields(fields, known_models=set())
-    return {}, get_model_definitions(flat_models=models, model_name_map=model_name_map)
+    return {}, get_model_definitions(flat_models=models, model_name_map=model_name_map)  # type: ignore[arg-type]
 
 
 def is_scalar_field(field: ModelField) -> bool:
@@ -268,12 +193,8 @@ def is_sequence_field(field: ModelField) -> bool:
     return field.shape in sequence_shapes or shared._annotation_is_sequence(field.type_)
 
 
-def is_scalar_sequence_field(field: ModelField) -> bool:
-    return is_pv1_scalar_sequence_field(field)
-
-
 def is_bytes_field(field: ModelField) -> bool:
-    return lenient_issubclass(field.type_, bytes)  # type: ignore[no-any-return]
+    return lenient_issubclass(field.type_, bytes)
 
 
 def is_bytes_sequence_field(field: ModelField) -> bool:
@@ -288,20 +209,14 @@ def serialize_sequence_value(*, field: ModelField, value: Any) -> Sequence[Any]:
     return sequence_shape_to_type[field.shape](value)  # type: ignore[no-any-return]
 
 
-def get_missing_field_error(loc: tuple[str, ...]) -> dict[str, Any]:
-    missing_field_error = ErrorWrapper(MissingError(), loc=loc)
-    new_error = ValidationError([missing_field_error], RequestErrorModel)
-    return new_error.errors()[0]  # type: ignore[return-value]
-
-
 def create_body_model(
     *, fields: Sequence[ModelField], model_name: str
 ) -> type[BaseModel]:
     BodyModel = create_model(model_name)
     for f in fields:
-        BodyModel.__fields__[f.name] = f  # type: ignore[index]
+        BodyModel.__fields__[f.name] = f
     return BodyModel
 
 
 def get_model_fields(model: type[BaseModel]) -> list[ModelField]:
-    return list(model.__fields__.values())  # type: ignore[attr-defined]
+    return list(model.__fields__.values())
index c4fa49e4032b9e673cf2a7e80621f89b0607e0f2..cbcb98e1a2eb29369f0d41a3518e0ec9126750e0 100644 (file)
@@ -216,10 +216,6 @@ def get_annotation_from_field_info(
     return annotation
 
 
-def _model_rebuild(model: type[BaseModel]) -> None:
-    model.model_rebuild()
-
-
 def _model_dump(
     model: BaseModel, mode: Literal["json", "python"] = "json", **kwargs: Any
 ) -> Any:
index b38a326def01dc878db7ff4bcfbe70a7d06159cb..492cbfcccbc87da739918c72c7a5a43d312b016c 100644 (file)
@@ -1,4 +1,3 @@
-from collections.abc import Iterable
 from typing import (
     Annotated,
     Any,
@@ -135,27 +134,12 @@ class UploadFile(StarletteUploadFile):
         """
         return await super().close()
 
-    @classmethod
-    def __get_validators__(cls: type["UploadFile"]) -> Iterable[Callable[..., Any]]:
-        yield cls.validate
-
-    @classmethod
-    def validate(cls: type["UploadFile"], v: Any) -> Any:
-        if not isinstance(v, StarletteUploadFile):
-            raise ValueError(f"Expected UploadFile, received: {type(v)}")
-        return v
-
     @classmethod
     def _validate(cls, __input_value: Any, _: Any) -> "UploadFile":
         if not isinstance(__input_value, StarletteUploadFile):
             raise ValueError(f"Expected UploadFile, received: {type(__input_value)}")
         return cast(UploadFile, __input_value)
 
-    # TODO: remove when deprecating Pydantic v1
-    @classmethod
-    def __modify_schema__(cls, field_schema: dict[str, Any]) -> None:
-        field_schema.update({"type": "string", "format": "binary"})
-
     @classmethod
     def __get_pydantic_json_schema__(
         cls, core_schema: CoreSchema, handler: GetJsonSchemaHandler
index 3db006a9189cd0920a32a6518912fab359444cab..0ba93524c45d49ec1ed4ca1c77dd697786d48137 100644 (file)
@@ -18,7 +18,6 @@ from typing import (
 import anyio
 from fastapi import params
 from fastapi._compat import (
-    PYDANTIC_V2,
     ModelField,
     RequiredParam,
     Undefined,
@@ -410,7 +409,8 @@ def analyze_param(
         if isinstance(fastapi_annotation, (FieldInfo, may_v1.FieldInfo)):
             # Copy `field_info` because we mutate `field_info.default` below.
             field_info = copy_field_info(
-                field_info=fastapi_annotation, annotation=use_annotation
+                field_info=fastapi_annotation,  # type: ignore[arg-type]
+                annotation=use_annotation,
             )
             assert field_info.default in {
                 Undefined,
@@ -444,10 +444,9 @@ def analyze_param(
             "Cannot specify FastAPI annotations in `Annotated` and default value"
             f" together for {param_name!r}"
         )
-        field_info = value
-        if PYDANTIC_V2:
-            if isinstance(field_info, FieldInfo):
-                field_info.annotation = type_annotation
+        field_info = value  # type: ignore[assignment]
+        if isinstance(field_info, FieldInfo):
+            field_info.annotation = type_annotation
 
     # Get Depends from type annotation
     if depends is not None and depends.dependency is None:
@@ -485,7 +484,7 @@ def analyze_param(
             field_info = params.File(annotation=use_annotation, default=default_value)
         elif not field_annotation_is_scalar(annotation=type_annotation):
             if annotation_is_pydantic_v1(use_annotation):
-                field_info = temp_pydantic_v1_params.Body(
+                field_info = temp_pydantic_v1_params.Body(  # type: ignore[assignment]
                     annotation=use_annotation, default=default_value
                 )
             else:
index cbeeee4559f08360f9e869159478b17f2c5dcf40..549da32797c368a775eaeae1c5671efe1ae9f72a 100644 (file)
@@ -228,11 +228,11 @@ def jsonable_encoder(
         # TODO: remove when deprecating Pydantic v1
         encoders: dict[Any, Any] = {}
         if isinstance(obj, may_v1.BaseModel):
-            encoders = getattr(obj.__config__, "json_encoders", {})  # type: ignore[attr-defined]
+            encoders = getattr(obj.__config__, "json_encoders", {})
             if custom_encoder:
                 encoders = {**encoders, **custom_encoder}
         obj_dict = _model_dump(
-            obj,
+            obj,  # type: ignore[arg-type]
             mode="json",
             include=include,
             exclude=exclude,
index 7aa80f5cb0a96ee76e15d08fc1bebabda1d7828a..680f678325719ffdbca6b26200db718dadd8dd88 100644 (file)
@@ -3,11 +3,9 @@ from enum import Enum
 from typing import Annotated, Any, Callable, Optional, Union
 
 from fastapi._compat import (
-    PYDANTIC_V2,
     CoreSchema,
     GetJsonSchemaHandler,
     JsonSchemaValue,
-    _model_rebuild,
     with_info_plain_validator_function,
 )
 from fastapi.logger import logger
@@ -57,13 +55,7 @@ except ImportError:  # pragma: no cover
 
 
 class BaseModelWithConfig(BaseModel):
-    if PYDANTIC_V2:
-        model_config = {"extra": "allow"}
-
-    else:
-
-        class Config:
-            extra = "allow"
+    model_config = {"extra": "allow"}
 
 
 class Contact(BaseModelWithConfig):
@@ -226,13 +218,7 @@ class Example(TypedDict, total=False):
     value: Optional[Any]
     externalValue: Optional[AnyUrl]
 
-    if PYDANTIC_V2:  # type: ignore [misc]
-        __pydantic_config__ = {"extra": "allow"}
-
-    else:
-
-        class Config:
-            extra = "allow"
+    __pydantic_config__ = {"extra": "allow"}  # type: ignore[misc]
 
 
 class ParameterInType(Enum):
@@ -447,6 +433,6 @@ class OpenAPI(BaseModelWithConfig):
     externalDocs: Optional[ExternalDocumentation] = None
 
 
-_model_rebuild(Schema)
-_model_rebuild(Operation)
-_model_rebuild(Encoding)
+Schema.model_rebuild()
+Operation.model_rebuild()
+Encoding.model_rebuild()
index 4990d0e70e2f57568d48a95f431de1caf9406f9a..c776c4a59efebcabc4b74315f74917ba0a95dbf6 100644 (file)
@@ -9,8 +9,6 @@ from pydantic.fields import FieldInfo
 from typing_extensions import Literal, deprecated
 
 from ._compat import (
-    PYDANTIC_V2,
-    PYDANTIC_VERSION_MINOR_TUPLE,
     Undefined,
 )
 
@@ -111,29 +109,24 @@ class Param(FieldInfo):  # type: ignore[misc]
                 stacklevel=4,
             )
         current_json_schema_extra = json_schema_extra or extra
-        if PYDANTIC_VERSION_MINOR_TUPLE < (2, 7):
-            self.deprecated = deprecated
-        else:
-            kwargs["deprecated"] = deprecated
-        if PYDANTIC_V2:
-            if serialization_alias in (_Unset, None) and isinstance(alias, str):
-                serialization_alias = alias
-            if validation_alias in (_Unset, None):
-                validation_alias = alias
-            kwargs.update(
-                {
-                    "annotation": annotation,
-                    "alias_priority": alias_priority,
-                    "validation_alias": validation_alias,
-                    "serialization_alias": serialization_alias,
-                    "strict": strict,
-                    "json_schema_extra": current_json_schema_extra,
-                }
-            )
-            kwargs["pattern"] = pattern or regex
-        else:
-            kwargs["regex"] = pattern or regex
-            kwargs.update(**current_json_schema_extra)
+        kwargs["deprecated"] = deprecated
+
+        if serialization_alias in (_Unset, None) and isinstance(alias, str):
+            serialization_alias = alias
+        if validation_alias in (_Unset, None):
+            validation_alias = alias
+        kwargs.update(
+            {
+                "annotation": annotation,
+                "alias_priority": alias_priority,
+                "validation_alias": validation_alias,
+                "serialization_alias": serialization_alias,
+                "strict": strict,
+                "json_schema_extra": current_json_schema_extra,
+            }
+        )
+        kwargs["pattern"] = pattern or regex
+
         use_kwargs = {k: v for k, v in kwargs.items() if v is not _Unset}
 
         super().__init__(**use_kwargs)
@@ -571,29 +564,22 @@ class Body(FieldInfo):  # type: ignore[misc]
                 stacklevel=4,
             )
         current_json_schema_extra = json_schema_extra or extra
-        if PYDANTIC_VERSION_MINOR_TUPLE < (2, 7):
-            self.deprecated = deprecated
-        else:
-            kwargs["deprecated"] = deprecated
-        if PYDANTIC_V2:
-            if serialization_alias in (_Unset, None) and isinstance(alias, str):
-                serialization_alias = alias
-            if validation_alias in (_Unset, None):
-                validation_alias = alias
-            kwargs.update(
-                {
-                    "annotation": annotation,
-                    "alias_priority": alias_priority,
-                    "validation_alias": validation_alias,
-                    "serialization_alias": serialization_alias,
-                    "strict": strict,
-                    "json_schema_extra": current_json_schema_extra,
-                }
-            )
-            kwargs["pattern"] = pattern or regex
-        else:
-            kwargs["regex"] = pattern or regex
-            kwargs.update(**current_json_schema_extra)
+        kwargs["deprecated"] = deprecated
+        if serialization_alias in (_Unset, None) and isinstance(alias, str):
+            serialization_alias = alias
+        if validation_alias in (_Unset, None):
+            validation_alias = alias
+        kwargs.update(
+            {
+                "annotation": annotation,
+                "alias_priority": alias_priority,
+                "validation_alias": validation_alias,
+                "serialization_alias": serialization_alias,
+                "strict": strict,
+                "json_schema_extra": current_json_schema_extra,
+            }
+        )
+        kwargs["pattern"] = pattern or regex
 
         use_kwargs = {k: v for k, v in kwargs.items() if v is not _Unset}
 
index fa6904a6b602c9e51afe9892fc13a857615fd865..a1f2e44bb4029b30378f6bbeba12bd8936c91c18 100644 (file)
@@ -1,4 +1,3 @@
-import dataclasses
 import email.message
 import functools
 import inspect
@@ -30,6 +29,7 @@ from fastapi._compat import (
     _model_dump,
     _normalize_errors,
     lenient_issubclass,
+    may_v1,
 )
 from fastapi.datastructures import Default, DefaultPlaceholder
 from fastapi.dependencies.models import Dependant
@@ -58,7 +58,6 @@ from fastapi.utils import (
     get_value_or_default,
     is_body_allowed_for_status_code,
 )
-from pydantic import BaseModel
 from starlette import routing
 from starlette._exception_handler import wrap_app_handling_exceptions
 from starlette._utils import is_async_callable
@@ -153,8 +152,8 @@ def _prepare_response_content(
     exclude_defaults: bool = False,
     exclude_none: bool = False,
 ) -> Any:
-    if isinstance(res, BaseModel):
-        read_with_orm_mode = getattr(_get_model_config(res), "read_with_orm_mode", None)
+    if isinstance(res, may_v1.BaseModel):
+        read_with_orm_mode = getattr(_get_model_config(res), "read_with_orm_mode", None)  # type: ignore[arg-type]
         if read_with_orm_mode:
             # Let from_orm extract the data from this model instead of converting
             # it now to a dict.
@@ -162,7 +161,7 @@ def _prepare_response_content(
             # access instead of dict iteration, e.g. lazy relationships.
             return res
         return _model_dump(
-            res,
+            res,  # type: ignore[arg-type]
             by_alias=True,
             exclude_unset=exclude_unset,
             exclude_defaults=exclude_defaults,
@@ -188,9 +187,6 @@ def _prepare_response_content(
             )
             for k, v in res.items()
         }
-    elif dataclasses.is_dataclass(res):
-        assert not isinstance(res, type)
-        return dataclasses.asdict(res)
     return res
 
 
index b6c804dc44981e6c950068cc79e6b435b903cd69..1bda0ea9b2ad329eff4859a804f3364cb970f6f5 100644 (file)
@@ -6,12 +6,11 @@ from fastapi.params import ParamTypes
 from typing_extensions import deprecated
 
 from ._compat.may_v1 import FieldInfo, Undefined
-from ._compat.shared import PYDANTIC_VERSION_MINOR_TUPLE
 
 _Unset: Any = Undefined
 
 
-class Param(FieldInfo):  # type: ignore[misc]
+class Param(FieldInfo):
     in_: ParamTypes
 
     def __init__(
@@ -98,10 +97,7 @@ class Param(FieldInfo):  # type: ignore[misc]
                 stacklevel=4,
             )
         current_json_schema_extra = json_schema_extra or extra
-        if PYDANTIC_VERSION_MINOR_TUPLE < (2, 7):
-            self.deprecated = deprecated
-        else:
-            kwargs["deprecated"] = deprecated
+        kwargs["deprecated"] = deprecated
         kwargs["regex"] = pattern or regex
         kwargs.update(**current_json_schema_extra)
         use_kwargs = {k: v for k, v in kwargs.items() if v is not _Unset}
@@ -112,7 +108,7 @@ class Param(FieldInfo):  # type: ignore[misc]
         return f"{self.__class__.__name__}({self.default})"
 
 
-class Path(Param):  # type: ignore[misc]
+class Path(Param):
     in_ = ParamTypes.path
 
     def __init__(
@@ -198,7 +194,7 @@ class Path(Param):  # type: ignore[misc]
         )
 
 
-class Query(Param):  # type: ignore[misc]
+class Query(Param):
     in_ = ParamTypes.query
 
     def __init__(
@@ -282,7 +278,7 @@ class Query(Param):  # type: ignore[misc]
         )
 
 
-class Header(Param):  # type: ignore[misc]
+class Header(Param):
     in_ = ParamTypes.header
 
     def __init__(
@@ -368,7 +364,7 @@ class Header(Param):  # type: ignore[misc]
         )
 
 
-class Cookie(Param):  # type: ignore[misc]
+class Cookie(Param):
     in_ = ParamTypes.cookie
 
     def __init__(
@@ -452,7 +448,7 @@ class Cookie(Param):  # type: ignore[misc]
         )
 
 
-class Body(FieldInfo):  # type: ignore[misc]
+class Body(FieldInfo):
     def __init__(
         self,
         default: Any = Undefined,
@@ -541,10 +537,7 @@ class Body(FieldInfo):  # type: ignore[misc]
                 stacklevel=4,
             )
         current_json_schema_extra = json_schema_extra or extra
-        if PYDANTIC_VERSION_MINOR_TUPLE < (2, 7):
-            self.deprecated = deprecated
-        else:
-            kwargs["deprecated"] = deprecated
+        kwargs["deprecated"] = deprecated
         kwargs["regex"] = pattern or regex
         kwargs.update(**current_json_schema_extra)
 
@@ -556,7 +549,7 @@ class Body(FieldInfo):  # type: ignore[misc]
         return f"{self.__class__.__name__}({self.default})"
 
 
-class Form(Body):  # type: ignore[misc]
+class Form(Body):
     def __init__(
         self,
         default: Any = Undefined,
@@ -640,7 +633,7 @@ class Form(Body):  # type: ignore[misc]
         )
 
 
-class File(Form):  # type: ignore[misc]
+class File(Form):
     def __init__(
         self,
         default: Any = Undefined,
index 5b93b9af8e09198d7000711dd6b833a0d668aee6..c4631d7ed224e7393faa816f2808a48a7b6f681d 100644 (file)
@@ -1,7 +1,6 @@
 import re
 import warnings
 from collections.abc import MutableMapping
-from dataclasses import is_dataclass
 from typing import (
     TYPE_CHECKING,
     Any,
@@ -13,7 +12,6 @@ from weakref import WeakKeyDictionary
 
 import fastapi
 from fastapi._compat import (
-    PYDANTIC_V2,
     BaseConfig,
     ModelField,
     PydanticSchemaGenerationError,
@@ -29,6 +27,8 @@ from pydantic import BaseModel
 from pydantic.fields import FieldInfo
 from typing_extensions import Literal
 
+from ._compat import v2
+
 if TYPE_CHECKING:  # pragma: nocover
     from .routing import APIRoute
 
@@ -105,14 +105,12 @@ def create_model_field(
         from fastapi._compat import v1
 
         try:
-            return v1.ModelField(**v1_kwargs)  # type: ignore[no-any-return]
+            return v1.ModelField(**v1_kwargs)  # type: ignore[return-value]
         except RuntimeError:
             raise fastapi.exceptions.FastAPIError(
                 _invalid_args_message.format(type_=type_)
             ) from None
-    elif PYDANTIC_V2:
-        from ._compat import v2
-
+    else:
         field_info = field_info or FieldInfo(
             annotation=type_, default=default, alias=alias
         )
@@ -128,7 +126,7 @@ def create_model_field(
     from fastapi._compat import v1
 
     try:
-        return v1.ModelField(**v1_kwargs)  # type: ignore[no-any-return]
+        return v1.ModelField(**v1_kwargs)
     except RuntimeError:
         raise fastapi.exceptions.FastAPIError(
             _invalid_args_message.format(type_=type_)
@@ -140,11 +138,8 @@ def create_cloned_field(
     *,
     cloned_types: Optional[MutableMapping[type[BaseModel], type[BaseModel]]] = None,
 ) -> ModelField:
-    if PYDANTIC_V2:
-        from ._compat import v2
-
-        if isinstance(field, v2.ModelField):
-            return field
+    if isinstance(field, v2.ModelField):
+        return field
 
     from fastapi._compat import v1
 
@@ -154,8 +149,6 @@ def create_cloned_field(
         cloned_types = _CLONED_TYPES_CACHE
 
     original_type = field.type_
-    if is_dataclass(original_type) and hasattr(original_type, "__pydantic_model__"):
-        original_type = original_type.__pydantic_model__
     use_type = original_type
     if lenient_issubclass(original_type, v1.BaseModel):
         original_type = cast(type[v1.BaseModel], original_type)
index dd16e1f8fac4736389f70b3d2f808b486c5973b0..ae97cb71bd270ca6aa23177d252e07d2eb43cf82 100644 (file)
@@ -30,7 +30,6 @@ classifiers = [
     "Framework :: AsyncIO",
     "Framework :: FastAPI",
     "Framework :: Pydantic",
-    "Framework :: Pydantic :: 1",
     "Framework :: Pydantic :: 2",
     "Intended Audience :: Developers",
     "Programming Language :: Python :: 3 :: Only",
@@ -45,7 +44,7 @@ classifiers = [
 ]
 dependencies = [
     "starlette>=0.40.0,<0.51.0",
-    "pydantic>=1.7.4,!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,!=2.1.0,<3.0.0",
+    "pydantic>=2.7.0",
     "typing-extensions>=4.8.0",
     "annotated-doc>=0.0.2",
 ]
@@ -71,11 +70,10 @@ standard = [
     "email-validator >=2.0.0",
     # Uvicorn with uvloop
     "uvicorn[standard] >=0.12.0",
-    # TODO: this should be part of some pydantic optional extra dependencies
     # # Settings management
-    "pydantic-settings >=2.0.0",
+    "pydantic-settings >=2.0.0",
     # # Extra Pydantic data types
-    "pydantic-extra-types >=2.0.0",
+    "pydantic-extra-types >=2.0.0",
 ]
 
 standard-no-fastapi-cloud-cli = [
@@ -90,11 +88,10 @@ standard-no-fastapi-cloud-cli = [
     "email-validator >=2.0.0",
     # Uvicorn with uvloop
     "uvicorn[standard] >=0.12.0",
-    # TODO: this should be part of some pydantic optional extra dependencies
     # # Settings management
-    "pydantic-settings >=2.0.0",
+    "pydantic-settings >=2.0.0",
     # # Extra Pydantic data types
-    "pydantic-extra-types >=2.0.0",
+    "pydantic-extra-types >=2.0.0",
 ]
 
 all = [
@@ -183,8 +180,6 @@ filterwarnings = [
     # Ref: https://github.com/python-trio/trio/pull/3054
     # Remove once there's a new version of Trio
     'ignore:The `hash` argument is deprecated*:DeprecationWarning:trio',
-    # Ignore flaky coverage / pytest warning about SQLite connection, only applies to Python 3.13 and Pydantic v1
-    'ignore:Exception ignored in. <sqlite3\.Connection object.*:pytest.PytestUnraisableExceptionWarning',
 ]
 
 [tool.coverage.run]
index de59e48ce749301db133d1b8f8ec43f1eb42d280..3756b7d7c999eb5d9313579af864b306160260ec 100644 (file)
@@ -2,18 +2,12 @@ from typing import Union
 
 from dirty_equals import IsDict
 from fastapi import FastAPI
-from fastapi._compat import PYDANTIC_V2
 from fastapi.testclient import TestClient
 from pydantic import BaseModel, ConfigDict
 
 
 class FooBaseModel(BaseModel):
-    if PYDANTIC_V2:
-        model_config = ConfigDict(extra="forbid")
-    else:
-
-        class Config:
-            extra = "forbid"
+    model_config = ConfigDict(extra="forbid")
 
 
 class Foo(FooBaseModel):
index 5e48782f8ddc083dedfbfde2fc653a9e8679dac7..44d49b781826219035f91e07b4b3d1ebd01d5a85 100644 (file)
@@ -4,7 +4,6 @@ import pytest
 from fastapi import Depends, FastAPI, Path
 from fastapi.param_functions import Query
 from fastapi.testclient import TestClient
-from fastapi.utils import PYDANTIC_V2
 
 app = FastAPI()
 
@@ -71,6 +70,5 @@ def test_multiple_annotations():
     response = client.get("/multi-query", params={"foo": "123"})
     assert response.status_code == 422
 
-    if PYDANTIC_V2:
-        response = client.get("/multi-query", params={"foo": "1"})
-        assert response.status_code == 422
+    response = client.get("/multi-query", params={"foo": "1"})
+    assert response.status_code == 422
index 8b8417bae0f0927af3f7fa2e94de944ef17c0004..481acc3bfc2870a9c5ab63c19ac9f41f091389b5 100644 (file)
@@ -5,8 +5,6 @@ from fastapi import FastAPI
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from .utils import needs_pydanticv2
-
 
 @pytest.fixture(name="client")
 def get_client():
@@ -42,13 +40,11 @@ def get_client():
     return client
 
 
-@needs_pydanticv2
 def test_get(client: TestClient):
     response = client.get("/")
     assert response.json() == {"custom_field": [1.0, 2.0, 3.0]}
 
 
-@needs_pydanticv2
 def test_typeadapter():
     # This test is only to confirm that Pydantic alone is working as expected
     from pydantic import (
@@ -93,7 +89,6 @@ def test_typeadapter():
     )
 
 
-@needs_pydanticv2
 def test_openapi_schema(client: TestClient):
     response = client.get("openapi.json")
     assert response.json() == snapshot(
index 3f9d84d894ec7b0b9fb86dbed9b4359914e18b36..8d20710303b4d87b200a3adcd20470a4446d3f34 100644 (file)
@@ -14,10 +14,9 @@ from fastapi.testclient import TestClient
 from pydantic import BaseModel, ConfigDict
 from pydantic.fields import FieldInfo
 
-from .utils import needs_py310, needs_py_lt_314, needs_pydanticv2
+from .utils import needs_py310, needs_py_lt_314
 
 
-@needs_pydanticv2
 def test_model_field_default_required():
     from fastapi._compat import v2
 
@@ -46,7 +45,6 @@ def test_is_model_field():
     assert not _is_model_field(str)
 
 
-@needs_pydanticv2
 def test_get_model_config():
     # For coverage in Pydantic v2
     class Foo(BaseModel):
@@ -75,7 +73,6 @@ def test_complex():
     assert response2.json() == [1, 2]
 
 
-@needs_pydanticv2
 def test_propagates_pydantic2_model_config():
     app = FastAPI()
 
@@ -136,7 +133,6 @@ def test_is_uploadfile_sequence_annotation():
     assert is_uploadfile_sequence_annotation(Union[list[str], list[UploadFile]])
 
 
-@needs_pydanticv2
 def test_serialize_sequence_value_with_optional_list():
     """Test that serialize_sequence_value handles optional lists correctly."""
     from fastapi._compat import v2
@@ -148,7 +144,6 @@ def test_serialize_sequence_value_with_optional_list():
     assert isinstance(result, list)
 
 
-@needs_pydanticv2
 @needs_py310
 def test_serialize_sequence_value_with_optional_list_pipe_union():
     """Test that serialize_sequence_value handles optional lists correctly (with new syntax)."""
@@ -161,7 +156,6 @@ def test_serialize_sequence_value_with_optional_list_pipe_union():
     assert isinstance(result, list)
 
 
-@needs_pydanticv2
 def test_serialize_sequence_value_with_none_first_in_union():
     """Test that serialize_sequence_value handles Union[None, List[...]] correctly."""
     from fastapi._compat import v2
index 8829a0a611feccb4515c80510f30f61df0e17b10..b4ca861be335bdeba8a6eb45c66aae0a9949657f 100644 (file)
@@ -3,7 +3,7 @@ from typing import Optional
 
 import pytest
 
-from tests.utils import pydantic_snapshot, skip_module_if_py_gte_314
+from tests.utils import skip_module_if_py_gte_314
 
 if sys.version_info >= (3, 14):
     skip_module_if_py_gte_314()
@@ -588,23 +588,14 @@ def test_openapi_schema():
                             "required": True,
                             "content": {
                                 "application/json": {
-                                    "schema": pydantic_snapshot(
-                                        v1=snapshot(
+                                    "schema": {
+                                        "title": "Body",
+                                        "allOf": [
                                             {
                                                 "$ref": "#/components/schemas/Body_update_item_items__item_id__put"
                                             }
-                                        ),
-                                        v2=snapshot(
-                                            {
-                                                "title": "Body",
-                                                "allOf": [
-                                                    {
-                                                        "$ref": "#/components/schemas/Body_update_item_items__item_id__put"
-                                                    }
-                                                ],
-                                            }
-                                        ),
-                                    ),
+                                        ],
+                                    }
                                 }
                             },
                         },
@@ -809,23 +800,14 @@ def test_openapi_schema():
                         "requestBody": {
                             "content": {
                                 "application/json": {
-                                    "schema": pydantic_snapshot(
-                                        v1=snapshot(
+                                    "schema": {
+                                        "allOf": [
                                             {
                                                 "$ref": "#/components/schemas/Body_create_item_embed_items_embed__post"
                                             }
-                                        ),
-                                        v2=snapshot(
-                                            {
-                                                "allOf": [
-                                                    {
-                                                        "$ref": "#/components/schemas/Body_create_item_embed_items_embed__post"
-                                                    }
-                                                ],
-                                                "title": "Body",
-                                            }
-                                        ),
-                                    ),
+                                        ],
+                                        "title": "Body",
+                                    }
                                 }
                             },
                             "required": True,
@@ -855,23 +837,14 @@ def test_openapi_schema():
                         "requestBody": {
                             "content": {
                                 "application/x-www-form-urlencoded": {
-                                    "schema": pydantic_snapshot(
-                                        v1=snapshot(
+                                    "schema": {
+                                        "allOf": [
                                             {
                                                 "$ref": "#/components/schemas/Body_submit_form_form_data__post"
                                             }
-                                        ),
-                                        v2=snapshot(
-                                            {
-                                                "allOf": [
-                                                    {
-                                                        "$ref": "#/components/schemas/Body_submit_form_form_data__post"
-                                                    }
-                                                ],
-                                                "title": "Body",
-                                            }
-                                        ),
-                                    ),
+                                        ],
+                                        "title": "Body",
+                                    }
                                 }
                             },
                             "required": True,
@@ -901,23 +874,14 @@ def test_openapi_schema():
                         "requestBody": {
                             "content": {
                                 "multipart/form-data": {
-                                    "schema": pydantic_snapshot(
-                                        v1=snapshot(
+                                    "schema": {
+                                        "allOf": [
                                             {
                                                 "$ref": "#/components/schemas/Body_upload_file_upload__post"
                                             }
-                                        ),
-                                        v2=snapshot(
-                                            {
-                                                "allOf": [
-                                                    {
-                                                        "$ref": "#/components/schemas/Body_upload_file_upload__post"
-                                                    }
-                                                ],
-                                                "title": "Body",
-                                            }
-                                        ),
-                                    ),
+                                        ],
+                                        "title": "Body",
+                                    },
                                 }
                             },
                             "required": True,
@@ -947,23 +911,14 @@ def test_openapi_schema():
                         "requestBody": {
                             "content": {
                                 "multipart/form-data": {
-                                    "schema": pydantic_snapshot(
-                                        v1=snapshot(
+                                    "schema": {
+                                        "allOf": [
                                             {
                                                 "$ref": "#/components/schemas/Body_upload_multiple_files_upload_multiple__post"
                                             }
-                                        ),
-                                        v2=snapshot(
-                                            {
-                                                "allOf": [
-                                                    {
-                                                        "$ref": "#/components/schemas/Body_upload_multiple_files_upload_multiple__post"
-                                                    }
-                                                ],
-                                                "title": "Body",
-                                            }
-                                        ),
-                                    ),
+                                        ],
+                                        "title": "Body",
+                                    }
                                 }
                             },
                             "required": True,
@@ -990,21 +945,12 @@ def test_openapi_schema():
             "components": {
                 "schemas": {
                     "Body_create_item_embed_items_embed__post": {
-                        "properties": pydantic_snapshot(
-                            v1=snapshot(
-                                {"item": {"$ref": "#/components/schemas/Item"}}
-                            ),
-                            v2=snapshot(
-                                {
-                                    "item": {
-                                        "allOf": [
-                                            {"$ref": "#/components/schemas/Item"}
-                                        ],
-                                        "title": "Item",
-                                    }
-                                }
-                            ),
-                        ),
+                        "properties": {
+                            "item": {
+                                "allOf": [{"$ref": "#/components/schemas/Item"}],
+                                "title": "Item",
+                            }
+                        },
                         "type": "object",
                         "required": ["item"],
                         "title": "Body_create_item_embed_items_embed__post",
@@ -1030,17 +976,10 @@ def test_openapi_schema():
                     },
                     "Body_update_item_items__item_id__put": {
                         "properties": {
-                            "item": pydantic_snapshot(
-                                v1=snapshot({"$ref": "#/components/schemas/Item"}),
-                                v2=snapshot(
-                                    {
-                                        "allOf": [
-                                            {"$ref": "#/components/schemas/Item"}
-                                        ],
-                                        "title": "Item",
-                                    }
-                                ),
-                            ),
+                            "item": {
+                                "allOf": [{"$ref": "#/components/schemas/Item"}],
+                                "title": "Item",
+                            },
                             "importance": {
                                 "type": "integer",
                                 "maximum": 10.0,
index f2e42999b35e71d43508fbed6b0955909a1e8d6b..e7f969f7cf4f9d590e32707702fc3eb3437d1244 100644 (file)
@@ -2,8 +2,6 @@ import pytest
 from fastapi import FastAPI
 from fastapi.testclient import TestClient
 
-from .utils import needs_pydanticv2
-
 
 @pytest.fixture(name="client")
 def get_client(request):
@@ -35,7 +33,6 @@ def get_client(request):
 
 @pytest.mark.parametrize("client", [True, False], indirect=True)
 @pytest.mark.parametrize("path", ["/", "/responses"])
-@needs_pydanticv2
 def test_get(client: TestClient, path: str):
     response = client.get(path)
     assert response.status_code == 200, response.text
@@ -43,7 +40,6 @@ def test_get(client: TestClient, path: str):
 
 
 @pytest.mark.parametrize("client", [True, False], indirect=True)
-@needs_pydanticv2
 def test_openapi_schema(client: TestClient):
     response = client.get("/openapi.json")
     assert response.status_code == 200, response.text
index bc3e1c5ec3af394e1b87876dd8f2478f17f98469..60b795e9badf6c93eed6f2c221f3a8f18ed801ca 100644 (file)
@@ -1,12 +1,8 @@
 from typing import Annotated, Optional
 
 from fastapi import FastAPI
-from fastapi._compat import PYDANTIC_V2
 from fastapi.testclient import TestClient
-from pydantic import BaseModel
-
-if PYDANTIC_V2:
-    from pydantic import WithJsonSchema
+from pydantic import BaseModel, WithJsonSchema
 
 app = FastAPI()
 
@@ -14,23 +10,15 @@ app = FastAPI()
 class Item(BaseModel):
     name: str
 
-    if PYDANTIC_V2:
-        description: Annotated[
-            Optional[str], WithJsonSchema({"type": ["string", "null"]})
-        ] = None
+    description: Annotated[
+        Optional[str], WithJsonSchema({"type": ["string", "null"]})
+    ] = None
 
-        model_config = {
-            "json_schema_extra": {
-                "x-something-internal": {"level": 4},
-            }
+    model_config = {
+        "json_schema_extra": {
+            "x-something-internal": {"level": 4},
         }
-    else:
-        description: Optional[str] = None  # type: ignore[no-redef]
-
-        class Config:
-            schema_extra = {
-                "x-something-internal": {"level": 4},
-            }
+    }
 
 
 @app.get("/foo", response_model=Item)
@@ -55,7 +43,7 @@ item_schema = {
         },
         "description": {
             "title": "Description",
-            "type": ["string", "null"] if PYDANTIC_V2 else "string",
+            "type": ["string", "null"],
         },
     },
 }
index c175147bc3171153cc58792f100351af2599d801..29a70cae0c3d96cd0c11587dc2a5425abefb8397 100644 (file)
@@ -7,12 +7,6 @@ from fastapi.datastructures import Default
 from fastapi.testclient import TestClient
 
 
-# TODO: remove when deprecating Pydantic v1
-def test_upload_file_invalid():
-    with pytest.raises(ValueError):
-        UploadFile.validate("not a Starlette UploadFile")
-
-
 def test_upload_file_invalid_pydantic_v2():
     with pytest.raises(ValueError):
         UploadFile._validate("not a Starlette UploadFile", {})
index 3aa77c0b1db47902d98d1bccd8dd9abced4c4ba6..822651f4f1f67f4e2230da5b36a62984734e32bb 100644 (file)
@@ -4,10 +4,9 @@ from fastapi import FastAPI
 from fastapi.testclient import TestClient
 from pydantic import BaseModel
 
-from .utils import needs_pydanticv1, needs_pydanticv2
+from .utils import needs_pydanticv1
 
 
-@needs_pydanticv2
 def test_pydanticv2():
     from pydantic import field_serializer
 
@@ -34,7 +33,9 @@ def test_pydanticv2():
 # TODO: remove when deprecating Pydantic v1
 @needs_pydanticv1
 def test_pydanticv1():
-    class ModelWithDatetimeField(BaseModel):
+    from pydantic import v1
+
+    class ModelWithDatetimeField(v1.BaseModel):
         dt_field: datetime
 
         class Config:
index 657e8c5d12624ec0565184ed15823aa26b79de4d..0b6ab53e04a0b37c0ca4073c15838dca9b550621 100644 (file)
@@ -1,7 +1,7 @@
 from typing import Optional
 
 from fastapi import Depends, FastAPI
-from pydantic import BaseModel, validator
+from pydantic.v1 import BaseModel, validator
 
 app = FastAPI()
 
@@ -18,6 +18,7 @@ class ModelA(BaseModel):
     name: str
     description: Optional[str] = None
     model_b: ModelB
+    tags: dict[str, str] = {}
 
     @validator("name")
     def lower_username(cls, name: str, values):
@@ -32,4 +33,9 @@ async def get_model_c() -> ModelC:
 
 @app.get("/model/{name}", response_model=ModelA)
 async def get_model_a(name: str, model_c=Depends(get_model_c)):
-    return {"name": name, "description": "model-a-desc", "model_b": model_c}
+    return {
+        "name": name,
+        "description": "model-a-desc",
+        "model_b": model_c,
+        "tags": {"key1": "value1", "key2": "value2"},
+    }
index 48732dbf06ea528f6144d8476d62e641bcfdb5df..b464b4f572c54a2de6c982cabe2be77b9dd34c10 100644 (file)
@@ -1,6 +1,7 @@
 import pytest
 from fastapi.exceptions import ResponseValidationError
 from fastapi.testclient import TestClient
+from inline_snapshot import snapshot
 
 from ..utils import needs_pydanticv1
 
@@ -21,6 +22,7 @@ def test_filter_sub_model(client: TestClient):
         "name": "modelA",
         "description": "model-a-desc",
         "model_b": {"username": "test-user"},
+        "tags": {"key1": "value1", "key2": "value2"},
     }
 
 
@@ -41,90 +43,104 @@ def test_validator_is_cloned(client: TestClient):
 def test_openapi_schema(client: TestClient):
     response = client.get("/openapi.json")
     assert response.status_code == 200, response.text
-    assert response.json() == {
-        "openapi": "3.1.0",
-        "info": {"title": "FastAPI", "version": "0.1.0"},
-        "paths": {
-            "/model/{name}": {
-                "get": {
-                    "summary": "Get Model A",
-                    "operationId": "get_model_a_model__name__get",
-                    "parameters": [
-                        {
-                            "required": True,
-                            "schema": {"title": "Name", "type": "string"},
-                            "name": "name",
-                            "in": "path",
-                        }
-                    ],
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {
-                                "application/json": {
-                                    "schema": {"$ref": "#/components/schemas/ModelA"}
-                                }
+    assert response.json() == snapshot(
+        {
+            "openapi": "3.1.0",
+            "info": {"title": "FastAPI", "version": "0.1.0"},
+            "paths": {
+                "/model/{name}": {
+                    "get": {
+                        "summary": "Get Model A",
+                        "operationId": "get_model_a_model__name__get",
+                        "parameters": [
+                            {
+                                "required": True,
+                                "schema": {"title": "Name", "type": "string"},
+                                "name": "name",
+                                "in": "path",
+                            }
+                        ],
+                        "responses": {
+                            "200": {
+                                "description": "Successful Response",
+                                "content": {
+                                    "application/json": {
+                                        "schema": {
+                                            "$ref": "#/components/schemas/ModelA"
+                                        }
+                                    }
+                                },
                             },
-                        },
-                        "422": {
-                            "description": "Validation Error",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
+                            "422": {
+                                "description": "Validation Error",
+                                "content": {
+                                    "application/json": {
+                                        "schema": {
+                                            "$ref": "#/components/schemas/HTTPValidationError"
+                                        }
                                     }
-                                }
+                                },
                             },
                         },
-                    },
+                    }
                 }
-            }
-        },
-        "components": {
-            "schemas": {
-                "HTTPValidationError": {
-                    "title": "HTTPValidationError",
-                    "type": "object",
-                    "properties": {
-                        "detail": {
-                            "title": "Detail",
-                            "type": "array",
-                            "items": {"$ref": "#/components/schemas/ValidationError"},
-                        }
+            },
+            "components": {
+                "schemas": {
+                    "HTTPValidationError": {
+                        "title": "HTTPValidationError",
+                        "type": "object",
+                        "properties": {
+                            "detail": {
+                                "title": "Detail",
+                                "type": "array",
+                                "items": {
+                                    "$ref": "#/components/schemas/ValidationError"
+                                },
+                            }
+                        },
                     },
-                },
-                "ModelA": {
-                    "title": "ModelA",
-                    "required": ["name", "model_b"],
-                    "type": "object",
-                    "properties": {
-                        "name": {"title": "Name", "type": "string"},
-                        "description": {"title": "Description", "type": "string"},
-                        "model_b": {"$ref": "#/components/schemas/ModelB"},
+                    "ModelA": {
+                        "title": "ModelA",
+                        "required": ["name", "model_b"],
+                        "type": "object",
+                        "properties": {
+                            "name": {"title": "Name", "type": "string"},
+                            "description": {"title": "Description", "type": "string"},
+                            "model_b": {"$ref": "#/components/schemas/ModelB"},
+                            "tags": {
+                                "additionalProperties": {"type": "string"},
+                                "type": "object",
+                                "title": "Tags",
+                                "default": {},
+                            },
+                        },
+                    },
+                    "ModelB": {
+                        "title": "ModelB",
+                        "required": ["username"],
+                        "type": "object",
+                        "properties": {
+                            "username": {"title": "Username", "type": "string"}
+                        },
                     },
-                },
-                "ModelB": {
-                    "title": "ModelB",
-                    "required": ["username"],
-                    "type": "object",
-                    "properties": {"username": {"title": "Username", "type": "string"}},
-                },
-                "ValidationError": {
-                    "title": "ValidationError",
-                    "required": ["loc", "msg", "type"],
-                    "type": "object",
-                    "properties": {
-                        "loc": {
-                            "title": "Location",
-                            "type": "array",
-                            "items": {
-                                "anyOf": [{"type": "string"}, {"type": "integer"}]
+                    "ValidationError": {
+                        "title": "ValidationError",
+                        "required": ["loc", "msg", "type"],
+                        "type": "object",
+                        "properties": {
+                            "loc": {
+                                "title": "Location",
+                                "type": "array",
+                                "items": {
+                                    "anyOf": [{"type": "string"}, {"type": "integer"}]
+                                },
                             },
+                            "msg": {"title": "Message", "type": "string"},
+                            "type": {"title": "Error Type", "type": "string"},
                         },
-                        "msg": {"title": "Message", "type": "string"},
-                        "type": {"title": "Error Type", "type": "string"},
                     },
-                },
-            }
-        },
-    }
+                }
+            },
+        }
+    )
index 2e2c26ddcbc5aab4bd4e04ecec7e35d2e518fa3a..d70f5304350948ef9d9419e2f6d518dd8ef1c551 100644 (file)
@@ -5,8 +5,7 @@ from dirty_equals import HasRepr, IsDict, IsOneOf
 from fastapi import Depends, FastAPI
 from fastapi.exceptions import ResponseValidationError
 from fastapi.testclient import TestClient
-
-from .utils import needs_pydanticv2
+from inline_snapshot import snapshot
 
 
 @pytest.fixture(name="client")
@@ -25,6 +24,7 @@ def get_client():
         name: str
         description: Optional[str] = None
         foo: ModelB
+        tags: dict[str, str] = {}
 
         @field_validator("name")
         def lower_username(cls, name: str, info: ValidationInfo):
@@ -37,13 +37,17 @@ def get_client():
 
     @app.get("/model/{name}", response_model=ModelA)
     async def get_model_a(name: str, model_c=Depends(get_model_c)):
-        return {"name": name, "description": "model-a-desc", "foo": model_c}
+        return {
+            "name": name,
+            "description": "model-a-desc",
+            "foo": model_c,
+            "tags": {"key1": "value1", "key2": "value2"},
+        }
 
     client = TestClient(app)
     return client
 
 
-@needs_pydanticv2
 def test_filter_sub_model(client: TestClient):
     response = client.get("/model/modelA")
     assert response.status_code == 200, response.text
@@ -51,10 +55,10 @@ def test_filter_sub_model(client: TestClient):
         "name": "modelA",
         "description": "model-a-desc",
         "foo": {"username": "test-user"},
+        "tags": {"key1": "value1", "key2": "value2"},
     }
 
 
-@needs_pydanticv2
 def test_validator_is_cloned(client: TestClient):
     with pytest.raises(ResponseValidationError) as err:
         client.get("/model/modelX")
@@ -79,106 +83,119 @@ def test_validator_is_cloned(client: TestClient):
     ]
 
 
-@needs_pydanticv2
 def test_openapi_schema(client: TestClient):
     response = client.get("/openapi.json")
     assert response.status_code == 200, response.text
-    assert response.json() == {
-        "openapi": "3.1.0",
-        "info": {"title": "FastAPI", "version": "0.1.0"},
-        "paths": {
-            "/model/{name}": {
-                "get": {
-                    "summary": "Get Model A",
-                    "operationId": "get_model_a_model__name__get",
-                    "parameters": [
-                        {
-                            "required": True,
-                            "schema": {"title": "Name", "type": "string"},
-                            "name": "name",
-                            "in": "path",
-                        }
-                    ],
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {
-                                "application/json": {
-                                    "schema": {"$ref": "#/components/schemas/ModelA"}
-                                }
+    assert response.json() == snapshot(
+        {
+            "openapi": "3.1.0",
+            "info": {"title": "FastAPI", "version": "0.1.0"},
+            "paths": {
+                "/model/{name}": {
+                    "get": {
+                        "summary": "Get Model A",
+                        "operationId": "get_model_a_model__name__get",
+                        "parameters": [
+                            {
+                                "required": True,
+                                "schema": {"title": "Name", "type": "string"},
+                                "name": "name",
+                                "in": "path",
+                            }
+                        ],
+                        "responses": {
+                            "200": {
+                                "description": "Successful Response",
+                                "content": {
+                                    "application/json": {
+                                        "schema": {
+                                            "$ref": "#/components/schemas/ModelA"
+                                        }
+                                    }
+                                },
                             },
-                        },
-                        "422": {
-                            "description": "Validation Error",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
+                            "422": {
+                                "description": "Validation Error",
+                                "content": {
+                                    "application/json": {
+                                        "schema": {
+                                            "$ref": "#/components/schemas/HTTPValidationError"
+                                        }
                                     }
-                                }
+                                },
                             },
                         },
-                    },
+                    }
                 }
-            }
-        },
-        "components": {
-            "schemas": {
-                "HTTPValidationError": {
-                    "title": "HTTPValidationError",
-                    "type": "object",
-                    "properties": {
-                        "detail": {
-                            "title": "Detail",
-                            "type": "array",
-                            "items": {"$ref": "#/components/schemas/ValidationError"},
-                        }
-                    },
-                },
-                "ModelA": {
-                    "title": "ModelA",
-                    "required": IsOneOf(
-                        ["name", "description", "foo"],
-                        # TODO remove when deprecating Pydantic v1
-                        ["name", "foo"],
-                    ),
-                    "type": "object",
-                    "properties": {
-                        "name": {"title": "Name", "type": "string"},
-                        "description": IsDict(
-                            {
-                                "title": "Description",
-                                "anyOf": [{"type": "string"}, {"type": "null"}],
+            },
+            "components": {
+                "schemas": {
+                    "HTTPValidationError": {
+                        "title": "HTTPValidationError",
+                        "type": "object",
+                        "properties": {
+                            "detail": {
+                                "title": "Detail",
+                                "type": "array",
+                                "items": {
+                                    "$ref": "#/components/schemas/ValidationError"
+                                },
                             }
-                        )
-                        |
-                        # TODO remove when deprecating Pydantic v1
-                        IsDict({"title": "Description", "type": "string"}),
-                        "foo": {"$ref": "#/components/schemas/ModelB"},
+                        },
                     },
-                },
-                "ModelB": {
-                    "title": "ModelB",
-                    "required": ["username"],
-                    "type": "object",
-                    "properties": {"username": {"title": "Username", "type": "string"}},
-                },
-                "ValidationError": {
-                    "title": "ValidationError",
-                    "required": ["loc", "msg", "type"],
-                    "type": "object",
-                    "properties": {
-                        "loc": {
-                            "title": "Location",
-                            "type": "array",
-                            "items": {
-                                "anyOf": [{"type": "string"}, {"type": "integer"}]
+                    "ModelA": {
+                        "title": "ModelA",
+                        "required": IsOneOf(
+                            ["name", "description", "foo"],
+                            # TODO remove when deprecating Pydantic v1
+                            ["name", "foo"],
+                        ),
+                        "type": "object",
+                        "properties": {
+                            "name": {"title": "Name", "type": "string"},
+                            "description": IsDict(
+                                {
+                                    "title": "Description",
+                                    "anyOf": [{"type": "string"}, {"type": "null"}],
+                                }
+                            )
+                            |
+                            # TODO remove when deprecating Pydantic v1
+                            IsDict({"title": "Description", "type": "string"}),
+                            "foo": {"$ref": "#/components/schemas/ModelB"},
+                            "tags": {
+                                "additionalProperties": {"type": "string"},
+                                "type": "object",
+                                "title": "Tags",
+                                "default": {},
                             },
                         },
-                        "msg": {"title": "Message", "type": "string"},
-                        "type": {"title": "Error Type", "type": "string"},
                     },
-                },
-            }
-        },
-    }
+                    "ModelB": {
+                        "title": "ModelB",
+                        "required": ["username"],
+                        "type": "object",
+                        "properties": {
+                            "username": {"title": "Username", "type": "string"}
+                        },
+                    },
+                    "ValidationError": {
+                        "title": "ValidationError",
+                        "required": ["loc", "msg", "type"],
+                        "type": "object",
+                        "properties": {
+                            "loc": {
+                                "title": "Location",
+                                "type": "array",
+                                "items": {
+                                    "anyOf": [{"type": "string"}, {"type": "integer"}]
+                                },
+                            },
+                            "msg": {"title": "Message", "type": "string"},
+                            "type": {"title": "Error Type", "type": "string"},
+                        },
+                    },
+                }
+            },
+        }
+    )
index b149b76539e972248abc34e80f620eae976ee268..c401cc937400f8f29e8b86f23386aa7d347ae177 100644 (file)
@@ -2,7 +2,6 @@ from typing import Annotated, Optional
 
 from dirty_equals import IsDict
 from fastapi import FastAPI, Form
-from fastapi._compat import PYDANTIC_V2
 from fastapi.testclient import TestClient
 from pydantic import BaseModel, Field
 
@@ -20,12 +19,7 @@ class FormModel(BaseModel):
 class FormModelExtraAllow(BaseModel):
     param: str
 
-    if PYDANTIC_V2:
-        model_config = {"extra": "allow"}
-    else:
-
-        class Config:
-            extra = "allow"
+    model_config = {"extra": "allow"}
 
 
 @app.post("/form/")
index 215d06a07262672021cb2cdd2eb1b386ad407626..50d799a57155ee4a7d3e8bf7ee3ec9aca9caa296 100644 (file)
-from collections.abc import Iterator
-from typing import Any
-
-import fastapi._compat
-import fastapi.openapi.utils
-import pydantic.schema
 import pytest
 from fastapi import FastAPI
-from pydantic import BaseModel
-from starlette.testclient import TestClient
+from fastapi.testclient import TestClient
+from inline_snapshot import snapshot
 
 from .utils import needs_pydanticv1
 
 
-class Address(BaseModel):
-    """
-    This is a public description of an Address
-    \f
-    You can't see this part of the docstring, it's private!
-    """
-
-    line_1: str
-    city: str
-    state_province: str
-
-
-class Facility(BaseModel):
-    id: str
-    address: Address
-
-
-app = FastAPI()
+@pytest.fixture(
+    name="client",
+    params=[
+        pytest.param("pydantic-v1", marks=needs_pydanticv1),
+        "pydantic-v2",
+    ],
+)
+def client_fixture(request: pytest.FixtureRequest) -> TestClient:
+    if request.param == "pydantic-v1":
+        from pydantic.v1 import BaseModel
+    else:
+        from pydantic import BaseModel
+
+    class Address(BaseModel):
+        """
+        This is a public description of an Address
+        \f
+        You can't see this part of the docstring, it's private!
+        """
+
+        line_1: str
+        city: str
+        state_province: str
+
+    class Facility(BaseModel):
+        id: str
+        address: Address
+
+    app = FastAPI()
+
+    @app.get("/facilities/{facility_id}")
+    def get_facility(facility_id: str) -> Facility:
+        return Facility(
+            id=facility_id,
+            address=Address(line_1="123 Main St", city="Anytown", state_province="CA"),
+        )
 
-client = TestClient(app)
+    client = TestClient(app)
+    return client
 
 
-@app.get("/facilities/{facility_id}")
-def get_facility(facility_id: str) -> Facility: ...
+def test_get(client: TestClient):
+    response = client.get("/facilities/42")
+    assert response.status_code == 200, response.text
+    assert response.json() == {
+        "id": "42",
+        "address": {
+            "line_1": "123 Main St",
+            "city": "Anytown",
+            "state_province": "CA",
+        },
+    }
 
 
-openapi_schema = {
-    "components": {
-        "schemas": {
-            "Address": {
-                # NOTE: the description of this model shows only the public-facing text, before the `\f` in docstring
-                "description": "This is a public description of an Address\n",
-                "properties": {
-                    "city": {"title": "City", "type": "string"},
-                    "line_1": {"title": "Line 1", "type": "string"},
-                    "state_province": {"title": "State Province", "type": "string"},
-                },
-                "required": ["line_1", "city", "state_province"],
-                "title": "Address",
-                "type": "object",
-            },
-            "Facility": {
-                "properties": {
-                    "address": {"$ref": "#/components/schemas/Address"},
-                    "id": {"title": "Id", "type": "string"},
-                },
-                "required": ["id", "address"],
-                "title": "Facility",
-                "type": "object",
-            },
-            "HTTPValidationError": {
-                "properties": {
-                    "detail": {
-                        "items": {"$ref": "#/components/schemas/ValidationError"},
-                        "title": "Detail",
-                        "type": "array",
-                    }
-                },
-                "title": "HTTPValidationError",
-                "type": "object",
-            },
-            "ValidationError": {
-                "properties": {
-                    "loc": {
-                        "items": {"anyOf": [{"type": "string"}, {"type": "integer"}]},
-                        "title": "Location",
-                        "type": "array",
+def test_openapi_schema(client: TestClient):
+    """
+    Sanity check to ensure our app's openapi schema renders as we expect
+    """
+    response = client.get("/openapi.json")
+    assert response.status_code == 200, response.text
+    assert response.json() == snapshot(
+        {
+            "components": {
+                "schemas": {
+                    "Address": {
+                        # NOTE: the description of this model shows only the public-facing text, before the `\f` in docstring
+                        "description": "This is a public description of an Address\n",
+                        "properties": {
+                            "city": {"title": "City", "type": "string"},
+                            "line_1": {"title": "Line 1", "type": "string"},
+                            "state_province": {
+                                "title": "State Province",
+                                "type": "string",
+                            },
+                        },
+                        "required": ["line_1", "city", "state_province"],
+                        "title": "Address",
+                        "type": "object",
                     },
-                    "msg": {"title": "Message", "type": "string"},
-                    "type": {"title": "Error Type", "type": "string"},
-                },
-                "required": ["loc", "msg", "type"],
-                "title": "ValidationError",
-                "type": "object",
-            },
-        }
-    },
-    "info": {"title": "FastAPI", "version": "0.1.0"},
-    "openapi": "3.1.0",
-    "paths": {
-        "/facilities/{facility_id}": {
-            "get": {
-                "operationId": "get_facility_facilities__facility_id__get",
-                "parameters": [
-                    {
-                        "in": "path",
-                        "name": "facility_id",
-                        "required": True,
-                        "schema": {"title": "Facility Id", "type": "string"},
-                    }
-                ],
-                "responses": {
-                    "200": {
-                        "content": {
-                            "application/json": {
-                                "schema": {"$ref": "#/components/schemas/Facility"}
-                            }
+                    "Facility": {
+                        "properties": {
+                            "address": {"$ref": "#/components/schemas/Address"},
+                            "id": {"title": "Id", "type": "string"},
                         },
-                        "description": "Successful Response",
+                        "required": ["id", "address"],
+                        "title": "Facility",
+                        "type": "object",
                     },
-                    "422": {
-                        "content": {
-                            "application/json": {
-                                "schema": {
-                                    "$ref": "#/components/schemas/HTTPValidationError"
-                                }
+                    "HTTPValidationError": {
+                        "properties": {
+                            "detail": {
+                                "items": {
+                                    "$ref": "#/components/schemas/ValidationError"
+                                },
+                                "title": "Detail",
+                                "type": "array",
                             }
                         },
-                        "description": "Validation Error",
+                        "title": "HTTPValidationError",
+                        "type": "object",
                     },
-                },
-                "summary": "Get Facility",
-            }
+                    "ValidationError": {
+                        "properties": {
+                            "loc": {
+                                "items": {
+                                    "anyOf": [{"type": "string"}, {"type": "integer"}]
+                                },
+                                "title": "Location",
+                                "type": "array",
+                            },
+                            "msg": {"title": "Message", "type": "string"},
+                            "type": {"title": "Error Type", "type": "string"},
+                        },
+                        "required": ["loc", "msg", "type"],
+                        "title": "ValidationError",
+                        "type": "object",
+                    },
+                }
+            },
+            "info": {"title": "FastAPI", "version": "0.1.0"},
+            "openapi": "3.1.0",
+            "paths": {
+                "/facilities/{facility_id}": {
+                    "get": {
+                        "operationId": "get_facility_facilities__facility_id__get",
+                        "parameters": [
+                            {
+                                "in": "path",
+                                "name": "facility_id",
+                                "required": True,
+                                "schema": {"title": "Facility Id", "type": "string"},
+                            }
+                        ],
+                        "responses": {
+                            "200": {
+                                "content": {
+                                    "application/json": {
+                                        "schema": {
+                                            "$ref": "#/components/schemas/Facility"
+                                        }
+                                    }
+                                },
+                                "description": "Successful Response",
+                            },
+                            "422": {
+                                "content": {
+                                    "application/json": {
+                                        "schema": {
+                                            "$ref": "#/components/schemas/HTTPValidationError"
+                                        }
+                                    }
+                                },
+                                "description": "Validation Error",
+                            },
+                        },
+                        "summary": "Get Facility",
+                    }
+                }
+            },
         }
-    },
-}
-
-
-def test_openapi_schema():
-    """
-    Sanity check to ensure our app's openapi schema renders as we expect
-    """
-    response = client.get("/openapi.json")
-    assert response.status_code == 200, response.text
-    assert response.json() == openapi_schema
-
-
-class SortedTypeSet(set):
-    """
-    Set of Types whose `__iter__()` method yields results sorted by the type names
-    """
-
-    def __init__(self, seq: set[type[Any]], *, sort_reversed: bool):
-        super().__init__(seq)
-        self.sort_reversed = sort_reversed
-
-    def __iter__(self) -> Iterator[type[Any]]:
-        members_sorted = sorted(
-            super().__iter__(),
-            key=lambda type_: type_.__name__,
-            reverse=self.sort_reversed,
-        )
-        yield from members_sorted
-
-
-@needs_pydanticv1
-@pytest.mark.parametrize("sort_reversed", [True, False])
-def test_model_description_escaped_with_formfeed(sort_reversed: bool):
-    """
-    Regression test for bug fixed by https://github.com/fastapi/fastapi/pull/6039.
-
-    Test `get_model_definitions` with models passed in different order.
-    """
-    from fastapi._compat import v1
-
-    all_fields = fastapi.openapi.utils.get_fields_from_routes(app.routes)
-
-    flat_models = v1.get_flat_models_from_fields(all_fields, known_models=set())
-    model_name_map = pydantic.schema.get_model_name_map(flat_models)
-
-    expected_address_description = "This is a public description of an Address\n"
-
-    models = v1.get_model_definitions(
-        flat_models=SortedTypeSet(flat_models, sort_reversed=sort_reversed),
-        model_name_map=model_name_map,
     )
-    assert models["Address"]["description"] == expected_address_description
index fe9350f4ef35307902db98973afa73d001732c68..7f29fe33eda756af5402e7fc6c489f1f0741304d 100644 (file)
@@ -5,7 +5,7 @@ from fastapi import FastAPI
 from fastapi.testclient import TestClient
 from pydantic import BaseModel
 
-from .utils import needs_pydanticv1, needs_pydanticv2
+from .utils import needs_pydanticv1
 
 
 class MyUuid:
@@ -26,7 +26,6 @@ class MyUuid:
         raise TypeError("vars() argument must have __dict__ attribute")
 
 
-@needs_pydanticv2
 def test_pydanticv2():
     from pydantic import field_serializer
 
@@ -73,6 +72,8 @@ def test_pydanticv2():
 # TODO: remove when deprecating Pydantic v1
 @needs_pydanticv1
 def test_pydanticv1():
+    from pydantic import v1
+
     app = FastAPI()
 
     @app.get("/fast_uuid")
@@ -84,7 +85,7 @@ def test_pydanticv1():
             vars(asyncpg_uuid)
         return {"fast_uuid": asyncpg_uuid}
 
-    class SomeCustomClass(BaseModel):
+    class SomeCustomClass(v1.BaseModel):
         class Config:
             arbitrary_types_allowed = True
             json_encoders = {uuid.UUID: str}
index 3b6513e27bf40eb3f85067180e7e4facb8041b3a..81bf94ece0aa73be877c8bd6937ac07d4d5bd409 100644 (file)
@@ -8,11 +8,11 @@ from pathlib import PurePath, PurePosixPath, PureWindowsPath
 from typing import Optional
 
 import pytest
-from fastapi._compat import PYDANTIC_V2, Undefined
+from fastapi._compat import Undefined
 from fastapi.encoders import jsonable_encoder
 from pydantic import BaseModel, Field, ValidationError
 
-from .utils import needs_pydanticv1, needs_pydanticv2
+from .utils import needs_pydanticv1
 
 
 class Person:
@@ -59,12 +59,7 @@ class RoleEnum(Enum):
 class ModelWithConfig(BaseModel):
     role: Optional[RoleEnum] = None
 
-    if PYDANTIC_V2:
-        model_config = {"use_enum_values": True}
-    else:
-
-        class Config:
-            use_enum_values = True
+    model_config = {"use_enum_values": True}
 
 
 class ModelWithAlias(BaseModel):
@@ -89,6 +84,18 @@ def test_encode_dict():
     }
 
 
+def test_encode_dict_include_exclude_list():
+    pet = {"name": "Firulais", "owner": {"name": "Foo"}}
+    assert jsonable_encoder(pet) == {"name": "Firulais", "owner": {"name": "Foo"}}
+    assert jsonable_encoder(pet, include=["name"]) == {"name": "Firulais"}
+    assert jsonable_encoder(pet, exclude=["owner"]) == {"name": "Firulais"}
+    assert jsonable_encoder(pet, include=[]) == {}
+    assert jsonable_encoder(pet, exclude=[]) == {
+        "name": "Firulais",
+        "owner": {"name": "Foo"},
+    }
+
+
 def test_encode_class():
     person = Person(name="Foo")
     pet = Pet(owner=person, name="Firulais")
@@ -130,7 +137,6 @@ def test_encode_unsupported():
         jsonable_encoder(unserializable)
 
 
-@needs_pydanticv2
 def test_encode_custom_json_encoders_model_pydanticv2():
     from pydantic import field_serializer
 
@@ -153,7 +159,9 @@ def test_encode_custom_json_encoders_model_pydanticv2():
 # TODO: remove when deprecating Pydantic v1
 @needs_pydanticv1
 def test_encode_custom_json_encoders_model_pydanticv1():
-    class ModelWithCustomEncoder(BaseModel):
+    from pydantic import v1
+
+    class ModelWithCustomEncoder(v1.BaseModel):
         dt_field: datetime
 
         class Config:
@@ -208,10 +216,12 @@ def test_encode_model_with_default():
 
 @needs_pydanticv1
 def test_custom_encoders():
+    from pydantic import v1
+
     class safe_datetime(datetime):
         pass
 
-    class MyModel(BaseModel):
+    class MyModel(v1.BaseModel):
         dt_field: safe_datetime
 
     instance = MyModel(dt_field=safe_datetime.now())
@@ -244,12 +254,7 @@ def test_encode_model_with_pure_path():
     class ModelWithPath(BaseModel):
         path: PurePath
 
-        if PYDANTIC_V2:
-            model_config = {"arbitrary_types_allowed": True}
-        else:
-
-            class Config:
-                arbitrary_types_allowed = True
+        model_config = {"arbitrary_types_allowed": True}
 
     test_path = PurePath("/foo", "bar")
     obj = ModelWithPath(path=test_path)
@@ -260,12 +265,7 @@ def test_encode_model_with_pure_posix_path():
     class ModelWithPath(BaseModel):
         path: PurePosixPath
 
-        if PYDANTIC_V2:
-            model_config = {"arbitrary_types_allowed": True}
-        else:
-
-            class Config:
-                arbitrary_types_allowed = True
+        model_config = {"arbitrary_types_allowed": True}
 
     obj = ModelWithPath(path=PurePosixPath("/foo", "bar"))
     assert jsonable_encoder(obj) == {"path": "/foo/bar"}
@@ -275,45 +275,44 @@ def test_encode_model_with_pure_windows_path():
     class ModelWithPath(BaseModel):
         path: PureWindowsPath
 
-        if PYDANTIC_V2:
-            model_config = {"arbitrary_types_allowed": True}
-        else:
-
-            class Config:
-                arbitrary_types_allowed = True
+        model_config = {"arbitrary_types_allowed": True}
 
     obj = ModelWithPath(path=PureWindowsPath("/foo", "bar"))
     assert jsonable_encoder(obj) == {"path": "\\foo\\bar"}
 
 
+def test_encode_pure_path():
+    test_path = PurePath("/foo", "bar")
+
+    assert jsonable_encoder({"path": test_path}) == {"path": str(test_path)}
+
+
 @needs_pydanticv1
 def test_encode_root():
-    class ModelWithRoot(BaseModel):
+    from pydantic import v1
+
+    class ModelWithRoot(v1.BaseModel):
         __root__: str
 
     model = ModelWithRoot(__root__="Foo")
     assert jsonable_encoder(model) == "Foo"
 
 
-@needs_pydanticv2
 def test_decimal_encoder_float():
     data = {"value": Decimal(1.23)}
     assert jsonable_encoder(data) == {"value": 1.23}
 
 
-@needs_pydanticv2
 def test_decimal_encoder_int():
     data = {"value": Decimal(2)}
     assert jsonable_encoder(data) == {"value": 2}
 
 
-@needs_pydanticv2
 def test_decimal_encoder_nan():
     data = {"value": Decimal("NaN")}
     assert isnan(jsonable_encoder(data)["value"])
 
 
-@needs_pydanticv2
 def test_decimal_encoder_infinity():
     data = {"value": Decimal("Infinity")}
     assert isinf(jsonable_encoder(data)["value"])
@@ -330,7 +329,6 @@ def test_encode_deque_encodes_child_models():
     assert jsonable_encoder(dq)[0]["test"] == "test"
 
 
-@needs_pydanticv2
 def test_encode_pydantic_undefined():
     data = {"value": Undefined}
     assert jsonable_encoder(data) == {"value": None}
index 6169867ba3a1337c9782a435f6a810f89bcb324b..131a3755e74e75603662c6e5a2fd64c0cd35cf97 100644 (file)
@@ -9,8 +9,6 @@ from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 from pydantic import BaseModel, Field
 
-from tests.utils import pydantic_snapshot
-
 
 class MessageEventType(str, Enum):
     alpha = "alpha"
@@ -126,47 +124,21 @@ def test_openapi_schema():
                     },
                     "MessageEvent": {
                         "properties": {
-                            "event_type": pydantic_snapshot(
-                                v2=snapshot(
-                                    {
-                                        "$ref": "#/components/schemas/MessageEventType",
-                                        "default": "alpha",
-                                    }
-                                ),
-                                v1=snapshot(
-                                    {
-                                        "allOf": [
-                                            {
-                                                "$ref": "#/components/schemas/MessageEventType"
-                                            }
-                                        ],
-                                        "default": "alpha",
-                                    }
-                                ),
-                            ),
+                            "event_type": {
+                                "$ref": "#/components/schemas/MessageEventType",
+                                "default": "alpha",
+                            },
                             "output": {"type": "string", "title": "Output"},
                         },
                         "type": "object",
                         "required": ["output"],
                         "title": "MessageEvent",
                     },
-                    "MessageEventType": pydantic_snapshot(
-                        v2=snapshot(
-                            {
-                                "type": "string",
-                                "enum": ["alpha", "beta"],
-                                "title": "MessageEventType",
-                            }
-                        ),
-                        v1=snapshot(
-                            {
-                                "type": "string",
-                                "enum": ["alpha", "beta"],
-                                "title": "MessageEventType",
-                                "description": "An enumeration.",
-                            }
-                        ),
-                    ),
+                    "MessageEventType": {
+                        "type": "string",
+                        "enum": ["alpha", "beta"],
+                        "title": "MessageEventType",
+                    },
                     "MessageOutput": {
                         "properties": {
                             "body": {"type": "string", "title": "Body", "default": ""},
index bfe5e9a712212524a5b909be6642998dfafb6277..1891f0bde0b8dc24819f037d813ad003379a4eeb 100644 (file)
@@ -3,37 +3,30 @@ from typing import Optional
 from fastapi import FastAPI
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
-from pydantic import BaseModel
-
-from .utils import PYDANTIC_V2, needs_pydanticv2
+from pydantic import BaseModel, computed_field
 
 
 class SubItem(BaseModel):
     subname: str
     sub_description: Optional[str] = None
     tags: list[str] = []
-    if PYDANTIC_V2:
-        model_config = {"json_schema_serialization_defaults_required": True}
+    model_config = {"json_schema_serialization_defaults_required": True}
 
 
 class Item(BaseModel):
     name: str
     description: Optional[str] = None
     sub: Optional[SubItem] = None
-    if PYDANTIC_V2:
-        model_config = {"json_schema_serialization_defaults_required": True}
-
+    model_config = {"json_schema_serialization_defaults_required": True}
 
-if PYDANTIC_V2:
-    from pydantic import computed_field
 
-    class WithComputedField(BaseModel):
-        name: str
+class WithComputedField(BaseModel):
+    name: str
 
-        @computed_field
-        @property
-        def computed_field(self) -> str:
-            return f"computed {self.name}"
+    @computed_field
+    @property
+    def computed_field(self) -> str:
+        return f"computed {self.name}"
 
 
 def get_app_client(separate_input_output_schemas: bool = True) -> TestClient:
@@ -58,13 +51,11 @@ def get_app_client(separate_input_output_schemas: bool = True) -> TestClient:
             Item(name="Plumbus"),
         ]
 
-    if PYDANTIC_V2:
-
-        @app.post("/with-computed-field/")
-        def create_with_computed_field(
-            with_computed_field: WithComputedField,
-        ) -> WithComputedField:
-            return with_computed_field
+    @app.post("/with-computed-field/")
+    def create_with_computed_field(
+        with_computed_field: WithComputedField,
+    ) -> WithComputedField:
+        return with_computed_field
 
     client = TestClient(app)
     return client
@@ -151,7 +142,6 @@ def test_read_items():
     )
 
 
-@needs_pydanticv2
 def test_with_computed_field():
     client = get_app_client()
     client_no = get_app_client(separate_input_output_schemas=False)
@@ -168,7 +158,6 @@ def test_with_computed_field():
     )
 
 
-@needs_pydanticv2
 def test_openapi_schema():
     client = get_app_client()
     response = client.get("/openapi.json")
@@ -449,7 +438,6 @@ def test_openapi_schema():
     )
 
 
-@needs_pydanticv2
 def test_openapi_schema_no_separate():
     client = get_app_client(separate_input_output_schemas=False)
     response = client.get("/openapi.json")
index ebf86b99f0ec6056350753058f643b3f0fd761d9..83536cafa2381229ab7b3e7317b5780ff9e2fa46 100644 (file)
@@ -1,7 +1,7 @@
 import sys
 from typing import Any, Union
 
-from tests.utils import pydantic_snapshot, skip_module_if_py_gte_314
+from tests.utils import skip_module_if_py_gte_314
 
 if sys.version_info >= (3, 14):
     skip_module_if_py_gte_314()
@@ -225,21 +225,12 @@ def test_openapi_schema():
                         "requestBody": {
                             "content": {
                                 "application/json": {
-                                    "schema": pydantic_snapshot(
-                                        v2=snapshot(
-                                            {
-                                                "allOf": [
-                                                    {
-                                                        "$ref": "#/components/schemas/SubItem"
-                                                    }
-                                                ],
-                                                "title": "Data",
-                                            }
-                                        ),
-                                        v1=snapshot(
+                                    "schema": {
+                                        "allOf": [
                                             {"$ref": "#/components/schemas/SubItem"}
-                                        ),
-                                    )
+                                        ],
+                                        "title": "Data",
+                                    }
                                 }
                             },
                             "required": True,
@@ -275,21 +266,12 @@ def test_openapi_schema():
                         "requestBody": {
                             "content": {
                                 "application/json": {
-                                    "schema": pydantic_snapshot(
-                                        v2=snapshot(
-                                            {
-                                                "allOf": [
-                                                    {
-                                                        "$ref": "#/components/schemas/SubItem"
-                                                    }
-                                                ],
-                                                "title": "Data",
-                                            }
-                                        ),
-                                        v1=snapshot(
+                                    "schema": {
+                                        "allOf": [
                                             {"$ref": "#/components/schemas/SubItem"}
-                                        ),
-                                    )
+                                        ],
+                                        "title": "Data",
+                                    }
                                 }
                             },
                             "required": True,
@@ -325,21 +307,12 @@ def test_openapi_schema():
                         "requestBody": {
                             "content": {
                                 "application/json": {
-                                    "schema": pydantic_snapshot(
-                                        v2=snapshot(
-                                            {
-                                                "allOf": [
-                                                    {
-                                                        "$ref": "#/components/schemas/Item"
-                                                    }
-                                                ],
-                                                "title": "Data",
-                                            }
-                                        ),
-                                        v1=snapshot(
+                                    "schema": {
+                                        "allOf": [
                                             {"$ref": "#/components/schemas/Item"}
-                                        ),
-                                    )
+                                        ],
+                                        "title": "Data",
+                                    }
                                 }
                             },
                             "required": True,
@@ -373,21 +346,12 @@ def test_openapi_schema():
                         "requestBody": {
                             "content": {
                                 "application/json": {
-                                    "schema": pydantic_snapshot(
-                                        v2=snapshot(
-                                            {
-                                                "allOf": [
-                                                    {
-                                                        "$ref": "#/components/schemas/Item"
-                                                    }
-                                                ],
-                                                "title": "Data",
-                                            }
-                                        ),
-                                        v1=snapshot(
+                                    "schema": {
+                                        "allOf": [
                                             {"$ref": "#/components/schemas/Item"}
-                                        ),
-                                    )
+                                        ],
+                                        "title": "Data",
+                                    }
                                 }
                             },
                             "required": True,
index 8879b010decc292d689c3a0a58afcd0182d247ed..4ddcbf240de40abdb9df00aec71041da3fc804a3 100644 (file)
@@ -1,7 +1,7 @@
 import sys
 from typing import Any, Union
 
-from tests.utils import pydantic_snapshot, skip_module_if_py_gte_314
+from tests.utils import skip_module_if_py_gte_314
 
 if sys.version_info >= (3, 14):
     skip_module_if_py_gte_314()
@@ -375,21 +375,12 @@ def test_openapi_schema():
                         "requestBody": {
                             "content": {
                                 "application/json": {
-                                    "schema": pydantic_snapshot(
-                                        v2=snapshot(
-                                            {
-                                                "allOf": [
-                                                    {
-                                                        "$ref": "#/components/schemas/Item"
-                                                    }
-                                                ],
-                                                "title": "Data",
-                                            }
-                                        ),
-                                        v1=snapshot(
+                                    "schema": {
+                                        "allOf": [
                                             {"$ref": "#/components/schemas/Item"}
-                                        ),
-                                    )
+                                        ],
+                                        "title": "Data",
+                                    }
                                 }
                             },
                             "required": True,
@@ -429,21 +420,12 @@ def test_openapi_schema():
                         "requestBody": {
                             "content": {
                                 "application/json": {
-                                    "schema": pydantic_snapshot(
-                                        v2=snapshot(
-                                            {
-                                                "allOf": [
-                                                    {
-                                                        "$ref": "#/components/schemas/Item"
-                                                    }
-                                                ],
-                                                "title": "Data",
-                                            }
-                                        ),
-                                        v1=snapshot(
+                                    "schema": {
+                                        "allOf": [
                                             {"$ref": "#/components/schemas/Item"}
-                                        ),
-                                    )
+                                        ],
+                                        "title": "Data",
+                                    }
                                 }
                             },
                             "required": True,
index e66583cd54d56aa966bad26cc56f8a3ac29c0396..61e5bb5827bfe4a68d407f913847497ed118f6c2 100644 (file)
@@ -1,7 +1,7 @@
 import sys
 from typing import Any, Union
 
-from tests.utils import pydantic_snapshot, skip_module_if_py_gte_314
+from tests.utils import skip_module_if_py_gte_314
 
 if sys.version_info >= (3, 14):
     skip_module_if_py_gte_314()
@@ -668,38 +668,20 @@ def test_v2_to_v1_validation_error():
     assert response.status_code == 422, response.text
     assert response.json() == snapshot(
         {
-            "detail": pydantic_snapshot(
-                v2=snapshot(
-                    [
-                        {
-                            "type": "missing",
-                            "loc": ["body", "new_size"],
-                            "msg": "Field required",
-                            "input": {"new_title": "Missing fields"},
-                        },
-                        {
-                            "type": "missing",
-                            "loc": ["body", "new_sub"],
-                            "msg": "Field required",
-                            "input": {"new_title": "Missing fields"},
-                        },
-                    ]
-                ),
-                v1=snapshot(
-                    [
-                        {
-                            "loc": ["body", "new_size"],
-                            "msg": "field required",
-                            "type": "value_error.missing",
-                        },
-                        {
-                            "loc": ["body", "new_sub"],
-                            "msg": "field required",
-                            "type": "value_error.missing",
-                        },
-                    ]
-                ),
-            )
+            "detail": [
+                {
+                    "type": "missing",
+                    "loc": ["body", "new_size"],
+                    "msg": "Field required",
+                    "input": {"new_title": "Missing fields"},
+                },
+                {
+                    "type": "missing",
+                    "loc": ["body", "new_sub"],
+                    "msg": "Field required",
+                    "input": {"new_title": "Missing fields"},
+                },
+            ]
         }
     )
 
@@ -717,23 +699,12 @@ def test_v2_to_v1_nested_validation_error():
     assert response.json() == snapshot(
         {
             "detail": [
-                pydantic_snapshot(
-                    v2=snapshot(
-                        {
-                            "type": "missing",
-                            "loc": ["body", "new_sub", "new_sub_name"],
-                            "msg": "Field required",
-                            "input": {"wrong_field": "value"},
-                        }
-                    ),
-                    v1=snapshot(
-                        {
-                            "loc": ["body", "new_sub", "new_sub_name"],
-                            "msg": "field required",
-                            "type": "value_error.missing",
-                        }
-                    ),
-                )
+                {
+                    "type": "missing",
+                    "loc": ["body", "new_sub", "new_sub_name"],
+                    "msg": "Field required",
+                    "input": {"wrong_field": "value"},
+                }
             ]
         }
     )
@@ -777,38 +748,20 @@ def test_v2_list_validation_error():
     assert response.status_code == 422, response.text
     assert response.json() == snapshot(
         {
-            "detail": pydantic_snapshot(
-                v2=snapshot(
-                    [
-                        {
-                            "type": "missing",
-                            "loc": ["body", 1, "new_size"],
-                            "msg": "Field required",
-                            "input": {"new_title": "Invalid"},
-                        },
-                        {
-                            "type": "missing",
-                            "loc": ["body", 1, "new_sub"],
-                            "msg": "Field required",
-                            "input": {"new_title": "Invalid"},
-                        },
-                    ]
-                ),
-                v1=snapshot(
-                    [
-                        {
-                            "loc": ["body", 1, "new_size"],
-                            "msg": "field required",
-                            "type": "value_error.missing",
-                        },
-                        {
-                            "loc": ["body", 1, "new_sub"],
-                            "msg": "field required",
-                            "type": "value_error.missing",
-                        },
-                    ]
-                ),
-            )
+            "detail": [
+                {
+                    "type": "missing",
+                    "loc": ["body", 1, "new_size"],
+                    "msg": "Field required",
+                    "input": {"new_title": "Invalid"},
+                },
+                {
+                    "type": "missing",
+                    "loc": ["body", 1, "new_sub"],
+                    "msg": "Field required",
+                    "input": {"new_title": "Invalid"},
+                },
+            ]
         }
     )
 
@@ -844,31 +797,18 @@ def test_invalid_list_structure_v2():
     assert response.status_code == 422, response.text
     assert response.json() == snapshot(
         {
-            "detail": pydantic_snapshot(
-                v2=snapshot(
-                    [
-                        {
-                            "type": "list_type",
-                            "loc": ["body"],
-                            "msg": "Input should be a valid list",
-                            "input": {
-                                "new_title": "Not a list",
-                                "new_size": 100,
-                                "new_sub": {"new_sub_name": "Sub"},
-                            },
-                        }
-                    ]
-                ),
-                v1=snapshot(
-                    [
-                        {
-                            "loc": ["body"],
-                            "msg": "value is not a valid list",
-                            "type": "type_error.list",
-                        }
-                    ]
-                ),
-            )
+            "detail": [
+                {
+                    "type": "list_type",
+                    "loc": ["body"],
+                    "msg": "Input should be a valid list",
+                    "input": {
+                        "new_title": "Not a list",
+                        "new_size": 100,
+                        "new_sub": {"new_sub_name": "Sub"},
+                    },
+                }
+            ]
         }
     )
 
@@ -888,21 +828,12 @@ def test_openapi_schema():
                         "requestBody": {
                             "content": {
                                 "application/json": {
-                                    "schema": pydantic_snapshot(
-                                        v2=snapshot(
-                                            {
-                                                "allOf": [
-                                                    {
-                                                        "$ref": "#/components/schemas/Item"
-                                                    }
-                                                ],
-                                                "title": "Data",
-                                            }
-                                        ),
-                                        v1=snapshot(
+                                    "schema": {
+                                        "allOf": [
                                             {"$ref": "#/components/schemas/Item"}
-                                        ),
-                                    )
+                                        ],
+                                        "title": "Data",
+                                    }
                                 }
                             },
                             "required": True,
@@ -938,21 +869,12 @@ def test_openapi_schema():
                         "requestBody": {
                             "content": {
                                 "application/json": {
-                                    "schema": pydantic_snapshot(
-                                        v2=snapshot(
-                                            {
-                                                "allOf": [
-                                                    {
-                                                        "$ref": "#/components/schemas/Item"
-                                                    }
-                                                ],
-                                                "title": "Data",
-                                            }
-                                        ),
-                                        v1=snapshot(
+                                    "schema": {
+                                        "allOf": [
                                             {"$ref": "#/components/schemas/Item"}
-                                        ),
-                                    )
+                                        ],
+                                        "title": "Data",
+                                    }
                                 }
                             },
                             "required": True,
@@ -1056,21 +978,12 @@ def test_openapi_schema():
                         "requestBody": {
                             "content": {
                                 "application/json": {
-                                    "schema": pydantic_snapshot(
-                                        v2=snapshot(
-                                            {
-                                                "allOf": [
-                                                    {
-                                                        "$ref": "#/components/schemas/Item"
-                                                    }
-                                                ],
-                                                "title": "Data",
-                                            }
-                                        ),
-                                        v1=snapshot(
+                                    "schema": {
+                                        "allOf": [
                                             {"$ref": "#/components/schemas/Item"}
-                                        ),
-                                    )
+                                        ],
+                                        "title": "Data",
+                                    }
                                 }
                             },
                             "required": True,
@@ -1440,17 +1353,10 @@ def test_openapi_schema():
                         "properties": {
                             "new_title": {"type": "string", "title": "New Title"},
                             "new_size": {"type": "integer", "title": "New Size"},
-                            "new_description": pydantic_snapshot(
-                                v2=snapshot(
-                                    {
-                                        "anyOf": [{"type": "string"}, {"type": "null"}],
-                                        "title": "New Description",
-                                    }
-                                ),
-                                v1=snapshot(
-                                    {"type": "string", "title": "New Description"}
-                                ),
-                            ),
+                            "new_description": {
+                                "anyOf": [{"type": "string"}, {"type": "null"}],
+                                "title": "New Description",
+                            },
                             "new_sub": {"$ref": "#/components/schemas/NewSubItem"},
                             "new_multi": {
                                 "items": {"$ref": "#/components/schemas/NewSubItem"},
index e66d102fb35d02ba1bd039a609a2d2d9f1e5cd7f..32d901961655b47c3ec325ef51867d2d1087c731 100644 (file)
@@ -1,6 +1,6 @@
 import sys
 
-from tests.utils import pydantic_snapshot, skip_module_if_py_gte_314
+from tests.utils import skip_module_if_py_gte_314
 
 if sys.version_info >= (3, 14):
     skip_module_if_py_gte_314()
@@ -292,23 +292,14 @@ def test_openapi_schema():
                         "requestBody": {
                             "content": {
                                 "application/json": {
-                                    "schema": pydantic_snapshot(
-                                        v2=snapshot(
-                                            {
-                                                "allOf": [
-                                                    {
-                                                        "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv1__Item"
-                                                    }
-                                                ],
-                                                "title": "Data",
-                                            }
-                                        ),
-                                        v1=snapshot(
+                                    "schema": {
+                                        "allOf": [
                                             {
                                                 "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv1__Item"
                                             }
-                                        ),
-                                    )
+                                        ],
+                                        "title": "Data",
+                                    }
                                 }
                             },
                             "required": True,
@@ -344,18 +335,9 @@ def test_openapi_schema():
                         "requestBody": {
                             "content": {
                                 "application/json": {
-                                    "schema": pydantic_snapshot(
-                                        v2=snapshot(
-                                            {
-                                                "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2__Item-Input"
-                                            }
-                                        ),
-                                        v1=snapshot(
-                                            {
-                                                "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2__Item"
-                                            }
-                                        ),
-                                    ),
+                                    "schema": {
+                                        "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2__Item-Input"
+                                    },
                                 }
                             },
                             "required": True,
@@ -391,23 +373,14 @@ def test_openapi_schema():
                         "requestBody": {
                             "content": {
                                 "application/json": {
-                                    "schema": pydantic_snapshot(
-                                        v2=snapshot(
-                                            {
-                                                "allOf": [
-                                                    {
-                                                        "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv1__Item"
-                                                    }
-                                                ],
-                                                "title": "Data",
-                                            }
-                                        ),
-                                        v1=snapshot(
+                                    "schema": {
+                                        "allOf": [
                                             {
                                                 "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv1__Item"
                                             }
-                                        ),
-                                    )
+                                        ],
+                                        "title": "Data",
+                                    }
                                 }
                             },
                             "required": True,
@@ -535,18 +508,9 @@ def test_openapi_schema():
                         "requestBody": {
                             "content": {
                                 "application/json": {
-                                    "schema": pydantic_snapshot(
-                                        v2=snapshot(
-                                            {
-                                                "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2__Item-Input"
-                                            }
-                                        ),
-                                        v1=snapshot(
-                                            {
-                                                "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2__Item"
-                                            }
-                                        ),
-                                    ),
+                                    "schema": {
+                                        "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2__Item-Input"
+                                    },
                                 }
                             },
                             "required": True,
@@ -587,18 +551,9 @@ def test_openapi_schema():
                             "content": {
                                 "application/json": {
                                     "schema": {
-                                        "items": pydantic_snapshot(
-                                            v2=snapshot(
-                                                {
-                                                    "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2__Item-Input"
-                                                }
-                                            ),
-                                            v1=snapshot(
-                                                {
-                                                    "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2__Item"
-                                                }
-                                            ),
-                                        ),
+                                        "items": {
+                                            "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2__Item-Input"
+                                        },
                                         "type": "array",
                                         "title": "Data",
                                     }
@@ -642,18 +597,9 @@ def test_openapi_schema():
                             "content": {
                                 "application/json": {
                                     "schema": {
-                                        "items": pydantic_snapshot(
-                                            v2=snapshot(
-                                                {
-                                                    "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2__Item-Input"
-                                                }
-                                            ),
-                                            v1=snapshot(
-                                                {
-                                                    "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2__Item"
-                                                }
-                                            ),
-                                        ),
+                                        "items": {
+                                            "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2__Item-Input"
+                                        },
                                         "type": "array",
                                         "title": "Data",
                                     }
@@ -767,460 +713,239 @@ def test_openapi_schema():
                 },
             },
             "components": {
-                "schemas": pydantic_snapshot(
-                    v1=snapshot(
-                        {
-                            "Body_handle_v2_items_in_list_to_v1_item_in_list_v2_to_v1_list_of_items_to_list_of_items_post": {
-                                "properties": {
-                                    "data1": {
-                                        "items": {
-                                            "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2__ItemInList"
-                                        },
-                                        "type": "array",
-                                        "title": "Data1",
-                                    },
-                                    "data2": {
-                                        "items": {
-                                            "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2b__ItemInList"
-                                        },
-                                        "type": "array",
-                                        "title": "Data2",
-                                    },
-                                },
-                                "type": "object",
-                                "required": ["data1", "data2"],
-                                "title": "Body_handle_v2_items_in_list_to_v1_item_in_list_v2_to_v1_list_of_items_to_list_of_items_post",
-                            },
-                            "Body_handle_v2_same_name_to_v1_v2_to_v1_same_name_post": {
-                                "properties": {
-                                    "item1": {
-                                        "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2__Item"
-                                    },
-                                    "item2": {
-                                        "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2b__Item"
-                                    },
-                                },
-                                "type": "object",
-                                "required": ["item1", "item2"],
-                                "title": "Body_handle_v2_same_name_to_v1_v2_to_v1_same_name_post",
-                            },
-                            "HTTPValidationError": {
-                                "properties": {
-                                    "detail": {
-                                        "items": {
-                                            "$ref": "#/components/schemas/ValidationError"
-                                        },
-                                        "type": "array",
-                                        "title": "Detail",
-                                    }
-                                },
-                                "type": "object",
-                                "title": "HTTPValidationError",
-                            },
-                            "ValidationError": {
-                                "properties": {
-                                    "loc": {
-                                        "items": {
-                                            "anyOf": [
-                                                {"type": "string"},
-                                                {"type": "integer"},
-                                            ]
-                                        },
-                                        "type": "array",
-                                        "title": "Location",
-                                    },
-                                    "msg": {"type": "string", "title": "Message"},
-                                    "type": {"type": "string", "title": "Error Type"},
-                                },
-                                "type": "object",
-                                "required": ["loc", "msg", "type"],
-                                "title": "ValidationError",
-                            },
-                            "tests__test_pydantic_v1_v2_multifile__modelsv1__Item": {
-                                "properties": {
-                                    "title": {"type": "string", "title": "Title"},
-                                    "size": {"type": "integer", "title": "Size"},
-                                    "description": {
-                                        "type": "string",
-                                        "title": "Description",
-                                    },
-                                    "sub": {
-                                        "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv1__SubItem"
-                                    },
-                                    "multi": {
-                                        "items": {
-                                            "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv1__SubItem"
-                                        },
-                                        "type": "array",
-                                        "title": "Multi",
-                                        "default": [],
-                                    },
-                                },
-                                "type": "object",
-                                "required": ["title", "size", "sub"],
-                                "title": "Item",
-                            },
-                            "tests__test_pydantic_v1_v2_multifile__modelsv1__ItemInList": {
-                                "properties": {
-                                    "name1": {"type": "string", "title": "Name1"}
-                                },
-                                "type": "object",
-                                "required": ["name1"],
-                                "title": "ItemInList",
-                            },
-                            "tests__test_pydantic_v1_v2_multifile__modelsv1__SubItem": {
-                                "properties": {
-                                    "name": {"type": "string", "title": "Name"}
-                                },
-                                "type": "object",
-                                "required": ["name"],
-                                "title": "SubItem",
-                            },
-                            "tests__test_pydantic_v1_v2_multifile__modelsv2__Item": {
-                                "properties": {
-                                    "new_title": {
-                                        "type": "string",
-                                        "title": "New Title",
-                                    },
-                                    "new_size": {
-                                        "type": "integer",
-                                        "title": "New Size",
-                                    },
-                                    "new_description": {
-                                        "type": "string",
-                                        "title": "New Description",
-                                    },
-                                    "new_sub": {
-                                        "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2__SubItem"
-                                    },
-                                    "new_multi": {
-                                        "items": {
-                                            "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2__SubItem"
-                                        },
-                                        "type": "array",
-                                        "title": "New Multi",
-                                        "default": [],
-                                    },
-                                },
-                                "type": "object",
-                                "required": ["new_title", "new_size", "new_sub"],
-                                "title": "Item",
-                            },
-                            "tests__test_pydantic_v1_v2_multifile__modelsv2__ItemInList": {
-                                "properties": {
-                                    "name2": {"type": "string", "title": "Name2"}
-                                },
-                                "type": "object",
-                                "required": ["name2"],
-                                "title": "ItemInList",
-                            },
-                            "tests__test_pydantic_v1_v2_multifile__modelsv2__SubItem": {
-                                "properties": {
-                                    "new_sub_name": {
-                                        "type": "string",
-                                        "title": "New Sub Name",
-                                    }
-                                },
-                                "type": "object",
-                                "required": ["new_sub_name"],
-                                "title": "SubItem",
-                            },
-                            "tests__test_pydantic_v1_v2_multifile__modelsv2b__Item": {
-                                "properties": {
-                                    "dup_title": {
-                                        "type": "string",
-                                        "title": "Dup Title",
-                                    },
-                                    "dup_size": {
-                                        "type": "integer",
-                                        "title": "Dup Size",
-                                    },
-                                    "dup_description": {
-                                        "type": "string",
-                                        "title": "Dup Description",
-                                    },
-                                    "dup_sub": {
-                                        "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2b__SubItem"
-                                    },
-                                    "dup_multi": {
-                                        "items": {
-                                            "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2b__SubItem"
-                                        },
-                                        "type": "array",
-                                        "title": "Dup Multi",
-                                        "default": [],
-                                    },
+                "schemas": {
+                    "Body_handle_v2_items_in_list_to_v1_item_in_list_v2_to_v1_list_of_items_to_list_of_items_post": {
+                        "properties": {
+                            "data1": {
+                                "items": {
+                                    "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2__ItemInList"
                                 },
-                                "type": "object",
-                                "required": ["dup_title", "dup_size", "dup_sub"],
-                                "title": "Item",
+                                "type": "array",
+                                "title": "Data1",
                             },
-                            "tests__test_pydantic_v1_v2_multifile__modelsv2b__ItemInList": {
-                                "properties": {
-                                    "dup_name2": {
-                                        "type": "string",
-                                        "title": "Dup Name2",
-                                    }
-                                },
-                                "type": "object",
-                                "required": ["dup_name2"],
-                                "title": "ItemInList",
-                            },
-                            "tests__test_pydantic_v1_v2_multifile__modelsv2b__SubItem": {
-                                "properties": {
-                                    "dup_sub_name": {
-                                        "type": "string",
-                                        "title": "Dup Sub Name",
-                                    }
-                                },
-                                "type": "object",
-                                "required": ["dup_sub_name"],
-                                "title": "SubItem",
-                            },
-                        }
-                    ),
-                    v2=snapshot(
-                        {
-                            "Body_handle_v2_items_in_list_to_v1_item_in_list_v2_to_v1_list_of_items_to_list_of_items_post": {
-                                "properties": {
-                                    "data1": {
-                                        "items": {
-                                            "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2__ItemInList"
-                                        },
-                                        "type": "array",
-                                        "title": "Data1",
-                                    },
-                                    "data2": {
-                                        "items": {
-                                            "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2b__ItemInList"
-                                        },
-                                        "type": "array",
-                                        "title": "Data2",
-                                    },
-                                },
-                                "type": "object",
-                                "required": ["data1", "data2"],
-                                "title": "Body_handle_v2_items_in_list_to_v1_item_in_list_v2_to_v1_list_of_items_to_list_of_items_post",
-                            },
-                            "Body_handle_v2_same_name_to_v1_v2_to_v1_same_name_post": {
-                                "properties": {
-                                    "item1": {
-                                        "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2__Item-Input"
-                                    },
-                                    "item2": {
-                                        "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2b__Item"
-                                    },
-                                },
-                                "type": "object",
-                                "required": ["item1", "item2"],
-                                "title": "Body_handle_v2_same_name_to_v1_v2_to_v1_same_name_post",
-                            },
-                            "HTTPValidationError": {
-                                "properties": {
-                                    "detail": {
-                                        "items": {
-                                            "$ref": "#/components/schemas/ValidationError"
-                                        },
-                                        "type": "array",
-                                        "title": "Detail",
-                                    }
-                                },
-                                "type": "object",
-                                "title": "HTTPValidationError",
-                            },
-                            "ValidationError": {
-                                "properties": {
-                                    "loc": {
-                                        "items": {
-                                            "anyOf": [
-                                                {"type": "string"},
-                                                {"type": "integer"},
-                                            ]
-                                        },
-                                        "type": "array",
-                                        "title": "Location",
-                                    },
-                                    "msg": {"type": "string", "title": "Message"},
-                                    "type": {"type": "string", "title": "Error Type"},
+                            "data2": {
+                                "items": {
+                                    "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2b__ItemInList"
                                 },
-                                "type": "object",
-                                "required": ["loc", "msg", "type"],
-                                "title": "ValidationError",
+                                "type": "array",
+                                "title": "Data2",
                             },
-                            "tests__test_pydantic_v1_v2_multifile__modelsv1__Item": {
-                                "properties": {
-                                    "title": {"type": "string", "title": "Title"},
-                                    "size": {"type": "integer", "title": "Size"},
-                                    "description": {
-                                        "type": "string",
-                                        "title": "Description",
-                                    },
-                                    "sub": {
-                                        "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv1__SubItem"
-                                    },
-                                    "multi": {
-                                        "items": {
-                                            "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv1__SubItem"
-                                        },
-                                        "type": "array",
-                                        "title": "Multi",
-                                        "default": [],
-                                    },
-                                },
-                                "type": "object",
-                                "required": ["title", "size", "sub"],
-                                "title": "Item",
-                            },
-                            "tests__test_pydantic_v1_v2_multifile__modelsv1__ItemInList": {
-                                "properties": {
-                                    "name1": {"type": "string", "title": "Name1"}
-                                },
-                                "type": "object",
-                                "required": ["name1"],
-                                "title": "ItemInList",
-                            },
-                            "tests__test_pydantic_v1_v2_multifile__modelsv1__SubItem": {
-                                "properties": {
-                                    "name": {"type": "string", "title": "Name"}
-                                },
-                                "type": "object",
-                                "required": ["name"],
-                                "title": "SubItem",
-                            },
-                            "tests__test_pydantic_v1_v2_multifile__modelsv2__Item": {
-                                "properties": {
-                                    "new_title": {
-                                        "type": "string",
-                                        "title": "New Title",
-                                    },
-                                    "new_size": {
-                                        "type": "integer",
-                                        "title": "New Size",
-                                    },
-                                    "new_description": {
-                                        "anyOf": [{"type": "string"}, {"type": "null"}],
-                                        "title": "New Description",
-                                    },
-                                    "new_sub": {
-                                        "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2__SubItem"
-                                    },
-                                    "new_multi": {
-                                        "items": {
-                                            "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2__SubItem"
-                                        },
-                                        "type": "array",
-                                        "title": "New Multi",
-                                        "default": [],
-                                    },
-                                },
-                                "type": "object",
-                                "required": ["new_title", "new_size", "new_sub"],
-                                "title": "Item",
-                            },
-                            "tests__test_pydantic_v1_v2_multifile__modelsv2__Item-Input": {
-                                "properties": {
-                                    "new_title": {
-                                        "type": "string",
-                                        "title": "New Title",
-                                    },
-                                    "new_size": {
-                                        "type": "integer",
-                                        "title": "New Size",
-                                    },
-                                    "new_description": {
-                                        "anyOf": [{"type": "string"}, {"type": "null"}],
-                                        "title": "New Description",
-                                    },
-                                    "new_sub": {
-                                        "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2__SubItem"
-                                    },
-                                    "new_multi": {
-                                        "items": {
-                                            "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2__SubItem"
-                                        },
-                                        "type": "array",
-                                        "title": "New Multi",
-                                        "default": [],
-                                    },
-                                },
-                                "type": "object",
-                                "required": ["new_title", "new_size", "new_sub"],
-                                "title": "Item",
-                            },
-                            "tests__test_pydantic_v1_v2_multifile__modelsv2__ItemInList": {
-                                "properties": {
-                                    "name2": {"type": "string", "title": "Name2"}
-                                },
-                                "type": "object",
-                                "required": ["name2"],
-                                "title": "ItemInList",
+                        },
+                        "type": "object",
+                        "required": ["data1", "data2"],
+                        "title": "Body_handle_v2_items_in_list_to_v1_item_in_list_v2_to_v1_list_of_items_to_list_of_items_post",
+                    },
+                    "Body_handle_v2_same_name_to_v1_v2_to_v1_same_name_post": {
+                        "properties": {
+                            "item1": {
+                                "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2__Item-Input"
+                            },
+                            "item2": {
+                                "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2b__Item"
                             },
-                            "tests__test_pydantic_v1_v2_multifile__modelsv2__SubItem": {
-                                "properties": {
-                                    "new_sub_name": {
-                                        "type": "string",
-                                        "title": "New Sub Name",
-                                    }
-                                },
-                                "type": "object",
-                                "required": ["new_sub_name"],
-                                "title": "SubItem",
+                        },
+                        "type": "object",
+                        "required": ["item1", "item2"],
+                        "title": "Body_handle_v2_same_name_to_v1_v2_to_v1_same_name_post",
+                    },
+                    "HTTPValidationError": {
+                        "properties": {
+                            "detail": {
+                                "items": {
+                                    "$ref": "#/components/schemas/ValidationError"
+                                },
+                                "type": "array",
+                                "title": "Detail",
+                            }
+                        },
+                        "type": "object",
+                        "title": "HTTPValidationError",
+                    },
+                    "ValidationError": {
+                        "properties": {
+                            "loc": {
+                                "items": {
+                                    "anyOf": [
+                                        {"type": "string"},
+                                        {"type": "integer"},
+                                    ]
+                                },
+                                "type": "array",
+                                "title": "Location",
+                            },
+                            "msg": {"type": "string", "title": "Message"},
+                            "type": {"type": "string", "title": "Error Type"},
+                        },
+                        "type": "object",
+                        "required": ["loc", "msg", "type"],
+                        "title": "ValidationError",
+                    },
+                    "tests__test_pydantic_v1_v2_multifile__modelsv1__Item": {
+                        "properties": {
+                            "title": {"type": "string", "title": "Title"},
+                            "size": {"type": "integer", "title": "Size"},
+                            "description": {
+                                "type": "string",
+                                "title": "Description",
+                            },
+                            "sub": {
+                                "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv1__SubItem"
+                            },
+                            "multi": {
+                                "items": {
+                                    "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv1__SubItem"
+                                },
+                                "type": "array",
+                                "title": "Multi",
+                                "default": [],
                             },
-                            "tests__test_pydantic_v1_v2_multifile__modelsv2b__Item": {
-                                "properties": {
-                                    "dup_title": {
-                                        "type": "string",
-                                        "title": "Dup Title",
-                                    },
-                                    "dup_size": {
-                                        "type": "integer",
-                                        "title": "Dup Size",
-                                    },
-                                    "dup_description": {
-                                        "anyOf": [{"type": "string"}, {"type": "null"}],
-                                        "title": "Dup Description",
-                                    },
-                                    "dup_sub": {
-                                        "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2b__SubItem"
-                                    },
-                                    "dup_multi": {
-                                        "items": {
-                                            "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2b__SubItem"
-                                        },
-                                        "type": "array",
-                                        "title": "Dup Multi",
-                                        "default": [],
-                                    },
-                                },
-                                "type": "object",
-                                "required": ["dup_title", "dup_size", "dup_sub"],
-                                "title": "Item",
+                        },
+                        "type": "object",
+                        "required": ["title", "size", "sub"],
+                        "title": "Item",
+                    },
+                    "tests__test_pydantic_v1_v2_multifile__modelsv1__ItemInList": {
+                        "properties": {"name1": {"type": "string", "title": "Name1"}},
+                        "type": "object",
+                        "required": ["name1"],
+                        "title": "ItemInList",
+                    },
+                    "tests__test_pydantic_v1_v2_multifile__modelsv1__SubItem": {
+                        "properties": {"name": {"type": "string", "title": "Name"}},
+                        "type": "object",
+                        "required": ["name"],
+                        "title": "SubItem",
+                    },
+                    "tests__test_pydantic_v1_v2_multifile__modelsv2__Item": {
+                        "properties": {
+                            "new_title": {
+                                "type": "string",
+                                "title": "New Title",
+                            },
+                            "new_size": {
+                                "type": "integer",
+                                "title": "New Size",
+                            },
+                            "new_description": {
+                                "anyOf": [{"type": "string"}, {"type": "null"}],
+                                "title": "New Description",
+                            },
+                            "new_sub": {
+                                "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2__SubItem"
+                            },
+                            "new_multi": {
+                                "items": {
+                                    "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2__SubItem"
+                                },
+                                "type": "array",
+                                "title": "New Multi",
+                                "default": [],
                             },
-                            "tests__test_pydantic_v1_v2_multifile__modelsv2b__ItemInList": {
-                                "properties": {
-                                    "dup_name2": {
-                                        "type": "string",
-                                        "title": "Dup Name2",
-                                    }
-                                },
-                                "type": "object",
-                                "required": ["dup_name2"],
-                                "title": "ItemInList",
+                        },
+                        "type": "object",
+                        "required": ["new_title", "new_size", "new_sub"],
+                        "title": "Item",
+                    },
+                    "tests__test_pydantic_v1_v2_multifile__modelsv2__Item-Input": {
+                        "properties": {
+                            "new_title": {
+                                "type": "string",
+                                "title": "New Title",
+                            },
+                            "new_size": {
+                                "type": "integer",
+                                "title": "New Size",
+                            },
+                            "new_description": {
+                                "anyOf": [{"type": "string"}, {"type": "null"}],
+                                "title": "New Description",
+                            },
+                            "new_sub": {
+                                "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2__SubItem"
+                            },
+                            "new_multi": {
+                                "items": {
+                                    "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2__SubItem"
+                                },
+                                "type": "array",
+                                "title": "New Multi",
+                                "default": [],
                             },
-                            "tests__test_pydantic_v1_v2_multifile__modelsv2b__SubItem": {
-                                "properties": {
-                                    "dup_sub_name": {
-                                        "type": "string",
-                                        "title": "Dup Sub Name",
-                                    }
-                                },
-                                "type": "object",
-                                "required": ["dup_sub_name"],
-                                "title": "SubItem",
+                        },
+                        "type": "object",
+                        "required": ["new_title", "new_size", "new_sub"],
+                        "title": "Item",
+                    },
+                    "tests__test_pydantic_v1_v2_multifile__modelsv2__ItemInList": {
+                        "properties": {"name2": {"type": "string", "title": "Name2"}},
+                        "type": "object",
+                        "required": ["name2"],
+                        "title": "ItemInList",
+                    },
+                    "tests__test_pydantic_v1_v2_multifile__modelsv2__SubItem": {
+                        "properties": {
+                            "new_sub_name": {
+                                "type": "string",
+                                "title": "New Sub Name",
+                            }
+                        },
+                        "type": "object",
+                        "required": ["new_sub_name"],
+                        "title": "SubItem",
+                    },
+                    "tests__test_pydantic_v1_v2_multifile__modelsv2b__Item": {
+                        "properties": {
+                            "dup_title": {
+                                "type": "string",
+                                "title": "Dup Title",
+                            },
+                            "dup_size": {
+                                "type": "integer",
+                                "title": "Dup Size",
+                            },
+                            "dup_description": {
+                                "anyOf": [{"type": "string"}, {"type": "null"}],
+                                "title": "Dup Description",
+                            },
+                            "dup_sub": {
+                                "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2b__SubItem"
+                            },
+                            "dup_multi": {
+                                "items": {
+                                    "$ref": "#/components/schemas/tests__test_pydantic_v1_v2_multifile__modelsv2b__SubItem"
+                                },
+                                "type": "array",
+                                "title": "Dup Multi",
+                                "default": [],
                             },
-                        }
-                    ),
-                ),
+                        },
+                        "type": "object",
+                        "required": ["dup_title", "dup_size", "dup_sub"],
+                        "title": "Item",
+                    },
+                    "tests__test_pydantic_v1_v2_multifile__modelsv2b__ItemInList": {
+                        "properties": {
+                            "dup_name2": {
+                                "type": "string",
+                                "title": "Dup Name2",
+                            }
+                        },
+                        "type": "object",
+                        "required": ["dup_name2"],
+                        "title": "ItemInList",
+                    },
+                    "tests__test_pydantic_v1_v2_multifile__modelsv2b__SubItem": {
+                        "properties": {
+                            "dup_sub_name": {
+                                "type": "string",
+                                "title": "Dup Sub Name",
+                            }
+                        },
+                        "type": "object",
+                        "required": ["dup_sub_name"],
+                        "title": "SubItem",
+                    },
+                },
             },
         }
     )
index 3e86469908f3a8f9604d9bc4c0622fffe225dab7..2cb6c3d6b4868a22ccc24585a9eef958d49f727e 100644 (file)
@@ -1,7 +1,7 @@
 import sys
 from typing import Any, Union
 
-from tests.utils import pydantic_snapshot, skip_module_if_py_gte_314
+from tests.utils import skip_module_if_py_gte_314
 
 if sys.version_info >= (3, 14):
     skip_module_if_py_gte_314()
@@ -312,38 +312,20 @@ def test_v2_to_v1_validation_error():
     assert response.status_code == 422, response.text
     assert response.json() == snapshot(
         {
-            "detail": pydantic_snapshot(
-                v2=snapshot(
-                    [
-                        {
-                            "type": "missing",
-                            "loc": ["body", "new_size"],
-                            "msg": "Field required",
-                            "input": {"new_title": "Missing fields"},
-                        },
-                        {
-                            "type": "missing",
-                            "loc": ["body", "new_sub"],
-                            "msg": "Field required",
-                            "input": {"new_title": "Missing fields"},
-                        },
-                    ]
-                ),
-                v1=snapshot(
-                    [
-                        {
-                            "loc": ["body", "new_size"],
-                            "msg": "field required",
-                            "type": "value_error.missing",
-                        },
-                        {
-                            "loc": ["body", "new_sub"],
-                            "msg": "field required",
-                            "type": "value_error.missing",
-                        },
-                    ]
-                ),
-            )
+            "detail": [
+                {
+                    "type": "missing",
+                    "loc": ["body", "new_size"],
+                    "msg": "Field required",
+                    "input": {"new_title": "Missing fields"},
+                },
+                {
+                    "type": "missing",
+                    "loc": ["body", "new_sub"],
+                    "msg": "Field required",
+                    "input": {"new_title": "Missing fields"},
+                },
+            ]
         }
     )
 
@@ -361,23 +343,12 @@ def test_v2_to_v1_nested_validation_error():
     assert response.json() == snapshot(
         {
             "detail": [
-                pydantic_snapshot(
-                    v2=snapshot(
-                        {
-                            "type": "missing",
-                            "loc": ["body", "new_sub", "new_sub_name"],
-                            "msg": "Field required",
-                            "input": {"wrong_field": "value"},
-                        }
-                    ),
-                    v1=snapshot(
-                        {
-                            "loc": ["body", "new_sub", "new_sub_name"],
-                            "msg": "field required",
-                            "type": "value_error.missing",
-                        }
-                    ),
-                )
+                {
+                    "type": "missing",
+                    "loc": ["body", "new_sub", "new_sub_name"],
+                    "msg": "Field required",
+                    "input": {"wrong_field": "value"},
+                }
             ]
         }
     )
@@ -396,23 +367,12 @@ def test_v2_to_v1_type_validation_error():
     assert response.json() == snapshot(
         {
             "detail": [
-                pydantic_snapshot(
-                    v2=snapshot(
-                        {
-                            "type": "int_parsing",
-                            "loc": ["body", "new_size"],
-                            "msg": "Input should be a valid integer, unable to parse string as an integer",
-                            "input": "not_a_number",
-                        }
-                    ),
-                    v1=snapshot(
-                        {
-                            "loc": ["body", "new_size"],
-                            "msg": "value is not a valid integer",
-                            "type": "type_error.integer",
-                        }
-                    ),
-                )
+                {
+                    "type": "int_parsing",
+                    "loc": ["body", "new_size"],
+                    "msg": "Input should be a valid integer, unable to parse string as an integer",
+                    "input": "not_a_number",
+                }
             ]
         }
     )
@@ -483,21 +443,12 @@ def test_openapi_schema():
                         "requestBody": {
                             "content": {
                                 "application/json": {
-                                    "schema": pydantic_snapshot(
-                                        v2=snapshot(
-                                            {
-                                                "allOf": [
-                                                    {
-                                                        "$ref": "#/components/schemas/Item"
-                                                    }
-                                                ],
-                                                "title": "Data",
-                                            }
-                                        ),
-                                        v1=snapshot(
+                                    "schema": {
+                                        "allOf": [
                                             {"$ref": "#/components/schemas/Item"}
-                                        ),
-                                    )
+                                        ],
+                                        "title": "Data",
+                                    }
                                 }
                             },
                             "required": True,
@@ -507,22 +458,15 @@ def test_openapi_schema():
                                 "description": "Successful Response",
                                 "content": {
                                     "application/json": {
-                                        "schema": pydantic_snapshot(
-                                            v2=snapshot(
+                                        "schema": {
+                                            "anyOf": [
                                                 {
-                                                    "anyOf": [
-                                                        {
-                                                            "$ref": "#/components/schemas/NewItem"
-                                                        },
-                                                        {"type": "null"},
-                                                    ],
-                                                    "title": "Response Handle V1 Item To V2 V1 To V2  Post",
-                                                }
-                                            ),
-                                            v1=snapshot(
-                                                {"$ref": "#/components/schemas/NewItem"}
-                                            ),
-                                        )
+                                                    "$ref": "#/components/schemas/NewItem"
+                                                },
+                                                {"type": "null"},
+                                            ],
+                                            "title": "Response Handle V1 Item To V2 V1 To V2  Post",
+                                        }
                                     }
                                 },
                             },
@@ -546,21 +490,12 @@ def test_openapi_schema():
                         "requestBody": {
                             "content": {
                                 "application/json": {
-                                    "schema": pydantic_snapshot(
-                                        v2=snapshot(
-                                            {
-                                                "allOf": [
-                                                    {
-                                                        "$ref": "#/components/schemas/Item"
-                                                    }
-                                                ],
-                                                "title": "Data",
-                                            }
-                                        ),
-                                        v1=snapshot(
+                                    "schema": {
+                                        "allOf": [
                                             {"$ref": "#/components/schemas/Item"}
-                                        ),
-                                    )
+                                        ],
+                                        "title": "Data",
+                                    }
                                 }
                             },
                             "required": True,
@@ -570,22 +505,15 @@ def test_openapi_schema():
                                 "description": "Successful Response",
                                 "content": {
                                     "application/json": {
-                                        "schema": pydantic_snapshot(
-                                            v2=snapshot(
+                                        "schema": {
+                                            "anyOf": [
                                                 {
-                                                    "anyOf": [
-                                                        {
-                                                            "$ref": "#/components/schemas/NewItem"
-                                                        },
-                                                        {"type": "null"},
-                                                    ],
-                                                    "title": "Response Handle V1 Item To V2 Filter V1 To V2 Item Filter Post",
-                                                }
-                                            ),
-                                            v1=snapshot(
-                                                {"$ref": "#/components/schemas/NewItem"}
-                                            ),
-                                        )
+                                                    "$ref": "#/components/schemas/NewItem"
+                                                },
+                                                {"type": "null"},
+                                            ],
+                                            "title": "Response Handle V1 Item To V2 Filter V1 To V2 Item Filter Post",
+                                        }
                                     }
                                 },
                             },
@@ -707,17 +635,10 @@ def test_openapi_schema():
                         "properties": {
                             "new_title": {"type": "string", "title": "New Title"},
                             "new_size": {"type": "integer", "title": "New Size"},
-                            "new_description": pydantic_snapshot(
-                                v2=snapshot(
-                                    {
-                                        "anyOf": [{"type": "string"}, {"type": "null"}],
-                                        "title": "New Description",
-                                    }
-                                ),
-                                v1=snapshot(
-                                    {"type": "string", "title": "New Description"}
-                                ),
-                            ),
+                            "new_description": {
+                                "anyOf": [{"type": "string"}, {"type": "null"}],
+                                "title": "New Description",
+                            },
                             "new_sub": {"$ref": "#/components/schemas/NewSubItem"},
                             "new_multi": {
                                 "items": {"$ref": "#/components/schemas/NewSubItem"},
index f4ebefb3f3ce4a91036037e008076ddd17e3f234..d361e1e533fc54f06a09e1389fd8f135c9ebb2e9 100644 (file)
@@ -1,5 +1,4 @@
 from fastapi import Cookie, FastAPI, Header, Query
-from fastapi._compat import PYDANTIC_V2
 from fastapi.testclient import TestClient
 from pydantic import BaseModel
 
@@ -9,12 +8,7 @@ app = FastAPI()
 class Model(BaseModel):
     param: str
 
-    if PYDANTIC_V2:
-        model_config = {"extra": "allow"}
-    else:
-
-        class Config:
-            extra = "allow"
+    model_config = {"extra": "allow"}
 
 
 @app.get("/query")
index b35987443928113594d0958d64498ea22b1230cc..5858f8e801476e76ebe1b3b5b787d8418b9f0e76 100644 (file)
@@ -4,10 +4,9 @@ from fastapi import FastAPI
 from fastapi.testclient import TestClient
 from pydantic import BaseModel, ConfigDict
 
-from .utils import needs_pydanticv1, needs_pydanticv2
+from .utils import needs_pydanticv1
 
 
-@needs_pydanticv2
 def test_read_with_orm_mode() -> None:
     class PersonBase(BaseModel):
         name: str
@@ -48,7 +47,9 @@ def test_read_with_orm_mode() -> None:
 
 @needs_pydanticv1
 def test_read_with_orm_mode_pv1() -> None:
-    class PersonBase(BaseModel):
+    from pydantic import v1
+
+    class PersonBase(v1.BaseModel):
         name: str
         lastname: str
 
index a6f759f23b488af6d916ff7c4ede9dfee4666495..c29130d7a6da4287d433a55b4e13f90af4d6517e 100644 (file)
@@ -1,6 +1,5 @@
 from dirty_equals import IsPartialDict
 from fastapi import Cookie, FastAPI, Header, Query
-from fastapi._compat import PYDANTIC_V2
 from fastapi.testclient import TestClient
 from pydantic import BaseModel, Field
 
@@ -53,8 +52,7 @@ def test_query_model_with_alias_by_name():
     response = client.get("/query", params={"param": "value"})
     assert response.status_code == 422, response.text
     details = response.json()
-    if PYDANTIC_V2:
-        assert details["detail"][0]["input"] == {"param": "value"}
+    assert details["detail"][0]["input"] == {"param": "value"}
 
 
 def test_header_model_with_alias_by_name():
@@ -62,8 +60,7 @@ def test_header_model_with_alias_by_name():
     response = client.get("/header", headers={"param": "value"})
     assert response.status_code == 422, response.text
     details = response.json()
-    if PYDANTIC_V2:
-        assert details["detail"][0]["input"] == IsPartialDict({"param": "value"})
+    assert details["detail"][0]["input"] == IsPartialDict({"param": "value"})
 
 
 def test_cookie_model_with_alias_by_name():
@@ -72,5 +69,4 @@ def test_cookie_model_with_alias_by_name():
     response = client.get("/cookie")
     assert response.status_code == 422, response.text
     details = response.json()
-    if PYDANTIC_V2:
-        assert details["detail"][0]["input"] == {"param": "value"}
+    assert details["detail"][0]["input"] == {"param": "value"}
index b2503a1c44f0c1d17e87d3facf0663718186f833..0048da0f8bcb32d86d13a9a4b4b2642c74700561 100644 (file)
@@ -6,8 +6,6 @@ from fastapi import Body, FastAPI
 from fastapi.testclient import TestClient
 from pydantic import BaseModel, Field
 
-from tests.utils import needs_pydanticv2
-
 from .utils import get_body_model_name
 
 app = FastAPI()
@@ -246,7 +244,6 @@ async def read_model_required_list_validation_alias(
     return {"p": p.p}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     ["/required-list-validation-alias", "/model-required-list-validation-alias"],
@@ -269,7 +266,6 @@ def test_required_list_validation_alias_schema(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize("json", [None, {}])
 @pytest.mark.parametrize(
     "path",
@@ -294,7 +290,6 @@ def test_required_list_validation_alias_missing(path: str, json: Union[dict, Non
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -319,7 +314,6 @@ def test_required_list_validation_alias_by_name(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -364,7 +358,6 @@ def read_model_required_list_alias_and_validation_alias(
     return {"p": p.p}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -390,7 +383,6 @@ def test_required_list_alias_and_validation_alias_schema(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize("json", [None, {}])
 @pytest.mark.parametrize(
     "path",
@@ -415,7 +407,6 @@ def test_required_list_alias_and_validation_alias_missing(path: str, json):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -442,7 +433,6 @@ def test_required_list_alias_and_validation_alias_by_name(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -467,7 +457,6 @@ def test_required_list_alias_and_validation_alias_by_alias(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
index ede635f840ac9cb0d2ae3bc669a89277d210f29f..960e8890f3900970b9af9edd4a7a8feb7cf15ed2 100644 (file)
@@ -6,8 +6,6 @@ from fastapi import Body, FastAPI
 from fastapi.testclient import TestClient
 from pydantic import BaseModel, Field
 
-from tests.utils import needs_pydanticv2
-
 from .utils import get_body_model_name
 
 app = FastAPI()
@@ -283,7 +281,6 @@ def read_model_optional_list_validation_alias(
     return {"p": p.p}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     ["/optional-list-validation-alias", "/model-optional-list-validation-alias"],
@@ -369,7 +366,6 @@ def test_optional_list_validation_alias_missing_empty_dict(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -384,7 +380,6 @@ def test_optional_list_validation_alias_by_name(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -432,7 +427,6 @@ def read_model_optional_list_alias_and_validation_alias(
     return {"p": p.p}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -524,7 +518,6 @@ def test_optional_list_alias_and_validation_alias_missing_empty_dict(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -539,7 +532,6 @@ def test_optional_list_alias_and_validation_alias_by_name(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -554,7 +546,6 @@ def test_optional_list_alias_and_validation_alias_by_alias(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
index 9e0c7217cc6ccd8c643dc1fcb9002952a0012d51..59732688a2654844a5b76d7c9f5f23e3929d9e45 100644 (file)
@@ -6,8 +6,6 @@ from fastapi import Body, FastAPI
 from fastapi.testclient import TestClient
 from pydantic import BaseModel, Field
 
-from tests.utils import needs_pydanticv2
-
 from .utils import get_body_model_name
 
 app = FastAPI()
@@ -268,7 +266,6 @@ def read_model_optional_validation_alias(
     return {"p": p.p}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     ["/optional-validation-alias", "/model-optional-validation-alias"],
@@ -300,7 +297,6 @@ def test_optional_validation_alias_schema(path: str):
     )
 
 
-@needs_pydanticv2
 def test_optional_validation_alias_missing():
     client = TestClient(app)
     response = client.post("/optional-validation-alias")
@@ -308,7 +304,6 @@ def test_optional_validation_alias_missing():
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 def test_model_optional_validation_alias_missing():
     client = TestClient(app)
     response = client.post("/model-optional-validation-alias")
@@ -338,7 +333,6 @@ def test_model_optional_validation_alias_missing():
     )
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     ["/optional-validation-alias", "/model-optional-validation-alias"],
@@ -350,7 +344,6 @@ def test_model_optional_validation_alias_missing_empty_dict(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -365,7 +358,6 @@ def test_optional_validation_alias_by_name(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -410,7 +402,6 @@ def read_model_optional_alias_and_validation_alias(
     return {"p": p.p}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -445,7 +436,6 @@ def test_optional_alias_and_validation_alias_schema(path: str):
     )
 
 
-@needs_pydanticv2
 def test_optional_alias_and_validation_alias_missing():
     client = TestClient(app)
     response = client.post("/optional-alias-and-validation-alias")
@@ -453,7 +443,6 @@ def test_optional_alias_and_validation_alias_missing():
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 def test_model_optional_alias_and_validation_alias_missing():
     client = TestClient(app)
     response = client.post("/model-optional-alias-and-validation-alias")
@@ -483,7 +472,6 @@ def test_model_optional_alias_and_validation_alias_missing():
     )
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -498,7 +486,6 @@ def test_model_optional_alias_and_validation_alias_missing_empty_dict(path: str)
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -513,7 +500,6 @@ def test_optional_alias_and_validation_alias_by_name(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -528,7 +514,6 @@ def test_optional_alias_and_validation_alias_by_alias(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
index aa47a4ede3300077e3aac7218ab9033e9958cff3..5571ba5d5a79f3cac2998d41cf53a95980d2ec0c 100644 (file)
@@ -6,8 +6,6 @@ from fastapi import Body, FastAPI
 from fastapi.testclient import TestClient
 from pydantic import BaseModel, Field
 
-from tests.utils import needs_pydanticv2
-
 from .utils import get_body_model_name
 
 app = FastAPI()
@@ -236,7 +234,6 @@ def read_model_required_validation_alias(
     return {"p": p.p}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     ["/required-validation-alias", "/model-required-validation-alias"],
@@ -255,7 +252,6 @@ def test_required_validation_alias_schema(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize("json", [None, {}])
 @pytest.mark.parametrize(
     "path",
@@ -282,7 +278,6 @@ def test_required_validation_alias_missing(
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -307,7 +302,6 @@ def test_required_validation_alias_by_name(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -353,7 +347,6 @@ def read_model_required_alias_and_validation_alias(
     return {"p": p.p}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -375,7 +368,6 @@ def test_required_alias_and_validation_alias_schema(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize("json", [None, {}])
 @pytest.mark.parametrize(
     "path",
@@ -402,7 +394,6 @@ def test_required_alias_and_validation_alias_missing(
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -430,7 +421,6 @@ def test_required_alias_and_validation_alias_by_name(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -455,7 +445,6 @@ def test_required_alias_and_validation_alias_by_alias(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
index f2d02dae545c17daf5375c27d8bacea03ef03a80..b2f7f9cef514aa1bf61b99f8d9f7b58b7babeb7c 100644 (file)
@@ -6,8 +6,6 @@ from fastapi import Cookie, FastAPI
 from fastapi.testclient import TestClient
 from pydantic import BaseModel, Field
 
-from tests.utils import needs_pydanticv2
-
 app = FastAPI()
 
 # =====================================================================================
@@ -189,7 +187,6 @@ def read_model_optional_validation_alias(
     return {"p": p.p}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     ["/optional-validation-alias", "/model-optional-validation-alias"],
@@ -208,7 +205,6 @@ def test_optional_validation_alias_schema(path: str):
     ]
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     ["/optional-validation-alias", "/model-optional-validation-alias"],
@@ -220,7 +216,6 @@ def test_optional_validation_alias_missing(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -236,7 +231,6 @@ def test_optional_validation_alias_by_name(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -276,7 +270,6 @@ def read_model_optional_alias_and_validation_alias(
     return {"p": p.p}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -298,7 +291,6 @@ def test_optional_alias_and_validation_alias_schema(path: str):
     ]
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -313,7 +305,6 @@ def test_optional_alias_and_validation_alias_missing(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -329,7 +320,6 @@ def test_optional_alias_and_validation_alias_by_name(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -345,7 +335,6 @@ def test_optional_alias_and_validation_alias_by_alias(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
index 3255857d448e44433db38c93bb21381dd7bb5853..58bb7af5b9a702105e3d95cb815c32296545fe80 100644 (file)
@@ -6,8 +6,6 @@ from fastapi import Cookie, FastAPI
 from fastapi.testclient import TestClient
 from pydantic import BaseModel, Field
 
-from tests.utils import needs_pydanticv2
-
 app = FastAPI()
 
 # =====================================================================================
@@ -231,7 +229,6 @@ def read_model_required_validation_alias(
     return {"p": p.p}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     ["/required-validation-alias", "/model-required-validation-alias"],
@@ -247,7 +244,6 @@ def test_required_validation_alias_schema(path: str):
     ]
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -274,7 +270,6 @@ def test_required_validation_alias_missing(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -300,7 +295,6 @@ def test_required_validation_alias_by_name(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -339,7 +333,6 @@ def read_model_required_alias_and_validation_alias(
     return {"p": p.p}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -358,7 +351,6 @@ def test_required_alias_and_validation_alias_schema(path: str):
     ]
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -385,7 +377,6 @@ def test_required_alias_and_validation_alias_missing(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -417,7 +408,6 @@ def test_required_alias_and_validation_alias_by_name(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -446,7 +436,6 @@ def test_required_alias_and_validation_alias_by_alias(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
index 52b032e4415419c05d7e20a525b21151a858c343..90f36e5f7cf75ed4773bb0ac1a155c962363097c 100644 (file)
@@ -5,8 +5,6 @@ from dirty_equals import IsDict
 from fastapi import FastAPI, File, UploadFile
 from fastapi.testclient import TestClient
 
-from tests.utils import needs_pydanticv2
-
 from .utils import get_body_model_name
 
 app = FastAPI()
@@ -280,7 +278,6 @@ def read_list_uploadfile_validation_alias(
     return {"file_size": [file.size for file in p]}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -322,7 +319,6 @@ def test_list_validation_alias_schema(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -349,7 +345,6 @@ def test_list_validation_alias_missing(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -374,7 +369,6 @@ def test_list_validation_alias_by_name(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -417,7 +411,6 @@ def read_list_uploadfile_alias_and_validation_alias(
     return {"file_size": [file.size for file in p]}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -459,7 +452,6 @@ def test_list_alias_and_validation_alias_schema(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -486,7 +478,6 @@ def test_list_alias_and_validation_alias_missing(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -514,7 +505,6 @@ def test_list_alias_and_validation_alias_by_name(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -539,7 +529,6 @@ def test_list_alias_and_validation_alias_by_alias(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
index b7177e071dc8b0e75fe05214b90091766675b556..4e9564873cef1032b731676f435a5b68cafd6bc1 100644 (file)
@@ -5,8 +5,6 @@ from dirty_equals import IsDict
 from fastapi import FastAPI, File, UploadFile
 from fastapi.testclient import TestClient
 
-from tests.utils import needs_pydanticv2
-
 from .utils import get_body_model_name
 
 app = FastAPI()
@@ -204,7 +202,6 @@ def read_optional_uploadfile_validation_alias(
     return {"file_size": p.size if p else None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -239,7 +236,6 @@ def test_optional_validation_alias_schema(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -254,7 +250,6 @@ def test_optional_validation_alias_missing(path: str):
     assert response.json() == {"file_size": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -269,7 +264,6 @@ def test_optional_validation_alias_by_name(path: str):
     assert response.json() == {"file_size": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -312,7 +306,6 @@ def read_optional_uploadfile_alias_and_validation_alias(
     return {"file_size": p.size if p else None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -347,7 +340,6 @@ def test_optional_alias_and_validation_alias_schema(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -362,7 +354,6 @@ def test_optional_alias_and_validation_alias_missing(path: str):
     assert response.json() == {"file_size": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -377,7 +368,6 @@ def test_optional_alias_and_validation_alias_by_name(path: str):
     assert response.json() == {"file_size": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -392,7 +382,6 @@ def test_optional_alias_and_validation_alias_by_alias(path: str):
     assert response.json() == {"file_size": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
index af9fe552c915f53ebe2cd2fe840c698fdc047fe9..e18f36e1520e3f4664a7e21fc79418d4c7cbd510 100644 (file)
@@ -5,8 +5,6 @@ from dirty_equals import IsDict
 from fastapi import FastAPI, File, UploadFile
 from fastapi.testclient import TestClient
 
-from tests.utils import needs_pydanticv2
-
 from .utils import get_body_model_name
 
 app = FastAPI()
@@ -217,7 +215,6 @@ def read_optional_list_uploadfile_validation_alias(
     return {"file_size": [file.size for file in p] if p else None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -259,7 +256,6 @@ def test_optional_validation_alias_schema(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -274,7 +270,6 @@ def test_optional_validation_alias_missing(path: str):
     assert response.json() == {"file_size": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -289,7 +284,6 @@ def test_optional_validation_alias_by_name(path: str):
     assert response.json() == {"file_size": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -329,7 +323,6 @@ def read_optional_list_uploadfile_alias_and_validation_alias(
     return {"file_size": [file.size for file in p] if p else None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -371,7 +364,6 @@ def test_optional_list_alias_and_validation_alias_schema(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -386,7 +378,6 @@ def test_optional_list_alias_and_validation_alias_missing(path: str):
     assert response.json() == {"file_size": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -401,7 +392,6 @@ def test_optional_list_alias_and_validation_alias_by_name(path: str):
     assert response.json() == {"file_size": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -416,7 +406,6 @@ def test_optional_list_alias_and_validation_alias_by_alias(path: str):
     assert response.json() == {"file_size": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
index 2979a1040a33c82b6d005ec960dd0d8a77b2ce78..9783f4bceb2f4fad8d63962b646dbea3b91aa700 100644 (file)
@@ -5,8 +5,6 @@ from dirty_equals import IsDict
 from fastapi import FastAPI, File, UploadFile
 from fastapi.testclient import TestClient
 
-from tests.utils import needs_pydanticv2
-
 from .utils import get_body_model_name
 
 app = FastAPI()
@@ -242,7 +240,6 @@ def read_required_uploadfile_validation_alias(
     return {"file_size": p.size}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -268,7 +265,6 @@ def test_required_validation_alias_schema(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -295,7 +291,6 @@ def test_required_validation_alias_missing(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -320,7 +315,6 @@ def test_required_validation_alias_by_name(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -359,7 +353,6 @@ def read_required_uploadfile_alias_and_validation_alias(
     return {"file_size": p.size}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -385,7 +378,6 @@ def test_required_alias_and_validation_alias_schema(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -412,7 +404,6 @@ def test_required_alias_and_validation_alias_missing(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -440,7 +431,6 @@ def test_required_alias_and_validation_alias_by_name(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -465,7 +455,6 @@ def test_required_alias_and_validation_alias_by_alias(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
index 9f45aa755d52d39439b3f5cafc69a0dcbb3c5f95..600dba4ae947efed5ad6c86c6632811c80a1ed8a 100644 (file)
@@ -6,8 +6,6 @@ from fastapi import FastAPI, Form
 from fastapi.testclient import TestClient
 from pydantic import BaseModel, Field
 
-from tests.utils import needs_pydanticv2
-
 from .utils import get_body_model_name
 
 app = FastAPI()
@@ -247,7 +245,6 @@ async def read_model_required_list_validation_alias(
     return {"p": p.p}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     ["/required-list-validation-alias", "/model-required-list-validation-alias"],
@@ -270,7 +267,6 @@ def test_required_list_validation_alias_schema(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -297,7 +293,6 @@ def test_required_list_validation_alias_missing(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -322,7 +317,6 @@ def test_required_list_validation_alias_by_name(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     ["/required-list-validation-alias", "/model-required-list-validation-alias"],
@@ -363,7 +357,6 @@ def read_model_required_list_alias_and_validation_alias(
     return {"p": p.p}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -389,7 +382,6 @@ def test_required_list_alias_and_validation_alias_schema(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -416,7 +408,6 @@ def test_required_list_alias_and_validation_alias_missing(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -446,7 +437,6 @@ def test_required_list_alias_and_validation_alias_by_name(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -470,7 +460,6 @@ def test_required_list_alias_and_validation_alias_by_alias(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
index 0af6d3477788eb71d046180d492e5bd47b7750d6..4552623f513f7e36fda3701d436574c09c16f525 100644 (file)
@@ -6,8 +6,6 @@ from fastapi import FastAPI, Form
 from fastapi.testclient import TestClient
 from pydantic import BaseModel, Field
 
-from tests.utils import needs_pydanticv2
-
 from .utils import get_body_model_name
 
 app = FastAPI()
@@ -211,7 +209,6 @@ def read_model_optional_list_validation_alias(
     return {"p": p.p}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     ["/optional-list-validation-alias", "/model-optional-list-validation-alias"],
@@ -250,7 +247,6 @@ def test_optional_list_validation_alias_schema(path: str):
     )
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     ["/optional-list-validation-alias", "/model-optional-list-validation-alias"],
@@ -262,7 +258,6 @@ def test_optional_list_validation_alias_missing(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -277,7 +272,6 @@ def test_optional_list_validation_alias_by_name(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     ["/optional-list-validation-alias", "/model-optional-list-validation-alias"],
@@ -321,7 +315,6 @@ def read_model_optional_list_alias_and_validation_alias(
     return {"p": p.p}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -363,7 +356,6 @@ def test_optional_list_alias_and_validation_alias_schema(path: str):
     )
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -378,7 +370,6 @@ def test_optional_list_alias_and_validation_alias_missing(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -393,7 +384,6 @@ def test_optional_list_alias_and_validation_alias_by_name(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -408,7 +398,6 @@ def test_optional_list_alias_and_validation_alias_by_alias(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
index 92329216ec0b13283c6eb6211e7d49d711fca085..1b08299046a310ef18af1b95c9c47cc542572a25 100644 (file)
@@ -6,8 +6,6 @@ from fastapi import FastAPI, Form
 from fastapi.testclient import TestClient
 from pydantic import BaseModel, Field
 
-from tests.utils import needs_pydanticv2
-
 from .utils import get_body_model_name
 
 app = FastAPI()
@@ -194,7 +192,6 @@ def read_model_optional_validation_alias(
     return {"p": p.p}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     ["/optional-validation-alias", "/model-optional-validation-alias"],
@@ -226,7 +223,6 @@ def test_optional_validation_alias_schema(path: str):
     )
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     ["/optional-validation-alias", "/model-optional-validation-alias"],
@@ -238,7 +234,6 @@ def test_optional_validation_alias_missing(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -253,7 +248,6 @@ def test_optional_validation_alias_by_name(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -298,7 +292,6 @@ def read_model_optional_alias_and_validation_alias(
     return {"p": p.p}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -333,7 +326,6 @@ def test_optional_alias_and_validation_alias_schema(path: str):
     )
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -348,7 +340,6 @@ def test_optional_alias_and_validation_alias_missing(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -363,7 +354,6 @@ def test_optional_alias_and_validation_alias_by_name(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -378,7 +368,6 @@ def test_optional_alias_and_validation_alias_by_alias(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
index 1e33038040e12f4f7c586e174662df9add8c9781..1d2431b3334446bd92ff24d0516c23ad4ced0732 100644 (file)
@@ -6,8 +6,6 @@ from fastapi import FastAPI, Form
 from fastapi.testclient import TestClient
 from pydantic import BaseModel, Field
 
-from tests.utils import needs_pydanticv2
-
 from .utils import get_body_model_name
 
 app = FastAPI()
@@ -232,7 +230,6 @@ def read_model_required_validation_alias(
     return {"p": p.p}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     ["/required-validation-alias", "/model-required-validation-alias"],
@@ -251,7 +248,6 @@ def test_required_validation_alias_schema(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -278,7 +274,6 @@ def test_required_validation_alias_missing(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -303,7 +298,6 @@ def test_required_validation_alias_by_name(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -347,7 +341,6 @@ def read_model_required_alias_and_validation_alias(
     return {"p": p.p}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -369,7 +362,6 @@ def test_required_alias_and_validation_alias_schema(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -396,7 +388,6 @@ def test_required_alias_and_validation_alias_missing(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -424,7 +415,6 @@ def test_required_alias_and_validation_alias_by_name(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -449,7 +439,6 @@ def test_required_alias_and_validation_alias_by_alias(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
index 62f9f36ff643ce642b53611566b09d6fa1b0ecce..2eba17559e67eb6b1d871192c0149ddc2339d84b 100644 (file)
@@ -6,8 +6,6 @@ from fastapi import FastAPI, Header
 from fastapi.testclient import TestClient
 from pydantic import BaseModel, Field
 
-from tests.utils import needs_pydanticv2
-
 app = FastAPI()
 
 # =====================================================================================
@@ -234,7 +232,6 @@ async def read_model_required_list_validation_alias(
     return {"p": p.p}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     ["/required-list-validation-alias", "/model-required-list-validation-alias"],
@@ -254,7 +251,6 @@ def test_required_list_validation_alias_schema(path: str):
     ]
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -281,7 +277,6 @@ def test_required_list_validation_alias_missing(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -306,7 +301,6 @@ def test_required_list_validation_alias_by_name(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     ["/required-list-validation-alias", "/model-required-list-validation-alias"],
@@ -343,7 +337,6 @@ def read_model_required_list_alias_and_validation_alias(
     return {"p": p.p}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -366,7 +359,6 @@ def test_required_list_alias_and_validation_alias_schema(path: str):
     ]
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -393,7 +385,6 @@ def test_required_list_alias_and_validation_alias_missing(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -423,7 +414,6 @@ def test_required_list_alias_and_validation_alias_by_name(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -450,7 +440,6 @@ def test_required_list_alias_and_validation_alias_by_alias(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
index 88243f05a93247328f68450e0aebf480fb5294b6..cd6167a1833dd3e8b8b5e29cb53e09bb76e9ccbd 100644 (file)
@@ -6,8 +6,6 @@ from fastapi import FastAPI, Header
 from fastapi.testclient import TestClient
 from pydantic import BaseModel, Field
 
-from tests.utils import needs_pydanticv2
-
 app = FastAPI()
 
 # =====================================================================================
@@ -202,7 +200,6 @@ def read_model_optional_list_validation_alias(
     return {"p": p.p}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     ["/optional-list-validation-alias", "/model-optional-list-validation-alias"],
@@ -224,7 +221,6 @@ def test_optional_list_validation_alias_schema(path: str):
     ]
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     ["/optional-list-validation-alias", "/model-optional-list-validation-alias"],
@@ -236,7 +232,6 @@ def test_optional_list_validation_alias_missing(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -251,7 +246,6 @@ def test_optional_list_validation_alias_by_name(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     ["/optional-list-validation-alias", "/model-optional-list-validation-alias"],
@@ -291,7 +285,6 @@ def read_model_optional_list_alias_and_validation_alias(
     return {"p": p.p}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -316,7 +309,6 @@ def test_optional_list_alias_and_validation_alias_schema(path: str):
     ]
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -331,7 +323,6 @@ def test_optional_list_alias_and_validation_alias_missing(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -346,7 +337,6 @@ def test_optional_list_alias_and_validation_alias_by_name(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -361,7 +351,6 @@ def test_optional_list_alias_and_validation_alias_by_alias(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
index e40b1669ee4618369b5330edcd33397b7ba1a191..d4f25cc1e7ddb8208fb78998eccfd6f345272458 100644 (file)
@@ -6,8 +6,6 @@ from fastapi import FastAPI, Header
 from fastapi.testclient import TestClient
 from pydantic import BaseModel, Field
 
-from tests.utils import needs_pydanticv2
-
 app = FastAPI()
 
 # =====================================================================================
@@ -186,7 +184,6 @@ def read_model_optional_validation_alias(
     return {"p": p.p}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     ["/optional-validation-alias", "/model-optional-validation-alias"],
@@ -205,7 +202,6 @@ def test_optional_validation_alias_schema(path: str):
     ]
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     ["/optional-validation-alias", "/model-optional-validation-alias"],
@@ -217,7 +213,6 @@ def test_optional_validation_alias_missing(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -232,7 +227,6 @@ def test_optional_validation_alias_by_name(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -271,7 +265,6 @@ def read_model_optional_alias_and_validation_alias(
     return {"p": p.p}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -293,7 +286,6 @@ def test_optional_alias_and_validation_alias_schema(path: str):
     ]
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -308,7 +300,6 @@ def test_optional_alias_and_validation_alias_missing(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -323,7 +314,6 @@ def test_optional_alias_and_validation_alias_by_name(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -338,7 +328,6 @@ def test_optional_alias_and_validation_alias_by_alias(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
index 23554d3e4a0d0b5181d9e063ee2b383fd3ac13e1..85bb43d5a872a31df33da295a9472be5bce863dc 100644 (file)
@@ -6,8 +6,6 @@ from fastapi import FastAPI, Header
 from fastapi.testclient import TestClient
 from pydantic import BaseModel, Field
 
-from tests.utils import needs_pydanticv2
-
 app = FastAPI()
 
 # =====================================================================================
@@ -225,7 +223,6 @@ def read_model_required_validation_alias(
     return {"p": p.p}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     ["/required-validation-alias", "/model-required-validation-alias"],
@@ -241,7 +238,6 @@ def test_required_validation_alias_schema(path: str):
     ]
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -268,7 +264,6 @@ def test_required_validation_alias_missing(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -293,7 +288,6 @@ def test_required_validation_alias_by_name(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -331,7 +325,6 @@ def read_model_required_alias_and_validation_alias(
     return {"p": p.p}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -350,7 +343,6 @@ def test_required_alias_and_validation_alias_schema(path: str):
     ]
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -377,7 +369,6 @@ def test_required_alias_and_validation_alias_missing(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -408,7 +399,6 @@ def test_required_alias_and_validation_alias_by_name(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -436,7 +426,6 @@ def test_required_alias_and_validation_alias_by_alias(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
index ecd4eb61cddd30bff400ffc64f11f1de651b8012..b2d63667e29f33086d56764c903fd92ca367882d 100644 (file)
@@ -4,8 +4,6 @@ import pytest
 from fastapi import FastAPI, Path
 from fastapi.testclient import TestClient
 
-from tests.utils import needs_pydanticv2
-
 app = FastAPI()
 
 
@@ -45,14 +43,12 @@ def read_required_alias_and_validation_alias(
             "p_val_alias",
             "P Val Alias",
             id="required-validation-alias",
-            marks=needs_pydanticv2,
         ),
         pytest.param(
             "/required-alias-and-validation-alias/{p_val_alias}",
             "p_val_alias",
             "P Val Alias",
             id="required-alias-and-validation-alias",
-            marks=needs_pydanticv2,
         ),
     ],
 )
@@ -75,12 +71,10 @@ def test_schema(path: str, expected_name: str, expected_title: str):
         pytest.param(
             "/required-validation-alias",
             id="required-validation-alias",
-            marks=needs_pydanticv2,
         ),
         pytest.param(
             "/required-alias-and-validation-alias",
             id="required-alias-and-validation-alias",
-            marks=needs_pydanticv2,
         ),
     ],
 )
index 6a3000fbf65ca31868b4031f0867e2f394041d43..dc21a8500623e429398e51d8cc239ea35ac74c6a 100644 (file)
@@ -6,8 +6,6 @@ from fastapi import FastAPI, Query
 from fastapi.testclient import TestClient
 from pydantic import BaseModel, Field
 
-from tests.utils import needs_pydanticv2
-
 app = FastAPI()
 
 # =====================================================================================
@@ -234,7 +232,6 @@ async def read_model_required_list_validation_alias(
     return {"p": p.p}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     ["/required-list-validation-alias", "/model-required-list-validation-alias"],
@@ -254,7 +251,6 @@ def test_required_list_validation_alias_schema(path: str):
     ]
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -281,7 +277,6 @@ def test_required_list_validation_alias_missing(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -306,7 +301,6 @@ def test_required_list_validation_alias_by_name(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     ["/required-list-validation-alias", "/model-required-list-validation-alias"],
@@ -341,7 +335,6 @@ def read_model_required_list_alias_and_validation_alias(
     return {"p": p.p}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -364,7 +357,6 @@ def test_required_list_alias_and_validation_alias_schema(path: str):
     ]
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -391,7 +383,6 @@ def test_required_list_alias_and_validation_alias_missing(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -426,7 +417,6 @@ def test_required_list_alias_and_validation_alias_by_name(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -453,7 +443,6 @@ def test_required_list_alias_and_validation_alias_by_alias(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
index f4b8ec6a823af1f56e1c0d59db08bfad2cb835ec..2a8f63a36a1192105991e2c9cffeb41485ccaf3a 100644 (file)
@@ -6,8 +6,6 @@ from fastapi import FastAPI, Query
 from fastapi.testclient import TestClient
 from pydantic import BaseModel, Field
 
-from tests.utils import needs_pydanticv2
-
 app = FastAPI()
 
 # =====================================================================================
@@ -202,7 +200,6 @@ def read_model_optional_list_validation_alias(
     return {"p": p.p}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     ["/optional-list-validation-alias", "/model-optional-list-validation-alias"],
@@ -224,7 +221,6 @@ def test_optional_list_validation_alias_schema(path: str):
     ]
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     ["/optional-list-validation-alias", "/model-optional-list-validation-alias"],
@@ -236,7 +232,6 @@ def test_optional_list_validation_alias_missing(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -251,7 +246,6 @@ def test_optional_list_validation_alias_by_name(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     ["/optional-list-validation-alias", "/model-optional-list-validation-alias"],
@@ -289,7 +283,6 @@ def read_model_optional_list_alias_and_validation_alias(
     return {"p": p.p}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -314,7 +307,6 @@ def test_optional_list_alias_and_validation_alias_schema(path: str):
     ]
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -329,7 +321,6 @@ def test_optional_list_alias_and_validation_alias_missing(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -344,7 +335,6 @@ def test_optional_list_alias_and_validation_alias_by_name(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -359,7 +349,6 @@ def test_optional_list_alias_and_validation_alias_by_alias(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
index c7d20e37d1697fed2b808b7abec293bf83e249a2..c6a70bc28382c09324f9bc228e42ceae679dc115 100644 (file)
@@ -6,8 +6,6 @@ from fastapi import FastAPI, Query
 from fastapi.testclient import TestClient
 from pydantic import BaseModel, Field
 
-from tests.utils import needs_pydanticv2
-
 app = FastAPI()
 
 # =====================================================================================
@@ -186,7 +184,6 @@ def read_model_optional_validation_alias(
     return {"p": p.p}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     ["/optional-validation-alias", "/model-optional-validation-alias"],
@@ -205,7 +202,6 @@ def test_optional_validation_alias_schema(path: str):
     ]
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     ["/optional-validation-alias", "/model-optional-validation-alias"],
@@ -217,7 +213,6 @@ def test_optional_validation_alias_missing(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -232,7 +227,6 @@ def test_optional_validation_alias_by_name(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -271,7 +265,6 @@ def read_model_optional_alias_and_validation_alias(
     return {"p": p.p}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -293,7 +286,6 @@ def test_optional_alias_and_validation_alias_schema(path: str):
     ]
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -308,7 +300,6 @@ def test_optional_alias_and_validation_alias_missing(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -323,7 +314,6 @@ def test_optional_alias_and_validation_alias_by_name(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -338,7 +328,6 @@ def test_optional_alias_and_validation_alias_by_alias(path: str):
     assert response.json() == {"p": None}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
index ce30f3b1f8fcf4be3f51c088f89ad060628ab02d..2ef1b0373da4cb2cf11f97b60fe99a2885a3aeec 100644 (file)
@@ -6,8 +6,6 @@ from fastapi import FastAPI, Query
 from fastapi.testclient import TestClient
 from pydantic import BaseModel, Field
 
-from tests.utils import needs_pydanticv2
-
 app = FastAPI()
 
 # =====================================================================================
@@ -228,7 +226,6 @@ def read_model_required_validation_alias(
     return {"p": p.p}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     ["/required-validation-alias", "/model-required-validation-alias"],
@@ -244,7 +241,6 @@ def test_required_validation_alias_schema(path: str):
     ]
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -271,7 +267,6 @@ def test_required_validation_alias_missing(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -296,7 +291,6 @@ def test_required_validation_alias_by_name(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -334,7 +328,6 @@ def read_model_required_alias_and_validation_alias(
     return {"p": p.p}
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -353,7 +346,6 @@ def test_required_alias_and_validation_alias_schema(path: str):
     ]
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -380,7 +372,6 @@ def test_required_alias_and_validation_alias_missing(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -411,7 +402,6 @@ def test_required_alias_and_validation_alias_by_name(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
@@ -439,7 +429,6 @@ def test_required_alias_and_validation_alias_by_alias(path: str):
     }
 
 
-@needs_pydanticv2
 @pytest.mark.parametrize(
     "path",
     [
index 5b241c76b6d73860d267da33e3fcc722efb8ac15..807d2600b99e8406427eacf124910f4dc661c960 100644 (file)
@@ -1,5 +1,4 @@
 from fastapi import FastAPI
-from fastapi._compat import PYDANTIC_V2
 from fastapi.testclient import TestClient
 from pydantic import BaseModel, ConfigDict, Field
 
@@ -13,24 +12,14 @@ class Model(BaseModel):
 class ModelNoAlias(BaseModel):
     name: str
 
-    if PYDANTIC_V2:
-        model_config = ConfigDict(
-            json_schema_extra={
-                "description": (
-                    "response_model_by_alias=False is basically a quick hack, to support "
-                    "proper OpenAPI use another model with the correct field names"
-                )
-            }
-        )
-    else:
-
-        class Config:
-            schema_extra = {
-                "description": (
-                    "response_model_by_alias=False is basically a quick hack, to support "
-                    "proper OpenAPI use another model with the correct field names"
-                )
-            }
+    model_config = ConfigDict(
+        json_schema_extra={
+            "description": (
+                "response_model_by_alias=False is basically a quick hack, to support "
+                "proper OpenAPI use another model with the correct field names"
+            )
+        }
+    )
 
 
 @app.get("/dict", response_model=Model, response_model_by_alias=False)
index 39626c0eca0a31efdea9ad16e9f203fab4158563..737687f2560d888547cf1c6c07fe941a2768d45f 100644 (file)
@@ -4,7 +4,7 @@ from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 from pydantic import BaseModel
 
-from tests.utils import needs_py310, needs_pydanticv2
+from tests.utils import needs_py310
 
 
 @pytest.fixture(name="client")
@@ -32,14 +32,12 @@ def get_client():
 
 
 @needs_py310
-@needs_pydanticv2
 def test_get(client: TestClient):
     response = client.get("/users")
     assert response.json() == {"username": "alice", "role": "admin"}
 
 
 @needs_py310
-@needs_pydanticv2
 def test_openapi_schema(client: TestClient):
     response = client.get("openapi.json")
     assert response.json() == snapshot(
index b313f47e90fa2f27f704bb37bf4568295dc2e2f6..176b5588d7e5d03cc72ba7c80c3bc7d783550865 100644 (file)
@@ -3,7 +3,6 @@ from typing import Union
 import pytest
 from dirty_equals import IsDict
 from fastapi import Body, Cookie, FastAPI, Header, Path, Query
-from fastapi._compat import PYDANTIC_V2
 from fastapi.testclient import TestClient
 from pydantic import BaseModel, ConfigDict
 
@@ -14,14 +13,9 @@ def create_app():
     class Item(BaseModel):
         data: str
 
-        if PYDANTIC_V2:
-            model_config = ConfigDict(
-                json_schema_extra={"example": {"data": "Data in schema_extra"}}
-            )
-        else:
-
-            class Config:
-                schema_extra = {"example": {"data": "Data in schema_extra"}}
+        model_config = ConfigDict(
+            json_schema_extra={"example": {"data": "Data in schema_extra"}}
+        )
 
     @app.post("/schema_extra/")
     def schema_extra(item: Item):
index 119b76a5299c57bb8c7364012a7d0acc0c2131a3..69cb82a356a43d92dd3067f5fa9ad224e56f8d1b 100644 (file)
@@ -6,8 +6,6 @@ from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 from pydantic import BaseModel, ConfigDict, Field
 
-from tests.utils import needs_pydanticv2
-
 
 @pytest.fixture(name="client")
 def get_client():
@@ -25,13 +23,11 @@ def get_client():
     return client
 
 
-@needs_pydanticv2
 def test_get(client: TestClient):
     response = client.get("/")
     assert response.json() == {"$ref": "some-ref"}
 
 
-@needs_pydanticv2
 def test_openapi_schema(client: TestClient):
     response = client.get("openapi.json")
     assert response.json() == snapshot(
index 8bbc4d699253a0d9bd113fd7f5d12bbe4845b0ba..0401eb7d0d08a54ed5f6a856a7ede45f7bfbfd88 100644 (file)
@@ -3,7 +3,7 @@ import importlib
 import pytest
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py310, needs_pydanticv1, needs_pydanticv2
+from ...utils import needs_py310
 
 
 @pytest.fixture(
@@ -45,7 +45,6 @@ def test_put(client: TestClient):
     }
 
 
-@needs_pydanticv2
 def test_openapi_schema(client: TestClient):
     response = client.get("/openapi.json")
     assert response.status_code == 200, response.text
@@ -185,137 +184,3 @@ def test_openapi_schema(client: TestClient):
             }
         },
     }
-
-
-# TODO: remove when deprecating Pydantic v1
-@needs_pydanticv1
-def test_openapi_schema_pv1(client: TestClient):
-    response = client.get("/openapi.json")
-    assert response.status_code == 200, response.text
-    assert response.json() == {
-        "openapi": "3.1.0",
-        "info": {"title": "FastAPI", "version": "0.1.0"},
-        "paths": {
-            "/items/{item_id}": {
-                "get": {
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {
-                                "application/json": {
-                                    "schema": {"$ref": "#/components/schemas/Item"}
-                                }
-                            },
-                        },
-                        "422": {
-                            "description": "Validation Error",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                    "summary": "Read Item",
-                    "operationId": "read_item_items__item_id__get",
-                    "parameters": [
-                        {
-                            "required": True,
-                            "schema": {"title": "Item Id", "type": "string"},
-                            "name": "item_id",
-                            "in": "path",
-                        }
-                    ],
-                },
-                "put": {
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {
-                                "application/json": {
-                                    "schema": {"$ref": "#/components/schemas/Item"}
-                                }
-                            },
-                        },
-                        "422": {
-                            "description": "Validation Error",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                    "summary": "Update Item",
-                    "operationId": "update_item_items__item_id__put",
-                    "parameters": [
-                        {
-                            "required": True,
-                            "schema": {"title": "Item Id", "type": "string"},
-                            "name": "item_id",
-                            "in": "path",
-                        }
-                    ],
-                    "requestBody": {
-                        "content": {
-                            "application/json": {
-                                "schema": {"$ref": "#/components/schemas/Item"}
-                            }
-                        },
-                        "required": True,
-                    },
-                },
-            }
-        },
-        "components": {
-            "schemas": {
-                "Item": {
-                    "title": "Item",
-                    "type": "object",
-                    "properties": {
-                        "name": {"title": "Name", "type": "string"},
-                        "description": {"title": "Description", "type": "string"},
-                        "price": {"title": "Price", "type": "number"},
-                        "tax": {"title": "Tax", "type": "number", "default": 10.5},
-                        "tags": {
-                            "title": "Tags",
-                            "type": "array",
-                            "items": {"type": "string"},
-                            "default": [],
-                        },
-                    },
-                },
-                "ValidationError": {
-                    "title": "ValidationError",
-                    "required": ["loc", "msg", "type"],
-                    "type": "object",
-                    "properties": {
-                        "loc": {
-                            "title": "Location",
-                            "type": "array",
-                            "items": {
-                                "anyOf": [{"type": "string"}, {"type": "integer"}]
-                            },
-                        },
-                        "msg": {"title": "Message", "type": "string"},
-                        "type": {"title": "Error Type", "type": "string"},
-                    },
-                },
-                "HTTPValidationError": {
-                    "title": "HTTPValidationError",
-                    "type": "object",
-                    "properties": {
-                        "detail": {
-                            "title": "Detail",
-                            "type": "array",
-                            "items": {"$ref": "#/components/schemas/ValidationError"},
-                        }
-                    },
-                },
-            }
-        },
-    }
index a425e893d85a24ff8fd26319d1c86986116c83f4..ddc282d85e5f24ee15b631e4bc07a788cad6a157 100644 (file)
@@ -2,8 +2,6 @@ import importlib
 
 from fastapi.testclient import TestClient
 
-from ...utils import needs_pydanticv2
-
 
 def get_client() -> TestClient:
     from docs_src.conditional_openapi import tutorial001_py39
@@ -14,7 +12,6 @@ def get_client() -> TestClient:
     return client
 
 
-@needs_pydanticv2
 def test_disable_openapi(monkeypatch):
     monkeypatch.setenv("OPENAPI_URL", "")
     # Load the client after setting the env var
@@ -27,7 +24,6 @@ def test_disable_openapi(monkeypatch):
     assert response.status_code == 404, response.text
 
 
-@needs_pydanticv2
 def test_root():
     client = get_client()
     response = client.get("/")
@@ -35,7 +31,6 @@ def test_root():
     assert response.json() == {"message": "Hello World"}
 
 
-@needs_pydanticv2
 def test_default_openapi():
     client = get_client()
     response = client.get("/docs")
index 4a826a53742e392d74ac84a5c85a6278471c5cd7..0fbf141e050d11bc70ce12e68512a06273ad2f3a 100644 (file)
@@ -5,25 +5,16 @@ from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from tests.utils import (
-    needs_py310,
-    needs_pydanticv1,
-    needs_pydanticv2,
-    pydantic_snapshot,
-)
+from tests.utils import needs_py310
 
 
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial002_py39", marks=needs_pydanticv2),
-        pytest.param("tutorial002_py310", marks=[needs_py310, needs_pydanticv2]),
-        pytest.param("tutorial002_an_py39", marks=needs_pydanticv2),
-        pytest.param("tutorial002_an_py310", marks=[needs_py310, needs_pydanticv2]),
-        pytest.param("tutorial002_pv1_py39", marks=needs_pydanticv1),
-        pytest.param("tutorial002_pv1_py310", marks=[needs_py310, needs_pydanticv1]),
-        pytest.param("tutorial002_pv1_an_py39", marks=needs_pydanticv1),
-        pytest.param("tutorial002_pv1_an_py310", marks=[needs_py310, needs_pydanticv1]),
+        pytest.param("tutorial002_py39"),
+        pytest.param("tutorial002_py310", marks=[needs_py310]),
+        pytest.param("tutorial002_an_py39"),
+        pytest.param("tutorial002_an_py310", marks=[needs_py310]),
     ],
 )
 def get_client(request: pytest.FixtureRequest):
@@ -62,31 +53,16 @@ def test_cookie_param_model_defaults(client: TestClient):
 def test_cookie_param_model_invalid(client: TestClient):
     response = client.get("/items/")
     assert response.status_code == 422
-    assert response.json() == pydantic_snapshot(
-        v2=snapshot(
-            {
-                "detail": [
-                    {
-                        "type": "missing",
-                        "loc": ["cookie", "session_id"],
-                        "msg": "Field required",
-                        "input": {},
-                    }
-                ]
-            }
-        ),
-        v1=snapshot(
+    assert response.json() == {
+        "detail": [
             {
-                "detail": [
-                    {
-                        "type": "value_error.missing",
-                        "loc": ["cookie", "session_id"],
-                        "msg": "field required",
-                    }
-                ]
+                "type": "missing",
+                "loc": ["cookie", "session_id"],
+                "msg": "Field required",
+                "input": {},
             }
-        ),
-    )
+        ]
+    }
 
 
 def test_cookie_param_model_extra(client: TestClient):
@@ -146,24 +122,13 @@ def test_openapi_schema(client: TestClient):
                                 "name": "fatebook_tracker",
                                 "in": "cookie",
                                 "required": False,
-                                "schema": pydantic_snapshot(
-                                    v2=snapshot(
-                                        {
-                                            "anyOf": [
-                                                {"type": "string"},
-                                                {"type": "null"},
-                                            ],
-                                            "title": "Fatebook Tracker",
-                                        }
-                                    ),
-                                    v1=snapshot(
-                                        # TODO: remove when deprecating Pydantic v1
-                                        {
-                                            "type": "string",
-                                            "title": "Fatebook Tracker",
-                                        }
-                                    ),
-                                ),
+                                "schema": {
+                                    "anyOf": [
+                                        {"type": "string"},
+                                        {"type": "null"},
+                                    ],
+                                    "title": "Fatebook Tracker",
+                                },
                             },
                             {
                                 "name": "googall_tracker",
index d8cc45dd69a9b35f72b107bafb501c439002ea5d..cddf4a9be867aee5521eba21d2d8c1fcdd4b19be 100644 (file)
@@ -3,7 +3,7 @@ import importlib
 import pytest
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py310, needs_pydanticv1, needs_pydanticv2
+from ...utils import needs_py310
 
 
 @pytest.fixture(
@@ -67,7 +67,6 @@ def test_get_authors(client: TestClient):
     ]
 
 
-@needs_pydanticv2
 def test_openapi_schema(client: TestClient):
     response = client.get("/openapi.json")
     assert response.status_code == 200
@@ -201,137 +200,3 @@ def test_openapi_schema(client: TestClient):
             }
         },
     }
-
-
-# TODO: remove when deprecating Pydantic v1
-@needs_pydanticv1
-def test_openapi_schema_pv1(client: TestClient):
-    response = client.get("/openapi.json")
-    assert response.status_code == 200
-    assert response.json() == {
-        "openapi": "3.1.0",
-        "info": {"title": "FastAPI", "version": "0.1.0"},
-        "paths": {
-            "/authors/{author_id}/items/": {
-                "post": {
-                    "summary": "Create Author Items",
-                    "operationId": "create_author_items_authors__author_id__items__post",
-                    "parameters": [
-                        {
-                            "required": True,
-                            "schema": {"title": "Author Id", "type": "string"},
-                            "name": "author_id",
-                            "in": "path",
-                        }
-                    ],
-                    "requestBody": {
-                        "content": {
-                            "application/json": {
-                                "schema": {
-                                    "title": "Items",
-                                    "type": "array",
-                                    "items": {"$ref": "#/components/schemas/Item"},
-                                }
-                            }
-                        },
-                        "required": True,
-                    },
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {
-                                "application/json": {
-                                    "schema": {"$ref": "#/components/schemas/Author"}
-                                }
-                            },
-                        },
-                        "422": {
-                            "description": "Validation Error",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                }
-            },
-            "/authors/": {
-                "get": {
-                    "summary": "Get Authors",
-                    "operationId": "get_authors_authors__get",
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "title": "Response Get Authors Authors  Get",
-                                        "type": "array",
-                                        "items": {
-                                            "$ref": "#/components/schemas/Author"
-                                        },
-                                    }
-                                }
-                            },
-                        }
-                    },
-                }
-            },
-        },
-        "components": {
-            "schemas": {
-                "Author": {
-                    "title": "Author",
-                    "required": ["name"],
-                    "type": "object",
-                    "properties": {
-                        "name": {"title": "Name", "type": "string"},
-                        "items": {
-                            "title": "Items",
-                            "type": "array",
-                            "items": {"$ref": "#/components/schemas/Item"},
-                        },
-                    },
-                },
-                "HTTPValidationError": {
-                    "title": "HTTPValidationError",
-                    "type": "object",
-                    "properties": {
-                        "detail": {
-                            "title": "Detail",
-                            "type": "array",
-                            "items": {"$ref": "#/components/schemas/ValidationError"},
-                        }
-                    },
-                },
-                "Item": {
-                    "title": "Item",
-                    "required": ["name"],
-                    "type": "object",
-                    "properties": {
-                        "name": {"title": "Name", "type": "string"},
-                        "description": {"title": "Description", "type": "string"},
-                    },
-                },
-                "ValidationError": {
-                    "title": "ValidationError",
-                    "required": ["loc", "msg", "type"],
-                    "type": "object",
-                    "properties": {
-                        "loc": {
-                            "title": "Location",
-                            "type": "array",
-                            "items": {
-                                "anyOf": [{"type": "string"}, {"type": "integer"}]
-                            },
-                        },
-                        "msg": {"title": "Message", "type": "string"},
-                        "type": {"title": "Error Type", "type": "string"},
-                    },
-                },
-            }
-        },
-    }
index a7a271ba41cad90a897673c01d7a3e3ea43cf6d8..ed4743ebf9bcd38690131ee49d9c29d8558c57c8 100644 (file)
@@ -5,20 +5,16 @@ from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from tests.utils import needs_py310, needs_pydanticv1, needs_pydanticv2
+from tests.utils import needs_py310
 
 
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial002_py39", marks=needs_pydanticv2),
-        pytest.param("tutorial002_py310", marks=[needs_py310, needs_pydanticv2]),
-        pytest.param("tutorial002_an_py39", marks=needs_pydanticv2),
-        pytest.param("tutorial002_an_py310", marks=[needs_py310, needs_pydanticv2]),
-        pytest.param("tutorial002_pv1_py39", marks=needs_pydanticv1),
-        pytest.param("tutorial002_pv1_py310", marks=[needs_py310, needs_pydanticv1]),
-        pytest.param("tutorial002_pv1_an_py39", marks=needs_pydanticv1),
-        pytest.param("tutorial002_pv1_an_py310", marks=[needs_py310, needs_pydanticv1]),
+        pytest.param("tutorial002_py39"),
+        pytest.param("tutorial002_py310", marks=[needs_py310]),
+        pytest.param("tutorial002_an_py39"),
+        pytest.param("tutorial002_an_py310", marks=[needs_py310]),
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index 3805536e76a4f2caf53fb266d19df484892a8949..a95540731dd1255282f8369356dab73086dbdd07 100644 (file)
@@ -3,7 +3,7 @@ import importlib
 import pytest
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py310, needs_pydanticv1, needs_pydanticv2
+from ...utils import needs_py310
 
 
 @pytest.fixture(
@@ -35,7 +35,6 @@ def test_query_params_str_validations(client: TestClient):
     }
 
 
-@needs_pydanticv2
 def test_openapi_schema(client: TestClient):
     response = client.get("/openapi.json")
     assert response.status_code == 200, response.text
@@ -135,100 +134,3 @@ def test_openapi_schema(client: TestClient):
             }
         },
     }
-
-
-# TODO: remove when deprecating Pydantic v1
-@needs_pydanticv1
-def test_openapi_schema_pv1(client: TestClient):
-    response = client.get("/openapi.json")
-    assert response.status_code == 200, response.text
-    assert response.json() == {
-        "openapi": "3.1.0",
-        "info": {"title": "FastAPI", "version": "0.1.0"},
-        "paths": {
-            "/items/": {
-                "post": {
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {
-                                "application/json": {
-                                    "schema": {"$ref": "#/components/schemas/Item"}
-                                }
-                            },
-                        },
-                        "422": {
-                            "description": "Validation Error",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                    "summary": "Create an item",
-                    "description": "Create an item with all the information:\n\n- **name**: each item must have a name\n- **description**: a long description\n- **price**: required\n- **tax**: if the item doesn't have tax, you can omit this\n- **tags**: a set of unique tag strings for this item",
-                    "operationId": "create_item_items__post",
-                    "requestBody": {
-                        "content": {
-                            "application/json": {
-                                "schema": {"$ref": "#/components/schemas/Item"}
-                            }
-                        },
-                        "required": True,
-                    },
-                }
-            }
-        },
-        "components": {
-            "schemas": {
-                "Item": {
-                    "title": "Item",
-                    "required": ["name", "price"],
-                    "type": "object",
-                    "properties": {
-                        "name": {"title": "Name", "type": "string"},
-                        "description": {"title": "Description", "type": "string"},
-                        "price": {"title": "Price", "type": "number"},
-                        "tax": {"title": "Tax", "type": "number"},
-                        "tags": {
-                            "title": "Tags",
-                            "uniqueItems": True,
-                            "type": "array",
-                            "items": {"type": "string"},
-                            "default": [],
-                        },
-                    },
-                },
-                "ValidationError": {
-                    "title": "ValidationError",
-                    "required": ["loc", "msg", "type"],
-                    "type": "object",
-                    "properties": {
-                        "loc": {
-                            "title": "Location",
-                            "type": "array",
-                            "items": {
-                                "anyOf": [{"type": "string"}, {"type": "integer"}]
-                            },
-                        },
-                        "msg": {"title": "Message", "type": "string"},
-                        "type": {"title": "Error Type", "type": "string"},
-                    },
-                },
-                "HTTPValidationError": {
-                    "title": "HTTPValidationError",
-                    "type": "object",
-                    "properties": {
-                        "detail": {
-                            "title": "Detail",
-                            "type": "array",
-                            "items": {"$ref": "#/components/schemas/ValidationError"},
-                        }
-                    },
-                },
-            }
-        },
-    }
index 204cca09edf46a8465f2282e0984bd48ffa90ef2..d5f284e3bd3e9500e0c2b3586196ca0072b4ce2e 100644 (file)
@@ -3,8 +3,6 @@ import importlib
 import pytest
 from fastapi.testclient import TestClient
 
-from ...utils import needs_pydanticv2
-
 
 @pytest.fixture(
     name="client",
@@ -21,7 +19,6 @@ def get_client(request: pytest.FixtureRequest):
     return client
 
 
-@needs_pydanticv2
 def test_post(client: TestClient):
     yaml_data = """
         name: Deadpoolio
@@ -38,7 +35,6 @@ def test_post(client: TestClient):
     }
 
 
-@needs_pydanticv2
 def test_post_broken_yaml(client: TestClient):
     yaml_data = """
         name: Deadpoolio
@@ -52,7 +48,6 @@ def test_post_broken_yaml(client: TestClient):
     assert response.json() == {"detail": "Invalid YAML"}
 
 
-@needs_pydanticv2
 def test_post_invalid(client: TestClient):
     yaml_data = """
         name: Deadpoolio
@@ -77,7 +72,6 @@ def test_post_invalid(client: TestClient):
     }
 
 
-@needs_pydanticv2
 def test_openapi_schema(client: TestClient):
     response = client.get("/openapi.json")
     assert response.status_code == 200, response.text
index 2a7a2b78b20f83966dbf9a1cc324e7bca94f232f..c5a3aec1d987df4c5ced42cca57c599cc59b507b 100644 (file)
@@ -3,7 +3,7 @@ import importlib
 import pytest
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py310, needs_pydanticv1, needs_pydanticv2
+from ...utils import needs_py310
 
 
 @pytest.fixture(
@@ -34,7 +34,6 @@ def test_query_params_str_validations(client: TestClient):
     }
 
 
-@needs_pydanticv2
 def test_openapi_schema(client: TestClient):
     response = client.get("/openapi.json")
     assert response.status_code == 200, response.text
@@ -134,100 +133,3 @@ def test_openapi_schema(client: TestClient):
             }
         },
     }
-
-
-# TODO: remove when deprecating Pydantic v1
-@needs_pydanticv1
-def test_openapi_schema_pv1(client: TestClient):
-    response = client.get("/openapi.json")
-    assert response.status_code == 200, response.text
-    assert response.json() == {
-        "openapi": "3.1.0",
-        "info": {"title": "FastAPI", "version": "0.1.0"},
-        "paths": {
-            "/items/": {
-                "post": {
-                    "responses": {
-                        "200": {
-                            "description": "The created item",
-                            "content": {
-                                "application/json": {
-                                    "schema": {"$ref": "#/components/schemas/Item"}
-                                }
-                            },
-                        },
-                        "422": {
-                            "description": "Validation Error",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                    "summary": "Create an item",
-                    "description": "Create an item with all the information:\n\n- **name**: each item must have a name\n- **description**: a long description\n- **price**: required\n- **tax**: if the item doesn't have tax, you can omit this\n- **tags**: a set of unique tag strings for this item",
-                    "operationId": "create_item_items__post",
-                    "requestBody": {
-                        "content": {
-                            "application/json": {
-                                "schema": {"$ref": "#/components/schemas/Item"}
-                            }
-                        },
-                        "required": True,
-                    },
-                }
-            }
-        },
-        "components": {
-            "schemas": {
-                "Item": {
-                    "title": "Item",
-                    "required": ["name", "price"],
-                    "type": "object",
-                    "properties": {
-                        "name": {"title": "Name", "type": "string"},
-                        "description": {"title": "Description", "type": "string"},
-                        "price": {"title": "Price", "type": "number"},
-                        "tax": {"title": "Tax", "type": "number"},
-                        "tags": {
-                            "title": "Tags",
-                            "uniqueItems": True,
-                            "type": "array",
-                            "items": {"type": "string"},
-                            "default": [],
-                        },
-                    },
-                },
-                "ValidationError": {
-                    "title": "ValidationError",
-                    "required": ["loc", "msg", "type"],
-                    "type": "object",
-                    "properties": {
-                        "loc": {
-                            "title": "Location",
-                            "type": "array",
-                            "items": {
-                                "anyOf": [{"type": "string"}, {"type": "integer"}]
-                            },
-                        },
-                        "msg": {"title": "Message", "type": "string"},
-                        "type": {"title": "Error Type", "type": "string"},
-                    },
-                },
-                "HTTPValidationError": {
-                    "title": "HTTPValidationError",
-                    "type": "object",
-                    "properties": {
-                        "detail": {
-                            "title": "Detail",
-                            "type": "array",
-                            "items": {"$ref": "#/components/schemas/ValidationError"},
-                        }
-                    },
-                },
-            }
-        },
-    }
index ce53a36eb8dbe2e2ef847a0ac6578db8f06f39a5..4090eba0125d28541868d95b4f1f56307d709608 100644 (file)
@@ -2,7 +2,6 @@ import sys
 from typing import Any
 
 import pytest
-from fastapi._compat import PYDANTIC_V2
 
 from tests.utils import skip_module_if_py_gte_314
 
@@ -10,13 +9,8 @@ if sys.version_info >= (3, 14):
     skip_module_if_py_gte_314()
 
 
-if not PYDANTIC_V2:
-    pytest.skip("This test is only for Pydantic v2", allow_module_level=True)
-
 import importlib
 
-import pytest
-
 from ...utils import needs_py310
 
 
index 57720bf4892a6041ba495fb99878dc3792f3a4bc..266d25944de71b957759af26b5a92996333aca24 100644 (file)
@@ -1,7 +1,6 @@
 import sys
 
 import pytest
-from fastapi._compat import PYDANTIC_V2
 from inline_snapshot import snapshot
 
 from tests.utils import skip_module_if_py_gte_314
@@ -10,12 +9,8 @@ if sys.version_info >= (3, 14):
     skip_module_if_py_gte_314()
 
 
-if not PYDANTIC_V2:
-    pytest.skip("This test is only for Pydantic v2", allow_module_level=True)
-
 import importlib
 
-import pytest
 from fastapi.testclient import TestClient
 
 from ...utils import needs_py310
index f020d4a9756de51cb630366f09840b4a74287ef4..693c3ba29048cfdb3b6c6dacbb99a8accff9b05c 100644 (file)
@@ -1,7 +1,6 @@
 import sys
 
 import pytest
-from fastapi._compat import PYDANTIC_V2
 from inline_snapshot import snapshot
 
 from tests.utils import skip_module_if_py_gte_314
@@ -9,9 +8,6 @@ from tests.utils import skip_module_if_py_gte_314
 if sys.version_info >= (3, 14):
     skip_module_if_py_gte_314()
 
-if not PYDANTIC_V2:
-    pytest.skip("This test is only for Pydantic v2", allow_module_level=True)
-
 
 import importlib
 
index daa6f0b05055acd5747f0d57db82a1d50e81de9b..0fd084c84b0be4c4f83fb9523a56cca86bbbf966 100644 (file)
@@ -1,7 +1,6 @@
 import sys
 
 import pytest
-from fastapi._compat import PYDANTIC_V2
 from inline_snapshot import snapshot
 
 from tests.utils import skip_module_if_py_gte_314
@@ -9,9 +8,6 @@ from tests.utils import skip_module_if_py_gte_314
 if sys.version_info >= (3, 14):
     skip_module_if_py_gte_314()
 
-if not PYDANTIC_V2:
-    pytest.skip("This test is only for Pydantic v2", allow_module_level=True)
-
 
 import importlib
 
index e7de73f8041e9a54c0b37e2381fcf96ba8ff3871..0e9c3351a0af26761193d093f33ace043bd51c1e 100644 (file)
@@ -5,20 +5,16 @@ from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from tests.utils import needs_py310, needs_pydanticv1, needs_pydanticv2
+from tests.utils import needs_py310
 
 
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial002_py39", marks=needs_pydanticv2),
-        pytest.param("tutorial002_py310", marks=[needs_py310, needs_pydanticv2]),
-        pytest.param("tutorial002_an_py39", marks=needs_pydanticv2),
-        pytest.param("tutorial002_an_py310", marks=[needs_py310, needs_pydanticv2]),
-        pytest.param("tutorial002_pv1_py39", marks=needs_pydanticv1),
-        pytest.param("tutorial002_pv1_py310", marks=[needs_py310, needs_pydanticv1]),
-        pytest.param("tutorial002_pv1_an_py39", marks=needs_pydanticv1),
-        pytest.param("tutorial002_pv1_an_py310", marks=[needs_py310, needs_pydanticv1]),
+        pytest.param("tutorial002_py39"),
+        pytest.param("tutorial002_py310", marks=[needs_py310]),
+        pytest.param("tutorial002_an_py39"),
+        pytest.param("tutorial002_an_py310", marks=[needs_py310]),
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index 50ebf711f5d1e3fb9066ad4c4fa79d42999adea5..82bb606a9b3c151bcfe636efb2283b1c33d62e8c 100644 (file)
@@ -5,14 +5,14 @@ from dirty_equals import IsStr
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from ...utils import needs_py310, needs_pydanticv2
+from ...utils import needs_py310
 
 
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial015_an_py39", marks=needs_pydanticv2),
-        pytest.param("tutorial015_an_py310", marks=(needs_py310, needs_pydanticv2)),
+        pytest.param("tutorial015_an_py39"),
+        pytest.param("tutorial015_an_py310", marks=[needs_py310]),
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index 9bb90fa064af813a06e9d56d911094f34e8b9ded..238f8fa2ef2eeb24fad68cf4eb3d390edaf9a6c6 100644 (file)
@@ -3,8 +3,6 @@ import importlib
 import pytest
 from fastapi.testclient import TestClient
 
-from ...utils import needs_pydanticv2
-
 
 @pytest.fixture(
     name="client",
@@ -20,14 +18,12 @@ def get_client(request: pytest.FixtureRequest):
     return client
 
 
-@needs_pydanticv2
 def test_post_body_form(client: TestClient):
     response = client.post("/login/", data={"username": "Foo", "password": "secret"})
     assert response.status_code == 200
     assert response.json() == {"username": "Foo", "password": "secret"}
 
 
-@needs_pydanticv2
 def test_post_body_extra_form(client: TestClient):
     response = client.post(
         "/login/", data={"username": "Foo", "password": "secret", "extra": "extra"}
@@ -45,7 +41,6 @@ def test_post_body_extra_form(client: TestClient):
     }
 
 
-@needs_pydanticv2
 def test_post_body_form_no_password(client: TestClient):
     response = client.post("/login/", data={"username": "Foo"})
     assert response.status_code == 422
@@ -61,7 +56,6 @@ def test_post_body_form_no_password(client: TestClient):
     }
 
 
-@needs_pydanticv2
 def test_post_body_form_no_username(client: TestClient):
     response = client.post("/login/", data={"password": "secret"})
     assert response.status_code == 422
@@ -77,7 +71,6 @@ def test_post_body_form_no_username(client: TestClient):
     }
 
 
-@needs_pydanticv2
 def test_post_body_form_no_data(client: TestClient):
     response = client.post("/login/")
     assert response.status_code == 422
@@ -99,7 +92,6 @@ def test_post_body_form_no_data(client: TestClient):
     }
 
 
-@needs_pydanticv2
 def test_post_body_json(client: TestClient):
     response = client.post("/login/", json={"username": "Foo", "password": "secret"})
     assert response.status_code == 422, response.text
@@ -121,7 +113,6 @@ def test_post_body_json(client: TestClient):
     }
 
 
-@needs_pydanticv2
 def test_openapi_schema(client: TestClient):
     response = client.get("/openapi.json")
     assert response.status_code == 200, response.text
index 41c7833beff55e747174511b22b7e3fafc2e2ed2..9ab30086bb7225d0d9773d20fcde032174a5cec0 100644 (file)
@@ -118,87 +118,3 @@ def test_post_body_json(client: TestClient):
             },
         ]
     }
-
-
-# TODO: remove when deprecating Pydantic v1
-@needs_pydanticv1
-def test_openapi_schema(client: TestClient):
-    response = client.get("/openapi.json")
-    assert response.status_code == 200, response.text
-    assert response.json() == {
-        "openapi": "3.1.0",
-        "info": {"title": "FastAPI", "version": "0.1.0"},
-        "paths": {
-            "/login/": {
-                "post": {
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "Validation Error",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                    "summary": "Login",
-                    "operationId": "login_login__post",
-                    "requestBody": {
-                        "content": {
-                            "application/x-www-form-urlencoded": {
-                                "schema": {"$ref": "#/components/schemas/FormData"}
-                            }
-                        },
-                        "required": True,
-                    },
-                }
-            }
-        },
-        "components": {
-            "schemas": {
-                "FormData": {
-                    "properties": {
-                        "username": {"type": "string", "title": "Username"},
-                        "password": {"type": "string", "title": "Password"},
-                    },
-                    "additionalProperties": False,
-                    "type": "object",
-                    "required": ["username", "password"],
-                    "title": "FormData",
-                },
-                "ValidationError": {
-                    "title": "ValidationError",
-                    "required": ["loc", "msg", "type"],
-                    "type": "object",
-                    "properties": {
-                        "loc": {
-                            "title": "Location",
-                            "type": "array",
-                            "items": {
-                                "anyOf": [{"type": "string"}, {"type": "integer"}]
-                            },
-                        },
-                        "msg": {"title": "Message", "type": "string"},
-                        "type": {"title": "Error Type", "type": "string"},
-                    },
-                },
-                "HTTPValidationError": {
-                    "title": "HTTPValidationError",
-                    "type": "object",
-                    "properties": {
-                        "detail": {
-                            "title": "Detail",
-                            "type": "array",
-                            "items": {"$ref": "#/components/schemas/ValidationError"},
-                        }
-                    },
-                },
-            }
-        },
-    }
index 127f0e4c1d6106eb11d13bb5e9cbc5617b5bf857..2d0c387195921bbaf1500ba0da918d506957559e 100644 (file)
@@ -3,7 +3,7 @@ import importlib
 import pytest
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py310, needs_pydanticv1, needs_pydanticv2
+from ...utils import needs_py310
 
 
 @pytest.fixture(
@@ -37,7 +37,6 @@ def test_path_operation(client: TestClient):
     }
 
 
-@needs_pydanticv2
 def test_openapi_schema_pv2(client: TestClient):
     response = client.get("/openapi.json")
     assert response.status_code == 200, response.text
@@ -151,138 +150,3 @@ def test_openapi_schema_pv2(client: TestClient):
             },
         },
     }
-
-
-@needs_pydanticv1
-def test_openapi_schema_pv1(client: TestClient):
-    response = client.get("/openapi.json")
-    assert response.status_code == 200, response.text
-    assert response.json() == {
-        "info": {
-            "title": "FastAPI",
-            "version": "0.1.0",
-        },
-        "openapi": "3.1.0",
-        "paths": {
-            "/items/{id}": {
-                "put": {
-                    "operationId": "update_item_items__id__put",
-                    "parameters": [
-                        {
-                            "in": "path",
-                            "name": "id",
-                            "required": True,
-                            "schema": {
-                                "title": "Id",
-                                "type": "string",
-                            },
-                        },
-                    ],
-                    "requestBody": {
-                        "content": {
-                            "application/json": {
-                                "schema": {
-                                    "$ref": "#/components/schemas/Item",
-                                },
-                            },
-                        },
-                        "required": True,
-                    },
-                    "responses": {
-                        "200": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {},
-                                },
-                            },
-                            "description": "Successful Response",
-                        },
-                        "422": {
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError",
-                                    },
-                                },
-                            },
-                            "description": "Validation Error",
-                        },
-                    },
-                    "summary": "Update Item",
-                },
-            },
-        },
-        "components": {
-            "schemas": {
-                "HTTPValidationError": {
-                    "properties": {
-                        "detail": {
-                            "items": {
-                                "$ref": "#/components/schemas/ValidationError",
-                            },
-                            "title": "Detail",
-                            "type": "array",
-                        },
-                    },
-                    "title": "HTTPValidationError",
-                    "type": "object",
-                },
-                "Item": {
-                    "properties": {
-                        "description": {
-                            "title": "Description",
-                            "type": "string",
-                        },
-                        "timestamp": {
-                            "format": "date-time",
-                            "title": "Timestamp",
-                            "type": "string",
-                        },
-                        "title": {
-                            "title": "Title",
-                            "type": "string",
-                        },
-                    },
-                    "required": [
-                        "title",
-                        "timestamp",
-                    ],
-                    "title": "Item",
-                    "type": "object",
-                },
-                "ValidationError": {
-                    "properties": {
-                        "loc": {
-                            "items": {
-                                "anyOf": [
-                                    {
-                                        "type": "string",
-                                    },
-                                    {
-                                        "type": "integer",
-                                    },
-                                ],
-                            },
-                            "title": "Location",
-                            "type": "array",
-                        },
-                        "msg": {
-                            "title": "Message",
-                            "type": "string",
-                        },
-                        "type": {
-                            "title": "Error Type",
-                            "type": "string",
-                        },
-                    },
-                    "required": [
-                        "loc",
-                        "msg",
-                        "type",
-                    ],
-                    "title": "ValidationError",
-                    "type": "object",
-                },
-            },
-        },
-    }
index 4d1808cf6a233b46045b69226f3c5c432adaf2be..82f69fd463d8e9ffeb380731278f19dbc34d0fcf 100644 (file)
@@ -3,7 +3,7 @@ import importlib
 import pytest
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py310, needs_pydanticv2
+from ...utils import needs_py310
 
 
 @pytest.fixture(
@@ -20,7 +20,6 @@ def get_client(request: pytest.FixtureRequest):
     return client
 
 
-@needs_pydanticv2
 def test_post_body_example(client: TestClient):
     response = client.put(
         "/items/5",
@@ -34,7 +33,6 @@ def test_post_body_example(client: TestClient):
     assert response.status_code == 200
 
 
-@needs_pydanticv2
 def test_openapi_schema(client: TestClient):
     response = client.get("/openapi.json")
     assert response.status_code == 200, response.text
index 552bb66970c651ca5a70481175f5049033cae7d5..60599628973a2c6354f631342dcba2b9089f4286 100644 (file)
@@ -2,6 +2,7 @@ import importlib
 
 import pytest
 from fastapi.testclient import TestClient
+from inline_snapshot import snapshot
 
 from ...utils import needs_py310, needs_pydanticv1
 
@@ -38,98 +39,106 @@ def test_post_body_example(client: TestClient):
 def test_openapi_schema(client: TestClient):
     response = client.get("/openapi.json")
     assert response.status_code == 200, response.text
-    # insert_assert(response.json())
-    assert response.json() == {
-        "openapi": "3.1.0",
-        "info": {"title": "FastAPI", "version": "0.1.0"},
-        "paths": {
-            "/items/{item_id}": {
-                "put": {
-                    "summary": "Update Item",
-                    "operationId": "update_item_items__item_id__put",
-                    "parameters": [
-                        {
-                            "required": True,
-                            "schema": {"type": "integer", "title": "Item Id"},
-                            "name": "item_id",
-                            "in": "path",
-                        }
-                    ],
-                    "requestBody": {
-                        "content": {
-                            "application/json": {
-                                "schema": {"$ref": "#/components/schemas/Item"}
+    assert response.json() == snapshot(
+        {
+            "openapi": "3.1.0",
+            "info": {"title": "FastAPI", "version": "0.1.0"},
+            "paths": {
+                "/items/{item_id}": {
+                    "put": {
+                        "summary": "Update Item",
+                        "operationId": "update_item_items__item_id__put",
+                        "parameters": [
+                            {
+                                "required": True,
+                                "schema": {"type": "integer", "title": "Item Id"},
+                                "name": "item_id",
+                                "in": "path",
                             }
-                        },
-                        "required": True,
-                    },
-                    "responses": {
-                        "200": {
-                            "description": "Successful Response",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "Validation Error",
+                        ],
+                        "requestBody": {
                             "content": {
                                 "application/json": {
                                     "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
+                                        "title": "Item",
+                                        "allOf": [
+                                            {"$ref": "#/components/schemas/Item"}
+                                        ],
                                     }
                                 }
                             },
+                            "required": True,
                         },
-                    },
+                        "responses": {
+                            "200": {
+                                "description": "Successful Response",
+                                "content": {"application/json": {"schema": {}}},
+                            },
+                            "422": {
+                                "description": "Validation Error",
+                                "content": {
+                                    "application/json": {
+                                        "schema": {
+                                            "$ref": "#/components/schemas/HTTPValidationError"
+                                        }
+                                    }
+                                },
+                            },
+                        },
+                    }
                 }
-            }
-        },
-        "components": {
-            "schemas": {
-                "HTTPValidationError": {
-                    "properties": {
-                        "detail": {
-                            "items": {"$ref": "#/components/schemas/ValidationError"},
-                            "type": "array",
-                            "title": "Detail",
-                        }
+            },
+            "components": {
+                "schemas": {
+                    "HTTPValidationError": {
+                        "properties": {
+                            "detail": {
+                                "items": {
+                                    "$ref": "#/components/schemas/ValidationError"
+                                },
+                                "type": "array",
+                                "title": "Detail",
+                            }
+                        },
+                        "type": "object",
+                        "title": "HTTPValidationError",
                     },
-                    "type": "object",
-                    "title": "HTTPValidationError",
-                },
-                "Item": {
-                    "properties": {
-                        "name": {"type": "string", "title": "Name"},
-                        "description": {"type": "string", "title": "Description"},
-                        "price": {"type": "number", "title": "Price"},
-                        "tax": {"type": "number", "title": "Tax"},
+                    "Item": {
+                        "properties": {
+                            "name": {"type": "string", "title": "Name"},
+                            "description": {"type": "string", "title": "Description"},
+                            "price": {"type": "number", "title": "Price"},
+                            "tax": {"type": "number", "title": "Tax"},
+                        },
+                        "type": "object",
+                        "required": ["name", "price"],
+                        "title": "Item",
+                        "examples": [
+                            {
+                                "name": "Foo",
+                                "description": "A very nice Item",
+                                "price": 35.4,
+                                "tax": 3.2,
+                            }
+                        ],
                     },
-                    "type": "object",
-                    "required": ["name", "price"],
-                    "title": "Item",
-                    "examples": [
-                        {
-                            "name": "Foo",
-                            "description": "A very nice Item",
-                            "price": 35.4,
-                            "tax": 3.2,
-                        }
-                    ],
-                },
-                "ValidationError": {
-                    "properties": {
-                        "loc": {
-                            "items": {
-                                "anyOf": [{"type": "string"}, {"type": "integer"}]
+                    "ValidationError": {
+                        "properties": {
+                            "loc": {
+                                "items": {
+                                    "anyOf": [{"type": "string"}, {"type": "integer"}]
+                                },
+                                "type": "array",
+                                "title": "Location",
                             },
-                            "type": "array",
-                            "title": "Location",
+                            "msg": {"type": "string", "title": "Message"},
+                            "type": {"type": "string", "title": "Error Type"},
                         },
-                        "msg": {"type": "string", "title": "Message"},
-                        "type": {"type": "string", "title": "Error Type"},
+                        "type": "object",
+                        "required": ["loc", "msg", "type"],
+                        "title": "ValidationError",
                     },
-                    "type": "object",
-                    "required": ["loc", "msg", "type"],
-                    "title": "ValidationError",
-                },
-            }
-        },
-    }
+                }
+            },
+        }
+    )
index b59d799a310e55af73566b562f1544496b3933b5..275b2348775b69097a45cc371a9b3845cbed2934 100644 (file)
@@ -3,7 +3,7 @@ import importlib
 import pytest
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py310, needs_pydanticv2
+from ...utils import needs_py310
 
 
 @pytest.fixture(
@@ -38,7 +38,6 @@ def test_read_items(client: TestClient) -> None:
     ]
 
 
-@needs_pydanticv2
 def test_openapi_schema(client: TestClient) -> None:
     response = client.get("/openapi.json")
     assert response.status_code == 200, response.text
index 61fbacfc34d839eb92378f8fba5f5770fd30cc9a..8230e3922676dc1abf4ec617ad9c28360753cc8f 100644 (file)
@@ -3,7 +3,7 @@ import importlib
 import pytest
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py310, needs_pydanticv2
+from ...utils import needs_py310
 
 
 @pytest.fixture(
@@ -38,7 +38,6 @@ def test_read_items(client: TestClient) -> None:
     ]
 
 
-@needs_pydanticv2
 def test_openapi_schema(client: TestClient) -> None:
     response = client.get("/openapi.json")
     assert response.status_code == 200, response.text
index 9cedc5a5264acf6df3b7c2260a2b2fddc9f6570c..9cbed4fd1bec3d6e35a50dbf3727bc199d35b1bc 100644 (file)
@@ -4,8 +4,6 @@ from types import ModuleType
 import pytest
 from pytest import MonkeyPatch
 
-from ...utils import needs_pydanticv2
-
 
 @pytest.fixture(
     name="mod_path",
@@ -31,7 +29,6 @@ def get_test_main_mod(mod_path: str) -> ModuleType:
     return test_main_mod
 
 
-@needs_pydanticv2
 def test_settings(main_mod: ModuleType, monkeypatch: MonkeyPatch):
     monkeypatch.setenv("ADMIN_EMAIL", "admin@example.com")
     settings = main_mod.get_settings()
@@ -39,6 +36,5 @@ def test_settings(main_mod: ModuleType, monkeypatch: MonkeyPatch):
     assert settings.items_per_user == 50
 
 
-@needs_pydanticv2
 def test_override_settings(test_main_mod: ModuleType):
     test_main_mod.test_app()
index dbaf8f3f900175010ecb385785273bb30f802770..06e82398d1e3d171f816abd5aba7d9029423e522 100644 (file)
@@ -5,7 +5,7 @@ import pytest
 from fastapi.testclient import TestClient
 from pytest import MonkeyPatch
 
-from ...utils import needs_pydanticv1, needs_pydanticv2
+from ...utils import needs_pydanticv1
 
 
 @pytest.fixture(
@@ -26,7 +26,6 @@ def get_main_mod(mod_path: str) -> ModuleType:
     return main_mod
 
 
-@needs_pydanticv2
 def test_settings(main_mod: ModuleType, monkeypatch: MonkeyPatch):
     monkeypatch.setenv("ADMIN_EMAIL", "admin@example.com")
     settings = main_mod.get_settings()
@@ -45,7 +44,6 @@ def test_settings_pv1(mod_path: str, monkeypatch: MonkeyPatch):
     assert settings.items_per_user == 50
 
 
-@needs_pydanticv2
 def test_endpoint(main_mod: ModuleType, monkeypatch: MonkeyPatch):
     monkeypatch.setenv("ADMIN_EMAIL", "admin@example.com")
     client = TestClient(main_mod.app)
index 2c6dce261fe74e38b4e2807743dbe14287ab7b17..6a08096989d03310f956dd63e2db51de7cf17e3f 100644 (file)
@@ -4,13 +4,13 @@ import pytest
 from fastapi.testclient import TestClient
 from pytest import MonkeyPatch
 
-from ...utils import needs_pydanticv1, needs_pydanticv2
+from ...utils import needs_pydanticv1
 
 
 @pytest.fixture(
     name="app",
     params=[
-        pytest.param("tutorial001_py39", marks=needs_pydanticv2),
+        pytest.param("tutorial001_py39"),
         pytest.param("tutorial001_pv1_py39", marks=needs_pydanticv1),
     ],
 )
index bf41a72915c5c7027afef19cedca7c03779de996..40fd0065a95fe67f82a234db455e8f8fb5e353de 100644 (file)
@@ -7,10 +7,7 @@ from inline_snapshot import snapshot
 from pydantic import BaseModel, Field
 from typing_extensions import Literal
 
-from .utils import needs_pydanticv2
 
-
-@needs_pydanticv2
 def test_discriminator_pydantic_v2() -> None:
     from pydantic import Tag
 
index f8108c8df4a2b120b40319d82befdbf3c5ba3996..42a6aed24c2e4eada168ea937bbfde0873ee0cb7 100644 (file)
@@ -8,8 +8,6 @@ from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 from pydantic import BaseModel
 
-from .utils import needs_pydanticv2
-
 
 @pytest.fixture(name="client")
 def client_fixture() -> TestClient:
@@ -47,21 +45,18 @@ def client_fixture() -> TestClient:
     return client
 
 
-@needs_pydanticv2
 def test_union_body_discriminator_assignment(client: TestClient) -> None:
     response = client.post("/pet/assignment", json={"pet_type": "cat", "meows": 5})
     assert response.status_code == 200, response.text
     assert response.json() == {"pet_type": "cat", "meows": 5}
 
 
-@needs_pydanticv2
 def test_union_body_discriminator_annotated(client: TestClient) -> None:
     response = client.post("/pet/annotated", json={"pet_type": "dog", "barks": 3.5})
     assert response.status_code == 200, response.text
     assert response.json() == {"pet_type": "dog", "barks": 3.5}
 
 
-@needs_pydanticv2
 def test_openapi_schema(client: TestClient) -> None:
     response = client.get("/openapi.json")
     assert response.status_code == 200, response.text
index 8f76572ba6ad82a4f4ec9c4e9fe28d8c860c6994..d51aa848d02deb5fbc208744c3267f021f32f307 100644 (file)
@@ -1,5 +1,4 @@
 from fastapi import FastAPI
-from fastapi._compat import PYDANTIC_V2
 from pydantic import BaseModel
 
 app = FastAPI()
@@ -20,13 +19,9 @@ class RecursiveItemViaSubmodel(BaseModel):
     name: str
 
 
-if PYDANTIC_V2:
-    RecursiveItem.model_rebuild()
-    RecursiveSubitemInSubmodel.model_rebuild()
-    RecursiveItemViaSubmodel.model_rebuild()
-else:
-    RecursiveItem.update_forward_refs()
-    RecursiveSubitemInSubmodel.update_forward_refs()
+RecursiveItem.model_rebuild()
+RecursiveSubitemInSubmodel.model_rebuild()
+RecursiveItemViaSubmodel.model_rebuild()
 
 
 @app.get("/items/recursive", response_model=RecursiveItem)
index 691e92bbfbdf3a447e38d1ba960d9faafc22d9d8..b896d4527f57beab7db43e2a327e236ff23eaee9 100644 (file)
@@ -1,43 +1,19 @@
 import sys
 
 import pytest
-from fastapi._compat import PYDANTIC_V2
-from inline_snapshot import Snapshot
 
 needs_py39 = pytest.mark.skipif(sys.version_info < (3, 9), reason="requires python3.9+")
 needs_py310 = pytest.mark.skipif(
     sys.version_info < (3, 10), reason="requires python3.10+"
 )
 needs_py_lt_314 = pytest.mark.skipif(
-    sys.version_info > (3, 13), reason="requires python3.13-"
+    sys.version_info >= (3, 14), reason="requires python3.13-"
 )
-needs_pydanticv2 = pytest.mark.skipif(not PYDANTIC_V2, reason="requires Pydantic v2")
-needs_pydanticv1 = pytest.mark.skipif(PYDANTIC_V2, reason="requires Pydantic v1")
+
+needs_pydanticv1 = needs_py_lt_314
 
 
 def skip_module_if_py_gte_314():
     """Skip entire module on Python 3.14+ at import time."""
     if sys.version_info >= (3, 14):
         pytest.skip("requires python3.13-", allow_module_level=True)
-
-
-def pydantic_snapshot(
-    *,
-    v2: Snapshot,
-    v1: Snapshot,  # TODO: remove v1 argument when deprecating Pydantic v1
-):
-    """
-    This function should be used like this:
-
-    >>> assert value == pydantic_snapshot(v2=snapshot(),v1=snapshot())
-
-    inline-snapshot will create the snapshots when pytest is executed for each versions of pydantic.
-
-    It is also possible to use the function inside snapshots for version-specific values.
-
-    >>> assert value == snapshot({
-        "data": "some data",
-        "version_specific": pydantic_snapshot(v2=snapshot(),v1=snapshot()),
-    })
-    """
-    return v2 if PYDANTIC_V2 else v1