Exemple #1
0
    async def __task_receiver__(self, tasks, error_collector):
        for name, task in tasks.items():
            task, node, field, path = task
            if isawaitable(task):
                try:
                    result = await task
                except Exception as e:
                    self.__handle_error__(e, node, path, error_collector)
                    result = None
            else:
                result = task

            if not self.__check_return_type__(field.ftype, result):
                if result is None and error_collector:
                    return None
                raise RuntimeError(
                    f'{result} is not a valid return value to'
                    f' {name}, please check {name}\'s type annotation', node,
                    path)

            await self.__circular_resolve__(result, node, error_collector,
                                            path)

            self.resolve_results[name] = result
        return self
Exemple #2
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
Exemple #3
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
Exemple #4
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
Exemple #5
0
 async def __check_and_circular_resolve(self, tasks, error_collector):
     for name, task in tasks.items():
         task, node, field, path = task
         result = self.resolve_results[self.__get_field_name(name, node)]
         if not self.__check_return_type(field.ftype, result):
             if result is None and error_collector:
                 return False
             raise RuntimeError(
                 f'{result} is not a valid return value to'
                 f' {name}, please check {name}\'s type annotation', node,
                 path)
         await self.__circular_resolve(result, node, error_collector, path)
     return self
Exemple #6
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)