Skip to content

Fix --allow-population-by-field-name for pydantic v2 dataclass output#3013

Merged
koxudaxi merged 2 commits intokoxudaxi:mainfrom
butvinm:fix/allow-population-by-field-name-dataclass
Mar 3, 2026
Merged

Fix --allow-population-by-field-name for pydantic v2 dataclass output#3013
koxudaxi merged 2 commits intokoxudaxi:mainfrom
butvinm:fix/allow-population-by-field-name-dataclass

Conversation

@butvinm
Copy link
Copy Markdown
Contributor

@butvinm butvinm commented Mar 2, 2026

Fixes #3010

--allow-population-by-field-name was silently ignored when using --output-model-type pydantic_v2.dataclass. DataClass.__init__ never read the flag from extra_template_data, so populate_by_name was never passed to ConfigDict.

Added _CONFIG_ATTRIBUTES processing (matching the BaseModel pattern), with validate_by_name support for --target-pydantic-version 2.11.

Before:

@dataclass
class Model:
      s: str

After:

@dataclass(config=ConfigDict(populate_by_name=True))
class Model:
      s: str

Summary by CodeRabbit

  • Bug Fixes

    • Improved Pydantic v2 dataclass generation with version-aware configuration mapping for more accurate config emission across v2.x releases.
    • Restored and unified handling of field-name population/validation options in generated dataclasses.
  • New Features

    • Emit generated dataclass examples that include the appropriate configuration annotations for populate/validate-by-name.
  • Tests

    • Added tests covering field-name population/validation behavior for multiple Pydantic v2 targets.

…koxudaxi#3010)

DataClass.__init__ never read allow_population_by_field_name from
extra_template_data, so the flag was silently ignored for
pydantic_v2.dataclass output. Add _CONFIG_ATTRIBUTES processing
(matching the BaseModel pattern) to emit populate_by_name in
ConfigDict, with validate_by_name support for --target-pydantic-version 2.11.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 2, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fd65a6a and 4080c70.

📒 Files selected for processing (2)
  • tests/data/expected/main/jsonschema/pydantic_v2_dataclass_validate_by_name.py
  • tests/main/jsonschema/test_main_jsonschema.py

📝 Walkthrough

Walkthrough

Adds version-aware mapping of dataclass ConfigDict attributes for Pydantic v2 generation and updates tests/expected outputs to validate populate/validate-by-name behavior across v2 versions.

Changes

Cohort / File(s) Summary
Pydantic v2 dataclass implementation
src/datamodel_code_generator/model/pydantic_v2/dataclass.py
Introduce _CONFIG_ATTRIBUTES_V2 and _CONFIG_ATTRIBUTES_V2_11 (ClassVar lists of ConfigAttribute), add _get_config_attributes() to select mappings by target_pydantic_version, replace single-attribute handling with looped application of mapped attributes, and import ConfigAttribute.
Generated fixtures
tests/data/expected/main/jsonschema/pydantic_v2_dataclass_populate_by_name.py, tests/data/expected/main/jsonschema/pydantic_v2_dataclass_validate_by_name.py
Add expected generated dataclass files showing ConfigDict(populate_by_name=True) and ConfigDict(validate_by_name=True) outputs.
Tests
tests/main/jsonschema/test_main_jsonschema.py
Add tests exercising allow_population_by_field_name handling for default and target v2.11 contexts (note: tests appear inserted twice in file).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

breaking-change-analyzed

Suggested reviewers

  • koxudaxi

Poem

🐰 I nibbled through configs, mapping names just right,
Pydantic versions hopped in line, from morning through the night.
Fields now populate and validate by name with cheer,
Tests and fixtures dance along — the meadow's code is clear!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Out of Scope Changes check ❓ Inconclusive Test files contain duplicate test function insertions which appear unintentional and are unexplained; unclear if this duplication is intentional or a merge artifact requiring clarification. Review and clarify why test_main_generate_pydantic_v2_dataclass_allow_population_by_field_name and related tests are duplicated in the test file.
✅ 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 'Fix --allow-population-by-field-name for pydantic v2 dataclass output' clearly and specifically describes the main change: fixing the CLI flag for pydantic v2 dataclasses.
Linked Issues check ✅ Passed The PR fully addresses issue #3010 by implementing populate_by_name for pydantic v2 dataclasses and adds validate_by_name support for v2.11, meeting all coding requirements.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Mar 2, 2026

Merging this PR will not alter performance

⚠️ Unknown Walltime execution environment detected

Using the Walltime instrument on standard Hosted Runners will lead to inconsistent data.

For the most accurate results, we recommend using CodSpeed Macro Runners: bare-metal machines fine-tuned for performance measurement consistency.

✅ 11 untouched benchmarks
⏩ 98 skipped benchmarks1


Comparing butvinm:fix/allow-population-by-field-name-dataclass (4080c70) with main (9955314)

Open in CodSpeed

Footnotes

  1. 98 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.

🧹 Nitpick comments (3)
src/datamodel_code_generator/model/pydantic_v2/dataclass.py (2)

120-127: Consider centralizing version-based config selection to avoid drift.

This method duplicates the selector in src/datamodel_code_generator/model/pydantic_v2/base_model.py (same version branching). A shared helper/mixin would reduce future divergence risk.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/datamodel_code_generator/model/pydantic_v2/dataclass.py` around lines 120
- 127, The _get_config_attributes method duplicates version-branching logic
present in base_model.py; extract the version selector into a single shared
helper (e.g., a function or mixin) that accepts the extra_template_data (or
target_version) and returns the appropriate config constant, then replace the
branching in dataclass._get_config_attributes and the analogous method in
base_model to call that shared helper; reference the symbols
TargetPydanticVersion, _CONFIG_ATTRIBUTES_V2_11, _CONFIG_ATTRIBUTES_V2, and
_get_config_attributes when locating places to replace.

38-48: Make key precedence explicit for duplicate destination mappings.

Both allow_population_by_field_name and populate_by_name target the same config key. Today precedence is implicit via list order. Consider documenting the intended winner (or enforcing it in code) to avoid accidental behavior changes during future reordering.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/datamodel_code_generator/model/pydantic_v2/dataclass.py` around lines 38
- 48, The lists _CONFIG_ATTRIBUTES_V2 and _CONFIG_ATTRIBUTES_V2_11 contain
duplicate destination mappings for allow_population_by_field_name and
populate_by_name which makes precedence implicit; update the dataclass mapping
so the intended winner is explicit—either remove the duplicate entry for the
losing key from those lists, add an explicit priority flag to the
ConfigAttribute type and set it for allow_population_by_field_name vs
populate_by_name, or update the resolution logic that consumes these lists to
prefer a named winner—ensure you modify ConfigAttribute and the consumer code
together (references: _CONFIG_ATTRIBUTES_V2, _CONFIG_ATTRIBUTES_V2_11,
ConfigAttribute, keys allow_population_by_field_name and populate_by_name) and
add a short comment documenting the chosen precedence.
tests/main/jsonschema/test_main_jsonschema.py (1)

1847-1861: Add coverage for the --target-pydantic-version 2.11 path.

This test covers the default v2 dataclass path well, but the PR also introduces version-specific config mapping. Please add a companion test with target_pydantic_version="2.11" so the new branch is regression-protected.

Proposed test addition
+def test_main_generate_pydantic_v2_dataclass_allow_population_by_field_name_target_2_11(tmp_path: Path) -> None:
+    """Test pydantic_v2.dataclass with allow_population_by_field_name for target pydantic 2.11."""
+    output_file: Path = tmp_path / "output.py"
+    input_ = (JSON_SCHEMA_DATA_PATH / "simple_string.json").relative_to(Path.cwd())
+    assert not input_.is_absolute()
+    generate(
+        input_=input_,
+        input_file_type=InputFileType.JsonSchema,
+        output=output_file,
+        output_model_type=DataModelType.PydanticV2Dataclass,
+        allow_population_by_field_name=True,
+        target_pydantic_version="2.11",
+    )
+
+    assert_file_content(output_file, "pydantic_v2_dataclass_populate_by_name_target_2_11.py")
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/main/jsonschema/test_main_jsonschema.py` around lines 1847 - 1861, Add
a new test mirroring
test_main_generate_pydantic_v2_dataclass_allow_population_by_field_name named
something like
test_main_generate_pydantic_v2_dataclass_allow_population_by_field_name_target_2_11
that calls generate with the same parameters but adds
target_pydantic_version="2.11" (keep input_ and output_file setup identical) and
asserts the generated output matches the expected fixture (use a new fixture
file name such as pydantic_v2_dataclass_populate_by_name_p2_11.py or reuse
appropriate expected content). This will exercise the version-specific config
mapping path in generate and protect the 2.11 branch.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/datamodel_code_generator/model/pydantic_v2/dataclass.py`:
- Around line 120-127: The _get_config_attributes method duplicates
version-branching logic present in base_model.py; extract the version selector
into a single shared helper (e.g., a function or mixin) that accepts the
extra_template_data (or target_version) and returns the appropriate config
constant, then replace the branching in dataclass._get_config_attributes and the
analogous method in base_model to call that shared helper; reference the symbols
TargetPydanticVersion, _CONFIG_ATTRIBUTES_V2_11, _CONFIG_ATTRIBUTES_V2, and
_get_config_attributes when locating places to replace.
- Around line 38-48: The lists _CONFIG_ATTRIBUTES_V2 and
_CONFIG_ATTRIBUTES_V2_11 contain duplicate destination mappings for
allow_population_by_field_name and populate_by_name which makes precedence
implicit; update the dataclass mapping so the intended winner is explicit—either
remove the duplicate entry for the losing key from those lists, add an explicit
priority flag to the ConfigAttribute type and set it for
allow_population_by_field_name vs populate_by_name, or update the resolution
logic that consumes these lists to prefer a named winner—ensure you modify
ConfigAttribute and the consumer code together (references:
_CONFIG_ATTRIBUTES_V2, _CONFIG_ATTRIBUTES_V2_11, ConfigAttribute, keys
allow_population_by_field_name and populate_by_name) and add a short comment
documenting the chosen precedence.

In `@tests/main/jsonschema/test_main_jsonschema.py`:
- Around line 1847-1861: Add a new test mirroring
test_main_generate_pydantic_v2_dataclass_allow_population_by_field_name named
something like
test_main_generate_pydantic_v2_dataclass_allow_population_by_field_name_target_2_11
that calls generate with the same parameters but adds
target_pydantic_version="2.11" (keep input_ and output_file setup identical) and
asserts the generated output matches the expected fixture (use a new fixture
file name such as pydantic_v2_dataclass_populate_by_name_p2_11.py or reuse
appropriate expected content). This will exercise the version-specific config
mapping path in generate and protect the 2.11 branch.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9955314 and fd65a6a.

📒 Files selected for processing (3)
  • src/datamodel_code_generator/model/pydantic_v2/dataclass.py
  • tests/data/expected/main/jsonschema/pydantic_v2_dataclass_populate_by_name.py
  • tests/main/jsonschema/test_main_jsonschema.py

@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 2, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (9955314) to head (4080c70).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##              main     #3013   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           94        94           
  Lines        18130     18152   +22     
  Branches      2099      2101    +2     
=========================================
+ Hits         18130     18152   +22     
Flag Coverage Δ
unittests 100.00% <100.00%> (ø)

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.

@koxudaxi koxudaxi merged commit bff6a30 into koxudaxi:main Mar 3, 2026
38 checks passed
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 3, 2026

Breaking Change Analysis

Result: No breaking changes detected

Reasoning: This PR is a bug fix, not a breaking change. The --allow-population-by-field-name flag was documented to add populate_by_name configuration to generated output, but it was silently ignored for pydantic_v2.dataclass output. This PR fixes that bug so the flag now works as documented and intended. Users who passed this flag expected the behavior that is now correctly implemented. No defaults changed, no API changed, no templates need updating - the flag simply now works correctly instead of being silently ignored.


This analysis was performed by Claude Code Action

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 4, 2026

🎉 Released in 0.54.1

This PR is now available in the latest release. See the release notes for details.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

allow-population-by-field-name doesn't work for dataclasses

2 participants