Added OmniScalar type

This commit is contained in:
James Boehmer 2016-11-12 11:25:58 -05:00
parent b1bffc4f8d
commit d639cdb762
4 changed files with 70 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,

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).
@ -49,6 +48,7 @@ class Scalar(six.with_metaclass(ScalarTypeMeta, UnmountedType)):
'''
return cls
# As per the GraphQL Spec, Integers are only treated as valid when a valid
# 32-bit signed integer, providing the broadest support across platforms.
#
@ -164,3 +164,43 @@ 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,
unicode: String,
bool: Boolean,
int: Int,
float: Float,
}
@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