def __package_args(self, node, field, path): kwargs = {} for arg in node.arguments: slot = field.params.get(to_snake_case(arg.name.value)) if not slot: raise RuntimeError( f'Can not find {arg.name.value}' f' as param in {field.name}', node, path) kwargs[to_snake_case(arg.name.value)] = load_literal_value( arg.value, slot) return kwargs
def __new__(cls, name, bases, attrs): attrs['__fields__'] = {} attrs['__description__'] = None attrs['__validated__'] = False cls = dataclasses.dataclass(super().__new__(cls, name, bases, attrs)) sign = inspect.signature(cls) cls.__description__ = inspect.getdoc(cls) for name, t in sign.parameters.items(): cls.__fields__[to_snake_case(name)] = Field( name=to_snake_case(name), _ftype=t.annotation, description=None, _obj=cls ) return cls
def __new__(cls, name, bases, attrs): cls = super().__new__(cls, name, bases, attrs) for name in dir(cls): attr = getattr(cls, name) if hasattr(attr, '__is_field__'): sign = inspect.signature(attr) cls.__fields__[to_snake_case(name)] = ResolverField( name=to_snake_case(name), _ftype=sign.return_annotation, _params=cls.remove_self(sign.parameters), description=inspect.getdoc(attr), _obj=cls) return cls
def load_literal_value(node, ptype): if isinstance(node, IntValueNode): return int(node.value) elif isinstance(node, FloatValueNode): return float(node.value) elif isinstance(node, BooleanValueNode): return bool(node.value) elif isinstance(node, StringValueNode): return node.value elif isinstance(node, NullValueNode): return None elif isinstance(node, ListValueNode): return [load_literal_value(v, ptype.__args__[0]) for v in node.values] elif isinstance(node, EnumValueNode): value = getattr(ptype, node.value) if not value: raise RuntimeError(f'{node.value} is not a valid member of {type}', node) return value elif isinstance(node, ObjectValueNode): data = {} keys = ptype.__dataclass_fields__.keys() for field in node.fields: name = field.name.value if name not in keys: name = to_snake_case(name) data[name] = load_literal_value( field.value, ptype.__fields__[to_snake_case(name)].ftype) return ptype(**data) elif isinstance(node, VariableNode): name = node.name.value variables = types.context.get().variables if name not in variables: raise RuntimeError(f'Can not find variable {name}') variable = variables[name] return load_variable(variable, ptype) raise RuntimeError(f'Can not convert {node.value}', node)
async def _resolve(self, nodes, error_collector, path=[]): self.resolve_results = {} tasks = {} for node in nodes: if hasattr(node, 'name'): path = copy(path) path.append(node.name.value) returned = await self.__resolve_fragment(node, error_collector, path) if returned: continue name = node.name.value snake_cases = to_snake_case(name) field = self.__fields__.get(snake_cases) keys = self.__dataclass_fields__.keys() resolver = self.__get_resover(name, node, field, path) if not resolver: try: tasks[name] = (getattr( self, name if name in keys else snake_cases), node, field, path) except AttributeError: raise RuntimeError(f'{name} is not a valid node of {self}', node, path) else: kwargs = self.__package_args(node, field, path) try: returned = resolver(**kwargs) except Exception as e: self.__handle_error(e, node, path, error_collector) tasks[name] = (None, node, field, path) continue if isawaitable(returned): tasks[name] = (asyncio.ensure_future(returned), node, field, path) else: tasks[name] = (returned, node, field, path) return self.__task_receiver(tasks, error_collector)
def load_variable(variable, ptype): if isinstance(ptype, types.InputType): data = {} keys = ptype.__dataclass_fields__.keys() for key, value in variable.items(): snake_cases = to_snake_case(key) data[snake_cases if key not in keys else key] = load_variable( value, ptype.__fields__[snake_cases].ftype) return ptype(**data) elif is_list(ptype): return [load_variable(i, ptype.__args__[0]) for i in variable] elif is_optional(ptype): if variable is None: return None return load_variable(variable, ptype.__args__[0]) elif isinstance(ptype, types.EnumType): return getattr(ptype, variable) else: return variable
def __get_resover__(self, name, node, field, path): snake_cases = to_snake_case(name) if not field: raise RuntimeError( f"Cannot query field '{name}' on type '{type(self)}'.", node, path) if not isinstance(field, ResolverField): return None if '__' in snake_cases: resolver = getattr(self, f'_{self.__class__.__name__}{snake_cases}', None) else: resolver = getattr(self, snake_cases, None) if not resolver or not resolver.__is_field__: raise RuntimeError( f"Cannot query field '{name}' on type '{type(self)}'.", node, path) return resolver
def __get_resover(self, name, node, field, path): snake_cases = to_snake_case(name) if not field: raise RuntimeError( f"Cannot query field '{name}' on type '{type(self)}'.", node, path) if not isinstance(field, ResolverField): return None if snake_cases.startswith('__'): resolver = getattr(self, f'_{snake_cases[2:]}', None) if not getattr(resolver, '__is_metafield__', False): resolver = None else: resolver = getattr(self, snake_cases, None) if not getattr(resolver, '__is_field__', False): resolver = None if not resolver: raise RuntimeError( f"Cannot query field '{name}' on type '{type(self)}'.", node, path) return resolver