1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
|
from typing import Any
from graphql import Undefined
from graphql.language.ast import (
BooleanValueNode,
FloatValueNode,
IntValueNode,
StringValueNode,
)
from .base import BaseOptions, BaseType
from .unmountedtype import UnmountedType
class ScalarOptions(BaseOptions):
pass
class Scalar(UnmountedType, BaseType):
"""
Scalar Type Definition
The leaf values of any request and input values to arguments are
Scalars (or Enums) and are defined with a name and a series of functions
used to parse input from ast or variables and to ensure validity.
"""
@classmethod
def __init_subclass_with_meta__(cls, **options):
_meta = ScalarOptions(cls)
super(Scalar, cls).__init_subclass_with_meta__(_meta=_meta, **options)
serialize = None
parse_value = None
parse_literal = None
@classmethod
def get_type(cls):
"""
This function is called when the unmounted type (Scalar instance)
is mounted (as a Field, InputField or Argument)
"""
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.
#
# n.b. JavaScript's integers are safe between -(2^53 - 1) and 2^53 - 1 because
# they are internally represented as IEEE 754 doubles.
MAX_INT = 2147483647
MIN_INT = -2147483648
class Int(Scalar):
"""
The `Int` scalar type represents non-fractional signed whole numeric
values. Int can represent values between -(2^53 - 1) and 2^53 - 1 since
represented in JSON as double-precision floating point numbers specified
by [IEEE 754](http://en.wikipedia.org/wiki/IEEE_floating_point).
"""
@staticmethod
def coerce_int(value):
try:
num = int(value)
except ValueError:
try:
num = int(float(value))
except ValueError:
return Undefined
if MIN_INT <= num <= MAX_INT:
return num
return Undefined
serialize = coerce_int
parse_value = coerce_int
@staticmethod
def parse_literal(ast, _variables=None):
if isinstance(ast, IntValueNode):
num = int(ast.value)
if MIN_INT <= num <= MAX_INT:
return num
return Undefined
class BigInt(Scalar):
"""
The `BigInt` scalar type represents non-fractional whole numeric values.
`BigInt` is not constrained to 32-bit like the `Int` type and thus is a less
compatible type.
"""
@staticmethod
def coerce_int(value):
try:
num = int(value)
except ValueError:
try:
num = int(float(value))
except ValueError:
return Undefined
return num
serialize = coerce_int
parse_value = coerce_int
@staticmethod
def parse_literal(ast, _variables=None):
if isinstance(ast, IntValueNode):
return int(ast.value)
return Undefined
class Float(Scalar):
"""
The `Float` scalar type represents signed double-precision fractional
values as specified by
[IEEE 754](http://en.wikipedia.org/wiki/IEEE_floating_point).
"""
@staticmethod
def coerce_float(value: Any) -> float:
try:
return float(value)
except ValueError:
return Undefined
serialize = coerce_float
parse_value = coerce_float
@staticmethod
def parse_literal(ast, _variables=None):
if isinstance(ast, (FloatValueNode, IntValueNode)):
return float(ast.value)
return Undefined
class String(Scalar):
"""
The `String` scalar type represents textual data, represented as UTF-8
character sequences. The String type is most often used by GraphQL to
represent free-form human-readable text.
"""
@staticmethod
def coerce_string(value):
if isinstance(value, bool):
return "true" if value else "false"
return str(value)
serialize = coerce_string
parse_value = coerce_string
@staticmethod
def parse_literal(ast, _variables=None):
if isinstance(ast, StringValueNode):
return ast.value
return Undefined
class Boolean(Scalar):
"""
The `Boolean` scalar type represents `true` or `false`.
"""
serialize = bool
parse_value = bool
@staticmethod
def parse_literal(ast, _variables=None):
if isinstance(ast, BooleanValueNode):
return ast.value
return Undefined
class ID(Scalar):
"""
The `ID` scalar type represents a unique identifier, often used to
refetch an object or as key for a cache. The ID type appears in a JSON
response as a String; however, it is not intended to be human-readable.
When expected as an input type, any string (such as `"4"`) or integer
(such as `4`) input value will be accepted as an ID.
"""
serialize = str
parse_value = str
@staticmethod
def parse_literal(ast, _variables=None):
if isinstance(ast, (StringValueNode, IntValueNode)):
return ast.value
return Undefined
|