Skip to content

Add input clean methods - #4554

Open
Speedy1991 wants to merge 3 commits into
strawberry-graphql:mainfrom
Speedy1991:fix-4552
Open

Add input clean methods#4554
Speedy1991 wants to merge 3 commits into
strawberry-graphql:mainfrom
Speedy1991:fix-4552

Conversation

@Speedy1991

@Speedy1991 Speedy1991 commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Description

Adds opt-in clean(info) methods for Strawberry input types. Clean methods run after input coercion and before field extensions and resolver execution. They support both synchronous and asynchronous implementations, receive the resolver Info, and process nested inputs before their containing input.

Also adds documentation for synchronous normalization, async request-scoped DataLoader hydration, and nested input validation.

Types of Changes

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

Issues Fixed or Closed by This PR

Fixes #4552

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

Introduce lifecycle clean hooks for input objects that run between input coercion and resolver execution.

New Features:

  • Allow input object types to define synchronous or asynchronous clean methods that receive resolver Info and run before resolvers and field extensions.
  • Support nested input clean execution in child-before-parent order, including for collections and Maybe values.

Build:

  • Add a release note entry describing the new input clean lifecycle hooks.

Documentation:

  • Document how to use input clean methods for synchronous normalization, async DataLoader hydration, and nested input validation.

Tests:

  • Add tests covering clean method ordering, async behavior, error handling, DataLoader integration, and mutation field ordering.

@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 adds lifecycle hooks for input objects.

Input objects can now define a synchronous or asynchronous clean method that
receives the resolver Info object after GraphQL input coercion and before
resolver execution.

This release was contributed by @Speedy1991 in #4554

Comment on lines 1019 to +1024
# explicitly to the extensions
field_kwargs.pop("info")

input_clean_methods = run_input_clean_methods(
[*field_args, *field_kwargs.values()], info
)

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.

P1 Argument mapping skips input cleaning

When a field extension such as InputMutationExtension unwraps the containing input in map_arguments, this code traverses only the already-transformed arguments, causing the containing input object's clean method to be skipped.

Knowledge Base Used: Schema Core: Building a GraphQL Schema from Python Types

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Meh, I wasn't aware of this extension. 😅
This is going to make things a lot more complicated, @patrick91.

@greptile-apps

greptile-apps Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Adds opt-in synchronous and asynchronous lifecycle hooks for Strawberry input objects.

  • Traverses nested coerced inputs in child-before-parent order.
  • Runs hooks before resolver execution and supports request-scoped asynchronous loading.
  • Documents normalization, DataLoader hydration, and nested validation.
  • Adds execution-order, error-handling, asynchronous, and mutation-order tests.

Confidence Score: 3/5

This PR should not merge until clean hooks are scheduled before argument-mapping extensions so extensions cannot cause the containing input hook to be skipped.

The new call site traverses arguments only after extension mapping, and the existing input-mutation extension explicitly removes the containing input object at that earlier stage.

Files Needing Attention: strawberry/schema/schema_converter.py, tests/schema/test_input.py

Important Files Changed

Filename Overview
strawberry/schema/schema_converter.py Integrates clean-hook execution into field resolution, but schedules it after extension argument mapping can remove the input object.
strawberry/types/input.py Implements sequential child-before-parent traversal with synchronous fast-path and asynchronous continuation.
tests/schema/test_input.py Covers core ordering and async behavior but does not cover an argument-mapping extension that unwraps the containing input before cleaning.
docs/types/input-types.md Documents synchronous normalization, asynchronous request-scoped loading, and nested cleaning behavior.

Sequence Diagram

sequenceDiagram
    participant GQL as graphql-core
    participant Args as Argument conversion
    participant Ext as Field extensions
    participant Clean as Input clean hooks
    participant Resolver
    GQL->>Args: Coerce field arguments
    Args->>Ext: map_arguments(kwargs)
    Ext-->>Args: Transformed arguments
    Args->>Clean: Traverse remaining inputs
    Clean-->>Resolver: Invoke extension chain and resolver
Loading

Reviews (1): Last reviewed commit: "implement input clean methods" | 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 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.

@codspeed-hq

codspeed-hq Bot commented Jul 28, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 34 untouched benchmarks


Comparing Speedy1991:fix-4552 (f20d630) 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.

Add sync and async input lifecycle hooks with Info support

1 participant