This commit is contained in:
James Boehmer 2017-05-31 08:39:51 +00:00 committed by GitHub
commit ddef8fa8c8
4 changed files with 72 additions and 4 deletions

View File

@ -26,7 +26,7 @@ if not __SETUP__:
InputField,
Schema,
Scalar,
String, ID, Int, Float, Boolean,
String, ID, Int, Float, Boolean, OmniScalar,
List, NonNull,
Enum,
Argument,
@ -61,6 +61,7 @@ if not __SETUP__:
'Float',
'Enum',
'Boolean',
'OmniScalar',
'List',
'NonNull',
'Argument',

View File

@ -4,7 +4,7 @@ from .objecttype import ObjectType
from .abstracttype import AbstractType
from .interface import Interface
from .mutation import Mutation
from .scalars import Scalar, String, ID, Int, Float, Boolean
from .scalars import Scalar, String, ID, Int, Float, Boolean, OmniScalar
from .schema import Schema
from .structures import List, NonNull
from .enum import Enum
@ -32,6 +32,7 @@ __all__ = [
'Int',
'Float',
'Boolean',
'OmniScalar',
'List',
'NonNull',
'Argument',

View File

@ -9,7 +9,6 @@ from .unmountedtype import UnmountedType
class ScalarTypeMeta(type):
def __new__(cls, name, bases, attrs):
# Also ensure initialization is only performed for subclasses of Model
# (excluding Model class itself).
@ -165,3 +164,45 @@ class ID(Scalar):
def parse_literal(ast):
if isinstance(ast, (StringValue, IntValue)):
return ast.value
class OmniScalar(Scalar):
'''
The `OmniScalar` type represents any kind of scalar type. For values
whose type is nondeterministic, an OmniScalar will parse and serialize it
appropriately. Non-scalar types (lists and objects) are considered null.
'''
_scalar_type_map = {
str: String,
bool: Boolean,
int: Int,
float: Float,
}
if six.PY2:
_scalar_type_map[unicode] = String
@staticmethod
def serialize(value):
scalar_type = OmniScalar._scalar_type_map.get(type(value))
if scalar_type:
return scalar_type.serialize(value)
else:
return None
@staticmethod
def parse_value(value):
scalar_type = OmniScalar._scalar_type_map.get(type(value))
if scalar_type:
return scalar_type.parse_value(value)
else:
return None
@staticmethod
def parse_literal(ast):
scalar_type = OmniScalar._scalar_type_map.get(type(ast))
if scalar_type:
return scalar_type.parse_literal(ast)
else:
return None

View File

@ -1,4 +1,4 @@
from ..scalars import Boolean, Float, Int, String
from ..scalars import Boolean, Float, Int, String, OmniScalar
def test_serializes_output_int():
@ -48,3 +48,28 @@ def test_serializes_output_boolean():
assert Boolean.serialize(0) is False
assert Boolean.serialize(True) is True
assert Boolean.serialize(False) is False
def test_serializes_output_omniscalar():
# Int
assert OmniScalar.serialize(1) == 1
assert OmniScalar.serialize(0) == 0
assert OmniScalar.serialize(-1) == -1
# Float
assert OmniScalar.serialize(0.1) == 0.1
assert OmniScalar.serialize(1.1) == 1.1
assert OmniScalar.serialize(-1.1) == -1.1
# String
assert OmniScalar.serialize('string') == 'string'
assert OmniScalar.serialize(u'\U0001F601') == u'\U0001F601'
# Boolean
assert OmniScalar.serialize(False) is False
assert OmniScalar.serialize(True) is True
# Other
assert OmniScalar.serialize(None) is None
assert OmniScalar.serialize([]) is None
assert OmniScalar.serialize({}) is None
assert OmniScalar.serialize(object()) is None
assert OmniScalar.serialize(object) is None
assert OmniScalar.serialize(lambda _: '') is None