예제 #1
0
    def parse(self, node: ast.Call, module: Module, context: Context):
        """Process a ``ast.Call`` node and extract relevant stats.

        A ``ast.Call`` node has the following fields:

            - ``func`` that represents the function, which will often be a ``ast.Name`` or ``ast.Attribute`` node
            - ``args`` that represents a list of the arguments passed by position
            - ``keywords`` that represents a list of keyword objects representing arguments passed by keyword
            - ``starargs`` holds a single node, for arguments passed as *args. This is removed in Python 3.5.
            - ``kwargs`` holds a single node, for arguments passed as **kwargs. This is removed in Python 3.5.

        :param node: The node that represents a call expression.
        :param module: The python module where this call is encountered.
        :param context: The context of the given node.
        :return: The CallEntity instance created from the given ``ast.Call`` node.
        """
        call: CallEntity = CallEntity(node, context)
        context.stack_ast_node(call)

        super().parse(node, module, context)

        context.unstack_ast_node()
        module.add_call(call)

        return call
예제 #2
0
    def parse(self, node: ast.Starred, module: Module, context: Context):
        """Parse the value type of the ``ast.Starred`` node.

        Typically, the value is going to be a ``ast.Name`` node, but might be
        something else, although it's very improbable.

        Still, something like the following is valid Python code and will get executed ::

            def f1():
                return [1, 2, 3]

            def f2(*args):
                for arg in args:
                    print(arg)

            f2(*f1())

        The above example will yield ::

            1
            2
            3
        """
        starred_variable: StarredEntity = StarredEntity(node)
        context.stack_ast_node(starred_variable)

        parser = self.get_parser(node.value)
        entity = parser.parse(node.value, module, context)
        starred_variable.set_value_entity(entity)

        context.unstack_ast_node()
        module.add_starred_variable(starred_variable)

        return starred_variable
예제 #3
0
    def parse(self, node: Any, module: Module, context: Context):
        """Process one of `[ast.List, ast.Tuple]` nodes and extract relevant stats.

        Tuple and List nodes have two fields:
            - `elts` that represents the elements of the array
            - `ctx` that represents the context under which the array is used (Store or Load)
        """
        entity = self.create_new_entity(node)
        context.stack_ast_node(entity)

        # if isinstance(node.ctx, ast.Store):
        #     context[UNPACKING_VALUES] = True

        # existing_context = set()
        # for key in context:
        #     if key in IS_PART_OF_MAPPER:
        #         existing_context.add(IS_PART_OF_MAPPER[key])
        #
        # # create a hierarchy of which
        # if self.node_type not in context:
        #     context[self.node_type] = ''
        #     delimiter = ''
        #     last_node_type_appearance = 0
        # else:
        #     delimiter = '_'
        #     last_node_type_appearance = len(context[self.node_type].split('_')) - 1  # remove 1 that is going to be accounted for in the intersection statement
        #
        # context[self.node_type] = f'{context[self.node_type]}' \
        #                           f'{delimiter}' \
        #                           f'{len(existing_context.intersection(COMPLEX_DATA_TYPES)) + 1 + last_node_type_appearance}'

        for element in node.elts:
            parser = self.get_parser(element)
            element_entity = parser.parse(element, module, context)
            entity.add_element(element_entity)

        context.unstack_ast_node()

        self.add_entity_to_module(entity, module, context)

        return entity
예제 #4
0
    def parse(self, node: ast.Assign, module: Module, context: Context):
        """Process an `ast.Assign` node and extract relevant stats.

        An ``ast.Assign`` node has two fields:
            - ``targets`` that represents a list of nodes
            - ``value`` that is a single node that is assigned to targets

        :param node: The node that represents an assignment operation.
        :param module: The python module where this variable is encountered.
        :param context: The context of the given node.
        :return: The AssignmentEntity instance created from the given ``ast.Assign`` node.
        """
        assignment = AssignmentEntity(node)
        context.stack_ast_node(assignment)

        super().parse(node, module, context)

        context.unstack_ast_node()
        module.add_assignment(assignment)

        return assignment
예제 #5
0
    def parse(self, node: Any, module: Module, context: Context):
        """Process a ``ast.IfExp`` node and extract relevant stats.

        A ``ast.IfExp`` node has the following fields:

            - ``test`` that represents the condition to be evaluated
            - ``body`` that represents the value to be assigned in case the condition evaluates to true
            - ``orelse`` that represents the value to be assigned in case the condition evaluates to false

        :param node: The node that represents an if expression.
        :param module: The python module where this expression is encountered.
        :param context: The context of the given node.
        :return: The ``pycodealizer.entities.IfExpressionEntity`` instance created from the given ``ast.IfExp`` node.
        """
        if_expression: IfExpressionEntity = IfExpressionEntity(node)
        context.stack_ast_node(if_expression)

        super().parse(node, module, context)

        context.unstack_ast_node()
        module.add_if_expression(if_expression)

        return if_expression
예제 #6
0
 def parse(self, node: Any):
     """Process the given node and extract relevant info from it."""
     parser = self.get_parser(node)
     parser.parse(node, self.modules[-1], Context(self.modules[-1]))
예제 #7
0
def test_context_current_ast_node_prop(ast_var_node: ast.Name, context: Context):
    context.stack_ast_node(ast_var_node)

    assert context.current_ast_node == ast_var_node
예제 #8
0
def test_context_current_execution_context_prop(variable_load_entity: VariableEntity, context: Context):
    context.stack_execution_context(variable_load_entity)

    assert context.current_execution_context == variable_load_entity
예제 #9
0
def test_context_unstack_ast_node(ast_var_node: ast.Name, context: Context):
    context.stack_ast_node(ast_var_node)
    context.unstack_ast_node()

    assert len(context.ast_context) == 1
예제 #10
0
def test_context_stack_ast_node(ast_var_node: ast.Name, context: Context):
    context.stack_ast_node(ast_var_node)

    assert len(context.ast_context) == 2 and context.ast_context[-1] == ast_var_node
예제 #11
0
def test_context_unstack_execution_context(variable_load_entity: VariableEntity, context: Context):
    context.stack_execution_context(variable_load_entity)
    context.unstack_execution_context()

    assert len(context.execution_context) == 1
예제 #12
0
def test_context_stack_execution_context(variable_load_entity: VariableEntity, context: Context):
    context.stack_execution_context(variable_load_entity)

    assert len(context.execution_context) == 2 and context.execution_context[-1] == variable_load_entity
예제 #13
0
def test_context_initialization(module_entity: Module):
    context = Context(module_entity)

    assert len(context.execution_context) == 1 and context.execution_context[0] == module_entity
    assert len(context.ast_context) == 1 and context.ast_context[0] == module_entity
예제 #14
0
def call_entity():
    return CallEntity(ast_call, Context(Module('test')))
예제 #15
0
def context():
    return Context(Module('test'))