def get_arg_serializer(arg_type, known_serializers): if isinstance(arg_type, GraphQLNonNull): return get_arg_serializer(arg_type.of_type, known_serializers) if isinstance(arg_type, GraphQLInputField): return get_arg_serializer(arg_type.type, known_serializers) if isinstance(arg_type, GraphQLInputObjectType): if arg_type in known_serializers: return known_serializers[arg_type] known_serializers[arg_type] = None serializers = { k: get_arg_serializer(v, known_serializers) for k, v in arg_type.fields.items() } known_serializers[arg_type] = lambda value: ObjectValueNode( fields=FrozenList( ObjectFieldNode(name=NameNode(value=k), value=serializers[k](v)) for k, v in value.items())) return known_serializers[arg_type] if isinstance(arg_type, GraphQLList): inner_serializer = get_arg_serializer(arg_type.of_type, known_serializers) return partial(serialize_list, inner_serializer) if isinstance(arg_type, GraphQLEnumType): return lambda value: EnumValueNode(value=arg_type.serialize(value)) return lambda value: ast_from_value(arg_type.serialize(value), arg_type)
def ast_from_value(value: Any, type_: GraphQLInputType) -> Optional[ValueNode]: """ This is a partial copy paste of the ast_from_value function in graphql-core utilities/ast_from_value.py Overwrite the if blocks that use recursion and add a new case to return a VariableNode when value is a DSLVariable Produce a GraphQL Value AST given a Python object. """ if isinstance(value, DSLVariable): return value.set_type(type_).ast_variable if is_non_null_type(type_): type_ = cast(GraphQLNonNull, type_) ast_value = ast_from_value(value, type_.of_type) if isinstance(ast_value, NullValueNode): return None return ast_value # only explicit None, not Undefined or NaN if value is None: return NullValueNode() # undefined if value is Undefined: return None # Convert Python list to GraphQL list. If the GraphQLType is a list, but the value # is not a list, convert the value using the list's item type. if is_list_type(type_): type_ = cast(GraphQLList, type_) item_type = type_.of_type if isinstance(value, Iterable) and not isinstance(value, str): maybe_value_nodes = (ast_from_value(item, item_type) for item in value) value_nodes = filter(None, maybe_value_nodes) return ListValueNode(values=FrozenList(value_nodes)) return ast_from_value(value, item_type) # Populate the fields of the input object by creating ASTs from each value in the # Python dict according to the fields in the input type. if is_input_object_type(type_): if value is None or not isinstance(value, Mapping): return None type_ = cast(GraphQLInputObjectType, type_) field_items = ( (field_name, ast_from_value(value[field_name], field.type)) for field_name, field in type_.fields.items() if field_name in value ) field_nodes = ( ObjectFieldNode(name=NameNode(value=field_name), value=field_value) for field_name, field_value in field_items if field_value ) return ObjectValueNode(fields=FrozenList(field_nodes)) return default_ast_from_value(value, type_)
def test_literal_object_input(): assert GraphQLJSON.parse_literal( ObjectValueNode( fields=[ ObjectFieldNode(name=NameNode(value='true'), value=BooleanValueNode(value=False)), ObjectFieldNode( name=NameNode(value='hello'), value=VariableNode(name=NameNode(value='world')) ), ObjectFieldNode( name=NameNode(value='array'), value=ListValueNode( values=[ IntValueNode(value=1), FloatValueNode(value=2.0), StringValueNode(value='3'), ] ), ), ObjectFieldNode(name=NameNode(value='maybe_null'), value=NullValueNode()), ObjectFieldNode( name=NameNode(value='obj'), value=ObjectValueNode( fields=[ ObjectFieldNode( name=NameNode(value='test'), value=VariableNode(name=NameNode(value='tenet')), ) ] ), ), ] ), { 'world': 'world', 'tenet': 'tenet', }, ) == { 'true': False, 'hello': 'world', 'array': [1, 2.0, '3'], 'maybe_null': None, 'obj': {'test': 'tenet'}, }