def __remove_type_from_union_implementation(if_test, type_, lineno, col_offset): param = __get_idiom_type_param(if_test) if type(param) is ast.Name: obj_type, obj_var = stypy_functions_copy.create_get_type_of( param.id, lineno, col_offset) remove_type_call = functions_copy.create_call( core_language_copy.create_Name("remove_type_from_union"), [obj_var, type_], line=lineno, column=col_offset) set_type = stypy_functions_copy.create_set_type_of( param.id, remove_type_call, lineno, col_offset) return stypy_functions_copy.flatten_lists(obj_type, set_type) if type(param) is ast.Attribute: # Get the owner of the attribute obj_type_stmts, obj_var = stypy_functions_copy.create_get_type_of( param.value.id, lineno, col_offset) # Get the current type of the owner of the attribute att_type_stmts, att_var = stypy_functions_copy.create_get_type_of_member( obj_var, param.attr, lineno, col_offset) remove_type_call = functions_copy.create_call( core_language_copy.create_Name("remove_type_from_union"), [att_var, type_], line=lineno, column=col_offset) set_member = stypy_functions_copy.create_set_type_of_member( obj_var, param.attr, remove_type_call, lineno, col_offset) return stypy_functions_copy.flatten_lists(obj_type_stmts, att_type_stmts, set_member) return []
def create_type_store(type_store_name=default_module_type_store_var_name): call_arg = core_language_copy.create_Name("__file__") call_func = core_language_copy.create_Name("TypeStore") call = functions_copy.create_call(call_func, call_arg) assign_target = core_language_copy.create_Name(type_store_name, False) assign = core_language_copy.create_Assign(assign_target, call) return assign
def create_default_return_variable(): """ Creates AST Nodes that adds the default return variable to a function. Functions of generated type inference programs only has a return clause """ assign_target = core_language_copy.create_Name( default_function_ret_var_name, False) assign = core_language_copy.create_Assign( assign_target, core_language_copy.create_Name("None")) return assign
def create_localization(line, col): """ Creates AST Nodes that creates a new Localization instance """ linen = core_language_copy.create_num(line) coln = core_language_copy.create_num(col) file_namen = core_language_copy.create_Name('__file__') loc_namen = core_language_copy.create_Name( 'stypy.python_lib.python_types.type_inference.localization.Localization' ) loc_call = functions_copy.create_call(loc_namen, [file_namen, linen, coln]) return loc_call
def create_function_def(name, localization, decorators, context, line=0, column=0): """ Creates a FunctionDef node, that represent a function declaration. This is used in type inference code, so every created function has the following parameters (type_of_self, localization, *varargs, **kwargs) for methods and (localization, *varargs, **kwargs) for functions. :param name: Name of the function :param localization: Localization parameter :param decorators: Decorators of the function, mainly the norecursion one :param context: Context passed to this method :param line: Line :param column: Column :return: An AST FunctionDef node """ function_def_arguments = ast.arguments() function_def_arguments.args = [localization] isconstructor = is_constructor(name) ismethod = is_method(context) function_def = ast.FunctionDef() function_def.lineno = line function_def.col_offset = column function_def.name = name function_def.args = function_def_arguments function_def_arguments.args = [] if isconstructor: function_def_arguments.args.append(core_language_copy.create_Name('type_of_self')) if ismethod and not isconstructor: function_def_arguments.args.append(core_language_copy.create_Name('type_of_self')) function_def_arguments.args.append(localization) function_def_arguments.kwarg = "kwargs" function_def_arguments.vararg = "varargs" function_def_arguments.defaults = [] if data_structures_copy.is_iterable(decorators): function_def.decorator_list = decorators else: function_def.decorator_list = [decorators] function_def.body = [] return function_def
def create_set_type_store(type_store_param, clone=True): attribute = core_language_copy.create_attribute("type_store", "set_type_store") if clone: clone_param = core_language_copy.create_Name("True") else: clone_param = core_language_copy.create_Name("False") set_call = functions_copy.create_call(attribute, [type_store_param, clone_param]) set_expr = ast.Expr() set_expr.value = set_call return set_expr
def create_unary_operator(op_name, op, line=0, column=0): localization = stypy_functions_copy.create_localization(line, column) unop_func = core_language_copy.create_Name("operator") unop = functions_copy.create_call(unop_func, [localization, op_name, op]) return unop
def create_get_type_of_member(owner_var, member_name, lineno, col_offset, test_unreferenced=True): comment = create_src_comment( "Obtaining the member '{0}' of a type".format(member_name), lineno) localization = create_localization(lineno, col_offset) # TODO: Remove? # get_type_of_member_func = core_language_copy.create_Name('get_type_of_member') # get_type_of_member_call = functions_copy.create_call(get_type_of_member_func, [localization, owner_var, # core_language_copy.create_str( # member_name)]) get_type_of_member_func = core_language_copy.create_attribute( owner_var, 'get_type_of_member') if not test_unreferenced: get_type_of_member_call = functions_copy.create_call( get_type_of_member_func, [ localization, core_language_copy.create_str(member_name), core_language_copy.create_Name('False') ]) else: get_type_of_member_call = functions_copy.create_call( get_type_of_member_func, [localization, core_language_copy.create_str(member_name)]) member_stmts, member_var = create_temp_Assign(get_type_of_member_call, lineno, col_offset) return flatten_lists(comment, member_stmts), member_var
def create_get_type_of(var_name, lineno, col_offset, test_unreferenced=True): get_type_of_comment = create_src_comment( "Getting the type of '{0}'".format(var_name), lineno) get_type_of_method = core_language_copy.create_attribute( default_module_type_store_var_name, "get_type_of", line=lineno, column=col_offset) localization = create_localization(lineno, col_offset) if test_unreferenced: get_type_of_call = functions_copy.create_call( get_type_of_method, [localization, core_language_copy.create_str(var_name)]) else: get_type_of_call = functions_copy.create_call(get_type_of_method, [ localization, core_language_copy.create_str(var_name), core_language_copy.create_Name('False') ]) assign_stmts, temp_assign = create_temp_Assign(get_type_of_call, lineno, col_offset) return flatten_lists(get_type_of_comment, assign_stmts), temp_assign
def assign_as_return_type(value): """ Creates AST nodes to store in default_function_ret_var_name a possible return type """ default_function_ret_var = core_language_copy.create_Name( default_function_ret_var_name) return core_language_copy.create_Assign(default_function_ret_var, value)
def create_binary_operator(op_name, op1, op2, line=0, column=0): localization = stypy_functions_copy.create_localization(line, column) binop_func = core_language_copy.create_Name("operator") binop = functions_copy.create_call(binop_func, [localization, op_name, op1, op2]) return binop
def create_join_type_store(join_func_name, type_stores_to_join): join_func = core_language_copy.create_Name(join_func_name) join_call = functions_copy.create_call(join_func, type_stores_to_join) left_hand_side = __new_temp_type_store_Name(right_hand_side=False) join_statement = ast.Assign([left_hand_side], join_call) return join_statement, left_hand_side
def create_print_var(variable): """ Creates a node to print a variable """ node = ast.Print() node.nl = True node.dest = None node.values = [core_language_copy.create_Name(variable)] return node
def new_temp_Name(right_hand_side=True, descriptive_var_name="", lineno=0, col_offset=0): """ Creates an AST Name node with a suitable name for a new temp variable. If descriptive_var_name has a value, then this value is added to the variable predefined name """ return core_language_copy.create_Name(__new_temp_str(descriptive_var_name), right_hand_side, lineno, col_offset)
def create_return_from_function(lineno, col_offset): """ Creates an AST node to return from a function """ return_ = ast.Return() return_var_name = core_language_copy.create_Name( default_function_ret_var_name) return_.value = return_var_name return flatten_lists(return_)
def create_set_unreferenced_var_check(state): if ENABLE_CODING_ADVICES: attribute = core_language_copy.create_attribute( "type_store", "set_check_unreferenced_vars") call_ = functions_copy.create_call_expression( attribute, [core_language_copy.create_Name(str(state))]) return call_ else: return []
def create_unsupported_feature_call(localization, feature_name, feature_desc, lineno, col_offset): """ Creates AST nodes to call to the unsupported_python_feature function """ unsupported_feature_func = core_language_copy.create_Name( 'unsupported_python_feature', line=lineno, column=col_offset) unsupported_feature = core_language_copy.create_str(feature_name) unsupported_description = core_language_copy.create_str(feature_desc) return functions_copy.create_call_expression( unsupported_feature_func, [localization, unsupported_feature, unsupported_description])
def create_store_return_from_function(lineno, col_offset): set_type_of_comment = create_src_comment("Storing return type", lineno) set_type_of_method = core_language_copy.create_attribute( default_module_type_store_var_name, "store_return_type_of_current_context") return_var_name = core_language_copy.create_Name( default_function_ret_var_name) set_type_of_call = functions_copy.create_call_expression( set_type_of_method, [return_var_name]) return flatten_lists(set_type_of_comment, set_type_of_call)
def create_stacktrace_push(func_name, declared_arguments): """ Creates an AST Node that model the call to the localitazion.set_stack_trace method :param func_name: Name of the function that will do the push to the stack trace :param declared_arguments: Arguments of the call :return: An AST Expr node """ # Code to push a new stack trace to handle errors. attribute = core_language_copy.create_attribute("localization", "set_stack_trace") arguments_var = core_language_copy.create_Name("arguments") stack_push_call = create_call(attribute, [core_language_copy.create_str(func_name), declared_arguments, arguments_var]) stack_push = ast.Expr() stack_push.value = stack_push_call return stack_push
def create_original_code_comment(file_name, original_code): """ Creates a Python block comment with the original source file code """ # Remove block comments, as this code will be placed in a block comment original_code = original_code.replace("\"\"\"", "'''") numbered_original_code = ModuleLineNumbering.put_line_numbers_to_module_code( file_name, original_code) comment_txt = core_language_copy.create_Name( "\"\"\"\nORIGINAL PROGRAM SOURCE CODE:\n" + numbered_original_code + "\n\"\"\"\n") initial_comment = ast.Expr() initial_comment.value = comment_txt return initial_comment
def create_type_for_lambda_function(function_name, lambda_call, lineno, col_offset): """ Creates a variable to store a lambda function definition :param function_name: Name of the lambda function :param lambda_call: Lambda function :param lineno: Line :param col_offset: Column :return: Statements to create the lambda function type """ # TODO: Remove? # call_arg = core_language.create_Name(lambda_call) # call_func = core_language.create_Name("LambdaFunctionType") # call = create_call(call_func, call_arg) # assign_target = core_language.create_Name(lambda_call, False) # assign = core_language.create_Assign(assign_target, call) call_arg = core_language_copy.create_Name(lambda_call) set_type_stmts = stypy_functions_copy.create_set_type_of(function_name, call_arg, lineno, col_offset) # return stypy_functions.flatten_lists(assign, set_type_stmts) return stypy_functions_copy.flatten_lists(set_type_stmts)
def __create_src_comment(comment_txt): comment_node = core_language_copy.create_Name(comment_txt) comment_expr = ast.Expr() comment_expr.value = comment_node return comment_expr
def create_arg_number_test(function_def_node, context=[]): """ Creates an AST Node that model the call to the process_argument_values method. This method is used to check the parameters passed to a function/method in a type inference program :param function_def_node: AST Node with the function definition :param context: Context passed to the call :return: List of AST nodes that perform the call to the mentioned function and make the necessary tests once it is called """ args_test_resul = core_language_copy.create_Name('arguments', False) # Call to arg test function func = core_language_copy.create_Name('process_argument_values') # Fixed parameters localization_arg = core_language_copy.create_Name('localization') type_store_arg = core_language_copy.create_Name('type_store') # Declaration data arguments # Func name if is_method(context): function_name_arg = core_language_copy.create_str(context[-1].name + "." + function_def_node.name) type_of_self_arg = core_language_copy.create_Name('type_of_self') else: function_name_arg = core_language_copy.create_str(function_def_node.name) type_of_self_arg = core_language_copy.create_Name('None') # Declared param names list param_names_list_arg = obtain_arg_list(function_def_node.args, is_method(context), is_static_method(function_def_node)) # Declared var args parameter name if function_def_node.args.vararg is None: declared_varargs = None else: declared_varargs = function_def_node.args.vararg varargs_param_name = core_language_copy.create_str(declared_varargs) # Declared kwargs parameter name if function_def_node.args.kwarg is None: declared_kwargs = None else: declared_kwargs = function_def_node.args.kwarg kwargs_param_name = core_language_copy.create_str(declared_kwargs) # Call data arguments # Declared defaults list name call_defaults = core_language_copy.create_Name('defaults') # function_def_node.args.defaults # Call varargs call_varargs = core_language_copy.create_Name('varargs') # Call kwargs call_kwargs = core_language_copy.create_Name('kwargs') # Parameter number check call call = create_call(func, [localization_arg, type_of_self_arg, type_store_arg, function_name_arg, param_names_list_arg, varargs_param_name, kwargs_param_name, call_defaults, call_varargs, call_kwargs]) assign = core_language_copy.create_Assign(args_test_resul, call) # After parameter number check call argument_errors = core_language_copy.create_Name('arguments') is_error_type = core_language_copy.create_Name('is_error_type') if_test = create_call(is_error_type, argument_errors) if is_constructor(function_def_node): argument_errors = None # core_language.create_Name('None') body = [create_context_unset(), create_return(argument_errors)] if_ = conditional_statements_copy.create_if(if_test, body) return [assign, if_]