mirror of
https://github.com/graphql-python/graphene.git
synced 2024-11-23 01:56:54 +03:00
Merge branch 'master' of github.com:graphql-python/graphene
This commit is contained in:
commit
a2b6d3dd05
|
@ -25,7 +25,7 @@ def resolve_xxx(self, args, context, info):
|
||||||
# ...
|
# ...
|
||||||
```
|
```
|
||||||
|
|
||||||
* `ObjectType and `Interface` no longer accept the `abstract` option in the `Meta`.
|
* `ObjectType` and `Interface` no longer accept the `abstract` option in the `Meta`.
|
||||||
Inheriting fields should be now achieved using `AbstractType` inheritance.
|
Inheriting fields should be now achieved using `AbstractType` inheritance.
|
||||||
|
|
||||||
Before:
|
Before:
|
||||||
|
|
|
@ -30,11 +30,13 @@ if not __SETUP__:
|
||||||
List, NonNull,
|
List, NonNull,
|
||||||
Enum,
|
Enum,
|
||||||
Argument,
|
Argument,
|
||||||
Dynamic
|
Dynamic,
|
||||||
|
Union,
|
||||||
)
|
)
|
||||||
from .relay import (
|
from .relay import (
|
||||||
Node,
|
Node,
|
||||||
is_node,
|
is_node,
|
||||||
|
GlobalID,
|
||||||
ClientIDMutation,
|
ClientIDMutation,
|
||||||
Connection,
|
Connection,
|
||||||
ConnectionField,
|
ConnectionField,
|
||||||
|
@ -62,9 +64,11 @@ if not __SETUP__:
|
||||||
'NonNull',
|
'NonNull',
|
||||||
'Argument',
|
'Argument',
|
||||||
'Dynamic',
|
'Dynamic',
|
||||||
|
'Union',
|
||||||
'resolve_only_args',
|
'resolve_only_args',
|
||||||
'Node',
|
'Node',
|
||||||
'is_node',
|
'is_node',
|
||||||
|
'GlobalID',
|
||||||
'ClientIDMutation',
|
'ClientIDMutation',
|
||||||
'Connection',
|
'Connection',
|
||||||
'ConnectionField',
|
'ConnectionField',
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
from .node import Node, is_node
|
from .node import Node, is_node, GlobalID
|
||||||
from .mutation import ClientIDMutation
|
from .mutation import ClientIDMutation
|
||||||
from .connection import Connection, ConnectionField, PageInfo
|
from .connection import Connection, ConnectionField, PageInfo
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'Node',
|
'Node',
|
||||||
'is_node',
|
'is_node',
|
||||||
|
'GlobalID',
|
||||||
'ClientIDMutation',
|
'ClientIDMutation',
|
||||||
'Connection',
|
'Connection',
|
||||||
'ConnectionField',
|
'ConnectionField',
|
||||||
|
|
|
@ -92,6 +92,16 @@ def test_edge_with_bases():
|
||||||
assert edge_fields['other'].type == String
|
assert edge_fields['other'].type == String
|
||||||
|
|
||||||
|
|
||||||
|
def test_edge_on_node():
|
||||||
|
Edge = MyObject.Connection.Edge
|
||||||
|
assert Edge._meta.name == 'MyObjectEdge'
|
||||||
|
edge_fields = Edge._meta.fields
|
||||||
|
assert list(edge_fields.keys()) == ['node', 'cursor']
|
||||||
|
|
||||||
|
assert isinstance(edge_fields['node'], Field)
|
||||||
|
assert edge_fields['node'].type == MyObject
|
||||||
|
|
||||||
|
|
||||||
def test_pageinfo():
|
def test_pageinfo():
|
||||||
assert PageInfo._meta.name == 'PageInfo'
|
assert PageInfo._meta.name == 'PageInfo'
|
||||||
fields = PageInfo._meta.fields
|
fields = PageInfo._meta.fields
|
||||||
|
|
|
@ -1,15 +1,26 @@
|
||||||
|
from collections import OrderedDict
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from ...types import (Argument, Field, InputField, InputObjectType, ObjectType,
|
from ...types import (Argument, Field, InputField, InputObjectType, ObjectType,
|
||||||
Schema, AbstractType, NonNull)
|
Schema, AbstractType, NonNull)
|
||||||
from ...types.scalars import String
|
from ...types.scalars import String
|
||||||
|
from ..connection import Connection
|
||||||
from ..mutation import ClientIDMutation
|
from ..mutation import ClientIDMutation
|
||||||
|
from ..node import Node
|
||||||
|
|
||||||
|
|
||||||
class SharedFields(AbstractType):
|
class SharedFields(AbstractType):
|
||||||
shared = String()
|
shared = String()
|
||||||
|
|
||||||
|
|
||||||
|
class MyNode(ObjectType):
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
interfaces = (Node, )
|
||||||
|
|
||||||
|
name = String()
|
||||||
|
|
||||||
|
|
||||||
class SaySomething(ClientIDMutation):
|
class SaySomething(ClientIDMutation):
|
||||||
|
|
||||||
class Input:
|
class Input:
|
||||||
|
@ -28,12 +39,16 @@ class OtherMutation(ClientIDMutation):
|
||||||
additional_field = String()
|
additional_field = String()
|
||||||
|
|
||||||
name = String()
|
name = String()
|
||||||
|
my_node_edge = Field(MyNode.Connection.Edge)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def mutate_and_get_payload(cls, args, context, info):
|
def mutate_and_get_payload(cls, args, context, info):
|
||||||
shared = args.get('shared', '')
|
shared = args.get('shared', '')
|
||||||
additionalField = args.get('additionalField', '')
|
additionalField = args.get('additionalField', '')
|
||||||
return SaySomething(name=shared + additionalField)
|
edge_type = MyNode.Connection.Edge
|
||||||
|
return OtherMutation(name=shared + additionalField,
|
||||||
|
my_node_edge=edge_type(
|
||||||
|
cursor='1', node=MyNode(name='name')))
|
||||||
|
|
||||||
|
|
||||||
class RootQuery(ObjectType):
|
class RootQuery(ObjectType):
|
||||||
|
@ -81,7 +96,7 @@ def test_mutation_input():
|
||||||
|
|
||||||
def test_subclassed_mutation():
|
def test_subclassed_mutation():
|
||||||
fields = OtherMutation._meta.fields
|
fields = OtherMutation._meta.fields
|
||||||
assert list(fields.keys()) == ['name']
|
assert list(fields.keys()) == ['name', 'my_node_edge']
|
||||||
assert isinstance(fields['name'], Field)
|
assert isinstance(fields['name'], Field)
|
||||||
field = OtherMutation.Field()
|
field = OtherMutation.Field()
|
||||||
assert field.type == OtherMutation
|
assert field.type == OtherMutation
|
||||||
|
@ -110,3 +125,10 @@ def test_subclassed_mutation_input():
|
||||||
# )
|
# )
|
||||||
# assert not executed.errors
|
# assert not executed.errors
|
||||||
# assert executed.data == {'say': {'phrase': 'hello'}}
|
# assert executed.data == {'say': {'phrase': 'hello'}}
|
||||||
|
|
||||||
|
def test_edge_query():
|
||||||
|
executed = schema.execute(
|
||||||
|
'mutation a { other(input: {clientMutationId:"1"}) { myNodeEdge { cursor node { name }} } }'
|
||||||
|
)
|
||||||
|
assert not executed.errors
|
||||||
|
assert dict(executed.data) == {'other': {'myNodeEdge': {'cursor': '1', 'node': {'name': 'name'}}}}
|
||||||
|
|
|
@ -13,6 +13,7 @@ from .inputfield import InputField
|
||||||
from .argument import Argument
|
from .argument import Argument
|
||||||
from .inputobjecttype import InputObjectType
|
from .inputobjecttype import InputObjectType
|
||||||
from .dynamic import Dynamic
|
from .dynamic import Dynamic
|
||||||
|
from .union import Union
|
||||||
|
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
|
@ -33,5 +34,6 @@ __all__ = [
|
||||||
'Boolean',
|
'Boolean',
|
||||||
'List',
|
'List',
|
||||||
'NonNull',
|
'NonNull',
|
||||||
'Argument'
|
'Argument',
|
||||||
'Dynamic']
|
'Dynamic',
|
||||||
|
]
|
||||||
|
|
|
@ -32,7 +32,7 @@ def to_arguments(args, extra_args):
|
||||||
raise ValueError('Unknown argument "{}".'.format(default_name))
|
raise ValueError('Unknown argument "{}".'.format(default_name))
|
||||||
|
|
||||||
arg_name = default_name or arg.name
|
arg_name = default_name or arg.name
|
||||||
assert arg_name not in arguments, 'More than one Argument have same name "{}".'.format(arg.name)
|
assert arg_name not in arguments, 'More than one Argument have same name "{}".'.format(arg_name)
|
||||||
arguments[arg_name] = arg
|
arguments[arg_name] = arg
|
||||||
|
|
||||||
return arguments
|
return arguments
|
||||||
|
|
|
@ -95,7 +95,7 @@ class ObjectType(six.with_metaclass(ObjectTypeMeta)):
|
||||||
if kwargs:
|
if kwargs:
|
||||||
for prop in list(kwargs):
|
for prop in list(kwargs):
|
||||||
try:
|
try:
|
||||||
if isinstance(getattr(self.__class__, prop), property):
|
if isinstance(getattr(self.__class__, prop), property) or prop.startswith('_'):
|
||||||
setattr(self, prop, kwargs.pop(prop))
|
setattr(self, prop, kwargs.pop(prop))
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -64,6 +64,20 @@ def test_generate_objecttype_with_fields():
|
||||||
assert 'field' in MyObjectType._meta.fields
|
assert 'field' in MyObjectType._meta.fields
|
||||||
|
|
||||||
|
|
||||||
|
def test_generate_objecttype_with_private_attributes():
|
||||||
|
class MyObjectType(ObjectType):
|
||||||
|
_private_state = None
|
||||||
|
|
||||||
|
assert '_private_state' not in MyObjectType._meta.fields
|
||||||
|
assert hasattr(MyObjectType, '_private_state')
|
||||||
|
|
||||||
|
m = MyObjectType(_private_state='custom')
|
||||||
|
assert m._private_state == 'custom'
|
||||||
|
|
||||||
|
with pytest.raises(TypeError):
|
||||||
|
MyObjectType(_other_private_state='Wrong')
|
||||||
|
|
||||||
|
|
||||||
def test_ordered_fields_in_objecttype():
|
def test_ordered_fields_in_objecttype():
|
||||||
class MyObjectType(ObjectType):
|
class MyObjectType(ObjectType):
|
||||||
b = Field(MyType)
|
b = Field(MyType)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user