Skip to content

Commit 361fb5a

Browse files
Add deprecation warning for Pydantic v2 without --use-annotated (#2914)
* Add deprecation warning for Pydantic v2 without --use-annotated * docs: update llms.txt files Generated by GitHub Actions --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent 69c51fd commit 361fb5a

File tree

7 files changed

+72
-6
lines changed

7 files changed

+72
-6
lines changed

docs/cli-reference/typing-customization.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2823,8 +2823,6 @@ syntax instead of default values. This also enables `--field-constraints`.
28232823

28242824
**Related:** [`--field-constraints`](field-customization.md#field-constraints)
28252825

2826-
**See also:** [Python Version Compatibility](../python-version-compatibility.md)
2827-
28282826
!!! tip "Usage"
28292827

28302828
```bash

docs/llms-full.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14224,8 +14224,6 @@ syntax instead of default values. This also enables `--field-constraints`.
1422414224

1422514225
**Related:** [`--field-constraints`](field-customization.md#field-constraints)
1422614226

14227-
**See also:** [Python Version Compatibility](../python-version-compatibility.md)
14228-
1422914227
!!! tip "Usage"
1423014228

1423114229
```bash

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ filterwarnings = [
214214
"error",
215215
"ignore:^.*Pydantic v1 runtime support is deprecated.*:DeprecationWarning",
216216
"ignore:^.*No --output-model-type specified.*:DeprecationWarning",
217+
"ignore:^.*Pydantic v2 with --use-annotated is recommended.*:DeprecationWarning",
217218
"ignore:^.*`--validation` option is deprecated.*",
218219
"ignore:^.*--parent-scoped-naming is deprecated.*",
219220
"ignore:^.*Field name `name` is duplicated on Pet.*",

src/datamodel_code_generator/__main__.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1209,6 +1209,22 @@ def main(args: Sequence[str] | None = None) -> Exit: # noqa: PLR0911, PLR0912,
12091209
stacklevel=1,
12101210
)
12111211

1212+
if (
1213+
config.output_model_type in {DataModelType.PydanticV2BaseModel, DataModelType.PydanticV2Dataclass}
1214+
and not config.use_annotated
1215+
and namespace.use_annotated is None
1216+
and pyproject_config.get("use_annotated") is None
1217+
):
1218+
warnings.warn(
1219+
"Pydantic v2 with --use-annotated is recommended for correct type annotations. "
1220+
"The current default (use_annotated=False) generates constrained types like "
1221+
"'conint(ge=1, le=365)' which are discouraged in Pydantic v2. "
1222+
"In a future version, --use-annotated will be enabled by default for Pydantic v2. "
1223+
"Please explicitly specify --use-annotated or --no-use-annotated.",
1224+
DeprecationWarning,
1225+
stacklevel=1,
1226+
)
1227+
12121228
if not is_pydantic_v2():
12131229
warnings.warn(
12141230
"Pydantic v1 runtime support is deprecated and will be removed in a future version. "

src/datamodel_code_generator/arguments.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -520,8 +520,9 @@ def start_section(self, heading: str | None) -> None:
520520
)
521521
typing_options.add_argument(
522522
"--use-annotated",
523-
help="Use typing.Annotated for Field(). Also, `--field-constraints` option will be enabled.",
524-
action="store_true",
523+
help="Use typing.Annotated for Field(). Also, `--field-constraints` option will be enabled. "
524+
"Will become default for Pydantic v2 in a future version.",
525+
action=BooleanOptionalAction,
525526
default=None,
526527
)
527528
typing_options.add_argument(

src/datamodel_code_generator/cli_options.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ class CLIOptionMeta:
179179
name="--use-generic-container-types", category=OptionCategory.TYPING
180180
),
181181
"--use-annotated": CLIOptionMeta(name="--use-annotated", category=OptionCategory.TYPING),
182+
"--no-use-annotated": CLIOptionMeta(name="--no-use-annotated", category=OptionCategory.TYPING),
182183
"--use-type-alias": CLIOptionMeta(name="--use-type-alias", category=OptionCategory.TYPING),
183184
"--use-root-model-type-alias": CLIOptionMeta(name="--use-root-model-type-alias", category=OptionCategory.TYPING),
184185
"--strict-types": CLIOptionMeta(name="--strict-types", category=OptionCategory.TYPING),

tests/main/test_main_general.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from __future__ import annotations
44

5+
import warnings
56
from argparse import ArgumentTypeError, Namespace
67
from typing import TYPE_CHECKING
78

@@ -2240,3 +2241,53 @@ def test_custom_formatters_kwargs_invalid(output_file: Path, capsys: pytest.Capt
22402241
capsys=capsys,
22412242
expected_stderr_contains="Unable to load custom_formatters_kwargs mapping: must be a JSON string mapping",
22422243
)
2244+
2245+
2246+
def test_use_annotated_deprecation_warning_pydantic_v2(output_file: Path) -> None:
2247+
"""Test that deprecation warning is emitted for Pydantic v2 without --use-annotated."""
2248+
with pytest.warns(DeprecationWarning, match=r"--use-annotated will be enabled by default for Pydantic v2"):
2249+
run_main_and_assert(
2250+
input_path=JSON_SCHEMA_DATA_PATH / "simple_string.json",
2251+
output_path=output_file,
2252+
input_file_type="jsonschema",
2253+
extra_args=["--output-model-type", "pydantic_v2.BaseModel"],
2254+
)
2255+
2256+
2257+
def test_use_annotated_no_warning_with_flag(output_file: Path) -> None:
2258+
"""Test that no warning is emitted when --use-annotated is explicitly set."""
2259+
with warnings.catch_warnings(record=True) as w:
2260+
warnings.simplefilter("always")
2261+
run_main_and_assert(
2262+
input_path=JSON_SCHEMA_DATA_PATH / "simple_string.json",
2263+
output_path=output_file,
2264+
input_file_type="jsonschema",
2265+
extra_args=["--output-model-type", "pydantic_v2.BaseModel", "--use-annotated"],
2266+
)
2267+
assert not any("--use-annotated will be enabled" in str(warning.message) for warning in w)
2268+
2269+
2270+
def test_use_annotated_no_warning_with_no_flag(output_file: Path) -> None:
2271+
"""Test that no warning is emitted when --no-use-annotated is explicitly set."""
2272+
with warnings.catch_warnings(record=True) as w:
2273+
warnings.simplefilter("always")
2274+
run_main_and_assert(
2275+
input_path=JSON_SCHEMA_DATA_PATH / "simple_string.json",
2276+
output_path=output_file,
2277+
input_file_type="jsonschema",
2278+
extra_args=["--output-model-type", "pydantic_v2.BaseModel", "--no-use-annotated"],
2279+
)
2280+
assert not any("--use-annotated will be enabled" in str(warning.message) for warning in w)
2281+
2282+
2283+
def test_use_annotated_no_warning_pydantic_v1(output_file: Path) -> None:
2284+
"""Test that use_annotated warning is not emitted for Pydantic v1."""
2285+
with warnings.catch_warnings(record=True) as w:
2286+
warnings.simplefilter("always")
2287+
run_main_and_assert(
2288+
input_path=JSON_SCHEMA_DATA_PATH / "simple_string.json",
2289+
output_path=output_file,
2290+
input_file_type="jsonschema",
2291+
extra_args=["--output-model-type", "pydantic.BaseModel"],
2292+
)
2293+
assert not any("--use-annotated will be enabled" in str(warning.message) for warning in w)

0 commit comments

Comments
 (0)