1# mode: run 2# tag: coverage,trace,nogil 3 4""" 5PYTHON setup.py build_ext -i 6PYTHON coverage_test.py 7""" 8 9######## setup.py ######## 10 11from distutils.core import setup 12from Cython.Build import cythonize 13 14setup(ext_modules = cythonize([ 15 'coverage_test_*.pyx', 16])) 17 18 19######## .coveragerc ######## 20[run] 21plugins = Cython.Coverage 22 23 24######## coverage_test_nogil.pyx ######## 25# cython: linetrace=True 26# distutils: define_macros=CYTHON_TRACE=1 CYTHON_TRACE_NOGIL=1 27 28cdef int func1(int a, int b) nogil: # 4 29 cdef int x # 5 30 with gil: # 6 31 x = 1 # 7 32 cdef int c = func2(a) + b # 8 33 return x + c # 9 34 35 36cdef int func2(int a) with gil: # 12 37 return a * 2 # 13 38 39 40def call(int a, int b): # 16 41 a, b = b, a # 17 42 with nogil: # 18 43 result = func1(b, a) # 19 44 return result # 20 45 46 47######## coverage_test.py ######## 48 49import os.path 50try: 51 # io.StringIO in Py2.x cannot handle str ... 52 from StringIO import StringIO 53except ImportError: 54 from io import StringIO 55 56from coverage import coverage 57 58 59def run_coverage(): 60 cov = coverage() 61 cov.start() 62 63 import coverage_test_nogil as module 64 module_name = module.__name__ 65 module_path = module_name + '.pyx' 66 assert not any(module.__file__.endswith(ext) 67 for ext in '.py .pyc .pyo .pyw .pyx .pxi'.split()), \ 68 module.__file__ 69 assert module.call(1, 2) == (1 * 2) + 2 + 1 70 71 cov.stop() 72 73 out = StringIO() 74 cov.report(file=out) 75 #cov.report([module], file=out) 76 lines = out.getvalue().splitlines() 77 assert any(module_path in line for line in lines), \ 78 "'%s' not found in coverage report:\n\n%s" % (module_path, out.getvalue()) 79 80 mod_file, exec_lines, excl_lines, missing_lines, _ = cov.analysis2(os.path.abspath(module_path)) 81 assert module_path in mod_file 82 83 executed = set(exec_lines) - set(missing_lines) 84 # check that everything that runs with the gil owned was executed 85 assert all(line in executed for line in [12, 13, 16, 17, 18, 20]), '%s / %s' % (exec_lines, missing_lines) 86 # check that everything that runs in nogil sections was executed 87 assert all(line in executed for line in [4, 6, 7, 8, 9]), '%s / %s' % (exec_lines, missing_lines) 88 89 90if __name__ == '__main__': 91 run_coverage() 92