Skip to content

Instantly share code, notes, and snippets.

@tomviner
Last active February 23, 2016 11:22
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tomviner/c3537c2f2b2b8172f83e to your computer and use it in GitHub Desktop.
Save tomviner/c3537c2f2b2b8172f83e to your computer and use it in GitHub Desktop.
Enabling viewing of rewritten AST trees as Python

Use pytest_configure to patch pytest/_pytest/assertion/rewrite.py::rewrite_asserts

Note: I'm now in the process of converting this guide to a pytest plugin.

Install this gist:

git clone git@gist.github.com:/c3537c2f2b2b8172f83e.git display_ast_rewrite
cd display_ast_rewrite
pip install -r requirements.txt

Run on example test:

Note: -s is required to see rewritten AST output, even for failing tests, because the output comes while tests are being collected and rewritten, not during the execution of a test. So pytest's "show output upon fail" cannot help here.

py.test -s test_simple.py

So for the test function:

def test_simple():
    a = 1
    b = 2
    assert  a == b

You should see the rewritten AST back as Python code:

import __builtin__ as @py_builtins
import _pytest.assertion.rewrite as @pytest_ar

def test_simple():
    a = 1
    b = 2
    @py_assert1 = a == b
    if not @py_assert1:
        @py_format3 = @pytest_ar._call_reprcompare(('==',), (@py_assert1,),
            ('%(py0)s == %(py2)s',), (a, b)) % {'py0': @pytest_ar._saferepr
            (a) if 'a' in @py_builtins.locals() or @pytest_ar.
            _should_repr_global_name(a) else 'a', 'py2': @pytest_ar.
            _saferepr(b) if 'b' in @py_builtins.locals() or @pytest_ar.
            _should_repr_global_name(b) else 'b'}
        @py_format5 = ('' + 'assert %(py4)s') % {'py4': @py_format3}
        raise AssertionError(@pytest_ar._format_explanation(@py_format5))
    @py_assert1 = None

Although this looks complicated, it should make developing pytest rewriting internals easier.

from __future__ import print_function
from _pytest.assertion.rewrite import rewrite_asserts
from _pytest.monkeypatch import monkeypatch
try:
import astor
except ImportError:
raise RuntimeError("Please install the astor library")
def replacement_rewrite_asserts(tree):
rewrite_asserts(tree)
print()
print()
print(astor.to_source((tree)))
def pytest_configure(config):
mp = monkeypatch()
mp.setattr(
'_pytest.assertion.rewrite.rewrite_asserts',
replacement_rewrite_asserts)
# written pyc files will bypass our patch, so disable reading them
mp.setattr(
'_pytest.assertion.rewrite._read_pyc',
lambda source, pyc, trace=None: None)
config._cleanup.append(mp.undo)
pytest
-e git+git@github.com:berkerpeksag/astor.git@d254ad799fb0866e03d658cca8794b73411c89ef#egg=astor
def test_simple():
a = 1
b = 2
assert a == b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment