Snippets

Antonio Cuni pytest+cython bug

Created by Antonio Cuni last modified

Cython TB not shown in pytest

This repo demonstrate a pytest bug in showing Cython tracebacks when we are in the wrong dir.

How to reproduce:

$ python setup.py build_ext --inplace
$ cd testing
$ py.test --nosugar
====================== test session starts ======================
platform linux2 -- Python 2.7.4 -- py-1.4.30 -- pytest-2.7.1
rootdir: /data/home/antocuni.large/pypy/misc/pytest-cython-tb, inifile:
plugins: sugar
collected 1 items

test_foo.py F

=========================== FAILURES ============================
_________________________ test_failing __________________________

    def test_failing():
>       foo.foo(1, 0)

test_foo.py:4:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
foo.pyx:1: in foo.foo (foo.c:751)
    ???
foo.pyx:2: in foo.foo (foo.c:655)
    ???
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

>   ???
E   ZeroDivisionError: integer division or modulo by zero

foo.pyx:5: ZeroDivisionError
=================== 1 failed in 0.01 seconds ====================

Note that the source lines of foo.pyx are not shown.

If we do it outside pytest, it works well:

$ PYTHONPATH=.. python -c 'import foo; foo.foo(1, 0)'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "foo.pyx", line 1, in foo.foo (foo.c:751)
    cpdef foo(x, y):
  File "foo.pyx", line 2, in foo.foo (foo.c:655)
    return bar(x, y)+1
  File "foo.pyx", line 5, in foo.bar (foo.c:794)
    return (x*2)/y
ZeroDivisionError: integer division or modulo by zero

The bug is triggered only when we are inside testing; if we start pytest from the root dir of the project, the traceback is shown correctly.

1
2
3
4
5
cpdef foo(x, y):
    return bar(x, y)+1

cdef bar(x, y):
    return (x*2)/y
1
2
3
4
5
6
7
from distutils.core import setup
from Cython.Build import cythonize

setup(
    name = "pytest-cython-tb",
    ext_modules = cythonize('foo.pyx'),  # accepts a glob pattern
)
1
2
3
4
5
import foo

def test_failing():
    foo.foo(1, 0)

Comments (0)

HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.