__del__ method incorrectly reported as missing in a problem with circular references
andymwood opened this issue · 1 comments
Summary
The following problem has two objects that reference each other and a __del__
method in one of the classes. pytest-cov incorrectly reports that the __del__
method hasn't been called.
Expected vs actual result
Expected 100% coverage. Get 91% coverage.
Reproducer
$ python3.10 -m venv venv
$ . venv/bin/activate
$ pip install pytest-cov
$ pytest --cov=. --cov-report=term-missing test_module.py
================================================================== test session starts ===================================================================
platform linux -- Python 3.10.11, pytest-7.4.0, pluggy-1.2.0
rootdir: ...
plugins: cov-4.1.0
collected 1 item
test_module.py . [100%]
A.__del__
---------- coverage: platform linux, python 3.10.11-final-0 ----------
Name Stmts Miss Cover Missing
----------------------------------------------
test_module.py 10 1 90% 3
----------------------------------------------
TOTAL 10 1 90%
=================================================================== 1 passed in 0.06s ====================================================================
Versions
$ pip list
Package Version
-------------- -------
coverage 7.2.7
exceptiongroup 1.1.2
iniconfig 2.0.0
packaging 23.1
pip 23.0.1
pluggy 1.2.0
pytest 7.4.0
pytest-cov 4.1.0
setuptools 65.5.0
tomli 2.0.1
$ python --version
Python 3.10.11
Code
test_module.py:
class A:
def __del__(self):
print('\nA.__del__')
class B:
pass
def test_case():
x = A()
x.y = B()
x.y.x = x
assert x is not None
__del__
methods are very difficult. In your case, the method is being called during interpreter shutdown, so possibly after coverage has stopped measurement. They can cause other troubles as well (see the pink warning box at https://docs.python.org/3/reference/datamodel.html#object.__del__). You might want to consider refactoring to avoid the need for __del__
.
In the meantime, you can add a pragma comment to indicate that you understand the line will not be measured: https://coverage.readthedocs.io/en/7.2.7/excluding.html#excluding-code-from-coverage-py