From 03329f1402817e6c1451b06b6b3125c4dcda2b25 Mon Sep 17 00:00:00 2001 From: Frost Ming Date: Mon, 9 Oct 2023 18:30:17 +0800 Subject: [PATCH] feat: --quiet optiona and package warning (#2304) --- docs/docs/usage/config.md | 25 +++++++++ news/{2282.venv-clean.md => 2282.bugfix.md} | 0 news/{2301.py312.md => 2301.misc.md} | 0 news/2304.feature.1.md | 1 + news/2304.feature.2.md | 1 + src/pdm/cli/commands/show.py | 24 +++++---- src/pdm/cli/completions/pdm.bash | 46 ++++++++--------- src/pdm/cli/completions/pdm.fish | 54 +++++++++++++++++--- src/pdm/cli/completions/pdm.ps1 | 2 +- src/pdm/cli/completions/pdm.zsh | 3 +- src/pdm/cli/options.py | 4 +- src/pdm/core.py | 7 ++- src/pdm/exceptions.py | 10 +++- src/pdm/installers/installers.py | 3 +- src/pdm/installers/synchronizers.py | 5 +- src/pdm/models/candidates.py | 4 +- src/pdm/models/repositories.py | 56 ++++++++++++++++++--- src/pdm/project/lockfile.py | 3 +- src/pdm/project/project_file.py | 3 +- src/pdm/pytest.py | 4 +- src/pdm/resolver/core.py | 11 +++- src/pdm/termui.py | 13 +++-- tests/resolver/test_resolve.py | 5 +- tests/test_project.py | 35 +++++++++++++ 24 files changed, 253 insertions(+), 66 deletions(-) rename news/{2282.venv-clean.md => 2282.bugfix.md} (100%) rename news/{2301.py312.md => 2301.misc.md} (100%) create mode 100644 news/2304.feature.1.md create mode 100644 news/2304.feature.2.md diff --git a/docs/docs/usage/config.md b/docs/docs/usage/config.md index 19494c1e96..2ad29e3536 100644 --- a/docs/docs/usage/config.md +++ b/docs/docs/usage/config.md @@ -315,3 +315,28 @@ lock = ["--no-cross-platform"] These options will be added right after the command name. For instance, based on the configuration above, `pdm add requests` is equivalent to `pdm add --no-isolation --no-self requests`. + + +## Ignore package warnings + +_New in version 2.10.0_ + +You may see some warnings when resolving dependencies like this: + +``` +PackageWarning: Skipping scipy@1.10.0 because it requires Python +<3.12,>=3.8 but the project claims to work with Python>=3.9. +Narrow down the `requires-python` range to include this version. For example, ">=3.9,<3.12" should work. + warnings.warn(record.message, PackageWarning, stacklevel=1) +Use `-q/--quiet` to suppress these warnings, or ignore them per-package with `ignore_package_warnings` config in [tool.pdm] table. +``` + +This is because the supported range of Python versions of the package doesn't cover the `requires-python` value specified in the `pyproject.toml`. +You can ignore these warnings in a per-package basis by adding the following config: + +```toml +[tool.pdm] +ignore_package_warnings = ["scipy", "tensorflow-*"] +``` + +Where each item is a case-insensitive glob pattern to match the package name. diff --git a/news/2282.venv-clean.md b/news/2282.bugfix.md similarity index 100% rename from news/2282.venv-clean.md rename to news/2282.bugfix.md diff --git a/news/2301.py312.md b/news/2301.misc.md similarity index 100% rename from news/2301.py312.md rename to news/2301.misc.md diff --git a/news/2304.feature.1.md b/news/2304.feature.1.md new file mode 100644 index 0000000000..8bcb4c3fe2 --- /dev/null +++ b/news/2304.feature.1.md @@ -0,0 +1 @@ +Add `-q/--quiet` option to suppress some warnings printed to the console. This option is mutually exclusive with `-v/--verbose`. diff --git a/news/2304.feature.2.md b/news/2304.feature.2.md new file mode 100644 index 0000000000..8cfeeb4f09 --- /dev/null +++ b/news/2304.feature.2.md @@ -0,0 +1 @@ +Show warnings when a package is rejected by the resolve because of uncovered `requires-python` range. And provide a way to ignore them per-package. diff --git a/src/pdm/cli/commands/show.py b/src/pdm/cli/commands/show.py index df9a7f2654..85c4b45fbb 100644 --- a/src/pdm/cli/commands/show.py +++ b/src/pdm/cli/commands/show.py @@ -1,4 +1,7 @@ +from __future__ import annotations + import argparse +from typing import TYPE_CHECKING from packaging.version import Version @@ -11,10 +14,13 @@ from pdm.project import Project from pdm.utils import normalize_name +if TYPE_CHECKING: + from unearth import Package + -def filter_stable(candidate: Candidate) -> bool: - assert candidate.version - return not Version(candidate.version).is_prerelease +def filter_stable(package: Package) -> bool: + assert package.version + return not Version(package.version).is_prerelease class Command(BaseCommand): @@ -36,19 +42,17 @@ def add_arguments(self, parser: argparse.ArgumentParser) -> None: def handle(self, project: Project, options: argparse.Namespace) -> None: package = options.package if package: - req = parse_requirement(package) - repository = project.get_repository() - # reverse the result so that latest is at first. - matches = repository.find_candidates(req, True, True) - latest = next(iter(matches), None) - if not latest: + with project.environment.get_finder() as finder: + best_match = finder.find_best_match(package, allow_prereleases=True) + if not best_match.applicable: project.core.ui.echo( f"No match found for the package {package!r}", err=True, style="warning", ) return - latest_stable = next(filter(filter_stable, matches), None) + latest = Candidate.from_installation_candidate(best_match.best, parse_requirement(package)) + latest_stable = next(filter(filter_stable, best_match.applicable), None) metadata = latest.prepare(project.environment).metadata else: if not project.name: diff --git a/src/pdm/cli/completions/pdm.bash b/src/pdm/cli/completions/pdm.bash index 289d888de6..772a4255bd 100644 --- a/src/pdm/cli/completions/pdm.bash +++ b/src/pdm/cli/completions/pdm.bash @@ -24,20 +24,20 @@ _pdm_a919b69078acdf0a_complete() # completing for an option if [[ ${cur} == --* ]] ; then - opts="--config --help --ignore-python --pep582 --verbose --version" + opts="--config --help --ignore-python --pep582 --quiet --verbose --version" case "$com" in (add) - opts="--dev --dry-run --editable --fail-fast --global --group --help --lockfile --no-editable --no-isolation --no-lock --no-self --no-sync --prerelease --project --save-compatible --save-exact --save-minimum --save-wildcard --skip --unconstrained --update-all --update-eager --update-reuse --venv --verbose" + opts="--dev --dry-run --editable --fail-fast --global --group --help --lockfile --no-editable --no-isolation --no-lock --no-self --no-sync --prerelease --project --quiet --save-compatible --save-exact --save-minimum --save-wildcard --skip --unconstrained --update-all --update-eager --update-reuse --venv --verbose" ;; (build) - opts="--config-setting --dest --help --no-clean --no-isolation --no-sdist --no-wheel --project --skip --verbose" + opts="--config-setting --dest --help --no-clean --no-isolation --no-sdist --no-wheel --project --quiet --skip --verbose" ;; (cache) - opts="--help --verbose" + opts="--help --quiet --verbose" ;; (completion) @@ -45,79 +45,79 @@ _pdm_a919b69078acdf0a_complete() ;; (config) - opts="--delete --edit --global --help --local --project --verbose" + opts="--delete --edit --global --help --local --project --quiet --verbose" ;; (export) - opts="--dev --expandvars --format --global --group --help --lockfile --no-default --output --production --project --pyproject --verbose --without-hashes" + opts="--dev --expandvars --format --global --group --help --lockfile --no-default --output --production --project --pyproject --quiet --verbose --without-hashes" ;; (fix) - opts="--dry-run --global --help --project --verbose" + opts="--dry-run --global --help --project --quiet --verbose" ;; (import) - opts="--dev --format --global --group --help --project --verbose" + opts="--dev --format --global --group --help --project --quiet --verbose" ;; (info) - opts="--env --global --help --json --packages --project --python --venv --verbose --where" + opts="--env --global --help --json --packages --project --python --quiet --venv --verbose --where" ;; (init) - opts="--backend --cookiecutter --copier --global --help --lib --non-interactive --overwrite --project --python --skip --verbose" + opts="--backend --cookiecutter --copier --global --help --lib --non-interactive --overwrite --project --python --quiet --skip --verbose" ;; (install) - opts="--check --dev --dry-run --fail-fast --global --group --help --lockfile --no-default --no-editable --no-isolation --no-lock --no-self --plugins --production --project --skip --venv --verbose" + opts="--check --dev --dry-run --fail-fast --global --group --help --lockfile --no-default --no-editable --no-isolation --no-lock --no-self --plugins --production --project --quiet --skip --venv --verbose" ;; (list) - opts="--csv --exclude --fields --freeze --global --graph --help --include --json --markdown --project --resolve --reverse --sort --venv --verbose" + opts="--csv --exclude --fields --freeze --global --graph --help --include --json --markdown --project --quiet --resolve --reverse --sort --venv --verbose" ;; (lock) - opts="--check --dev --global --group --help --lockfile --no-cross-platform --no-default --no-isolation --no-static-urls --production --project --refresh --skip --static-urls --verbose" + opts="--check --dev --global --group --help --lockfile --no-cross-platform --no-default --no-isolation --no-static-urls --production --project --quiet --refresh --skip --static-urls --verbose" ;; (plugin) - opts="--help --verbose" + opts="--help --quiet --verbose" ;; (publish) - opts="--ca-certs --comment --help --identity --no-build --no-very-ssl --password --project --repository --sign --skip --username --verbose" + opts="--ca-certs --comment --help --identity --no-build --no-very-ssl --password --project --quiet --repository --sign --skip --username --verbose" ;; (remove) - opts="--dev --dry-run --fail-fast --global --group --help --lockfile --no-editable --no-isolation --no-lock --no-self --no-sync --project --skip --venv --verbose" + opts="--dev --dry-run --fail-fast --global --group --help --lockfile --no-editable --no-isolation --no-lock --no-self --no-sync --project --quiet --skip --venv --verbose" ;; (run) - opts="--global --help --json --list --project --site-packages --skip --venv --verbose" + opts="--global --help --json --list --project --quiet --site-packages --skip --venv --verbose" ;; (search) - opts="--help --verbose" + opts="--help --quiet --verbose" ;; (self) - opts="--help --verbose" + opts="--help --quiet --verbose" ;; (show) - opts="--global --help --keywords --license --name --platform --project --summary --venv --verbose --version" + opts="--global --help --keywords --license --name --platform --project --quiet --summary --venv --verbose --version" ;; (sync) - opts="--clean --dev --dry-run --fail-fast --global --group --help --lockfile --no-default --no-editable --no-isolation --no-self --only-keep --production --project --reinstall --skip --venv --verbose" + opts="--clean --dev --dry-run --fail-fast --global --group --help --lockfile --no-default --no-editable --no-isolation --no-self --only-keep --production --project --quiet --reinstall --skip --venv --verbose" ;; (update) - opts="--dev --fail-fast --global --group --help --lockfile --no-default --no-editable --no-isolation --no-lock --no-self --no-sync --outdated --prerelease --production --project --save-compatible --save-exact --save-minimum --save-wildcard --skip --top --unconstrained --update-all --update-eager --update-reuse --venv --verbose" + opts="--dev --fail-fast --global --group --help --lockfile --no-default --no-editable --no-isolation --no-lock --no-self --no-sync --outdated --prerelease --production --project --quiet --save-compatible --save-exact --save-minimum --save-wildcard --skip --top --unconstrained --update-all --update-eager --update-reuse --venv --verbose" ;; (use) - opts="--first --global --help --ignore-remembered --project --skip --venv --verbose" + opts="--first --global --help --ignore-remembered --project --quiet --skip --venv --verbose" ;; (venv) diff --git a/src/pdm/cli/completions/pdm.fish b/src/pdm/cli/completions/pdm.fish index 187e527144..13a4e6b4d0 100644 --- a/src/pdm/cli/completions/pdm.fish +++ b/src/pdm/cli/completions/pdm.fish @@ -15,6 +15,7 @@ complete -c pdm -n '__fish_pdm_a919b69078acdf0a_complete_no_subcommand' -l confi complete -c pdm -n '__fish_pdm_a919b69078acdf0a_complete_no_subcommand' -l help -d 'Show this help message and exit.' complete -c pdm -n '__fish_pdm_a919b69078acdf0a_complete_no_subcommand' -l ignore-python -d 'Ignore the Python path saved in .pdm-python. [env var: PDM_IGNORE_SAVED_PYTHON]' complete -c pdm -n '__fish_pdm_a919b69078acdf0a_complete_no_subcommand' -l pep582 -d 'Print the command line to be eval\'d by the shell' +complete -c pdm -n '__fish_pdm_a919b69078acdf0a_complete_no_subcommand' -l quiet -d 'Suppress output' complete -c pdm -n '__fish_pdm_a919b69078acdf0a_complete_no_subcommand' -l verbose -d 'Use `-v` for detailed output and `-vv` for more detailed' complete -c pdm -n '__fish_pdm_a919b69078acdf0a_complete_no_subcommand' -l version -d 'Show the version and exit' @@ -30,12 +31,13 @@ complete -c pdm -A -n '__fish_seen_subcommand_from add' -l group -d 'Specify the complete -c pdm -A -n '__fish_seen_subcommand_from add' -l help -d 'Show this help message and exit.' complete -c pdm -A -n '__fish_seen_subcommand_from add' -l lockfile -d 'Specify another lockfile path. Default: pdm.lock. [env var: PDM_LOCKFILE]' complete -c pdm -A -n '__fish_seen_subcommand_from add' -l no-editable -d 'Install non-editable versions for all packages' -complete -c pdm -A -n '__fish_seen_subcommand_from add' -l no-isolation -d 'Do not isolate the build in a clean environment' +complete -c pdm -A -n '__fish_seen_subcommand_from add' -l no-isolation -d 'Disable isolation when building a source distribution that follows PEP 517, as in: build dependencies specified by PEP 518 must be already installed if this option is used.' complete -c pdm -A -n '__fish_seen_subcommand_from add' -l no-lock -d 'Don\'t try to create or update the lockfile. [env var: PDM_NO_LOCK]' complete -c pdm -A -n '__fish_seen_subcommand_from add' -l no-self -d 'Don\'t install the project itself. [env var: PDM_NO_SELF]' complete -c pdm -A -n '__fish_seen_subcommand_from add' -l no-sync -d 'Only write pyproject.toml and do not sync the working set' complete -c pdm -A -n '__fish_seen_subcommand_from add' -l prerelease -d 'Allow prereleases to be pinned' complete -c pdm -A -n '__fish_seen_subcommand_from add' -l project -d 'Specify another path as the project root, which changes the base of pyproject.toml and __pypackages__ [env var: PDM_PROJECT]' +complete -c pdm -A -n '__fish_seen_subcommand_from add' -l quiet -d 'Suppress output' complete -c pdm -A -n '__fish_seen_subcommand_from add' -l save-compatible -d 'Save compatible version specifiers' complete -c pdm -A -n '__fish_seen_subcommand_from add' -l save-exact -d 'Save exact version specifiers' complete -c pdm -A -n '__fish_seen_subcommand_from add' -l save-minimum -d 'Save minimum version specifiers' @@ -54,37 +56,43 @@ complete -c pdm -A -n '__fish_seen_subcommand_from build' -l config-setting -d ' complete -c pdm -A -n '__fish_seen_subcommand_from build' -l dest -d 'Target directory to put artifacts' complete -c pdm -A -n '__fish_seen_subcommand_from build' -l help -d 'Show this help message and exit.' complete -c pdm -A -n '__fish_seen_subcommand_from build' -l no-clean -d 'Do not clean the target directory' -complete -c pdm -A -n '__fish_seen_subcommand_from build' -l no-isolation -d 'Do not isolate the build in a clean environment' +complete -c pdm -A -n '__fish_seen_subcommand_from build' -l no-isolation -d 'Disable isolation when building a source distribution that follows PEP 517, as in: build dependencies specified by PEP 518 must be already installed if this option is used.' complete -c pdm -A -n '__fish_seen_subcommand_from build' -l no-sdist -d 'Don\'t build source tarballs' complete -c pdm -A -n '__fish_seen_subcommand_from build' -l no-wheel -d 'Don\'t build wheels' complete -c pdm -A -n '__fish_seen_subcommand_from build' -l project -d 'Specify another path as the project root, which changes the base of pyproject.toml and __pypackages__ [env var: PDM_PROJECT]' +complete -c pdm -A -n '__fish_seen_subcommand_from build' -l quiet -d 'Suppress output' complete -c pdm -A -n '__fish_seen_subcommand_from build' -l skip -d 'Skip some tasks and/or hooks by their comma-separated names. Can be supplied multiple times. Use ":all" to skip all hooks. Use ":pre" and ":post" to skip all pre or post hooks.' complete -c pdm -A -n '__fish_seen_subcommand_from build' -l verbose -d 'Use `-v` for detailed output and `-vv` for more detailed' # cache complete -c pdm -f -n '__fish_pdm_a919b69078acdf0a_complete_no_subcommand' -a cache -d 'Control the caches of PDM' complete -c pdm -A -n '__fish_seen_subcommand_from cache' -l help -d 'Show this help message and exit.' +complete -c pdm -A -n '__fish_seen_subcommand_from cache' -l quiet -d 'Suppress output' complete -c pdm -A -n '__fish_seen_subcommand_from cache' -l verbose -d 'Use `-v` for detailed output and `-vv` for more detailed' # cache subcommands set -l cache_subcommands clear info list remove # cache clear complete -c pdm -f -n '__fish_seen_subcommand_from cache; and not __fish_seen_subcommand_from $cache_subcommands' -a clear -d 'Clean all the files under cache directory' complete -c pdm -A -n '__fish_seen_subcommand_from cache; and __fish_seen_subcommand_from clear' -l help -d 'Show this help message and exit.' +complete -c pdm -A -n '__fish_seen_subcommand_from cache; and __fish_seen_subcommand_from clear' -l quiet -d 'Suppress output' complete -c pdm -A -n '__fish_seen_subcommand_from cache; and __fish_seen_subcommand_from clear' -l verbose -d 'Use `-v` for detailed output and `-vv` for more detailed' # cache info complete -c pdm -f -n '__fish_seen_subcommand_from cache; and not __fish_seen_subcommand_from $cache_subcommands' -a info -d 'Show the info and current size of caches' complete -c pdm -A -n '__fish_seen_subcommand_from cache; and __fish_seen_subcommand_from info' -l help -d 'Show this help message and exit.' +complete -c pdm -A -n '__fish_seen_subcommand_from cache; and __fish_seen_subcommand_from info' -l quiet -d 'Suppress output' complete -c pdm -A -n '__fish_seen_subcommand_from cache; and __fish_seen_subcommand_from info' -l verbose -d 'Use `-v` for detailed output and `-vv` for more detailed' # cache list complete -c pdm -f -n '__fish_seen_subcommand_from cache; and not __fish_seen_subcommand_from $cache_subcommands' -a list -d 'List the built wheels stored in the cache' complete -c pdm -A -n '__fish_seen_subcommand_from cache; and __fish_seen_subcommand_from list' -l help -d 'Show this help message and exit.' +complete -c pdm -A -n '__fish_seen_subcommand_from cache; and __fish_seen_subcommand_from list' -l quiet -d 'Suppress output' complete -c pdm -A -n '__fish_seen_subcommand_from cache; and __fish_seen_subcommand_from list' -l verbose -d 'Use `-v` for detailed output and `-vv` for more detailed' # cache remove complete -c pdm -f -n '__fish_seen_subcommand_from cache; and not __fish_seen_subcommand_from $cache_subcommands' -a remove -d 'Remove files matching the given pattern' complete -c pdm -A -n '__fish_seen_subcommand_from cache; and __fish_seen_subcommand_from remove' -l help -d 'Show this help message and exit.' +complete -c pdm -A -n '__fish_seen_subcommand_from cache; and __fish_seen_subcommand_from remove' -l quiet -d 'Suppress output' complete -c pdm -A -n '__fish_seen_subcommand_from cache; and __fish_seen_subcommand_from remove' -l verbose -d 'Use `-v` for detailed output and `-vv` for more detailed' # completion @@ -99,6 +107,7 @@ complete -c pdm -A -n '__fish_seen_subcommand_from config' -l global -d 'Use the complete -c pdm -A -n '__fish_seen_subcommand_from config' -l help -d 'Show this help message and exit.' complete -c pdm -A -n '__fish_seen_subcommand_from config' -l local -d 'Set config in the project\'s local configuration file' complete -c pdm -A -n '__fish_seen_subcommand_from config' -l project -d 'Specify another path as the project root, which changes the base of pyproject.toml and __pypackages__ [env var: PDM_PROJECT]' +complete -c pdm -A -n '__fish_seen_subcommand_from config' -l quiet -d 'Suppress output' complete -c pdm -A -n '__fish_seen_subcommand_from config' -l verbose -d 'Use `-v` for detailed output and `-vv` for more detailed' # export @@ -115,6 +124,7 @@ complete -c pdm -A -n '__fish_seen_subcommand_from export' -l output -d 'Write o complete -c pdm -A -n '__fish_seen_subcommand_from export' -l production -d 'Unselect dev dependencies' complete -c pdm -A -n '__fish_seen_subcommand_from export' -l project -d 'Specify another path as the project root, which changes the base of pyproject.toml and __pypackages__ [env var: PDM_PROJECT]' complete -c pdm -A -n '__fish_seen_subcommand_from export' -l pyproject -d 'Read the list of packages from pyproject.toml' +complete -c pdm -A -n '__fish_seen_subcommand_from export' -l quiet -d 'Suppress output' complete -c pdm -A -n '__fish_seen_subcommand_from export' -l verbose -d 'Use `-v` for detailed output and `-vv` for more detailed' complete -c pdm -A -n '__fish_seen_subcommand_from export' -l without-hashes -d 'Don\'t include artifact hashes' @@ -124,6 +134,7 @@ complete -c pdm -A -n '__fish_seen_subcommand_from fix' -l dry-run -d 'Only show complete -c pdm -A -n '__fish_seen_subcommand_from fix' -l global -d 'Use the global project, supply the project root with `-p` option' complete -c pdm -A -n '__fish_seen_subcommand_from fix' -l help -d 'Show this help message and exit.' complete -c pdm -A -n '__fish_seen_subcommand_from fix' -l project -d 'Specify another path as the project root, which changes the base of pyproject.toml and __pypackages__ [env var: PDM_PROJECT]' +complete -c pdm -A -n '__fish_seen_subcommand_from fix' -l quiet -d 'Suppress output' complete -c pdm -A -n '__fish_seen_subcommand_from fix' -l verbose -d 'Use `-v` for detailed output and `-vv` for more detailed' # import @@ -134,6 +145,7 @@ complete -c pdm -A -n '__fish_seen_subcommand_from import' -l global -d 'Use the complete -c pdm -A -n '__fish_seen_subcommand_from import' -l group -d 'Specify the target dependency group to import into' complete -c pdm -A -n '__fish_seen_subcommand_from import' -l help -d 'Show this help message and exit.' complete -c pdm -A -n '__fish_seen_subcommand_from import' -l project -d 'Specify another path as the project root, which changes the base of pyproject.toml and __pypackages__ [env var: PDM_PROJECT]' +complete -c pdm -A -n '__fish_seen_subcommand_from import' -l quiet -d 'Suppress output' complete -c pdm -A -n '__fish_seen_subcommand_from import' -l verbose -d 'Use `-v` for detailed output and `-vv` for more detailed' # info @@ -145,6 +157,7 @@ complete -c pdm -A -n '__fish_seen_subcommand_from info' -l json -d 'Dump the in complete -c pdm -A -n '__fish_seen_subcommand_from info' -l packages -d 'Show the local packages root' complete -c pdm -A -n '__fish_seen_subcommand_from info' -l project -d 'Specify another path as the project root, which changes the base of pyproject.toml and __pypackages__ [env var: PDM_PROJECT]' complete -c pdm -A -n '__fish_seen_subcommand_from info' -l python -d 'Show the interpreter path' +complete -c pdm -A -n '__fish_seen_subcommand_from info' -l quiet -d 'Suppress output' complete -c pdm -A -n '__fish_seen_subcommand_from info' -l venv -d 'Run the command in the virtual environment with the given key. [env var: PDM_IN_VENV]' complete -c pdm -A -n '__fish_seen_subcommand_from info' -l verbose -d 'Use `-v` for detailed output and `-vv` for more detailed' complete -c pdm -A -n '__fish_seen_subcommand_from info' -l where -d 'Show the project root path' @@ -161,6 +174,7 @@ complete -c pdm -A -n '__fish_seen_subcommand_from init' -l non-interactive -d ' complete -c pdm -A -n '__fish_seen_subcommand_from init' -l overwrite -d 'Overwrite existing files' complete -c pdm -A -n '__fish_seen_subcommand_from init' -l project -d 'Specify another path as the project root, which changes the base of pyproject.toml and __pypackages__ [env var: PDM_PROJECT]' complete -c pdm -A -n '__fish_seen_subcommand_from init' -l python -d 'Specify the Python version/path to use' +complete -c pdm -A -n '__fish_seen_subcommand_from init' -l quiet -d 'Suppress output' complete -c pdm -A -n '__fish_seen_subcommand_from init' -l skip -d 'Skip some tasks and/or hooks by their comma-separated names. Can be supplied multiple times. Use ":all" to skip all hooks. Use ":pre" and ":post" to skip all pre or post hooks.' complete -c pdm -A -n '__fish_seen_subcommand_from init' -l verbose -d 'Use `-v` for detailed output and `-vv` for more detailed' @@ -176,12 +190,13 @@ complete -c pdm -A -n '__fish_seen_subcommand_from install' -l help -d 'Show thi complete -c pdm -A -n '__fish_seen_subcommand_from install' -l lockfile -d 'Specify another lockfile path. Default: pdm.lock. [env var: PDM_LOCKFILE]' complete -c pdm -A -n '__fish_seen_subcommand_from install' -l no-default -d 'Don\'t include dependencies from the default group' complete -c pdm -A -n '__fish_seen_subcommand_from install' -l no-editable -d 'Install non-editable versions for all packages' -complete -c pdm -A -n '__fish_seen_subcommand_from install' -l no-isolation -d 'Do not isolate the build in a clean environment' +complete -c pdm -A -n '__fish_seen_subcommand_from install' -l no-isolation -d 'Disable isolation when building a source distribution that follows PEP 517, as in: build dependencies specified by PEP 518 must be already installed if this option is used.' complete -c pdm -A -n '__fish_seen_subcommand_from install' -l no-lock -d 'Don\'t try to create or update the lockfile. [env var: PDM_NO_LOCK]' complete -c pdm -A -n '__fish_seen_subcommand_from install' -l no-self -d 'Don\'t install the project itself. [env var: PDM_NO_SELF]' complete -c pdm -A -n '__fish_seen_subcommand_from install' -l plugins -d 'Install the plugins specified in pyproject.toml' complete -c pdm -A -n '__fish_seen_subcommand_from install' -l production -d 'Unselect dev dependencies' complete -c pdm -A -n '__fish_seen_subcommand_from install' -l project -d 'Specify another path as the project root, which changes the base of pyproject.toml and __pypackages__ [env var: PDM_PROJECT]' +complete -c pdm -A -n '__fish_seen_subcommand_from install' -l quiet -d 'Suppress output' complete -c pdm -A -n '__fish_seen_subcommand_from install' -l skip -d 'Skip some tasks and/or hooks by their comma-separated names. Can be supplied multiple times. Use ":all" to skip all hooks. Use ":pre" and ":post" to skip all pre or post hooks.' complete -c pdm -A -n '__fish_seen_subcommand_from install' -l venv -d 'Run the command in the virtual environment with the given key. [env var: PDM_IN_VENV]' complete -c pdm -A -n '__fish_seen_subcommand_from install' -l verbose -d 'Use `-v` for detailed output and `-vv` for more detailed' @@ -199,6 +214,7 @@ complete -c pdm -A -n '__fish_seen_subcommand_from list' -l include -d 'Dependen complete -c pdm -A -n '__fish_seen_subcommand_from list' -l json -d 'Output dependencies in JSON document format' complete -c pdm -A -n '__fish_seen_subcommand_from list' -l markdown -d 'Output dependencies and legal notices in markdown document format - best effort basis' complete -c pdm -A -n '__fish_seen_subcommand_from list' -l project -d 'Specify another path as the project root, which changes the base of pyproject.toml and __pypackages__ [env var: PDM_PROJECT]' +complete -c pdm -A -n '__fish_seen_subcommand_from list' -l quiet -d 'Suppress output' complete -c pdm -A -n '__fish_seen_subcommand_from list' -l resolve -d 'Resolve all requirements to output licenses (instead of just showing those currently installed)' complete -c pdm -A -n '__fish_seen_subcommand_from list' -l reverse -d 'Reverse the dependency tree' complete -c pdm -A -n '__fish_seen_subcommand_from list' -l sort -d 'Sort the output using a given field name. If nothing is set, no sort is applied. Multiple fields can be combined with \',\'.' @@ -215,10 +231,11 @@ complete -c pdm -A -n '__fish_seen_subcommand_from lock' -l help -d 'Show this h complete -c pdm -A -n '__fish_seen_subcommand_from lock' -l lockfile -d 'Specify another lockfile path. Default: pdm.lock. [env var: PDM_LOCKFILE]' complete -c pdm -A -n '__fish_seen_subcommand_from lock' -l no-cross-platform -d 'Only lock packages for the current platform' complete -c pdm -A -n '__fish_seen_subcommand_from lock' -l no-default -d 'Don\'t include dependencies from the default group' -complete -c pdm -A -n '__fish_seen_subcommand_from lock' -l no-isolation -d 'Do not isolate the build in a clean environment' +complete -c pdm -A -n '__fish_seen_subcommand_from lock' -l no-isolation -d 'Disable isolation when building a source distribution that follows PEP 517, as in: build dependencies specified by PEP 518 must be already installed if this option is used.' complete -c pdm -A -n '__fish_seen_subcommand_from lock' -l no-static-urls -d 'Do not store static file URLs in the lockfile' complete -c pdm -A -n '__fish_seen_subcommand_from lock' -l production -d 'Unselect dev dependencies' complete -c pdm -A -n '__fish_seen_subcommand_from lock' -l project -d 'Specify another path as the project root, which changes the base of pyproject.toml and __pypackages__ [env var: PDM_PROJECT]' +complete -c pdm -A -n '__fish_seen_subcommand_from lock' -l quiet -d 'Suppress output' complete -c pdm -A -n '__fish_seen_subcommand_from lock' -l refresh -d 'Don\'t update pinned versions, only refresh the lock file' complete -c pdm -A -n '__fish_seen_subcommand_from lock' -l skip -d 'Skip some tasks and/or hooks by their comma-separated names. Can be supplied multiple times. Use ":all" to skip all hooks. Use ":pre" and ":post" to skip all pre or post hooks.' complete -c pdm -A -n '__fish_seen_subcommand_from lock' -l static-urls -d 'Store static file URLs in the lockfile' @@ -227,6 +244,7 @@ complete -c pdm -A -n '__fish_seen_subcommand_from lock' -l verbose -d 'Use `-v` # plugin complete -c pdm -f -n '__fish_pdm_a919b69078acdf0a_complete_no_subcommand' -a plugin -d 'Manage the PDM program itself (previously known as plugin)' complete -c pdm -A -n '__fish_seen_subcommand_from plugin' -l help -d 'Show this help message and exit.' +complete -c pdm -A -n '__fish_seen_subcommand_from plugin' -l quiet -d 'Suppress output' complete -c pdm -A -n '__fish_seen_subcommand_from plugin' -l verbose -d 'Use `-v` for detailed output and `-vv` for more detailed' # plugin subcommands set -l plugin_subcommands add list remove update @@ -234,18 +252,21 @@ set -l plugin_subcommands add list remove update complete -c pdm -f -n '__fish_seen_subcommand_from plugin; and not __fish_seen_subcommand_from $plugin_subcommands' -a add -d 'Install packages to the PDM\'s environment' complete -c pdm -A -n '__fish_seen_subcommand_from plugin; and __fish_seen_subcommand_from add' -l help -d 'Show this help message and exit.' complete -c pdm -A -n '__fish_seen_subcommand_from plugin; and __fish_seen_subcommand_from add' -l pip-args -d 'Arguments that will be passed to pip install' +complete -c pdm -A -n '__fish_seen_subcommand_from plugin; and __fish_seen_subcommand_from add' -l quiet -d 'Suppress output' complete -c pdm -A -n '__fish_seen_subcommand_from plugin; and __fish_seen_subcommand_from add' -l verbose -d 'Use `-v` for detailed output and `-vv` for more detailed' # plugin list complete -c pdm -f -n '__fish_seen_subcommand_from plugin; and not __fish_seen_subcommand_from $plugin_subcommands' -a list -d 'List all packages installed with PDM' complete -c pdm -A -n '__fish_seen_subcommand_from plugin; and __fish_seen_subcommand_from list' -l help -d 'Show this help message and exit.' complete -c pdm -A -n '__fish_seen_subcommand_from plugin; and __fish_seen_subcommand_from list' -l plugins -d 'List plugins only' +complete -c pdm -A -n '__fish_seen_subcommand_from plugin; and __fish_seen_subcommand_from list' -l quiet -d 'Suppress output' complete -c pdm -A -n '__fish_seen_subcommand_from plugin; and __fish_seen_subcommand_from list' -l verbose -d 'Use `-v` for detailed output and `-vv` for more detailed' # plugin remove complete -c pdm -f -n '__fish_seen_subcommand_from plugin; and not __fish_seen_subcommand_from $plugin_subcommands' -a remove -d 'Remove packages from PDM\'s environment' complete -c pdm -A -n '__fish_seen_subcommand_from plugin; and __fish_seen_subcommand_from remove' -l help -d 'Show this help message and exit.' complete -c pdm -A -n '__fish_seen_subcommand_from plugin; and __fish_seen_subcommand_from remove' -l pip-args -d 'Arguments that will be passed to pip uninstall' +complete -c pdm -A -n '__fish_seen_subcommand_from plugin; and __fish_seen_subcommand_from remove' -l quiet -d 'Suppress output' complete -c pdm -A -n '__fish_seen_subcommand_from plugin; and __fish_seen_subcommand_from remove' -l verbose -d 'Use `-v` for detailed output and `-vv` for more detailed' complete -c pdm -A -n '__fish_seen_subcommand_from plugin; and __fish_seen_subcommand_from remove' -l yes -d 'Answer yes on the question' @@ -255,6 +276,7 @@ complete -c pdm -A -n '__fish_seen_subcommand_from plugin; and __fish_seen_subco complete -c pdm -A -n '__fish_seen_subcommand_from plugin; and __fish_seen_subcommand_from update' -l help -d 'Show this help message and exit.' complete -c pdm -A -n '__fish_seen_subcommand_from plugin; and __fish_seen_subcommand_from update' -l pip-args -d 'Additional arguments that will be passed to pip install' complete -c pdm -A -n '__fish_seen_subcommand_from plugin; and __fish_seen_subcommand_from update' -l pre -d 'Update to the latest prerelease version' +complete -c pdm -A -n '__fish_seen_subcommand_from plugin; and __fish_seen_subcommand_from update' -l quiet -d 'Suppress output' complete -c pdm -A -n '__fish_seen_subcommand_from plugin; and __fish_seen_subcommand_from update' -l verbose -d 'Use `-v` for detailed output and `-vv` for more detailed' # publish @@ -267,6 +289,7 @@ complete -c pdm -A -n '__fish_seen_subcommand_from publish' -l no-build -d 'Don\ complete -c pdm -A -n '__fish_seen_subcommand_from publish' -l no-very-ssl -d 'Disable SSL verification' complete -c pdm -A -n '__fish_seen_subcommand_from publish' -l password -d 'The password to access the repository [env var: PDM_PUBLISH_PASSWORD]' complete -c pdm -A -n '__fish_seen_subcommand_from publish' -l project -d 'Specify another path as the project root, which changes the base of pyproject.toml and __pypackages__ [env var: PDM_PROJECT]' +complete -c pdm -A -n '__fish_seen_subcommand_from publish' -l quiet -d 'Suppress output' complete -c pdm -A -n '__fish_seen_subcommand_from publish' -l repository -d 'The repository name or url to publish the package to [env var: PDM_PUBLISH_REPO]' complete -c pdm -A -n '__fish_seen_subcommand_from publish' -l sign -d 'Upload the package with PGP signature' complete -c pdm -A -n '__fish_seen_subcommand_from publish' -l skip -d 'Skip some tasks and/or hooks by their comma-separated names. Can be supplied multiple times. Use ":all" to skip all hooks. Use ":pre" and ":post" to skip all pre or post hooks.' @@ -283,11 +306,12 @@ complete -c pdm -A -n '__fish_seen_subcommand_from remove' -l group -d 'Specify complete -c pdm -A -n '__fish_seen_subcommand_from remove' -l help -d 'Show this help message and exit.' complete -c pdm -A -n '__fish_seen_subcommand_from remove' -l lockfile -d 'Specify another lockfile path. Default: pdm.lock. [env var: PDM_LOCKFILE]' complete -c pdm -A -n '__fish_seen_subcommand_from remove' -l no-editable -d 'Install non-editable versions for all packages' -complete -c pdm -A -n '__fish_seen_subcommand_from remove' -l no-isolation -d 'Do not isolate the build in a clean environment' +complete -c pdm -A -n '__fish_seen_subcommand_from remove' -l no-isolation -d 'Disable isolation when building a source distribution that follows PEP 517, as in: build dependencies specified by PEP 518 must be already installed if this option is used.' complete -c pdm -A -n '__fish_seen_subcommand_from remove' -l no-lock -d 'Don\'t try to create or update the lockfile. [env var: PDM_NO_LOCK]' complete -c pdm -A -n '__fish_seen_subcommand_from remove' -l no-self -d 'Don\'t install the project itself. [env var: PDM_NO_SELF]' complete -c pdm -A -n '__fish_seen_subcommand_from remove' -l no-sync -d 'Only write pyproject.toml and do not uninstall packages' complete -c pdm -A -n '__fish_seen_subcommand_from remove' -l project -d 'Specify another path as the project root, which changes the base of pyproject.toml and __pypackages__ [env var: PDM_PROJECT]' +complete -c pdm -A -n '__fish_seen_subcommand_from remove' -l quiet -d 'Suppress output' complete -c pdm -A -n '__fish_seen_subcommand_from remove' -l skip -d 'Skip some tasks and/or hooks by their comma-separated names. Can be supplied multiple times. Use ":all" to skip all hooks. Use ":pre" and ":post" to skip all pre or post hooks.' complete -c pdm -A -n '__fish_seen_subcommand_from remove' -l venv -d 'Run the command in the virtual environment with the given key. [env var: PDM_IN_VENV]' complete -c pdm -A -n '__fish_seen_subcommand_from remove' -l verbose -d 'Use `-v` for detailed output and `-vv` for more detailed' @@ -299,6 +323,7 @@ complete -c pdm -A -n '__fish_seen_subcommand_from run' -l help -d 'Show this he complete -c pdm -A -n '__fish_seen_subcommand_from run' -l json -d 'Output all scripts infos in JSON' complete -c pdm -A -n '__fish_seen_subcommand_from run' -l list -d 'Show all available scripts defined in pyproject.toml' complete -c pdm -A -n '__fish_seen_subcommand_from run' -l project -d 'Specify another path as the project root, which changes the base of pyproject.toml and __pypackages__ [env var: PDM_PROJECT]' +complete -c pdm -A -n '__fish_seen_subcommand_from run' -l quiet -d 'Suppress output' complete -c pdm -A -n '__fish_seen_subcommand_from run' -l site-packages -d 'Load site-packages from the selected interpreter' complete -c pdm -A -n '__fish_seen_subcommand_from run' -l skip -d 'Skip some tasks and/or hooks by their comma-separated names. Can be supplied multiple times. Use ":all" to skip all hooks. Use ":pre" and ":post" to skip all pre or post hooks.' complete -c pdm -A -n '__fish_seen_subcommand_from run' -l venv -d 'Run the command in the virtual environment with the given key. [env var: PDM_IN_VENV]' @@ -307,11 +332,13 @@ complete -c pdm -A -n '__fish_seen_subcommand_from run' -l verbose -d 'Use `-v` # search complete -c pdm -f -n '__fish_pdm_a919b69078acdf0a_complete_no_subcommand' -a search -d 'Search for PyPI packages' complete -c pdm -A -n '__fish_seen_subcommand_from search' -l help -d 'Show this help message and exit.' +complete -c pdm -A -n '__fish_seen_subcommand_from search' -l quiet -d 'Suppress output' complete -c pdm -A -n '__fish_seen_subcommand_from search' -l verbose -d 'Use `-v` for detailed output and `-vv` for more detailed' # self complete -c pdm -f -n '__fish_pdm_a919b69078acdf0a_complete_no_subcommand' -a self -d 'Manage the PDM program itself (previously known as plugin)' complete -c pdm -A -n '__fish_seen_subcommand_from self' -l help -d 'Show this help message and exit.' +complete -c pdm -A -n '__fish_seen_subcommand_from self' -l quiet -d 'Suppress output' complete -c pdm -A -n '__fish_seen_subcommand_from self' -l verbose -d 'Use `-v` for detailed output and `-vv` for more detailed' # self subcommands set -l self_subcommands add list remove update @@ -319,18 +346,21 @@ set -l self_subcommands add list remove update complete -c pdm -f -n '__fish_seen_subcommand_from self; and not __fish_seen_subcommand_from $self_subcommands' -a add -d 'Install packages to the PDM\'s environment' complete -c pdm -A -n '__fish_seen_subcommand_from self; and __fish_seen_subcommand_from add' -l help -d 'Show this help message and exit.' complete -c pdm -A -n '__fish_seen_subcommand_from self; and __fish_seen_subcommand_from add' -l pip-args -d 'Arguments that will be passed to pip install' +complete -c pdm -A -n '__fish_seen_subcommand_from self; and __fish_seen_subcommand_from add' -l quiet -d 'Suppress output' complete -c pdm -A -n '__fish_seen_subcommand_from self; and __fish_seen_subcommand_from add' -l verbose -d 'Use `-v` for detailed output and `-vv` for more detailed' # self list complete -c pdm -f -n '__fish_seen_subcommand_from self; and not __fish_seen_subcommand_from $self_subcommands' -a list -d 'List all packages installed with PDM' complete -c pdm -A -n '__fish_seen_subcommand_from self; and __fish_seen_subcommand_from list' -l help -d 'Show this help message and exit.' complete -c pdm -A -n '__fish_seen_subcommand_from self; and __fish_seen_subcommand_from list' -l plugins -d 'List plugins only' +complete -c pdm -A -n '__fish_seen_subcommand_from self; and __fish_seen_subcommand_from list' -l quiet -d 'Suppress output' complete -c pdm -A -n '__fish_seen_subcommand_from self; and __fish_seen_subcommand_from list' -l verbose -d 'Use `-v` for detailed output and `-vv` for more detailed' # self remove complete -c pdm -f -n '__fish_seen_subcommand_from self; and not __fish_seen_subcommand_from $self_subcommands' -a remove -d 'Remove packages from PDM\'s environment' complete -c pdm -A -n '__fish_seen_subcommand_from self; and __fish_seen_subcommand_from remove' -l help -d 'Show this help message and exit.' complete -c pdm -A -n '__fish_seen_subcommand_from self; and __fish_seen_subcommand_from remove' -l pip-args -d 'Arguments that will be passed to pip uninstall' +complete -c pdm -A -n '__fish_seen_subcommand_from self; and __fish_seen_subcommand_from remove' -l quiet -d 'Suppress output' complete -c pdm -A -n '__fish_seen_subcommand_from self; and __fish_seen_subcommand_from remove' -l verbose -d 'Use `-v` for detailed output and `-vv` for more detailed' complete -c pdm -A -n '__fish_seen_subcommand_from self; and __fish_seen_subcommand_from remove' -l yes -d 'Answer yes on the question' @@ -340,6 +370,7 @@ complete -c pdm -A -n '__fish_seen_subcommand_from self; and __fish_seen_subcomm complete -c pdm -A -n '__fish_seen_subcommand_from self; and __fish_seen_subcommand_from update' -l help -d 'Show this help message and exit.' complete -c pdm -A -n '__fish_seen_subcommand_from self; and __fish_seen_subcommand_from update' -l pip-args -d 'Additional arguments that will be passed to pip install' complete -c pdm -A -n '__fish_seen_subcommand_from self; and __fish_seen_subcommand_from update' -l pre -d 'Update to the latest prerelease version' +complete -c pdm -A -n '__fish_seen_subcommand_from self; and __fish_seen_subcommand_from update' -l quiet -d 'Suppress output' complete -c pdm -A -n '__fish_seen_subcommand_from self; and __fish_seen_subcommand_from update' -l verbose -d 'Use `-v` for detailed output and `-vv` for more detailed' # show @@ -351,6 +382,7 @@ complete -c pdm -A -n '__fish_seen_subcommand_from show' -l license -d 'Show lic complete -c pdm -A -n '__fish_seen_subcommand_from show' -l name -d 'Show name' complete -c pdm -A -n '__fish_seen_subcommand_from show' -l platform -d 'Show platform' complete -c pdm -A -n '__fish_seen_subcommand_from show' -l project -d 'Specify another path as the project root, which changes the base of pyproject.toml and __pypackages__ [env var: PDM_PROJECT]' +complete -c pdm -A -n '__fish_seen_subcommand_from show' -l quiet -d 'Suppress output' complete -c pdm -A -n '__fish_seen_subcommand_from show' -l summary -d 'Show summary' complete -c pdm -A -n '__fish_seen_subcommand_from show' -l venv -d 'Run the command in the virtual environment with the given key. [env var: PDM_IN_VENV]' complete -c pdm -A -n '__fish_seen_subcommand_from show' -l verbose -d 'Use `-v` for detailed output and `-vv` for more detailed' @@ -368,11 +400,12 @@ complete -c pdm -A -n '__fish_seen_subcommand_from sync' -l help -d 'Show this h complete -c pdm -A -n '__fish_seen_subcommand_from sync' -l lockfile -d 'Specify another lockfile path. Default: pdm.lock. [env var: PDM_LOCKFILE]' complete -c pdm -A -n '__fish_seen_subcommand_from sync' -l no-default -d 'Don\'t include dependencies from the default group' complete -c pdm -A -n '__fish_seen_subcommand_from sync' -l no-editable -d 'Install non-editable versions for all packages' -complete -c pdm -A -n '__fish_seen_subcommand_from sync' -l no-isolation -d 'Do not isolate the build in a clean environment' +complete -c pdm -A -n '__fish_seen_subcommand_from sync' -l no-isolation -d 'Disable isolation when building a source distribution that follows PEP 517, as in: build dependencies specified by PEP 518 must be already installed if this option is used.' complete -c pdm -A -n '__fish_seen_subcommand_from sync' -l no-self -d 'Don\'t install the project itself. [env var: PDM_NO_SELF]' complete -c pdm -A -n '__fish_seen_subcommand_from sync' -l only-keep -d 'Only keep the selected packages' complete -c pdm -A -n '__fish_seen_subcommand_from sync' -l production -d 'Unselect dev dependencies' complete -c pdm -A -n '__fish_seen_subcommand_from sync' -l project -d 'Specify another path as the project root, which changes the base of pyproject.toml and __pypackages__ [env var: PDM_PROJECT]' +complete -c pdm -A -n '__fish_seen_subcommand_from sync' -l quiet -d 'Suppress output' complete -c pdm -A -n '__fish_seen_subcommand_from sync' -l reinstall -d 'Force reinstall existing dependencies' complete -c pdm -A -n '__fish_seen_subcommand_from sync' -l skip -d 'Skip some tasks and/or hooks by their comma-separated names. Can be supplied multiple times. Use ":all" to skip all hooks. Use ":pre" and ":post" to skip all pre or post hooks.' complete -c pdm -A -n '__fish_seen_subcommand_from sync' -l venv -d 'Run the command in the virtual environment with the given key. [env var: PDM_IN_VENV]' @@ -388,7 +421,7 @@ complete -c pdm -A -n '__fish_seen_subcommand_from update' -l help -d 'Show this complete -c pdm -A -n '__fish_seen_subcommand_from update' -l lockfile -d 'Specify another lockfile path. Default: pdm.lock. [env var: PDM_LOCKFILE]' complete -c pdm -A -n '__fish_seen_subcommand_from update' -l no-default -d 'Don\'t include dependencies from the default group' complete -c pdm -A -n '__fish_seen_subcommand_from update' -l no-editable -d 'Install non-editable versions for all packages' -complete -c pdm -A -n '__fish_seen_subcommand_from update' -l no-isolation -d 'Do not isolate the build in a clean environment' +complete -c pdm -A -n '__fish_seen_subcommand_from update' -l no-isolation -d 'Disable isolation when building a source distribution that follows PEP 517, as in: build dependencies specified by PEP 518 must be already installed if this option is used.' complete -c pdm -A -n '__fish_seen_subcommand_from update' -l no-lock -d 'Don\'t try to create or update the lockfile. [env var: PDM_NO_LOCK]' complete -c pdm -A -n '__fish_seen_subcommand_from update' -l no-self -d 'Don\'t install the project itself. [env var: PDM_NO_SELF]' complete -c pdm -A -n '__fish_seen_subcommand_from update' -l no-sync -d 'Only update lock file but do not sync packages' @@ -396,6 +429,7 @@ complete -c pdm -A -n '__fish_seen_subcommand_from update' -l outdated -d 'Show complete -c pdm -A -n '__fish_seen_subcommand_from update' -l prerelease -d 'Allow prereleases to be pinned' complete -c pdm -A -n '__fish_seen_subcommand_from update' -l production -d 'Unselect dev dependencies' complete -c pdm -A -n '__fish_seen_subcommand_from update' -l project -d 'Specify another path as the project root, which changes the base of pyproject.toml and __pypackages__ [env var: PDM_PROJECT]' +complete -c pdm -A -n '__fish_seen_subcommand_from update' -l quiet -d 'Suppress output' complete -c pdm -A -n '__fish_seen_subcommand_from update' -l save-compatible -d 'Save compatible version specifiers' complete -c pdm -A -n '__fish_seen_subcommand_from update' -l save-exact -d 'Save exact version specifiers' complete -c pdm -A -n '__fish_seen_subcommand_from update' -l save-minimum -d 'Save minimum version specifiers' @@ -416,6 +450,7 @@ complete -c pdm -A -n '__fish_seen_subcommand_from use' -l global -d 'Use the gl complete -c pdm -A -n '__fish_seen_subcommand_from use' -l help -d 'Show this help message and exit.' complete -c pdm -A -n '__fish_seen_subcommand_from use' -l ignore-remembered -d 'Ignore the remembered selection' complete -c pdm -A -n '__fish_seen_subcommand_from use' -l project -d 'Specify another path as the project root, which changes the base of pyproject.toml and __pypackages__ [env var: PDM_PROJECT]' +complete -c pdm -A -n '__fish_seen_subcommand_from use' -l quiet -d 'Suppress output' complete -c pdm -A -n '__fish_seen_subcommand_from use' -l skip -d 'Skip some tasks and/or hooks by their comma-separated names. Can be supplied multiple times. Use ":all" to skip all hooks. Use ":pre" and ":post" to skip all pre or post hooks.' complete -c pdm -A -n '__fish_seen_subcommand_from use' -l venv -d 'Use the interpreter in the virtual environment with the given name' complete -c pdm -A -n '__fish_seen_subcommand_from use' -l verbose -d 'Use `-v` for detailed output and `-vv` for more detailed' @@ -431,6 +466,7 @@ set -l venv_subcommands activate create list purge remove # venv activate complete -c pdm -f -n '__fish_seen_subcommand_from venv; and not __fish_seen_subcommand_from $venv_subcommands' -a activate -d 'Activate the virtualenv with the given name' complete -c pdm -A -n '__fish_seen_subcommand_from venv; and __fish_seen_subcommand_from activate' -l help -d 'Show this help message and exit.' +complete -c pdm -A -n '__fish_seen_subcommand_from venv; and __fish_seen_subcommand_from activate' -l quiet -d 'Suppress output' complete -c pdm -A -n '__fish_seen_subcommand_from venv; and __fish_seen_subcommand_from activate' -l verbose -d 'Use `-v` for detailed output and `-vv` for more detailed' # venv create @@ -438,6 +474,7 @@ complete -c pdm -f -n '__fish_seen_subcommand_from venv; and not __fish_seen_sub complete -c pdm -A -n '__fish_seen_subcommand_from venv; and __fish_seen_subcommand_from create' -l force -d 'Recreate if the virtualenv already exists' complete -c pdm -A -n '__fish_seen_subcommand_from venv; and __fish_seen_subcommand_from create' -l help -d 'Show this help message and exit.' complete -c pdm -A -n '__fish_seen_subcommand_from venv; and __fish_seen_subcommand_from create' -l name -d 'Specify the name of the virtualenv' +complete -c pdm -A -n '__fish_seen_subcommand_from venv; and __fish_seen_subcommand_from create' -l quiet -d 'Suppress output' complete -c pdm -A -n '__fish_seen_subcommand_from venv; and __fish_seen_subcommand_from create' -l verbose -d 'Use `-v` for detailed output and `-vv` for more detailed' complete -c pdm -A -n '__fish_seen_subcommand_from venv; and __fish_seen_subcommand_from create' -l with -d 'Specify the backend to create the virtualenv' complete -c pdm -A -n '__fish_seen_subcommand_from venv; and __fish_seen_subcommand_from create' -l with-pip -d 'Install pip with the virtualenv' @@ -445,6 +482,7 @@ complete -c pdm -A -n '__fish_seen_subcommand_from venv; and __fish_seen_subcomm # venv list complete -c pdm -f -n '__fish_seen_subcommand_from venv; and not __fish_seen_subcommand_from $venv_subcommands' -a list -d 'List all virtualenvs associated with this project' complete -c pdm -A -n '__fish_seen_subcommand_from venv; and __fish_seen_subcommand_from list' -l help -d 'Show this help message and exit.' +complete -c pdm -A -n '__fish_seen_subcommand_from venv; and __fish_seen_subcommand_from list' -l quiet -d 'Suppress output' complete -c pdm -A -n '__fish_seen_subcommand_from venv; and __fish_seen_subcommand_from list' -l verbose -d 'Use `-v` for detailed output and `-vv` for more detailed' # venv purge @@ -452,10 +490,12 @@ complete -c pdm -f -n '__fish_seen_subcommand_from venv; and not __fish_seen_sub complete -c pdm -A -n '__fish_seen_subcommand_from venv; and __fish_seen_subcommand_from purge' -l force -d 'Force purging without prompting for confirmation' complete -c pdm -A -n '__fish_seen_subcommand_from venv; and __fish_seen_subcommand_from purge' -l help -d 'Show this help message and exit.' complete -c pdm -A -n '__fish_seen_subcommand_from venv; and __fish_seen_subcommand_from purge' -l interactive -d 'Interactively purge selected Virtualenvs' +complete -c pdm -A -n '__fish_seen_subcommand_from venv; and __fish_seen_subcommand_from purge' -l quiet -d 'Suppress output' complete -c pdm -A -n '__fish_seen_subcommand_from venv; and __fish_seen_subcommand_from purge' -l verbose -d 'Use `-v` for detailed output and `-vv` for more detailed' # venv remove complete -c pdm -f -n '__fish_seen_subcommand_from venv; and not __fish_seen_subcommand_from $venv_subcommands' -a remove -d 'Remove the virtualenv with the given name' complete -c pdm -A -n '__fish_seen_subcommand_from venv; and __fish_seen_subcommand_from remove' -l help -d 'Show this help message and exit.' +complete -c pdm -A -n '__fish_seen_subcommand_from venv; and __fish_seen_subcommand_from remove' -l quiet -d 'Suppress output' complete -c pdm -A -n '__fish_seen_subcommand_from venv; and __fish_seen_subcommand_from remove' -l verbose -d 'Use `-v` for detailed output and `-vv` for more detailed' complete -c pdm -A -n '__fish_seen_subcommand_from venv; and __fish_seen_subcommand_from remove' -l yes -d 'Answer yes on the following question' diff --git a/src/pdm/cli/completions/pdm.ps1 b/src/pdm/cli/completions/pdm.ps1 index eb188b781c..4a272f69e6 100644 --- a/src/pdm/cli/completions/pdm.ps1 +++ b/src/pdm/cli/completions/pdm.ps1 @@ -196,7 +196,7 @@ function TabExpansion($line, $lastWord) { [string[]]$commands = $words.Where( { $_ -notlike "-*" }) $command = $commands[0] $completer = [Completer]::new() - $completer.AddOpts(([Option]::new(("-h", "--help", "-v", "--verbose")))) + $completer.AddOpts(([Option]::new(("-h", "--help", "-v", "--verbose", "-q", "--quiet")))) $sectionOption = [Option]::new(@("-G", "--group")).WithValues(@(getSections)) $projectOption = [Option]::new(@("-p", "--project")).WithValues(@()) $skipOption = [Option]::new(@("-k", "--skip")).WithValues(@()) diff --git a/src/pdm/cli/completions/pdm.zsh b/src/pdm/cli/completions/pdm.zsh index 42524051b2..750fdd9320 100644 --- a/src/pdm/cli/completions/pdm.zsh +++ b/src/pdm/cli/completions/pdm.zsh @@ -12,7 +12,8 @@ _pdm() { local curcontext=$curcontext ret=1 local -a arguments=( {-h,--help}'[Show help message and exit]' - {-v,--verbose}'[Show detailed output]' + {-v,--verbose}'[Use `-v` for detailed output and `-vv` for more detailed]' + {-q,--quiet}'[Suppress output]' ) local sub_commands=( 'add:Add package(s) to pyproject.toml and install them' diff --git a/src/pdm/cli/options.py b/src/pdm/cli/options.py index 1f431c08f2..81c261ffe6 100644 --- a/src/pdm/cli/options.py +++ b/src/pdm/cli/options.py @@ -117,13 +117,15 @@ def from_splitted_env(name: str, separator: str) -> list[str] | None: return [v.strip() for v in value.split(separator) if v.strip()] or None -verbose_option = Option( +verbose_option = ArgumentGroup("Verbosity options", is_mutually_exclusive=True) +verbose_option.add_argument( "-v", "--verbose", action="count", default=0, help="Use `-v` for detailed output and `-vv` for more detailed", ) +verbose_option.add_argument("-q", "--quiet", action="store_const", const=-1, dest="verbose", help="Suppress output") dry_run_option = Option( diff --git a/src/pdm/core.py b/src/pdm/core.py index e7ae5e65ab..380278b546 100644 --- a/src/pdm/core.py +++ b/src/pdm/core.py @@ -211,7 +211,12 @@ def main( err=True, ) if should_show_tb: - self.ui.echo("Add '-v' to see the detailed traceback", style="warning", err=True) + self.ui.echo( + "Add '-v' to see the detailed traceback", + style="warning", + err=True, + verbosity=termui.Verbosity.NORMAL, + ) sys.exit(1) else: if project.config["check_update"] and not is_in_zipapp(): diff --git a/src/pdm/exceptions.py b/src/pdm/exceptions.py index e330339392..24ebd76efb 100644 --- a/src/pdm/exceptions.py +++ b/src/pdm/exceptions.py @@ -41,7 +41,15 @@ def __init__(self, candidate: Candidate) -> None: super().__init__(message) -class ExtrasWarning(UserWarning): +class PDMWarning(UserWarning): + pass + + +class PackageWarning(PDMWarning): + pass + + +class ExtrasWarning(PDMWarning): def __init__(self, project_name: str, extras: list[str]) -> None: super().__init__(f"Extras not found for {project_name}: [{','.join(extras)}]") self.extras = tuple(extras) diff --git a/src/pdm/installers/installers.py b/src/pdm/installers/installers.py index 944a6dd20b..7213b8c4e2 100644 --- a/src/pdm/installers/installers.py +++ b/src/pdm/installers/installers.py @@ -18,6 +18,7 @@ from installer.sources import _WheelFileValidationError from pdm.compat import cached_property +from pdm.exceptions import PDMWarning from pdm.installers.packages import CachedPackage from pdm.termui import logger from pdm.utils import fs_supports_symlink @@ -262,7 +263,7 @@ def _install_wheel( " Please report to the maintainers of that package so they can fix" f" their build process. Details:\n{formatted_issues}\n" ) - warnings.warn(warning, UserWarning, stacklevel=2) + warnings.warn(warning, PDMWarning, stacklevel=2) root_scheme = _process_WHEEL_file(source) source.exclude = excludes if additional_contents: diff --git a/src/pdm/installers/synchronizers.py b/src/pdm/installers/synchronizers.py index 42dc74cb56..6bfd0ff9ac 100644 --- a/src/pdm/installers/synchronizers.py +++ b/src/pdm/installers/synchronizers.py @@ -76,8 +76,9 @@ def __exit__(self, *args: Any, **kwargs: Any) -> None: def editables_candidate(environment: BaseEnvironment) -> Candidate | None: """Return a candidate for `editables` package""" - repository = environment.project.get_repository() - return next(iter(repository.find_candidates(parse_requirement("editables"))), None) + with environment.get_finder() as finder: + best = finder.find_best_match("editables").best + return None if best is None else Candidate.from_installation_candidate(best, parse_requirement("editables")) class BaseSynchronizer: diff --git a/src/pdm/models/candidates.py b/src/pdm/models/candidates.py index b8cfb7b61e..40d3d6ab60 100644 --- a/src/pdm/models/candidates.py +++ b/src/pdm/models/candidates.py @@ -17,7 +17,7 @@ from pdm.builders import EditableBuilder, WheelBuilder from pdm.compat import cached_property from pdm.compat import importlib_metadata as im -from pdm.exceptions import BuildError, CandidateNotFound, InvalidPyVersion +from pdm.exceptions import BuildError, CandidateNotFound, InvalidPyVersion, PDMWarning from pdm.models.backends import get_backend, get_backend_by_spec from pdm.models.requirements import ( FileRequirement, @@ -559,7 +559,7 @@ def _get_metadata_from_build(self, source_dir: Path, metadata_parent: str) -> im except Exception: message = "Failed to parse the project files, dependencies may be missing" termui.logger.warning(message) - warnings.warn(message, RuntimeWarning, stacklevel=1) + warnings.warn(message, PDMWarning, stacklevel=1) setup = Setup() return setup.as_dist() else: diff --git a/src/pdm/models/repositories.py b/src/pdm/models/repositories.py index f76c1df1a7..9711c3fd53 100644 --- a/src/pdm/models/repositories.py +++ b/src/pdm/models/repositories.py @@ -1,13 +1,16 @@ from __future__ import annotations import dataclasses +import fnmatch import posixpath +import re import sys +import warnings from functools import wraps -from typing import TYPE_CHECKING, TypeVar, cast +from typing import TYPE_CHECKING, Generator, TypeVar, cast from pdm import termui -from pdm.exceptions import CandidateInfoNotFound, CandidateNotFound +from pdm.exceptions import CandidateInfoNotFound, CandidateNotFound, PackageWarning from pdm.models.candidates import Candidate, make_candidate from pdm.models.requirements import ( Requirement, @@ -70,6 +73,7 @@ def __init__( self.ignore_compatibility = ignore_compatibility self._candidate_info_cache = environment.project.make_candidate_info_cache() self._hash_cache = environment.project.make_hash_cache() + self.has_warnings = False def get_filtered_sources(self, req: Requirement) -> list[RepositoryConfig]: """Get matching sources based on the index attribute.""" @@ -135,6 +139,16 @@ def make_this_candidate(self, requirement: Requirement) -> Candidate: candidate.prepare(self.environment).metadata return candidate + def _should_ignore_package_warning(self, requirement: Requirement) -> bool: + ignore_settings = self.environment.project.pyproject.settings.get("ignore_package_warnings", []) + package_name = requirement.key + assert package_name is not None + for pat in ignore_settings: + pat = re.sub(r"[^A-Za-z0-9?*\[\]]+", "-", pat).lower() + if fnmatch.fnmatch(package_name, pat): + return True + return False + def find_candidates( self, requirement: Requirement, @@ -158,9 +172,37 @@ def find_candidates( if requirement.specifier.contains(c.version, allow_prereleases) # type: ignore[arg-type, union-attr] ) - applicable_cans_python_compatible = LazySequence( - c for c in applicable_cans if ignore_requires_python or requires_python.is_subset(c.requires_python) - ) + def filter_candidates_with_requires_python(candidates: Iterable[Candidate]) -> Generator[Candidate, None, None]: + project_requires_python = self.environment.python_requires + if ignore_requires_python: + yield from candidates + return + + def python_specifier(spec: str | PySpecSet) -> str: + if isinstance(spec, PySpecSet): + spec = str(spec) + return "all Python versions" if not spec else f"Python{spec}" + + for candidate in candidates: + if not requires_python.is_subset(candidate.requires_python): + if self._should_ignore_package_warning(requirement): + continue + working_requires_python = project_requires_python & PySpecSet(candidate.requires_python) + if working_requires_python.is_impossible: # pragma: no cover + continue + warnings.warn( + f"Skipping {candidate.name}@{candidate.version} because it requires " + f"{python_specifier(candidate.requires_python)} but the project claims to work with " + f"{python_specifier(project_requires_python)}.\nNarrow down the `requires-python` range to " + f'include this version. For example, "{working_requires_python}" should work.', + PackageWarning, + stacklevel=4, + ) + self.has_warnings = True + else: + yield candidate + + applicable_cans_python_compatible = LazySequence(filter_candidates_with_requires_python(applicable_cans)) # Evaluate data-requires-python attr and discard incompatible candidates # to reduce the number of candidates to resolve. if applicable_cans_python_compatible: @@ -174,9 +216,7 @@ def find_candidates( applicable_cans = LazySequence( c for c in cans if requirement.specifier.contains(c.version, True) # type: ignore[arg-type, union-attr] ) - applicable_cans_python_compatible = LazySequence( - c for c in applicable_cans if ignore_requires_python or requires_python.is_subset(c.requires_python) - ) + applicable_cans_python_compatible = LazySequence(filter_candidates_with_requires_python(applicable_cans)) if applicable_cans_python_compatible: applicable_cans = applicable_cans_python_compatible diff --git a/src/pdm/project/lockfile.py b/src/pdm/project/lockfile.py index b0c3acb260..9f8fc952c8 100644 --- a/src/pdm/project/lockfile.py +++ b/src/pdm/project/lockfile.py @@ -4,6 +4,7 @@ import tomlkit +from pdm import termui from pdm.models.specifiers import get_specifier from pdm.project.toml_file import TOMLBase @@ -52,7 +53,7 @@ def set_data(self, data: Mapping[str, Any]) -> None: def write(self, show_message: bool = True) -> None: super().write() if show_message: - self.ui.echo(f"Changes are written to [success]{self._path.name}[/].") + self.ui.echo(f"Changes are written to [success]{self._path.name}[/].", verbosity=termui.Verbosity.NORMAL) def __getitem__(self, key: str) -> dict: return self._data[key] diff --git a/src/pdm/project/project_file.py b/src/pdm/project/project_file.py index cb02ce1055..c12c83740c 100644 --- a/src/pdm/project/project_file.py +++ b/src/pdm/project/project_file.py @@ -6,6 +6,7 @@ from tomlkit import TOMLDocument, items +from pdm import termui from pdm.project.toml_file import TOMLBase from pdm.utils import deprecation_warning @@ -41,7 +42,7 @@ def write(self, show_message: bool = True) -> None: _remove_empty_tables(self._data) super().write() if show_message: - self.ui.echo("Changes are written to [success]pyproject.toml[/].") + self.ui.echo("Changes are written to [success]pyproject.toml[/].", verbosity=termui.Verbosity.NORMAL) @property def is_valid(self) -> bool: diff --git a/src/pdm/pytest.py b/src/pdm/pytest.py index dd5585ace8..ffff042f7a 100644 --- a/src/pdm/pytest.py +++ b/src/pdm/pytest.py @@ -25,6 +25,7 @@ import os import shutil import sys +import warnings from dataclasses import dataclass from io import BufferedReader, BytesIO, StringIO from pathlib import Path @@ -367,7 +368,8 @@ def core() -> Iterator[Core]: # Turn off use_venv by default, for testing Config._config_map["python.use_venv"].default = False main = Core() - yield main + with warnings.catch_warnings(): + yield main # Restore the config items Config._config_map = old_config_map diff --git a/src/pdm/resolver/core.py b/src/pdm/resolver/core.py index cca3b7a5b8..88c8b66202 100644 --- a/src/pdm/resolver/core.py +++ b/src/pdm/resolver/core.py @@ -2,6 +2,7 @@ from typing import TYPE_CHECKING, Dict, cast +from pdm import termui from pdm.models.candidates import Candidate from pdm.models.repositories import BaseRepository from pdm.models.requirements import strip_extras @@ -32,9 +33,17 @@ def resolve( requirements.append(PythonRequirement.from_pyspec_set(requires_python)) provider = cast(BaseProvider, resolver.provider) repository = cast(BaseRepository, provider.repository) - result = resolver.resolve(requirements, max_rounds) + if repository.has_warnings: + repository.environment.project.core.ui.echo( + "Use `-q/--quiet` to suppress these warnings, or ignore them per-package with " + r"`ignore_package_warnings` config in \[tool.pdm] table.", + err=True, + style="info", + verbosity=termui.Verbosity.NORMAL, + ) + mapping = cast(Dict[str, Candidate], result.mapping) mapping.pop("python", None) diff --git a/src/pdm/termui.py b/src/pdm/termui.py index 045cc09dfe..e82f794a1e 100644 --- a/src/pdm/termui.py +++ b/src/pdm/termui.py @@ -5,6 +5,7 @@ import enum import logging import os +import warnings from tempfile import mktemp from typing import TYPE_CHECKING @@ -15,6 +16,8 @@ from rich.table import Table from rich.theme import Theme +from pdm.exceptions import PDMWarning + if TYPE_CHECKING: from typing import Any, Iterator, Sequence @@ -85,9 +88,10 @@ def ask(*args: str, prompt_type: type[str] | type[int] | None = None, **kwargs: class Verbosity(enum.IntEnum): + QUIET = -1 NORMAL = 0 - DETAIL = enum.auto() - DEBUG = enum.auto() + DETAIL = 1 + DEBUG = 2 LOG_LEVELS = { @@ -157,6 +161,9 @@ def __init__(self, verbosity: Verbosity = Verbosity.NORMAL) -> None: def set_verbosity(self, verbosity: int) -> None: self.verbosity = Verbosity(verbosity) + if self.verbosity == Verbosity.QUIET: + warnings.simplefilter("ignore", PDMWarning, append=True) + warnings.simplefilter("ignore", FutureWarning, append=True) def set_theme(self, theme: Theme) -> None: """set theme for rich console @@ -170,7 +177,7 @@ def echo( self, message: str | RichProtocol = "", err: bool = False, - verbosity: Verbosity = Verbosity.NORMAL, + verbosity: Verbosity = Verbosity.QUIET, **kwargs: Any, ) -> None: """print message using rich console diff --git a/tests/resolver/test_resolve.py b/tests/resolver/test_resolve.py index 1ac8e8f57d..eb5f68953d 100644 --- a/tests/resolver/test_resolve.py +++ b/tests/resolver/test_resolve.py @@ -2,6 +2,7 @@ from resolvelib.resolvers import ResolutionImpossible, Resolver from pdm.cli.actions import resolve_candidates_from_lockfile +from pdm.exceptions import PackageWarning from pdm.models.requirements import parse_requirement from pdm.models.specifiers import PySpecSet from pdm.resolver import resolve as _resolve @@ -50,7 +51,9 @@ def test_resolve_named_requirement(resolve): def test_resolve_requires_python(resolve): - result = resolve(["django"]) + with pytest.warns(PackageWarning) as records: + result = resolve(["django"]) + assert len(records) > 0 assert result["django"].version == "1.11.8" assert "sqlparse" not in result diff --git a/tests/test_project.py b/tests/test_project.py index 4be1b41530..b8623412e4 100644 --- a/tests/test_project.py +++ b/tests/test_project.py @@ -9,6 +9,8 @@ from pdm.environments import PythonEnvironment from pdm.exceptions import PdmException +from pdm.models.requirements import parse_requirement +from pdm.models.specifiers import PySpecSet from pdm.models.venv import get_venv_python from pdm.utils import cd @@ -328,3 +330,36 @@ def test_invoke_pdm_adding_configured_args(project, pdm, mocker): parser.assert_called_with(["install", "--no-self", "--no-editable", "--check"]) pdm(["lock", "--lockfile", "pdm.2.lock"], obj=project) parser.assert_called_with(["lock", "--no-cross-platform", "--lockfile", "pdm.2.lock"]) + + +@pytest.fixture() +def prepare_repository(repository, project): + repository.add_candidate("foo", "3.0", ">=3.8,<3.13") + repository.add_candidate("foo", "2.0", ">=3.7,<3.12") + repository.add_candidate("foo", "1.0", ">=3.7") + repository.environment.python_requires = PySpecSet(">=3.9") + project.add_dependencies({"foo": parse_requirement("foo")}) + + +@pytest.mark.usefixtures("prepare_repository") +@pytest.mark.parametrize("is_quiet,extra_args", [(True, ("-q",)), (False, ())]) +def test_quiet_mode(pdm, project, is_quiet, extra_args, recwarn): + result = pdm(["lock", *extra_args], obj=project) + + assert result.exit_code == 0 + assert len(recwarn) > 0 + + assert 'For example, ">=3.9,<3.13"' in str(recwarn[0].message) + assert 'For example, ">=3.9,<3.12"' in str(recwarn[1].message) + assert ("to suppress these warnings" in result.stderr) is not is_quiet + assert project.locked_repository.all_candidates["foo"].version == "1.0" + + +@pytest.mark.usefixtures("prepare_repository") +@pytest.mark.parametrize("pattern,suppressed", [("foo", True), ("bar", False), ("*", True), ("f?o", True)]) +def test_ignore_package_warning(pdm, project, recwarn, pattern, suppressed): + project.pyproject.settings["ignore_package_warnings"] = [pattern] + result = pdm(["lock"], obj=project) + + assert result.exit_code == 0 + assert (len(recwarn) == 0) is suppressed