コード例 #1
0
 def test_only(self):
     for n in range(5):
         gen = (i for i in range(n))
         if n == 1:
             self.assertEqual(only(gen), 0)
         else:
             with self.assertRaises(NotOneValueFound):
                 only(gen)
コード例 #2
0
    def __init__(self, pp_object, args, deep):
        self.config = pp_object.config
        self.args = args
        depth = getattr(self.config.thread_local, 'depth', 0)
        frame = inspect.currentframe().f_back.f_back
        self.event = Event(FrameInfo(frame), 'log', None, depth)
        formatted = self.config.formatter.format_log(self.event)
        self.config.write(formatted)

        self.returns = None
        try:
            assert not NO_ASTTOKENS
            self.call = call = Source.executing(frame).node
            assert isinstance(call, ast.Call)
            assert len(args) == len(call.args)
        except Exception:
            if deep:
                self.returns = args[0] = args[0]()
            for i, arg in enumerate(args):
                self.write_placeholder(i, arg)
        else:
            if deep:
                call_arg = only(call.args)
                assert isinstance(
                    call_arg, ast.Lambda
                ), "You must pass a lambda DIRECTLY to pp.deep, not as a result of any other expression"
                self.returns = self.deep_pp(call_arg.body, frame)
            else:
                self.plain_pp(args, call.args)
コード例 #3
0
    def executing_piece(self) -> range:
        """
        The piece (range of lines) containing the line currently being executed
        by the interpreter in this frame.

        Raises an exception if .scope is None, which usually means the source code
        for this frame is unavailable.
        """
        return only(piece for piece in self.scope_pieces
                    if self.lineno in piece)
コード例 #4
0
ファイル: tests.py プロジェクト: cnheider/executing
def tester(arg, returns=None):
    frame = inspect.currentframe().f_back
    Source.lazycache(frame)
    call = Source.executing(frame).node
    result = eval(
        compile(ast.Expression(only(call.args)), '<>', 'eval'),
        frame.f_globals,
        frame.f_locals,
    )
    assert result == result, (result, arg)
    if returns is None:
        return arg
    return returns
コード例 #5
0
    def check_code(self, code, nodes):
        linestarts = dict(dis.findlinestarts(code))
        instructions = get_instructions(code)
        lineno = None
        for inst in instructions:
            if time.time() - self.start_time > 45 * 60:
                # Avoid travis time limit of 50 minutes
                raise TimeOut

            lineno = linestarts.get(inst.offset, lineno)
            if not inst.opname.startswith((
                    'BINARY_', 'UNARY_', 'LOAD_ATTR', 'LOAD_METHOD', 'LOOKUP_METHOD',
                    'SLICE+', 'COMPARE_OP', 'CALL_', 'IS_OP', 'CONTAINS_OP',
            )):
                continue
            frame = C()
            frame.f_lasti = inst.offset
            frame.f_code = code
            frame.f_globals = globals()
            frame.f_lineno = lineno
            source = Source.for_frame(frame)
            node = None

            try:
                try:
                    node = Source.executing(frame).node
                except Exception:
                    if inst.opname.startswith(('COMPARE_OP', 'CALL_')):
                        continue
                    if isinstance(only(source.statements_at_line(lineno)), (ast.AugAssign, ast.Import)):
                        continue
                    raise
            except Exception:
                print(source.text, lineno, inst, node and ast.dump(node), code, file=sys.stderr, sep='\n')
                raise

            nodes[node].append((inst, frame.__dict__))

            yield [inst.opname, node_string(source, node)]

        for const in code.co_consts:
            if isinstance(const, type(code)):
                for x in self.check_code(const, nodes):
                    yield x
コード例 #6
0
ファイル: test_core.py プロジェクト: alexmojaki/stack_data
def test_markers():
    options = Options(before=0, after=0)
    line = only(FrameInfo(inspect.currentframe(), options).lines)
    assert line.is_current
    assert re.match(r"<Line \d+ ", repr(line))
    assert (
        " (current=True) "
        "'    line = only(FrameInfo(inspect.currentframe(), options).lines)'"
        " of " in repr(line))
    assert repr(line).endswith("test_core.py>")
    assert repr(LINE_GAP) == "LINE_GAP"

    assert '*'.join(t.string for t in line.tokens) == \
           'line*=*only*(*FrameInfo*(*inspect*.*currentframe*(*)*,*options*)*.*lines*)*\n'

    def convert_token_range(r):
        if r.data.type == token.NAME:
            return '[[', ']]'

    markers = markers_from_ranges(line.token_ranges, convert_token_range)
    assert line.render(markers) == \
           '[[line]] = [[only]]([[FrameInfo]]([[inspect]].[[currentframe]](), [[options]]).[[lines]])'
    assert line.render(markers, strip_leading_indent=False) == \
           '    [[line]] = [[only]]([[FrameInfo]]([[inspect]].[[currentframe]](), [[options]]).[[lines]])'

    def convert_variable_range(r):
        return '[[', ' of type {}]]'.format(r.data[0].value.__class__.__name__)

    markers = markers_from_ranges(line.variable_ranges, convert_variable_range)
    assert sorted(markers) == [
        (4, True, '[['),
        (8, False, ' of type Line]]'),
        (50, True, '[['),
        (57, False, ' of type Options]]'),
    ]

    line.text += '  # < > " & done'
    assert line.render(markers) == \
           '[[line of type Line]] = only(FrameInfo(inspect.currentframe(), [[options of type Options]]).lines)' \
           '  # < > " & done'

    assert line.render(markers, escape_html=True) == \
           '[[line of type Line]] = only(FrameInfo(inspect.currentframe(), [[options of type Options]]).lines)' \
           '  # &lt; &gt; &quot; &amp; done'
コード例 #7
0
ファイル: core.py プロジェクト: alexmojaki/sorcery
def assigned_names(node, *, allow_one: bool,
                   allow_loops: bool) -> Tuple[Tuple[str], ast.AST]:
    """
    Finds the names being assigned to in the nearest ancestor of
    the given node that assigns names and satisfies the given conditions.

    If allow_loops is false, this only considers assignment statements,
    e.g. `x, y = ...`. If it's true, then for loops and comprehensions are
    also considered.

    If allow_one is false, nodes which assign only one name are ignored.

    Returns:
    1. a tuple of strings containing the names of the nodes being assigned
    2. The AST node where the assignment happens
    """

    while hasattr(node, 'parent'):
        node = node.parent

        target = None

        if NAMED_EXPR_SUPPORT and isinstance(node, ast.NamedExpr):
            target = node.target
        elif isinstance(node, ast.Assign):
            target = only(node.targets)
        elif isinstance(node, (ast.For, ast.comprehension)) and allow_loops:
            target = node.target

        if not target:
            continue

        names = node_names(target)
        if len(names) > 1 or allow_one:
            break
    else:
        raise TypeError('No assignment found')

    return names, node
コード例 #8
0
ファイル: tests.py プロジェクト: yishuihanhan/executing
    def check_code(self, code, nodes):
        linestarts = dict(dis.findlinestarts(code))
        instructions = get_instructions(code)
        lineno = None
        for inst in instructions:
            lineno = linestarts.get(inst.offset, lineno)
            if not inst.opname.startswith((
                    'BINARY_',
                    'UNARY_',
                    'LOAD_ATTR',
                    'LOAD_METHOD',
                    'LOOKUP_METHOD',
                    'SLICE+',
                    'COMPARE_OP',
                    'CALL_',
            )):
                continue
            frame = C()
            frame.f_lasti = inst.offset
            frame.f_code = code
            frame.f_globals = globals()
            frame.f_lineno = lineno
            source = Source.for_frame(frame)
            node = None

            try:
                try:
                    node = Source.executing(frame).node
                except Exception:
                    if inst.opname.startswith(('COMPARE_OP', 'CALL_')):
                        continue
                    if isinstance(only(source.statements_at_line(lineno)),
                                  (ast.AugAssign, ast.Import)):
                        continue
                    raise

                try:
                    self.assertIsNone(nodes[node])
                except KeyError:
                    print(ast.dump(source.tree),
                          list(ast.walk(source.tree)),
                          nodes,
                          node,
                          ast.dump(node),
                          file=sys.stderr,
                          sep='\n')
            except Exception:
                print(source.text,
                      lineno,
                      inst,
                      node and ast.dump(node),
                      code,
                      file=sys.stderr,
                      sep='\n')
                raise

            nodes[node] = (inst, frame.__dict__)

            yield [inst.opname, node_string(source, node)]

        for const in code.co_consts:
            if isinstance(const, type(code)):
                for x in self.check_code(const, nodes):
                    yield x