Ejemplo n.º 1
0
 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
Ejemplo n.º 2
0
 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
Ejemplo n.º 3
0
 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
Ejemplo n.º 4
0
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)
Ejemplo n.º 5
0
    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)
Ejemplo n.º 6
0
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
Ejemplo n.º 7
0
 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
Ejemplo n.º 8
0
    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