On Thu, Feb 26, 2026, 3:32 AM Thomas Huth <[email protected]> wrote:

> On 25/02/2026 22.04, John Snow wrote:
> > Following suit with the rest of this repository, drop avocado and
> > replace it with the Python standard "pytest" package.
> >
> > In this case, we do not truly need pytest as all we are using it for is
> > running other python processes formerly launched by shell scripts, but
> > this matches how the standalone python-qemu-qmp package does things,
> > which keeps things simple on my end.
> >
> > (pytest version chosen based off of Debian 11's package version as
> queried by
> > repology; under the assumption that this is the likely the oldest
> > version we currently leverage in testing.)
> >
> > Signed-off-by: John Snow <[email protected]>
> > ---
> >   python/Makefile          |  4 +-
> >   python/setup.cfg         |  1 +
> >   python/tests/linters.py  | 89 ++++++++++++++++++++++++++++++++++++++++
> >   python/tests/minreqs.txt |  1 +
> >   4 files changed, 93 insertions(+), 2 deletions(-)
> >   create mode 100644 python/tests/linters.py
> >
> > diff --git a/python/Makefile b/python/Makefile
> > index b6c9cd1bce2..42994d39618 100644
> > --- a/python/Makefile
> > +++ b/python/Makefile
> > @@ -105,7 +105,7 @@ develop:
> >
> >   .PHONY: check
> >   check:
> > -     @avocado --config avocado.cfg run tests/
> > +     @pytest -v tests/*.py
> >
> >   .PHONY: check-tox
> >   check-tox:
> > @@ -113,7 +113,7 @@ check-tox:
> >
> >   .PHONY: check-coverage
> >   check-coverage:
> > -     @coverage run -m avocado --config avocado.cfg run tests/*.py
> > +     @coverage run -m pytest -v tests/*.py
> >       @coverage combine
> >       @coverage html
> >       @coverage report
> > diff --git a/python/setup.cfg b/python/setup.cfg
> > index c46a95f8d41..03344526730 100644
> > --- a/python/setup.cfg
> > +++ b/python/setup.cfg
> > @@ -43,6 +43,7 @@ devel =
> >       mypy >= 1.4.0
> >       pylint >= 2.17.3
> >       pylint != 3.2.4; python_version<"3.9"
> > +    pytest >= 6.0.2
> >       tox >= 3.18.0
> >       sphinx >= 3.4.3
> >
> > diff --git a/python/tests/linters.py b/python/tests/linters.py
> > new file mode 100644
> > index 00000000000..28556c09910
> > --- /dev/null
> > +++ b/python/tests/linters.py
> > @@ -0,0 +1,89 @@
> > +# SPDX-License-Identifier: GPL-2.0-or-later
> > +
> > +import os
> > +import subprocess
> > +import sys
> > +
> > +
> > +def pyrun(*args):
> > +    subprocess.run((sys.executable, *args), check=True)
> > +
> > +
> > +class TestLinters:
> > +
> > +    def test_flake8_pkg(self):
> > +        pyrun("-m", "flake8", "qemu/")
> > +
> > +    def test_flake8_scripts(self):
> > +        pyrun("-m", "flake8", "scripts/")
> > +
> > +    def test_flake8_qapi(self):
> > +        pyrun("-m", "flake8",
> > +              "../scripts/qapi/",
> > +              "../docs/sphinx/qapidoc.py",
> > +              "../docs/sphinx/qapi_domain.py")
> > +
> > +    def test_isort_pkg(self):
> > +        pyrun("-m", "isort", "-c", "qemu/")
> > +
> > +    def test_isort_scripts(self):
> > +        pyrun("-m", "isort", "-c", "scripts/")
> > +
> > +    def test_isort_qapi(self):
> > +        pyrun("-m", "isort", "--sp", ".", "-c", "../scripts/qapi/")
> > +
> > +    def test_isort_qapi_sphinx(self):
> > +        # Force isort to recognize 'compat' as a local module and not
> > +        # third-party
> > +        pyrun("-m", "isort", "--sp", ".", "-c", "-p", "compat",
> > +              "../docs/sphinx/qapi_domain.py",
> > +              "../docs/sphinx/qapidoc.py")
> > +
> > +    def test_mypy_pkg(self):
> > +        pyrun("-m", "mypy", "-p", "qemu")
> > +
> > +    def test_mypy_scripts(self):
> > +        pyrun("-m", "mypy", "scripts/")
> > +
> > +    def test_mypy_qapi(self):
> > +        pyrun("-m", "mypy", "../scripts/qapi")
> > +
> > +    def test_mypy_iotests(self):
> > +        cwd = os.getcwd()
> > +        try:
> > +            os.chdir("../tests/qemu-iotests/")
> > +            pyrun("-m", "linters", "--mypy")
> > +        finally:
> > +            os.chdir(cwd)
>
> Not my area of expertise, but as far as I know, the iotest linters are
> already run during "make check-block", see tests/qemu-iotests/297 ... so
> aren't we checking those iotests now twice? ... so maybe best leave the
> iotests out of this script?
>

297 is skipped if the deps aren't there, this is a guaranteed run.

Plan is (someday, eventually) to drop 297 and leave it to the Python check.



>
> > +    # Setuptools v60 introduced the SETUPTOOLS_USE_DISTUTILS=stdlib
> > +    # workaround; stdlib distutils was fully removed in Python
> > +    # 3.12+. Once we are on >=3.12+ exclusively, this workaround can be
> > +    # dropped safely. Until then, it is needed for some versions on
> > +    # Fedora/Debian distributions which relied upon distro-patched
> > +    # setuptools present in CPython, but not within setuptools itself.
> > +
> > +    def test_pylint_pkg(self):
> > +        os.environ['SETUPTOOLS_USE_DISTUTILS'] = 'stdlib'
> > +        pyrun("-m", "pylint", "qemu/")
> > +
> > +    def test_pylint_scripts(self):
> > +        os.environ['SETUPTOOLS_USE_DISTUTILS'] = 'stdlib'
> > +        pyrun("-m", "pylint", "qemu/")
>
> That should be "scripts/" instead of "qemu/", shouldn't it?
>

...Oops! Sorry...


> > +    def test_pylint_qapi(self):
> > +        os.environ['SETUPTOOLS_USE_DISTUTILS'] = 'stdlib'
> > +        pyrun("-m", "pylint",
> > +              "--rcfile=../scripts/qapi/pylintrc",
> > +              "../scripts/qapi/",
> > +              "../docs/sphinx/qapidoc.py",
> > +              "../docs/sphinx/qapi_domain.py")
> > +
> > +    def test_pylint_iotests(self):
> > +        os.environ['SETUPTOOLS_USE_DISTUTILS'] = 'stdlib'
> > +        cwd = os.getcwd()
> > +        try:
> > +            os.chdir("../tests/qemu-iotests/")
> > +            pyrun("-m", "linters", "--pylint")
> > +        finally:
> > +            os.chdir(cwd)
>
> Same question here about the iotests as above.
>
>   Thomas
>
>

Reply via email to