def evaluate_call(node: ast3.Call, *, scope: Scope, module_path: catalog.Path) -> Node: if not is_named_tuple_definition(node, scope=scope, module_path=module_path): return node class_name_node, fields_node = node.args def field_to_parameter(field_node: ast3.expr) -> ast3.arg: name_node, annotation_node = field_node.elts return ast3.arg(ast3.literal_eval(name_node), annotation_node) initializer_node = ast3.FunctionDef( '__init__', ast3.arguments([ast3.arg('self', None)] + list(map(field_to_parameter, fields_node.elts)), None, [], [], None, []), [ast3.Pass()], [], None) function_path = evaluate_node(node.func, scope=scope, module_path=module_path) class_def = ast3.ClassDef(ast3.literal_eval(class_name_node), [ast3.Name(str(function_path), ast3.Load())], [], [initializer_node], []) return ast3.fix_missing_locations(ast3.copy_location(class_def, node))
def _Argument(self, node: ET.Element): # pylint: disable=invalid-name try: annotation = self.types.resolved_types[node.attrib['type']] except KeyError as error: raise NotImplementedError('cannot generalize the node {}'.format( ET.tostring(node).decode().rstrip())) from error assert annotation is not None return typed_ast3.arg(arg=node.attrib['name'], annotation=annotation)
def convert_arg(arg, type_comment): if isinstance(arg, ast27.Name): v = arg.id elif isinstance(arg, ast27.Tuple): v = self.visit(arg) else: raise RuntimeError("'{}' is not a valid argument.".format(ast27.dump(arg))) return ast3.arg(v, None, type_comment, lineno=arg.lineno, col_offset=arg.col_offset)
def visit_arguments(self, n): def convert_arg(arg, type_comment): if isinstance(arg, ast27.Name): v = arg.id elif isinstance(arg, ast27.Tuple): v = self.visit(arg) else: raise RuntimeError("'{}' is not a valid argument.".format( ast27.dump(arg))) return ast3.arg(v, None, type_comment, lineno=arg.lineno, col_offset=arg.col_offset) def get_type_comment(i): if i < len(n.type_comments) and n.type_comments[i] is not None: return n.type_comments[i] return None args = [ convert_arg(arg, get_type_comment(i)) for i, arg in enumerate(n.args) ] vararg = None if n.vararg is not None: vararg = ast3.arg(n.vararg, None, get_type_comment(len(args)), lineno=-1, col_offset=-1) kwarg = None if n.kwarg is not None: kwarg = ast3.arg( n.kwarg, None, get_type_comment(len(args) + (0 if n.vararg is None else 1)), lineno=-1, col_offset=-1, ) defaults = self.visit(n.defaults) return ast3.arguments(args, vararg, [], [], kwarg, defaults)
def visit_ParamList(self, node) -> typed_ast3.arguments: # pylint: disable=invalid-name """Transform ParamList.""" params = [self.visit(subnode) for subnode in node.params] # assert all(isinstance(param, tuple) for param in params), params # params = [typed_ast3.arg(arg=param[0], annotation=param[1]) for param in params] assert all(isinstance(param, typed_ast3.AnnAssign) for param in params), params assert all(isinstance(param.target, typed_ast3.Name) for param in params), params params = [typed_ast3.arg(arg=param.target.id, annotation=param.annotation) for param in params] _ = self.visit(node.coord) return typed_ast3.arguments(args=params, vararg=None, kwonlyargs=[], kwarg=None, defaults=[], kw_defaults=[])
def visit_arguments(self, n): def convert_arg(arg, type_comment): if isinstance(arg, ast27.Name): v = arg.id elif isinstance(arg, ast27.Tuple): v = self.visit(arg) else: raise RuntimeError("'{}' is not a valid argument.".format(ast27.dump(arg))) return ast3.arg(v, None, type_comment, lineno=arg.lineno, col_offset=arg.col_offset) def get_type_comment(i): if i < len(n.type_comments) and n.type_comments[i] is not None: return n.type_comments[i] return None args = [convert_arg(arg, get_type_comment(i)) for i, arg in enumerate(n.args)] vararg = None if n.vararg is not None: vararg = ast3.arg(n.vararg, None, get_type_comment(len(args)), lineno=-1, col_offset=-1) kwarg = None if n.kwarg is not None: kwarg = ast3.arg(n.kwarg, None, get_type_comment(len(args) + (0 if n.vararg is None else 1)), lineno=-1, col_offset=-1) defaults = self.visit(n.defaults) return ast3.arguments(args, vararg, [], [], kwarg, defaults)
def visit_arg(self, node): pred_type, pred_prob = self.__extract_type_and_prob( node.arg, node.lineno, AnnotationKind.PARA) if pred_prob is None: return self.__process_old_anns(node) elif pred_prob == self.__IGNORED_PRED_PROB: return node else: return copy_location( arg( arg=node.arg, annotation=Name(id=pred_type, ctx=Load()), type_comment=None, ), node, )
def __process_old_anns(self, node): # ! For One-at-a-Time, don't remove original type annotations if self.__granularity == "var": return node if isinstance(node, arg): return copy_location( arg(arg=node.arg, annotation=None, type_comment=None), node) elif isinstance(node, FunctionDef): return copy_location( FunctionDef( name=node.name, args=node.args, body=node.body, decorator_list=node.decorator_list, returns=None, type_comment=None, ), node, ) elif isinstance(node, AnnAssign): return copy_location( AnnAssign( target=node.target, annotation=None, value=node.value, simple=node.simple, ), node, ) elif isinstance(node, Assign): return copy_location( Assign( targets=node.targets, annotation=None, value=node.value, type_comment=None, ), node, ) else: return node
def _Argument(self, node: ET.Element): # pylint: disable=invalid-name annotation = self.fundamental_types[node.attrib['type']] assert annotation is not None return typed_ast3.arg(arg=node.attrib['name'], annotation=annotation)
def field_to_parameter(field_node: ast3.expr) -> ast3.arg: name_node, annotation_node = field_node.elts return ast3.arg(ast3.literal_eval(name_node), annotation_node)
def global_actions_class(project: Project) -> str: tree = Module(body=[]) tree.body.append( ImportFrom(module='resources', names=[alias(name='Resources', asname=None)], level=0)) cls_def = ClassDef(name='Actions', bases=[], keywords=[], body=[ FunctionDef(name='__init__', args=arguments(args=[ arg(arg='self', annotation=None, type_comment=None), arg(arg='res', annotation=Name(id='Resources', ctx=Load()), type_comment=None) ], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=[ Assign(targets=[ Attribute(value=Name( id='self', ctx=Load()), attr='_res', ctx=Store()) ], value=Name(id='res', ctx=Load()), type_comment=None) ], decorator_list=[], returns=None, type_comment=None) ], decorator_list=[]) for ap in project.action_points: for action in ap.actions: ac_obj, ac_type = action.parse_type() m = FunctionDef( name=clean(action.name), args=arguments( args=[arg(arg='self', annotation=None, type_comment=None)], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=[ Expr(value=Call(func=Attribute(value=Subscript( value=Attribute(value=Attribute(value=Name(id='self', ctx=Load()), attr='_res', ctx=Load()), attr='all_instances', ctx=Load()), slice=Index(value=Str(s=ac_obj, kind='')), ctx=Load()), attr=ac_type, ctx=Load()), args=[ Attribute(value=Attribute(value=Name( id='self', ctx=Load()), attr='_res', ctx=Load()), attr=clean(action.name), ctx=Load()) ], keywords=[])) ], decorator_list=[], returns=None, type_comment=None) cls_def.body.append(m) tree.body.append(cls_def) return tree_to_str(tree)
def global_action_points_class(project: Project) -> str: tree = Module(body=[]) tree.body.append( ImportFrom(module=arcor2.data.common.__name__, names=[alias(name=ActionPoint.__name__, asname=None)], level=0)) tree.body.append( ImportFrom(module='resources', names=[alias(name='Resources', asname=None)], level=0)) cls_def = ClassDef(name='ActionPoints', bases=[], keywords=[], body=[ FunctionDef(name='__init__', args=arguments(args=[ arg(arg='self', annotation=None, type_comment=None), arg(arg='res', annotation=Name(id='Resources', ctx=Load()), type_comment=None) ], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=[ Assign(targets=[ Attribute(value=Name( id='self', ctx=Load()), attr='_res', ctx=Store()) ], value=Name(id='res', ctx=Load()), type_comment=None) ], decorator_list=[], returns=None, type_comment=None) ], decorator_list=[]) for ap in project.action_points: fd = FunctionDef( name=clean(ap.name), # TODO avoid possible collisions args=arguments( args=[arg(arg='self', annotation=None, type_comment=None)], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=[ Return(value=Call(func=Attribute(value=Attribute( value=Attribute(value=Name(id='self', ctx=Load()), attr='_res', ctx=Load()), attr='project', ctx=Load()), attr='action_point', ctx=Load()), args=[Str(s=ap.id, kind='')], keywords=[])) ], decorator_list=[Name(id='property', ctx=Load())], returns=Name(id='ActionPoint', ctx=Load()), type_comment=None) cls_def.body.append(fd) tree.body.append(cls_def) return tree_to_str(tree)
def empty_script_tree(add_main_loop: bool = True) -> Module: """ Creates barebones of the script (empty 'main' function). Returns ------- """ main_body: List[stmt] = [] if add_main_loop: main_body.append( While(test=NameConstant(value=True), body=[Pass()], orelse=[])) else: """ put there "pass" in order to make code valid even if there is no other statement (e.g. no object from resources) """ main_body.append(Pass()) # TODO helper function for try ... except tree = Module(body=[ FunctionDef(name='main', args=arguments(args=[ arg(arg='res', annotation=Name(id='Resources', ctx=Load()), type_comment=None) ], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=main_body, decorator_list=[], returns=NameConstant(value=None), type_comment=None), If(test=Compare(left=Name(id='__name__', ctx=Load()), ops=[Eq()], comparators=[Str(s='__main__', kind='')]), body=[ Try(body=[ With(items=[ withitem(context_expr=Call(func=Name(id='Resources', ctx=Load()), args=[], keywords=[]), optional_vars=Name(id='res', ctx=Store())) ], body=[ Expr(value=Call(func=Name(id='main', ctx=Load()), args=[Name(id='res', ctx=Load())], keywords=[])) ], type_comment=None) ], handlers=[ ExceptHandler( type=Name(id='Exception', ctx=Load()), name='e', body=[ Expr(value=Call(func=Name(id='print_exception', ctx=Load()), args=[Name(id='e', ctx=Load())], keywords=[])) ]) ], orelse=[], finalbody=[]) ], orelse=[]) ], type_ignores=[]) add_import(tree, "arcor2.helpers", "print_exception") add_import(tree, "resources", "Resources", try_to_import=False) return tree
def visit_If(self, node: ast3.If) -> VisitorOutput: """Transforms an if statement into what Pytropos understands: For example, it converts:: if question: body1 else: body2 into:: if_qstn = TRANSFORMED(question) def if_(st): body1 return st def else_(st): body2 return st st = pt.runIf(st, if_qstn, if_, else_) """ self.generic_visit(node) new_body = node.body.copy() new_orelse = node.orelse.copy() orelse = bool(node.orelse) new_body.append( ast3.Return(value=ast3.Name(id='st', ctx=ast3.Load()), )) new_node = [ ast3.Assign(targets=[ast3.Name(id='if_qstn', ctx=ast3.Store())], value=node.test), ast3.FunctionDef( name='if_', args=ast3.arguments(args=[ast3.arg(arg='st', annotation=None)], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=new_body, decorator_list=[], returns=None, ), ] if orelse: # adding "return st" new_orelse.append( ast3.Return(value=ast3.Name(id='st', ctx=ast3.Load()), )) new_node.append( ast3.FunctionDef( name='else_', args=ast3.arguments( args=[ast3.arg(arg='st', annotation=None)], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=new_orelse, decorator_list=[], returns=None, )) new_node.append( ast3.Assign(targets=[ast3.Name(id='st', ctx=ast3.Store())], value=ast3.Call( func=ast3.Attribute( value=ast3.Name(id='pt', ctx=ast3.Load()), attr='runIf', ctx=ast3.Load(), ), args=[ ast3.Name(id='st', ctx=ast3.Load()), ast3.Name(id='if_qstn', ctx=ast3.Load()), ast3.Name(id='if_', ctx=ast3.Load()), ast3.Name(id='else_', ctx=ast3.Load()) ] if orelse else [ ast3.Name(id='st', ctx=ast3.Load()), ast3.Name(id='if_qstn', ctx=ast3.Load()), ast3.Name(id='if_', ctx=ast3.Load()) ], keywords=[], ))) return new_node # type: ignore
def visit_While(self, node: ast3.While) -> VisitorOutput: """Transforms an if statement into what Pytropos understands: For example, it converts:: while question: body into:: if_qstn = TRANSFORMED(question) def while_qst(st): return question def while_(st): body return st st = pt.runWhile(st, while_qstn, while_) """ if node.orelse: raise AstTransformerError( f"Pytropos doesn't support else statement in while loop yet, sorry :(" ) self.generic_visit(node) new_body = node.body.copy() new_body.append( ast3.Return(value=ast3.Name(id='st', ctx=ast3.Load()), )) new_node = [ ast3.FunctionDef( name='while_qst', args=ast3.arguments(args=[ast3.arg(arg='st', annotation=None)], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=[ast3.Return(value=node.test)], decorator_list=[], returns=None, ), ast3.FunctionDef( name='while_', args=ast3.arguments(args=[ast3.arg(arg='st', annotation=None)], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=new_body, decorator_list=[], returns=None, ), ast3.Assign(targets=[ast3.Name(id='st', ctx=ast3.Store())], value=ast3.Call( func=ast3.Attribute( value=ast3.Name(id='pt', ctx=ast3.Load()), attr='runWhile', ctx=ast3.Load(), ), args=[ ast3.Name(id='st', ctx=ast3.Load()), ast3.Name(id='while_qst', ctx=ast3.Load()), ast3.Name(id='while_', ctx=ast3.Load()) ], keywords=[], )) ] return new_node # type: ignore
def derived_resources_class(project: Project) -> str: # TODO temporary and ugly solution of circular import import arcor2.resources from arcor2.resources import ResourcesBase tree = Module(body=[]) parameters = [(act.id, clean(act.name)) for aps in project.action_points for act in aps.actions] add_import(tree, arcor2.resources.__name__, ResourcesBase.__name__) derived_cls_name = "Resources" init_body: List = [ Expr(value=Call(func=Attribute(value=Call( func=Name(id='super', ctx=Load()), args=[ Name(id=derived_cls_name, ctx=Load()), Name(id='self', ctx=Load()) ], keywords=[]), attr='__init__', ctx=Load()), args=[Str(s=project.id)], keywords=[])) ] for a_id, a_name in parameters: init_body.append( Assign(targets=[get_name_attr("self", "_" + a_name, Store)], value=Call(func=get_name_attr("self", "parameters"), args=[Str(s=a_id)], keywords=[]))) cls_def = ClassDef( name=derived_cls_name, bases=[Name(id=ResourcesBase.__name__, ctx=Load())], keywords=[], body=[ FunctionDef(name='__init__', args=arguments(args=[arg(arg='self', annotation=None)], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=init_body, decorator_list=[], returns=None) ], decorator_list=[]) tree.body.append(cls_def) for a_id, a_name in parameters: cls_def.body.append( FunctionDef( name=a_name, args=arguments( args=[arg(arg='self', annotation=None, type_comment=None)], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=[ Expr(value=Call(func=Attribute(value=Name(id='self', ctx=Load()), attr='print_info', ctx=Load()), args=[ Str(s=a_id, kind=''), get_name_attr('self', '_' + a_name) ], keywords=[])), Return(value=get_name_attr('self', '_' + a_name)) ], decorator_list=[Name(id='property', ctx=Load())], returns=None, type_comment=None)) return tree_to_str(tree)