not-pegasus commited on
Commit
2f99b25
·
verified ·
1 Parent(s): 4cceaa6

Add files using upload-large-folder tool

Browse files
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
+ )