-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
pytest.raises(AssertionError) fails with compiled cython modules #645
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
rauses should take the assertion rewriting into acount and match the BuiltinAssertionError when assertion rewriting is enabled |
pytest-output.txt synced the attachements |
Yesterday I stumbled over this, and it looks like "assert False" in Cython raises an exception with the name 'AssertionError', but with a different type object than Python's AssertionError isinstance(exc, AssertionError) => False
try:
except AssertionError: # didn't caught exception (but Exception does) |
seems like we need a cython bug workaround, i wonder where to put it |
Hmm, here's what Cython does for an "assert": https://github.com/cython/cython/blob/master/Cython/Compiler/Nodes.py#L5762 Specifically: code.putln(
"PyErr_SetObject(PyExc_AssertionError, %s);" % self.value.py_result())
code.putln(
"PyErr_SetNone(PyExc_AssertionError);") I'll test whether this behaviour can be reproduced with a simple, plain extension module. |
does the same happen if with --assert plain i recall putting in a fix for a certain assertion error issue, since pytest used a custom assdertionerror subclass for reinterpretation for a while i wonder if it resurfaced due to the c api usage |
Looks like Works (ugly as hell) def test_nsindex_segment_limit():
idx = NSIndex()
# work around known bug in py.test https://github.com/pytest-dev/pytest/issues/645
try:
idx[H(1)] = hashindex.MAX_REF + 1, 0
except Exception as e:
# it's not Python's AssertionError
assert e.__class__.__name__ == "AssertionError"
else:
assert False
assert H(1) not in idx
idx[H(2)] = hashindex.MAX_REF, 0
assert H(2) in idx Works: def test_nsindex_segment_limit():
idx = NSIndex()
with pytest.raises(AssertionError):
idx[H(1)] = hashindex.MAX_REF + 1, 0 (^ just noticed that now, I just assumed that pytest.raises wouldn't work, too, so I'm going to use that instead) Nope: class NSSLTestCase(BaseTestCase):
def test_1234(self):
idx = NSIndex()
with self.assert_raises(AssertionError):
idx[H(1)] = hashindex.MAX_REF + 1, 0 With Both "reinterp" and "rewrite" fail. |
does it work with |
Yep, but neither reinterp nor rewrite pass. |
FWIW this is also a valid workaround: with self.assertRaises(self.failureException):
... I never took the time to look it up, but I suspect that |
since we now do have assertion rewriting we should decide if we want to stop that monkeypatching and close this issue after a decission |
Do we need the monkey patching when using assertion rewriting? |
as far as i can tell its mostly unnecessary |
What I don't quite understand is why "assertion rewriting" has any effect here. The |
the problem is the assertion reinterpreter fallback replacing the built-in assertion error with a custom one thats a subclass c code then will still use the base class, but isinstance will fail on the python side |
What about getting rid of If you agree in principle I'll open a separate issue. |
Okay. But I pass the same "wrong" AssertionError to both kind of "raises" check, why does one work and the other doesn't? Aha. _pytest.python, line 1205ff: def raises(expected_exception, *args, **kwargs):
...
if expected_exception is AssertionError:
# we want to catch a AssertionError
# replace our subclass with the builtin one
# see https://github.com/pytest-dev/pytest/issues/176
from _pytest.assertion.util import BuiltinAssertionError \
as expected_exception ... and this special-casing of AssertionError is then not present in UnitTest.assertRaises. Got it. |
the pytest one special cases AssertionError replacing it with the builtin one |
@The-Compiler see the pytest-dev ml |
Assertion reinterpret is still used if the assertion code is in a non-test module, right? |
@flub @nicoddemus can this be closed for the 3.0 release? |
Yes, should no longer be an issue because we no longer replace the builtin |
Was this issue closed because it was fixed? Using a freshly cloned pytest, I'm seeing a difference between pytest's handling of With two files # pytestbug.pyx
def assert_func():
assert False, "AssertionError"
def type_func():
raise TypeError("TypeError") and test_foo.py
import unittest
import pyximport
pyximport.install() # avoids need for setup.py
import pytestbug
def assert_func():
assert False, "AssertionError"
def type_func():
raise TypeError("TypeError")
class TestFoo(unittest.TestCase):
def test_assert(self):
with self.assertRaisesRegexp(AssertionError, "AssertionError"):
assert_func()
def test_type(self):
with self.assertRaisesRegexp(TypeError, "TypeError"):
type_func()
def test_assert_cython(self):
with self.assertRaisesRegexp(AssertionError, "AssertionError"):
pytestbug.assert_func()
def test_type_cython(self):
with self.assertRaisesRegexp(TypeError, "TypeError"):
pytestbug.type_func()
EDIT: Forgot to mention that EDIT2: I see now that the original issue was for |
It should be fixed in the |
Yep, user error on my part, sorry :( Checking out the feature-branch fixed it. Thanks, I'm excited to be porting pandas over to pytest. |
Cool! 😎 |
We're seeing a strange error in xenial builds which appear to be stemming from the AssertionError that pytest produces being _different_ from the standard AssertionError. This means that the helpers modified here weren't behaving correctly, because they weren't catching AssertionErrors as one would expect. (I believe this is related, in some way, to pytest-dev/pytest#645, but the only version of pytest where we're affected is so far in the past that it's not worth pursuing it any further as we have a workaround.)
These libraries provide backports of Python 3's stdlib components to Python 2. As we only support Python 3, we can simply use the stdlib now. This pull request does the following: * removes some unneeded compatibility code for the old spelling of `assertRaisesRegex` * replaces invocations of the Python 2-only `assertItemsEqual` with its new name, `assertCountEqual` * replaces all usage of `unittest2` with `unittest` * replaces all usage of `contextlib2` with `contextlib` * drops `unittest2` and `contextlib2` from requirements files and tox.ini It also rewrites some `test_azure` helpers to use bare asserts. We were seeing a strange error in xenial builds of this branch which appear to be stemming from the AssertionError that pytest produces being _different_ from the standard AssertionError. This means that the modified helpers weren't behaving correctly, because they weren't catching AssertionErrors as one would expect. (I believe this is related, in some way, to pytest-dev/pytest#645, but the only version of pytest where we're affected is so far in the past that it's not worth pursuing it any further as we have a workaround.)
Originally reported by: Steffen Roecker (BitBucket: sroecker, GitHub: sroecker)
This issue seems similar to issue #176.
Running with unittest works fine, however pytest fails when the imported module assert_helper is compiled to a .so with Cython.
platform linux2 -- Python 2.7.3 -- py-1.4.26 -- pytest-2.6.4
plugins: xdist, cov, mock
Cython==0.21
The text was updated successfully, but these errors were encountered: