def to_ast(self): value = (ast.Constant(None) if self.optional else None ) # Default value if optional return ast.AnnAssign(ast.Name(self.name), ast.Name(self.type_annotation), value=value, simple=1)
def visit_Assign(self, node): body = [] for t in node.targets: try: target_type = self.get_target_type(t) if hasattr(target_type, "is_gen"): raise Exception("Already generate type") anno = self.get_type_name(self.get_real_type(target_type)) target_type.is_gen = True body.append( ast.AnnAssign( target=t, value=node.value, annotation=anno, lineno=node.lineno, simple=1, ) ) except: body.append( ast.Assign( targets=[t], value=node.value, lineno=node.lineno, ) ) return body
def _init_nodes(tree: ast.FunctionDef) -> Iterator[ast.AST]: """ Transform attribute assignments like "self.foo = 42" to name assignments like "foo = 42", keep all constant expressions, and no-op everything else. This essentially allows us to inline __init__ when parsing a class definition. """ for a in tree.body: if (isinstance(a, ast.AnnAssign) and isinstance(a.target, ast.Attribute) and isinstance(a.target.value, ast.Name) and a.target.value.id == "self"): yield ast.AnnAssign(ast.Name(a.target.attr), a.annotation, a.value, simple=1) elif (isinstance(a, ast.Assign) and len(a.targets) == 1 and isinstance(a.targets[0], ast.Attribute) and isinstance(a.targets[0].value, ast.Name) and a.targets[0].value.id == "self"): yield ast.Assign( [ast.Name(a.targets[0].attr)], value=a.value, # not available on Python 3.7 type_comment=getattr(a, "type_comment", None), ) elif (isinstance(a, ast.Expr) and isinstance(a.value, ast.Constant) and isinstance(a.value.value, str)): yield a elif isinstance(a, ast.Expr) and isinstance( a.value, ast.Str): # pragma: no cover # Python <= 3.7 yield a else: yield ast.Pass()
def visit_Assign(self, node): """Versions of visit_Assign are one of the workhorses for TypeDeducer, as they track the types of assignment targets Each Assignment node also gets turned into an Annotated assignment such that the annotation bears the type of the target. This functionality may not be needed in the future, depending on if these annotations are ever used or if the var and target lists in TypeDeducerState will be sufficient """ if type(node.value).__name__ == "Num": self.var_type = 'scalar' else: x = TypeDeducer(self.type_deducer_state) x.visit(node.value) if x.type_deducer_state.new_variable_ref: raise Exception("Attempting to use undeclared variable in" " assignment: Line number: {} Column Offset: {}".format( node.lineno, node.col_offset)) self.var_type = x.var_type self.dims = x.dims self.type_deducer_state.add_to_target_list(node.targets[0], self.var_type, self.dims) node = ast.AnnAssign(lineno=node.lineno, col_offset=node.col_offset, target=node.targets, annotation=self.var_type, value=node.value, simple=1) self.type_deducer_state.assign_list.append(node)
def assign_property(node_assign, object_): """ Required property -> self.prop = parent_dict["prop"] Optional property -> self.prop = parent_dict.get("prop") Primative nested list -> self.prop = parent_dict.get("prop") Non-primative nested list -> self.props = [PropertyClass(el) for el in parent_dict.get('props', {})] """ prop = ObjectGenerator._get_property_name(node_assign) if ObjectGenerator._non_primitive_nested_list(node_assign): value = ObjectGenerator._init_non_primitive_nested_class( node_assign, object_, prop) else: # Assign the property as self.prop = table.get("prop") value = ObjectGenerator._get_key_from_object(object_, prop) # If the property is required, assign as self.prop = table["prop"] value = ObjectGenerator._hint_required_property( node_assign, value, object_, prop) value = ObjectGenerator._get_default_for_property( node_assign, value, object_, prop) return ast.AnnAssign( target=ast.Attribute(value=ast.Name(id="self"), attr=prop), value=value, simple=0, annotation=Annotations(node_assign).type, )
def to_ast(self) -> AnyAstAssign: if self.annotation is None: return ast.Assign(targets=[self.target], value=self.value) else: return ast.AnnAssign(target=self.target, value=self.value, annotation=self.annotation, simple=1)
def to_ast(self) -> ast.AnnAssign: """ Generate Python AST for this field info """ return ast.AnnAssign( ast.Name(self.name), ast.Name(self.get_type_name(self.type)), ast.Constant(...), simple=1 )
def visit_AnnAssign(self, node: AnnAssign, *args, **kwargs) -> C.AnnAssign: target = self.visit(node.target, *args, **kwargs) annotation = self.visit(node.annotation, *args, **kwargs) value = self.visit(node.value, *args, **kwargs) simple = self.visit(node.simple, *args, **kwargs) return C.AnnAssign( target=target, annotation=annotation, value=value, simple=simple, )
def make_dataclass(name, arguments_spec): return ast.ClassDef( name=name, bases=[], keywords=[], body=[ ast.AnnAssign( target=ast.Name(id=argument_name, ctx=ast.Store()), annotation=argument_type, value=None, simple=1, ) for argument_name, argument_type in arguments_spec.items() ], decorator_list=[ast.Name(id='dataclass', ctx=ast.Load())])
def _resolve_self_properties(self, node): members = {} for child in node.body: if isinstance(child, ast.AnnAssign) and isinstance(child.target, ast.Attribute) and child.target.value.id == "self": name = child.target.attr members[name] = { "name": name, "type": "property", "private": name.startswith("__"), "static": False, "value": self.translator._run_node(child.value), "node": ast.AnnAssign(target=ast.Name(id=name), value=child.value, annotation=child.annotation), } return members
def insert_annotation(cursor_trail, tree, _): selected_node = core_logic.get_node_at_cursor(cursor_trail, tree) default_annotation = ast.Name(id="annotation", ctx=ast.Load()) if hasattr(selected_node, "returns"): # Toggle the return annotation if selected_node.returns is None: selected_node.returns = default_annotation else: selected_node.returns = None # The assignments must come befor the generic annotation case # Because otherwise the annotated assignment's annotation will be # erroneously set to None elif isinstance(selected_node, ast.Assign): # Make it into an annotated assign annotated_assign = ast.AnnAssign( target=selected_node.targets[0], annotation=default_annotation, value=selected_node.value, # TODO: What does simple mean? simple=1 ) core_logic.set_node_at_cursor(cursor_trail, tree, annotated_assign) elif isinstance(selected_node, ast.AnnAssign): # Make it into a regular assign value = selected_node.value assign = ast.Assign( targets=[selected_node.target], value = value if value is not None else make_node.make_expression() ) core_logic.set_node_at_cursor(cursor_trail, tree, assign) elif hasattr(selected_node, "annotation"): # Toggle the annotation if selected_node.annotation is None: selected_node.annotation = default_annotation else: selected_node.annotation = None else: print("This node can't have type annotations") return []
def visit_AugAssign(self, node): aug_op = ast.BinOp(left=node.target, op=node.op, right=node.value, lineno=node.lineno, col_offset=node.col_offset) x = TypeDeducer(self.type_deducer_state) x.visit(aug_op) if x.type_deducer_state.new_variable_ref: raise Exception("Attempting to use undeclared variable in augmented" " assignment: Line number: {} Column Offset: {}".format( node.lineno, node.col_offset)) self.var_type = x.var_type self.dims = x.dims node = ast.AnnAssign(lineno=node.lineno, col_offset=node.col_offset, target=node.target, annotation=self.var_type, value=aug_op, simple=1) self.type_deducer_state.assign_list.append(node) self.type_deducer_state.add_to_target_list(node.target, self.var_type, self.dims)
def record_to_class(record: Record) -> ResolvedClassResult: """Convert Record into AST class definition.""" imports = [ ast.ImportFrom( # from typing import NamedTuple module='typing', names=[ast.alias(name='NamedTuple', asname=None)], level=0), ] class_body = [] if record.doc is not None: class_body.append(docstring_declaration(record.doc)) new_frontier = [] fields = [] for field in record.fields: new_frontier.extend(locate_new_class_definitions(field.type)) field_def = ast.AnnAssign( target=ast.Name(id=field.name), annotation=resolve_field_type( field.type, required_imports=imports, ), value=None, # TODO - default value goes here simple=1, ) fields.append(field_def) class_body.extend(fields) class_body.append( ast.Assign( # _original_schema = "..." targets=[ast.Name(id='_original_schema')], value=ast.Str(s=json.dumps(record.original_schema)))) class_def = ast.ClassDef(name=record.name, bases=[ast.Name(id='NamedTuple')], keywords=[], body=class_body, decorator_list=[]) return ResolvedClassResult( resolved_class=class_def, imports=imports, new_frontier=new_frontier, )
def _create_property(self, prop: raml_types.Property): attribute_name = prop.attribute_name if not attribute_name: print( f"[ERROR]: '{self.resource.name}.{prop.name}' - No valid attribute_name" ) assert len(self.properties) == 1, self.properties return None annotation_type = self._get_annotation_for_property(prop) node = ast.AnnAssign( target=ast.Name(id=attribute_name), annotation=annotation_type, value=None, simple=1, ) return node
def visit_Assign(self, node): target = node.targets[0] # Assumes all targets have same annotation if isinstance(target, ast.Subscript): return node annotation = getattr(target, "annotation", False) if not annotation: return node if isinstance(annotation, ast.ClassDef): annotation = ast.Name(id=get_id(annotation)) col_offset = getattr(node, "col_offset", None) assigns = [] for assign_target in node.targets: definition = node.scopes.parent_scopes.find(get_id(assign_target)) if definition is None: definition = node.scopes.find(get_id(assign_target)) if definition is not assign_target: previous_type = get_inferred_type(definition) if get_id(previous_type) == get_id(annotation): if len(node.targets) == 1: return node else: new_node = ast.Assign( targets=[assign_target], value=node.value, lineno=node.lineno, col_offset=col_offset, ) assigns.append(new_node) continue new_node = ast.AnnAssign( target=assign_target, value=node.value, lineno=node.lineno, col_offset=col_offset, simple=True, annotation=annotation, ) assigns.append(new_node) if len(assigns) == 1: return assigns[0] return create_ast_block(body=assigns, at_node=node)
def visit_Field(self, node): target = ast.Name(node.name, ast.Store()) annotation = ast.Name(node.kind, ast.Load()) if node.qualifier is not None: if node.qualifier is pyasdl.FieldQualifier.SEQUENCE: qualifier = "List" elif node.qualifier is pyasdl.FieldQualifier.OPTIONAL: qualifier = "Optional" else: raise ValueError( f"Unexpected field qualifier: {node.qualifier}") annotation = ast.Subscript( value=ast.Attribute(_TYPING, qualifier, ast.Load()), slice=annotation, ctx=ast.Load(), ) return ast.AnnAssign(target, annotation, simple=1)
def expr_stmt_rewrite(lhs, ann, aug, aug_exp, rhs: t.Optional[list]): if rhs: as_store(lhs) *init, end = rhs for each in init: as_store(each) return ast.Assign([lhs, *init], end) if ann: as_store(lhs) anno, value = ann return ast.AnnAssign(lhs, anno, value, 1) if aug_exp: as_store(lhs) return ast.AugAssign(lhs, aug(), aug_exp) # NO AS STORE HERE! return ast.Expr(lhs)
def inline_axiom(function_def): function_args = [each.arg for each in function_def.args.args] function_name = function_def.name inline_function_def = copy.deepcopy(function_def) for arg in function_args: inline_function_def = InlineSubstitution(arg).visit(inline_function_def) ann_assigns = [] fresh_vars_assigns = [] for arg in function_args: ann_assigns.append(ast.AnnAssign(target=ast.Name(id='_'+arg, ctx=ast.Store()), value=None, annotation=ast.Name(id='PEGNode', ctx=ast.Load()), simple=1)) fresh_vars_assigns.append(ast.Assign(targets=[ast.Name(id='_'+arg+'_fresh', ctx=ast.Store())], value=ast.Name(id='_'+arg, ctx=ast.Load()))) function_body = inline_function_def.body ret_stmt = [stmt for stmt in function_body if isinstance(stmt, ast.Return)][0] function_body.remove(ret_stmt) retval = ret_stmt.value rhs_assignement = ast.Assign(targets=[ast.Name(id='rhs', ctx=ast.Store())], value=retval) call = ast.Call(func=ast.Name(id=function_name, ctx=ast.Store), args=[ast.Name(id='_' + a + '_fresh', ctx=ast.Load()) for a in function_args], keywords=[]) lhs_assignement = ast.Assign(targets=[ast.Name(id='lhs', ctx=ast.Store())], value=call) axiom_name = ast.Assign(targets=[ast.Name(id='axiom_name', ctx=ast.Store())], value=ast.Str(function_name + '-inline')) axiom_str = astor.to_source(ast.Module(body=[axiom_name] + ann_assigns + fresh_vars_assigns + function_body + [lhs_assignement, rhs_assignement])) return axiom_str
def p_expr_stmt4(self, p): ''' expr_stmt : testlist_star_expr annassign ''' target = ast_for_testlist(p[1]) if isinstance(target, ast.Name): simple = 1 elif isinstance(target, (ast.Attribute, ast.Subscript)): simple = 0 elif isinstance(target, (ast.Tuple, ast.List)): msg = "only single target (not tuple/list) can be annotated" syntax_error(msg, FakeToken(p.lexer.lexer, target.lineno)) else: msg = "illegal target for annotation" syntax_error(msg, FakeToken(p.lexer.lexer, target.lineno)) self.set_context(target, Store, p) assg = ast.AnnAssign() assg.target = target assg.annotation, assg.value = p[2] # simple is set to 1 for simple names (without parentheses) and is used # to know if the annotation should be stored on module or class. As # this analysis is painful we consider all ast.Name nodes as simple. assg.simple = simple p[0] = assg
def make_interaction(self, target, ann, value): if ann and isinstance(target, ast.Name): self.annotated[target.id] = ann ann_arg = ann if ann else ast.Constant(value=None) value_arg = self._absent() if value is None else value if isinstance(target, ast.Name): value_args = [ ast.Constant(value=target.id), ast.Constant(value=None), # self._absent(), ann_arg, self.fself(), value_arg, ] elif isinstance(target, ast.Subscript): value_args = [ ast.Constant(value=target.value.id), target.slice.value, ann_arg, self.fself(), value_arg, ] else: raise SyntaxError(target) new_value = ast.Call( func=ast.Name("__ptera_interact", ctx=ast.Load()), args=value_args, keywords=[], ) if ann is None: return [ast.Assign(targets=[target], value=new_value)] else: return [ ast.AnnAssign(target=target, value=new_value, annotation=ann, simple=True) ]
def visit_Field(self, node): target = ast.Name(node.name, ast.Store()) annotation = ast.Name(node.kind, ast.Load()) if node.qualifier is not None: if node.qualifier is pyasdl.FieldQualifier.SEQUENCE: qualifier = "List" default = ast.Call( _FIELD, [], [ ast.keyword( "default_factory", ast.Name("list", ast.Load()) ) ], ) elif node.qualifier is pyasdl.FieldQualifier.OPTIONAL: qualifier = "Optional" default = ast.Call( _FIELD, [], [ast.keyword("default", ast.Constant(None))] ) else: raise ValueError( f"Unexpected field qualifier: {node.qualifier}" ) annotation = ast.Subscript( value=ast.Attribute(_TYPING, qualifier, ast.Load()), slice=annotation, ctx=ast.Load(), ) else: # no-default! default = None if not self.with_defaults: default = None return ast.AnnAssign(target, annotation, default, simple=1)
def visit_ClassDef(self, node): self.className = node.name self.dispatch_flag = False newFunctionList = self.getDispatch() newNode = self.generic_visit(node) newBody = self.visit_body(node.body) needCommu = False for callee in calleeArr: if classArr.get(self.className) == 'Arduino' and (callee[1] == self.className or callee[2] == self.className): newBody.insert(0, ast.parse("_include = 'ArduinoJson.h'")) needCommu = True break newNode.body = newBody num = 0 for stmt in newNode.body: if type(stmt).__name__ == 'FunctionDef' and classArr.get(self.className) == 'Arduino' and needCommu: annAst = ast.AnnAssign(target = ast.Name(id = 'jsonBuffer', ctx = ast.Load()), annotation = ast.Name(id = 'DynamicJsonBuffer', ctx = ast.Load()), value = None, simple = 1) newNode.body.insert(num, annAst) # newNode.body.insert(num, ast.parse('_DynamicJsonBuffer_jsonBuffer')) # newNode.body.insert(num + 1, ast.Expr(value = ast.Name(id = '_JsonObject&_jsonObject', ctx = ast.Load()))) needCommu = False break else: num = num + 1 num = 0 if classArr.get(self.className) == 'Arduino': loopFunction = self.getLoop() for stmt in newNode.body: if type(stmt).__name__ == 'FunctionDef' and stmt.name == 'setup': newNode.body.insert(num + 1, loopFunction) break else: num = num + 1 num = 0 for stmt in newNode.body: if type(stmt).__name__ == 'FunctionDef': if classArr.get(self.className) == 'Arduino': num = num + 1 if stmt.name == 'loop': for newFunction in newFunctionList: newNode.body.insert(num, newFunction) num = num + 1 break else: for newFunction in newFunctionList: newNode.body.insert(num, newFunction) num = num + 1 break else: num = num + 1 for impStmt in replaceAST.importList: newNode.body.insert(0, ast.Import(names = [ast.alias(name = impStmt, asname = None)])) replaceAST.importList = [] newNode = ast.ClassDef(bases = node.bases, body = newNode, decorator_list = node.decorator_list, name = node.name) if self.dispatch_flag == True and classArr.get(self.className) != 'Arduino': if len(newFunctionList) > 1: num = 0 for newFunction in newFunctionList: newNode.body.body.append(ast.parse("thread"+ str(num) + " = threading.Thread(target = " + newFunction.name + ", args = ())")) num = num + 1 for n in range(0, num): newNode.body.body.append(ast.parse("thread" + str(n) + ".start()")) for n in range(0, num): newNode.body.body.append(ast.parse("thread" + str(n) + ".join()")) else: for newFunction in newFunctionList: newNode.body.body.append(ast.parse(newFunction.name + "()")) # dispatchValue = ast.Call(args = [], func = ast.Name(id='dispatch', ctx=ast.Load()), keywords = []) # dispatchCall = ast.Assign(targets = [ast.Name(id='_firstCall', ctx = ast.Store())], value = dispatchValue) # newNode.body.body.append(dispatchCall) return newNode
def getCommuNode(self, callee, caller, ifNode): calleeClass = classArr.get(callee) callerClass = classArr.get(caller) comm = commuTable.get(callerClass).get(calleeClass) newCommu = [] if comm == 'Serial': if calleeClass == 'Arduino': newCommu.append(ast.parse('str: String = ""')) bodySource = "if Serial.available() > 0:\n" + "\tstr = Serial.readStringUntil(char('\\n'))\n" newCommu.append(ast.parse("funid: int = 0")) newCommu.append(ast.parse(bodySource)) ifBodyAst = [] valueAst = ast.Call(args = [ast.Name(id = "str", ctx = ast.Load())], func = ast.Attribute(attr = "parseObject", ctx = ast.Load(), value = ast.Name(id = "jsonBuffer", ctx = ast.Load())), keywords = [], kwargs = None, starargs = None) ifBodyAst.append(ast.AnnAssign(target = [ast.Name(id="jsonObject", ctx = ast.Load())], annotation = ast.Name(id = "JsonObject", ctx = ast.Load()), value = valueAst, simple = 1)) ifBodyAst.append(ast.parse("funid = jsonObject['_funid']")) newCommu.append(ast.If(test = ast.Compare(comparators = [ast.Str(s = "")], left = ast.Name(id = "str", ctx = ast.Load()), ops = [ast.NotEq()]), body = ifBodyAst, orelse = [])) newCommu.append(ifNode) newCommu.append(ast.parse('funid = -1')) return newCommu elif calleeClass == 'Raspberry': newCommu.append(ast.parse('global _ser, _jsonData')) newCommu.append(ast.parse('_ser = serial.Serial("/dev/ttyACM0", 9600)')) whileBody = [] whileBody.append(ast.parse('jsonStr = _ser.readline().strip().decode("utf-8")')) whileBody.append(ast.parse('if jsonStr == "":\n\tcontinue')) whileBody.append(ast.parse('_jsonData = json.loads(jsonStr)')) whileBody.append(ast.parse('funid = _jsonData["_funid"]')) whileBody.append(ifNode) whileBody.append(ast.parse('funid = -1')) whileNode = ast.While(test = ast.Name(id = 'True', ctx = ast.Load()), body = whileBody, orelse = []) newCommu.append(whileNode) return newCommu elif comm == 'Socket': if calleeClass == 'Raspberry': newCommu.append(ast.parse('global _conn')) newCommu.append(ast.parse('s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)')) newCommu.append(ast.parse('s.bind((HOST, PORT))')) newCommu.append(ast.parse('s.listen(1)')) whileBody = [] whileBody.append(ast.parse('_conn, addr = s.accept()')) whileBody.append(ast.parse('global _recieveJsonData')) whileBody.append(ast.parse('_recieveData = ""')) whileBody.append(ast.parse('_cnt = 0')) source = "while True:\n" source += "\ttmp = _conn.recv(1).decode('utf-8')\n" + "\t_recieveData += tmp\n" source += "\tif tmp == '{':\n" + "\t\t_cnt = _cnt + 1\n" + "\telif tmp == '}':\n" + "\t\t_cnt = _cnt - 1\n" source += "\tif _cnt == 0:\n" + "\t\tbreak\n" whileBody.append(ast.parse(source)) whileBody.append(ast.parse('if _recieveData == "":\n\tcontinue\n')) whileBody.append(ast.parse('_recieveJsonData = json.loads(_recieveData)')) whileBody.append(ast.parse('funid = _recieveJsonData["_funid"]')) whileBody.append(ifNode) whileBody.append(ast.parse('funid = -1')) whileNode = ast.While(test = ast.Name(id='True', ctx = ast.Load()), body = whileBody, orelse = []) newCommu.append(whileNode) return newCommu elif calleeClass == 'Mobile': newCommu.append(ast.parse('global _conn')) newCommu.append(ast.parse('s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)')) newCommu.append(ast.parse('s.bind((HOST, PORT))')) newCommu.append(ast.parse('s.listen(1)')) whileBody = [] whileBody.append(ast.parse('_conn, addr = s.accept()')) source = "while True:\n" source += "\ttmp = _conn.recv(1).decode('utf-8')\n" + "\t_recieveData += tmp\n" source += "\tif tmp == '{':\n" + "\t\t_cnt = _cnt + 1\n" + "\telif tmp == '}':\n" + "\t\t_cnt = _cnt - 1\n" source += "\tif _cnt == 0:\n" + "\t\tbreak\n" whileBody.append(ast.parse(source)) whileBody.append(ifNode) whileBody.append(ast.parse('funid = -1')) whileNode = ast.While(test = ast.Name(id = 'True', ctx = ast.Load()), body = whileBody, orelse = []) newCommu.append(whileNode) return newCommu elif comm == 'http': if calleeClass == 'Cloud': newCommu.append(ast.parse('funid = int(sys.argv[1])')) newCommu.append(ifNode) return newCommu elif calleeClass == 'Mobile': newCommu.append(ifNode) return newCommu elif comm == 'Bluetooth': newCommu.append(ifNode) return newCommu else: print ("Not Supported Communication way") return newCommu
def make_serialize_query_params(self, method: ServiceMethod, node, module_name: str): """Code to serialize optional parameters to the `params` dict passed to the client post/get call. This method might also optionally generate a marshmallow schema where it uses the various traits as base classes. """ query_params = { param.name: param for param in method.query_params if param.type != "file" } # TODO: This should be fixed in the raml specifications since version is # part of the body and not part of the query parmaters for update calls if method.type == "update" and "version" in query_params: del query_params["version"] # If this method doesn't accept parameters we just exit early with a # `params = {}` line. if not query_params: line = ast.AnnAssign( target=ast.Name(id="params"), annotation=ast.Subscript( value=ast.Attribute(value=ast.Name(id="typing"), attr="Dict"), slice=ast.Index(value=ast.Tuple( elts=[ast.Name( id="str"), ast.Name(id="str")])), ), value=ast.Dict(keys=[], values=[]), simple=True, ) node.body.append(line) return bases = [] for trait in method.traits: if trait.params: bases.append(ast.Name(id="traits.%sSchema" % trait.class_name)) # Generate a custom schema if required if method.extra_params or len(bases) != 1: if method.type != "action": schema_name = f"_{method.context_name}{method.type.title()}Schema" else: schema_name = f"_{method.context_name}{method.name.title()}Schema" if not bases: self.add_import_statement(module_name, "marshmallow", "fields") self.add_import_statement(module_name, "marshmallow") bases = [ ast.Name(id="marshmallow.Schema"), ast.Name(id="RemoveEmptyValuesMixin"), ] schema_node = ast.ClassDef(name=schema_name, bases=bases, keywords=[], decorator_list=[], body=[]) # Marshmallow field definitions schema_methods = [] for param in method.extra_params: # We skip files since we post the value in the request body if param.type == "file": continue field_node, methods, imports = _create_schema_field(param) if field_node: schema_node.body.append(field_node) schema_methods.extend(methods) for import_ in imports: self.add_import_statement(module_name, *import_) schema_node.body.extend(schema_methods) if not schema_node.body: schema_node.body.append(ast.Pass()) self.add_schema(method.context_name, schema_node) else: schema_name = bases[0].id # params = self._serialize_params({}, schema) input_params = [] for key, param in query_params.items(): if key.startswith("/"): key = snakeit( param.extra_data["(placeholderParam)"]["paramName"]) input_params.append(snakeit(key)) line = ast.Assign( targets=[ast.Name(id="params")], value=ast.Call( func=ast.Attribute(value=ast.Name(id="self"), attr="_serialize_params"), args=[ ast.Dict( keys=[ast.Str(s=val, kind="") for val in input_params], values=[ast.Name(id=val) for val in input_params], ), ast.Name(id=schema_name), ], keywords=[], ), ) node.body.append(line)
def visitAssign(self, node): return ast.AnnAssign(ast.Name("foo", ast.Store), ast.Str("foo"), ast.Num(1), True)
ast.AsyncFunctionDef(body=[]), ast.arguments( defaults=[1], posonlyargs=[], args=[], kw_defaults=[], kwonlyargs=[], ), ast.arguments( defaults=[], posonlyargs=[], args=[], kw_defaults=[1], kwonlyargs=[], ), ast.AnnAssign(simple=True, target=ast.Tuple(ast.Name("a", ast.Load()))), ast.With(items=[]), ast.Raise(exc=None, cause=1), ast.Try(body=[]), ast.Try(body=[ast.Pass()], handlers=[], finalbody=[]), ast.Try( body=[ast.Pass()], handlers=[], finalbody=[ast.Pass()], orelse=[ast.Pass()], ), ast.ImportFrom(level=-1, names=[1]), ast.BoolOp(values=[1]), ast.Dict(keys=[1], values=[]), ast.Compare(comparators=[]), ast.Compare(comparators=[1], ops=[]),
def required_element(name, type): target = ast.Name(id=name) annotation = ast.Name(id=type) return ast.AnnAssign(target=target, annotation=annotation, simple=1)
def optional_element(name, type): target = ast.Name(id=name) annotation = ast.Subscript(value=ast.Name(id=OPTIONAL), slice=ast.Name(id=type)) return ast.AnnAssign(target=target, annotation=annotation, simple=1)
def AnnAssign(draw) -> ast.AnnAssign: target = draw(Name(ast.Store)) return ast.AnnAssign(target=target, annotation=draw(expression()), value=draw(expression()), simple=True)
def sync_property( input_eval, input_param, input_ast, input_filename, output_param, output_param_wrap, output_ast, ): """ Sync a single property :param input_eval: Whether to evaluate the `param`, or just leave it :type input_eval: ```bool``` :param input_param: Location within file of property. Can be top level like `'a'` for `a=5` or with the `.` syntax as in `output_params`. :type input_param: ```List[str]``` :param input_ast: AST of the input file :type input_ast: ```AST``` :param input_filename: Filename of the input (used in `eval`) :type input_filename: ```str``` :param output_param: Parameters to update. E.g., `'A.F'` for `class A: F = None`, `'f.g'` for `def f(g): pass` :type output_param: ```str``` :param output_param_wrap: Wrap all input_str params with this. E.g., `Optional[Union[{output_param}, str]]` :param output_param_wrap: ```Optional[str]``` :param output_ast: AST of the input file :type output_ast: ```AST``` :return: New AST derived from `output_ast` :rtype: ```AST``` """ search = list(strip_split(output_param, ".")) if input_eval: if input_param.count(".") != 0: raise NotImplementedError("Anything not on the top-level of the module") local = {} output = eval(compile(input_ast, filename=input_filename, mode="exec"), local) assert output is None replacement_node = ast.AnnAssign( annotation=it2literal(local[input_param]), simple=1, target=ast.Name( # input_param search[-1], ast.Store(), ), value=None, expr=None, expr_annotation=None, expr_target=None, ) else: annotate_ancestry(input_ast) assert isinstance(input_ast, ast.Module) replacement_node = find_in_ast(list(strip_split(input_param, ".")), input_ast) assert replacement_node is not None if output_param_wrap is not None: if hasattr(replacement_node, "annotation"): if replacement_node.annotation is not None: replacement_node.annotation = ( ast.parse( output_param_wrap.format( output_param=to_code(replacement_node.annotation) ) ) .body[0] .value ) else: raise NotImplementedError(type(replacement_node).__name__) rewrite_at_query = RewriteAtQuery( search=search, replacement_node=replacement_node, ) gen_ast = rewrite_at_query.visit(output_ast) assert rewrite_at_query.replaced is True, "Failed to update with {!r}".format( to_code(replacement_node) ) return gen_ast