From 341207baa62dda2a8c62cabb32e92171e5a0fe6d Mon Sep 17 00:00:00 2001 From: Stephen Rosen Date: Mon, 19 May 2025 11:14:55 -0400 Subject: [PATCH 01/27] Add a doc for supporting 8.1.x|8.2.0 This uses `get_metavar` as an example, demonstrates how to feature-detect based on `kwargs` containing `"ctx"`, and shows simplified usage. A note block indicates how this same strategy applies to other ``ParamType`` methods. Section naming is setup to support: - future documentation of other version transitions - documentation of other transitional methods for 8.1 vs 8.2 --- docs/index.rst | 1 + docs/support-multiple-versions.rst | 59 ++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 docs/support-multiple-versions.rst diff --git a/docs/index.rst b/docs/index.rst index 3c5c7ba33..bda2ee26d 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -80,6 +80,7 @@ How to Guides entry-points setuptools + support-multiple-versions Conceptual Guides ^^^^^^^^^^^^^^^^^^^ diff --git a/docs/support-multiple-versions.rst b/docs/support-multiple-versions.rst new file mode 100644 index 000000000..2eeb42400 --- /dev/null +++ b/docs/support-multiple-versions.rst @@ -0,0 +1,59 @@ +Supporting Multiple Versions +============================ + +Supporting multiple versions of ``click`` in a single codebase is usually +straightforward. Most features of ``click`` are stable across releases, and don't +require special handling. + +However, feature releases may deprecate and change APIs. Some features require special +handling to function correctly across a range of versions. + +click 8.1.x and 8.2.x +--------------------- + +This section will help you support click version 8.1 and 8.2 simultaneously. + + +``ParamType`` methods require ``ctx`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In 8.2, several methods of ``ParamType`` now accept a ``ctx: click.Context`` argument. +By way of example, this section covers ``ParamType.get_metavar``. + +To handle this while supporting 8.1, you can define a decorator: + +.. code-block:: python + + import functools + import typing as t + + C = t.TypeVar("C", bound=t.Callable[..., t.Any]) + + def shim_get_metavar(f: C) -> C: + @functools.wraps(f) + def wrapper(*args: t.Any, **kwargs: t.Any) -> t.Any: + if "ctx" not in kwargs: + kwargs["ctx"] = click.get_current_context(silent=True) + return f(*args, **kwargs) + + return wrapper # type: ignore[return-value] + +And then use the decorator on your ``ParamType`` to write a compatible ``get_metavar`` +method. +For example: + +.. code-block:: python + + import click + + class CommaDelimitedString(click.ParamType): + @shim_get_metavar + def get_metavar(self, param: click.Parameter, ctx: click.Context | None) -> str: + return "TEXT,TEXT,..." + + +.. note:: + + This methodology, creating a wrapper which does feature detection based on ``"ctx"`` + being in ``kwargs``, works for several other methods, e.g. + ``ParamType.get_missing_message``. From 55189e3ccf6677f3f350d4a1180c7c95142d79d7 Mon Sep 17 00:00:00 2001 From: David Lord Date: Tue, 20 May 2025 22:50:35 -0400 Subject: [PATCH 02/27] more compat docs, use markdown --- docs/support-multiple-versions.md | 62 ++++++++++++++++++++++++++++++ docs/support-multiple-versions.rst | 59 ---------------------------- 2 files changed, 62 insertions(+), 59 deletions(-) create mode 100644 docs/support-multiple-versions.md delete mode 100644 docs/support-multiple-versions.rst diff --git a/docs/support-multiple-versions.md b/docs/support-multiple-versions.md new file mode 100644 index 000000000..faa50ad13 --- /dev/null +++ b/docs/support-multiple-versions.md @@ -0,0 +1,62 @@ +# Supporting Multiple Versions + +If you are a library maintainer, you may want to support multiple versions of +Click. See the Pallets [version policy] for information about our version +numbers and support policy. + +[version policy]: https://palletsprojects.com/versions + +Most features of Click are stable across releases, and don't require special +handling. However, feature releases may deprecate and change APIs. Occasionally, +a change will require special handling. + +## Use Feature Detection + +Prefer using feature detection. Looking at the version can be tempting, but is +often more brittle or results in more complicated code. Try to use `if` or `try` +blocks to decide whether to use a new or old pattern. + +If you do need to look at the version, use {func}`importlib.metadata.version`, +the standardized way to get versions for any installed Python package. + +## Changes in 8.2 + +### `ParamType` methods require `ctx` + +In 8.2, several methods of `ParamType` now have a `ctx: click.Context` +argument. Because this changes the signature of the methods from 8.1, it's not +obvious how to support both when subclassing or calling. + +This example uses `ParamType.get_metavar`, and the same technique should be +applicable to other methods such as `get_missing_message`. + +Update your methods overrides to take the new `ctx` argument. Use the +following decorator to wrap each method. In 8.1, it will get the context where +possible and pass it using the 8.2 signature. + +```python +import functools +import typing as t +import click + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) + +def add_ctx_arg(f: F) -> F: + @functools.wraps(f) + def wrapper(*args: t.Any, **kwargs: t.Any) -> t.Any: + if "ctx" not in kwargs: + kwargs["ctx"] = click.get_current_context(silent=True) + + return f(*args, **kwargs) + + return wrapper # type: ignore[return-value] +``` + +Here's an example ``ParamType`` subclass which uses this: + +```python +class CommaDelimitedString(click.ParamType): + @add_ctx_arg + def get_metavar(self, param: click.Parameter, ctx: click.Context | None) -> str: + return "TEXT,TEXT,..." +``` diff --git a/docs/support-multiple-versions.rst b/docs/support-multiple-versions.rst deleted file mode 100644 index 2eeb42400..000000000 --- a/docs/support-multiple-versions.rst +++ /dev/null @@ -1,59 +0,0 @@ -Supporting Multiple Versions -============================ - -Supporting multiple versions of ``click`` in a single codebase is usually -straightforward. Most features of ``click`` are stable across releases, and don't -require special handling. - -However, feature releases may deprecate and change APIs. Some features require special -handling to function correctly across a range of versions. - -click 8.1.x and 8.2.x ---------------------- - -This section will help you support click version 8.1 and 8.2 simultaneously. - - -``ParamType`` methods require ``ctx`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -In 8.2, several methods of ``ParamType`` now accept a ``ctx: click.Context`` argument. -By way of example, this section covers ``ParamType.get_metavar``. - -To handle this while supporting 8.1, you can define a decorator: - -.. code-block:: python - - import functools - import typing as t - - C = t.TypeVar("C", bound=t.Callable[..., t.Any]) - - def shim_get_metavar(f: C) -> C: - @functools.wraps(f) - def wrapper(*args: t.Any, **kwargs: t.Any) -> t.Any: - if "ctx" not in kwargs: - kwargs["ctx"] = click.get_current_context(silent=True) - return f(*args, **kwargs) - - return wrapper # type: ignore[return-value] - -And then use the decorator on your ``ParamType`` to write a compatible ``get_metavar`` -method. -For example: - -.. code-block:: python - - import click - - class CommaDelimitedString(click.ParamType): - @shim_get_metavar - def get_metavar(self, param: click.Parameter, ctx: click.Context | None) -> str: - return "TEXT,TEXT,..." - - -.. note:: - - This methodology, creating a wrapper which does feature detection based on ``"ctx"`` - being in ``kwargs``, works for several other methods, e.g. - ``ParamType.get_missing_message``. From 9b24c115e14da68dc1ad8d73d9256db3a5ed6434 Mon Sep 17 00:00:00 2001 From: Bob Kerns <1154903+BobKerns@users.noreply.github.com> Date: Wed, 21 May 2025 15:47:37 -0700 Subject: [PATCH 03/27] Fixed the description of `is_flag=False, flag_value=value` The text had "only if", but the example shows that the behavior "if only" the flag is given, is to return the `flag_value`. --- docs/options.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/options.md b/docs/options.md index 99899f7d5..243069f3c 100644 --- a/docs/options.md +++ b/docs/options.md @@ -432,8 +432,8 @@ providing only the option's flag without a value will either show a prompt or use its `flag_value`. Setting `is_flag=False, flag_value=value` tells Click that the option -can still be passed a value, but only if the flag is given the -`flag_value`. +can still be passed a value, but if only the flag is given, the +value will be `flag_value`. ```{eval-rst} .. click:example:: From 950cc7e8db632e20f179b1c70fb26e247a9d1079 Mon Sep 17 00:00:00 2001 From: nudopnu Date: Fri, 23 May 2025 16:12:36 +0200 Subject: [PATCH 04/27] Fix import path --- docs/entry-points.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/entry-points.rst b/docs/entry-points.rst index bdfa95223..d5fce617d 100644 --- a/docs/entry-points.rst +++ b/docs/entry-points.rst @@ -55,7 +55,7 @@ Contents of ``pyproject.toml``: ] [project.scripts] - hello = "hello:cli" + hello = "hello.hello:cli" [build-system] requires = ["flit_core<4"] From 79ba04f1263c1d18ec98332d0e24dde0bd4220e2 Mon Sep 17 00:00:00 2001 From: denuoweb Date: Mon, 26 May 2025 00:57:11 -0700 Subject: [PATCH 05/27] change extension to .md --- docs/{why.rst => why.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/{why.rst => why.md} (100%) diff --git a/docs/why.rst b/docs/why.md similarity index 100% rename from docs/why.rst rename to docs/why.md From e57ba322957732326f65295834724b26604ee7a2 Mon Sep 17 00:00:00 2001 From: denuoweb Date: Mon, 26 May 2025 01:00:39 -0700 Subject: [PATCH 06/27] convert from reST to MyST --- docs/why.md | 236 ++++++++++++++++++++++------------------------------ 1 file changed, 98 insertions(+), 138 deletions(-) diff --git a/docs/why.md b/docs/why.md index 29f3d6c14..31fc546e2 100644 --- a/docs/why.md +++ b/docs/why.md @@ -1,146 +1,106 @@ -Why Click? -========== - -There are so many libraries out there for writing command line utilities; -why does Click exist? - -This question is easy to answer: because there is not a single command -line utility for Python out there which ticks the following boxes: - -* Is lazily composable without restrictions. -* Supports implementation of Unix/POSIX command line conventions. -* Supports loading values from environment variables out of the box. -* Support for prompting of custom values. -* Is fully nestable and composable. -* Supports file handling out of the box. -* Comes with useful common helpers (getting terminal dimensions, - ANSI colors, fetching direct keyboard input, screen clearing, - finding config paths, launching apps and editors, etc.). - -There are many alternatives to Click; the obvious ones are ``optparse`` -and ``argparse`` from the standard library. Have a look to see if something -else resonates with you. - -Click actually implements its own parsing of arguments and does not use -``optparse`` or ``argparse`` following the ``optparse`` parsing behavior. -The reason it's not based on ``argparse`` is that ``argparse`` does not -allow proper nesting of commands by design and has some deficiencies when -it comes to POSIX compliant argument handling. - -Click is designed to be fun and customizable but not overly flexible. -For instance, the customizability of help pages is constrained. This -constraint is intentional because Click promises multiple Click instances -will continue to function as intended when strung together. +# Why Click? + +There are so many libraries out there for writing command line utilities; why does Click exist? + +This question is easy to answer: because there is not a single command line utility for Python out there which ticks the +following boxes: + +- Is lazily composable without restrictions. +- Supports implementation of Unix/POSIX command line conventions. +- Supports loading values from environment variables out of the box. +- Support for prompting of custom values. +- Is fully nestable and composable. +- Supports file handling out of the box. +- Comes with useful common helpers (getting terminal dimensions, ANSI colors, fetching direct keyboard input, screen + clearing, finding config paths, launching apps and editors, etc.). + +There are many alternatives to Click; the obvious ones are `optparse` and `argparse` from the standard library. Have a +look to see if something else resonates with you. + +Click actually implements its own parsing of arguments and does not use `optparse` or `argparse` following the +`optparse` parsing behavior. The reason it's not based on `argparse` is that `argparse` does not allow proper nesting of +commands by design and has some deficiencies when it comes to POSIX compliant argument handling. + +Click is designed to be fun and customizable but not overly flexible. For instance, the customizability of help pages is +constrained. This constraint is intentional because Click promises multiple Click instances will continue to function as +intended when strung together. Too much customizability would break this promise. -Click was written to support the `Flask `_ -microframework ecosystem because no tool could provide it with the -functionality it needed. - -To get an understanding of what Click is all about, I strongly recommend -looking at the :ref:`complex-guide` chapter. - -Why not Argparse? ------------------ - -Click is internally based on ``optparse`` instead of ``argparse``. This -is an implementation detail that a user does not have to be concerned -with. Click is not based on ``argparse`` because it has some behaviors that -make handling arbitrary command line interfaces hard: - -* ``argparse`` has built-in behavior to guess if something is an - argument or an option. This becomes a problem when dealing with - incomplete command lines; the behaviour becomes unpredictable - without full knowledge of a command line. This goes against Click's - ambitions of dispatching to subparsers. -* ``argparse`` does not support disabling interspersed arguments. Without - this feature, it's not possible to safely implement Click's nested - parsing. - -Why not Docopt etc.? --------------------- - -Docopt, and many tools like it, are cool in how they work, but very few of -these tools deal with nesting of commands and composability in a way like -Click. To the best of the developer's knowledge, Click is the first -Python library that aims to create a level of composability of applications -that goes beyond what the system itself supports. - -Docopt, for instance, acts by parsing your help pages and then parsing -according to those rules. The side effect of this is that docopt is quite -rigid in how it handles the command line interface. The upside of docopt -is that it gives you strong control over your help page; the downside is -that due to this it cannot rewrap your output for the current terminal -width, and it makes translations hard. On top of that, docopt is restricted -to basic parsing. It does not handle argument dispatching and callback -invocation or types. This means there is a lot of code that needs to be -written in addition to the basic help page to handle the parsing results. - -Most of all, however, it makes composability hard. While docopt does -support dispatching to subcommands, it, for instance, does not directly -support any kind of automatic subcommand enumeration based on what's -available or it does not enforce subcommands to work in a consistent way. - -This is fine, but it's different from how Click wants to work. Click aims -to support fully composable command line user interfaces by doing the -following: - -- Click does not just parse, it also dispatches to the appropriate code. -- Click has a strong concept of an invocation context that allows - subcommands to respond to data from the parent command. -- Click has strong information available for all parameters and commands, - so it can generate unified help pages for the full CLI and - assist the user in converting the input data as necessary. -- Click has a strong understanding of what types are, and it can give the user - consistent error messages if something goes wrong. A subcommand - written by a different developer will not suddenly die with a - different error message because it's manually handled. -- Click has enough meta information available for its whole program - to evolve over time and improve the user experience without - forcing developers to adjust their programs. For instance, if Click - decides to change how help pages are formatted, all Click programs - will automatically benefit from this. - -The aim of Click is to make composable systems. Whereas, the aim of docopt -is to build the most beautiful and hand-crafted command line interfaces. -These two goals conflict with one another in subtle ways. Click -actively prevents people from implementing certain patterns in order to -achieve unified command line interfaces. For instance, as a developer, you -are given very little choice in formatting your help pages. - - -Why Hardcoded Behaviors? ------------------------- - -The other question is why Click goes away from optparse and hardcodes -certain behaviors instead of staying configurable. There are multiple -reasons for this. The biggest one is that too much configurability makes -it hard to achieve a consistent command line experience. - -The best example for this is optparse's ``callback`` functionality for -accepting an arbitrary number of arguments. Due to syntactical ambiguities -on the command line, there is no way to implement fully variadic arguments. -There are always tradeoffs that need to be made and in case of -``argparse`` these tradeoffs have been critical enough, that a system like +Click was written to support the [Flask](https://palletsprojects.com/p/flask/) microframework ecosystem because no tool +could provide it with the functionality it needed. + +To get an understanding of what Click is all about, I strongly recommend looking at the {ref}`complex-guide` chapter. + +## Why not Argparse? + +Click is internally based on `optparse` instead of `argparse`. This is an implementation detail that a user does not +have to be concerned with. Click is not based on `argparse` because it has some behaviors that make handling arbitrary +command line interfaces hard: + +- `argparse` has built-in behavior to guess if something is an argument or an option. This becomes a problem when + dealing with incomplete command lines; the behaviour becomes unpredictable without full knowledge of a command line. + This goes against Click's ambitions of dispatching to subparsers. +- `argparse` does not support disabling interspersed arguments. Without this feature, it's not possible to safely + implement Click's nested parsing. + +## Why not Docopt etc.? + +Docopt, and many tools like it, are cool in how they work, but very few of these tools deal with nesting of commands and +composability in a way like Click. To the best of the developer's knowledge, Click is the first Python library that aims +to create a level of composability of applications that goes beyond what the system itself supports. + +Docopt, for instance, acts by parsing your help pages and then parsing according to those rules. The side effect of this +is that docopt is quite rigid in how it handles the command line interface. The upside of docopt is that it gives you +strong control over your help page; the downside is that due to this it cannot rewrap your output for the current +terminal width, and it makes translations hard. On top of that, docopt is restricted to basic parsing. It does not +handle argument dispatching and callback invocation or types. This means there is a lot of code that needs to be written +in addition to the basic help page to handle the parsing results. + +Most of all, however, it makes composability hard. While docopt does support dispatching to subcommands, it, for +instance, does not directly support any kind of automatic subcommand enumeration based on what's available or it does +not enforce subcommands to work in a consistent way. + +This is fine, but it's different from how Click wants to work. Click aims to support fully composable command line user +interfaces by doing the following: + +- Click does not just parse, it also dispatches to the appropriate code. +- Click has a strong concept of an invocation context that allows subcommands to respond to data from the parent + command. +- Click has strong information available for all parameters and commands, so it can generate unified help pages for the + full CLI and assist the user in converting the input data as necessary. +- Click has a strong understanding of what types are, and it can give the user consistent error messages if something + goes wrong. A subcommand written by a different developer will not suddenly die with a different error message because + it's manually handled. +- Click has enough meta information available for its whole program to evolve over time and improve the user experience + without forcing developers to adjust their programs. For instance, if Click decides to change how help pages are + formatted, all Click programs will automatically benefit from this. + +The aim of Click is to make composable systems. Whereas, the aim of docopt is to build the most beautiful and +hand-crafted command line interfaces. These two goals conflict with one another in subtle ways. Click actively prevents +people from implementing certain patterns in order to achieve unified command line interfaces. For instance, as a +developer, you are given very little choice in formatting your help pages. + +## Why Hardcoded Behaviors? + +The other question is why Click goes away from optparse and hardcodes certain behaviors instead of staying configurable. +There are multiple reasons for this. The biggest one is that too much configurability makes it hard to achieve a +consistent command line experience. + +The best example for this is optparse's `callback` functionality for accepting an arbitrary number of arguments. Due to +syntactical ambiguities on the command line, there is no way to implement fully variadic arguments. There are always +tradeoffs that need to be made and in case of `argparse` these tradeoffs have been critical enough, that a system like Click cannot even be implemented on top of it. -In this particular case, Click attempts to stay with a handful of accepted -paradigms for building command line interfaces that can be well documented -and tested. - +In this particular case, Click attempts to stay with a handful of accepted paradigms for building command line +interfaces that can be well documented and tested. -Why No Auto Correction? ------------------------ +## Why No Auto Correction? -The question came up why Click does not auto correct parameters given that -even optparse and ``argparse`` support automatic expansion of long arguments. -The reason for this is that it's a liability for backwards compatibility. -If people start relying on automatically modified parameters and someone -adds a new parameter in the future, the script might stop working. These -kinds of problems are hard to find, so Click does not attempt to be magical -about this. +The question came up why Click does not auto correct parameters given that even optparse and `argparse` support +automatic expansion of long arguments. The reason for this is that it's a liability for backwards compatibility. If +people start relying on automatically modified parameters and someone adds a new parameter in the future, the script +might stop working. These kinds of problems are hard to find, so Click does not attempt to be magical about this. -This sort of behavior however can be implemented on a higher level to -support things such as explicit aliases. For more information see -:ref:`aliases`. +This sort of behavior however can be implemented on a higher level to support things such as explicit aliases. For more +information see {ref}`aliases`. From 5deb99b20d3ccc40471a2554ae0f8e7cb9307f03 Mon Sep 17 00:00:00 2001 From: denuoweb Date: Mon, 26 May 2025 01:28:33 -0700 Subject: [PATCH 07/27] chore: rerun CI checks From 7559bb8fb82f7bcb923bcb6b900c11472c6f227f Mon Sep 17 00:00:00 2001 From: Jean-Louis Fuchs Date: Sun, 25 May 2025 23:35:13 +0200 Subject: [PATCH 08/27] Expect alternate errors in test_file_surrogates() Not all file systems trigger a FileNotFoundError when encountering surrogates. Inside Podman the file system triggers an `OSError: [Errno 84] Illegal byte sequence: '\udcff'`. --- tests/test_types.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/test_types.py b/tests/test_types.py index c287e371c..75434f104 100644 --- a/tests/test_types.py +++ b/tests/test_types.py @@ -226,7 +226,12 @@ def no_access(*args, **kwargs): def test_file_surrogates(type, tmp_path): path = tmp_path / "\udcff" - with pytest.raises(click.BadParameter, match="�': No such file or directory"): + # - common case: �': No such file or directory + # - special case: Illegal byte sequence + # The spacial case is seen with rootless Podman. The root cause is most + # likely that the path is handled by a user-space program (FUSE). + match = r"(�': No such file or directory|Illegal byte sequence)" + with pytest.raises(click.BadParameter, match=match): type.convert(path, None, None) From 460af4cfee15072aee432b3c8c38ff58d9b0fe11 Mon Sep 17 00:00:00 2001 From: Edward G Date: Tue, 27 May 2025 01:11:54 -0700 Subject: [PATCH 09/27] Remove make files since use sphinx-build. --- docs/Makefile | 20 -------------------- docs/make.bat | 36 ------------------------------------ 2 files changed, 56 deletions(-) delete mode 100644 docs/Makefile delete mode 100644 docs/make.bat diff --git a/docs/Makefile b/docs/Makefile deleted file mode 100644 index 6e3c9b90d..000000000 --- a/docs/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -SPHINXPROJ = Jinja -SOURCEDIR = . -BUILDDIR = _build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/make.bat b/docs/make.bat deleted file mode 100644 index 147946324..000000000 --- a/docs/make.bat +++ /dev/null @@ -1,36 +0,0 @@ -@ECHO OFF - -pushd %~dp0 - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set SOURCEDIR=. -set BUILDDIR=_build -set SPHINXPROJ=Jinja - -if "%1" == "" goto help - -%SPHINXBUILD% >NUL 2>NUL -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ - exit /b 1 -) - -%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% -goto end - -:help -%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% - -:end -popd From c5734ce469e116e3433275ade7d4f97282f6f5b8 Mon Sep 17 00:00:00 2001 From: Edward G Date: Tue, 27 May 2025 01:27:10 -0700 Subject: [PATCH 10/27] Try altering readthedocs config to define different builds. --- .readthedocs.yaml | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index acbd83f90..e7e414783 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -1,10 +1,17 @@ version: 2 + build: os: ubuntu-24.04 tools: python: '3.13' - commands: - - asdf plugin add uv - - asdf install uv latest - - asdf global uv latest - - uv run --group docs sphinx-build -W -b dirhtml docs $READTHEDOCS_OUTPUT/html + jobs: + create_environment: + - echo "Preparing environment" + install: + - echo "Installing dependencies" + - asdf plugin add uv + - asdf install uv latest + - asdf global uv latest + build: + html: + - uv run --group docs sphinx-build -W -b dirhtml docs $READTHEDOCS_OUTPUT/html From b046a41d54ada7083d8e0abeb69c2648a4c89d24 Mon Sep 17 00:00:00 2001 From: Edward G Date: Tue, 27 May 2025 01:36:10 -0700 Subject: [PATCH 11/27] Minor tweaks to readthdocs builds. --- .readthedocs.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index e7e414783..961761bc0 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -1,12 +1,12 @@ version: 2 +# Do not specify sphinx key here to be in full control of build steps. +# https://docs.readthedocs.com/platform/stable/build-customization.html#extend-or-override-the-build-process build: os: ubuntu-24.04 tools: python: '3.13' jobs: - create_environment: - - echo "Preparing environment" install: - echo "Installing dependencies" - asdf plugin add uv From 9900533c120f871e5f79a2121277ef5c8f56f37c Mon Sep 17 00:00:00 2001 From: Edward G Date: Tue, 27 May 2025 01:48:22 -0700 Subject: [PATCH 12/27] Align index header levels. --- docs/index.rst | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index bda2ee26d..1c7e32c80 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -58,7 +58,7 @@ You can get the library directly from PyPI:: pip install click Documentation -------------- +============== .. toctree:: :maxdepth: 2 @@ -66,7 +66,7 @@ Documentation faqs Tutorials -^^^^^^^^^^^^^ +------------ .. toctree:: :maxdepth: 1 @@ -74,7 +74,7 @@ Tutorials virtualenv How to Guides -^^^^^^^^^^^^^ +--------------- .. toctree:: :maxdepth: 1 @@ -83,7 +83,7 @@ How to Guides support-multiple-versions Conceptual Guides -^^^^^^^^^^^^^^^^^^^ +------------------- .. toctree:: :maxdepth: 1 @@ -91,7 +91,7 @@ Conceptual Guides click-concepts General Reference -^^^^^^^^^^^^^^^^^^^ +-------------------- .. toctree:: :maxdepth: 1 @@ -117,7 +117,7 @@ General Reference wincmd API Reference -^^^^^^^^^^^^^^^ +------------------- .. toctree:: :maxdepth: 2 @@ -125,7 +125,7 @@ API Reference api About Project -------------------- +=============== * This documentation is structured according to `Diataxis `_ From 4e343841c35137a54c34c34f6399bf63ba892e5d Mon Sep 17 00:00:00 2001 From: Edward G Date: Tue, 27 May 2025 23:09:32 -0700 Subject: [PATCH 13/27] Convert parameters file to md. --- docs/parameters.md | 56 +++++++++++++++++++++++++++++++++++++++++++ docs/parameters.rst | 58 --------------------------------------------- 2 files changed, 56 insertions(+), 58 deletions(-) create mode 100644 docs/parameters.md delete mode 100644 docs/parameters.rst diff --git a/docs/parameters.md b/docs/parameters.md new file mode 100644 index 000000000..5e53e9d33 --- /dev/null +++ b/docs/parameters.md @@ -0,0 +1,56 @@ +(parameters)= + +# Parameters + +```{eval-rst} +.. currentmodule:: click +``` + +Click supports only two principle types of parameters for scripts (by design): options and arguments. + +## Options + +- Are optional. +- Recommended to use for everything except subcommands, urls, or files. +- Can take a fixed number of arguments. The default is 1. They may be specified multiple times using {ref}`multiple-options`. +- Are fully documented by the help page. +- Have automatic prompting for missing input. +- Can act as flags (boolean or otherwise). +- Can be pulled from environment variables. + +## Arguments + +- Are optional with in reason, but not entirely so. +- Recommended to use for subcommands, urls, or files. +- Can take an arbitrary number of arguments. +- Are not fully documented by the help page since they may be too specific to be automatically documented. For more see {ref}`documenting-arguments`. +- Can be pulled from environment variables but only explicitly named ones. For more see {ref}`environment-variables`. + +On each principle type you can specify {ref}`parameter-types`. Specifying these types helps Click add details to your help pages and help with the handling of those types. + +(parameter-names)= + +## Parameter Names + +Parameters (options and arguments) have a name that will be used as +the Python argument name when calling the decorated function with +values. + +In the example, the argument's name is `filename`. The name must match the python arg name. To provide a different name for use in help text, see {ref}`doc-meta-variables`. +The option's names are `-t` and `--times`. More names are available for options and are covered in {ref}`options`. + +```{eval-rst} +.. click:example:: + + @click.command() + @click.argument('filename') + @click.option('-t', '--times', type=int) + def multi_echo(filename, times): + """Print value filename multiple times.""" + for x in range(times): + click.echo(filename) + +.. click:run:: + + invoke(multi_echo, ['--times=3', 'index.txt'], prog_name='multi_echo') +``` diff --git a/docs/parameters.rst b/docs/parameters.rst deleted file mode 100644 index 9f7cc78e6..000000000 --- a/docs/parameters.rst +++ /dev/null @@ -1,58 +0,0 @@ -.. _parameters: - -Parameters -========== - -.. currentmodule:: click - -Click supports only two principle types of parameters for scripts (by design): options and arguments. - -Options ----------------- - -* Are optional. -* Recommended to use for everything except subcommands, urls, or files. -* Can take a fixed number of arguments. The default is 1. They may be specified multiple times using :ref:`multiple-options`. -* Are fully documented by the help page. -* Have automatic prompting for missing input. -* Can act as flags (boolean or otherwise). -* Can be pulled from environment variables. - -Arguments ----------------- - -* Are optional with in reason, but not entirely so. -* Recommended to use for subcommands, urls, or files. -* Can take an arbitrary number of arguments. -* Are not fully documented by the help page since they may be too specific to be automatically documented. For more see :ref:`documenting-arguments`. -* Can be pulled from environment variables but only explicitly named ones. For more see :ref:`environment-variables`. - -On each principle type you can specify :ref:`parameter-types`. Specifying these types helps Click add details to your help pages and help with the handling of those types. - -.. _parameter_names: - -Parameter Names ---------------- - -Parameters (options and arguments) have a name that will be used as -the Python argument name when calling the decorated function with -values. - -.. click:example:: - - @click.command() - @click.argument('filename') - @click.option('-t', '--times', type=int) - def multi_echo(filename, times): - """Print value filename multiple times.""" - for x in range(times): - click.echo(filename) - -In the above example the argument's name is ``filename``. The name must match the python arg name. To provide a different name for use in help text, see :ref:`doc-meta-variables`. -The option's names are ``-t`` and ``--times``. More names are available for options and are covered in :ref:`options`. - -And what it looks like when run: - -.. click:run:: - - invoke(multi_echo, ['--times=3', 'index.txt'], prog_name='multi_echo') From 36e99d1954e21f230c1599a2db92dd294288a8e2 Mon Sep 17 00:00:00 2001 From: denuoweb Date: Wed, 28 May 2025 01:10:48 -0700 Subject: [PATCH 14/27] change extension to .md --- docs/{wincmd.rst => wincmd.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/{wincmd.rst => wincmd.md} (100%) diff --git a/docs/wincmd.rst b/docs/wincmd.md similarity index 100% rename from docs/wincmd.rst rename to docs/wincmd.md From cb4656743d6311893e8a8ad1f98d016726133535 Mon Sep 17 00:00:00 2001 From: denuoweb Date: Wed, 28 May 2025 01:11:35 -0700 Subject: [PATCH 15/27] convert from reST to MyST --- docs/wincmd.md | 85 ++++++++++++++++++++------------------------------ 1 file changed, 34 insertions(+), 51 deletions(-) diff --git a/docs/wincmd.md b/docs/wincmd.md index 5727f2ff8..2029c6859 100644 --- a/docs/wincmd.md +++ b/docs/wincmd.md @@ -1,64 +1,47 @@ -Windows Console Notes -===================== +# Windows Console Notes -.. versionadded:: 6.0 +:::{versionadded} 6.0 +::: -Click emulates output streams on Windows to support unicode to the -Windows console through separate APIs and we perform different decoding of -parameters. +Click emulates output streams on Windows to support unicode to the Windows console through separate APIs and we perform +different decoding of parameters. Here is a brief overview of how this works and what it means to you. -Unicode Arguments ------------------ +## Unicode Arguments -Click internally is generally based on the concept that any argument can -come in as either byte string or unicode string and conversion is -performed to the type expected value as late as possible. This has some -advantages as it allows us to accept the data in the most appropriate form -for the operating system and Python version. +Click internally is generally based on the concept that any argument can come in as either byte string or unicode string +and conversion is performed to the type expected value as late as possible. This has some advantages as it allows us to +accept the data in the most appropriate form for the operating system and Python version. -This caused some problems on Windows where initially the wrong encoding -was used and garbage ended up in your input data. We not only fixed the -encoding part, but we also now extract unicode parameters from `sys.argv`. +This caused some problems on Windows where initially the wrong encoding was used and garbage ended up in your input +data. We not only fixed the encoding part, but we also now extract unicode parameters from `sys.argv`. -There is also another limitation with this: if `sys.argv` was modified -prior to invoking a click handler, we have to fall back to the regular -byte input in which case not all unicode values are available but only a -subset of the codepage used for parameters. +There is also another limitation with this: if `sys.argv` was modified prior to invoking a click handler, we have to +fall back to the regular byte input in which case not all unicode values are available but only a subset of the codepage +used for parameters. -Unicode Output and Input ------------------------- +## Unicode Output and Input -Unicode output and input on Windows is implemented through the concept of -a dispatching text stream. What this means is that when click first needs -a text output (or input) stream on windows it goes through a few checks to -figure out of a windows console is connected or not. If no Windows -console is present then the text output stream is returned as such and the -encoding for that stream is set to ``utf-8`` like on all platforms. +Unicode output and input on Windows is implemented through the concept of a dispatching text stream. What this means is +that when click first needs a text output (or input) stream on windows it goes through a few checks to figure out of a +windows console is connected or not. If no Windows console is present then the text output stream is returned as such +and the encoding for that stream is set to `utf-8` like on all platforms. -However if a console is connected the stream will instead be emulated and -use the cmd.exe unicode APIs to output text information. In this case the -stream will also use ``utf-16-le`` as internal encoding. However there is -some hackery going on that the underlying raw IO buffer is still bypassing -the unicode APIs and byte output through an indirection is still possible. +However if a console is connected the stream will instead be emulated and use the cmd.exe unicode APIs to output text +information. In this case the stream will also use `utf-16-le` as internal encoding. However there is some hackery going +on that the underlying raw IO buffer is still bypassing the unicode APIs and byte output through an indirection is still +possible. -* This unicode support is limited to ``click.echo``, ``click.prompt`` as - well as ``click.get_text_stream``. -* Depending on if unicode values or byte strings are passed the control - flow goes completely different places internally which can have some - odd artifacts if data partially ends up being buffered. Click - attempts to protect against that by manually always flushing but if - you are mixing and matching different string types to ``stdout`` or - ``stderr`` you will need to manually flush. -* The raw output stream is set to binary mode, which is a global - operation on Windows, so ``print`` calls will be affected. Prefer - ``click.echo`` over ``print``. -* On Windows 7 and below, there is a limitation where at most 64k - characters can be written in one call in binary mode. In this - situation, ``sys.stdout`` and ``sys.stderr`` are replaced with - wrappers that work around the limitation. +- This unicode support is limited to `click.echo`, `click.prompt` as well as `click.get_text_stream`. +- Depending on if unicode values or byte strings are passed the control flow goes completely different places internally + which can have some odd artifacts if data partially ends up being buffered. Click attempts to protect against that by + manually always flushing but if you are mixing and matching different string types to `stdout` or `stderr` you will + need to manually flush. +- The raw output stream is set to binary mode, which is a global operation on Windows, so `print` calls will be + affected. Prefer `click.echo` over `print`. +- On Windows 7 and below, there is a limitation where at most 64k characters can be written in one call in binary mode. + In this situation, `sys.stdout` and `sys.stderr` are replaced with wrappers that work around the limitation. -Another important thing to note is that the Windows console's default -fonts do not support a lot of characters which means that you are mostly -limited to international letters but no emojis or special characters. +Another important thing to note is that the Windows console's default fonts do not support a lot of characters which +means that you are mostly limited to international letters but no emojis or special characters. From 03e957ea70e15e7ffca464c016634b0ed04221d8 Mon Sep 17 00:00:00 2001 From: denuoweb Date: Wed, 28 May 2025 01:52:13 -0700 Subject: [PATCH 16/27] change extension to .md --- docs/{virtualenv.rst => virtualenv.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/{virtualenv.rst => virtualenv.md} (100%) diff --git a/docs/virtualenv.rst b/docs/virtualenv.md similarity index 100% rename from docs/virtualenv.rst rename to docs/virtualenv.md From 1b29d5c1d0142295c5c3e244a8bc4c7fe44d9dea Mon Sep 17 00:00:00 2001 From: denuoweb Date: Wed, 28 May 2025 01:54:50 -0700 Subject: [PATCH 17/27] convert from reST to MyST --- docs/virtualenv.md | 46 +++++++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/docs/virtualenv.md b/docs/virtualenv.md index 2a565c102..20cbe7342 100644 --- a/docs/virtualenv.md +++ b/docs/virtualenv.md @@ -1,29 +1,29 @@ -.. _virtualenv-heading: +(virtualenv-heading)= -Virtualenv -========================= +# Virtualenv -Why Use Virtualenv? -------------------------- +## Why Use Virtualenv? -You should use `Virtualenv `_ because: +You should use [Virtualenv](https://virtualenv.pypa.io/en/latest/) because: -* It allows you to install multiple versions of the same dependency. +- It allows you to install multiple versions of the same dependency. +- If you have an operating system version of Python, it prevents you from changing its dependencies and potentially + messing up your os. -* If you have an operating system version of Python, it prevents you from changing its dependencies and potentially messing up your os. +## How to Use Virtualenv -How to Use Virtualenv ------------------------------ +Create your project folder, then a virtualenv within it: -Create your project folder, then a virtualenv within it:: +```console +$ mkdir myproject +$ cd myproject +$ python3 -m venv .venv +``` - $ mkdir myproject - $ cd myproject - $ python3 -m venv .venv +Now, whenever you want to work on a project, you only have to activate the corresponding environment. -Now, whenever you want to work on a project, you only have to activate the -corresponding environment. +```{eval-rst} .. tabs:: .. group-tab:: OSX/Linux @@ -39,16 +39,20 @@ corresponding environment. > .venv\scripts\activate (venv) > - +``` You are now using your virtualenv (notice how the prompt of your shell has changed to show the active environment). -To install packages in the virtual environment:: +To install packages in the virtual environment: - $ pip install click +```console +$ pip install click +``` -And if you want to stop using the virtualenv, use the following command:: +And if you want to stop using the virtualenv, use the following command: - $ deactivate +```console +$ deactivate +``` After doing this, the prompt of your shell should be as familiar as before. From 7a07426828dd964653d034695f0dd3abd029a57f Mon Sep 17 00:00:00 2001 From: Edward G Date: Wed, 28 May 2025 23:49:44 -0700 Subject: [PATCH 18/27] Fix anchor for meta variable --- docs/documentation.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/documentation.rst b/docs/documentation.rst index c0e7f8e0c..b60e5b3de 100644 --- a/docs/documentation.rst +++ b/docs/documentation.rst @@ -199,7 +199,7 @@ To change the rendering maximum width, pass ``max_content_width`` when calling t cli(max_content_width=120) -.. _doc-meta-variables: + Truncating Help Texts --------------------- @@ -222,6 +222,7 @@ Example: invoke(cli, args=['--help']) +.. _doc-meta-variables: Placeholder / Meta Variable ----------------------------- From 3aebc6e5314f8ef03f31a56f605f92b0c012f4b8 Mon Sep 17 00:00:00 2001 From: Edward G Date: Thu, 29 May 2025 00:01:22 -0700 Subject: [PATCH 19/27] move current module directive to md. --- docs/parameters.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/parameters.md b/docs/parameters.md index 5e53e9d33..ae908f9eb 100644 --- a/docs/parameters.md +++ b/docs/parameters.md @@ -2,8 +2,7 @@ # Parameters -```{eval-rst} -.. currentmodule:: click +```{currentmodule} click ``` Click supports only two principle types of parameters for scripts (by design): options and arguments. From 799413a0e6e73a109d5d9f361fcb3f94c0dddffc Mon Sep 17 00:00:00 2001 From: Edward G Date: Fri, 30 May 2025 01:28:00 -0700 Subject: [PATCH 20/27] Fix version added and version changed in options docs. --- docs/options.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/options.md b/docs/options.md index 99899f7d5..450a746cf 100644 --- a/docs/options.md +++ b/docs/options.md @@ -152,8 +152,8 @@ To make an option take multiple values, pass in `nargs`. Note only a fixed numbe ## Multi Value Options as Tuples -:::{versionadded} 4.0 -::: +```{versionadded} 4.0 +``` As you can see that by using `nargs` set to a specific number each item in the resulting tuple is of the same type. This might not be what you want. @@ -289,8 +289,8 @@ If a forward slash(`/`) is contained in your option name already, you can split click.echo(f"debug={debug}") ``` -:::{versionchanged} 6.0 -::: +```{versionchanged} 6.0 +``` If you want to define an alias for the second option only, then you will need to use leading whitespace to disambiguate the format string. From 60b9c0e88f299dfdbe395e168f3fa146f494d50e Mon Sep 17 00:00:00 2001 From: denuoweb Date: Sat, 31 May 2025 00:07:44 -0700 Subject: [PATCH 21/27] switch from colon fence to backtick fence --- docs/wincmd.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/wincmd.md b/docs/wincmd.md index 2029c6859..0579a3731 100644 --- a/docs/wincmd.md +++ b/docs/wincmd.md @@ -1,7 +1,7 @@ # Windows Console Notes -:::{versionadded} 6.0 -::: +```{versionadded} 6.0 +``` Click emulates output streams on Windows to support unicode to the Windows console through separate APIs and we perform different decoding of parameters. From d1a80aa95cc207f50da1c438af742b7edad02267 Mon Sep 17 00:00:00 2001 From: David Lord Date: Sun, 8 Jun 2025 11:14:49 -0700 Subject: [PATCH 22/27] update dev dependencies --- .github/workflows/pre-commit.yaml | 2 +- .github/workflows/publish.yaml | 2 +- .github/workflows/tests.yaml | 4 +- .pre-commit-config.yaml | 4 +- src/click/_termui_impl.py | 2 +- src/click/utils.py | 2 +- uv.lock | 199 ++++++++++++++++-------------- 7 files changed, 113 insertions(+), 102 deletions(-) diff --git a/.github/workflows/pre-commit.yaml b/.github/workflows/pre-commit.yaml index 4c27fb447..eda8c518a 100644 --- a/.github/workflows/pre-commit.yaml +++ b/.github/workflows/pre-commit.yaml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: astral-sh/setup-uv@6b9c6063abd6010835644d4c2e1bef4cf5cd0fca # v6.0.1 + - uses: astral-sh/setup-uv@f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb # v6.1.0 with: enable-cache: true prune-cache: false diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index 04082015f..46a0c3a30 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -9,7 +9,7 @@ jobs: hash: ${{ steps.hash.outputs.hash }} steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: astral-sh/setup-uv@6b9c6063abd6010835644d4c2e1bef4cf5cd0fca # v6.0.1 + - uses: astral-sh/setup-uv@f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb # v6.1.0 with: enable-cache: true prune-cache: false diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 1ffaae366..db947befe 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -22,7 +22,7 @@ jobs: - {name: PyPy, python: 'pypy-3.11', tox: pypy3.11} steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: astral-sh/setup-uv@6b9c6063abd6010835644d4c2e1bef4cf5cd0fca # v6.0.1 + - uses: astral-sh/setup-uv@f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb # v6.1.0 with: enable-cache: true prune-cache: false @@ -34,7 +34,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: astral-sh/setup-uv@6b9c6063abd6010835644d4c2e1bef4cf5cd0fca # v6.0.1 + - uses: astral-sh/setup-uv@f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb # v6.1.0 with: enable-cache: true prune-cache: false diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 370866300..bf712b269 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,11 +1,11 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: 24e02b24b8ab2b7c76225602d13fa60e12d114e6 # frozen: v0.11.9 + rev: 9aeda5d1f4bbd212c557da1ea78eca9e8c829e19 # frozen: v0.11.13 hooks: - id: ruff - id: ruff-format - repo: https://github.com/astral-sh/uv-pre-commit - rev: 14ac15b122e538e407d036ff45e3895b7cf4a2bf # frozen: 0.7.3 + rev: a621b109bab2e7e832d98c88fd3e83399f4e6657 # frozen: 0.7.12 hooks: - id: uv-lock - repo: https://github.com/pre-commit/pre-commit-hooks diff --git a/src/click/_termui_impl.py b/src/click/_termui_impl.py index 51fd9bf35..b8f23a55e 100644 --- a/src/click/_termui_impl.py +++ b/src/click/_termui_impl.py @@ -616,7 +616,7 @@ def edit(self, text: str | bytes | bytearray | None) -> str | bytes | None: import tempfile if text is None: - data = b"" + data: bytes | bytearray = b"" elif isinstance(text, (bytes, bytearray)): data = text else: diff --git a/src/click/utils.py b/src/click/utils.py index ab2fe5889..beae26f76 100644 --- a/src/click/utils.py +++ b/src/click/utils.py @@ -277,7 +277,7 @@ def echo( # Convert non bytes/text into the native string type. if message is not None and not isinstance(message, (str, bytes, bytearray)): - out: str | bytes | None = str(message) + out: str | bytes | bytearray | None = str(message) else: out = message diff --git a/uv.lock b/uv.lock index cfe09dedd..455b15e31 100644 --- a/uv.lock +++ b/uv.lock @@ -42,11 +42,11 @@ wheels = [ [[package]] name = "cachetools" -version = "5.5.2" +version = "6.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6c/81/3747dad6b14fa2cf53fcf10548cf5aea6913e96fab41a3c198676f8948a5/cachetools-5.5.2.tar.gz", hash = "sha256:1a661caa9175d26759571b2e19580f9d6393969e5dfca11fdb1f947a23e640d4", size = 28380, upload-time = "2025-02-20T21:01:19.524Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c0/b0/f539a1ddff36644c28a61490056e5bae43bd7386d9f9c69beae2d7e7d6d1/cachetools-6.0.0.tar.gz", hash = "sha256:f225782b84438f828328fc2ad74346522f27e5b1440f4e9fd18b20ebfd1aa2cf", size = 30160, upload-time = "2025-05-23T20:01:13.076Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/72/76/20fa66124dbe6be5cafeb312ece67de6b61dd91a0247d1ea13db4ebb33c2/cachetools-5.5.2-py3-none-any.whl", hash = "sha256:d26a22bcc62eb95c3beabd9f1ee5e820d3d2704fe2967cbe350e20c8ffcd3f0a", size = 10080, upload-time = "2025-02-20T21:01:16.647Z" }, + { url = "https://files.pythonhosted.org/packages/6a/c3/8bb087c903c95a570015ce84e0c23ae1d79f528c349cbc141b5c4e250293/cachetools-6.0.0-py3-none-any.whl", hash = "sha256:82e73ba88f7b30228b5507dce1a1f878498fc669d972aef2dde4f3a3c24f103e", size = 10964, upload-time = "2025-05-23T20:01:11.323Z" }, ] [[package]] @@ -307,11 +307,11 @@ wheels = [ [[package]] name = "identify" -version = "2.6.10" +version = "2.6.12" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0c/83/b6ea0334e2e7327084a46aaaf71f2146fc061a192d6518c0d020120cd0aa/identify-2.6.10.tar.gz", hash = "sha256:45e92fd704f3da71cc3880036633f48b4b7265fd4de2b57627cb157216eb7eb8", size = 99201, upload-time = "2025-04-19T15:10:38.32Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/88/d193a27416618628a5eea64e3223acd800b40749a96ffb322a9b55a49ed1/identify-2.6.12.tar.gz", hash = "sha256:d8de45749f1efb108badef65ee8386f0f7bb19a7f26185f74de6367bffbaf0e6", size = 99254, upload-time = "2025-05-23T20:37:53.3Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2b/d3/85feeba1d097b81a44bcffa6a0beab7b4dfffe78e82fc54978d3ac380736/identify-2.6.10-py2.py3-none-any.whl", hash = "sha256:5f34248f54136beed1a7ba6a6b5c4b6cf21ff495aac7c359e1ef831ae3b8ab25", size = 99101, upload-time = "2025-04-19T15:10:36.701Z" }, + { url = "https://files.pythonhosted.org/packages/7a/cd/18f8da995b658420625f7ef13f037be53ae04ec5ad33f9b718240dcfd48c/identify-2.6.12-py2.py3-none-any.whl", hash = "sha256:ad9672d5a72e0d2ff7c5c8809b62dfa60458626352fb0eb7b55e69bdc45334a2", size = 99145, upload-time = "2025-05-23T20:37:51.495Z" }, ] [[package]] @@ -446,40 +446,41 @@ wheels = [ [[package]] name = "mypy" -version = "1.15.0" +version = "1.16.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mypy-extensions" }, + { name = "pathspec" }, { name = "tomli", marker = "python_full_version < '3.11'" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ce/43/d5e49a86afa64bd3839ea0d5b9c7103487007d728e1293f52525d6d5486a/mypy-1.15.0.tar.gz", hash = "sha256:404534629d51d3efea5c800ee7c42b72a6554d6c400e6a79eafe15d11341fd43", size = 3239717, upload-time = "2025-02-05T03:50:34.655Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/68/f8/65a7ce8d0e09b6329ad0c8d40330d100ea343bd4dd04c4f8ae26462d0a17/mypy-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:979e4e1a006511dacf628e36fadfecbcc0160a8af6ca7dad2f5025529e082c13", size = 10738433, upload-time = "2025-02-05T03:49:29.145Z" }, - { url = "https://files.pythonhosted.org/packages/b4/95/9c0ecb8eacfe048583706249439ff52105b3f552ea9c4024166c03224270/mypy-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c4bb0e1bd29f7d34efcccd71cf733580191e9a264a2202b0239da95984c5b559", size = 9861472, upload-time = "2025-02-05T03:49:16.986Z" }, - { url = "https://files.pythonhosted.org/packages/84/09/9ec95e982e282e20c0d5407bc65031dfd0f0f8ecc66b69538296e06fcbee/mypy-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:be68172e9fd9ad8fb876c6389f16d1c1b5f100ffa779f77b1fb2176fcc9ab95b", size = 11611424, upload-time = "2025-02-05T03:49:46.908Z" }, - { url = "https://files.pythonhosted.org/packages/78/13/f7d14e55865036a1e6a0a69580c240f43bc1f37407fe9235c0d4ef25ffb0/mypy-1.15.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c7be1e46525adfa0d97681432ee9fcd61a3964c2446795714699a998d193f1a3", size = 12365450, upload-time = "2025-02-05T03:50:05.89Z" }, - { url = "https://files.pythonhosted.org/packages/48/e1/301a73852d40c241e915ac6d7bcd7fedd47d519246db2d7b86b9d7e7a0cb/mypy-1.15.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2e2c2e6d3593f6451b18588848e66260ff62ccca522dd231cd4dd59b0160668b", size = 12551765, upload-time = "2025-02-05T03:49:33.56Z" }, - { url = "https://files.pythonhosted.org/packages/77/ba/c37bc323ae5fe7f3f15a28e06ab012cd0b7552886118943e90b15af31195/mypy-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:6983aae8b2f653e098edb77f893f7b6aca69f6cffb19b2cc7443f23cce5f4828", size = 9274701, upload-time = "2025-02-05T03:49:38.981Z" }, - { url = "https://files.pythonhosted.org/packages/03/bc/f6339726c627bd7ca1ce0fa56c9ae2d0144604a319e0e339bdadafbbb599/mypy-1.15.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2922d42e16d6de288022e5ca321cd0618b238cfc5570e0263e5ba0a77dbef56f", size = 10662338, upload-time = "2025-02-05T03:50:17.287Z" }, - { url = "https://files.pythonhosted.org/packages/e2/90/8dcf506ca1a09b0d17555cc00cd69aee402c203911410136cd716559efe7/mypy-1.15.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2ee2d57e01a7c35de00f4634ba1bbf015185b219e4dc5909e281016df43f5ee5", size = 9787540, upload-time = "2025-02-05T03:49:51.21Z" }, - { url = "https://files.pythonhosted.org/packages/05/05/a10f9479681e5da09ef2f9426f650d7b550d4bafbef683b69aad1ba87457/mypy-1.15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:973500e0774b85d9689715feeffcc980193086551110fd678ebe1f4342fb7c5e", size = 11538051, upload-time = "2025-02-05T03:50:20.885Z" }, - { url = "https://files.pythonhosted.org/packages/e9/9a/1f7d18b30edd57441a6411fcbc0c6869448d1a4bacbaee60656ac0fc29c8/mypy-1.15.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a95fb17c13e29d2d5195869262f8125dfdb5c134dc8d9a9d0aecf7525b10c2c", size = 12286751, upload-time = "2025-02-05T03:49:42.408Z" }, - { url = "https://files.pythonhosted.org/packages/72/af/19ff499b6f1dafcaf56f9881f7a965ac2f474f69f6f618b5175b044299f5/mypy-1.15.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1905f494bfd7d85a23a88c5d97840888a7bd516545fc5aaedff0267e0bb54e2f", size = 12421783, upload-time = "2025-02-05T03:49:07.707Z" }, - { url = "https://files.pythonhosted.org/packages/96/39/11b57431a1f686c1aed54bf794870efe0f6aeca11aca281a0bd87a5ad42c/mypy-1.15.0-cp311-cp311-win_amd64.whl", hash = "sha256:c9817fa23833ff189db061e6d2eff49b2f3b6ed9856b4a0a73046e41932d744f", size = 9265618, upload-time = "2025-02-05T03:49:54.581Z" }, - { url = "https://files.pythonhosted.org/packages/98/3a/03c74331c5eb8bd025734e04c9840532226775c47a2c39b56a0c8d4f128d/mypy-1.15.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:aea39e0583d05124836ea645f412e88a5c7d0fd77a6d694b60d9b6b2d9f184fd", size = 10793981, upload-time = "2025-02-05T03:50:28.25Z" }, - { url = "https://files.pythonhosted.org/packages/f0/1a/41759b18f2cfd568848a37c89030aeb03534411eef981df621d8fad08a1d/mypy-1.15.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2f2147ab812b75e5b5499b01ade1f4a81489a147c01585cda36019102538615f", size = 9749175, upload-time = "2025-02-05T03:50:13.411Z" }, - { url = "https://files.pythonhosted.org/packages/12/7e/873481abf1ef112c582db832740f4c11b2bfa510e829d6da29b0ab8c3f9c/mypy-1.15.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ce436f4c6d218a070048ed6a44c0bbb10cd2cc5e272b29e7845f6a2f57ee4464", size = 11455675, upload-time = "2025-02-05T03:50:31.421Z" }, - { url = "https://files.pythonhosted.org/packages/b3/d0/92ae4cde706923a2d3f2d6c39629134063ff64b9dedca9c1388363da072d/mypy-1.15.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8023ff13985661b50a5928fc7a5ca15f3d1affb41e5f0a9952cb68ef090b31ee", size = 12410020, upload-time = "2025-02-05T03:48:48.705Z" }, - { url = "https://files.pythonhosted.org/packages/46/8b/df49974b337cce35f828ba6fda228152d6db45fed4c86ba56ffe442434fd/mypy-1.15.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1124a18bc11a6a62887e3e137f37f53fbae476dc36c185d549d4f837a2a6a14e", size = 12498582, upload-time = "2025-02-05T03:49:03.628Z" }, - { url = "https://files.pythonhosted.org/packages/13/50/da5203fcf6c53044a0b699939f31075c45ae8a4cadf538a9069b165c1050/mypy-1.15.0-cp312-cp312-win_amd64.whl", hash = "sha256:171a9ca9a40cd1843abeca0e405bc1940cd9b305eaeea2dda769ba096932bb22", size = 9366614, upload-time = "2025-02-05T03:50:00.313Z" }, - { url = "https://files.pythonhosted.org/packages/6a/9b/fd2e05d6ffff24d912f150b87db9e364fa8282045c875654ce7e32fffa66/mypy-1.15.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:93faf3fdb04768d44bf28693293f3904bbb555d076b781ad2530214ee53e3445", size = 10788592, upload-time = "2025-02-05T03:48:55.789Z" }, - { url = "https://files.pythonhosted.org/packages/74/37/b246d711c28a03ead1fd906bbc7106659aed7c089d55fe40dd58db812628/mypy-1.15.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:811aeccadfb730024c5d3e326b2fbe9249bb7413553f15499a4050f7c30e801d", size = 9753611, upload-time = "2025-02-05T03:48:44.581Z" }, - { url = "https://files.pythonhosted.org/packages/a6/ac/395808a92e10cfdac8003c3de9a2ab6dc7cde6c0d2a4df3df1b815ffd067/mypy-1.15.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:98b7b9b9aedb65fe628c62a6dc57f6d5088ef2dfca37903a7d9ee374d03acca5", size = 11438443, upload-time = "2025-02-05T03:49:25.514Z" }, - { url = "https://files.pythonhosted.org/packages/d2/8b/801aa06445d2de3895f59e476f38f3f8d610ef5d6908245f07d002676cbf/mypy-1.15.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c43a7682e24b4f576d93072216bf56eeff70d9140241f9edec0c104d0c515036", size = 12402541, upload-time = "2025-02-05T03:49:57.623Z" }, - { url = "https://files.pythonhosted.org/packages/c7/67/5a4268782eb77344cc613a4cf23540928e41f018a9a1ec4c6882baf20ab8/mypy-1.15.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:baefc32840a9f00babd83251560e0ae1573e2f9d1b067719479bfb0e987c6357", size = 12494348, upload-time = "2025-02-05T03:48:52.361Z" }, - { url = "https://files.pythonhosted.org/packages/83/3e/57bb447f7bbbfaabf1712d96f9df142624a386d98fb026a761532526057e/mypy-1.15.0-cp313-cp313-win_amd64.whl", hash = "sha256:b9378e2c00146c44793c98b8d5a61039a048e31f429fb0eb546d93f4b000bedf", size = 9373648, upload-time = "2025-02-05T03:49:11.395Z" }, - { url = "https://files.pythonhosted.org/packages/09/4e/a7d65c7322c510de2c409ff3828b03354a7c43f5a8ed458a7a131b41c7b9/mypy-1.15.0-py3-none-any.whl", hash = "sha256:5469affef548bd1895d86d3bf10ce2b44e33d86923c29e4d675b3e323437ea3e", size = 2221777, upload-time = "2025-02-05T03:50:08.348Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/d4/38/13c2f1abae94d5ea0354e146b95a1be9b2137a0d506728e0da037c4276f6/mypy-1.16.0.tar.gz", hash = "sha256:84b94283f817e2aa6350a14b4a8fb2a35a53c286f97c9d30f53b63620e7af8ab", size = 3323139, upload-time = "2025-05-29T13:46:12.532Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/64/5e/a0485f0608a3d67029d3d73cec209278b025e3493a3acfda3ef3a88540fd/mypy-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7909541fef256527e5ee9c0a7e2aeed78b6cda72ba44298d1334fe7881b05c5c", size = 10967416, upload-time = "2025-05-29T13:34:17.783Z" }, + { url = "https://files.pythonhosted.org/packages/4b/53/5837c221f74c0d53a4bfc3003296f8179c3a2a7f336d7de7bbafbe96b688/mypy-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e71d6f0090c2256c713ed3d52711d01859c82608b5d68d4fa01a3fe30df95571", size = 10087654, upload-time = "2025-05-29T13:32:37.878Z" }, + { url = "https://files.pythonhosted.org/packages/29/59/5fd2400352c3093bed4c09017fe671d26bc5bb7e6ef2d4bf85f2a2488104/mypy-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:936ccfdd749af4766be824268bfe22d1db9eb2f34a3ea1d00ffbe5b5265f5491", size = 11875192, upload-time = "2025-05-29T13:34:54.281Z" }, + { url = "https://files.pythonhosted.org/packages/ad/3e/4bfec74663a64c2012f3e278dbc29ffe82b121bc551758590d1b6449ec0c/mypy-1.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4086883a73166631307fdd330c4a9080ce24913d4f4c5ec596c601b3a4bdd777", size = 12612939, upload-time = "2025-05-29T13:33:14.766Z" }, + { url = "https://files.pythonhosted.org/packages/88/1f/fecbe3dcba4bf2ca34c26ca016383a9676711907f8db4da8354925cbb08f/mypy-1.16.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:feec38097f71797da0231997e0de3a58108c51845399669ebc532c815f93866b", size = 12874719, upload-time = "2025-05-29T13:21:52.09Z" }, + { url = "https://files.pythonhosted.org/packages/f3/51/c2d280601cd816c43dfa512a759270d5a5ef638d7ac9bea9134c8305a12f/mypy-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:09a8da6a0ee9a9770b8ff61b39c0bb07971cda90e7297f4213741b48a0cc8d93", size = 9487053, upload-time = "2025-05-29T13:33:29.797Z" }, + { url = "https://files.pythonhosted.org/packages/24/c4/ff2f79db7075c274fe85b5fff8797d29c6b61b8854c39e3b7feb556aa377/mypy-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9f826aaa7ff8443bac6a494cf743f591488ea940dd360e7dd330e30dd772a5ab", size = 10884498, upload-time = "2025-05-29T13:18:54.066Z" }, + { url = "https://files.pythonhosted.org/packages/02/07/12198e83006235f10f6a7808917376b5d6240a2fd5dce740fe5d2ebf3247/mypy-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:82d056e6faa508501af333a6af192c700b33e15865bda49611e3d7d8358ebea2", size = 10011755, upload-time = "2025-05-29T13:34:00.851Z" }, + { url = "https://files.pythonhosted.org/packages/f1/9b/5fd5801a72b5d6fb6ec0105ea1d0e01ab2d4971893076e558d4b6d6b5f80/mypy-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:089bedc02307c2548eb51f426e085546db1fa7dd87fbb7c9fa561575cf6eb1ff", size = 11800138, upload-time = "2025-05-29T13:32:55.082Z" }, + { url = "https://files.pythonhosted.org/packages/2e/81/a117441ea5dfc3746431e51d78a4aca569c677aa225bca2cc05a7c239b61/mypy-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6a2322896003ba66bbd1318c10d3afdfe24e78ef12ea10e2acd985e9d684a666", size = 12533156, upload-time = "2025-05-29T13:19:12.963Z" }, + { url = "https://files.pythonhosted.org/packages/3f/38/88ec57c6c86014d3f06251e00f397b5a7daa6888884d0abf187e4f5f587f/mypy-1.16.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:021a68568082c5b36e977d54e8f1de978baf401a33884ffcea09bd8e88a98f4c", size = 12742426, upload-time = "2025-05-29T13:20:22.72Z" }, + { url = "https://files.pythonhosted.org/packages/bd/53/7e9d528433d56e6f6f77ccf24af6ce570986c2d98a5839e4c2009ef47283/mypy-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:54066fed302d83bf5128632d05b4ec68412e1f03ef2c300434057d66866cea4b", size = 9478319, upload-time = "2025-05-29T13:21:17.582Z" }, + { url = "https://files.pythonhosted.org/packages/70/cf/158e5055e60ca2be23aec54a3010f89dcffd788732634b344fc9cb1e85a0/mypy-1.16.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c5436d11e89a3ad16ce8afe752f0f373ae9620841c50883dc96f8b8805620b13", size = 11062927, upload-time = "2025-05-29T13:35:52.328Z" }, + { url = "https://files.pythonhosted.org/packages/94/34/cfff7a56be1609f5d10ef386342ce3494158e4d506516890142007e6472c/mypy-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f2622af30bf01d8fc36466231bdd203d120d7a599a6d88fb22bdcb9dbff84090", size = 10083082, upload-time = "2025-05-29T13:35:33.378Z" }, + { url = "https://files.pythonhosted.org/packages/b3/7f/7242062ec6288c33d8ad89574df87c3903d394870e5e6ba1699317a65075/mypy-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d045d33c284e10a038f5e29faca055b90eee87da3fc63b8889085744ebabb5a1", size = 11828306, upload-time = "2025-05-29T13:21:02.164Z" }, + { url = "https://files.pythonhosted.org/packages/6f/5f/b392f7b4f659f5b619ce5994c5c43caab3d80df2296ae54fa888b3d17f5a/mypy-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b4968f14f44c62e2ec4a038c8797a87315be8df7740dc3ee8d3bfe1c6bf5dba8", size = 12702764, upload-time = "2025-05-29T13:20:42.826Z" }, + { url = "https://files.pythonhosted.org/packages/9b/c0/7646ef3a00fa39ac9bc0938626d9ff29d19d733011be929cfea59d82d136/mypy-1.16.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:eb14a4a871bb8efb1e4a50360d4e3c8d6c601e7a31028a2c79f9bb659b63d730", size = 12896233, upload-time = "2025-05-29T13:18:37.446Z" }, + { url = "https://files.pythonhosted.org/packages/6d/38/52f4b808b3fef7f0ef840ee8ff6ce5b5d77381e65425758d515cdd4f5bb5/mypy-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:bd4e1ebe126152a7bbaa4daedd781c90c8f9643c79b9748caa270ad542f12bec", size = 9565547, upload-time = "2025-05-29T13:20:02.836Z" }, + { url = "https://files.pythonhosted.org/packages/97/9c/ca03bdbefbaa03b264b9318a98950a9c683e06472226b55472f96ebbc53d/mypy-1.16.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a9e056237c89f1587a3be1a3a70a06a698d25e2479b9a2f57325ddaaffc3567b", size = 11059753, upload-time = "2025-05-29T13:18:18.167Z" }, + { url = "https://files.pythonhosted.org/packages/36/92/79a969b8302cfe316027c88f7dc6fee70129490a370b3f6eb11d777749d0/mypy-1.16.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0b07e107affb9ee6ce1f342c07f51552d126c32cd62955f59a7db94a51ad12c0", size = 10073338, upload-time = "2025-05-29T13:19:48.079Z" }, + { url = "https://files.pythonhosted.org/packages/14/9b/a943f09319167da0552d5cd722104096a9c99270719b1afeea60d11610aa/mypy-1.16.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c6fb60cbd85dc65d4d63d37cb5c86f4e3a301ec605f606ae3a9173e5cf34997b", size = 11827764, upload-time = "2025-05-29T13:46:04.47Z" }, + { url = "https://files.pythonhosted.org/packages/ec/64/ff75e71c65a0cb6ee737287c7913ea155845a556c64144c65b811afdb9c7/mypy-1.16.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a7e32297a437cc915599e0578fa6bc68ae6a8dc059c9e009c628e1c47f91495d", size = 12701356, upload-time = "2025-05-29T13:35:13.553Z" }, + { url = "https://files.pythonhosted.org/packages/0a/ad/0e93c18987a1182c350f7a5fab70550852f9fabe30ecb63bfbe51b602074/mypy-1.16.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:afe420c9380ccec31e744e8baff0d406c846683681025db3531b32db56962d52", size = 12900745, upload-time = "2025-05-29T13:17:24.409Z" }, + { url = "https://files.pythonhosted.org/packages/28/5d/036c278d7a013e97e33f08c047fe5583ab4f1fc47c9a49f985f1cdd2a2d7/mypy-1.16.0-cp313-cp313-win_amd64.whl", hash = "sha256:55f9076c6ce55dd3f8cd0c6fff26a008ca8e5131b89d5ba6d86bd3f47e736eeb", size = 9572200, upload-time = "2025-05-29T13:33:44.92Z" }, + { url = "https://files.pythonhosted.org/packages/99/a3/6ed10530dec8e0fdc890d81361260c9ef1f5e5c217ad8c9b21ecb2b8366b/mypy-1.16.0-py3-none-any.whl", hash = "sha256:29e1499864a3888bca5c1542f2d7232c6e586295183320caa95758fc84034031", size = 2265773, upload-time = "2025-05-29T13:35:18.762Z" }, ] [[package]] @@ -542,6 +543,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ff/7d/a4aa06e452e031559dcfb066e035d2615ebfa6148e93514d7c36030004c1/pallets_sphinx_themes-2.3.0-py3-none-any.whl", hash = "sha256:7ed13de3743c462c2804e2aa63d96cc9ffa82cb76d0251cea03de9bcd9f8dbec", size = 24745, upload-time = "2024-10-24T18:52:37.265Z" }, ] +[[package]] +name = "pathspec" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043, upload-time = "2023-12-10T22:30:45Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" }, +] + [[package]] name = "platformdirs" version = "4.3.8" @@ -613,20 +623,20 @@ wheels = [ [[package]] name = "pyright" -version = "1.1.400" +version = "1.1.401" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "nodeenv" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6c/cb/c306618a02d0ee8aed5fb8d0fe0ecfed0dbf075f71468f03a30b5f4e1fe0/pyright-1.1.400.tar.gz", hash = "sha256:b8a3ba40481aa47ba08ffb3228e821d22f7d391f83609211335858bf05686bdb", size = 3846546, upload-time = "2025-04-24T12:55:18.907Z" } +sdist = { url = "https://files.pythonhosted.org/packages/79/9a/7ab2b333b921b2d6bfcffe05a0e0a0bbeff884bd6fb5ed50cd68e2898e53/pyright-1.1.401.tar.gz", hash = "sha256:788a82b6611fa5e34a326a921d86d898768cddf59edde8e93e56087d277cc6f1", size = 3894193, upload-time = "2025-05-21T10:44:52.03Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c8/a5/5d285e4932cf149c90e3c425610c5efaea005475d5f96f1bfdb452956c62/pyright-1.1.400-py3-none-any.whl", hash = "sha256:c80d04f98b5a4358ad3a35e241dbf2a408eee33a40779df365644f8054d2517e", size = 5563460, upload-time = "2025-04-24T12:55:17.002Z" }, + { url = "https://files.pythonhosted.org/packages/0d/e6/1f908fce68b0401d41580e0f9acc4c3d1b248adcff00dfaad75cd21a1370/pyright-1.1.401-py3-none-any.whl", hash = "sha256:6fde30492ba5b0d7667c16ecaf6c699fab8d7a1263f6a18549e0b00bf7724c06", size = 5629193, upload-time = "2025-05-21T10:44:50.129Z" }, ] [[package]] name = "pytest" -version = "8.3.5" +version = "8.4.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, @@ -634,11 +644,12 @@ dependencies = [ { name = "iniconfig" }, { name = "packaging" }, { name = "pluggy" }, + { name = "pygments" }, { name = "tomli", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ae/3c/c9d525a414d506893f0cd8a8d0de7706446213181570cdbd766691164e40/pytest-8.3.5.tar.gz", hash = "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845", size = 1450891, upload-time = "2025-03-02T12:54:54.503Z" } +sdist = { url = "https://files.pythonhosted.org/packages/fb/aa/405082ce2749be5398045152251ac69c0f3578c7077efc53431303af97ce/pytest-8.4.0.tar.gz", hash = "sha256:14d920b48472ea0dbf68e45b96cd1ffda4705f33307dcc86c676c1b5104838a6", size = 1515232, upload-time = "2025-06-02T17:36:30.03Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/30/3d/64ad57c803f1fa1e963a7946b6e0fea4a70df53c1a7fed304586539c2bac/pytest-8.3.5-py3-none-any.whl", hash = "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820", size = 343634, upload-time = "2025-03-02T12:54:52.069Z" }, + { url = "https://files.pythonhosted.org/packages/2f/de/afa024cbe022b1b318a3d224125aa24939e99b4ff6f22e0ba639a2eaee47/pytest-8.4.0-py3-none-any.whl", hash = "sha256:f40f825768ad76c0977cbacdf1fd37c6f7a468e460ea6a0636078f8972d4517e", size = 363797, upload-time = "2025-06-02T17:36:27.859Z" }, ] [[package]] @@ -711,27 +722,27 @@ wheels = [ [[package]] name = "ruff" -version = "0.11.10" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e8/4c/4a3c5a97faaae6b428b336dcca81d03ad04779f8072c267ad2bd860126bf/ruff-0.11.10.tar.gz", hash = "sha256:d522fb204b4959909ecac47da02830daec102eeb100fb50ea9554818d47a5fa6", size = 4165632, upload-time = "2025-05-15T14:08:56.76Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2f/9f/596c628f8824a2ce4cd12b0f0b4c0629a62dfffc5d0f742c19a1d71be108/ruff-0.11.10-py3-none-linux_armv6l.whl", hash = "sha256:859a7bfa7bc8888abbea31ef8a2b411714e6a80f0d173c2a82f9041ed6b50f58", size = 10316243, upload-time = "2025-05-15T14:08:12.884Z" }, - { url = "https://files.pythonhosted.org/packages/3c/38/c1e0b77ab58b426f8c332c1d1d3432d9fc9a9ea622806e208220cb133c9e/ruff-0.11.10-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:968220a57e09ea5e4fd48ed1c646419961a0570727c7e069842edd018ee8afed", size = 11083636, upload-time = "2025-05-15T14:08:16.551Z" }, - { url = "https://files.pythonhosted.org/packages/23/41/b75e15961d6047d7fe1b13886e56e8413be8467a4e1be0a07f3b303cd65a/ruff-0.11.10-py3-none-macosx_11_0_arm64.whl", hash = "sha256:1067245bad978e7aa7b22f67113ecc6eb241dca0d9b696144256c3a879663bca", size = 10441624, upload-time = "2025-05-15T14:08:19.032Z" }, - { url = "https://files.pythonhosted.org/packages/b6/2c/e396b6703f131406db1811ea3d746f29d91b41bbd43ad572fea30da1435d/ruff-0.11.10-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4854fd09c7aed5b1590e996a81aeff0c9ff51378b084eb5a0b9cd9518e6cff2", size = 10624358, upload-time = "2025-05-15T14:08:21.542Z" }, - { url = "https://files.pythonhosted.org/packages/bd/8c/ee6cca8bdaf0f9a3704796022851a33cd37d1340bceaf4f6e991eb164e2e/ruff-0.11.10-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8b4564e9f99168c0f9195a0fd5fa5928004b33b377137f978055e40008a082c5", size = 10176850, upload-time = "2025-05-15T14:08:23.682Z" }, - { url = "https://files.pythonhosted.org/packages/e9/ce/4e27e131a434321b3b7c66512c3ee7505b446eb1c8a80777c023f7e876e6/ruff-0.11.10-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b6a9cc5b62c03cc1fea0044ed8576379dbaf751d5503d718c973d5418483641", size = 11759787, upload-time = "2025-05-15T14:08:25.733Z" }, - { url = "https://files.pythonhosted.org/packages/58/de/1e2e77fc72adc7cf5b5123fd04a59ed329651d3eab9825674a9e640b100b/ruff-0.11.10-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:607ecbb6f03e44c9e0a93aedacb17b4eb4f3563d00e8b474298a201622677947", size = 12430479, upload-time = "2025-05-15T14:08:28.013Z" }, - { url = "https://files.pythonhosted.org/packages/07/ed/af0f2340f33b70d50121628ef175523cc4c37619e98d98748c85764c8d88/ruff-0.11.10-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7b3a522fa389402cd2137df9ddefe848f727250535c70dafa840badffb56b7a4", size = 11919760, upload-time = "2025-05-15T14:08:30.956Z" }, - { url = "https://files.pythonhosted.org/packages/24/09/d7b3d3226d535cb89234390f418d10e00a157b6c4a06dfbe723e9322cb7d/ruff-0.11.10-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2f071b0deed7e9245d5820dac235cbdd4ef99d7b12ff04c330a241ad3534319f", size = 14041747, upload-time = "2025-05-15T14:08:33.297Z" }, - { url = "https://files.pythonhosted.org/packages/62/b3/a63b4e91850e3f47f78795e6630ee9266cb6963de8f0191600289c2bb8f4/ruff-0.11.10-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a60e3a0a617eafba1f2e4186d827759d65348fa53708ca547e384db28406a0b", size = 11550657, upload-time = "2025-05-15T14:08:35.639Z" }, - { url = "https://files.pythonhosted.org/packages/46/63/a4f95c241d79402ccdbdb1d823d156c89fbb36ebfc4289dce092e6c0aa8f/ruff-0.11.10-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:da8ec977eaa4b7bf75470fb575bea2cb41a0e07c7ea9d5a0a97d13dbca697bf2", size = 10489671, upload-time = "2025-05-15T14:08:38.437Z" }, - { url = "https://files.pythonhosted.org/packages/6a/9b/c2238bfebf1e473495659c523d50b1685258b6345d5ab0b418ca3f010cd7/ruff-0.11.10-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:ddf8967e08227d1bd95cc0851ef80d2ad9c7c0c5aab1eba31db49cf0a7b99523", size = 10160135, upload-time = "2025-05-15T14:08:41.247Z" }, - { url = "https://files.pythonhosted.org/packages/ba/ef/ba7251dd15206688dbfba7d413c0312e94df3b31b08f5d695580b755a899/ruff-0.11.10-py3-none-musllinux_1_2_i686.whl", hash = "sha256:5a94acf798a82db188f6f36575d80609072b032105d114b0f98661e1679c9125", size = 11170179, upload-time = "2025-05-15T14:08:43.762Z" }, - { url = "https://files.pythonhosted.org/packages/73/9f/5c336717293203ba275dbfa2ea16e49b29a9fd9a0ea8b6febfc17e133577/ruff-0.11.10-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:3afead355f1d16d95630df28d4ba17fb2cb9c8dfac8d21ced14984121f639bad", size = 11626021, upload-time = "2025-05-15T14:08:46.451Z" }, - { url = "https://files.pythonhosted.org/packages/d9/2b/162fa86d2639076667c9aa59196c020dc6d7023ac8f342416c2f5ec4bda0/ruff-0.11.10-py3-none-win32.whl", hash = "sha256:dc061a98d32a97211af7e7f3fa1d4ca2fcf919fb96c28f39551f35fc55bdbc19", size = 10494958, upload-time = "2025-05-15T14:08:49.601Z" }, - { url = "https://files.pythonhosted.org/packages/24/f3/66643d8f32f50a4b0d09a4832b7d919145ee2b944d43e604fbd7c144d175/ruff-0.11.10-py3-none-win_amd64.whl", hash = "sha256:5cc725fbb4d25b0f185cb42df07ab6b76c4489b4bfb740a175f3a59c70e8a224", size = 11650285, upload-time = "2025-05-15T14:08:52.392Z" }, - { url = "https://files.pythonhosted.org/packages/95/3a/2e8704d19f376c799748ff9cb041225c1d59f3e7711bc5596c8cfdc24925/ruff-0.11.10-py3-none-win_arm64.whl", hash = "sha256:ef69637b35fb8b210743926778d0e45e1bffa850a7c61e428c6b971549b5f5d1", size = 10765278, upload-time = "2025-05-15T14:08:54.56Z" }, +version = "0.11.13" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ed/da/9c6f995903b4d9474b39da91d2d626659af3ff1eeb43e9ae7c119349dba6/ruff-0.11.13.tar.gz", hash = "sha256:26fa247dc68d1d4e72c179e08889a25ac0c7ba4d78aecfc835d49cbfd60bf514", size = 4282054, upload-time = "2025-06-05T21:00:15.721Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7d/ce/a11d381192966e0b4290842cc8d4fac7dc9214ddf627c11c1afff87da29b/ruff-0.11.13-py3-none-linux_armv6l.whl", hash = "sha256:4bdfbf1240533f40042ec00c9e09a3aade6f8c10b6414cf11b519488d2635d46", size = 10292516, upload-time = "2025-06-05T20:59:32.944Z" }, + { url = "https://files.pythonhosted.org/packages/78/db/87c3b59b0d4e753e40b6a3b4a2642dfd1dcaefbff121ddc64d6c8b47ba00/ruff-0.11.13-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:aef9c9ed1b5ca28bb15c7eac83b8670cf3b20b478195bd49c8d756ba0a36cf48", size = 11106083, upload-time = "2025-06-05T20:59:37.03Z" }, + { url = "https://files.pythonhosted.org/packages/77/79/d8cec175856ff810a19825d09ce700265f905c643c69f45d2b737e4a470a/ruff-0.11.13-py3-none-macosx_11_0_arm64.whl", hash = "sha256:53b15a9dfdce029c842e9a5aebc3855e9ab7771395979ff85b7c1dedb53ddc2b", size = 10436024, upload-time = "2025-06-05T20:59:39.741Z" }, + { url = "https://files.pythonhosted.org/packages/8b/5b/f6d94f2980fa1ee854b41568368a2e1252681b9238ab2895e133d303538f/ruff-0.11.13-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ab153241400789138d13f362c43f7edecc0edfffce2afa6a68434000ecd8f69a", size = 10646324, upload-time = "2025-06-05T20:59:42.185Z" }, + { url = "https://files.pythonhosted.org/packages/6c/9c/b4c2acf24ea4426016d511dfdc787f4ce1ceb835f3c5fbdbcb32b1c63bda/ruff-0.11.13-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6c51f93029d54a910d3d24f7dd0bb909e31b6cd989a5e4ac513f4eb41629f0dc", size = 10174416, upload-time = "2025-06-05T20:59:44.319Z" }, + { url = "https://files.pythonhosted.org/packages/f3/10/e2e62f77c65ede8cd032c2ca39c41f48feabedb6e282bfd6073d81bb671d/ruff-0.11.13-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1808b3ed53e1a777c2ef733aca9051dc9bf7c99b26ece15cb59a0320fbdbd629", size = 11724197, upload-time = "2025-06-05T20:59:46.935Z" }, + { url = "https://files.pythonhosted.org/packages/bb/f0/466fe8469b85c561e081d798c45f8a1d21e0b4a5ef795a1d7f1a9a9ec182/ruff-0.11.13-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:d28ce58b5ecf0f43c1b71edffabe6ed7f245d5336b17805803312ec9bc665933", size = 12511615, upload-time = "2025-06-05T20:59:49.534Z" }, + { url = "https://files.pythonhosted.org/packages/17/0e/cefe778b46dbd0cbcb03a839946c8f80a06f7968eb298aa4d1a4293f3448/ruff-0.11.13-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:55e4bc3a77842da33c16d55b32c6cac1ec5fb0fbec9c8c513bdce76c4f922165", size = 12117080, upload-time = "2025-06-05T20:59:51.654Z" }, + { url = "https://files.pythonhosted.org/packages/5d/2c/caaeda564cbe103bed145ea557cb86795b18651b0f6b3ff6a10e84e5a33f/ruff-0.11.13-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:633bf2c6f35678c56ec73189ba6fa19ff1c5e4807a78bf60ef487b9dd272cc71", size = 11326315, upload-time = "2025-06-05T20:59:54.469Z" }, + { url = "https://files.pythonhosted.org/packages/75/f0/782e7d681d660eda8c536962920c41309e6dd4ebcea9a2714ed5127d44bd/ruff-0.11.13-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ffbc82d70424b275b089166310448051afdc6e914fdab90e08df66c43bb5ca9", size = 11555640, upload-time = "2025-06-05T20:59:56.986Z" }, + { url = "https://files.pythonhosted.org/packages/5d/d4/3d580c616316c7f07fb3c99dbecfe01fbaea7b6fd9a82b801e72e5de742a/ruff-0.11.13-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:4a9ddd3ec62a9a89578c85842b836e4ac832d4a2e0bfaad3b02243f930ceafcc", size = 10507364, upload-time = "2025-06-05T20:59:59.154Z" }, + { url = "https://files.pythonhosted.org/packages/5a/dc/195e6f17d7b3ea6b12dc4f3e9de575db7983db187c378d44606e5d503319/ruff-0.11.13-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d237a496e0778d719efb05058c64d28b757c77824e04ffe8796c7436e26712b7", size = 10141462, upload-time = "2025-06-05T21:00:01.481Z" }, + { url = "https://files.pythonhosted.org/packages/f4/8e/39a094af6967faa57ecdeacb91bedfb232474ff8c3d20f16a5514e6b3534/ruff-0.11.13-py3-none-musllinux_1_2_i686.whl", hash = "sha256:26816a218ca6ef02142343fd24c70f7cd8c5aa6c203bca284407adf675984432", size = 11121028, upload-time = "2025-06-05T21:00:04.06Z" }, + { url = "https://files.pythonhosted.org/packages/5a/c0/b0b508193b0e8a1654ec683ebab18d309861f8bd64e3a2f9648b80d392cb/ruff-0.11.13-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:51c3f95abd9331dc5b87c47ac7f376db5616041173826dfd556cfe3d4977f492", size = 11602992, upload-time = "2025-06-05T21:00:06.249Z" }, + { url = "https://files.pythonhosted.org/packages/7c/91/263e33ab93ab09ca06ce4f8f8547a858cc198072f873ebc9be7466790bae/ruff-0.11.13-py3-none-win32.whl", hash = "sha256:96c27935418e4e8e77a26bb05962817f28b8ef3843a6c6cc49d8783b5507f250", size = 10474944, upload-time = "2025-06-05T21:00:08.459Z" }, + { url = "https://files.pythonhosted.org/packages/46/f4/7c27734ac2073aae8efb0119cae6931b6fb48017adf048fdf85c19337afc/ruff-0.11.13-py3-none-win_amd64.whl", hash = "sha256:29c3189895a8a6a657b7af4e97d330c8a3afd2c9c8f46c81e2fc5a31866517e3", size = 11548669, upload-time = "2025-06-05T21:00:11.147Z" }, + { url = "https://files.pythonhosted.org/packages/ec/bf/b273dd11673fed8a6bd46032c0ea2a04b2ac9bfa9c628756a5856ba113b0/ruff-0.11.13-py3-none-win_arm64.whl", hash = "sha256:b4385285e9179d608ff1d2fb9922062663c658605819a6876d8beef0c30b7f3b", size = 10683928, upload-time = "2025-06-05T21:00:13.758Z" }, ] [[package]] @@ -930,14 +941,14 @@ wheels = [ [[package]] name = "starlette" -version = "0.46.2" +version = "0.47.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ce/20/08dfcd9c983f6a6f4a1000d934b9e6d626cff8d2eeb77a89a68eef20a2b7/starlette-0.46.2.tar.gz", hash = "sha256:7f7361f34eed179294600af672f565727419830b54b7b084efe44bb82d2fccd5", size = 2580846, upload-time = "2025-04-13T13:56:17.942Z" } +sdist = { url = "https://files.pythonhosted.org/packages/8b/d0/0332bd8a25779a0e2082b0e179805ad39afad642938b371ae0882e7f880d/starlette-0.47.0.tar.gz", hash = "sha256:1f64887e94a447fed5f23309fb6890ef23349b7e478faa7b24a851cd4eb844af", size = 2582856, upload-time = "2025-05-29T15:45:27.628Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8b/0c/9d30a4ebeb6db2b25a841afbb80f6ef9a854fc3b41be131d249a977b4959/starlette-0.46.2-py3-none-any.whl", hash = "sha256:595633ce89f8ffa71a015caed34a5b2dc1c0cdb3f0f1fbd1e69339cf2abeec35", size = 72037, upload-time = "2025-04-13T13:56:16.21Z" }, + { url = "https://files.pythonhosted.org/packages/e3/81/c60b35fe9674f63b38a8feafc414fca0da378a9dbd5fa1e0b8d23fcc7a9b/starlette-0.47.0-py3-none-any.whl", hash = "sha256:9d052d4933683af40ffd47c7465433570b4949dc937e20ad1d73b34e72f10c37", size = 72796, upload-time = "2025-05-29T15:45:26.305Z" }, ] [[package]] @@ -1003,25 +1014,25 @@ wheels = [ [[package]] name = "tox-uv" -version = "1.25.0" +version = "1.26.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "packaging" }, { name = "tox" }, { name = "uv" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5d/3a/3e445f25978a716ba6674f33f687d9336d0312086a277a778a5e9e9220d7/tox_uv-1.25.0.tar.gz", hash = "sha256:59ee5e694c41fef7bbcf058f22a5f9b6a8509698def2ea60c08554f4e36b9fcc", size = 21114, upload-time = "2025-02-21T16:37:51.796Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7e/da/37790b4a176f05b0ec7a699f54979078fc726f743640aa5c10c551c27edb/tox_uv-1.26.0.tar.gz", hash = "sha256:5045880c467eed58a98f7eaa7fe286b7ef688e2c56f2123d53e275011495c381", size = 21523, upload-time = "2025-05-27T14:51:42.702Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3c/a7/f5c29e0e6faaccefcab607f672b176927144e9412c8183d21301ea2a6f6c/tox_uv-1.25.0-py3-none-any.whl", hash = "sha256:50cfe7795dcd49b2160d7d65b5ece8717f38cfedc242c852a40ec0a71e159bf7", size = 16431, upload-time = "2025-02-21T16:37:49.657Z" }, + { url = "https://files.pythonhosted.org/packages/46/b8/04c5cb83da072a3f96d357d68a551f5e97e162573c2011a09437df995811/tox_uv-1.26.0-py3-none-any.whl", hash = "sha256:894b2e7274fd6131c3bd1012813edc858753cad67727050c21cd973a08e691c8", size = 16562, upload-time = "2025-05-27T14:51:40.803Z" }, ] [[package]] name = "typing-extensions" -version = "4.13.2" +version = "4.14.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f6/37/23083fcd6e35492953e8d2aaaa68b860eb422b34627b13f2ce3eb6106061/typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef", size = 106967, upload-time = "2025-04-10T14:19:05.416Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d1/bc/51647cd02527e87d05cb083ccc402f93e441606ff1f01739a62c8ad09ba5/typing_extensions-4.14.0.tar.gz", hash = "sha256:8676b788e32f02ab42d9e7c61324048ae4c6d844a399eebace3d4979d75ceef4", size = 107423, upload-time = "2025-06-02T14:52:11.399Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8b/54/b1ae86c0973cc6f0210b53d508ca3641fb6d0c56823f288d108bc7ab3cc8/typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", size = 45806, upload-time = "2025-04-10T14:19:03.967Z" }, + { url = "https://files.pythonhosted.org/packages/69/e0/552843e0d356fbb5256d21449fa957fa4eff3bbc135a74a691ee70c7c5da/typing_extensions-4.14.0-py3-none-any.whl", hash = "sha256:a1514509136dd0b477638fc68d6a91497af5076466ad0fa6c338e44e359944af", size = 43839, upload-time = "2025-06-02T14:52:10.026Z" }, ] [[package]] @@ -1035,41 +1046,41 @@ wheels = [ [[package]] name = "uv" -version = "0.7.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/77/9e/4ea6d224f868badecd48b8fed17f83adb0ff62f75bc21785d91dee75c744/uv-0.7.3.tar.gz", hash = "sha256:863ceb63aefc7c2db9918313a1cb3c8bf3fc3d59b656b617db9e4abad90373f3", size = 3242256, upload-time = "2025-05-07T20:01:59.783Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e4/8b/09a9d9da09d90ec6829dc4b3e9b7ff99222b7f05bc5d292bc30b04b92209/uv-0.7.3-py3-none-linux_armv6l.whl", hash = "sha256:f37c8a6b172776fb5305afe0699907aff44a778669de7a8fbe5a9c09c1a88a97", size = 16673361, upload-time = "2025-05-07T20:01:04.641Z" }, - { url = "https://files.pythonhosted.org/packages/ba/de/794ea8c9729784c7626f05a98fe91b8367587f57f023cb95adcd8f8a9215/uv-0.7.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3e6e1fd5755d4ef4c6e1ce55bd2c6d9dec278a8bef5752703d702ce03704fe29", size = 16755964, upload-time = "2025-05-07T20:01:09.43Z" }, - { url = "https://files.pythonhosted.org/packages/df/1b/50922bfbe1631d022e0c6434ade17158b9b4e0bb7fccc77c928e32dd9021/uv-0.7.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:db8a5d5995b160158405379deadf0ffccf849a5e7ce048900b73517daf109e2c", size = 15577471, upload-time = "2025-05-07T20:01:12.235Z" }, - { url = "https://files.pythonhosted.org/packages/69/39/cba47262d9547695657885391b34e8732cb0c34b5b876b811851cd320f3a/uv-0.7.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:d246243f348796730e8ea9736ddd48702d4448d98af5e61693063ed616e30378", size = 16027456, upload-time = "2025-05-07T20:01:14.653Z" }, - { url = "https://files.pythonhosted.org/packages/e6/33/1acf89318fb987a6eb9989a6991b76b6c930b6a724ce5f1ed848519d6a5f/uv-0.7.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:acef117a0c52299e60c6f7a3e60849050cd233704c561f688fac1100d113da2e", size = 16390903, upload-time = "2025-05-07T20:01:17.018Z" }, - { url = "https://files.pythonhosted.org/packages/ad/66/2fe8ec6e5390de4cfc6db312464b4f28e5b3d98d576adc42731c0aeb5073/uv-0.7.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:90990e4c289feee24164c8e463fc0ebc9a336960119cd256acca7c1439f0f536", size = 17167937, upload-time = "2025-05-07T20:01:19.567Z" }, - { url = "https://files.pythonhosted.org/packages/a5/8a/dc46e79f5fd068cb841a716a96f0344af62cf2deb2e78f57e0e147de26ac/uv-0.7.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:4809e5f7f5b2d6423d6573fda5655389c955ca649499fe9750b61af95daf9b7d", size = 18077868, upload-time = "2025-05-07T20:01:22.447Z" }, - { url = "https://files.pythonhosted.org/packages/da/af/f7165a205ce8bb5e00f197d86a6fce4b4a317db0e471a31db9137ca1cc2d/uv-0.7.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:acff7fba5ff40dcb5a42de496db92a3965edac7a3d687d9b013ba6e0336995df", size = 17793072, upload-time = "2025-05-07T20:01:25.942Z" }, - { url = "https://files.pythonhosted.org/packages/27/5e/2e9172ec3fa8acfa69642900d6eee8e5021f6c14d135edef524c674b4cfb/uv-0.7.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fbb2d322d453e498e1431c51421cee597962ecd3f93fcef853b258e9c7e7636c", size = 22181943, upload-time = "2025-05-07T20:01:28.576Z" }, - { url = "https://files.pythonhosted.org/packages/f1/b1/8af4ea6d09d05b9edead5e701dd91e04d55971483a7a644bab7a979bb46b/uv-0.7.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1414a026c153ae0731daed0812b17bf77d34eafedaeb3a5c72e08181aea116b", size = 17400777, upload-time = "2025-05-07T20:01:32.27Z" }, - { url = "https://files.pythonhosted.org/packages/09/ae/ccd123274ae59707e84fc5542776f89887818bad915167fbaeda65ebf52a/uv-0.7.3-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:c976fce3d1068a1d007f50127cc7873d67643c1a60439564970f092d9be41877", size = 16306132, upload-time = "2025-05-07T20:01:36.572Z" }, - { url = "https://files.pythonhosted.org/packages/01/5c/99ef96ca53c74552b616bd341cd5d298bc8a603151343c409efeaf1552a0/uv-0.7.3-py3-none-musllinux_1_1_armv7l.whl", hash = "sha256:cc27207c35c959d2e0e873e86a80a2470a77b7a34a4512a831e8d4f7c87f4404", size = 16376728, upload-time = "2025-05-07T20:01:39.357Z" }, - { url = "https://files.pythonhosted.org/packages/74/91/07f7e68f08e617d27ae9908a4e8deb756368b942319634956ed92d7cf35c/uv-0.7.3-py3-none-musllinux_1_1_i686.whl", hash = "sha256:5eb4872888a9fb10b62cc00be8e84822d63d3e622a5f340248e53ecf321dba96", size = 16707670, upload-time = "2025-05-07T20:01:46.816Z" }, - { url = "https://files.pythonhosted.org/packages/a9/73/385a5a55fccfebac84a88b629992e301c080640691f2e27a3e3ccee8315e/uv-0.7.3-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:0646e463365e7277f22200ce2d43b7a44e5a3192320500b4983b4fe34d69a5fb", size = 17514613, upload-time = "2025-05-07T20:01:49.245Z" }, - { url = "https://files.pythonhosted.org/packages/6a/97/1138bb26038805a14d930c7261faf363a5256757390b4be0aaf6e33a41c0/uv-0.7.3-py3-none-win32.whl", hash = "sha256:44e2f3fcbd1ab519bdb68986449b2e3103d2261be95f985cadcf7ec7c510b595", size = 16897117, upload-time = "2025-05-07T20:01:51.728Z" }, - { url = "https://files.pythonhosted.org/packages/64/1b/c9f0ad7c75bf0a04c52c7e766593f5e79b1ac7d97fa1cb34c6ce0cfe3746/uv-0.7.3-py3-none-win_amd64.whl", hash = "sha256:0a446d4e5b10ce8a793156a276727bb7affa96a85e80dc5ad34e0c2de7e71cc8", size = 18323992, upload-time = "2025-05-07T20:01:54.495Z" }, - { url = "https://files.pythonhosted.org/packages/47/1b/7ca1b8ec4bcf1c807f61e6ced7ca704791843cf1297db5edb54db07bd1db/uv-0.7.3-py3-none-win_arm64.whl", hash = "sha256:cb2547fd1466698e9b4f11de5eef7055b8cbcc3c693d79f6d747e3f8e6be2ab7", size = 17017988, upload-time = "2025-05-07T20:01:57.283Z" }, +version = "0.7.12" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/67/35/360a4aa325254b7f11d0898d30588861428659011b34f1e19c40fdd15db6/uv-0.7.12.tar.gz", hash = "sha256:4aa152e6a70d5662ca66a918f697bf8fb710f391068aa7d04e032af2edebb095", size = 3298683, upload-time = "2025-06-06T20:39:04.308Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f8/64/ee9f1b27f006c49a6765e9655ab93e7c8cbd6f0bf8b731f30f608b0be9fd/uv-0.7.12-py3-none-linux_armv6l.whl", hash = "sha256:81824caf5756ffee54b4c937d92d7c8c224c416270c90a83b9b4a973f6e4e559", size = 17024991, upload-time = "2025-06-06T20:38:17.053Z" }, + { url = "https://files.pythonhosted.org/packages/43/aa/f42707faa13a9c1b4f662456b2dca4bde169eb921f135319d8856c6e5e8e/uv-0.7.12-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:02e67c5f9d141fb25976cddb28abceaf715412ed83070cb9b87c5c488c8451af", size = 17097383, upload-time = "2025-06-06T20:38:21.174Z" }, + { url = "https://files.pythonhosted.org/packages/b9/a9/0f27e16e161f98240a328b5201b8abf178b751fde4fc56c54c1321812cd5/uv-0.7.12-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e70a4393fd6a09b056e1ac500fe2b796d26c30783194868c6801ea08c3bbf863", size = 15812649, upload-time = "2025-06-06T20:38:23.51Z" }, + { url = "https://files.pythonhosted.org/packages/0b/eb/605d8f1d08606024209d0e31c3799c696199a887260ee1db52663e4da2e8/uv-0.7.12-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:bb47326b9c4802db28e11f1aab174d5c9c0a8b26ed0a83094d3882dd8f5049ad", size = 16344497, upload-time = "2025-06-06T20:38:25.899Z" }, + { url = "https://files.pythonhosted.org/packages/b7/86/3503eb869fa17d607cc296a6514db52ec73c2ec85ad608952a207fd2e8ff/uv-0.7.12-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:14214a51e0ae0f0e8dbcac35a29722c45dbf40d0fd37309897642f7989af6caf", size = 16773525, upload-time = "2025-06-06T20:38:28.619Z" }, + { url = "https://files.pythonhosted.org/packages/9b/d6/868fb3f0b9f2a0d2f14cb8079171b862adbd782e47e0469dad3d3d71c938/uv-0.7.12-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0fa630d865111c26f26c5e6f4547a73b13284f098471a4ca982d7b0caf0e658b", size = 17551173, upload-time = "2025-06-06T20:38:31.166Z" }, + { url = "https://files.pythonhosted.org/packages/d4/a8/b5be1c67c7894caf178e850903ac25f465e3508a6eada2ae735b187dc39d/uv-0.7.12-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:1557a154d2c36030ff0b707f3c2bfafd977e54fcd4d628dd0fa8a265449e9f13", size = 18359491, upload-time = "2025-06-06T20:38:33.569Z" }, + { url = "https://files.pythonhosted.org/packages/95/23/f62bab13f67ed785f7ad01546c499809d1db71b03f94950380f0bc407625/uv-0.7.12-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7e0ba7767b21d58d65703c3cd43814ccfe06d7664ac42b3589d5f2b72486b903", size = 18098855, upload-time = "2025-06-06T20:38:36.029Z" }, + { url = "https://files.pythonhosted.org/packages/a6/4a/db21a5d3839771799af2df366cc5ed0933ebe9fc9e920f212e33dc00136e/uv-0.7.12-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0672dc5dc1b0ae7191d11ecae8bb794c7e860936b66c2bc3855bd0dee17fca1", size = 18206282, upload-time = "2025-06-06T20:38:38.582Z" }, + { url = "https://files.pythonhosted.org/packages/bc/ae/fcfd916cbc109c5626dc25b208395b47ba12b27af82f3bb8e247b4e95692/uv-0.7.12-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e34b4ad4288828210c2e075934009903514ca97bd603aced7d0755040b4d0489", size = 17777690, upload-time = "2025-06-06T20:38:41.021Z" }, + { url = "https://files.pythonhosted.org/packages/92/78/608163b35ffaf1054cd10197646b6336e7be7b6a51dfef6d98a91600c6be/uv-0.7.12-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:8a7ed9e94ec409bfc7181ee274d1b0ed6292698a20df0ae035ce422224863af5", size = 16599406, upload-time = "2025-06-06T20:38:43.72Z" }, + { url = "https://files.pythonhosted.org/packages/d4/d6/6fe3b16390472a9d31dd1e0e7e3759b884d71e8a0dff1baf4a753b4adaaa/uv-0.7.12-py3-none-musllinux_1_1_armv7l.whl", hash = "sha256:85e8d3dea95016a45ed8c48343f98734d1b5c4be7bba26257d4c8873059646fa", size = 16714823, upload-time = "2025-06-06T20:38:45.949Z" }, + { url = "https://files.pythonhosted.org/packages/b3/a5/b0432a25eaa23e9f909649321784b8e4be4579e9957eb5d369aa30c79164/uv-0.7.12-py3-none-musllinux_1_1_i686.whl", hash = "sha256:01310c45d55f6e7580124c9b1f7e3586b9609c4f8e5a78558a75951b03541bb2", size = 17086446, upload-time = "2025-06-06T20:38:48.648Z" }, + { url = "https://files.pythonhosted.org/packages/da/d8/673591f34f897aa4216144a513e60c2004399155c47e7b550612960359c6/uv-0.7.12-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:4c697ef9d9f6b6f42df5a661efa8a745c0e4c330039d45b549b2ca7e7b66f8a5", size = 17903789, upload-time = "2025-06-06T20:38:51.864Z" }, + { url = "https://files.pythonhosted.org/packages/15/09/e476187c0a1da78b9c2021f3c3ab31ed2469a70d222bde5dc892236b3c4f/uv-0.7.12-py3-none-win32.whl", hash = "sha256:6008abf92c8d37060944377d89bf9f514aa18370391d9d63dc7d449dac94aca1", size = 17344011, upload-time = "2025-06-06T20:38:54.276Z" }, + { url = "https://files.pythonhosted.org/packages/08/9e/c52c7f50280e57110ca79b6805877f50514d9a777d31a683a4eb1de52312/uv-0.7.12-py3-none-win_amd64.whl", hash = "sha256:bb57bd26becd86194788f832af373b6ba431314fa0f6f7e904c90cac1818a7dc", size = 18803328, upload-time = "2025-06-06T20:38:59.368Z" }, + { url = "https://files.pythonhosted.org/packages/8e/35/4800ff7bc1663d9f967eabc8440074f906c8a98ea28d1aae66d2d19b7ae9/uv-0.7.12-py3-none-win_arm64.whl", hash = "sha256:8aba24e12ded2f2974a2f213e55daabf78002613d3772c1396fc924c6682cd27", size = 17450522, upload-time = "2025-06-06T20:39:01.963Z" }, ] [[package]] name = "uvicorn" -version = "0.34.2" +version = "0.34.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, { name = "h11" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a6/ae/9bbb19b9e1c450cf9ecaef06463e40234d98d95bf572fab11b4f19ae5ded/uvicorn-0.34.2.tar.gz", hash = "sha256:0e929828f6186353a80b58ea719861d2629d766293b6d19baf086ba31d4f3328", size = 76815, upload-time = "2025-04-19T06:02:50.101Z" } +sdist = { url = "https://files.pythonhosted.org/packages/de/ad/713be230bcda622eaa35c28f0d328c3675c371238470abdea52417f17a8e/uvicorn-0.34.3.tar.gz", hash = "sha256:35919a9a979d7a59334b6b10e05d77c1d0d574c50e0fc98b8b1a0f165708b55a", size = 76631, upload-time = "2025-06-01T07:48:17.531Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b1/4b/4cef6ce21a2aaca9d852a6e84ef4f135d99fcd74fa75105e2fc0c8308acd/uvicorn-0.34.2-py3-none-any.whl", hash = "sha256:deb49af569084536d269fe0a6d67e3754f104cf03aba7c11c40f01aadf33c403", size = 62483, upload-time = "2025-04-19T06:02:48.42Z" }, + { url = "https://files.pythonhosted.org/packages/6d/0d/8adfeaa62945f90d19ddc461c55f4a50c258af7662d34b6a3d5d1f8646f6/uvicorn-0.34.3-py3-none-any.whl", hash = "sha256:16246631db62bdfbf069b0645177d6e8a77ba950cfedbfd093acef9444e4d885", size = 62431, upload-time = "2025-06-01T07:48:15.664Z" }, ] [[package]] From 35c22ca7890d04b570ffb3187e17a5d21534f112 Mon Sep 17 00:00:00 2001 From: David Lord Date: Sun, 8 Jun 2025 11:17:04 -0700 Subject: [PATCH 23/27] remove slsa provenance PyPI and trusted publishing has built-in attestation support now. --- .github/workflows/publish.yaml | 24 +++--------------------- pyproject.toml | 5 ----- 2 files changed, 3 insertions(+), 26 deletions(-) diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index 46a0c3a30..bf3b2d992 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -5,8 +5,6 @@ on: jobs: build: runs-on: ubuntu-latest - outputs: - hash: ${{ steps.hash.outputs.hash }} steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - uses: astral-sh/setup-uv@f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb # v6.1.0 @@ -18,38 +16,22 @@ jobs: python-version-file: pyproject.toml - run: echo "SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)" >> $GITHUB_ENV - run: uv build - - name: generate hash - id: hash - run: cd dist && echo "hash=$(sha256sum * | base64 -w0)" >> $GITHUB_OUTPUT - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: path: ./dist - provenance: - needs: [build] - permissions: - actions: read - id-token: write - contents: write - # Can't pin with hash due to how this workflow works. - uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.1.0 - with: - base64-subjects: ${{ needs.build.outputs.hash }} create-release: - needs: [provenance] + needs: [build] runs-on: ubuntu-latest permissions: contents: write steps: - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 - name: create release - run: > - gh release create --draft --repo ${{ github.repository }} - ${{ github.ref_name }} - *.intoto.jsonl/* artifact/* + run: gh release create --draft --repo ${{ github.repository }} ${{ github.ref_name }} artifact/* env: GH_TOKEN: ${{ github.token }} publish-pypi: - needs: [provenance] + needs: [build] environment: name: publish url: https://pypi.org/project/click/${{ github.ref_name }} diff --git a/pyproject.toml b/pyproject.toml index 66ce28a3b..eee0ac769 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -140,11 +140,6 @@ ignore = [ force-single-line = true order-by-type = false -[tool.gha-update] -tag-only = [ - "slsa-framework/slsa-github-generator", -] - [tool.tox] env_list = [ "py3.13", "py3.12", "py3.11", "py3.10", From b1d172a5dfc017bbd51b9a7b12d00e984109601f Mon Sep 17 00:00:00 2001 From: David Lord Date: Sun, 8 Jun 2025 12:07:37 -0700 Subject: [PATCH 24/27] new logo --- README.md | 4 +- artwork/logo.svg | 75 ---------------------------- docs/_static/click-horizontal.svg | 1 + docs/_static/click-icon.png | Bin 625 -> 0 bytes docs/_static/click-icon.svg | 1 + docs/_static/click-logo-sidebar.png | Bin 4246 -> 0 bytes docs/_static/click-logo.png | Bin 26081 -> 0 bytes docs/_static/click-vertical.svg | 1 + docs/conf.py | 4 +- docs/index.rst | 5 +- 10 files changed, 10 insertions(+), 81 deletions(-) delete mode 100644 artwork/logo.svg create mode 100644 docs/_static/click-horizontal.svg delete mode 100644 docs/_static/click-icon.png create mode 100644 docs/_static/click-icon.svg delete mode 100644 docs/_static/click-logo-sidebar.png delete mode 100644 docs/_static/click-logo.png create mode 100644 docs/_static/click-vertical.svg diff --git a/README.md b/README.md index cee84bfc2..7f73c72aa 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ -# $ click_ +
+ +# Click Click is a Python package for creating beautiful command line interfaces in a composable way with as little code as necessary. It's the "Command diff --git a/artwork/logo.svg b/artwork/logo.svg deleted file mode 100644 index e0e1b5883..000000000 --- a/artwork/logo.svg +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - diff --git a/docs/_static/click-horizontal.svg b/docs/_static/click-horizontal.svg new file mode 100644 index 000000000..b1fdb90f2 --- /dev/null +++ b/docs/_static/click-horizontal.svg @@ -0,0 +1 @@ + diff --git a/docs/_static/click-icon.png b/docs/_static/click-icon.png deleted file mode 100644 index b883cfaa17f0ac31dd52effb9aaf6fe58feede06..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 625 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=EX7WqAsj$Z!;#Vf4nJ z@W_HNW6JLzZ-Ii6C9V-A!TD(=<%vb94CUqJdYO6I#mR{Use1WE>9gP2NHH)lzVmc( z45^s&_U7(vkw6jl2l{R%QieYiG{l@XbSx3D=03RJ!9&zKH-}Z*TAG*ZT2i)p#?pl3 z><;2VrHyQSqZl1ll^LcaPvKe=OzMW}ZEbr~5xpYbp3ZeS- zp^4SvW|zt)$vK^To1$h*{qPa*J0mBbpERxXaZ}Ov^bf+$FF1U+xNS?62wuf>CO5xO z@^0eGs5b`pe*A9Nztgse$!yiUWw(2upPDW2_CetN^SQ>IhBnz*yUYsxcJ2cY!wG|uAl diff --git a/docs/_static/click-logo-sidebar.png b/docs/_static/click-logo-sidebar.png deleted file mode 100644 index 4c2bc07a8dfbb1ff2ac81b1b3447249539713a3c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4246 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 diff --git a/docs/_static/click-logo.png b/docs/_static/click-logo.png deleted file mode 100644 index a8874506885e8a101d24789ce7033634d895eb77..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26081 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 diff --git a/docs/_static/click-vertical.svg b/docs/_static/click-vertical.svg new file mode 100644 index 000000000..108c8c024 --- /dev/null +++ b/docs/_static/click-vertical.svg @@ -0,0 +1 @@ + diff --git a/docs/conf.py b/docs/conf.py index c420f60d6..660a90cae 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -51,7 +51,7 @@ } singlehtml_sidebars = {"index": ["project.html", "localtoc.html", "ethicalads.html"]} html_static_path = ["_static"] -html_favicon = "_static/click-icon.png" -html_logo = "_static/click-logo-sidebar.png" +html_favicon = "_static/click-icon.svg" +html_logo = "_static/click-vertical.svg" html_title = f"Click Documentation ({version})" html_show_sourcelink = False diff --git a/docs/index.rst b/docs/index.rst index 1c7e32c80..917d6d029 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -3,10 +3,9 @@ Welcome to Click ================ -.. image:: _static/click-logo.png +.. image:: _static/click-horizontal.svg :align: center - :scale: 50% - :target: https://palletsprojects.com/p/click/ + :height: 200px Click is a Python package for creating beautiful command line interfaces in a composable way with as little code as necessary. It's the "Command From beb4c356844f62f501ead054f947f05313ca2e2b Mon Sep 17 00:00:00 2001 From: David Lord Date: Mon, 9 Jun 2025 21:45:06 -0700 Subject: [PATCH 25/27] cleanup svg --- docs/_static/click-horizontal.svg | 2 +- docs/_static/click-icon.svg | 2 +- docs/_static/click-vertical.svg | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/_static/click-horizontal.svg b/docs/_static/click-horizontal.svg index b1fdb90f2..467b953e3 100644 --- a/docs/_static/click-horizontal.svg +++ b/docs/_static/click-horizontal.svg @@ -1 +1 @@ - + diff --git a/docs/_static/click-icon.svg b/docs/_static/click-icon.svg index 6eb5e3963..80f36c536 100644 --- a/docs/_static/click-icon.svg +++ b/docs/_static/click-icon.svg @@ -1 +1 @@ - + diff --git a/docs/_static/click-vertical.svg b/docs/_static/click-vertical.svg index 108c8c024..eb0a06498 100644 --- a/docs/_static/click-vertical.svg +++ b/docs/_static/click-vertical.svg @@ -1 +1 @@ - + From 316d58ef45d29eb9865679260a52315647d259ca Mon Sep 17 00:00:00 2001 From: David Lord Date: Tue, 10 Jun 2025 14:30:15 -0700 Subject: [PATCH 26/27] cleanup svg --- docs/_static/click-horizontal.svg | 25 ++++++++++++++++++++++++- docs/_static/click-icon.svg | 10 +++++++++- docs/_static/click-vertical.svg | 25 ++++++++++++++++++++++++- 3 files changed, 57 insertions(+), 3 deletions(-) diff --git a/docs/_static/click-horizontal.svg b/docs/_static/click-horizontal.svg index 467b953e3..845a77e72 100644 --- a/docs/_static/click-horizontal.svg +++ b/docs/_static/click-horizontal.svg @@ -1 +1,24 @@ - + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/_static/click-icon.svg b/docs/_static/click-icon.svg index 80f36c536..c9414f092 100644 --- a/docs/_static/click-icon.svg +++ b/docs/_static/click-icon.svg @@ -1 +1,9 @@ - + + + + + + + + + diff --git a/docs/_static/click-vertical.svg b/docs/_static/click-vertical.svg index eb0a06498..3ca900b72 100644 --- a/docs/_static/click-vertical.svg +++ b/docs/_static/click-vertical.svg @@ -1 +1,24 @@ - + + + + + + + + + + + + + + + + + + + + + + + + From 28650344c54dd54e673d3e9a35e76bf9f4bedf8d Mon Sep 17 00:00:00 2001 From: David Lord Date: Thu, 12 Jun 2025 13:55:01 -0700 Subject: [PATCH 27/27] svg logo --- README.md | 2 +- docs/_static/click-horizontal.svg | 24 ------------------------ docs/_static/click-icon.svg | 10 ++++++---- docs/_static/click-logo.svg | 18 ++++++++++++++++++ docs/_static/click-name.svg | 24 ++++++++++++++++++++++++ docs/_static/click-vertical.svg | 24 ------------------------ docs/conf.py | 2 +- docs/index.rst | 2 +- 8 files changed, 51 insertions(+), 55 deletions(-) delete mode 100644 docs/_static/click-horizontal.svg create mode 100644 docs/_static/click-logo.svg create mode 100644 docs/_static/click-name.svg delete mode 100644 docs/_static/click-vertical.svg diff --git a/README.md b/README.md index 7f73c72aa..bb688b257 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -
+
# Click diff --git a/docs/_static/click-horizontal.svg b/docs/_static/click-horizontal.svg deleted file mode 100644 index 845a77e72..000000000 --- a/docs/_static/click-horizontal.svg +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/_static/click-icon.svg b/docs/_static/click-icon.svg index c9414f092..d2d5578da 100644 --- a/docs/_static/click-icon.svg +++ b/docs/_static/click-icon.svg @@ -2,8 +2,10 @@ - - - - + + + + + + diff --git a/docs/_static/click-logo.svg b/docs/_static/click-logo.svg new file mode 100644 index 000000000..0a3394866 --- /dev/null +++ b/docs/_static/click-logo.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/docs/_static/click-name.svg b/docs/_static/click-name.svg new file mode 100644 index 000000000..bf0cd1415 --- /dev/null +++ b/docs/_static/click-name.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + diff --git a/docs/_static/click-vertical.svg b/docs/_static/click-vertical.svg deleted file mode 100644 index 3ca900b72..000000000 --- a/docs/_static/click-vertical.svg +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/conf.py b/docs/conf.py index 660a90cae..2b223ab42 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -52,6 +52,6 @@ singlehtml_sidebars = {"index": ["project.html", "localtoc.html", "ethicalads.html"]} html_static_path = ["_static"] html_favicon = "_static/click-icon.svg" -html_logo = "_static/click-vertical.svg" +html_logo = "_static/click-logo.svg" html_title = f"Click Documentation ({version})" html_show_sourcelink = False diff --git a/docs/index.rst b/docs/index.rst index 917d6d029..a6bcd8416 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -3,7 +3,7 @@ Welcome to Click ================ -.. image:: _static/click-horizontal.svg +.. image:: _static/click-name.svg :align: center :height: 200px