Add files using upload-large-folder tool
Browse files- env/lib/python3.13/site-packages/idna-3.11.dist-info/INSTALLER +1 -0
- env/lib/python3.13/site-packages/idna-3.11.dist-info/METADATA +209 -0
- env/lib/python3.13/site-packages/idna-3.11.dist-info/RECORD +22 -0
- env/lib/python3.13/site-packages/idna-3.11.dist-info/WHEEL +4 -0
- env/lib/python3.13/site-packages/pip-25.1.1.dist-info/INSTALLER +1 -0
- env/lib/python3.13/site-packages/pip-25.1.1.dist-info/METADATA +90 -0
- env/lib/python3.13/site-packages/pip-25.1.1.dist-info/RECORD +850 -0
- env/lib/python3.13/site-packages/pip-25.1.1.dist-info/REQUESTED +0 -0
- env/lib/python3.13/site-packages/pip-25.1.1.dist-info/WHEEL +5 -0
- env/lib/python3.13/site-packages/pip-25.1.1.dist-info/entry_points.txt +3 -0
- env/lib/python3.13/site-packages/pip-25.1.1.dist-info/top_level.txt +1 -0
- env/lib/python3.13/site-packages/typer/__init__.py +39 -0
- env/lib/python3.13/site-packages/typer/_completion_shared.py +240 -0
- env/lib/python3.13/site-packages/typer/_types.py +27 -0
- env/lib/python3.13/site-packages/typer/completion.py +149 -0
- env/lib/python3.13/site-packages/typer/core.py +829 -0
- env/lib/python3.13/site-packages/typer/main.py +1142 -0
- env/lib/python3.13/site-packages/typer/py.typed +0 -0
- env/lib/python3.13/site-packages/typer/rich_utils.py +770 -0
- env/lib/python3.13/site-packages/typer/testing.py +29 -0
env/lib/python3.13/site-packages/idna-3.11.dist-info/INSTALLER
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
pip
|
env/lib/python3.13/site-packages/idna-3.11.dist-info/METADATA
ADDED
|
@@ -0,0 +1,209 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Metadata-Version: 2.4
|
| 2 |
+
Name: idna
|
| 3 |
+
Version: 3.11
|
| 4 |
+
Summary: Internationalized Domain Names in Applications (IDNA)
|
| 5 |
+
Author-email: Kim Davies <kim+pypi@gumleaf.org>
|
| 6 |
+
Requires-Python: >=3.8
|
| 7 |
+
Description-Content-Type: text/x-rst
|
| 8 |
+
License-Expression: BSD-3-Clause
|
| 9 |
+
Classifier: Development Status :: 5 - Production/Stable
|
| 10 |
+
Classifier: Intended Audience :: Developers
|
| 11 |
+
Classifier: Intended Audience :: System Administrators
|
| 12 |
+
Classifier: Operating System :: OS Independent
|
| 13 |
+
Classifier: Programming Language :: Python
|
| 14 |
+
Classifier: Programming Language :: Python :: 3
|
| 15 |
+
Classifier: Programming Language :: Python :: 3 :: Only
|
| 16 |
+
Classifier: Programming Language :: Python :: 3.8
|
| 17 |
+
Classifier: Programming Language :: Python :: 3.9
|
| 18 |
+
Classifier: Programming Language :: Python :: 3.10
|
| 19 |
+
Classifier: Programming Language :: Python :: 3.11
|
| 20 |
+
Classifier: Programming Language :: Python :: 3.12
|
| 21 |
+
Classifier: Programming Language :: Python :: 3.13
|
| 22 |
+
Classifier: Programming Language :: Python :: 3.14
|
| 23 |
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
| 24 |
+
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
| 25 |
+
Classifier: Topic :: Internet :: Name Service (DNS)
|
| 26 |
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
| 27 |
+
Classifier: Topic :: Utilities
|
| 28 |
+
License-File: LICENSE.md
|
| 29 |
+
Requires-Dist: ruff >= 0.6.2 ; extra == "all"
|
| 30 |
+
Requires-Dist: mypy >= 1.11.2 ; extra == "all"
|
| 31 |
+
Requires-Dist: pytest >= 8.3.2 ; extra == "all"
|
| 32 |
+
Requires-Dist: flake8 >= 7.1.1 ; extra == "all"
|
| 33 |
+
Project-URL: Changelog, https://github.com/kjd/idna/blob/master/HISTORY.rst
|
| 34 |
+
Project-URL: Issue tracker, https://github.com/kjd/idna/issues
|
| 35 |
+
Project-URL: Source, https://github.com/kjd/idna
|
| 36 |
+
Provides-Extra: all
|
| 37 |
+
|
| 38 |
+
Internationalized Domain Names in Applications (IDNA)
|
| 39 |
+
=====================================================
|
| 40 |
+
|
| 41 |
+
Support for `Internationalized Domain Names in
|
| 42 |
+
Applications (IDNA) <https://tools.ietf.org/html/rfc5891>`_
|
| 43 |
+
and `Unicode IDNA Compatibility Processing
|
| 44 |
+
<https://unicode.org/reports/tr46/>`_.
|
| 45 |
+
|
| 46 |
+
The latest versions of these standards supplied here provide
|
| 47 |
+
more comprehensive language coverage and reduce the potential of
|
| 48 |
+
allowing domains with known security vulnerabilities. This library
|
| 49 |
+
is a suitable replacement for the “encodings.idna”
|
| 50 |
+
module that comes with the Python standard library, but which
|
| 51 |
+
only supports an older superseded IDNA specification from 2003.
|
| 52 |
+
|
| 53 |
+
Basic functions are simply executed:
|
| 54 |
+
|
| 55 |
+
.. code-block:: pycon
|
| 56 |
+
|
| 57 |
+
>>> import idna
|
| 58 |
+
>>> idna.encode('ドメイン.テスト')
|
| 59 |
+
b'xn--eckwd4c7c.xn--zckzah'
|
| 60 |
+
>>> print(idna.decode('xn--eckwd4c7c.xn--zckzah'))
|
| 61 |
+
ドメイン.テスト
|
| 62 |
+
|
| 63 |
+
|
| 64 |
+
Installation
|
| 65 |
+
------------
|
| 66 |
+
|
| 67 |
+
This package is available for installation from PyPI via the
|
| 68 |
+
typical mechanisms, such as:
|
| 69 |
+
|
| 70 |
+
.. code-block:: bash
|
| 71 |
+
|
| 72 |
+
$ python3 -m pip install idna
|
| 73 |
+
|
| 74 |
+
|
| 75 |
+
Usage
|
| 76 |
+
-----
|
| 77 |
+
|
| 78 |
+
For typical usage, the ``encode`` and ``decode`` functions will take a
|
| 79 |
+
domain name argument and perform a conversion to ASCII compatible encoding
|
| 80 |
+
(known as A-labels), or to Unicode strings (known as U-labels)
|
| 81 |
+
respectively.
|
| 82 |
+
|
| 83 |
+
.. code-block:: pycon
|
| 84 |
+
|
| 85 |
+
>>> import idna
|
| 86 |
+
>>> idna.encode('ドメイン.テスト')
|
| 87 |
+
b'xn--eckwd4c7c.xn--zckzah'
|
| 88 |
+
>>> print(idna.decode('xn--eckwd4c7c.xn--zckzah'))
|
| 89 |
+
ドメイン.テスト
|
| 90 |
+
|
| 91 |
+
Conversions can be applied at a per-label basis using the ``ulabel`` or
|
| 92 |
+
``alabel`` functions if necessary:
|
| 93 |
+
|
| 94 |
+
.. code-block:: pycon
|
| 95 |
+
|
| 96 |
+
>>> idna.alabel('测试')
|
| 97 |
+
b'xn--0zwm56d'
|
| 98 |
+
|
| 99 |
+
|
| 100 |
+
Compatibility Mapping (UTS #46)
|
| 101 |
+
+++++++++++++++++++++++++++++++
|
| 102 |
+
|
| 103 |
+
This library provides support for `Unicode IDNA Compatibility
|
| 104 |
+
Processing <https://unicode.org/reports/tr46/>`_ which normalizes input from
|
| 105 |
+
different potential ways a user may input a domain prior to performing the IDNA
|
| 106 |
+
conversion operations. This functionality, known as a
|
| 107 |
+
`mapping <https://tools.ietf.org/html/rfc5895>`_, is considered by the
|
| 108 |
+
specification to be a local user-interface issue distinct from IDNA
|
| 109 |
+
conversion functionality.
|
| 110 |
+
|
| 111 |
+
For example, “Königsgäßchen” is not a permissible label as *LATIN
|
| 112 |
+
CAPITAL LETTER K* is not allowed (nor are capital letters in general).
|
| 113 |
+
UTS 46 will convert this into lower case prior to applying the IDNA
|
| 114 |
+
conversion.
|
| 115 |
+
|
| 116 |
+
.. code-block:: pycon
|
| 117 |
+
|
| 118 |
+
>>> import idna
|
| 119 |
+
>>> idna.encode('Königsgäßchen')
|
| 120 |
+
...
|
| 121 |
+
idna.core.InvalidCodepoint: Codepoint U+004B at position 1 of 'Königsgäßchen' not allowed
|
| 122 |
+
>>> idna.encode('Königsgäßchen', uts46=True)
|
| 123 |
+
b'xn--knigsgchen-b4a3dun'
|
| 124 |
+
>>> print(idna.decode('xn--knigsgchen-b4a3dun'))
|
| 125 |
+
königsgäßchen
|
| 126 |
+
|
| 127 |
+
|
| 128 |
+
Exceptions
|
| 129 |
+
----------
|
| 130 |
+
|
| 131 |
+
All errors raised during the conversion following the specification
|
| 132 |
+
should raise an exception derived from the ``idna.IDNAError`` base
|
| 133 |
+
class.
|
| 134 |
+
|
| 135 |
+
More specific exceptions that may be generated as ``idna.IDNABidiError``
|
| 136 |
+
when the error reflects an illegal combination of left-to-right and
|
| 137 |
+
right-to-left characters in a label; ``idna.InvalidCodepoint`` when
|
| 138 |
+
a specific codepoint is an illegal character in an IDN label (i.e.
|
| 139 |
+
INVALID); and ``idna.InvalidCodepointContext`` when the codepoint is
|
| 140 |
+
illegal based on its position in the string (i.e. it is CONTEXTO or CONTEXTJ
|
| 141 |
+
but the contextual requirements are not satisfied.)
|
| 142 |
+
|
| 143 |
+
Building and Diagnostics
|
| 144 |
+
------------------------
|
| 145 |
+
|
| 146 |
+
The IDNA and UTS 46 functionality relies upon pre-calculated lookup
|
| 147 |
+
tables for performance. These tables are derived from computing against
|
| 148 |
+
eligibility criteria in the respective standards using the command-line
|
| 149 |
+
script ``tools/idna-data``.
|
| 150 |
+
|
| 151 |
+
This tool will fetch relevant codepoint data from the Unicode repository
|
| 152 |
+
and perform the required calculations to identify eligibility. There are
|
| 153 |
+
three main modes:
|
| 154 |
+
|
| 155 |
+
* ``idna-data make-libdata``. Generates ``idnadata.py`` and
|
| 156 |
+
``uts46data.py``, the pre-calculated lookup tables used for IDNA and
|
| 157 |
+
UTS 46 conversions. Implementers who wish to track this library against
|
| 158 |
+
a different Unicode version may use this tool to manually generate a
|
| 159 |
+
different version of the ``idnadata.py`` and ``uts46data.py`` files.
|
| 160 |
+
|
| 161 |
+
* ``idna-data make-table``. Generate a table of the IDNA disposition
|
| 162 |
+
(e.g. PVALID, CONTEXTJ, CONTEXTO) in the format found in Appendix
|
| 163 |
+
B.1 of RFC 5892 and the pre-computed tables published by `IANA
|
| 164 |
+
<https://www.iana.org/>`_.
|
| 165 |
+
|
| 166 |
+
* ``idna-data U+0061``. Prints debugging output on the various
|
| 167 |
+
properties associated with an individual Unicode codepoint (in this
|
| 168 |
+
case, U+0061), that are used to assess the IDNA and UTS 46 status of a
|
| 169 |
+
codepoint. This is helpful in debugging or analysis.
|
| 170 |
+
|
| 171 |
+
The tool accepts a number of arguments, described using ``idna-data
|
| 172 |
+
-h``. Most notably, the ``--version`` argument allows the specification
|
| 173 |
+
of the version of Unicode to be used in computing the table data. For
|
| 174 |
+
example, ``idna-data --version 9.0.0 make-libdata`` will generate
|
| 175 |
+
library data against Unicode 9.0.0.
|
| 176 |
+
|
| 177 |
+
|
| 178 |
+
Additional Notes
|
| 179 |
+
----------------
|
| 180 |
+
|
| 181 |
+
* **Packages**. The latest tagged release version is published in the
|
| 182 |
+
`Python Package Index <https://pypi.org/project/idna/>`_.
|
| 183 |
+
|
| 184 |
+
* **Version support**. This library supports Python 3.8 and higher.
|
| 185 |
+
As this library serves as a low-level toolkit for a variety of
|
| 186 |
+
applications, many of which strive for broad compatibility with older
|
| 187 |
+
Python versions, there is no rush to remove older interpreter support.
|
| 188 |
+
Support for older versions are likely to be removed from new releases
|
| 189 |
+
as automated tests can no longer easily be run, i.e. once the Python
|
| 190 |
+
version is officially end-of-life.
|
| 191 |
+
|
| 192 |
+
* **Testing**. The library has a test suite based on each rule of the
|
| 193 |
+
IDNA specification, as well as tests that are provided as part of the
|
| 194 |
+
Unicode Technical Standard 46, `Unicode IDNA Compatibility Processing
|
| 195 |
+
<https://unicode.org/reports/tr46/>`_.
|
| 196 |
+
|
| 197 |
+
* **Emoji**. It is an occasional request to support emoji domains in
|
| 198 |
+
this library. Encoding of symbols like emoji is expressly prohibited by
|
| 199 |
+
the technical standard IDNA 2008 and emoji domains are broadly phased
|
| 200 |
+
out across the domain industry due to associated security risks. For
|
| 201 |
+
now, applications that need to support these non-compliant labels
|
| 202 |
+
may wish to consider trying the encode/decode operation in this library
|
| 203 |
+
first, and then falling back to using `encodings.idna`. See `the Github
|
| 204 |
+
project <https://github.com/kjd/idna/issues/18>`_ for more discussion.
|
| 205 |
+
|
| 206 |
+
* **Transitional processing**. Unicode 16.0.0 removed transitional
|
| 207 |
+
processing so the `transitional` argument for the encode() method
|
| 208 |
+
no longer has any effect and will be removed at a later date.
|
| 209 |
+
|
env/lib/python3.13/site-packages/idna-3.11.dist-info/RECORD
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
idna-3.11.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
| 2 |
+
idna-3.11.dist-info/METADATA,sha256=fCwSww9SuiN8TIHllFSASUQCW55hAs8dzKnr9RaEEbA,8378
|
| 3 |
+
idna-3.11.dist-info/RECORD,,
|
| 4 |
+
idna-3.11.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
| 5 |
+
idna-3.11.dist-info/licenses/LICENSE.md,sha256=t6M2q_OwThgOwGXN0W5wXQeeHMehT5EKpukYfza5zYc,1541
|
| 6 |
+
idna/__init__.py,sha256=MPqNDLZbXqGaNdXxAFhiqFPKEQXju2jNQhCey6-5eJM,868
|
| 7 |
+
idna/__pycache__/__init__.cpython-313.pyc,,
|
| 8 |
+
idna/__pycache__/codec.cpython-313.pyc,,
|
| 9 |
+
idna/__pycache__/compat.cpython-313.pyc,,
|
| 10 |
+
idna/__pycache__/core.cpython-313.pyc,,
|
| 11 |
+
idna/__pycache__/idnadata.cpython-313.pyc,,
|
| 12 |
+
idna/__pycache__/intranges.cpython-313.pyc,,
|
| 13 |
+
idna/__pycache__/package_data.cpython-313.pyc,,
|
| 14 |
+
idna/__pycache__/uts46data.cpython-313.pyc,,
|
| 15 |
+
idna/codec.py,sha256=M2SGWN7cs_6B32QmKTyTN6xQGZeYQgQ2wiX3_DR6loE,3438
|
| 16 |
+
idna/compat.py,sha256=RzLy6QQCdl9784aFhb2EX9EKGCJjg0P3PilGdeXXcx8,316
|
| 17 |
+
idna/core.py,sha256=P26_XVycuMTZ1R2mNK1ZREVzM5mvTzdabBXfyZVU1Lc,13246
|
| 18 |
+
idna/idnadata.py,sha256=SG8jhaGE53iiD6B49pt2pwTv_UvClciWE-N54oR2p4U,79623
|
| 19 |
+
idna/intranges.py,sha256=amUtkdhYcQG8Zr-CoMM_kVRacxkivC1WgxN1b63KKdU,1898
|
| 20 |
+
idna/package_data.py,sha256=_CUavOxobnbyNG2FLyHoN8QHP3QM9W1tKuw7eq9QwBk,21
|
| 21 |
+
idna/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
| 22 |
+
idna/uts46data.py,sha256=H9J35VkD0F9L9mKOqjeNGd2A-Va6FlPoz6Jz4K7h-ps,243725
|
env/lib/python3.13/site-packages/idna-3.11.dist-info/WHEEL
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Wheel-Version: 1.0
|
| 2 |
+
Generator: flit 3.12.0
|
| 3 |
+
Root-Is-Purelib: true
|
| 4 |
+
Tag: py3-none-any
|
env/lib/python3.13/site-packages/pip-25.1.1.dist-info/INSTALLER
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
pip
|
env/lib/python3.13/site-packages/pip-25.1.1.dist-info/METADATA
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Metadata-Version: 2.4
|
| 2 |
+
Name: pip
|
| 3 |
+
Version: 25.1.1
|
| 4 |
+
Summary: The PyPA recommended tool for installing Python packages.
|
| 5 |
+
Author-email: The pip developers <distutils-sig@python.org>
|
| 6 |
+
License: MIT
|
| 7 |
+
Project-URL: Homepage, https://pip.pypa.io/
|
| 8 |
+
Project-URL: Documentation, https://pip.pypa.io
|
| 9 |
+
Project-URL: Source, https://github.com/pypa/pip
|
| 10 |
+
Project-URL: Changelog, https://pip.pypa.io/en/stable/news/
|
| 11 |
+
Classifier: Development Status :: 5 - Production/Stable
|
| 12 |
+
Classifier: Intended Audience :: Developers
|
| 13 |
+
Classifier: License :: OSI Approved :: MIT License
|
| 14 |
+
Classifier: Topic :: Software Development :: Build Tools
|
| 15 |
+
Classifier: Programming Language :: Python
|
| 16 |
+
Classifier: Programming Language :: Python :: 3
|
| 17 |
+
Classifier: Programming Language :: Python :: 3 :: Only
|
| 18 |
+
Classifier: Programming Language :: Python :: 3.9
|
| 19 |
+
Classifier: Programming Language :: Python :: 3.10
|
| 20 |
+
Classifier: Programming Language :: Python :: 3.11
|
| 21 |
+
Classifier: Programming Language :: Python :: 3.12
|
| 22 |
+
Classifier: Programming Language :: Python :: 3.13
|
| 23 |
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
| 24 |
+
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
| 25 |
+
Requires-Python: >=3.9
|
| 26 |
+
Description-Content-Type: text/x-rst
|
| 27 |
+
License-File: LICENSE.txt
|
| 28 |
+
License-File: AUTHORS.txt
|
| 29 |
+
Dynamic: license-file
|
| 30 |
+
|
| 31 |
+
pip - The Python Package Installer
|
| 32 |
+
==================================
|
| 33 |
+
|
| 34 |
+
.. |pypi-version| image:: https://img.shields.io/pypi/v/pip.svg
|
| 35 |
+
:target: https://pypi.org/project/pip/
|
| 36 |
+
:alt: PyPI
|
| 37 |
+
|
| 38 |
+
.. |python-versions| image:: https://img.shields.io/pypi/pyversions/pip
|
| 39 |
+
:target: https://pypi.org/project/pip
|
| 40 |
+
:alt: PyPI - Python Version
|
| 41 |
+
|
| 42 |
+
.. |docs-badge| image:: https://readthedocs.org/projects/pip/badge/?version=latest
|
| 43 |
+
:target: https://pip.pypa.io/en/latest
|
| 44 |
+
:alt: Documentation
|
| 45 |
+
|
| 46 |
+
|pypi-version| |python-versions| |docs-badge|
|
| 47 |
+
|
| 48 |
+
pip is the `package installer`_ for Python. You can use pip to install packages from the `Python Package Index`_ and other indexes.
|
| 49 |
+
|
| 50 |
+
Please take a look at our documentation for how to install and use pip:
|
| 51 |
+
|
| 52 |
+
* `Installation`_
|
| 53 |
+
* `Usage`_
|
| 54 |
+
|
| 55 |
+
We release updates regularly, with a new version every 3 months. Find more details in our documentation:
|
| 56 |
+
|
| 57 |
+
* `Release notes`_
|
| 58 |
+
* `Release process`_
|
| 59 |
+
|
| 60 |
+
If you find bugs, need help, or want to talk to the developers, please use our mailing lists or chat rooms:
|
| 61 |
+
|
| 62 |
+
* `Issue tracking`_
|
| 63 |
+
* `Discourse channel`_
|
| 64 |
+
* `User IRC`_
|
| 65 |
+
|
| 66 |
+
If you want to get involved head over to GitHub to get the source code, look at our development documentation and feel free to jump on the developer mailing lists and chat rooms:
|
| 67 |
+
|
| 68 |
+
* `GitHub page`_
|
| 69 |
+
* `Development documentation`_
|
| 70 |
+
* `Development IRC`_
|
| 71 |
+
|
| 72 |
+
Code of Conduct
|
| 73 |
+
---------------
|
| 74 |
+
|
| 75 |
+
Everyone interacting in the pip project's codebases, issue trackers, chat
|
| 76 |
+
rooms, and mailing lists is expected to follow the `PSF Code of Conduct`_.
|
| 77 |
+
|
| 78 |
+
.. _package installer: https://packaging.python.org/guides/tool-recommendations/
|
| 79 |
+
.. _Python Package Index: https://pypi.org
|
| 80 |
+
.. _Installation: https://pip.pypa.io/en/stable/installation/
|
| 81 |
+
.. _Usage: https://pip.pypa.io/en/stable/
|
| 82 |
+
.. _Release notes: https://pip.pypa.io/en/stable/news.html
|
| 83 |
+
.. _Release process: https://pip.pypa.io/en/latest/development/release-process/
|
| 84 |
+
.. _GitHub page: https://github.com/pypa/pip
|
| 85 |
+
.. _Development documentation: https://pip.pypa.io/en/latest/development
|
| 86 |
+
.. _Issue tracking: https://github.com/pypa/pip/issues
|
| 87 |
+
.. _Discourse channel: https://discuss.python.org/c/packaging
|
| 88 |
+
.. _User IRC: https://kiwiirc.com/nextclient/#ircs://irc.libera.chat:+6697/pypa
|
| 89 |
+
.. _Development IRC: https://kiwiirc.com/nextclient/#ircs://irc.libera.chat:+6697/pypa-dev
|
| 90 |
+
.. _PSF Code of Conduct: https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md
|
env/lib/python3.13/site-packages/pip-25.1.1.dist-info/RECORD
ADDED
|
@@ -0,0 +1,850 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
../../../bin/pip,sha256=ZUI_bbUCe2twwpOKS6thu0j5JYmwueJBOpX1QrD28xw,270
|
| 2 |
+
../../../bin/pip3,sha256=ZUI_bbUCe2twwpOKS6thu0j5JYmwueJBOpX1QrD28xw,270
|
| 3 |
+
../../../bin/pip3.13,sha256=ZUI_bbUCe2twwpOKS6thu0j5JYmwueJBOpX1QrD28xw,270
|
| 4 |
+
pip-25.1.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
| 5 |
+
pip-25.1.1.dist-info/METADATA,sha256=QFxj1tLpk8hGWrgQLRhJYUpwo_1FqBr43OT0srIZcmU,3649
|
| 6 |
+
pip-25.1.1.dist-info/RECORD,,
|
| 7 |
+
pip-25.1.1.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
| 8 |
+
pip-25.1.1.dist-info/WHEEL,sha256=lTU6B6eIfYoiQJTZNc-fyaR6BpL6ehTzU3xGYxn2n8k,91
|
| 9 |
+
pip-25.1.1.dist-info/entry_points.txt,sha256=eeIjuzfnfR2PrhbjnbzFU6MnSS70kZLxwaHHq6M-bD0,87
|
| 10 |
+
pip-25.1.1.dist-info/licenses/AUTHORS.txt,sha256=YzDFTYpeYnwpmODDFTgyKZNKWcfdO10L5Ex_U6kJLRc,11223
|
| 11 |
+
pip-25.1.1.dist-info/licenses/LICENSE.txt,sha256=Y0MApmnUmurmWxLGxIySTFGkzfPR_whtw0VtyLyqIQQ,1093
|
| 12 |
+
pip-25.1.1.dist-info/top_level.txt,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
| 13 |
+
pip/__init__.py,sha256=zQQ7Na8YWi0IN86IUKEzDAJtyVpXdJXYDkQ536caUiQ,357
|
| 14 |
+
pip/__main__.py,sha256=WzbhHXTbSE6gBY19mNN9m4s5o_365LOvTYSgqgbdBhE,854
|
| 15 |
+
pip/__pip-runner__.py,sha256=JOoEZTwrtv7jRaXBkgSQKAE04yNyfFmGHxqpHiGHvL0,1450
|
| 16 |
+
pip/__pycache__/__init__.cpython-313.pyc,,
|
| 17 |
+
pip/__pycache__/__main__.cpython-313.pyc,,
|
| 18 |
+
pip/__pycache__/__pip-runner__.cpython-313.pyc,,
|
| 19 |
+
pip/_internal/__init__.py,sha256=MfcoOluDZ8QMCFYal04IqOJ9q6m2V7a0aOsnI-WOxUo,513
|
| 20 |
+
pip/_internal/__pycache__/__init__.cpython-313.pyc,,
|
| 21 |
+
pip/_internal/__pycache__/build_env.cpython-313.pyc,,
|
| 22 |
+
pip/_internal/__pycache__/cache.cpython-313.pyc,,
|
| 23 |
+
pip/_internal/__pycache__/configuration.cpython-313.pyc,,
|
| 24 |
+
pip/_internal/__pycache__/exceptions.cpython-313.pyc,,
|
| 25 |
+
pip/_internal/__pycache__/main.cpython-313.pyc,,
|
| 26 |
+
pip/_internal/__pycache__/pyproject.cpython-313.pyc,,
|
| 27 |
+
pip/_internal/__pycache__/self_outdated_check.cpython-313.pyc,,
|
| 28 |
+
pip/_internal/__pycache__/wheel_builder.cpython-313.pyc,,
|
| 29 |
+
pip/_internal/build_env.py,sha256=60_espLI9X3C2db3Ww2gIcyjNk2cAPNcc5gsVO4DOqg,10924
|
| 30 |
+
pip/_internal/cache.py,sha256=SjhJK1C6NbonrU4AyYXKTOH0CGOk5cJrYt60mRANnPM,10368
|
| 31 |
+
pip/_internal/cli/__init__.py,sha256=Iqg_tKA771XuMO1P4t_sDHnSKPzkUb9D0DqunAmw_ko,131
|
| 32 |
+
pip/_internal/cli/__pycache__/__init__.cpython-313.pyc,,
|
| 33 |
+
pip/_internal/cli/__pycache__/autocompletion.cpython-313.pyc,,
|
| 34 |
+
pip/_internal/cli/__pycache__/base_command.cpython-313.pyc,,
|
| 35 |
+
pip/_internal/cli/__pycache__/cmdoptions.cpython-313.pyc,,
|
| 36 |
+
pip/_internal/cli/__pycache__/command_context.cpython-313.pyc,,
|
| 37 |
+
pip/_internal/cli/__pycache__/index_command.cpython-313.pyc,,
|
| 38 |
+
pip/_internal/cli/__pycache__/main.cpython-313.pyc,,
|
| 39 |
+
pip/_internal/cli/__pycache__/main_parser.cpython-313.pyc,,
|
| 40 |
+
pip/_internal/cli/__pycache__/parser.cpython-313.pyc,,
|
| 41 |
+
pip/_internal/cli/__pycache__/progress_bars.cpython-313.pyc,,
|
| 42 |
+
pip/_internal/cli/__pycache__/req_command.cpython-313.pyc,,
|
| 43 |
+
pip/_internal/cli/__pycache__/spinners.cpython-313.pyc,,
|
| 44 |
+
pip/_internal/cli/__pycache__/status_codes.cpython-313.pyc,,
|
| 45 |
+
pip/_internal/cli/autocompletion.py,sha256=fs0Wy16Ga5tX1IZKvww5BDi7i5zyzfCPvu7cgXlgXys,6864
|
| 46 |
+
pip/_internal/cli/base_command.py,sha256=0A8YuJVJh2YyXU8pdW0eidLg1eklCW5cU01mpI-FAxA,8351
|
| 47 |
+
pip/_internal/cli/cmdoptions.py,sha256=VHJ-32dTF1X3iQz1jaVPt3JxksyZcCfGZ5qrStZmvTM,31908
|
| 48 |
+
pip/_internal/cli/command_context.py,sha256=RHgIPwtObh5KhMrd3YZTkl8zbVG-6Okml7YbFX4Ehg0,774
|
| 49 |
+
pip/_internal/cli/index_command.py,sha256=kplkusUgCZy75jNCo-etaDmSG8UvqcR2W50ALDdm6dk,5720
|
| 50 |
+
pip/_internal/cli/main.py,sha256=1bXC7uL3tdb_EZlGVKs6_TgzC9tlKU7zhAZsbZA-IzY,2816
|
| 51 |
+
pip/_internal/cli/main_parser.py,sha256=chZqNmCuO_JYt8ynBCumh4crURaRoXBZ0RxoSYQIwCw,4337
|
| 52 |
+
pip/_internal/cli/parser.py,sha256=VCMtduzECUV87KaHNu-xJ-wLNL82yT3x16V4XBxOAqI,10825
|
| 53 |
+
pip/_internal/cli/progress_bars.py,sha256=r9BD4T2-egcInB1Uh9Jjw3EP9F3INy5kZhGwSePm9jo,4435
|
| 54 |
+
pip/_internal/cli/req_command.py,sha256=1yfssBvnUKNer8D7iT3OHqdJJNdCqRhwDqUFWgieppk,12934
|
| 55 |
+
pip/_internal/cli/spinners.py,sha256=hIJ83GerdFgFCdobIA23Jggetegl_uC4Sp586nzFbPE,5118
|
| 56 |
+
pip/_internal/cli/status_codes.py,sha256=sEFHUaUJbqv8iArL3HAtcztWZmGOFX01hTesSytDEh0,116
|
| 57 |
+
pip/_internal/commands/__init__.py,sha256=3405KyFv4l0ruxeF69oosFanxNQcC_fHBGv7Rpt0PXg,4009
|
| 58 |
+
pip/_internal/commands/__pycache__/__init__.cpython-313.pyc,,
|
| 59 |
+
pip/_internal/commands/__pycache__/cache.cpython-313.pyc,,
|
| 60 |
+
pip/_internal/commands/__pycache__/check.cpython-313.pyc,,
|
| 61 |
+
pip/_internal/commands/__pycache__/completion.cpython-313.pyc,,
|
| 62 |
+
pip/_internal/commands/__pycache__/configuration.cpython-313.pyc,,
|
| 63 |
+
pip/_internal/commands/__pycache__/debug.cpython-313.pyc,,
|
| 64 |
+
pip/_internal/commands/__pycache__/download.cpython-313.pyc,,
|
| 65 |
+
pip/_internal/commands/__pycache__/freeze.cpython-313.pyc,,
|
| 66 |
+
pip/_internal/commands/__pycache__/hash.cpython-313.pyc,,
|
| 67 |
+
pip/_internal/commands/__pycache__/help.cpython-313.pyc,,
|
| 68 |
+
pip/_internal/commands/__pycache__/index.cpython-313.pyc,,
|
| 69 |
+
pip/_internal/commands/__pycache__/inspect.cpython-313.pyc,,
|
| 70 |
+
pip/_internal/commands/__pycache__/install.cpython-313.pyc,,
|
| 71 |
+
pip/_internal/commands/__pycache__/list.cpython-313.pyc,,
|
| 72 |
+
pip/_internal/commands/__pycache__/lock.cpython-313.pyc,,
|
| 73 |
+
pip/_internal/commands/__pycache__/search.cpython-313.pyc,,
|
| 74 |
+
pip/_internal/commands/__pycache__/show.cpython-313.pyc,,
|
| 75 |
+
pip/_internal/commands/__pycache__/uninstall.cpython-313.pyc,,
|
| 76 |
+
pip/_internal/commands/__pycache__/wheel.cpython-313.pyc,,
|
| 77 |
+
pip/_internal/commands/cache.py,sha256=IOezTicHjGE5sWdBx2nwPVgbjuJHM3s-BZEkpZLemuY,8107
|
| 78 |
+
pip/_internal/commands/check.py,sha256=Hr_4eiMd9cgVDgEvjtIdw915NmL7ROIWW8enkr8slPQ,2268
|
| 79 |
+
pip/_internal/commands/completion.py,sha256=W9QFQTPLjy2tPACJ_y3g9EgB1pbsh7pvCUX8ocuIdPg,4554
|
| 80 |
+
pip/_internal/commands/configuration.py,sha256=n98enwp6y0b5G6fiRQjaZo43FlJKYve_daMhN-4BRNc,9766
|
| 81 |
+
pip/_internal/commands/debug.py,sha256=DNDRgE9YsKrbYzU0s3VKi8rHtKF4X13CJ_br_8PUXO0,6797
|
| 82 |
+
pip/_internal/commands/download.py,sha256=0qB0nys6ZEPsog451lDsjL5Bx7Z97t-B80oFZKhpzKM,5273
|
| 83 |
+
pip/_internal/commands/freeze.py,sha256=i9LzK6tJDgtfShSrS38Gn6aCfFlj7K4ZZTMbBwZTPmA,3215
|
| 84 |
+
pip/_internal/commands/hash.py,sha256=EVVOuvGtoPEdFi8SNnmdqlCQrhCxV-kJsdwtdcCnXGQ,1703
|
| 85 |
+
pip/_internal/commands/help.py,sha256=gcc6QDkcgHMOuAn5UxaZwAStsRBrnGSn_yxjS57JIoM,1132
|
| 86 |
+
pip/_internal/commands/index.py,sha256=8UucFVwx6FmM8cNbaPY8iI5kZdV3f6jhqDa-S8aGgpg,5068
|
| 87 |
+
pip/_internal/commands/inspect.py,sha256=PGrY9TRTRCM3y5Ml8Bdk8DEOXquWRfscr4DRo1LOTPc,3189
|
| 88 |
+
pip/_internal/commands/install.py,sha256=SRsiLpead7A8bLdxMqxTAJM3sUFHtgN9zgBT98UQz5E,29757
|
| 89 |
+
pip/_internal/commands/list.py,sha256=3ciKAsDVrmmuUWQKDttrKeGv9N5Dk8lUli8G5Q6YzAE,13371
|
| 90 |
+
pip/_internal/commands/lock.py,sha256=bUYrryKa769UXM61imojoeVVgc_1ZHK-9a0hIJmmlCg,5941
|
| 91 |
+
pip/_internal/commands/search.py,sha256=IrfvxcRCSoZY9A5XAlCF1wtl_y2HPcXslQdHcjzwMNk,5784
|
| 92 |
+
pip/_internal/commands/show.py,sha256=Yh5rGYhR2Io5TkL0fFCMWE1VqqM4xhPHjhbdS3QgEac,8028
|
| 93 |
+
pip/_internal/commands/uninstall.py,sha256=7pOR7enK76gimyxQbzxcG1OsyLXL3DvX939xmM8Fvtg,3892
|
| 94 |
+
pip/_internal/commands/wheel.py,sha256=NEfaVF4f41VBNSn93RL8gkfCEDmdGhbP9xu_dE6cdUk,6346
|
| 95 |
+
pip/_internal/configuration.py,sha256=-KOok6jh3hFzXMPQFPJ1_EFjBpAsge-RSreQuLHLmzo,14005
|
| 96 |
+
pip/_internal/distributions/__init__.py,sha256=Hq6kt6gXBgjNit5hTTWLAzeCNOKoB-N0pGYSqehrli8,858
|
| 97 |
+
pip/_internal/distributions/__pycache__/__init__.cpython-313.pyc,,
|
| 98 |
+
pip/_internal/distributions/__pycache__/base.cpython-313.pyc,,
|
| 99 |
+
pip/_internal/distributions/__pycache__/installed.cpython-313.pyc,,
|
| 100 |
+
pip/_internal/distributions/__pycache__/sdist.cpython-313.pyc,,
|
| 101 |
+
pip/_internal/distributions/__pycache__/wheel.cpython-313.pyc,,
|
| 102 |
+
pip/_internal/distributions/base.py,sha256=QeB9qvKXDIjLdPBDE5fMgpfGqMMCr-govnuoQnGuiF8,1783
|
| 103 |
+
pip/_internal/distributions/installed.py,sha256=QinHFbWAQ8oE0pbD8MFZWkwlnfU1QYTccA1vnhrlYOU,842
|
| 104 |
+
pip/_internal/distributions/sdist.py,sha256=PlcP4a6-R6c98XnOM-b6Lkb3rsvh9iG4ok8shaanrzs,6751
|
| 105 |
+
pip/_internal/distributions/wheel.py,sha256=THBYfnv7VVt8mYhMYUtH13S1E7FDwtDyDfmUcl8ai0E,1317
|
| 106 |
+
pip/_internal/exceptions.py,sha256=wpE11H0e4L9G6AH70sRG149z82X7wX530HK-9eA_DIQ,28464
|
| 107 |
+
pip/_internal/index/__init__.py,sha256=tzwMH_fhQeubwMqHdSivasg1cRgTSbNg2CiMVnzMmyU,29
|
| 108 |
+
pip/_internal/index/__pycache__/__init__.cpython-313.pyc,,
|
| 109 |
+
pip/_internal/index/__pycache__/collector.cpython-313.pyc,,
|
| 110 |
+
pip/_internal/index/__pycache__/package_finder.cpython-313.pyc,,
|
| 111 |
+
pip/_internal/index/__pycache__/sources.cpython-313.pyc,,
|
| 112 |
+
pip/_internal/index/collector.py,sha256=RdPO0JLAlmyBWPAWYHPyRoGjz3GNAeTngCNkbGey_mE,16265
|
| 113 |
+
pip/_internal/index/package_finder.py,sha256=RohRzzLExoXl7QDdTiqyxIaQEcHUn6UNOr9KzC1vjL0,38446
|
| 114 |
+
pip/_internal/index/sources.py,sha256=lPBLK5Xiy8Q6IQMio26Wl7ocfZOKkgGklIBNyUJ23fI,8632
|
| 115 |
+
pip/_internal/locations/__init__.py,sha256=vvTMNxghT0aEXrSdqpNtuRDGx08bzJxfDAUUfQ0Vb0A,14309
|
| 116 |
+
pip/_internal/locations/__pycache__/__init__.cpython-313.pyc,,
|
| 117 |
+
pip/_internal/locations/__pycache__/_distutils.cpython-313.pyc,,
|
| 118 |
+
pip/_internal/locations/__pycache__/_sysconfig.cpython-313.pyc,,
|
| 119 |
+
pip/_internal/locations/__pycache__/base.cpython-313.pyc,,
|
| 120 |
+
pip/_internal/locations/_distutils.py,sha256=x6nyVLj7X11Y4khIdf-mFlxMl2FWadtVEgeb8upc_WI,6013
|
| 121 |
+
pip/_internal/locations/_sysconfig.py,sha256=IGzds60qsFneRogC-oeBaY7bEh3lPt_v47kMJChQXsU,7724
|
| 122 |
+
pip/_internal/locations/base.py,sha256=RQiPi1d4FVM2Bxk04dQhXZ2PqkeljEL2fZZ9SYqIQ78,2556
|
| 123 |
+
pip/_internal/main.py,sha256=r-UnUe8HLo5XFJz8inTcOOTiu_sxNhgHb6VwlGUllOI,340
|
| 124 |
+
pip/_internal/metadata/__init__.py,sha256=nGWuZvjQlIHudlMz_-bsUs2LDA2ZKNPGevZoEGcd64Y,5723
|
| 125 |
+
pip/_internal/metadata/__pycache__/__init__.cpython-313.pyc,,
|
| 126 |
+
pip/_internal/metadata/__pycache__/_json.cpython-313.pyc,,
|
| 127 |
+
pip/_internal/metadata/__pycache__/base.cpython-313.pyc,,
|
| 128 |
+
pip/_internal/metadata/__pycache__/pkg_resources.cpython-313.pyc,,
|
| 129 |
+
pip/_internal/metadata/_json.py,sha256=ezrIYazHCINM2QUk1eA9wEAMj3aeGWeDVgGalgUzKpc,2707
|
| 130 |
+
pip/_internal/metadata/base.py,sha256=jCbzdIc8MgWnPR4rfrvSQhSVzSoOyKOXhj3xe8BoG8c,25467
|
| 131 |
+
pip/_internal/metadata/importlib/__init__.py,sha256=jUUidoxnHcfITHHaAWG1G2i5fdBYklv_uJcjo2x7VYE,135
|
| 132 |
+
pip/_internal/metadata/importlib/__pycache__/__init__.cpython-313.pyc,,
|
| 133 |
+
pip/_internal/metadata/importlib/__pycache__/_compat.cpython-313.pyc,,
|
| 134 |
+
pip/_internal/metadata/importlib/__pycache__/_dists.cpython-313.pyc,,
|
| 135 |
+
pip/_internal/metadata/importlib/__pycache__/_envs.cpython-313.pyc,,
|
| 136 |
+
pip/_internal/metadata/importlib/_compat.py,sha256=c6av8sP8BBjAZuFSJow1iWfygUXNM3xRTCn5nqw6B9M,2796
|
| 137 |
+
pip/_internal/metadata/importlib/_dists.py,sha256=ftmYiyfUGUIjnVwt6W-Ijsimy5c28KgmXly5Q5IQ2P4,8279
|
| 138 |
+
pip/_internal/metadata/importlib/_envs.py,sha256=X63CkdAPJCYPhefYSLiQzPf9ijMXm5nL_A_Z68yp2-w,5297
|
| 139 |
+
pip/_internal/metadata/pkg_resources.py,sha256=U07ETAINSGeSRBfWUG93E4tZZbaW_f7PGzEqZN0hulc,10542
|
| 140 |
+
pip/_internal/models/__init__.py,sha256=AjmCEBxX_MH9f_jVjIGNCFJKYCYeSEe18yyvNx4uRKQ,62
|
| 141 |
+
pip/_internal/models/__pycache__/__init__.cpython-313.pyc,,
|
| 142 |
+
pip/_internal/models/__pycache__/candidate.cpython-313.pyc,,
|
| 143 |
+
pip/_internal/models/__pycache__/direct_url.cpython-313.pyc,,
|
| 144 |
+
pip/_internal/models/__pycache__/format_control.cpython-313.pyc,,
|
| 145 |
+
pip/_internal/models/__pycache__/index.cpython-313.pyc,,
|
| 146 |
+
pip/_internal/models/__pycache__/installation_report.cpython-313.pyc,,
|
| 147 |
+
pip/_internal/models/__pycache__/link.cpython-313.pyc,,
|
| 148 |
+
pip/_internal/models/__pycache__/pylock.cpython-313.pyc,,
|
| 149 |
+
pip/_internal/models/__pycache__/scheme.cpython-313.pyc,,
|
| 150 |
+
pip/_internal/models/__pycache__/search_scope.cpython-313.pyc,,
|
| 151 |
+
pip/_internal/models/__pycache__/selection_prefs.cpython-313.pyc,,
|
| 152 |
+
pip/_internal/models/__pycache__/target_python.cpython-313.pyc,,
|
| 153 |
+
pip/_internal/models/__pycache__/wheel.cpython-313.pyc,,
|
| 154 |
+
pip/_internal/models/candidate.py,sha256=zzgFRuw_kWPjKpGw7LC0ZUMD2CQ2EberUIYs8izjdCA,753
|
| 155 |
+
pip/_internal/models/direct_url.py,sha256=lJ1fIVTgk5UG5SzTNR0FpgSGAQjChlH-3otgiEJAhIs,6576
|
| 156 |
+
pip/_internal/models/format_control.py,sha256=wtsQqSK9HaUiNxQEuB-C62eVimw6G4_VQFxV9-_KDBE,2486
|
| 157 |
+
pip/_internal/models/index.py,sha256=tYnL8oxGi4aSNWur0mG8DAP7rC6yuha_MwJO8xw0crI,1030
|
| 158 |
+
pip/_internal/models/installation_report.py,sha256=zRVZoaz-2vsrezj_H3hLOhMZCK9c7TbzWgC-jOalD00,2818
|
| 159 |
+
pip/_internal/models/link.py,sha256=wIAgxhiu05ycLhbtAibknXX5L6X9ju_PPLVnMcvh9B4,21511
|
| 160 |
+
pip/_internal/models/pylock.py,sha256=n3-I26bf2v-Kn6qcx4ATB_Zel2SLhaUxZBmsMeGgYAo,6196
|
| 161 |
+
pip/_internal/models/scheme.py,sha256=PakmHJM3e8OOWSZFtfz1Az7f1meONJnkGuQxFlt3wBE,575
|
| 162 |
+
pip/_internal/models/search_scope.py,sha256=67NEnsYY84784S-MM7ekQuo9KXLH-7MzFntXjapvAo0,4531
|
| 163 |
+
pip/_internal/models/selection_prefs.py,sha256=qaFfDs3ciqoXPg6xx45N1jPLqccLJw4N0s4P0PyHTQ8,2015
|
| 164 |
+
pip/_internal/models/target_python.py,sha256=2XaH2rZ5ZF-K5wcJbEMGEl7SqrTToDDNkrtQ2v_v_-Q,4271
|
| 165 |
+
pip/_internal/models/wheel.py,sha256=10NUTXIRjf2P8oe1Wzolv8oUv7-YurrOduVFUIaDhdM,5506
|
| 166 |
+
pip/_internal/network/__init__.py,sha256=FMy06P__y6jMjUc8z3ZcQdKF-pmZ2zM14_vBeHPGhUI,49
|
| 167 |
+
pip/_internal/network/__pycache__/__init__.cpython-313.pyc,,
|
| 168 |
+
pip/_internal/network/__pycache__/auth.cpython-313.pyc,,
|
| 169 |
+
pip/_internal/network/__pycache__/cache.cpython-313.pyc,,
|
| 170 |
+
pip/_internal/network/__pycache__/download.cpython-313.pyc,,
|
| 171 |
+
pip/_internal/network/__pycache__/lazy_wheel.cpython-313.pyc,,
|
| 172 |
+
pip/_internal/network/__pycache__/session.cpython-313.pyc,,
|
| 173 |
+
pip/_internal/network/__pycache__/utils.cpython-313.pyc,,
|
| 174 |
+
pip/_internal/network/__pycache__/xmlrpc.cpython-313.pyc,,
|
| 175 |
+
pip/_internal/network/auth.py,sha256=D4gASjUrqoDFlSt6gQ767KAAjv6PUyJU0puDlhXNVRE,20809
|
| 176 |
+
pip/_internal/network/cache.py,sha256=JGYT-BUaSMdEBwII_K1UE6qyBItz7hzGkyLl_JRzkBY,4613
|
| 177 |
+
pip/_internal/network/download.py,sha256=6IdZyoERWIsXXFUFL_h_e_xi8Z0G0UlpkodPy8qKv2U,11078
|
| 178 |
+
pip/_internal/network/lazy_wheel.py,sha256=PBdoMoNQQIA84Fhgne38jWF52W4x_KtsHjxgv4dkRKA,7622
|
| 179 |
+
pip/_internal/network/session.py,sha256=msM4es16LmmNEYNkrYyg8fTc7gAHbKFltawfKP27LOI,18771
|
| 180 |
+
pip/_internal/network/utils.py,sha256=Inaxel-NxBu4PQWkjyErdnfewsFCcgHph7dzR1-FboY,4088
|
| 181 |
+
pip/_internal/network/xmlrpc.py,sha256=jW9oDSWamMld3iZOO9RbonVC8ZStkHyppCszoevkuJg,1837
|
| 182 |
+
pip/_internal/operations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
| 183 |
+
pip/_internal/operations/__pycache__/__init__.cpython-313.pyc,,
|
| 184 |
+
pip/_internal/operations/__pycache__/check.cpython-313.pyc,,
|
| 185 |
+
pip/_internal/operations/__pycache__/freeze.cpython-313.pyc,,
|
| 186 |
+
pip/_internal/operations/__pycache__/prepare.cpython-313.pyc,,
|
| 187 |
+
pip/_internal/operations/build/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
| 188 |
+
pip/_internal/operations/build/__pycache__/__init__.cpython-313.pyc,,
|
| 189 |
+
pip/_internal/operations/build/__pycache__/build_tracker.cpython-313.pyc,,
|
| 190 |
+
pip/_internal/operations/build/__pycache__/metadata.cpython-313.pyc,,
|
| 191 |
+
pip/_internal/operations/build/__pycache__/metadata_editable.cpython-313.pyc,,
|
| 192 |
+
pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-313.pyc,,
|
| 193 |
+
pip/_internal/operations/build/__pycache__/wheel.cpython-313.pyc,,
|
| 194 |
+
pip/_internal/operations/build/__pycache__/wheel_editable.cpython-313.pyc,,
|
| 195 |
+
pip/_internal/operations/build/__pycache__/wheel_legacy.cpython-313.pyc,,
|
| 196 |
+
pip/_internal/operations/build/build_tracker.py,sha256=-ARW_TcjHCOX7D2NUOGntB4Fgc6b4aolsXkAK6BWL7w,4774
|
| 197 |
+
pip/_internal/operations/build/metadata.py,sha256=INHaeiRfOiLYCXApfDNRo9Cw2xI4VwTc0KItvfdfOjk,1421
|
| 198 |
+
pip/_internal/operations/build/metadata_editable.py,sha256=oWudMsnjy4loO_Jy7g4N9nxsnaEX_iDlVRgCy7pu1rs,1509
|
| 199 |
+
pip/_internal/operations/build/metadata_legacy.py,sha256=wv8cFA0wTqF62Jlm9QwloYZsofOyQ7sWBBmvCcVvn1k,2189
|
| 200 |
+
pip/_internal/operations/build/wheel.py,sha256=sT12FBLAxDC6wyrDorh8kvcZ1jG5qInCRWzzP-UkJiQ,1075
|
| 201 |
+
pip/_internal/operations/build/wheel_editable.py,sha256=yOtoH6zpAkoKYEUtr8FhzrYnkNHQaQBjWQ2HYae1MQg,1417
|
| 202 |
+
pip/_internal/operations/build/wheel_legacy.py,sha256=KXpyGYoCQYcudXNZvohLXgWHaCk4Gf3z0dbS9ol4uu0,3620
|
| 203 |
+
pip/_internal/operations/check.py,sha256=4cnD_2eglsDe5s2CoYkxDt4HcRitTywzLMfTZ-tGQ4U,5911
|
| 204 |
+
pip/_internal/operations/freeze.py,sha256=1_M79jAQKnCxWr-KCCmHuVXOVFGaUJHmoWLfFzgh7K4,9843
|
| 205 |
+
pip/_internal/operations/install/__init__.py,sha256=ak-UETcQPKlFZaWoYKWu5QVXbpFBvg0sXc3i0O4vSYY,50
|
| 206 |
+
pip/_internal/operations/install/__pycache__/__init__.cpython-313.pyc,,
|
| 207 |
+
pip/_internal/operations/install/__pycache__/editable_legacy.cpython-313.pyc,,
|
| 208 |
+
pip/_internal/operations/install/__pycache__/wheel.cpython-313.pyc,,
|
| 209 |
+
pip/_internal/operations/install/editable_legacy.py,sha256=TI6wT8sLqDTprWZLYEOBOe7a6-1B9uwKb7kTBxLIaWY,1282
|
| 210 |
+
pip/_internal/operations/install/wheel.py,sha256=4NYSQ9ypl69iiduh5gUPCK3WNYqouTHZ0rMXoVgkiZw,27553
|
| 211 |
+
pip/_internal/operations/prepare.py,sha256=-i9dYwwJJjN7h6sZTabcz84tizgn7EAsY0sHnLAfs3Q,28363
|
| 212 |
+
pip/_internal/pyproject.py,sha256=GLJ6rWRS5_2noKdajohoLyDty57Z7QXhcUAYghmTnWc,7286
|
| 213 |
+
pip/_internal/req/__init__.py,sha256=dX2QGlfDwEqE5pLjOeM-f2qEgXFn6f2Vdi_zIHAYy1k,3096
|
| 214 |
+
pip/_internal/req/__pycache__/__init__.cpython-313.pyc,,
|
| 215 |
+
pip/_internal/req/__pycache__/constructors.cpython-313.pyc,,
|
| 216 |
+
pip/_internal/req/__pycache__/req_dependency_group.cpython-313.pyc,,
|
| 217 |
+
pip/_internal/req/__pycache__/req_file.cpython-313.pyc,,
|
| 218 |
+
pip/_internal/req/__pycache__/req_install.cpython-313.pyc,,
|
| 219 |
+
pip/_internal/req/__pycache__/req_set.cpython-313.pyc,,
|
| 220 |
+
pip/_internal/req/__pycache__/req_uninstall.cpython-313.pyc,,
|
| 221 |
+
pip/_internal/req/constructors.py,sha256=v1qzCN1mIldwx-nCrPc8JO4lxkm3Fv8M5RWvt8LISjc,18430
|
| 222 |
+
pip/_internal/req/req_dependency_group.py,sha256=5PGuZidqwDeTHZkP4tnNrlPrasfvJBONd1B5S0146zs,2677
|
| 223 |
+
pip/_internal/req/req_file.py,sha256=eys82McgaICOGic2UZRHjD720piKJPwmeSYdXlWwl6w,20234
|
| 224 |
+
pip/_internal/req/req_install.py,sha256=gMoFak9zrhjHlHaOQxPFheHKtIobppFgq1WrKel_nTE,35788
|
| 225 |
+
pip/_internal/req/req_set.py,sha256=j3esG0s6SzoVReX9rWn4rpYNtyET_fwxbwJPRimvRxo,2858
|
| 226 |
+
pip/_internal/req/req_uninstall.py,sha256=PQ6SyocDycUYsLAsTpjkbdwO_qjdo-y8BvQfZ5Avdrw,24075
|
| 227 |
+
pip/_internal/resolution/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
| 228 |
+
pip/_internal/resolution/__pycache__/__init__.cpython-313.pyc,,
|
| 229 |
+
pip/_internal/resolution/__pycache__/base.cpython-313.pyc,,
|
| 230 |
+
pip/_internal/resolution/base.py,sha256=qlmh325SBVfvG6Me9gc5Nsh5sdwHBwzHBq6aEXtKsLA,583
|
| 231 |
+
pip/_internal/resolution/legacy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
| 232 |
+
pip/_internal/resolution/legacy/__pycache__/__init__.cpython-313.pyc,,
|
| 233 |
+
pip/_internal/resolution/legacy/__pycache__/resolver.cpython-313.pyc,,
|
| 234 |
+
pip/_internal/resolution/legacy/resolver.py,sha256=3HZiJBRd1FTN6jQpI4qRO8-TbLYeIbUTS6PFvXnXs2w,24068
|
| 235 |
+
pip/_internal/resolution/resolvelib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
| 236 |
+
pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-313.pyc,,
|
| 237 |
+
pip/_internal/resolution/resolvelib/__pycache__/base.cpython-313.pyc,,
|
| 238 |
+
pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-313.pyc,,
|
| 239 |
+
pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-313.pyc,,
|
| 240 |
+
pip/_internal/resolution/resolvelib/__pycache__/found_candidates.cpython-313.pyc,,
|
| 241 |
+
pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-313.pyc,,
|
| 242 |
+
pip/_internal/resolution/resolvelib/__pycache__/reporter.cpython-313.pyc,,
|
| 243 |
+
pip/_internal/resolution/resolvelib/__pycache__/requirements.cpython-313.pyc,,
|
| 244 |
+
pip/_internal/resolution/resolvelib/__pycache__/resolver.cpython-313.pyc,,
|
| 245 |
+
pip/_internal/resolution/resolvelib/base.py,sha256=DCf669FsqyQY5uqXeePDHQY1e4QO-pBzWH8O0s9-K94,5023
|
| 246 |
+
pip/_internal/resolution/resolvelib/candidates.py,sha256=U3Qp83jhM_RiJviyrlPCijbps6wYO6VsTDaTnCf_B3o,20241
|
| 247 |
+
pip/_internal/resolution/resolvelib/factory.py,sha256=FCvHc9M8UJ_7iU63QtPiHuq_BmfdnBiMJ8WaDBJNFxk,32668
|
| 248 |
+
pip/_internal/resolution/resolvelib/found_candidates.py,sha256=6lAF_pLQ2_Z0CBOHIFxGp6NfvT1uwIpCui6e-GgI5tk,6000
|
| 249 |
+
pip/_internal/resolution/resolvelib/provider.py,sha256=8ptYOOjfa336D4FZ751EQHR0LDq8jJhIGJXDou8Cv8Y,11190
|
| 250 |
+
pip/_internal/resolution/resolvelib/reporter.py,sha256=EwJAHOjWZ8eTHQWss7zJjmQEj6ooP6oWSwwVXFtgpqQ,3260
|
| 251 |
+
pip/_internal/resolution/resolvelib/requirements.py,sha256=7JG4Z72e5Yk4vU0S5ulGvbqTy4FMQGYhY5zQhX9zTtY,8065
|
| 252 |
+
pip/_internal/resolution/resolvelib/resolver.py,sha256=9zcR4c7UZV1j2ILTmb68Ck_5HdvQvf4cmTBE2bWHkKg,12785
|
| 253 |
+
pip/_internal/self_outdated_check.py,sha256=1PFtttvLAeyCVR3tPoBq2sOlPD0IJ-KSqU6bc1HUk9c,8318
|
| 254 |
+
pip/_internal/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
| 255 |
+
pip/_internal/utils/__pycache__/__init__.cpython-313.pyc,,
|
| 256 |
+
pip/_internal/utils/__pycache__/_jaraco_text.cpython-313.pyc,,
|
| 257 |
+
pip/_internal/utils/__pycache__/_log.cpython-313.pyc,,
|
| 258 |
+
pip/_internal/utils/__pycache__/appdirs.cpython-313.pyc,,
|
| 259 |
+
pip/_internal/utils/__pycache__/compat.cpython-313.pyc,,
|
| 260 |
+
pip/_internal/utils/__pycache__/compatibility_tags.cpython-313.pyc,,
|
| 261 |
+
pip/_internal/utils/__pycache__/datetime.cpython-313.pyc,,
|
| 262 |
+
pip/_internal/utils/__pycache__/deprecation.cpython-313.pyc,,
|
| 263 |
+
pip/_internal/utils/__pycache__/direct_url_helpers.cpython-313.pyc,,
|
| 264 |
+
pip/_internal/utils/__pycache__/egg_link.cpython-313.pyc,,
|
| 265 |
+
pip/_internal/utils/__pycache__/entrypoints.cpython-313.pyc,,
|
| 266 |
+
pip/_internal/utils/__pycache__/filesystem.cpython-313.pyc,,
|
| 267 |
+
pip/_internal/utils/__pycache__/filetypes.cpython-313.pyc,,
|
| 268 |
+
pip/_internal/utils/__pycache__/glibc.cpython-313.pyc,,
|
| 269 |
+
pip/_internal/utils/__pycache__/hashes.cpython-313.pyc,,
|
| 270 |
+
pip/_internal/utils/__pycache__/logging.cpython-313.pyc,,
|
| 271 |
+
pip/_internal/utils/__pycache__/misc.cpython-313.pyc,,
|
| 272 |
+
pip/_internal/utils/__pycache__/packaging.cpython-313.pyc,,
|
| 273 |
+
pip/_internal/utils/__pycache__/retry.cpython-313.pyc,,
|
| 274 |
+
pip/_internal/utils/__pycache__/setuptools_build.cpython-313.pyc,,
|
| 275 |
+
pip/_internal/utils/__pycache__/subprocess.cpython-313.pyc,,
|
| 276 |
+
pip/_internal/utils/__pycache__/temp_dir.cpython-313.pyc,,
|
| 277 |
+
pip/_internal/utils/__pycache__/unpacking.cpython-313.pyc,,
|
| 278 |
+
pip/_internal/utils/__pycache__/urls.cpython-313.pyc,,
|
| 279 |
+
pip/_internal/utils/__pycache__/virtualenv.cpython-313.pyc,,
|
| 280 |
+
pip/_internal/utils/__pycache__/wheel.cpython-313.pyc,,
|
| 281 |
+
pip/_internal/utils/_jaraco_text.py,sha256=M15uUPIh5NpP1tdUGBxRau6q1ZAEtI8-XyLEETscFfE,3350
|
| 282 |
+
pip/_internal/utils/_log.py,sha256=-jHLOE_THaZz5BFcCnoSL9EYAtJ0nXem49s9of4jvKw,1015
|
| 283 |
+
pip/_internal/utils/appdirs.py,sha256=zrIISCn2QxlXYw-zJZZBTrFNTyy_0WNKiI-TOoN6wJo,1705
|
| 284 |
+
pip/_internal/utils/compat.py,sha256=ckkFveBiYQjRWjkNsajt_oWPS57tJvE8XxoC4OIYgCY,2399
|
| 285 |
+
pip/_internal/utils/compatibility_tags.py,sha256=q5W7IrNlqC5ke0AqWRG6aX5pimiqh--xuPCCNwCKPsU,6662
|
| 286 |
+
pip/_internal/utils/datetime.py,sha256=Gt29Ml4ToPSM88j54iu43WKtrU9A-moP4QmMiiqzedU,241
|
| 287 |
+
pip/_internal/utils/deprecation.py,sha256=k7Qg_UBAaaTdyq82YVARA6D7RmcGTXGv7fnfcgigj4Q,3707
|
| 288 |
+
pip/_internal/utils/direct_url_helpers.py,sha256=r2MRtkVDACv9AGqYODBUC9CjwgtsUU1s68hmgfCJMtA,3196
|
| 289 |
+
pip/_internal/utils/egg_link.py,sha256=0FePZoUYKv4RGQ2t6x7w5Z427wbA_Uo3WZnAkrgsuqo,2463
|
| 290 |
+
pip/_internal/utils/entrypoints.py,sha256=4CheZ81OBPPLb3Gn-X_WEPtllUibpwDVzlVQ4RFh7PM,3325
|
| 291 |
+
pip/_internal/utils/filesystem.py,sha256=ajvA-q4ocliW9kPp8Yquh-4vssXbu-UKbo5FV9V4X64,4950
|
| 292 |
+
pip/_internal/utils/filetypes.py,sha256=OCPzUxq3Aa6k_95MiI8DYgkOzutTs47fA-v-vYUJp9E,715
|
| 293 |
+
pip/_internal/utils/glibc.py,sha256=vUkWq_1pJuzcYNcGKLlQmABoUiisK8noYY1yc8Wq4w4,3734
|
| 294 |
+
pip/_internal/utils/hashes.py,sha256=XGGLL0AG8-RhWnyz87xF6MFZ--BKadHU35D47eApCKI,4972
|
| 295 |
+
pip/_internal/utils/logging.py,sha256=zMZK1NxfhM4QMGUyaU9q1grNuDhLSVbSkGCvZBKmaPw,12076
|
| 296 |
+
pip/_internal/utils/misc.py,sha256=DWnYxBUItjRp7hhxEg4ih6P6YpKrykM86dbi_EcU8SQ,23450
|
| 297 |
+
pip/_internal/utils/packaging.py,sha256=CjJOqLNENW-U88ojOllVL40f1ab2W2Bm3KHCavwNNfw,1603
|
| 298 |
+
pip/_internal/utils/retry.py,sha256=mhFbykXjhTnZfgzeuy-vl9c8nECnYn_CMtwNJX2tYzQ,1392
|
| 299 |
+
pip/_internal/utils/setuptools_build.py,sha256=J9EyRantVgu4V-xS_qfQy2mcPLVUM7A-227QdKGUZCA,4482
|
| 300 |
+
pip/_internal/utils/subprocess.py,sha256=EsvqSRiSMHF98T8Txmu6NLU3U--MpTTQjtNgKP0P--M,8988
|
| 301 |
+
pip/_internal/utils/temp_dir.py,sha256=5qOXe8M4JeY6vaFQM867d5zkp1bSwMZ-KT5jymmP0Zg,9310
|
| 302 |
+
pip/_internal/utils/unpacking.py,sha256=4yCqlRAI2zxl5tfxlnLoWLNcEn-k1c3vaet_oaJ42iI,11926
|
| 303 |
+
pip/_internal/utils/urls.py,sha256=qceSOZb5lbNDrHNsv7_S4L4Ytszja5NwPKUMnZHbYnM,1599
|
| 304 |
+
pip/_internal/utils/virtualenv.py,sha256=S6f7csYorRpiD6cvn3jISZYc3I8PJC43H5iMFpRAEDU,3456
|
| 305 |
+
pip/_internal/utils/wheel.py,sha256=MHObYn6d7VyZL10i-W1xoJZ2hT5-wB1WkII70AsYUE8,4493
|
| 306 |
+
pip/_internal/vcs/__init__.py,sha256=UAqvzpbi0VbZo3Ub6skEeZAw-ooIZR-zX_WpCbxyCoU,596
|
| 307 |
+
pip/_internal/vcs/__pycache__/__init__.cpython-313.pyc,,
|
| 308 |
+
pip/_internal/vcs/__pycache__/bazaar.cpython-313.pyc,,
|
| 309 |
+
pip/_internal/vcs/__pycache__/git.cpython-313.pyc,,
|
| 310 |
+
pip/_internal/vcs/__pycache__/mercurial.cpython-313.pyc,,
|
| 311 |
+
pip/_internal/vcs/__pycache__/subversion.cpython-313.pyc,,
|
| 312 |
+
pip/_internal/vcs/__pycache__/versioncontrol.cpython-313.pyc,,
|
| 313 |
+
pip/_internal/vcs/bazaar.py,sha256=EKStcQaKpNu0NK4p5Q10Oc4xb3DUxFw024XrJy40bFQ,3528
|
| 314 |
+
pip/_internal/vcs/git.py,sha256=3KLPrKsDL9xZchmz4H1Obo8fM2Fh8ChrhtDHWjbkj-I,18591
|
| 315 |
+
pip/_internal/vcs/mercurial.py,sha256=oULOhzJ2Uie-06d1omkL-_Gc6meGaUkyogvqG9ZCyPs,5249
|
| 316 |
+
pip/_internal/vcs/subversion.py,sha256=ddTugHBqHzV3ebKlU5QXHPN4gUqlyXbOx8q8NgXKvs8,11735
|
| 317 |
+
pip/_internal/vcs/versioncontrol.py,sha256=cvf_-hnTAjQLXJ3d17FMNhQfcO1AcKWUF10tfrYyP-c,22440
|
| 318 |
+
pip/_internal/wheel_builder.py,sha256=Z5Z2ANADbKdSHY9BHqw9zG5-1AxstO6YM6m9yLWe7Vw,11212
|
| 319 |
+
pip/_vendor/__init__.py,sha256=WzusPTGWIMeQQWSVJ0h2rafGkVTa9WKJ2HT-2-EoZrU,4907
|
| 320 |
+
pip/_vendor/__pycache__/__init__.cpython-313.pyc,,
|
| 321 |
+
pip/_vendor/__pycache__/typing_extensions.cpython-313.pyc,,
|
| 322 |
+
pip/_vendor/cachecontrol/__init__.py,sha256=x9ecUkiwNvAGfE3g0eaRx3VrJZnZWAluA2LRcvab3HQ,677
|
| 323 |
+
pip/_vendor/cachecontrol/__pycache__/__init__.cpython-313.pyc,,
|
| 324 |
+
pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-313.pyc,,
|
| 325 |
+
pip/_vendor/cachecontrol/__pycache__/adapter.cpython-313.pyc,,
|
| 326 |
+
pip/_vendor/cachecontrol/__pycache__/cache.cpython-313.pyc,,
|
| 327 |
+
pip/_vendor/cachecontrol/__pycache__/controller.cpython-313.pyc,,
|
| 328 |
+
pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-313.pyc,,
|
| 329 |
+
pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-313.pyc,,
|
| 330 |
+
pip/_vendor/cachecontrol/__pycache__/serialize.cpython-313.pyc,,
|
| 331 |
+
pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-313.pyc,,
|
| 332 |
+
pip/_vendor/cachecontrol/_cmd.py,sha256=iist2EpzJvDVIhMAxXq8iFnTBsiZAd6iplxfmNboNyk,1737
|
| 333 |
+
pip/_vendor/cachecontrol/adapter.py,sha256=8y6rTPXOzVHmDKCW5CR9sivLVuDv-cpdGcZYdRWNaPw,6599
|
| 334 |
+
pip/_vendor/cachecontrol/cache.py,sha256=OXwv7Fn2AwnKNiahJHnjtvaKLndvVLv_-zO-ltlV9qI,1953
|
| 335 |
+
pip/_vendor/cachecontrol/caches/__init__.py,sha256=dtrrroK5BnADR1GWjCZ19aZ0tFsMfvFBtLQQU1sp_ag,303
|
| 336 |
+
pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-313.pyc,,
|
| 337 |
+
pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-313.pyc,,
|
| 338 |
+
pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-313.pyc,,
|
| 339 |
+
pip/_vendor/cachecontrol/caches/file_cache.py,sha256=d8upFmy_zwaCmlbWEVBlLXFddt8Zw8c5SFpxeOZsdfw,4117
|
| 340 |
+
pip/_vendor/cachecontrol/caches/redis_cache.py,sha256=9rmqwtYu_ljVkW6_oLqbC7EaX_a8YT_yLuna-eS0dgo,1386
|
| 341 |
+
pip/_vendor/cachecontrol/controller.py,sha256=cx0Hl8xLZgUuXuy78Gih9AYjCtqurmYjVJxyA4yWt7w,19101
|
| 342 |
+
pip/_vendor/cachecontrol/filewrapper.py,sha256=2ktXNPE0KqnyzF24aOsKCA58HQq1xeC6l2g6_zwjghc,4291
|
| 343 |
+
pip/_vendor/cachecontrol/heuristics.py,sha256=gqMXU8w0gQuEQiSdu3Yg-0vd9kW7nrWKbLca75rheGE,4881
|
| 344 |
+
pip/_vendor/cachecontrol/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
| 345 |
+
pip/_vendor/cachecontrol/serialize.py,sha256=HQd2IllQ05HzPkVLMXTF2uX5mjEQjDBkxCqUJUODpZk,5163
|
| 346 |
+
pip/_vendor/cachecontrol/wrapper.py,sha256=hsGc7g8QGQTT-4f8tgz3AM5qwScg6FO0BSdLSRdEvpU,1417
|
| 347 |
+
pip/_vendor/certifi/__init__.py,sha256=neIaAf7BM36ygmQCmy-ZsSyjnvjWghFeu13wwEAnjj0,94
|
| 348 |
+
pip/_vendor/certifi/__main__.py,sha256=1k3Cr95vCxxGRGDljrW3wMdpZdL3Nhf0u1n-k2qdsCY,255
|
| 349 |
+
pip/_vendor/certifi/__pycache__/__init__.cpython-313.pyc,,
|
| 350 |
+
pip/_vendor/certifi/__pycache__/__main__.cpython-313.pyc,,
|
| 351 |
+
pip/_vendor/certifi/__pycache__/core.cpython-313.pyc,,
|
| 352 |
+
pip/_vendor/certifi/cacert.pem,sha256=xVsh-Qf3-G1IrdCTVS-1ZRdJ_1-GBQjMu0I9bB-9gMc,297255
|
| 353 |
+
pip/_vendor/certifi/core.py,sha256=vHXkYJt_CVYbDuS-aPFRfDZu7RkKcP9ltm-DiL4Zo30,4738
|
| 354 |
+
pip/_vendor/certifi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
| 355 |
+
pip/_vendor/dependency_groups/__init__.py,sha256=C3OFu0NGwDzQ4LOmmSOFPsRSvkbBn-mdd4j_5YqJw-s,250
|
| 356 |
+
pip/_vendor/dependency_groups/__main__.py,sha256=UNTM7P5mfVtT7wDi9kOTXWgV3fu3e8bTrt1Qp1jvjKo,1709
|
| 357 |
+
pip/_vendor/dependency_groups/__pycache__/__init__.cpython-313.pyc,,
|
| 358 |
+
pip/_vendor/dependency_groups/__pycache__/__main__.cpython-313.pyc,,
|
| 359 |
+
pip/_vendor/dependency_groups/__pycache__/_implementation.cpython-313.pyc,,
|
| 360 |
+
pip/_vendor/dependency_groups/__pycache__/_lint_dependency_groups.cpython-313.pyc,,
|
| 361 |
+
pip/_vendor/dependency_groups/__pycache__/_pip_wrapper.cpython-313.pyc,,
|
| 362 |
+
pip/_vendor/dependency_groups/__pycache__/_toml_compat.cpython-313.pyc,,
|
| 363 |
+
pip/_vendor/dependency_groups/_implementation.py,sha256=Gqb2DlQELRakeHlKf6QtQSW0M-bcEomxHw4JsvID1ls,8041
|
| 364 |
+
pip/_vendor/dependency_groups/_lint_dependency_groups.py,sha256=yp-DDqKXtbkDTNa0ifa-FmOA8ra24lPZEXftW-R5AuI,1710
|
| 365 |
+
pip/_vendor/dependency_groups/_pip_wrapper.py,sha256=nuVW_w_ntVxpE26ELEvngMY0N04sFLsijXRyZZROFG8,1865
|
| 366 |
+
pip/_vendor/dependency_groups/_toml_compat.py,sha256=BHnXnFacm3DeolsA35GjI6qkDApvua-1F20kv3BfZWE,285
|
| 367 |
+
pip/_vendor/dependency_groups/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
| 368 |
+
pip/_vendor/distlib/__init__.py,sha256=dcwgYGYGQqAEawBXPDtIx80DO_3cOmFv8HTc8JMzknQ,625
|
| 369 |
+
pip/_vendor/distlib/__pycache__/__init__.cpython-313.pyc,,
|
| 370 |
+
pip/_vendor/distlib/__pycache__/compat.cpython-313.pyc,,
|
| 371 |
+
pip/_vendor/distlib/__pycache__/database.cpython-313.pyc,,
|
| 372 |
+
pip/_vendor/distlib/__pycache__/index.cpython-313.pyc,,
|
| 373 |
+
pip/_vendor/distlib/__pycache__/locators.cpython-313.pyc,,
|
| 374 |
+
pip/_vendor/distlib/__pycache__/manifest.cpython-313.pyc,,
|
| 375 |
+
pip/_vendor/distlib/__pycache__/markers.cpython-313.pyc,,
|
| 376 |
+
pip/_vendor/distlib/__pycache__/metadata.cpython-313.pyc,,
|
| 377 |
+
pip/_vendor/distlib/__pycache__/resources.cpython-313.pyc,,
|
| 378 |
+
pip/_vendor/distlib/__pycache__/scripts.cpython-313.pyc,,
|
| 379 |
+
pip/_vendor/distlib/__pycache__/util.cpython-313.pyc,,
|
| 380 |
+
pip/_vendor/distlib/__pycache__/version.cpython-313.pyc,,
|
| 381 |
+
pip/_vendor/distlib/__pycache__/wheel.cpython-313.pyc,,
|
| 382 |
+
pip/_vendor/distlib/compat.py,sha256=2jRSjRI4o-vlXeTK2BCGIUhkc6e9ZGhSsacRM5oseTw,41467
|
| 383 |
+
pip/_vendor/distlib/database.py,sha256=mHy_LxiXIsIVRb-T0-idBrVLw3Ffij5teHCpbjmJ9YU,51160
|
| 384 |
+
pip/_vendor/distlib/index.py,sha256=lTbw268rRhj8dw1sib3VZ_0EhSGgoJO3FKJzSFMOaeA,20797
|
| 385 |
+
pip/_vendor/distlib/locators.py,sha256=oBeAZpFuPQSY09MgNnLfQGGAXXvVO96BFpZyKMuK4tM,51026
|
| 386 |
+
pip/_vendor/distlib/manifest.py,sha256=3qfmAmVwxRqU1o23AlfXrQGZzh6g_GGzTAP_Hb9C5zQ,14168
|
| 387 |
+
pip/_vendor/distlib/markers.py,sha256=X6sDvkFGcYS8gUW8hfsWuKEKAqhQZAJ7iXOMLxRYjYk,5164
|
| 388 |
+
pip/_vendor/distlib/metadata.py,sha256=zil3sg2EUfLXVigljY2d_03IJt-JSs7nX-73fECMX2s,38724
|
| 389 |
+
pip/_vendor/distlib/resources.py,sha256=LwbPksc0A1JMbi6XnuPdMBUn83X7BPuFNWqPGEKI698,10820
|
| 390 |
+
pip/_vendor/distlib/scripts.py,sha256=BJliaDAZaVB7WAkwokgC3HXwLD2iWiHaVI50H7C6eG8,18608
|
| 391 |
+
pip/_vendor/distlib/util.py,sha256=vMPGvsS4j9hF6Y9k3Tyom1aaHLb0rFmZAEyzeAdel9w,66682
|
| 392 |
+
pip/_vendor/distlib/version.py,sha256=s5VIs8wBn0fxzGxWM_aA2ZZyx525HcZbMvcTlTyZ3Rg,23727
|
| 393 |
+
pip/_vendor/distlib/wheel.py,sha256=DFIVguEQHCdxnSdAO0dfFsgMcvVZitg7bCOuLwZ7A_s,43979
|
| 394 |
+
pip/_vendor/distro/__init__.py,sha256=2fHjF-SfgPvjyNZ1iHh_wjqWdR_Yo5ODHwZC0jLBPhc,981
|
| 395 |
+
pip/_vendor/distro/__main__.py,sha256=bu9d3TifoKciZFcqRBuygV3GSuThnVD_m2IK4cz96Vs,64
|
| 396 |
+
pip/_vendor/distro/__pycache__/__init__.cpython-313.pyc,,
|
| 397 |
+
pip/_vendor/distro/__pycache__/__main__.cpython-313.pyc,,
|
| 398 |
+
pip/_vendor/distro/__pycache__/distro.cpython-313.pyc,,
|
| 399 |
+
pip/_vendor/distro/distro.py,sha256=XqbefacAhDT4zr_trnbA15eY8vdK4GTghgmvUGrEM_4,49430
|
| 400 |
+
pip/_vendor/distro/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
| 401 |
+
pip/_vendor/idna/__init__.py,sha256=MPqNDLZbXqGaNdXxAFhiqFPKEQXju2jNQhCey6-5eJM,868
|
| 402 |
+
pip/_vendor/idna/__pycache__/__init__.cpython-313.pyc,,
|
| 403 |
+
pip/_vendor/idna/__pycache__/codec.cpython-313.pyc,,
|
| 404 |
+
pip/_vendor/idna/__pycache__/compat.cpython-313.pyc,,
|
| 405 |
+
pip/_vendor/idna/__pycache__/core.cpython-313.pyc,,
|
| 406 |
+
pip/_vendor/idna/__pycache__/idnadata.cpython-313.pyc,,
|
| 407 |
+
pip/_vendor/idna/__pycache__/intranges.cpython-313.pyc,,
|
| 408 |
+
pip/_vendor/idna/__pycache__/package_data.cpython-313.pyc,,
|
| 409 |
+
pip/_vendor/idna/__pycache__/uts46data.cpython-313.pyc,,
|
| 410 |
+
pip/_vendor/idna/codec.py,sha256=PEew3ItwzjW4hymbasnty2N2OXvNcgHB-JjrBuxHPYY,3422
|
| 411 |
+
pip/_vendor/idna/compat.py,sha256=RzLy6QQCdl9784aFhb2EX9EKGCJjg0P3PilGdeXXcx8,316
|
| 412 |
+
pip/_vendor/idna/core.py,sha256=YJYyAMnwiQEPjVC4-Fqu_p4CJ6yKKuDGmppBNQNQpFs,13239
|
| 413 |
+
pip/_vendor/idna/idnadata.py,sha256=W30GcIGvtOWYwAjZj4ZjuouUutC6ffgNuyjJy7fZ-lo,78306
|
| 414 |
+
pip/_vendor/idna/intranges.py,sha256=amUtkdhYcQG8Zr-CoMM_kVRacxkivC1WgxN1b63KKdU,1898
|
| 415 |
+
pip/_vendor/idna/package_data.py,sha256=q59S3OXsc5VI8j6vSD0sGBMyk6zZ4vWFREE88yCJYKs,21
|
| 416 |
+
pip/_vendor/idna/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
| 417 |
+
pip/_vendor/idna/uts46data.py,sha256=rt90K9J40gUSwppDPCrhjgi5AA6pWM65dEGRSf6rIhM,239289
|
| 418 |
+
pip/_vendor/msgpack/__init__.py,sha256=reRaiOtEzSjPnr7TpxjgIvbfln5pV66FhricAs2eC-g,1109
|
| 419 |
+
pip/_vendor/msgpack/__pycache__/__init__.cpython-313.pyc,,
|
| 420 |
+
pip/_vendor/msgpack/__pycache__/exceptions.cpython-313.pyc,,
|
| 421 |
+
pip/_vendor/msgpack/__pycache__/ext.cpython-313.pyc,,
|
| 422 |
+
pip/_vendor/msgpack/__pycache__/fallback.cpython-313.pyc,,
|
| 423 |
+
pip/_vendor/msgpack/exceptions.py,sha256=dCTWei8dpkrMsQDcjQk74ATl9HsIBH0ybt8zOPNqMYc,1081
|
| 424 |
+
pip/_vendor/msgpack/ext.py,sha256=kteJv03n9tYzd5oo3xYopVTo4vRaAxonBQQJhXohZZo,5726
|
| 425 |
+
pip/_vendor/msgpack/fallback.py,sha256=0g1Pzp0vtmBEmJ5w9F3s_-JMVURP8RS4G1cc5TRaAsI,32390
|
| 426 |
+
pip/_vendor/packaging/__init__.py,sha256=_0cDiPVf2S-bNfVmZguxxzmrIYWlyASxpqph4qsJWUc,494
|
| 427 |
+
pip/_vendor/packaging/__pycache__/__init__.cpython-313.pyc,,
|
| 428 |
+
pip/_vendor/packaging/__pycache__/_elffile.cpython-313.pyc,,
|
| 429 |
+
pip/_vendor/packaging/__pycache__/_manylinux.cpython-313.pyc,,
|
| 430 |
+
pip/_vendor/packaging/__pycache__/_musllinux.cpython-313.pyc,,
|
| 431 |
+
pip/_vendor/packaging/__pycache__/_parser.cpython-313.pyc,,
|
| 432 |
+
pip/_vendor/packaging/__pycache__/_structures.cpython-313.pyc,,
|
| 433 |
+
pip/_vendor/packaging/__pycache__/_tokenizer.cpython-313.pyc,,
|
| 434 |
+
pip/_vendor/packaging/__pycache__/markers.cpython-313.pyc,,
|
| 435 |
+
pip/_vendor/packaging/__pycache__/metadata.cpython-313.pyc,,
|
| 436 |
+
pip/_vendor/packaging/__pycache__/requirements.cpython-313.pyc,,
|
| 437 |
+
pip/_vendor/packaging/__pycache__/specifiers.cpython-313.pyc,,
|
| 438 |
+
pip/_vendor/packaging/__pycache__/tags.cpython-313.pyc,,
|
| 439 |
+
pip/_vendor/packaging/__pycache__/utils.cpython-313.pyc,,
|
| 440 |
+
pip/_vendor/packaging/__pycache__/version.cpython-313.pyc,,
|
| 441 |
+
pip/_vendor/packaging/_elffile.py,sha256=UkrbDtW7aeq3qqoAfU16ojyHZ1xsTvGke_WqMTKAKd0,3286
|
| 442 |
+
pip/_vendor/packaging/_manylinux.py,sha256=t4y_-dTOcfr36gLY-ztiOpxxJFGO2ikC11HgfysGxiM,9596
|
| 443 |
+
pip/_vendor/packaging/_musllinux.py,sha256=p9ZqNYiOItGee8KcZFeHF_YcdhVwGHdK6r-8lgixvGQ,2694
|
| 444 |
+
pip/_vendor/packaging/_parser.py,sha256=gYfnj0pRHflVc4RHZit13KNTyN9iiVcU2RUCGi22BwM,10221
|
| 445 |
+
pip/_vendor/packaging/_structures.py,sha256=q3eVNmbWJGG_S0Dit_S3Ao8qQqz_5PYTXFAKBZe5yr4,1431
|
| 446 |
+
pip/_vendor/packaging/_tokenizer.py,sha256=OYzt7qKxylOAJ-q0XyK1qAycyPRYLfMPdGQKRXkZWyI,5310
|
| 447 |
+
pip/_vendor/packaging/licenses/__init__.py,sha256=3bx-gryo4sRv5LsrwApouy65VIs3u6irSORJzALkrzU,5727
|
| 448 |
+
pip/_vendor/packaging/licenses/__pycache__/__init__.cpython-313.pyc,,
|
| 449 |
+
pip/_vendor/packaging/licenses/__pycache__/_spdx.cpython-313.pyc,,
|
| 450 |
+
pip/_vendor/packaging/licenses/_spdx.py,sha256=oAm1ztPFwlsmCKe7lAAsv_OIOfS1cWDu9bNBkeu-2ns,48398
|
| 451 |
+
pip/_vendor/packaging/markers.py,sha256=P0we27jm1xUzgGMJxBjtUFCIWeBxTsMeJTOJ6chZmAY,12049
|
| 452 |
+
pip/_vendor/packaging/metadata.py,sha256=8IZErqQQnNm53dZZuYq4FGU4_dpyinMeH1QFBIWIkfE,34739
|
| 453 |
+
pip/_vendor/packaging/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
| 454 |
+
pip/_vendor/packaging/requirements.py,sha256=gYyRSAdbrIyKDY66ugIDUQjRMvxkH2ALioTmX3tnL6o,2947
|
| 455 |
+
pip/_vendor/packaging/specifiers.py,sha256=yc9D_MycJEmwUpZvcs1OZL9HfiNFmyw0RZaeHRNHkPw,40079
|
| 456 |
+
pip/_vendor/packaging/tags.py,sha256=41s97W9Zatrq2Ed7Rc3qeBDaHe8pKKvYq2mGjwahfXk,22745
|
| 457 |
+
pip/_vendor/packaging/utils.py,sha256=0F3Hh9OFuRgrhTgGZUl5K22Fv1YP2tZl1z_2gO6kJiA,5050
|
| 458 |
+
pip/_vendor/packaging/version.py,sha256=oiHqzTUv_p12hpjgsLDVcaF5hT7pDaSOViUNMD4GTW0,16688
|
| 459 |
+
pip/_vendor/pkg_resources/__init__.py,sha256=jrhDRbOubP74QuPXxd7U7Po42PH2l-LZ2XfcO7llpZ4,124463
|
| 460 |
+
pip/_vendor/pkg_resources/__pycache__/__init__.cpython-313.pyc,,
|
| 461 |
+
pip/_vendor/platformdirs/__init__.py,sha256=UfeSHWl8AeTtbOBOoHAxK4dODOWkZtfy-m_i7cWdJ8c,22344
|
| 462 |
+
pip/_vendor/platformdirs/__main__.py,sha256=jBJ8zb7Mpx5ebcqF83xrpO94MaeCpNGHVf9cvDN2JLg,1505
|
| 463 |
+
pip/_vendor/platformdirs/__pycache__/__init__.cpython-313.pyc,,
|
| 464 |
+
pip/_vendor/platformdirs/__pycache__/__main__.cpython-313.pyc,,
|
| 465 |
+
pip/_vendor/platformdirs/__pycache__/android.cpython-313.pyc,,
|
| 466 |
+
pip/_vendor/platformdirs/__pycache__/api.cpython-313.pyc,,
|
| 467 |
+
pip/_vendor/platformdirs/__pycache__/macos.cpython-313.pyc,,
|
| 468 |
+
pip/_vendor/platformdirs/__pycache__/unix.cpython-313.pyc,,
|
| 469 |
+
pip/_vendor/platformdirs/__pycache__/version.cpython-313.pyc,,
|
| 470 |
+
pip/_vendor/platformdirs/__pycache__/windows.cpython-313.pyc,,
|
| 471 |
+
pip/_vendor/platformdirs/android.py,sha256=r0DshVBf-RO1jXJGX8C4Til7F1XWt-bkdWMgmvEiaYg,9013
|
| 472 |
+
pip/_vendor/platformdirs/api.py,sha256=U9EzI3EYxcXWUCtIGRllqrcN99i2LSY1mq2-GtsUwEQ,9277
|
| 473 |
+
pip/_vendor/platformdirs/macos.py,sha256=UlbyFZ8Rzu3xndCqQEHrfsYTeHwYdFap1Ioz-yxveT4,6154
|
| 474 |
+
pip/_vendor/platformdirs/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
| 475 |
+
pip/_vendor/platformdirs/unix.py,sha256=WZmkUA--L3JNRGmz32s35YfoD3ica6xKIPdCV_HhLcs,10458
|
| 476 |
+
pip/_vendor/platformdirs/version.py,sha256=0fnw4ljascx7O5PfIeZ2yj6w3pAkqwp099vDcivxuvY,511
|
| 477 |
+
pip/_vendor/platformdirs/windows.py,sha256=IFpiohUBwxPtCzlyKwNtxyW4Jk8haa6W8o59mfrDXVo,10125
|
| 478 |
+
pip/_vendor/pygments/__init__.py,sha256=qMm7-KYqNpMrmjymZaqfH-_9iJtjnexAKodkb9G5D5g,2983
|
| 479 |
+
pip/_vendor/pygments/__main__.py,sha256=WrndpSe6i1ckX_SQ1KaxD9CTKGzD0EuCOFxcbwFpoLU,353
|
| 480 |
+
pip/_vendor/pygments/__pycache__/__init__.cpython-313.pyc,,
|
| 481 |
+
pip/_vendor/pygments/__pycache__/__main__.cpython-313.pyc,,
|
| 482 |
+
pip/_vendor/pygments/__pycache__/console.cpython-313.pyc,,
|
| 483 |
+
pip/_vendor/pygments/__pycache__/filter.cpython-313.pyc,,
|
| 484 |
+
pip/_vendor/pygments/__pycache__/formatter.cpython-313.pyc,,
|
| 485 |
+
pip/_vendor/pygments/__pycache__/lexer.cpython-313.pyc,,
|
| 486 |
+
pip/_vendor/pygments/__pycache__/modeline.cpython-313.pyc,,
|
| 487 |
+
pip/_vendor/pygments/__pycache__/plugin.cpython-313.pyc,,
|
| 488 |
+
pip/_vendor/pygments/__pycache__/regexopt.cpython-313.pyc,,
|
| 489 |
+
pip/_vendor/pygments/__pycache__/scanner.cpython-313.pyc,,
|
| 490 |
+
pip/_vendor/pygments/__pycache__/sphinxext.cpython-313.pyc,,
|
| 491 |
+
pip/_vendor/pygments/__pycache__/style.cpython-313.pyc,,
|
| 492 |
+
pip/_vendor/pygments/__pycache__/token.cpython-313.pyc,,
|
| 493 |
+
pip/_vendor/pygments/__pycache__/unistring.cpython-313.pyc,,
|
| 494 |
+
pip/_vendor/pygments/__pycache__/util.cpython-313.pyc,,
|
| 495 |
+
pip/_vendor/pygments/console.py,sha256=AagDWqwea2yBWf10KC9ptBgMpMjxKp8yABAmh-NQOVk,1718
|
| 496 |
+
pip/_vendor/pygments/filter.py,sha256=YLtpTnZiu07nY3oK9nfR6E9Y1FBHhP5PX8gvkJWcfag,1910
|
| 497 |
+
pip/_vendor/pygments/filters/__init__.py,sha256=4U4jtA0X3iP83uQnB9-TI-HDSw8E8y8zMYHa0UjbbaI,40392
|
| 498 |
+
pip/_vendor/pygments/filters/__pycache__/__init__.cpython-313.pyc,,
|
| 499 |
+
pip/_vendor/pygments/formatter.py,sha256=KZQMmyo_xkOIkQG8g66LYEkBh1bx7a0HyGCBcvhI9Ew,4390
|
| 500 |
+
pip/_vendor/pygments/formatters/__init__.py,sha256=KTwBmnXlaopJhQDOemVHYHskiDghuq-08YtP6xPNJPg,5385
|
| 501 |
+
pip/_vendor/pygments/formatters/__pycache__/__init__.cpython-313.pyc,,
|
| 502 |
+
pip/_vendor/pygments/formatters/__pycache__/_mapping.cpython-313.pyc,,
|
| 503 |
+
pip/_vendor/pygments/formatters/_mapping.py,sha256=1Cw37FuQlNacnxRKmtlPX4nyLoX9_ttko5ZwscNUZZ4,4176
|
| 504 |
+
pip/_vendor/pygments/lexer.py,sha256=_kBrOJ_NT5Tl0IVM0rA9c8eysP6_yrlGzEQI0eVYB-A,35349
|
| 505 |
+
pip/_vendor/pygments/lexers/__init__.py,sha256=wbIME35GH7bI1B9rNPJFqWT-ij_RApZDYPUlZycaLzA,12115
|
| 506 |
+
pip/_vendor/pygments/lexers/__pycache__/__init__.cpython-313.pyc,,
|
| 507 |
+
pip/_vendor/pygments/lexers/__pycache__/_mapping.cpython-313.pyc,,
|
| 508 |
+
pip/_vendor/pygments/lexers/__pycache__/python.cpython-313.pyc,,
|
| 509 |
+
pip/_vendor/pygments/lexers/_mapping.py,sha256=l4tCXM8e9aPC2BD6sjIr0deT-J-z5tHgCwL-p1fS0PE,77602
|
| 510 |
+
pip/_vendor/pygments/lexers/python.py,sha256=vxjn1cOHclIKJKxoyiBsQTY65GHbkZtZRuKQ2AVCKaw,53853
|
| 511 |
+
pip/_vendor/pygments/modeline.py,sha256=K5eSkR8GS1r5OkXXTHOcV0aM_6xpk9eWNEIAW-OOJ2g,1005
|
| 512 |
+
pip/_vendor/pygments/plugin.py,sha256=tPx0rJCTIZ9ioRgLNYG4pifCbAwTRUZddvLw-NfAk2w,1891
|
| 513 |
+
pip/_vendor/pygments/regexopt.py,sha256=wXaP9Gjp_hKAdnICqoDkRxAOQJSc4v3X6mcxx3z-TNs,3072
|
| 514 |
+
pip/_vendor/pygments/scanner.py,sha256=nNcETRR1tRuiTaHmHSTTECVYFPcLf6mDZu1e4u91A9E,3092
|
| 515 |
+
pip/_vendor/pygments/sphinxext.py,sha256=5x7Zh9YlU6ISJ31dMwduiaanb5dWZnKg3MyEQsseNnQ,7981
|
| 516 |
+
pip/_vendor/pygments/style.py,sha256=PlOZqlsnTVd58RGy50vkA2cXQ_lP5bF5EGMEBTno6DA,6420
|
| 517 |
+
pip/_vendor/pygments/styles/__init__.py,sha256=x9ebctfyvCAFpMTlMJ5YxwcNYBzjgq6zJaKkNm78r4M,2042
|
| 518 |
+
pip/_vendor/pygments/styles/__pycache__/__init__.cpython-313.pyc,,
|
| 519 |
+
pip/_vendor/pygments/styles/__pycache__/_mapping.cpython-313.pyc,,
|
| 520 |
+
pip/_vendor/pygments/styles/_mapping.py,sha256=6lovFUE29tz6EsV3XYY4hgozJ7q1JL7cfO3UOlgnS8w,3312
|
| 521 |
+
pip/_vendor/pygments/token.py,sha256=WbdWGhYm_Vosb0DDxW9lHNPgITXfWTsQmHt6cy9RbcM,6226
|
| 522 |
+
pip/_vendor/pygments/unistring.py,sha256=al-_rBemRuGvinsrM6atNsHTmJ6DUbw24q2O2Ru1cBc,63208
|
| 523 |
+
pip/_vendor/pygments/util.py,sha256=oRtSpiAo5jM9ulntkvVbgXUdiAW57jnuYGB7t9fYuhc,10031
|
| 524 |
+
pip/_vendor/pyproject_hooks/__init__.py,sha256=cPB_a9LXz5xvsRbX1o2qyAdjLatZJdQ_Lc5McNX-X7Y,691
|
| 525 |
+
pip/_vendor/pyproject_hooks/__pycache__/__init__.cpython-313.pyc,,
|
| 526 |
+
pip/_vendor/pyproject_hooks/__pycache__/_impl.cpython-313.pyc,,
|
| 527 |
+
pip/_vendor/pyproject_hooks/_impl.py,sha256=jY-raxnmyRyB57ruAitrJRUzEexuAhGTpgMygqx67Z4,14936
|
| 528 |
+
pip/_vendor/pyproject_hooks/_in_process/__init__.py,sha256=MJNPpfIxcO-FghxpBbxkG1rFiQf6HOUbV4U5mq0HFns,557
|
| 529 |
+
pip/_vendor/pyproject_hooks/_in_process/__pycache__/__init__.cpython-313.pyc,,
|
| 530 |
+
pip/_vendor/pyproject_hooks/_in_process/__pycache__/_in_process.cpython-313.pyc,,
|
| 531 |
+
pip/_vendor/pyproject_hooks/_in_process/_in_process.py,sha256=qcXMhmx__MIJq10gGHW3mA4Tl8dy8YzHMccwnNoKlw0,12216
|
| 532 |
+
pip/_vendor/pyproject_hooks/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
| 533 |
+
pip/_vendor/requests/__init__.py,sha256=HlB_HzhrzGtfD_aaYUwUh1zWXLZ75_YCLyit75d0Vz8,5057
|
| 534 |
+
pip/_vendor/requests/__pycache__/__init__.cpython-313.pyc,,
|
| 535 |
+
pip/_vendor/requests/__pycache__/__version__.cpython-313.pyc,,
|
| 536 |
+
pip/_vendor/requests/__pycache__/_internal_utils.cpython-313.pyc,,
|
| 537 |
+
pip/_vendor/requests/__pycache__/adapters.cpython-313.pyc,,
|
| 538 |
+
pip/_vendor/requests/__pycache__/api.cpython-313.pyc,,
|
| 539 |
+
pip/_vendor/requests/__pycache__/auth.cpython-313.pyc,,
|
| 540 |
+
pip/_vendor/requests/__pycache__/certs.cpython-313.pyc,,
|
| 541 |
+
pip/_vendor/requests/__pycache__/compat.cpython-313.pyc,,
|
| 542 |
+
pip/_vendor/requests/__pycache__/cookies.cpython-313.pyc,,
|
| 543 |
+
pip/_vendor/requests/__pycache__/exceptions.cpython-313.pyc,,
|
| 544 |
+
pip/_vendor/requests/__pycache__/help.cpython-313.pyc,,
|
| 545 |
+
pip/_vendor/requests/__pycache__/hooks.cpython-313.pyc,,
|
| 546 |
+
pip/_vendor/requests/__pycache__/models.cpython-313.pyc,,
|
| 547 |
+
pip/_vendor/requests/__pycache__/packages.cpython-313.pyc,,
|
| 548 |
+
pip/_vendor/requests/__pycache__/sessions.cpython-313.pyc,,
|
| 549 |
+
pip/_vendor/requests/__pycache__/status_codes.cpython-313.pyc,,
|
| 550 |
+
pip/_vendor/requests/__pycache__/structures.cpython-313.pyc,,
|
| 551 |
+
pip/_vendor/requests/__pycache__/utils.cpython-313.pyc,,
|
| 552 |
+
pip/_vendor/requests/__version__.py,sha256=FVfglgZmNQnmYPXpOohDU58F5EUb_-VnSTaAesS187g,435
|
| 553 |
+
pip/_vendor/requests/_internal_utils.py,sha256=nMQymr4hs32TqVo5AbCrmcJEhvPUh7xXlluyqwslLiQ,1495
|
| 554 |
+
pip/_vendor/requests/adapters.py,sha256=J7VeVxKBvawbtlX2DERVo05J9BXTcWYLMHNd1Baa-bk,27607
|
| 555 |
+
pip/_vendor/requests/api.py,sha256=_Zb9Oa7tzVIizTKwFrPjDEY9ejtm_OnSRERnADxGsQs,6449
|
| 556 |
+
pip/_vendor/requests/auth.py,sha256=kF75tqnLctZ9Mf_hm9TZIj4cQWnN5uxRz8oWsx5wmR0,10186
|
| 557 |
+
pip/_vendor/requests/certs.py,sha256=kHDlkK_beuHXeMPc5jta2wgl8gdKeUWt5f2nTDVrvt8,441
|
| 558 |
+
pip/_vendor/requests/compat.py,sha256=Mo9f9xZpefod8Zm-n9_StJcVTmwSukXR2p3IQyyVXvU,1485
|
| 559 |
+
pip/_vendor/requests/cookies.py,sha256=bNi-iqEj4NPZ00-ob-rHvzkvObzN3lEpgw3g6paS3Xw,18590
|
| 560 |
+
pip/_vendor/requests/exceptions.py,sha256=D1wqzYWne1mS2rU43tP9CeN1G7QAy7eqL9o1god6Ejw,4272
|
| 561 |
+
pip/_vendor/requests/help.py,sha256=hRKaf9u0G7fdwrqMHtF3oG16RKktRf6KiwtSq2Fo1_0,3813
|
| 562 |
+
pip/_vendor/requests/hooks.py,sha256=CiuysiHA39V5UfcCBXFIx83IrDpuwfN9RcTUgv28ftQ,733
|
| 563 |
+
pip/_vendor/requests/models.py,sha256=x4K4CmH-lC0l2Kb-iPfMN4dRXxHEcbOaEWBL_i09AwI,35483
|
| 564 |
+
pip/_vendor/requests/packages.py,sha256=_ZQDCJTJ8SP3kVWunSqBsRZNPzj2c1WFVqbdr08pz3U,1057
|
| 565 |
+
pip/_vendor/requests/sessions.py,sha256=ykTI8UWGSltOfH07HKollH7kTBGw4WhiBVaQGmckTw4,30495
|
| 566 |
+
pip/_vendor/requests/status_codes.py,sha256=iJUAeA25baTdw-6PfD0eF4qhpINDJRJI-yaMqxs4LEI,4322
|
| 567 |
+
pip/_vendor/requests/structures.py,sha256=-IbmhVz06S-5aPSZuUthZ6-6D9XOjRuTXHOabY041XM,2912
|
| 568 |
+
pip/_vendor/requests/utils.py,sha256=vYPUlkjBB0t9jMQeX9U62dFhde5q3z9FRC2j_bdMfH8,33360
|
| 569 |
+
pip/_vendor/resolvelib/__init__.py,sha256=4LcBWHMH317EKEkpV5XLVnqiU1lrmCiygjsADuCgz4s,541
|
| 570 |
+
pip/_vendor/resolvelib/__pycache__/__init__.cpython-313.pyc,,
|
| 571 |
+
pip/_vendor/resolvelib/__pycache__/providers.cpython-313.pyc,,
|
| 572 |
+
pip/_vendor/resolvelib/__pycache__/reporters.cpython-313.pyc,,
|
| 573 |
+
pip/_vendor/resolvelib/__pycache__/structs.cpython-313.pyc,,
|
| 574 |
+
pip/_vendor/resolvelib/providers.py,sha256=pIWJbIdJJ9GFtNbtwTH0Ia43Vj6hYCEJj2DOLue15FM,8914
|
| 575 |
+
pip/_vendor/resolvelib/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
| 576 |
+
pip/_vendor/resolvelib/reporters.py,sha256=8BNa7G9cKW4Lie4BhDhd7Z57J_Vlb1CYPGSgVN2erMA,2038
|
| 577 |
+
pip/_vendor/resolvelib/resolvers/__init__.py,sha256=GMYuhrbSsYTIjOij0tuJKLvlk6UXmp3nXQetn2sOvpQ,640
|
| 578 |
+
pip/_vendor/resolvelib/resolvers/__pycache__/__init__.cpython-313.pyc,,
|
| 579 |
+
pip/_vendor/resolvelib/resolvers/__pycache__/abstract.cpython-313.pyc,,
|
| 580 |
+
pip/_vendor/resolvelib/resolvers/__pycache__/criterion.cpython-313.pyc,,
|
| 581 |
+
pip/_vendor/resolvelib/resolvers/__pycache__/exceptions.cpython-313.pyc,,
|
| 582 |
+
pip/_vendor/resolvelib/resolvers/__pycache__/resolution.cpython-313.pyc,,
|
| 583 |
+
pip/_vendor/resolvelib/resolvers/abstract.py,sha256=jZOBVigE4PUub9i3F-bTvBwaIXX8S9EU3CGASBvFqEU,1558
|
| 584 |
+
pip/_vendor/resolvelib/resolvers/criterion.py,sha256=lcmZGv5sKHOnFD_RzZwvlGSj19MeA-5rCMpdf2Sgw7Y,1768
|
| 585 |
+
pip/_vendor/resolvelib/resolvers/exceptions.py,sha256=ln_jaQtgLlRUSFY627yiHG2gD7AgaXzRKaElFVh7fDQ,1768
|
| 586 |
+
pip/_vendor/resolvelib/resolvers/resolution.py,sha256=yQegMuOmlzAElLLpgD-k6NbPDMCQf29rWhiFC26OdkM,20671
|
| 587 |
+
pip/_vendor/resolvelib/structs.py,sha256=pu-EJiR2IBITr2SQeNPRa0rXhjlStfmO_GEgAhr3004,6420
|
| 588 |
+
pip/_vendor/rich/__init__.py,sha256=dRxjIL-SbFVY0q3IjSMrfgBTHrm1LZDgLOygVBwiYZc,6090
|
| 589 |
+
pip/_vendor/rich/__main__.py,sha256=eO7Cq8JnrgG8zVoeImiAs92q3hXNMIfp0w5lMsO7Q2Y,8477
|
| 590 |
+
pip/_vendor/rich/__pycache__/__init__.cpython-313.pyc,,
|
| 591 |
+
pip/_vendor/rich/__pycache__/__main__.cpython-313.pyc,,
|
| 592 |
+
pip/_vendor/rich/__pycache__/_cell_widths.cpython-313.pyc,,
|
| 593 |
+
pip/_vendor/rich/__pycache__/_emoji_codes.cpython-313.pyc,,
|
| 594 |
+
pip/_vendor/rich/__pycache__/_emoji_replace.cpython-313.pyc,,
|
| 595 |
+
pip/_vendor/rich/__pycache__/_export_format.cpython-313.pyc,,
|
| 596 |
+
pip/_vendor/rich/__pycache__/_extension.cpython-313.pyc,,
|
| 597 |
+
pip/_vendor/rich/__pycache__/_fileno.cpython-313.pyc,,
|
| 598 |
+
pip/_vendor/rich/__pycache__/_inspect.cpython-313.pyc,,
|
| 599 |
+
pip/_vendor/rich/__pycache__/_log_render.cpython-313.pyc,,
|
| 600 |
+
pip/_vendor/rich/__pycache__/_loop.cpython-313.pyc,,
|
| 601 |
+
pip/_vendor/rich/__pycache__/_null_file.cpython-313.pyc,,
|
| 602 |
+
pip/_vendor/rich/__pycache__/_palettes.cpython-313.pyc,,
|
| 603 |
+
pip/_vendor/rich/__pycache__/_pick.cpython-313.pyc,,
|
| 604 |
+
pip/_vendor/rich/__pycache__/_ratio.cpython-313.pyc,,
|
| 605 |
+
pip/_vendor/rich/__pycache__/_spinners.cpython-313.pyc,,
|
| 606 |
+
pip/_vendor/rich/__pycache__/_stack.cpython-313.pyc,,
|
| 607 |
+
pip/_vendor/rich/__pycache__/_timer.cpython-313.pyc,,
|
| 608 |
+
pip/_vendor/rich/__pycache__/_win32_console.cpython-313.pyc,,
|
| 609 |
+
pip/_vendor/rich/__pycache__/_windows.cpython-313.pyc,,
|
| 610 |
+
pip/_vendor/rich/__pycache__/_windows_renderer.cpython-313.pyc,,
|
| 611 |
+
pip/_vendor/rich/__pycache__/_wrap.cpython-313.pyc,,
|
| 612 |
+
pip/_vendor/rich/__pycache__/abc.cpython-313.pyc,,
|
| 613 |
+
pip/_vendor/rich/__pycache__/align.cpython-313.pyc,,
|
| 614 |
+
pip/_vendor/rich/__pycache__/ansi.cpython-313.pyc,,
|
| 615 |
+
pip/_vendor/rich/__pycache__/bar.cpython-313.pyc,,
|
| 616 |
+
pip/_vendor/rich/__pycache__/box.cpython-313.pyc,,
|
| 617 |
+
pip/_vendor/rich/__pycache__/cells.cpython-313.pyc,,
|
| 618 |
+
pip/_vendor/rich/__pycache__/color.cpython-313.pyc,,
|
| 619 |
+
pip/_vendor/rich/__pycache__/color_triplet.cpython-313.pyc,,
|
| 620 |
+
pip/_vendor/rich/__pycache__/columns.cpython-313.pyc,,
|
| 621 |
+
pip/_vendor/rich/__pycache__/console.cpython-313.pyc,,
|
| 622 |
+
pip/_vendor/rich/__pycache__/constrain.cpython-313.pyc,,
|
| 623 |
+
pip/_vendor/rich/__pycache__/containers.cpython-313.pyc,,
|
| 624 |
+
pip/_vendor/rich/__pycache__/control.cpython-313.pyc,,
|
| 625 |
+
pip/_vendor/rich/__pycache__/default_styles.cpython-313.pyc,,
|
| 626 |
+
pip/_vendor/rich/__pycache__/diagnose.cpython-313.pyc,,
|
| 627 |
+
pip/_vendor/rich/__pycache__/emoji.cpython-313.pyc,,
|
| 628 |
+
pip/_vendor/rich/__pycache__/errors.cpython-313.pyc,,
|
| 629 |
+
pip/_vendor/rich/__pycache__/file_proxy.cpython-313.pyc,,
|
| 630 |
+
pip/_vendor/rich/__pycache__/filesize.cpython-313.pyc,,
|
| 631 |
+
pip/_vendor/rich/__pycache__/highlighter.cpython-313.pyc,,
|
| 632 |
+
pip/_vendor/rich/__pycache__/json.cpython-313.pyc,,
|
| 633 |
+
pip/_vendor/rich/__pycache__/jupyter.cpython-313.pyc,,
|
| 634 |
+
pip/_vendor/rich/__pycache__/layout.cpython-313.pyc,,
|
| 635 |
+
pip/_vendor/rich/__pycache__/live.cpython-313.pyc,,
|
| 636 |
+
pip/_vendor/rich/__pycache__/live_render.cpython-313.pyc,,
|
| 637 |
+
pip/_vendor/rich/__pycache__/logging.cpython-313.pyc,,
|
| 638 |
+
pip/_vendor/rich/__pycache__/markup.cpython-313.pyc,,
|
| 639 |
+
pip/_vendor/rich/__pycache__/measure.cpython-313.pyc,,
|
| 640 |
+
pip/_vendor/rich/__pycache__/padding.cpython-313.pyc,,
|
| 641 |
+
pip/_vendor/rich/__pycache__/pager.cpython-313.pyc,,
|
| 642 |
+
pip/_vendor/rich/__pycache__/palette.cpython-313.pyc,,
|
| 643 |
+
pip/_vendor/rich/__pycache__/panel.cpython-313.pyc,,
|
| 644 |
+
pip/_vendor/rich/__pycache__/pretty.cpython-313.pyc,,
|
| 645 |
+
pip/_vendor/rich/__pycache__/progress.cpython-313.pyc,,
|
| 646 |
+
pip/_vendor/rich/__pycache__/progress_bar.cpython-313.pyc,,
|
| 647 |
+
pip/_vendor/rich/__pycache__/prompt.cpython-313.pyc,,
|
| 648 |
+
pip/_vendor/rich/__pycache__/protocol.cpython-313.pyc,,
|
| 649 |
+
pip/_vendor/rich/__pycache__/region.cpython-313.pyc,,
|
| 650 |
+
pip/_vendor/rich/__pycache__/repr.cpython-313.pyc,,
|
| 651 |
+
pip/_vendor/rich/__pycache__/rule.cpython-313.pyc,,
|
| 652 |
+
pip/_vendor/rich/__pycache__/scope.cpython-313.pyc,,
|
| 653 |
+
pip/_vendor/rich/__pycache__/screen.cpython-313.pyc,,
|
| 654 |
+
pip/_vendor/rich/__pycache__/segment.cpython-313.pyc,,
|
| 655 |
+
pip/_vendor/rich/__pycache__/spinner.cpython-313.pyc,,
|
| 656 |
+
pip/_vendor/rich/__pycache__/status.cpython-313.pyc,,
|
| 657 |
+
pip/_vendor/rich/__pycache__/style.cpython-313.pyc,,
|
| 658 |
+
pip/_vendor/rich/__pycache__/styled.cpython-313.pyc,,
|
| 659 |
+
pip/_vendor/rich/__pycache__/syntax.cpython-313.pyc,,
|
| 660 |
+
pip/_vendor/rich/__pycache__/table.cpython-313.pyc,,
|
| 661 |
+
pip/_vendor/rich/__pycache__/terminal_theme.cpython-313.pyc,,
|
| 662 |
+
pip/_vendor/rich/__pycache__/text.cpython-313.pyc,,
|
| 663 |
+
pip/_vendor/rich/__pycache__/theme.cpython-313.pyc,,
|
| 664 |
+
pip/_vendor/rich/__pycache__/themes.cpython-313.pyc,,
|
| 665 |
+
pip/_vendor/rich/__pycache__/traceback.cpython-313.pyc,,
|
| 666 |
+
pip/_vendor/rich/__pycache__/tree.cpython-313.pyc,,
|
| 667 |
+
pip/_vendor/rich/_cell_widths.py,sha256=fbmeyetEdHjzE_Vx2l1uK7tnPOhMs2X1lJfO3vsKDpA,10209
|
| 668 |
+
pip/_vendor/rich/_emoji_codes.py,sha256=hu1VL9nbVdppJrVoijVshRlcRRe_v3dju3Mmd2sKZdY,140235
|
| 669 |
+
pip/_vendor/rich/_emoji_replace.py,sha256=n-kcetsEUx2ZUmhQrfeMNc-teeGhpuSQ5F8VPBsyvDo,1064
|
| 670 |
+
pip/_vendor/rich/_export_format.py,sha256=RI08pSrm5tBSzPMvnbTqbD9WIalaOoN5d4M1RTmLq1Y,2128
|
| 671 |
+
pip/_vendor/rich/_extension.py,sha256=Xt47QacCKwYruzjDi-gOBq724JReDj9Cm9xUi5fr-34,265
|
| 672 |
+
pip/_vendor/rich/_fileno.py,sha256=HWZxP5C2ajMbHryvAQZseflVfQoGzsKOHzKGsLD8ynQ,799
|
| 673 |
+
pip/_vendor/rich/_inspect.py,sha256=QM05lEFnFoTaFqpnbx-zBEI6k8oIKrD3cvjEOQNhKig,9655
|
| 674 |
+
pip/_vendor/rich/_log_render.py,sha256=1ByI0PA1ZpxZY3CGJOK54hjlq4X-Bz_boIjIqCd8Kns,3225
|
| 675 |
+
pip/_vendor/rich/_loop.py,sha256=hV_6CLdoPm0va22Wpw4zKqM0RYsz3TZxXj0PoS-9eDQ,1236
|
| 676 |
+
pip/_vendor/rich/_null_file.py,sha256=ADGKp1yt-k70FMKV6tnqCqecB-rSJzp-WQsD7LPL-kg,1394
|
| 677 |
+
pip/_vendor/rich/_palettes.py,sha256=cdev1JQKZ0JvlguV9ipHgznTdnvlIzUFDBb0It2PzjI,7063
|
| 678 |
+
pip/_vendor/rich/_pick.py,sha256=evDt8QN4lF5CiwrUIXlOJCntitBCOsI3ZLPEIAVRLJU,423
|
| 679 |
+
pip/_vendor/rich/_ratio.py,sha256=Zt58apszI6hAAcXPpgdWKpu3c31UBWebOeR4mbyptvU,5471
|
| 680 |
+
pip/_vendor/rich/_spinners.py,sha256=U2r1_g_1zSjsjiUdAESc2iAMc3i4ri_S8PYP6kQ5z1I,19919
|
| 681 |
+
pip/_vendor/rich/_stack.py,sha256=-C8OK7rxn3sIUdVwxZBBpeHhIzX0eI-VM3MemYfaXm0,351
|
| 682 |
+
pip/_vendor/rich/_timer.py,sha256=zelxbT6oPFZnNrwWPpc1ktUeAT-Vc4fuFcRZLQGLtMI,417
|
| 683 |
+
pip/_vendor/rich/_win32_console.py,sha256=BSaDRIMwBLITn_m0mTRLPqME5q-quGdSMuYMpYeYJwc,22755
|
| 684 |
+
pip/_vendor/rich/_windows.py,sha256=aBwaD_S56SbgopIvayVmpk0Y28uwY2C5Bab1wl3Bp-I,1925
|
| 685 |
+
pip/_vendor/rich/_windows_renderer.py,sha256=t74ZL3xuDCP3nmTp9pH1L5LiI2cakJuQRQleHCJerlk,2783
|
| 686 |
+
pip/_vendor/rich/_wrap.py,sha256=FlSsom5EX0LVkA3KWy34yHnCfLtqX-ZIepXKh-70rpc,3404
|
| 687 |
+
pip/_vendor/rich/abc.py,sha256=ON-E-ZqSSheZ88VrKX2M3PXpFbGEUUZPMa_Af0l-4f0,890
|
| 688 |
+
pip/_vendor/rich/align.py,sha256=Rh-3adnDaN1Ao07EjR2PhgE62PGLPgO8SMwJBku1urQ,10469
|
| 689 |
+
pip/_vendor/rich/ansi.py,sha256=Avs1LHbSdcyOvDOdpELZUoULcBiYewY76eNBp6uFBhs,6921
|
| 690 |
+
pip/_vendor/rich/bar.py,sha256=ldbVHOzKJOnflVNuv1xS7g6dLX2E3wMnXkdPbpzJTcs,3263
|
| 691 |
+
pip/_vendor/rich/box.py,sha256=nr5fYIUghB_iUCEq6y0Z3LlCT8gFPDrzN9u2kn7tJl4,10831
|
| 692 |
+
pip/_vendor/rich/cells.py,sha256=KrQkj5-LghCCpJLSNQIyAZjndc4bnEqOEmi5YuZ9UCY,5130
|
| 693 |
+
pip/_vendor/rich/color.py,sha256=3HSULVDj7qQkXUdFWv78JOiSZzfy5y1nkcYhna296V0,18211
|
| 694 |
+
pip/_vendor/rich/color_triplet.py,sha256=3lhQkdJbvWPoLDO-AnYImAWmJvV5dlgYNCVZ97ORaN4,1054
|
| 695 |
+
pip/_vendor/rich/columns.py,sha256=HUX0KcMm9dsKNi11fTbiM_h2iDtl8ySCaVcxlalEzq8,7131
|
| 696 |
+
pip/_vendor/rich/console.py,sha256=_RJizBQIn9qxr4Ln7Q_SC5N9ekPWPAxH0KGVxsgg69Y,100565
|
| 697 |
+
pip/_vendor/rich/constrain.py,sha256=1VIPuC8AgtKWrcncQrjBdYqA3JVWysu6jZo1rrh7c7Q,1288
|
| 698 |
+
pip/_vendor/rich/containers.py,sha256=c_56TxcedGYqDepHBMTuZdUIijitAQgnox-Qde0Z1qo,5502
|
| 699 |
+
pip/_vendor/rich/control.py,sha256=DSkHTUQLorfSERAKE_oTAEUFefZnZp4bQb4q8rHbKws,6630
|
| 700 |
+
pip/_vendor/rich/default_styles.py,sha256=khQFqqaoDs3bprMqWpHw8nO5UpG2DN6QtuTd6LzZwYc,8257
|
| 701 |
+
pip/_vendor/rich/diagnose.py,sha256=WNPjU2pEdrPICJ24KOaTD_hzP839qArpmF1JIM5x_EQ,998
|
| 702 |
+
pip/_vendor/rich/emoji.py,sha256=omTF9asaAnsM4yLY94eR_9dgRRSm1lHUszX20D1yYCQ,2501
|
| 703 |
+
pip/_vendor/rich/errors.py,sha256=5pP3Kc5d4QJ_c0KFsxrfyhjiPVe7J1zOqSFbFAzcV-Y,642
|
| 704 |
+
pip/_vendor/rich/file_proxy.py,sha256=Tl9THMDZ-Pk5Wm8sI1gGg_U5DhusmxD-FZ0fUbcU0W0,1683
|
| 705 |
+
pip/_vendor/rich/filesize.py,sha256=_iz9lIpRgvW7MNSeCZnLg-HwzbP4GETg543WqD8SFs0,2484
|
| 706 |
+
pip/_vendor/rich/highlighter.py,sha256=G_sn-8DKjM1sEjLG_oc4ovkWmiUpWvj8bXi0yed2LnY,9586
|
| 707 |
+
pip/_vendor/rich/json.py,sha256=vVEoKdawoJRjAFayPwXkMBPLy7RSTs-f44wSQDR2nJ0,5031
|
| 708 |
+
pip/_vendor/rich/jupyter.py,sha256=QyoKoE_8IdCbrtiSHp9TsTSNyTHY0FO5whE7jOTd9UE,3252
|
| 709 |
+
pip/_vendor/rich/layout.py,sha256=ajkSFAtEVv9EFTcFs-w4uZfft7nEXhNzL7ZVdgrT5rI,14004
|
| 710 |
+
pip/_vendor/rich/live.py,sha256=DhzAPEnjTxQuq9_0Y2xh2MUwQcP_aGPkenLfKETslwM,14270
|
| 711 |
+
pip/_vendor/rich/live_render.py,sha256=zJtB471jGziBtEwxc54x12wEQtH4BuQr1SA8v9kU82w,3666
|
| 712 |
+
pip/_vendor/rich/logging.py,sha256=ZgpKMMBY_BuMAI_BYzo-UtXak6t5oH9VK8m9Q2Lm0f4,12458
|
| 713 |
+
pip/_vendor/rich/markup.py,sha256=3euGKP5s41NCQwaSjTnJxus5iZMHjxpIM0W6fCxra38,8451
|
| 714 |
+
pip/_vendor/rich/measure.py,sha256=HmrIJX8sWRTHbgh8MxEay_83VkqNW_70s8aKP5ZcYI8,5305
|
| 715 |
+
pip/_vendor/rich/padding.py,sha256=KVEI3tOwo9sgK1YNSuH__M1_jUWmLZwRVV_KmOtVzyM,4908
|
| 716 |
+
pip/_vendor/rich/pager.py,sha256=SO_ETBFKbg3n_AgOzXm41Sv36YxXAyI3_R-KOY2_uSc,828
|
| 717 |
+
pip/_vendor/rich/palette.py,sha256=lInvR1ODDT2f3UZMfL1grq7dY_pDdKHw4bdUgOGaM4Y,3396
|
| 718 |
+
pip/_vendor/rich/panel.py,sha256=SUDaa3z4MU7vIjzvbi0SXuc6BslDzADwdY1AX4TbTdY,11225
|
| 719 |
+
pip/_vendor/rich/pretty.py,sha256=gy3S72u4FRg2ytoo7N1ZDWDIvB4unbzd5iUGdgm-8fc,36391
|
| 720 |
+
pip/_vendor/rich/progress.py,sha256=MtmCjTk5zYU_XtRHxRHTAEHG6hF9PeF7EMWbEPleIC0,60357
|
| 721 |
+
pip/_vendor/rich/progress_bar.py,sha256=mZTPpJUwcfcdgQCTTz3kyY-fc79ddLwtx6Ghhxfo064,8162
|
| 722 |
+
pip/_vendor/rich/prompt.py,sha256=l0RhQU-0UVTV9e08xW1BbIj0Jq2IXyChX4lC0lFNzt4,12447
|
| 723 |
+
pip/_vendor/rich/protocol.py,sha256=5hHHDDNHckdk8iWH5zEbi-zuIVSF5hbU2jIo47R7lTE,1391
|
| 724 |
+
pip/_vendor/rich/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
| 725 |
+
pip/_vendor/rich/region.py,sha256=rNT9xZrVZTYIXZC0NYn41CJQwYNbR-KecPOxTgQvB8Y,166
|
| 726 |
+
pip/_vendor/rich/repr.py,sha256=5MZJZmONgC6kud-QW-_m1okXwL2aR6u6y-pUcUCJz28,4431
|
| 727 |
+
pip/_vendor/rich/rule.py,sha256=0fNaS_aERa3UMRc3T5WMpN_sumtDxfaor2y3of1ftBk,4602
|
| 728 |
+
pip/_vendor/rich/scope.py,sha256=TMUU8qo17thyqQCPqjDLYpg_UU1k5qVd-WwiJvnJVas,2843
|
| 729 |
+
pip/_vendor/rich/screen.py,sha256=YoeReESUhx74grqb0mSSb9lghhysWmFHYhsbMVQjXO8,1591
|
| 730 |
+
pip/_vendor/rich/segment.py,sha256=otnKeKGEV-WRlQVosfJVeFDcDxAKHpvJ_hLzSu5lumM,24743
|
| 731 |
+
pip/_vendor/rich/spinner.py,sha256=PT5qgXPG3ZpqRj7n3EZQ6NW56mx3ldZqZCU7gEMyZk4,4364
|
| 732 |
+
pip/_vendor/rich/status.py,sha256=kkPph3YeAZBo-X-4wPp8gTqZyU466NLwZBA4PZTTewo,4424
|
| 733 |
+
pip/_vendor/rich/style.py,sha256=xpj4uMBZMtuNuNomfUiamigl3p1sDvTCZwrG1tcTVeg,27059
|
| 734 |
+
pip/_vendor/rich/styled.py,sha256=eZNnzGrI4ki_54pgY3Oj0T-x3lxdXTYh4_ryDB24wBU,1258
|
| 735 |
+
pip/_vendor/rich/syntax.py,sha256=qqAnEUZ4K57Po81_5RBxnsuU4KRzSdvDPAhKw8ma_3E,35763
|
| 736 |
+
pip/_vendor/rich/table.py,sha256=ZmT7V7MMCOYKw7TGY9SZLyYDf6JdM-WVf07FdVuVhTI,40049
|
| 737 |
+
pip/_vendor/rich/terminal_theme.py,sha256=1j5-ufJfnvlAo5Qsi_ACZiXDmwMXzqgmFByObT9-yJY,3370
|
| 738 |
+
pip/_vendor/rich/text.py,sha256=AO7JPCz6-gaN1thVLXMBntEmDPVYFgFNG1oM61_sanU,47552
|
| 739 |
+
pip/_vendor/rich/theme.py,sha256=oNyhXhGagtDlbDye3tVu3esWOWk0vNkuxFw-_unlaK0,3771
|
| 740 |
+
pip/_vendor/rich/themes.py,sha256=0xgTLozfabebYtcJtDdC5QkX5IVUEaviqDUJJh4YVFk,102
|
| 741 |
+
pip/_vendor/rich/traceback.py,sha256=ZA8Q67DyP5a_stpIh6GPf9IiXj_s3dAhDIr6Zbfkahk,35170
|
| 742 |
+
pip/_vendor/rich/tree.py,sha256=yWnQ6rAvRGJ3qZGqBrxS2SW2TKBTNrP0SdY8QxOFPuw,9451
|
| 743 |
+
pip/_vendor/tomli/__init__.py,sha256=PhNw_eyLgdn7McJ6nrAN8yIm3dXC75vr1sVGVVwDSpA,314
|
| 744 |
+
pip/_vendor/tomli/__pycache__/__init__.cpython-313.pyc,,
|
| 745 |
+
pip/_vendor/tomli/__pycache__/_parser.cpython-313.pyc,,
|
| 746 |
+
pip/_vendor/tomli/__pycache__/_re.cpython-313.pyc,,
|
| 747 |
+
pip/_vendor/tomli/__pycache__/_types.cpython-313.pyc,,
|
| 748 |
+
pip/_vendor/tomli/_parser.py,sha256=9w8LG0jB7fwmZZWB0vVXbeejDHcl4ANIJxB2scEnDlA,25591
|
| 749 |
+
pip/_vendor/tomli/_re.py,sha256=sh4sBDRgO94KJZwNIrgdcyV_qQast50YvzOAUGpRDKA,3171
|
| 750 |
+
pip/_vendor/tomli/_types.py,sha256=-GTG2VUqkpxwMqzmVO4F7ybKddIbAnuAHXfmWQcTi3Q,254
|
| 751 |
+
pip/_vendor/tomli/py.typed,sha256=8PjyZ1aVoQpRVvt71muvuq5qE-jTFZkK-GLHkhdebmc,26
|
| 752 |
+
pip/_vendor/tomli_w/__init__.py,sha256=0F8yDtXx3Uunhm874KrAcP76srsM98y7WyHQwCulZbo,169
|
| 753 |
+
pip/_vendor/tomli_w/__pycache__/__init__.cpython-313.pyc,,
|
| 754 |
+
pip/_vendor/tomli_w/__pycache__/_writer.cpython-313.pyc,,
|
| 755 |
+
pip/_vendor/tomli_w/_writer.py,sha256=dsifFS2xYf1i76mmRyfz9y125xC7Z_HQ845ZKhJsYXs,6961
|
| 756 |
+
pip/_vendor/tomli_w/py.typed,sha256=8PjyZ1aVoQpRVvt71muvuq5qE-jTFZkK-GLHkhdebmc,26
|
| 757 |
+
pip/_vendor/truststore/__init__.py,sha256=2wRSVijjRzPLVXUzWqvdZLNsEOhDfopKLd2EKAYLwKU,1320
|
| 758 |
+
pip/_vendor/truststore/__pycache__/__init__.cpython-313.pyc,,
|
| 759 |
+
pip/_vendor/truststore/__pycache__/_api.cpython-313.pyc,,
|
| 760 |
+
pip/_vendor/truststore/__pycache__/_macos.cpython-313.pyc,,
|
| 761 |
+
pip/_vendor/truststore/__pycache__/_openssl.cpython-313.pyc,,
|
| 762 |
+
pip/_vendor/truststore/__pycache__/_ssl_constants.cpython-313.pyc,,
|
| 763 |
+
pip/_vendor/truststore/__pycache__/_windows.cpython-313.pyc,,
|
| 764 |
+
pip/_vendor/truststore/_api.py,sha256=40I0ojO2DnITiHvOnUYvJ1bfQMBKHOkci14noNxEnCs,11246
|
| 765 |
+
pip/_vendor/truststore/_macos.py,sha256=nZlLkOmszUE0g6ryRwBVGY5COzPyudcsiJtDWarM5LQ,20503
|
| 766 |
+
pip/_vendor/truststore/_openssl.py,sha256=LLUZ7ZGaio-i5dpKKjKCSeSufmn6T8pi9lDcFnvSyq0,2324
|
| 767 |
+
pip/_vendor/truststore/_ssl_constants.py,sha256=NUD4fVKdSD02ri7-db0tnO0VqLP9aHuzmStcW7tAl08,1130
|
| 768 |
+
pip/_vendor/truststore/_windows.py,sha256=rAHyKYD8M7t-bXfG8VgOVa3TpfhVhbt4rZQlO45YuP8,17993
|
| 769 |
+
pip/_vendor/truststore/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
| 770 |
+
pip/_vendor/typing_extensions.py,sha256=ipKHUPtZCqL6c-HfvGl-9t0opsXcSL72y4GYjyJXs_g,172702
|
| 771 |
+
pip/_vendor/urllib3/__init__.py,sha256=iXLcYiJySn0GNbWOOZDDApgBL1JgP44EZ8i1760S8Mc,3333
|
| 772 |
+
pip/_vendor/urllib3/__pycache__/__init__.cpython-313.pyc,,
|
| 773 |
+
pip/_vendor/urllib3/__pycache__/_collections.cpython-313.pyc,,
|
| 774 |
+
pip/_vendor/urllib3/__pycache__/_version.cpython-313.pyc,,
|
| 775 |
+
pip/_vendor/urllib3/__pycache__/connection.cpython-313.pyc,,
|
| 776 |
+
pip/_vendor/urllib3/__pycache__/connectionpool.cpython-313.pyc,,
|
| 777 |
+
pip/_vendor/urllib3/__pycache__/exceptions.cpython-313.pyc,,
|
| 778 |
+
pip/_vendor/urllib3/__pycache__/fields.cpython-313.pyc,,
|
| 779 |
+
pip/_vendor/urllib3/__pycache__/filepost.cpython-313.pyc,,
|
| 780 |
+
pip/_vendor/urllib3/__pycache__/poolmanager.cpython-313.pyc,,
|
| 781 |
+
pip/_vendor/urllib3/__pycache__/request.cpython-313.pyc,,
|
| 782 |
+
pip/_vendor/urllib3/__pycache__/response.cpython-313.pyc,,
|
| 783 |
+
pip/_vendor/urllib3/_collections.py,sha256=pyASJJhW7wdOpqJj9QJA8FyGRfr8E8uUUhqUvhF0728,11372
|
| 784 |
+
pip/_vendor/urllib3/_version.py,sha256=t9wGB6ooOTXXgiY66K1m6BZS1CJyXHAU8EoWDTe6Shk,64
|
| 785 |
+
pip/_vendor/urllib3/connection.py,sha256=ttIA909BrbTUzwkqEe_TzZVh4JOOj7g61Ysei2mrwGg,20314
|
| 786 |
+
pip/_vendor/urllib3/connectionpool.py,sha256=e2eiAwNbFNCKxj4bwDKNK-w7HIdSz3OmMxU_TIt-evQ,40408
|
| 787 |
+
pip/_vendor/urllib3/contrib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
| 788 |
+
pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-313.pyc,,
|
| 789 |
+
pip/_vendor/urllib3/contrib/__pycache__/_appengine_environ.cpython-313.pyc,,
|
| 790 |
+
pip/_vendor/urllib3/contrib/__pycache__/appengine.cpython-313.pyc,,
|
| 791 |
+
pip/_vendor/urllib3/contrib/__pycache__/ntlmpool.cpython-313.pyc,,
|
| 792 |
+
pip/_vendor/urllib3/contrib/__pycache__/pyopenssl.cpython-313.pyc,,
|
| 793 |
+
pip/_vendor/urllib3/contrib/__pycache__/securetransport.cpython-313.pyc,,
|
| 794 |
+
pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-313.pyc,,
|
| 795 |
+
pip/_vendor/urllib3/contrib/_appengine_environ.py,sha256=bDbyOEhW2CKLJcQqAKAyrEHN-aklsyHFKq6vF8ZFsmk,957
|
| 796 |
+
pip/_vendor/urllib3/contrib/_securetransport/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
| 797 |
+
pip/_vendor/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-313.pyc,,
|
| 798 |
+
pip/_vendor/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-313.pyc,,
|
| 799 |
+
pip/_vendor/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-313.pyc,,
|
| 800 |
+
pip/_vendor/urllib3/contrib/_securetransport/bindings.py,sha256=4Xk64qIkPBt09A5q-RIFUuDhNc9mXilVapm7WnYnzRw,17632
|
| 801 |
+
pip/_vendor/urllib3/contrib/_securetransport/low_level.py,sha256=B2JBB2_NRP02xK6DCa1Pa9IuxrPwxzDzZbixQkb7U9M,13922
|
| 802 |
+
pip/_vendor/urllib3/contrib/appengine.py,sha256=VR68eAVE137lxTgjBDwCna5UiBZTOKa01Aj_-5BaCz4,11036
|
| 803 |
+
pip/_vendor/urllib3/contrib/ntlmpool.py,sha256=NlfkW7WMdW8ziqudopjHoW299og1BTWi0IeIibquFwk,4528
|
| 804 |
+
pip/_vendor/urllib3/contrib/pyopenssl.py,sha256=hDJh4MhyY_p-oKlFcYcQaVQRDv6GMmBGuW9yjxyeejM,17081
|
| 805 |
+
pip/_vendor/urllib3/contrib/securetransport.py,sha256=Fef1IIUUFHqpevzXiDPbIGkDKchY2FVKeVeLGR1Qq3g,34446
|
| 806 |
+
pip/_vendor/urllib3/contrib/socks.py,sha256=aRi9eWXo9ZEb95XUxef4Z21CFlnnjbEiAo9HOseoMt4,7097
|
| 807 |
+
pip/_vendor/urllib3/exceptions.py,sha256=0Mnno3KHTNfXRfY7638NufOPkUb6mXOm-Lqj-4x2w8A,8217
|
| 808 |
+
pip/_vendor/urllib3/fields.py,sha256=kvLDCg_JmH1lLjUUEY_FLS8UhY7hBvDPuVETbY8mdrM,8579
|
| 809 |
+
pip/_vendor/urllib3/filepost.py,sha256=5b_qqgRHVlL7uLtdAYBzBh-GHmU5AfJVt_2N0XS3PeY,2440
|
| 810 |
+
pip/_vendor/urllib3/packages/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
| 811 |
+
pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-313.pyc,,
|
| 812 |
+
pip/_vendor/urllib3/packages/__pycache__/six.cpython-313.pyc,,
|
| 813 |
+
pip/_vendor/urllib3/packages/backports/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
| 814 |
+
pip/_vendor/urllib3/packages/backports/__pycache__/__init__.cpython-313.pyc,,
|
| 815 |
+
pip/_vendor/urllib3/packages/backports/__pycache__/makefile.cpython-313.pyc,,
|
| 816 |
+
pip/_vendor/urllib3/packages/backports/__pycache__/weakref_finalize.cpython-313.pyc,,
|
| 817 |
+
pip/_vendor/urllib3/packages/backports/makefile.py,sha256=nbzt3i0agPVP07jqqgjhaYjMmuAi_W5E0EywZivVO8E,1417
|
| 818 |
+
pip/_vendor/urllib3/packages/backports/weakref_finalize.py,sha256=tRCal5OAhNSRyb0DhHp-38AtIlCsRP8BxF3NX-6rqIA,5343
|
| 819 |
+
pip/_vendor/urllib3/packages/six.py,sha256=b9LM0wBXv7E7SrbCjAm4wwN-hrH-iNxv18LgWNMMKPo,34665
|
| 820 |
+
pip/_vendor/urllib3/poolmanager.py,sha256=mJmZWy_Mb4-dHbmNCKbDqv3fZS9UF_2bVDuiECHyPaI,20943
|
| 821 |
+
pip/_vendor/urllib3/request.py,sha256=YTWFNr7QIwh7E1W9dde9LM77v2VWTJ5V78XuTTw7D1A,6691
|
| 822 |
+
pip/_vendor/urllib3/response.py,sha256=fmDJAFkG71uFTn-sVSTh2Iw0WmcXQYqkbRjihvwBjU8,30641
|
| 823 |
+
pip/_vendor/urllib3/util/__init__.py,sha256=JEmSmmqqLyaw8P51gUImZh8Gwg9i1zSe-DoqAitn2nc,1155
|
| 824 |
+
pip/_vendor/urllib3/util/__pycache__/__init__.cpython-313.pyc,,
|
| 825 |
+
pip/_vendor/urllib3/util/__pycache__/connection.cpython-313.pyc,,
|
| 826 |
+
pip/_vendor/urllib3/util/__pycache__/proxy.cpython-313.pyc,,
|
| 827 |
+
pip/_vendor/urllib3/util/__pycache__/queue.cpython-313.pyc,,
|
| 828 |
+
pip/_vendor/urllib3/util/__pycache__/request.cpython-313.pyc,,
|
| 829 |
+
pip/_vendor/urllib3/util/__pycache__/response.cpython-313.pyc,,
|
| 830 |
+
pip/_vendor/urllib3/util/__pycache__/retry.cpython-313.pyc,,
|
| 831 |
+
pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-313.pyc,,
|
| 832 |
+
pip/_vendor/urllib3/util/__pycache__/ssl_match_hostname.cpython-313.pyc,,
|
| 833 |
+
pip/_vendor/urllib3/util/__pycache__/ssltransport.cpython-313.pyc,,
|
| 834 |
+
pip/_vendor/urllib3/util/__pycache__/timeout.cpython-313.pyc,,
|
| 835 |
+
pip/_vendor/urllib3/util/__pycache__/url.cpython-313.pyc,,
|
| 836 |
+
pip/_vendor/urllib3/util/__pycache__/wait.cpython-313.pyc,,
|
| 837 |
+
pip/_vendor/urllib3/util/connection.py,sha256=5Lx2B1PW29KxBn2T0xkN1CBgRBa3gGVJBKoQoRogEVk,4901
|
| 838 |
+
pip/_vendor/urllib3/util/proxy.py,sha256=zUvPPCJrp6dOF0N4GAVbOcl6o-4uXKSrGiTkkr5vUS4,1605
|
| 839 |
+
pip/_vendor/urllib3/util/queue.py,sha256=nRgX8_eX-_VkvxoX096QWoz8Ps0QHUAExILCY_7PncM,498
|
| 840 |
+
pip/_vendor/urllib3/util/request.py,sha256=C0OUt2tcU6LRiQJ7YYNP9GvPrSvl7ziIBekQ-5nlBZk,3997
|
| 841 |
+
pip/_vendor/urllib3/util/response.py,sha256=GJpg3Egi9qaJXRwBh5wv-MNuRWan5BIu40oReoxWP28,3510
|
| 842 |
+
pip/_vendor/urllib3/util/retry.py,sha256=6ENvOZ8PBDzh8kgixpql9lIrb2dxH-k7ZmBanJF2Ng4,22050
|
| 843 |
+
pip/_vendor/urllib3/util/ssl_.py,sha256=QDuuTxPSCj1rYtZ4xpD7Ux-r20TD50aHyqKyhQ7Bq4A,17460
|
| 844 |
+
pip/_vendor/urllib3/util/ssl_match_hostname.py,sha256=Ir4cZVEjmAk8gUAIHWSi7wtOO83UCYABY2xFD1Ql_WA,5758
|
| 845 |
+
pip/_vendor/urllib3/util/ssltransport.py,sha256=NA-u5rMTrDFDFC8QzRKUEKMG0561hOD4qBTr3Z4pv6E,6895
|
| 846 |
+
pip/_vendor/urllib3/util/timeout.py,sha256=cwq4dMk87mJHSBktK1miYJ-85G-3T3RmT20v7SFCpno,10168
|
| 847 |
+
pip/_vendor/urllib3/util/url.py,sha256=lCAE7M5myA8EDdW0sJuyyZhVB9K_j38ljWhHAnFaWoE,14296
|
| 848 |
+
pip/_vendor/urllib3/util/wait.py,sha256=fOX0_faozG2P7iVojQoE1mbydweNyTcm-hXEfFrTtLI,5403
|
| 849 |
+
pip/_vendor/vendor.txt,sha256=Fym1hhuw75IJOl33NPi5nIJJc66DioBSUWrVRIVtRUE,373
|
| 850 |
+
pip/py.typed,sha256=EBVvvPRTn_eIpz5e5QztSCdrMX7Qwd7VP93RSoIlZ2I,286
|
env/lib/python3.13/site-packages/pip-25.1.1.dist-info/REQUESTED
ADDED
|
File without changes
|
env/lib/python3.13/site-packages/pip-25.1.1.dist-info/WHEEL
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Wheel-Version: 1.0
|
| 2 |
+
Generator: setuptools (78.1.1)
|
| 3 |
+
Root-Is-Purelib: true
|
| 4 |
+
Tag: py3-none-any
|
| 5 |
+
|
env/lib/python3.13/site-packages/pip-25.1.1.dist-info/entry_points.txt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[console_scripts]
|
| 2 |
+
pip = pip._internal.cli.main:main
|
| 3 |
+
pip3 = pip._internal.cli.main:main
|
env/lib/python3.13/site-packages/pip-25.1.1.dist-info/top_level.txt
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
pip
|
env/lib/python3.13/site-packages/typer/__init__.py
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Typer, build great CLIs. Easy to code. Based on Python type hints."""
|
| 2 |
+
|
| 3 |
+
__version__ = "0.20.0"
|
| 4 |
+
|
| 5 |
+
from shutil import get_terminal_size as get_terminal_size
|
| 6 |
+
|
| 7 |
+
from click.exceptions import Abort as Abort
|
| 8 |
+
from click.exceptions import BadParameter as BadParameter
|
| 9 |
+
from click.exceptions import Exit as Exit
|
| 10 |
+
from click.termui import clear as clear
|
| 11 |
+
from click.termui import confirm as confirm
|
| 12 |
+
from click.termui import echo_via_pager as echo_via_pager
|
| 13 |
+
from click.termui import edit as edit
|
| 14 |
+
from click.termui import getchar as getchar
|
| 15 |
+
from click.termui import pause as pause
|
| 16 |
+
from click.termui import progressbar as progressbar
|
| 17 |
+
from click.termui import prompt as prompt
|
| 18 |
+
from click.termui import secho as secho
|
| 19 |
+
from click.termui import style as style
|
| 20 |
+
from click.termui import unstyle as unstyle
|
| 21 |
+
from click.utils import echo as echo
|
| 22 |
+
from click.utils import format_filename as format_filename
|
| 23 |
+
from click.utils import get_app_dir as get_app_dir
|
| 24 |
+
from click.utils import get_binary_stream as get_binary_stream
|
| 25 |
+
from click.utils import get_text_stream as get_text_stream
|
| 26 |
+
from click.utils import open_file as open_file
|
| 27 |
+
|
| 28 |
+
from . import colors as colors
|
| 29 |
+
from .main import Typer as Typer
|
| 30 |
+
from .main import launch as launch
|
| 31 |
+
from .main import run as run
|
| 32 |
+
from .models import CallbackParam as CallbackParam
|
| 33 |
+
from .models import Context as Context
|
| 34 |
+
from .models import FileBinaryRead as FileBinaryRead
|
| 35 |
+
from .models import FileBinaryWrite as FileBinaryWrite
|
| 36 |
+
from .models import FileText as FileText
|
| 37 |
+
from .models import FileTextWrite as FileTextWrite
|
| 38 |
+
from .params import Argument as Argument
|
| 39 |
+
from .params import Option as Option
|
env/lib/python3.13/site-packages/typer/_completion_shared.py
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import re
|
| 3 |
+
import subprocess
|
| 4 |
+
from enum import Enum
|
| 5 |
+
from pathlib import Path
|
| 6 |
+
from typing import Optional, Tuple
|
| 7 |
+
|
| 8 |
+
import click
|
| 9 |
+
|
| 10 |
+
try:
|
| 11 |
+
import shellingham
|
| 12 |
+
except ImportError: # pragma: no cover
|
| 13 |
+
shellingham = None
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
class Shells(str, Enum):
|
| 17 |
+
bash = "bash"
|
| 18 |
+
zsh = "zsh"
|
| 19 |
+
fish = "fish"
|
| 20 |
+
powershell = "powershell"
|
| 21 |
+
pwsh = "pwsh"
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
COMPLETION_SCRIPT_BASH = """
|
| 25 |
+
%(complete_func)s() {
|
| 26 |
+
local IFS=$'\n'
|
| 27 |
+
COMPREPLY=( $( env COMP_WORDS="${COMP_WORDS[*]}" \\
|
| 28 |
+
COMP_CWORD=$COMP_CWORD \\
|
| 29 |
+
%(autocomplete_var)s=complete_bash $1 ) )
|
| 30 |
+
return 0
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
complete -o default -F %(complete_func)s %(prog_name)s
|
| 34 |
+
"""
|
| 35 |
+
|
| 36 |
+
COMPLETION_SCRIPT_ZSH = """
|
| 37 |
+
#compdef %(prog_name)s
|
| 38 |
+
|
| 39 |
+
%(complete_func)s() {
|
| 40 |
+
eval $(env _TYPER_COMPLETE_ARGS="${words[1,$CURRENT]}" %(autocomplete_var)s=complete_zsh %(prog_name)s)
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
compdef %(complete_func)s %(prog_name)s
|
| 44 |
+
"""
|
| 45 |
+
|
| 46 |
+
COMPLETION_SCRIPT_FISH = 'complete --command %(prog_name)s --no-files --arguments "(env %(autocomplete_var)s=complete_fish _TYPER_COMPLETE_FISH_ACTION=get-args _TYPER_COMPLETE_ARGS=(commandline -cp) %(prog_name)s)" --condition "env %(autocomplete_var)s=complete_fish _TYPER_COMPLETE_FISH_ACTION=is-args _TYPER_COMPLETE_ARGS=(commandline -cp) %(prog_name)s"'
|
| 47 |
+
|
| 48 |
+
COMPLETION_SCRIPT_POWER_SHELL = """
|
| 49 |
+
Import-Module PSReadLine
|
| 50 |
+
Set-PSReadLineKeyHandler -Chord Tab -Function MenuComplete
|
| 51 |
+
$scriptblock = {
|
| 52 |
+
param($wordToComplete, $commandAst, $cursorPosition)
|
| 53 |
+
$Env:%(autocomplete_var)s = "complete_powershell"
|
| 54 |
+
$Env:_TYPER_COMPLETE_ARGS = $commandAst.ToString()
|
| 55 |
+
$Env:_TYPER_COMPLETE_WORD_TO_COMPLETE = $wordToComplete
|
| 56 |
+
%(prog_name)s | ForEach-Object {
|
| 57 |
+
$commandArray = $_ -Split ":::"
|
| 58 |
+
$command = $commandArray[0]
|
| 59 |
+
$helpString = $commandArray[1]
|
| 60 |
+
[System.Management.Automation.CompletionResult]::new(
|
| 61 |
+
$command, $command, 'ParameterValue', $helpString)
|
| 62 |
+
}
|
| 63 |
+
$Env:%(autocomplete_var)s = ""
|
| 64 |
+
$Env:_TYPER_COMPLETE_ARGS = ""
|
| 65 |
+
$Env:_TYPER_COMPLETE_WORD_TO_COMPLETE = ""
|
| 66 |
+
}
|
| 67 |
+
Register-ArgumentCompleter -Native -CommandName %(prog_name)s -ScriptBlock $scriptblock
|
| 68 |
+
"""
|
| 69 |
+
|
| 70 |
+
_completion_scripts = {
|
| 71 |
+
"bash": COMPLETION_SCRIPT_BASH,
|
| 72 |
+
"zsh": COMPLETION_SCRIPT_ZSH,
|
| 73 |
+
"fish": COMPLETION_SCRIPT_FISH,
|
| 74 |
+
"powershell": COMPLETION_SCRIPT_POWER_SHELL,
|
| 75 |
+
"pwsh": COMPLETION_SCRIPT_POWER_SHELL,
|
| 76 |
+
}
|
| 77 |
+
|
| 78 |
+
# TODO: Probably refactor this, copied from Click 7.x
|
| 79 |
+
_invalid_ident_char_re = re.compile(r"[^a-zA-Z0-9_]")
|
| 80 |
+
|
| 81 |
+
|
| 82 |
+
def get_completion_script(*, prog_name: str, complete_var: str, shell: str) -> str:
|
| 83 |
+
cf_name = _invalid_ident_char_re.sub("", prog_name.replace("-", "_"))
|
| 84 |
+
script = _completion_scripts.get(shell)
|
| 85 |
+
if script is None:
|
| 86 |
+
click.echo(f"Shell {shell} not supported.", err=True)
|
| 87 |
+
raise click.exceptions.Exit(1)
|
| 88 |
+
return (
|
| 89 |
+
script
|
| 90 |
+
% {
|
| 91 |
+
"complete_func": f"_{cf_name}_completion",
|
| 92 |
+
"prog_name": prog_name,
|
| 93 |
+
"autocomplete_var": complete_var,
|
| 94 |
+
}
|
| 95 |
+
).strip()
|
| 96 |
+
|
| 97 |
+
|
| 98 |
+
def install_bash(*, prog_name: str, complete_var: str, shell: str) -> Path:
|
| 99 |
+
# Ref: https://github.com/scop/bash-completion#faq
|
| 100 |
+
# It seems bash-completion is the official completion system for bash:
|
| 101 |
+
# Ref: https://www.gnu.org/software/bash/manual/html_node/A-Programmable-Completion-Example.html
|
| 102 |
+
# But installing in the locations from the docs doesn't seem to have effect
|
| 103 |
+
completion_path = Path.home() / ".bash_completions" / f"{prog_name}.sh"
|
| 104 |
+
rc_path = Path.home() / ".bashrc"
|
| 105 |
+
rc_path.parent.mkdir(parents=True, exist_ok=True)
|
| 106 |
+
rc_content = ""
|
| 107 |
+
if rc_path.is_file():
|
| 108 |
+
rc_content = rc_path.read_text()
|
| 109 |
+
completion_init_lines = [f"source '{completion_path}'"]
|
| 110 |
+
for line in completion_init_lines:
|
| 111 |
+
if line not in rc_content: # pragma: no cover
|
| 112 |
+
rc_content += f"\n{line}"
|
| 113 |
+
rc_content += "\n"
|
| 114 |
+
rc_path.write_text(rc_content)
|
| 115 |
+
# Install completion
|
| 116 |
+
completion_path.parent.mkdir(parents=True, exist_ok=True)
|
| 117 |
+
script_content = get_completion_script(
|
| 118 |
+
prog_name=prog_name, complete_var=complete_var, shell=shell
|
| 119 |
+
)
|
| 120 |
+
completion_path.write_text(script_content)
|
| 121 |
+
return completion_path
|
| 122 |
+
|
| 123 |
+
|
| 124 |
+
def install_zsh(*, prog_name: str, complete_var: str, shell: str) -> Path:
|
| 125 |
+
# Setup Zsh and load ~/.zfunc
|
| 126 |
+
zshrc_path = Path.home() / ".zshrc"
|
| 127 |
+
zshrc_path.parent.mkdir(parents=True, exist_ok=True)
|
| 128 |
+
zshrc_content = ""
|
| 129 |
+
if zshrc_path.is_file():
|
| 130 |
+
zshrc_content = zshrc_path.read_text()
|
| 131 |
+
completion_line = "fpath+=~/.zfunc; autoload -Uz compinit; compinit"
|
| 132 |
+
if completion_line not in zshrc_content:
|
| 133 |
+
zshrc_content += f"\n{completion_line}\n"
|
| 134 |
+
style_line = "zstyle ':completion:*' menu select"
|
| 135 |
+
# TODO: consider setting the style only for the current program
|
| 136 |
+
# style_line = f"zstyle ':completion:*:*:{prog_name}:*' menu select"
|
| 137 |
+
# Install zstyle completion config only if the user doesn't have a customization
|
| 138 |
+
if "zstyle" not in zshrc_content:
|
| 139 |
+
zshrc_content += f"\n{style_line}\n"
|
| 140 |
+
zshrc_content = f"{zshrc_content.strip()}\n"
|
| 141 |
+
zshrc_path.write_text(zshrc_content)
|
| 142 |
+
# Install completion under ~/.zfunc/
|
| 143 |
+
path_obj = Path.home() / f".zfunc/_{prog_name}"
|
| 144 |
+
path_obj.parent.mkdir(parents=True, exist_ok=True)
|
| 145 |
+
script_content = get_completion_script(
|
| 146 |
+
prog_name=prog_name, complete_var=complete_var, shell=shell
|
| 147 |
+
)
|
| 148 |
+
path_obj.write_text(script_content)
|
| 149 |
+
return path_obj
|
| 150 |
+
|
| 151 |
+
|
| 152 |
+
def install_fish(*, prog_name: str, complete_var: str, shell: str) -> Path:
|
| 153 |
+
path_obj = Path.home() / f".config/fish/completions/{prog_name}.fish"
|
| 154 |
+
parent_dir: Path = path_obj.parent
|
| 155 |
+
parent_dir.mkdir(parents=True, exist_ok=True)
|
| 156 |
+
script_content = get_completion_script(
|
| 157 |
+
prog_name=prog_name, complete_var=complete_var, shell=shell
|
| 158 |
+
)
|
| 159 |
+
path_obj.write_text(f"{script_content}\n")
|
| 160 |
+
return path_obj
|
| 161 |
+
|
| 162 |
+
|
| 163 |
+
def install_powershell(*, prog_name: str, complete_var: str, shell: str) -> Path:
|
| 164 |
+
subprocess.run(
|
| 165 |
+
[
|
| 166 |
+
shell,
|
| 167 |
+
"-Command",
|
| 168 |
+
"Set-ExecutionPolicy",
|
| 169 |
+
"Unrestricted",
|
| 170 |
+
"-Scope",
|
| 171 |
+
"CurrentUser",
|
| 172 |
+
]
|
| 173 |
+
)
|
| 174 |
+
result = subprocess.run(
|
| 175 |
+
[shell, "-NoProfile", "-Command", "echo", "$profile"],
|
| 176 |
+
check=True,
|
| 177 |
+
stdout=subprocess.PIPE,
|
| 178 |
+
)
|
| 179 |
+
if result.returncode != 0: # pragma: no cover
|
| 180 |
+
click.echo("Couldn't get PowerShell user profile", err=True)
|
| 181 |
+
raise click.exceptions.Exit(result.returncode)
|
| 182 |
+
path_str = ""
|
| 183 |
+
if isinstance(result.stdout, str): # pragma: no cover
|
| 184 |
+
path_str = result.stdout
|
| 185 |
+
if isinstance(result.stdout, bytes):
|
| 186 |
+
for encoding in ["windows-1252", "utf8", "cp850"]:
|
| 187 |
+
try:
|
| 188 |
+
path_str = result.stdout.decode(encoding)
|
| 189 |
+
break
|
| 190 |
+
except UnicodeDecodeError: # pragma: no cover
|
| 191 |
+
pass
|
| 192 |
+
if not path_str: # pragma: no cover
|
| 193 |
+
click.echo("Couldn't decode the path automatically", err=True)
|
| 194 |
+
raise click.exceptions.Exit(1)
|
| 195 |
+
path_obj = Path(path_str.strip())
|
| 196 |
+
parent_dir: Path = path_obj.parent
|
| 197 |
+
parent_dir.mkdir(parents=True, exist_ok=True)
|
| 198 |
+
script_content = get_completion_script(
|
| 199 |
+
prog_name=prog_name, complete_var=complete_var, shell=shell
|
| 200 |
+
)
|
| 201 |
+
with path_obj.open(mode="a") as f:
|
| 202 |
+
f.write(f"{script_content}\n")
|
| 203 |
+
return path_obj
|
| 204 |
+
|
| 205 |
+
|
| 206 |
+
def install(
|
| 207 |
+
shell: Optional[str] = None,
|
| 208 |
+
prog_name: Optional[str] = None,
|
| 209 |
+
complete_var: Optional[str] = None,
|
| 210 |
+
) -> Tuple[str, Path]:
|
| 211 |
+
prog_name = prog_name or click.get_current_context().find_root().info_name
|
| 212 |
+
assert prog_name
|
| 213 |
+
if complete_var is None:
|
| 214 |
+
complete_var = "_{}_COMPLETE".format(prog_name.replace("-", "_").upper())
|
| 215 |
+
test_disable_detection = os.getenv("_TYPER_COMPLETE_TEST_DISABLE_SHELL_DETECTION")
|
| 216 |
+
if shell is None and shellingham is not None and not test_disable_detection:
|
| 217 |
+
shell, _ = shellingham.detect_shell()
|
| 218 |
+
if shell == "bash":
|
| 219 |
+
installed_path = install_bash(
|
| 220 |
+
prog_name=prog_name, complete_var=complete_var, shell=shell
|
| 221 |
+
)
|
| 222 |
+
return shell, installed_path
|
| 223 |
+
elif shell == "zsh":
|
| 224 |
+
installed_path = install_zsh(
|
| 225 |
+
prog_name=prog_name, complete_var=complete_var, shell=shell
|
| 226 |
+
)
|
| 227 |
+
return shell, installed_path
|
| 228 |
+
elif shell == "fish":
|
| 229 |
+
installed_path = install_fish(
|
| 230 |
+
prog_name=prog_name, complete_var=complete_var, shell=shell
|
| 231 |
+
)
|
| 232 |
+
return shell, installed_path
|
| 233 |
+
elif shell in {"powershell", "pwsh"}:
|
| 234 |
+
installed_path = install_powershell(
|
| 235 |
+
prog_name=prog_name, complete_var=complete_var, shell=shell
|
| 236 |
+
)
|
| 237 |
+
return shell, installed_path
|
| 238 |
+
else:
|
| 239 |
+
click.echo(f"Shell {shell} is not supported.")
|
| 240 |
+
raise click.exceptions.Exit(1)
|
env/lib/python3.13/site-packages/typer/_types.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from enum import Enum
|
| 2 |
+
from typing import Generic, TypeVar, Union
|
| 3 |
+
|
| 4 |
+
import click
|
| 5 |
+
|
| 6 |
+
ParamTypeValue = TypeVar("ParamTypeValue")
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
class TyperChoice(click.Choice, Generic[ParamTypeValue]): # type: ignore[type-arg]
|
| 10 |
+
def normalize_choice(
|
| 11 |
+
self, choice: ParamTypeValue, ctx: Union[click.Context, None]
|
| 12 |
+
) -> str:
|
| 13 |
+
# Click 8.2.0 added a new method `normalize_choice` to the `Choice` class
|
| 14 |
+
# to support enums, but it uses the enum names, while Typer has always used the
|
| 15 |
+
# enum values.
|
| 16 |
+
# This class overrides that method to maintain the previous behavior.
|
| 17 |
+
# In Click:
|
| 18 |
+
# normed_value = choice.name if isinstance(choice, Enum) else str(choice)
|
| 19 |
+
normed_value = str(choice.value) if isinstance(choice, Enum) else str(choice)
|
| 20 |
+
|
| 21 |
+
if ctx is not None and ctx.token_normalize_func is not None:
|
| 22 |
+
normed_value = ctx.token_normalize_func(normed_value)
|
| 23 |
+
|
| 24 |
+
if not self.case_sensitive:
|
| 25 |
+
normed_value = normed_value.casefold()
|
| 26 |
+
|
| 27 |
+
return normed_value
|
env/lib/python3.13/site-packages/typer/completion.py
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import sys
|
| 3 |
+
from typing import Any, MutableMapping, Tuple
|
| 4 |
+
|
| 5 |
+
import click
|
| 6 |
+
|
| 7 |
+
from ._completion_classes import completion_init
|
| 8 |
+
from ._completion_shared import Shells, get_completion_script, install
|
| 9 |
+
from .models import ParamMeta
|
| 10 |
+
from .params import Option
|
| 11 |
+
from .utils import get_params_from_function
|
| 12 |
+
|
| 13 |
+
try:
|
| 14 |
+
import shellingham
|
| 15 |
+
except ImportError: # pragma: no cover
|
| 16 |
+
shellingham = None
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
_click_patched = False
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
def get_completion_inspect_parameters() -> Tuple[ParamMeta, ParamMeta]:
|
| 23 |
+
completion_init()
|
| 24 |
+
test_disable_detection = os.getenv("_TYPER_COMPLETE_TEST_DISABLE_SHELL_DETECTION")
|
| 25 |
+
if shellingham and not test_disable_detection:
|
| 26 |
+
parameters = get_params_from_function(_install_completion_placeholder_function)
|
| 27 |
+
else:
|
| 28 |
+
parameters = get_params_from_function(
|
| 29 |
+
_install_completion_no_auto_placeholder_function
|
| 30 |
+
)
|
| 31 |
+
install_param, show_param = parameters.values()
|
| 32 |
+
return install_param, show_param
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
def install_callback(ctx: click.Context, param: click.Parameter, value: Any) -> Any:
|
| 36 |
+
if not value or ctx.resilient_parsing:
|
| 37 |
+
return value # pragma: no cover
|
| 38 |
+
if isinstance(value, str):
|
| 39 |
+
shell, path = install(shell=value)
|
| 40 |
+
else:
|
| 41 |
+
shell, path = install()
|
| 42 |
+
click.secho(f"{shell} completion installed in {path}", fg="green")
|
| 43 |
+
click.echo("Completion will take effect once you restart the terminal")
|
| 44 |
+
sys.exit(0)
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
def show_callback(ctx: click.Context, param: click.Parameter, value: Any) -> Any:
|
| 48 |
+
if not value or ctx.resilient_parsing:
|
| 49 |
+
return value # pragma: no cover
|
| 50 |
+
prog_name = ctx.find_root().info_name
|
| 51 |
+
assert prog_name
|
| 52 |
+
complete_var = "_{}_COMPLETE".format(prog_name.replace("-", "_").upper())
|
| 53 |
+
shell = ""
|
| 54 |
+
test_disable_detection = os.getenv("_TYPER_COMPLETE_TEST_DISABLE_SHELL_DETECTION")
|
| 55 |
+
if isinstance(value, str):
|
| 56 |
+
shell = value
|
| 57 |
+
elif shellingham and not test_disable_detection:
|
| 58 |
+
shell, _ = shellingham.detect_shell()
|
| 59 |
+
script_content = get_completion_script(
|
| 60 |
+
prog_name=prog_name, complete_var=complete_var, shell=shell
|
| 61 |
+
)
|
| 62 |
+
click.echo(script_content)
|
| 63 |
+
sys.exit(0)
|
| 64 |
+
|
| 65 |
+
|
| 66 |
+
# Create a fake command function to extract the completion parameters
|
| 67 |
+
def _install_completion_placeholder_function(
|
| 68 |
+
install_completion: bool = Option(
|
| 69 |
+
None,
|
| 70 |
+
"--install-completion",
|
| 71 |
+
callback=install_callback,
|
| 72 |
+
expose_value=False,
|
| 73 |
+
help="Install completion for the current shell.",
|
| 74 |
+
),
|
| 75 |
+
show_completion: bool = Option(
|
| 76 |
+
None,
|
| 77 |
+
"--show-completion",
|
| 78 |
+
callback=show_callback,
|
| 79 |
+
expose_value=False,
|
| 80 |
+
help="Show completion for the current shell, to copy it or customize the installation.",
|
| 81 |
+
),
|
| 82 |
+
) -> Any:
|
| 83 |
+
pass # pragma: no cover
|
| 84 |
+
|
| 85 |
+
|
| 86 |
+
def _install_completion_no_auto_placeholder_function(
|
| 87 |
+
install_completion: Shells = Option(
|
| 88 |
+
None,
|
| 89 |
+
callback=install_callback,
|
| 90 |
+
expose_value=False,
|
| 91 |
+
help="Install completion for the specified shell.",
|
| 92 |
+
),
|
| 93 |
+
show_completion: Shells = Option(
|
| 94 |
+
None,
|
| 95 |
+
callback=show_callback,
|
| 96 |
+
expose_value=False,
|
| 97 |
+
help="Show completion for the specified shell, to copy it or customize the installation.",
|
| 98 |
+
),
|
| 99 |
+
) -> Any:
|
| 100 |
+
pass # pragma: no cover
|
| 101 |
+
|
| 102 |
+
|
| 103 |
+
# Re-implement Click's shell_complete to add error message with:
|
| 104 |
+
# Invalid completion instruction
|
| 105 |
+
# To use 7.x instruction style for compatibility
|
| 106 |
+
# And to add extra error messages, for compatibility with Typer in previous versions
|
| 107 |
+
# This is only called in new Command method, only used by Click 8.x+
|
| 108 |
+
def shell_complete(
|
| 109 |
+
cli: click.Command,
|
| 110 |
+
ctx_args: MutableMapping[str, Any],
|
| 111 |
+
prog_name: str,
|
| 112 |
+
complete_var: str,
|
| 113 |
+
instruction: str,
|
| 114 |
+
) -> int:
|
| 115 |
+
import click
|
| 116 |
+
import click.shell_completion
|
| 117 |
+
|
| 118 |
+
if "_" not in instruction:
|
| 119 |
+
click.echo("Invalid completion instruction.", err=True)
|
| 120 |
+
return 1
|
| 121 |
+
|
| 122 |
+
# Click 8 changed the order/style of shell instructions from e.g.
|
| 123 |
+
# source_bash to bash_source
|
| 124 |
+
# Typer override to preserve the old style for compatibility
|
| 125 |
+
# Original in Click 8.x commented:
|
| 126 |
+
# shell, _, instruction = instruction.partition("_")
|
| 127 |
+
instruction, _, shell = instruction.partition("_")
|
| 128 |
+
# Typer override end
|
| 129 |
+
|
| 130 |
+
comp_cls = click.shell_completion.get_completion_class(shell)
|
| 131 |
+
|
| 132 |
+
if comp_cls is None:
|
| 133 |
+
click.echo(f"Shell {shell} not supported.", err=True)
|
| 134 |
+
return 1
|
| 135 |
+
|
| 136 |
+
comp = comp_cls(cli, ctx_args, prog_name, complete_var)
|
| 137 |
+
|
| 138 |
+
if instruction == "source":
|
| 139 |
+
click.echo(comp.source())
|
| 140 |
+
return 0
|
| 141 |
+
|
| 142 |
+
# Typer override to print the completion help msg with Rich
|
| 143 |
+
if instruction == "complete":
|
| 144 |
+
click.echo(comp.complete())
|
| 145 |
+
return 0
|
| 146 |
+
# Typer override end
|
| 147 |
+
|
| 148 |
+
click.echo(f'Completion instruction "{instruction}" not supported.', err=True)
|
| 149 |
+
return 1
|
env/lib/python3.13/site-packages/typer/core.py
ADDED
|
@@ -0,0 +1,829 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import errno
|
| 2 |
+
import importlib.util
|
| 3 |
+
import inspect
|
| 4 |
+
import os
|
| 5 |
+
import sys
|
| 6 |
+
from difflib import get_close_matches
|
| 7 |
+
from enum import Enum
|
| 8 |
+
from gettext import gettext as _
|
| 9 |
+
from typing import (
|
| 10 |
+
Any,
|
| 11 |
+
Callable,
|
| 12 |
+
Dict,
|
| 13 |
+
List,
|
| 14 |
+
MutableMapping,
|
| 15 |
+
Optional,
|
| 16 |
+
Sequence,
|
| 17 |
+
TextIO,
|
| 18 |
+
Tuple,
|
| 19 |
+
Union,
|
| 20 |
+
cast,
|
| 21 |
+
)
|
| 22 |
+
|
| 23 |
+
import click
|
| 24 |
+
import click.core
|
| 25 |
+
import click.formatting
|
| 26 |
+
import click.shell_completion
|
| 27 |
+
import click.types
|
| 28 |
+
import click.utils
|
| 29 |
+
|
| 30 |
+
from ._typing import Literal
|
| 31 |
+
|
| 32 |
+
MarkupMode = Literal["markdown", "rich", None]
|
| 33 |
+
|
| 34 |
+
HAS_RICH = importlib.util.find_spec("rich") is not None
|
| 35 |
+
|
| 36 |
+
if HAS_RICH:
|
| 37 |
+
DEFAULT_MARKUP_MODE: MarkupMode = "rich"
|
| 38 |
+
else: # pragma: no cover
|
| 39 |
+
DEFAULT_MARKUP_MODE = None
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
# Copy from click.parser._split_opt
|
| 43 |
+
def _split_opt(opt: str) -> Tuple[str, str]:
|
| 44 |
+
first = opt[:1]
|
| 45 |
+
if first.isalnum():
|
| 46 |
+
return "", opt
|
| 47 |
+
if opt[1:2] == first:
|
| 48 |
+
return opt[:2], opt[2:]
|
| 49 |
+
return first, opt[1:]
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
def _typer_param_setup_autocompletion_compat(
|
| 53 |
+
self: click.Parameter,
|
| 54 |
+
*,
|
| 55 |
+
autocompletion: Optional[
|
| 56 |
+
Callable[[click.Context, List[str], str], List[Union[Tuple[str, str], str]]]
|
| 57 |
+
] = None,
|
| 58 |
+
) -> None:
|
| 59 |
+
if self._custom_shell_complete is not None:
|
| 60 |
+
import warnings
|
| 61 |
+
|
| 62 |
+
warnings.warn(
|
| 63 |
+
"In Typer, only the parameter 'autocompletion' is supported. "
|
| 64 |
+
"The support for 'shell_complete' is deprecated and will be removed in upcoming versions. ",
|
| 65 |
+
DeprecationWarning,
|
| 66 |
+
stacklevel=2,
|
| 67 |
+
)
|
| 68 |
+
|
| 69 |
+
if autocompletion is not None:
|
| 70 |
+
|
| 71 |
+
def compat_autocompletion(
|
| 72 |
+
ctx: click.Context, param: click.core.Parameter, incomplete: str
|
| 73 |
+
) -> List["click.shell_completion.CompletionItem"]:
|
| 74 |
+
from click.shell_completion import CompletionItem
|
| 75 |
+
|
| 76 |
+
out = []
|
| 77 |
+
|
| 78 |
+
for c in autocompletion(ctx, [], incomplete):
|
| 79 |
+
if isinstance(c, tuple):
|
| 80 |
+
use_completion = CompletionItem(c[0], help=c[1])
|
| 81 |
+
else:
|
| 82 |
+
assert isinstance(c, str)
|
| 83 |
+
use_completion = CompletionItem(c)
|
| 84 |
+
|
| 85 |
+
if use_completion.value.startswith(incomplete):
|
| 86 |
+
out.append(use_completion)
|
| 87 |
+
|
| 88 |
+
return out
|
| 89 |
+
|
| 90 |
+
self._custom_shell_complete = compat_autocompletion
|
| 91 |
+
|
| 92 |
+
|
| 93 |
+
def _get_default_string(
|
| 94 |
+
obj: Union["TyperArgument", "TyperOption"],
|
| 95 |
+
*,
|
| 96 |
+
ctx: click.Context,
|
| 97 |
+
show_default_is_str: bool,
|
| 98 |
+
default_value: Union[List[Any], Tuple[Any, ...], str, Callable[..., Any], Any],
|
| 99 |
+
) -> str:
|
| 100 |
+
# Extracted from click.core.Option.get_help_record() to be reused by
|
| 101 |
+
# rich_utils avoiding RegEx hacks
|
| 102 |
+
if show_default_is_str:
|
| 103 |
+
default_string = f"({obj.show_default})"
|
| 104 |
+
elif isinstance(default_value, (list, tuple)):
|
| 105 |
+
default_string = ", ".join(
|
| 106 |
+
_get_default_string(
|
| 107 |
+
obj, ctx=ctx, show_default_is_str=show_default_is_str, default_value=d
|
| 108 |
+
)
|
| 109 |
+
for d in default_value
|
| 110 |
+
)
|
| 111 |
+
elif isinstance(default_value, Enum):
|
| 112 |
+
default_string = str(default_value.value)
|
| 113 |
+
elif inspect.isfunction(default_value):
|
| 114 |
+
default_string = _("(dynamic)")
|
| 115 |
+
elif isinstance(obj, TyperOption) and obj.is_bool_flag and obj.secondary_opts:
|
| 116 |
+
# For boolean flags that have distinct True/False opts,
|
| 117 |
+
# use the opt without prefix instead of the value.
|
| 118 |
+
# Typer override, original commented
|
| 119 |
+
# default_string = click.parser.split_opt(
|
| 120 |
+
# (self.opts if self.default else self.secondary_opts)[0]
|
| 121 |
+
# )[1]
|
| 122 |
+
if obj.default:
|
| 123 |
+
if obj.opts:
|
| 124 |
+
default_string = _split_opt(obj.opts[0])[1]
|
| 125 |
+
else:
|
| 126 |
+
default_string = str(default_value)
|
| 127 |
+
else:
|
| 128 |
+
default_string = _split_opt(obj.secondary_opts[0])[1]
|
| 129 |
+
# Typer override end
|
| 130 |
+
elif (
|
| 131 |
+
isinstance(obj, TyperOption)
|
| 132 |
+
and obj.is_bool_flag
|
| 133 |
+
and not obj.secondary_opts
|
| 134 |
+
and not default_value
|
| 135 |
+
):
|
| 136 |
+
default_string = ""
|
| 137 |
+
else:
|
| 138 |
+
default_string = str(default_value)
|
| 139 |
+
return default_string
|
| 140 |
+
|
| 141 |
+
|
| 142 |
+
def _extract_default_help_str(
|
| 143 |
+
obj: Union["TyperArgument", "TyperOption"], *, ctx: click.Context
|
| 144 |
+
) -> Optional[Union[Any, Callable[[], Any]]]:
|
| 145 |
+
# Extracted from click.core.Option.get_help_record() to be reused by
|
| 146 |
+
# rich_utils avoiding RegEx hacks
|
| 147 |
+
# Temporarily enable resilient parsing to avoid type casting
|
| 148 |
+
# failing for the default. Might be possible to extend this to
|
| 149 |
+
# help formatting in general.
|
| 150 |
+
resilient = ctx.resilient_parsing
|
| 151 |
+
ctx.resilient_parsing = True
|
| 152 |
+
|
| 153 |
+
try:
|
| 154 |
+
default_value = obj.get_default(ctx, call=False)
|
| 155 |
+
finally:
|
| 156 |
+
ctx.resilient_parsing = resilient
|
| 157 |
+
return default_value
|
| 158 |
+
|
| 159 |
+
|
| 160 |
+
def _main(
|
| 161 |
+
self: click.Command,
|
| 162 |
+
*,
|
| 163 |
+
args: Optional[Sequence[str]] = None,
|
| 164 |
+
prog_name: Optional[str] = None,
|
| 165 |
+
complete_var: Optional[str] = None,
|
| 166 |
+
standalone_mode: bool = True,
|
| 167 |
+
windows_expand_args: bool = True,
|
| 168 |
+
rich_markup_mode: MarkupMode = DEFAULT_MARKUP_MODE,
|
| 169 |
+
**extra: Any,
|
| 170 |
+
) -> Any:
|
| 171 |
+
# Typer override, duplicated from click.main() to handle custom rich exceptions
|
| 172 |
+
# Verify that the environment is configured correctly, or reject
|
| 173 |
+
# further execution to avoid a broken script.
|
| 174 |
+
if args is None:
|
| 175 |
+
args = sys.argv[1:]
|
| 176 |
+
|
| 177 |
+
# Covered in Click tests
|
| 178 |
+
if os.name == "nt" and windows_expand_args: # pragma: no cover
|
| 179 |
+
args = click.utils._expand_args(args)
|
| 180 |
+
else:
|
| 181 |
+
args = list(args)
|
| 182 |
+
|
| 183 |
+
if prog_name is None:
|
| 184 |
+
prog_name = click.utils._detect_program_name()
|
| 185 |
+
|
| 186 |
+
# Process shell completion requests and exit early.
|
| 187 |
+
self._main_shell_completion(extra, prog_name, complete_var)
|
| 188 |
+
|
| 189 |
+
try:
|
| 190 |
+
try:
|
| 191 |
+
with self.make_context(prog_name, args, **extra) as ctx:
|
| 192 |
+
rv = self.invoke(ctx)
|
| 193 |
+
if not standalone_mode:
|
| 194 |
+
return rv
|
| 195 |
+
# it's not safe to `ctx.exit(rv)` here!
|
| 196 |
+
# note that `rv` may actually contain data like "1" which
|
| 197 |
+
# has obvious effects
|
| 198 |
+
# more subtle case: `rv=[None, None]` can come out of
|
| 199 |
+
# chained commands which all returned `None` -- so it's not
|
| 200 |
+
# even always obvious that `rv` indicates success/failure
|
| 201 |
+
# by its truthiness/falsiness
|
| 202 |
+
ctx.exit()
|
| 203 |
+
except EOFError as e:
|
| 204 |
+
click.echo(file=sys.stderr)
|
| 205 |
+
raise click.Abort() from e
|
| 206 |
+
except KeyboardInterrupt as e:
|
| 207 |
+
raise click.exceptions.Exit(130) from e
|
| 208 |
+
except click.ClickException as e:
|
| 209 |
+
if not standalone_mode:
|
| 210 |
+
raise
|
| 211 |
+
# Typer override
|
| 212 |
+
if HAS_RICH and rich_markup_mode is not None:
|
| 213 |
+
from . import rich_utils
|
| 214 |
+
|
| 215 |
+
rich_utils.rich_format_error(e)
|
| 216 |
+
else:
|
| 217 |
+
e.show()
|
| 218 |
+
# Typer override end
|
| 219 |
+
sys.exit(e.exit_code)
|
| 220 |
+
except OSError as e:
|
| 221 |
+
if e.errno == errno.EPIPE:
|
| 222 |
+
sys.stdout = cast(TextIO, click.utils.PacifyFlushWrapper(sys.stdout))
|
| 223 |
+
sys.stderr = cast(TextIO, click.utils.PacifyFlushWrapper(sys.stderr))
|
| 224 |
+
sys.exit(1)
|
| 225 |
+
else:
|
| 226 |
+
raise
|
| 227 |
+
except click.exceptions.Exit as e:
|
| 228 |
+
if standalone_mode:
|
| 229 |
+
sys.exit(e.exit_code)
|
| 230 |
+
else:
|
| 231 |
+
# in non-standalone mode, return the exit code
|
| 232 |
+
# note that this is only reached if `self.invoke` above raises
|
| 233 |
+
# an Exit explicitly -- thus bypassing the check there which
|
| 234 |
+
# would return its result
|
| 235 |
+
# the results of non-standalone execution may therefore be
|
| 236 |
+
# somewhat ambiguous: if there are codepaths which lead to
|
| 237 |
+
# `ctx.exit(1)` and to `return 1`, the caller won't be able to
|
| 238 |
+
# tell the difference between the two
|
| 239 |
+
return e.exit_code
|
| 240 |
+
except click.Abort:
|
| 241 |
+
if not standalone_mode:
|
| 242 |
+
raise
|
| 243 |
+
# Typer override
|
| 244 |
+
if HAS_RICH and rich_markup_mode is not None:
|
| 245 |
+
from . import rich_utils
|
| 246 |
+
|
| 247 |
+
rich_utils.rich_abort_error()
|
| 248 |
+
else:
|
| 249 |
+
click.echo(_("Aborted!"), file=sys.stderr)
|
| 250 |
+
# Typer override end
|
| 251 |
+
sys.exit(1)
|
| 252 |
+
|
| 253 |
+
|
| 254 |
+
class TyperArgument(click.core.Argument):
|
| 255 |
+
def __init__(
|
| 256 |
+
self,
|
| 257 |
+
*,
|
| 258 |
+
# Parameter
|
| 259 |
+
param_decls: List[str],
|
| 260 |
+
type: Optional[Any] = None,
|
| 261 |
+
required: Optional[bool] = None,
|
| 262 |
+
default: Optional[Any] = None,
|
| 263 |
+
callback: Optional[Callable[..., Any]] = None,
|
| 264 |
+
nargs: Optional[int] = None,
|
| 265 |
+
metavar: Optional[str] = None,
|
| 266 |
+
expose_value: bool = True,
|
| 267 |
+
is_eager: bool = False,
|
| 268 |
+
envvar: Optional[Union[str, List[str]]] = None,
|
| 269 |
+
# Note that shell_complete is not fully supported and will be removed in future versions
|
| 270 |
+
# TODO: Remove shell_complete in a future version (after 0.16.0)
|
| 271 |
+
shell_complete: Optional[
|
| 272 |
+
Callable[
|
| 273 |
+
[click.Context, click.Parameter, str],
|
| 274 |
+
Union[List["click.shell_completion.CompletionItem"], List[str]],
|
| 275 |
+
]
|
| 276 |
+
] = None,
|
| 277 |
+
autocompletion: Optional[Callable[..., Any]] = None,
|
| 278 |
+
# TyperArgument
|
| 279 |
+
show_default: Union[bool, str] = True,
|
| 280 |
+
show_choices: bool = True,
|
| 281 |
+
show_envvar: bool = True,
|
| 282 |
+
help: Optional[str] = None,
|
| 283 |
+
hidden: bool = False,
|
| 284 |
+
# Rich settings
|
| 285 |
+
rich_help_panel: Union[str, None] = None,
|
| 286 |
+
):
|
| 287 |
+
self.help = help
|
| 288 |
+
self.show_default = show_default
|
| 289 |
+
self.show_choices = show_choices
|
| 290 |
+
self.show_envvar = show_envvar
|
| 291 |
+
self.hidden = hidden
|
| 292 |
+
self.rich_help_panel = rich_help_panel
|
| 293 |
+
|
| 294 |
+
super().__init__(
|
| 295 |
+
param_decls=param_decls,
|
| 296 |
+
type=type,
|
| 297 |
+
required=required,
|
| 298 |
+
default=default,
|
| 299 |
+
callback=callback,
|
| 300 |
+
nargs=nargs,
|
| 301 |
+
metavar=metavar,
|
| 302 |
+
expose_value=expose_value,
|
| 303 |
+
is_eager=is_eager,
|
| 304 |
+
envvar=envvar,
|
| 305 |
+
shell_complete=shell_complete,
|
| 306 |
+
)
|
| 307 |
+
_typer_param_setup_autocompletion_compat(self, autocompletion=autocompletion)
|
| 308 |
+
|
| 309 |
+
def _get_default_string(
|
| 310 |
+
self,
|
| 311 |
+
*,
|
| 312 |
+
ctx: click.Context,
|
| 313 |
+
show_default_is_str: bool,
|
| 314 |
+
default_value: Union[List[Any], Tuple[Any, ...], str, Callable[..., Any], Any],
|
| 315 |
+
) -> str:
|
| 316 |
+
return _get_default_string(
|
| 317 |
+
self,
|
| 318 |
+
ctx=ctx,
|
| 319 |
+
show_default_is_str=show_default_is_str,
|
| 320 |
+
default_value=default_value,
|
| 321 |
+
)
|
| 322 |
+
|
| 323 |
+
def _extract_default_help_str(
|
| 324 |
+
self, *, ctx: click.Context
|
| 325 |
+
) -> Optional[Union[Any, Callable[[], Any]]]:
|
| 326 |
+
return _extract_default_help_str(self, ctx=ctx)
|
| 327 |
+
|
| 328 |
+
def get_help_record(self, ctx: click.Context) -> Optional[Tuple[str, str]]:
|
| 329 |
+
# Modified version of click.core.Option.get_help_record()
|
| 330 |
+
# to support Arguments
|
| 331 |
+
if self.hidden:
|
| 332 |
+
return None
|
| 333 |
+
name = self.make_metavar(ctx=ctx)
|
| 334 |
+
help = self.help or ""
|
| 335 |
+
extra = []
|
| 336 |
+
if self.show_envvar:
|
| 337 |
+
envvar = self.envvar
|
| 338 |
+
# allow_from_autoenv is currently not supported in Typer for CLI Arguments
|
| 339 |
+
if envvar is not None:
|
| 340 |
+
var_str = (
|
| 341 |
+
", ".join(str(d) for d in envvar)
|
| 342 |
+
if isinstance(envvar, (list, tuple))
|
| 343 |
+
else envvar
|
| 344 |
+
)
|
| 345 |
+
extra.append(f"env var: {var_str}")
|
| 346 |
+
|
| 347 |
+
# Typer override:
|
| 348 |
+
# Extracted to _extract_default_help_str() to allow re-using it in rich_utils
|
| 349 |
+
default_value = self._extract_default_help_str(ctx=ctx)
|
| 350 |
+
# Typer override end
|
| 351 |
+
|
| 352 |
+
show_default_is_str = isinstance(self.show_default, str)
|
| 353 |
+
|
| 354 |
+
if show_default_is_str or (
|
| 355 |
+
default_value is not None and (self.show_default or ctx.show_default)
|
| 356 |
+
):
|
| 357 |
+
# Typer override:
|
| 358 |
+
# Extracted to _get_default_string() to allow re-using it in rich_utils
|
| 359 |
+
default_string = self._get_default_string(
|
| 360 |
+
ctx=ctx,
|
| 361 |
+
show_default_is_str=show_default_is_str,
|
| 362 |
+
default_value=default_value,
|
| 363 |
+
)
|
| 364 |
+
# Typer override end
|
| 365 |
+
if default_string:
|
| 366 |
+
extra.append(_("default: {default}").format(default=default_string))
|
| 367 |
+
if self.required:
|
| 368 |
+
extra.append(_("required"))
|
| 369 |
+
if extra:
|
| 370 |
+
extra_str = "; ".join(extra)
|
| 371 |
+
extra_str = f"[{extra_str}]"
|
| 372 |
+
if HAS_RICH:
|
| 373 |
+
# This is needed for when we want to export to HTML
|
| 374 |
+
from . import rich_utils
|
| 375 |
+
|
| 376 |
+
extra_str = rich_utils.escape_before_html_export(extra_str)
|
| 377 |
+
|
| 378 |
+
help = f"{help} {extra_str}" if help else f"{extra_str}"
|
| 379 |
+
return name, help
|
| 380 |
+
|
| 381 |
+
def make_metavar(self, ctx: Union[click.Context, None] = None) -> str:
|
| 382 |
+
# Modified version of click.core.Argument.make_metavar()
|
| 383 |
+
# to include Argument name
|
| 384 |
+
if self.metavar is not None:
|
| 385 |
+
return self.metavar
|
| 386 |
+
var = (self.name or "").upper()
|
| 387 |
+
if not self.required:
|
| 388 |
+
var = f"[{var}]"
|
| 389 |
+
# TODO: When deprecating Click < 8.2, remove this
|
| 390 |
+
signature = inspect.signature(self.type.get_metavar)
|
| 391 |
+
if "ctx" in signature.parameters:
|
| 392 |
+
# Click >= 8.2
|
| 393 |
+
type_var = self.type.get_metavar(self, ctx=ctx) # type: ignore[arg-type]
|
| 394 |
+
else:
|
| 395 |
+
# Click < 8.2
|
| 396 |
+
type_var = self.type.get_metavar(self) # type: ignore[call-arg]
|
| 397 |
+
# TODO: /When deprecating Click < 8.2, remove this, uncomment the line below
|
| 398 |
+
# type_var = self.type.get_metavar(self, ctx=ctx)
|
| 399 |
+
if type_var:
|
| 400 |
+
var += f":{type_var}"
|
| 401 |
+
if self.nargs != 1:
|
| 402 |
+
var += "..."
|
| 403 |
+
return var
|
| 404 |
+
|
| 405 |
+
def value_is_missing(self, value: Any) -> bool:
|
| 406 |
+
return _value_is_missing(self, value)
|
| 407 |
+
|
| 408 |
+
|
| 409 |
+
class TyperOption(click.core.Option):
|
| 410 |
+
def __init__(
|
| 411 |
+
self,
|
| 412 |
+
*,
|
| 413 |
+
# Parameter
|
| 414 |
+
param_decls: List[str],
|
| 415 |
+
type: Optional[Union[click.types.ParamType, Any]] = None,
|
| 416 |
+
required: Optional[bool] = None,
|
| 417 |
+
default: Optional[Any] = None,
|
| 418 |
+
callback: Optional[Callable[..., Any]] = None,
|
| 419 |
+
nargs: Optional[int] = None,
|
| 420 |
+
metavar: Optional[str] = None,
|
| 421 |
+
expose_value: bool = True,
|
| 422 |
+
is_eager: bool = False,
|
| 423 |
+
envvar: Optional[Union[str, List[str]]] = None,
|
| 424 |
+
# Note that shell_complete is not fully supported and will be removed in future versions
|
| 425 |
+
# TODO: Remove shell_complete in a future version (after 0.16.0)
|
| 426 |
+
shell_complete: Optional[
|
| 427 |
+
Callable[
|
| 428 |
+
[click.Context, click.Parameter, str],
|
| 429 |
+
Union[List["click.shell_completion.CompletionItem"], List[str]],
|
| 430 |
+
]
|
| 431 |
+
] = None,
|
| 432 |
+
autocompletion: Optional[Callable[..., Any]] = None,
|
| 433 |
+
# Option
|
| 434 |
+
show_default: Union[bool, str] = False,
|
| 435 |
+
prompt: Union[bool, str] = False,
|
| 436 |
+
confirmation_prompt: Union[bool, str] = False,
|
| 437 |
+
prompt_required: bool = True,
|
| 438 |
+
hide_input: bool = False,
|
| 439 |
+
is_flag: Optional[bool] = None,
|
| 440 |
+
multiple: bool = False,
|
| 441 |
+
count: bool = False,
|
| 442 |
+
allow_from_autoenv: bool = True,
|
| 443 |
+
help: Optional[str] = None,
|
| 444 |
+
hidden: bool = False,
|
| 445 |
+
show_choices: bool = True,
|
| 446 |
+
show_envvar: bool = False,
|
| 447 |
+
# Rich settings
|
| 448 |
+
rich_help_panel: Union[str, None] = None,
|
| 449 |
+
):
|
| 450 |
+
super().__init__(
|
| 451 |
+
param_decls=param_decls,
|
| 452 |
+
type=type,
|
| 453 |
+
required=required,
|
| 454 |
+
default=default,
|
| 455 |
+
callback=callback,
|
| 456 |
+
nargs=nargs,
|
| 457 |
+
metavar=metavar,
|
| 458 |
+
expose_value=expose_value,
|
| 459 |
+
is_eager=is_eager,
|
| 460 |
+
envvar=envvar,
|
| 461 |
+
show_default=show_default,
|
| 462 |
+
prompt=prompt,
|
| 463 |
+
confirmation_prompt=confirmation_prompt,
|
| 464 |
+
hide_input=hide_input,
|
| 465 |
+
is_flag=is_flag,
|
| 466 |
+
multiple=multiple,
|
| 467 |
+
count=count,
|
| 468 |
+
allow_from_autoenv=allow_from_autoenv,
|
| 469 |
+
help=help,
|
| 470 |
+
hidden=hidden,
|
| 471 |
+
show_choices=show_choices,
|
| 472 |
+
show_envvar=show_envvar,
|
| 473 |
+
prompt_required=prompt_required,
|
| 474 |
+
shell_complete=shell_complete,
|
| 475 |
+
)
|
| 476 |
+
_typer_param_setup_autocompletion_compat(self, autocompletion=autocompletion)
|
| 477 |
+
self.rich_help_panel = rich_help_panel
|
| 478 |
+
|
| 479 |
+
def _get_default_string(
|
| 480 |
+
self,
|
| 481 |
+
*,
|
| 482 |
+
ctx: click.Context,
|
| 483 |
+
show_default_is_str: bool,
|
| 484 |
+
default_value: Union[List[Any], Tuple[Any, ...], str, Callable[..., Any], Any],
|
| 485 |
+
) -> str:
|
| 486 |
+
return _get_default_string(
|
| 487 |
+
self,
|
| 488 |
+
ctx=ctx,
|
| 489 |
+
show_default_is_str=show_default_is_str,
|
| 490 |
+
default_value=default_value,
|
| 491 |
+
)
|
| 492 |
+
|
| 493 |
+
def _extract_default_help_str(
|
| 494 |
+
self, *, ctx: click.Context
|
| 495 |
+
) -> Optional[Union[Any, Callable[[], Any]]]:
|
| 496 |
+
return _extract_default_help_str(self, ctx=ctx)
|
| 497 |
+
|
| 498 |
+
def make_metavar(self, ctx: Union[click.Context, None] = None) -> str:
|
| 499 |
+
signature = inspect.signature(super().make_metavar)
|
| 500 |
+
if "ctx" in signature.parameters:
|
| 501 |
+
# Click >= 8.2
|
| 502 |
+
return super().make_metavar(ctx=ctx) # type: ignore[arg-type]
|
| 503 |
+
# Click < 8.2
|
| 504 |
+
return super().make_metavar() # type: ignore[call-arg]
|
| 505 |
+
|
| 506 |
+
def get_help_record(self, ctx: click.Context) -> Optional[Tuple[str, str]]:
|
| 507 |
+
# Duplicate all of Click's logic only to modify a single line, to allow boolean
|
| 508 |
+
# flags with only names for False values as it's currently supported by Typer
|
| 509 |
+
# Ref: https://typer.tiangolo.com/tutorial/parameter-types/bool/#only-names-for-false
|
| 510 |
+
if self.hidden:
|
| 511 |
+
return None
|
| 512 |
+
|
| 513 |
+
any_prefix_is_slash = False
|
| 514 |
+
|
| 515 |
+
def _write_opts(opts: Sequence[str]) -> str:
|
| 516 |
+
nonlocal any_prefix_is_slash
|
| 517 |
+
|
| 518 |
+
rv, any_slashes = click.formatting.join_options(opts)
|
| 519 |
+
|
| 520 |
+
if any_slashes:
|
| 521 |
+
any_prefix_is_slash = True
|
| 522 |
+
|
| 523 |
+
if not self.is_flag and not self.count:
|
| 524 |
+
rv += f" {self.make_metavar(ctx=ctx)}"
|
| 525 |
+
|
| 526 |
+
return rv
|
| 527 |
+
|
| 528 |
+
rv = [_write_opts(self.opts)]
|
| 529 |
+
|
| 530 |
+
if self.secondary_opts:
|
| 531 |
+
rv.append(_write_opts(self.secondary_opts))
|
| 532 |
+
|
| 533 |
+
help = self.help or ""
|
| 534 |
+
extra = []
|
| 535 |
+
|
| 536 |
+
if self.show_envvar:
|
| 537 |
+
envvar = self.envvar
|
| 538 |
+
|
| 539 |
+
if envvar is None:
|
| 540 |
+
if (
|
| 541 |
+
self.allow_from_autoenv
|
| 542 |
+
and ctx.auto_envvar_prefix is not None
|
| 543 |
+
and self.name is not None
|
| 544 |
+
):
|
| 545 |
+
envvar = f"{ctx.auto_envvar_prefix}_{self.name.upper()}"
|
| 546 |
+
|
| 547 |
+
if envvar is not None:
|
| 548 |
+
var_str = (
|
| 549 |
+
envvar
|
| 550 |
+
if isinstance(envvar, str)
|
| 551 |
+
else ", ".join(str(d) for d in envvar)
|
| 552 |
+
)
|
| 553 |
+
extra.append(_("env var: {var}").format(var=var_str))
|
| 554 |
+
|
| 555 |
+
# Typer override:
|
| 556 |
+
# Extracted to _extract_default() to allow re-using it in rich_utils
|
| 557 |
+
default_value = self._extract_default_help_str(ctx=ctx)
|
| 558 |
+
# Typer override end
|
| 559 |
+
|
| 560 |
+
show_default_is_str = isinstance(self.show_default, str)
|
| 561 |
+
|
| 562 |
+
if show_default_is_str or (
|
| 563 |
+
default_value is not None and (self.show_default or ctx.show_default)
|
| 564 |
+
):
|
| 565 |
+
# Typer override:
|
| 566 |
+
# Extracted to _get_default_string() to allow re-using it in rich_utils
|
| 567 |
+
default_string = self._get_default_string(
|
| 568 |
+
ctx=ctx,
|
| 569 |
+
show_default_is_str=show_default_is_str,
|
| 570 |
+
default_value=default_value,
|
| 571 |
+
)
|
| 572 |
+
# Typer override end
|
| 573 |
+
if default_string:
|
| 574 |
+
extra.append(_("default: {default}").format(default=default_string))
|
| 575 |
+
|
| 576 |
+
if isinstance(self.type, click.types._NumberRangeBase):
|
| 577 |
+
range_str = self.type._describe_range()
|
| 578 |
+
|
| 579 |
+
if range_str:
|
| 580 |
+
extra.append(range_str)
|
| 581 |
+
|
| 582 |
+
if self.required:
|
| 583 |
+
extra.append(_("required"))
|
| 584 |
+
|
| 585 |
+
if extra:
|
| 586 |
+
extra_str = "; ".join(extra)
|
| 587 |
+
extra_str = f"[{extra_str}]"
|
| 588 |
+
if HAS_RICH:
|
| 589 |
+
# This is needed for when we want to export to HTML
|
| 590 |
+
from . import rich_utils
|
| 591 |
+
|
| 592 |
+
extra_str = rich_utils.escape_before_html_export(extra_str)
|
| 593 |
+
|
| 594 |
+
help = f"{help} {extra_str}" if help else f"{extra_str}"
|
| 595 |
+
|
| 596 |
+
return ("; " if any_prefix_is_slash else " / ").join(rv), help
|
| 597 |
+
|
| 598 |
+
def value_is_missing(self, value: Any) -> bool:
|
| 599 |
+
return _value_is_missing(self, value)
|
| 600 |
+
|
| 601 |
+
|
| 602 |
+
def _value_is_missing(param: click.Parameter, value: Any) -> bool:
|
| 603 |
+
if value is None:
|
| 604 |
+
return True
|
| 605 |
+
|
| 606 |
+
# Click 8.3 and beyond
|
| 607 |
+
# if value is UNSET:
|
| 608 |
+
# return True
|
| 609 |
+
|
| 610 |
+
if (param.nargs != 1 or param.multiple) and value == ():
|
| 611 |
+
return True # pragma: no cover
|
| 612 |
+
|
| 613 |
+
return False
|
| 614 |
+
|
| 615 |
+
|
| 616 |
+
def _typer_format_options(
|
| 617 |
+
self: click.core.Command, *, ctx: click.Context, formatter: click.HelpFormatter
|
| 618 |
+
) -> None:
|
| 619 |
+
args = []
|
| 620 |
+
opts = []
|
| 621 |
+
for param in self.get_params(ctx):
|
| 622 |
+
rv = param.get_help_record(ctx)
|
| 623 |
+
if rv is not None:
|
| 624 |
+
if param.param_type_name == "argument":
|
| 625 |
+
args.append(rv)
|
| 626 |
+
elif param.param_type_name == "option":
|
| 627 |
+
opts.append(rv)
|
| 628 |
+
|
| 629 |
+
if args:
|
| 630 |
+
with formatter.section(_("Arguments")):
|
| 631 |
+
formatter.write_dl(args)
|
| 632 |
+
if opts:
|
| 633 |
+
with formatter.section(_("Options")):
|
| 634 |
+
formatter.write_dl(opts)
|
| 635 |
+
|
| 636 |
+
|
| 637 |
+
def _typer_main_shell_completion(
|
| 638 |
+
self: click.core.Command,
|
| 639 |
+
*,
|
| 640 |
+
ctx_args: MutableMapping[str, Any],
|
| 641 |
+
prog_name: str,
|
| 642 |
+
complete_var: Optional[str] = None,
|
| 643 |
+
) -> None:
|
| 644 |
+
if complete_var is None:
|
| 645 |
+
complete_var = f"_{prog_name}_COMPLETE".replace("-", "_").upper()
|
| 646 |
+
|
| 647 |
+
instruction = os.environ.get(complete_var)
|
| 648 |
+
|
| 649 |
+
if not instruction:
|
| 650 |
+
return
|
| 651 |
+
|
| 652 |
+
from .completion import shell_complete
|
| 653 |
+
|
| 654 |
+
rv = shell_complete(self, ctx_args, prog_name, complete_var, instruction)
|
| 655 |
+
sys.exit(rv)
|
| 656 |
+
|
| 657 |
+
|
| 658 |
+
class TyperCommand(click.core.Command):
|
| 659 |
+
def __init__(
|
| 660 |
+
self,
|
| 661 |
+
name: Optional[str],
|
| 662 |
+
*,
|
| 663 |
+
context_settings: Optional[Dict[str, Any]] = None,
|
| 664 |
+
callback: Optional[Callable[..., Any]] = None,
|
| 665 |
+
params: Optional[List[click.Parameter]] = None,
|
| 666 |
+
help: Optional[str] = None,
|
| 667 |
+
epilog: Optional[str] = None,
|
| 668 |
+
short_help: Optional[str] = None,
|
| 669 |
+
options_metavar: Optional[str] = "[OPTIONS]",
|
| 670 |
+
add_help_option: bool = True,
|
| 671 |
+
no_args_is_help: bool = False,
|
| 672 |
+
hidden: bool = False,
|
| 673 |
+
deprecated: bool = False,
|
| 674 |
+
# Rich settings
|
| 675 |
+
rich_markup_mode: MarkupMode = DEFAULT_MARKUP_MODE,
|
| 676 |
+
rich_help_panel: Union[str, None] = None,
|
| 677 |
+
) -> None:
|
| 678 |
+
super().__init__(
|
| 679 |
+
name=name,
|
| 680 |
+
context_settings=context_settings,
|
| 681 |
+
callback=callback,
|
| 682 |
+
params=params,
|
| 683 |
+
help=help,
|
| 684 |
+
epilog=epilog,
|
| 685 |
+
short_help=short_help,
|
| 686 |
+
options_metavar=options_metavar,
|
| 687 |
+
add_help_option=add_help_option,
|
| 688 |
+
no_args_is_help=no_args_is_help,
|
| 689 |
+
hidden=hidden,
|
| 690 |
+
deprecated=deprecated,
|
| 691 |
+
)
|
| 692 |
+
self.rich_markup_mode: MarkupMode = rich_markup_mode
|
| 693 |
+
self.rich_help_panel = rich_help_panel
|
| 694 |
+
|
| 695 |
+
def format_options(
|
| 696 |
+
self, ctx: click.Context, formatter: click.HelpFormatter
|
| 697 |
+
) -> None:
|
| 698 |
+
_typer_format_options(self, ctx=ctx, formatter=formatter)
|
| 699 |
+
|
| 700 |
+
def _main_shell_completion(
|
| 701 |
+
self,
|
| 702 |
+
ctx_args: MutableMapping[str, Any],
|
| 703 |
+
prog_name: str,
|
| 704 |
+
complete_var: Optional[str] = None,
|
| 705 |
+
) -> None:
|
| 706 |
+
_typer_main_shell_completion(
|
| 707 |
+
self, ctx_args=ctx_args, prog_name=prog_name, complete_var=complete_var
|
| 708 |
+
)
|
| 709 |
+
|
| 710 |
+
def main(
|
| 711 |
+
self,
|
| 712 |
+
args: Optional[Sequence[str]] = None,
|
| 713 |
+
prog_name: Optional[str] = None,
|
| 714 |
+
complete_var: Optional[str] = None,
|
| 715 |
+
standalone_mode: bool = True,
|
| 716 |
+
windows_expand_args: bool = True,
|
| 717 |
+
**extra: Any,
|
| 718 |
+
) -> Any:
|
| 719 |
+
return _main(
|
| 720 |
+
self,
|
| 721 |
+
args=args,
|
| 722 |
+
prog_name=prog_name,
|
| 723 |
+
complete_var=complete_var,
|
| 724 |
+
standalone_mode=standalone_mode,
|
| 725 |
+
windows_expand_args=windows_expand_args,
|
| 726 |
+
rich_markup_mode=self.rich_markup_mode,
|
| 727 |
+
**extra,
|
| 728 |
+
)
|
| 729 |
+
|
| 730 |
+
def format_help(self, ctx: click.Context, formatter: click.HelpFormatter) -> None:
|
| 731 |
+
if not HAS_RICH or self.rich_markup_mode is None:
|
| 732 |
+
return super().format_help(ctx, formatter)
|
| 733 |
+
from . import rich_utils
|
| 734 |
+
|
| 735 |
+
return rich_utils.rich_format_help(
|
| 736 |
+
obj=self,
|
| 737 |
+
ctx=ctx,
|
| 738 |
+
markup_mode=self.rich_markup_mode,
|
| 739 |
+
)
|
| 740 |
+
|
| 741 |
+
|
| 742 |
+
class TyperGroup(click.core.Group):
|
| 743 |
+
def __init__(
|
| 744 |
+
self,
|
| 745 |
+
*,
|
| 746 |
+
name: Optional[str] = None,
|
| 747 |
+
commands: Optional[
|
| 748 |
+
Union[Dict[str, click.Command], Sequence[click.Command]]
|
| 749 |
+
] = None,
|
| 750 |
+
# Rich settings
|
| 751 |
+
rich_markup_mode: MarkupMode = DEFAULT_MARKUP_MODE,
|
| 752 |
+
rich_help_panel: Union[str, None] = None,
|
| 753 |
+
suggest_commands: bool = True,
|
| 754 |
+
**attrs: Any,
|
| 755 |
+
) -> None:
|
| 756 |
+
super().__init__(name=name, commands=commands, **attrs)
|
| 757 |
+
self.rich_markup_mode: MarkupMode = rich_markup_mode
|
| 758 |
+
self.rich_help_panel = rich_help_panel
|
| 759 |
+
self.suggest_commands = suggest_commands
|
| 760 |
+
|
| 761 |
+
def format_options(
|
| 762 |
+
self, ctx: click.Context, formatter: click.HelpFormatter
|
| 763 |
+
) -> None:
|
| 764 |
+
_typer_format_options(self, ctx=ctx, formatter=formatter)
|
| 765 |
+
self.format_commands(ctx, formatter)
|
| 766 |
+
|
| 767 |
+
def _main_shell_completion(
|
| 768 |
+
self,
|
| 769 |
+
ctx_args: MutableMapping[str, Any],
|
| 770 |
+
prog_name: str,
|
| 771 |
+
complete_var: Optional[str] = None,
|
| 772 |
+
) -> None:
|
| 773 |
+
_typer_main_shell_completion(
|
| 774 |
+
self, ctx_args=ctx_args, prog_name=prog_name, complete_var=complete_var
|
| 775 |
+
)
|
| 776 |
+
|
| 777 |
+
def resolve_command(
|
| 778 |
+
self, ctx: click.Context, args: List[str]
|
| 779 |
+
) -> Tuple[Optional[str], Optional[click.Command], List[str]]:
|
| 780 |
+
try:
|
| 781 |
+
return super().resolve_command(ctx, args)
|
| 782 |
+
except click.UsageError as e:
|
| 783 |
+
if self.suggest_commands:
|
| 784 |
+
available_commands = list(self.commands.keys())
|
| 785 |
+
if available_commands and args:
|
| 786 |
+
typo = args[0]
|
| 787 |
+
matches = get_close_matches(typo, available_commands)
|
| 788 |
+
if matches:
|
| 789 |
+
suggestions = ", ".join(f"{m!r}" for m in matches)
|
| 790 |
+
message = e.message.rstrip(".")
|
| 791 |
+
e.message = f"{message}. Did you mean {suggestions}?"
|
| 792 |
+
raise
|
| 793 |
+
|
| 794 |
+
def main(
|
| 795 |
+
self,
|
| 796 |
+
args: Optional[Sequence[str]] = None,
|
| 797 |
+
prog_name: Optional[str] = None,
|
| 798 |
+
complete_var: Optional[str] = None,
|
| 799 |
+
standalone_mode: bool = True,
|
| 800 |
+
windows_expand_args: bool = True,
|
| 801 |
+
**extra: Any,
|
| 802 |
+
) -> Any:
|
| 803 |
+
return _main(
|
| 804 |
+
self,
|
| 805 |
+
args=args,
|
| 806 |
+
prog_name=prog_name,
|
| 807 |
+
complete_var=complete_var,
|
| 808 |
+
standalone_mode=standalone_mode,
|
| 809 |
+
windows_expand_args=windows_expand_args,
|
| 810 |
+
rich_markup_mode=self.rich_markup_mode,
|
| 811 |
+
**extra,
|
| 812 |
+
)
|
| 813 |
+
|
| 814 |
+
def format_help(self, ctx: click.Context, formatter: click.HelpFormatter) -> None:
|
| 815 |
+
if not HAS_RICH or self.rich_markup_mode is None:
|
| 816 |
+
return super().format_help(ctx, formatter)
|
| 817 |
+
from . import rich_utils
|
| 818 |
+
|
| 819 |
+
return rich_utils.rich_format_help(
|
| 820 |
+
obj=self,
|
| 821 |
+
ctx=ctx,
|
| 822 |
+
markup_mode=self.rich_markup_mode,
|
| 823 |
+
)
|
| 824 |
+
|
| 825 |
+
def list_commands(self, ctx: click.Context) -> List[str]:
|
| 826 |
+
"""Returns a list of subcommand names.
|
| 827 |
+
Note that in Click's Group class, these are sorted.
|
| 828 |
+
In Typer, we wish to maintain the original order of creation (cf Issue #933)"""
|
| 829 |
+
return [n for n, c in self.commands.items()]
|
env/lib/python3.13/site-packages/typer/main.py
ADDED
|
@@ -0,0 +1,1142 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import inspect
|
| 2 |
+
import os
|
| 3 |
+
import platform
|
| 4 |
+
import shutil
|
| 5 |
+
import subprocess
|
| 6 |
+
import sys
|
| 7 |
+
import traceback
|
| 8 |
+
from datetime import datetime
|
| 9 |
+
from enum import Enum
|
| 10 |
+
from functools import update_wrapper
|
| 11 |
+
from pathlib import Path
|
| 12 |
+
from traceback import FrameSummary, StackSummary
|
| 13 |
+
from types import TracebackType
|
| 14 |
+
from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Type, Union
|
| 15 |
+
from uuid import UUID
|
| 16 |
+
|
| 17 |
+
import click
|
| 18 |
+
from typer._types import TyperChoice
|
| 19 |
+
|
| 20 |
+
from ._typing import get_args, get_origin, is_literal_type, is_union, literal_values
|
| 21 |
+
from .completion import get_completion_inspect_parameters
|
| 22 |
+
from .core import (
|
| 23 |
+
DEFAULT_MARKUP_MODE,
|
| 24 |
+
HAS_RICH,
|
| 25 |
+
MarkupMode,
|
| 26 |
+
TyperArgument,
|
| 27 |
+
TyperCommand,
|
| 28 |
+
TyperGroup,
|
| 29 |
+
TyperOption,
|
| 30 |
+
)
|
| 31 |
+
from .models import (
|
| 32 |
+
AnyType,
|
| 33 |
+
ArgumentInfo,
|
| 34 |
+
CommandFunctionType,
|
| 35 |
+
CommandInfo,
|
| 36 |
+
Default,
|
| 37 |
+
DefaultPlaceholder,
|
| 38 |
+
DeveloperExceptionConfig,
|
| 39 |
+
FileBinaryRead,
|
| 40 |
+
FileBinaryWrite,
|
| 41 |
+
FileText,
|
| 42 |
+
FileTextWrite,
|
| 43 |
+
NoneType,
|
| 44 |
+
OptionInfo,
|
| 45 |
+
ParameterInfo,
|
| 46 |
+
ParamMeta,
|
| 47 |
+
Required,
|
| 48 |
+
TyperInfo,
|
| 49 |
+
TyperPath,
|
| 50 |
+
)
|
| 51 |
+
from .utils import get_params_from_function
|
| 52 |
+
|
| 53 |
+
_original_except_hook = sys.excepthook
|
| 54 |
+
_typer_developer_exception_attr_name = "__typer_developer_exception__"
|
| 55 |
+
|
| 56 |
+
|
| 57 |
+
def except_hook(
|
| 58 |
+
exc_type: Type[BaseException], exc_value: BaseException, tb: Optional[TracebackType]
|
| 59 |
+
) -> None:
|
| 60 |
+
exception_config: Union[DeveloperExceptionConfig, None] = getattr(
|
| 61 |
+
exc_value, _typer_developer_exception_attr_name, None
|
| 62 |
+
)
|
| 63 |
+
standard_traceback = os.getenv("_TYPER_STANDARD_TRACEBACK")
|
| 64 |
+
if (
|
| 65 |
+
standard_traceback
|
| 66 |
+
or not exception_config
|
| 67 |
+
or not exception_config.pretty_exceptions_enable
|
| 68 |
+
):
|
| 69 |
+
_original_except_hook(exc_type, exc_value, tb)
|
| 70 |
+
return
|
| 71 |
+
typer_path = os.path.dirname(__file__)
|
| 72 |
+
click_path = os.path.dirname(click.__file__)
|
| 73 |
+
internal_dir_names = [typer_path, click_path]
|
| 74 |
+
exc = exc_value
|
| 75 |
+
if HAS_RICH:
|
| 76 |
+
from . import rich_utils
|
| 77 |
+
|
| 78 |
+
rich_tb = rich_utils.get_traceback(exc, exception_config, internal_dir_names)
|
| 79 |
+
console_stderr = rich_utils._get_rich_console(stderr=True)
|
| 80 |
+
console_stderr.print(rich_tb)
|
| 81 |
+
return
|
| 82 |
+
tb_exc = traceback.TracebackException.from_exception(exc)
|
| 83 |
+
stack: List[FrameSummary] = []
|
| 84 |
+
for frame in tb_exc.stack:
|
| 85 |
+
if any(frame.filename.startswith(path) for path in internal_dir_names):
|
| 86 |
+
if not exception_config.pretty_exceptions_short:
|
| 87 |
+
# Hide the line for internal libraries, Typer and Click
|
| 88 |
+
stack.append(
|
| 89 |
+
traceback.FrameSummary(
|
| 90 |
+
filename=frame.filename,
|
| 91 |
+
lineno=frame.lineno,
|
| 92 |
+
name=frame.name,
|
| 93 |
+
line="",
|
| 94 |
+
)
|
| 95 |
+
)
|
| 96 |
+
else:
|
| 97 |
+
stack.append(frame)
|
| 98 |
+
# Type ignore ref: https://github.com/python/typeshed/pull/8244
|
| 99 |
+
final_stack_summary = StackSummary.from_list(stack)
|
| 100 |
+
tb_exc.stack = final_stack_summary
|
| 101 |
+
for line in tb_exc.format():
|
| 102 |
+
print(line, file=sys.stderr)
|
| 103 |
+
return
|
| 104 |
+
|
| 105 |
+
|
| 106 |
+
def get_install_completion_arguments() -> Tuple[click.Parameter, click.Parameter]:
|
| 107 |
+
install_param, show_param = get_completion_inspect_parameters()
|
| 108 |
+
click_install_param, _ = get_click_param(install_param)
|
| 109 |
+
click_show_param, _ = get_click_param(show_param)
|
| 110 |
+
return click_install_param, click_show_param
|
| 111 |
+
|
| 112 |
+
|
| 113 |
+
class Typer:
|
| 114 |
+
def __init__(
|
| 115 |
+
self,
|
| 116 |
+
*,
|
| 117 |
+
name: Optional[str] = Default(None),
|
| 118 |
+
cls: Optional[Type[TyperGroup]] = Default(None),
|
| 119 |
+
invoke_without_command: bool = Default(False),
|
| 120 |
+
no_args_is_help: bool = Default(False),
|
| 121 |
+
subcommand_metavar: Optional[str] = Default(None),
|
| 122 |
+
chain: bool = Default(False),
|
| 123 |
+
result_callback: Optional[Callable[..., Any]] = Default(None),
|
| 124 |
+
# Command
|
| 125 |
+
context_settings: Optional[Dict[Any, Any]] = Default(None),
|
| 126 |
+
callback: Optional[Callable[..., Any]] = Default(None),
|
| 127 |
+
help: Optional[str] = Default(None),
|
| 128 |
+
epilog: Optional[str] = Default(None),
|
| 129 |
+
short_help: Optional[str] = Default(None),
|
| 130 |
+
options_metavar: str = Default("[OPTIONS]"),
|
| 131 |
+
add_help_option: bool = Default(True),
|
| 132 |
+
hidden: bool = Default(False),
|
| 133 |
+
deprecated: bool = Default(False),
|
| 134 |
+
add_completion: bool = True,
|
| 135 |
+
# Rich settings
|
| 136 |
+
rich_markup_mode: MarkupMode = Default(DEFAULT_MARKUP_MODE),
|
| 137 |
+
rich_help_panel: Union[str, None] = Default(None),
|
| 138 |
+
suggest_commands: bool = True,
|
| 139 |
+
pretty_exceptions_enable: bool = True,
|
| 140 |
+
pretty_exceptions_show_locals: bool = True,
|
| 141 |
+
pretty_exceptions_short: bool = True,
|
| 142 |
+
):
|
| 143 |
+
self._add_completion = add_completion
|
| 144 |
+
self.rich_markup_mode: MarkupMode = rich_markup_mode
|
| 145 |
+
self.rich_help_panel = rich_help_panel
|
| 146 |
+
self.suggest_commands = suggest_commands
|
| 147 |
+
self.pretty_exceptions_enable = pretty_exceptions_enable
|
| 148 |
+
self.pretty_exceptions_show_locals = pretty_exceptions_show_locals
|
| 149 |
+
self.pretty_exceptions_short = pretty_exceptions_short
|
| 150 |
+
self.info = TyperInfo(
|
| 151 |
+
name=name,
|
| 152 |
+
cls=cls,
|
| 153 |
+
invoke_without_command=invoke_without_command,
|
| 154 |
+
no_args_is_help=no_args_is_help,
|
| 155 |
+
subcommand_metavar=subcommand_metavar,
|
| 156 |
+
chain=chain,
|
| 157 |
+
result_callback=result_callback,
|
| 158 |
+
context_settings=context_settings,
|
| 159 |
+
callback=callback,
|
| 160 |
+
help=help,
|
| 161 |
+
epilog=epilog,
|
| 162 |
+
short_help=short_help,
|
| 163 |
+
options_metavar=options_metavar,
|
| 164 |
+
add_help_option=add_help_option,
|
| 165 |
+
hidden=hidden,
|
| 166 |
+
deprecated=deprecated,
|
| 167 |
+
)
|
| 168 |
+
self.registered_groups: List[TyperInfo] = []
|
| 169 |
+
self.registered_commands: List[CommandInfo] = []
|
| 170 |
+
self.registered_callback: Optional[TyperInfo] = None
|
| 171 |
+
|
| 172 |
+
def callback(
|
| 173 |
+
self,
|
| 174 |
+
*,
|
| 175 |
+
cls: Optional[Type[TyperGroup]] = Default(None),
|
| 176 |
+
invoke_without_command: bool = Default(False),
|
| 177 |
+
no_args_is_help: bool = Default(False),
|
| 178 |
+
subcommand_metavar: Optional[str] = Default(None),
|
| 179 |
+
chain: bool = Default(False),
|
| 180 |
+
result_callback: Optional[Callable[..., Any]] = Default(None),
|
| 181 |
+
# Command
|
| 182 |
+
context_settings: Optional[Dict[Any, Any]] = Default(None),
|
| 183 |
+
help: Optional[str] = Default(None),
|
| 184 |
+
epilog: Optional[str] = Default(None),
|
| 185 |
+
short_help: Optional[str] = Default(None),
|
| 186 |
+
options_metavar: str = Default("[OPTIONS]"),
|
| 187 |
+
add_help_option: bool = Default(True),
|
| 188 |
+
hidden: bool = Default(False),
|
| 189 |
+
deprecated: bool = Default(False),
|
| 190 |
+
# Rich settings
|
| 191 |
+
rich_help_panel: Union[str, None] = Default(None),
|
| 192 |
+
) -> Callable[[CommandFunctionType], CommandFunctionType]:
|
| 193 |
+
def decorator(f: CommandFunctionType) -> CommandFunctionType:
|
| 194 |
+
self.registered_callback = TyperInfo(
|
| 195 |
+
cls=cls,
|
| 196 |
+
invoke_without_command=invoke_without_command,
|
| 197 |
+
no_args_is_help=no_args_is_help,
|
| 198 |
+
subcommand_metavar=subcommand_metavar,
|
| 199 |
+
chain=chain,
|
| 200 |
+
result_callback=result_callback,
|
| 201 |
+
context_settings=context_settings,
|
| 202 |
+
callback=f,
|
| 203 |
+
help=help,
|
| 204 |
+
epilog=epilog,
|
| 205 |
+
short_help=short_help,
|
| 206 |
+
options_metavar=options_metavar,
|
| 207 |
+
add_help_option=add_help_option,
|
| 208 |
+
hidden=hidden,
|
| 209 |
+
deprecated=deprecated,
|
| 210 |
+
rich_help_panel=rich_help_panel,
|
| 211 |
+
)
|
| 212 |
+
return f
|
| 213 |
+
|
| 214 |
+
return decorator
|
| 215 |
+
|
| 216 |
+
def command(
|
| 217 |
+
self,
|
| 218 |
+
name: Optional[str] = None,
|
| 219 |
+
*,
|
| 220 |
+
cls: Optional[Type[TyperCommand]] = None,
|
| 221 |
+
context_settings: Optional[Dict[Any, Any]] = None,
|
| 222 |
+
help: Optional[str] = None,
|
| 223 |
+
epilog: Optional[str] = None,
|
| 224 |
+
short_help: Optional[str] = None,
|
| 225 |
+
options_metavar: str = "[OPTIONS]",
|
| 226 |
+
add_help_option: bool = True,
|
| 227 |
+
no_args_is_help: bool = False,
|
| 228 |
+
hidden: bool = False,
|
| 229 |
+
deprecated: bool = False,
|
| 230 |
+
# Rich settings
|
| 231 |
+
rich_help_panel: Union[str, None] = Default(None),
|
| 232 |
+
) -> Callable[[CommandFunctionType], CommandFunctionType]:
|
| 233 |
+
if cls is None:
|
| 234 |
+
cls = TyperCommand
|
| 235 |
+
|
| 236 |
+
def decorator(f: CommandFunctionType) -> CommandFunctionType:
|
| 237 |
+
self.registered_commands.append(
|
| 238 |
+
CommandInfo(
|
| 239 |
+
name=name,
|
| 240 |
+
cls=cls,
|
| 241 |
+
context_settings=context_settings,
|
| 242 |
+
callback=f,
|
| 243 |
+
help=help,
|
| 244 |
+
epilog=epilog,
|
| 245 |
+
short_help=short_help,
|
| 246 |
+
options_metavar=options_metavar,
|
| 247 |
+
add_help_option=add_help_option,
|
| 248 |
+
no_args_is_help=no_args_is_help,
|
| 249 |
+
hidden=hidden,
|
| 250 |
+
deprecated=deprecated,
|
| 251 |
+
# Rich settings
|
| 252 |
+
rich_help_panel=rich_help_panel,
|
| 253 |
+
)
|
| 254 |
+
)
|
| 255 |
+
return f
|
| 256 |
+
|
| 257 |
+
return decorator
|
| 258 |
+
|
| 259 |
+
def add_typer(
|
| 260 |
+
self,
|
| 261 |
+
typer_instance: "Typer",
|
| 262 |
+
*,
|
| 263 |
+
name: Optional[str] = Default(None),
|
| 264 |
+
cls: Optional[Type[TyperGroup]] = Default(None),
|
| 265 |
+
invoke_without_command: bool = Default(False),
|
| 266 |
+
no_args_is_help: bool = Default(False),
|
| 267 |
+
subcommand_metavar: Optional[str] = Default(None),
|
| 268 |
+
chain: bool = Default(False),
|
| 269 |
+
result_callback: Optional[Callable[..., Any]] = Default(None),
|
| 270 |
+
# Command
|
| 271 |
+
context_settings: Optional[Dict[Any, Any]] = Default(None),
|
| 272 |
+
callback: Optional[Callable[..., Any]] = Default(None),
|
| 273 |
+
help: Optional[str] = Default(None),
|
| 274 |
+
epilog: Optional[str] = Default(None),
|
| 275 |
+
short_help: Optional[str] = Default(None),
|
| 276 |
+
options_metavar: str = Default("[OPTIONS]"),
|
| 277 |
+
add_help_option: bool = Default(True),
|
| 278 |
+
hidden: bool = Default(False),
|
| 279 |
+
deprecated: bool = Default(False),
|
| 280 |
+
# Rich settings
|
| 281 |
+
rich_help_panel: Union[str, None] = Default(None),
|
| 282 |
+
) -> None:
|
| 283 |
+
self.registered_groups.append(
|
| 284 |
+
TyperInfo(
|
| 285 |
+
typer_instance,
|
| 286 |
+
name=name,
|
| 287 |
+
cls=cls,
|
| 288 |
+
invoke_without_command=invoke_without_command,
|
| 289 |
+
no_args_is_help=no_args_is_help,
|
| 290 |
+
subcommand_metavar=subcommand_metavar,
|
| 291 |
+
chain=chain,
|
| 292 |
+
result_callback=result_callback,
|
| 293 |
+
context_settings=context_settings,
|
| 294 |
+
callback=callback,
|
| 295 |
+
help=help,
|
| 296 |
+
epilog=epilog,
|
| 297 |
+
short_help=short_help,
|
| 298 |
+
options_metavar=options_metavar,
|
| 299 |
+
add_help_option=add_help_option,
|
| 300 |
+
hidden=hidden,
|
| 301 |
+
deprecated=deprecated,
|
| 302 |
+
rich_help_panel=rich_help_panel,
|
| 303 |
+
)
|
| 304 |
+
)
|
| 305 |
+
|
| 306 |
+
def __call__(self, *args: Any, **kwargs: Any) -> Any:
|
| 307 |
+
if sys.excepthook != except_hook:
|
| 308 |
+
sys.excepthook = except_hook
|
| 309 |
+
try:
|
| 310 |
+
return get_command(self)(*args, **kwargs)
|
| 311 |
+
except Exception as e:
|
| 312 |
+
# Set a custom attribute to tell the hook to show nice exceptions for user
|
| 313 |
+
# code. An alternative/first implementation was a custom exception with
|
| 314 |
+
# raise custom_exc from e
|
| 315 |
+
# but that means the last error shown is the custom exception, not the
|
| 316 |
+
# actual error. This trick improves developer experience by showing the
|
| 317 |
+
# actual error last.
|
| 318 |
+
setattr(
|
| 319 |
+
e,
|
| 320 |
+
_typer_developer_exception_attr_name,
|
| 321 |
+
DeveloperExceptionConfig(
|
| 322 |
+
pretty_exceptions_enable=self.pretty_exceptions_enable,
|
| 323 |
+
pretty_exceptions_show_locals=self.pretty_exceptions_show_locals,
|
| 324 |
+
pretty_exceptions_short=self.pretty_exceptions_short,
|
| 325 |
+
),
|
| 326 |
+
)
|
| 327 |
+
raise e
|
| 328 |
+
|
| 329 |
+
|
| 330 |
+
def get_group(typer_instance: Typer) -> TyperGroup:
|
| 331 |
+
group = get_group_from_info(
|
| 332 |
+
TyperInfo(typer_instance),
|
| 333 |
+
pretty_exceptions_short=typer_instance.pretty_exceptions_short,
|
| 334 |
+
rich_markup_mode=typer_instance.rich_markup_mode,
|
| 335 |
+
suggest_commands=typer_instance.suggest_commands,
|
| 336 |
+
)
|
| 337 |
+
return group
|
| 338 |
+
|
| 339 |
+
|
| 340 |
+
def get_command(typer_instance: Typer) -> click.Command:
|
| 341 |
+
if typer_instance._add_completion:
|
| 342 |
+
click_install_param, click_show_param = get_install_completion_arguments()
|
| 343 |
+
if (
|
| 344 |
+
typer_instance.registered_callback
|
| 345 |
+
or typer_instance.info.callback
|
| 346 |
+
or typer_instance.registered_groups
|
| 347 |
+
or len(typer_instance.registered_commands) > 1
|
| 348 |
+
):
|
| 349 |
+
# Create a Group
|
| 350 |
+
click_command: click.Command = get_group(typer_instance)
|
| 351 |
+
if typer_instance._add_completion:
|
| 352 |
+
click_command.params.append(click_install_param)
|
| 353 |
+
click_command.params.append(click_show_param)
|
| 354 |
+
return click_command
|
| 355 |
+
elif len(typer_instance.registered_commands) == 1:
|
| 356 |
+
# Create a single Command
|
| 357 |
+
single_command = typer_instance.registered_commands[0]
|
| 358 |
+
|
| 359 |
+
if not single_command.context_settings and not isinstance(
|
| 360 |
+
typer_instance.info.context_settings, DefaultPlaceholder
|
| 361 |
+
):
|
| 362 |
+
single_command.context_settings = typer_instance.info.context_settings
|
| 363 |
+
|
| 364 |
+
click_command = get_command_from_info(
|
| 365 |
+
single_command,
|
| 366 |
+
pretty_exceptions_short=typer_instance.pretty_exceptions_short,
|
| 367 |
+
rich_markup_mode=typer_instance.rich_markup_mode,
|
| 368 |
+
)
|
| 369 |
+
if typer_instance._add_completion:
|
| 370 |
+
click_command.params.append(click_install_param)
|
| 371 |
+
click_command.params.append(click_show_param)
|
| 372 |
+
return click_command
|
| 373 |
+
raise RuntimeError(
|
| 374 |
+
"Could not get a command for this Typer instance"
|
| 375 |
+
) # pragma: no cover
|
| 376 |
+
|
| 377 |
+
|
| 378 |
+
def solve_typer_info_help(typer_info: TyperInfo) -> str:
|
| 379 |
+
# Priority 1: Explicit value was set in app.add_typer()
|
| 380 |
+
if not isinstance(typer_info.help, DefaultPlaceholder):
|
| 381 |
+
return inspect.cleandoc(typer_info.help or "")
|
| 382 |
+
# Priority 2: Explicit value was set in sub_app.callback()
|
| 383 |
+
try:
|
| 384 |
+
callback_help = typer_info.typer_instance.registered_callback.help
|
| 385 |
+
if not isinstance(callback_help, DefaultPlaceholder):
|
| 386 |
+
return inspect.cleandoc(callback_help or "")
|
| 387 |
+
except AttributeError:
|
| 388 |
+
pass
|
| 389 |
+
# Priority 3: Explicit value was set in sub_app = typer.Typer()
|
| 390 |
+
try:
|
| 391 |
+
instance_help = typer_info.typer_instance.info.help
|
| 392 |
+
if not isinstance(instance_help, DefaultPlaceholder):
|
| 393 |
+
return inspect.cleandoc(instance_help or "")
|
| 394 |
+
except AttributeError:
|
| 395 |
+
pass
|
| 396 |
+
# Priority 4: Implicit inference from callback docstring in app.add_typer()
|
| 397 |
+
if typer_info.callback:
|
| 398 |
+
doc = inspect.getdoc(typer_info.callback)
|
| 399 |
+
if doc:
|
| 400 |
+
return doc
|
| 401 |
+
# Priority 5: Implicit inference from callback docstring in @app.callback()
|
| 402 |
+
try:
|
| 403 |
+
callback = typer_info.typer_instance.registered_callback.callback
|
| 404 |
+
if not isinstance(callback, DefaultPlaceholder):
|
| 405 |
+
doc = inspect.getdoc(callback or "")
|
| 406 |
+
if doc:
|
| 407 |
+
return doc
|
| 408 |
+
except AttributeError:
|
| 409 |
+
pass
|
| 410 |
+
# Priority 6: Implicit inference from callback docstring in typer.Typer()
|
| 411 |
+
try:
|
| 412 |
+
instance_callback = typer_info.typer_instance.info.callback
|
| 413 |
+
if not isinstance(instance_callback, DefaultPlaceholder):
|
| 414 |
+
doc = inspect.getdoc(instance_callback)
|
| 415 |
+
if doc:
|
| 416 |
+
return doc
|
| 417 |
+
except AttributeError:
|
| 418 |
+
pass
|
| 419 |
+
# Value not set, use the default
|
| 420 |
+
return typer_info.help.value
|
| 421 |
+
|
| 422 |
+
|
| 423 |
+
def solve_typer_info_defaults(typer_info: TyperInfo) -> TyperInfo:
|
| 424 |
+
values: Dict[str, Any] = {}
|
| 425 |
+
for name, value in typer_info.__dict__.items():
|
| 426 |
+
# Priority 1: Value was set in app.add_typer()
|
| 427 |
+
if not isinstance(value, DefaultPlaceholder):
|
| 428 |
+
values[name] = value
|
| 429 |
+
continue
|
| 430 |
+
# Priority 2: Value was set in @subapp.callback()
|
| 431 |
+
try:
|
| 432 |
+
callback_value = getattr(
|
| 433 |
+
typer_info.typer_instance.registered_callback, # type: ignore
|
| 434 |
+
name,
|
| 435 |
+
)
|
| 436 |
+
if not isinstance(callback_value, DefaultPlaceholder):
|
| 437 |
+
values[name] = callback_value
|
| 438 |
+
continue
|
| 439 |
+
except AttributeError:
|
| 440 |
+
pass
|
| 441 |
+
# Priority 3: Value set in subapp = typer.Typer()
|
| 442 |
+
try:
|
| 443 |
+
instance_value = getattr(
|
| 444 |
+
typer_info.typer_instance.info, # type: ignore
|
| 445 |
+
name,
|
| 446 |
+
)
|
| 447 |
+
if not isinstance(instance_value, DefaultPlaceholder):
|
| 448 |
+
values[name] = instance_value
|
| 449 |
+
continue
|
| 450 |
+
except AttributeError:
|
| 451 |
+
pass
|
| 452 |
+
# Value not set, use the default
|
| 453 |
+
values[name] = value.value
|
| 454 |
+
values["help"] = solve_typer_info_help(typer_info)
|
| 455 |
+
return TyperInfo(**values)
|
| 456 |
+
|
| 457 |
+
|
| 458 |
+
def get_group_from_info(
|
| 459 |
+
group_info: TyperInfo,
|
| 460 |
+
*,
|
| 461 |
+
pretty_exceptions_short: bool,
|
| 462 |
+
suggest_commands: bool,
|
| 463 |
+
rich_markup_mode: MarkupMode,
|
| 464 |
+
) -> TyperGroup:
|
| 465 |
+
assert group_info.typer_instance, (
|
| 466 |
+
"A Typer instance is needed to generate a Click Group"
|
| 467 |
+
)
|
| 468 |
+
commands: Dict[str, click.Command] = {}
|
| 469 |
+
for command_info in group_info.typer_instance.registered_commands:
|
| 470 |
+
command = get_command_from_info(
|
| 471 |
+
command_info=command_info,
|
| 472 |
+
pretty_exceptions_short=pretty_exceptions_short,
|
| 473 |
+
rich_markup_mode=rich_markup_mode,
|
| 474 |
+
)
|
| 475 |
+
if command.name:
|
| 476 |
+
commands[command.name] = command
|
| 477 |
+
for sub_group_info in group_info.typer_instance.registered_groups:
|
| 478 |
+
sub_group = get_group_from_info(
|
| 479 |
+
sub_group_info,
|
| 480 |
+
pretty_exceptions_short=pretty_exceptions_short,
|
| 481 |
+
rich_markup_mode=rich_markup_mode,
|
| 482 |
+
suggest_commands=suggest_commands,
|
| 483 |
+
)
|
| 484 |
+
if sub_group.name:
|
| 485 |
+
commands[sub_group.name] = sub_group
|
| 486 |
+
else:
|
| 487 |
+
if sub_group.callback:
|
| 488 |
+
import warnings
|
| 489 |
+
|
| 490 |
+
warnings.warn(
|
| 491 |
+
"The 'callback' parameter is not supported by Typer when using `add_typer` without a name",
|
| 492 |
+
stacklevel=5,
|
| 493 |
+
)
|
| 494 |
+
for sub_command_name, sub_command in sub_group.commands.items():
|
| 495 |
+
commands[sub_command_name] = sub_command
|
| 496 |
+
solved_info = solve_typer_info_defaults(group_info)
|
| 497 |
+
(
|
| 498 |
+
params,
|
| 499 |
+
convertors,
|
| 500 |
+
context_param_name,
|
| 501 |
+
) = get_params_convertors_ctx_param_name_from_function(solved_info.callback)
|
| 502 |
+
cls = solved_info.cls or TyperGroup
|
| 503 |
+
assert issubclass(cls, TyperGroup), f"{cls} should be a subclass of {TyperGroup}"
|
| 504 |
+
group = cls(
|
| 505 |
+
name=solved_info.name or "",
|
| 506 |
+
commands=commands,
|
| 507 |
+
invoke_without_command=solved_info.invoke_without_command,
|
| 508 |
+
no_args_is_help=solved_info.no_args_is_help,
|
| 509 |
+
subcommand_metavar=solved_info.subcommand_metavar,
|
| 510 |
+
chain=solved_info.chain,
|
| 511 |
+
result_callback=solved_info.result_callback,
|
| 512 |
+
context_settings=solved_info.context_settings,
|
| 513 |
+
callback=get_callback(
|
| 514 |
+
callback=solved_info.callback,
|
| 515 |
+
params=params,
|
| 516 |
+
convertors=convertors,
|
| 517 |
+
context_param_name=context_param_name,
|
| 518 |
+
pretty_exceptions_short=pretty_exceptions_short,
|
| 519 |
+
),
|
| 520 |
+
params=params,
|
| 521 |
+
help=solved_info.help,
|
| 522 |
+
epilog=solved_info.epilog,
|
| 523 |
+
short_help=solved_info.short_help,
|
| 524 |
+
options_metavar=solved_info.options_metavar,
|
| 525 |
+
add_help_option=solved_info.add_help_option,
|
| 526 |
+
hidden=solved_info.hidden,
|
| 527 |
+
deprecated=solved_info.deprecated,
|
| 528 |
+
rich_markup_mode=rich_markup_mode,
|
| 529 |
+
# Rich settings
|
| 530 |
+
rich_help_panel=solved_info.rich_help_panel,
|
| 531 |
+
suggest_commands=suggest_commands,
|
| 532 |
+
)
|
| 533 |
+
return group
|
| 534 |
+
|
| 535 |
+
|
| 536 |
+
def get_command_name(name: str) -> str:
|
| 537 |
+
return name.lower().replace("_", "-")
|
| 538 |
+
|
| 539 |
+
|
| 540 |
+
def get_params_convertors_ctx_param_name_from_function(
|
| 541 |
+
callback: Optional[Callable[..., Any]],
|
| 542 |
+
) -> Tuple[List[Union[click.Argument, click.Option]], Dict[str, Any], Optional[str]]:
|
| 543 |
+
params = []
|
| 544 |
+
convertors = {}
|
| 545 |
+
context_param_name = None
|
| 546 |
+
if callback:
|
| 547 |
+
parameters = get_params_from_function(callback)
|
| 548 |
+
for param_name, param in parameters.items():
|
| 549 |
+
if lenient_issubclass(param.annotation, click.Context):
|
| 550 |
+
context_param_name = param_name
|
| 551 |
+
continue
|
| 552 |
+
click_param, convertor = get_click_param(param)
|
| 553 |
+
if convertor:
|
| 554 |
+
convertors[param_name] = convertor
|
| 555 |
+
params.append(click_param)
|
| 556 |
+
return params, convertors, context_param_name
|
| 557 |
+
|
| 558 |
+
|
| 559 |
+
def get_command_from_info(
|
| 560 |
+
command_info: CommandInfo,
|
| 561 |
+
*,
|
| 562 |
+
pretty_exceptions_short: bool,
|
| 563 |
+
rich_markup_mode: MarkupMode,
|
| 564 |
+
) -> click.Command:
|
| 565 |
+
assert command_info.callback, "A command must have a callback function"
|
| 566 |
+
name = command_info.name or get_command_name(command_info.callback.__name__)
|
| 567 |
+
use_help = command_info.help
|
| 568 |
+
if use_help is None:
|
| 569 |
+
use_help = inspect.getdoc(command_info.callback)
|
| 570 |
+
else:
|
| 571 |
+
use_help = inspect.cleandoc(use_help)
|
| 572 |
+
(
|
| 573 |
+
params,
|
| 574 |
+
convertors,
|
| 575 |
+
context_param_name,
|
| 576 |
+
) = get_params_convertors_ctx_param_name_from_function(command_info.callback)
|
| 577 |
+
cls = command_info.cls or TyperCommand
|
| 578 |
+
command = cls(
|
| 579 |
+
name=name,
|
| 580 |
+
context_settings=command_info.context_settings,
|
| 581 |
+
callback=get_callback(
|
| 582 |
+
callback=command_info.callback,
|
| 583 |
+
params=params,
|
| 584 |
+
convertors=convertors,
|
| 585 |
+
context_param_name=context_param_name,
|
| 586 |
+
pretty_exceptions_short=pretty_exceptions_short,
|
| 587 |
+
),
|
| 588 |
+
params=params, # type: ignore
|
| 589 |
+
help=use_help,
|
| 590 |
+
epilog=command_info.epilog,
|
| 591 |
+
short_help=command_info.short_help,
|
| 592 |
+
options_metavar=command_info.options_metavar,
|
| 593 |
+
add_help_option=command_info.add_help_option,
|
| 594 |
+
no_args_is_help=command_info.no_args_is_help,
|
| 595 |
+
hidden=command_info.hidden,
|
| 596 |
+
deprecated=command_info.deprecated,
|
| 597 |
+
rich_markup_mode=rich_markup_mode,
|
| 598 |
+
# Rich settings
|
| 599 |
+
rich_help_panel=command_info.rich_help_panel,
|
| 600 |
+
)
|
| 601 |
+
return command
|
| 602 |
+
|
| 603 |
+
|
| 604 |
+
def determine_type_convertor(type_: Any) -> Optional[Callable[[Any], Any]]:
|
| 605 |
+
convertor: Optional[Callable[[Any], Any]] = None
|
| 606 |
+
if lenient_issubclass(type_, Path):
|
| 607 |
+
convertor = param_path_convertor
|
| 608 |
+
if lenient_issubclass(type_, Enum):
|
| 609 |
+
convertor = generate_enum_convertor(type_)
|
| 610 |
+
return convertor
|
| 611 |
+
|
| 612 |
+
|
| 613 |
+
def param_path_convertor(value: Optional[str] = None) -> Optional[Path]:
|
| 614 |
+
if value is not None:
|
| 615 |
+
# allow returning any subclass of Path created by an annotated parser without converting
|
| 616 |
+
# it back to a Path
|
| 617 |
+
return value if isinstance(value, Path) else Path(value)
|
| 618 |
+
return None
|
| 619 |
+
|
| 620 |
+
|
| 621 |
+
def generate_enum_convertor(enum: Type[Enum]) -> Callable[[Any], Any]:
|
| 622 |
+
val_map = {str(val.value): val for val in enum}
|
| 623 |
+
|
| 624 |
+
def convertor(value: Any) -> Any:
|
| 625 |
+
if value is not None:
|
| 626 |
+
val = str(value)
|
| 627 |
+
if val in val_map:
|
| 628 |
+
key = val_map[val]
|
| 629 |
+
return enum(key)
|
| 630 |
+
|
| 631 |
+
return convertor
|
| 632 |
+
|
| 633 |
+
|
| 634 |
+
def generate_list_convertor(
|
| 635 |
+
convertor: Optional[Callable[[Any], Any]], default_value: Optional[Any]
|
| 636 |
+
) -> Callable[[Optional[Sequence[Any]]], Optional[List[Any]]]:
|
| 637 |
+
def internal_convertor(value: Optional[Sequence[Any]]) -> Optional[List[Any]]:
|
| 638 |
+
if (value is None) or (default_value is None and len(value) == 0):
|
| 639 |
+
return None
|
| 640 |
+
return [convertor(v) if convertor else v for v in value]
|
| 641 |
+
|
| 642 |
+
return internal_convertor
|
| 643 |
+
|
| 644 |
+
|
| 645 |
+
def generate_tuple_convertor(
|
| 646 |
+
types: Sequence[Any],
|
| 647 |
+
) -> Callable[[Optional[Tuple[Any, ...]]], Optional[Tuple[Any, ...]]]:
|
| 648 |
+
convertors = [determine_type_convertor(type_) for type_ in types]
|
| 649 |
+
|
| 650 |
+
def internal_convertor(
|
| 651 |
+
param_args: Optional[Tuple[Any, ...]],
|
| 652 |
+
) -> Optional[Tuple[Any, ...]]:
|
| 653 |
+
if param_args is None:
|
| 654 |
+
return None
|
| 655 |
+
return tuple(
|
| 656 |
+
convertor(arg) if convertor else arg
|
| 657 |
+
for (convertor, arg) in zip(convertors, param_args)
|
| 658 |
+
)
|
| 659 |
+
|
| 660 |
+
return internal_convertor
|
| 661 |
+
|
| 662 |
+
|
| 663 |
+
def get_callback(
|
| 664 |
+
*,
|
| 665 |
+
callback: Optional[Callable[..., Any]] = None,
|
| 666 |
+
params: Sequence[click.Parameter] = [],
|
| 667 |
+
convertors: Optional[Dict[str, Callable[[str], Any]]] = None,
|
| 668 |
+
context_param_name: Optional[str] = None,
|
| 669 |
+
pretty_exceptions_short: bool,
|
| 670 |
+
) -> Optional[Callable[..., Any]]:
|
| 671 |
+
use_convertors = convertors or {}
|
| 672 |
+
if not callback:
|
| 673 |
+
return None
|
| 674 |
+
parameters = get_params_from_function(callback)
|
| 675 |
+
use_params: Dict[str, Any] = {}
|
| 676 |
+
for param_name in parameters:
|
| 677 |
+
use_params[param_name] = None
|
| 678 |
+
for param in params:
|
| 679 |
+
if param.name:
|
| 680 |
+
use_params[param.name] = param.default
|
| 681 |
+
|
| 682 |
+
def wrapper(**kwargs: Any) -> Any:
|
| 683 |
+
_rich_traceback_guard = pretty_exceptions_short # noqa: F841
|
| 684 |
+
for k, v in kwargs.items():
|
| 685 |
+
if k in use_convertors:
|
| 686 |
+
use_params[k] = use_convertors[k](v)
|
| 687 |
+
else:
|
| 688 |
+
use_params[k] = v
|
| 689 |
+
if context_param_name:
|
| 690 |
+
use_params[context_param_name] = click.get_current_context()
|
| 691 |
+
return callback(**use_params)
|
| 692 |
+
|
| 693 |
+
update_wrapper(wrapper, callback)
|
| 694 |
+
return wrapper
|
| 695 |
+
|
| 696 |
+
|
| 697 |
+
def get_click_type(
|
| 698 |
+
*, annotation: Any, parameter_info: ParameterInfo
|
| 699 |
+
) -> click.ParamType:
|
| 700 |
+
if parameter_info.click_type is not None:
|
| 701 |
+
return parameter_info.click_type
|
| 702 |
+
|
| 703 |
+
elif parameter_info.parser is not None:
|
| 704 |
+
return click.types.FuncParamType(parameter_info.parser)
|
| 705 |
+
|
| 706 |
+
elif annotation is str:
|
| 707 |
+
return click.STRING
|
| 708 |
+
elif annotation is int:
|
| 709 |
+
if parameter_info.min is not None or parameter_info.max is not None:
|
| 710 |
+
min_ = None
|
| 711 |
+
max_ = None
|
| 712 |
+
if parameter_info.min is not None:
|
| 713 |
+
min_ = int(parameter_info.min)
|
| 714 |
+
if parameter_info.max is not None:
|
| 715 |
+
max_ = int(parameter_info.max)
|
| 716 |
+
return click.IntRange(min=min_, max=max_, clamp=parameter_info.clamp)
|
| 717 |
+
else:
|
| 718 |
+
return click.INT
|
| 719 |
+
elif annotation is float:
|
| 720 |
+
if parameter_info.min is not None or parameter_info.max is not None:
|
| 721 |
+
return click.FloatRange(
|
| 722 |
+
min=parameter_info.min,
|
| 723 |
+
max=parameter_info.max,
|
| 724 |
+
clamp=parameter_info.clamp,
|
| 725 |
+
)
|
| 726 |
+
else:
|
| 727 |
+
return click.FLOAT
|
| 728 |
+
elif annotation is bool:
|
| 729 |
+
return click.BOOL
|
| 730 |
+
elif annotation == UUID:
|
| 731 |
+
return click.UUID
|
| 732 |
+
elif annotation == datetime:
|
| 733 |
+
return click.DateTime(formats=parameter_info.formats)
|
| 734 |
+
elif (
|
| 735 |
+
annotation == Path
|
| 736 |
+
or parameter_info.allow_dash
|
| 737 |
+
or parameter_info.path_type
|
| 738 |
+
or parameter_info.resolve_path
|
| 739 |
+
):
|
| 740 |
+
return TyperPath(
|
| 741 |
+
exists=parameter_info.exists,
|
| 742 |
+
file_okay=parameter_info.file_okay,
|
| 743 |
+
dir_okay=parameter_info.dir_okay,
|
| 744 |
+
writable=parameter_info.writable,
|
| 745 |
+
readable=parameter_info.readable,
|
| 746 |
+
resolve_path=parameter_info.resolve_path,
|
| 747 |
+
allow_dash=parameter_info.allow_dash,
|
| 748 |
+
path_type=parameter_info.path_type,
|
| 749 |
+
)
|
| 750 |
+
elif lenient_issubclass(annotation, FileTextWrite):
|
| 751 |
+
return click.File(
|
| 752 |
+
mode=parameter_info.mode or "w",
|
| 753 |
+
encoding=parameter_info.encoding,
|
| 754 |
+
errors=parameter_info.errors,
|
| 755 |
+
lazy=parameter_info.lazy,
|
| 756 |
+
atomic=parameter_info.atomic,
|
| 757 |
+
)
|
| 758 |
+
elif lenient_issubclass(annotation, FileText):
|
| 759 |
+
return click.File(
|
| 760 |
+
mode=parameter_info.mode or "r",
|
| 761 |
+
encoding=parameter_info.encoding,
|
| 762 |
+
errors=parameter_info.errors,
|
| 763 |
+
lazy=parameter_info.lazy,
|
| 764 |
+
atomic=parameter_info.atomic,
|
| 765 |
+
)
|
| 766 |
+
elif lenient_issubclass(annotation, FileBinaryRead):
|
| 767 |
+
return click.File(
|
| 768 |
+
mode=parameter_info.mode or "rb",
|
| 769 |
+
encoding=parameter_info.encoding,
|
| 770 |
+
errors=parameter_info.errors,
|
| 771 |
+
lazy=parameter_info.lazy,
|
| 772 |
+
atomic=parameter_info.atomic,
|
| 773 |
+
)
|
| 774 |
+
elif lenient_issubclass(annotation, FileBinaryWrite):
|
| 775 |
+
return click.File(
|
| 776 |
+
mode=parameter_info.mode or "wb",
|
| 777 |
+
encoding=parameter_info.encoding,
|
| 778 |
+
errors=parameter_info.errors,
|
| 779 |
+
lazy=parameter_info.lazy,
|
| 780 |
+
atomic=parameter_info.atomic,
|
| 781 |
+
)
|
| 782 |
+
elif lenient_issubclass(annotation, Enum):
|
| 783 |
+
# The custom TyperChoice is only needed for Click < 8.2.0, to parse the
|
| 784 |
+
# command line values matching them to the enum values. Click 8.2.0 added
|
| 785 |
+
# support for enum values but reading enum names.
|
| 786 |
+
# Passing here the list of enum values (instead of just the enum) accounts for
|
| 787 |
+
# Click < 8.2.0.
|
| 788 |
+
return TyperChoice(
|
| 789 |
+
[item.value for item in annotation],
|
| 790 |
+
case_sensitive=parameter_info.case_sensitive,
|
| 791 |
+
)
|
| 792 |
+
elif is_literal_type(annotation):
|
| 793 |
+
return click.Choice(
|
| 794 |
+
literal_values(annotation),
|
| 795 |
+
case_sensitive=parameter_info.case_sensitive,
|
| 796 |
+
)
|
| 797 |
+
raise RuntimeError(f"Type not yet supported: {annotation}") # pragma: no cover
|
| 798 |
+
|
| 799 |
+
|
| 800 |
+
def lenient_issubclass(
|
| 801 |
+
cls: Any, class_or_tuple: Union[AnyType, Tuple[AnyType, ...]]
|
| 802 |
+
) -> bool:
|
| 803 |
+
return isinstance(cls, type) and issubclass(cls, class_or_tuple)
|
| 804 |
+
|
| 805 |
+
|
| 806 |
+
def get_click_param(
|
| 807 |
+
param: ParamMeta,
|
| 808 |
+
) -> Tuple[Union[click.Argument, click.Option], Any]:
|
| 809 |
+
# First, find out what will be:
|
| 810 |
+
# * ParamInfo (ArgumentInfo or OptionInfo)
|
| 811 |
+
# * default_value
|
| 812 |
+
# * required
|
| 813 |
+
default_value = None
|
| 814 |
+
required = False
|
| 815 |
+
if isinstance(param.default, ParameterInfo):
|
| 816 |
+
parameter_info = param.default
|
| 817 |
+
if parameter_info.default == Required:
|
| 818 |
+
required = True
|
| 819 |
+
else:
|
| 820 |
+
default_value = parameter_info.default
|
| 821 |
+
elif param.default == Required or param.default is param.empty:
|
| 822 |
+
required = True
|
| 823 |
+
parameter_info = ArgumentInfo()
|
| 824 |
+
else:
|
| 825 |
+
default_value = param.default
|
| 826 |
+
parameter_info = OptionInfo()
|
| 827 |
+
annotation: Any
|
| 828 |
+
if param.annotation is not param.empty:
|
| 829 |
+
annotation = param.annotation
|
| 830 |
+
else:
|
| 831 |
+
annotation = str
|
| 832 |
+
main_type = annotation
|
| 833 |
+
is_list = False
|
| 834 |
+
is_tuple = False
|
| 835 |
+
parameter_type: Any = None
|
| 836 |
+
is_flag = None
|
| 837 |
+
origin = get_origin(main_type)
|
| 838 |
+
|
| 839 |
+
if origin is not None:
|
| 840 |
+
# Handle SomeType | None and Optional[SomeType]
|
| 841 |
+
if is_union(origin):
|
| 842 |
+
types = []
|
| 843 |
+
for type_ in get_args(main_type):
|
| 844 |
+
if type_ is NoneType:
|
| 845 |
+
continue
|
| 846 |
+
types.append(type_)
|
| 847 |
+
assert len(types) == 1, "Typer Currently doesn't support Union types"
|
| 848 |
+
main_type = types[0]
|
| 849 |
+
origin = get_origin(main_type)
|
| 850 |
+
# Handle Tuples and Lists
|
| 851 |
+
if lenient_issubclass(origin, List):
|
| 852 |
+
main_type = get_args(main_type)[0]
|
| 853 |
+
assert not get_origin(main_type), (
|
| 854 |
+
"List types with complex sub-types are not currently supported"
|
| 855 |
+
)
|
| 856 |
+
is_list = True
|
| 857 |
+
elif lenient_issubclass(origin, Tuple): # type: ignore
|
| 858 |
+
types = []
|
| 859 |
+
for type_ in get_args(main_type):
|
| 860 |
+
assert not get_origin(type_), (
|
| 861 |
+
"Tuple types with complex sub-types are not currently supported"
|
| 862 |
+
)
|
| 863 |
+
types.append(
|
| 864 |
+
get_click_type(annotation=type_, parameter_info=parameter_info)
|
| 865 |
+
)
|
| 866 |
+
parameter_type = tuple(types)
|
| 867 |
+
is_tuple = True
|
| 868 |
+
if parameter_type is None:
|
| 869 |
+
parameter_type = get_click_type(
|
| 870 |
+
annotation=main_type, parameter_info=parameter_info
|
| 871 |
+
)
|
| 872 |
+
convertor = determine_type_convertor(main_type)
|
| 873 |
+
if is_list:
|
| 874 |
+
convertor = generate_list_convertor(
|
| 875 |
+
convertor=convertor, default_value=default_value
|
| 876 |
+
)
|
| 877 |
+
if is_tuple:
|
| 878 |
+
convertor = generate_tuple_convertor(get_args(main_type))
|
| 879 |
+
if isinstance(parameter_info, OptionInfo):
|
| 880 |
+
if main_type is bool:
|
| 881 |
+
is_flag = True
|
| 882 |
+
# Click doesn't accept a flag of type bool, only None, and then it sets it
|
| 883 |
+
# to bool internally
|
| 884 |
+
parameter_type = None
|
| 885 |
+
default_option_name = get_command_name(param.name)
|
| 886 |
+
if is_flag:
|
| 887 |
+
default_option_declaration = (
|
| 888 |
+
f"--{default_option_name}/--no-{default_option_name}"
|
| 889 |
+
)
|
| 890 |
+
else:
|
| 891 |
+
default_option_declaration = f"--{default_option_name}"
|
| 892 |
+
param_decls = [param.name]
|
| 893 |
+
if parameter_info.param_decls:
|
| 894 |
+
param_decls.extend(parameter_info.param_decls)
|
| 895 |
+
else:
|
| 896 |
+
param_decls.append(default_option_declaration)
|
| 897 |
+
return (
|
| 898 |
+
TyperOption(
|
| 899 |
+
# Option
|
| 900 |
+
param_decls=param_decls,
|
| 901 |
+
show_default=parameter_info.show_default,
|
| 902 |
+
prompt=parameter_info.prompt,
|
| 903 |
+
confirmation_prompt=parameter_info.confirmation_prompt,
|
| 904 |
+
prompt_required=parameter_info.prompt_required,
|
| 905 |
+
hide_input=parameter_info.hide_input,
|
| 906 |
+
is_flag=is_flag,
|
| 907 |
+
multiple=is_list,
|
| 908 |
+
count=parameter_info.count,
|
| 909 |
+
allow_from_autoenv=parameter_info.allow_from_autoenv,
|
| 910 |
+
type=parameter_type,
|
| 911 |
+
help=parameter_info.help,
|
| 912 |
+
hidden=parameter_info.hidden,
|
| 913 |
+
show_choices=parameter_info.show_choices,
|
| 914 |
+
show_envvar=parameter_info.show_envvar,
|
| 915 |
+
# Parameter
|
| 916 |
+
required=required,
|
| 917 |
+
default=default_value,
|
| 918 |
+
callback=get_param_callback(
|
| 919 |
+
callback=parameter_info.callback, convertor=convertor
|
| 920 |
+
),
|
| 921 |
+
metavar=parameter_info.metavar,
|
| 922 |
+
expose_value=parameter_info.expose_value,
|
| 923 |
+
is_eager=parameter_info.is_eager,
|
| 924 |
+
envvar=parameter_info.envvar,
|
| 925 |
+
shell_complete=parameter_info.shell_complete,
|
| 926 |
+
autocompletion=get_param_completion(parameter_info.autocompletion),
|
| 927 |
+
# Rich settings
|
| 928 |
+
rich_help_panel=parameter_info.rich_help_panel,
|
| 929 |
+
),
|
| 930 |
+
convertor,
|
| 931 |
+
)
|
| 932 |
+
elif isinstance(parameter_info, ArgumentInfo):
|
| 933 |
+
param_decls = [param.name]
|
| 934 |
+
nargs = None
|
| 935 |
+
if is_list:
|
| 936 |
+
nargs = -1
|
| 937 |
+
return (
|
| 938 |
+
TyperArgument(
|
| 939 |
+
# Argument
|
| 940 |
+
param_decls=param_decls,
|
| 941 |
+
type=parameter_type,
|
| 942 |
+
required=required,
|
| 943 |
+
nargs=nargs,
|
| 944 |
+
# TyperArgument
|
| 945 |
+
show_default=parameter_info.show_default,
|
| 946 |
+
show_choices=parameter_info.show_choices,
|
| 947 |
+
show_envvar=parameter_info.show_envvar,
|
| 948 |
+
help=parameter_info.help,
|
| 949 |
+
hidden=parameter_info.hidden,
|
| 950 |
+
# Parameter
|
| 951 |
+
default=default_value,
|
| 952 |
+
callback=get_param_callback(
|
| 953 |
+
callback=parameter_info.callback, convertor=convertor
|
| 954 |
+
),
|
| 955 |
+
metavar=parameter_info.metavar,
|
| 956 |
+
expose_value=parameter_info.expose_value,
|
| 957 |
+
is_eager=parameter_info.is_eager,
|
| 958 |
+
envvar=parameter_info.envvar,
|
| 959 |
+
shell_complete=parameter_info.shell_complete,
|
| 960 |
+
autocompletion=get_param_completion(parameter_info.autocompletion),
|
| 961 |
+
# Rich settings
|
| 962 |
+
rich_help_panel=parameter_info.rich_help_panel,
|
| 963 |
+
),
|
| 964 |
+
convertor,
|
| 965 |
+
)
|
| 966 |
+
raise AssertionError("A click.Parameter should be returned") # pragma: no cover
|
| 967 |
+
|
| 968 |
+
|
| 969 |
+
def get_param_callback(
|
| 970 |
+
*,
|
| 971 |
+
callback: Optional[Callable[..., Any]] = None,
|
| 972 |
+
convertor: Optional[Callable[..., Any]] = None,
|
| 973 |
+
) -> Optional[Callable[..., Any]]:
|
| 974 |
+
if not callback:
|
| 975 |
+
return None
|
| 976 |
+
parameters = get_params_from_function(callback)
|
| 977 |
+
ctx_name = None
|
| 978 |
+
click_param_name = None
|
| 979 |
+
value_name = None
|
| 980 |
+
untyped_names: List[str] = []
|
| 981 |
+
for param_name, param_sig in parameters.items():
|
| 982 |
+
if lenient_issubclass(param_sig.annotation, click.Context):
|
| 983 |
+
ctx_name = param_name
|
| 984 |
+
elif lenient_issubclass(param_sig.annotation, click.Parameter):
|
| 985 |
+
click_param_name = param_name
|
| 986 |
+
else:
|
| 987 |
+
untyped_names.append(param_name)
|
| 988 |
+
# Extract value param name first
|
| 989 |
+
if untyped_names:
|
| 990 |
+
value_name = untyped_names.pop()
|
| 991 |
+
# If context and Click param were not typed (old/Click callback style) extract them
|
| 992 |
+
if untyped_names:
|
| 993 |
+
if ctx_name is None:
|
| 994 |
+
ctx_name = untyped_names.pop(0)
|
| 995 |
+
if click_param_name is None:
|
| 996 |
+
if untyped_names:
|
| 997 |
+
click_param_name = untyped_names.pop(0)
|
| 998 |
+
if untyped_names:
|
| 999 |
+
raise click.ClickException(
|
| 1000 |
+
"Too many CLI parameter callback function parameters"
|
| 1001 |
+
)
|
| 1002 |
+
|
| 1003 |
+
def wrapper(ctx: click.Context, param: click.Parameter, value: Any) -> Any:
|
| 1004 |
+
use_params: Dict[str, Any] = {}
|
| 1005 |
+
if ctx_name:
|
| 1006 |
+
use_params[ctx_name] = ctx
|
| 1007 |
+
if click_param_name:
|
| 1008 |
+
use_params[click_param_name] = param
|
| 1009 |
+
if value_name:
|
| 1010 |
+
if convertor:
|
| 1011 |
+
use_value = convertor(value)
|
| 1012 |
+
else:
|
| 1013 |
+
use_value = value
|
| 1014 |
+
use_params[value_name] = use_value
|
| 1015 |
+
return callback(**use_params)
|
| 1016 |
+
|
| 1017 |
+
update_wrapper(wrapper, callback)
|
| 1018 |
+
return wrapper
|
| 1019 |
+
|
| 1020 |
+
|
| 1021 |
+
def get_param_completion(
|
| 1022 |
+
callback: Optional[Callable[..., Any]] = None,
|
| 1023 |
+
) -> Optional[Callable[..., Any]]:
|
| 1024 |
+
if not callback:
|
| 1025 |
+
return None
|
| 1026 |
+
parameters = get_params_from_function(callback)
|
| 1027 |
+
ctx_name = None
|
| 1028 |
+
args_name = None
|
| 1029 |
+
incomplete_name = None
|
| 1030 |
+
unassigned_params = list(parameters.values())
|
| 1031 |
+
for param_sig in unassigned_params[:]:
|
| 1032 |
+
origin = get_origin(param_sig.annotation)
|
| 1033 |
+
if lenient_issubclass(param_sig.annotation, click.Context):
|
| 1034 |
+
ctx_name = param_sig.name
|
| 1035 |
+
unassigned_params.remove(param_sig)
|
| 1036 |
+
elif lenient_issubclass(origin, List):
|
| 1037 |
+
args_name = param_sig.name
|
| 1038 |
+
unassigned_params.remove(param_sig)
|
| 1039 |
+
elif lenient_issubclass(param_sig.annotation, str):
|
| 1040 |
+
incomplete_name = param_sig.name
|
| 1041 |
+
unassigned_params.remove(param_sig)
|
| 1042 |
+
# If there are still unassigned parameters (not typed), extract by name
|
| 1043 |
+
for param_sig in unassigned_params[:]:
|
| 1044 |
+
if ctx_name is None and param_sig.name == "ctx":
|
| 1045 |
+
ctx_name = param_sig.name
|
| 1046 |
+
unassigned_params.remove(param_sig)
|
| 1047 |
+
elif args_name is None and param_sig.name == "args":
|
| 1048 |
+
args_name = param_sig.name
|
| 1049 |
+
unassigned_params.remove(param_sig)
|
| 1050 |
+
elif incomplete_name is None and param_sig.name == "incomplete":
|
| 1051 |
+
incomplete_name = param_sig.name
|
| 1052 |
+
unassigned_params.remove(param_sig)
|
| 1053 |
+
# Extract value param name first
|
| 1054 |
+
if unassigned_params:
|
| 1055 |
+
show_params = " ".join([param.name for param in unassigned_params])
|
| 1056 |
+
raise click.ClickException(
|
| 1057 |
+
f"Invalid autocompletion callback parameters: {show_params}"
|
| 1058 |
+
)
|
| 1059 |
+
|
| 1060 |
+
def wrapper(ctx: click.Context, args: List[str], incomplete: Optional[str]) -> Any:
|
| 1061 |
+
use_params: Dict[str, Any] = {}
|
| 1062 |
+
if ctx_name:
|
| 1063 |
+
use_params[ctx_name] = ctx
|
| 1064 |
+
if args_name:
|
| 1065 |
+
use_params[args_name] = args
|
| 1066 |
+
if incomplete_name:
|
| 1067 |
+
use_params[incomplete_name] = incomplete
|
| 1068 |
+
return callback(**use_params)
|
| 1069 |
+
|
| 1070 |
+
update_wrapper(wrapper, callback)
|
| 1071 |
+
return wrapper
|
| 1072 |
+
|
| 1073 |
+
|
| 1074 |
+
def run(function: Callable[..., Any]) -> None:
|
| 1075 |
+
app = Typer(add_completion=False)
|
| 1076 |
+
app.command()(function)
|
| 1077 |
+
app()
|
| 1078 |
+
|
| 1079 |
+
|
| 1080 |
+
def _is_macos() -> bool:
|
| 1081 |
+
return platform.system() == "Darwin"
|
| 1082 |
+
|
| 1083 |
+
|
| 1084 |
+
def _is_linux_or_bsd() -> bool:
|
| 1085 |
+
if platform.system() == "Linux":
|
| 1086 |
+
return True
|
| 1087 |
+
|
| 1088 |
+
return "BSD" in platform.system()
|
| 1089 |
+
|
| 1090 |
+
|
| 1091 |
+
def launch(url: str, wait: bool = False, locate: bool = False) -> int:
|
| 1092 |
+
"""This function launches the given URL (or filename) in the default
|
| 1093 |
+
viewer application for this file type. If this is an executable, it
|
| 1094 |
+
might launch the executable in a new session. The return value is
|
| 1095 |
+
the exit code of the launched application. Usually, ``0`` indicates
|
| 1096 |
+
success.
|
| 1097 |
+
|
| 1098 |
+
This function handles url in different operating systems separately:
|
| 1099 |
+
- On macOS (Darwin), it uses the 'open' command.
|
| 1100 |
+
- On Linux and BSD, it uses 'xdg-open' if available.
|
| 1101 |
+
- On Windows (and other OSes), it uses the standard webbrowser module.
|
| 1102 |
+
|
| 1103 |
+
The function avoids, when possible, using the webbrowser module on Linux and macOS
|
| 1104 |
+
to prevent spammy terminal messages from some browsers (e.g., Chrome).
|
| 1105 |
+
|
| 1106 |
+
Examples::
|
| 1107 |
+
|
| 1108 |
+
typer.launch("https://typer.tiangolo.com/")
|
| 1109 |
+
typer.launch("/my/downloaded/file", locate=True)
|
| 1110 |
+
|
| 1111 |
+
:param url: URL or filename of the thing to launch.
|
| 1112 |
+
:param wait: Wait for the program to exit before returning. This
|
| 1113 |
+
only works if the launched program blocks. In particular,
|
| 1114 |
+
``xdg-open`` on Linux does not block.
|
| 1115 |
+
:param locate: if this is set to `True` then instead of launching the
|
| 1116 |
+
application associated with the URL it will attempt to
|
| 1117 |
+
launch a file manager with the file located. This
|
| 1118 |
+
might have weird effects if the URL does not point to
|
| 1119 |
+
the filesystem.
|
| 1120 |
+
"""
|
| 1121 |
+
|
| 1122 |
+
if url.startswith("http://") or url.startswith("https://"):
|
| 1123 |
+
if _is_macos():
|
| 1124 |
+
return subprocess.Popen(
|
| 1125 |
+
["open", url], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT
|
| 1126 |
+
).wait()
|
| 1127 |
+
|
| 1128 |
+
has_xdg_open = _is_linux_or_bsd() and shutil.which("xdg-open") is not None
|
| 1129 |
+
|
| 1130 |
+
if has_xdg_open:
|
| 1131 |
+
return subprocess.Popen(
|
| 1132 |
+
["xdg-open", url], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT
|
| 1133 |
+
).wait()
|
| 1134 |
+
|
| 1135 |
+
import webbrowser
|
| 1136 |
+
|
| 1137 |
+
webbrowser.open(url)
|
| 1138 |
+
|
| 1139 |
+
return 0
|
| 1140 |
+
|
| 1141 |
+
else:
|
| 1142 |
+
return click.launch(url)
|
env/lib/python3.13/site-packages/typer/py.typed
ADDED
|
File without changes
|
env/lib/python3.13/site-packages/typer/rich_utils.py
ADDED
|
@@ -0,0 +1,770 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Extracted and modified from https://github.com/ewels/rich-click
|
| 2 |
+
|
| 3 |
+
import inspect
|
| 4 |
+
import io
|
| 5 |
+
import sys
|
| 6 |
+
from collections import defaultdict
|
| 7 |
+
from gettext import gettext as _
|
| 8 |
+
from os import getenv
|
| 9 |
+
from typing import Any, DefaultDict, Dict, Iterable, List, Optional, Union
|
| 10 |
+
|
| 11 |
+
import click
|
| 12 |
+
from rich import box
|
| 13 |
+
from rich.align import Align
|
| 14 |
+
from rich.columns import Columns
|
| 15 |
+
from rich.console import Console, RenderableType, group
|
| 16 |
+
from rich.emoji import Emoji
|
| 17 |
+
from rich.highlighter import RegexHighlighter
|
| 18 |
+
from rich.markdown import Markdown
|
| 19 |
+
from rich.markup import escape
|
| 20 |
+
from rich.padding import Padding
|
| 21 |
+
from rich.panel import Panel
|
| 22 |
+
from rich.table import Table
|
| 23 |
+
from rich.text import Text
|
| 24 |
+
from rich.theme import Theme
|
| 25 |
+
from rich.traceback import Traceback
|
| 26 |
+
from typer.models import DeveloperExceptionConfig
|
| 27 |
+
|
| 28 |
+
if sys.version_info >= (3, 9):
|
| 29 |
+
from typing import Literal
|
| 30 |
+
else:
|
| 31 |
+
from typing_extensions import Literal
|
| 32 |
+
|
| 33 |
+
# Default styles
|
| 34 |
+
STYLE_OPTION = "bold cyan"
|
| 35 |
+
STYLE_SWITCH = "bold green"
|
| 36 |
+
STYLE_NEGATIVE_OPTION = "bold magenta"
|
| 37 |
+
STYLE_NEGATIVE_SWITCH = "bold red"
|
| 38 |
+
STYLE_METAVAR = "bold yellow"
|
| 39 |
+
STYLE_METAVAR_SEPARATOR = "dim"
|
| 40 |
+
STYLE_USAGE = "yellow"
|
| 41 |
+
STYLE_USAGE_COMMAND = "bold"
|
| 42 |
+
STYLE_DEPRECATED = "red"
|
| 43 |
+
STYLE_DEPRECATED_COMMAND = "dim"
|
| 44 |
+
STYLE_HELPTEXT_FIRST_LINE = ""
|
| 45 |
+
STYLE_HELPTEXT = "dim"
|
| 46 |
+
STYLE_OPTION_HELP = ""
|
| 47 |
+
STYLE_OPTION_DEFAULT = "dim"
|
| 48 |
+
STYLE_OPTION_ENVVAR = "dim yellow"
|
| 49 |
+
STYLE_REQUIRED_SHORT = "red"
|
| 50 |
+
STYLE_REQUIRED_LONG = "dim red"
|
| 51 |
+
STYLE_OPTIONS_PANEL_BORDER = "dim"
|
| 52 |
+
ALIGN_OPTIONS_PANEL: Literal["left", "center", "right"] = "left"
|
| 53 |
+
STYLE_OPTIONS_TABLE_SHOW_LINES = False
|
| 54 |
+
STYLE_OPTIONS_TABLE_LEADING = 0
|
| 55 |
+
STYLE_OPTIONS_TABLE_PAD_EDGE = False
|
| 56 |
+
STYLE_OPTIONS_TABLE_PADDING = (0, 1)
|
| 57 |
+
STYLE_OPTIONS_TABLE_BOX = ""
|
| 58 |
+
STYLE_OPTIONS_TABLE_ROW_STYLES = None
|
| 59 |
+
STYLE_OPTIONS_TABLE_BORDER_STYLE = None
|
| 60 |
+
STYLE_COMMANDS_PANEL_BORDER = "dim"
|
| 61 |
+
ALIGN_COMMANDS_PANEL: Literal["left", "center", "right"] = "left"
|
| 62 |
+
STYLE_COMMANDS_TABLE_SHOW_LINES = False
|
| 63 |
+
STYLE_COMMANDS_TABLE_LEADING = 0
|
| 64 |
+
STYLE_COMMANDS_TABLE_PAD_EDGE = False
|
| 65 |
+
STYLE_COMMANDS_TABLE_PADDING = (0, 1)
|
| 66 |
+
STYLE_COMMANDS_TABLE_BOX = ""
|
| 67 |
+
STYLE_COMMANDS_TABLE_ROW_STYLES = None
|
| 68 |
+
STYLE_COMMANDS_TABLE_BORDER_STYLE = None
|
| 69 |
+
STYLE_COMMANDS_TABLE_FIRST_COLUMN = "bold cyan"
|
| 70 |
+
STYLE_ERRORS_PANEL_BORDER = "red"
|
| 71 |
+
ALIGN_ERRORS_PANEL: Literal["left", "center", "right"] = "left"
|
| 72 |
+
STYLE_ERRORS_SUGGESTION = "dim"
|
| 73 |
+
STYLE_ABORTED = "red"
|
| 74 |
+
_TERMINAL_WIDTH = getenv("TERMINAL_WIDTH")
|
| 75 |
+
MAX_WIDTH = int(_TERMINAL_WIDTH) if _TERMINAL_WIDTH else None
|
| 76 |
+
COLOR_SYSTEM: Optional[Literal["auto", "standard", "256", "truecolor", "windows"]] = (
|
| 77 |
+
"auto" # Set to None to disable colors
|
| 78 |
+
)
|
| 79 |
+
_TYPER_FORCE_DISABLE_TERMINAL = getenv("_TYPER_FORCE_DISABLE_TERMINAL")
|
| 80 |
+
FORCE_TERMINAL = (
|
| 81 |
+
True
|
| 82 |
+
if getenv("GITHUB_ACTIONS") or getenv("FORCE_COLOR") or getenv("PY_COLORS")
|
| 83 |
+
else None
|
| 84 |
+
)
|
| 85 |
+
if _TYPER_FORCE_DISABLE_TERMINAL:
|
| 86 |
+
FORCE_TERMINAL = False
|
| 87 |
+
|
| 88 |
+
# Fixed strings
|
| 89 |
+
DEPRECATED_STRING = _("(deprecated) ")
|
| 90 |
+
DEFAULT_STRING = _("[default: {}]")
|
| 91 |
+
ENVVAR_STRING = _("[env var: {}]")
|
| 92 |
+
REQUIRED_SHORT_STRING = "*"
|
| 93 |
+
REQUIRED_LONG_STRING = _("[required]")
|
| 94 |
+
RANGE_STRING = " [{}]"
|
| 95 |
+
ARGUMENTS_PANEL_TITLE = _("Arguments")
|
| 96 |
+
OPTIONS_PANEL_TITLE = _("Options")
|
| 97 |
+
COMMANDS_PANEL_TITLE = _("Commands")
|
| 98 |
+
ERRORS_PANEL_TITLE = _("Error")
|
| 99 |
+
ABORTED_TEXT = _("Aborted.")
|
| 100 |
+
RICH_HELP = _("Try [blue]'{command_path} {help_option}'[/] for help.")
|
| 101 |
+
|
| 102 |
+
MARKUP_MODE_MARKDOWN = "markdown"
|
| 103 |
+
MARKUP_MODE_RICH = "rich"
|
| 104 |
+
_RICH_HELP_PANEL_NAME = "rich_help_panel"
|
| 105 |
+
|
| 106 |
+
MarkupMode = Literal["markdown", "rich", None]
|
| 107 |
+
|
| 108 |
+
|
| 109 |
+
# Rich regex highlighter
|
| 110 |
+
class OptionHighlighter(RegexHighlighter):
|
| 111 |
+
"""Highlights our special options."""
|
| 112 |
+
|
| 113 |
+
highlights = [
|
| 114 |
+
r"(^|\W)(?P<switch>\-\w+)(?![a-zA-Z0-9])",
|
| 115 |
+
r"(^|\W)(?P<option>\-\-[\w\-]+)(?![a-zA-Z0-9])",
|
| 116 |
+
r"(?P<metavar>\<[^\>]+\>)",
|
| 117 |
+
r"(?P<usage>Usage: )",
|
| 118 |
+
]
|
| 119 |
+
|
| 120 |
+
|
| 121 |
+
class NegativeOptionHighlighter(RegexHighlighter):
|
| 122 |
+
highlights = [
|
| 123 |
+
r"(^|\W)(?P<negative_switch>\-\w+)(?![a-zA-Z0-9])",
|
| 124 |
+
r"(^|\W)(?P<negative_option>\-\-[\w\-]+)(?![a-zA-Z0-9])",
|
| 125 |
+
]
|
| 126 |
+
|
| 127 |
+
|
| 128 |
+
highlighter = OptionHighlighter()
|
| 129 |
+
negative_highlighter = NegativeOptionHighlighter()
|
| 130 |
+
|
| 131 |
+
|
| 132 |
+
def _get_rich_console(stderr: bool = False) -> Console:
|
| 133 |
+
return Console(
|
| 134 |
+
theme=Theme(
|
| 135 |
+
{
|
| 136 |
+
"option": STYLE_OPTION,
|
| 137 |
+
"switch": STYLE_SWITCH,
|
| 138 |
+
"negative_option": STYLE_NEGATIVE_OPTION,
|
| 139 |
+
"negative_switch": STYLE_NEGATIVE_SWITCH,
|
| 140 |
+
"metavar": STYLE_METAVAR,
|
| 141 |
+
"metavar_sep": STYLE_METAVAR_SEPARATOR,
|
| 142 |
+
"usage": STYLE_USAGE,
|
| 143 |
+
},
|
| 144 |
+
),
|
| 145 |
+
highlighter=highlighter,
|
| 146 |
+
color_system=COLOR_SYSTEM,
|
| 147 |
+
force_terminal=FORCE_TERMINAL,
|
| 148 |
+
width=MAX_WIDTH,
|
| 149 |
+
stderr=stderr,
|
| 150 |
+
)
|
| 151 |
+
|
| 152 |
+
|
| 153 |
+
def _make_rich_text(
|
| 154 |
+
*, text: str, style: str = "", markup_mode: MarkupMode
|
| 155 |
+
) -> Union[Markdown, Text]:
|
| 156 |
+
"""Take a string, remove indentations, and return styled text.
|
| 157 |
+
|
| 158 |
+
By default, the text is not parsed for any special formatting.
|
| 159 |
+
If `markup_mode` is `"rich"`, the text is parsed for Rich markup strings.
|
| 160 |
+
If `markup_mode` is `"markdown"`, parse as Markdown.
|
| 161 |
+
"""
|
| 162 |
+
# Remove indentations from input text
|
| 163 |
+
text = inspect.cleandoc(text)
|
| 164 |
+
if markup_mode == MARKUP_MODE_MARKDOWN:
|
| 165 |
+
text = Emoji.replace(text)
|
| 166 |
+
return Markdown(text, style=style)
|
| 167 |
+
if markup_mode == MARKUP_MODE_RICH:
|
| 168 |
+
return highlighter(Text.from_markup(text, style=style))
|
| 169 |
+
else:
|
| 170 |
+
return highlighter(Text(text, style=style))
|
| 171 |
+
|
| 172 |
+
|
| 173 |
+
@group()
|
| 174 |
+
def _get_help_text(
|
| 175 |
+
*,
|
| 176 |
+
obj: Union[click.Command, click.Group],
|
| 177 |
+
markup_mode: MarkupMode,
|
| 178 |
+
) -> Iterable[Union[Markdown, Text]]:
|
| 179 |
+
"""Build primary help text for a click command or group.
|
| 180 |
+
|
| 181 |
+
Returns the prose help text for a command or group, rendered either as a
|
| 182 |
+
Rich Text object or as Markdown.
|
| 183 |
+
If the command is marked as deprecated, the deprecated string will be prepended.
|
| 184 |
+
"""
|
| 185 |
+
# Prepend deprecated status
|
| 186 |
+
if obj.deprecated:
|
| 187 |
+
yield Text(DEPRECATED_STRING, style=STYLE_DEPRECATED)
|
| 188 |
+
|
| 189 |
+
# Fetch and dedent the help text
|
| 190 |
+
help_text = inspect.cleandoc(obj.help or "")
|
| 191 |
+
|
| 192 |
+
# Trim off anything that comes after \f on its own line
|
| 193 |
+
help_text = help_text.partition("\f")[0]
|
| 194 |
+
|
| 195 |
+
# Get the first paragraph
|
| 196 |
+
first_line, *remaining_paragraphs = help_text.split("\n\n")
|
| 197 |
+
|
| 198 |
+
# Remove single linebreaks
|
| 199 |
+
if markup_mode != MARKUP_MODE_MARKDOWN and not first_line.startswith("\b"):
|
| 200 |
+
first_line = first_line.replace("\n", " ")
|
| 201 |
+
yield _make_rich_text(
|
| 202 |
+
text=first_line.strip(),
|
| 203 |
+
style=STYLE_HELPTEXT_FIRST_LINE,
|
| 204 |
+
markup_mode=markup_mode,
|
| 205 |
+
)
|
| 206 |
+
|
| 207 |
+
# Get remaining lines, remove single line breaks and format as dim
|
| 208 |
+
if remaining_paragraphs:
|
| 209 |
+
# Add a newline inbetween the header and the remaining paragraphs
|
| 210 |
+
yield Text("")
|
| 211 |
+
if markup_mode not in (MARKUP_MODE_RICH, MARKUP_MODE_MARKDOWN):
|
| 212 |
+
# Remove single linebreaks
|
| 213 |
+
remaining_paragraphs = [
|
| 214 |
+
x.replace("\n", " ").strip()
|
| 215 |
+
if not x.startswith("\b")
|
| 216 |
+
else "{}\n".format(x.strip("\b\n"))
|
| 217 |
+
for x in remaining_paragraphs
|
| 218 |
+
]
|
| 219 |
+
# Join back together
|
| 220 |
+
remaining_lines = "\n".join(remaining_paragraphs)
|
| 221 |
+
else:
|
| 222 |
+
# Join with double linebreaks if markdown or Rich markup
|
| 223 |
+
remaining_lines = "\n\n".join(remaining_paragraphs)
|
| 224 |
+
|
| 225 |
+
yield _make_rich_text(
|
| 226 |
+
text=remaining_lines,
|
| 227 |
+
style=STYLE_HELPTEXT,
|
| 228 |
+
markup_mode=markup_mode,
|
| 229 |
+
)
|
| 230 |
+
|
| 231 |
+
|
| 232 |
+
def _get_parameter_help(
|
| 233 |
+
*,
|
| 234 |
+
param: Union[click.Option, click.Argument, click.Parameter],
|
| 235 |
+
ctx: click.Context,
|
| 236 |
+
markup_mode: MarkupMode,
|
| 237 |
+
) -> Columns:
|
| 238 |
+
"""Build primary help text for a click option or argument.
|
| 239 |
+
|
| 240 |
+
Returns the prose help text for an option or argument, rendered either
|
| 241 |
+
as a Rich Text object or as Markdown.
|
| 242 |
+
Additional elements are appended to show the default and required status if
|
| 243 |
+
applicable.
|
| 244 |
+
"""
|
| 245 |
+
# import here to avoid cyclic imports
|
| 246 |
+
from .core import TyperArgument, TyperOption
|
| 247 |
+
|
| 248 |
+
items: List[Union[Text, Markdown]] = []
|
| 249 |
+
|
| 250 |
+
# Get the environment variable first
|
| 251 |
+
|
| 252 |
+
envvar = getattr(param, "envvar", None)
|
| 253 |
+
var_str = ""
|
| 254 |
+
# https://github.com/pallets/click/blob/0aec1168ac591e159baf6f61026d6ae322c53aaf/src/click/core.py#L2720-L2726
|
| 255 |
+
if envvar is None:
|
| 256 |
+
if (
|
| 257 |
+
getattr(param, "allow_from_autoenv", None)
|
| 258 |
+
and getattr(ctx, "auto_envvar_prefix", None) is not None
|
| 259 |
+
and param.name is not None
|
| 260 |
+
):
|
| 261 |
+
envvar = f"{ctx.auto_envvar_prefix}_{param.name.upper()}"
|
| 262 |
+
if envvar is not None:
|
| 263 |
+
var_str = (
|
| 264 |
+
envvar if isinstance(envvar, str) else ", ".join(str(d) for d in envvar)
|
| 265 |
+
)
|
| 266 |
+
|
| 267 |
+
# Main help text
|
| 268 |
+
help_value: Union[str, None] = getattr(param, "help", None)
|
| 269 |
+
if help_value:
|
| 270 |
+
paragraphs = help_value.split("\n\n")
|
| 271 |
+
# Remove single linebreaks
|
| 272 |
+
if markup_mode != MARKUP_MODE_MARKDOWN:
|
| 273 |
+
paragraphs = [
|
| 274 |
+
x.replace("\n", " ").strip()
|
| 275 |
+
if not x.startswith("\b")
|
| 276 |
+
else "{}\n".format(x.strip("\b\n"))
|
| 277 |
+
for x in paragraphs
|
| 278 |
+
]
|
| 279 |
+
items.append(
|
| 280 |
+
_make_rich_text(
|
| 281 |
+
text="\n".join(paragraphs).strip(),
|
| 282 |
+
style=STYLE_OPTION_HELP,
|
| 283 |
+
markup_mode=markup_mode,
|
| 284 |
+
)
|
| 285 |
+
)
|
| 286 |
+
|
| 287 |
+
# Environment variable AFTER help text
|
| 288 |
+
if envvar and getattr(param, "show_envvar", None):
|
| 289 |
+
items.append(Text(ENVVAR_STRING.format(var_str), style=STYLE_OPTION_ENVVAR))
|
| 290 |
+
|
| 291 |
+
# Default value
|
| 292 |
+
# This uses Typer's specific param._get_default_string
|
| 293 |
+
if isinstance(param, (TyperOption, TyperArgument)):
|
| 294 |
+
default_value = param._extract_default_help_str(ctx=ctx)
|
| 295 |
+
show_default_is_str = isinstance(param.show_default, str)
|
| 296 |
+
if show_default_is_str or (
|
| 297 |
+
default_value is not None and (param.show_default or ctx.show_default)
|
| 298 |
+
):
|
| 299 |
+
default_str = param._get_default_string(
|
| 300 |
+
ctx=ctx,
|
| 301 |
+
show_default_is_str=show_default_is_str,
|
| 302 |
+
default_value=default_value,
|
| 303 |
+
)
|
| 304 |
+
if default_str:
|
| 305 |
+
items.append(
|
| 306 |
+
Text(
|
| 307 |
+
DEFAULT_STRING.format(default_str),
|
| 308 |
+
style=STYLE_OPTION_DEFAULT,
|
| 309 |
+
)
|
| 310 |
+
)
|
| 311 |
+
|
| 312 |
+
# Required?
|
| 313 |
+
if param.required:
|
| 314 |
+
items.append(Text(REQUIRED_LONG_STRING, style=STYLE_REQUIRED_LONG))
|
| 315 |
+
|
| 316 |
+
# Use Columns - this allows us to group different renderable types
|
| 317 |
+
# (Text, Markdown) onto a single line.
|
| 318 |
+
return Columns(items)
|
| 319 |
+
|
| 320 |
+
|
| 321 |
+
def _make_command_help(
|
| 322 |
+
*,
|
| 323 |
+
help_text: str,
|
| 324 |
+
markup_mode: MarkupMode,
|
| 325 |
+
) -> Union[Text, Markdown]:
|
| 326 |
+
"""Build cli help text for a click group command.
|
| 327 |
+
|
| 328 |
+
That is, when calling help on groups with multiple subcommands
|
| 329 |
+
(not the main help text when calling the subcommand help).
|
| 330 |
+
|
| 331 |
+
Returns the first paragraph of help text for a command, rendered either as a
|
| 332 |
+
Rich Text object or as Markdown.
|
| 333 |
+
Ignores single newlines as paragraph markers, looks for double only.
|
| 334 |
+
"""
|
| 335 |
+
paragraphs = inspect.cleandoc(help_text).split("\n\n")
|
| 336 |
+
# Remove single linebreaks
|
| 337 |
+
if markup_mode != MARKUP_MODE_RICH and not paragraphs[0].startswith("\b"):
|
| 338 |
+
paragraphs[0] = paragraphs[0].replace("\n", " ")
|
| 339 |
+
elif paragraphs[0].startswith("\b"):
|
| 340 |
+
paragraphs[0] = paragraphs[0].replace("\b\n", "")
|
| 341 |
+
return _make_rich_text(
|
| 342 |
+
text=paragraphs[0].strip(),
|
| 343 |
+
style=STYLE_OPTION_HELP,
|
| 344 |
+
markup_mode=markup_mode,
|
| 345 |
+
)
|
| 346 |
+
|
| 347 |
+
|
| 348 |
+
def _print_options_panel(
|
| 349 |
+
*,
|
| 350 |
+
name: str,
|
| 351 |
+
params: Union[List[click.Option], List[click.Argument]],
|
| 352 |
+
ctx: click.Context,
|
| 353 |
+
markup_mode: MarkupMode,
|
| 354 |
+
console: Console,
|
| 355 |
+
) -> None:
|
| 356 |
+
options_rows: List[List[RenderableType]] = []
|
| 357 |
+
required_rows: List[Union[str, Text]] = []
|
| 358 |
+
for param in params:
|
| 359 |
+
# Short and long form
|
| 360 |
+
opt_long_strs = []
|
| 361 |
+
opt_short_strs = []
|
| 362 |
+
secondary_opt_long_strs = []
|
| 363 |
+
secondary_opt_short_strs = []
|
| 364 |
+
for opt_str in param.opts:
|
| 365 |
+
if "--" in opt_str:
|
| 366 |
+
opt_long_strs.append(opt_str)
|
| 367 |
+
else:
|
| 368 |
+
opt_short_strs.append(opt_str)
|
| 369 |
+
for opt_str in param.secondary_opts:
|
| 370 |
+
if "--" in opt_str:
|
| 371 |
+
secondary_opt_long_strs.append(opt_str)
|
| 372 |
+
else:
|
| 373 |
+
secondary_opt_short_strs.append(opt_str)
|
| 374 |
+
|
| 375 |
+
# Column for a metavar, if we have one
|
| 376 |
+
metavar = Text(style=STYLE_METAVAR, overflow="fold")
|
| 377 |
+
# TODO: when deprecating Click < 8.2, make ctx required
|
| 378 |
+
signature = inspect.signature(param.make_metavar)
|
| 379 |
+
if "ctx" in signature.parameters:
|
| 380 |
+
metavar_str = param.make_metavar(ctx=ctx)
|
| 381 |
+
else:
|
| 382 |
+
# Click < 8.2
|
| 383 |
+
metavar_str = param.make_metavar() # type: ignore[call-arg]
|
| 384 |
+
|
| 385 |
+
# Do it ourselves if this is a positional argument
|
| 386 |
+
if (
|
| 387 |
+
isinstance(param, click.Argument)
|
| 388 |
+
and param.name
|
| 389 |
+
and metavar_str == param.name.upper()
|
| 390 |
+
):
|
| 391 |
+
metavar_str = param.type.name.upper()
|
| 392 |
+
|
| 393 |
+
# Skip booleans and choices (handled above)
|
| 394 |
+
if metavar_str != "BOOLEAN":
|
| 395 |
+
metavar.append(metavar_str)
|
| 396 |
+
|
| 397 |
+
# Range - from
|
| 398 |
+
# https://github.com/pallets/click/blob/c63c70dabd3f86ca68678b4f00951f78f52d0270/src/click/core.py#L2698-L2706 # noqa: E501
|
| 399 |
+
# skip count with default range type
|
| 400 |
+
if (
|
| 401 |
+
isinstance(param.type, click.types._NumberRangeBase)
|
| 402 |
+
and isinstance(param, click.Option)
|
| 403 |
+
and not (param.count and param.type.min == 0 and param.type.max is None)
|
| 404 |
+
):
|
| 405 |
+
range_str = param.type._describe_range()
|
| 406 |
+
if range_str:
|
| 407 |
+
metavar.append(RANGE_STRING.format(range_str))
|
| 408 |
+
|
| 409 |
+
# Required asterisk
|
| 410 |
+
required: Union[str, Text] = ""
|
| 411 |
+
if param.required:
|
| 412 |
+
required = Text(REQUIRED_SHORT_STRING, style=STYLE_REQUIRED_SHORT)
|
| 413 |
+
|
| 414 |
+
# Highlighter to make [ | ] and <> dim
|
| 415 |
+
class MetavarHighlighter(RegexHighlighter):
|
| 416 |
+
highlights = [
|
| 417 |
+
r"^(?P<metavar_sep>(\[|<))",
|
| 418 |
+
r"(?P<metavar_sep>\|)",
|
| 419 |
+
r"(?P<metavar_sep>(\]|>)$)",
|
| 420 |
+
]
|
| 421 |
+
|
| 422 |
+
metavar_highlighter = MetavarHighlighter()
|
| 423 |
+
|
| 424 |
+
required_rows.append(required)
|
| 425 |
+
options_rows.append(
|
| 426 |
+
[
|
| 427 |
+
highlighter(",".join(opt_long_strs)),
|
| 428 |
+
highlighter(",".join(opt_short_strs)),
|
| 429 |
+
negative_highlighter(",".join(secondary_opt_long_strs)),
|
| 430 |
+
negative_highlighter(",".join(secondary_opt_short_strs)),
|
| 431 |
+
metavar_highlighter(metavar),
|
| 432 |
+
_get_parameter_help(
|
| 433 |
+
param=param,
|
| 434 |
+
ctx=ctx,
|
| 435 |
+
markup_mode=markup_mode,
|
| 436 |
+
),
|
| 437 |
+
]
|
| 438 |
+
)
|
| 439 |
+
rows_with_required: List[List[RenderableType]] = []
|
| 440 |
+
if any(required_rows):
|
| 441 |
+
for required, row in zip(required_rows, options_rows):
|
| 442 |
+
rows_with_required.append([required, *row])
|
| 443 |
+
else:
|
| 444 |
+
rows_with_required = options_rows
|
| 445 |
+
if options_rows:
|
| 446 |
+
t_styles: Dict[str, Any] = {
|
| 447 |
+
"show_lines": STYLE_OPTIONS_TABLE_SHOW_LINES,
|
| 448 |
+
"leading": STYLE_OPTIONS_TABLE_LEADING,
|
| 449 |
+
"box": STYLE_OPTIONS_TABLE_BOX,
|
| 450 |
+
"border_style": STYLE_OPTIONS_TABLE_BORDER_STYLE,
|
| 451 |
+
"row_styles": STYLE_OPTIONS_TABLE_ROW_STYLES,
|
| 452 |
+
"pad_edge": STYLE_OPTIONS_TABLE_PAD_EDGE,
|
| 453 |
+
"padding": STYLE_OPTIONS_TABLE_PADDING,
|
| 454 |
+
}
|
| 455 |
+
box_style = getattr(box, t_styles.pop("box"), None)
|
| 456 |
+
|
| 457 |
+
options_table = Table(
|
| 458 |
+
highlight=True,
|
| 459 |
+
show_header=False,
|
| 460 |
+
expand=True,
|
| 461 |
+
box=box_style,
|
| 462 |
+
**t_styles,
|
| 463 |
+
)
|
| 464 |
+
for row in rows_with_required:
|
| 465 |
+
options_table.add_row(*row)
|
| 466 |
+
console.print(
|
| 467 |
+
Panel(
|
| 468 |
+
options_table,
|
| 469 |
+
border_style=STYLE_OPTIONS_PANEL_BORDER,
|
| 470 |
+
title=name,
|
| 471 |
+
title_align=ALIGN_OPTIONS_PANEL,
|
| 472 |
+
)
|
| 473 |
+
)
|
| 474 |
+
|
| 475 |
+
|
| 476 |
+
def _print_commands_panel(
|
| 477 |
+
*,
|
| 478 |
+
name: str,
|
| 479 |
+
commands: List[click.Command],
|
| 480 |
+
markup_mode: MarkupMode,
|
| 481 |
+
console: Console,
|
| 482 |
+
cmd_len: int,
|
| 483 |
+
) -> None:
|
| 484 |
+
t_styles: Dict[str, Any] = {
|
| 485 |
+
"show_lines": STYLE_COMMANDS_TABLE_SHOW_LINES,
|
| 486 |
+
"leading": STYLE_COMMANDS_TABLE_LEADING,
|
| 487 |
+
"box": STYLE_COMMANDS_TABLE_BOX,
|
| 488 |
+
"border_style": STYLE_COMMANDS_TABLE_BORDER_STYLE,
|
| 489 |
+
"row_styles": STYLE_COMMANDS_TABLE_ROW_STYLES,
|
| 490 |
+
"pad_edge": STYLE_COMMANDS_TABLE_PAD_EDGE,
|
| 491 |
+
"padding": STYLE_COMMANDS_TABLE_PADDING,
|
| 492 |
+
}
|
| 493 |
+
box_style = getattr(box, t_styles.pop("box"), None)
|
| 494 |
+
|
| 495 |
+
commands_table = Table(
|
| 496 |
+
highlight=False,
|
| 497 |
+
show_header=False,
|
| 498 |
+
expand=True,
|
| 499 |
+
box=box_style,
|
| 500 |
+
**t_styles,
|
| 501 |
+
)
|
| 502 |
+
# Define formatting in first column, as commands don't match highlighter
|
| 503 |
+
# regex
|
| 504 |
+
commands_table.add_column(
|
| 505 |
+
style=STYLE_COMMANDS_TABLE_FIRST_COLUMN,
|
| 506 |
+
no_wrap=True,
|
| 507 |
+
width=cmd_len,
|
| 508 |
+
)
|
| 509 |
+
|
| 510 |
+
# A big ratio makes the description column be greedy and take all the space
|
| 511 |
+
# available instead of allowing the command column to grow and misalign with
|
| 512 |
+
# other panels.
|
| 513 |
+
commands_table.add_column("Description", justify="left", no_wrap=False, ratio=10)
|
| 514 |
+
rows: List[List[Union[RenderableType, None]]] = []
|
| 515 |
+
deprecated_rows: List[Union[RenderableType, None]] = []
|
| 516 |
+
for command in commands:
|
| 517 |
+
helptext = command.short_help or command.help or ""
|
| 518 |
+
command_name = command.name or ""
|
| 519 |
+
if command.deprecated:
|
| 520 |
+
command_name_text = Text(f"{command_name}", style=STYLE_DEPRECATED_COMMAND)
|
| 521 |
+
deprecated_rows.append(Text(DEPRECATED_STRING, style=STYLE_DEPRECATED))
|
| 522 |
+
else:
|
| 523 |
+
command_name_text = Text(command_name)
|
| 524 |
+
deprecated_rows.append(None)
|
| 525 |
+
rows.append(
|
| 526 |
+
[
|
| 527 |
+
command_name_text,
|
| 528 |
+
_make_command_help(
|
| 529 |
+
help_text=helptext,
|
| 530 |
+
markup_mode=markup_mode,
|
| 531 |
+
),
|
| 532 |
+
]
|
| 533 |
+
)
|
| 534 |
+
rows_with_deprecated = rows
|
| 535 |
+
if any(deprecated_rows):
|
| 536 |
+
rows_with_deprecated = []
|
| 537 |
+
for row, deprecated_text in zip(rows, deprecated_rows):
|
| 538 |
+
rows_with_deprecated.append([*row, deprecated_text])
|
| 539 |
+
for row in rows_with_deprecated:
|
| 540 |
+
commands_table.add_row(*row)
|
| 541 |
+
if commands_table.row_count:
|
| 542 |
+
console.print(
|
| 543 |
+
Panel(
|
| 544 |
+
commands_table,
|
| 545 |
+
border_style=STYLE_COMMANDS_PANEL_BORDER,
|
| 546 |
+
title=name,
|
| 547 |
+
title_align=ALIGN_COMMANDS_PANEL,
|
| 548 |
+
)
|
| 549 |
+
)
|
| 550 |
+
|
| 551 |
+
|
| 552 |
+
def rich_format_help(
|
| 553 |
+
*,
|
| 554 |
+
obj: Union[click.Command, click.Group],
|
| 555 |
+
ctx: click.Context,
|
| 556 |
+
markup_mode: MarkupMode,
|
| 557 |
+
) -> None:
|
| 558 |
+
"""Print nicely formatted help text using rich.
|
| 559 |
+
|
| 560 |
+
Based on original code from rich-cli, by @willmcgugan.
|
| 561 |
+
https://github.com/Textualize/rich-cli/blob/8a2767c7a340715fc6fbf4930ace717b9b2fc5e5/src/rich_cli/__main__.py#L162-L236
|
| 562 |
+
|
| 563 |
+
Replacement for the click function format_help().
|
| 564 |
+
Takes a command or group and builds the help text output.
|
| 565 |
+
"""
|
| 566 |
+
console = _get_rich_console()
|
| 567 |
+
|
| 568 |
+
# Print usage
|
| 569 |
+
console.print(
|
| 570 |
+
Padding(highlighter(obj.get_usage(ctx)), 1), style=STYLE_USAGE_COMMAND
|
| 571 |
+
)
|
| 572 |
+
|
| 573 |
+
# Print command / group help if we have some
|
| 574 |
+
if obj.help:
|
| 575 |
+
# Print with some padding
|
| 576 |
+
console.print(
|
| 577 |
+
Padding(
|
| 578 |
+
Align(
|
| 579 |
+
_get_help_text(
|
| 580 |
+
obj=obj,
|
| 581 |
+
markup_mode=markup_mode,
|
| 582 |
+
),
|
| 583 |
+
pad=False,
|
| 584 |
+
),
|
| 585 |
+
(0, 1, 1, 1),
|
| 586 |
+
)
|
| 587 |
+
)
|
| 588 |
+
panel_to_arguments: DefaultDict[str, List[click.Argument]] = defaultdict(list)
|
| 589 |
+
panel_to_options: DefaultDict[str, List[click.Option]] = defaultdict(list)
|
| 590 |
+
for param in obj.get_params(ctx):
|
| 591 |
+
# Skip if option is hidden
|
| 592 |
+
if getattr(param, "hidden", False):
|
| 593 |
+
continue
|
| 594 |
+
if isinstance(param, click.Argument):
|
| 595 |
+
panel_name = (
|
| 596 |
+
getattr(param, _RICH_HELP_PANEL_NAME, None) or ARGUMENTS_PANEL_TITLE
|
| 597 |
+
)
|
| 598 |
+
panel_to_arguments[panel_name].append(param)
|
| 599 |
+
elif isinstance(param, click.Option):
|
| 600 |
+
panel_name = (
|
| 601 |
+
getattr(param, _RICH_HELP_PANEL_NAME, None) or OPTIONS_PANEL_TITLE
|
| 602 |
+
)
|
| 603 |
+
panel_to_options[panel_name].append(param)
|
| 604 |
+
default_arguments = panel_to_arguments.get(ARGUMENTS_PANEL_TITLE, [])
|
| 605 |
+
_print_options_panel(
|
| 606 |
+
name=ARGUMENTS_PANEL_TITLE,
|
| 607 |
+
params=default_arguments,
|
| 608 |
+
ctx=ctx,
|
| 609 |
+
markup_mode=markup_mode,
|
| 610 |
+
console=console,
|
| 611 |
+
)
|
| 612 |
+
for panel_name, arguments in panel_to_arguments.items():
|
| 613 |
+
if panel_name == ARGUMENTS_PANEL_TITLE:
|
| 614 |
+
# Already printed above
|
| 615 |
+
continue
|
| 616 |
+
_print_options_panel(
|
| 617 |
+
name=panel_name,
|
| 618 |
+
params=arguments,
|
| 619 |
+
ctx=ctx,
|
| 620 |
+
markup_mode=markup_mode,
|
| 621 |
+
console=console,
|
| 622 |
+
)
|
| 623 |
+
default_options = panel_to_options.get(OPTIONS_PANEL_TITLE, [])
|
| 624 |
+
_print_options_panel(
|
| 625 |
+
name=OPTIONS_PANEL_TITLE,
|
| 626 |
+
params=default_options,
|
| 627 |
+
ctx=ctx,
|
| 628 |
+
markup_mode=markup_mode,
|
| 629 |
+
console=console,
|
| 630 |
+
)
|
| 631 |
+
for panel_name, options in panel_to_options.items():
|
| 632 |
+
if panel_name == OPTIONS_PANEL_TITLE:
|
| 633 |
+
# Already printed above
|
| 634 |
+
continue
|
| 635 |
+
_print_options_panel(
|
| 636 |
+
name=panel_name,
|
| 637 |
+
params=options,
|
| 638 |
+
ctx=ctx,
|
| 639 |
+
markup_mode=markup_mode,
|
| 640 |
+
console=console,
|
| 641 |
+
)
|
| 642 |
+
|
| 643 |
+
if isinstance(obj, click.Group):
|
| 644 |
+
panel_to_commands: DefaultDict[str, List[click.Command]] = defaultdict(list)
|
| 645 |
+
for command_name in obj.list_commands(ctx):
|
| 646 |
+
command = obj.get_command(ctx, command_name)
|
| 647 |
+
if command and not command.hidden:
|
| 648 |
+
panel_name = (
|
| 649 |
+
getattr(command, _RICH_HELP_PANEL_NAME, None)
|
| 650 |
+
or COMMANDS_PANEL_TITLE
|
| 651 |
+
)
|
| 652 |
+
panel_to_commands[panel_name].append(command)
|
| 653 |
+
|
| 654 |
+
# Identify the longest command name in all panels
|
| 655 |
+
max_cmd_len = max(
|
| 656 |
+
[
|
| 657 |
+
len(command.name or "")
|
| 658 |
+
for commands in panel_to_commands.values()
|
| 659 |
+
for command in commands
|
| 660 |
+
],
|
| 661 |
+
default=0,
|
| 662 |
+
)
|
| 663 |
+
|
| 664 |
+
# Print each command group panel
|
| 665 |
+
default_commands = panel_to_commands.get(COMMANDS_PANEL_TITLE, [])
|
| 666 |
+
_print_commands_panel(
|
| 667 |
+
name=COMMANDS_PANEL_TITLE,
|
| 668 |
+
commands=default_commands,
|
| 669 |
+
markup_mode=markup_mode,
|
| 670 |
+
console=console,
|
| 671 |
+
cmd_len=max_cmd_len,
|
| 672 |
+
)
|
| 673 |
+
for panel_name, commands in panel_to_commands.items():
|
| 674 |
+
if panel_name == COMMANDS_PANEL_TITLE:
|
| 675 |
+
# Already printed above
|
| 676 |
+
continue
|
| 677 |
+
_print_commands_panel(
|
| 678 |
+
name=panel_name,
|
| 679 |
+
commands=commands,
|
| 680 |
+
markup_mode=markup_mode,
|
| 681 |
+
console=console,
|
| 682 |
+
cmd_len=max_cmd_len,
|
| 683 |
+
)
|
| 684 |
+
|
| 685 |
+
# Epilogue if we have it
|
| 686 |
+
if obj.epilog:
|
| 687 |
+
# Remove single linebreaks, replace double with single
|
| 688 |
+
lines = obj.epilog.split("\n\n")
|
| 689 |
+
epilogue = "\n".join([x.replace("\n", " ").strip() for x in lines])
|
| 690 |
+
epilogue_text = _make_rich_text(text=epilogue, markup_mode=markup_mode)
|
| 691 |
+
console.print(Padding(Align(epilogue_text, pad=False), 1))
|
| 692 |
+
|
| 693 |
+
|
| 694 |
+
def rich_format_error(self: click.ClickException) -> None:
|
| 695 |
+
"""Print richly formatted click errors.
|
| 696 |
+
|
| 697 |
+
Called by custom exception handler to print richly formatted click errors.
|
| 698 |
+
Mimics original click.ClickException.echo() function but with rich formatting.
|
| 699 |
+
"""
|
| 700 |
+
# Don't do anything when it's a NoArgsIsHelpError (without importing it, cf. #1278)
|
| 701 |
+
if self.__class__.__name__ == "NoArgsIsHelpError":
|
| 702 |
+
return
|
| 703 |
+
|
| 704 |
+
console = _get_rich_console(stderr=True)
|
| 705 |
+
ctx: Union[click.Context, None] = getattr(self, "ctx", None)
|
| 706 |
+
if ctx is not None:
|
| 707 |
+
console.print(ctx.get_usage())
|
| 708 |
+
|
| 709 |
+
if ctx is not None and ctx.command.get_help_option(ctx) is not None:
|
| 710 |
+
console.print(
|
| 711 |
+
RICH_HELP.format(
|
| 712 |
+
command_path=ctx.command_path, help_option=ctx.help_option_names[0]
|
| 713 |
+
),
|
| 714 |
+
style=STYLE_ERRORS_SUGGESTION,
|
| 715 |
+
)
|
| 716 |
+
|
| 717 |
+
console.print(
|
| 718 |
+
Panel(
|
| 719 |
+
highlighter(self.format_message()),
|
| 720 |
+
border_style=STYLE_ERRORS_PANEL_BORDER,
|
| 721 |
+
title=ERRORS_PANEL_TITLE,
|
| 722 |
+
title_align=ALIGN_ERRORS_PANEL,
|
| 723 |
+
)
|
| 724 |
+
)
|
| 725 |
+
|
| 726 |
+
|
| 727 |
+
def rich_abort_error() -> None:
|
| 728 |
+
"""Print richly formatted abort error."""
|
| 729 |
+
console = _get_rich_console(stderr=True)
|
| 730 |
+
console.print(ABORTED_TEXT, style=STYLE_ABORTED)
|
| 731 |
+
|
| 732 |
+
|
| 733 |
+
def escape_before_html_export(input_text: str) -> str:
|
| 734 |
+
"""Ensure that the input string can be used for HTML export."""
|
| 735 |
+
return escape(input_text).strip()
|
| 736 |
+
|
| 737 |
+
|
| 738 |
+
def rich_to_html(input_text: str) -> str:
|
| 739 |
+
"""Print the HTML version of a rich-formatted input string.
|
| 740 |
+
|
| 741 |
+
This function does not provide a full HTML page, but can be used to insert
|
| 742 |
+
HTML-formatted text spans into a markdown file.
|
| 743 |
+
"""
|
| 744 |
+
console = Console(record=True, highlight=False, file=io.StringIO())
|
| 745 |
+
|
| 746 |
+
console.print(input_text, overflow="ignore", crop=False)
|
| 747 |
+
|
| 748 |
+
return console.export_html(inline_styles=True, code_format="{code}").strip()
|
| 749 |
+
|
| 750 |
+
|
| 751 |
+
def rich_render_text(text: str) -> str:
|
| 752 |
+
"""Remove rich tags and render a pure text representation"""
|
| 753 |
+
console = _get_rich_console()
|
| 754 |
+
return "".join(segment.text for segment in console.render(text)).rstrip("\n")
|
| 755 |
+
|
| 756 |
+
|
| 757 |
+
def get_traceback(
|
| 758 |
+
exc: BaseException,
|
| 759 |
+
exception_config: DeveloperExceptionConfig,
|
| 760 |
+
internal_dir_names: List[str],
|
| 761 |
+
) -> Traceback:
|
| 762 |
+
rich_tb = Traceback.from_exception(
|
| 763 |
+
type(exc),
|
| 764 |
+
exc,
|
| 765 |
+
exc.__traceback__,
|
| 766 |
+
show_locals=exception_config.pretty_exceptions_show_locals,
|
| 767 |
+
suppress=internal_dir_names,
|
| 768 |
+
width=MAX_WIDTH,
|
| 769 |
+
)
|
| 770 |
+
return rich_tb
|
env/lib/python3.13/site-packages/typer/testing.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from typing import IO, Any, Mapping, Optional, Sequence, Union
|
| 2 |
+
|
| 3 |
+
from click.testing import CliRunner as ClickCliRunner # noqa
|
| 4 |
+
from click.testing import Result
|
| 5 |
+
from typer.main import Typer
|
| 6 |
+
from typer.main import get_command as _get_command
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
class CliRunner(ClickCliRunner):
|
| 10 |
+
def invoke( # type: ignore
|
| 11 |
+
self,
|
| 12 |
+
app: Typer,
|
| 13 |
+
args: Optional[Union[str, Sequence[str]]] = None,
|
| 14 |
+
input: Optional[Union[bytes, str, IO[Any]]] = None,
|
| 15 |
+
env: Optional[Mapping[str, Optional[str]]] = None,
|
| 16 |
+
catch_exceptions: bool = True,
|
| 17 |
+
color: bool = False,
|
| 18 |
+
**extra: Any,
|
| 19 |
+
) -> Result:
|
| 20 |
+
use_cli = _get_command(app)
|
| 21 |
+
return super().invoke(
|
| 22 |
+
use_cli,
|
| 23 |
+
args=args,
|
| 24 |
+
input=input,
|
| 25 |
+
env=env,
|
| 26 |
+
catch_exceptions=catch_exceptions,
|
| 27 |
+
color=color,
|
| 28 |
+
**extra,
|
| 29 |
+
)
|