From d0daf6f63cd04287b313312f41d32388dbeb5753 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 13 Aug 2024 14:59:46 -0400 Subject: [PATCH 1/3] Rename the project to setuptools-scm in docs and GitHub. Closes #1067 --- CHANGELOG.md | 3 ++- README.md | 10 ++++----- docs/config.md | 8 +++---- docs/customizing.md | 8 +++---- .../version_scheme_code/pyproject.toml | 4 ++-- docs/extending.md | 6 ++--- docs/index.md | 10 ++++----- docs/overrides.md | 4 ++-- docs/usage.md | 22 +++++++++---------- 9 files changed, 38 insertions(+), 37 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fcf3123d..62d1b1be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,7 @@ - fix #925: allow `write_to` to be an absolute path when it's a subdirectory of the root - fix #932: ensure type annotations in version file don't cause linter issues -- fix #930: temporary restore `DEFAULT_VERSION_SCHEME` and `DEFAULT_LOCAL_SCHEME` on the `setuptools_scm` package +- fix #930: temporary restore `DEFAULT_VERSION_SCHEME` and `DEFAULT_LOCAL_SCHEME` on the `setuptools-scm` package @@ -60,6 +60,7 @@ - use normalized dist names for the `SETUPTOOLS_SCM_PRETEND_VERSION_FOR_${DIST_NAME}` env var - drop support for python 3.7 - introduce `version_file` as replacement for `write_to` +- renameed the project from `setuptools_scm` to `setuptools-scm` ## features diff --git a/README.md b/README.md index 3d097177..e1f06f82 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -# setuptools_scm -[![github ci](https://github.com/pypa/setuptools_scm/actions/workflows/python-tests.yml/badge.svg)](https://github.com/pypa/setuptools_scm/actions/workflows/python-tests.yml) +# setuptools-scm +[![github ci](https://github.com/pypa/setuptools-scm/actions/workflows/python-tests.yml/badge.svg)](https://github.com/pypa/setuptools-scm/actions/workflows/python-tests.yml) [![Documentation Status](https://readthedocs.org/projects/setuptools-scm/badge/?version=latest)](https://setuptools-scm.readthedocs.io/en/latest/?badge=latest) [![tidelift](https://tidelift.com/badges/package/pypi/setuptools-scm) ](https://tidelift.com/subscription/pkg/pypi-setuptools-scm?utm_source=pypi-setuptools-scm&utm_medium=readme) @@ -28,7 +28,7 @@ build step by specifying it as one of the build requirements. ```toml title="pyproject.toml" [build-system] -requires = ["setuptools>=64", "setuptools_scm>=8"] +requires = ["setuptools>=64", "setuptools-scm>=8"] build-backend = "setuptools.build_meta" ``` @@ -71,7 +71,7 @@ $ python -m setuptools_scm --help For further configuration see the [documentation]. -[setuptools-scm]: https://github.com/pypa/setuptools_scm +[setuptools-scm]: https://github.com/pypa/setuptools-scm [documentation]: https://setuptools-scm.readthedocs.io/ [git-archive-docs]: https://setuptools-scm.readthedocs.io/en/stable/usage/#builtin-mechanisms-for-obtaining-version-numbers @@ -81,7 +81,7 @@ For further configuration see the [documentation]. Some enterprise distributions like RHEL7 ship rather old setuptools versions. -In those cases its typically possible to build by using an sdist against `setuptools_scm<2.0`. +In those cases its typically possible to build by using an sdist against `setuptools-scm<2.0`. As those old setuptools versions lack sensible types for versions, modern [setuptools-scm] is unable to support them sensibly. diff --git a/docs/config.md b/docs/config.md index 7e859aae..1d6dfb43 100644 --- a/docs/config.md +++ b/docs/config.md @@ -69,14 +69,14 @@ Callables or other Python objects have to be passed in `setup.py` (via the `use_ `fallback_version: str | None = None` : A version string that will be used if no other method for detecting the version worked (e.g., when using a tarball with no metadata). If this is - unset (the default), `setuptools_scm` will error if it fails to detect the + unset (the default), `setuptools-scm` will error if it fails to detect the version. `parse: Callable[[Path, Config], ScmVersion] | None = None` : A function that will be used instead of the discovered SCM for parsing the version. Use with caution, this is a function for advanced use and you should be - familiar with the `setuptools_scm` internals to use it. + familiar with the `setuptools-scm` internals to use it. `git_describe_command` : This command will be used instead the default `git describe --long` command. @@ -96,7 +96,7 @@ Callables or other Python objects have to be passed in `setup.py` (via the `use_ The [setuptools_scm.NonNormalizedVersion][] convenience class is provided to disable the normalization step done by - `packaging.version.Version`. If this is used while `setuptools_scm` + `packaging.version.Version`. If this is used while `setuptools-scm` is integrated in a setuptools packaging process, the non-normalized version number will appear in all files (see `version_file` note). @@ -121,7 +121,7 @@ Callables or other Python objects have to be passed in `setup.py` (via the `use_ in which case it will be an unparsed string. Specifying distribution-specific pretend versions will avoid possible collisions with third party distributions - also using ``setuptools_scm`` + also using ``setuptools-scm`` the dist name normalization follows adapted PEP 503 semantics, with one or more of ".-\_" being replaced by a single "\_", and the name being upper-cased diff --git a/docs/customizing.md b/docs/customizing.md index b4bc7a15..616e12e9 100644 --- a/docs/customizing.md +++ b/docs/customizing.md @@ -3,10 +3,10 @@ ## providing project local version schemes As PEP 621 provides no way to specify local code as a build backend plugin, -setuptools_scm has to piggyback on setuptools for passing functions over. +setuptools-scm has to piggyback on setuptools for passing functions over. To facilitate that one needs to write a `setup.py` file and -pass partial setuptools_scm configuration in via the use_scm_version keyword. +pass partial setuptools-scm configuration in via the use_scm_version keyword. It's strongly recommended to experiment with using stock version schemes or creating plugins as package. (This recommendation will change if there ever is something like build-time entrypoints). @@ -33,7 +33,7 @@ setup(use_scm_version={"version_scheme": myversion_func}) ``` { .toml title="pyproject.toml" file="docs/examples/version_scheme_code/pyproject.toml" } [build-system] -requires = ["setuptools>=64", "setuptools_scm>=8"] +requires = ["setuptools>=64", "setuptools-scm>=8"] build-backend = "setuptools.build_meta" [project] @@ -52,7 +52,7 @@ dynamic = [ ## Importing in setup.py -With the pep 517/518 build backend, setuptools_scm is importable from `setup.py` +With the pep 517/518 build backend, setuptools-scm is importable from `setup.py` ``` { .python title="setup.py" } import setuptools diff --git a/docs/examples/version_scheme_code/pyproject.toml b/docs/examples/version_scheme_code/pyproject.toml index 10ef31d4..389aad09 100644 --- a/docs/examples/version_scheme_code/pyproject.toml +++ b/docs/examples/version_scheme_code/pyproject.toml @@ -1,6 +1,6 @@ # ~/~ begin <>[init] [build-system] -requires = ["setuptools>=64", "setuptools_scm>=8"] +requires = ["setuptools>=64", "setuptools-scm>=8"] build-backend = "setuptools.build_meta" [project] @@ -10,4 +10,4 @@ dynamic = [ ] [tool.setuptools_scm] -# ~/~ end \ No newline at end of file +# ~/~ end diff --git a/docs/extending.md b/docs/extending.md index fa71841e..66f1ffd4 100644 --- a/docs/extending.md +++ b/docs/extending.md @@ -1,12 +1,12 @@ -# Extending setuptools_scm +# Extending setuptools-scm -`setuptools_scm` uses [entry-point][entry-point] based hooks to extend its default capabilities. +`setuptools-scm` uses [entry-point][entry-point] based hooks to extend its default capabilities. [entry-point]: https://packaging.python.org/en/latest/specifications/entry-points/ ## Adding a new SCM -`setuptools_scm` provides two entrypoints for adding new SCMs: +`setuptools-scm` provides two entrypoints for adding new SCMs: `setuptools_scm.parse_scm` : A function used to parse the metadata of the current workdir diff --git a/docs/index.md b/docs/index.md index 212a0a1d..11538bc9 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,10 +1,10 @@ # About -`setuptools_scm` extracts Python package versions from `git` or `hg` metadata +`setuptools-scm` extracts Python package versions from `git` or `hg` metadata instead of declaring them as the version argument or in a Source Code Managed (SCM) managed file. -Additionally `setuptools_scm` provides `setuptools` with a list of +Additionally `setuptools-scm` provides `setuptools` with a list of files that are managed by the SCM (i.e. it automatically adds all the SCM-managed files to the sdist). Unwanted files must be excluded via `MANIFEST.in` @@ -16,13 +16,13 @@ or [configuring Git archive][git-archive-docs]. ### with setuptools -Note: `setuptools_scm>=8` intentionally doesn't depend on setuptools to ease non-setuptools usage. +Note: `setuptools-scm>=8` intentionally doesn't depend on setuptools to ease non-setuptools usage. Please ensure a recent version of setuptools (>=64) is installed. ```toml title="pyproject.toml" [build-system] -requires = ["setuptools>=64", "setuptools_scm>=8"] +requires = ["setuptools>=64", "setuptools-scm>=8"] build-backend = "setuptools.build_meta" [project] @@ -39,6 +39,6 @@ dynamic = ["version"] ### with hatch -[Hatch-vcs](https://github.com/ofek/hatch-vcs) integrates with setuptools_scm +[Hatch-vcs](https://github.com/ofek/hatch-vcs) integrates with setuptools-scm but provides its own configuration options, please see its [documentation](https://github.com/ofek/hatch-vcs#readme) diff --git a/docs/overrides.md b/docs/overrides.md index 22d285e4..5a6093bb 100644 --- a/docs/overrides.md +++ b/docs/overrides.md @@ -2,7 +2,7 @@ ## pretend versions -setuptools_scm provides a mechanism to override the version number build time. +setuptools-scm provides a mechanism to override the version number build time. the environment variable `SETUPTOOLS_SCM_PRETEND_VERSION` is used as the override source for the version number unparsed string. @@ -12,7 +12,7 @@ where the dist name normalization follows adapted PEP 503 semantics. ## config overrides -setuptools_scm parses the environment variable `SETUPTOOLS_SCM_OVERRIDES_FOR_${NORMALIZED_DIST_NAME}` +setuptools-scm parses the environment variable `SETUPTOOLS_SCM_OVERRIDES_FOR_${NORMALIZED_DIST_NAME}` as a toml inline map to override the configuration data from `pyproject.toml`. ## subprocess timeouts diff --git a/docs/usage.md b/docs/usage.md index 23f38b4b..c48f6b46 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -2,14 +2,14 @@ ## at build time -The preferred way to configure `setuptools_scm` is to author +The preferred way to configure `setuptools-scm` is to author settings in the `tool.setuptools_scm` section of `pyproject.toml`. It's necessary to use a setuptools version released after 2022. ```toml title="pyproject.toml" [build-system] -requires = ["setuptools>=64", "setuptools_scm>=8"] +requires = ["setuptools>=64", "setuptools-scm>=8"] build-backend = "setuptools.build_meta" [project] @@ -17,10 +17,10 @@ build-backend = "setuptools.build_meta" dynamic = ["version"] [tool.setuptools_scm] -# can be empty if no extra settings are needed, presence enables setuptools_scm +# can be empty if no extra settings are needed, presence enables setuptools-scm ``` -That will be sufficient to require `setuptools_scm` for projects +That will be sufficient to require `setuptools-scm` for projects that support PEP 518 ([pip](https://pypi.org/project/pip) and [pep517](https://pypi.org/project/pep517/)). Tools that still invoke `setup.py` must ensure build requirements are installed @@ -46,7 +46,7 @@ $ python -m setuptools_scm --help If you need to confirm which version string is being generated or debug the configuration, you can install -[setuptools-scm](https://github.com/pypa/setuptools_scm) +[setuptools-scm](https://github.com/pypa/setuptools-scm) directly in your working environment and run: ```commandline @@ -77,7 +77,7 @@ $ python -m setuptools_scm ls # output trimmed for brevity ## at runtime (strongly discouraged) -the most simple **looking** way to use `setuptools_scm` at runtime is: +the most simple **looking** way to use `setuptools-scm` at runtime is: ```python from setuptools_scm import get_version @@ -85,7 +85,7 @@ version = get_version() ``` -In order to use `setuptools_scm` from code that is one directory deeper +In order to use `setuptools-scm` from code that is one directory deeper than the project's root, you can use: ```python @@ -172,7 +172,7 @@ is preferred over `SETUPTOOLS_SCM_PRETEND_VERSION`. ## Default versioning scheme -In the standard configuration `setuptools_scm` takes a look at three things: +In the standard configuration `setuptools-scm` takes a look at three things: 1. latest tag (with a version number) 2. the distance to this tag (e.g. number of revisions since latest tag) @@ -261,14 +261,14 @@ $ git add .git_archival.txt .gitattributes && git commit -m "add export config" Note that if you are creating a `_version.py` file, note that it should not be kept in version control. It's strongly recommended to be put into gitignore. -[git-archive-issue]: https://github.com/pypa/setuptools_scm/issues/806 +[git-archive-issue]: https://github.com/pypa/setuptools-scm/issues/806 ### File finders hook makes most of `MANIFEST.in` unnecessary -`setuptools_scm` implements a [file_finders] entry point +`setuptools-scm` implements a [file_finders] entry point which returns all files tracked by your SCM. This eliminates the need for a manually constructed `MANIFEST.in` in most cases where this -would be required when not using `setuptools_scm`, namely: +would be required when not using `setuptools-scm`, namely: * To ensure all relevant files are packaged when running the `sdist` command. * When using [include_package_data] to include package data as part of the `build` or `bdist_wheel`. From 12fc28ecb861aa95f4384d4f134671bb2ffabe82 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 13 Aug 2024 15:07:01 -0400 Subject: [PATCH 2/3] Updated more references to the legacy name in Python code. --- src/setuptools_scm/_cli.py | 4 ++-- src/setuptools_scm/_get_version_impl.py | 2 +- .../_integration/dump_version.py | 2 +- src/setuptools_scm/_integration/setuptools.py | 6 +++--- testing/test_git.py | 20 +++++++++---------- testing/test_mercurial.py | 2 +- testing/test_version.py | 2 +- 7 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/setuptools_scm/_cli.py b/src/setuptools_scm/_cli.py index 8c815237..b54903a4 100644 --- a/src/setuptools_scm/_cli.py +++ b/src/setuptools_scm/_cli.py @@ -61,7 +61,7 @@ def _get_cli_opts(args: list[str] | None) -> argparse.Namespace: "--config", default=None, metavar="PATH", - help="path to 'pyproject.toml' with setuptools_scm config, " + help="path to 'pyproject.toml' with setuptools-scm config, " "default: looked up in the current or parent directories", ) parser.add_argument( @@ -89,7 +89,7 @@ def _get_cli_opts(args: list[str] | None) -> argparse.Namespace: "--query", type=str.casefold, nargs="*", - help="display setuptools_scm settings according to query, " + help="display setuptools-scm settings according to query, " "e.g. dist_name, do not supply an argument in order to " "print a list of valid queries.", ) diff --git a/src/setuptools_scm/_get_version_impl.py b/src/setuptools_scm/_get_version_impl.py index 877804c1..1b81a4b2 100644 --- a/src/setuptools_scm/_get_version_impl.py +++ b/src/setuptools_scm/_get_version_impl.py @@ -149,7 +149,7 @@ def get_version( """ If supplied, relative_to should be a file from which root may be resolved. Typically called by a script or module that is not - in the root of the repository to direct setuptools_scm to the + in the root of the repository to direct setuptools-scm to the root of the repository by supplying ``__file__``. """ diff --git a/src/setuptools_scm/_integration/dump_version.py b/src/setuptools_scm/_integration/dump_version.py index 1901b1d3..cc7d3b1b 100644 --- a/src/setuptools_scm/_integration/dump_version.py +++ b/src/setuptools_scm/_integration/dump_version.py @@ -13,7 +13,7 @@ TEMPLATES = { ".py": """\ -# file generated by setuptools_scm +# file generated by setuptools-scm # don't change, don't track in version control TYPE_CHECKING = False if TYPE_CHECKING: diff --git a/src/setuptools_scm/_integration/setuptools.py b/src/setuptools_scm/_integration/setuptools.py index dfc5a286..3ed48470 100644 --- a/src/setuptools_scm/_integration/setuptools.py +++ b/src/setuptools_scm/_integration/setuptools.py @@ -31,10 +31,10 @@ def _warn_on_old_setuptools(_version: str = setuptools.__version__) -> None: warnings.warn( RuntimeWarning( f""" -ERROR: setuptools=={_version} is used in combination with setuptools_scm>=8.x +ERROR: setuptools=={_version} is used in combination with setuptools-scm>=8.x Your build configuration is incomplete and previously worked by accident! -setuptools_scm requires setuptools>=61 +setuptools-scm requires setuptools>=61 Suggested workaround if applicable: - migrating from the deprecated setup_requires mechanism to pep517/518 @@ -113,7 +113,7 @@ def infer_version(dist: setuptools.Distribution) -> None: dist_name = read_dist_name_from_setup_cfg() if not os.path.isfile("pyproject.toml"): return - if dist_name == "setuptools_scm": + if dist_name == "setuptools-scm": return try: config = _config.Configuration.from_file(dist_name=dist_name) diff --git a/testing/test_git.py b/testing/test_git.py index f0f3504d..661dcb76 100644 --- a/testing/test_git.py +++ b/testing/test_git.py @@ -107,7 +107,7 @@ def test_git_gone(wd: WorkDir, monkeypatch: pytest.MonkeyPatch) -> None: assert wd.get_version(fallback_version="1.0") == "1.0" -@pytest.mark.issue("https://github.com/pypa/setuptools_scm/issues/298") +@pytest.mark.issue("https://github.com/pypa/setuptools-scm/issues/298") @pytest.mark.issue(403) def test_file_finder_no_history(wd: WorkDir, caplog: pytest.LogCaptureFixture) -> None: file_list = git_find_files(str(wd.cwd)) @@ -116,7 +116,7 @@ def test_file_finder_no_history(wd: WorkDir, caplog: pytest.LogCaptureFixture) - assert "listing git files failed - pretending there aren't any" in caplog.text -@pytest.mark.issue("https://github.com/pypa/setuptools_scm/issues/281") +@pytest.mark.issue("https://github.com/pypa/setuptools-scm/issues/281") def test_parse_call_order(wd: WorkDir) -> None: git.parse(str(wd.cwd), Configuration(), git.DEFAULT_DESCRIBE) @@ -153,7 +153,7 @@ def break_folder_permissions(path: Path) -> Generator[None, None, None]: sudo_devnull(["chgrp", "-R", str(original_stat.st_gid), path], check=True) -@pytest.mark.issue("https://github.com/pypa/setuptools_scm/issues/707") +@pytest.mark.issue("https://github.com/pypa/setuptools-scm/issues/707") def test_not_owner(wd: WorkDir) -> None: with break_folder_permissions(wd.cwd): assert git.parse(str(wd.cwd), Configuration()) @@ -401,7 +401,7 @@ def test_git_archive_run_from_subdirectory( assert setuptools_scm._file_finders.find_files(".") == [opj(".", "test1.txt")] -@pytest.mark.issue("https://github.com/pypa/setuptools_scm/issues/728") +@pytest.mark.issue("https://github.com/pypa/setuptools-scm/issues/728") def test_git_branch_names_correct(wd: WorkDir) -> None: wd.commit_testfile() wd("git checkout -b test/fun") @@ -419,7 +419,7 @@ def test_git_feature_branch_increments_major(wd: WorkDir) -> None: assert wd.get_version(version_scheme="python-simplified-semver").startswith("1.1.0") -@pytest.mark.issue("https://github.com/pypa/setuptools_scm/issues/303") +@pytest.mark.issue("https://github.com/pypa/setuptools-scm/issues/303") def test_not_matching_tags(wd: WorkDir) -> None: wd.commit_testfile() wd("git tag apache-arrow-0.11.1") @@ -432,7 +432,7 @@ def test_not_matching_tags(wd: WorkDir) -> None: ).startswith("0.11.2") -@pytest.mark.issue("https://github.com/pypa/setuptools_scm/issues/411") +@pytest.mark.issue("https://github.com/pypa/setuptools-scm/issues/411") def test_non_dotted_version(wd: WorkDir) -> None: wd.commit_testfile() wd("git tag apache-arrow-1") @@ -456,12 +456,12 @@ def test_non_dotted_tag_no_version_match(wd: WorkDir) -> None: assert wd.get_version().startswith("0.11.2.dev2") -@pytest.mark.issue("https://github.com/pypa/setuptools_scm/issues/381") +@pytest.mark.issue("https://github.com/pypa/setuptools-scm/issues/381") def test_gitdir(monkeypatch: pytest.MonkeyPatch, wd: WorkDir) -> None: """ """ wd.commit_testfile() normal = wd.get_version() - # git hooks set this and break subsequent setuptools_scm unless we clean + # git hooks set this and break subsequent setuptools-scm unless we clean monkeypatch.setenv("GIT_DIR", __file__) assert wd.get_version() == normal @@ -540,7 +540,7 @@ def signed_commit_wd(monkeypatch: pytest.MonkeyPatch, wd: WorkDir) -> WorkDir: return wd -@pytest.mark.issue("https://github.com/pypa/setuptools_scm/issues/548") +@pytest.mark.issue("https://github.com/pypa/setuptools-scm/issues/548") def test_git_getdate_signed_commit(signed_commit_wd: WorkDir) -> None: today = datetime.now(timezone.utc).date() signed_commit_wd.commit_testfile(signed=True) @@ -578,7 +578,7 @@ def test_git_archival_to_version(expected: str, from_data: dict[str, str]) -> No assert format_version(version) == expected -@pytest.mark.issue("https://github.com/pypa/setuptools_scm/issues/727") +@pytest.mark.issue("https://github.com/pypa/setuptools-scm/issues/727") def test_git_archival_node_missing_no_version() -> None: config = Configuration() version = archival_to_version({}, config=config) diff --git a/testing/test_mercurial.py b/testing/test_mercurial.py index c0ecb8cc..b51c3fd9 100644 --- a/testing/test_mercurial.py +++ b/testing/test_mercurial.py @@ -201,7 +201,7 @@ def test_version_bump_from_commit_including_hgtag_mods(wd: WorkDir) -> None: @pytest.mark.usefixtures("version_1_0") def test_latest_tag_detection(wd: WorkDir) -> None: """Tests that tags not containing a "." are ignored, the same as for git. - Note that will be superseded by the fix for pypa/setuptools_scm/issues/235 + Note that will be superseded by the fix for pypa/setuptools-scm/issues/235 """ wd('hg tag some-random-tag -u test -d "0 0"') assert wd.get_version() == "1.0.0" diff --git a/testing/test_version.py b/testing/test_version.py index 10a8f9a8..5233ef57 100644 --- a/testing/test_version.py +++ b/testing/test_version.py @@ -221,7 +221,7 @@ def test_tag_regex1(tag: str, expected: str) -> None: assert result.tag.public == expected -@pytest.mark.issue("https://github.com/pypa/setuptools_scm/issues/471") +@pytest.mark.issue("https://github.com/pypa/setuptools-scm/issues/471") def test_version_bump_bad() -> None: class YikesVersion: val: str From 5f7ba1564bf3530b756dcd0b29bf11d830c4f3ee Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 13 Aug 2024 15:14:34 -0400 Subject: [PATCH 3/3] Also update URL reference in pyproject. --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 0966b807..a55d0731 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -68,7 +68,7 @@ toml = [ ] [project.urls] documentation = "https://setuptools-scm.readthedocs.io/" -repository = "https://github.com/pypa/setuptools_scm/" +repository = "https://github.com/pypa/setuptools-scm/" [project.entry-points."distutils.setup_keywords"] use_scm_version = "setuptools_scm._integration.setuptools:version_keyword" [project.entry-points."pipx.run"]