Skip to content

Commit

Permalink
fix: preserve extra annotations when resolving auto/lazy fields (#2983)
Browse files Browse the repository at this point in the history
Fix a typo which made extra `Annotated` arguments to be discarded by mistake when resolving auto/lazy fields.
  • Loading branch information
bellini666 authored Jul 26, 2023
1 parent 557f5fa commit 5bd4102
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 3 deletions.
5 changes: 5 additions & 0 deletions RELEASE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Release type: patch

This release fixes an issue where annotations resolution for auto and lazy fields
using `Annotated` where not preserving the remaining arguments because of a
typo in the arguments filtering.
9 changes: 9 additions & 0 deletions strawberry/lazy_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,15 @@ def __init__(self, module: str) -> None:
def resolve_forward_ref(self, forward_ref: ForwardRef) -> LazyType:
return LazyType(forward_ref.__forward_arg__, self.module, self.package)

def __eq__(self, other: object) -> bool:
if not isinstance(other, StrawberryLazyReference):
return NotImplemented

return self.module == other.module and self.package == other.package

def __hash__(self) -> int:
return hash((self.__class__, self.module, self.package))


def lazy(module_path: str) -> StrawberryLazyReference:
return StrawberryLazyReference(module_path)
6 changes: 3 additions & 3 deletions strawberry/utils/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ def _get_namespace_from_ast(
# here to resolve lazy types by execing the annotated args, resolving the
# type directly and then adding it to extra namespace, so that _eval_type
# can properly resolve it later
type_name = args[0]
type_name = args[0].strip()
for arg in args[1:]:
evaled_arg = eval(arg, globalns, localns) # noqa: PGH001, S307
if isinstance(evaled_arg, StrawberryLazyReference):
Expand Down Expand Up @@ -348,7 +348,7 @@ def eval_type(
remaining_args = [
a
for a in args[1:]
if not isinstance(arg, StrawberryLazyReference)
if not isinstance(a, StrawberryLazyReference)
]
type_arg = (
arg.resolve_forward_ref(args[0])
Expand All @@ -359,7 +359,7 @@ def eval_type(
break
if isinstance(arg, StrawberryAuto):
remaining_args = [
a for a in args[1:] if not isinstance(arg, StrawberryAuto)
a for a in args[1:] if not isinstance(a, StrawberryAuto)
]
args = (arg, *remaining_args)
break
Expand Down
23 changes: 23 additions & 0 deletions tests/utils/test_typing.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
import typing
from typing import ClassVar, ForwardRef, Optional, Union
from typing_extensions import Annotated

import strawberry
from strawberry.lazy_type import LazyType
from strawberry.utils.typing import eval_type, get_optional_annotation, is_classvar


@strawberry.type
class Fruit:
...


def test_get_optional_annotation():
# Pair Union
assert get_optional_annotation(Optional[Union[str, bool]]) == Union[str, bool]
Expand Down Expand Up @@ -33,6 +41,21 @@ class Foo:
eval_type(ForwardRef("Optional[Union[Foo, str]]"), globals(), locals())
== Union[Foo, str, None]
)
assert (
eval_type(ForwardRef("Annotated[str, 'foobar']"), globals(), locals())
is Annotated[str, "foobar"]
)
assert (
eval_type(
ForwardRef("Annotated[Fruit, strawberry.lazy('tests.utils.test_typing')]"),
{"strawberry": strawberry, "Annotated": Annotated},
None,
)
== Annotated[
LazyType("Fruit", "tests.utils.test_typing"),
strawberry.lazy("tests.utils.test_typing"),
]
)


def test_is_classvar():
Expand Down

0 comments on commit 5bd4102

Please sign in to comment.