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
4 changes: 0 additions & 4 deletions src/datamodel_code_generator/model/pydantic/base_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -297,10 +297,6 @@ def annotated(self) -> str | None:
@property
def imports(self) -> tuple[Import, ...]:
"""Get all required imports including Field if needed."""
# Fast path: skip expensive self.field check for simple required fields
if self.required and not self.nullable and not self.alias and self.constraints is None and not self.extras:
return super().imports

if self.field:
return chain_as_tuple(super().imports, (IMPORT_FIELD,))
return super().imports
Expand Down
4 changes: 4 additions & 0 deletions tests/data/aliases/multiple_aliases_required.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": ["full_name", "customer_name"],
"email": ["email_address", "mail"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"Customer": {
"full_name": "John"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# generated by datamodel-codegen:
# filename: <dict>
# timestamp: 2019-07-26T00:00:00+00:00

from __future__ import annotations

from pydantic import AliasChoices, BaseModel, Field


class Customer(BaseModel):
full_name: str = Field(
..., validation_alias=AliasChoices('name', 'full_name', 'customer_name')
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# generated by datamodel-codegen:
# filename: multiple_aliases_required.json
# timestamp: 2019-07-26T00:00:00+00:00

from __future__ import annotations

from pydantic import AliasChoices, BaseModel, Field


class Root(BaseModel):
full_name: str = Field(
..., validation_alias=AliasChoices('name', 'full_name', 'customer_name')
)
email_address: str = Field(
..., validation_alias=AliasChoices('email', 'email_address', 'mail')
)
10 changes: 10 additions & 0 deletions tests/data/jsonschema/multiple_aliases_required.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Root",
"type": "object",
"properties": {
"name": { "type": "string" },
"email": { "type": "string" }
},
"required": ["name", "email"]
}
16 changes: 16 additions & 0 deletions tests/main/jsonschema/test_main_jsonschema.py
Original file line number Diff line number Diff line change
Expand Up @@ -8495,3 +8495,19 @@ def test_main_jsonschema_dynamic_ref_in_defs_pydantic_v2(output_file: Path) -> N
expected_file="dynamic_ref_in_defs_pydantic_v2.py",
extra_args=["--output-model-type", "pydantic_v2.BaseModel"],
)


def test_main_jsonschema_multiple_aliases_required_pydantic_v2(output_file: Path) -> None:
"""Test multiple aliases with AliasChoices on required fields for Pydantic v2. (#2989)."""
run_main_and_assert(
input_path=JSON_SCHEMA_DATA_PATH / "multiple_aliases_required.json",
output_path=output_file,
input_file_type="jsonschema",
assert_func=assert_file_content,
extra_args=[
"--aliases",
str(ALIASES_DATA_PATH / "multiple_aliases_required.json"),
"--output-model-type",
"pydantic_v2.BaseModel",
],
)
31 changes: 31 additions & 0 deletions tests/main/test_dynamic_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,37 @@ def test_execute_multi_module_no_models() -> None:
assert models == {}


def test_multiple_aliases_required_field() -> None:
"""Test dynamic models with multiple aliases on required fields. (#2989)."""
schema = make_object_schema({"name": {"type": "string"}}, required=["name"])
config = GenerateConfig(
input_file_type=InputFileType.JsonSchema,
output_model_type=DataModelType.PydanticV2BaseModel,
aliases={"name": ["full_name", "customer_name"]},
class_name="Customer",
)
assert_dynamic_models(
schema,
{"Customer": {"name": "John"}},
EXPECTED_PATH / "multiple_aliases_required.json",
config=config,
)


def test_multiple_aliases_required_field_code_output() -> None:
"""Test generated code includes Field import with multiple aliases on required fields. (#2989)."""
schema = make_object_schema({"name": {"type": "string"}}, required=["name"])
config = GenerateConfig(
input_file_type=InputFileType.JsonSchema,
output_model_type=DataModelType.PydanticV2BaseModel,
aliases={"name": ["full_name", "customer_name"]},
class_name="Customer",
)
result = generate(input_=schema, config=config)
assert isinstance(result, str)
assert_output(result, EXPECTED_PATH / "multiple_aliases_required_code.py")


def test_execute_multi_module_enum_only() -> None:
"""Test _execute_multi_module with enum only to cover non-BaseModel branch."""
from datamodel_code_generator.dynamic import _execute_multi_module
Expand Down
Loading