Add --use-standard-primitive-types option#2736
Conversation
WalkthroughAdds a new CLI flag Changes
Sequence DiagramsequenceDiagram
actor User
participant CLI as CLI Arguments
participant Config as Config
participant Generator as generate()
participant Parser as Parser
participant DTM as DataTypeManager
participant TypeMap as Type Map Factory
User->>CLI: --use-standard-primitive-types
CLI->>Config: use_standard_primitive_types=True
Config->>Generator: run_generate_from_config(use_standard_primitive_types=True)
Generator->>Parser: Parser(..., use_standard_primitive_types=True)
Parser->>DTM: DataTypeManager(..., use_standard_primitive_types=True)
DTM->>TypeMap: standard_primitive_type_map_factory()
TypeMap-->>DTM: {UUID→Type, IPv4Address→Type, ...}
DTM->>DTM: Merge primitive mappings into type_map
DTM-->>Parser: Configured type mappings
Parser-->>Generator: Generate models with standard lib types
Generator-->>User: Output with UUID, IPv4Address, Path, etc.
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (5 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
🤖 Generated by GitHub Actions
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #2736 +/- ##
=======================================
Coverage 99.36% 99.36%
=======================================
Files 83 83
Lines 12107 12123 +16
Branches 1458 1458
=======================================
+ Hits 12030 12046 +16
Misses 45 45
Partials 32 32
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
CodSpeed Performance ReportMerging #2736 will not alter performanceComparing Summary
Footnotes
|
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/datamodel_code_generator/model/pydantic/types.py (1)
173-201: Clarify intentional no-op flag and clean up unusednoqadirectives
DataTypeManager.__init__now acceptsuse_standard_primitive_typesbut doesn’t forward it tosuper().__init__, effectively making the flag a no-op for Pydantic v1. That’s reasonable given the docs explicitly say Pydantic already uses these standard types by default, and the parameter is needed mainly so this class can be constructed with the shared kwargs set.Ruff is flagging the newly added
# noqaentries here (FBT001,FBT002) as unused. To satisfy the linter while keeping the intentional “unused-arg” suppression, consider trimming the comments as follows:Suggested change to align with Ruff RUF100
- use_standard_primitive_types: bool = False, # noqa: FBT001, FBT002, ARG002 - treat_dot_as_module: bool | None = None, # noqa: FBT001 - use_serialize_as_any: bool = False, # noqa: FBT001, FBT002 + use_standard_primitive_types: bool = False, # noqa: ARG002 + treat_dot_as_module: bool | None = None, + use_serialize_as_any: bool = False,This keeps the constructor signature compatible with the shared parser kwargs, avoids new RUF100 warnings, and leaves behavior unchanged.
🧹 Nitpick comments (4)
docs/cli-reference/typing-customization.md (1)
22-23:--use-standard-primitive-typesdocs and example are accurate; minor markdownlint nitThe option description, “Related” links, and dataclass example (UUID / IPv4Address / Path) accurately reflect the new behavior and match the test/golden output wiring.
markdownlint (MD050) flags the
**Related:**line here for strong-style; if that rule is enforced, consider switching to__Related:__(or relaxing the rule) to keep the linter happy.Also applies to: 2959-3024
src/datamodel_code_generator/model/pydantic_v2/types.py (1)
72-100: Tidy up unusednoqacodes onuse_standard_primitive_typesThe extra ctor parameter is fine as an API compatibility shim (Parser can always pass it) and leaving it unused here preserves existing Pydantic v2 behavior. Given Ruff’s RUF100 hint, you can drop the
FBT001, FBT002parts from thenoqaand keep onlyARG002:Proposed tweak
- use_standard_primitive_types: bool = False, # noqa: FBT001, FBT002, ARG002 + use_standard_primitive_types: bool = False, # noqa: ARG002src/datamodel_code_generator/model/types.py (1)
10-21: Standard primitive mapping is well factored; consider trimming unusednoqaThe new
standard_primitive_type_map_factory()and theuse_standard_primitive_typesswitch inDataTypeManager.__init__cleanly layer stdlib types (UUID,IPv4Address,IPv6Address, networks,Path) on top of the existingtype_map_factorywhile preserving previous defaults when the flag is False.Minor lint nit: Ruff reports unused
noqadirectives forFBT001/FBT002on theuse_standard_primitive_types,treat_dot_as_module, anduse_serialize_as_anyparameters. If those codes aren’t enabled in your config, you can safely drop them and keep only the ones you actually need.Also applies to: 77-141
src/datamodel_code_generator/model/dataclass.py (1)
220-220: Remove unused noqa directive.The
noqadirective forFBT001andFBT002is no longer needed according to Ruff.🔎 Proposed fix
- use_standard_primitive_types: bool = False, # noqa: FBT001, FBT002 + use_standard_primitive_types: bool = False,
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (21)
docs/cli-reference/index.mddocs/cli-reference/quick-reference.mddocs/cli-reference/typing-customization.mdsrc/datamodel_code_generator/__init__.pysrc/datamodel_code_generator/__main__.pysrc/datamodel_code_generator/arguments.pysrc/datamodel_code_generator/cli_options.pysrc/datamodel_code_generator/imports.pysrc/datamodel_code_generator/model/dataclass.pysrc/datamodel_code_generator/model/msgspec.pysrc/datamodel_code_generator/model/pydantic/types.pysrc/datamodel_code_generator/model/pydantic_v2/types.pysrc/datamodel_code_generator/model/types.pysrc/datamodel_code_generator/parser/base.pysrc/datamodel_code_generator/parser/graphql.pysrc/datamodel_code_generator/parser/jsonschema.pysrc/datamodel_code_generator/parser/openapi.pysrc/datamodel_code_generator/types.pytests/data/expected/main/use_standard_primitive_types.pytests/data/jsonschema/use_standard_primitive_types.jsontests/main/test_main_general.py
🧰 Additional context used
🧬 Code graph analysis (4)
src/datamodel_code_generator/model/msgspec.py (1)
src/datamodel_code_generator/model/types.py (2)
standard_primitive_type_map_factory(77-96)type_map_factory(34-74)
src/datamodel_code_generator/model/types.py (1)
src/datamodel_code_generator/types.py (3)
DataType(285-757)Types(767-803)from_import(344-368)
src/datamodel_code_generator/model/dataclass.py (3)
src/datamodel_code_generator/model/types.py (2)
standard_primitive_type_map_factory(77-96)type_map_factory(34-74)src/datamodel_code_generator/model/pydantic_v2/types.py (1)
type_map_factory(116-150)src/datamodel_code_generator/types.py (2)
Types(767-803)DataType(285-757)
tests/main/test_main_general.py (3)
tests/conftest.py (1)
freeze_time(285-288)tests/main/conftest.py (2)
output_file(98-100)run_main_and_assert(244-408)tests/test_main_kr.py (1)
output_file(44-46)
🪛 GitHub Check: CodeQL
src/datamodel_code_generator/model/msgspec.py
[notice] 37-37: Cyclic import
Import of module datamodel_code_generator.model.types begins an import cycle.
src/datamodel_code_generator/model/dataclass.py
[notice] 23-23: Cyclic import
Import of module datamodel_code_generator.model.types begins an import cycle.
🪛 markdownlint-cli2 (0.18.1)
docs/cli-reference/typing-customization.md
2968-2968: Strong style
Expected: underscore; Actual: asterisk
(MD050, strong-style)
2968-2968: Strong style
Expected: underscore; Actual: asterisk
(MD050, strong-style)
🪛 Ruff (0.14.8)
src/datamodel_code_generator/types.py
827-827: Unused noqa directive (non-enabled: FBT001, FBT002)
Remove unused noqa directive
(RUF100)
src/datamodel_code_generator/model/pydantic/types.py
183-183: Unused noqa directive (non-enabled: FBT001, FBT002)
Remove unused noqa directive
(RUF100)
185-185: Unused noqa directive (non-enabled: FBT001)
Remove unused noqa directive
(RUF100)
186-186: Unused noqa directive (non-enabled: FBT001, FBT002)
Remove unused noqa directive
(RUF100)
src/datamodel_code_generator/model/pydantic_v2/types.py
82-82: Unused noqa directive (non-enabled: FBT001, FBT002)
Remove unused noqa directive
(RUF100)
src/datamodel_code_generator/model/msgspec.py
506-506: Unused noqa directive (non-enabled: FBT001, FBT002)
Remove unused noqa directive
(RUF100)
src/datamodel_code_generator/model/types.py
114-114: Unused noqa directive (non-enabled: FBT001, FBT002)
Remove unused noqa directive
(RUF100)
116-116: Unused noqa directive (non-enabled: FBT001)
Remove unused noqa directive
(RUF100)
117-117: Unused noqa directive (non-enabled: FBT001, FBT002)
Remove unused noqa directive
(RUF100)
src/datamodel_code_generator/model/dataclass.py
220-220: Unused noqa directive (non-enabled: FBT001, FBT002)
Remove unused noqa directive
(RUF100)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: 3.13 on Windows
- GitHub Check: benchmarks
🔇 Additional comments (18)
docs/cli-reference/quick-reference.md (1)
44-44: Quick reference entries for--use-standard-primitive-typesare consistentAnchor targets, wording, and placement in both the Typing Customization table and the alphabetical index all look correct and aligned with the detailed typing-customization docs.
Also applies to: 278-278
docs/cli-reference/index.md (1)
12-12: CLI index updates for--use-standard-primitive-typesare consistentThe Typing Customization option count and the new
--use-standard-primitive-typesentry in the U-section both line up with the detailed docs and quick-reference table.Also applies to: 181-181
src/datamodel_code_generator/parser/openapi.py (1)
181-283: OpenAPI parser correctly threadsuse_standard_primitive_typesto the base parserAdding
use_standard_primitive_typesto the OpenAPIParser initializer and passing it through tosuper().__init__keeps the constructor API compatible while allowing the shared parser/type manager logic to honor this flag.Also applies to: 365-383
src/datamodel_code_generator/__init__.py (1)
393-501: Plumbing ofuse_standard_primitive_typesthroughgenerate()looks correctThe new
use_standard_primitive_typesargument is added togenerate()with a safe default and is forwarded into the chosen parser class, keeping existing behavior unchanged unless the flag is explicitly set.Also applies to: 646-749
tests/data/jsonschema/use_standard_primitive_types.json (1)
1-18: Test schema for standard primitive types matches the documented behaviorThe schema cleanly exercises the uuid, ipv4, and path string formats that the new flag is intended to map to UUID, IPv4Address, and Path, respectively.
tests/main/test_main_general.py (1)
1062-1092: End-to-end test for--use-standard-primitive-typesis well wiredThe new CLI-doc test correctly ties together the JSON Schema fixture, the dataclasses output model type, the
--use-standard-primitive-typesflag, and the expected golden file, while freezing time for stable headers. This gives good coverage for the new option’s behavior in the main entry point.tests/data/expected/main/use_standard_primitive_types.py (1)
1-16: LGTM! Expected output correctly demonstrates the feature.The expected test output properly shows the intended behavior: dataclass fields use Python standard library types (
UUID,IPv4Address,Path) instead of plainstrfor formatted string fields. The imports and type annotations are correct.src/datamodel_code_generator/arguments.py (1)
306-313: LGTM! Clear and well-documented CLI argument.The help text accurately describes the feature and appropriately notes that Pydantic models already use standard library types by default, helping users understand when this flag is relevant.
src/datamodel_code_generator/parser/jsonschema.py (1)
594-694: LGTM! Parameter correctly threaded to base class.The
use_standard_primitive_typesparameter is properly added to the constructor signature and forwarded to the parent class using keyword arguments, which makes the code clear and maintainable.However, note that the effectiveness of this change depends on the
DataTypeManagerimplementation (intypes.py), which currently has a critical issue where the parameter is unused.src/datamodel_code_generator/types.py (1)
827-827: This review comment is incorrect and should be dismissed.The
use_standard_primitive_typesparameter is fully implemented and actively used. The parameter appears in the abstract base classDataTypeManagerwhere it's markedARG002because the base class itself doesn't directly consume it. However, concrete subclasses likeDataTypeManagerinmodel/types.py(lines 134–140) explicitly use it to conditionally create and merge astandard_primitive_mapintoself.type_mapviastandard_primitive_type_map_factory(). The same pattern is applied indataclass.py,msgspec.py, and other model implementations. The feature is fully functional with passing tests (test_use_standard_primitive_types) and expected golden output files demonstrating correct type generation (UUID, IPv4Address, IPv6Address, etc.).Likely an incorrect or invalid review comment.
src/datamodel_code_generator/parser/base.py (1)
677-793: Clean wiring ofuse_standard_primitive_typesinto DataTypeManagerThe new kw-only parameter is added conservatively with a default and passed straight into
data_type_manager_type, so existing callers remain compatible and behavior is opt‑in via the manager. No issues here.src/datamodel_code_generator/__main__.py (1)
372-479: Config/CLI plumbing foruse_standard_primitive_typeslooks consistentThe new Config field and the pass-through in
run_generate_from_config()correctly integrate the option into generation, and pyproject / CLI command generation will handle it naturally (bool default False, no--no-variant needed). No further changes needed here.Also applies to: 671-786
src/datamodel_code_generator/cli_options.py (1)
144-171: Doc metadata entry for--use-standard-primitive-typesis correctOption is categorized under Typing and matches the argparse spelling, so it will appear in generated CLI docs and sync tests should pass.
src/datamodel_code_generator/parser/graphql.py (1)
98-199: GraphQLParser correctly forwardsuse_standard_primitive_typesThe constructor mirrors the base
Parser.__init__signature and passes the flag through tosuper().__init__, so GraphQL parsing benefits from the same primitive‑type handling without changing defaults.src/datamodel_code_generator/imports.py (1)
199-234: New ipaddress Import constants are correctThe added
IMPORT_IPV4ADDRESS,IMPORT_IPV6ADDRESS,IMPORT_IPV4NETWORK, andIMPORT_IPV6NETWORKcorrectly useipaddress.*and integrate cleanly with existing import constants.src/datamodel_code_generator/model/msgspec.py (1)
37-38: msgspec DataTypeManager correctly integrates standard primitive map; retain FBT noqa codesThe msgspec
DataTypeManagercorrectly:
- Accepts
use_standard_primitive_typesand forwards it to the base manager (line 522).- Builds
self.type_mapfromtype_map_factory, msgspec-specificdatetime_map, and (optionally)standard_primitive_type_map_factory, so UUID/IP/path formats resolve to stdlib types only when the flag is enabled (lines 542-546).The
# noqa: FBT001, FBT002codes on all boolean parameters (lines 503-510) should be kept: these parameters are positional-or-keyword arguments, so FBT001 and FBT002 warnings legitimately apply and the suppression codes are necessary.No import cycle issues detected.
src/datamodel_code_generator/model/dataclass.py (2)
235-235: Parameter propagation and map creation logic confirmed as correct.The
use_standard_primitive_typesparameter is properly accepted by the superclass_DataTypeManager.__init__(line 114 in types.py) and correctly propagated at line 235. The conditional map creation pattern (lines 252–259) mirrors the existingdatetime_mapimplementation, and merging an empty dict when disabled is harmless.
23-23: No cyclic import exists at this location.The import at line 23 is valid.
dataclass.pyimports fromtypes.py, buttypes.pydoes not import back fromdataclass.py, creating a one-way dependency rather than a cycle. The CodeQL cyclic import notice is a false positive.
Fixes: #1784
Summary by CodeRabbit
Release Notes
New Features
--use-standard-primitive-typesCLI option to use Python standard library types (UUID, IPv4Address, IPv6Address, Path) for string format fields instead of plain strings in dataclass, msgspec, and TypedDict model outputs. Pydantic models already use these types by default.Documentation
--use-standard-primitive-typesoption and its effects.✏️ Tip: You can customize this high-level summary in your review settings.