Skip to content

feat: add field_args property to Info - #4484

Open
rcybulski1122012 wants to merge 8 commits into
strawberry-graphql:mainfrom
rcybulski1122012:info-field-args
Open

feat: add field_args property to Info#4484
rcybulski1122012 wants to merge 8 commits into
strawberry-graphql:mainfrom
rcybulski1122012:info-field-args

Conversation

@rcybulski1122012

@rcybulski1122012 rcybulski1122012 commented Jun 26, 2026

Copy link
Copy Markdown
Member

Description

Adds Info.field_args, a cached property returning the current field's arguments converted to strawberry types — the same values a resolver receives (coerced scalars, input dataclasses, Maybe/UNSET sentinels). This lets extensions, permission classes, and generic field logic that only have Info access those values without re-implementing argument conversion.

@strawberry.field
def search(self, info: strawberry.Info, filter: Filter) -> str:
    info.field_args  # {"filter": Filter(name="...", limit=...)}

Handles literals and variables, nested inputs, and lists; omitted args stay UNSET.

Types of Changes

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

Issues Fixed or Closed by This PR

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

Add a cached field_args property on Info that exposes the current field's arguments in their converted Strawberry types and document and test its behavior.

New Features:

  • Expose Info.field_args to access the current field's arguments as already-coerced Strawberry types, including scalars and input objects.

Documentation:

  • Document the new Info.field_args property in the resolvers Info reference table.

Tests:

  • Add comprehensive tests covering Info.field_args for scalars, input objects, nested inputs, lists, Maybe/UNSET handling, and variable-based arguments.

Chores:

  • Add a release note entry describing the new Info.field_args feature as a minor release change.

@github-actions

github-actions Bot commented Jun 26, 2026

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 adds Info.field_args, a cached property that returns the arguments
passed to the current field, already converted to Strawberry types. Scalars are
coerced and input types are converted to their proper dataclasses, mirroring the
values a resolver receives. Both inline literals and variables are handled, and
arguments that were not provided are omitted.

This release was contributed by @rcybulski1122012 in #4484

@rcybulski1122012

Copy link
Copy Markdown
Member Author

I wanted to add this method to my custom Info class but I've got problems with typing - with strawberry_django.field prefetch_related argument and resolve_id inherited from relay.Node.

@rcybulski1122012
rcybulski1122012 marked this pull request as draft June 26, 2026 12:23

@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 found 2 issues, and left some high level feedback:

  • In Info.field_args, get_field_def can return None (e.g. for introspection or invalid fields), so it would be safer to guard against this and either return an empty dict or raise a clearer error rather than unconditionally passing it to get_argument_values.
  • field_args currently uses raw_info.field_nodes[0]; if there are multiple field nodes for the same field (e.g. via fragments), consider either documenting that only the first node is used or merging arguments across all nodes to avoid surprising behavior.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `Info.field_args`, `get_field_def` can return `None` (e.g. for introspection or invalid fields), so it would be safer to guard against this and either return an empty dict or raise a clearer error rather than unconditionally passing it to `get_argument_values`.
- `field_args` currently uses `raw_info.field_nodes[0]`; if there are multiple field nodes for the same field (e.g. via fragments), consider either documenting that only the first node is used or merging arguments across all nodes to avoid surprising behavior.

## Individual Comments

### Comment 1
<location path="strawberry/types/info.py" line_range="111-114" />
<code_context>

+    @cached_property
+    def field_args(self) -> dict[str, Any]:
+        """The arguments passed to the current field, converted to strawberry types.
+
+        Scalars are coerced and input types are converted to their proper
+        dataclasses, mirroring the values a resolver receives. Arguments that
+        were not provided are omitted.
+        """
</code_context>
<issue_to_address>
**suggestion:** Clarify behavior regarding defaulted vs explicitly provided arguments

`get_argument_values` typically includes parameters that weren’t explicitly provided but have default values. If `convert_arguments` keeps those, the actual behavior will differ from what’s described. Either filter out defaulted-but-not-provided arguments or update the docstring to clarify that defaulted arguments are included.
</issue_to_address>

### Comment 2
<location path="RELEASE.md" line_range="5-6" />
<code_context>
+---
+
+This release adds `Info.field_args`, a cached property that returns the arguments
+passed to the current field, already converted to strawberry types. Scalars are
+coerced and input types are converted to their proper dataclasses, mirroring the
+values a resolver receives. Both inline literals and variables are handled, and
</code_context>
<issue_to_address>
**nitpick (typo):** Consider capitalizing "Strawberry" here for consistency with the rest of the docs.

For example, the new `field_args` row in `resolvers.md` uses the capitalized phrase "Strawberry types", so it would be good to match that here.

```suggestion
This release adds `Info.field_args`, a cached property that returns the arguments
passed to the current field, already converted to Strawberry types. Scalars are
```
</issue_to_address>

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.

Comment thread strawberry/types/info.py Outdated
Comment thread RELEASE.md Outdated
rcybulski1122012 and others added 2 commits June 26, 2026 14:27
`get_field_def` is not importable from `graphql.execution.execute` on
graphql-core 3.3, breaking module import. Look the field up directly off
`parent_type.fields` instead, which works on both 3.2 and 3.3.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Guard against an unresolvable field definition (e.g. introspection
  fields) by returning an empty dict instead of failing.
- Clarify in the docstring that defaulted-but-not-provided arguments are
  included with their defaults, and that arguments are read from the
  first field node (identical across fragment selections).
- Capitalize "Strawberry" in RELEASE.md for consistency.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@greptile-apps

greptile-apps Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Adds Info.field_args, a cached_property on the Info dataclass that returns the current field's arguments converted to Strawberry types — mirroring exactly what a resolver receives (coerced scalars, input dataclasses, Maybe/UNSET sentinels).

  • Calls get_argument_values from graphql-core to resolve literals and variables from the first field node, then passes the result through the existing convert_arguments pipeline used by regular resolvers.
  • Includes an IS_GQL_33 shim that wraps the plain variable_values dict in a VariableValues object required by graphql-core 3.3's updated get_argument_values signature, with a guard for the case where it is already a VariableValues.
  • Returns {} when field_def cannot be resolved (e.g. introspection fields), preventing a crash from passing None to get_argument_values.

Confidence Score: 5/5

Safe to merge — the new property is additive, delegates to the existing and well-tested convert_arguments pipeline, and follows the established cached_property pattern already used by selected_fields.

The change adds a single read-only cached property that reuses existing conversion logic. The null guard on field_def, the graphql-core 3.3 compatibility shim, and the delegation to convert_arguments are all handled correctly. Tests cover scalars, nested inputs, lists, Maybe/UNSET, and both literal and variable argument paths.

No files require special attention.

Important Files Changed

Filename Overview
strawberry/types/info.py Adds field_args cached_property following the same pattern as selected_fields; correctly handles null field_def, IS_GQL_33 VariableValues wrapping, and delegates conversion to the existing convert_arguments pipeline.
tests/test_info.py Adds 10 integration tests covering scalars, input types, nested inputs, lists, Maybe/UNSET handling, and variable vs literal paths — good coverage of the stated use cases.
docs/types/resolvers.md Adds field_args row to the Info properties table with accurate type and description.
RELEASE.md Release note correctly declares a minor release and accurately describes the new Info.field_args property.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant Resolver/Extension
    participant Info
    participant graphql-core
    participant convert_arguments

    Resolver/Extension->>Info: access info.field_args
    Info->>Info: read _raw_info.field_nodes[0]
    Info->>Info: parent_type.fields.get(field_name)
    alt field_def is None (introspection)
        Info-->>Resolver/Extension: "return {}"
    end
    Info->>Info: IS_GQL_33? wrap variable_values in VariableValues
    Info->>graphql-core: get_argument_values(field_def, field_node, variable_values)
    graphql-core-->>Info: raw_args (camelCase keys, coerced values)
    Info->>convert_arguments: "value=raw_args, arguments=_field.arguments, config, scalar_registry"
    convert_arguments-->>Info: dict[python_name, strawberry_value]
    Info-->>Resolver/Extension: cached dict[str, Any]
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant Resolver/Extension
    participant Info
    participant graphql-core
    participant convert_arguments

    Resolver/Extension->>Info: access info.field_args
    Info->>Info: read _raw_info.field_nodes[0]
    Info->>Info: parent_type.fields.get(field_name)
    alt field_def is None (introspection)
        Info-->>Resolver/Extension: "return {}"
    end
    Info->>Info: IS_GQL_33? wrap variable_values in VariableValues
    Info->>graphql-core: get_argument_values(field_def, field_node, variable_values)
    graphql-core-->>Info: raw_args (camelCase keys, coerced values)
    Info->>convert_arguments: "value=raw_args, arguments=_field.arguments, config, scalar_registry"
    convert_arguments-->>Info: dict[python_name, strawberry_value]
    Info-->>Resolver/Extension: cached dict[str, Any]
Loading

Reviews (2): Last reviewed commit: "fix: also silence pyright for 3.3-only V..." | Re-trigger Greptile

Comment thread strawberry/types/info.py
Comment thread strawberry/types/info.py
rcybulski1122012 and others added 3 commits June 26, 2026 14:42
graphql-core 3.3's `get_argument_values` expects a `VariableValues`
wrapper (with `.coerced`/`.sources`) rather than the plain dict that
strawberry's resolve info exposes, causing
"'dict' object has no attribute 'coerced'" for variable-based arguments.
Wrap the dict in `VariableValues` on 3.3 while leaving 3.2 unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The import is runtime-guarded by IS_GQL_33 but mypy checks against the
installed graphql-core 3.2, which lacks the symbol.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Match the codebase convention (see schema/_graphql_core.py) of pairing
type: ignore[attr-defined] with pyright: ignore[reportAttributeAccessIssue]
for version-specific graphql-core 3.3 imports.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@codspeed-hq

codspeed-hq Bot commented Jun 26, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 31 untouched benchmarks


Comparing rcybulski1122012:info-field-args (f7495d8) with main (13865ee)1

Open in CodSpeed

Footnotes

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

@rcybulski1122012
rcybulski1122012 marked this pull request as ready for review June 27, 2026 13:40

@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 reviewed your changes and they look great!


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.

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