Skip to content
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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix info by adding a custom __class_getitem__ #3419

Merged
merged 5 commits into from
Mar 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions RELEASE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
Release type: patch

This release properly allows passing one argument to the `Info` class.

This is now fully supported:

```python
import strawberry

from typing import TypedDict


class Context(TypedDict):
user_id: str


@strawberry.type
class Query:
@strawberry.field
def info(self, info: strawberry.Info[Context]) -> str:
return info.context["user_id"]
```
16 changes: 16 additions & 0 deletions strawberry/types/info.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
Generic,
List,
Optional,
Tuple,
Type,
Union,
)
Expand Down Expand Up @@ -38,6 +39,21 @@ class Info(Generic[ContextType, RootValueType]):
_raw_info: GraphQLResolveInfo
_field: StrawberryField

def __class_getitem__(cls, types: Union[type, Tuple[type, ...]]) -> Type[Info]:
patrick91 marked this conversation as resolved.
Show resolved Hide resolved
"""Workaround for when passing only one type.

Python doesn't yet support directly passing only one type to a generic class
that has typevars with defaults. This is a workaround for that.

See:
https://discuss.python.org/t/passing-only-one-typevar-of-two-when-using-defaults/49134
"""

if not isinstance(types, tuple):
types = (types, Any) # type: ignore

return super().__class_getitem__(types) # type: ignore

@property
def field_name(self) -> str:
return self._raw_info.field_name
Expand Down
25 changes: 25 additions & 0 deletions tests/test_info.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from typing import Any
Copy link
Contributor

Choose a reason for hiding this comment

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

suggestion (testing): Consider adding a test case for error conditions.

It would be beneficial to include a test case that verifies the behavior when invalid types are passed to strawberry.Info. This could help ensure that the custom __class_getitem__ method handles error conditions gracefully.

Copy link
Contributor

Choose a reason for hiding this comment

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

suggestion (testing): Add a test case for using strawberry.Info without any arguments.

Including a test case for strawberry.Info invoked without any arguments could verify that the default behavior aligns with expectations. This scenario seems to be missing and could be an important edge case.

Copy link
Contributor

Choose a reason for hiding this comment

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

praise (testing): Praise for covering both one and two argument use cases.

The inclusion of tests for both one and two argument scenarios for strawberry.Info is commendable. It ensures that the functionality works as expected in these common use cases.


import pytest

import strawberry


def test_can_use_info_with_two_arguments():
CustomInfo = strawberry.Info[int, str]

assert CustomInfo.__args__ == (int, str)


def test_can_use_info_with_one_argument():
CustomInfo = strawberry.Info[int]

assert CustomInfo.__args__ == (int, Any)


def test_cannot_use_info_with_more_than_two_arguments():
with pytest.raises(
TypeError,
match="Too many (arguments|parameters) for <class '.*.Info'>; actual 3, expected 2",
):
strawberry.Info[int, str, int] # type: ignore
Loading