Skip to content

Commit 359aeed

Browse files
authored
Merge pull request statsmodels#5188 from bashtage/cycov-rebase
BLD/TST: Add coverage for Cython files
2 parents 7ffda05 + ce3b6e5 commit 359aeed

File tree

9 files changed

+198
-17
lines changed

9 files changed

+198
-17
lines changed

.coveragerc

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,37 @@
11
# .coveragerc to control coverage.py
22
[run]
3-
branch = False
3+
source = statsmodels
4+
branch = True
5+
6+
omit =
7+
# print_version is untestable
8+
*/print_version.py
9+
# skip compatibility code
10+
*/compat/*
11+
# Unused file
12+
*/results/gee_generate_tests.py
13+
# Results for tests
14+
*/tests/results/*
15+
# Simulation checks
16+
*/tests/*_simulation_check.py
17+
# Misc non-test files in test directories
18+
*/tests/_*
19+
*/tests/e*
20+
*/tests/c*
21+
*/tests/d*
22+
*/tests/g*
23+
*/tests/m*
24+
*/tests/p*
25+
*/tests/r*
26+
*/tests/s*
27+
# Versioneer
28+
*/_version.py
429

530
[report]
631
show_missing = True
732

33+
ignore_errors = False
34+
835
# Regexes for lines to exclude from consideration
936
exclude_lines =
1037
# Have to re-enable the standard pragma
@@ -17,12 +44,13 @@ exclude_lines =
1744
# Don't complain if tests don't hit defensive assertion code:
1845
raise AssertionError
1946
raise NotImplementedError
47+
except NotImplementedError
48+
# Ignore pass
49+
pass
2050

2151
# Don't complain if non-runnable code isn't run:
2252
if 0:
2353
if __name__ == .__main__.:
2454

25-
ignore_errors = False
26-
2755
[html]
2856
directory = coverage_html_report

.travis.yml

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ env:
2323
- BLAS="mkl blas=*=mkl" # Use Intel MKL by default
2424
- BUILD_INIT=tools/ci/travis_conda.sh
2525
- DEPEND_ALWAYS="pyyaml joblib pip colorama"
26+
- SM_CYTHON_COVERAGE=false # Run takes > 1 hour and so not feasible
2627

2728
matrix:
2829
fast_finish: true
@@ -100,6 +101,8 @@ notifications:
100101
on_success: always
101102

102103
before_install:
104+
# Ensure latest tags are available
105+
- git fetch --tags
103106
# Show information about CPU running job to understand BLAS issues
104107
- sudo lshw -class processor
105108
# Fix for headless TravisCI
@@ -114,7 +117,12 @@ before_install:
114117
- |
115118
if [ ${COVERAGE} = true ]; then
116119
pip install codecov coverage coveralls pytest-cov
117-
export COVERAGE_OPTS="--cov-config=.travis_coveragerc --cov=statsmodels"
120+
if [ -z ${SM_CYTHON_COVERAGE} ] || [ ${SM_CYTHON_COVERAGE} = false ]; then
121+
export COVERAGE_OPTS="--cov-config=tools/coveragerc/.coveragerc_travis --cov=statsmodels"
122+
else
123+
export COVERAGE_OPTS="--cov-config=tools/coveragerc/.coveragerc_cython --cov=statsmodels"
124+
fi
125+
echo "Cython coverage:" ${SM_CYTHON_COVERAGE}
118126
else
119127
export COVERAGE_OPTS=""
120128
fi
@@ -124,7 +132,6 @@ before_install:
124132

125133
# Install packages
126134
install:
127-
- python setup.py build_ext --inplace
128135
- python setup.py develop
129136

130137
script:
@@ -138,5 +145,5 @@ script:
138145
- ./lint.sh
139146

140147
after_success:
141-
- if [ ${COVERAGE} = true ]; then coveralls --rcfile=${SRCDIR}/.travis_coveragerc; fi
148+
- if [ ${COVERAGE} = true ]; then coveralls --rcfile=${SRCDIR}/tools/coveragerc/.coveragerc_travis; fi
142149
- if [ ${COVERAGE} = true ]; then codecov; fi

MANIFEST.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
global-include *.csv *.py *.txt *.pyx *.pxd *.pxi *.c *.h
1+
global-include *.csv *.py *.txt *.pyx *.pyx.in *.pxd *.pxi *.c *.h
22
include MANIFEST.in
33
include README.rst
44

requirements.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
numpy>=1.11
2+
scipy>=0.18
3+
pandas>=0.18
4+
patsy>=0.5

setup.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
"""
2+
To build with coverage of Cython files
3+
export SM_CYTHON_COVERAGE=1
4+
python setup.py develop
5+
pytest --cov-config=tools/coveragerc/.coveragerc_cython --cov=statsmodels \
6+
statsmodels
7+
"""
18
import fnmatch
29
import os
310
import sys
@@ -86,6 +93,7 @@
8693
'Environment :: Console',
8794
'Programming Language :: Cython',
8895
'Programming Language :: Python :: 2.7',
96+
'Programming Language :: Python :: 3.4',
8997
'Programming Language :: Python :: 3.5',
9098
'Programming Language :: Python :: 3.6',
9199
'Programming Language :: Python :: 3.7',
@@ -112,8 +120,13 @@
112120
##############################################################################
113121
# Extension Building
114122
##############################################################################
115-
COMPILER_DIRECTIVES = {}
116-
DEFINE_MACROS = []
123+
CYTHON_COVERAGE = os.environ.get('SM_CYTHON_COVERAGE', False)
124+
CYTHON_COVERAGE = CYTHON_COVERAGE in ('1', 'true', '"true"')
125+
CYTHON_TRACE_NOGIL = str(int(CYTHON_COVERAGE))
126+
if CYTHON_COVERAGE:
127+
print('Building with coverage for Cython code')
128+
COMPILER_DIRECTIVES = {'linetrace': CYTHON_COVERAGE}
129+
DEFINE_MACROS = [('CYTHON_TRACE_NOGIL', CYTHON_TRACE_NOGIL)]
117130

118131

119132
exts = dict(
@@ -268,14 +281,14 @@ def process_tempita(source_name):
268281
##############################################################################
269282
package_data = defaultdict(list)
270283
filetypes = ['*.csv', '*.txt', '*.dta']
271-
for root, dirnames, filenames in os.walk(pjoin(os.getcwd(), 'statsmodels', 'datasets')): # noqa: E501
284+
for root, _, filenames in os.walk(pjoin(os.getcwd(), 'statsmodels', 'datasets')): # noqa: E501
272285
matches = []
273286
for filetype in filetypes:
274287
for filename in fnmatch.filter(filenames, filetype):
275288
matches.append(filename)
276289
if matches:
277290
package_data['.'.join(relpath(root).split(os.path.sep))] = filetypes
278-
for root, dirnames, filenames in os.walk(pjoin(os.getcwd(), 'statsmodels')):
291+
for root, _, _ in os.walk(pjoin(os.getcwd(), 'statsmodels')):
279292
if root.endswith('results'):
280293
package_data['.'.join(relpath(root).split(os.path.sep))] = filetypes
281294

tools/ci/travis_conda.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ PKGS="${PKGS} patsy"; if [ ${PATSY} ]; then PKGS="${PKGS}=${PATSY}"; fi
1212
PKGS="${PKGS} pandas"; if [ ${PANDAS} ]; then PKGS="${PKGS}=${PANDAS}"; fi
1313
PKGS="${PKGS} Cython"; if [ ${CYTHON} ]; then PKGS="${PKGS}=${CYTHON}"; fi
1414
if [ ${USEMPL} = true ]; then PKGS="${PKGS} matplotlib"; if [ ${MATPLOTLIB} ]; then PKGS="${PKGS}=${MATPLOTLIB}"; fi; fi
15-
if [ ${COVERAGE} = true ]; then export COVERAGE_OPTS=" --cov-config=.travis_coveragerc --cov=statsmodels "; else export COVERAGE_OPTS=""; fi
15+
if [ ${COVERAGE} = true ]; then export COVERAGE_OPTS=" --cov-config=.coveragerc_travis --cov=statsmodels "; else export COVERAGE_OPTS=""; fi
1616
echo conda create --yes --quiet -n statsmodels-test python=${PYTHON} ${BLAS} ${PKGS} ${OPTIONAL} ${DEPEND_ALWAYS}
1717
conda create --yes --quiet -n statsmodels-test python=${PYTHON} ${BLAS} ${PKGS} ${OPTIONAL} ${DEPEND_ALWAYS}
1818
source activate statsmodels-test

tools/coveragerc/.coveragerc_cython

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
[run]
2+
source = statsmodels
3+
branch = True
4+
plugins = Cython.Coverage
5+
6+
omit =
7+
# print_version is untestable
8+
*/print_version.py
9+
# skip compatibility code
10+
*/compat/*
11+
# Unused file
12+
*/results/gee_generate_tests.py
13+
# Results for tests
14+
*/tests/results/*
15+
# Simulation checks
16+
*/tests/*_simulation_check.py
17+
# Misc non-test files in test directories
18+
*/tests/_*
19+
*/tests/e*
20+
*/tests/c*
21+
*/tests/d*
22+
*/tests/g*
23+
*/tests/m*
24+
*/tests/p*
25+
*/tests/r*
26+
*/tests/s*
27+
# Versioneer
28+
*/_version.py
29+
30+
[report]
31+
show_missing = True
32+
33+
ignore_errors = True
34+
35+
# Regexes for lines to exclude from consideration
36+
exclude_lines =
37+
# Have to re-enable the standard pragma
38+
pragma: no cover
39+
40+
# Don't complain about missing debug-only code:
41+
def __repr__
42+
if self\.debug
43+
44+
# Don't complain if tests don't hit defensive assertion code:
45+
raise AssertionError
46+
raise NotImplementedError
47+
except NotImplementedError
48+
# Ignore pass
49+
pass
50+
51+
# Don't complain if non-runnable code isn't run:
52+
if 0:
53+
if __name__ == .__main__.:
54+
55+
[html]
56+
directory = cython_coverage_report

.travis_coveragerc renamed to tools/coveragerc/.coveragerc_travis

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
[run]
2+
source = statsmodels
23
branch = True
3-
include =
4-
*/statsmodels/*
54

65
omit =
76
# print_version is untestable
87
*/print_version.py
9-
# skip compatability code
8+
# skip compatibility code
109
*/compat/*
1110
# Unused file
1211
*/results/gee_generate_tests.py
@@ -27,8 +26,11 @@ omit =
2726
# Versioneer
2827
*/_version.py
2928

30-
3129
[report]
30+
show_missing = True
31+
32+
ignore_errors = True
33+
3234
# Regexes for lines to exclude from consideration
3335
exclude_lines =
3436
# Have to re-enable the standard pragma
@@ -41,8 +43,11 @@ exclude_lines =
4143
# Don't complain if tests don't hit defensive assertion code:
4244
raise AssertionError
4345
raise NotImplementedError
46+
except NotImplementedError
47+
48+
# Ignore pass
49+
pass
4450

4551
# Don't complain if non-runnable code isn't run:
4652
if 0:
4753
if __name__ == .__main__.:
48-
if name == .__main__.:

tox.ini

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
##############################################################################
2+
# Intended to simplify local generation of coverage of Cython files
3+
#
4+
# tox -e cython-coverage
5+
#
6+
# will produce a HTML report showing line-by-line coverage
7+
#
8+
# can be used to run standard tests on Python 2.7, 3.5, 3.6, and 3.7 or a
9+
# run with coverage but without coverage of Cython files using
10+
#
11+
# tox -e ENV
12+
#
13+
# where env is one of the values in envlist or all environments (slow)
14+
#
15+
# tox
16+
#
17+
##############################################################################
18+
[tox]
19+
envlist =
20+
py27
21+
py35
22+
py36
23+
py37
24+
coverage
25+
cython-coverage
26+
27+
[testenv]
28+
deps =
29+
-rrequirements.txt
30+
cython
31+
matplotlib
32+
joblib
33+
pytest>=3
34+
pytest-xdist
35+
setenv =
36+
MKL_NUM_THREADS=1
37+
NUMEXPR_NUM_THREADS=1
38+
OMP_NUM_THREADS=1
39+
OPENBLAS_NUM_THREADS=1
40+
changedir = {homedir}
41+
commands =
42+
python -c "import statsmodels;statsmodels.test(['-n 2'], exit=True)"
43+
44+
[testenv:coverage]
45+
usedevelop = True
46+
deps =
47+
{[testenv]deps}
48+
pytest-cov
49+
setenv =
50+
{[testenv]setenv}
51+
SM_CYTHON_COVERAGE=false
52+
changedir = {toxinidir}
53+
commands =
54+
coverage erase
55+
pytest -n 2 --cov-config .coveragerc --cov-report html --cov=statsmodels statsmodels
56+
57+
[testenv:cython-coverage]
58+
usedevelop = True
59+
deps =
60+
{[testenv]deps}
61+
pytest-cov
62+
setenv =
63+
{[testenv]setenv}
64+
SM_CYTHON_COVERAGE=true
65+
changedir = {toxinidir}
66+
commands =
67+
coverage erase
68+
pytest -n 2 --cov-config tools/coveragerc/.coveragerc_cython --cov-report html --cov=statsmodels statsmodels

0 commit comments

Comments
 (0)