For my mpu
package I have execution-environment dependend code like
if sys.version_info < (3, 0):
pass # do something
else:
pass # do something else
and a tox file
[tox]
envlist = py27,py36
[testenv]
deps =
pytest
pytest-cov
pytest-pep8
pydocstyle
commands =
pip install -r test-requirements.txt
pip install -e .[all]
pytest .
pydocstyle
and a setup.cfg
[metadata]
description-file = README.md
[tool:pytest]
addopts = ./tests/ --doctest-modules --cov=./mpu --cov-report html:tests/reports/coverage-html --cov-report xml:tests/reports/coverage.xml --pep8 --ignore=docs/
doctest_encoding = utf-8
[pydocstyle]
ignore = D104, D105, D107, D301, D413, D203, D212, D100
match_dir = mpu
The tox file seems to do what I want, but the coverage is only for one of the tested environments. I have seen Reporting cumulative coverage across multiple Python versions in the branch coverage-combined
coverage-combined, but it doesn't work. For the first run, it seems as if it didn't execute all tests as the test coverage was way lower than before. My guess is that doctests were not executed. For the second run, I get
ERROR: InvocationError: '/home/moose/GitHub/mpu/.tox/py27/bin/coverage run --source=mpu/ setup.py test'
System
$ coverage --version
Coverage.py, version 4.5.1 with C extension
Documentation at https://coverage.readthedocs.io
Errors
Now I get this error:
======================================================================
ERROR: test_pd (unittest.loader._FailedTest)
----------------------------------------------------------------------
ImportError: Failed to import test module: test_pd
Traceback (most recent call last):
File "/usr/lib/python3.6/unittest/loader.py", line 428, in _find_test_path
module = self._get_module_from_name(name)
File "/usr/lib/python3.6/unittest/loader.py", line 369, in _get_module_from_name
__import__(name)
File "/home/moose/GitHub/mpu/tests/test_pd.py", line 8, in <module>
from mpu.pd import example_df
File "/home/moose/GitHub/mpu/mpu/pd.py", line 10, in <module>
import pandas as pd
File "/home/moose/.local/lib/python3.6/site-packages/pandas/__init__.py", line 42, in <module>
from pandas.core.api import *
File "/home/moose/.local/lib/python3.6/site-packages/pandas/core/api.py", line 10, in <module>
from pandas.core.groupby.groupby import Grouper
File "/home/moose/.local/lib/python3.6/site-packages/pandas/core/groupby/__init__.py", line 2, in <module>
from pandas.core.groupby.groupby import (
File "/home/moose/.local/lib/python3.6/site-packages/pandas/core/groupby/groupby.py", line 49, in <module>
from pandas.core.frame import DataFrame
File "/home/moose/.local/lib/python3.6/site-packages/pandas/core/frame.py", line 74, in <module>
from pandas.core.series import Series
File "/home/moose/.local/lib/python3.6/site-packages/pandas/core/series.py", line 80, in <module>
import pandas.plotting._core as gfx
File "/home/moose/.local/lib/python3.6/site-packages/pandas/plotting/__init__.py", line 11, in <module>
from pandas.plotting._core import boxplot
File "/home/moose/.local/lib/python3.6/site-packages/pandas/plotting/_core.py", line 45, in <module>
from pandas.plotting import _converter
File "/home/moose/.local/lib/python3.6/site-packages/pandas/plotting/_converter.py", line 8, in <module>
import matplotlib.units as units
File "/home/moose/.local/lib/python3.6/site-packages/matplotlib/__init__.py", line 131, in <module>
from matplotlib.rcsetup import defaultParams, validate_backend, cycler
File "/home/moose/.local/lib/python3.6/site-packages/matplotlib/rcsetup.py", line 29, in <module>
from matplotlib.fontconfig_pattern import parse_fontconfig_pattern
File "/home/moose/.local/lib/python3.6/site-packages/matplotlib/fontconfig_pattern.py", line 22, in <module>
from pyparsing import (Literal, ZeroOrMore, Optional, Regex, StringEnd,
File "/home/moose/.local/lib/python3.6/site-packages/pyparsing.py", line 943, in <module>
collections.MutableMapping.register(ParseResults)
File "/usr/lib/python3.6/abc.py", line 158, in register
if issubclass(subclass, cls):
File "/usr/lib/python3.6/abc.py", line 228, in __subclasscheck__
if issubclass(subclass, scls):
File "/usr/lib/python3.6/abc.py", line 228, in __subclasscheck__
if issubclass(subclass, scls):
File "/usr/lib/python3.6/typing.py", line 1154, in __subclasscheck__
return super().__subclasscheck__(cls)
File "/usr/lib/python3.6/abc.py", line 209, in __subclasscheck__
ok = cls.__subclasshook__(subclass)
File "/usr/lib/python3.6/typing.py", line 884, in __extrahook__
if issubclass(subclass, scls):
File "/usr/lib/python3.6/typing.py", line 1154, in __subclasscheck__
return super().__subclasscheck__(cls)
File "/usr/lib/python3.6/abc.py", line 209, in __subclasscheck__
ok = cls.__subclasshook__(subclass)
File "/usr/lib/python3.6/typing.py", line 884, in __extrahook__
[...]
File "/usr/lib/python3.6/typing.py", line 884, in __extrahook__
if issubclass(subclass, scls):
File "/usr/lib/python3.6/abc.py", line 206, in __subclasscheck__
elif subclass in cls._abc_negative_cache:
File "/usr/lib/python3.6/_weakrefset.py", line 75, in __contains__
return wr in self.data
RecursionError: maximum recursion depth exceeded in comparison