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, InputField,
Schema, Schema,
Scalar, Scalar,
String, ID, Int, Float, Boolean, String, ID, Int, Float, Boolean, OmniScalar,
List, NonNull, List, NonNull,
Enum, Enum,
Argument, Argument,

View File

@ -4,7 +4,7 @@ from .objecttype import ObjectType
from .abstracttype import AbstractType from .abstracttype import AbstractType
from .interface import Interface from .interface import Interface
from .mutation import Mutation 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 .schema import Schema
from .structures import List, NonNull from .structures import List, NonNull
from .enum import Enum from .enum import Enum
@ -32,6 +32,7 @@ __all__ = [
'Int', 'Int',
'Float', 'Float',
'Boolean', 'Boolean',
'OmniScalar',
'List', 'List',
'NonNull', 'NonNull',
'Argument', 'Argument',

View File

@ -9,7 +9,6 @@ from .unmountedtype import UnmountedType
class ScalarTypeMeta(type): class ScalarTypeMeta(type):
def __new__(cls, name, bases, attrs): def __new__(cls, name, bases, attrs):
# Also ensure initialization is only performed for subclasses of Model # Also ensure initialization is only performed for subclasses of Model
# (excluding Model class itself). # (excluding Model class itself).
@ -49,6 +48,7 @@ class Scalar(six.with_metaclass(ScalarTypeMeta, UnmountedType)):
''' '''
return cls return cls
# As per the GraphQL Spec, Integers are only treated as valid when a valid # As per the GraphQL Spec, Integers are only treated as valid when a valid
# 32-bit signed integer, providing the broadest support across platforms. # 32-bit signed integer, providing the broadest support across platforms.
# #
@ -164,3 +164,43 @@ class ID(Scalar):
def parse_literal(ast): def parse_literal(ast):
if isinstance(ast, (StringValue, IntValue)): if isinstance(ast, (StringValue, IntValue)):
return ast.value 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(): def test_serializes_output_int():
@ -48,3 +48,28 @@ def test_serializes_output_boolean():
assert Boolean.serialize(0) is False assert Boolean.serialize(0) is False
assert Boolean.serialize(True) is True assert Boolean.serialize(True) is True
assert Boolean.serialize(False) is False 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