Skip to content

feat: Add support for number type with time-delta format#2689

Merged
koxudaxi merged 3 commits intomainfrom
feat/support-number-time-delta-format
Dec 19, 2025
Merged

feat: Add support for number type with time-delta format#2689
koxudaxi merged 3 commits intomainfrom
feat/support-number-time-delta-format

Conversation

@koxudaxi
Copy link
Copy Markdown
Owner

@koxudaxi koxudaxi commented Dec 19, 2025

Closes: #1624

Summary by CodeRabbit

  • New Features

    • Added support for JSON Schema "time-delta" format type, enabling code generation to map time-delta formatted fields to Python timedelta objects.
  • Documentation

    • Enhanced CLI reference documentation with improved formatting for example command outputs.
  • Tests

    • Expanded test coverage for time_delta schema handling across multiple output model generators.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Dec 19, 2025

Walkthrough

This pull request implements timedelta support in datamodel-code-generator by mapping the JSON Schema "time-delta" format on number types to Python's timedelta type. It includes test cases, expected generated outputs for both Pydantic v2 and msgspec backends, and updates to CLI documentation generation.

Changes

Cohort / File(s) Summary
Core feature implementation
src/datamodel_code_generator/parser/jsonschema.py
Added format mapping "time-delta": Types.timedelta to json_schema_data_formats under the "number" type to enable JSON Schema time-delta format recognition.
Test input schema
tests/data/jsonschema/time_delta.json
New JSON Schema file defining a Test object with a number property formatted as "time-delta".
Expected generated outputs
tests/data/expected/main/jsonschema/time_delta_pydantic_v2.py, time_delta_msgspec.py
Generated Python datamodel files showing expected output for Pydantic v2 (BaseModel with Optional[timedelta]) and msgspec (Struct with Union[timedelta, UnsetType]).
Test cases
tests/main/jsonschema/test_main_jsonschema.py, tests/parser/test_jsonschema.py
Added parameterized test test_main_jsonschema_time_delta for both Pydantic v2 and msgspec output models; extended test_nested_array with two time-delta format test cases.
Build script and documentation
scripts/build_cli_docs.py, docs/cli-reference/general-options.md
Modified generate_option_section to treat expected_stdout as either a file path (if containing "/" or .py/.txt extension) or inline text, with improved error reporting; documentation examples reformatted as concise code blocks.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Areas warranting attention:

  • tests/main/jsonschema/test_main_jsonschema.py: Contains an apparent duplication of test_main_jsonschema_time_delta function that should be deduplicated.
  • scripts/build_cli_docs.py: Logic change to distinguish file paths from inline text in generate_option_section requires verification of the heuristic (checking for "/" or .py/.txt extensions) against real usage patterns.
  • Coherence check: Verify that generated outputs in time_delta_pydantic_v2.py and time_delta_msgspec.py match the actual code generation behavior for the new format mapping.

Possibly related PRs

Poem

🐰 A timedelta hops into the schema,
No more floats that confuse the getter,
Pydantic and msgspec now understand,
The passage of time, both measured and grand!
Seconds to strings, formats aligned—
Native support for the time-inclined! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Out of Scope Changes check ❓ Inconclusive Documentation changes in general-options.md are formatting improvements unrelated to the time-delta feature, and build script updates support the new feature testing. Clarify whether documentation and build script changes are necessary for this feature or should be addressed in separate PRs.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main feature addition: adding support for a number type with time-delta format, which is the core change across the codebase.
Linked Issues check ✅ Passed The PR addresses issue #1624 by implementing support for 'number' type with 'time-delta' format as native timedelta [#1624], aligning with the requested feature.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/support-number-time-delta-format

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

🤖 Generated by GitHub Actions
@codecov
Copy link
Copy Markdown

codecov Bot commented Dec 19, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.53%. Comparing base (d325cf3) to head (58ceecf).
⚠️ Report is 1 commits behind head on main.

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           
Flag Coverage Δ
unittests 99.53% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Dec 19, 2025

CodSpeed Performance Report

Merging #2689 will not alter performance

Comparing feat/support-number-time-delta-format (58ceecf) with main (d325cf3)

Summary

✅ 52 untouched
⏩ 10 skipped1

Footnotes

  1. 10 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
scripts/build_cli_docs.py (1)

313-329: expected_stdout handling is a nice improvement; consider tightening the path heuristic

The new logic correctly supports both:

  • File-based expected_stdout (snapshot files under tests/data/expected/...).
  • Inline text expected_stdout (simple messages like the --watch error / “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 .py aren’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 .py files.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d325cf3 and 58ceecf.

📒 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: Numeric time-deltaTypes.timedelta mapping looks correct

Adding "time-delta": Types.timedelta under the "number" formats cleanly aligns numeric time-delta schemas with the existing Types.timedelta handling (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 stdout

Representing the --watch error and --watch-delay “Watching” message as minimal fenced blocks matches the new expected_stdout handling 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 in FileNotFoundError improves usability

Switching the not-found message to relative_path keeps error output concise and avoids exposing full local paths in generated docs. The path-traversal guard via relative_to remains intact.

tests/data/jsonschema/time_delta.json (1)

1-14: Fixture cleanly exercises numeric time-delta format

The schema is minimal and directly targets {"type": "number", "format": "time-delta"} on Test.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 for number + time-delta format

Adding the two ("number", "time-delta", ...) rows (stdlib timedelta and pendulum Duration) keeps test_get_data_type’s matrix in sync with the new json_schema_data_formats entry and with existing "duration" tests for strings. This should catch regressions in both standard-datetime and use_pendulum modes.

tests/data/expected/main/jsonschema/time_delta_pydantic_v2.py (1)

1-18: Expected Pydantic v2 model matches new time-delta mapping

The 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] = None correctly reflects the Types.timedelta mapping 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 optional timedelta

For the msgspec backend:

  • Model: TypeAlias = Any matches the simple root schema.
  • class Test(Struct): n_timedelta: Union[timedelta, UnsetType] = UNSET is consistent with how other optional fields are modeled (using UnsetType/UNSET) and with the new Types.timedelta mapping.

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, and time_delta_msgspec.py), and there are no duplicate function definitions—only the single test instance at line 3151.

@koxudaxi koxudaxi merged commit 114feaa into main Dec 19, 2025
70 of 71 checks passed
@koxudaxi koxudaxi deleted the feat/support-number-time-delta-format branch December 19, 2025 03:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature request: timedelta support

1 participant