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
6 changes: 3 additions & 3 deletions docs/cli-reference/model-customization.md
Original file line number Diff line number Diff line change
Expand Up @@ -2671,9 +2671,9 @@ Generate dataclasses with keyword-only fields (Python 3.10+).

The `--keyword-only` flag generates dataclasses where all fields must be
specified as keyword arguments (kw_only=True). This is only available for
Python 3.10+. When combined with `--frozen`, it creates immutable dataclasses
with keyword-only arguments, improving code clarity and preventing positional
argument errors.
Python 3.10+. When combined with `--frozen-dataclasses`, it creates immutable
dataclasses with keyword-only arguments, improving code clarity and preventing
positional argument errors.

**Related:** [`--frozen-dataclasses`](model-customization.md#frozen-dataclasses), [`--output-model-type`](model-customization.md#output-model-type), [`--target-python-version`](model-customization.md#target-python-version)

Expand Down
30 changes: 30 additions & 0 deletions tests/main/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

from datamodel_code_generator import DataModelType
from datamodel_code_generator.__main__ import Exit, main
from datamodel_code_generator.arguments import arg_parser
from datamodel_code_generator.util import PYDANTIC_V2
from tests.conftest import (
AssertFileContent,
Expand Down Expand Up @@ -133,6 +134,34 @@ def _assert_exit_code(return_code: Exit, expected_exit: Exit, context: str) -> N
pytest.fail(f"Expected exit code {expected_exit!r}, got {return_code!r}\n{context}")


def _get_valid_cli_options() -> frozenset[str]:
"""Get all valid CLI option names from arg_parser."""
valid_options: set[str] = set()
for action in arg_parser._actions:
valid_options.update(action.option_strings)
return frozenset(valid_options)


_VALID_CLI_OPTIONS = _get_valid_cli_options()


def _validate_extra_args(extra_args: Sequence[str] | None) -> None:
"""Validate that all option-like arguments in extra_args are valid CLI options."""
if extra_args is None:
return
invalid_args: list[str] = [
arg
for arg in extra_args
if (
(arg.startswith("--") and "=" not in arg)
or (arg.startswith("-") and not arg.startswith("--") and len(arg) == 2)
)
and arg not in _VALID_CLI_OPTIONS
]
if invalid_args: # pragma: no cover
pytest.fail(f"Invalid CLI options in extra_args: {invalid_args}. Valid options: {sorted(_VALID_CLI_OPTIONS)}")


def _extend_args(
args: list[str],
*,
Expand All @@ -148,6 +177,7 @@ def _extend_args(
args.extend(["--output", str(output_path)])
if input_file_type is not None:
args.extend(["--input-file-type", input_file_type])
_validate_extra_args(extra_args)
if extra_args is not None:
args.extend(extra_args)

Expand Down
8 changes: 4 additions & 4 deletions tests/main/graphql/test_main_graphql.py
Original file line number Diff line number Diff line change
Expand Up @@ -582,9 +582,9 @@ def test_main_graphql_dataclass_frozen_keyword_only(output_file: Path) -> None:

The `--keyword-only` flag generates dataclasses where all fields must be
specified as keyword arguments (kw_only=True). This is only available for
Python 3.10+. When combined with `--frozen`, it creates immutable dataclasses
with keyword-only arguments, improving code clarity and preventing positional
argument errors.
Python 3.10+. When combined with `--frozen-dataclasses`, it creates immutable
dataclasses with keyword-only arguments, improving code clarity and preventing
positional argument errors.
"""
run_main_and_assert(
input_path=GRAPHQL_DATA_PATH / "simple-star-wars.graphql",
Expand All @@ -595,7 +595,7 @@ def test_main_graphql_dataclass_frozen_keyword_only(output_file: Path) -> None:
extra_args=[
"--output-model-type",
"dataclasses.dataclass",
"--frozen",
"--frozen-dataclasses",
"--keyword-only",
"--target-python-version",
"3.10",
Expand Down
8 changes: 4 additions & 4 deletions tests/main/jsonschema/test_main_jsonschema.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ def test_main_jsonschema_dataclass_arguments_with_pydantic(output_file: Path) ->
@pytest.mark.cli_doc(
options=["--keyword-only"],
input_schema="jsonschema/person.json",
cli_args=["--output-model-type", "dataclasses.dataclass", "--frozen", "--keyword-only"],
cli_args=["--output-model-type", "dataclasses.dataclass", "--frozen-dataclasses", "--keyword-only"],
golden_output="main/jsonschema/general_dataclass_frozen_kw_only.py",
related_options=["--frozen-dataclasses", "--output-model-type"],
)
Expand All @@ -323,7 +323,7 @@ def test_main_jsonschema_dataclass_frozen_keyword_only(output_file: Path) -> Non

The `--keyword-only` flag generates all dataclass fields as keyword-only,
requiring explicit parameter names when instantiating models. Combined with
`--frozen`, creates immutable models with keyword-only constructors.
`--frozen-dataclasses`, creates immutable models with keyword-only constructors.
"""
run_main_and_assert(
input_path=JSON_SCHEMA_DATA_PATH / "person.json",
Expand All @@ -334,7 +334,7 @@ def test_main_jsonschema_dataclass_frozen_keyword_only(output_file: Path) -> Non
extra_args=[
"--output-model-type",
"dataclasses.dataclass",
"--frozen",
"--frozen-dataclasses",
"--keyword-only",
"--target-python-version",
"3.10",
Expand Down Expand Up @@ -4005,7 +4005,7 @@ def test_main_jsonschema_reuse_scope_tree_dataclass_frozen(output_dir: Path) ->
"tree",
"--output-model-type",
"dataclasses.dataclass",
"--frozen",
"--frozen-dataclasses",
],
)

Expand Down
Loading