feat: Add support for number type with time-delta format#2689
Conversation
…g model generation
WalkthroughThis pull request implements timedelta support in datamodel-code-generator by mapping the JSON Schema "time-delta" format on number types to Python's Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Areas warranting attention:
Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 inconclusive)
✅ Passed checks (4 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 #2689 +/- ##
=======================================
Coverage 99.53% 99.53%
=======================================
Files 81 81
Lines 11366 11369 +3
Branches 1357 1357
=======================================
+ Hits 11313 11316 +3
Misses 32 32
Partials 21 21
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 #2689 will not alter performanceComparing Summary
Footnotes
|
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
scripts/build_cli_docs.py (1)
313-329:expected_stdouthandling is a nice improvement; consider tightening the path heuristicThe new logic correctly supports both:
- File-based
expected_stdout(snapshot files undertests/data/expected/...).- Inline text
expected_stdout(simple messages like the--watcherror / “Watching”).Two small robustness tweaks you might consider:
- Guard type up front to avoid surprises if a non-string ever sneaks in:
stdout_value = str(kwargs["expected_stdout"])- Make the “path-like” heuristic stricter so ordinary messages containing
/or.pyaren’t mistaken for filenames, e.g. require no whitespace/newlines:is_path_like = ( ("/" in stdout_value or stdout_value.endswith((".py", ".txt"))) and " " not in stdout_value and "\n" not in stdout_value )That would keep the current behavior for snapshot filenames while reducing the risk of misclassifying inline error messages that mention paths or
.pyfiles.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
docs/cli-reference/general-options.md(2 hunks)scripts/build_cli_docs.py(2 hunks)src/datamodel_code_generator/parser/jsonschema.py(1 hunks)tests/data/expected/main/jsonschema/time_delta_msgspec.py(1 hunks)tests/data/expected/main/jsonschema/time_delta_pydantic_v2.py(1 hunks)tests/data/jsonschema/time_delta.json(1 hunks)tests/main/jsonschema/test_main_jsonschema.py(1 hunks)tests/parser/test_jsonschema.py(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
src/datamodel_code_generator/parser/jsonschema.py (1)
src/datamodel_code_generator/types.py (1)
Types(622-658)
tests/data/expected/main/jsonschema/time_delta_pydantic_v2.py (1)
tests/data/expected/main/jsonschema/time_delta_msgspec.py (1)
Test(16-17)
tests/main/jsonschema/test_main_jsonschema.py (2)
tests/conftest.py (1)
min_version(587-589)tests/main/conftest.py (2)
output_file(94-96)run_main_and_assert(196-352)
⏰ 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). (14)
- GitHub Check: 3.10 on Windows
- GitHub Check: py312-isort5 on Ubuntu
- GitHub Check: 3.12 on Ubuntu
- GitHub Check: py312-isort7 on Ubuntu
- GitHub Check: py312-black22 on Ubuntu
- GitHub Check: py312-isort6 on Ubuntu
- GitHub Check: 3.9 on Windows
- GitHub Check: 3.9 on Ubuntu
- GitHub Check: 3.11 on Windows
- GitHub Check: 3.10 on Ubuntu
- GitHub Check: 3.12 on Windows
- GitHub Check: 3.14 on Windows
- GitHub Check: Analyze (python)
- GitHub Check: benchmarks
🔇 Additional comments (8)
src/datamodel_code_generator/parser/jsonschema.py (1)
120-136: Numerictime-delta→Types.timedeltamapping looks correctAdding
"time-delta": Types.timedeltaunder the"number"formats cleanly aligns numerictime-deltaschemas with the existingTypes.timedeltahandling (used for string"duration"), and matches the new tests. No issues spotted.docs/cli-reference/general-options.md (1)
1899-1901: Output examples now accurately mirror CLI stdoutRepresenting the
--watcherror and--watch-delay“Watching” message as minimal fenced blocks matches the newexpected_stdouthandling and keeps the docs focused on the actual CLI output. Looks good.Also applies to: 1955-1957
scripts/build_cli_docs.py (1)
148-159: Use of relative path inFileNotFoundErrorimproves usabilitySwitching the not-found message to
relative_pathkeeps error output concise and avoids exposing full local paths in generated docs. The path-traversal guard viarelative_toremains intact.tests/data/jsonschema/time_delta.json (1)
1-14: Fixture cleanly exercises numerictime-deltaformatThe schema is minimal and directly targets
{"type": "number", "format": "time-delta"}onTest.n_timedelta, which is exactly what’s needed to validate the new mapping. No issues.tests/parser/test_jsonschema.py (1)
372-398: Good matrix extension fornumber+time-deltaformatAdding the two
("number", "time-delta", ...)rows (stdlibtimedeltaand pendulumDuration) keepstest_get_data_type’s matrix in sync with the newjson_schema_data_formatsentry and with existing"duration"tests for strings. This should catch regressions in both standard-datetimeanduse_pendulummodes.tests/data/expected/main/jsonschema/time_delta_pydantic_v2.py (1)
1-18: Expected Pydantic v2 model matches newtime-deltamappingThe generated classes look consistent with other JSON Schema fixtures:
- Root wrapper:
class Model(RootModel[Any])is the usual pattern for schema-level roots.- Definition:
class Test(BaseModel): n_timedelta: Optional[timedelta] = Nonecorrectly reflects theTypes.timedeltamapping and the property being optional.This should align with the parser change and the new CLI/tests around
time-delta.tests/data/expected/main/jsonschema/time_delta_msgspec.py (1)
1-17: Msgspec expected model correctly represents optionaltimedeltaFor the msgspec backend:
Model: TypeAlias = Anymatches the simple root schema.class Test(Struct): n_timedelta: Union[timedelta, UnsetType] = UNSETis consistent with how other optional fields are modeled (usingUnsetType/UNSET) and with the newTypes.timedeltamapping.Looks coherent with the rest of the generated expectations.
tests/main/jsonschema/test_main_jsonschema.py (1)
3138-3163: Approved: Test structure and data files verified.The new parameterized test correctly follows the established pattern of
test_main_jsonschema_duration, with proper parametrization for both Pydantic v2 and msgspec output models. All referenced test data files exist (time_delta.json,time_delta_pydantic_v2.py, andtime_delta_msgspec.py), and there are no duplicate function definitions—only the single test instance at line 3151.
Closes: #1624
Summary by CodeRabbit
New Features
Documentation
Tests
✏️ Tip: You can customize this high-level summary in your review settings.