Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions docs/cli-reference/typing-customization.md
Original file line number Diff line number Diff line change
Expand Up @@ -2823,8 +2823,6 @@ syntax instead of default values. This also enables `--field-constraints`.

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

**See also:** [Python Version Compatibility](../python-version-compatibility.md)

!!! tip "Usage"

```bash
Expand Down
2 changes: 0 additions & 2 deletions docs/llms-full.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14224,8 +14224,6 @@ syntax instead of default values. This also enables `--field-constraints`.

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

**See also:** [Python Version Compatibility](../python-version-compatibility.md)

!!! tip "Usage"

```bash
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ filterwarnings = [
"error",
"ignore:^.*Pydantic v1 runtime support is deprecated.*:DeprecationWarning",
"ignore:^.*No --output-model-type specified.*:DeprecationWarning",
"ignore:^.*Pydantic v2 with --use-annotated is recommended.*:DeprecationWarning",
"ignore:^.*`--validation` option is deprecated.*",
"ignore:^.*--parent-scoped-naming is deprecated.*",
"ignore:^.*Field name `name` is duplicated on Pet.*",
Expand Down
16 changes: 16 additions & 0 deletions src/datamodel_code_generator/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1209,6 +1209,22 @@ def main(args: Sequence[str] | None = None) -> Exit: # noqa: PLR0911, PLR0912,
stacklevel=1,
)

if (
config.output_model_type in {DataModelType.PydanticV2BaseModel, DataModelType.PydanticV2Dataclass}
and not config.use_annotated
and namespace.use_annotated is None
and pyproject_config.get("use_annotated") is None
):
warnings.warn(
"Pydantic v2 with --use-annotated is recommended for correct type annotations. "
"The current default (use_annotated=False) generates constrained types like "
"'conint(ge=1, le=365)' which are discouraged in Pydantic v2. "
"In a future version, --use-annotated will be enabled by default for Pydantic v2. "
"Please explicitly specify --use-annotated or --no-use-annotated.",
DeprecationWarning,
stacklevel=1,
)

if not is_pydantic_v2():
warnings.warn(
"Pydantic v1 runtime support is deprecated and will be removed in a future version. "
Expand Down
5 changes: 3 additions & 2 deletions src/datamodel_code_generator/arguments.py
Original file line number Diff line number Diff line change
Expand Up @@ -520,8 +520,9 @@ def start_section(self, heading: str | None) -> None:
)
typing_options.add_argument(
"--use-annotated",
help="Use typing.Annotated for Field(). Also, `--field-constraints` option will be enabled.",
action="store_true",
help="Use typing.Annotated for Field(). Also, `--field-constraints` option will be enabled. "
"Will become default for Pydantic v2 in a future version.",
action=BooleanOptionalAction,
default=None,
)
typing_options.add_argument(
Expand Down
1 change: 1 addition & 0 deletions src/datamodel_code_generator/cli_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ class CLIOptionMeta:
name="--use-generic-container-types", category=OptionCategory.TYPING
),
"--use-annotated": CLIOptionMeta(name="--use-annotated", category=OptionCategory.TYPING),
"--no-use-annotated": CLIOptionMeta(name="--no-use-annotated", category=OptionCategory.TYPING),
"--use-type-alias": CLIOptionMeta(name="--use-type-alias", category=OptionCategory.TYPING),
"--use-root-model-type-alias": CLIOptionMeta(name="--use-root-model-type-alias", category=OptionCategory.TYPING),
"--strict-types": CLIOptionMeta(name="--strict-types", category=OptionCategory.TYPING),
Expand Down
51 changes: 51 additions & 0 deletions tests/main/test_main_general.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from __future__ import annotations

import warnings
from argparse import ArgumentTypeError, Namespace
from typing import TYPE_CHECKING

Expand Down Expand Up @@ -2240,3 +2241,53 @@ def test_custom_formatters_kwargs_invalid(output_file: Path, capsys: pytest.Capt
capsys=capsys,
expected_stderr_contains="Unable to load custom_formatters_kwargs mapping: must be a JSON string mapping",
)


def test_use_annotated_deprecation_warning_pydantic_v2(output_file: Path) -> None:
"""Test that deprecation warning is emitted for Pydantic v2 without --use-annotated."""
with pytest.warns(DeprecationWarning, match=r"--use-annotated will be enabled by default for Pydantic v2"):
run_main_and_assert(
input_path=JSON_SCHEMA_DATA_PATH / "simple_string.json",
output_path=output_file,
input_file_type="jsonschema",
extra_args=["--output-model-type", "pydantic_v2.BaseModel"],
)


def test_use_annotated_no_warning_with_flag(output_file: Path) -> None:
"""Test that no warning is emitted when --use-annotated is explicitly set."""
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always")
run_main_and_assert(
input_path=JSON_SCHEMA_DATA_PATH / "simple_string.json",
output_path=output_file,
input_file_type="jsonschema",
extra_args=["--output-model-type", "pydantic_v2.BaseModel", "--use-annotated"],
)
assert not any("--use-annotated will be enabled" in str(warning.message) for warning in w)


def test_use_annotated_no_warning_with_no_flag(output_file: Path) -> None:
"""Test that no warning is emitted when --no-use-annotated is explicitly set."""
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always")
run_main_and_assert(
input_path=JSON_SCHEMA_DATA_PATH / "simple_string.json",
output_path=output_file,
input_file_type="jsonschema",
extra_args=["--output-model-type", "pydantic_v2.BaseModel", "--no-use-annotated"],
)
assert not any("--use-annotated will be enabled" in str(warning.message) for warning in w)


def test_use_annotated_no_warning_pydantic_v1(output_file: Path) -> None:
"""Test that use_annotated warning is not emitted for Pydantic v1."""
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always")
run_main_and_assert(
input_path=JSON_SCHEMA_DATA_PATH / "simple_string.json",
output_path=output_file,
input_file_type="jsonschema",
extra_args=["--output-model-type", "pydantic.BaseModel"],
)
assert not any("--use-annotated will be enabled" in str(warning.message) for warning in w)
Loading