Skip to content

Instantly share code, notes, and snippets.

@tomviner
Last active February 23, 2016 11:22

Patching _pytest.assertion.rewrite.rewrite_asserts to output the rewritten ast tree

Follow up to:

Which version of Meta?

When the above was written Meta couldn't cope with some of the rewritten ast trees in pytest tests. But srossross kindly responded quickly to my comment and merged the already written Meta/PR#19.

But until Meta>0.4.1 is released, we'll still need to use pip install -e git+git@github.com:srossross/Meta.git#egg=Meta

# question: can we find a pytest hook, so this is called before tests are rewritten?
import mock
def patch_to_print_rewritten_source():
from _pytest.assertion.rewrite import rewrite_asserts
def replacement_rewrite_asserts(tree):
import meta
# question: is there a pytest logging convention we can use - instead of print - here?
# display unparsed source prior to rewritting
print meta.asttools.dump_python_source(tree)
# execute the original rewrite_asserts
rewrite_asserts(tree)
# display unparsed source now it's beeen rewritten
print meta.asttools.dump_python_source(tree)
mock.patch('_pytest.assertion.rewrite.rewrite_asserts',
side_effect=replacement_rewrite_asserts).start()
$ python view_rewritting_tests.py -k test_len
===================================================== test session starts =====================================================
platform linux2 -- Python 2.7.6 -- py-1.4.25 -- pytest-2.7.0.dev1
plugins: mock
collected 41 items
pytest-git-remote-2/testing/test_assertrewrite.py
def f():
l = list(range(10))
assert (len(l) == 11)
import __builtin__ as @py_builtins
import _pytest.assertion.rewrite as @pytest_ar
def f():
l = list(range(10))
@py_assert2 = len(l)
@py_assert5 = 11
@py_assert4 = (@py_assert2 == @py_assert5)
if (not @py_assert4):
@py_format7 = (@pytest_ar._call_reprcompare(('==',), (@py_assert4,), ('%(py3)s\n{%(py3)s = %(py0)s(%(py1)s)\n} == %(py6)s',), (@py_assert2, @py_assert5)) % {'py0':@pytest_ar._saferepr(len) if (('len' in @py_builtins.locals()) or @pytest_ar._should_repr_global_name(len)) else 'len', 'py1':@pytest_ar._saferepr(l) if (('l' in @py_builtins.locals()) or @pytest_ar._should_repr_global_name(l)) else 'l', 'py3':@pytest_ar._saferepr(@py_assert2), 'py6':@pytest_ar._saferepr(@py_assert5)})
@py_format9 = (('' + 'assert %(py8)s') % {'py8':@py_format7})
raise AssertionError(@pytest_ar._format_explanation(@py_format9))
@py_assert2 = @py_assert4 = @py_assert5 = None
.
============================================= 40 tests deselected by '-ktest_len' =============================================
=========================================== 1 passed, 40 deselected in 0.03 seconds ===========================================
"""
Use like:
python view_rewritting_tests.py -k test_len
"""
import os, sys
import pytest
from unparse_prep import patch_to_print_rewritten_source
patch_to_print_rewritten_source()
pytestdir = os.path.dirname(pytest.__file__)
test_assertrewrite_path = os.path.join(pytestdir, 'testing/test_assertrewrite.py')
pytest.main(['-s', test_assertrewrite_path] + sys.argv[1:])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment