Skip to content

fix(codegen): keep GraphQL field names that don't survive camel-casing - #4551

Open
ritsth wants to merge 2 commits into
strawberry-graphql:mainfrom
ritsth:fix/codegen-field-name-roundtrip
Open

fix(codegen): keep GraphQL field names that don't survive camel-casing#4551
ritsth wants to merge 2 commits into
strawberry-graphql:mainfrom
ritsth:fix/codegen-field-name-roundtrip

Conversation

@ritsth

@ritsth ritsth commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Description

schema-codegen generated code that produces a different schema than the SDL it
was given. Strawberry derives a field's GraphQL name by camel-casing its Python
name, but codegen only added an explicit name= alias for Python keywords. Any
name that isn't reproduced by camel-casing was silently renamed:

SDL in Schema produced by generated code
some_field: Int someField: Int
allowCustomExportURL: Boolean! allowCustomExportUrl: Boolean!
URL: String url: String

Additionally, two GraphQL names converting to the same Python name (e.g.
someField and some_field) produced a duplicate attribute, silently dropping
one field.

Codegen now adds an alias whenever camel-casing wouldn't give the original name
back, and makes colliding Python names unique.

Note: this updates test_converts_names_to_snake_case, which asserted the
previous (incorrect) output for allowCustomExportURL / allowInsecureTLS
those generated allowCustomExportUrl / allowInsecureTls in the resulting
schema.

Types of Changes

  • Core
  • Bugfix
  • New feature
  • Enhancement/optimization
  • Documentation

Issues Fixed or Closed by This PR

  • N/A

Checklist

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • I have tested the changes and verified that they work and don't break anything (as well as I can manage).

Summary by Sourcery

Ensure schema codegen preserves original GraphQL field names and avoids silently dropping fields when names collide after conversion to Python identifiers.

Bug Fixes:

  • Prevent schema codegen from silently renaming GraphQL fields whose names are not reproduced by camel-casing their Python counterparts.
  • Avoid losing fields when multiple GraphQL names convert to the same Python attribute name by generating unique Python names.

Documentation:

  • Add a release note describing the schema codegen bug with camel-cased field names and the fix for preserving original GraphQL names.

Tests:

  • Update existing name-conversion test to assert the corrected generated schema for fields with acronyms and add new tests covering non-camel-case GraphQL names and colliding name conversions.

@github-actions

Copy link
Copy Markdown
Contributor

Thanks for adding the RELEASE.md file!

Below is the changelog that will be used for the release.


This release fixes schema codegen silently renaming fields whose GraphQL names
are not reproduced by camel-casing.

Strawberry derives the GraphQL name of a field by camel-casing its Python name,
so generating some_field from a GraphQL field named some_field produced a
schema exposing someField instead. The same happened to names containing
acronyms, such as allowCustomExportURL, which came back as
allowCustomExportUrl.

Codegen now adds an explicit alias whenever camel-casing would not give the
original name back:

@strawberry.type
class Example:
    some_field: int | None = strawberry.field(name="some_field")
    allow_custom_export_url: bool = strawberry.field(name="allowCustomExportURL")

Fields whose GraphQL names convert to the same Python name (for example
someField and some_field) are also no longer silently dropped.

This release was contributed by @ritsth in #4551

@greptile-apps

greptile-apps Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR preserves original GraphQL field names during SDL-to-Python schema generation.

  • Adds explicit field aliases when camel-casing a generated Python name would change the GraphQL name.
  • Assigns unique Python attribute names when fields in the same GraphQL definition normalize to the same snake-case name.
  • Adds regression tests for acronym, underscore, uppercase, keyword, and collision cases.
  • Documents the fix as a patch release.

Confidence Score: 5/5

The PR appears safe to merge, with no actionable defects identified in the changed behavior.

The generated fields retain distinct Python attributes while explicit aliases preserve their distinct original GraphQL names, and the added tests cover the principal naming transformations addressed by the fix.

Important Files Changed

Filename Overview
strawberry/schema_codegen/init.py Adds per-definition Python-name collision handling and aliases fields whose original GraphQL names cannot be recovered through camel-casing.
tests/schema_codegen/test_names.py Updates acronym expectations and adds focused coverage for preserved GraphQL names and colliding generated Python attributes.
RELEASE.md Clearly documents the schema-codegen naming defect and corrected generated output.

Reviews (1): Last reviewed commit: "fix(codegen): keep GraphQL field names t..." | Re-trigger Greptile

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hey - I've left some high level feedback:

  • The new test_handles_names_converting_to_the_same_python_name builds an expected string but never asserts against codegen(schema), so the test currently doesn't validate behavior and should add an assertion similar to the other tests.
  • The collision-handling logic that repeatedly appends underscores to name in _get_field would benefit from being factored into a small helper (e.g. make_unique_name(name, used_names)) to make the intent clearer and easier to reuse or adjust.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new `test_handles_names_converting_to_the_same_python_name` builds an `expected` string but never asserts against `codegen(schema)`, so the test currently doesn't validate behavior and should add an assertion similar to the other tests.
- The collision-handling logic that repeatedly appends underscores to `name` in `_get_field` would benefit from being factored into a small helper (e.g. `make_unique_name(name, used_names)`) to make the intent clearer and easier to reuse or adjust.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@codspeed-hq

codspeed-hq Bot commented Jul 27, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 34 untouched benchmarks


Comparing ritsth:fix/codegen-field-name-roundtrip (b9e5e62) with main (3ba583f)1

Open in CodSpeed

Footnotes

  1. No successful run was found on main (34e9707) during the generation of this report, so 3ba583f was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

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