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