<commit_before>import copy

from graphql.parser import GraphQLParser
from django_graph_api.graphql.types import (
    CharField,
    ManyRelatedField,
    Object,
    OBJECT,
    RelatedField,
)


class FieldObject(Object):
    # self.data will be an item from a declared fields dict
    object_name = '__Field'
    name = CharField()
    description = CharField()
    type = RelatedField(lambda: TypeObject)

    def get_name(self):
        return self.data[0]

    def get_description(self):
        return getattr(self.data[1], 'description', None)

    def get_type(self):
        return self.data[1].type_


class TypeObject(Object):
    # self.data will be an object or scalar
    object_name = '__Type'
    kind = CharField()
    name = CharField()
    description = CharField()
    fields = ManyRelatedField(FieldObject)

    def get_name(self):
        return getattr(self.data, 'object_name', self.data.__name__)

    def get_fields(self):
        if self.data.kind != OBJECT:
            return None
        return self.data._declared_fields.items()


class SchemaObject(Object):
    # self.data will be the query_root.
    object_name = '__Schema'
    types = ManyRelatedField(TypeObject)
    queryType = RelatedField(TypeObject)
    mutationType = RelatedField(TypeObject)

    def _collect_types(self, object_type, types=None):
        if types is None:
            types = set()
        for field in object_type._declared_fields.values():
            if isinstance(field, RelatedField):
                new_object_type = field.resolve_object_type(field.object_type)
                if new_object_type == 'self':
                    continue
                if new_object_type in types:
                    continue
                types.add(new_object_type)
                self._collect_types(new_object_type, types)
            elif field.type_:
                types.add(field.type_)
        return types

    def get_types(self):
        return list(self._collect_types(self.data))

    def get_queryType(self):
        return self.data

    def get_mutationType(self):
        return None


class Schema(object):
    """
    Required for a GraphQL API.

    A schema is a set of nodes and edges with at least one query root to access the rest of
    the schema.<commit_msg>Made sorting of types and fields deterministic<commit_after>import copy

from graphql.parser import GraphQLParser
from django_graph_api.graphql.types import (
    CharField,
    ManyRelatedField,
    Object,
    OBJECT,
    RelatedField,
)


class FieldObject(Object):
    # self.data will be an item from a declared fields dict
    object_name = '__Field'
    name = CharField()
    description = CharField()
    type = RelatedField(lambda: TypeObject)

    def get_name(self):
        return self.data[0]

    def get_description(self):
        return getattr(self.data[1], 'description', None)

    def get_type(self):
        return self.data[1].type_


class TypeObject(Object):
    # self.data will be an object or scalar
    object_name = '__Type'
    kind = CharField()
    name = CharField()
    description = CharField()
    fields = ManyRelatedField(FieldObject)

    def get_name(self):
        return getattr(self.data, 'object_name', self.data.__name__)

    def get_fields(self):
        if self.data.kind != OBJECT:
            return None
        # return self.data._declared_fields.items()
        return sorted(
            self.data._declared_fields.items(),
            key=lambda item: item[0],
        )


class SchemaObject(Object):
    # self.data will be the query_root.
    object_name = '__Schema'
    types = ManyRelatedField(TypeObject)
    queryType = RelatedField(TypeObject)
    mutationType = RelatedField(TypeObject)

    def _collect_types(self, object_type, types=None):
        if types is None:
            types = set()
        for field in object_type._declared_fields.values():
            if isinstance(field, RelatedField):
                new_object_type = field.resolve_object_type(field.object_type)
                if new_object_type == 'self':
                    continue
                if new_object_type in types:
                    continue
                types.add(new_object_type)
                self._collect_types(new_object_type, types)
            elif field.type_:
                types.add(field.type_)
        return types

    def _type_key(self, type_):
        object_name = getattr(type_, 'object_name', type_.__name__)
        return (
            object_name.startswith('__'),
            type_.kind,
            object_name,
        )

    def get_types(self):
        types = self._collect_types(self.data)
        return sorted(types, key=self._type_key)

    def get_queryType(self):
        return self.data

    def get_mutationType(self):
        return None


class Schema(object):
    """
    Required for a GraphQL API.

    A schema is a set of nodes and edges with at least one query root to access the rest of
    the schema.
{'fraction_non_alphanumeric': 0.0825504697181691, 'fraction_numerical': 0.0013991605036977814, 'mean_word_length': 2.3742414025623737, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7130282', 'n_tokens_mistral': 1452, 'n_tokens_neox': 1393, 'n_words': 375}