Пример #1
0
def collect_gen_expr(statement_info):        
    expressions = []
    # Join all of the constant expressions into a single GeneralExpression.
    constant_names = []
    lines = []
    for names, node in statement_info.constant_expressions:
        lines.append(unparse(node))
        # Inform the statement of the variables it is writing to.
        constant_names.extend(names)
    if lines:
        ge = GeneralExpression()
        ge.code = ''.join(lines)
        expressions.append(ge)

    for node in statement_info.general_assignments:
        ge = GeneralExpression()
        ge.code = unparse(node)
        # Now check this expression for any inputs that are provided by the
        # import statements we had. If so, add that import statement to the
        # object and remove that input.
        imported_inputs = []
        for iv in ge.inputs:
            node = statement_info.import_statements.get(iv.binding, None)
            if node is not None:
                ge.import_statements.append(unparse(node))
                imported_inputs.append(iv)
        for iv in imported_inputs:
            ge.inputs.remove(iv)
        expressions.append(ge)
    return expressions
Пример #2
0
    def test_multi_line_partial_delete_block_update(self):
        code = "x=1\ny=2+x\nz=3"

        block = Block(code)
        code_block = CodeBlock(code=code)

        new_code="x=1\ny=2"

        code_block.code = new_code

        self.assertEqual(len(code_block.block.ast.nodes), 2)
        self.assertEqual(unparse(code_block.block.ast.nodes[0]).strip(), "x = 1")
        self.assertEqual(unparse(code_block.block.ast.nodes[1]).strip(), "y = 2")
Пример #3
0
    def test_block_static(self):
        """ Tests if a block changes if a line does not change """
        code = "x=1\ny=2\nz=3"

        block = Block(code)
        code_block = CodeBlock(code=code)

        new_code="x=1\ny=2"

        old_block = code_block.block.sub_blocks[0]
        code_block.code = new_code
        new_block = code_block.block.sub_blocks[0]

        self.assertEqual(unparse(old_block.ast), unparse(new_block.ast))
        self.assertEqual(old_block.uuid, new_block.uuid)
Пример #4
0
def _get_keyword_defaults(default_nodes, func_name):
    """ Translate the default nodes of an ast into default arguments.
    """
    # Unwrap the default values.
    # fixme: We could stand better warning messages here.
    defaults=[]
    for node in default_nodes:
        # fixme
        if isinstance(node, compiler.ast.Const):
            default = str(node.value)
        elif isinstance(node, compiler.ast.Name):
            if node.name in ["None", "True", "False"]:
                default = node.name
            else:    
                msg = "Got variable name for keyword value in " \
                      "function: %s.  Using its name: %s" % \
                      (func_name, node.name)
                warnings.warn(msg)
                default = node.name
        else:
            # Try unparsing and evaluating it.  This will work if
            # the value is something like "-1.0".  If we fail for
            # any reason, issue a warning and use undefined as the
            # value.
            try:
                default = unparse(node)
            except:   
                msg = "Got '%s' node for keyword value in function." \
                      "  Using None as a stopgap." % node
                warnings.warn(msg)
                default = None
                
        defaults.append(default)                    
        
    return defaults
Пример #5
0
    def test_block_static_special_case(self):
        """ Tests if a block changes if a line does not change when its the only line unchanged """
        code = "x=1\ny=2+x\nz=3"

        block = Block(code)
        code_block = CodeBlock(code=code)

        old_ast = code_block.block.ast
        old_block = code_block.block.sub_blocks[0]

        new_code="x=1\ny=2"
        code_block.code = new_code
        new_block = code_block.block.sub_blocks[0]

        self.assertNotEqual(unparse(old_ast), unparse(code_block.block.ast))
        self.assertEqual(unparse(old_block.ast), unparse(new_block.ast))
        self.assertEqual(old_block.uuid, new_block.uuid)
Пример #6
0
 def test_block_name_replacer(self):
     """ Does BlockNameReplacer work?
     """
     code = "x = x(x, x)\nx\n"
     desired = "y = y(y, y)\ny\n"
     b = Block(code)
     rename_variable(b.ast, 'x', 'y')
     self.assertEqual(desired, unparse(b.ast))
Пример #7
0
    def test_block_decomposition(self):
        """ Tests if a block changes if its the only line left """

        code = "x=1\ny=2"

        block = Block(code)
        code_block = CodeBlock(code=code)

        old_ast = code_block.block.ast
        old_block = code_block.block.sub_blocks[0]

        new_code="x=1"
        code_block.code = new_code
        new_block = code_block.block.sub_blocks[0]

        self.assertNotEqual(unparse(old_ast), unparse(code_block.block.ast))
        self.assertEqual(unparse(old_block.ast), unparse(new_block.ast))
        self.assertEqual(old_block.uuid, new_block.uuid)
Пример #8
0
    def _get_imports_and_locals(self):
        """ Generate the import statements and local definitions  
            Should we worry about the order of the imports?
        """

        local_funcs = []
        imports = {}
        #        function_calls = [statement for statement in self.statements \
        #                               if isinstance(statement, FunctionCall) ]
        #        
        #        # Function calls merged into a group 
        #        for stmt in self.statements:
        #            if isinstance(stmt, FunctionCallGroup):
        #                for statement in stmt.group_statements:
        #                    function_calls.append(statement)
                
        
        function_calls = explode_model_func_calls(self.statements)
                
        info_items = set([(call.label_name, call.function) for call in function_calls])
        for name, func in info_items:
            if isinstance(func, PythonFunctionInfo):
                # This function is imported
                # FIXME - Need to be able to handle 'as' names.
                # If a function has an 'as' name, then it shouldn't be added
                # to the imports dictionary.
                module = func.module
                if imports.has_key(module):
                    imports[module].append(name)
                else:
                    imports[module] = [name]
            elif isinstance(func, LocalFunctionInfo):
                local_funcs.append(func.code + '\n')

        import_lines = []
        for module in imports:
            names = []
            for name in imports[module]:
                names.append((name, None))
            import_lines.append(unparse(From(module, names, 0)))

        # Get the import statements from GeneralExpressions.
        for stmt in self.statements:
            if isinstance(stmt, GeneralExpression):
                import_lines.extend(stmt.import_statements)

        # Uniquify the import list while maintaining order.
        seen = set()
        unique_lines = []
        for line in import_lines:
            if line not in seen:
                unique_lines.append(line)
                seen.add(line)

        return ''.join(unique_lines) + '\n' + ''.join(local_funcs)
Пример #9
0
    def save_block_to_file(self, file_path):
        """ Save the block to a file as python code.
        """
        # We convert the block to code directly instead of using the
        # code displayed, because the user may have put it in an unparsable
        # state.
        # fixme: Is this what we should do?

        # Should write it out as .py file
        split_path = os.path.splitext(file_path)
        if split_path[1] != 'py':
            new_path = '.'.join((split_path[0], 'py'))
        else:
            new_path = file_path

        # Save the current code to the file.
        file_obj = open(new_path, 'w')
        block_code = unparse(self.block_unit.codeblock.block.ast)
        file_obj.write(block_code)
        file_obj.close()

        # And point at the new path name.
        self.file_path = new_path
        return
Пример #10
0
 def from_function_ast(cls, function_ast):
     code = unparse(function_ast)
     return cls(code=code)
Пример #11
0
 def visitFrom(self, node):
     if node.names[0][0] == '*':
         raise ValueError('cannot deal * imports: %s' % unparse(node))
     for name, alias in node.names:
         self.import_statements[(alias or name)] = node
Пример #12
0
 def visitFrom(self, node):
     if node.names[0][0] == '*':
         raise ValueError('cannot deal * imports: %s' % unparse(node))
     for name, alias in node.names:
         self.imported_names.append(alias or name)