Mingke977 commited on
Commit
e3e1fef
·
verified ·
1 Parent(s): da26373

Add files using upload-large-folder tool

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. venv/lib/python3.10/site-packages/anyio-4.12.1.dist-info/METADATA +96 -0
  2. venv/lib/python3.10/site-packages/anyio-4.12.1.dist-info/RECORD +92 -0
  3. venv/lib/python3.10/site-packages/anyio-4.12.1.dist-info/WHEEL +5 -0
  4. venv/lib/python3.10/site-packages/anyio-4.12.1.dist-info/entry_points.txt +2 -0
  5. venv/lib/python3.10/site-packages/anyio-4.12.1.dist-info/licenses/LICENSE +20 -0
  6. venv/lib/python3.10/site-packages/anyio-4.12.1.dist-info/top_level.txt +1 -0
  7. venv/lib/python3.10/site-packages/anyio/streams/__pycache__/memory.cpython-310.pyc +0 -0
  8. venv/lib/python3.10/site-packages/anyio/streams/__pycache__/stapled.cpython-310.pyc +0 -0
  9. venv/lib/python3.10/site-packages/anyio/streams/__pycache__/text.cpython-310.pyc +0 -0
  10. venv/lib/python3.10/site-packages/anyio/streams/__pycache__/tls.cpython-310.pyc +0 -0
  11. venv/lib/python3.10/site-packages/certifi-2026.2.25.dist-info/INSTALLER +1 -0
  12. venv/lib/python3.10/site-packages/certifi-2026.2.25.dist-info/METADATA +78 -0
  13. venv/lib/python3.10/site-packages/certifi-2026.2.25.dist-info/RECORD +14 -0
  14. venv/lib/python3.10/site-packages/certifi-2026.2.25.dist-info/WHEEL +5 -0
  15. venv/lib/python3.10/site-packages/certifi-2026.2.25.dist-info/licenses/LICENSE +20 -0
  16. venv/lib/python3.10/site-packages/certifi-2026.2.25.dist-info/top_level.txt +1 -0
  17. venv/lib/python3.10/site-packages/certifi/__init__.py +4 -0
  18. venv/lib/python3.10/site-packages/certifi/__main__.py +12 -0
  19. venv/lib/python3.10/site-packages/certifi/__pycache__/__init__.cpython-310.pyc +0 -0
  20. venv/lib/python3.10/site-packages/certifi/__pycache__/__main__.cpython-310.pyc +0 -0
  21. venv/lib/python3.10/site-packages/certifi/__pycache__/core.cpython-310.pyc +0 -0
  22. venv/lib/python3.10/site-packages/certifi/cacert.pem +0 -0
  23. venv/lib/python3.10/site-packages/certifi/core.py +83 -0
  24. venv/lib/python3.10/site-packages/certifi/py.typed +0 -0
  25. venv/lib/python3.10/site-packages/click-8.3.1.dist-info/INSTALLER +1 -0
  26. venv/lib/python3.10/site-packages/click-8.3.1.dist-info/METADATA +84 -0
  27. venv/lib/python3.10/site-packages/click-8.3.1.dist-info/RECORD +40 -0
  28. venv/lib/python3.10/site-packages/click-8.3.1.dist-info/WHEEL +4 -0
  29. venv/lib/python3.10/site-packages/click-8.3.1.dist-info/licenses/LICENSE.txt +28 -0
  30. venv/lib/python3.10/site-packages/click/__init__.py +123 -0
  31. venv/lib/python3.10/site-packages/click/__pycache__/__init__.cpython-310.pyc +0 -0
  32. venv/lib/python3.10/site-packages/click/__pycache__/_compat.cpython-310.pyc +0 -0
  33. venv/lib/python3.10/site-packages/click/__pycache__/_termui_impl.cpython-310.pyc +0 -0
  34. venv/lib/python3.10/site-packages/click/__pycache__/_textwrap.cpython-310.pyc +0 -0
  35. venv/lib/python3.10/site-packages/click/__pycache__/_utils.cpython-310.pyc +0 -0
  36. venv/lib/python3.10/site-packages/click/__pycache__/_winconsole.cpython-310.pyc +0 -0
  37. venv/lib/python3.10/site-packages/click/__pycache__/core.cpython-310.pyc +0 -0
  38. venv/lib/python3.10/site-packages/click/__pycache__/decorators.cpython-310.pyc +0 -0
  39. venv/lib/python3.10/site-packages/click/__pycache__/exceptions.cpython-310.pyc +0 -0
  40. venv/lib/python3.10/site-packages/click/__pycache__/formatting.cpython-310.pyc +0 -0
  41. venv/lib/python3.10/site-packages/click/__pycache__/globals.cpython-310.pyc +0 -0
  42. venv/lib/python3.10/site-packages/click/__pycache__/parser.cpython-310.pyc +0 -0
  43. venv/lib/python3.10/site-packages/click/__pycache__/shell_completion.cpython-310.pyc +0 -0
  44. venv/lib/python3.10/site-packages/click/__pycache__/termui.cpython-310.pyc +0 -0
  45. venv/lib/python3.10/site-packages/click/__pycache__/testing.cpython-310.pyc +0 -0
  46. venv/lib/python3.10/site-packages/click/__pycache__/types.cpython-310.pyc +0 -0
  47. venv/lib/python3.10/site-packages/click/__pycache__/utils.cpython-310.pyc +0 -0
  48. venv/lib/python3.10/site-packages/click/_compat.py +622 -0
  49. venv/lib/python3.10/site-packages/click/_termui_impl.py +852 -0
  50. venv/lib/python3.10/site-packages/click/_textwrap.py +51 -0
venv/lib/python3.10/site-packages/anyio-4.12.1.dist-info/METADATA ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Metadata-Version: 2.4
2
+ Name: anyio
3
+ Version: 4.12.1
4
+ Summary: High-level concurrency and networking framework on top of asyncio or Trio
5
+ Author-email: Alex Grönholm <alex.gronholm@nextday.fi>
6
+ License-Expression: MIT
7
+ Project-URL: Documentation, https://anyio.readthedocs.io/en/latest/
8
+ Project-URL: Changelog, https://anyio.readthedocs.io/en/stable/versionhistory.html
9
+ Project-URL: Source code, https://github.com/agronholm/anyio
10
+ Project-URL: Issue tracker, https://github.com/agronholm/anyio/issues
11
+ Classifier: Development Status :: 5 - Production/Stable
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Framework :: AnyIO
14
+ Classifier: Typing :: Typed
15
+ Classifier: Programming Language :: Python
16
+ Classifier: Programming Language :: Python :: 3
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
+ Requires-Python: >=3.9
24
+ Description-Content-Type: text/x-rst
25
+ License-File: LICENSE
26
+ Requires-Dist: exceptiongroup>=1.0.2; python_version < "3.11"
27
+ Requires-Dist: idna>=2.8
28
+ Requires-Dist: typing_extensions>=4.5; python_version < "3.13"
29
+ Provides-Extra: trio
30
+ Requires-Dist: trio>=0.32.0; python_version >= "3.10" and extra == "trio"
31
+ Requires-Dist: trio>=0.31.0; python_version < "3.10" and extra == "trio"
32
+ Dynamic: license-file
33
+
34
+ .. image:: https://github.com/agronholm/anyio/actions/workflows/test.yml/badge.svg
35
+ :target: https://github.com/agronholm/anyio/actions/workflows/test.yml
36
+ :alt: Build Status
37
+ .. image:: https://coveralls.io/repos/github/agronholm/anyio/badge.svg?branch=master
38
+ :target: https://coveralls.io/github/agronholm/anyio?branch=master
39
+ :alt: Code Coverage
40
+ .. image:: https://readthedocs.org/projects/anyio/badge/?version=latest
41
+ :target: https://anyio.readthedocs.io/en/latest/?badge=latest
42
+ :alt: Documentation
43
+ .. image:: https://badges.gitter.im/gitterHQ/gitter.svg
44
+ :target: https://gitter.im/python-trio/AnyIO
45
+ :alt: Gitter chat
46
+
47
+ AnyIO is an asynchronous networking and concurrency library that works on top of either asyncio_ or
48
+ Trio_. It implements Trio-like `structured concurrency`_ (SC) on top of asyncio and works in harmony
49
+ with the native SC of Trio itself.
50
+
51
+ Applications and libraries written against AnyIO's API will run unmodified on either asyncio_ or
52
+ Trio_. AnyIO can also be adopted into a library or application incrementally – bit by bit, no full
53
+ refactoring necessary. It will blend in with the native libraries of your chosen backend.
54
+
55
+ To find out why you might want to use AnyIO's APIs instead of asyncio's, you can read about it
56
+ `here <https://anyio.readthedocs.io/en/stable/why.html>`_.
57
+
58
+ Documentation
59
+ -------------
60
+
61
+ View full documentation at: https://anyio.readthedocs.io/
62
+
63
+ Features
64
+ --------
65
+
66
+ AnyIO offers the following functionality:
67
+
68
+ * Task groups (nurseries_ in trio terminology)
69
+ * High-level networking (TCP, UDP and UNIX sockets)
70
+
71
+ * `Happy eyeballs`_ algorithm for TCP connections (more robust than that of asyncio on Python
72
+ 3.8)
73
+ * async/await style UDP sockets (unlike asyncio where you still have to use Transports and
74
+ Protocols)
75
+
76
+ * A versatile API for byte streams and object streams
77
+ * Inter-task synchronization and communication (locks, conditions, events, semaphores, object
78
+ streams)
79
+ * Worker threads
80
+ * Subprocesses
81
+ * Subinterpreter support for code parallelization (on Python 3.13 and later)
82
+ * Asynchronous file I/O (using worker threads)
83
+ * Signal handling
84
+ * Asynchronous version of the functools_ module
85
+
86
+ AnyIO also comes with its own pytest_ plugin which also supports asynchronous fixtures.
87
+ It even works with the popular Hypothesis_ library.
88
+
89
+ .. _asyncio: https://docs.python.org/3/library/asyncio.html
90
+ .. _Trio: https://github.com/python-trio/trio
91
+ .. _structured concurrency: https://en.wikipedia.org/wiki/Structured_concurrency
92
+ .. _nurseries: https://trio.readthedocs.io/en/stable/reference-core.html#nurseries-and-spawning
93
+ .. _Happy eyeballs: https://en.wikipedia.org/wiki/Happy_Eyeballs
94
+ .. _pytest: https://docs.pytest.org/en/latest/
95
+ .. _functools: https://docs.python.org/3/library/functools.html
96
+ .. _Hypothesis: https://hypothesis.works/
venv/lib/python3.10/site-packages/anyio-4.12.1.dist-info/RECORD ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ anyio-4.12.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
2
+ anyio-4.12.1.dist-info/METADATA,sha256=DfiDab9Tmmcfy802lOLTMEHJQShkOSbopCwqCYbLuJk,4277
3
+ anyio-4.12.1.dist-info/RECORD,,
4
+ anyio-4.12.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
5
+ anyio-4.12.1.dist-info/entry_points.txt,sha256=_d6Yu6uiaZmNe0CydowirE9Cmg7zUL2g08tQpoS3Qvc,39
6
+ anyio-4.12.1.dist-info/licenses/LICENSE,sha256=U2GsncWPLvX9LpsJxoKXwX8ElQkJu8gCO9uC6s8iwrA,1081
7
+ anyio-4.12.1.dist-info/top_level.txt,sha256=QglSMiWX8_5dpoVAEIHdEYzvqFMdSYWmCj6tYw2ITkQ,6
8
+ anyio/__init__.py,sha256=7iDVqMUprUuKNY91FuoKqayAhR-OY136YDPI6P78HHk,6170
9
+ anyio/__pycache__/__init__.cpython-310.pyc,,
10
+ anyio/__pycache__/from_thread.cpython-310.pyc,,
11
+ anyio/__pycache__/functools.cpython-310.pyc,,
12
+ anyio/__pycache__/lowlevel.cpython-310.pyc,,
13
+ anyio/__pycache__/pytest_plugin.cpython-310.pyc,,
14
+ anyio/__pycache__/to_interpreter.cpython-310.pyc,,
15
+ anyio/__pycache__/to_process.cpython-310.pyc,,
16
+ anyio/__pycache__/to_thread.cpython-310.pyc,,
17
+ anyio/_backends/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
+ anyio/_backends/__pycache__/__init__.cpython-310.pyc,,
19
+ anyio/_backends/__pycache__/_asyncio.cpython-310.pyc,,
20
+ anyio/_backends/__pycache__/_trio.cpython-310.pyc,,
21
+ anyio/_backends/_asyncio.py,sha256=xG6qv60mgGnL0mK82dxjH2b8hlkMlJ-x2BqIq3qv70Y,98863
22
+ anyio/_backends/_trio.py,sha256=30Rctb7lm8g63ZHljVPVnj5aH-uK6oQvphjwUBoAzuI,41456
23
+ anyio/_core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
+ anyio/_core/__pycache__/__init__.cpython-310.pyc,,
25
+ anyio/_core/__pycache__/_asyncio_selector_thread.cpython-310.pyc,,
26
+ anyio/_core/__pycache__/_contextmanagers.cpython-310.pyc,,
27
+ anyio/_core/__pycache__/_eventloop.cpython-310.pyc,,
28
+ anyio/_core/__pycache__/_exceptions.cpython-310.pyc,,
29
+ anyio/_core/__pycache__/_fileio.cpython-310.pyc,,
30
+ anyio/_core/__pycache__/_resources.cpython-310.pyc,,
31
+ anyio/_core/__pycache__/_signals.cpython-310.pyc,,
32
+ anyio/_core/__pycache__/_sockets.cpython-310.pyc,,
33
+ anyio/_core/__pycache__/_streams.cpython-310.pyc,,
34
+ anyio/_core/__pycache__/_subprocesses.cpython-310.pyc,,
35
+ anyio/_core/__pycache__/_synchronization.cpython-310.pyc,,
36
+ anyio/_core/__pycache__/_tasks.cpython-310.pyc,,
37
+ anyio/_core/__pycache__/_tempfile.cpython-310.pyc,,
38
+ anyio/_core/__pycache__/_testing.cpython-310.pyc,,
39
+ anyio/_core/__pycache__/_typedattr.cpython-310.pyc,,
40
+ anyio/_core/_asyncio_selector_thread.py,sha256=2PdxFM3cs02Kp6BSppbvmRT7q7asreTW5FgBxEsflBo,5626
41
+ anyio/_core/_contextmanagers.py,sha256=YInBCabiEeS-UaP_Jdxa1CaFC71ETPW8HZTHIM8Rsc8,7215
42
+ anyio/_core/_eventloop.py,sha256=c2EdcBX-xnKwxPcC4Pjn3_qG9I-x4IWFO2R9RqCGjM4,6448
43
+ anyio/_core/_exceptions.py,sha256=Y3aq-Wxd7Q2HqwSg7nZPvRsHEuGazv_qeet6gqEBdPk,4407
44
+ anyio/_core/_fileio.py,sha256=uc7t10Vb-If7GbdWM_zFf-ajUe6uek63fSt7IBLlZW0,25731
45
+ anyio/_core/_resources.py,sha256=NbmU5O5UX3xEyACnkmYX28Fmwdl-f-ny0tHym26e0w0,435
46
+ anyio/_core/_signals.py,sha256=mjTBB2hTKNPRlU0IhnijeQedpWOGERDiMjSlJQsFrug,1016
47
+ anyio/_core/_sockets.py,sha256=RBXHcUqZt5gg_-OOfgHVv8uq2FSKk1uVUzTdpjBoI1o,34977
48
+ anyio/_core/_streams.py,sha256=FczFwIgDpnkK0bODWJXMpsUJYdvAD04kaUaGzJU8DK0,1806
49
+ anyio/_core/_subprocesses.py,sha256=EXm5igL7dj55iYkPlbYVAqtbqxJxjU-6OndSTIx9SRg,8047
50
+ anyio/_core/_synchronization.py,sha256=MgVVqFzvt580tHC31LiOcq1G6aryut--xRG4Ff8KwxQ,20869
51
+ anyio/_core/_tasks.py,sha256=pVB7K6AAulzUM8YgXAeqNZG44nSyZ1bYJjH8GznC00I,5435
52
+ anyio/_core/_tempfile.py,sha256=lHb7CW4FyIlpkf5ADAf4VmLHCKwEHF9nxqNyBCFFUiA,19697
53
+ anyio/_core/_testing.py,sha256=u7MPqGXwpTxqI7hclSdNA30z2GH1Nw258uwKvy_RfBg,2340
54
+ anyio/_core/_typedattr.py,sha256=P4ozZikn3-DbpoYcvyghS_FOYAgbmUxeoU8-L_07pZM,2508
55
+ anyio/abc/__init__.py,sha256=6mWhcl_pGXhrgZVHP_TCfMvIXIOp9mroEFM90fYCU_U,2869
56
+ anyio/abc/__pycache__/__init__.cpython-310.pyc,,
57
+ anyio/abc/__pycache__/_eventloop.cpython-310.pyc,,
58
+ anyio/abc/__pycache__/_resources.cpython-310.pyc,,
59
+ anyio/abc/__pycache__/_sockets.cpython-310.pyc,,
60
+ anyio/abc/__pycache__/_streams.cpython-310.pyc,,
61
+ anyio/abc/__pycache__/_subprocesses.cpython-310.pyc,,
62
+ anyio/abc/__pycache__/_tasks.cpython-310.pyc,,
63
+ anyio/abc/__pycache__/_testing.cpython-310.pyc,,
64
+ anyio/abc/_eventloop.py,sha256=GlzgB3UJGgG6Kr7olpjOZ-o00PghecXuofVDQ_5611Q,10749
65
+ anyio/abc/_resources.py,sha256=DrYvkNN1hH6Uvv5_5uKySvDsnknGVDe8FCKfko0VtN8,783
66
+ anyio/abc/_sockets.py,sha256=ECTY0jLEF18gryANHR3vFzXzGdZ-xPwELq1QdgOb0Jo,13258
67
+ anyio/abc/_streams.py,sha256=005GKSCXGprxnhucILboSqc2JFovECZk9m3p-qqxXVc,7640
68
+ anyio/abc/_subprocesses.py,sha256=cumAPJTktOQtw63IqG0lDpyZqu_l1EElvQHMiwJgL08,2067
69
+ anyio/abc/_tasks.py,sha256=KC7wrciE48AINOI-AhPutnFhe1ewfP7QnamFlDzqesQ,3721
70
+ anyio/abc/_testing.py,sha256=tBJUzkSfOXJw23fe8qSJ03kJlShOYjjaEyFB6k6MYT8,1821
71
+ anyio/from_thread.py,sha256=L-0w1HxJ6BSb-KuVi57k5Tkc3yzQrx3QK5tAxMPcY-0,19141
72
+ anyio/functools.py,sha256=HWj7GBEmc0Z-mZg3uok7Z7ZJn0rEC_0Pzbt0nYUDaTQ,10973
73
+ anyio/lowlevel.py,sha256=AyKLVK3LaWSoK39LkCKxE4_GDMLKZBNqTrLUgk63y80,5158
74
+ anyio/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
75
+ anyio/pytest_plugin.py,sha256=3jAFQn0jv_pyoWE2GBBlHaj9sqXj4e8vob0_hgrsXE8,10244
76
+ anyio/streams/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
77
+ anyio/streams/__pycache__/__init__.cpython-310.pyc,,
78
+ anyio/streams/__pycache__/buffered.cpython-310.pyc,,
79
+ anyio/streams/__pycache__/file.cpython-310.pyc,,
80
+ anyio/streams/__pycache__/memory.cpython-310.pyc,,
81
+ anyio/streams/__pycache__/stapled.cpython-310.pyc,,
82
+ anyio/streams/__pycache__/text.cpython-310.pyc,,
83
+ anyio/streams/__pycache__/tls.cpython-310.pyc,,
84
+ anyio/streams/buffered.py,sha256=2R3PeJhe4EXrdYqz44Y6-Eg9R6DrmlsYrP36Ir43-po,6263
85
+ anyio/streams/file.py,sha256=4WZ7XGz5WNu39FQHvqbe__TQ0HDP9OOhgO1mk9iVpVU,4470
86
+ anyio/streams/memory.py,sha256=F0zwzvFJKAhX_LRZGoKzzqDC2oMM-f-yyTBrEYEGOaU,10740
87
+ anyio/streams/stapled.py,sha256=T8Xqwf8K6EgURPxbt1N4i7A8BAk-gScv-GRhjLXIf_o,4390
88
+ anyio/streams/text.py,sha256=BcVAGJw1VRvtIqnv-o0Rb0pwH7p8vwlvl21xHq522ag,5765
89
+ anyio/streams/tls.py,sha256=Jpxy0Mfbcp1BxHCwE-YjSSFaLnIBbnnwur-excYThs4,15368
90
+ anyio/to_interpreter.py,sha256=_mLngrMy97TMR6VbW4Y6YzDUk9ZuPcQMPlkuyRh3C9k,7100
91
+ anyio/to_process.py,sha256=J7gAA_YOuoHqnpDAf5fm1Qu6kOmTzdFbiDNvnV755vk,9798
92
+ anyio/to_thread.py,sha256=menEgXYmUV7Fjg_9WqCV95P9MAtQS8BzPGGcWB_QnfQ,2687
venv/lib/python3.10/site-packages/anyio-4.12.1.dist-info/WHEEL ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
venv/lib/python3.10/site-packages/anyio-4.12.1.dist-info/entry_points.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ [pytest11]
2
+ anyio = anyio.pytest_plugin
venv/lib/python3.10/site-packages/anyio-4.12.1.dist-info/licenses/LICENSE ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 Alex Grönholm
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
venv/lib/python3.10/site-packages/anyio-4.12.1.dist-info/top_level.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ anyio
venv/lib/python3.10/site-packages/anyio/streams/__pycache__/memory.cpython-310.pyc ADDED
Binary file (10.2 kB). View file
 
venv/lib/python3.10/site-packages/anyio/streams/__pycache__/stapled.cpython-310.pyc ADDED
Binary file (5.52 kB). View file
 
venv/lib/python3.10/site-packages/anyio/streams/__pycache__/text.cpython-310.pyc ADDED
Binary file (7.24 kB). View file
 
venv/lib/python3.10/site-packages/anyio/streams/__pycache__/tls.cpython-310.pyc ADDED
Binary file (12.9 kB). View file
 
venv/lib/python3.10/site-packages/certifi-2026.2.25.dist-info/INSTALLER ADDED
@@ -0,0 +1 @@
 
 
1
+ pip
venv/lib/python3.10/site-packages/certifi-2026.2.25.dist-info/METADATA ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Metadata-Version: 2.4
2
+ Name: certifi
3
+ Version: 2026.2.25
4
+ Summary: Python package for providing Mozilla's CA Bundle.
5
+ Home-page: https://github.com/certifi/python-certifi
6
+ Author: Kenneth Reitz
7
+ Author-email: me@kennethreitz.com
8
+ License: MPL-2.0
9
+ Project-URL: Source, https://github.com/certifi/python-certifi
10
+ Classifier: Development Status :: 5 - Production/Stable
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)
13
+ Classifier: Natural Language :: English
14
+ Classifier: Programming Language :: Python
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3 :: Only
17
+ Classifier: Programming Language :: Python :: 3.7
18
+ Classifier: Programming Language :: Python :: 3.8
19
+ Classifier: Programming Language :: Python :: 3.9
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
24
+ Classifier: Programming Language :: Python :: 3.14
25
+ Requires-Python: >=3.7
26
+ License-File: LICENSE
27
+ Dynamic: author
28
+ Dynamic: author-email
29
+ Dynamic: classifier
30
+ Dynamic: description
31
+ Dynamic: home-page
32
+ Dynamic: license
33
+ Dynamic: license-file
34
+ Dynamic: project-url
35
+ Dynamic: requires-python
36
+ Dynamic: summary
37
+
38
+ Certifi: Python SSL Certificates
39
+ ================================
40
+
41
+ Certifi provides Mozilla's carefully curated collection of Root Certificates for
42
+ validating the trustworthiness of SSL certificates while verifying the identity
43
+ of TLS hosts. It has been extracted from the `Requests`_ project.
44
+
45
+ Installation
46
+ ------------
47
+
48
+ ``certifi`` is available on PyPI. Simply install it with ``pip``::
49
+
50
+ $ pip install certifi
51
+
52
+ Usage
53
+ -----
54
+
55
+ To reference the installed certificate authority (CA) bundle, you can use the
56
+ built-in function::
57
+
58
+ >>> import certifi
59
+
60
+ >>> certifi.where()
61
+ '/usr/local/lib/python3.7/site-packages/certifi/cacert.pem'
62
+
63
+ Or from the command line::
64
+
65
+ $ python -m certifi
66
+ /usr/local/lib/python3.7/site-packages/certifi/cacert.pem
67
+
68
+ Enjoy!
69
+
70
+ .. _`Requests`: https://requests.readthedocs.io/en/master/
71
+
72
+ Addition/Removal of Certificates
73
+ --------------------------------
74
+
75
+ Certifi does not support any addition/removal or other modification of the
76
+ CA trust store content. This project is intended to provide a reliable and
77
+ highly portable root of trust to python deployments. Look to upstream projects
78
+ for methods to use alternate trust.
venv/lib/python3.10/site-packages/certifi-2026.2.25.dist-info/RECORD ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ certifi-2026.2.25.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
2
+ certifi-2026.2.25.dist-info/METADATA,sha256=4NMuGXdg_hBiRA3paKVXYcDmE3VXEBWxTvCL2xlDyPU,2474
3
+ certifi-2026.2.25.dist-info/RECORD,,
4
+ certifi-2026.2.25.dist-info/WHEEL,sha256=YCfwYGOYMi5Jhw2fU4yNgwErybb2IX5PEwBKV4ZbdBo,91
5
+ certifi-2026.2.25.dist-info/licenses/LICENSE,sha256=6TcW2mucDVpKHfYP5pWzcPBpVgPSH2-D8FPkLPwQyvc,989
6
+ certifi-2026.2.25.dist-info/top_level.txt,sha256=KMu4vUCfsjLrkPbSNdgdekS-pVJzBAJFO__nI8NF6-U,8
7
+ certifi/__init__.py,sha256=c9eaYufv1pSLl0Q8QNcMiMLLH4WquDcxdPyKjmI4opY,94
8
+ certifi/__main__.py,sha256=xBBoj905TUWBLRGANOcf7oi6e-3dMP4cEoG9OyMs11g,243
9
+ certifi/__pycache__/__init__.cpython-310.pyc,,
10
+ certifi/__pycache__/__main__.cpython-310.pyc,,
11
+ certifi/__pycache__/core.cpython-310.pyc,,
12
+ certifi/cacert.pem,sha256=_JFloSQDJj5-v72te-ej6sD6XTJdPHBGXyjTaQByyig,272441
13
+ certifi/core.py,sha256=XFXycndG5pf37ayeF8N32HUuDafsyhkVMbO4BAPWHa0,3394
14
+ certifi/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
venv/lib/python3.10/site-packages/certifi-2026.2.25.dist-info/WHEEL ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
venv/lib/python3.10/site-packages/certifi-2026.2.25.dist-info/licenses/LICENSE ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ This package contains a modified version of ca-bundle.crt:
2
+
3
+ ca-bundle.crt -- Bundle of CA Root Certificates
4
+
5
+ This is a bundle of X.509 certificates of public Certificate Authorities
6
+ (CA). These were automatically extracted from Mozilla's root certificates
7
+ file (certdata.txt). This file can be found in the mozilla source tree:
8
+ https://hg.mozilla.org/mozilla-central/file/tip/security/nss/lib/ckfw/builtins/certdata.txt
9
+ It contains the certificates in PEM format and therefore
10
+ can be directly used with curl / libcurl / php_curl, or with
11
+ an Apache+mod_ssl webserver for SSL client authentication.
12
+ Just configure this file as the SSLCACertificateFile.#
13
+
14
+ ***** BEGIN LICENSE BLOCK *****
15
+ This Source Code Form is subject to the terms of the Mozilla Public License,
16
+ v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain
17
+ one at http://mozilla.org/MPL/2.0/.
18
+
19
+ ***** END LICENSE BLOCK *****
20
+ @(#) $RCSfile: certdata.txt,v $ $Revision: 1.80 $ $Date: 2011/11/03 15:11:58 $
venv/lib/python3.10/site-packages/certifi-2026.2.25.dist-info/top_level.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ certifi
venv/lib/python3.10/site-packages/certifi/__init__.py ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ from .core import contents, where
2
+
3
+ __all__ = ["contents", "where"]
4
+ __version__ = "2026.02.25"
venv/lib/python3.10/site-packages/certifi/__main__.py ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import argparse
2
+
3
+ from certifi import contents, where
4
+
5
+ parser = argparse.ArgumentParser()
6
+ parser.add_argument("-c", "--contents", action="store_true")
7
+ args = parser.parse_args()
8
+
9
+ if args.contents:
10
+ print(contents())
11
+ else:
12
+ print(where())
venv/lib/python3.10/site-packages/certifi/__pycache__/__init__.cpython-310.pyc ADDED
Binary file (391 Bytes). View file
 
venv/lib/python3.10/site-packages/certifi/__pycache__/__main__.cpython-310.pyc ADDED
Binary file (529 Bytes). View file
 
venv/lib/python3.10/site-packages/certifi/__pycache__/core.cpython-310.pyc ADDED
Binary file (1.5 kB). View file
 
venv/lib/python3.10/site-packages/certifi/cacert.pem ADDED
The diff for this file is too large to render. See raw diff
 
venv/lib/python3.10/site-packages/certifi/core.py ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ certifi.py
3
+ ~~~~~~~~~~
4
+
5
+ This module returns the installation location of cacert.pem or its contents.
6
+ """
7
+ import sys
8
+ import atexit
9
+
10
+ def exit_cacert_ctx() -> None:
11
+ _CACERT_CTX.__exit__(None, None, None) # type: ignore[union-attr]
12
+
13
+
14
+ if sys.version_info >= (3, 11):
15
+
16
+ from importlib.resources import as_file, files
17
+
18
+ _CACERT_CTX = None
19
+ _CACERT_PATH = None
20
+
21
+ def where() -> str:
22
+ # This is slightly terrible, but we want to delay extracting the file
23
+ # in cases where we're inside of a zipimport situation until someone
24
+ # actually calls where(), but we don't want to re-extract the file
25
+ # on every call of where(), so we'll do it once then store it in a
26
+ # global variable.
27
+ global _CACERT_CTX
28
+ global _CACERT_PATH
29
+ if _CACERT_PATH is None:
30
+ # This is slightly janky, the importlib.resources API wants you to
31
+ # manage the cleanup of this file, so it doesn't actually return a
32
+ # path, it returns a context manager that will give you the path
33
+ # when you enter it and will do any cleanup when you leave it. In
34
+ # the common case of not needing a temporary file, it will just
35
+ # return the file system location and the __exit__() is a no-op.
36
+ #
37
+ # We also have to hold onto the actual context manager, because
38
+ # it will do the cleanup whenever it gets garbage collected, so
39
+ # we will also store that at the global level as well.
40
+ _CACERT_CTX = as_file(files("certifi").joinpath("cacert.pem"))
41
+ _CACERT_PATH = str(_CACERT_CTX.__enter__())
42
+ atexit.register(exit_cacert_ctx)
43
+
44
+ return _CACERT_PATH
45
+
46
+ def contents() -> str:
47
+ return files("certifi").joinpath("cacert.pem").read_text(encoding="ascii")
48
+
49
+ else:
50
+
51
+ from importlib.resources import path as get_path, read_text
52
+
53
+ _CACERT_CTX = None
54
+ _CACERT_PATH = None
55
+
56
+ def where() -> str:
57
+ # This is slightly terrible, but we want to delay extracting the
58
+ # file in cases where we're inside of a zipimport situation until
59
+ # someone actually calls where(), but we don't want to re-extract
60
+ # the file on every call of where(), so we'll do it once then store
61
+ # it in a global variable.
62
+ global _CACERT_CTX
63
+ global _CACERT_PATH
64
+ if _CACERT_PATH is None:
65
+ # This is slightly janky, the importlib.resources API wants you
66
+ # to manage the cleanup of this file, so it doesn't actually
67
+ # return a path, it returns a context manager that will give
68
+ # you the path when you enter it and will do any cleanup when
69
+ # you leave it. In the common case of not needing a temporary
70
+ # file, it will just return the file system location and the
71
+ # __exit__() is a no-op.
72
+ #
73
+ # We also have to hold onto the actual context manager, because
74
+ # it will do the cleanup whenever it gets garbage collected, so
75
+ # we will also store that at the global level as well.
76
+ _CACERT_CTX = get_path("certifi", "cacert.pem")
77
+ _CACERT_PATH = str(_CACERT_CTX.__enter__())
78
+ atexit.register(exit_cacert_ctx)
79
+
80
+ return _CACERT_PATH
81
+
82
+ def contents() -> str:
83
+ return read_text("certifi", "cacert.pem", encoding="ascii")
venv/lib/python3.10/site-packages/certifi/py.typed ADDED
File without changes
venv/lib/python3.10/site-packages/click-8.3.1.dist-info/INSTALLER ADDED
@@ -0,0 +1 @@
 
 
1
+ pip
venv/lib/python3.10/site-packages/click-8.3.1.dist-info/METADATA ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Metadata-Version: 2.4
2
+ Name: click
3
+ Version: 8.3.1
4
+ Summary: Composable command line interface toolkit
5
+ Maintainer-email: Pallets <contact@palletsprojects.com>
6
+ Requires-Python: >=3.10
7
+ Description-Content-Type: text/markdown
8
+ License-Expression: BSD-3-Clause
9
+ Classifier: Development Status :: 5 - Production/Stable
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Programming Language :: Python
13
+ Classifier: Typing :: Typed
14
+ License-File: LICENSE.txt
15
+ Requires-Dist: colorama; platform_system == 'Windows'
16
+ Project-URL: Changes, https://click.palletsprojects.com/page/changes/
17
+ Project-URL: Chat, https://discord.gg/pallets
18
+ Project-URL: Documentation, https://click.palletsprojects.com/
19
+ Project-URL: Donate, https://palletsprojects.com/donate
20
+ Project-URL: Source, https://github.com/pallets/click/
21
+
22
+ <div align="center"><img src="https://raw.githubusercontent.com/pallets/click/refs/heads/stable/docs/_static/click-name.svg" alt="" height="150"></div>
23
+
24
+ # Click
25
+
26
+ Click is a Python package for creating beautiful command line interfaces
27
+ in a composable way with as little code as necessary. It's the "Command
28
+ Line Interface Creation Kit". It's highly configurable but comes with
29
+ sensible defaults out of the box.
30
+
31
+ It aims to make the process of writing command line tools quick and fun
32
+ while also preventing any frustration caused by the inability to
33
+ implement an intended CLI API.
34
+
35
+ Click in three points:
36
+
37
+ - Arbitrary nesting of commands
38
+ - Automatic help page generation
39
+ - Supports lazy loading of subcommands at runtime
40
+
41
+
42
+ ## A Simple Example
43
+
44
+ ```python
45
+ import click
46
+
47
+ @click.command()
48
+ @click.option("--count", default=1, help="Number of greetings.")
49
+ @click.option("--name", prompt="Your name", help="The person to greet.")
50
+ def hello(count, name):
51
+ """Simple program that greets NAME for a total of COUNT times."""
52
+ for _ in range(count):
53
+ click.echo(f"Hello, {name}!")
54
+
55
+ if __name__ == '__main__':
56
+ hello()
57
+ ```
58
+
59
+ ```
60
+ $ python hello.py --count=3
61
+ Your name: Click
62
+ Hello, Click!
63
+ Hello, Click!
64
+ Hello, Click!
65
+ ```
66
+
67
+
68
+ ## Donate
69
+
70
+ The Pallets organization develops and supports Click and other popular
71
+ packages. In order to grow the community of contributors and users, and
72
+ allow the maintainers to devote more time to the projects, [please
73
+ donate today][].
74
+
75
+ [please donate today]: https://palletsprojects.com/donate
76
+
77
+ ## Contributing
78
+
79
+ See our [detailed contributing documentation][contrib] for many ways to
80
+ contribute, including reporting issues, requesting features, asking or answering
81
+ questions, and making PRs.
82
+
83
+ [contrib]: https://palletsprojects.com/contributing/
84
+
venv/lib/python3.10/site-packages/click-8.3.1.dist-info/RECORD ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ click-8.3.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
2
+ click-8.3.1.dist-info/METADATA,sha256=XZeBrMAE0ghTE88SjfrSDuSyNCpBPplxJR1tbwD9oZg,2621
3
+ click-8.3.1.dist-info/RECORD,,
4
+ click-8.3.1.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
5
+ click-8.3.1.dist-info/licenses/LICENSE.txt,sha256=morRBqOU6FO_4h9C9OctWSgZoigF2ZG18ydQKSkrZY0,1475
6
+ click/__init__.py,sha256=6YyS1aeyknZ0LYweWozNZy0A9nZ_11wmYIhv3cbQrYo,4473
7
+ click/__pycache__/__init__.cpython-310.pyc,,
8
+ click/__pycache__/_compat.cpython-310.pyc,,
9
+ click/__pycache__/_termui_impl.cpython-310.pyc,,
10
+ click/__pycache__/_textwrap.cpython-310.pyc,,
11
+ click/__pycache__/_utils.cpython-310.pyc,,
12
+ click/__pycache__/_winconsole.cpython-310.pyc,,
13
+ click/__pycache__/core.cpython-310.pyc,,
14
+ click/__pycache__/decorators.cpython-310.pyc,,
15
+ click/__pycache__/exceptions.cpython-310.pyc,,
16
+ click/__pycache__/formatting.cpython-310.pyc,,
17
+ click/__pycache__/globals.cpython-310.pyc,,
18
+ click/__pycache__/parser.cpython-310.pyc,,
19
+ click/__pycache__/shell_completion.cpython-310.pyc,,
20
+ click/__pycache__/termui.cpython-310.pyc,,
21
+ click/__pycache__/testing.cpython-310.pyc,,
22
+ click/__pycache__/types.cpython-310.pyc,,
23
+ click/__pycache__/utils.cpython-310.pyc,,
24
+ click/_compat.py,sha256=v3xBZkFbvA1BXPRkFfBJc6-pIwPI7345m-kQEnpVAs4,18693
25
+ click/_termui_impl.py,sha256=rgCb3On8X5A4200rA5L6i13u5iapmFer7sru57Jy6zA,27093
26
+ click/_textwrap.py,sha256=BOae0RQ6vg3FkNgSJyOoGzG1meGMxJ_ukWVZKx_v-0o,1400
27
+ click/_utils.py,sha256=kZwtTf5gMuCilJJceS2iTCvRvCY-0aN5rJq8gKw7p8g,943
28
+ click/_winconsole.py,sha256=_vxUuUaxwBhoR0vUWCNuHY8VUefiMdCIyU2SXPqoF-A,8465
29
+ click/core.py,sha256=U6Bfxt8GkjNDqyJ0HqXvluJHtyZ4sY5USAvM1Cdq7mQ,132105
30
+ click/decorators.py,sha256=5P7abhJtAQYp_KHgjUvhMv464ERwOzrv2enNknlwHyQ,18461
31
+ click/exceptions.py,sha256=8utf8w6V5hJXMnO_ic1FNrtbwuEn1NUu1aDwV8UqnG4,9954
32
+ click/formatting.py,sha256=RVfwwr0rwWNpgGr8NaHodPzkIr7_tUyVh_nDdanLMNc,9730
33
+ click/globals.py,sha256=gM-Nh6A4M0HB_SgkaF5M4ncGGMDHc_flHXu9_oh4GEU,1923
34
+ click/parser.py,sha256=Q31pH0FlQZEq-UXE_ABRzlygEfvxPTuZbWNh4xfXmzw,19010
35
+ click/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
36
+ click/shell_completion.py,sha256=Cc4GQUFuWpfQBa9sF5qXeeYI7n3tI_1k6ZdSn4BZbT0,20994
37
+ click/termui.py,sha256=hqCEjNndU-nzW08nRAkBaVgfZp_FdCA9KxfIWlKYaMc,31037
38
+ click/testing.py,sha256=EERbzcl1br0mW0qBS9EqkknfNfXB9WQEW0ELIpkvuSs,19102
39
+ click/types.py,sha256=ek54BNSFwPKsqtfT7jsqcc4WHui8AIFVMKM4oVZIXhc,39927
40
+ click/utils.py,sha256=gCUoewdAhA-QLBUUHxrLh4uj6m7T1WjZZMNPvR0I7YA,20257
venv/lib/python3.10/site-packages/click-8.3.1.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
venv/lib/python3.10/site-packages/click-8.3.1.dist-info/licenses/LICENSE.txt ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright 2014 Pallets
2
+
3
+ Redistribution and use in source and binary forms, with or without
4
+ modification, are permitted provided that the following conditions are
5
+ met:
6
+
7
+ 1. Redistributions of source code must retain the above copyright
8
+ notice, this list of conditions and the following disclaimer.
9
+
10
+ 2. Redistributions in binary form must reproduce the above copyright
11
+ notice, this list of conditions and the following disclaimer in the
12
+ documentation and/or other materials provided with the distribution.
13
+
14
+ 3. Neither the name of the copyright holder nor the names of its
15
+ contributors may be used to endorse or promote products derived from
16
+ this software without specific prior written permission.
17
+
18
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
21
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
+ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
24
+ TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
venv/lib/python3.10/site-packages/click/__init__.py ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Click is a simple Python module inspired by the stdlib optparse to make
3
+ writing command line scripts fun. Unlike other modules, it's based
4
+ around a simple API that does not come with too much magic and is
5
+ composable.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from .core import Argument as Argument
11
+ from .core import Command as Command
12
+ from .core import CommandCollection as CommandCollection
13
+ from .core import Context as Context
14
+ from .core import Group as Group
15
+ from .core import Option as Option
16
+ from .core import Parameter as Parameter
17
+ from .decorators import argument as argument
18
+ from .decorators import command as command
19
+ from .decorators import confirmation_option as confirmation_option
20
+ from .decorators import group as group
21
+ from .decorators import help_option as help_option
22
+ from .decorators import make_pass_decorator as make_pass_decorator
23
+ from .decorators import option as option
24
+ from .decorators import pass_context as pass_context
25
+ from .decorators import pass_obj as pass_obj
26
+ from .decorators import password_option as password_option
27
+ from .decorators import version_option as version_option
28
+ from .exceptions import Abort as Abort
29
+ from .exceptions import BadArgumentUsage as BadArgumentUsage
30
+ from .exceptions import BadOptionUsage as BadOptionUsage
31
+ from .exceptions import BadParameter as BadParameter
32
+ from .exceptions import ClickException as ClickException
33
+ from .exceptions import FileError as FileError
34
+ from .exceptions import MissingParameter as MissingParameter
35
+ from .exceptions import NoSuchOption as NoSuchOption
36
+ from .exceptions import UsageError as UsageError
37
+ from .formatting import HelpFormatter as HelpFormatter
38
+ from .formatting import wrap_text as wrap_text
39
+ from .globals import get_current_context as get_current_context
40
+ from .termui import clear as clear
41
+ from .termui import confirm as confirm
42
+ from .termui import echo_via_pager as echo_via_pager
43
+ from .termui import edit as edit
44
+ from .termui import getchar as getchar
45
+ from .termui import launch as launch
46
+ from .termui import pause as pause
47
+ from .termui import progressbar as progressbar
48
+ from .termui import prompt as prompt
49
+ from .termui import secho as secho
50
+ from .termui import style as style
51
+ from .termui import unstyle as unstyle
52
+ from .types import BOOL as BOOL
53
+ from .types import Choice as Choice
54
+ from .types import DateTime as DateTime
55
+ from .types import File as File
56
+ from .types import FLOAT as FLOAT
57
+ from .types import FloatRange as FloatRange
58
+ from .types import INT as INT
59
+ from .types import IntRange as IntRange
60
+ from .types import ParamType as ParamType
61
+ from .types import Path as Path
62
+ from .types import STRING as STRING
63
+ from .types import Tuple as Tuple
64
+ from .types import UNPROCESSED as UNPROCESSED
65
+ from .types import UUID as UUID
66
+ from .utils import echo as echo
67
+ from .utils import format_filename as format_filename
68
+ from .utils import get_app_dir as get_app_dir
69
+ from .utils import get_binary_stream as get_binary_stream
70
+ from .utils import get_text_stream as get_text_stream
71
+ from .utils import open_file as open_file
72
+
73
+
74
+ def __getattr__(name: str) -> object:
75
+ import warnings
76
+
77
+ if name == "BaseCommand":
78
+ from .core import _BaseCommand
79
+
80
+ warnings.warn(
81
+ "'BaseCommand' is deprecated and will be removed in Click 9.0. Use"
82
+ " 'Command' instead.",
83
+ DeprecationWarning,
84
+ stacklevel=2,
85
+ )
86
+ return _BaseCommand
87
+
88
+ if name == "MultiCommand":
89
+ from .core import _MultiCommand
90
+
91
+ warnings.warn(
92
+ "'MultiCommand' is deprecated and will be removed in Click 9.0. Use"
93
+ " 'Group' instead.",
94
+ DeprecationWarning,
95
+ stacklevel=2,
96
+ )
97
+ return _MultiCommand
98
+
99
+ if name == "OptionParser":
100
+ from .parser import _OptionParser
101
+
102
+ warnings.warn(
103
+ "'OptionParser' is deprecated and will be removed in Click 9.0. The"
104
+ " old parser is available in 'optparse'.",
105
+ DeprecationWarning,
106
+ stacklevel=2,
107
+ )
108
+ return _OptionParser
109
+
110
+ if name == "__version__":
111
+ import importlib.metadata
112
+ import warnings
113
+
114
+ warnings.warn(
115
+ "The '__version__' attribute is deprecated and will be removed in"
116
+ " Click 9.1. Use feature detection or"
117
+ " 'importlib.metadata.version(\"click\")' instead.",
118
+ DeprecationWarning,
119
+ stacklevel=2,
120
+ )
121
+ return importlib.metadata.version("click")
122
+
123
+ raise AttributeError(name)
venv/lib/python3.10/site-packages/click/__pycache__/__init__.cpython-310.pyc ADDED
Binary file (3.76 kB). View file
 
venv/lib/python3.10/site-packages/click/__pycache__/_compat.cpython-310.pyc ADDED
Binary file (16.1 kB). View file
 
venv/lib/python3.10/site-packages/click/__pycache__/_termui_impl.cpython-310.pyc ADDED
Binary file (18.2 kB). View file
 
venv/lib/python3.10/site-packages/click/__pycache__/_textwrap.cpython-310.pyc ADDED
Binary file (1.76 kB). View file
 
venv/lib/python3.10/site-packages/click/__pycache__/_utils.cpython-310.pyc ADDED
Binary file (1.01 kB). View file
 
venv/lib/python3.10/site-packages/click/__pycache__/_winconsole.cpython-310.pyc ADDED
Binary file (8.37 kB). View file
 
venv/lib/python3.10/site-packages/click/__pycache__/core.cpython-310.pyc ADDED
Binary file (98.7 kB). View file
 
venv/lib/python3.10/site-packages/click/__pycache__/decorators.cpython-310.pyc ADDED
Binary file (17.7 kB). View file
 
venv/lib/python3.10/site-packages/click/__pycache__/exceptions.cpython-310.pyc ADDED
Binary file (11.1 kB). View file
 
venv/lib/python3.10/site-packages/click/__pycache__/formatting.cpython-310.pyc ADDED
Binary file (9.8 kB). View file
 
venv/lib/python3.10/site-packages/click/__pycache__/globals.cpython-310.pyc ADDED
Binary file (2.58 kB). View file
 
venv/lib/python3.10/site-packages/click/__pycache__/parser.cpython-310.pyc ADDED
Binary file (14.3 kB). View file
 
venv/lib/python3.10/site-packages/click/__pycache__/shell_completion.cpython-310.pyc ADDED
Binary file (18.4 kB). View file
 
venv/lib/python3.10/site-packages/click/__pycache__/termui.cpython-310.pyc ADDED
Binary file (29.1 kB). View file
 
venv/lib/python3.10/site-packages/click/__pycache__/testing.cpython-310.pyc ADDED
Binary file (19.3 kB). View file
 
venv/lib/python3.10/site-packages/click/__pycache__/types.cpython-310.pyc ADDED
Binary file (37.4 kB). View file
 
venv/lib/python3.10/site-packages/click/__pycache__/utils.cpython-310.pyc ADDED
Binary file (19.2 kB). View file
 
venv/lib/python3.10/site-packages/click/_compat.py ADDED
@@ -0,0 +1,622 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import codecs
4
+ import collections.abc as cabc
5
+ import io
6
+ import os
7
+ import re
8
+ import sys
9
+ import typing as t
10
+ from types import TracebackType
11
+ from weakref import WeakKeyDictionary
12
+
13
+ CYGWIN = sys.platform.startswith("cygwin")
14
+ WIN = sys.platform.startswith("win")
15
+ auto_wrap_for_ansi: t.Callable[[t.TextIO], t.TextIO] | None = None
16
+ _ansi_re = re.compile(r"\033\[[;?0-9]*[a-zA-Z]")
17
+
18
+
19
+ def _make_text_stream(
20
+ stream: t.BinaryIO,
21
+ encoding: str | None,
22
+ errors: str | None,
23
+ force_readable: bool = False,
24
+ force_writable: bool = False,
25
+ ) -> t.TextIO:
26
+ if encoding is None:
27
+ encoding = get_best_encoding(stream)
28
+ if errors is None:
29
+ errors = "replace"
30
+ return _NonClosingTextIOWrapper(
31
+ stream,
32
+ encoding,
33
+ errors,
34
+ line_buffering=True,
35
+ force_readable=force_readable,
36
+ force_writable=force_writable,
37
+ )
38
+
39
+
40
+ def is_ascii_encoding(encoding: str) -> bool:
41
+ """Checks if a given encoding is ascii."""
42
+ try:
43
+ return codecs.lookup(encoding).name == "ascii"
44
+ except LookupError:
45
+ return False
46
+
47
+
48
+ def get_best_encoding(stream: t.IO[t.Any]) -> str:
49
+ """Returns the default stream encoding if not found."""
50
+ rv = getattr(stream, "encoding", None) or sys.getdefaultencoding()
51
+ if is_ascii_encoding(rv):
52
+ return "utf-8"
53
+ return rv
54
+
55
+
56
+ class _NonClosingTextIOWrapper(io.TextIOWrapper):
57
+ def __init__(
58
+ self,
59
+ stream: t.BinaryIO,
60
+ encoding: str | None,
61
+ errors: str | None,
62
+ force_readable: bool = False,
63
+ force_writable: bool = False,
64
+ **extra: t.Any,
65
+ ) -> None:
66
+ self._stream = stream = t.cast(
67
+ t.BinaryIO, _FixupStream(stream, force_readable, force_writable)
68
+ )
69
+ super().__init__(stream, encoding, errors, **extra)
70
+
71
+ def __del__(self) -> None:
72
+ try:
73
+ self.detach()
74
+ except Exception:
75
+ pass
76
+
77
+ def isatty(self) -> bool:
78
+ # https://bitbucket.org/pypy/pypy/issue/1803
79
+ return self._stream.isatty()
80
+
81
+
82
+ class _FixupStream:
83
+ """The new io interface needs more from streams than streams
84
+ traditionally implement. As such, this fix-up code is necessary in
85
+ some circumstances.
86
+
87
+ The forcing of readable and writable flags are there because some tools
88
+ put badly patched objects on sys (one such offender are certain version
89
+ of jupyter notebook).
90
+ """
91
+
92
+ def __init__(
93
+ self,
94
+ stream: t.BinaryIO,
95
+ force_readable: bool = False,
96
+ force_writable: bool = False,
97
+ ):
98
+ self._stream = stream
99
+ self._force_readable = force_readable
100
+ self._force_writable = force_writable
101
+
102
+ def __getattr__(self, name: str) -> t.Any:
103
+ return getattr(self._stream, name)
104
+
105
+ def read1(self, size: int) -> bytes:
106
+ f = getattr(self._stream, "read1", None)
107
+
108
+ if f is not None:
109
+ return t.cast(bytes, f(size))
110
+
111
+ return self._stream.read(size)
112
+
113
+ def readable(self) -> bool:
114
+ if self._force_readable:
115
+ return True
116
+ x = getattr(self._stream, "readable", None)
117
+ if x is not None:
118
+ return t.cast(bool, x())
119
+ try:
120
+ self._stream.read(0)
121
+ except Exception:
122
+ return False
123
+ return True
124
+
125
+ def writable(self) -> bool:
126
+ if self._force_writable:
127
+ return True
128
+ x = getattr(self._stream, "writable", None)
129
+ if x is not None:
130
+ return t.cast(bool, x())
131
+ try:
132
+ self._stream.write(b"")
133
+ except Exception:
134
+ try:
135
+ self._stream.write(b"")
136
+ except Exception:
137
+ return False
138
+ return True
139
+
140
+ def seekable(self) -> bool:
141
+ x = getattr(self._stream, "seekable", None)
142
+ if x is not None:
143
+ return t.cast(bool, x())
144
+ try:
145
+ self._stream.seek(self._stream.tell())
146
+ except Exception:
147
+ return False
148
+ return True
149
+
150
+
151
+ def _is_binary_reader(stream: t.IO[t.Any], default: bool = False) -> bool:
152
+ try:
153
+ return isinstance(stream.read(0), bytes)
154
+ except Exception:
155
+ return default
156
+ # This happens in some cases where the stream was already
157
+ # closed. In this case, we assume the default.
158
+
159
+
160
+ def _is_binary_writer(stream: t.IO[t.Any], default: bool = False) -> bool:
161
+ try:
162
+ stream.write(b"")
163
+ except Exception:
164
+ try:
165
+ stream.write("")
166
+ return False
167
+ except Exception:
168
+ pass
169
+ return default
170
+ return True
171
+
172
+
173
+ def _find_binary_reader(stream: t.IO[t.Any]) -> t.BinaryIO | None:
174
+ # We need to figure out if the given stream is already binary.
175
+ # This can happen because the official docs recommend detaching
176
+ # the streams to get binary streams. Some code might do this, so
177
+ # we need to deal with this case explicitly.
178
+ if _is_binary_reader(stream, False):
179
+ return t.cast(t.BinaryIO, stream)
180
+
181
+ buf = getattr(stream, "buffer", None)
182
+
183
+ # Same situation here; this time we assume that the buffer is
184
+ # actually binary in case it's closed.
185
+ if buf is not None and _is_binary_reader(buf, True):
186
+ return t.cast(t.BinaryIO, buf)
187
+
188
+ return None
189
+
190
+
191
+ def _find_binary_writer(stream: t.IO[t.Any]) -> t.BinaryIO | None:
192
+ # We need to figure out if the given stream is already binary.
193
+ # This can happen because the official docs recommend detaching
194
+ # the streams to get binary streams. Some code might do this, so
195
+ # we need to deal with this case explicitly.
196
+ if _is_binary_writer(stream, False):
197
+ return t.cast(t.BinaryIO, stream)
198
+
199
+ buf = getattr(stream, "buffer", None)
200
+
201
+ # Same situation here; this time we assume that the buffer is
202
+ # actually binary in case it's closed.
203
+ if buf is not None and _is_binary_writer(buf, True):
204
+ return t.cast(t.BinaryIO, buf)
205
+
206
+ return None
207
+
208
+
209
+ def _stream_is_misconfigured(stream: t.TextIO) -> bool:
210
+ """A stream is misconfigured if its encoding is ASCII."""
211
+ # If the stream does not have an encoding set, we assume it's set
212
+ # to ASCII. This appears to happen in certain unittest
213
+ # environments. It's not quite clear what the correct behavior is
214
+ # but this at least will force Click to recover somehow.
215
+ return is_ascii_encoding(getattr(stream, "encoding", None) or "ascii")
216
+
217
+
218
+ def _is_compat_stream_attr(stream: t.TextIO, attr: str, value: str | None) -> bool:
219
+ """A stream attribute is compatible if it is equal to the
220
+ desired value or the desired value is unset and the attribute
221
+ has a value.
222
+ """
223
+ stream_value = getattr(stream, attr, None)
224
+ return stream_value == value or (value is None and stream_value is not None)
225
+
226
+
227
+ def _is_compatible_text_stream(
228
+ stream: t.TextIO, encoding: str | None, errors: str | None
229
+ ) -> bool:
230
+ """Check if a stream's encoding and errors attributes are
231
+ compatible with the desired values.
232
+ """
233
+ return _is_compat_stream_attr(
234
+ stream, "encoding", encoding
235
+ ) and _is_compat_stream_attr(stream, "errors", errors)
236
+
237
+
238
+ def _force_correct_text_stream(
239
+ text_stream: t.IO[t.Any],
240
+ encoding: str | None,
241
+ errors: str | None,
242
+ is_binary: t.Callable[[t.IO[t.Any], bool], bool],
243
+ find_binary: t.Callable[[t.IO[t.Any]], t.BinaryIO | None],
244
+ force_readable: bool = False,
245
+ force_writable: bool = False,
246
+ ) -> t.TextIO:
247
+ if is_binary(text_stream, False):
248
+ binary_reader = t.cast(t.BinaryIO, text_stream)
249
+ else:
250
+ text_stream = t.cast(t.TextIO, text_stream)
251
+ # If the stream looks compatible, and won't default to a
252
+ # misconfigured ascii encoding, return it as-is.
253
+ if _is_compatible_text_stream(text_stream, encoding, errors) and not (
254
+ encoding is None and _stream_is_misconfigured(text_stream)
255
+ ):
256
+ return text_stream
257
+
258
+ # Otherwise, get the underlying binary reader.
259
+ possible_binary_reader = find_binary(text_stream)
260
+
261
+ # If that's not possible, silently use the original reader
262
+ # and get mojibake instead of exceptions.
263
+ if possible_binary_reader is None:
264
+ return text_stream
265
+
266
+ binary_reader = possible_binary_reader
267
+
268
+ # Default errors to replace instead of strict in order to get
269
+ # something that works.
270
+ if errors is None:
271
+ errors = "replace"
272
+
273
+ # Wrap the binary stream in a text stream with the correct
274
+ # encoding parameters.
275
+ return _make_text_stream(
276
+ binary_reader,
277
+ encoding,
278
+ errors,
279
+ force_readable=force_readable,
280
+ force_writable=force_writable,
281
+ )
282
+
283
+
284
+ def _force_correct_text_reader(
285
+ text_reader: t.IO[t.Any],
286
+ encoding: str | None,
287
+ errors: str | None,
288
+ force_readable: bool = False,
289
+ ) -> t.TextIO:
290
+ return _force_correct_text_stream(
291
+ text_reader,
292
+ encoding,
293
+ errors,
294
+ _is_binary_reader,
295
+ _find_binary_reader,
296
+ force_readable=force_readable,
297
+ )
298
+
299
+
300
+ def _force_correct_text_writer(
301
+ text_writer: t.IO[t.Any],
302
+ encoding: str | None,
303
+ errors: str | None,
304
+ force_writable: bool = False,
305
+ ) -> t.TextIO:
306
+ return _force_correct_text_stream(
307
+ text_writer,
308
+ encoding,
309
+ errors,
310
+ _is_binary_writer,
311
+ _find_binary_writer,
312
+ force_writable=force_writable,
313
+ )
314
+
315
+
316
+ def get_binary_stdin() -> t.BinaryIO:
317
+ reader = _find_binary_reader(sys.stdin)
318
+ if reader is None:
319
+ raise RuntimeError("Was not able to determine binary stream for sys.stdin.")
320
+ return reader
321
+
322
+
323
+ def get_binary_stdout() -> t.BinaryIO:
324
+ writer = _find_binary_writer(sys.stdout)
325
+ if writer is None:
326
+ raise RuntimeError("Was not able to determine binary stream for sys.stdout.")
327
+ return writer
328
+
329
+
330
+ def get_binary_stderr() -> t.BinaryIO:
331
+ writer = _find_binary_writer(sys.stderr)
332
+ if writer is None:
333
+ raise RuntimeError("Was not able to determine binary stream for sys.stderr.")
334
+ return writer
335
+
336
+
337
+ def get_text_stdin(encoding: str | None = None, errors: str | None = None) -> t.TextIO:
338
+ rv = _get_windows_console_stream(sys.stdin, encoding, errors)
339
+ if rv is not None:
340
+ return rv
341
+ return _force_correct_text_reader(sys.stdin, encoding, errors, force_readable=True)
342
+
343
+
344
+ def get_text_stdout(encoding: str | None = None, errors: str | None = None) -> t.TextIO:
345
+ rv = _get_windows_console_stream(sys.stdout, encoding, errors)
346
+ if rv is not None:
347
+ return rv
348
+ return _force_correct_text_writer(sys.stdout, encoding, errors, force_writable=True)
349
+
350
+
351
+ def get_text_stderr(encoding: str | None = None, errors: str | None = None) -> t.TextIO:
352
+ rv = _get_windows_console_stream(sys.stderr, encoding, errors)
353
+ if rv is not None:
354
+ return rv
355
+ return _force_correct_text_writer(sys.stderr, encoding, errors, force_writable=True)
356
+
357
+
358
+ def _wrap_io_open(
359
+ file: str | os.PathLike[str] | int,
360
+ mode: str,
361
+ encoding: str | None,
362
+ errors: str | None,
363
+ ) -> t.IO[t.Any]:
364
+ """Handles not passing ``encoding`` and ``errors`` in binary mode."""
365
+ if "b" in mode:
366
+ return open(file, mode)
367
+
368
+ return open(file, mode, encoding=encoding, errors=errors)
369
+
370
+
371
+ def open_stream(
372
+ filename: str | os.PathLike[str],
373
+ mode: str = "r",
374
+ encoding: str | None = None,
375
+ errors: str | None = "strict",
376
+ atomic: bool = False,
377
+ ) -> tuple[t.IO[t.Any], bool]:
378
+ binary = "b" in mode
379
+ filename = os.fspath(filename)
380
+
381
+ # Standard streams first. These are simple because they ignore the
382
+ # atomic flag. Use fsdecode to handle Path("-").
383
+ if os.fsdecode(filename) == "-":
384
+ if any(m in mode for m in ["w", "a", "x"]):
385
+ if binary:
386
+ return get_binary_stdout(), False
387
+ return get_text_stdout(encoding=encoding, errors=errors), False
388
+ if binary:
389
+ return get_binary_stdin(), False
390
+ return get_text_stdin(encoding=encoding, errors=errors), False
391
+
392
+ # Non-atomic writes directly go out through the regular open functions.
393
+ if not atomic:
394
+ return _wrap_io_open(filename, mode, encoding, errors), True
395
+
396
+ # Some usability stuff for atomic writes
397
+ if "a" in mode:
398
+ raise ValueError(
399
+ "Appending to an existing file is not supported, because that"
400
+ " would involve an expensive `copy`-operation to a temporary"
401
+ " file. Open the file in normal `w`-mode and copy explicitly"
402
+ " if that's what you're after."
403
+ )
404
+ if "x" in mode:
405
+ raise ValueError("Use the `overwrite`-parameter instead.")
406
+ if "w" not in mode:
407
+ raise ValueError("Atomic writes only make sense with `w`-mode.")
408
+
409
+ # Atomic writes are more complicated. They work by opening a file
410
+ # as a proxy in the same folder and then using the fdopen
411
+ # functionality to wrap it in a Python file. Then we wrap it in an
412
+ # atomic file that moves the file over on close.
413
+ import errno
414
+ import random
415
+
416
+ try:
417
+ perm: int | None = os.stat(filename).st_mode
418
+ except OSError:
419
+ perm = None
420
+
421
+ flags = os.O_RDWR | os.O_CREAT | os.O_EXCL
422
+
423
+ if binary:
424
+ flags |= getattr(os, "O_BINARY", 0)
425
+
426
+ while True:
427
+ tmp_filename = os.path.join(
428
+ os.path.dirname(filename),
429
+ f".__atomic-write{random.randrange(1 << 32):08x}",
430
+ )
431
+ try:
432
+ fd = os.open(tmp_filename, flags, 0o666 if perm is None else perm)
433
+ break
434
+ except OSError as e:
435
+ if e.errno == errno.EEXIST or (
436
+ os.name == "nt"
437
+ and e.errno == errno.EACCES
438
+ and os.path.isdir(e.filename)
439
+ and os.access(e.filename, os.W_OK)
440
+ ):
441
+ continue
442
+ raise
443
+
444
+ if perm is not None:
445
+ os.chmod(tmp_filename, perm) # in case perm includes bits in umask
446
+
447
+ f = _wrap_io_open(fd, mode, encoding, errors)
448
+ af = _AtomicFile(f, tmp_filename, os.path.realpath(filename))
449
+ return t.cast(t.IO[t.Any], af), True
450
+
451
+
452
+ class _AtomicFile:
453
+ def __init__(self, f: t.IO[t.Any], tmp_filename: str, real_filename: str) -> None:
454
+ self._f = f
455
+ self._tmp_filename = tmp_filename
456
+ self._real_filename = real_filename
457
+ self.closed = False
458
+
459
+ @property
460
+ def name(self) -> str:
461
+ return self._real_filename
462
+
463
+ def close(self, delete: bool = False) -> None:
464
+ if self.closed:
465
+ return
466
+ self._f.close()
467
+ os.replace(self._tmp_filename, self._real_filename)
468
+ self.closed = True
469
+
470
+ def __getattr__(self, name: str) -> t.Any:
471
+ return getattr(self._f, name)
472
+
473
+ def __enter__(self) -> _AtomicFile:
474
+ return self
475
+
476
+ def __exit__(
477
+ self,
478
+ exc_type: type[BaseException] | None,
479
+ exc_value: BaseException | None,
480
+ tb: TracebackType | None,
481
+ ) -> None:
482
+ self.close(delete=exc_type is not None)
483
+
484
+ def __repr__(self) -> str:
485
+ return repr(self._f)
486
+
487
+
488
+ def strip_ansi(value: str) -> str:
489
+ return _ansi_re.sub("", value)
490
+
491
+
492
+ def _is_jupyter_kernel_output(stream: t.IO[t.Any]) -> bool:
493
+ while isinstance(stream, (_FixupStream, _NonClosingTextIOWrapper)):
494
+ stream = stream._stream
495
+
496
+ return stream.__class__.__module__.startswith("ipykernel.")
497
+
498
+
499
+ def should_strip_ansi(
500
+ stream: t.IO[t.Any] | None = None, color: bool | None = None
501
+ ) -> bool:
502
+ if color is None:
503
+ if stream is None:
504
+ stream = sys.stdin
505
+ return not isatty(stream) and not _is_jupyter_kernel_output(stream)
506
+ return not color
507
+
508
+
509
+ # On Windows, wrap the output streams with colorama to support ANSI
510
+ # color codes.
511
+ # NOTE: double check is needed so mypy does not analyze this on Linux
512
+ if sys.platform.startswith("win") and WIN:
513
+ from ._winconsole import _get_windows_console_stream
514
+
515
+ def _get_argv_encoding() -> str:
516
+ import locale
517
+
518
+ return locale.getpreferredencoding()
519
+
520
+ _ansi_stream_wrappers: cabc.MutableMapping[t.TextIO, t.TextIO] = WeakKeyDictionary()
521
+
522
+ def auto_wrap_for_ansi(stream: t.TextIO, color: bool | None = None) -> t.TextIO:
523
+ """Support ANSI color and style codes on Windows by wrapping a
524
+ stream with colorama.
525
+ """
526
+ try:
527
+ cached = _ansi_stream_wrappers.get(stream)
528
+ except Exception:
529
+ cached = None
530
+
531
+ if cached is not None:
532
+ return cached
533
+
534
+ import colorama
535
+
536
+ strip = should_strip_ansi(stream, color)
537
+ ansi_wrapper = colorama.AnsiToWin32(stream, strip=strip)
538
+ rv = t.cast(t.TextIO, ansi_wrapper.stream)
539
+ _write = rv.write
540
+
541
+ def _safe_write(s: str) -> int:
542
+ try:
543
+ return _write(s)
544
+ except BaseException:
545
+ ansi_wrapper.reset_all()
546
+ raise
547
+
548
+ rv.write = _safe_write # type: ignore[method-assign]
549
+
550
+ try:
551
+ _ansi_stream_wrappers[stream] = rv
552
+ except Exception:
553
+ pass
554
+
555
+ return rv
556
+
557
+ else:
558
+
559
+ def _get_argv_encoding() -> str:
560
+ return getattr(sys.stdin, "encoding", None) or sys.getfilesystemencoding()
561
+
562
+ def _get_windows_console_stream(
563
+ f: t.TextIO, encoding: str | None, errors: str | None
564
+ ) -> t.TextIO | None:
565
+ return None
566
+
567
+
568
+ def term_len(x: str) -> int:
569
+ return len(strip_ansi(x))
570
+
571
+
572
+ def isatty(stream: t.IO[t.Any]) -> bool:
573
+ try:
574
+ return stream.isatty()
575
+ except Exception:
576
+ return False
577
+
578
+
579
+ def _make_cached_stream_func(
580
+ src_func: t.Callable[[], t.TextIO | None],
581
+ wrapper_func: t.Callable[[], t.TextIO],
582
+ ) -> t.Callable[[], t.TextIO | None]:
583
+ cache: cabc.MutableMapping[t.TextIO, t.TextIO] = WeakKeyDictionary()
584
+
585
+ def func() -> t.TextIO | None:
586
+ stream = src_func()
587
+
588
+ if stream is None:
589
+ return None
590
+
591
+ try:
592
+ rv = cache.get(stream)
593
+ except Exception:
594
+ rv = None
595
+ if rv is not None:
596
+ return rv
597
+ rv = wrapper_func()
598
+ try:
599
+ cache[stream] = rv
600
+ except Exception:
601
+ pass
602
+ return rv
603
+
604
+ return func
605
+
606
+
607
+ _default_text_stdin = _make_cached_stream_func(lambda: sys.stdin, get_text_stdin)
608
+ _default_text_stdout = _make_cached_stream_func(lambda: sys.stdout, get_text_stdout)
609
+ _default_text_stderr = _make_cached_stream_func(lambda: sys.stderr, get_text_stderr)
610
+
611
+
612
+ binary_streams: cabc.Mapping[str, t.Callable[[], t.BinaryIO]] = {
613
+ "stdin": get_binary_stdin,
614
+ "stdout": get_binary_stdout,
615
+ "stderr": get_binary_stderr,
616
+ }
617
+
618
+ text_streams: cabc.Mapping[str, t.Callable[[str | None, str | None], t.TextIO]] = {
619
+ "stdin": get_text_stdin,
620
+ "stdout": get_text_stdout,
621
+ "stderr": get_text_stderr,
622
+ }
venv/lib/python3.10/site-packages/click/_termui_impl.py ADDED
@@ -0,0 +1,852 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ This module contains implementations for the termui module. To keep the
3
+ import time of Click down, some infrequently used functionality is
4
+ placed in this module and only imported as needed.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import collections.abc as cabc
10
+ import contextlib
11
+ import math
12
+ import os
13
+ import shlex
14
+ import sys
15
+ import time
16
+ import typing as t
17
+ from gettext import gettext as _
18
+ from io import StringIO
19
+ from pathlib import Path
20
+ from types import TracebackType
21
+
22
+ from ._compat import _default_text_stdout
23
+ from ._compat import CYGWIN
24
+ from ._compat import get_best_encoding
25
+ from ._compat import isatty
26
+ from ._compat import open_stream
27
+ from ._compat import strip_ansi
28
+ from ._compat import term_len
29
+ from ._compat import WIN
30
+ from .exceptions import ClickException
31
+ from .utils import echo
32
+
33
+ V = t.TypeVar("V")
34
+
35
+ if os.name == "nt":
36
+ BEFORE_BAR = "\r"
37
+ AFTER_BAR = "\n"
38
+ else:
39
+ BEFORE_BAR = "\r\033[?25l"
40
+ AFTER_BAR = "\033[?25h\n"
41
+
42
+
43
+ class ProgressBar(t.Generic[V]):
44
+ def __init__(
45
+ self,
46
+ iterable: cabc.Iterable[V] | None,
47
+ length: int | None = None,
48
+ fill_char: str = "#",
49
+ empty_char: str = " ",
50
+ bar_template: str = "%(bar)s",
51
+ info_sep: str = " ",
52
+ hidden: bool = False,
53
+ show_eta: bool = True,
54
+ show_percent: bool | None = None,
55
+ show_pos: bool = False,
56
+ item_show_func: t.Callable[[V | None], str | None] | None = None,
57
+ label: str | None = None,
58
+ file: t.TextIO | None = None,
59
+ color: bool | None = None,
60
+ update_min_steps: int = 1,
61
+ width: int = 30,
62
+ ) -> None:
63
+ self.fill_char = fill_char
64
+ self.empty_char = empty_char
65
+ self.bar_template = bar_template
66
+ self.info_sep = info_sep
67
+ self.hidden = hidden
68
+ self.show_eta = show_eta
69
+ self.show_percent = show_percent
70
+ self.show_pos = show_pos
71
+ self.item_show_func = item_show_func
72
+ self.label: str = label or ""
73
+
74
+ if file is None:
75
+ file = _default_text_stdout()
76
+
77
+ # There are no standard streams attached to write to. For example,
78
+ # pythonw on Windows.
79
+ if file is None:
80
+ file = StringIO()
81
+
82
+ self.file = file
83
+ self.color = color
84
+ self.update_min_steps = update_min_steps
85
+ self._completed_intervals = 0
86
+ self.width: int = width
87
+ self.autowidth: bool = width == 0
88
+
89
+ if length is None:
90
+ from operator import length_hint
91
+
92
+ length = length_hint(iterable, -1)
93
+
94
+ if length == -1:
95
+ length = None
96
+ if iterable is None:
97
+ if length is None:
98
+ raise TypeError("iterable or length is required")
99
+ iterable = t.cast("cabc.Iterable[V]", range(length))
100
+ self.iter: cabc.Iterable[V] = iter(iterable)
101
+ self.length = length
102
+ self.pos: int = 0
103
+ self.avg: list[float] = []
104
+ self.last_eta: float
105
+ self.start: float
106
+ self.start = self.last_eta = time.time()
107
+ self.eta_known: bool = False
108
+ self.finished: bool = False
109
+ self.max_width: int | None = None
110
+ self.entered: bool = False
111
+ self.current_item: V | None = None
112
+ self._is_atty = isatty(self.file)
113
+ self._last_line: str | None = None
114
+
115
+ def __enter__(self) -> ProgressBar[V]:
116
+ self.entered = True
117
+ self.render_progress()
118
+ return self
119
+
120
+ def __exit__(
121
+ self,
122
+ exc_type: type[BaseException] | None,
123
+ exc_value: BaseException | None,
124
+ tb: TracebackType | None,
125
+ ) -> None:
126
+ self.render_finish()
127
+
128
+ def __iter__(self) -> cabc.Iterator[V]:
129
+ if not self.entered:
130
+ raise RuntimeError("You need to use progress bars in a with block.")
131
+ self.render_progress()
132
+ return self.generator()
133
+
134
+ def __next__(self) -> V:
135
+ # Iteration is defined in terms of a generator function,
136
+ # returned by iter(self); use that to define next(). This works
137
+ # because `self.iter` is an iterable consumed by that generator,
138
+ # so it is re-entry safe. Calling `next(self.generator())`
139
+ # twice works and does "what you want".
140
+ return next(iter(self))
141
+
142
+ def render_finish(self) -> None:
143
+ if self.hidden or not self._is_atty:
144
+ return
145
+ self.file.write(AFTER_BAR)
146
+ self.file.flush()
147
+
148
+ @property
149
+ def pct(self) -> float:
150
+ if self.finished:
151
+ return 1.0
152
+ return min(self.pos / (float(self.length or 1) or 1), 1.0)
153
+
154
+ @property
155
+ def time_per_iteration(self) -> float:
156
+ if not self.avg:
157
+ return 0.0
158
+ return sum(self.avg) / float(len(self.avg))
159
+
160
+ @property
161
+ def eta(self) -> float:
162
+ if self.length is not None and not self.finished:
163
+ return self.time_per_iteration * (self.length - self.pos)
164
+ return 0.0
165
+
166
+ def format_eta(self) -> str:
167
+ if self.eta_known:
168
+ t = int(self.eta)
169
+ seconds = t % 60
170
+ t //= 60
171
+ minutes = t % 60
172
+ t //= 60
173
+ hours = t % 24
174
+ t //= 24
175
+ if t > 0:
176
+ return f"{t}d {hours:02}:{minutes:02}:{seconds:02}"
177
+ else:
178
+ return f"{hours:02}:{minutes:02}:{seconds:02}"
179
+ return ""
180
+
181
+ def format_pos(self) -> str:
182
+ pos = str(self.pos)
183
+ if self.length is not None:
184
+ pos += f"/{self.length}"
185
+ return pos
186
+
187
+ def format_pct(self) -> str:
188
+ return f"{int(self.pct * 100): 4}%"[1:]
189
+
190
+ def format_bar(self) -> str:
191
+ if self.length is not None:
192
+ bar_length = int(self.pct * self.width)
193
+ bar = self.fill_char * bar_length
194
+ bar += self.empty_char * (self.width - bar_length)
195
+ elif self.finished:
196
+ bar = self.fill_char * self.width
197
+ else:
198
+ chars = list(self.empty_char * (self.width or 1))
199
+ if self.time_per_iteration != 0:
200
+ chars[
201
+ int(
202
+ (math.cos(self.pos * self.time_per_iteration) / 2.0 + 0.5)
203
+ * self.width
204
+ )
205
+ ] = self.fill_char
206
+ bar = "".join(chars)
207
+ return bar
208
+
209
+ def format_progress_line(self) -> str:
210
+ show_percent = self.show_percent
211
+
212
+ info_bits = []
213
+ if self.length is not None and show_percent is None:
214
+ show_percent = not self.show_pos
215
+
216
+ if self.show_pos:
217
+ info_bits.append(self.format_pos())
218
+ if show_percent:
219
+ info_bits.append(self.format_pct())
220
+ if self.show_eta and self.eta_known and not self.finished:
221
+ info_bits.append(self.format_eta())
222
+ if self.item_show_func is not None:
223
+ item_info = self.item_show_func(self.current_item)
224
+ if item_info is not None:
225
+ info_bits.append(item_info)
226
+
227
+ return (
228
+ self.bar_template
229
+ % {
230
+ "label": self.label,
231
+ "bar": self.format_bar(),
232
+ "info": self.info_sep.join(info_bits),
233
+ }
234
+ ).rstrip()
235
+
236
+ def render_progress(self) -> None:
237
+ if self.hidden:
238
+ return
239
+
240
+ if not self._is_atty:
241
+ # Only output the label once if the output is not a TTY.
242
+ if self._last_line != self.label:
243
+ self._last_line = self.label
244
+ echo(self.label, file=self.file, color=self.color)
245
+ return
246
+
247
+ buf = []
248
+ # Update width in case the terminal has been resized
249
+ if self.autowidth:
250
+ import shutil
251
+
252
+ old_width = self.width
253
+ self.width = 0
254
+ clutter_length = term_len(self.format_progress_line())
255
+ new_width = max(0, shutil.get_terminal_size().columns - clutter_length)
256
+ if new_width < old_width and self.max_width is not None:
257
+ buf.append(BEFORE_BAR)
258
+ buf.append(" " * self.max_width)
259
+ self.max_width = new_width
260
+ self.width = new_width
261
+
262
+ clear_width = self.width
263
+ if self.max_width is not None:
264
+ clear_width = self.max_width
265
+
266
+ buf.append(BEFORE_BAR)
267
+ line = self.format_progress_line()
268
+ line_len = term_len(line)
269
+ if self.max_width is None or self.max_width < line_len:
270
+ self.max_width = line_len
271
+
272
+ buf.append(line)
273
+ buf.append(" " * (clear_width - line_len))
274
+ line = "".join(buf)
275
+ # Render the line only if it changed.
276
+
277
+ if line != self._last_line:
278
+ self._last_line = line
279
+ echo(line, file=self.file, color=self.color, nl=False)
280
+ self.file.flush()
281
+
282
+ def make_step(self, n_steps: int) -> None:
283
+ self.pos += n_steps
284
+ if self.length is not None and self.pos >= self.length:
285
+ self.finished = True
286
+
287
+ if (time.time() - self.last_eta) < 1.0:
288
+ return
289
+
290
+ self.last_eta = time.time()
291
+
292
+ # self.avg is a rolling list of length <= 7 of steps where steps are
293
+ # defined as time elapsed divided by the total progress through
294
+ # self.length.
295
+ if self.pos:
296
+ step = (time.time() - self.start) / self.pos
297
+ else:
298
+ step = time.time() - self.start
299
+
300
+ self.avg = self.avg[-6:] + [step]
301
+
302
+ self.eta_known = self.length is not None
303
+
304
+ def update(self, n_steps: int, current_item: V | None = None) -> None:
305
+ """Update the progress bar by advancing a specified number of
306
+ steps, and optionally set the ``current_item`` for this new
307
+ position.
308
+
309
+ :param n_steps: Number of steps to advance.
310
+ :param current_item: Optional item to set as ``current_item``
311
+ for the updated position.
312
+
313
+ .. versionchanged:: 8.0
314
+ Added the ``current_item`` optional parameter.
315
+
316
+ .. versionchanged:: 8.0
317
+ Only render when the number of steps meets the
318
+ ``update_min_steps`` threshold.
319
+ """
320
+ if current_item is not None:
321
+ self.current_item = current_item
322
+
323
+ self._completed_intervals += n_steps
324
+
325
+ if self._completed_intervals >= self.update_min_steps:
326
+ self.make_step(self._completed_intervals)
327
+ self.render_progress()
328
+ self._completed_intervals = 0
329
+
330
+ def finish(self) -> None:
331
+ self.eta_known = False
332
+ self.current_item = None
333
+ self.finished = True
334
+
335
+ def generator(self) -> cabc.Iterator[V]:
336
+ """Return a generator which yields the items added to the bar
337
+ during construction, and updates the progress bar *after* the
338
+ yielded block returns.
339
+ """
340
+ # WARNING: the iterator interface for `ProgressBar` relies on
341
+ # this and only works because this is a simple generator which
342
+ # doesn't create or manage additional state. If this function
343
+ # changes, the impact should be evaluated both against
344
+ # `iter(bar)` and `next(bar)`. `next()` in particular may call
345
+ # `self.generator()` repeatedly, and this must remain safe in
346
+ # order for that interface to work.
347
+ if not self.entered:
348
+ raise RuntimeError("You need to use progress bars in a with block.")
349
+
350
+ if not self._is_atty:
351
+ yield from self.iter
352
+ else:
353
+ for rv in self.iter:
354
+ self.current_item = rv
355
+
356
+ # This allows show_item_func to be updated before the
357
+ # item is processed. Only trigger at the beginning of
358
+ # the update interval.
359
+ if self._completed_intervals == 0:
360
+ self.render_progress()
361
+
362
+ yield rv
363
+ self.update(1)
364
+
365
+ self.finish()
366
+ self.render_progress()
367
+
368
+
369
+ def pager(generator: cabc.Iterable[str], color: bool | None = None) -> None:
370
+ """Decide what method to use for paging through text."""
371
+ stdout = _default_text_stdout()
372
+
373
+ # There are no standard streams attached to write to. For example,
374
+ # pythonw on Windows.
375
+ if stdout is None:
376
+ stdout = StringIO()
377
+
378
+ if not isatty(sys.stdin) or not isatty(stdout):
379
+ return _nullpager(stdout, generator, color)
380
+
381
+ # Split and normalize the pager command into parts.
382
+ pager_cmd_parts = shlex.split(os.environ.get("PAGER", ""), posix=False)
383
+ if pager_cmd_parts:
384
+ if WIN:
385
+ if _tempfilepager(generator, pager_cmd_parts, color):
386
+ return
387
+ elif _pipepager(generator, pager_cmd_parts, color):
388
+ return
389
+
390
+ if os.environ.get("TERM") in ("dumb", "emacs"):
391
+ return _nullpager(stdout, generator, color)
392
+ if (WIN or sys.platform.startswith("os2")) and _tempfilepager(
393
+ generator, ["more"], color
394
+ ):
395
+ return
396
+ if _pipepager(generator, ["less"], color):
397
+ return
398
+
399
+ import tempfile
400
+
401
+ fd, filename = tempfile.mkstemp()
402
+ os.close(fd)
403
+ try:
404
+ if _pipepager(generator, ["more"], color):
405
+ return
406
+ return _nullpager(stdout, generator, color)
407
+ finally:
408
+ os.unlink(filename)
409
+
410
+
411
+ def _pipepager(
412
+ generator: cabc.Iterable[str], cmd_parts: list[str], color: bool | None
413
+ ) -> bool:
414
+ """Page through text by feeding it to another program. Invoking a
415
+ pager through this might support colors.
416
+
417
+ Returns `True` if the command was found, `False` otherwise and thus another
418
+ pager should be attempted.
419
+ """
420
+ # Split the command into the invoked CLI and its parameters.
421
+ if not cmd_parts:
422
+ return False
423
+
424
+ import shutil
425
+
426
+ cmd = cmd_parts[0]
427
+ cmd_params = cmd_parts[1:]
428
+
429
+ cmd_filepath = shutil.which(cmd)
430
+ if not cmd_filepath:
431
+ return False
432
+
433
+ # Produces a normalized absolute path string.
434
+ # multi-call binaries such as busybox derive their identity from the symlink
435
+ # less -> busybox. resolve() causes them to misbehave. (eg. less becomes busybox)
436
+ cmd_path = Path(cmd_filepath).absolute()
437
+ cmd_name = cmd_path.name
438
+
439
+ import subprocess
440
+
441
+ # Make a local copy of the environment to not affect the global one.
442
+ env = dict(os.environ)
443
+
444
+ # If we're piping to less and the user hasn't decided on colors, we enable
445
+ # them by default we find the -R flag in the command line arguments.
446
+ if color is None and cmd_name == "less":
447
+ less_flags = f"{os.environ.get('LESS', '')}{' '.join(cmd_params)}"
448
+ if not less_flags:
449
+ env["LESS"] = "-R"
450
+ color = True
451
+ elif "r" in less_flags or "R" in less_flags:
452
+ color = True
453
+
454
+ c = subprocess.Popen(
455
+ [str(cmd_path)] + cmd_params,
456
+ shell=False,
457
+ stdin=subprocess.PIPE,
458
+ env=env,
459
+ errors="replace",
460
+ text=True,
461
+ )
462
+ assert c.stdin is not None
463
+ try:
464
+ for text in generator:
465
+ if not color:
466
+ text = strip_ansi(text)
467
+
468
+ c.stdin.write(text)
469
+ except BrokenPipeError:
470
+ # In case the pager exited unexpectedly, ignore the broken pipe error.
471
+ pass
472
+ except Exception as e:
473
+ # In case there is an exception we want to close the pager immediately
474
+ # and let the caller handle it.
475
+ # Otherwise the pager will keep running, and the user may not notice
476
+ # the error message, or worse yet it may leave the terminal in a broken state.
477
+ c.terminate()
478
+ raise e
479
+ finally:
480
+ # We must close stdin and wait for the pager to exit before we continue
481
+ try:
482
+ c.stdin.close()
483
+ # Close implies flush, so it might throw a BrokenPipeError if the pager
484
+ # process exited already.
485
+ except BrokenPipeError:
486
+ pass
487
+
488
+ # Less doesn't respect ^C, but catches it for its own UI purposes (aborting
489
+ # search or other commands inside less).
490
+ #
491
+ # That means when the user hits ^C, the parent process (click) terminates,
492
+ # but less is still alive, paging the output and messing up the terminal.
493
+ #
494
+ # If the user wants to make the pager exit on ^C, they should set
495
+ # `LESS='-K'`. It's not our decision to make.
496
+ while True:
497
+ try:
498
+ c.wait()
499
+ except KeyboardInterrupt:
500
+ pass
501
+ else:
502
+ break
503
+
504
+ return True
505
+
506
+
507
+ def _tempfilepager(
508
+ generator: cabc.Iterable[str], cmd_parts: list[str], color: bool | None
509
+ ) -> bool:
510
+ """Page through text by invoking a program on a temporary file.
511
+
512
+ Returns `True` if the command was found, `False` otherwise and thus another
513
+ pager should be attempted.
514
+ """
515
+ # Split the command into the invoked CLI and its parameters.
516
+ if not cmd_parts:
517
+ return False
518
+
519
+ import shutil
520
+
521
+ cmd = cmd_parts[0]
522
+
523
+ cmd_filepath = shutil.which(cmd)
524
+ if not cmd_filepath:
525
+ return False
526
+ # Produces a normalized absolute path string.
527
+ # multi-call binaries such as busybox derive their identity from the symlink
528
+ # less -> busybox. resolve() causes them to misbehave. (eg. less becomes busybox)
529
+ cmd_path = Path(cmd_filepath).absolute()
530
+
531
+ import subprocess
532
+ import tempfile
533
+
534
+ fd, filename = tempfile.mkstemp()
535
+ # TODO: This never terminates if the passed generator never terminates.
536
+ text = "".join(generator)
537
+ if not color:
538
+ text = strip_ansi(text)
539
+ encoding = get_best_encoding(sys.stdout)
540
+ with open_stream(filename, "wb")[0] as f:
541
+ f.write(text.encode(encoding))
542
+ try:
543
+ subprocess.call([str(cmd_path), filename])
544
+ except OSError:
545
+ # Command not found
546
+ pass
547
+ finally:
548
+ os.close(fd)
549
+ os.unlink(filename)
550
+
551
+ return True
552
+
553
+
554
+ def _nullpager(
555
+ stream: t.TextIO, generator: cabc.Iterable[str], color: bool | None
556
+ ) -> None:
557
+ """Simply print unformatted text. This is the ultimate fallback."""
558
+ for text in generator:
559
+ if not color:
560
+ text = strip_ansi(text)
561
+ stream.write(text)
562
+
563
+
564
+ class Editor:
565
+ def __init__(
566
+ self,
567
+ editor: str | None = None,
568
+ env: cabc.Mapping[str, str] | None = None,
569
+ require_save: bool = True,
570
+ extension: str = ".txt",
571
+ ) -> None:
572
+ self.editor = editor
573
+ self.env = env
574
+ self.require_save = require_save
575
+ self.extension = extension
576
+
577
+ def get_editor(self) -> str:
578
+ if self.editor is not None:
579
+ return self.editor
580
+ for key in "VISUAL", "EDITOR":
581
+ rv = os.environ.get(key)
582
+ if rv:
583
+ return rv
584
+ if WIN:
585
+ return "notepad"
586
+
587
+ from shutil import which
588
+
589
+ for editor in "sensible-editor", "vim", "nano":
590
+ if which(editor) is not None:
591
+ return editor
592
+ return "vi"
593
+
594
+ def edit_files(self, filenames: cabc.Iterable[str]) -> None:
595
+ import subprocess
596
+
597
+ editor = self.get_editor()
598
+ environ: dict[str, str] | None = None
599
+
600
+ if self.env:
601
+ environ = os.environ.copy()
602
+ environ.update(self.env)
603
+
604
+ exc_filename = " ".join(f'"{filename}"' for filename in filenames)
605
+
606
+ try:
607
+ c = subprocess.Popen(
608
+ args=f"{editor} {exc_filename}", env=environ, shell=True
609
+ )
610
+ exit_code = c.wait()
611
+ if exit_code != 0:
612
+ raise ClickException(
613
+ _("{editor}: Editing failed").format(editor=editor)
614
+ )
615
+ except OSError as e:
616
+ raise ClickException(
617
+ _("{editor}: Editing failed: {e}").format(editor=editor, e=e)
618
+ ) from e
619
+
620
+ @t.overload
621
+ def edit(self, text: bytes | bytearray) -> bytes | None: ...
622
+
623
+ # We cannot know whether or not the type expected is str or bytes when None
624
+ # is passed, so str is returned as that was what was done before.
625
+ @t.overload
626
+ def edit(self, text: str | None) -> str | None: ...
627
+
628
+ def edit(self, text: str | bytes | bytearray | None) -> str | bytes | None:
629
+ import tempfile
630
+
631
+ if text is None:
632
+ data: bytes | bytearray = b""
633
+ elif isinstance(text, (bytes, bytearray)):
634
+ data = text
635
+ else:
636
+ if text and not text.endswith("\n"):
637
+ text += "\n"
638
+
639
+ if WIN:
640
+ data = text.replace("\n", "\r\n").encode("utf-8-sig")
641
+ else:
642
+ data = text.encode("utf-8")
643
+
644
+ fd, name = tempfile.mkstemp(prefix="editor-", suffix=self.extension)
645
+ f: t.BinaryIO
646
+
647
+ try:
648
+ with os.fdopen(fd, "wb") as f:
649
+ f.write(data)
650
+
651
+ # If the filesystem resolution is 1 second, like Mac OS
652
+ # 10.12 Extended, or 2 seconds, like FAT32, and the editor
653
+ # closes very fast, require_save can fail. Set the modified
654
+ # time to be 2 seconds in the past to work around this.
655
+ os.utime(name, (os.path.getatime(name), os.path.getmtime(name) - 2))
656
+ # Depending on the resolution, the exact value might not be
657
+ # recorded, so get the new recorded value.
658
+ timestamp = os.path.getmtime(name)
659
+
660
+ self.edit_files((name,))
661
+
662
+ if self.require_save and os.path.getmtime(name) == timestamp:
663
+ return None
664
+
665
+ with open(name, "rb") as f:
666
+ rv = f.read()
667
+
668
+ if isinstance(text, (bytes, bytearray)):
669
+ return rv
670
+
671
+ return rv.decode("utf-8-sig").replace("\r\n", "\n")
672
+ finally:
673
+ os.unlink(name)
674
+
675
+
676
+ def open_url(url: str, wait: bool = False, locate: bool = False) -> int:
677
+ import subprocess
678
+
679
+ def _unquote_file(url: str) -> str:
680
+ from urllib.parse import unquote
681
+
682
+ if url.startswith("file://"):
683
+ url = unquote(url[7:])
684
+
685
+ return url
686
+
687
+ if sys.platform == "darwin":
688
+ args = ["open"]
689
+ if wait:
690
+ args.append("-W")
691
+ if locate:
692
+ args.append("-R")
693
+ args.append(_unquote_file(url))
694
+ null = open("/dev/null", "w")
695
+ try:
696
+ return subprocess.Popen(args, stderr=null).wait()
697
+ finally:
698
+ null.close()
699
+ elif WIN:
700
+ if locate:
701
+ url = _unquote_file(url)
702
+ args = ["explorer", f"/select,{url}"]
703
+ else:
704
+ args = ["start"]
705
+ if wait:
706
+ args.append("/WAIT")
707
+ args.append("")
708
+ args.append(url)
709
+ try:
710
+ return subprocess.call(args)
711
+ except OSError:
712
+ # Command not found
713
+ return 127
714
+ elif CYGWIN:
715
+ if locate:
716
+ url = _unquote_file(url)
717
+ args = ["cygstart", os.path.dirname(url)]
718
+ else:
719
+ args = ["cygstart"]
720
+ if wait:
721
+ args.append("-w")
722
+ args.append(url)
723
+ try:
724
+ return subprocess.call(args)
725
+ except OSError:
726
+ # Command not found
727
+ return 127
728
+
729
+ try:
730
+ if locate:
731
+ url = os.path.dirname(_unquote_file(url)) or "."
732
+ else:
733
+ url = _unquote_file(url)
734
+ c = subprocess.Popen(["xdg-open", url])
735
+ if wait:
736
+ return c.wait()
737
+ return 0
738
+ except OSError:
739
+ if url.startswith(("http://", "https://")) and not locate and not wait:
740
+ import webbrowser
741
+
742
+ webbrowser.open(url)
743
+ return 0
744
+ return 1
745
+
746
+
747
+ def _translate_ch_to_exc(ch: str) -> None:
748
+ if ch == "\x03":
749
+ raise KeyboardInterrupt()
750
+
751
+ if ch == "\x04" and not WIN: # Unix-like, Ctrl+D
752
+ raise EOFError()
753
+
754
+ if ch == "\x1a" and WIN: # Windows, Ctrl+Z
755
+ raise EOFError()
756
+
757
+ return None
758
+
759
+
760
+ if sys.platform == "win32":
761
+ import msvcrt
762
+
763
+ @contextlib.contextmanager
764
+ def raw_terminal() -> cabc.Iterator[int]:
765
+ yield -1
766
+
767
+ def getchar(echo: bool) -> str:
768
+ # The function `getch` will return a bytes object corresponding to
769
+ # the pressed character. Since Windows 10 build 1803, it will also
770
+ # return \x00 when called a second time after pressing a regular key.
771
+ #
772
+ # `getwch` does not share this probably-bugged behavior. Moreover, it
773
+ # returns a Unicode object by default, which is what we want.
774
+ #
775
+ # Either of these functions will return \x00 or \xe0 to indicate
776
+ # a special key, and you need to call the same function again to get
777
+ # the "rest" of the code. The fun part is that \u00e0 is
778
+ # "latin small letter a with grave", so if you type that on a French
779
+ # keyboard, you _also_ get a \xe0.
780
+ # E.g., consider the Up arrow. This returns \xe0 and then \x48. The
781
+ # resulting Unicode string reads as "a with grave" + "capital H".
782
+ # This is indistinguishable from when the user actually types
783
+ # "a with grave" and then "capital H".
784
+ #
785
+ # When \xe0 is returned, we assume it's part of a special-key sequence
786
+ # and call `getwch` again, but that means that when the user types
787
+ # the \u00e0 character, `getchar` doesn't return until a second
788
+ # character is typed.
789
+ # The alternative is returning immediately, but that would mess up
790
+ # cross-platform handling of arrow keys and others that start with
791
+ # \xe0. Another option is using `getch`, but then we can't reliably
792
+ # read non-ASCII characters, because return values of `getch` are
793
+ # limited to the current 8-bit codepage.
794
+ #
795
+ # Anyway, Click doesn't claim to do this Right(tm), and using `getwch`
796
+ # is doing the right thing in more situations than with `getch`.
797
+
798
+ if echo:
799
+ func = t.cast(t.Callable[[], str], msvcrt.getwche)
800
+ else:
801
+ func = t.cast(t.Callable[[], str], msvcrt.getwch)
802
+
803
+ rv = func()
804
+
805
+ if rv in ("\x00", "\xe0"):
806
+ # \x00 and \xe0 are control characters that indicate special key,
807
+ # see above.
808
+ rv += func()
809
+
810
+ _translate_ch_to_exc(rv)
811
+ return rv
812
+
813
+ else:
814
+ import termios
815
+ import tty
816
+
817
+ @contextlib.contextmanager
818
+ def raw_terminal() -> cabc.Iterator[int]:
819
+ f: t.TextIO | None
820
+ fd: int
821
+
822
+ if not isatty(sys.stdin):
823
+ f = open("/dev/tty")
824
+ fd = f.fileno()
825
+ else:
826
+ fd = sys.stdin.fileno()
827
+ f = None
828
+
829
+ try:
830
+ old_settings = termios.tcgetattr(fd)
831
+
832
+ try:
833
+ tty.setraw(fd)
834
+ yield fd
835
+ finally:
836
+ termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
837
+ sys.stdout.flush()
838
+
839
+ if f is not None:
840
+ f.close()
841
+ except termios.error:
842
+ pass
843
+
844
+ def getchar(echo: bool) -> str:
845
+ with raw_terminal() as fd:
846
+ ch = os.read(fd, 32).decode(get_best_encoding(sys.stdin), "replace")
847
+
848
+ if echo and isatty(sys.stdout):
849
+ sys.stdout.write(ch)
850
+
851
+ _translate_ch_to_exc(ch)
852
+ return ch
venv/lib/python3.10/site-packages/click/_textwrap.py ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import collections.abc as cabc
4
+ import textwrap
5
+ from contextlib import contextmanager
6
+
7
+
8
+ class TextWrapper(textwrap.TextWrapper):
9
+ def _handle_long_word(
10
+ self,
11
+ reversed_chunks: list[str],
12
+ cur_line: list[str],
13
+ cur_len: int,
14
+ width: int,
15
+ ) -> None:
16
+ space_left = max(width - cur_len, 1)
17
+
18
+ if self.break_long_words:
19
+ last = reversed_chunks[-1]
20
+ cut = last[:space_left]
21
+ res = last[space_left:]
22
+ cur_line.append(cut)
23
+ reversed_chunks[-1] = res
24
+ elif not cur_line:
25
+ cur_line.append(reversed_chunks.pop())
26
+
27
+ @contextmanager
28
+ def extra_indent(self, indent: str) -> cabc.Iterator[None]:
29
+ old_initial_indent = self.initial_indent
30
+ old_subsequent_indent = self.subsequent_indent
31
+ self.initial_indent += indent
32
+ self.subsequent_indent += indent
33
+
34
+ try:
35
+ yield
36
+ finally:
37
+ self.initial_indent = old_initial_indent
38
+ self.subsequent_indent = old_subsequent_indent
39
+
40
+ def indent_only(self, text: str) -> str:
41
+ rv = []
42
+
43
+ for idx, line in enumerate(text.splitlines()):
44
+ indent = self.initial_indent
45
+
46
+ if idx > 0:
47
+ indent = self.subsequent_indent
48
+
49
+ rv.append(f"{indent}{line}")
50
+
51
+ return "\n".join(rv)