ayousanz commited on
Commit
1e6dc22
·
verified ·
1 Parent(s): a902c8a

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/site-packages/unidic/dicdir/char.bin +3 -0
  2. .venv/Lib/site-packages/unidic_lite/dicdir/right-id.def +0 -0
  3. .venv/Lib/site-packages/unidic_lite/dicdir/unidic-mecab.pdf +0 -0
  4. .venv/Lib/site-packages/unidic_lite/dicdir/unk.dic +0 -0
  5. .venv/Lib/site-packages/unidic_lite/dicdir/version +1 -0
  6. .venv/Lib/site-packages/urllib3-2.2.3.dist-info/INSTALLER +1 -0
  7. .venv/Lib/site-packages/urllib3-2.2.3.dist-info/METADATA +155 -0
  8. .venv/Lib/site-packages/urllib3-2.2.3.dist-info/RECORD +44 -0
  9. .venv/Lib/site-packages/urllib3-2.2.3.dist-info/REQUESTED +0 -0
  10. .venv/Lib/site-packages/urllib3-2.2.3.dist-info/WHEEL +4 -0
  11. .venv/Lib/site-packages/urllib3-2.2.3.dist-info/licenses/LICENSE.txt +21 -0
  12. .venv/Lib/site-packages/urllib3/__pycache__/__init__.cpython-39.pyc +0 -0
  13. .venv/Lib/site-packages/urllib3/__pycache__/_base_connection.cpython-39.pyc +0 -0
  14. .venv/Lib/site-packages/urllib3/__pycache__/_collections.cpython-39.pyc +0 -0
  15. .venv/Lib/site-packages/urllib3/__pycache__/_request_methods.cpython-39.pyc +0 -0
  16. .venv/Lib/site-packages/urllib3/__pycache__/_version.cpython-39.pyc +0 -0
  17. .venv/Lib/site-packages/urllib3/__pycache__/connection.cpython-39.pyc +0 -0
  18. .venv/Lib/site-packages/urllib3/__pycache__/connectionpool.cpython-39.pyc +0 -0
  19. .venv/Lib/site-packages/urllib3/__pycache__/exceptions.cpython-39.pyc +0 -0
  20. .venv/Lib/site-packages/urllib3/__pycache__/fields.cpython-39.pyc +0 -0
  21. .venv/Lib/site-packages/urllib3/__pycache__/filepost.cpython-39.pyc +0 -0
  22. .venv/Lib/site-packages/urllib3/__pycache__/poolmanager.cpython-39.pyc +0 -0
  23. .venv/Lib/site-packages/urllib3/__pycache__/response.cpython-39.pyc +0 -0
  24. .venv/Lib/site-packages/urllib3/util/__pycache__/__init__.cpython-39.pyc +0 -0
  25. .venv/Lib/site-packages/urllib3/util/__pycache__/response.cpython-39.pyc +0 -0
  26. .venv/Lib/site-packages/urllib3/util/__pycache__/retry.cpython-39.pyc +0 -0
  27. .venv/Lib/site-packages/urllib3/util/__pycache__/ssl_.cpython-39.pyc +0 -0
  28. .venv/Lib/site-packages/urllib3/util/__pycache__/ssl_match_hostname.cpython-39.pyc +0 -0
  29. .venv/Lib/site-packages/urllib3/util/__pycache__/ssltransport.cpython-39.pyc +0 -0
  30. .venv/Lib/site-packages/urllib3/util/__pycache__/timeout.cpython-39.pyc +0 -0
  31. .venv/Lib/site-packages/urllib3/util/__pycache__/url.cpython-39.pyc +0 -0
  32. .venv/Lib/site-packages/urllib3/util/__pycache__/util.cpython-39.pyc +0 -0
  33. .venv/Lib/site-packages/urllib3/util/__pycache__/wait.cpython-39.pyc +0 -0
  34. .venv/Lib/site-packages/wasabi/__init__.py +12 -0
  35. .venv/Lib/site-packages/wasabi/about.py +7 -0
  36. .venv/Lib/site-packages/wasabi/markdown.py +106 -0
  37. .venv/Lib/site-packages/wasabi/printer.py +250 -0
  38. .venv/Lib/site-packages/wasabi/tables.py +154 -0
  39. .venv/Lib/site-packages/wasabi/tests/test_markdown.py +28 -0
  40. .venv/Lib/site-packages/wasabi/tests/test_printer.py +239 -0
  41. .venv/Lib/site-packages/wasabi/tests/test_tables.py +422 -0
  42. .venv/Lib/site-packages/wasabi/tests/test_traceback.py +67 -0
  43. .venv/Lib/site-packages/wasabi/traceback_printer.py +118 -0
  44. .venv/Lib/site-packages/wasabi/util.py +234 -0
  45. .venv/Lib/site-packages/xlstm-1.0.8.dist-info/WHEEL +5 -0
  46. .venv/Lib/site-packages/xlstm-1.0.8.dist-info/top_level.txt +1 -0
  47. .venv/Lib/site-packages/xlstm/blocks/__pycache__/__init__.cpython-39.pyc +0 -0
  48. .venv/Lib/site-packages/xlstm/blocks/__pycache__/xlstm_block.cpython-39.pyc +0 -0
  49. .venv/Lib/site-packages/xlstm/blocks/slstm/__pycache__/__init__.cpython-39.pyc +0 -0
  50. .venv/Lib/site-packages/xlstm/blocks/slstm/__pycache__/block.cpython-39.pyc +0 -0
.venv/Lib/site-packages/unidic/dicdir/char.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:dd31396563d8924645b80fd3c9aa7b13ca089d7748f25553a1d6bc3f9b511ae8
3
+ size 262496
.venv/Lib/site-packages/unidic_lite/dicdir/right-id.def ADDED
The diff for this file is too large to render. See raw diff
 
.venv/Lib/site-packages/unidic_lite/dicdir/unidic-mecab.pdf ADDED
Binary file (21.5 kB). View file
 
.venv/Lib/site-packages/unidic_lite/dicdir/unk.dic ADDED
Binary file (5.48 kB). View file
 
.venv/Lib/site-packages/unidic_lite/dicdir/version ADDED
@@ -0,0 +1 @@
 
 
1
+ 2.1.2
.venv/Lib/site-packages/urllib3-2.2.3.dist-info/INSTALLER ADDED
@@ -0,0 +1 @@
 
 
1
+ uv
.venv/Lib/site-packages/urllib3-2.2.3.dist-info/METADATA ADDED
@@ -0,0 +1,155 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Metadata-Version: 2.3
2
+ Name: urllib3
3
+ Version: 2.2.3
4
+ Summary: HTTP library with thread-safe connection pooling, file post, and more.
5
+ Project-URL: Changelog, https://github.com/urllib3/urllib3/blob/main/CHANGES.rst
6
+ Project-URL: Documentation, https://urllib3.readthedocs.io
7
+ Project-URL: Code, https://github.com/urllib3/urllib3
8
+ Project-URL: Issue tracker, https://github.com/urllib3/urllib3/issues
9
+ Author-email: Andrey Petrov <[email protected]>
10
+ Maintainer-email: Seth Michael Larson <[email protected]>, Quentin Pradet <[email protected]>, Illia Volochii <[email protected]>
11
+ License-File: LICENSE.txt
12
+ Keywords: filepost,http,httplib,https,pooling,ssl,threadsafe,urllib
13
+ Classifier: Environment :: Web Environment
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3 :: Only
20
+ Classifier: Programming Language :: Python :: 3.8
21
+ Classifier: Programming Language :: Python :: 3.9
22
+ Classifier: Programming Language :: Python :: 3.10
23
+ Classifier: Programming Language :: Python :: 3.11
24
+ Classifier: Programming Language :: Python :: 3.12
25
+ Classifier: Programming Language :: Python :: 3.13
26
+ Classifier: Programming Language :: Python :: Implementation :: CPython
27
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
28
+ Classifier: Topic :: Internet :: WWW/HTTP
29
+ Classifier: Topic :: Software Development :: Libraries
30
+ Requires-Python: >=3.8
31
+ Provides-Extra: brotli
32
+ Requires-Dist: brotli>=1.0.9; (platform_python_implementation == 'CPython') and extra == 'brotli'
33
+ Requires-Dist: brotlicffi>=0.8.0; (platform_python_implementation != 'CPython') and extra == 'brotli'
34
+ Provides-Extra: h2
35
+ Requires-Dist: h2<5,>=4; extra == 'h2'
36
+ Provides-Extra: socks
37
+ Requires-Dist: pysocks!=1.5.7,<2.0,>=1.5.6; extra == 'socks'
38
+ Provides-Extra: zstd
39
+ Requires-Dist: zstandard>=0.18.0; extra == 'zstd'
40
+ Description-Content-Type: text/markdown
41
+
42
+ <h1 align="center">
43
+
44
+ ![urllib3](https://github.com/urllib3/urllib3/raw/main/docs/_static/banner_github.svg)
45
+
46
+ </h1>
47
+
48
+ <p align="center">
49
+ <a href="https://pypi.org/project/urllib3"><img alt="PyPI Version" src="https://img.shields.io/pypi/v/urllib3.svg?maxAge=86400" /></a>
50
+ <a href="https://pypi.org/project/urllib3"><img alt="Python Versions" src="https://img.shields.io/pypi/pyversions/urllib3.svg?maxAge=86400" /></a>
51
+ <a href="https://discord.gg/urllib3"><img alt="Join our Discord" src="https://img.shields.io/discord/756342717725933608?color=%237289da&label=discord" /></a>
52
+ <a href="https://github.com/urllib3/urllib3/actions?query=workflow%3ACI"><img alt="Coverage Status" src="https://img.shields.io/badge/coverage-100%25-success" /></a>
53
+ <a href="https://github.com/urllib3/urllib3/actions?query=workflow%3ACI"><img alt="Build Status on GitHub" src="https://github.com/urllib3/urllib3/workflows/CI/badge.svg" /></a>
54
+ <a href="https://urllib3.readthedocs.io"><img alt="Documentation Status" src="https://readthedocs.org/projects/urllib3/badge/?version=latest" /></a><br>
55
+ <a href="https://deps.dev/pypi/urllib3"><img alt="OpenSSF Scorecard" src="https://api.securityscorecards.dev/projects/github.com/urllib3/urllib3/badge" /></a>
56
+ <a href="https://slsa.dev"><img alt="SLSA 3" src="https://slsa.dev/images/gh-badge-level3.svg" /></a>
57
+ <a href="https://bestpractices.coreinfrastructure.org/projects/6227"><img alt="CII Best Practices" src="https://bestpractices.coreinfrastructure.org/projects/6227/badge" /></a>
58
+ </p>
59
+
60
+ urllib3 is a powerful, *user-friendly* HTTP client for Python. Much of the
61
+ Python ecosystem already uses urllib3 and you should too.
62
+ urllib3 brings many critical features that are missing from the Python
63
+ standard libraries:
64
+
65
+ - Thread safety.
66
+ - Connection pooling.
67
+ - Client-side SSL/TLS verification.
68
+ - File uploads with multipart encoding.
69
+ - Helpers for retrying requests and dealing with HTTP redirects.
70
+ - Support for gzip, deflate, brotli, and zstd encoding.
71
+ - Proxy support for HTTP and SOCKS.
72
+ - 100% test coverage.
73
+
74
+ urllib3 is powerful and easy to use:
75
+
76
+ ```python3
77
+ >>> import urllib3
78
+ >>> resp = urllib3.request("GET", "http://httpbin.org/robots.txt")
79
+ >>> resp.status
80
+ 200
81
+ >>> resp.data
82
+ b"User-agent: *\nDisallow: /deny\n"
83
+ ```
84
+
85
+ ## Installing
86
+
87
+ urllib3 can be installed with [pip](https://pip.pypa.io):
88
+
89
+ ```bash
90
+ $ python -m pip install urllib3
91
+ ```
92
+
93
+ Alternatively, you can grab the latest source code from [GitHub](https://github.com/urllib3/urllib3):
94
+
95
+ ```bash
96
+ $ git clone https://github.com/urllib3/urllib3.git
97
+ $ cd urllib3
98
+ $ pip install .
99
+ ```
100
+
101
+
102
+ ## Documentation
103
+
104
+ urllib3 has usage and reference documentation at [urllib3.readthedocs.io](https://urllib3.readthedocs.io).
105
+
106
+
107
+ ## Community
108
+
109
+ urllib3 has a [community Discord channel](https://discord.gg/urllib3) for asking questions and
110
+ collaborating with other contributors. Drop by and say hello 👋
111
+
112
+
113
+ ## Contributing
114
+
115
+ urllib3 happily accepts contributions. Please see our
116
+ [contributing documentation](https://urllib3.readthedocs.io/en/latest/contributing.html)
117
+ for some tips on getting started.
118
+
119
+
120
+ ## Security Disclosures
121
+
122
+ To report a security vulnerability, please use the
123
+ [Tidelift security contact](https://tidelift.com/security).
124
+ Tidelift will coordinate the fix and disclosure with maintainers.
125
+
126
+
127
+ ## Maintainers
128
+
129
+ - [@sethmlarson](https://github.com/sethmlarson) (Seth M. Larson)
130
+ - [@pquentin](https://github.com/pquentin) (Quentin Pradet)
131
+ - [@illia-v](https://github.com/illia-v) (Illia Volochii)
132
+ - [@theacodes](https://github.com/theacodes) (Thea Flowers)
133
+ - [@haikuginger](https://github.com/haikuginger) (Jess Shapiro)
134
+ - [@lukasa](https://github.com/lukasa) (Cory Benfield)
135
+ - [@sigmavirus24](https://github.com/sigmavirus24) (Ian Stapleton Cordasco)
136
+ - [@shazow](https://github.com/shazow) (Andrey Petrov)
137
+
138
+ 👋
139
+
140
+
141
+ ## Sponsorship
142
+
143
+ If your company benefits from this library, please consider [sponsoring its
144
+ development](https://urllib3.readthedocs.io/en/latest/sponsors.html).
145
+
146
+
147
+ ## For Enterprise
148
+
149
+ Professional support for urllib3 is available as part of the [Tidelift
150
+ Subscription][1]. Tidelift gives software development teams a single source for
151
+ purchasing and maintaining their software, with professional grade assurances
152
+ from the experts who know it best, while seamlessly integrating with existing
153
+ tools.
154
+
155
+ [1]: https://tidelift.com/subscription/pkg/pypi-urllib3?utm_source=pypi-urllib3&utm_medium=referral&utm_campaign=readme
.venv/Lib/site-packages/urllib3-2.2.3.dist-info/RECORD ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ urllib3-2.2.3.dist-info/METADATA,sha256=NpyLMYu-QoAmQK6pmmgoZRuq0HPt-lf_J9zIuCGMRNY,6485
2
+ urllib3-2.2.3.dist-info/RECORD,,
3
+ urllib3-2.2.3.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
4
+ urllib3-2.2.3.dist-info/licenses/LICENSE.txt,sha256=Ew46ZNX91dCWp1JpRjSn2d8oRGnehuVzIQAmgEHj1oY,1093
5
+ urllib3-2.2.3.dist-info\INSTALLER,sha256=5hhM4Q4mYTT9z6QB6PGpUAW81PGNFrYrdXMj4oM_6ak,2
6
+ urllib3-2.2.3.dist-info\REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ urllib3/__init__.py,sha256=JMo1tg1nIV1AeJ2vENC_Txfl0e5h6Gzl9DGVk1rWRbo,6979
8
+ urllib3/_base_connection.py,sha256=tH0ZlOxWKika-S9NW-MuIlI_PLFQUUmSnoE_9MeywkM,5652
9
+ urllib3/_collections.py,sha256=aGhh9zCYce3o-5FW9DPSUay6O9LjHx8z6T7wDtdhrkY,17370
10
+ urllib3/_request_methods.py,sha256=LTDxHenEP5XX-tVWBNkEkAgizCERkZF0JK-F-wCxqwI,9938
11
+ urllib3/_version.py,sha256=gF7zM8AsdLRqhgteXesNHb7_t8ukr2zzkok2g1nvvhA,411
12
+ urllib3/connection.py,sha256=QAwhOV5GOVdsFnMvX5Vv6fQ8f47EzfrROAArfxRdQOY,39508
13
+ urllib3/connectionpool.py,sha256=5fPIHypPwlbKBASMs6bESTEJVEGlsj9FOY9_GGU2GpM,43393
14
+ urllib3/contrib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
+ urllib3/contrib/emscripten/__init__.py,sha256=u6KNgzjlFZbuAAXa_ybCR7gQ71VJESnF-IIdDA73brw,733
16
+ urllib3/contrib/emscripten/connection.py,sha256=kaBe2tWt7Yy9vNUFRBV7CSyDnfhCYILGxju9KTZj8Sw,8755
17
+ urllib3/contrib/emscripten/emscripten_fetch_worker.js,sha256=CDfYF_9CDobtx2lGidyJ1zjDEvwNT5F-dchmVWXDh0E,3655
18
+ urllib3/contrib/emscripten/fetch.py,sha256=ymwJlHBBuw6WTpKgPHpdmmrNBxlsr75HqoD4Rn27YXk,14131
19
+ urllib3/contrib/emscripten/request.py,sha256=mL28szy1KvE3NJhWor5jNmarp8gwplDU-7gwGZY5g0Q,566
20
+ urllib3/contrib/emscripten/response.py,sha256=wEYWPHCL-JsgCtpCpfnWGYA1-DcjDGpFGqWCXZLwbHY,10017
21
+ urllib3/contrib/pyopenssl.py,sha256=9iP4j8JafA4hqtX9AgJ9zxrqI-icohGrqFqAMryoNdA,19338
22
+ urllib3/contrib/socks.py,sha256=-iardc61GypsJzD6W6yuRS7KVCyfowcQrl_719H7lIM,7549
23
+ urllib3/exceptions.py,sha256=RDaiudtR7rqbVKTKpLSgZBBtwaIqV7eZtervZV_mZag,9393
24
+ urllib3/fields.py,sha256=8vi0PeRo_pE5chPmJA07LZtMkVls4UrBS1k2xM506jM,10843
25
+ urllib3/filepost.py,sha256=-9qJT11cNGjO9dqnI20-oErZuTvNaM18xZZPCjZSbOE,2395
26
+ urllib3/http2/__init__.py,sha256=xzrASH7R5ANRkPJOot5lGnATOq3KKuyXzI42rcnwmqs,1741
27
+ urllib3/http2/connection.py,sha256=GNlp9BjI3DmfSKe1W0b9IqRBeM8Q13xd2MA3ROcJ3dY,12668
28
+ urllib3/http2/probe.py,sha256=nnAkqbhAakOiF75rz7W0udZ38Eeh_uD8fjV74N73FEI,3014
29
+ urllib3/poolmanager.py,sha256=2_L2AjVDgoQ0qBmYbX9u9QqyU1u5J37zQbtv_-ueZQA,22913
30
+ urllib3/py.typed,sha256=UaCuPFa3H8UAakbt-5G8SPacldTOGvJv18pPjUJ5gDY,93
31
+ urllib3/response.py,sha256=NS0rqwRmtwWtC_6XDqgDJN_uo-jEmBVzx0V6KCsHlwg,44801
32
+ urllib3/util/__init__.py,sha256=-qeS0QceivazvBEKDNFCAI-6ACcdDOE4TMvo7SLNlAQ,1001
33
+ urllib3/util/connection.py,sha256=0o79-5NbRfpBDyoehGPLmCA544sCSiXvx0mF9xy3GG0,4458
34
+ urllib3/util/proxy.py,sha256=seP8-Q5B6bB0dMtwPj-YcZZQ30vHuLqRu-tI0JZ2fzs,1148
35
+ urllib3/util/request.py,sha256=UrZ2g3y3stGpH8rm-Sx8-ollgeiiKI496DZXRCwxb9o,8064
36
+ urllib3/util/response.py,sha256=vQE639uoEhj1vpjEdxu5lNIhJCSUZkd7pqllUI0BZOA,3374
37
+ urllib3/util/retry.py,sha256=bj-2YUqblxLlv8THg5fxww-DM54XCbjgZXIQ71XioCY,18459
38
+ urllib3/util/ssl_.py,sha256=WN8a6KPPcvukbZ0MUlBAOkGil8bYKY8NoIYOw7QeOLI,19238
39
+ urllib3/util/ssl_match_hostname.py,sha256=gaWqixoYtQ_GKO8fcRGFj3VXeMoqyxQQuUTPgWeiL_M,5812
40
+ urllib3/util/ssltransport.py,sha256=wprBvhkgjddhhMwwEbHyP4lygHpP6SS-45Euh7oe48k,8887
41
+ urllib3/util/timeout.py,sha256=4eT1FVeZZU7h7mYD1Jq2OXNe4fxekdNvhoWUkZusRpA,10346
42
+ urllib3/util/url.py,sha256=wHORhp80RAXyTlAIkTqLFzSrkU7J34ZDxX-tN65MBZk,15213
43
+ urllib3/util/util.py,sha256=j3lbZK1jPyiwD34T8IgJzdWEZVT-4E-0vYIJi9UjeNA,1146
44
+ urllib3/util/wait.py,sha256=_ph8IrUR3sqPqi0OopQgJUlH4wzkGeM5CiyA7XGGtmI,4423
.venv/Lib/site-packages/urllib3-2.2.3.dist-info/REQUESTED ADDED
File without changes
.venv/Lib/site-packages/urllib3-2.2.3.dist-info/WHEEL ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.25.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
.venv/Lib/site-packages/urllib3-2.2.3.dist-info/licenses/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2008-2020 Andrey Petrov and contributors.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, 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,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
.venv/Lib/site-packages/urllib3/__pycache__/__init__.cpython-39.pyc ADDED
Binary file (6 kB). View file
 
.venv/Lib/site-packages/urllib3/__pycache__/_base_connection.cpython-39.pyc ADDED
Binary file (5.46 kB). View file
 
.venv/Lib/site-packages/urllib3/__pycache__/_collections.cpython-39.pyc ADDED
Binary file (15.8 kB). View file
 
.venv/Lib/site-packages/urllib3/__pycache__/_request_methods.cpython-39.pyc ADDED
Binary file (8.94 kB). View file
 
.venv/Lib/site-packages/urllib3/__pycache__/_version.cpython-39.pyc ADDED
Binary file (502 Bytes). View file
 
.venv/Lib/site-packages/urllib3/__pycache__/connection.cpython-39.pyc ADDED
Binary file (23.3 kB). View file
 
.venv/Lib/site-packages/urllib3/__pycache__/connectionpool.cpython-39.pyc ADDED
Binary file (28.6 kB). View file
 
.venv/Lib/site-packages/urllib3/__pycache__/exceptions.cpython-39.pyc ADDED
Binary file (13.6 kB). View file
 
.venv/Lib/site-packages/urllib3/__pycache__/fields.cpython-39.pyc ADDED
Binary file (9.64 kB). View file
 
.venv/Lib/site-packages/urllib3/__pycache__/filepost.cpython-39.pyc ADDED
Binary file (2.32 kB). View file
 
.venv/Lib/site-packages/urllib3/__pycache__/poolmanager.cpython-39.pyc ADDED
Binary file (17.8 kB). View file
 
.venv/Lib/site-packages/urllib3/__pycache__/response.cpython-39.pyc ADDED
Binary file (33.1 kB). View file
 
.venv/Lib/site-packages/urllib3/util/__pycache__/__init__.cpython-39.pyc ADDED
Binary file (967 Bytes). View file
 
.venv/Lib/site-packages/urllib3/util/__pycache__/response.cpython-39.pyc ADDED
Binary file (2.31 kB). View file
 
.venv/Lib/site-packages/urllib3/util/__pycache__/retry.cpython-39.pyc ADDED
Binary file (15.3 kB). View file
 
.venv/Lib/site-packages/urllib3/util/__pycache__/ssl_.cpython-39.pyc ADDED
Binary file (12.1 kB). View file
 
.venv/Lib/site-packages/urllib3/util/__pycache__/ssl_match_hostname.cpython-39.pyc ADDED
Binary file (3.66 kB). View file
 
.venv/Lib/site-packages/urllib3/util/__pycache__/ssltransport.cpython-39.pyc ADDED
Binary file (9.16 kB). View file
 
.venv/Lib/site-packages/urllib3/util/__pycache__/timeout.cpython-39.pyc ADDED
Binary file (9.53 kB). View file
 
.venv/Lib/site-packages/urllib3/util/__pycache__/url.cpython-39.pyc ADDED
Binary file (11 kB). View file
 
.venv/Lib/site-packages/urllib3/util/__pycache__/util.cpython-39.pyc ADDED
Binary file (1.25 kB). View file
 
.venv/Lib/site-packages/urllib3/util/__pycache__/wait.cpython-39.pyc ADDED
Binary file (2.39 kB). View file
 
.venv/Lib/site-packages/wasabi/__init__.py ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # coding: utf8
2
+ from __future__ import unicode_literals
3
+
4
+ from .printer import Printer # noqa
5
+ from .tables import table, row # noqa
6
+ from .traceback_printer import TracebackPrinter # noqa
7
+ from .markdown import MarkdownRenderer # noqa
8
+ from .util import color, wrap, get_raw_input, format_repr, diff_strings # noqa
9
+ from .util import MESSAGES # noqa
10
+ from .about import __version__ # noqa
11
+
12
+ msg = Printer()
.venv/Lib/site-packages/wasabi/about.py ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ __title__ = "wasabi"
2
+ __version__ = "0.10.1"
3
+ __summary__ = "A lightweight console printing and formatting toolkit"
4
+ __uri__ = "https://ines.io"
5
+ __author__ = "Ines Montani"
6
+ __email__ = "[email protected]"
7
+ __license__ = "MIT"
.venv/Lib/site-packages/wasabi/markdown.py ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # coding: utf8
2
+ from __future__ import unicode_literals, print_function
3
+
4
+
5
+ class MarkdownRenderer:
6
+ """Simple helper for generating raw Markdown."""
7
+
8
+ def __init__(self, no_emoji=False):
9
+ """Initialize the renderer.
10
+
11
+ no_emoji (bool): Don't show emoji in titles etc.
12
+ """
13
+ self.data = []
14
+ self.no_emoji = no_emoji
15
+
16
+ @property
17
+ def text(self):
18
+ """RETURNS (str): The Markdown document."""
19
+ return "\n\n".join(self.data)
20
+
21
+ def add(self, content):
22
+ """Add a string to the Markdown document.
23
+
24
+ content (str): Add content to the document.
25
+ """
26
+ self.data.append(content)
27
+
28
+ def table(self, data, header, aligns=None):
29
+ """Create a Markdown table.
30
+
31
+ data (Iterable[Iterable[str]]): The body, one iterable per row,
32
+ containig an interable of column contents.
33
+ header (Iterable[str]): The column names.
34
+ RETURNS (str): The rendered table.
35
+ """
36
+ if aligns is None:
37
+ aligns = ["l"] * len(header)
38
+ if len(aligns) != len(header):
39
+ err = "Invalid aligns: {} (header length: {})".format(aligns, len(header))
40
+ raise ValueError(err)
41
+ get_divider = lambda a: ":---:" if a == "c" else "---:" if a == "r" else "---"
42
+ head = "| {} |".format(" | ".join(header))
43
+ divider = "| {} |".format(
44
+ " | ".join(get_divider(aligns[i]) for i in range(len(header)))
45
+ )
46
+ body = "\n".join("| {} |".format(" | ".join(row)) for row in data)
47
+ return "{}\n{}\n{}".format(head, divider, body)
48
+
49
+ def title(self, level, text, emoji=None):
50
+ """Create a Markdown heading.
51
+
52
+ level (int): The heading level, e.g. 3 for ###
53
+ text (str): The heading text.
54
+ emoji (str): Optional emoji to show before heading text, if enabled.
55
+ RETURNS (str): The rendered title.
56
+ """
57
+ prefix = "{} ".format(emoji) if emoji and not self.no_emoji else ""
58
+ return "{} {}{}".format("#" * level, prefix, text)
59
+
60
+ def list(self, items, numbered=False):
61
+ """Create a non-nested list.
62
+
63
+ items (Iterable[str]): The list items.
64
+ numbered (bool): Whether to use a numbered list.
65
+ RETURNS (str): The rendered list.
66
+ """
67
+ content = []
68
+ for i, item in enumerate(items):
69
+ if numbered:
70
+ content.append("{}. {}".format(i + 1, item))
71
+ else:
72
+ content.append("- {}".format(item))
73
+ return "\n".join(content)
74
+
75
+ def link(self, text, url):
76
+ """Create a Markdown link.
77
+
78
+ text (str): The link text.
79
+ url (str): The link URL.
80
+ RETURNS (str): The rendered link.
81
+ """
82
+ return "[{}]({})".format(text, url)
83
+
84
+ def code_block(self, text, lang=""):
85
+ """Create a Markdown code block.
86
+
87
+ text (str): The code text.
88
+ lang (str): Optional code language.
89
+ RETURNS (str): The rendered code block.
90
+ """
91
+ return "```{}\n{}\n```".format(lang, text)
92
+
93
+ def code(self, text):
94
+ """Create Markdown inline code."""
95
+ return self._wrap(text, "`")
96
+
97
+ def bold(self, text):
98
+ """Create bold text."""
99
+ return self._wrap(text, "**")
100
+
101
+ def italic(self, text):
102
+ """Create italic text."""
103
+ return self._wrap(text, "_")
104
+
105
+ def _wrap(self, text, marker):
106
+ return "{}{}{}".format(marker, text, marker)
.venv/Lib/site-packages/wasabi/printer.py ADDED
@@ -0,0 +1,250 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # coding: utf8
2
+ from __future__ import unicode_literals, print_function
3
+
4
+ import datetime
5
+ from collections import Counter
6
+ from contextlib import contextmanager
7
+ from multiprocessing import Process
8
+ import itertools
9
+ import sys
10
+ import time
11
+ import os
12
+ import traceback
13
+
14
+ from .tables import table, row
15
+ from .util import wrap, supports_ansi, can_render, locale_escape
16
+ from .util import MESSAGES, COLORS, ICONS
17
+ from .util import color as _color
18
+
19
+
20
+ class Printer(object):
21
+ def __init__(
22
+ self,
23
+ pretty=True,
24
+ no_print=False,
25
+ colors=None,
26
+ icons=None,
27
+ line_max=80,
28
+ animation="⠙⠹⠸⠼⠴⠦⠧⠇⠏",
29
+ animation_ascii="|/-\\",
30
+ hide_animation=False,
31
+ ignore_warnings=False,
32
+ env_prefix="WASABI",
33
+ timestamp=False,
34
+ ):
35
+ """Initialize the command-line printer.
36
+
37
+ pretty (bool): Pretty-print output (colors, icons).
38
+ no_print (bool): Don't actually print, just return.
39
+ colors (dict): Add or overwrite color values, name mapped to value.
40
+ icons (dict): Add or overwrite icons. Name mapped to unicode icon.
41
+ line_max (int): Maximum line length (for divider).
42
+ animation (unicode): Steps of loading animation for loading() method.
43
+ animation_ascii (unicode): Alternative animation for ASCII terminals.
44
+ hide_animation (bool): Don't display animation, e.g. for logs.
45
+ ignore_warnings (bool): Do not output messages of type MESSAGE.WARN.
46
+ env_prefix (unicode): Prefix for environment variables, e.g.
47
+ WASABI_LOG_FRIENDLY.
48
+ timestamp (bool): Print a timestamp (default False).
49
+ RETURNS (Printer): The initialized printer.
50
+ """
51
+ env_log_friendly = os.getenv("{}_LOG_FRIENDLY".format(env_prefix), False)
52
+ env_no_pretty = os.getenv("{}_NO_PRETTY".format(env_prefix), False)
53
+ self._counts = Counter()
54
+ self.pretty = pretty and not env_no_pretty
55
+ self.no_print = no_print
56
+ self.show_color = supports_ansi() and not env_log_friendly
57
+ self.hide_animation = hide_animation or env_log_friendly
58
+ self.ignore_warnings = ignore_warnings
59
+ self.line_max = line_max
60
+ self.colors = dict(COLORS)
61
+ self.icons = dict(ICONS)
62
+ self.timestamp = timestamp
63
+ if colors:
64
+ self.colors.update(colors)
65
+ if icons:
66
+ self.icons.update(icons)
67
+ self.anim = animation if can_render(animation) else animation_ascii
68
+
69
+ @property
70
+ def counts(self):
71
+ """Get the counts of how often the special printers were fired,
72
+ e.g. MESSAGES.GOOD. Can be used to print an overview like "X warnings".
73
+ """
74
+ return self._counts
75
+
76
+ def good(self, title="", text="", show=True, spaced=False, exits=None):
77
+ """Print a success message."""
78
+ return self._get_msg(
79
+ title, text, style=MESSAGES.GOOD, show=show, spaced=spaced, exits=exits
80
+ )
81
+
82
+ def fail(self, title="", text="", show=True, spaced=False, exits=None):
83
+ """Print an error message."""
84
+ return self._get_msg(
85
+ title, text, style=MESSAGES.FAIL, show=show, spaced=spaced, exits=exits
86
+ )
87
+
88
+ def warn(self, title="", text="", show=True, spaced=False, exits=None):
89
+ """Print a warning message."""
90
+ return self._get_msg(
91
+ title, text, style=MESSAGES.WARN, show=show, spaced=spaced, exits=exits
92
+ )
93
+
94
+ def info(self, title="", text="", show=True, spaced=False, exits=None):
95
+ """Print an informational message."""
96
+ return self._get_msg(
97
+ title, text, style=MESSAGES.INFO, show=show, spaced=spaced, exits=exits
98
+ )
99
+
100
+ def text(
101
+ self,
102
+ title="",
103
+ text="",
104
+ color=None,
105
+ bg_color=None,
106
+ icon=None,
107
+ spaced=False,
108
+ show=True,
109
+ no_print=False,
110
+ exits=None,
111
+ ):
112
+ """Print a message.
113
+
114
+ title (unicode): The main text to print.
115
+ text (unicode): Optional additional text to print.
116
+ color (unicode / int): Foreground color.
117
+ bg_color (unicode / int): Background color.
118
+ icon (unicode): Name of icon to add.
119
+ spaced (unicode): Whether to add newlines around the output.
120
+ show (bool): Whether to print or not. Can be used to only output
121
+ messages under certain condition, e.g. if --verbose flag is set.
122
+ no_print (bool): Don't actually print, just return.
123
+ exits (int): Perform a system exit.
124
+ """
125
+ if not show:
126
+ return
127
+ if self.pretty:
128
+ color = self.colors.get(color, color)
129
+ bg_color = self.colors.get(bg_color, bg_color)
130
+ icon = self.icons.get(icon)
131
+ if icon:
132
+ title = locale_escape("{} {}".format(icon, title)).strip()
133
+ if self.show_color:
134
+ title = _color(title, fg=color, bg=bg_color)
135
+ title = wrap(title, indent=0)
136
+ if text:
137
+ title = "{}\n{}".format(title, wrap(text, indent=0))
138
+ if self.timestamp:
139
+ now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
140
+ title = "{}\t{}".format(now, title)
141
+ if exits is not None or spaced:
142
+ title = "\n{}\n".format(title)
143
+ if not self.no_print and not no_print:
144
+ print(title)
145
+ if exits is not None:
146
+ sys.stdout.flush()
147
+ sys.stderr.flush()
148
+ if self.no_print or no_print and exits != 0:
149
+ try:
150
+ raise RuntimeError(title.strip())
151
+ except Exception as e:
152
+ # Remove wasabi from the traceback and re-raise
153
+ tb = "\n".join(traceback.format_stack()[:-3])
154
+ raise SystemExit("{}\n{}".format(tb, e))
155
+ sys.exit(exits)
156
+ if self.no_print or no_print:
157
+ return title
158
+
159
+ def divider(self, text="", char="=", show=True, icon=None):
160
+ """Print a divider with a headline:
161
+ ============================ Headline here ===========================
162
+
163
+ text (unicode): Headline text. If empty, only the line is printed.
164
+ char (unicode): Line character to repeat, e.g. =.
165
+ show (bool): Whether to print or not.
166
+ icon (unicode): Optional icon to display with title.
167
+ """
168
+ if not show:
169
+ return
170
+ if len(char) != 1:
171
+ raise ValueError(
172
+ "Divider chars need to be one character long. "
173
+ "Received: {}".format(char)
174
+ )
175
+ if self.pretty:
176
+ icon = self.icons.get(icon)
177
+ if icon:
178
+ text = locale_escape("{} {}".format(icon, text)).strip()
179
+ deco = char * (int(round((self.line_max - len(text))) / 2) - 2)
180
+ text = " {} ".format(text) if text else ""
181
+ text = _color(
182
+ "\n{deco}{text}{deco}".format(deco=deco, text=text), bold=True
183
+ )
184
+ if len(text) < self.line_max:
185
+ text = text + char * (self.line_max - len(text))
186
+ if self.no_print:
187
+ return text
188
+ print(text)
189
+
190
+ def table(self, data, **kwargs):
191
+ """Print data as a table.
192
+
193
+ data (iterable / dict): The data to render. Either a list of lists
194
+ (one per row) or a dict for two-column tables.
195
+ kwargs: Table settings. See tables.table for details.
196
+ """
197
+ title = kwargs.pop("title", None)
198
+ text = table(data, **kwargs)
199
+ if title:
200
+ self.divider(title)
201
+ if self.no_print:
202
+ return text
203
+ print(text)
204
+
205
+ def row(self, data, **kwargs):
206
+ """Print a table row.
207
+
208
+ data (iterable): The individual columns to format.
209
+ kwargs: Row settings. See tables.row for details.
210
+ """
211
+ text = row(data, **kwargs)
212
+ if self.no_print:
213
+ return text
214
+ print(text)
215
+
216
+ @contextmanager
217
+ def loading(self, text="Loading..."):
218
+ if self.no_print:
219
+ yield
220
+ elif self.hide_animation:
221
+ print(text)
222
+ yield
223
+ else:
224
+ sys.stdout.flush()
225
+ t = Process(target=self._spinner, args=(text,))
226
+ t.start()
227
+ try:
228
+ yield
229
+ except Exception as e:
230
+ # Handle exception inside the with block
231
+ t.terminate()
232
+ sys.stdout.write("\n")
233
+ raise (e)
234
+ t.terminate()
235
+ sys.stdout.write("\r\x1b[2K") # erase line
236
+ sys.stdout.flush()
237
+
238
+ def _spinner(self, text="Loading..."):
239
+ for char in itertools.cycle(self.anim):
240
+ sys.stdout.write("\r{} {}".format(char, text))
241
+ sys.stdout.flush()
242
+ time.sleep(0.1)
243
+
244
+ def _get_msg(self, title, text, style=None, show=None, spaced=False, exits=None):
245
+ if self.ignore_warnings and style == MESSAGES.WARN:
246
+ show = False
247
+ self._counts[style] += 1
248
+ return self.text(
249
+ title, text, color=style, icon=style, show=show, spaced=spaced, exits=exits
250
+ )
.venv/Lib/site-packages/wasabi/tables.py ADDED
@@ -0,0 +1,154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # coding: utf8
2
+ from __future__ import unicode_literals, print_function
3
+ import os
4
+
5
+ from .util import COLORS
6
+ from .util import color as _color
7
+ from .util import supports_ansi, to_string, zip_longest, basestring_
8
+
9
+
10
+ ALIGN_MAP = {"l": "<", "r": ">", "c": "^"}
11
+
12
+
13
+ def table(
14
+ data,
15
+ header=None,
16
+ footer=None,
17
+ divider=False,
18
+ widths="auto",
19
+ max_col=30,
20
+ spacing=3,
21
+ aligns=None,
22
+ multiline=False,
23
+ env_prefix="WASABI",
24
+ color_values=None,
25
+ fg_colors=None,
26
+ bg_colors=None,
27
+ ):
28
+ """Format tabular data.
29
+
30
+ data (iterable / dict): The data to render. Either a list of lists (one per
31
+ row) or a dict for two-column tables.
32
+ header (iterable): The header columns.
33
+ footer (iterable): The footer columns.
34
+ divider (bool): Show a divider line between header/footer and body.
35
+ widths (iterable or 'auto'): Column widths in order. If "auto", widths
36
+ will be calculated automatically based on the largest value.
37
+ max_col (int): Maximum column width.
38
+ spacing (int): Spacing between columns, in spaces.
39
+ aligns (iterable / unicode): Column alignments in order. 'l' (left,
40
+ default), 'r' (right) or 'c' (center). If a string, value is used
41
+ for all columns.
42
+ multiline (bool): If a cell value is a list of a tuple, render it on
43
+ multiple lines, with one value per line.
44
+ env_prefix (unicode): Prefix for environment variables, e.g.
45
+ WASABI_LOG_FRIENDLY.
46
+ color_values (dict): Add or overwrite color values, name mapped to value.
47
+ fg_colors (iterable): Foreground colors, one per column. None can be specified
48
+ for individual columns to retain the default foreground color.
49
+ bg_colors (iterable): Background colors, one per column. None can be specified
50
+ for individual columns to retain the default background color.
51
+ RETURNS (unicode): The formatted table.
52
+ """
53
+ if fg_colors is not None or bg_colors is not None:
54
+ colors = dict(COLORS)
55
+ if color_values is not None:
56
+ colors.update(color_values)
57
+ if fg_colors is not None:
58
+ fg_colors = [colors.get(fg_color, fg_color) for fg_color in fg_colors]
59
+ if bg_colors is not None:
60
+ bg_colors = [colors.get(bg_color, bg_color) for bg_color in bg_colors]
61
+ if isinstance(data, dict):
62
+ data = list(data.items())
63
+ if multiline:
64
+ zipped_data = []
65
+ for i, item in enumerate(data):
66
+ vals = [v if isinstance(v, (list, tuple)) else [v] for v in item]
67
+ zipped_data.extend(list(zip_longest(*vals, fillvalue="")))
68
+ if i < len(data) - 1:
69
+ zipped_data.append(["" for i in item])
70
+ data = zipped_data
71
+ if widths == "auto":
72
+ widths = _get_max_widths(data, header, footer, max_col)
73
+ settings = {
74
+ "widths": widths,
75
+ "spacing": spacing,
76
+ "aligns": aligns,
77
+ "env_prefix": env_prefix,
78
+ "fg_colors": fg_colors,
79
+ "bg_colors": bg_colors,
80
+ }
81
+ divider_row = row(["-" * width for width in widths], **settings)
82
+ rows = []
83
+ if header:
84
+ rows.append(row(header, **settings))
85
+ if divider:
86
+ rows.append(divider_row)
87
+ for i, item in enumerate(data):
88
+ rows.append(row(item, **settings))
89
+ if footer:
90
+ if divider:
91
+ rows.append(divider_row)
92
+ rows.append(row(footer, **settings))
93
+ return "\n{}\n".format("\n".join(rows))
94
+
95
+
96
+ def row(
97
+ data,
98
+ widths="auto",
99
+ spacing=3,
100
+ aligns=None,
101
+ env_prefix="WASABI",
102
+ fg_colors=None,
103
+ bg_colors=None,
104
+ ):
105
+ """Format data as a table row.
106
+
107
+ data (iterable): The individual columns to format.
108
+ widths (list, int or 'auto'): Column widths, either one integer for all
109
+ columns or an iterable of values. If "auto", widths will be calculated
110
+ automatically based on the largest value.
111
+ spacing (int): Spacing between columns, in spaces.
112
+ aligns (list / unicode): Column alignments in order. 'l' (left,
113
+ default), 'r' (right) or 'c' (center). If a string, value is used
114
+ for all columns.
115
+ env_prefix (unicode): Prefix for environment variables, e.g.
116
+ WASABI_LOG_FRIENDLY.
117
+ fg_colors (list): Foreground colors for the columns, in order. None can be
118
+ specified for individual columns to retain the default foreground color.
119
+ bg_colors (list): Background colors for the columns, in order. None can be
120
+ specified for individual columns to retain the default background color.
121
+ RETURNS (unicode): The formatted row.
122
+ """
123
+ env_log_friendly = os.getenv("{}_LOG_FRIENDLY".format(env_prefix), False)
124
+ show_colors = (
125
+ supports_ansi()
126
+ and not env_log_friendly
127
+ and (fg_colors is not None or bg_colors is not None)
128
+ )
129
+ cols = []
130
+ if isinstance(aligns, basestring_): # single align value
131
+ aligns = [aligns for _ in data]
132
+ if not hasattr(widths, "__iter__") and widths != "auto": # single number
133
+ widths = [widths for _ in range(len(data))]
134
+ for i, col in enumerate(data):
135
+ align = ALIGN_MAP.get(aligns[i] if aligns and i < len(aligns) else "l")
136
+ col_width = len(col) if widths == "auto" else widths[i]
137
+ tpl = "{:%s%d}" % (align, col_width)
138
+ col = tpl.format(to_string(col))
139
+ if show_colors:
140
+ fg = fg_colors[i] if fg_colors is not None else None
141
+ bg = bg_colors[i] if bg_colors is not None else None
142
+ col = _color(col, fg=fg, bg=bg)
143
+ cols.append(col)
144
+ return (" " * spacing).join(cols)
145
+
146
+
147
+ def _get_max_widths(data, header, footer, max_col):
148
+ all_data = list(data)
149
+ if header:
150
+ all_data.append(header)
151
+ if footer:
152
+ all_data.append(footer)
153
+ widths = [[len(to_string(col)) for col in item] for item in all_data]
154
+ return [min(max(w), max_col) for w in list(zip(*widths))]
.venv/Lib/site-packages/wasabi/tests/test_markdown.py ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # coding: utf8
2
+ from __future__ import unicode_literals, print_function
3
+
4
+ from wasabi.markdown import MarkdownRenderer
5
+ import pytest
6
+
7
+
8
+ def test_markdown():
9
+ md = MarkdownRenderer()
10
+ md.add(md.title(1, "Title"))
11
+ md.add("Paragraph with {}".format(md.bold("bold")))
12
+ md.add(md.list(["foo", "bar"]))
13
+ md.add(md.table([("a", "b"), ("c", "d")], ["foo", "bar"]))
14
+ md.add(md.code_block('import spacy\n\nnlp = spacy.blank("en")', "python"))
15
+ md.add(md.list(["first", "second"], numbered=True))
16
+ expected = """# Title\n\nParagraph with **bold**\n\n- foo\n- bar\n\n| foo | bar |\n| --- | --- |\n| a | b |\n| c | d |\n\n```python\nimport spacy\n\nnlp = spacy.blank("en")\n```\n\n1. first\n2. second"""
17
+ assert md.text == expected
18
+
19
+
20
+ def test_markdown_table_aligns():
21
+ md = MarkdownRenderer()
22
+ md.add(md.table([("a", "b", "c")], ["foo", "bar", "baz"], aligns=("c", "r", "l")))
23
+ expected = """| foo | bar | baz |\n| :---: | ---: | --- |\n| a | b | c |"""
24
+ assert md.text == expected
25
+ with pytest.raises(ValueError):
26
+ md.table([("a", "b", "c")], ["foo", "bar", "baz"], aligns=("c", "r"))
27
+ with pytest.raises(ValueError):
28
+ md.table([("a", "b", "c")], ["foo", "bar", "baz"], aligns=("c", "r", "l", "l"))
.venv/Lib/site-packages/wasabi/tests/test_printer.py ADDED
@@ -0,0 +1,239 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # coding: utf8
2
+ from __future__ import unicode_literals, print_function
3
+
4
+ import re
5
+
6
+ import pytest
7
+ import time
8
+ import os
9
+ from wasabi.printer import Printer
10
+ from wasabi.util import MESSAGES, NO_UTF8, supports_ansi
11
+
12
+
13
+ SUPPORTS_ANSI = supports_ansi()
14
+
15
+
16
+ def test_printer():
17
+ p = Printer(no_print=True)
18
+ text = "This is a test."
19
+ good = p.good(text)
20
+ fail = p.fail(text)
21
+ warn = p.warn(text)
22
+ info = p.info(text)
23
+ assert p.text(text) == text
24
+ if SUPPORTS_ANSI and not NO_UTF8:
25
+ assert good == "\x1b[38;5;2m\u2714 {}\x1b[0m".format(text)
26
+ assert fail == "\x1b[38;5;1m\u2718 {}\x1b[0m".format(text)
27
+ assert warn == "\x1b[38;5;3m\u26a0 {}\x1b[0m".format(text)
28
+ assert info == "\x1b[38;5;4m\u2139 {}\x1b[0m".format(text)
29
+ if SUPPORTS_ANSI and NO_UTF8:
30
+ assert good == "\x1b[38;5;2m[+] {}\x1b[0m".format(text)
31
+ assert fail == "\x1b[38;5;1m[x] {}\x1b[0m".format(text)
32
+ assert warn == "\x1b[38;5;3m[!] {}\x1b[0m".format(text)
33
+ assert info == "\x1b[38;5;4m[i] {}\x1b[0m".format(text)
34
+ if not SUPPORTS_ANSI and not NO_UTF8:
35
+ assert good == "\u2714 {}".format(text)
36
+ assert fail == "\u2718 {}".format(text)
37
+ assert warn == "\u26a0 {}".format(text)
38
+ assert info == "\u2139 {}".format(text)
39
+ if not SUPPORTS_ANSI and NO_UTF8:
40
+ assert good == "[+] {}".format(text)
41
+ assert fail == "[x] {}".format(text)
42
+ assert warn == "[!] {}".format(text)
43
+ assert info == "[i] {}".format(text)
44
+
45
+
46
+ def test_printer_print():
47
+ p = Printer()
48
+ text = "This is a test."
49
+ p.good(text)
50
+ p.fail(text)
51
+ p.info(text)
52
+ p.text(text)
53
+
54
+
55
+ def test_printer_print_timestamp():
56
+ p = Printer(no_print=True, timestamp=True)
57
+ result = p.info("Hello world")
58
+ matches = re.match("^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}", result)
59
+ assert matches
60
+
61
+
62
+ def test_printer_no_pretty():
63
+ p = Printer(no_print=True, pretty=False)
64
+ text = "This is a test."
65
+ assert p.good(text) == text
66
+ assert p.fail(text) == text
67
+ assert p.warn(text) == text
68
+ assert p.info(text) == text
69
+ assert p.text(text) == text
70
+
71
+
72
+ def test_printer_custom():
73
+ colors = {"yellow": 220, "purple": 99}
74
+ icons = {"warn": "\u26a0\ufe0f", "question": "?"}
75
+ p = Printer(no_print=True, colors=colors, icons=icons)
76
+ text = "This is a test."
77
+ purple_question = p.text(text, color="purple", icon="question")
78
+ warning = p.warn(text)
79
+ if SUPPORTS_ANSI and not NO_UTF8:
80
+ assert purple_question == "\x1b[38;5;99m? {}\x1b[0m".format(text)
81
+ assert warning == "\x1b[38;5;3m\u26a0\ufe0f {}\x1b[0m".format(text)
82
+ if SUPPORTS_ANSI and NO_UTF8:
83
+ assert purple_question == "\x1b[38;5;99m? {}\x1b[0m".format(text)
84
+ assert warning == "\x1b[38;5;3m?? {}\x1b[0m".format(text)
85
+ if not SUPPORTS_ANSI and not NO_UTF8:
86
+ assert purple_question == "? {}".format(text)
87
+ assert warning == "\u26a0\ufe0f {}".format(text)
88
+ if not SUPPORTS_ANSI and NO_UTF8:
89
+ assert purple_question == "? {}".format(text)
90
+ assert warning == "?? {}".format(text)
91
+
92
+
93
+ def test_color_as_int():
94
+ p = Printer(no_print=True)
95
+ text = "This is a text."
96
+ result = p.text(text, color=220)
97
+ if SUPPORTS_ANSI:
98
+ assert result == "\x1b[38;5;220mThis is a text.\x1b[0m"
99
+ else:
100
+ assert result == "This is a text."
101
+
102
+
103
+ def test_bg_color():
104
+ p = Printer(no_print=True)
105
+ text = "This is a text."
106
+ result = p.text(text, bg_color="red")
107
+ print(result)
108
+ if SUPPORTS_ANSI:
109
+ assert result == "\x1b[48;5;1mThis is a text.\x1b[0m"
110
+ else:
111
+ assert result == "This is a text."
112
+
113
+
114
+ def test_bg_color_as_int():
115
+ p = Printer(no_print=True)
116
+ text = "This is a text."
117
+ result = p.text(text, bg_color=220)
118
+ print(result)
119
+ if SUPPORTS_ANSI:
120
+ assert result == "\x1b[48;5;220mThis is a text.\x1b[0m"
121
+ else:
122
+ assert result == "This is a text."
123
+
124
+
125
+ def test_color_and_bc_color():
126
+ p = Printer(no_print=True)
127
+ text = "This is a text."
128
+ result = p.text(text, color="green", bg_color="yellow")
129
+ print(result)
130
+ if SUPPORTS_ANSI:
131
+ assert result == "\x1b[38;5;2;48;5;3mThis is a text.\x1b[0m"
132
+ else:
133
+ assert result == "This is a text."
134
+
135
+
136
+ def test_printer_counts():
137
+ p = Printer()
138
+ text = "This is a test."
139
+ for i in range(2):
140
+ p.good(text)
141
+ for i in range(1):
142
+ p.fail(text)
143
+ for i in range(4):
144
+ p.warn(text)
145
+ assert p.counts[MESSAGES.GOOD] == 2
146
+ assert p.counts[MESSAGES.FAIL] == 1
147
+ assert p.counts[MESSAGES.WARN] == 4
148
+
149
+
150
+ def test_printer_spaced():
151
+ p = Printer(no_print=True, pretty=False)
152
+ text = "This is a test."
153
+ assert p.good(text) == text
154
+ assert p.good(text, spaced=True) == "\n{}\n".format(text)
155
+
156
+
157
+ def test_printer_divider():
158
+ p = Printer(line_max=20, no_print=True)
159
+ p.divider() == "\x1b[1m\n================\x1b[0m"
160
+ p.divider("test") == "\x1b[1m\n====== test ======\x1b[0m"
161
+ p.divider("test", char="*") == "\x1b[1m\n****** test ******\x1b[0m"
162
+ assert (
163
+ p.divider("This is a very long text, it is very long")
164
+ == "\x1b[1m\n This is a very long text, it is very long \x1b[0m"
165
+ )
166
+ with pytest.raises(ValueError):
167
+ p.divider("test", char="~.")
168
+
169
+
170
+ @pytest.mark.parametrize("hide_animation", [False, True])
171
+ def test_printer_loading(hide_animation):
172
+ p = Printer(hide_animation=hide_animation)
173
+ print("\n")
174
+ with p.loading("Loading..."):
175
+ time.sleep(1)
176
+ p.good("Success!")
177
+
178
+ with p.loading("Something else..."):
179
+ time.sleep(2)
180
+ p.good("Yo!")
181
+
182
+ with p.loading("Loading..."):
183
+ time.sleep(1)
184
+ p.good("Success!")
185
+
186
+
187
+ def test_printer_loading_raises_exception():
188
+ def loading_with_exception():
189
+ p = Printer()
190
+ print("\n")
191
+ with p.loading():
192
+ raise Exception("This is an error.")
193
+
194
+ with pytest.raises(Exception):
195
+ loading_with_exception()
196
+
197
+
198
+ def test_printer_loading_no_print():
199
+ p = Printer(no_print=True)
200
+ with p.loading("Loading..."):
201
+ time.sleep(1)
202
+ p.good("Success!")
203
+
204
+
205
+ def test_printer_log_friendly():
206
+ text = "This is a test."
207
+ ENV_LOG_FRIENDLY = "WASABI_LOG_FRIENDLY"
208
+ os.environ[ENV_LOG_FRIENDLY] = "True"
209
+ p = Printer(no_print=True)
210
+ assert p.good(text) in ("\u2714 This is a test.", "[+] This is a test.")
211
+ del os.environ[ENV_LOG_FRIENDLY]
212
+
213
+
214
+ def test_printer_log_friendly_prefix():
215
+ text = "This is a test."
216
+ ENV_LOG_FRIENDLY = "CUSTOM_LOG_FRIENDLY"
217
+ os.environ[ENV_LOG_FRIENDLY] = "True"
218
+ p = Printer(no_print=True, env_prefix="CUSTOM")
219
+ assert p.good(text) in ("\u2714 This is a test.", "[+] This is a test.")
220
+ print(p.good(text))
221
+ del os.environ[ENV_LOG_FRIENDLY]
222
+
223
+
224
+ @pytest.mark.skip(reason="Now seems to raise TypeError: readonly attribute?")
225
+ def test_printer_none_encoding(monkeypatch):
226
+ """Test that printer works even if sys.stdout.encoding is set to None. This
227
+ previously caused a very confusing error."""
228
+ monkeypatch.setattr("sys.stdout.encoding", None)
229
+ p = Printer() # noqa: F841
230
+
231
+
232
+ def test_printer_no_print_raise_on_exit():
233
+ """Test that the printer raises if a non-zero exit code is provided, even
234
+ if no_print is set to True."""
235
+ err = "This is an error."
236
+ p = Printer(no_print=True, pretty=False)
237
+ with pytest.raises(SystemExit) as e:
238
+ p.fail(err, exits=True)
239
+ assert str(e.value).strip()[-len(err) :] == err
.venv/Lib/site-packages/wasabi/tests/test_tables.py ADDED
@@ -0,0 +1,422 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # coding: utf8
2
+ from __future__ import unicode_literals, print_function
3
+
4
+ import os
5
+ import pytest
6
+ from wasabi.tables import table, row
7
+ from wasabi.util import supports_ansi
8
+
9
+ SUPPORTS_ANSI = supports_ansi()
10
+
11
+
12
+ @pytest.fixture()
13
+ def data():
14
+ return [("Hello", "World", "12344342"), ("This is a test", "World", "1234")]
15
+
16
+
17
+ @pytest.fixture()
18
+ def header():
19
+ return ["COL A", "COL B", "COL 3"]
20
+
21
+
22
+ @pytest.fixture()
23
+ def footer():
24
+ return ["", "", "2030203.00"]
25
+
26
+
27
+ @pytest.fixture()
28
+ def fg_colors():
29
+ return ["", "yellow", "87"]
30
+
31
+
32
+ @pytest.fixture()
33
+ def bg_colors():
34
+ return ["green", "23", ""]
35
+
36
+
37
+ def test_table_default(data):
38
+ result = table(data)
39
+ assert (
40
+ result
41
+ == "\nHello World 12344342\nThis is a test World 1234 \n"
42
+ )
43
+
44
+
45
+ def test_table_header(data, header):
46
+ result = table(data, header=header)
47
+ assert (
48
+ result
49
+ == "\nCOL A COL B COL 3 \nHello World 12344342\nThis is a test World 1234 \n"
50
+ )
51
+
52
+
53
+ def test_table_header_footer_divider(data, header, footer):
54
+ result = table(data, header=header, footer=footer, divider=True)
55
+ assert (
56
+ result
57
+ == "\nCOL A COL B COL 3 \n-------------- ----- ----------\nHello World 12344342 \nThis is a test World 1234 \n-------------- ----- ----------\n 2030203.00\n"
58
+ )
59
+
60
+
61
+ def test_table_aligns(data):
62
+ result = table(data, aligns=("r", "c", "l"))
63
+ assert (
64
+ result
65
+ == "\n Hello World 12344342\nThis is a test World 1234 \n"
66
+ )
67
+
68
+
69
+ def test_table_aligns_single(data):
70
+ result = table(data, aligns="r")
71
+ assert (
72
+ result
73
+ == "\n Hello World 12344342\nThis is a test World 1234\n"
74
+ )
75
+
76
+
77
+ def test_table_widths():
78
+ data = [("a", "bb", "ccc"), ("d", "ee", "fff")]
79
+ widths = (5, 2, 10)
80
+ result = table(data, widths=widths)
81
+ assert result == "\na bb ccc \nd ee fff \n"
82
+
83
+
84
+ def test_row_single_widths():
85
+ data = ("a", "bb", "ccc")
86
+ result = row(data, widths=10)
87
+ assert result == "a bb ccc "
88
+
89
+
90
+ def test_table_multiline(header):
91
+ data = [
92
+ ("hello", ["foo", "bar", "baz"], "world"),
93
+ ("hello", "world", ["world 1", "world 2"]),
94
+ ]
95
+ result = table(data, header=header, divider=True, multiline=True)
96
+ assert (
97
+ result
98
+ == "\nCOL A COL B COL 3 \n----- ----- -------\nhello foo world \n bar \n baz \n \nhello world world 1\n world 2\n"
99
+ )
100
+
101
+
102
+ def test_row_fg_colors(fg_colors):
103
+ result = row(("Hello", "World", "12344342"), fg_colors=fg_colors)
104
+ if SUPPORTS_ANSI:
105
+ assert (
106
+ result == "Hello \x1b[38;5;3mWorld\x1b[0m \x1b[38;5;87m12344342\x1b[0m"
107
+ )
108
+ else:
109
+ assert result == "Hello World 12344342"
110
+
111
+
112
+ def test_row_bg_colors(bg_colors):
113
+ result = row(("Hello", "World", "12344342"), bg_colors=bg_colors)
114
+ if SUPPORTS_ANSI:
115
+ assert (
116
+ result == "\x1b[48;5;2mHello\x1b[0m \x1b[48;5;23mWorld\x1b[0m 12344342"
117
+ )
118
+ else:
119
+ assert result == "Hello World 12344342"
120
+
121
+
122
+ def test_row_fg_colors_and_bg_colors(fg_colors, bg_colors):
123
+ result = row(
124
+ ("Hello", "World", "12344342"), fg_colors=fg_colors, bg_colors=bg_colors
125
+ )
126
+ if SUPPORTS_ANSI:
127
+ assert (
128
+ result
129
+ == "\x1b[48;5;2mHello\x1b[0m \x1b[38;5;3;48;5;23mWorld\x1b[0m \x1b[38;5;87m12344342\x1b[0m"
130
+ )
131
+ else:
132
+ assert result == "Hello World 12344342"
133
+
134
+
135
+ def test_row_fg_colors_and_bg_colors_log_friendly(fg_colors, bg_colors):
136
+ ENV_LOG_FRIENDLY = "WASABI_LOG_FRIENDLY"
137
+ os.environ[ENV_LOG_FRIENDLY] = "True"
138
+ result = row(
139
+ ("Hello", "World", "12344342"), fg_colors=fg_colors, bg_colors=bg_colors
140
+ )
141
+ assert result == "Hello World 12344342"
142
+ del os.environ[ENV_LOG_FRIENDLY]
143
+
144
+
145
+ def test_row_fg_colors_and_bg_colors_log_friendly_prefix(fg_colors, bg_colors):
146
+ ENV_LOG_FRIENDLY = "CUSTOM_LOG_FRIENDLY"
147
+ os.environ[ENV_LOG_FRIENDLY] = "True"
148
+ result = row(
149
+ ("Hello", "World", "12344342"),
150
+ fg_colors=fg_colors,
151
+ bg_colors=bg_colors,
152
+ env_prefix="CUSTOM",
153
+ )
154
+ assert result == "Hello World 12344342"
155
+ del os.environ[ENV_LOG_FRIENDLY]
156
+
157
+
158
+ def test_row_fg_colors_and_bg_colors_supports_ansi_false(fg_colors, bg_colors):
159
+ os.environ["ANSI_COLORS_DISABLED"] = "True"
160
+ result = row(
161
+ ("Hello", "World", "12344342"), fg_colors=fg_colors, bg_colors=bg_colors
162
+ )
163
+ assert result == "Hello World 12344342"
164
+ del os.environ["ANSI_COLORS_DISABLED"]
165
+
166
+
167
+ def test_colors_whole_table_with_automatic_widths(
168
+ data, header, footer, fg_colors, bg_colors
169
+ ):
170
+ result = table(
171
+ data,
172
+ header=header,
173
+ footer=footer,
174
+ divider=True,
175
+ fg_colors=fg_colors,
176
+ bg_colors=bg_colors,
177
+ )
178
+ if SUPPORTS_ANSI:
179
+ assert (
180
+ result
181
+ == "\n\x1b[48;5;2mCOL A \x1b[0m \x1b[38;5;3;48;5;23mCOL B\x1b[0m \x1b[38;5;87mCOL 3 \x1b[0m\n\x1b[48;5;2m--------------\x1b[0m \x1b[38;5;3;48;5;23m-----\x1b[0m \x1b[38;5;87m----------\x1b[0m\n\x1b[48;5;2mHello \x1b[0m \x1b[38;5;3;48;5;23mWorld\x1b[0m \x1b[38;5;87m12344342 \x1b[0m\n\x1b[48;5;2mThis is a test\x1b[0m \x1b[38;5;3;48;5;23mWorld\x1b[0m \x1b[38;5;87m1234 \x1b[0m\n\x1b[48;5;2m--------------\x1b[0m \x1b[38;5;3;48;5;23m-----\x1b[0m \x1b[38;5;87m----------\x1b[0m\n\x1b[48;5;2m \x1b[0m \x1b[38;5;3;48;5;23m \x1b[0m \x1b[38;5;87m2030203.00\x1b[0m\n"
182
+ )
183
+ else:
184
+ assert (
185
+ result
186
+ == "\nCOL A COL B COL 3 \n-------------- ----- ----------\nHello World 12344342 \nThis is a test World 1234 \n-------------- ----- ----------\n 2030203.00\n"
187
+ )
188
+
189
+
190
+ def test_colors_whole_table_only_fg_colors(data, header, footer, fg_colors):
191
+ result = table(
192
+ data,
193
+ header=header,
194
+ footer=footer,
195
+ divider=True,
196
+ fg_colors=fg_colors,
197
+ )
198
+ if SUPPORTS_ANSI:
199
+ assert (
200
+ result
201
+ == "\nCOL A \x1b[38;5;3mCOL B\x1b[0m \x1b[38;5;87mCOL 3 \x1b[0m\n-------------- \x1b[38;5;3m-----\x1b[0m \x1b[38;5;87m----------\x1b[0m\nHello \x1b[38;5;3mWorld\x1b[0m \x1b[38;5;87m12344342 \x1b[0m\nThis is a test \x1b[38;5;3mWorld\x1b[0m \x1b[38;5;87m1234 \x1b[0m\n-------------- \x1b[38;5;3m-----\x1b[0m \x1b[38;5;87m----------\x1b[0m\n \x1b[38;5;3m \x1b[0m \x1b[38;5;87m2030203.00\x1b[0m\n"
202
+ )
203
+ else:
204
+ assert (
205
+ result
206
+ == "\nCOL A COL B COL 3 \n-------------- ----- ----------\nHello World 12344342 \nThis is a test World 1234 \n-------------- ----- ----------\n 2030203.00\n"
207
+ )
208
+
209
+
210
+ def test_colors_whole_table_only_bg_colors(data, header, footer, bg_colors):
211
+ result = table(
212
+ data,
213
+ header=header,
214
+ footer=footer,
215
+ divider=True,
216
+ bg_colors=bg_colors,
217
+ )
218
+ if SUPPORTS_ANSI:
219
+ assert (
220
+ result
221
+ == "\n\x1b[48;5;2mCOL A \x1b[0m \x1b[48;5;23mCOL B\x1b[0m COL 3 \n\x1b[48;5;2m--------------\x1b[0m \x1b[48;5;23m-----\x1b[0m ----------\n\x1b[48;5;2mHello \x1b[0m \x1b[48;5;23mWorld\x1b[0m 12344342 \n\x1b[48;5;2mThis is a test\x1b[0m \x1b[48;5;23mWorld\x1b[0m 1234 \n\x1b[48;5;2m--------------\x1b[0m \x1b[48;5;23m-----\x1b[0m ----------\n\x1b[48;5;2m \x1b[0m \x1b[48;5;23m \x1b[0m 2030203.00\n"
222
+ )
223
+ else:
224
+ assert (
225
+ result
226
+ == "\nCOL A COL B COL 3 \n-------------- ----- ----------\nHello World 12344342 \nThis is a test World 1234 \n-------------- ----- ----------\n 2030203.00\n"
227
+ )
228
+
229
+
230
+ def test_colors_whole_table_with_supplied_spacing(
231
+ data, header, footer, fg_colors, bg_colors
232
+ ):
233
+ result = table(
234
+ data,
235
+ header=header,
236
+ footer=footer,
237
+ divider=True,
238
+ fg_colors=fg_colors,
239
+ bg_colors=bg_colors,
240
+ spacing=5,
241
+ )
242
+ if SUPPORTS_ANSI:
243
+ assert (
244
+ result
245
+ == "\n\x1b[48;5;2mCOL A \x1b[0m \x1b[38;5;3;48;5;23mCOL B\x1b[0m \x1b[38;5;87mCOL 3 \x1b[0m\n\x1b[48;5;2m--------------\x1b[0m \x1b[38;5;3;48;5;23m-----\x1b[0m \x1b[38;5;87m----------\x1b[0m\n\x1b[48;5;2mHello \x1b[0m \x1b[38;5;3;48;5;23mWorld\x1b[0m \x1b[38;5;87m12344342 \x1b[0m\n\x1b[48;5;2mThis is a test\x1b[0m \x1b[38;5;3;48;5;23mWorld\x1b[0m \x1b[38;5;87m1234 \x1b[0m\n\x1b[48;5;2m--------------\x1b[0m \x1b[38;5;3;48;5;23m-----\x1b[0m \x1b[38;5;87m----------\x1b[0m\n\x1b[48;5;2m \x1b[0m \x1b[38;5;3;48;5;23m \x1b[0m \x1b[38;5;87m2030203.00\x1b[0m\n"
246
+ )
247
+ else:
248
+ assert (
249
+ result
250
+ == "\nCOL A COL B COL 3 \n-------------- ----- ----------\nHello World 12344342 \nThis is a test World 1234 \n-------------- ----- ----------\n 2030203.00\n"
251
+ )
252
+
253
+
254
+ def test_colors_whole_table_with_supplied_widths(
255
+ data, header, footer, fg_colors, bg_colors
256
+ ):
257
+ result = table(
258
+ data,
259
+ header=header,
260
+ footer=footer,
261
+ divider=True,
262
+ fg_colors=fg_colors,
263
+ bg_colors=bg_colors,
264
+ widths=(5, 2, 10),
265
+ )
266
+ if SUPPORTS_ANSI:
267
+ assert (
268
+ result
269
+ == "\n\x1b[48;5;2mCOL A\x1b[0m \x1b[38;5;3;48;5;23mCOL B\x1b[0m \x1b[38;5;87mCOL 3 \x1b[0m\n\x1b[48;5;2m-----\x1b[0m \x1b[38;5;3;48;5;23m--\x1b[0m \x1b[38;5;87m----------\x1b[0m\n\x1b[48;5;2mHello\x1b[0m \x1b[38;5;3;48;5;23mWorld\x1b[0m \x1b[38;5;87m12344342 \x1b[0m\n\x1b[48;5;2mThis is a test\x1b[0m \x1b[38;5;3;48;5;23mWorld\x1b[0m \x1b[38;5;87m1234 \x1b[0m\n\x1b[48;5;2m-----\x1b[0m \x1b[38;5;3;48;5;23m--\x1b[0m \x1b[38;5;87m----------\x1b[0m\n\x1b[48;5;2m \x1b[0m \x1b[38;5;3;48;5;23m \x1b[0m \x1b[38;5;87m2030203.00\x1b[0m\n"
270
+ )
271
+ else:
272
+ assert (
273
+ result
274
+ == "\nCOL A COL B COL 3 \n----- -- ----------\nHello World 12344342 \nThis is a test World 1234 \n----- -- ----------\n 2030203.00\n"
275
+ )
276
+
277
+
278
+ def test_colors_whole_table_with_single_alignment(
279
+ data, header, footer, fg_colors, bg_colors
280
+ ):
281
+ result = table(
282
+ data,
283
+ header=header,
284
+ footer=footer,
285
+ divider=True,
286
+ fg_colors=fg_colors,
287
+ bg_colors=bg_colors,
288
+ aligns="r",
289
+ )
290
+ if SUPPORTS_ANSI:
291
+ assert (
292
+ result
293
+ == "\n\x1b[48;5;2m COL A\x1b[0m \x1b[38;5;3;48;5;23mCOL B\x1b[0m \x1b[38;5;87m COL 3\x1b[0m\n\x1b[48;5;2m--------------\x1b[0m \x1b[38;5;3;48;5;23m-----\x1b[0m \x1b[38;5;87m----------\x1b[0m\n\x1b[48;5;2m Hello\x1b[0m \x1b[38;5;3;48;5;23mWorld\x1b[0m \x1b[38;5;87m 12344342\x1b[0m\n\x1b[48;5;2mThis is a test\x1b[0m \x1b[38;5;3;48;5;23mWorld\x1b[0m \x1b[38;5;87m 1234\x1b[0m\n\x1b[48;5;2m--------------\x1b[0m \x1b[38;5;3;48;5;23m-----\x1b[0m \x1b[38;5;87m----------\x1b[0m\n\x1b[48;5;2m \x1b[0m \x1b[38;5;3;48;5;23m \x1b[0m \x1b[38;5;87m2030203.00\x1b[0m\n"
294
+ )
295
+ else:
296
+ assert (
297
+ result
298
+ == "\n COL A COL B COL 3\n-------------- ----- ----------\n Hello World 12344342\nThis is a test World 1234\n-------------- ----- ----------\n 2030203.00\n"
299
+ )
300
+
301
+
302
+ def test_colors_whole_table_with_multiple_alignment(
303
+ data, header, footer, fg_colors, bg_colors
304
+ ):
305
+ result = table(
306
+ data,
307
+ header=header,
308
+ footer=footer,
309
+ divider=True,
310
+ fg_colors=fg_colors,
311
+ bg_colors=bg_colors,
312
+ aligns=("c", "r", "l"),
313
+ )
314
+ if SUPPORTS_ANSI:
315
+ assert (
316
+ result
317
+ == "\n\x1b[48;5;2m COL A \x1b[0m \x1b[38;5;3;48;5;23mCOL B\x1b[0m \x1b[38;5;87mCOL 3 \x1b[0m\n\x1b[48;5;2m--------------\x1b[0m \x1b[38;5;3;48;5;23m-----\x1b[0m \x1b[38;5;87m----------\x1b[0m\n\x1b[48;5;2m Hello \x1b[0m \x1b[38;5;3;48;5;23mWorld\x1b[0m \x1b[38;5;87m12344342 \x1b[0m\n\x1b[48;5;2mThis is a test\x1b[0m \x1b[38;5;3;48;5;23mWorld\x1b[0m \x1b[38;5;87m1234 \x1b[0m\n\x1b[48;5;2m--------------\x1b[0m \x1b[38;5;3;48;5;23m-----\x1b[0m \x1b[38;5;87m----------\x1b[0m\n\x1b[48;5;2m \x1b[0m \x1b[38;5;3;48;5;23m \x1b[0m \x1b[38;5;87m2030203.00\x1b[0m\n"
318
+ )
319
+ else:
320
+ assert (
321
+ result
322
+ == "\n COL A COL B COL 3 \n-------------- ----- ----------\n Hello World 12344342 \nThis is a test World 1234 \n-------------- ----- ----------\n 2030203.00\n"
323
+ )
324
+
325
+
326
+ def test_colors_whole_table_with_multiline(data, header, footer, fg_colors, bg_colors):
327
+ result = table(
328
+ data=((["Charles", "Quinton", "Murphy"], "my", "brother"), ("1", "2", "3")),
329
+ fg_colors=fg_colors,
330
+ bg_colors=bg_colors,
331
+ multiline=True,
332
+ )
333
+ if SUPPORTS_ANSI:
334
+ assert (
335
+ result
336
+ == "\n\x1b[48;5;2mCharles\x1b[0m \x1b[38;5;3;48;5;23mmy\x1b[0m \x1b[38;5;87mbrother\x1b[0m\n\x1b[48;5;2mQuinton\x1b[0m \x1b[38;5;3;48;5;23m \x1b[0m \x1b[38;5;87m \x1b[0m\n\x1b[48;5;2mMurphy \x1b[0m \x1b[38;5;3;48;5;23m \x1b[0m \x1b[38;5;87m \x1b[0m\n\x1b[48;5;2m \x1b[0m \x1b[38;5;3;48;5;23m \x1b[0m \x1b[38;5;87m \x1b[0m\n\x1b[48;5;2m1 \x1b[0m \x1b[38;5;3;48;5;23m2 \x1b[0m \x1b[38;5;87m3 \x1b[0m\n"
337
+ )
338
+ else:
339
+ assert (
340
+ result
341
+ == "\nCharles my brother\nQuinton \nMurphy \n \n1 2 3 \n"
342
+ )
343
+
344
+
345
+ def test_colors_whole_table_log_friendly(data, header, footer, fg_colors, bg_colors):
346
+ ENV_LOG_FRIENDLY = "WASABI_LOG_FRIENDLY"
347
+ os.environ[ENV_LOG_FRIENDLY] = "True"
348
+ result = table(
349
+ data,
350
+ header=header,
351
+ footer=footer,
352
+ divider=True,
353
+ fg_colors=fg_colors,
354
+ bg_colors=bg_colors,
355
+ )
356
+ assert (
357
+ result
358
+ == "\nCOL A COL B COL 3 \n-------------- ----- ----------\nHello World 12344342 \nThis is a test World 1234 \n-------------- ----- ----------\n 2030203.00\n"
359
+ )
360
+ del os.environ[ENV_LOG_FRIENDLY]
361
+
362
+
363
+ def test_colors_whole_table_log_friendly_prefix(
364
+ data, header, footer, fg_colors, bg_colors
365
+ ):
366
+ ENV_LOG_FRIENDLY = "CUSTOM_LOG_FRIENDLY"
367
+ os.environ[ENV_LOG_FRIENDLY] = "True"
368
+ result = table(
369
+ data,
370
+ header=header,
371
+ footer=footer,
372
+ divider=True,
373
+ fg_colors=fg_colors,
374
+ bg_colors=bg_colors,
375
+ env_prefix="CUSTOM",
376
+ )
377
+ assert (
378
+ result
379
+ == "\nCOL A COL B COL 3 \n-------------- ----- ----------\nHello World 12344342 \nThis is a test World 1234 \n-------------- ----- ----------\n 2030203.00\n"
380
+ )
381
+ del os.environ[ENV_LOG_FRIENDLY]
382
+
383
+
384
+ def test_colors_whole_table_supports_ansi_false(
385
+ data, header, footer, fg_colors, bg_colors
386
+ ):
387
+ os.environ["ANSI_COLORS_DISABLED"] = "True"
388
+ result = table(
389
+ data,
390
+ header=header,
391
+ footer=footer,
392
+ divider=True,
393
+ fg_colors=fg_colors,
394
+ bg_colors=bg_colors,
395
+ )
396
+ assert (
397
+ result
398
+ == "\nCOL A COL B COL 3 \n-------------- ----- ----------\nHello World 12344342 \nThis is a test World 1234 \n-------------- ----- ----------\n 2030203.00\n"
399
+ )
400
+ del os.environ["ANSI_COLORS_DISABLED"]
401
+
402
+
403
+ def test_colors_whole_table_color_values(data, header, footer, fg_colors, bg_colors):
404
+ result = table(
405
+ data,
406
+ header=header,
407
+ footer=footer,
408
+ divider=True,
409
+ fg_colors=fg_colors,
410
+ bg_colors=bg_colors,
411
+ color_values={"yellow": 11},
412
+ )
413
+ if SUPPORTS_ANSI:
414
+ assert (
415
+ result
416
+ == "\n\x1b[48;5;2mCOL A \x1b[0m \x1b[38;5;11;48;5;23mCOL B\x1b[0m \x1b[38;5;87mCOL 3 \x1b[0m\n\x1b[48;5;2m--------------\x1b[0m \x1b[38;5;11;48;5;23m-----\x1b[0m \x1b[38;5;87m----------\x1b[0m\n\x1b[48;5;2mHello \x1b[0m \x1b[38;5;11;48;5;23mWorld\x1b[0m \x1b[38;5;87m12344342 \x1b[0m\n\x1b[48;5;2mThis is a test\x1b[0m \x1b[38;5;11;48;5;23mWorld\x1b[0m \x1b[38;5;87m1234 \x1b[0m\n\x1b[48;5;2m--------------\x1b[0m \x1b[38;5;11;48;5;23m-----\x1b[0m \x1b[38;5;87m----------\x1b[0m\n\x1b[48;5;2m \x1b[0m \x1b[38;5;11;48;5;23m \x1b[0m \x1b[38;5;87m2030203.00\x1b[0m\n"
417
+ )
418
+ else:
419
+ assert (
420
+ result
421
+ == "\nCOL A COL B COL 3 \n-------------- ----- ----------\nHello World 12344342 \nThis is a test World 1234 \n-------------- ----- ----------\n 2030203.00\n"
422
+ )
.venv/Lib/site-packages/wasabi/tests/test_traceback.py ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # coding: utf8
2
+ from __future__ import unicode_literals, print_function
3
+
4
+ import pytest
5
+ import traceback
6
+ from wasabi.traceback_printer import TracebackPrinter
7
+
8
+
9
+ @pytest.fixture
10
+ def tb():
11
+ return traceback.extract_stack()
12
+
13
+
14
+ def test_traceback_printer(tb):
15
+ tbp = TracebackPrinter(tb_base="wasabi")
16
+ msg = tbp("Hello world", "This is a test", tb=tb)
17
+ print(msg)
18
+
19
+
20
+ def test_traceback_printer_highlight(tb):
21
+ tbp = TracebackPrinter(tb_base="wasabi")
22
+ msg = tbp("Hello world", "This is a test", tb=tb, highlight="kwargs")
23
+ print(msg)
24
+
25
+
26
+ def test_traceback_printer_custom_colors(tb):
27
+ tbp = TracebackPrinter(
28
+ tb_base="wasabi", color_error="blue", color_highlight="green", color_tb="yellow"
29
+ )
30
+ msg = tbp("Hello world", "This is a test", tb=tb, highlight="kwargs")
31
+ print(msg)
32
+
33
+
34
+ def test_traceback_printer_only_title(tb):
35
+ tbp = TracebackPrinter(tb_base="wasabi")
36
+ msg = tbp("Hello world", tb=tb)
37
+ print(msg)
38
+
39
+
40
+ def test_traceback_dot_relative_path_tb_base(tb):
41
+ tbp = TracebackPrinter(tb_base=".")
42
+ msg = tbp("Hello world", tb=tb)
43
+ print(msg)
44
+
45
+
46
+ def test_traceback_tb_base_none(tb):
47
+ tbp = TracebackPrinter()
48
+ msg = tbp("Hello world", tb=tb)
49
+ print(msg)
50
+
51
+
52
+ def test_traceback_printer_no_tb():
53
+ tbp = TracebackPrinter(tb_base="wasabi")
54
+ msg = tbp("Hello world", "This is a test")
55
+ print(msg)
56
+
57
+
58
+ def test_traceback_printer_custom_tb_range():
59
+ tbp = TracebackPrinter(tb_range_start=-10, tb_range_end=-3)
60
+ msg = tbp("Hello world", "This is a test")
61
+ print(msg)
62
+
63
+
64
+ def test_traceback_printer_custom_tb_range_start():
65
+ tbp = TracebackPrinter(tb_range_start=-1)
66
+ msg = tbp("Hello world", "This is a test")
67
+ print(msg)
.venv/Lib/site-packages/wasabi/traceback_printer.py ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # coding: utf8
2
+ from __future__ import unicode_literals, print_function
3
+ import os
4
+ from .util import color, supports_ansi, NO_UTF8
5
+
6
+
7
+ LINE_EDGE = "└─" if not NO_UTF8 else "|_"
8
+ LINE_FORK = "├─" if not NO_UTF8 else "|__"
9
+ LINE_PATH = "──" if not NO_UTF8 else "__"
10
+
11
+
12
+ class TracebackPrinter(object):
13
+ def __init__(
14
+ self,
15
+ color_error="red",
16
+ color_tb="blue",
17
+ color_highlight="yellow",
18
+ indent=2,
19
+ tb_base=None,
20
+ tb_exclude=tuple(),
21
+ tb_range_start=-5,
22
+ tb_range_end=-2,
23
+ ):
24
+ """Initialize a traceback printer.
25
+
26
+ color_error (unicode / int): Color name or code for errors.
27
+ color_tb (unicode / int): Color name or code for traceback headline.
28
+ color_highlight (unicode / int): Color name or code for highlights.
29
+ indent (int): Indentation in spaces.
30
+ tb_base (unicode): Name of directory to use to show relative paths. For
31
+ example, "thinc" will look for the last occurence of "/thinc/" in
32
+ a path and only show path to the right of it.
33
+ tb_exclude (tuple): List of filenames to exclude from traceback.
34
+ tb_range_start (int): The starting index from a traceback to include.
35
+ tb_range_end (int): The final index from a traceback to include. If None
36
+ the traceback will continue until the last record.
37
+ RETURNS (TracebackPrinter): The traceback printer.
38
+ """
39
+ self.color_error = color_error
40
+ self.color_tb = color_tb
41
+ self.color_highlight = color_highlight
42
+ self.indent = " " * indent
43
+ if tb_base == ".":
44
+ tb_base = "{}{}".format(os.getcwd(), os.path.sep)
45
+ elif tb_base is not None:
46
+ tb_base = "/{}/".format(tb_base)
47
+ self.tb_base = tb_base
48
+ self.tb_exclude = tuple(tb_exclude)
49
+ self.tb_range_start = tb_range_start
50
+ self.tb_range_end = tb_range_end
51
+ self.supports_ansi = supports_ansi()
52
+
53
+ def __call__(self, title, *texts, **settings):
54
+ """Output custom formatted tracebacks and errors.
55
+
56
+ title (unicode): The message title.
57
+ *texts (unicode): The texts to print (one per line).
58
+ highlight (unicode): Optional sequence to highlight in the traceback,
59
+ e.g. the bad value that caused the error.
60
+ tb (iterable): The traceback, e.g. generated by traceback.extract_stack().
61
+ RETURNS (unicode): The formatted traceback. Can be printed or raised
62
+ by custom exception.
63
+ """
64
+ highlight = settings.get("highlight", False)
65
+ tb = settings.get("tb", None)
66
+ if self.supports_ansi: # use first line as title
67
+ title = color(title, fg=self.color_error, bold=True)
68
+ info = "\n" + "\n".join([self.indent + text for text in texts]) if texts else ""
69
+ tb = self._get_traceback(tb, highlight) if tb else ""
70
+ msg = "\n\n{}{}{}{}\n".format(self.indent, title, info, tb)
71
+ return msg
72
+
73
+ def _get_traceback(self, tb, highlight):
74
+ # Exclude certain file names from traceback
75
+ tb = [record for record in tb if not record[0].endswith(self.tb_exclude)]
76
+ tb_range = (
77
+ tb[self.tb_range_start : self.tb_range_end]
78
+ if self.tb_range_end is not None
79
+ else tb[self.tb_range_start :]
80
+ )
81
+ tb_list = [
82
+ self._format_traceback(path, line, fn, text, i, len(tb_range), highlight)
83
+ for i, (path, line, fn, text) in enumerate(tb_range)
84
+ ]
85
+ tb_data = "\n".join(tb_list).strip()
86
+ title = "Traceback:"
87
+ if self.supports_ansi:
88
+ title = color(title, fg=self.color_tb, bold=True)
89
+ return "\n\n{indent}{title}\n{indent}{tb}".format(
90
+ title=title, tb=tb_data, indent=self.indent
91
+ )
92
+
93
+ def _format_traceback(self, path, line, fn, text, i, count, highlight):
94
+ template = "{base_indent}{indent} {fn} in {path}:{line}{text}"
95
+ indent = (LINE_EDGE if i == count - 1 else LINE_FORK) + LINE_PATH * i
96
+ if self.tb_base and self.tb_base in path:
97
+ path = path.rsplit(self.tb_base, 1)[1]
98
+ text = self._format_user_error(text, i, highlight) if i == count - 1 else ""
99
+ if self.supports_ansi:
100
+ fn = color(fn, bold=True)
101
+ path = color(path, underline=True)
102
+ return template.format(
103
+ base_indent=self.indent,
104
+ line=line,
105
+ indent=indent,
106
+ text=text,
107
+ fn=fn,
108
+ path=path,
109
+ )
110
+
111
+ def _format_user_error(self, text, i, highlight):
112
+ spacing = " " * i + " >>>"
113
+ if self.supports_ansi:
114
+ spacing = color(spacing, fg=self.color_error)
115
+ if highlight and self.supports_ansi:
116
+ formatted_highlight = color(highlight, fg=self.color_highlight)
117
+ text = text.replace(highlight, formatted_highlight)
118
+ return "\n{} {} {}".format(self.indent, spacing, text)
.venv/Lib/site-packages/wasabi/util.py ADDED
@@ -0,0 +1,234 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # coding: utf8
2
+ from __future__ import unicode_literals, print_function
3
+
4
+ import os
5
+ import sys
6
+ import textwrap
7
+ import difflib
8
+ import itertools
9
+
10
+
11
+ STDOUT_ENCODING = sys.stdout.encoding if hasattr(sys.stdout, "encoding") else None
12
+ ENCODING = STDOUT_ENCODING or "ascii"
13
+ NO_UTF8 = ENCODING.lower() not in ("utf8", "utf-8")
14
+
15
+
16
+ # Environment variables
17
+ ENV_ANSI_DISABLED = "ANSI_COLORS_DISABLED" # no colors
18
+
19
+
20
+ class MESSAGES(object):
21
+ GOOD = "good"
22
+ FAIL = "fail"
23
+ WARN = "warn"
24
+ INFO = "info"
25
+
26
+
27
+ COLORS = {
28
+ MESSAGES.GOOD: 2,
29
+ MESSAGES.FAIL: 1,
30
+ MESSAGES.WARN: 3,
31
+ MESSAGES.INFO: 4,
32
+ "red": 1,
33
+ "green": 2,
34
+ "yellow": 3,
35
+ "blue": 4,
36
+ "pink": 5,
37
+ "cyan": 6,
38
+ "white": 7,
39
+ "grey": 8,
40
+ "black": 16,
41
+ }
42
+
43
+
44
+ ICONS = {
45
+ MESSAGES.GOOD: "\u2714" if not NO_UTF8 else "[+]",
46
+ MESSAGES.FAIL: "\u2718" if not NO_UTF8 else "[x]",
47
+ MESSAGES.WARN: "\u26a0" if not NO_UTF8 else "[!]",
48
+ MESSAGES.INFO: "\u2139" if not NO_UTF8 else "[i]",
49
+ }
50
+
51
+ INSERT_SYMBOL = "+"
52
+ DELETE_SYMBOL = "-"
53
+
54
+
55
+ # Python 2 compatibility
56
+ IS_PYTHON_2 = sys.version_info[0] == 2
57
+
58
+ if IS_PYTHON_2:
59
+ basestring_ = basestring # noqa: F821
60
+ input_ = raw_input # noqa: F821
61
+ zip_longest = itertools.izip_longest # noqa: F821
62
+ else:
63
+ basestring_ = str
64
+ input_ = input
65
+ zip_longest = itertools.zip_longest
66
+
67
+
68
+ def color(text, fg=None, bg=None, bold=False, underline=False):
69
+ """Color text by applying ANSI escape sequence.
70
+
71
+ text (unicode): The text to be formatted.
72
+ fg (unicode / int): Foreground color. String name or 0 - 256 (see COLORS).
73
+ bg (unicode / int): Background color. String name or 0 - 256 (see COLORS).
74
+ bold (bool): Format text in bold.
75
+ underline (bool): Underline text.
76
+ RETURNS (unicode): The formatted text.
77
+ """
78
+ fg = COLORS.get(fg, fg)
79
+ bg = COLORS.get(bg, bg)
80
+ if not any([fg, bg, bold]):
81
+ return text
82
+ styles = []
83
+ if bold:
84
+ styles.append("1")
85
+ if underline:
86
+ styles.append("4")
87
+ if fg:
88
+ styles.append("38;5;{}".format(fg))
89
+ if bg:
90
+ styles.append("48;5;{}".format(bg))
91
+ return "\x1b[{}m{}\x1b[0m".format(";".join(styles), text)
92
+
93
+
94
+ def wrap(text, wrap_max=80, indent=4):
95
+ """Wrap text at given width using textwrap module.
96
+
97
+ text (unicode): The text to wrap.
98
+ wrap_max (int): Maximum line width, including indentation. Defaults to 80.
99
+ indent (int): Number of spaces used for indentation. Defaults to 4.
100
+ RETURNS (unicode): The wrapped text with line breaks.
101
+ """
102
+ indent = indent * " "
103
+ wrap_width = wrap_max - len(indent)
104
+ text = to_string(text)
105
+ return textwrap.fill(
106
+ text,
107
+ width=wrap_width,
108
+ initial_indent=indent,
109
+ subsequent_indent=indent,
110
+ break_long_words=False,
111
+ break_on_hyphens=False,
112
+ )
113
+
114
+
115
+ def format_repr(obj, max_len=50, ellipsis="..."):
116
+ """Wrapper around `repr()` to print shortened and formatted string version.
117
+
118
+ obj: The object to represent.
119
+ max_len (int): Maximum string length. Longer strings will be cut in the
120
+ middle so only the beginning and end is displayed, separated by ellipsis.
121
+ ellipsis (unicode): Ellipsis character(s), e.g. "...".
122
+ RETURNS (unicode): The formatted representation.
123
+ """
124
+ string = repr(obj)
125
+ if len(string) >= max_len:
126
+ half = int(max_len / 2)
127
+ return "{} {} {}".format(string[:half], ellipsis, string[-half:])
128
+ else:
129
+ return string
130
+
131
+
132
+ def diff_strings(a, b, fg="black", bg=("green", "red"), add_symbols=False):
133
+ """Compare two strings and return a colored diff with red/green background
134
+ for deletion and insertions.
135
+
136
+ a (unicode): The first string to diff.
137
+ b (unicode): The second string to diff.
138
+ fg (unicode / int): Foreground color. String name or 0 - 256 (see COLORS).
139
+ bg (tuple): Background colors as (insert, delete) tuple of string name or
140
+ 0 - 256 (see COLORS).
141
+ add_symbols (bool): Whether to add symbols before the diff lines. Uses '+'
142
+ for inserts and '-' for deletions. Default is False.
143
+ RETURNS (unicode): The formatted diff.
144
+ """
145
+ a = a.split("\n")
146
+ b = b.split("\n")
147
+ output = []
148
+ matcher = difflib.SequenceMatcher(None, a, b)
149
+ for opcode, a0, a1, b0, b1 in matcher.get_opcodes():
150
+ if opcode == "equal":
151
+ for item in a[a0:a1]:
152
+ output.append(item)
153
+ if opcode == "insert" or opcode == "replace":
154
+ for item in b[b0:b1]:
155
+ item = "{} {}".format(INSERT_SYMBOL, item) if add_symbols else item
156
+ output.append(color(item, fg=fg, bg=bg[0]))
157
+ if opcode == "delete" or opcode == "replace":
158
+ for item in a[a0:a1]:
159
+ item = "{} {}".format(DELETE_SYMBOL, item) if add_symbols else item
160
+ output.append(color(item, fg=fg, bg=bg[1]))
161
+ return "\n".join(output)
162
+
163
+
164
+ def get_raw_input(description, default=False, indent=4):
165
+ """Get user input from the command line via raw_input / input.
166
+
167
+ description (unicode): Text to display before prompt.
168
+ default (unicode or False/None): Default value to display with prompt.
169
+ indent (int): Indentation in spaces.
170
+ RETURNS (unicode): User input.
171
+ """
172
+ additional = " (default: {})".format(default) if default else ""
173
+ prompt = wrap("{}{}: ".format(description, additional), indent=indent)
174
+ user_input = input_(prompt)
175
+ return user_input
176
+
177
+
178
+ def locale_escape(string, errors="replace"):
179
+ """Mangle non-supported characters, for savages with ASCII terminals.
180
+
181
+ string (unicode): The string to escape.
182
+ errors (unicode): The str.encode errors setting. Defaults to `"replace"`.
183
+ RETURNS (unicode): The escaped string.
184
+ """
185
+ string = to_string(string)
186
+ string = string.encode(ENCODING, errors).decode("utf8")
187
+ return string
188
+
189
+
190
+ def can_render(string):
191
+ """Check if terminal can render unicode characters, e.g. special loading
192
+ icons. Can be used to display fallbacks for ASCII terminals.
193
+
194
+ string (unicode): The string to render.
195
+ RETURNS (bool): Whether the terminal can render the text.
196
+ """
197
+ try:
198
+ string.encode(ENCODING)
199
+ return True
200
+ except UnicodeEncodeError:
201
+ return False
202
+
203
+
204
+ def supports_ansi():
205
+ """Returns True if the running system's terminal supports ANSI escape
206
+ sequences for color, formatting etc. and False otherwise. Inspired by
207
+ Django's solution – hacky, but an okay approximation.
208
+
209
+ RETURNS (bool): Whether the terminal supports ANSI colors.
210
+ """
211
+ if os.getenv(ENV_ANSI_DISABLED):
212
+ return False
213
+ # See: https://stackoverflow.com/q/7445658/6400719
214
+ supported_platform = sys.platform != "Pocket PC" and (
215
+ sys.platform != "win32" or "ANSICON" in os.environ
216
+ )
217
+ if not supported_platform:
218
+ return False
219
+ return True
220
+
221
+
222
+ def to_string(text):
223
+ """Minimal compat helper to make sure text is unicode. Mostly used to
224
+ convert Paths and other Python objects.
225
+
226
+ text: The text/object to be converted.
227
+ RETURNS (unicode): The converted string.
228
+ """
229
+ if not isinstance(text, basestring_):
230
+ if IS_PYTHON_2:
231
+ text = str(text).decode("utf8")
232
+ else:
233
+ text = str(text)
234
+ return text
.venv/Lib/site-packages/xlstm-1.0.8.dist-info/WHEEL ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (75.3.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
.venv/Lib/site-packages/xlstm-1.0.8.dist-info/top_level.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ xlstm
.venv/Lib/site-packages/xlstm/blocks/__pycache__/__init__.cpython-39.pyc ADDED
Binary file (184 Bytes). View file
 
.venv/Lib/site-packages/xlstm/blocks/__pycache__/xlstm_block.cpython-39.pyc ADDED
Binary file (3.12 kB). View file
 
.venv/Lib/site-packages/xlstm/blocks/slstm/__pycache__/__init__.cpython-39.pyc ADDED
Binary file (190 Bytes). View file
 
.venv/Lib/site-packages/xlstm/blocks/slstm/__pycache__/block.cpython-39.pyc ADDED
Binary file (1.52 kB). View file