coverage_nogil.srctree 2.38 KB
Newer Older
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
# mode: run
# tag: coverage,trace,nogil

"""
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.pyx ########
# cython: linetrace=True
26
# distutils: define_macros=CYTHON_TRACE=1 CYTHON_TRACE_NOGIL=1
27

28 29 30 31 32 33
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
34 35


36
cdef int func2(int a) with gil:  # 12
Stefan Behnel's avatar
Stefan Behnel committed
37
    return a * 2                 # 13
38 39


40
def call(int a, int b):          # 16
Stefan Behnel's avatar
Stefan Behnel committed
41 42 43 44
    a, b = b, a                  # 17
    with nogil:                  # 18
        result = func1(b, a)     # 19
    return result                # 20
45 46 47 48 49 50 51 52 53 54 55 56 57 58


######## 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


59 60 61
def run_coverage():
    cov = coverage()
    cov.start()
62

63
    import coverage_test_nogil as module
64 65
    module_name = module.__name__
    module_path = module_name + '.pyx'
66 67 68
    assert not any(module.__file__.endswith(ext)
                   for ext in '.py .pyc .pyo .pyw .pyx .pxi'.split()), \
        module.__file__
69
    assert module.call(1, 2) == (1 * 2) + 2 + 1
70

71 72 73 74 75 76 77 78 79 80 81 82 83 84
    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())

    mod_file, exec_lines, excl_lines, missing_lines, _ = cov.analysis2(os.path.abspath(module_path))
    assert module_path in mod_file

    executed = set(exec_lines) - set(missing_lines)
    # 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 90


if __name__ == '__main__':
91
    run_coverage()