Skip to content

Commit

Permalink
Remove assertion reinterpretation
Browse files Browse the repository at this point in the history
The assertion reinterpretation is an old backwards compatibility
mode which was no longer being maintained on feature-parity with
the assertion rewriting mode.  It was also responsible for some
dubious patching of builtins and test with side-effects would
suddenly start passing.  Since re-writing has been the default for
a long time and plugins are now also re-written it is time to
retire reinterpretation.
  • Loading branch information
flub committed Jul 14, 2016
1 parent ee374e3 commit d1852a4
Show file tree
Hide file tree
Showing 10 changed files with 45 additions and 864 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
A number of incompatible changes were made in this release, with the intent of removing features deprecated for a long
time or change existing behaviors in order to make them less surprising/more useful.

* Reinterpretation mode has now been removed. Only plain and rewrite
mode are available, consequently the ``--assert=reinterp`` option is
no longer available. Thanks `@flub`_ for the PR.

* The following deprecated commandline options were removed:

* ``--genscript``: no longer supported;
Expand Down
3 changes: 0 additions & 3 deletions _pytest/_code/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@
from .code import Frame # noqa
from .code import Traceback # noqa
from .code import getrawcode # noqa
from .code import patch_builtins # noqa
from .code import unpatch_builtins # noqa
from .source import Source # noqa
from .source import compile_ as compile # noqa
from .source import getfslineno # noqa

35 changes: 0 additions & 35 deletions _pytest/_code/code.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,18 +179,6 @@ def getlocals(self):
return self.frame.f_locals
locals = property(getlocals, None, None, "locals of underlaying frame")

def reinterpret(self):
"""Reinterpret the failing statement and returns a detailed information
about what operations are performed."""
from _pytest.assertion.reinterpret import reinterpret
if self.exprinfo is None:
source = py.builtin._totext(self.statement).strip()
x = reinterpret(source, self.frame, should_fail=True)
if not py.builtin._istext(x):
raise TypeError("interpret returned non-string %r" % (x,))
self.exprinfo = x
return self.exprinfo

def getfirstlinesource(self):
# on Jython this firstlineno can be -1 apparently
return max(self.frame.code.firstlineno, 0)
Expand Down Expand Up @@ -830,29 +818,6 @@ def toterminal(self, tw):
tw.line("")



oldbuiltins = {}

def patch_builtins(assertion=True, compile=True):
""" put compile and AssertionError builtins to Python's builtins. """
if assertion:
from _pytest.assertion import reinterpret
l = oldbuiltins.setdefault('AssertionError', [])
l.append(py.builtin.builtins.AssertionError)
py.builtin.builtins.AssertionError = reinterpret.AssertionError
if compile:
import _pytest._code
l = oldbuiltins.setdefault('compile', [])
l.append(py.builtin.builtins.compile)
py.builtin.builtins.compile = _pytest._code.compile

def unpatch_builtins(assertion=True, compile=True):
""" remove compile and AssertionError builtins from Python builtins. """
if assertion:
py.builtin.builtins.AssertionError = oldbuiltins['AssertionError'].pop()
if compile:
py.builtin.builtins.compile = oldbuiltins['compile'].pop()

def getrawcode(obj, trycall=True):
""" return code object for given function. """
try:
Expand Down
64 changes: 19 additions & 45 deletions _pytest/assertion/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,14 @@ def pytest_addoption(parser):
group.addoption('--assert',
action="store",
dest="assertmode",
choices=("rewrite", "reinterp", "plain",),
choices=("rewrite", "plain",),
default="rewrite",
metavar="MODE",
help="""control assertion debugging tools. 'plain'
performs no assertion debugging. 'reinterp'
reinterprets assert statements after they failed
to provide assertion expression information.
'rewrite' (the default) rewrites assert
statements in test modules on import to
provide assert expression information. """)
help="""Control assertion debugging tools. 'plain'
performs no assertion debugging. 'rewrite'
(the default) rewrites assert statements in
test modules on import to provide assert
expression information.""")


def pytest_namespace():
Expand Down Expand Up @@ -60,37 +58,21 @@ class AssertionState:
def __init__(self, config, mode):
self.mode = mode
self.trace = config.trace.root.get("assertion")
self.hook = None


def install_importhook(config, mode):
if mode == "rewrite":
try:
import ast # noqa
except ImportError:
mode = "reinterp"
else:
# Both Jython and CPython 2.6.0 have AST bugs that make the
# assertion rewriting hook malfunction.
if (sys.platform.startswith('java') or
sys.version_info[:3] == (2, 6, 0)):
mode = "reinterp"

config._assertstate = AssertionState(config, mode)

_load_modules(mode)
from _pytest.monkeypatch import MonkeyPatch
m = MonkeyPatch()
config._cleanup.append(m.undo)
m.setattr(py.builtin.builtins, 'AssertionError',
reinterpret.AssertionError) # noqa

hook = None
if mode == "rewrite":
hook = rewrite.AssertionRewritingHook(config) # noqa
sys.meta_path.insert(0, hook)

config._assertstate.hook = hook
config._assertstate.trace("configured with mode set to %r" % (mode,))
def install_importhook(config):
"""Try to install the rewrite hook, raise SystemError if it fails."""
# Both Jython and CPython 2.6.0 have AST bugs that make the
# assertion rewriting hook malfunction.
if (sys.platform.startswith('java') or
sys.version_info[:3] == (2, 6, 0)):
raise SystemError('rewrite not supported')

config._assertstate = AssertionState(config, 'rewrite')
config._assertstate.hook = hook = rewrite.AssertionRewritingHook(config)
sys.meta_path.insert(0, hook)
config._assertstate.trace('installed rewrite import hook')
def undo():
hook = config._assertstate.hook
if hook is not None and hook in sys.meta_path:
Expand Down Expand Up @@ -169,13 +151,5 @@ def pytest_sessionfinish(session):
assertstate.hook.set_session(None)


def _load_modules(mode):
"""Lazily import assertion related code."""
global rewrite, reinterpret
from _pytest.assertion import reinterpret # noqa
if mode == "rewrite":
from _pytest.assertion import rewrite # noqa


# Expose this plugin's implementation for the pytest_assertrepr_compare hook
pytest_assertrepr_compare = util.assertrepr_compare
Loading

0 comments on commit d1852a4

Please sign in to comment.