strawberry-graphql / strawberry

A GraphQL library for Python that leverages type annotations 🍓
https://strawberry.rocks
MIT License
3.84k stars 510 forks source link

`field: None = strawberry.field()` results in `UnresolvedFieldTypeError: Could not resolve the type of ...` error #3493

Open huonw opened 1 month ago

huonw commented 1 month ago

Describe the Bug

Using None as an annotation directly (not None | Something, just None) on a data class-style field with strawberry.field() doesn't work. Various other similar incantations do work.

import strawberry

@strawberry.type
class Query:
    working1: "None" = strawberry.field() # deferred
    working2: None # no strawberry.field
    @strawberry.field # method
    def working3(self) -> None: return None 

    # BUG:
    broken: None = strawberry.field()

schema = strawberry.Schema(Query)
Traceback (most recent call last):
  File "/lib/python311.zip/_pyodide/_base.py", line 573, in eval_code_async
    await CodeRunner(
  File "/lib/python311.zip/_pyodide/_base.py", line 395, in run_async
    await coroutine
  File "<exec>", line 21, in <module>
  File "/lib/python3.11/site-packages/strawberry/schema/schema.py", line 162, in __init__
    raise error.__cause__ from None
  File "/lib/python3.11/site-packages/graphql/type/definition.py", line 808, in fields
    fields = resolve_thunk(self._fields)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/lib/python3.11/site-packages/graphql/type/definition.py", line 300, in resolve_thunk
    return thunk() if callable(thunk) else thunk
           ^^^^^^^
  File "/lib/python3.11/site-packages/strawberry/schema/schema_converter.py", line 525, in <lambda>
    fields=lambda: self.get_graphql_fields(object_type),
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/lib/python3.11/site-packages/strawberry/schema/schema_converter.py", line 382, in get_graphql_fields
    return _get_thunk_mapping(
           ^^^^^^^^^^^^^^^^^^^
  File "/lib/python3.11/site-packages/strawberry/schema/schema_converter.py", line 132, in _get_thunk_mapping
    raise UnresolvedFieldTypeError(type_definition, field)
strawberry.exceptions.unresolved_field_type.UnresolvedFieldTypeError: Could not resolve the type of 'broken'. Check that the class is accessible from the global module scope.

If I comment out broken, then strawberry accepts this code, and the resulting schema is what I expect ✅

type Query {
  working1: Void
  working2: Void
  working3: Void
}

"""Represents NULL values"""
scalar Void

(The fact that "None" works means that it also works to run with from __future__ import annotations to have all annotations be deferred strings.)

System Information

Additional Context

This annotation is weird but is meaningful/semi-useful (for historical reasons, we have an input type that has no real fields, so we have _unused: None = strawberry.field(default=None) instead.

Upvote & Fund

Fund with Polar

brunodantas commented 1 month ago

I suppose this is because None is an object instead of a type. NoneType seems to work:

https://play.strawberry.rocks/?gist=a3f099e36521e55d71d6c178b2364ee9