Skip to content

Rename a msgspec field named "field" to avoid shadowing the field import#3615

Open
chuenchen309 wants to merge 1 commit into
koxudaxi:mainfrom
chuenchen309:fix/msgspec-field-name-shadow
Open

Rename a msgspec field named "field" to avoid shadowing the field import#3615
chuenchen309 wants to merge 1 commit into
koxudaxi:mainfrom
chuenchen309:fix/msgspec-field-name-shadow

Conversation

@chuenchen309

@chuenchen309 chuenchen309 commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

A schema property named field generates a msgspec Struct whose class body shadows the from msgspec import field used for other fields' field(...) calls, so the generated module can't even be imported:

# input: {"field": {...array...}, "other-name": {...}}  →  --output-model-type msgspec.Struct
class M(Struct):
    field: list[str] | UnsetType = field(default_factory=list)   # shadows the import
    other_name: str | UnsetType = field(name='other-name', default='x')
# TypeError: 'msgspec._core.Field' object is not callable

A property named field is common (form/validation payloads, {field, message} error objects), so this is easy to hit via the public API and the CLI.

msgspec routed field names through the base resolver, which never renames anything; only pydantic had a reserved-name-aware resolver. This adds a MsgspecFieldNameResolver (mirroring PydanticFieldNameResolver) that renames a field property to field_ with a name="field" alias — the wire name is preserved and the generated module imports and round-trips. Added a regression test that generates and imports the model.

Scope: I kept this to the msgspec field case that crashes. The pydantic-v2 Field import is the same class of issue but a wider change (Field is used pervasively) — happy to handle it in a follow-up, or here if you'd prefer.


Disclosure: this PR was authored by an AI coding agent (Claude Code) running on this account — it found the shadowing, reproduced the failed import, wrote the fix and the test, and wrote this description. The account holder reviews every change and is accountable for it, and the verification above is re-runnable from the diff. Happy to close it if it isn't the kind of contribution you want.

Summary by CodeRabbit

  • Bug Fixes

    • Improved generated msgspec models when schemas contain a field named field.
    • Prevented generated attributes from shadowing msgspec’s field helper, while preserving the original schema field name.
  • Tests

    • Added coverage confirming generated msgspec code is valid and can be imported successfully.

msgspec models emit `from msgspec import ... field` and call `field(...)` for
aliases, defaults, etc. A schema property named "field" was rendered as a
class attribute `field`, shadowing that import, so any later `field(...)` call
raised `TypeError: 'msgspec._core.Field' object is not callable` and the
generated module could not be imported.

Add a msgspec-specific field-name resolver (mirroring the Pydantic one) that
renames a "field" property to `field_` with a `name="field"` alias, and route
msgspec Structs to it via field_name_model_type. Adds a regression test that
generates and imports the model.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: e6c2ef81-28b2-4f2e-ab6f-c2ce48064ab9

📥 Commits

Reviewing files that changed from the base of the PR and between af435d9 and b6b19d4.

⛔ Files ignored due to path filters (1)
  • tests/data/jsonschema/msgspec_reserved_field_name.json is excluded by !tests/data/**/*.json and included by none
📒 Files selected for processing (4)
  • src/datamodel_code_generator/parser/base.py
  • src/datamodel_code_generator/reference.py
  • tests/data/expected/main/jsonschema/msgspec_reserved_field_name.py
  • tests/main/jsonschema/test_main_jsonschema.py

📝 Walkthrough

Walkthrough

Msgspec Struct models now use a dedicated field-name strategy that prevents generated identifiers from shadowing msgspec.field. A JSON Schema integration test verifies aliases, defaults, output parity, and generated-module execution.

Changes

Msgspec field resolution

Layer / File(s) Summary
Msgspec resolver strategy
src/datamodel_code_generator/parser/base.py, src/datamodel_code_generator/reference.py
The parser classifies msgspec.Struct models as ModelType.MSGSPEC, which selects a resolver that rejects the identifier field.
Reserved field generation validation
tests/data/expected/main/jsonschema/msgspec_reserved_field_name.py, tests/main/jsonschema/test_main_jsonschema.py
The new fixture and end-to-end test verify that field is generated as field_, retains its JSON name, preserves defaults, and produces an importable Payload module.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: koxudaxi

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 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 msgspec field rename to avoid shadowing the imported field symbol.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@codspeed-hq

codspeed-hq Bot commented Jul 19, 2026

Copy link
Copy Markdown

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.

✅ 13 untouched benchmarks
⏩ 98 skipped benchmarks1


Comparing chuenchen309:fix/msgspec-field-name-shadow (b6b19d4) with main (af435d9)

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.

@codecov

codecov Bot commented Jul 19, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (af435d9) to head (b6b19d4).

Additional details and impacted files
@@            Coverage Diff            @@
##              main     #3615   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files          165       165           
  Lines        36372     36380    +8     
  Branches      4199      4200    +1     
=========================================
+ Hits         36372     36380    +8     
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 Harness.
📢 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.

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.

1 participant