mirror of
				https://github.com/graphql-python/graphene-django.git
				synced 2025-11-04 18:08:01 +03:00 
			
		
		
		
	Fix remaining graphene 3.0 and graphql 3.0 compatiblity
* names must be strings * update to expected schemas to new format * Call get() on django promises to get the actual value
This commit is contained in:
		
							parent
							
								
									84ae00f803
								
							
						
					
					
						commit
						eb46f0da0a
					
				| 
						 | 
				
			
			@ -3,11 +3,14 @@ from functools import singledispatch
 | 
			
		|||
 | 
			
		||||
from django.db import models
 | 
			
		||||
from django.utils.encoding import force_str
 | 
			
		||||
from django.utils.functional import Promise
 | 
			
		||||
from django.utils.module_loading import import_string
 | 
			
		||||
 | 
			
		||||
from graphene import (
 | 
			
		||||
    ID,
 | 
			
		||||
    UUID,
 | 
			
		||||
    Boolean,
 | 
			
		||||
    Date,
 | 
			
		||||
    DateTime,
 | 
			
		||||
    Dynamic,
 | 
			
		||||
    Enum,
 | 
			
		||||
    Field,
 | 
			
		||||
| 
						 | 
				
			
			@ -16,18 +19,16 @@ from graphene import (
 | 
			
		|||
    List,
 | 
			
		||||
    NonNull,
 | 
			
		||||
    String,
 | 
			
		||||
    UUID,
 | 
			
		||||
    DateTime,
 | 
			
		||||
    Date,
 | 
			
		||||
    Time,
 | 
			
		||||
)
 | 
			
		||||
from graphene.types.json import JSONString
 | 
			
		||||
from graphene.utils.str_converters import to_camel_case, to_const
 | 
			
		||||
from graphql import assert_valid_name, GraphQLError
 | 
			
		||||
from graphql import GraphQLError, assert_valid_name
 | 
			
		||||
from graphql.pyutils import register_description
 | 
			
		||||
 | 
			
		||||
from .settings import graphene_settings
 | 
			
		||||
from .compat import ArrayField, HStoreField, JSONField, RangeField
 | 
			
		||||
from .fields import DjangoListField, DjangoConnectionField
 | 
			
		||||
from .fields import DjangoConnectionField, DjangoListField
 | 
			
		||||
from .settings import graphene_settings
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def convert_choice_name(name):
 | 
			
		||||
| 
						 | 
				
			
			@ -66,7 +67,7 @@ def convert_choices_to_named_enum_with_descriptions(name, choices):
 | 
			
		|||
    class EnumWithDescriptionsType(object):
 | 
			
		||||
        @property
 | 
			
		||||
        def description(self):
 | 
			
		||||
            return named_choices_descriptions[self.name]
 | 
			
		||||
            return str(named_choices_descriptions[self.name])
 | 
			
		||||
 | 
			
		||||
    return Enum(name, list(named_choices), type=EnumWithDescriptionsType)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -278,3 +279,8 @@ def convert_postgres_range_to_string(field, registry=None):
 | 
			
		|||
    if not isinstance(inner_type, (List, NonNull)):
 | 
			
		||||
        inner_type = type(inner_type)
 | 
			
		||||
    return List(inner_type, description=field.help_text, required=not field.null)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Register Django lazy()-wrapped values as GraphQL description/help_text.
 | 
			
		||||
# This is needed for using lazy translations, see https://github.com/graphql-python/graphql-core-next/issues/58.
 | 
			
		||||
register_description(Promise)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,7 +17,7 @@ class DjangoDebugContext(object):
 | 
			
		|||
        if not self.debug_promise:
 | 
			
		||||
            self.debug_promise = Promise.all(self.promises)
 | 
			
		||||
            self.promises = []
 | 
			
		||||
        return self.debug_promise.then(self.on_resolve_all_promises)
 | 
			
		||||
        return self.debug_promise.then(self.on_resolve_all_promises).get()
 | 
			
		||||
 | 
			
		||||
    def on_resolve_all_promises(self, values):
 | 
			
		||||
        if self.promises:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,7 +5,8 @@ from graphql_relay.connection.arrayconnection import connection_from_array_slice
 | 
			
		|||
from promise import Promise
 | 
			
		||||
 | 
			
		||||
from graphene import NonNull
 | 
			
		||||
from graphene.relay import ConnectionField, PageInfo
 | 
			
		||||
from graphene.relay import ConnectionField
 | 
			
		||||
from graphene.relay.connection import connection_adapter, page_info_adapter
 | 
			
		||||
from graphene.types import Field, List
 | 
			
		||||
 | 
			
		||||
from .settings import graphene_settings
 | 
			
		||||
| 
						 | 
				
			
			@ -126,11 +127,11 @@ class DjangoConnectionField(ConnectionField):
 | 
			
		|||
            iterable,
 | 
			
		||||
            args,
 | 
			
		||||
            slice_start=0,
 | 
			
		||||
            connection_type=connection,
 | 
			
		||||
            array_length=_len,
 | 
			
		||||
            array_slice_length=_len,
 | 
			
		||||
            connection_type=partial(connection_adapter, connection),
 | 
			
		||||
            edge_type=connection.Edge,
 | 
			
		||||
            page_info_type=PageInfo,
 | 
			
		||||
            page_info_type=page_info_adapter,
 | 
			
		||||
        )
 | 
			
		||||
        connection.iterable = iterable
 | 
			
		||||
        connection.length = _len
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -806,38 +806,56 @@ def test_integer_field_filter_type():
 | 
			
		|||
 | 
			
		||||
    assert str(schema) == dedent(
 | 
			
		||||
        """\
 | 
			
		||||
        schema {
 | 
			
		||||
          query: Query
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        interface Node {
 | 
			
		||||
          id: ID!
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type PageInfo {
 | 
			
		||||
          hasNextPage: Boolean!
 | 
			
		||||
          hasPreviousPage: Boolean!
 | 
			
		||||
          startCursor: String
 | 
			
		||||
          endCursor: String
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type PetType implements Node {
 | 
			
		||||
          age: Int!
 | 
			
		||||
          id: ID!
 | 
			
		||||
        type Query {
 | 
			
		||||
          pets(before: String = null, after: String = null, first: Int = null, last: Int = null, age: Int = null): PetTypeConnection
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type PetTypeConnection {
 | 
			
		||||
          \"""Pagination data for this connection.\"""
 | 
			
		||||
          pageInfo: PageInfo!
 | 
			
		||||
 | 
			
		||||
          \"""Contains the nodes in this connection.\"""
 | 
			
		||||
          edges: [PetTypeEdge]!
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        \"""
 | 
			
		||||
        The Relay compliant `PageInfo` type, containing data necessary to paginate this connection.
 | 
			
		||||
        \"""
 | 
			
		||||
        type PageInfo {
 | 
			
		||||
          \"""When paginating forwards, are there more items?\"""
 | 
			
		||||
          hasNextPage: Boolean!
 | 
			
		||||
    
 | 
			
		||||
          \"""When paginating backwards, are there more items?\"""
 | 
			
		||||
          hasPreviousPage: Boolean!
 | 
			
		||||
    
 | 
			
		||||
          \"""When paginating backwards, the cursor to continue.\"""
 | 
			
		||||
          startCursor: String
 | 
			
		||||
    
 | 
			
		||||
          \"""When paginating forwards, the cursor to continue.\"""
 | 
			
		||||
          endCursor: String
 | 
			
		||||
        }
 | 
			
		||||
    
 | 
			
		||||
        \"""A Relay edge containing a `PetType` and its cursor.\"""
 | 
			
		||||
        type PetTypeEdge {
 | 
			
		||||
          \"""The item at the end of the edge\"""
 | 
			
		||||
          node: PetType
 | 
			
		||||
    
 | 
			
		||||
          \"""A cursor for use in pagination\"""
 | 
			
		||||
          cursor: String!
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type Query {
 | 
			
		||||
          pets(before: String, after: String, first: Int, last: Int, age: Int): PetTypeConnection
 | 
			
		||||
    
 | 
			
		||||
        type PetType implements Node {
 | 
			
		||||
          \"""\"""
 | 
			
		||||
          age: Int!
 | 
			
		||||
    
 | 
			
		||||
          \"""The ID of the object\"""
 | 
			
		||||
          id: ID!
 | 
			
		||||
        }
 | 
			
		||||
    
 | 
			
		||||
        \"""An object with an ID\"""
 | 
			
		||||
        interface Node {
 | 
			
		||||
          \"""The ID of the object\"""
 | 
			
		||||
          id: ID!
 | 
			
		||||
        }
 | 
			
		||||
    """
 | 
			
		||||
    )
 | 
			
		||||
| 
						 | 
				
			
			@ -858,40 +876,58 @@ def test_other_filter_types():
 | 
			
		|||
 | 
			
		||||
    assert str(schema) == dedent(
 | 
			
		||||
        """\
 | 
			
		||||
        schema {
 | 
			
		||||
          query: Query
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        interface Node {
 | 
			
		||||
          id: ID!
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type PageInfo {
 | 
			
		||||
          hasNextPage: Boolean!
 | 
			
		||||
          hasPreviousPage: Boolean!
 | 
			
		||||
          startCursor: String
 | 
			
		||||
          endCursor: String
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type PetType implements Node {
 | 
			
		||||
          age: Int!
 | 
			
		||||
          id: ID!
 | 
			
		||||
        type Query {
 | 
			
		||||
          pets(before: String = null, after: String = null, first: Int = null, last: Int = null, age: Int = null, age_Isnull: Boolean = null, age_Lt: Int = null): PetTypeConnection
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type PetTypeConnection {
 | 
			
		||||
          \"""Pagination data for this connection.\"""
 | 
			
		||||
          pageInfo: PageInfo!
 | 
			
		||||
          
 | 
			
		||||
          \"""Contains the nodes in this connection.\"""
 | 
			
		||||
          edges: [PetTypeEdge]!
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        \"""
 | 
			
		||||
        The Relay compliant `PageInfo` type, containing data necessary to paginate this connection.
 | 
			
		||||
        \"""
 | 
			
		||||
        type PageInfo {
 | 
			
		||||
          \"""When paginating forwards, are there more items?\"""
 | 
			
		||||
          hasNextPage: Boolean!
 | 
			
		||||
 | 
			
		||||
          \"""When paginating backwards, are there more items?\"""
 | 
			
		||||
          hasPreviousPage: Boolean!
 | 
			
		||||
 | 
			
		||||
          \"""When paginating backwards, the cursor to continue.\"""
 | 
			
		||||
          startCursor: String
 | 
			
		||||
 | 
			
		||||
          \"""When paginating forwards, the cursor to continue.\"""
 | 
			
		||||
          endCursor: String
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        \"""A Relay edge containing a `PetType` and its cursor.\"""
 | 
			
		||||
        type PetTypeEdge {
 | 
			
		||||
          \"""The item at the end of the edge\"""
 | 
			
		||||
          node: PetType
 | 
			
		||||
        
 | 
			
		||||
          \"""A cursor for use in pagination\"""
 | 
			
		||||
          cursor: String!
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type Query {
 | 
			
		||||
          pets(before: String, after: String, first: Int, last: Int, age: Int, age_Isnull: Boolean, age_Lt: Int): PetTypeConnection
 | 
			
		||||
        type PetType implements Node {
 | 
			
		||||
          \"""\"""
 | 
			
		||||
          age: Int!
 | 
			
		||||
        
 | 
			
		||||
          \"""The ID of the object\"""
 | 
			
		||||
          id: ID!
 | 
			
		||||
        }
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
        \"""An object with an ID\"""
 | 
			
		||||
        interface Node {
 | 
			
		||||
          \"""The ID of the object\"""
 | 
			
		||||
          id: ID!
 | 
			
		||||
        }
 | 
			
		||||
        """
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -56,7 +56,7 @@ class Command(CommandArguments):
 | 
			
		|||
 | 
			
		||||
    def save_graphql_file(self, out, schema):
 | 
			
		||||
        with open(out, "w") as outfile:
 | 
			
		||||
            outfile.write(print_schema(schema))
 | 
			
		||||
            outfile.write(print_schema(schema.graphql_schema))
 | 
			
		||||
 | 
			
		||||
    def get_schema(self, schema, out, indent):
 | 
			
		||||
        schema_dict = {"data": schema.introspect()}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -51,10 +51,6 @@ def test_generate_graphql_file_on_call_graphql_schema():
 | 
			
		|||
    schema_output = handle.write.call_args[0][0]
 | 
			
		||||
    assert schema_output == dedent(
 | 
			
		||||
        """\
 | 
			
		||||
        schema {
 | 
			
		||||
          query: Query
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type Query {
 | 
			
		||||
          hi: String
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -713,7 +713,7 @@ def test_should_query_promise_connectionfields():
 | 
			
		|||
        all_reporters = DjangoConnectionField(ReporterType)
 | 
			
		||||
 | 
			
		||||
        def resolve_all_reporters(self, info, **args):
 | 
			
		||||
            return Promise.resolve([Reporter(id=1)])
 | 
			
		||||
            return Promise.resolve([Reporter(id=1)]).get()
 | 
			
		||||
 | 
			
		||||
    schema = graphene.Schema(query=Query)
 | 
			
		||||
    query = """
 | 
			
		||||
| 
						 | 
				
			
			@ -842,7 +842,7 @@ def test_should_query_dataloader_fields():
 | 
			
		|||
        articles = DjangoConnectionField(ArticleType)
 | 
			
		||||
 | 
			
		||||
        def resolve_articles(self, info, **args):
 | 
			
		||||
            return article_loader.load(self.id)
 | 
			
		||||
            return article_loader.load(self.id).get()
 | 
			
		||||
 | 
			
		||||
    class Query(graphene.ObjectType):
 | 
			
		||||
        all_reporters = DjangoConnectionField(ReporterType)
 | 
			
		||||
| 
						 | 
				
			
			@ -1075,7 +1075,7 @@ def test_should_preserve_prefetch_related(django_assert_num_queries):
 | 
			
		|||
    class Query(graphene.ObjectType):
 | 
			
		||||
        films = DjangoConnectionField(FilmType)
 | 
			
		||||
 | 
			
		||||
        def resolve_films(root, info, **args):
 | 
			
		||||
        def resolve_films(root, info, **kwargs):
 | 
			
		||||
            qs = Film.objects.prefetch_related("reporters")
 | 
			
		||||
            return qs
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1105,6 +1105,7 @@ def test_should_preserve_prefetch_related(django_assert_num_queries):
 | 
			
		|||
        }
 | 
			
		||||
    """
 | 
			
		||||
    schema = graphene.Schema(query=Query)
 | 
			
		||||
 | 
			
		||||
    with django_assert_num_queries(3) as captured:
 | 
			
		||||
        result = schema.execute(query)
 | 
			
		||||
        assert not result.errors
 | 
			
		||||
| 
						 | 
				
			
			@ -1127,7 +1128,7 @@ def test_should_preserve_annotations():
 | 
			
		|||
    class Query(graphene.ObjectType):
 | 
			
		||||
        films = DjangoConnectionField(FilmType)
 | 
			
		||||
 | 
			
		||||
        def resolve_films(root, info):
 | 
			
		||||
        def resolve_films(root, info, **kwargs):
 | 
			
		||||
            qs = Film.objects.prefetch_related("reporters")
 | 
			
		||||
            return qs.annotate(reporters_count=models.Count("reporters"))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -111,83 +111,165 @@ def test_django_objecttype_with_custom_meta():
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
def test_schema_representation():
 | 
			
		||||
    expected = """
 | 
			
		||||
schema {
 | 
			
		||||
  query: RootQuery
 | 
			
		||||
}
 | 
			
		||||
    expected = dedent(
 | 
			
		||||
        """\
 | 
			
		||||
        schema {
 | 
			
		||||
          query: RootQuery
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
type Article implements Node {
 | 
			
		||||
  id: ID!
 | 
			
		||||
  headline: String!
 | 
			
		||||
  pubDate: Date!
 | 
			
		||||
  pubDateTime: DateTime!
 | 
			
		||||
  reporter: Reporter!
 | 
			
		||||
  editor: Reporter!
 | 
			
		||||
  lang: ArticleLang!
 | 
			
		||||
  importance: ArticleImportance
 | 
			
		||||
}
 | 
			
		||||
        \"""Article description\"""
 | 
			
		||||
        type Article implements Node {
 | 
			
		||||
          \"""The ID of the object\"""
 | 
			
		||||
          id: ID!
 | 
			
		||||
 | 
			
		||||
type ArticleConnection {
 | 
			
		||||
  pageInfo: PageInfo!
 | 
			
		||||
  edges: [ArticleEdge]!
 | 
			
		||||
  test: String
 | 
			
		||||
}
 | 
			
		||||
          \"""\"""
 | 
			
		||||
          headline: String!
 | 
			
		||||
 | 
			
		||||
type ArticleEdge {
 | 
			
		||||
  node: Article
 | 
			
		||||
  cursor: String!
 | 
			
		||||
}
 | 
			
		||||
          \"""\"""
 | 
			
		||||
          pubDate: Date!
 | 
			
		||||
 | 
			
		||||
enum ArticleImportance {
 | 
			
		||||
  A_1
 | 
			
		||||
  A_2
 | 
			
		||||
}
 | 
			
		||||
          \"""\"""
 | 
			
		||||
          pubDateTime: DateTime!
 | 
			
		||||
 | 
			
		||||
enum ArticleLang {
 | 
			
		||||
  ES
 | 
			
		||||
  EN
 | 
			
		||||
}
 | 
			
		||||
          \"""\"""
 | 
			
		||||
          reporter: Reporter!
 | 
			
		||||
 | 
			
		||||
scalar Date
 | 
			
		||||
          \"""\"""
 | 
			
		||||
          editor: Reporter!
 | 
			
		||||
 | 
			
		||||
scalar DateTime
 | 
			
		||||
          \"""Language\"""
 | 
			
		||||
          lang: ArticleLang!
 | 
			
		||||
 | 
			
		||||
interface Node {
 | 
			
		||||
  id: ID!
 | 
			
		||||
}
 | 
			
		||||
          \"""\"""
 | 
			
		||||
          importance: ArticleImportance
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
type PageInfo {
 | 
			
		||||
  hasNextPage: Boolean!
 | 
			
		||||
  hasPreviousPage: Boolean!
 | 
			
		||||
  startCursor: String
 | 
			
		||||
  endCursor: String
 | 
			
		||||
}
 | 
			
		||||
        \"""An object with an ID\"""
 | 
			
		||||
        interface Node {
 | 
			
		||||
          \"""The ID of the object\"""
 | 
			
		||||
          id: ID!
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
type Reporter {
 | 
			
		||||
  id: ID!
 | 
			
		||||
  firstName: String!
 | 
			
		||||
  lastName: String!
 | 
			
		||||
  email: String!
 | 
			
		||||
  pets: [Reporter!]!
 | 
			
		||||
  aChoice: ReporterAChoice
 | 
			
		||||
  reporterType: ReporterReporterType
 | 
			
		||||
  articles(before: String, after: String, first: Int, last: Int): ArticleConnection!
 | 
			
		||||
}
 | 
			
		||||
        \"""
 | 
			
		||||
        The `Date` scalar type represents a Date
 | 
			
		||||
        value as specified by
 | 
			
		||||
        [iso8601](https://en.wikipedia.org/wiki/ISO_8601).
 | 
			
		||||
        \"""
 | 
			
		||||
        scalar Date
 | 
			
		||||
 | 
			
		||||
enum ReporterAChoice {
 | 
			
		||||
  A_1
 | 
			
		||||
  A_2
 | 
			
		||||
}
 | 
			
		||||
        \"""
 | 
			
		||||
        The `DateTime` scalar type represents a DateTime
 | 
			
		||||
        value as specified by
 | 
			
		||||
        [iso8601](https://en.wikipedia.org/wiki/ISO_8601).
 | 
			
		||||
        \"""
 | 
			
		||||
        scalar DateTime
 | 
			
		||||
 | 
			
		||||
enum ReporterReporterType {
 | 
			
		||||
  A_1
 | 
			
		||||
  A_2
 | 
			
		||||
}
 | 
			
		||||
        \"""An enumeration.\"""
 | 
			
		||||
        enum ArticleLang {
 | 
			
		||||
          \"""Spanish\"""
 | 
			
		||||
          ES
 | 
			
		||||
 | 
			
		||||
type RootQuery {
 | 
			
		||||
  node(id: ID!): Node
 | 
			
		||||
}
 | 
			
		||||
""".lstrip()
 | 
			
		||||
          \"""English\"""
 | 
			
		||||
          EN
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        \"""An enumeration.\"""
 | 
			
		||||
        enum ArticleImportance {
 | 
			
		||||
          \"""Very important\"""
 | 
			
		||||
          A_1
 | 
			
		||||
 | 
			
		||||
          \"""Not as important\"""
 | 
			
		||||
          A_2
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        \"""Reporter description\"""
 | 
			
		||||
        type Reporter {
 | 
			
		||||
          \"""\"""
 | 
			
		||||
          id: ID!
 | 
			
		||||
 | 
			
		||||
          \"""\"""
 | 
			
		||||
          firstName: String!
 | 
			
		||||
 | 
			
		||||
          \"""\"""
 | 
			
		||||
          lastName: String!
 | 
			
		||||
 | 
			
		||||
          \"""\"""
 | 
			
		||||
          email: String!
 | 
			
		||||
 | 
			
		||||
          \"""\"""
 | 
			
		||||
          pets: [Reporter!]!
 | 
			
		||||
 | 
			
		||||
          \"""\"""
 | 
			
		||||
          aChoice: ReporterAChoice
 | 
			
		||||
 | 
			
		||||
          \"""\"""
 | 
			
		||||
          reporterType: ReporterReporterType
 | 
			
		||||
 | 
			
		||||
          \"""\"""
 | 
			
		||||
          articles(before: String = null, after: String = null, first: Int = null, last: Int = null): ArticleConnection!
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        \"""An enumeration.\"""
 | 
			
		||||
        enum ReporterAChoice {
 | 
			
		||||
          \"""this\"""
 | 
			
		||||
          A_1
 | 
			
		||||
 | 
			
		||||
          \"""that\"""
 | 
			
		||||
          A_2
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        \"""An enumeration.\"""
 | 
			
		||||
        enum ReporterReporterType {
 | 
			
		||||
          \"""Regular\"""
 | 
			
		||||
          A_1
 | 
			
		||||
 | 
			
		||||
          \"""CNN Reporter\"""
 | 
			
		||||
          A_2
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type ArticleConnection {
 | 
			
		||||
          \"""Pagination data for this connection.\"""
 | 
			
		||||
          pageInfo: PageInfo!
 | 
			
		||||
 | 
			
		||||
          \"""Contains the nodes in this connection.\"""
 | 
			
		||||
          edges: [ArticleEdge]!
 | 
			
		||||
          test: String
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        \"""
 | 
			
		||||
        The Relay compliant `PageInfo` type, containing data necessary to paginate this connection.
 | 
			
		||||
        \"""
 | 
			
		||||
        type PageInfo {
 | 
			
		||||
          \"""When paginating forwards, are there more items?\"""
 | 
			
		||||
          hasNextPage: Boolean!
 | 
			
		||||
 | 
			
		||||
          \"""When paginating backwards, are there more items?\"""
 | 
			
		||||
          hasPreviousPage: Boolean!
 | 
			
		||||
 | 
			
		||||
          \"""When paginating backwards, the cursor to continue.\"""
 | 
			
		||||
          startCursor: String
 | 
			
		||||
 | 
			
		||||
          \"""When paginating forwards, the cursor to continue.\"""
 | 
			
		||||
          endCursor: String
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        \"""A Relay edge containing a `Article` and its cursor.\"""
 | 
			
		||||
        type ArticleEdge {
 | 
			
		||||
          \"""The item at the end of the edge\"""
 | 
			
		||||
          node: Article
 | 
			
		||||
 | 
			
		||||
          \"""A cursor for use in pagination\"""
 | 
			
		||||
          cursor: String!
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        type RootQuery {
 | 
			
		||||
          node(
 | 
			
		||||
            \"""The ID of the object\"""
 | 
			
		||||
            id: ID!
 | 
			
		||||
          ): Node
 | 
			
		||||
        }
 | 
			
		||||
        """
 | 
			
		||||
    )
 | 
			
		||||
    assert str(schema) == expected
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -415,20 +497,21 @@ class TestDjangoObjectType:
 | 
			
		|||
 | 
			
		||||
        assert str(schema) == dedent(
 | 
			
		||||
            """\
 | 
			
		||||
        schema {
 | 
			
		||||
          query: Query
 | 
			
		||||
        }
 | 
			
		||||
            type Query {
 | 
			
		||||
              pet: Pet
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        type Pet {
 | 
			
		||||
          id: ID!
 | 
			
		||||
          kind: String!
 | 
			
		||||
          cuteness: Int!
 | 
			
		||||
        }
 | 
			
		||||
            type Pet {
 | 
			
		||||
              \"""\"""
 | 
			
		||||
              id: ID!
 | 
			
		||||
 | 
			
		||||
        type Query {
 | 
			
		||||
          pet: Pet
 | 
			
		||||
        }
 | 
			
		||||
        """
 | 
			
		||||
              \"""\"""
 | 
			
		||||
              kind: String!
 | 
			
		||||
 | 
			
		||||
              \"""\"""
 | 
			
		||||
              cuteness: Int!
 | 
			
		||||
            }
 | 
			
		||||
            """
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def test_django_objecttype_convert_choices_enum_list(self, PetModel):
 | 
			
		||||
| 
						 | 
				
			
			@ -444,25 +527,30 @@ class TestDjangoObjectType:
 | 
			
		|||
 | 
			
		||||
        assert str(schema) == dedent(
 | 
			
		||||
            """\
 | 
			
		||||
        schema {
 | 
			
		||||
          query: Query
 | 
			
		||||
        }
 | 
			
		||||
            type Query {
 | 
			
		||||
              pet: Pet
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        type Pet {
 | 
			
		||||
          id: ID!
 | 
			
		||||
          kind: PetModelKind!
 | 
			
		||||
          cuteness: Int!
 | 
			
		||||
        }
 | 
			
		||||
            type Pet {
 | 
			
		||||
              \"""\"""
 | 
			
		||||
              id: ID!
 | 
			
		||||
 | 
			
		||||
        enum PetModelKind {
 | 
			
		||||
          CAT
 | 
			
		||||
          DOG
 | 
			
		||||
        }
 | 
			
		||||
              \"""\"""
 | 
			
		||||
              kind: PetModelKind!
 | 
			
		||||
 | 
			
		||||
        type Query {
 | 
			
		||||
          pet: Pet
 | 
			
		||||
        }
 | 
			
		||||
        """
 | 
			
		||||
              \"""\"""
 | 
			
		||||
              cuteness: Int!
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            \"""An enumeration.\"""
 | 
			
		||||
            enum PetModelKind {
 | 
			
		||||
              \"""Cat\"""
 | 
			
		||||
              CAT
 | 
			
		||||
 | 
			
		||||
              \"""Dog\"""
 | 
			
		||||
              DOG
 | 
			
		||||
            }
 | 
			
		||||
            """
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def test_django_objecttype_convert_choices_enum_empty_list(self, PetModel):
 | 
			
		||||
| 
						 | 
				
			
			@ -478,20 +566,21 @@ class TestDjangoObjectType:
 | 
			
		|||
 | 
			
		||||
        assert str(schema) == dedent(
 | 
			
		||||
            """\
 | 
			
		||||
        schema {
 | 
			
		||||
          query: Query
 | 
			
		||||
        }
 | 
			
		||||
            type Query {
 | 
			
		||||
              pet: Pet
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        type Pet {
 | 
			
		||||
          id: ID!
 | 
			
		||||
          kind: String!
 | 
			
		||||
          cuteness: Int!
 | 
			
		||||
        }
 | 
			
		||||
            type Pet {
 | 
			
		||||
              \"""\"""
 | 
			
		||||
              id: ID!
 | 
			
		||||
 | 
			
		||||
        type Query {
 | 
			
		||||
          pet: Pet
 | 
			
		||||
        }
 | 
			
		||||
        """
 | 
			
		||||
              \"""\"""
 | 
			
		||||
              kind: String!
 | 
			
		||||
 | 
			
		||||
              \"""\"""
 | 
			
		||||
              cuteness: Int!
 | 
			
		||||
            }
 | 
			
		||||
            """
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def test_django_objecttype_convert_choices_enum_naming_collisions(
 | 
			
		||||
| 
						 | 
				
			
			@ -511,24 +600,27 @@ class TestDjangoObjectType:
 | 
			
		|||
 | 
			
		||||
        assert str(schema) == dedent(
 | 
			
		||||
            """\
 | 
			
		||||
        schema {
 | 
			
		||||
          query: Query
 | 
			
		||||
        }
 | 
			
		||||
            type Query {
 | 
			
		||||
              pet: PetModelKind
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        type PetModelKind {
 | 
			
		||||
          id: ID!
 | 
			
		||||
          kind: TestsPetModelKindChoices!
 | 
			
		||||
        }
 | 
			
		||||
            type PetModelKind {
 | 
			
		||||
              \"""\"""
 | 
			
		||||
              id: ID!
 | 
			
		||||
 | 
			
		||||
        type Query {
 | 
			
		||||
          pet: PetModelKind
 | 
			
		||||
        }
 | 
			
		||||
              \"""\"""
 | 
			
		||||
              kind: TestsPetModelKindChoices!
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        enum TestsPetModelKindChoices {
 | 
			
		||||
          CAT
 | 
			
		||||
          DOG
 | 
			
		||||
        }
 | 
			
		||||
        """
 | 
			
		||||
            \"""An enumeration.\"""
 | 
			
		||||
            enum TestsPetModelKindChoices {
 | 
			
		||||
              \"""Cat\"""
 | 
			
		||||
              CAT
 | 
			
		||||
 | 
			
		||||
              \"""Dog\"""
 | 
			
		||||
              DOG
 | 
			
		||||
            }
 | 
			
		||||
            """
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def test_django_objecttype_choices_custom_enum_name(
 | 
			
		||||
| 
						 | 
				
			
			@ -550,22 +642,25 @@ class TestDjangoObjectType:
 | 
			
		|||
 | 
			
		||||
        assert str(schema) == dedent(
 | 
			
		||||
            """\
 | 
			
		||||
        schema {
 | 
			
		||||
          query: Query
 | 
			
		||||
        }
 | 
			
		||||
            type Query {
 | 
			
		||||
              pet: PetModelKind
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        enum CustomEnumKind {
 | 
			
		||||
          CAT
 | 
			
		||||
          DOG
 | 
			
		||||
        }
 | 
			
		||||
            type PetModelKind {
 | 
			
		||||
              \"""\"""
 | 
			
		||||
              id: ID!
 | 
			
		||||
 | 
			
		||||
        type PetModelKind {
 | 
			
		||||
          id: ID!
 | 
			
		||||
          kind: CustomEnumKind!
 | 
			
		||||
        }
 | 
			
		||||
              \"""\"""
 | 
			
		||||
              kind: CustomEnumKind!
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        type Query {
 | 
			
		||||
          pet: PetModelKind
 | 
			
		||||
        }
 | 
			
		||||
        """
 | 
			
		||||
            \"""An enumeration.\"""
 | 
			
		||||
            enum CustomEnumKind {
 | 
			
		||||
              \"""Cat\"""
 | 
			
		||||
              CAT
 | 
			
		||||
 | 
			
		||||
              \"""Dog\"""
 | 
			
		||||
              DOG
 | 
			
		||||
            }
 | 
			
		||||
            """
 | 
			
		||||
        )
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -92,9 +92,6 @@ def test_allows_get_with_operation_name(client):
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.xfail(
 | 
			
		||||
    reason="SourceLocation serialization problem: https://github.com/graphql-python/graphql-core-next/issues/61"
 | 
			
		||||
)
 | 
			
		||||
def test_reports_validation_errors(client):
 | 
			
		||||
    response = client.get(url_string(query="{ test, unknownOne, unknownTwo }"))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -129,8 +126,8 @@ def test_errors_when_missing_operation_name(client):
 | 
			
		|||
    assert response_json(response) == {
 | 
			
		||||
        "errors": [
 | 
			
		||||
            {
 | 
			
		||||
                "locations": None,
 | 
			
		||||
                "message": "Must provide operation name if query contains multiple operations.",
 | 
			
		||||
                "locations": None,
 | 
			
		||||
                "path": None,
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
| 
						 | 
				
			
			@ -449,9 +446,6 @@ def test_supports_pretty_printing_by_request(client):
 | 
			
		|||
    )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.xfail(
 | 
			
		||||
    reason="SourceLocation serialization problem: https://github.com/graphql-python/graphql-core-next/issues/61"
 | 
			
		||||
)
 | 
			
		||||
def test_handles_field_errors_caught_by_graphql(client):
 | 
			
		||||
    response = client.get(url_string(query="{thrower}"))
 | 
			
		||||
    assert response.status_code == 200
 | 
			
		||||
| 
						 | 
				
			
			@ -467,9 +461,6 @@ def test_handles_field_errors_caught_by_graphql(client):
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.mark.xfail(
 | 
			
		||||
    reason="SourceLocation serialization problem: https://github.com/graphql-python/graphql-core-next/issues/61"
 | 
			
		||||
)
 | 
			
		||||
def test_handles_syntax_errors_caught_by_graphql(client):
 | 
			
		||||
    response = client.get(url_string(query="syntaxerror"))
 | 
			
		||||
    assert response.status_code == 400
 | 
			
		||||
| 
						 | 
				
			
			@ -477,8 +468,8 @@ def test_handles_syntax_errors_caught_by_graphql(client):
 | 
			
		|||
        "errors": [
 | 
			
		||||
            {
 | 
			
		||||
                "locations": [{"column": 1, "line": 1}],
 | 
			
		||||
                "message": "Syntax Error GraphQL (1:1) "
 | 
			
		||||
                'Unexpected Name "syntaxerror"\n\n1: syntaxerror\n   ^\n',
 | 
			
		||||
                "message": "Syntax Error: Unexpected Name 'syntaxerror'.",
 | 
			
		||||
                "path": None,
 | 
			
		||||
            }
 | 
			
		||||
        ]
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,11 +8,10 @@ from django.shortcuts import render
 | 
			
		|||
from django.utils.decorators import method_decorator
 | 
			
		||||
from django.views.decorators.csrf import ensure_csrf_cookie
 | 
			
		||||
from django.views.generic import View
 | 
			
		||||
from graphql import OperationType, execute, get_operation_ast, parse, validate
 | 
			
		||||
from graphql import OperationType, get_operation_ast, parse, validate
 | 
			
		||||
from graphql.error import GraphQLError
 | 
			
		||||
from graphql.error import format_error as format_graphql_error
 | 
			
		||||
from graphql.execution import ExecutionResult
 | 
			
		||||
from graphql.type.schema import GraphQLSchema
 | 
			
		||||
 | 
			
		||||
from graphene import Schema
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -259,9 +258,8 @@ class GraphQLView(View):
 | 
			
		|||
        if validation_errors:
 | 
			
		||||
            return ExecutionResult(data=None, errors=validation_errors)
 | 
			
		||||
 | 
			
		||||
        return execute(
 | 
			
		||||
            schema=self.schema.graphql_schema,
 | 
			
		||||
            document=document,
 | 
			
		||||
        return self.schema.execute(
 | 
			
		||||
            source=query,
 | 
			
		||||
            root_value=self.get_root_value(request),
 | 
			
		||||
            variable_values=variables,
 | 
			
		||||
            operation_name=operation_name,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user