コード例 #1
0
ファイル: test_returned_expr.py プロジェクト: roch1990/peon
def test_return_value_is_filled_dict_by_keyword():
    # when method return dict(a='b')
    try:
        assert ReturnedExpression(
            _ast.Return(
                value=_ast.Call(
                    func=_ast.Name(id='dict', ctx=_ast.Load()),
                    args=[],
                    keywords=[_ast.keyword(arg='a', value=_ast.Str(s='b'))],
                ),
                lineno=1,
            ), ).value_not_none() is True
    except (AttributeError):
        assert ReturnedExpression(
            _ast.Return(
                value=_ast.Call(
                    func=_ast.Name(id='dict', ctx=_ast.Load()),
                    args=[],
                    keywords=[
                        _ast.keyword(arg='a',
                                     value=_ast.JoinedStr(values=['a', 'b']))
                    ],
                ),
                lineno=1,
            ), ).value_not_none() is True
コード例 #2
0
 def _replace_with_block_context(with_node, block_type):
     with_node.items[0].context_expr = _ast.Call(
         func=_ast.Attribute(value=_ast.Name(id='self', ctx=_ast.Load()),
                             attr='_feature_block_context',
                             ctx=_ast.Load()),
         args=[_ast.Str(s=block_type)],
         keywords=[])
コード例 #3
0
    def visit_Expr(self, expression_node):
        value = expression_node.value
        if not isinstance(value, _ast.BinOp) or not isinstance(
                value.op, _ast.Mult) or not isinstance(value.right, _ast.Call):
            return expression_node

        number_of_invocations = value.left
        if MockAssertionTransformer._value_is_a_wildcard(
                number_of_invocations):
            number_of_invocations = _ast.Num(n=-1)
        target_mock = value.right.func.value
        target_method = _ast.Str(s=value.right.func.attr)

        list_of_arguments = [
            MockAssertionTransformer._transform_arg_if_wildcard(x)
            for x in value.right.args
        ]
        spread_list_of_arguments = _ast.Starred(value=_ast.List(
            elts=list_of_arguments, ctx=_ast.Load()),
                                                ctx=_ast.Load())
        expression_node.value = _ast.Call(
            func=_ast.Attribute(value=_ast.Name(id='self', ctx=_ast.Load()),
                                attr='_assert_mock',
                                ctx=_ast.Load()),
            args=[
                number_of_invocations, target_mock, target_method,
                spread_list_of_arguments
            ],
            keywords=[])
        return expression_node
コード例 #4
0
 def new_class(self, items):
     identifier = items[0]
     if len(items) > 1:
         args = items[1]
     else:
         args = []
     return _ast.Call(func=_ast.Name(id=identifier), args=args, keywords=[])
コード例 #5
0
    def visit_Expr(self, expression_node):
        value = expression_node.value
        if not isinstance(value, _ast.Compare):
            if isinstance(value, _ast.BinOp):
                if hasattr(value,
                           'op') and not isinstance(value.op, _ast.MatMult):
                    return expression_node
            else:
                return expression_node

        left_value = value.left

        # TODO: Support multiple comparators (1 < 2 < 3). This may be tricky because one expression of multiple
        if hasattr(value, 'op'):
            comparison_operation = value.op
            right_value = value.right
        else:
            comparison_operation = value.ops[0]
            right_value = value.comparators[0]
        comparison_operation_type = type(comparison_operation)
        internal_comparison_type = self.comparator_methods[
            comparison_operation_type]

        expression_node.value = _ast.Call(
            func=_ast.Attribute(value=_ast.Name(id='self', ctx=_ast.Load()),
                                attr='_compare',
                                ctx=_ast.Load()),
            args=[
                left_value, right_value,
                _ast.Str(s=internal_comparison_type.name)
            ],
            keywords=[])
        return expression_node
コード例 #6
0
  def make_call(i, bytecode):
    op = bytecode[i][2]

    def get_call_arg_length(op, arg):
      na = arg & 0xff         # num args
      nk = (arg >> 8) & 0xff  # num keywords
      return na, nk, na + 2 * nk + CALL_EXTRA_ARG_OFFSET[op]

    has_var, has_kw = 0, 0
    if op in (CALL_FUNCTION_VAR, CALL_FUNCTION_VAR_KW): has_var = 1
    if op in (CALL_FUNCTION_KW, CALL_FUNCTION_VAR_KW): has_kw = 1

    op, arg = bytecode[i][2], bytecode[i][3]
    num_args, num_keywords, offset = get_call_arg_length(op, arg)

    func, args, keywords, starargs, kwargs = None, None, None, None, None

    if has_kw > 0:
      i, kwargs = Statement.make_expr(i - 1, bytecode)

    if has_var > 0:
      i, starargs = Statement.make_expr(i - 1, bytecode)

    # Handle keywords
    if num_keywords > 0:
      keywords = []
      while num_keywords > 0:
        i, kw_value = Statement.make_expr(i - 1, bytecode)
        i, kw_name = Statement.make_expr(i - 1, bytecode)
        keywords.insert(0, _ast.keyword(kw_name, kw_value))
        num_keywords -= 1

    finger = i - 1

    if num_args > 0:
      n = num_args - 1
      args = [None] * num_args
      for k in range(num_args):
        cur_stack = 0
        loc_bytecode = []
        is_first = True
        while True:
          op, arg = bytecode[finger][2], bytecode[finger][3]
          pop, push = get_stack_effect(op, arg)
          cur_stack -= (pop - push) if not is_first else pop
          is_first = False
          loc_bytecode.insert(0, bytecode[finger])
          if cur_stack == 0:
            break
          finger -= 1
        _, args[n] = Statement.make_expr(len(loc_bytecode) - 1, loc_bytecode)
        n -= 1
        finger -= 1

    _, func = Statement.make_expr(finger, bytecode)

    call = _ast.Call(func, args, keywords, starargs, kwargs)
    logger.debug("\n%s", dump(call))
    return finger, call
コード例 #7
0
ファイル: test_returned_expr.py プロジェクト: roch1990/peon
def test_return_value_is_empty_frozenset_by_keyword():
    # when method return frozenset()
    assert ReturnedExpression(
        _ast.Return(
            value=_ast.Call(
                func=_ast.Name(id='frozenset', ctx=_ast.Load()),
                args=[],
                keywords=[],
            ),
            lineno=1,
        ), ).value_not_none() is False
コード例 #8
0
 def visit_Call(self, expression_node):
     if isinstance(expression_node, _ast.Call):
         if hasattr(expression_node.func,
                    'id') and expression_node.func.id == 'thrown':
             expected_exception = expression_node.args[0]
             expression_node = _ast.Call(func=_ast.Attribute(
                 value=_ast.Name(id='self', ctx=_ast.Load()),
                 attr='_exception_thrown',
                 ctx=_ast.Load()),
                                         args=[expected_exception],
                                         keywords=[])
     return expression_node
コード例 #9
0
    def visit_Expr(self, expression_node):
        expression_value = expression_node.value
        if type(expression_value) is _ast.Compare:
            comparison_method = 'assertEquals'

            expression_node.value = _ast.Call(
                func=_ast.Attribute(value=_ast.Name(id='self',
                                                    ctx=_ast.Load()),
                                    attr=comparison_method,
                                    ctx=_ast.Load()),
                args=[expression_value.left, expression_value.comparators[0]],
                keywords=[])
            return expression_node
コード例 #10
0
ファイル: test_returned_expr.py プロジェクト: roch1990/peon
def test_return_value_is_filled_frozenset_by_keyword():
    # when method return frozenset('1')
    try:
        assert ReturnedExpression(
            _ast.Return(
                value=_ast.Call(
                    func=_ast.Name(id='frozenset', ctx=_ast.Load()),
                    args=[_ast.Str(s='1')],
                    keywords=[],
                ),
                lineno=1,
            ), ).value_not_none() is True
    except (AttributeError):
        assert ReturnedExpression(
            _ast.Return(
                value=_ast.Call(
                    func=_ast.Name(id='frozenset', ctx=_ast.Load()),
                    args=[_ast.JoinedStr(values=['1'])],
                    keywords=[],
                ),
                lineno=1,
            ), ).value_not_none() is True
コード例 #11
0
ファイル: test_returned_expr.py プロジェクト: roch1990/peon
def test_return_value_is_func():
    assert ReturnedExpression(
        _ast.Return(
            value=_ast.Call(
                func=_ast.Attribute(
                    value=_ast.Name(id='Function', ctx=_ast.Load()),
                    attr='staticm',
                    ctx=_ast.Load(),
                ),
                args=[],
                keywords=[],
            ),
            lineno=1,
        ), ).value_not_none() is True
コード例 #12
0
def Call(caller, args=(), keys=(), values=(), starargs=None, kwargs=None):
    """Creates an _ast.Call node.

  Args:
    caller: Either a node of the appropriate type
      (_ast.Str, _ast.Name, or _ast.Attribute), or a dot-separated string.
    args: A list of args.
    keys: A list of keys, must be the same length as values.
    values: A list of values, correspond to keys.
    starargs: A node with a star in front of it. Passing a string will be
      interpreted as a VarReference.
    kwargs: A node with two stars in front of it. Passing a string will be
      interpreted as a VarReference.

  Raises:
    ValueError: If len(keys) != len(values) or caller is not the right type.

  Returns:
    An _ast.Call object.
  """
    if len(keys) != len(values):
        raise ValueError('len(keys)={} != len(values)={}'.format(
            len(keys), len(values)))
    if isinstance(caller, str):
        caller = VarReference(*caller.split('.'))
    if not isinstance(caller, (_ast.Str, _ast.Name, _ast.Attribute)):
        raise ValueError('caller must be a: \n'
                         '1. string\n'
                         '2. _ast.Str node\n'
                         '3. _ast.Name node\n'
                         '4. _ast.Attr node\n'
                         'not {}'.format(caller))
    keywords = [
        _ast.keyword(arg=key, value=val) for key, val in zip(keys, values)
    ]
    args = [_WrapWithName(arg, ctx_type=CtxEnum.LOAD) for arg in args]
    if isinstance(starargs, str):
        starargs = VarReference(*starargs.split('.'))
    if isinstance(kwargs, str):
        kwargs = VarReference(*kwargs.split('.'))
    return _ast.Call(func=caller,
                     args=args,
                     keywords=keywords,
                     starargs=starargs,
                     kwargs=kwargs)
コード例 #13
0
  def visit_Call( self, node ):
    # TODO: specially handle self.visit( node.func ) if attr
    #       currently not visiting at all!
    args     = [self.visit(x) for x in node.args]
    keywords = [self.visit(x) for x in node.keywords]
    if node.starargs:
      starargs = [self.visit(x) for x in node.starargs]
    else:
      starargs = None
    if node.kwargs:
      kwargs = [self.visit(x) for x in node.kwargs]
    else:
      kwargs = None

    return _ast.Call(func=node.func,
                     args=args,
                     keyword=keywords,
                     starargs=starargs,
                     kwargs=kwargs)
コード例 #14
0
    def CALL_FUNCTION(self, instr):
        nkwargs = instr.oparg >> 8
        nargs = (~(nkwargs << 8)) & instr.oparg

        args = []
        keywords = []

        for _ in range(nkwargs):
            expr = self.ast_stack.pop()
            name = self.ast_stack.pop()

            keyword = _ast.keyword(arg=name.s, value=expr, lineno=instr.lineno)
            keywords.insert(0, keyword)

        for _ in range(nargs):
            arg = self.ast_stack.pop()
            args.insert(0, arg)

        if len(args) == 1 and isinstance(args[0],
                                         (_ast.FunctionDef, _ast.ClassDef)):
            function = args[0]

            if function.decorator_list is None:
                function.decorator_list = []

            node = self.ast_stack.pop()
            function.decorator_list.insert(0, node)

            self.ast_stack.append(function)
            return

        node = self.ast_stack.pop()
        callfunc = _ast.Call(
            func=node,
            args=args,
            keywords=keywords,
            starargs=None,
            kwargs=None,
            lineno=instr.lineno,
            col_offset=0,
        )

        self.ast_stack.append(callfunc)
コード例 #15
0
ファイル: test_ast.py プロジェクト: Qointum/pypy
 def test_bug_null_in_objspace_type(self):
     import ast
     code = ast.Expression(
         lineno=1,
         col_offset=1,
         body=ast.ListComp(
             lineno=1,
             col_offset=1,
             elt=ast.Call(lineno=1,
                          col_offset=1,
                          func=ast.Name(lineno=1,
                                        col_offset=1,
                                        id='str',
                                        ctx=ast.Load(lineno=1,
                                                     col_offset=1)),
                          args=[
                              ast.Name(lineno=1,
                                       col_offset=1,
                                       id='x',
                                       ctx=ast.Load(lineno=1, col_offset=1))
                          ],
                          keywords=[]),
             generators=[
                 ast.comprehension(
                     lineno=1,
                     col_offset=1,
                     target=ast.Name(lineno=1,
                                     col_offset=1,
                                     id='x',
                                     ctx=ast.Store(lineno=1, col_offset=1)),
                     iter=ast.List(
                         lineno=1,
                         col_offset=1,
                         elts=[ast.Num(lineno=1, col_offset=1, n=23)],
                         ctx=ast.Load(
                             lineno=1,
                             col_offset=1,
                         )),
                     ifs=[])
             ]))
     compile(code, '<template>', 'eval')
コード例 #16
0
    def visit_Assign(self, node):
        """Rewrite the Assign visitor function to deal with list
        comprehensions and function calls.

        """

        # if the value is a list comprehension, the we need to handle
        # it specially
        if isinstance(node.value,
                      (_ast.ListComp, _ast.GeneratorExp, _ast.Lambda)):
            node.value = self.extract(node.value, cthreshold=1)
            iden = self.visit(node.value)

            if isinstance(node.value, _ast.GeneratorExp):
                val = _ast.Call(func=_ast.Name(id=iden, ctx=_ast.Load()),
                                args=[],
                                keywords=[],
                                starargs=None,
                                kwargs=None)
            else:
                val = _ast.Name(id=iden, ctx=_ast.Load())

            node = ast.Assign(value=val, targets=node.targets)

        elif isinstance(node.value, _ast.Dict) or \
                 isinstance(node.value, _ast.List) or \
                 isinstance(node.value, _ast.Tuple):
            node.value = self.extract(node.value, threshold=0)

        else:
            # do Call/ListComp extraction on the node's value
            node.value = self.extract(node.value, cthreshold=0)

        self.newline(node)
        for idx, target in enumerate(node.targets):
            if idx:
                self.write(' = ')
            self.visit(target)
        self.write(' = ')
        self.visit(node.value)
コード例 #17
0
def _cfa(body, state, on_gen):
    assert isinstance(on_gen, list)
    for c in on_gen:
        assert callable(c)

    cfg = state.cfg

    def make_connect(cur_bid):
        assert isinstance(cur_bid, int)

        def inner(new_bid):
            assert isinstance(new_bid, int)
            state.connect([cur_bid], [new_bid])

        return inner

    def push_block(block):
        block_id = len(cfg.blocks)
        assert block_id not in cfg.blocks
        cfg.blocks[block_id] = block
        for c in on_gen:
            c(block_id)
        return block_id

    cur_block = []

    for b in body:
        if REDUCE_FORS_TO_WHILES and isinstance(b, _ast.For):
            if isinstance(b.iter, _ast.Call) and isinstance(
                    b.iter.func,
                    _ast.Name) and b.iter.func.id in ("range", "xrange"):
                if not b.iter.keywords and not b.iter.starargs and not b.iter.kwargs:
                    end_var = "__wfend_%d_%d_" % (b.lineno, b.col_offset)
                    iter_var = "__wfiter_%d_%d_" % (b.lineno, b.col_offset)
                    if len(b.iter.args) in (1, 2):
                        if len(b.iter.args) == 1:
                            start = _ast.Num(0)
                            end = b.iter.args[0]
                        elif len(b.iter.args) == 2:
                            start = b.iter.args[0]
                            end = b.iter.args[1]
                        else:
                            start = b.iter.args[0]
                            end = b.iter.args[1]
                        cur_block.append(
                            _ast.Assign([
                                _ast.Name(
                                    iter_var, _ast.Store(), not_real=True)
                            ],
                                        start,
                                        lineno=b.lineno,
                                        col_offset=b.col_offset,
                                        not_real=True))
                        cur_block.append(
                            _ast.Assign([
                                _ast.Name(end_var, _ast.Store(), not_real=True)
                            ],
                                        end,
                                        lineno=b.lineno,
                                        col_offset=b.col_offset,
                                        not_real=True))

                        body = [
                            _ast.Assign([b.target],
                                        _ast.Name(iter_var,
                                                  _ast.Load(),
                                                  not_real=True),
                                        lineno=b.lineno,
                                        col_offset=b.col_offset,
                                        not_real=True),
                            _ast.Assign([
                                _ast.Name(
                                    iter_var, _ast.Store(), not_real=True)
                            ],
                                        _ast.BinOp(
                                            _ast.Name(iter_var,
                                                      _ast.Load(),
                                                      not_real=True),
                                            _ast.Add(), _ast.Num(1)),
                                        lineno=b.lineno,
                                        col_offset=b.col_offset,
                                        not_real=True)
                        ] + b.body
                        b = _ast.While(_ast.Compare(
                            _ast.Name(iter_var, _ast.Load(),
                                      not_real=True), [_ast.Lt()],
                            [_ast.Name(end_var, _ast.Load(), not_real=True)],
                            lineno=b.lineno,
                            col_offset=b.col_offset,
                            not_real=True),
                                       body,
                                       b.orelse,
                                       not_real=True)

        if isinstance(b, (
                _ast.Assign,
                _ast.AugAssign,
                _ast.ClassDef,
                _ast.Delete,
                _ast.Exec,
                _ast.Expr,
                _ast.FunctionDef,
                _ast.Global,
                _ast.Import,
                _ast.ImportFrom,
                _ast.Print,
                _ast.Pass,
        )):
            cur_block.append(b)
        elif isinstance(b, _ast.Assert):
            cur_block.append(b)
            if isinstance(b.test, _ast.Call) and isinstance(
                    b.test.func, _ast.Name
            ) and b.test.func.id == "isinstance" and isinstance(
                    b.test.args[0], _ast.Name) and isinstance(
                        b.test.args[1], _ast.Name):
                varname = b.test.args[0].id
                cast = _ast.Call(_ast.Name(
                    "__cast__", _ast.Load(), not_real=True, **pos(b)), [
                        _ast.Name(
                            varname, _ast.Store(), not_real=True, **pos(b)),
                        b.test.args[1]
                    ], [],
                                 None,
                                 None,
                                 not_real=True,
                                 **pos(b))
                assign = _ast.Assign([
                    _ast.Name(varname, _ast.Store(), not_real=True, **pos(b))
                ],
                                     cast,
                                     not_real=True,
                                     lineno=b.lineno,
                                     col_offset=b.col_offset)
                cur_block.append(assign)
        elif isinstance(b, (_ast.Break, _ast.Continue)):
            f = state.add_break if isinstance(
                b, _ast.Break) else state.add_continue
            if cur_block:
                j = Jump()
                cur_block.append(j)
                block_id = push_block(cur_block)
                f(j.set_dest)
                f(make_connect(block_id))
            else:
                for c in on_gen:
                    f(c)
            return []
        elif isinstance(b, _ast.If):
            br = Branch(b.test, lineno=b.lineno)
            cur_block.append(br)
            next_block = push_block(cur_block)
            on_gen = None  # make sure this doesn't get used
            cur_block = []

            gen_true = [br.set_true, make_connect(next_block)]
            gen_false = [br.set_false, make_connect(next_block)]
            if ENFORCE_NO_MULTIMULTI:
                on_gen = gen_true
                j1 = Jump()
                gen_true = [make_connect(push_block([j1])), j1.set_dest]

                on_gen = gen_false
                j2 = Jump()
                gen_false = [make_connect(push_block([j2])), j2.set_dest]

                on_gen = None

            assert b.body
            body = b.body
            if isinstance(b.test, _ast.Call) and isinstance(
                    b.test.func, _ast.Name
            ) and b.test.func.id == "isinstance" and isinstance(
                    b.test.args[0], _ast.Name) and isinstance(
                        b.test.args[1], _ast.Name):
                varname = b.test.args[0].id
                cast = _ast.Call(_ast.Name(
                    "__cast__", _ast.Load(), not_real=True, **pos(b)), [
                        _ast.Name(
                            varname, _ast.Store(), not_real=True, **pos(b)),
                        b.test.args[1]
                    ], [],
                                 None,
                                 None,
                                 not_real=True,
                                 **pos(b))
                assign = _ast.Assign([
                    _ast.Name(varname, _ast.Store(), not_real=True, **pos(b))
                ],
                                     cast,
                                     not_real=True,
                                     lineno=b.lineno,
                                     col_offset=b.col_offset)
                body = [assign] + body
            if ADD_IF_ASSERTS:
                body = [_ast.Assert(b.test, None, not_real=True, **pos(b))
                        ] + body
            ending_gen = _cfa(body, state, gen_true)
            if b.orelse:
                ending_gen += _cfa(b.orelse, state, gen_false)
            else:
                ending_gen += gen_false
            on_gen = ending_gen

            if not on_gen and PRUNE_UNREACHABLE_BLOCKS:
                return []
        elif isinstance(b, _ast.TryExcept):
            j = Jump()
            cur_block.append(j)
            next_block = push_block(cur_block)
            on_gen = [j.set_dest, make_connect(next_block)]
            cur_block = []

            on_gen = _cfa(b.body, state, on_gen)

            # Set this to evaluate a string to try to defeat simple flow analysis
            br = Branch(_ast.Str("nonzero"))
            next_block = push_block([br])

            on_except = [br.set_false, make_connect(next_block)]
            on_fine = [br.set_true, make_connect(next_block)]

            assert len(b.handlers) >= 1
            # for handler in b.handlers:
            # on_except = _cfa(b.handlers[0].body, state, on_except)

            if b.orelse:
                on_fine = _cfa(b.orelse, state, on_fine)

            if ENFORCE_NO_MULTIMULTI:
                j = Jump()
                on_gen = on_fine
                next_block = push_block([j])
                on_fine = [j.set_dest, make_connect(next_block)]

                j = Jump()
                on_gen = on_except
                next_block = push_block([j])
                on_except = [j.set_dest, make_connect(next_block)]

            on_gen = on_fine + on_except
            cur_block = []
        elif isinstance(b, _ast.TryFinally):
            j = Jump()
            cur_block.append(j)
            next_block = push_block(cur_block)
            on_gen = [j.set_dest, make_connect(next_block)]
            cur_block = []

            on_gen = _cfa(b.body, state, on_gen)
            on_gen = _cfa(b.finalbody, state, on_gen)
        elif isinstance(b, _ast.While):
            # This could also be architected as having no extra block and having two jump statements, but I don't like that
            if cur_block:
                j = Jump()
                cur_block.append(j)
                on_gen = [make_connect(push_block(cur_block)), j.set_dest]
                cur_block = []

            always_true = False
            always_false = False
            if isinstance(b.test, _ast.Name):
                if b.test.id == "True":
                    always_true = True
                elif b.test.id == "False":
                    always_false = True
            elif isinstance(b.test, _ast.Num):
                if b.test.n:
                    always_true = True
                else:
                    always_false = True

            if always_true:
                br = Jump()
                on_true = br.set_dest
            elif always_false:
                br = Jump()
                on_false = br.set_dest
            else:
                br = Branch(b.test)
                on_true = br.set_true
                on_false = br.set_false
            init_id = push_block([br])
            on_gen = None
            assert cur_block == []  # just checking

            if not always_false:
                gen_true = [on_true, make_connect(init_id)]
            if not always_true:
                gen_false = [on_false, make_connect(init_id)]
            if ENFORCE_NO_MULTIMULTI:
                if not always_false:
                    on_gen = gen_true
                    j1 = Jump()
                    gen_true = [make_connect(push_block([j1])), j1.set_dest]

                if not always_true:
                    on_gen = gen_false
                    j2 = Jump()
                    gen_false = [make_connect(push_block([j2])), j2.set_dest]

                on_gen = None

            ending_gen = []
            if not always_false:
                state.push_loop()
                assert b.body
                loop_ending_gen = _cfa(b.body, state, gen_true)
                loop_ending_gen += state.get_continues()
                for c in loop_ending_gen:
                    c(init_id)
                ending_gen = state.get_breaks()
                state.pop_loop()

            if not always_true:
                if b.orelse:
                    ending_gen += _cfa(b.orelse, state, gen_false)
                else:
                    ending_gen += gen_false

            on_gen = ending_gen
            if not on_gen and PRUNE_UNREACHABLE_BLOCKS:
                return []
        elif isinstance(b, _ast.For):
            iter_func = _ast.Attribute(b.iter,
                                       "__iter__",
                                       _ast.Load(),
                                       not_real=True,
                                       lineno=b.lineno,
                                       col_offset=b.col_offset)
            iter_call = _ast.Call(iter_func, [], [],
                                  None,
                                  None,
                                  not_real=True,
                                  lineno=b.lineno,
                                  col_offset=b.col_offset)
            # iter_var = _make_temp_name()
            iter_var = "__foriter_%d_%d_" % (b.lineno, b.col_offset)
            iter_assign = _ast.Assign(
                [_ast.Name(iter_var, _ast.Store(), not_real=True, **pos(b))],
                iter_call,
                not_real=True,
                lineno=b.lineno,
                col_offset=b.col_offset)
            cur_block.append(iter_assign)

            j = Jump()
            cur_block.append(j)
            on_gen = [make_connect(push_block(cur_block)), j.set_dest]
            cur_block = []

            br = Branch(
                HasNext(
                    _ast.Name(iter_var, _ast.Load(), not_real=True, **pos(b)),
                    **pos(b)), **pos(b))
            init_id = push_block([br])
            on_gen = None
            assert cur_block == []  # just checking

            gen_true = [br.set_true, make_connect(init_id)]
            gen_false = [br.set_false, make_connect(init_id)]
            if ENFORCE_NO_MULTIMULTI:
                on_gen = gen_true
                j1 = Jump()
                gen_true = [make_connect(push_block([j1])), j1.set_dest]

                on_gen = gen_false
                j2 = Jump()
                gen_false = [make_connect(push_block([j2])), j2.set_dest]

                on_gen = None

            ending_gen = []

            state.push_loop()

            next_func = _ast.Attribute(_ast.Name(iter_var,
                                                 _ast.Load(),
                                                 not_real=True,
                                                 **pos(b)),
                                       "next",
                                       _ast.Load(),
                                       not_real=True,
                                       lineno=b.lineno,
                                       col_offset=b.col_offset)
            next = _ast.Call(next_func, [], [],
                             None,
                             None,
                             not_real=True,
                             lineno=b.lineno,
                             col_offset=b.col_offset)
            next_assign = _ast.Assign([b.target],
                                      next,
                                      not_real=True,
                                      lineno=b.lineno,
                                      col_offset=b.col_offset)
            next_iter_gen = _cfa([next_assign] + b.body, state, gen_true)
            next_iter_gen += state.get_continues()
            for c in next_iter_gen:
                c(init_id)

            loop_done_gen = list(state.get_breaks())

            state.pop_loop()

            if b.orelse:
                # if b.orelse and loop_ending_blocks:
                loop_done_gen += _cfa(b.orelse, state, gen_false)
            else:
                loop_done_gen += gen_false

            on_gen = loop_done_gen
            if not on_gen and PRUNE_UNREACHABLE_BLOCKS:
                return []
        elif isinstance(b, (_ast.Return, _ast.Raise)):
            cur_block.append(b)
            block_id = push_block(cur_block)
            state.returns.append(make_connect(block_id))
            return []
        elif isinstance(b, _ast.With):
            # XXX totally ignores the functionality of with statements

            # Have to save the context manager because the expression might not be valid later
            mgr_name = "__mgr_%s_%s_" % (b.lineno, b.col_offset)
            save_mgr = _ast.Assign([
                _ast.Name(mgr_name,
                          _ast.Store(),
                          lineno=b.lineno,
                          col_offset=b.col_offset,
                          not_real=True)
            ],
                                   b.context_expr,
                                   lineno=b.lineno,
                                   col_offset=b.col_offset,
                                   not_real=True)

            enter_func = _ast.Attribute(_ast.Name(mgr_name,
                                                  _ast.Load(),
                                                  lineno=b.lineno,
                                                  col_offset=b.col_offset,
                                                  not_real=True),
                                        "__enter__",
                                        _ast.Load(),
                                        lineno=b.lineno,
                                        col_offset=b.col_offset,
                                        not_real=True)
            bind = _ast.Call(enter_func, [], [],
                             None,
                             None,
                             lineno=b.lineno,
                             col_offset="__enter__()",
                             not_real=True)

            if b.optional_vars:
                assert isinstance(b.optional_vars, _ast.AST)
                init = _ast.Assign([b.optional_vars],
                                   bind,
                                   lineno=b.lineno,
                                   col_offset=b.col_offset,
                                   not_real=True)
            else:
                init = _ast.Expr(bind,
                                 lineno=b.lineno,
                                 col_offset=b.col_offset,
                                 not_real=True)

            exit_func = _ast.Attribute(_ast.Name(mgr_name,
                                                 _ast.Load(),
                                                 lineno=b.lineno,
                                                 col_offset=b.col_offset,
                                                 not_real=True),
                                       "__exit__",
                                       _ast.Load(),
                                       lineno=b.lineno,
                                       col_offset=b.col_offset,
                                       not_real=True)
            if SIMPLE_WITH_EXIT:
                exit_call = _ast.Call(exit_func, [], [],
                                      None,
                                      None,
                                      lineno=b.lineno,
                                      col_offset=b.col_offset,
                                      not_real=True)
            else:
                none_ = _ast.Name("None",
                                  _ast.Load(),
                                  lineno=b.lineno,
                                  col_offset=b.col_offset,
                                  not_real=True)
                exit_call = _ast.Call(exit_func, [none_, none_, none_], [],
                                      None,
                                      None,
                                      lineno=b.lineno,
                                      col_offset=b.col_offset,
                                      not_real=True)
            exit = _ast.Expr(exit_call,
                             lineno=b.lineno,
                             col_offset="__exit__()",
                             not_real=True)

            cur_block.extend([save_mgr, init])
            j = Jump()
            cur_block.append(j)
            next_block = push_block(cur_block)
            on_gen = [j.set_dest, make_connect(next_block)]
            cur_block = []

            body = b.body + [exit]
            next_gen = _cfa(body, state, on_gen)
            on_gen = next_gen
        else:
            raise Exception(b)

    if cur_block:
        j = Jump()
        cur_block.append(j)
        next = push_block(cur_block)
        return [j.set_dest, make_connect(next)]
    return on_gen

    return on_gen
コード例 #18
0
ファイル: pyast.py プロジェクト: laomobk/AIL-Language
def call_expr(func: _ast.expr,
              args: List[_ast.expr],
              keywords: List[_ast.expr] = None) -> _ast.Call:
    if keywords is None:
        keywords = list()
    return _ast.Call(func=func, args=args, keywords=keywords)