graphene/graphene/types/inputobjecttype.py
Mel van Londen 8e7d76bbce
Graphene v3 following v3 graphql-core (#1048)
* v3.0 - remove Python 2.x from build (#983)

* Change travis to only compile for p3.6+

* Changed tox to only run Python 3.6+

* Changed library classifiers to reflect support in Python 3.6+

* Changed version to 3.0.0 development

In [15]: get_version((3, 0, 0, "alpha", 0))
Out[15]: '3.0.dev20190601212304'

* Reorganize Tests (#985)

We no longer need a dedicated folder for Python3.6+ tests
We no longer need to check six.PY3 in tests

* Upgrade black to 19.3b0 (#987)

* Remove six dependency (#986)

* No one is using func_name

* Remove six simple usages

* Remove six requirement

* Remove `six.with_metaclass` calls

* pytest-asyncio should be a regular dependency now with Py3 move

* Change dependency to graphql-core-next (#988)

* Changed dependencies to core-next

* Converted Scalars

* ResolveInfo name change

* Ignore .venv

* Make Schema compatible with GraphQL-core-next

* Ignore more venv names and mypy and pytest caches

* Remove print statements for debugging in schema test

* core-next now provides out_type and out_name

* Adapt date and time scalar types to core-next

* Ignore the non-standard result.invalid flag

* Results are named tuples in core-next (immutable)

* Enum values are returned as dict in core-next

* Fix mutation tests with promises

* Make all 345 tests pass with graphql-core-next

* Remove the compat module which was only needed for older Py version

* Remove object as base class (not needed in Py 3)

* We can assume that dicts are ordered in Py 3.6+

* Make use of the fact that dicts are iterable

* Use consistent style of importing from pytest

* Restore compatibility with graphql-relay-py v3

Add adpaters for the PageInfo and Connection args.

* Avoid various deprecation warnings

* Use graphql-core 3 instead of graphql-core-next

* Update dependencies, reformat changes with black

* Update graphene/relay/connection.py

Co-Authored-By: Jonathan Kim <jkimbo@gmail.com>

* Run black on setup.py

* Remove trailing whitespace
2019-08-17 17:07:53 -04:00

91 lines
3.1 KiB
Python

from .base import BaseOptions, BaseType
from .inputfield import InputField
from .unmountedtype import UnmountedType
from .utils import yank_fields_from_attrs
# For static type checking with Mypy
MYPY = False
if MYPY:
from typing import Dict, Callable # NOQA
class InputObjectTypeOptions(BaseOptions):
fields = None # type: Dict[str, InputField]
container = None # type: InputObjectTypeContainer
class InputObjectTypeContainer(dict, BaseType):
class Meta:
abstract = True
def __init__(self, *args, **kwargs):
dict.__init__(self, *args, **kwargs)
for key in self._meta.fields:
setattr(self, key, self.get(key, None))
def __init_subclass__(cls, *args, **kwargs):
pass
class InputObjectType(UnmountedType, BaseType):
"""
Input Object Type Definition
An input object defines a structured collection of fields which may be
supplied to a field argument.
Using ``graphene.NonNull`` will ensure that a input value must be provided by the query.
All class attributes of ``graphene.InputObjectType`` are implicitly mounted as InputField
using the below Meta class options.
.. code:: python
from graphene import InputObjectType, String, InputField
class Person(InputObjectType):
# implicitly mounted as Input Field
first_name = String(required=True)
# explicitly mounted as Input Field
last_name = InputField(String, description="Surname")
The fields on an input object type can themselves refer to input object types, but you can't
mix input and output types in your schema.
Meta class options (optional):
name (str): the name of the GraphQL type (must be unique in schema). Defaults to class
name.
description (str): the description of the GraphQL type in the schema. Defaults to class
docstring.
container (class): A class reference for a value object that allows for
attribute initialization and access. Default InputObjectTypeContainer.
fields (Dict[str, graphene.InputField]): Dictionary of field name to InputField. Not
recommended to use (prefer class attributes).
"""
@classmethod
def __init_subclass_with_meta__(cls, container=None, _meta=None, **options):
if not _meta:
_meta = InputObjectTypeOptions(cls)
fields = {}
for base in reversed(cls.__mro__):
fields.update(yank_fields_from_attrs(base.__dict__, _as=InputField))
if _meta.fields:
_meta.fields.update(fields)
else:
_meta.fields = fields
if container is None:
container = type(cls.__name__, (InputObjectTypeContainer, cls), {})
_meta.container = container
super(InputObjectType, cls).__init_subclass_with_meta__(_meta=_meta, **options)
@classmethod
def get_type(cls):
"""
This function is called when the unmounted type (InputObjectType instance)
is mounted (as a Field, InputField or Argument)
"""
return cls