Exemple #1
0
def test_group_expressions():
    x = (1, 2)
    evaluator = Evaluator({'x': x})
    tree = ast.parse('x[0] + x[x[0]]').body[0].value
    expressions = evaluator.find_expressions(tree)
    grouped = set((frozenset(nodes), value)
                  for nodes, value in group_expressions(expressions))
    expected = {
        (frozenset([tree.left, subscript_item(tree.right)]), x[0]),
        (frozenset([
            tree.left.value,
            subscript_item(tree.right).value, tree.right.value
        ]), x),
        (frozenset([
            subscript_item(tree.left),
            subscript_item(subscript_item(tree.right))
        ]), 0),
        (frozenset([tree.right]), x[x[0]]),
        (frozenset([tree]), x[0] + x[x[0]]),
    }
    assert grouped == expected

    grouped = set(
        (frozenset(nodes), value)
        for nodes, value in evaluator.interesting_expressions_grouped(tree))
    expected = set((nodes, value) for nodes, value in expected if value != 0)
    assert grouped == expected
Exemple #2
0
def test_cannot_subscript(expr):
    with pytest.raises(Exception):
        eval(expr)

    evaluator = Evaluator({})
    tree = ast.parse(expr)
    node = tree.body[0].value
    assert isinstance(node, ast.Subscript)
    with pytest.raises(CannotEval):
        str(evaluator[node])
Exemple #3
0
def test_evaluator_wrong_getitem():
    evaluator = Evaluator({})
    with pytest.raises(TypeError,
                       match="node should be an ast.expr, not 'str'"):
        # noinspection PyTypeChecker
        str(evaluator["foo"])
def get_all_objects(line, frame):
    """Given a (partial) line of code and a frame,
    obtains a dict containing all the relevant information about objects
    found on that line so that they can be formatted as part of the
    answer to "where()" or they can be used during the analysis
    of the cause of the exception.

    The dict returned has four keys.
    The first three, 'locals', 'globals', 'nonlocals',
    each containing a list of tuples, each tuple being of the form
    (name, repr(obj), obj) where name --> obj.

    The fourth key, 'literals', contains a list of tuples of the form
    ('name', obj). It is only occasionally used in helping to make
    suggestions regarding the cause of some exception.
    """
    objects = {
        "locals": [],
        "globals": [],
        "literals": [],
        "builtins": [],
        "name, obj": [],
    }

    scopes = (
        ("locals", frame.f_locals),  # always have locals before globals
        ("globals", frame.f_globals),
    )

    names = set([])
    try:
        atok = ASTTokens(line, parse=True)
    except SyntaxError:  # this should not happen
        atok = None

    if atok is not None:
        for scope, scope_dict in scopes:
            for nodes, obj in Evaluator(
                    scope_dict).interesting_expressions_grouped(atok.tree):
                name = atok.get_text(nodes[0])
                if name in names:
                    continue
                names.add(name)
                objects[scope].append((name, repr(obj), obj))
                objects["name, obj"].append((name, obj))

        Evaluator.literal_expressions_grouped = literal_expressions_grouped
        for nodes, obj in Evaluator({}).literal_expressions_grouped(
                atok.tree):  # noqa
            name = atok.get_text(nodes[0])
            objects["literals"].append((name, obj))
            objects["name, obj"].append((name, obj))

    tokens = token_utils.get_significant_tokens(line)
    for tok in tokens:
        if tok.is_identifier():
            name = tok.string
            if name in names:
                continue
            for scope, scope_dict in scopes:
                if name in scope_dict:
                    names.add(name)
                    obj = scope_dict[name]
                    objects[scope].append((name, repr(obj), obj))
                    objects["name, obj"].append((name, obj))
                    break
            else:
                if name in dir(builtins):
                    obj = getattr(builtins, name)
                    objects["builtins"].append((name, repr(obj), obj))
                    objects["name, obj"].append((name, obj))

    dotted_names = get_dotted_names(line)
    for name in dotted_names:
        for scope, scope_dict in scopes:
            if name not in scope_dict:
                continue
            obj = scope_dict[name]
            if (name, obj) not in objects["name, obj"]:
                objects[scope].append((name, repr(obj), obj))
                objects["name, obj"].append((name, obj))

    # TODO: check to see if this is still needed
    objects["nonlocals"] = get_nonlocal_objects(frame)
    return objects