Skip to content

feat(parent): Support strawberry.Parent with future annotations #3851

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 10, 2025

Conversation

bellini666
Copy link
Member

@bellini666 bellini666 commented May 10, 2025

Fix #3481

This also makes #3714 not required

Summary by Sourcery

Add support for using strawberry.Parent with future annotations and delayed type evaluation

New Features:

  • Support using strawberry.Parent with forward references and future annotations

Enhancements:

  • Improve type resolution for Parent types in different annotation scenarios

Tests:

  • Add test cases for Parent type with future annotations and string-based type references

Chores:

  • Add a release note explaining the new Parent type annotation support

Copy link
Contributor

sourcery-ai bot commented May 10, 2025

Reviewer's Guide

This pull request enables strawberry.Parent to work with future annotations (both from __future__ import annotations and string literals like "User"). This is primarily achieved by introducing resolve_parent_forward_arg in strawberry/parent.py to parse and correctly reconstruct Parent types using ForwardRef internally when a string or ForwardRef is detected as its argument. Consequently, eval_type in strawberry/utils/typing.py was updated to handle StrawberryParent instances, and the field resolver logic in strawberry/types/fields/resolver.py was modified to use the new parsing function to correctly identify Parent types with forward references. Error handling for NameError during argument type evaluation in strawberry/types/field.py was also improved to accommodate unevaluated forward references.

File-Level Changes

Change Details Files
Implemented support for future annotations in strawberry.Parent.
  • Introduced resolve_parent_forward_arg function to parse string/ForwardRef arguments within Parent annotations and re-wrap them with ForwardRef.
  • Updated eval_type to correctly process and evaluate StrawberryParent instances.
  • Modified field resolver to use resolve_parent_forward_arg for identifying Parent types with forward-referenced arguments.
strawberry/parent.py
strawberry/utils/typing.py
strawberry/types/fields/resolver.py
Enhanced robustness of field argument type evaluation.
  • Added NameError handling during argument type access to support forward references.
strawberry/types/field.py
Added comprehensive tests for the new strawberry.Parent functionality.
  • Created test suite for strawberry.Parent with from __future__ import annotations.
  • Created test suite for strawberry.Parent with string literal type hints.
tests/types/test_parent_type_future_annotations.py
tests/types/test_parent_type.py
Added release notes for the feature.
  • Documented the support for strawberry.Parent with future annotations.
RELEASE.md

Assessment against linked issues

Issue Objective Addressed Explanation
#3481 Enable strawberry.Parent to work with forward references, allowing type hints to refer to types that are not yet defined.
#3481 Update documentation to reflect the correct usage of strawberry.Parent with function resolvers, specifically addressing the NameError encountered when using forward references.

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@bellini666 bellini666 requested a review from patrick91 May 10, 2025 13:19
Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

PR Summary

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here: https://app.greptile.com/review/github.

💡 (3/5) Reply to the bot's comments like "Can you suggest a fix for this @greptileai?" or ask follow-up questions!

7 file(s) reviewed, no comment(s)
Edit PR Review Bot Settings | Greptile

@bellini666 bellini666 requested a review from Copilot May 10, 2025 13:19
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR introduces support for using strawberry.Parent with future annotations, addressing a previously reported issue and simplifying related annotation handling.

  • Added tests for both direct and string-based forward references using strawberry.Parent.
  • Updated type evaluation and resolver logic to gracefully handle strawberry.Parent types.
  • Introduced a new helper function resolve_parent_forward_arg in strawberry/parent.py.

Reviewed Changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.

Show a summary per file
File Description
tests/types/test_parent_type_future_annotations.py Adds a test using future annotations with strawberry.Parent (e.g. Parent[User]).
tests/types/test_parent_type.py Adds a test using string-based forward references with strawberry.Parent (e.g. Parent["User"]).
strawberry/utils/typing.py Updates eval_type to handle StrawberryParent types by checking for instances and adjusting args.
strawberry/types/fields/resolver.py Modifies forward reference evaluation to use resolve_parent_forward_arg when a NameError occurs.
strawberry/types/field.py Refactors argument type evaluation to catch NameError and skip forward references.
strawberry/parent.py Adds the helper function resolve_parent_forward_arg to support parsing strawberry.Parent annotations.
RELEASE.md Updates release notes detailing support for strawberry.Parent with both future annotations and delayed evaluation.

@bellini666 bellini666 force-pushed the parent-forward-refs branch from 6e2d70a to e75995b Compare May 10, 2025 13:20
@botberry
Copy link
Member

botberry commented May 10, 2025

Thanks for adding the RELEASE.md file!

Here's a preview of the changelog:


This release adds support to use strawberry.Parent with future annotations.

For example, the following code will now work as intended:

from __future__ import annotations


def get_full_name(user: strawberry.Parent[User]) -> str:
    return f"{user.first_name} {user.last_name}"


@strawberry.type
class User:
    first_name: str
    last_name: str
    full_name: str = strawberry.field(resolver=get_full_name)


@strawberry.type
class Query:
    @strawberry.field
    def user(self) -> User:
        return User(first_name="John", last_name="Doe")


schema = strawberry.Schema(query=Query)

Or even when not using future annotations, but delaying the evaluation of User, like:

# Note the User being delayed by passing it as a string
def get_full_name(user: strawberry.Parent["User"]) -> str:
    return f"{user.first_name} {user.last_name}"


@strawberry.type
class User:
    first_name: str
    last_name: str
    full_name: str = strawberry.field(resolver=get_full_name)


@strawberry.type
class Query:
    @strawberry.field
    def user(self) -> User:
        return User(first_name="John", last_name="Doe")


schema = strawberry.Schema(query=Query)

Here's the tweet text:

🆕 Release (next) is out! Thanks to @_bellini666 for the PR 👏

Get it here 👉 https://strawberry.rocks/release/(next)

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

We encountered an error and are unable to review this PR. We have been notified and are working to fix it.

You can try again by commenting this pull request with @sourcery-ai review, or contact us for help.

Copy link

codecov bot commented May 10, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 95.05%. Comparing base (f6ac9bb) to head (81d9e36).
Report is 5 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff            @@
##             main    #3851    +/-   ##
========================================
  Coverage   95.04%   95.05%            
========================================
  Files         502      507     +5     
  Lines       32719    32931   +212     
  Branches     1696     1710    +14     
========================================
+ Hits        31098    31302   +204     
- Misses       1348     1355     +7     
- Partials      273      274     +1     
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@bellini666 bellini666 force-pushed the parent-forward-refs branch from e75995b to b497961 Compare May 10, 2025 13:25
Copy link

codspeed-hq bot commented May 10, 2025

CodSpeed Performance Report

Merging #3851 will not alter performance

Comparing parent-forward-refs (81d9e36) with main (68d694e)

Summary

✅ 21 untouched benchmarks

@bellini666 bellini666 force-pushed the parent-forward-refs branch from b497961 to d2abf06 Compare May 10, 2025 13:48
@bellini666 bellini666 merged commit 0a217e8 into main May 10, 2025
103 checks passed
@bellini666 bellini666 deleted the parent-forward-refs branch May 10, 2025 15:34
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.

strawberry.Parent not supporting forward refs
3 participants