Skip to content

Commit f0960e9

Browse files
authored
Prefer CLI input over pyproject url (#3083)
1 parent 05901ff commit f0960e9

File tree

2 files changed

+100
-0
lines changed

2 files changed

+100
-0
lines changed

src/datamodel_code_generator/__main__.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,13 @@ def validate_class_name_affix_scope(cls, v: str | ClassNameAffixScope | None) ->
553553
def merge_args(self, args: Namespace) -> None:
554554
"""Merge command-line arguments into config."""
555555
set_args = {f: getattr(args, f) for f in self.get_fields() if getattr(args, f) is not None}
556+
explicit_input_sources = {
557+
field_name for field_name in ("input", "url", "input_model") if field_name in set_args
558+
}
559+
560+
if explicit_input_sources:
561+
for field_name in {"input", "url", "input_model"} - explicit_input_sources:
562+
setattr(self, field_name, None)
556563

557564
if set_args.get("output_model_type") == DataModelType.MsgspecStruct.value:
558565
set_args["use_annotated"] = True

tests/main/test_main_general.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1458,6 +1458,99 @@ def test_use_specialized_enum_pyproject_override_with_cli(output_file: Path, tmp
14581458
)
14591459

14601460

1461+
def test_cli_input_overrides_pyproject_url(output_file: Path, tmp_path: Path, mocker: MockerFixture) -> None:
1462+
"""Test --input takes precedence over pyproject.toml url setting."""
1463+
pyproject_toml = tmp_path / "pyproject.toml"
1464+
pyproject_toml.write_text(
1465+
'[tool.datamodel-codegen]\nurl = "https://example.com/schema.json"\ninput-file-type = "jsonschema"\n',
1466+
encoding="utf-8",
1467+
)
1468+
1469+
cli_input = tmp_path / "cli.json"
1470+
cli_input.write_text(
1471+
'{"type": "object", "properties": {"from_input": {"type": "string"}}}',
1472+
encoding="utf-8",
1473+
)
1474+
1475+
httpx_get_mock = mocker.patch("httpx.get")
1476+
1477+
with chdir(tmp_path):
1478+
run_main_and_assert(
1479+
input_path=cli_input.relative_to(tmp_path),
1480+
output_path=output_file,
1481+
extra_args=["--disable-timestamp"],
1482+
expected_output=snapshot(
1483+
"""\
1484+
# generated by datamodel-codegen:
1485+
# filename: cli.json
1486+
1487+
from __future__ import annotations
1488+
1489+
from pydantic import BaseModel
1490+
1491+
1492+
class Model(BaseModel):
1493+
from_input: str | None = None
1494+
"""
1495+
),
1496+
)
1497+
1498+
httpx_get_mock.assert_not_called()
1499+
1500+
1501+
def test_cli_url_overrides_pyproject_input(output_file: Path, tmp_path: Path, mocker: MockerFixture) -> None:
1502+
"""Test --url takes precedence over pyproject.toml input setting."""
1503+
pyproject_toml = tmp_path / "pyproject.toml"
1504+
pyproject_toml.write_text(
1505+
'[tool.datamodel-codegen]\ninput = "config.json"\ninput-file-type = "jsonschema"\n',
1506+
encoding="utf-8",
1507+
)
1508+
1509+
config_input = tmp_path / "config.json"
1510+
config_input.write_text(
1511+
'{"type": "object", "properties": {"from_config": {"type": "string"}}}',
1512+
encoding="utf-8",
1513+
)
1514+
1515+
mock_response = mocker.Mock()
1516+
mock_response.status_code = 200
1517+
mock_response.headers = {}
1518+
mock_response.text = '{"type": "object", "properties": {"from_url": {"type": "integer"}}}'
1519+
httpx_get_mock = mocker.patch("httpx.get", return_value=mock_response)
1520+
1521+
with chdir(tmp_path):
1522+
run_main_with_args([
1523+
"--url",
1524+
"http://127.0.0.1:8123/schema.json",
1525+
"--output",
1526+
str(output_file),
1527+
"--disable-timestamp",
1528+
])
1529+
1530+
assert output_file.read_text(encoding="utf-8") == snapshot(
1531+
"""\
1532+
# generated by datamodel-codegen:
1533+
# filename: http://127.0.0.1:8123/schema.json
1534+
1535+
from __future__ import annotations
1536+
1537+
from pydantic import BaseModel
1538+
1539+
1540+
class Model(BaseModel):
1541+
from_url: int | None = None
1542+
"""
1543+
)
1544+
httpx_get_mock.assert_called_once_with(
1545+
"http://127.0.0.1:8123/schema.json",
1546+
headers=None,
1547+
verify=True,
1548+
follow_redirects=True,
1549+
params=None,
1550+
timeout=30.0,
1551+
)
1552+
1553+
14611554
@pytest.mark.cli_doc(
14621555
options=["--module-split-mode"],
14631556
option_description="""Split generated models into separate files, one per model class.

0 commit comments

Comments
 (0)