1
0
mirror of https://git.savannah.gnu.org/git/guix.git synced 2026-04-06 13:10:33 +02:00

build-system/pyproject: Ignore selected pytest inputs.

This commit includes squashed changes from
https://codeberg.org/guix/guix/pulls/7220 and
https://codeberg.org/guix/guix/pulls/7338.

* gnu/packages/aux-files/python/pytest_guix.py: New file.
* Makefile.am: Record it.
* guix/build/pyproject-build-system.scm (check): Preload pytest_guix
plugin when available.
* guix/build-system/pyproject.scm (default-pytest-guix-plugin): New
package, generated from pytest_guix.py.
(lower): Add python-pytest-guix argument, and inject it if
python-pytest is in the native-inputs.

Change-Id: I13263b461e9962aad340347657b9c9685db63927
Signed-off-by: Sharlatan Hellseher <sharlatanus@gmail.com>
This commit is contained in:
Nicolas Graves
2025-10-29 15:11:55 +01:00
committed by Sharlatan Hellseher
parent 4ae394522c
commit 3a96221c79
4 changed files with 135 additions and 12 deletions

View File

@@ -484,6 +484,7 @@ AUX_FILES = \
gnu/packages/aux-files/linux-libre/5.10-x86_64.conf \
gnu/packages/aux-files/ovmf/51-edk2-ovmf-2m-raw-x64-nosb.json \
gnu/packages/aux-files/pack-audit.c \
gnu/packages/aux-files/python/pytest_guix.py \
gnu/packages/aux-files/python/sanity-check.py \
gnu/packages/aux-files/python/sitecustomize.py \
gnu/packages/aux-files/renpy/renpy.in \

View File

@@ -0,0 +1,68 @@
# GNU Guix --- Functional package management for GNU
# Copyright © 2025 Nicolas Graves <ngraves@ngraves.fr>
#
# This file is part of GNU Guix.
#
# GNU Guix is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or (at
# your option) any later version.
#
# GNU Guix is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
import importlib.util
def pytest_addoption(parser):
"""Add stub options to be ignored by pytest.
More precisely, inject all options provided in .pytest_guix_options.json,
except options whose plugin is indeed installed.
For example, if the json file records --cov:
if the pytest_cov module is installed, its --cov will be used.
otherwise, --cov is ignored (read by this parser, but nothing is done
with it).
This allows to remove development packages, which are not required at build
time while at the same time avoiding the need to adjust test options in
pyproject.toml or other configuration files.
"""
plugin_options = {
"cov": [
"--cov",
"--cov-reset",
"--cov-report",
"--cov-config",
"--no-cov-on-fail",
"--no-cov",
"--cov-fail-under",
"--cov-append",
"--cov-branch",
"--cov-context",
],
"mypy": ["--mypy", "--mypy-config-file", "--mypy-ignore-missing-imports"],
"isort": ["--isort"],
"flake8": ["--flake8"],
"black": ["--black"],
"flakes": ["--flakes"],
"pep8": ["--pep8"],
"html": ["--html", "--self-contained-html", "--css"],
}
group = parser.getgroup(
"guix", "Options ignored by the Guix pyproject-build-system"
)
# Only add options for plugins that are not present.
for key, options in plugin_options.items():
if importlib.util.find_spec(f"pytest_{key}") is None:
# Plugin not found, add stub options
for option in options:
group.addoption(option, action="append", nargs="?")

View File

@@ -23,15 +23,19 @@
#:use-module (guix store)
#:use-module (guix utils)
#:use-module (guix gexp)
#:use-module ((guix licenses) #:prefix license:)
#:use-module (guix monads)
#:use-module (guix packages)
#:use-module (guix search-paths)
#:use-module (guix build-system)
#:use-module (guix build-system gnu)
#:use-module (guix build-system python)
#:use-module (guix build-system trivial)
#:use-module (srfi srfi-1)
#:use-module (ice-9 match)
#:export (%pyproject-build-system-modules
default-python
default-pytest-guix-plugin
default-sanity-check.py
pyproject-build
pyproject-build-system
@@ -62,6 +66,37 @@
"Return the default guile-json package, resolved lazily."
(@* (gnu packages guile) guile-json-4))
;; Maybe try to upstream it at some point, it's currently flavored for guix
;; but the idea itself is more general.
(define (default-pytest-guix-plugin python)
(let* ((effective (version-major+minor (package-version python)))
(site (string-append "lib/python" effective "/site-packages/")))
(package
(name "python-pytest-guix")
(version "0.0.1")
(source (local-file (search-auxiliary-file "python/pytest_guix.py")))
(build-system trivial-build-system)
(arguments
(list
#:modules '((guix build utils))
#:builder
#~(begin
(use-modules (guix build utils))
(let* ((site (string-append #$output "/" #$site))
(dist (string-append site "pytest_guix-" #$version
".dist.info")))
(mkdir-p dist)
(copy-file #$source (string-append site "/pytest_guix.py"))
(call-with-output-file (string-append dist "/entry_points.txt")
(lambda (port)
(format port "[pytest11]~%guix=pytest_guix~%")))))))
(home-page "https://guix.gnu.org/")
(synopsis "Ignore selected pytest options")
(description
"This package provides the script to cleanly ignore pytest options at the
build-system level.")
(license license:gpl3+))))
;; TODO: On the next iteration of python-team, migrate the sanity-check to
;; importlib_metadata instead of setuptools.
(define (default-sanity-check.py)
@@ -69,13 +104,21 @@
(define* (lower name
#:key source inputs native-inputs outputs system target
test-backend
(python (default-python))
(python-pytest-guix (default-pytest-guix-plugin python))
(sanity-check.py (default-sanity-check.py))
#:allow-other-keys
#:rest arguments)
"Return a bag for NAME."
(define private-keywords
'(#:target #:python #:inputs #:native-inputs #:sanity-check.py))
'(#:target #:python #:inputs #:native-inputs
#:python-pytest-guix #:sanity-check.py))
(define native-inputs-labels (map car native-inputs))
(define has-pytest?
(or (member "python-pytest-bootstrap" native-inputs-labels)
(member "python-pytest" native-inputs-labels)))
(and (not target) ;XXX: no cross-compilation
(bag
@@ -88,9 +131,16 @@
;; Keep the standard inputs of 'gnu-build-system'.
,@(standard-packages)))
(build-inputs `(("python" ,python)
("sanity-check.py" ,sanity-check.py)
,@native-inputs))
(build-inputs
`(("python" ,python)
("sanity-check.py" ,sanity-check.py)
,@(if (and has-pytest?
(match test-backend
((or 'pytest-with-guix-plugin #f) #t)
(_ #f)))
`(("python-pytest-guix" ,python-pytest-guix))
`())
,@native-inputs))
(outputs (append outputs '(wheel)))
(build pyproject-build)
(arguments (strip-keyword-arguments private-keywords arguments)))))

View File

@@ -314,7 +314,7 @@ without errors."
(with-directory-excursion "/tmp"
(invoke "python" sanity-check.py (site-packages inputs outputs)))))
(define* (check #:key tests? test-backend test-flags #:allow-other-keys)
(define* (check #:key inputs tests? test-backend test-flags #:allow-other-keys)
"Run the test suite of a given Python package."
(if tests?
;; Unfortunately with PEP 517 there is no common method to specify test
@@ -330,20 +330,24 @@ without errors."
(tests-found (find-files "." "test.*\\.py$"))
(use-test-backend
(or test-backend
;; Prefer pytest
(if pytest 'pytest #f)
(if stestr 'stestr #f)
(if nosetests 'nose #f)
(if nose2 'nose2 #f)
;; By order of preference.
(and (assoc-ref inputs "python-pytest-guix")
'pytest-with-guix-plugin)
(and pytest 'pytest)
(and stestr 'stestr)
(and nosetests 'nose)
(and nose2 'nose2)
;; Fall back to setup.py. The command is deprecated, but is
;; a superset of unittest, so should work for most packages.
;; Keep it until setuptools removes `setup.py test'.
;; See https://setuptools.pypa.io/en/latest/deprecated/\
;; commands.html#test-build-package-and-run-a-unittest-suite
(if have-setup-py 'setup.py #f)
(if tests-found 'unittest #f))))
(and have-setup-py 'setup.py)
(and tests-found 'unittest))))
(format #t "Using ~a~%" use-test-backend)
(match use-test-backend
('pytest-with-guix-plugin
(apply invoke pytest "-vv" "-p" "pytest_guix" test-flags))
('pytest
(apply invoke pytest "-vv" test-flags))
('nose