Skip to content

Commit d1852a4

Browse files
committed
Remove assertion reinterpretation
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.
1 parent ee374e3 commit d1852a4

File tree

10 files changed

+45
-864
lines changed

10 files changed

+45
-864
lines changed

CHANGELOG.rst

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
A number of incompatible changes were made in this release, with the intent of removing features deprecated for a long
77
time or change existing behaviors in order to make them less surprising/more useful.
88

9+
* Reinterpretation mode has now been removed. Only plain and rewrite
10+
mode are available, consequently the ``--assert=reinterp`` option is
11+
no longer available. Thanks `@flub`_ for the PR.
12+
913
* The following deprecated commandline options were removed:
1014

1115
* ``--genscript``: no longer supported;

_pytest/_code/__init__.py

-3
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@
44
from .code import Frame # noqa
55
from .code import Traceback # noqa
66
from .code import getrawcode # noqa
7-
from .code import patch_builtins # noqa
8-
from .code import unpatch_builtins # noqa
97
from .source import Source # noqa
108
from .source import compile_ as compile # noqa
119
from .source import getfslineno # noqa
12-

_pytest/_code/code.py

-35
Original file line numberDiff line numberDiff line change
@@ -179,18 +179,6 @@ def getlocals(self):
179179
return self.frame.f_locals
180180
locals = property(getlocals, None, None, "locals of underlaying frame")
181181

182-
def reinterpret(self):
183-
"""Reinterpret the failing statement and returns a detailed information
184-
about what operations are performed."""
185-
from _pytest.assertion.reinterpret import reinterpret
186-
if self.exprinfo is None:
187-
source = py.builtin._totext(self.statement).strip()
188-
x = reinterpret(source, self.frame, should_fail=True)
189-
if not py.builtin._istext(x):
190-
raise TypeError("interpret returned non-string %r" % (x,))
191-
self.exprinfo = x
192-
return self.exprinfo
193-
194182
def getfirstlinesource(self):
195183
# on Jython this firstlineno can be -1 apparently
196184
return max(self.frame.code.firstlineno, 0)
@@ -830,29 +818,6 @@ def toterminal(self, tw):
830818
tw.line("")
831819

832820

833-
834-
oldbuiltins = {}
835-
836-
def patch_builtins(assertion=True, compile=True):
837-
""" put compile and AssertionError builtins to Python's builtins. """
838-
if assertion:
839-
from _pytest.assertion import reinterpret
840-
l = oldbuiltins.setdefault('AssertionError', [])
841-
l.append(py.builtin.builtins.AssertionError)
842-
py.builtin.builtins.AssertionError = reinterpret.AssertionError
843-
if compile:
844-
import _pytest._code
845-
l = oldbuiltins.setdefault('compile', [])
846-
l.append(py.builtin.builtins.compile)
847-
py.builtin.builtins.compile = _pytest._code.compile
848-
849-
def unpatch_builtins(assertion=True, compile=True):
850-
""" remove compile and AssertionError builtins from Python builtins. """
851-
if assertion:
852-
py.builtin.builtins.AssertionError = oldbuiltins['AssertionError'].pop()
853-
if compile:
854-
py.builtin.builtins.compile = oldbuiltins['compile'].pop()
855-
856821
def getrawcode(obj, trycall=True):
857822
""" return code object for given function. """
858823
try:

_pytest/assertion/__init__.py

+19-45
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,14 @@ def pytest_addoption(parser):
1414
group.addoption('--assert',
1515
action="store",
1616
dest="assertmode",
17-
choices=("rewrite", "reinterp", "plain",),
17+
choices=("rewrite", "plain",),
1818
default="rewrite",
1919
metavar="MODE",
20-
help="""control assertion debugging tools. 'plain'
21-
performs no assertion debugging. 'reinterp'
22-
reinterprets assert statements after they failed
23-
to provide assertion expression information.
24-
'rewrite' (the default) rewrites assert
25-
statements in test modules on import to
26-
provide assert expression information. """)
20+
help="""Control assertion debugging tools. 'plain'
21+
performs no assertion debugging. 'rewrite'
22+
(the default) rewrites assert statements in
23+
test modules on import to provide assert
24+
expression information.""")
2725

2826

2927
def pytest_namespace():
@@ -60,37 +58,21 @@ class AssertionState:
6058
def __init__(self, config, mode):
6159
self.mode = mode
6260
self.trace = config.trace.root.get("assertion")
61+
self.hook = None
6362

6463

65-
def install_importhook(config, mode):
66-
if mode == "rewrite":
67-
try:
68-
import ast # noqa
69-
except ImportError:
70-
mode = "reinterp"
71-
else:
72-
# Both Jython and CPython 2.6.0 have AST bugs that make the
73-
# assertion rewriting hook malfunction.
74-
if (sys.platform.startswith('java') or
75-
sys.version_info[:3] == (2, 6, 0)):
76-
mode = "reinterp"
77-
78-
config._assertstate = AssertionState(config, mode)
79-
80-
_load_modules(mode)
81-
from _pytest.monkeypatch import MonkeyPatch
82-
m = MonkeyPatch()
83-
config._cleanup.append(m.undo)
84-
m.setattr(py.builtin.builtins, 'AssertionError',
85-
reinterpret.AssertionError) # noqa
86-
87-
hook = None
88-
if mode == "rewrite":
89-
hook = rewrite.AssertionRewritingHook(config) # noqa
90-
sys.meta_path.insert(0, hook)
91-
92-
config._assertstate.hook = hook
93-
config._assertstate.trace("configured with mode set to %r" % (mode,))
64+
def install_importhook(config):
65+
"""Try to install the rewrite hook, raise SystemError if it fails."""
66+
# Both Jython and CPython 2.6.0 have AST bugs that make the
67+
# assertion rewriting hook malfunction.
68+
if (sys.platform.startswith('java') or
69+
sys.version_info[:3] == (2, 6, 0)):
70+
raise SystemError('rewrite not supported')
71+
72+
config._assertstate = AssertionState(config, 'rewrite')
73+
config._assertstate.hook = hook = rewrite.AssertionRewritingHook(config)
74+
sys.meta_path.insert(0, hook)
75+
config._assertstate.trace('installed rewrite import hook')
9476
def undo():
9577
hook = config._assertstate.hook
9678
if hook is not None and hook in sys.meta_path:
@@ -169,13 +151,5 @@ def pytest_sessionfinish(session):
169151
assertstate.hook.set_session(None)
170152

171153

172-
def _load_modules(mode):
173-
"""Lazily import assertion related code."""
174-
global rewrite, reinterpret
175-
from _pytest.assertion import reinterpret # noqa
176-
if mode == "rewrite":
177-
from _pytest.assertion import rewrite # noqa
178-
179-
180154
# Expose this plugin's implementation for the pytest_assertrepr_compare hook
181155
pytest_assertrepr_compare = util.assertrepr_compare

0 commit comments

Comments
 (0)