diff --git a/gnu/packages/aux-files/python/pytest_guix.py b/gnu/packages/aux-files/python/pytest_guix.py index dbe8dfe136..2ec0a3bc53 100644 --- a/gnu/packages/aux-files/python/pytest_guix.py +++ b/gnu/packages/aux-files/python/pytest_guix.py @@ -31,6 +31,12 @@ def pytest_addoption(parser): otherwise, --cov is ignored (read by this parser, but nothing is done with it). + Flags can be given with additional keyword arguments in a json object. + If the json object is not given, fallback to the default + {"action": "append", "nargs": "?"}. In practice, these arguments are only + mandatory for the store_true and store_const actions to avoid eating other + arguments. + 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. @@ -45,5 +51,8 @@ def pytest_addoption(parser): 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="?") + for option, kwargs in options.items(): + if kwargs: + group.addoption(option, **kwargs) + else: + group.addoption(option, action="append", nargs="?") diff --git a/guix/build-system/pyproject.scm b/guix/build-system/pyproject.scm index a46bd7751b..739ba451db 100644 --- a/guix/build-system/pyproject.scm +++ b/guix/build-system/pyproject.scm @@ -98,26 +98,40 @@ build-system level.") (license license:gpl3+)))) (define %default-pytest-guix-options + ;; Guile keyword arguments are translated to Python keyword arguments + ;; and passed to `group.addoption'. pytest_guix assumes default options + ;; '(#:action "append" #:nargs "?") + ;; It is required to store at least the store_const and store_true actions + ;; to ensure boolean args are not eating the next argument, but it is not + ;; necessary to do more than that so keep it minimal for maintainability. #~'(("cov" - "--cov" - "--cov-reset" - "--cov-report" - "--cov-config" - "--no-cov-on-fail" - "--no-cov" - "--cov-fail-under" - "--cov-append" - "--cov-branch" - "--cov-context") + ("--cov") + ("--cov-reset" #:action "store_const") + ("--cov-report") + ("--cov-config") + ("--no-cov-on-fail" #:action "store_true") + ("--no-cov" #:action "store_true") + ("--cov-fail-under") + ("--cov-append" #:action "store_true") + ("--cov-branch" #:action "store_true") + ("--cov-precision") + ("--cov-context")) ("html" - "--html" "--self-contained-html" "--css") + ("--html") + ("--self-contained-html" #:action "store_true") + ("--css")) ("mypy" - "--mypy" "--mypy-config-file" "--mypy-ignore-missing-imports") - ("isort" "isort") - ("flake8" "flake8") - ("black" "black") - ("flakes" "flakes") - ("pep8" "pep8"))) + ("--mypy" #:action "store_true") + ("--mypy-ignore-missing-imports" #:action "store_true") + ("--mypy-config-file") + ("--mypy-report-style") + ("--mypy-no-status-check" #:action "store_true") + ("--mypy-xfail" #:action "store_true")) + ("isort" ("--isort" #:action "store_true")) + ("flake8" ("--flake8" #:action "store_true")) + ("black" ("--black" #:action "store_true")) + ("flakes" ("--flakes" #:action "store_true")) + ("pep8" ("--pep8" #:action "store_true")))) ;; TODO: On the next iteration of python-team, migrate the sanity-check to ;; importlib_metadata instead of setuptools. diff --git a/guix/build/pyproject-build-system.scm b/guix/build/pyproject-build-system.scm index 8cf2d2c599..90995af49f 100644 --- a/guix/build/pyproject-build-system.scm +++ b/guix/build/pyproject-build-system.scm @@ -314,6 +314,27 @@ without errors." (with-directory-excursion "/tmp" (invoke "python" sanity-check.py (site-packages inputs outputs))))) +(define (keywords->alist lst) + (let loop ((lst lst) + (result '())) + (match lst + (() + (reverse result)) + ((kw value rest ...) + (cons (symbol->string (keyword->symbol kw)) value))))) + +(define (guile->python-keywords args) + (map (match-lambda + ((head . tail) + (cons head + (map (match-lambda + ((arg . ()) + (cons arg '())) + ((arg . keyword-args) + (cons arg (list (keywords->alist keyword-args))))) + tail)))) + args)) + (define* (check #:key inputs tests? test-backend test-flags pytest-guix-options #:allow-other-keys) "Run the test suite of a given Python package." @@ -349,7 +370,10 @@ without errors." (match use-test-backend ('pytest-with-guix-plugin (call-with-output-file ".pytest_guix_options.json" - (cut scm->json pytest-guix-options <>)) + (lambda (port) + (scm->json + (guile->python-keywords pytest-guix-options) + port))) (apply invoke pytest "-vv" "-p" "pytest_guix" test-flags)) ('pytest (apply invoke pytest "-vv" test-flags))