wyfo / apischema

JSON (de)serialization, GraphQL and JSON schema generation using Python typing.

Home Page:https://wyfo.github.io/apischema/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

GraphQL Any type return value no longer mapped to JSON in 0.17

thomascobb opened this issue · comments

The following code:

from dataclasses import dataclass
from typing import Any, Optional

from apischema import serialize
from apischema.graphql import graphql_schema
from graphql import print_schema

@dataclass
class Foo:
    bar: str
    foo: Optional["Foo"]

def serialize_foo(foo: Foo) -> Any:
    return serialize(foo)

def test_schema():
    schema = graphql_schema(query=[serialize_foo])
    assert (
        print_schema(schema)
        == """\
type Query {
  serializeFoo(foo: FooInput!): JSON!
}

scalar JSON @specifiedBy(url: "http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf")

input FooInput {
  bar: String!
  foo: FooInput
}
"""
    )

used to work in 0.16.6, but fails in 0.17.0:

Traceback (most recent call last):
  File "/home/tom/Programming/scanspec/tests/test_graphql_any.py", line 20, in test_schema
    schema = graphql_schema(query=[serialize_foo])
  File "/home/tom/.local/share/virtualenvs/scanspec-L6XIN2FT/lib/python3.9/site-packages/apischema/utils.py", line 397, in wrapper
    return wrapped(*args, **kwargs)
  File "/home/tom/.local/share/virtualenvs/scanspec-L6XIN2FT/lib/python3.9/site-packages/apischema/graphql/schema.py", line 1033, in graphql_schema
    query=root_type("Query", query_fields),
  File "/home/tom/.local/share/virtualenvs/scanspec-L6XIN2FT/lib/python3.9/site-packages/apischema/graphql/schema.py", line 1030, in root_type
    return output_builder.object(tp, (), fields).merge(type_name, None).raw_type  # type: ignore
  File "/home/tom/.local/share/virtualenvs/scanspec-L6XIN2FT/lib/python3.9/site-packages/apischema/graphql/schema.py", line 225, in wrapper
    factory = method(self, *args, **kwargs)
  File "/home/tom/.local/share/virtualenvs/scanspec-L6XIN2FT/lib/python3.9/site-packages/apischema/graphql/schema.py", line 759, in object
    self._resolver(tp, resolver_field),
  File "/home/tom/.local/share/virtualenvs/scanspec-L6XIN2FT/lib/python3.9/site-packages/apischema/graphql/schema.py", line 640, in _resolver
    resolver_resolve(
  File "/home/tom/.local/share/virtualenvs/scanspec-L6XIN2FT/lib/python3.9/site-packages/apischema/graphql/resolvers.py", line 307, in resolver_resolve
    serialize_result = method_factory(types["return"]).serialize
  File "/home/tom/.local/share/virtualenvs/scanspec-L6XIN2FT/lib/python3.9/site-packages/apischema/graphql/resolvers.py", line 108, in factory
    return PartialSerializationMethodVisitor(
  File "/home/tom/.local/share/virtualenvs/scanspec-L6XIN2FT/lib/python3.9/site-packages/apischema/conversions/visitor.py", line 96, in visit_with_conv
    return self.visit(tp)
  File "/home/tom/.local/share/virtualenvs/scanspec-L6XIN2FT/lib/python3.9/site-packages/apischema/graphql/resolvers.py", line 97, in visit
    return METHODS[NoneType] if tp is UndefinedType else super().visit(tp)
  File "/home/tom/.local/share/virtualenvs/scanspec-L6XIN2FT/lib/python3.9/site-packages/apischema/recursion.py", line 175, in visit
    return super().visit(tp)
  File "/home/tom/.local/share/virtualenvs/scanspec-L6XIN2FT/lib/python3.9/site-packages/apischema/conversions/visitor.py", line 122, in visit
    return self.visit_conversion(tp, None, False, self._conversion)
  File "/home/tom/.local/share/virtualenvs/scanspec-L6XIN2FT/lib/python3.9/site-packages/apischema/serialization/__init__.py", line 509, in visit_conversion
    return super().visit_conversion(tp, conversion, dynamic, next_conversion)
  File "/home/tom/.local/share/virtualenvs/scanspec-L6XIN2FT/lib/python3.9/site-packages/apischema/conversions/visitor.py", line 118, in visit_conversion
    return super().visit(tp)
  File "/home/tom/.local/share/virtualenvs/scanspec-L6XIN2FT/lib/python3.9/site-packages/apischema/visitor.py", line 185, in visit
    return self.any()
  File "/home/tom/.local/share/virtualenvs/scanspec-L6XIN2FT/lib/python3.9/site-packages/apischema/serialization/__init__.py", line 278, in any
    return AnyMethod(self._factory)
  File "/home/tom/.local/share/virtualenvs/scanspec-L6XIN2FT/lib/python3.9/site-packages/apischema/graphql/resolvers.py", line 88, in _factory
    raise NotImplementedError
NotImplementedError

Is this expected?

Indeed, this is a regression. I will fix it and release a patch tonight.