strawberry.Parent
and type checkers / type safety
#3128
Replies: 2 comments 3 replies
-
Hi there! thanks for the great write up! 😊 In my head this was the recommended option: @strawberry.type
class Query:
@strawberry.field(graphql_type=User)
def user(self) -> UserRow:
return UserRow(id_="1234") but yes it is not type same unfortunately. I was thinking that maybe we could add support for protocols (if they don't work already), which could help a bit with type safety, but it really depends on what you're doing 😊 Regarding your suggestion: @dataclass
class UserRow:
id_: str
@dataclass
class NotAUserRow:
name: str
@strawberry.type
class User:
@strawberry.field
@staticmethod
async def name(parent: strawberry.Parent[UserRow]) -> str:
return f"User Number {parent.id_}"
@strawberry.field
@staticmethod
async def name2(parent: strawberry.Parent[NotAUserRow]) -> str:
return f"User Number {parent.name}" this would thrown an error/warning on name2, right? |
Beta Was this translation helpful? Give feedback.
-
Thanks for the quick reply!
Unless I am missing something, I am not entirely sure this solves the issue. Would the protocol be the parent type or the GraphQL type? From that example If @strawberry.type
class User(Protocol):
id_: str
@strawberry.field
@staticmethod
def name(parent: strawberry.Parent[User]) -> str:
return f"User Number {parent.id_}" then class UserProto(Protocol):
id_: str
@dataclass
class UserRow:
id_: str
@strawberry.type
class User(Protocol):
id_: str
@strawberry.field
@staticmethod
def name(parent: strawberry.Parent[UserProto]) -> str:
return f"User Number {parent.id_}"
@strawberry.type
class Query:
# UserProto isn't in play here.
@strawberry.field
def user(self) -> User:
return UserRow(id_="1234")
# Or:
@strawberry.field(graphql_type=User)
def user(self) -> UserProto:
return UserRow(id_="1234")
Yes this breaks but at runtime but only at query execution time ( To clarify: I think the main point for me is that if I need to rely on With the protocol as well I think the checking would still allow them so it should be possible to use a protocol for the |
Beta Was this translation helpful? Give feedback.
-
Version 0.208.0 introduced the
strawberry.Parent
annotation; however I am a bit confused with the expectations w.r.t. type safety so opening this to write down what I think is confusing and possibly discuss improvements.Taking the example in the docs as of today:
Using the latest versions of strawberry and mypy (configured with the plugin) this doesn't type check:
The comment in the docs act as a warning and roughly say "the type don't matter in practice"; however I am not sure it's clear enough that using
strawberry.Parent
as documented means giving up on the type checker for these fields.Is the intention that users disable type checking for these cases (e.g. with a
# type: ignore[return-value]
comment)? Or am I missing something in the API that would make this typecheck?I've started thinking about this a bit more and after reading the original discussion and PR I think a possible issue with the solution (as exposed in the docs) is that it conflates 2 concepts into one by expressing themn using a single piece of information.:
With that difference in mind, there's already a way to express these 2 things separately which actually works at runtime and doesn't change the API:
However it's not fully type safe as this also works (until it breaks at query execution time):
One approach could be to have
strawberry.field
validate that the return value is consistent with thestrawberry.Parent
? However that leads to a second issue:Is technically allowed and works (until it breaks at query execution time) although I assume is not the intended usage. Equally that's solvable by validating in
strawberry.type
that all parent annotations are consistent.So I reckon having these 2 checks (whether at schema definition time, in the mypy plugin, or both):
strawberry.Parent
usage must be consistent across a single typegraphql_type
's parent typewould allow maintaining the same API but in a way which type-checks properly while preserving the API and not relying on
type: ignore
.If there's agreement it's worth doping I'd be happy to take it on if it helps.
Beta Was this translation helpful? Give feedback.
All reactions