peek-python 1.3.20.post1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- peek/__init__.py +3 -0
- peek/peek.py +1541 -0
- peek_python-1.3.20.post1.dist-info/METADATA +1331 -0
- peek_python-1.3.20.post1.dist-info/RECORD +7 -0
- peek_python-1.3.20.post1.dist-info/WHEEL +5 -0
- peek_python-1.3.20.post1.dist-info/license.txt +20 -0
- peek_python-1.3.20.post1.dist-info/top_level.txt +1 -0
peek/peek.py
ADDED
|
@@ -0,0 +1,1541 @@
|
|
|
1
|
+
# _ _ ___ ___ ___ _ __ ___ __ _ _ __ ___
|
|
2
|
+
# | | | | / __| / _ \ / __|| '__| / _ \ / _` || '_ ` _ \
|
|
3
|
+
# \__, || (__ | __/| (__ | | | __/| (_| || | | | | |
|
|
4
|
+
# |___/ \___| \___| \___||_| \___| \__,_||_| |_| |_|
|
|
5
|
+
# sweeter debugging and benchmarking
|
|
6
|
+
|
|
7
|
+
__version__ = "1.3.20"
|
|
8
|
+
|
|
9
|
+
"""
|
|
10
|
+
See https://github.com/salabim/ycecream for details
|
|
11
|
+
|
|
12
|
+
(c)2024 Ruud van der Ham - rt.van.der.ham@gmail.com
|
|
13
|
+
|
|
14
|
+
Inspired by IceCream "Never use print() to debug again".
|
|
15
|
+
Also contains some of the original code.
|
|
16
|
+
IceCream was written by Ansgar Grunseid / grunseid.com / grunseid@gmail.com
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def copy_contents(package, prefer_installed, filecontents):
|
|
21
|
+
import tempfile
|
|
22
|
+
import shutil
|
|
23
|
+
import sys
|
|
24
|
+
from pathlib import Path
|
|
25
|
+
import zlib
|
|
26
|
+
import base64
|
|
27
|
+
|
|
28
|
+
if package in sys.modules:
|
|
29
|
+
return
|
|
30
|
+
if prefer_installed:
|
|
31
|
+
for dir in sys.path:
|
|
32
|
+
dir = Path(dir)
|
|
33
|
+
if (dir / package).is_dir() and (dir / package / "__init__.py").is_file():
|
|
34
|
+
return
|
|
35
|
+
if (dir / (package + ".py")).is_file():
|
|
36
|
+
return
|
|
37
|
+
target_dir = Path(tempfile.gettempdir()) / ("embedded_" + package)
|
|
38
|
+
if target_dir.is_dir():
|
|
39
|
+
shutil.rmtree(target_dir, ignore_errors=True)
|
|
40
|
+
for file, contents in filecontents:
|
|
41
|
+
((target_dir / file).parent).mkdir(parents=True, exist_ok=True)
|
|
42
|
+
with open(target_dir / file, "wb") as f:
|
|
43
|
+
f.write(zlib.decompress(base64.b64decode(contents)))
|
|
44
|
+
sys.path.insert(prefer_installed * len(sys.path), str(target_dir))
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
copy_contents(
|
|
48
|
+
package="executing",
|
|
49
|
+
prefer_installed=False,
|
|
50
|
+
filecontents=(
|
|
51
|
+
(
|
|
52
|
+
"executing/executing.py",
|
|
53
|
+
b"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",
|
|
54
|
+
),
|
|
55
|
+
("executing/py.typed", b"eJwDAAAAAAE="),
|
|
56
|
+
("executing/version.py", b"eJyLjy9LLSrOzM+Lj1ewVVA30jPUM1AHAFGfBj0="),
|
|
57
|
+
(
|
|
58
|
+
"executing/_exceptions.py",
|
|
59
|
+
b"eJylz8FOwzAMBuB7nsIal1bq+gCTxm1ICMEBIS4IVWnmtoEsjmJHbG9Pk6FuHDjhSyIl9v9ZGaeZ4cHTl79nTljtjgaDWPL1RsFcq9WqnM/aMu7BejCaEWgA7eEz90GI1Ds8tPBILO4EPRqdzn9MOMlEHvo0clvm7I5oklg/tp72CCMKA6OAEDyRxxwgk+WS0i6CcgkzVSl1Jr9itIPFeKetS/Fv98sUs3GgmMHJ4zGgkXmTgw5hZsAQ6TCnssRkcn+WaBbIvP+K9zhA11lvpesqRjc0IFYcNmV6cx37w851A3IKuIGK+o/Z2sDvs4b1bUleGvLkM257YS8P17ttryPV5V8KGKu6XaxFWS8SO3qK+Ga0c2sdx3f1DRnEs2M=",
|
|
60
|
+
),
|
|
61
|
+
(
|
|
62
|
+
"executing/_position_node_finder.py",
|
|
63
|
+
b"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",
|
|
64
|
+
),
|
|
65
|
+
(
|
|
66
|
+
"executing/__init__.py",
|
|
67
|
+
b"eJyNUsFupDAMvecrrPQArCjSXpGq0R6m1V52D616qSrkCYZJFRIUnLb8fQMZOmhPGwkRPfvZz36RUooHYtC2c35A1s4Cnlxg+DgjA0LncSDQE6jgPVk2M7RO276Cp3nUCg2ECXuqhYB49DA6z0CfpALHrIRa1xLcXdHq0QWvqPoG8rVLUS2JK+MmcT60MXAiQAu/Hp8S5jz8cZaEjMpF590AyhlDapE+bQJsLNdyGA2J5pn8FGO/44RRxDWSZ/tQVkKeDfjmfLxlg7bbRXmXFUXqdFW8NUqTlHDcAiU4a+YyauS/lp7RBLp3wbYlKFTnmNkFDp6azmA/CfZzvQ6cyr8nPVvxprkATRM3wvNINeg+KqOXlPGalt6BbOldRhP3lFR4OR71RLBqOXrvvKBPRSNH0csvJteXpV+41TgvjmNgd9uTJY9MbTSDz8Bngl4zMPbxhZCFU9CmXZxeKuwF34E8HA7yH3x5Z2twv/v89mcJ6SsEmYnq/2L9GHDMteVy37eaRqM5z6poWiGEaBo0ZuW+yGSWfBVfV3/8ag==",
|
|
68
|
+
),
|
|
69
|
+
),
|
|
70
|
+
)
|
|
71
|
+
copy_contents(
|
|
72
|
+
package="asttokens",
|
|
73
|
+
prefer_installed=False,
|
|
74
|
+
filecontents=(
|
|
75
|
+
(
|
|
76
|
+
"asttokens/astroid_compat.py",
|
|
77
|
+
b"eJyNUUtuwyAU3HOKkbuNcoBI2bSKussFoggR+6UgYZ4F5Hf7gO1GxXWirEDzZt7MQPS3lQCOnluoED2bBqbt2Ec4bigk8BeXGZC1VSFQEEn0MTtB0HyyDQ6Eiza1pjN5tNycLEGnbVETtom//UavmLgvB9sxw0B8SflUgb7YRWUceUHXmrqITX8YdrlcHDo+b/mI/qzsVLwsVNOsb3BlkTr7ljWAf0Xye3de/bRqlUKj5nPPw/wnrFMcR/18fOw/SGk+DoSQUlkrZQJ21dzSaoFqWJZvxZJqL+79I8vC",
|
|
78
|
+
),
|
|
79
|
+
(
|
|
80
|
+
"asttokens/asttokens.py",
|
|
81
|
+
b"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",
|
|
82
|
+
),
|
|
83
|
+
(
|
|
84
|
+
"asttokens/line_numbers.py",
|
|
85
|
+
b"eJydVk1v4zYQvetXDJxDZKyiOHsoirRewJukW6OpA8TeLhaGa9DyyGYrkSpJrWMU/e8dfkiWnRgFmoMUkcM3M+89kr6AO1ntFd9sDbwf3HwHnxTXBh7ZSicwFlkaXUQX8MgzFBrXUIs1KjBbhFHFMnqFmQR+Q6W5FPA+HUBsA3phqtf/gRD2soaS7UFIA7VGguAacl4g4EuGlQEuIJNlVXAmMoQdN1uXJoBQGfA1QMiVYRTNKL6ir7wbB8y4gulva0x1e3292+1S5mpNpdpcFz5OXz+O7x4m04crqtet+CwK1BoU/lVzRZ2u9sAqKidjKyqyYDuQCthGIc0ZacvdKW642CSgZW52TCGhrIk8xVe1OeKqKY5a7gYQW0xAbzSF8bQHH0fT8TQhjC/j2c9Pn2fwZfT8PJrMxg9TeHqGu6fJ/Xg2fprQ108wmnyFX8aT+wSQmKI0+FIpWz8VyS2LuLaUTRGPCsilL0hXmPGcZ9SX2NRsg7CR31AJagcqVCXXVktN5a0JpeAlN8y4kVdNpVFECaUysOIaM9N8ER25kiWYfWVRw+g9z0xCSzU9Z3VVYBQtCy5wqQ1TZqkQhrQytU4gb8Tq8vfLxA782o+irGDU4CNFT+pyRXaL5eoPyti/jQB6vR4971wIyZNJQf1QTWh2iGStLVMsM1S6zHONRoNzkMEXA1YQKyM1CxXjSkNsS0oIpKhL0bcWu7laMfI/pbBTLnTgh0IUCF8TwWhrcGcgI/9EzyKMpjPy/ho18QUws+73/ZBw1IMllmc07yTioqqNW6aNJFmhkpp7/qnsEJnCRwriVH9dWW414RrFhC6YtaVlwSI4EWqTf990nsBuy7MtkGHbQhlt+YrRBhabtCVzjTksl1xws1zGGos8cXw5ugEurLJ4CzHR14erDzCRAsPMiFgiROLtNe80iLQbHY+X9ghQFNmGpQ7BJku9L5plQ5iXqTNJPOg7kkrLxbF50pyLNSeY2BW66IA5pYeugZPRZUH+GAI9/arOtKUtVLDM3HE3hL//aVu3Zp5zEQxt/1ssaLJklfY2IU9YGbpkBB5cB46H1d6g7cQuiALrVjOfnMwVqPeWbAatL090cIXQw4lBbzfrlQT4xL+hNXzwcVseWfbIzM4oHt/uO1Mr69/DdDCpj0iPUhyUOkNeukHjdpanmOeHvaide3xDACjWYWEL1vXC3H4s7HrXxY9OutdhfcCCjrxjoUMGFxcscQiYn8kFV3CzgNtOXYsoAHXsyf3WTTKrJhK3qJjBuE3lXdvInaUoLJXxpeXpMni1BaQrq6J0sW3tgNAPQWcIDsQMGxBfpFexGZuX7CUeJFBy4cAbsq5ujs3VXzRm9OllyHTkxv9hxDt/MOv/dGI4Vmn7tCMnZ4nFlm5HHxvRSzaEm8ZmbuDD8JxPGtsFot4wDBYHsw1OwgchQuPJhGX4rHnfQdAhUJicpO037Ad9iX+7MLDvB9/g3VHu7tV5o8LibfrPkkqU2kuwcwd2L8Bz158DD1fgW8cCmbJjvONe2376rXx066zxhRb53xSpfy3dz9Q3SG0R7E7tmj7ugL2DmyaOws4o42MXRH/0Lwbcom0=",
|
|
86
|
+
),
|
|
87
|
+
(
|
|
88
|
+
"asttokens/mark_tokens.py",
|
|
89
|
+
b"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",
|
|
90
|
+
),
|
|
91
|
+
("asttokens/py.typed", b"eJwDAAAAAAE="),
|
|
92
|
+
(
|
|
93
|
+
"asttokens/util.py",
|
|
94
|
+
b"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",
|
|
95
|
+
),
|
|
96
|
+
("asttokens/version.py", b"eJyLjy9LLSrOzM+Lj1ewVVAy0jPRM1TiAgBXxgZB"),
|
|
97
|
+
(
|
|
98
|
+
"asttokens/__init__.py",
|
|
99
|
+
b"eJxlU8FunDAQvfMVI3LYVqJsmkMPrXqgSdqirtgokEZRVa28MIAVsKk9lN2/79jQ1UZBK7H2PL957425gGs9HI1sWoKry/cf4JuRlmAj9jaCVJVxcBFcwEaWqCxWMKoKDVCLkAyi5NdSieAnGiu1gqv4Et44QLiUwrefmOGoR+jFEZQmGC0yhbRQyw4BDyUOBFJBqfuhk0KVCJOk1rdZSFgGPC0Uek+C0YLxA6/qcxwI8oL5aYmGj+v1NE2x8FpjbZp1N+PsepNe32b57TvW6088qA6tBYN/RmnY6f4IYmA5pdizyE5MoA2IxiDXSDu5k5EkVROB1TVNwiCzVByekfuRXmT1XxxbPgdwWkJBmOSQ5iF8SfI0j5jjMS2+bx8KeEzu75OsSG9z2N7D9Ta7SYt0m/HqKyTZE/xIs5sIkJPiNngYjNPPIqVLESsXWY74QkCtZ0F2wFLWsmRfqhlFg9Dov2gU24EBTS+tm6VleRWzdLKXJMjvvDIVB0EYhkHh5tnranQTVa0bovWwuyO1bDTJCyAOb5msfkZnvuLsRsPzLnXF8SjW1/tGHOpY164DMTiokLCkWfp8gPBAbvbIk/Xkihli8DL412I31GM3G9a6c1oE8fV5xvOWARmh7Kmrjb2XoDa6h7iTCndq7Pd8s12o2vB3wXvZvLWghCXv5gRhMQWLi/wfX3FmBlezOw91Fy0IdjvRdbsdfIZfq+XMKoLV6ZRbnLVzy9c0q9/BP/0mR0E=",
|
|
100
|
+
),
|
|
101
|
+
),
|
|
102
|
+
)
|
|
103
|
+
copy_contents(
|
|
104
|
+
package="six",
|
|
105
|
+
prefer_installed=False,
|
|
106
|
+
filecontents=(
|
|
107
|
+
(
|
|
108
|
+
"six.py",
|
|
109
|
+
b"eJzFPftz2zaTv/uvwCnTMZVP4SV22rvL1J06jtPoPr9Odpr28nloioQs1hSp8mFb/eb+99sHQIJPyXJuzpOJSGB3sdhdLBYPAi/EUbxcJcHtPBOWNxR7r9+8frX3eu+1eC+jP9xFEIkLmckkjaOdFzsv4CVZBGkaxJEIUjGXiZyuxG3iRpn0R2KWSCnimfDmbnIrRyKLhRutxJLwRTzN3CAKolvhCg9KBXIAm82BUBrPsgc3kQDuCzdNYy9wgaLwYy9fyChzMyxxFoQyFVY2l2JwqTAGQyrGl24I9IBdzNWZ4iHI5nGeiUSmWRJ4SGUEQF6Y+8iHzg6DRaDKQHQSRwrkgHCeQj2Q25FYxH4ww19JlVvm0zBI5yPhB0h8mmeQmGKiJyPEgrr8a5yIVIbIGtAIgHuqcckhQWE5SxRspkSVYsrDPF5UaxMgT7M8iaBYSVh+DKKjUv+QXoYpiDCLwzB+wAp6ceQHWK/0HanvCnLdaXwvqUqs9ijOgGPmA3WxLFWsstK5G4ZiKpXkoGiQs1upVYI8pBnYQeCGYhknVGi9tjYz8elYXJ5/vPpyODkW40txMTn/dfzh+IMYHF7C+2AkvoyvPp1/vhIAMTk8u/pdnH8Uh2e/i7+Pzz6MxPFvF5Pjy0txPgFi49OLk/ExpI7Pjk4+fxif/SLeA+bZ+ZU4GZ+Or4Ds1TkVqYiNjy+R3Onx5OgTvB6+H5+Mr34fAamP46szpPvxfCIOxcXh5Gp89PnkcCIuPk8uzi+PgYUPQPhsfPZxAuUcnx6fXdlQLqSJ41/hRVx+Ojw5wcKA2uFnqMMEuRRH5xe/T8a/fLoSn85PPhxD4vtj4O7w/ckxFwZVOzo5HJ+OxIfD08NfjgnrHOhgDRGQeRRfPh1jIpZ5CP+OrsbnZ1iZo/Ozqwm8jqCuk6sC+cv48ngkDifjSxTLx8n5KVYTBQs450QGMM+OmQ4KvaobAMH3z5fHBUnx4fjwBKhdIjJXVIPbOzuDweBzFoRgcWATMzCKhwSeyQ59CZbgQkvM0SzAq6yg6UVij+xuHxB3dmYJGLzjzPIsT6TjiGCBdgT2msYhNC6H33d2VPosj7wsjsNUJwTgpyoJMZiym8WJfk9XRVa2Wsp0Z8dx3Bz4SKC0AzFouDzx41Ql/bwkfu04uf1pAGj3kA8Wznhv7Dc/2K+hBiCNz6mc5SFVHmBWUHM3SaVQ8OArZjNwmthMsIXYOxe/7wEJ4MzWJINoFn99fS0ODsQeZO93Z+9j9tvW/Hd71+KnA2Htj8TbIYhsJgD03Y6AP3RW0a1DEkDcLBlRegA+/FYmRQa8c4YXgkcukvGX0zP5mFEyU6G0aRC5yUqnTlcZShkzTg9/uxz/97FiduE+psFfckeGqWzlauqmkpPambOQOxHG0e2whUeLmGQl20eYdQWPwwbXeRSgZbZwjvXhgmfE8DJ0M9DpwgYfl2QpdhzW4A/33h0MmX/8eyH+k63aDR/cVYp9Ryr294B0ltoFVCkJqINlvRE//ij23wzFK/GGOSyFwkTH2S545Rhc8jSU6OPnLjhwlF88s0gE4l8O9PvFyknx0cmGZZEkHfGbFVM3ARwXOfjnyxk0u1CCNVvQWc2MGum/REKbjITitcjOklUVFohYv1nDYZEoHz25zMQ5WOcM+qTjJImTKsoLkNArkFAlca2MmnJiWj+83YjWD/s1Wr4MxW+6nbxlquSP2F+EwdTOwbNpn5QupedgvhPGri8T05BrWVDuWRxJcA4kZ9f3HYhqLPReI4xvlLTBAx769YAH4yf2c+gr0EkSX5BgO0iF3A/8auLMnQOBSh5KK3IXsqQ+Zs45b6Q0ir4ZO2hOFe4M/B4lgMFkQDkrCnU0cYfp7hhmQS2aKKRfMfMa+GGTc07cv1YfZOolNdtjm4NoMFNGNxIGuyRHSLQxDaqIPyberSzRgC609KWBCcFeHmbYiJGEA69xeC+toUEa5JsRS6OynJFCHFKbi+7jO2i9jpNiWXa3yWNQBVET/HOxoYv8NoQYEaJB6I+Eex8HfoqdnhI1gt1CFAyusUYlkYv4vgDyUWbBEjovu9ZWQ806mAB7PceoRKPlHWYqNm1pekvANqRGumQZFAo8hVjRP2V7KpW5RouglBBGA5F8OEDTN5WaQ5dsGUSZ9aFdUKlWwuy3jDSgjAJH4k1fhZnKZMxkEhFYKebJhx4nYgBCNYyKakOq+UgluFrj01SGNbtF7RXCwheDksLtsdx7N8wxXxGyHN2ciVLDwMtSRow6rHNNqdXmqrTNnSe/UO+5ecslJRu01iiZK1v4M/WqbFtnmIX7QdLsqrCW2Pd/HSgMGEfAIxYFz9c1uL8BID6xh8FoDd9wXMPFL9BEHVc3nvS6Ljgiw0xBCJxPiV1wGCkMKENfAHqSBBT0BtzGGiSR1+tqQysa6xPbGpoBtTd+wBQsh1ofpxev7Y2xKHjr9ogl97ZJR7W9/naJUG3UWTtd5AFI17kbSPNBUC2M4F/TG7Rg6qKa1dCkFezGTqat1usrVEB0SbXO71pXVvifTmemIVUr0H5oYbRzm31R4VMug8dTALtwsznHILIeDOgY41AsABC6pWyuAi2MRuIi6AoebWxEKY0ZIabGOQcVd9hMibpiLheQQomhFHbMF8cX+6/3xCyIMCJDdA7OYPie6SY7xUmRBRSOYTZRwyi/GKja3/PkVBhC1xqkNKxVYy6a52C4/aJCXY0WaqHE6vREPDWoKsxdFD9EKhvdyD//xygNA0xDbTRtNRIvYVAaIqXUKBDdnk5H11fAtNhqpcyvJat/EwN7AP9rXBiYYokGQxisVRjSoM0+9GkllWWgXtvLGJE11T0fNC+z3s1iqwIwuKtzzKF9hQ8cALRyAWEqTotm34ib2jjDKgujVt3PqbORWhrBbreeSq1oWBWA/l2uWkLPxA1SKdgfULY1oLarxkx+DIYdxZnAQrRbMpVvhFWI8vSa0Fyx56Y0X+1CxZBMa12Nwc0TK1mJr9nZq+DGEH5ZI8MegjSIcDbVkxY1XyNiro3OmSz83xYuNvsdAlQWU0RbpXdpq6tq0DWxVNp4kDpL17tzb3s0oJ08/k2YRpbkYK0BzxEjuK9VTaMpRdIuZyu+AJiUap4a+op5TLPgIE1w3UmCU+DYLAR3Lyk58AJZOfJ9+60ALiX2CW+/N6YATAZVJeduWsTRHVqjIBNbNwSZhlEiKE4t9cpjUm+ZLJs/8yDB1ZTAFCyKpOjSpG8y28Md2rm8B4wc+q0Vt7rUbHatXgLfkVoa54mnhhtUGySXopty0yKtrLOXSDeT1aaI6ujw85V2C2B2rV3LR3Bw9Z6s2gCoge04Raxw0B5t6FGAEZRQgxpncpGaAxUjIMFEci3Yz4OLoOhdG1Y5KcKap1AehbNwkzsUjlIalNca9hNyLeIfeJc03zk+x4FL5SWI8f8iZThqxZ8FIVSW4PVEOL5Mc0gHb0IZJYx66qU1c8F/NAhWX2qQ5msH7SBa5hkPzhRvPFYzGU3cB6eA44dOalBe1EIOfFkXzsJd9otJAeBPBwmwfu/BR6A4Lf/n1Lx87EeftuOXT9Me/DjPlHwgal1AaEoUICJeJrEn087KJ250K9eI/7EA4ocuUtJowy0ki7nTgRo4vqUeiTKIOOF3U/dzr41ssfDThZnOQ/no/JnHGaEvg6Vk4WA6PnBWB7bZ8mqtsAPjcyqTD4FHyjCfvTgMJc3ddrKK4CcwmtCo+nlDVOZPI5dvG6A/fkND+CtY06AUAP50k3BwLUNy/Xs8Tg3SfDVpq2msCh9mTdtgvTiaBbdLXLEjJ3lE7xf83o5QyNlxp15d9NVXGyH0gpK5XKdX6vaHqn10qa8sdrlKpNL0cuXgcxucP104txH7I3jGX/ixMakLPCrhNDgltcE7fr5YrJxsDh0/ea36exWgteo/Us3/Q9dcw7YVN8+yJYQc8V0g/3ATrjy+oIOBF8y2y+w1FFLWLz7WkNtFPs8WoYPrtpnCxQR6X0GwUqTYBUgnkdK8Pl2dnlwUb4S+7LY1Zj4MoATNcaXmnNOGKRduEDqLAGIgXFdFFEqyT8enx+8rKQhkE9AaQtBH3tYojatJRIrB1tBa5NAmoeZZld5pM5loluBr6EZx1EEawtwu6hWkNQXgWnKV8FUlhQgSUBshlPynq6uLS5ncswk0U0i1Kb+20Tj6ZVxFaCSso3BJo4oqTlvaOjreReDdcRhgPC75qQ3hz1zmBPNf9NAGkshlomwcH1th0ti7k1la8k7vl92MGv7J8FQ9fie7oyATwa7UYw+Y4wduGJNv/lA8qTxb5fWh4ya3ksRHeGuSMWD6SKVegh2Jr830Ur1rI9XkKnC9BMkuSu7YTpr8VeD6CGYBxWNX/KPRMbUXK7sjcPWjseC1Dws6d9qglrIiK6+aRpnYq+HIZxrqodBu1GtAwEEYJ948jpXHz+6OMOVIpzRm+A2+DMz+IhYL3PNXauSIUrSO+oowMHulf1c10ezuWUY6iyNljB+LJ0Ug7ujPNOoChjnQvUxjZT2n/P4+rliTAdVfrbp1Z3dV++6W3Vp7z5MQ/Bh3/UBaT0jQnDYtadg1CIXB8UAfSYmzOL0kNYQmye/dJPuI9eb1cJnE0zgrA5/aq2LMTG2j9bgIk6VnhECcoDoIfukLgxR+Wuvmfjs9mVwclR2dIlR2dde4m9P3xUMQ+fFDSnNawSzwRLH2VNskhnvzBgC9vzfguarmJNDf9CxQg0vAU6G9ox5VXa53dsx16gZNtf1I7wwoZ7h4B4Da41JuFKhOM/MmgfZ55mKCzTZXlxhjwCaAc/NFKcMd3E7FS44GH81VdZywq6ft7PAa30F1kq5hdYPhTjtflKsZGwyNFXZaTuOVNchyzCa3zSwgLdboNclqA8b1v51KAZvPA9KIYELbcFTjWO8UzOkLGBVk26Mzs3+mz8ENt0EGGBhIJe7tlsh/xEG0JaoJ/1TcFMW9JW4ePafkPNq67GJqrPDqm6M5yzBPn46bR1sWqhCfV6yTxQ5tRu6hgO8Gk3XEbkXICNdBns4bqQ9GQclqS9ysaCxPxcwrPe+TUGnH2BaKSMHjYvNeqM77yRaPBCKZhbG3NTpAuIutXBuhm7p6OnaCWzeD+7XN/brazfd2ItU+v7eHa4kCyl66F7O93+7la6ejb17TB68Ji4fNEFwF4u0xtJmq5bs2HKDw+JuFAxxsV8IBSto8HPg8OTmuRvB7vcG8gYoTONviHsHgC1rqVRxfzvVicWurL6i02217bTezW8Ldym4Js9du2/l6qt0qY+my26qI19ltMVBrI7HWbhMJ7inNvpnlKnpV21WJm1sv4MVLGbUboC6ic2kXxiZh6CAB2WHDa0jgco//HAK4vo/K3QPwVvNfgw9Qe5rGNvi3Mlsm8WPQEbmswZ6o7G1qfk5C+xDgrpouD7KGBPqfD3LmwlCE/McnN/LDLRWBtCbSJ3aeS4eXfS54nXzLugH24+o5jNBc/zMrcgEO4SFO/NPbb0LjS5DNlb4m0g0XW9E8nKZZ4noZ1C/wDvNs/txKfhNCpK5vQknX70OAS87fooLfhhLV8Nsx9Vz8y+cQwAnlZ+E/j/8j15vLZ9L4HNH+2OeKkfzm8zwVQCUS3uT9Vj0QQHmhdKN8uQ02RK/13vcJanQjb/UsCth3rmAAjxsFt8Kn0Q2tvIfBlh0p07iTf95vRqM9ju6KvDaLpBX2VrG0wu2Npru4e2o8XQSxnRF1TdjrYmoNXo+qCzIbxNXpMo6+4QyxJliPrDl189AaxKl3c7SYtSqjwyYB1wvjVM4hEtqWAG7feQ5ud0Rdone1hQ5ZbdoYGH3L1sDIa5pDB4NPbw/a+HoaRFXa61uEgm82CU1ofZsoV+q+XbMwVv+qLaPM2LxxTBAJw4hyf9VGi44dBtfDwoY2V1LYzuxK/H7L6+H0ycZnarnb/pqrtmtNsKqJbnLrDLHzI2WwoCP6GkG4DUujL03SpevpE2lkKhdT/JIOP0PRX4mUUBtv9kcg4rz8gBIlbXyX0TZPqc78wDhvQzw9I4R4qh/bELPs9RiXG/zGyIV/IOxSUZsSqKoWifR8z60+Ffm6Sxi7I7FL9cYHVQ1+ZKbouaS/e/1EY+828A2NmowVq8Nl3fM6dPVwDzfCM4oW+MlSaZTavFoX7hFEeQoip8qgsyK4d6md8jGhHC6Gzi9pFlT5FE6fJ1Eptfwcbc0hEo2v6tCRcWmoVS9znK9P/iiwWpg1iEBauTcnuiPxXTIQ3wmq9WiI8jA/SXfwmzAHvw/AY5kcenKcgZGHRsZ5+IR5nEmQGBLlieR89VKgMwR+BMXZ8FTN83nmJOV8/VaFuQ3jqRsqEPWCEOWHetUqBAt6bKsBZOFjVwXM97YaFC9dVagkdNTBfMcuu7AH17/HXSUO7tzHE7joo/jHbEep/wy0Z+ifm00VwwqypjMIMhvJWMMd/AGidSyTB88NQ3dKn7Prx57yNQh+mt4s2I1WFiodp6OdAYYGd9gvFVZOn1Lf8XfnEZ07RXQgf5HE/OGZaaf6C8E8msZ55Dv6iB9LJTQZUBmsbPWhHeOqzyAP1GlXp/SKfWHjwzxdGmOoE4i8MG2WhlmMPi4VyMGbYapb18JWZt3gsIW/VnXUq1rC0n/l6SHDZwihoxA+UwMxlDJI61pOLUdsYeFktS1naxlFWfrgDYTV3eFOpyUXB0m1acDoscDr/yIzPhZS5Qo88pK+elaHiq20YgoQwEKbpa6cBFCQRkNQx+rRQQ8AQp9YFm5raGIpZ9WNwbVEDF2A4cRa0UzHVsdk39aDBgA1HMPldeNpoBpu6Qm7URVMmwdAp3UnV6mF5zO8vHto83dAx7cJiCAMe8Y82ouxHl+BtVEIaHfdOgIM1YaPM1rr8RnKxL8P5ANWy5Qd2wxaOCANMHdgQHMluuE538QgrrsRKBvgqw5tvVJIHEmpk6ephLFNjTxJIYxu6ONJ6mBsQxubKkNDPEkhBcwTlFKAIE7h47TAYbA40R2yKGILiAv50DqqAzk2n8/6dZOVjftETTrM0hpKqm7raBGnprPto2kBe/oYLhgnBsl6+qSpp9H/yqxf9xTR9ERTq6X/S23e2GYNcN9S9OqNOWjLWzEoAQ/VnGPAAP9Tgj6+J0tyj49mDKJsD3fV8UGbkGpf0o81+On9YGjjgFqVFJpoiLIHuKb5oAqUw32t9jVHvnykPXsmHMAgKEMAtAbAZ5PLIKY3/eEvQsS2fqOs94ipc9RLwa1Cd/AwsCQ7gk41O/4zd0OMlutpHFS3fBT59c21+PFAvDF2YDPuhM5vmMhb+VgSNBKXgwZGDZagTt3Mm8u0AXwW1+F1ShWleqzIhrxtxNoTWBrUHHe7DVPCC/ElTu7chEMcPKs6cyPfDSGSE1OwtRRCuPka21ZHxVqpnchl6HrSSnb/8Y/dkcAfeBjSnlGCcWTquUs9T1I0B36o2z8mlXVQBm5NWziIEx/Sv76+Nn1+YevWNJ+NRNCBls++BtfDhvEXX9Lj7jg8udsqPrXGLzeXI8Qems2j0hKMRlI2Cp1YbTQ9DYImHYwG8TRb39jOn2DjhQ+ejjB+xrqJkBxuSIFxkZ9TPn5OV8lXE0G1GqtDTF66yW3KHTQ+KYXVzlNj0IbQhlYdu1KWIZ2tCzNorCvteeVsUILWzNaFaAKt5ZidIJ01Y5yryXNY+ugA0DICmP1fImmyysqWqksfiWxaP9irMT0GRfIJnp1n+ukDPrOlcYyTiQoDRNx+ItFv4RnpfExWNm05s5lm0xgJD0Iq8axsWiVugBbpsyDCM4OqdDV7xTFBRVWnxTnHVbdMkrV4ugz0gsOh1FEHUzph7KmX6sFIx4CUZ5KPjce7BsrZeNs8+SiYaYrtEp0l6jQ96GBxXprerTfVymsKBwxuz/SYrS5/Zrdbdyq/pAPvdTIYI1B2OSMariFdkFWMGnOp0rNAHPgrWMK0aMVgWrzskTS8gwgbGXDFeNlAKrA7rUZS2oHyhG3hDR1Oj+c+DN+1MIZF0cF2liqLDrnjuLmTNTZMmvEuwdtZrNgwcVm12A0YqJUL1VxCX5f1ehCCGPD80RDFolAqOsfyOb3hsSoNBO/xiOTDqzRbhZIxyukdjHCKUyvf0qmVe/b3lYYzWwKrTNhexks68AlXhFFVaebHeVY5jg7AW02TfW91qguvfJCW72busOH80FUZ3xwi0Mg46r/l4HkE4VECk6wAvBBjPjsOucfD2nBgRIMWvDeAn6SO3Pg0zyCz60xZBkczsHAkNkSpNZghhDr7inw3xmxpa560u655PP1HC1ypYUTIzoBTC8tpMDTTeL0n3xa0B3wTzqBL1PijR34G6yNFocoAABj6LrIe3AgnJQM1IfcRjwMrMlNZNz5IaVQP/YZcmgJrWJOhCgAtNdEUQI2fqySv9l7kg2vGSSTTyvnc+o+bPs4JqyUq5HSRpxmeIYus4n04rrrSYmAcxxj5tZpLOkCgUXME3LDmAPqta04kN6w5crpBzaEQrnbbgp9BLojAoQY+zuTgnmQBKDmf4YtXJKGbs4ZVssi7WclaAIDsJLcUQzRKbwoTYPqEuYlA9d80ke6dyWg3k+DIwyAy7iOxBv+IBtWGxvsVDAgx6DvmsySJpFopAYWWxtY0N26uhNViok14NnLFQNnhgCKCkdaFjECriZuRxNNmPxG0GDK5GWCmKhdOBiqG86EkYGPYGXz8qI7bUkuu3H8eqJ63DPLX9sRmNwo+u7cbnYV5Oq/3upgG8OQgS1BmqDlmMSTE1LBrn/U4SXDPBGiZk6kq8hvxdgFugthv0tKoumdk2B64vS6F91aJQV1/QQf2ykfXy8IVdcl0TOgD7q/Bt3cYnLy7Wa7235VzDvnSxxW5h8RdLmVyo8gVYQyRLG+KKs7a5ktK9u09PrxbZrxx5+bGUaR8x7nR1IrdT0jp5kaXdaNWM9VJ4lRWtJuJUhq0HwdkgPfXxTNFDcsxtl2hZwKW+D60mxsYcwa38AbUkezNDVeQ3hMp6FI13A0XKWqaHb9gxy5Mz6kKx1K/I6FQuvakCKG5OCgF/WVyeHFxPHEOLy/Hv5zhtWWX3fiK6Rb0zxcfDq+OL2sHiOu9crrcqgU2hsD4V7/FQtepdosF/m1wiwn+eTFoImr0bW2H+aeVQpOO6zHMmimJVEndtpEZKpu2Wms2Ev/8n6HppwjTNswWZKKe67N4Cpj9VdU2jKszutpW8xINzEgN9rYymqeYirGzoDrjWKtNYeEHay29+Cu41w+jgjX1y1KnSreKq5JjTmFQRhNUTVPRtAreWUCbACx8An9NA5pyS1axERHT1XYBGou4okAtBmfKnSZ8CLS+UyjGeZRl6EZ0LdQ78kNT/JhJBL500f9DeLRw77AUOnJR0Srokz1jeBbKexnSFZ1qs4q6s1HdfUnbIWl6O8ULFnD1vjhDW7k/D8+SNjinPKZWSiIz9mJqk8OdDQ+OY3lhqq8uwXO86UhCSPGbYUD7xAGflflvLfGZEp6+aw/60CTGM2R9POtbfP/Da11DU7gtVEjcWeIKD/229YC+ewHCpu6MOjtcOFgJPk7ULzab2A1a6kh2nytZbNJRyZxqsb20haY1dNXP00t7dOp/3XWcOAluGcNxdvH4dnrewDU2uG0i6tPfQdNWcWmWgYR6LNX+M0mGV3hrtrAEO3Nxe127PbTvk8FibROX0QwBGhtqbG1whVmOxG4mcR0DL/qjlN2RsIbkl83dm5UGTU9GayZL96UX8/IrNizaWqTute1v3tr1Ypde3XRESrt3aYgOOcXOMhsPeDXvLgtj3qyi4SnwBK1TBii8OoQm6E0H0QjcNfLT5X6lh+tKPi2pUfHAEG3ux5cmjZJnjH4LjGFTCASwq2WwWx8iN+AeYLCVyFkLKFRRn+JPhgbAuJLCm313axUt6H6tgl0XSikT6z1baTUMyVAjhaea46gsomKvuntnI5QR7TzlGymtdFTMaR3s5tns1b/v6smYg12ezNk17DOWeGb/y5fpy5d6o7FxtaW6TOGjMUWoRfBK3KjR5Y149ZOaPaP7FW6glJsSCt8QgpPr9PbfNSFNWrT2aFDjd6JnZOkGU7PQkXlNZ9dybwOnuPKzZ5ND+zxXY4IC2xF0xXg4M17Vh5eF7n6X7uKeZN7ENxxWlYgzl9tpMH1ZyP7/R2s1AqWi0Ps1CikjmHMYRi6Cv1Ss8hFvktTRX8xbVfisSbp+xdYqU+JDZwU0u1WLF+bSqO0bqZhmwPCa3SbRfluzWQx9ZOtTitDbFIxWyTcWFp5ocxVJVQwwo62nz7BA9CAF15tbYvHSYlhF1v+dGT7RcWygzM0NTuGYIdYzHAnfPO3s6clDp7ylzLqrBif0e6iCkDJGoagXSAUR3Wiq6Thk8g66KHjmKC0VOV2RVqwfEcnPZtq+njBB854D9/ruNfxOY0m7RKqXe+twCGc/QrWoi/3hSPEEWVUmDGsm4eD+Crp7bbmk2aWgUjm+894YjBgmAM6i1AG876qCdrlp1rfxt81O/4oTA0ppP/foArxZRNG5JD4DMMzmGkvlbwCsf5cCgufmqTSnoZRcFLPW0Aaz6Kel66Evuqmnlzo/KNKIeAOSFXEgQncx9V26quedvmKooAIsKaeqvEnFAxEpug39KMYTVjOpLhnGcz2LS4zUBehq0MZL/TAm4wlDnEWOZ+qiJ74TCl3REm9/ypc6SX1gSkQo7DfAYfQXm5dINT7fU8NA3hGGA0S8IRDNDJ/ffv+GMAiZkIoPxPAOJL4+Suz/8IP4eSLpqFj/kCYfsGY4d6r2EICgaGLYoWvh8NqJZjSu8+ziOkMnlW7izWkDAd0CUTCteBM/Y5NEI/F/dZOAvgh4IdTHX9AqobWC2265ThHj+yCiTx/lSrDhLZMY8BeprTThRkBrjgFpRGMIIERTEvwNL39VVl4URiIDapG6Q036trAuwRCWNF9CNr3zglVDA4V4IQHUTUH5xQw9Mkr6YYmo1YLiXqfKkkEFvnL7+ieZyN20KCGEUSXe0yjT9J04jFgsA+3EB2xfkgXFNrMIbueZQRDa8gzqxGM72j6IMoJSgEFwXw/U6KG9UvMtu4ch2qo3l94d1sSgVxTX0IuhFkN/miJ40DCka98NYpApAZU/K9SSIlfrB7MZMBllpldUHpCmZiwNPyxcBp1Z3HZ71qB1Ybv4tpLvqyybR21ERTt4TYV9Dapjx3KdjLbPlkoHm/nIWzdGOConyZiXgpJHqclR4HkG9k6lQJsM2beKz0GHO/8LH/2XGA==",
|
|
110
|
+
),
|
|
111
|
+
),
|
|
112
|
+
)
|
|
113
|
+
del copy_contents
|
|
114
|
+
|
|
115
|
+
import inspect
|
|
116
|
+
import sys
|
|
117
|
+
import datetime
|
|
118
|
+
import time
|
|
119
|
+
import textwrap
|
|
120
|
+
import contextlib
|
|
121
|
+
import functools
|
|
122
|
+
import json
|
|
123
|
+
import logging
|
|
124
|
+
import collections
|
|
125
|
+
import numbers
|
|
126
|
+
import ast
|
|
127
|
+
import os
|
|
128
|
+
import copy
|
|
129
|
+
import traceback
|
|
130
|
+
import executing
|
|
131
|
+
|
|
132
|
+
nv = object()
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def perf_counter():
|
|
136
|
+
return time.perf_counter() if _fixed_perf_counter is None else _fixed_perf_counter
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
from pathlib import Path
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def ycecream_pformat(obj, width, compact, indent, depth, sort_dicts, underscore_numbers):
|
|
143
|
+
return pformat(obj, width=width, compact=compact, indent=indent, depth=depth, sort_dicts=sort_dicts, underscore_numbers=underscore_numbers).replace(
|
|
144
|
+
"\\n", "\n"
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
class Source(executing.Source):
|
|
149
|
+
def get_text_with_indentation(self, node):
|
|
150
|
+
result = self.asttokens().get_text(node)
|
|
151
|
+
if "\n" in result:
|
|
152
|
+
result = " " * node.first_token.start[1] + result
|
|
153
|
+
result = dedent(result)
|
|
154
|
+
result = result.strip()
|
|
155
|
+
return result
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
class Default(object):
|
|
159
|
+
pass
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
default = Default()
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def change_path(new_path): # used in tests
|
|
166
|
+
global Path
|
|
167
|
+
Path = new_path
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
_fixed_perf_counter = None
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def fix_perf_counter(val): # for tests
|
|
174
|
+
global _fixed_perf_counter
|
|
175
|
+
_fixed_perf_counter = val
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
shortcut_to_name = {
|
|
179
|
+
"p": "prefix",
|
|
180
|
+
"o": "output",
|
|
181
|
+
"sln": "show_line_number",
|
|
182
|
+
"st": "show_time",
|
|
183
|
+
"sd": "show_delta",
|
|
184
|
+
"sdi": "sort_dicts",
|
|
185
|
+
"un": "underscore_numbers",
|
|
186
|
+
"se": "show_enter",
|
|
187
|
+
"sx": "show_exit",
|
|
188
|
+
"stb": "show_traceback",
|
|
189
|
+
"e": "enabled",
|
|
190
|
+
"ll": "line_length",
|
|
191
|
+
"c": "compact",
|
|
192
|
+
"i": "indent",
|
|
193
|
+
"de": "depth",
|
|
194
|
+
"wi": "wrap_indent",
|
|
195
|
+
"cs": "context_separator",
|
|
196
|
+
"sep": "separator",
|
|
197
|
+
"es": "equals_separator",
|
|
198
|
+
"vo": "values_only",
|
|
199
|
+
"voff": "values_only_for_fstrings",
|
|
200
|
+
"rn": "return_none",
|
|
201
|
+
"ell": "enforce_line_length",
|
|
202
|
+
"dl": "delta",
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
def set_defaults():
|
|
207
|
+
default.prefix = "y| "
|
|
208
|
+
default.output = "stderr"
|
|
209
|
+
default.serialize = ycecream_pformat # can't use pformat directly as that is defined later
|
|
210
|
+
default.show_line_number = False
|
|
211
|
+
default.show_time = False
|
|
212
|
+
default.show_delta = False
|
|
213
|
+
default.sort_dicts = False
|
|
214
|
+
default.underscore_numbers = False
|
|
215
|
+
default.show_enter = True
|
|
216
|
+
default.show_exit = True
|
|
217
|
+
default.show_traceback = False
|
|
218
|
+
default.enabled = True
|
|
219
|
+
default.line_length = 80
|
|
220
|
+
default.compact = False
|
|
221
|
+
default.indent = 1
|
|
222
|
+
default.depth = 1000000
|
|
223
|
+
default.wrap_indent = " "
|
|
224
|
+
default.context_separator = " ==> "
|
|
225
|
+
default.separator = ", "
|
|
226
|
+
default.equals_separator = ": "
|
|
227
|
+
default.values_only = False
|
|
228
|
+
default.values_only_for_fstrings = False
|
|
229
|
+
default.return_none = False
|
|
230
|
+
default.enforce_line_length = False
|
|
231
|
+
default.one_line_per_pairenforce_line_length = False
|
|
232
|
+
default.start_time = perf_counter()
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def apply_json():
|
|
236
|
+
ycecream_name = "ycecream"
|
|
237
|
+
|
|
238
|
+
config = {}
|
|
239
|
+
for path in sys.path:
|
|
240
|
+
json_file = os.path.join(path, ycecream_name + ".json")
|
|
241
|
+
if os.path.isfile(json_file):
|
|
242
|
+
with open(json_file, "r") as f:
|
|
243
|
+
config = json.load(f)
|
|
244
|
+
break
|
|
245
|
+
json_dir = os.path.join(path, ycecream_name)
|
|
246
|
+
json_file = os.path.join(json_dir, ycecream_name + ".json")
|
|
247
|
+
if os.path.isfile(json_file):
|
|
248
|
+
with open(json_file, "r") as f:
|
|
249
|
+
config = json.load(f)
|
|
250
|
+
break
|
|
251
|
+
|
|
252
|
+
for k, v in config.items():
|
|
253
|
+
if k in ("serialize", "start_time"):
|
|
254
|
+
raise ValueError("error in {json_file}: key {k} not allowed".format(json_file=json_file, k=k))
|
|
255
|
+
|
|
256
|
+
if k in shortcut_to_name:
|
|
257
|
+
k = shortcut_to_name[k]
|
|
258
|
+
if hasattr(default, k):
|
|
259
|
+
setattr(default, k, v)
|
|
260
|
+
else:
|
|
261
|
+
if k == "delta":
|
|
262
|
+
setattr(default, "start_time", perf_counter() - v)
|
|
263
|
+
else:
|
|
264
|
+
raise ValueError("error in {json_file}: key {k} not recognized".format(json_file=json_file, k=k))
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
def no_source_error(s=None):
|
|
268
|
+
if s is not None:
|
|
269
|
+
print(s) # for debugging only
|
|
270
|
+
raise NotImplementedError(
|
|
271
|
+
"""
|
|
272
|
+
Failed to access the underlying source code for analysis. Possible causes:
|
|
273
|
+
- decorated function/method definition spawns more than one line
|
|
274
|
+
- used from a frozen application (e.g. packaged with PyInstaller)
|
|
275
|
+
- underlying source code was changed during execution"""
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
def return_args(args, return_none):
|
|
280
|
+
if return_none:
|
|
281
|
+
return None
|
|
282
|
+
if len(args) == 0:
|
|
283
|
+
return None
|
|
284
|
+
if len(args) == 1:
|
|
285
|
+
return args[0]
|
|
286
|
+
return args
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
class _Y(object):
|
|
290
|
+
def __init__(
|
|
291
|
+
self,
|
|
292
|
+
prefix=nv,
|
|
293
|
+
output=nv,
|
|
294
|
+
serialize=nv,
|
|
295
|
+
show_line_number=nv,
|
|
296
|
+
show_time=nv,
|
|
297
|
+
show_delta=nv,
|
|
298
|
+
show_enter=nv,
|
|
299
|
+
show_exit=nv,
|
|
300
|
+
show_traceback=nv,
|
|
301
|
+
sort_dicts=nv,
|
|
302
|
+
underscore_numbers=nv,
|
|
303
|
+
enabled=nv,
|
|
304
|
+
line_length=nv,
|
|
305
|
+
compact=nv,
|
|
306
|
+
indent=nv,
|
|
307
|
+
depth=nv,
|
|
308
|
+
wrap_indent=nv,
|
|
309
|
+
context_separator=nv,
|
|
310
|
+
separator=nv,
|
|
311
|
+
equals_separator=nv,
|
|
312
|
+
values_only=nv,
|
|
313
|
+
values_only_for_fstrings=nv,
|
|
314
|
+
return_none=nv,
|
|
315
|
+
enforce_line_length=nv,
|
|
316
|
+
# decorator=nv,
|
|
317
|
+
# context_manager=nv,
|
|
318
|
+
delta=nv,
|
|
319
|
+
_parent=nv,
|
|
320
|
+
**kwargs,
|
|
321
|
+
):
|
|
322
|
+
self._attributes = {}
|
|
323
|
+
if _parent is nv:
|
|
324
|
+
self._parent = default
|
|
325
|
+
else:
|
|
326
|
+
self._parent = _parent
|
|
327
|
+
for key in vars(default):
|
|
328
|
+
setattr(self, key, None)
|
|
329
|
+
|
|
330
|
+
if _parent == default:
|
|
331
|
+
func = "y.new()"
|
|
332
|
+
else:
|
|
333
|
+
func = "y.fork()"
|
|
334
|
+
self.assign(kwargs, locals(), func=func)
|
|
335
|
+
|
|
336
|
+
self.check()
|
|
337
|
+
|
|
338
|
+
def __repr__(self):
|
|
339
|
+
pairs = []
|
|
340
|
+
for key in vars(default):
|
|
341
|
+
if not key.startswith("__"):
|
|
342
|
+
value = getattr(self, key)
|
|
343
|
+
if not callable(value):
|
|
344
|
+
pairs.append(str(key) + "=" + repr(value))
|
|
345
|
+
return "y.new(" + ", ".join(pairs) + ")"
|
|
346
|
+
|
|
347
|
+
def __getattr__(self, item):
|
|
348
|
+
if item in shortcut_to_name:
|
|
349
|
+
item = shortcut_to_name[item]
|
|
350
|
+
if item == "delta":
|
|
351
|
+
return perf_counter() - getattr(self, "start_time")
|
|
352
|
+
|
|
353
|
+
if item in self._attributes:
|
|
354
|
+
if self._attributes[item] is None:
|
|
355
|
+
return getattr(self._parent, item)
|
|
356
|
+
else:
|
|
357
|
+
return self._attributes[item]
|
|
358
|
+
raise AttributeError("{item} not found".format(item=item))
|
|
359
|
+
|
|
360
|
+
def __setattr__(self, item, value):
|
|
361
|
+
if item in shortcut_to_name:
|
|
362
|
+
item = shortcut_to_name[item]
|
|
363
|
+
if item == "delta":
|
|
364
|
+
item = "start_time"
|
|
365
|
+
if value is not None:
|
|
366
|
+
value = perf_counter() - value
|
|
367
|
+
|
|
368
|
+
if item in ["_attributes"]:
|
|
369
|
+
super(_Y, self).__setattr__(item, value)
|
|
370
|
+
else:
|
|
371
|
+
self._attributes[item] = value
|
|
372
|
+
|
|
373
|
+
def assign(self, shortcuts, source, func):
|
|
374
|
+
for key, value in shortcuts.items():
|
|
375
|
+
if key in shortcut_to_name:
|
|
376
|
+
if value is not nv:
|
|
377
|
+
full_name = shortcut_to_name[key]
|
|
378
|
+
if source[full_name] is nv:
|
|
379
|
+
source[full_name] = value
|
|
380
|
+
else:
|
|
381
|
+
raise ValueError("can't use {key} and {full_name} in {func}".format(key=key, full_name=full_name, func=func))
|
|
382
|
+
else:
|
|
383
|
+
raise TypeError("{func} got an unexpected keyword argument {key}".format(func=func, key=key))
|
|
384
|
+
for key, value in source.items():
|
|
385
|
+
if value is not nv:
|
|
386
|
+
if key == "delta":
|
|
387
|
+
key = "start_time"
|
|
388
|
+
if value is not None:
|
|
389
|
+
value = perf_counter() - value
|
|
390
|
+
setattr(self, key, value)
|
|
391
|
+
|
|
392
|
+
def fork(self, **kwargs):
|
|
393
|
+
kwargs["_parent"] = self
|
|
394
|
+
return _Y(**kwargs)
|
|
395
|
+
|
|
396
|
+
def __call__(self, *args, **kwargs):
|
|
397
|
+
prefix = kwargs.pop("prefix", nv)
|
|
398
|
+
output = kwargs.pop("output", nv)
|
|
399
|
+
serialize = kwargs.pop("serialize", nv)
|
|
400
|
+
show_line_number = kwargs.pop("show_line_number", nv)
|
|
401
|
+
show_time = kwargs.pop("show_time", nv)
|
|
402
|
+
show_delta = kwargs.pop("show_delta", nv)
|
|
403
|
+
show_enter = kwargs.pop("show_enter", nv)
|
|
404
|
+
show_exit = kwargs.pop("show_exit", nv)
|
|
405
|
+
show_traceback = kwargs.pop("show_traceback", nv)
|
|
406
|
+
sort_dicts = kwargs.pop("sort_dicts", nv)
|
|
407
|
+
underscore_numbers = kwargs.pop("underscore_numbers", nv)
|
|
408
|
+
enabled = kwargs.pop("enabled", nv)
|
|
409
|
+
line_length = kwargs.pop("line_length", nv)
|
|
410
|
+
compact = kwargs.pop("compact", nv)
|
|
411
|
+
indent = kwargs.pop("indent", nv)
|
|
412
|
+
depth = kwargs.pop("depth", nv)
|
|
413
|
+
wrap_indent = kwargs.pop("wrap_indent", nv)
|
|
414
|
+
context_separator = kwargs.pop("context_separator", nv)
|
|
415
|
+
separator = kwargs.pop("separator", nv)
|
|
416
|
+
equals_separator = kwargs.pop("equals_separator", nv)
|
|
417
|
+
values_only = kwargs.pop("values_only", nv)
|
|
418
|
+
values_only_for_fstrings = kwargs.pop("values_only_for_fstrings", nv)
|
|
419
|
+
return_none = kwargs.pop("return_none", nv)
|
|
420
|
+
enforce_line_length = kwargs.pop("enforce_line_length", nv)
|
|
421
|
+
decorator = kwargs.pop("decorator", nv)
|
|
422
|
+
d = kwargs.pop("decorator", nv)
|
|
423
|
+
context_manager = kwargs.pop("context_manager", nv)
|
|
424
|
+
cm = kwargs.pop("cm", nv)
|
|
425
|
+
delta = kwargs.pop("delta", nv)
|
|
426
|
+
as_str = kwargs.pop("as_str", nv)
|
|
427
|
+
provided = kwargs.pop("provided", nv)
|
|
428
|
+
pr = kwargs.pop("pr", nv)
|
|
429
|
+
|
|
430
|
+
if d is not nv and decorator is not nv:
|
|
431
|
+
raise TypeError("can't use both d and decorator")
|
|
432
|
+
if cm is not nv and context_manager is not nv:
|
|
433
|
+
raise TypeError("can't use both cm and context_manager")
|
|
434
|
+
if pr is not nv and provided is not nv:
|
|
435
|
+
raise TypeError("can't use both pr and provided")
|
|
436
|
+
|
|
437
|
+
as_str = False if as_str is nv else bool(as_str)
|
|
438
|
+
provided = True if provided is nv else bool(provided)
|
|
439
|
+
decorator = False if decorator is nv else bool(decorator)
|
|
440
|
+
context_manager = False if context_manager is nv else bool(context_manager)
|
|
441
|
+
|
|
442
|
+
if decorator and context_manager:
|
|
443
|
+
raise TypeError("decorator and context_manager can't be specified both.")
|
|
444
|
+
|
|
445
|
+
self.is_context_manager = False
|
|
446
|
+
|
|
447
|
+
Pair = collections.namedtuple("Pair", "left right")
|
|
448
|
+
|
|
449
|
+
this = self.fork()
|
|
450
|
+
this.assign(kwargs, locals(), func="__call__")
|
|
451
|
+
|
|
452
|
+
if this.enabled == [] and not (as_str or this.decorator or this.context_manager):
|
|
453
|
+
return return_args(args, this.return_none)
|
|
454
|
+
|
|
455
|
+
if not provided:
|
|
456
|
+
this.enabled = False
|
|
457
|
+
|
|
458
|
+
this.check()
|
|
459
|
+
|
|
460
|
+
call_frame = inspect.currentframe()
|
|
461
|
+
filename0 = call_frame.f_code.co_filename
|
|
462
|
+
|
|
463
|
+
call_frame = call_frame.f_back
|
|
464
|
+
filename = call_frame.f_code.co_filename
|
|
465
|
+
|
|
466
|
+
if filename == filename0:
|
|
467
|
+
call_frame = call_frame.f_back
|
|
468
|
+
filename = call_frame.f_code.co_filename
|
|
469
|
+
|
|
470
|
+
if filename in ("<stdin>", "<string>"):
|
|
471
|
+
filename_name = ""
|
|
472
|
+
code = "\n\n"
|
|
473
|
+
this_line = ""
|
|
474
|
+
this_line_prev = ""
|
|
475
|
+
line_number = 0
|
|
476
|
+
parent_function = ""
|
|
477
|
+
else:
|
|
478
|
+
try:
|
|
479
|
+
main_file = sys.modules["__main__"].__file__
|
|
480
|
+
main_file_resolved = os.path.abspath(main_file)
|
|
481
|
+
except AttributeError:
|
|
482
|
+
main_file_resolved = None
|
|
483
|
+
filename_resolved = os.path.abspath(filename)
|
|
484
|
+
if (filename.startswith("<") and filename.endswith(">")) or (main_file_resolved is None) or (filename_resolved == main_file_resolved):
|
|
485
|
+
filename_name = ""
|
|
486
|
+
else:
|
|
487
|
+
filename_name = "[" + os.path.basename(filename) + "]"
|
|
488
|
+
|
|
489
|
+
if filename not in codes:
|
|
490
|
+
frame_info = inspect.getframeinfo(call_frame, context=1000000) # get the full source code
|
|
491
|
+
if frame_info.code_context is None:
|
|
492
|
+
no_source_error()
|
|
493
|
+
codes[filename] = frame_info.code_context
|
|
494
|
+
code = codes[filename]
|
|
495
|
+
frame_info = inspect.getframeinfo(call_frame, context=1)
|
|
496
|
+
|
|
497
|
+
parent_function = frame_info.function # changed in version 1.3.10 ****
|
|
498
|
+
parent_function = Source.executing(call_frame).code_qualname()
|
|
499
|
+
parent_function = parent_function.replace(".<locals>.", ".")
|
|
500
|
+
if parent_function == "<module>" or str(this.show_line_number) in ("n", "no parent"):
|
|
501
|
+
parent_function = ""
|
|
502
|
+
else:
|
|
503
|
+
parent_function = " in {parent_function}()".format(parent_function=parent_function)
|
|
504
|
+
line_number = frame_info.lineno
|
|
505
|
+
if 0 <= line_number - 1 < len(code):
|
|
506
|
+
this_line = code[line_number - 1].strip()
|
|
507
|
+
else:
|
|
508
|
+
this_line = ""
|
|
509
|
+
if 0 <= line_number - 2 < len(code):
|
|
510
|
+
this_line_prev = code[line_number - 2].strip()
|
|
511
|
+
else:
|
|
512
|
+
this_line_prev = ""
|
|
513
|
+
if this_line.startswith("@") or this_line_prev.startswith("@") or this.decorator:
|
|
514
|
+
if as_str:
|
|
515
|
+
raise TypeError("as_str may not be True when y used as decorator")
|
|
516
|
+
|
|
517
|
+
for ln, line in enumerate(code[line_number - 1 :], line_number):
|
|
518
|
+
if line.strip().startswith("def") or line.strip().startswith("class"):
|
|
519
|
+
line_number = ln
|
|
520
|
+
break
|
|
521
|
+
else:
|
|
522
|
+
line_number += 1
|
|
523
|
+
this.line_number_with_filename_and_parent = "#{line_number}{filename_name}{parent_function}".format(
|
|
524
|
+
line_number=line_number, filename_name=filename_name, parent_function=parent_function
|
|
525
|
+
)
|
|
526
|
+
|
|
527
|
+
def real_decorator(function):
|
|
528
|
+
@functools.wraps(function)
|
|
529
|
+
def wrapper(*args, **kwargs):
|
|
530
|
+
enter_time = perf_counter()
|
|
531
|
+
context = this.context()
|
|
532
|
+
|
|
533
|
+
args_kwargs = [repr(arg) for arg in args] + ["{k}={repr_v}".format(k=k, repr_v=repr(v)) for k, v in kwargs.items()]
|
|
534
|
+
function_arguments = function.__name__ + "(" + (", ".join(args_kwargs)) + ")"
|
|
535
|
+
|
|
536
|
+
if this.show_enter:
|
|
537
|
+
this.do_output(
|
|
538
|
+
"{context}called {function_arguments}{traceback}".format(
|
|
539
|
+
context=context, function_arguments=function_arguments, traceback=this.traceback()
|
|
540
|
+
)
|
|
541
|
+
)
|
|
542
|
+
result = function(*args, **kwargs)
|
|
543
|
+
duration = perf_counter() - enter_time
|
|
544
|
+
|
|
545
|
+
context = this.context()
|
|
546
|
+
if this.show_exit:
|
|
547
|
+
this.do_output(
|
|
548
|
+
"{context}returned {repr_result} from {function_arguments} in {duration:.6f} seconds{traceback}".format(
|
|
549
|
+
context=context, repr_result=repr(result), function_arguments=function_arguments, duration=duration, traceback=this.traceback()
|
|
550
|
+
)
|
|
551
|
+
)
|
|
552
|
+
|
|
553
|
+
return result
|
|
554
|
+
|
|
555
|
+
return wrapper
|
|
556
|
+
|
|
557
|
+
if len(args) == 0:
|
|
558
|
+
return real_decorator
|
|
559
|
+
|
|
560
|
+
if len(args) == 1 and callable(args[0]):
|
|
561
|
+
return real_decorator(args[0])
|
|
562
|
+
raise TypeError("arguments are not allowed in y used as decorator")
|
|
563
|
+
|
|
564
|
+
if filename in ("<stdin>", "<string>"):
|
|
565
|
+
this.line_number_with_filename_and_parent = ""
|
|
566
|
+
else:
|
|
567
|
+
call_node = Source.executing(call_frame).node
|
|
568
|
+
if call_node is None:
|
|
569
|
+
no_source_error()
|
|
570
|
+
line_number = call_node.lineno
|
|
571
|
+
this_line = code[line_number - 1].strip()
|
|
572
|
+
|
|
573
|
+
this.line_number_with_filename_and_parent = "#{line_number}{filename_name}{parent_function}".format(
|
|
574
|
+
line_number=line_number, filename_name=filename_name, parent_function=parent_function
|
|
575
|
+
)
|
|
576
|
+
|
|
577
|
+
if this_line.startswith("with ") or this_line.startswith("with\t") or this.context_manager:
|
|
578
|
+
if as_str:
|
|
579
|
+
raise TypeError("as_str may not be True when y used as context manager")
|
|
580
|
+
if args:
|
|
581
|
+
raise TypeError("non-keyword arguments are not allowed when y used as context manager")
|
|
582
|
+
|
|
583
|
+
this.is_context_manager = True
|
|
584
|
+
return this
|
|
585
|
+
|
|
586
|
+
if not this.enabled and not as_str:
|
|
587
|
+
return return_args(args, this.return_none)
|
|
588
|
+
|
|
589
|
+
if args:
|
|
590
|
+
context = this.context()
|
|
591
|
+
pairs = []
|
|
592
|
+
if filename in ("<stdin>", "<string>") or this.values_only:
|
|
593
|
+
for right in args:
|
|
594
|
+
pairs.append(Pair(left="", right=right))
|
|
595
|
+
else:
|
|
596
|
+
source = Source.for_frame(call_frame)
|
|
597
|
+
for node, right in zip(call_node.args, args):
|
|
598
|
+
left = source.asttokens().get_text(node)
|
|
599
|
+
if "\n" in left:
|
|
600
|
+
left = " " * node.first_token.start[1] + left
|
|
601
|
+
left = textwrap.dedent(left)
|
|
602
|
+
try:
|
|
603
|
+
ast.literal_eval(left) # it's indeed a literal
|
|
604
|
+
left = ""
|
|
605
|
+
except Exception:
|
|
606
|
+
pass
|
|
607
|
+
if left:
|
|
608
|
+
try:
|
|
609
|
+
if isinstance(left, str):
|
|
610
|
+
s = ast.parse(left, mode="eval")
|
|
611
|
+
if isinstance(s, ast.Expression):
|
|
612
|
+
s = s.body
|
|
613
|
+
if s and isinstance(s, ast.JoinedStr): # it is indeed an f-string
|
|
614
|
+
if this.values_only_for_fstrings:
|
|
615
|
+
left = ""
|
|
616
|
+
except Exception:
|
|
617
|
+
pass
|
|
618
|
+
if left:
|
|
619
|
+
left += this.equals_separator
|
|
620
|
+
pairs.append(Pair(left=left, right=right))
|
|
621
|
+
|
|
622
|
+
just_one_line = False
|
|
623
|
+
if not (len(pairs) > 1 and this.separator == ""):
|
|
624
|
+
if not any("\n" in pair.left for pair in pairs):
|
|
625
|
+
as_one_line = context + this.separator.join(pair.left + this.serialize_kwargs(obj=pair.right, width=10000) for pair in pairs)
|
|
626
|
+
if len(as_one_line) <= this.line_length and "\n" not in as_one_line:
|
|
627
|
+
out = as_one_line
|
|
628
|
+
just_one_line = True
|
|
629
|
+
|
|
630
|
+
if not just_one_line:
|
|
631
|
+
if isinstance(this.wrap_indent, numbers.Number):
|
|
632
|
+
wrap_indent = int(this.wrap_indent) * " "
|
|
633
|
+
else:
|
|
634
|
+
wrap_indent = str(this.wrap_indent)
|
|
635
|
+
|
|
636
|
+
if context.strip():
|
|
637
|
+
if len(context.rstrip()) >= len(wrap_indent):
|
|
638
|
+
indent1 = wrap_indent
|
|
639
|
+
indent1_rest = wrap_indent
|
|
640
|
+
lines = [context]
|
|
641
|
+
else:
|
|
642
|
+
indent1 = context.rstrip().ljust(len(wrap_indent))
|
|
643
|
+
indent1_rest = wrap_indent
|
|
644
|
+
lines = []
|
|
645
|
+
else:
|
|
646
|
+
indent1 = ""
|
|
647
|
+
indent1_rest = ""
|
|
648
|
+
lines = []
|
|
649
|
+
|
|
650
|
+
for pair in pairs:
|
|
651
|
+
do_right = False
|
|
652
|
+
if "\n" in pair.left:
|
|
653
|
+
for s in pair.left.splitlines():
|
|
654
|
+
lines.append(indent1 + s)
|
|
655
|
+
do_right = True
|
|
656
|
+
else:
|
|
657
|
+
start = indent1 + pair.left
|
|
658
|
+
line = start + this.serialize_kwargs(obj=pair.right, width=this.line_length - len(start))
|
|
659
|
+
if "\n" in line:
|
|
660
|
+
lines.append(start)
|
|
661
|
+
do_right = True
|
|
662
|
+
else:
|
|
663
|
+
lines.append(line)
|
|
664
|
+
indent1 = indent1_rest
|
|
665
|
+
if do_right:
|
|
666
|
+
indent2 = indent1 + wrap_indent
|
|
667
|
+
line = this.serialize_kwargs(obj=pair.right, width=this.line_length - len(indent2))
|
|
668
|
+
for s in line.splitlines():
|
|
669
|
+
lines.append(indent2 + s)
|
|
670
|
+
|
|
671
|
+
out = "\n".join(line.rstrip() for line in lines)
|
|
672
|
+
|
|
673
|
+
else:
|
|
674
|
+
if not this.show_line_number: # if "n" or "no parent", keep that info
|
|
675
|
+
this.show_line_number = True
|
|
676
|
+
out = this.context(omit_context_separator=True)
|
|
677
|
+
|
|
678
|
+
if this.show_traceback:
|
|
679
|
+
out += this.traceback()
|
|
680
|
+
|
|
681
|
+
if as_str:
|
|
682
|
+
if this.enabled:
|
|
683
|
+
if this.enforce_line_length:
|
|
684
|
+
out = "\n".join(line[: this.line_length] for line in out.splitlines())
|
|
685
|
+
return out + "\n"
|
|
686
|
+
else:
|
|
687
|
+
return ""
|
|
688
|
+
this.do_output(out)
|
|
689
|
+
|
|
690
|
+
return return_args(args, this.return_none)
|
|
691
|
+
|
|
692
|
+
def configure(
|
|
693
|
+
self,
|
|
694
|
+
prefix=nv,
|
|
695
|
+
output=nv,
|
|
696
|
+
serialize=nv,
|
|
697
|
+
show_line_number=nv,
|
|
698
|
+
show_time=nv,
|
|
699
|
+
show_delta=nv,
|
|
700
|
+
show_enter=nv,
|
|
701
|
+
show_exit=nv,
|
|
702
|
+
show_traceback=nv,
|
|
703
|
+
sort_dicts=nv,
|
|
704
|
+
underscore_numbers=nv,
|
|
705
|
+
enabled=nv,
|
|
706
|
+
line_length=nv,
|
|
707
|
+
compact=nv,
|
|
708
|
+
indent=nv,
|
|
709
|
+
depth=nv,
|
|
710
|
+
wrap_indent=nv,
|
|
711
|
+
context_separator=nv,
|
|
712
|
+
separator=nv,
|
|
713
|
+
equals_separator=nv,
|
|
714
|
+
values_only=nv,
|
|
715
|
+
values_only_for_fstrings=nv,
|
|
716
|
+
return_none=nv,
|
|
717
|
+
enforce_line_length=nv,
|
|
718
|
+
# decorator=nv,
|
|
719
|
+
# context_manager=nv,
|
|
720
|
+
delta=nv,
|
|
721
|
+
**kwargs,
|
|
722
|
+
):
|
|
723
|
+
self.assign(kwargs, locals(), "configure()")
|
|
724
|
+
self.check()
|
|
725
|
+
return self
|
|
726
|
+
|
|
727
|
+
def new(self, ignore_json=False, **kwargs):
|
|
728
|
+
if ignore_json:
|
|
729
|
+
return _Y(_parent=default_pre_json, **kwargs)
|
|
730
|
+
else:
|
|
731
|
+
return _Y(**kwargs)
|
|
732
|
+
|
|
733
|
+
def clone(
|
|
734
|
+
self,
|
|
735
|
+
prefix=nv,
|
|
736
|
+
output=nv,
|
|
737
|
+
serialize=nv,
|
|
738
|
+
show_line_number=nv,
|
|
739
|
+
show_time=nv,
|
|
740
|
+
show_delta=nv,
|
|
741
|
+
show_enter=nv,
|
|
742
|
+
show_exit=nv,
|
|
743
|
+
show_traceback=nv,
|
|
744
|
+
sort_dicts=nv,
|
|
745
|
+
underscore_numbers=nv,
|
|
746
|
+
enabled=nv,
|
|
747
|
+
line_length=nv,
|
|
748
|
+
compact=nv,
|
|
749
|
+
indent=nv,
|
|
750
|
+
depth=nv,
|
|
751
|
+
wrap_indent=nv,
|
|
752
|
+
context_separator=nv,
|
|
753
|
+
separator=nv,
|
|
754
|
+
equals_separator=nv,
|
|
755
|
+
values_only=nv,
|
|
756
|
+
values_only_for_fstrings=nv,
|
|
757
|
+
return_none=nv,
|
|
758
|
+
enforce_line_length=nv,
|
|
759
|
+
# decorator=nv,
|
|
760
|
+
# context_manager=nv,
|
|
761
|
+
delta=nv,
|
|
762
|
+
**kwargs,
|
|
763
|
+
):
|
|
764
|
+
this = _Y(_parent=self._parent)
|
|
765
|
+
this.assign({}, self._attributes, func="clone()")
|
|
766
|
+
this.assign(kwargs, locals(), func="clone()")
|
|
767
|
+
|
|
768
|
+
return this
|
|
769
|
+
|
|
770
|
+
def assert_(self, condition):
|
|
771
|
+
if self.enabled:
|
|
772
|
+
assert condition
|
|
773
|
+
|
|
774
|
+
@contextlib.contextmanager
|
|
775
|
+
def preserve(self):
|
|
776
|
+
save = dict(self._attributes)
|
|
777
|
+
yield
|
|
778
|
+
self._attributes = save
|
|
779
|
+
|
|
780
|
+
def __enter__(self):
|
|
781
|
+
if not hasattr(self, "is_context_manager"):
|
|
782
|
+
raise ValueError("not allowed as context_manager")
|
|
783
|
+
self.save_traceback = self.traceback()
|
|
784
|
+
self.enter_time = perf_counter()
|
|
785
|
+
if self.show_enter:
|
|
786
|
+
context = self.context()
|
|
787
|
+
self.do_output(context + "enter" + self.save_traceback)
|
|
788
|
+
return self
|
|
789
|
+
|
|
790
|
+
def __exit__(self, *args):
|
|
791
|
+
if self.show_exit:
|
|
792
|
+
context = self.context()
|
|
793
|
+
duration = perf_counter() - self.enter_time
|
|
794
|
+
self.do_output("{context}exit in {duration:.6f} seconds{traceback}".format(context=context, duration=duration, traceback=self.save_traceback))
|
|
795
|
+
self.is_context_manager = False
|
|
796
|
+
|
|
797
|
+
def context(self, omit_context_separator=False):
|
|
798
|
+
if self.show_line_number and self.line_number_with_filename_and_parent != "":
|
|
799
|
+
parts = [self.line_number_with_filename_and_parent]
|
|
800
|
+
else:
|
|
801
|
+
parts = []
|
|
802
|
+
if self.show_time:
|
|
803
|
+
parts.append("@ " + str(datetime.datetime.now().strftime("%H:%M:%S.%f")))
|
|
804
|
+
|
|
805
|
+
if self.show_delta:
|
|
806
|
+
t0 = perf_counter() - self.start_time
|
|
807
|
+
parts.append("delta={t0:.3f}".format(t0=t0))
|
|
808
|
+
|
|
809
|
+
context = " ".join(parts)
|
|
810
|
+
if not omit_context_separator and context:
|
|
811
|
+
context += self.context_separator
|
|
812
|
+
|
|
813
|
+
return (self.prefix() if callable(self.prefix) else self.prefix) + context
|
|
814
|
+
|
|
815
|
+
def do_output(self, s):
|
|
816
|
+
if self.enforce_line_length:
|
|
817
|
+
s = "\n".join(line[: self.line_length] for line in s.splitlines())
|
|
818
|
+
if self.enabled:
|
|
819
|
+
if callable(self.output):
|
|
820
|
+
self.output(s)
|
|
821
|
+
elif self.output == "stderr":
|
|
822
|
+
print(s, file=sys.stderr)
|
|
823
|
+
elif self.output == "stdout":
|
|
824
|
+
print(s, file=sys.stdout)
|
|
825
|
+
elif self.output == "logging.debug":
|
|
826
|
+
logging.debug(s)
|
|
827
|
+
elif self.output == "logging.info":
|
|
828
|
+
logging.info(s)
|
|
829
|
+
elif self.output == "logging.warning":
|
|
830
|
+
logging.warning(s)
|
|
831
|
+
elif self.output == "logging.error":
|
|
832
|
+
logging.error(s)
|
|
833
|
+
elif self.output == "logging.critical":
|
|
834
|
+
logging.critical(s)
|
|
835
|
+
elif self.output in ("", "null"):
|
|
836
|
+
pass
|
|
837
|
+
|
|
838
|
+
elif isinstance(self.output, str):
|
|
839
|
+
with open(self.output, "a+", encoding="utf-8") as f:
|
|
840
|
+
print(s, file=f)
|
|
841
|
+
elif isinstance(self.output, Path):
|
|
842
|
+
with self.output.open("a+", encoding="utf-8") as f:
|
|
843
|
+
print(s, file=f)
|
|
844
|
+
|
|
845
|
+
else:
|
|
846
|
+
print(s, file=self.output)
|
|
847
|
+
|
|
848
|
+
def traceback(self):
|
|
849
|
+
if self.show_traceback:
|
|
850
|
+
if isinstance(self.wrap_indent, numbers.Number):
|
|
851
|
+
wrap_indent = int(self.wrap_indent) * " "
|
|
852
|
+
else:
|
|
853
|
+
wrap_indent = str(self.wrap_indent)
|
|
854
|
+
|
|
855
|
+
result = "\n" + wrap_indent + "Traceback (most recent call last)\n"
|
|
856
|
+
# Python 2.7 does not allow entry.filename, entry.line, etc, so we have to index entry
|
|
857
|
+
return result + "\n".join(
|
|
858
|
+
wrap_indent + ' File "' + entry[0] + '", line ' + str(entry[1]) + ", in " + entry[2] + "\n" + wrap_indent + " " + entry[3]
|
|
859
|
+
for entry in traceback.extract_stack()[:-2]
|
|
860
|
+
)
|
|
861
|
+
else:
|
|
862
|
+
return ""
|
|
863
|
+
|
|
864
|
+
def check(self):
|
|
865
|
+
if callable(self.output):
|
|
866
|
+
return
|
|
867
|
+
if isinstance(self.output, (str, Path)):
|
|
868
|
+
return
|
|
869
|
+
try:
|
|
870
|
+
self.output.write("")
|
|
871
|
+
return
|
|
872
|
+
|
|
873
|
+
except Exception:
|
|
874
|
+
pass
|
|
875
|
+
raise TypeError("output should be a callable, str, Path or open text file.")
|
|
876
|
+
|
|
877
|
+
def serialize_kwargs(self, obj, width):
|
|
878
|
+
kwargs = {
|
|
879
|
+
key: getattr(self, key)
|
|
880
|
+
for key in ("sort_dicts", "compact", "indent", "depth", "underscore_numbers")
|
|
881
|
+
if key in inspect.signature(self.serialize).parameters
|
|
882
|
+
}
|
|
883
|
+
if "width" in inspect.signature(self.serialize).parameters:
|
|
884
|
+
kwargs["width"] = width
|
|
885
|
+
return self.serialize(obj, **kwargs)
|
|
886
|
+
|
|
887
|
+
|
|
888
|
+
codes = {}
|
|
889
|
+
|
|
890
|
+
set_defaults()
|
|
891
|
+
default_pre_json = copy.copy(default)
|
|
892
|
+
apply_json()
|
|
893
|
+
y = _Y()
|
|
894
|
+
yc = y.fork(prefix="yc| ")
|
|
895
|
+
|
|
896
|
+
|
|
897
|
+
# source of pprint (3.13) module
|
|
898
|
+
|
|
899
|
+
# Author: Fred L. Drake, Jr.
|
|
900
|
+
# fdrake@acm.org
|
|
901
|
+
#
|
|
902
|
+
# This is a simple little module I wrote to make life easier. I didn't
|
|
903
|
+
# see anything quite like it in the library, though I may have overlooked
|
|
904
|
+
# something. I wrote this when I was trying to read some heavily nested
|
|
905
|
+
# tuples with fairly non-descriptive content. This is modeled very much
|
|
906
|
+
# after Lisp/Scheme - style pretty-printing of lists. If you find it
|
|
907
|
+
# useful, thank small children who sleep at night.
|
|
908
|
+
|
|
909
|
+
"""Support to pretty-print lists, tuples, & dictionaries recursively.
|
|
910
|
+
|
|
911
|
+
Very simple, but useful, especially in debugging data structures.
|
|
912
|
+
|
|
913
|
+
Classes
|
|
914
|
+
-------
|
|
915
|
+
|
|
916
|
+
PrettyPrinter()
|
|
917
|
+
Handle pretty-printing operations onto a stream using a configured
|
|
918
|
+
set of formatting parameters.
|
|
919
|
+
|
|
920
|
+
Functions
|
|
921
|
+
---------
|
|
922
|
+
|
|
923
|
+
pformat()
|
|
924
|
+
Format a Python object into a pretty-printed representation.
|
|
925
|
+
|
|
926
|
+
pprint()
|
|
927
|
+
Pretty-print a Python object to a stream [default is sys.stdout].
|
|
928
|
+
|
|
929
|
+
saferepr()
|
|
930
|
+
Generate a 'standard' repr()-like value, but protect against recursive
|
|
931
|
+
data structures.
|
|
932
|
+
|
|
933
|
+
"""
|
|
934
|
+
|
|
935
|
+
import collections as _collections
|
|
936
|
+
import sys as _sys
|
|
937
|
+
import types as _types
|
|
938
|
+
from io import StringIO as _StringIO
|
|
939
|
+
|
|
940
|
+
|
|
941
|
+
def pprint(object, stream=None, indent=1, width=80, depth=None, *, compact=False, sort_dicts=True, underscore_numbers=False):
|
|
942
|
+
"""Pretty-print a Python object to a stream [default is sys.stdout]."""
|
|
943
|
+
printer = PrettyPrinter(
|
|
944
|
+
stream=stream, indent=indent, width=width, depth=depth, compact=compact, sort_dicts=sort_dicts, underscore_numbers=underscore_numbers
|
|
945
|
+
)
|
|
946
|
+
printer.pprint(object)
|
|
947
|
+
|
|
948
|
+
|
|
949
|
+
def pformat(object, indent=1, width=80, depth=None, *, compact=False, sort_dicts=True, underscore_numbers=False):
|
|
950
|
+
"""Format a Python object into a pretty-printed representation."""
|
|
951
|
+
return PrettyPrinter(indent=indent, width=width, depth=depth, compact=compact, sort_dicts=sort_dicts, underscore_numbers=underscore_numbers).pformat(object)
|
|
952
|
+
|
|
953
|
+
|
|
954
|
+
def pp(object, *args, sort_dicts=False, **kwargs):
|
|
955
|
+
"""Pretty-print a Python object"""
|
|
956
|
+
pprint(object, *args, sort_dicts=sort_dicts, **kwargs)
|
|
957
|
+
|
|
958
|
+
|
|
959
|
+
def saferepr(object):
|
|
960
|
+
"""Version of repr() which can handle recursive data structures."""
|
|
961
|
+
return PrettyPrinter()._safe_repr(object, {}, None, 0)[0]
|
|
962
|
+
|
|
963
|
+
|
|
964
|
+
def isreadable(object):
|
|
965
|
+
"""Determine if saferepr(object) is readable by eval()."""
|
|
966
|
+
return PrettyPrinter()._safe_repr(object, {}, None, 0)[1]
|
|
967
|
+
|
|
968
|
+
|
|
969
|
+
def isrecursive(object):
|
|
970
|
+
"""Determine if object requires a recursive representation."""
|
|
971
|
+
return PrettyPrinter()._safe_repr(object, {}, None, 0)[2]
|
|
972
|
+
|
|
973
|
+
|
|
974
|
+
class _safe_key:
|
|
975
|
+
"""Helper function for key functions when sorting unorderable objects.
|
|
976
|
+
|
|
977
|
+
The wrapped-object will fallback to a Py2.x style comparison for
|
|
978
|
+
unorderable types (sorting first comparing the type name and then by
|
|
979
|
+
the obj ids). Does not work recursively, so dict.items() must have
|
|
980
|
+
_safe_key applied to both the key and the value.
|
|
981
|
+
|
|
982
|
+
"""
|
|
983
|
+
|
|
984
|
+
__slots__ = ["obj"]
|
|
985
|
+
|
|
986
|
+
def __init__(self, obj):
|
|
987
|
+
self.obj = obj
|
|
988
|
+
|
|
989
|
+
def __lt__(self, other):
|
|
990
|
+
try:
|
|
991
|
+
return self.obj < other.obj
|
|
992
|
+
except TypeError:
|
|
993
|
+
return (str(type(self.obj)), id(self.obj)) < (str(type(other.obj)), id(other.obj))
|
|
994
|
+
|
|
995
|
+
|
|
996
|
+
def _safe_tuple(t):
|
|
997
|
+
"Helper function for comparing 2-tuples"
|
|
998
|
+
return _safe_key(t[0]), _safe_key(t[1])
|
|
999
|
+
|
|
1000
|
+
|
|
1001
|
+
class PrettyPrinter:
|
|
1002
|
+
def __init__(self, indent=1, width=80, depth=None, stream=None, *, compact=False, sort_dicts=True, underscore_numbers=False):
|
|
1003
|
+
"""Handle pretty printing operations onto a stream using a set of
|
|
1004
|
+
configured parameters.
|
|
1005
|
+
|
|
1006
|
+
indent
|
|
1007
|
+
Number of spaces to indent for each level of nesting.
|
|
1008
|
+
|
|
1009
|
+
width
|
|
1010
|
+
Attempted maximum number of columns in the output.
|
|
1011
|
+
|
|
1012
|
+
depth
|
|
1013
|
+
The maximum depth to print out nested structures.
|
|
1014
|
+
|
|
1015
|
+
stream
|
|
1016
|
+
The desired output stream. If omitted (or false), the standard
|
|
1017
|
+
output stream available at construction will be used.
|
|
1018
|
+
|
|
1019
|
+
compact
|
|
1020
|
+
If true, several items will be combined in one line.
|
|
1021
|
+
|
|
1022
|
+
sort_dicts
|
|
1023
|
+
If true, dict keys are sorted.
|
|
1024
|
+
|
|
1025
|
+
underscore_numbers
|
|
1026
|
+
If true, digit groups are separated with underscores.
|
|
1027
|
+
|
|
1028
|
+
"""
|
|
1029
|
+
indent = int(indent)
|
|
1030
|
+
width = int(width)
|
|
1031
|
+
if indent < 0:
|
|
1032
|
+
raise ValueError("indent must be >= 0")
|
|
1033
|
+
if depth is not None and depth <= 0:
|
|
1034
|
+
raise ValueError("depth must be > 0")
|
|
1035
|
+
if not width:
|
|
1036
|
+
raise ValueError("width must be != 0")
|
|
1037
|
+
self._depth = depth
|
|
1038
|
+
self._indent_per_level = indent
|
|
1039
|
+
self._width = width
|
|
1040
|
+
if stream is not None:
|
|
1041
|
+
self._stream = stream
|
|
1042
|
+
else:
|
|
1043
|
+
self._stream = _sys.stdout
|
|
1044
|
+
self._compact = bool(compact)
|
|
1045
|
+
self._sort_dicts = sort_dicts
|
|
1046
|
+
self._underscore_numbers = underscore_numbers
|
|
1047
|
+
|
|
1048
|
+
def pprint(self, object):
|
|
1049
|
+
if self._stream is not None:
|
|
1050
|
+
self._format(object, self._stream, 0, 0, {}, 0)
|
|
1051
|
+
self._stream.write("\n")
|
|
1052
|
+
|
|
1053
|
+
def pformat(self, object):
|
|
1054
|
+
sio = _StringIO()
|
|
1055
|
+
self._format(object, sio, 0, 0, {}, 0)
|
|
1056
|
+
return sio.getvalue()
|
|
1057
|
+
|
|
1058
|
+
def isrecursive(self, object):
|
|
1059
|
+
return self.format(object, {}, 0, 0)[2]
|
|
1060
|
+
|
|
1061
|
+
def isreadable(self, object):
|
|
1062
|
+
s, readable, recursive = self.format(object, {}, 0, 0)
|
|
1063
|
+
return readable and not recursive
|
|
1064
|
+
|
|
1065
|
+
def _format(self, object, stream, indent, allowance, context, level):
|
|
1066
|
+
objid = id(object)
|
|
1067
|
+
if objid in context:
|
|
1068
|
+
stream.write(_recursion(object))
|
|
1069
|
+
self._recursive = True
|
|
1070
|
+
self._readable = False
|
|
1071
|
+
return
|
|
1072
|
+
rep = self._repr(object, context, level)
|
|
1073
|
+
max_width = self._width - indent - allowance
|
|
1074
|
+
if len(rep) > max_width:
|
|
1075
|
+
p = self._dispatch.get(type(object).__repr__, None)
|
|
1076
|
+
# Lazy import to improve module import time
|
|
1077
|
+
from dataclasses import is_dataclass
|
|
1078
|
+
|
|
1079
|
+
if p is not None:
|
|
1080
|
+
context[objid] = 1
|
|
1081
|
+
p(self, object, stream, indent, allowance, context, level + 1)
|
|
1082
|
+
del context[objid]
|
|
1083
|
+
return
|
|
1084
|
+
elif (
|
|
1085
|
+
is_dataclass(object)
|
|
1086
|
+
and not isinstance(object, type)
|
|
1087
|
+
and object.__dataclass_params__.repr
|
|
1088
|
+
and
|
|
1089
|
+
# Check dataclass has generated repr method.
|
|
1090
|
+
hasattr(object.__repr__, "__wrapped__")
|
|
1091
|
+
and "__create_fn__" in object.__repr__.__wrapped__.__qualname__
|
|
1092
|
+
):
|
|
1093
|
+
context[objid] = 1
|
|
1094
|
+
self._pprint_dataclass(object, stream, indent, allowance, context, level + 1)
|
|
1095
|
+
del context[objid]
|
|
1096
|
+
return
|
|
1097
|
+
stream.write(rep)
|
|
1098
|
+
|
|
1099
|
+
def _pprint_dataclass(self, object, stream, indent, allowance, context, level):
|
|
1100
|
+
# Lazy import to improve module import time
|
|
1101
|
+
from dataclasses import fields as dataclass_fields
|
|
1102
|
+
|
|
1103
|
+
cls_name = object.__class__.__name__
|
|
1104
|
+
indent += len(cls_name) + 1
|
|
1105
|
+
items = [(f.name, getattr(object, f.name)) for f in dataclass_fields(object) if f.repr]
|
|
1106
|
+
stream.write(cls_name + "(")
|
|
1107
|
+
self._format_namespace_items(items, stream, indent, allowance, context, level)
|
|
1108
|
+
stream.write(")")
|
|
1109
|
+
|
|
1110
|
+
_dispatch = {}
|
|
1111
|
+
|
|
1112
|
+
def _pprint_dict(self, object, stream, indent, allowance, context, level):
|
|
1113
|
+
write = stream.write
|
|
1114
|
+
write("{")
|
|
1115
|
+
if self._indent_per_level > 1:
|
|
1116
|
+
write((self._indent_per_level - 1) * " ")
|
|
1117
|
+
length = len(object)
|
|
1118
|
+
if length:
|
|
1119
|
+
if self._sort_dicts:
|
|
1120
|
+
items = sorted(object.items(), key=_safe_tuple)
|
|
1121
|
+
else:
|
|
1122
|
+
items = object.items()
|
|
1123
|
+
self._format_dict_items(items, stream, indent, allowance + 1, context, level)
|
|
1124
|
+
write("}")
|
|
1125
|
+
|
|
1126
|
+
_dispatch[dict.__repr__] = _pprint_dict
|
|
1127
|
+
|
|
1128
|
+
def _pprint_ordered_dict(self, object, stream, indent, allowance, context, level):
|
|
1129
|
+
if not len(object):
|
|
1130
|
+
stream.write(repr(object))
|
|
1131
|
+
return
|
|
1132
|
+
cls = object.__class__
|
|
1133
|
+
stream.write(cls.__name__ + "(")
|
|
1134
|
+
self._format(list(object.items()), stream, indent + len(cls.__name__) + 1, allowance + 1, context, level)
|
|
1135
|
+
stream.write(")")
|
|
1136
|
+
|
|
1137
|
+
_dispatch[_collections.OrderedDict.__repr__] = _pprint_ordered_dict
|
|
1138
|
+
|
|
1139
|
+
def _pprint_list(self, object, stream, indent, allowance, context, level):
|
|
1140
|
+
stream.write("[")
|
|
1141
|
+
self._format_items(object, stream, indent, allowance + 1, context, level)
|
|
1142
|
+
stream.write("]")
|
|
1143
|
+
|
|
1144
|
+
_dispatch[list.__repr__] = _pprint_list
|
|
1145
|
+
|
|
1146
|
+
def _pprint_tuple(self, object, stream, indent, allowance, context, level):
|
|
1147
|
+
stream.write("(")
|
|
1148
|
+
endchar = ",)" if len(object) == 1 else ")"
|
|
1149
|
+
self._format_items(object, stream, indent, allowance + len(endchar), context, level)
|
|
1150
|
+
stream.write(endchar)
|
|
1151
|
+
|
|
1152
|
+
_dispatch[tuple.__repr__] = _pprint_tuple
|
|
1153
|
+
|
|
1154
|
+
def _pprint_set(self, object, stream, indent, allowance, context, level):
|
|
1155
|
+
if not len(object):
|
|
1156
|
+
stream.write(repr(object))
|
|
1157
|
+
return
|
|
1158
|
+
typ = object.__class__
|
|
1159
|
+
if typ is set:
|
|
1160
|
+
stream.write("{")
|
|
1161
|
+
endchar = "}"
|
|
1162
|
+
else:
|
|
1163
|
+
stream.write(typ.__name__ + "({")
|
|
1164
|
+
endchar = "})"
|
|
1165
|
+
indent += len(typ.__name__) + 1
|
|
1166
|
+
object = sorted(object, key=_safe_key)
|
|
1167
|
+
self._format_items(object, stream, indent, allowance + len(endchar), context, level)
|
|
1168
|
+
stream.write(endchar)
|
|
1169
|
+
|
|
1170
|
+
_dispatch[set.__repr__] = _pprint_set
|
|
1171
|
+
_dispatch[frozenset.__repr__] = _pprint_set
|
|
1172
|
+
|
|
1173
|
+
def _pprint_str(self, object, stream, indent, allowance, context, level):
|
|
1174
|
+
write = stream.write
|
|
1175
|
+
if not len(object):
|
|
1176
|
+
write(repr(object))
|
|
1177
|
+
return
|
|
1178
|
+
chunks = []
|
|
1179
|
+
lines = object.splitlines(True)
|
|
1180
|
+
if level == 1:
|
|
1181
|
+
indent += 1
|
|
1182
|
+
allowance += 1
|
|
1183
|
+
max_width1 = max_width = self._width - indent
|
|
1184
|
+
for i, line in enumerate(lines):
|
|
1185
|
+
rep = repr(line)
|
|
1186
|
+
if i == len(lines) - 1:
|
|
1187
|
+
max_width1 -= allowance
|
|
1188
|
+
if len(rep) <= max_width1:
|
|
1189
|
+
chunks.append(rep)
|
|
1190
|
+
else:
|
|
1191
|
+
# Lazy import to improve module import time
|
|
1192
|
+
import re
|
|
1193
|
+
|
|
1194
|
+
# A list of alternating (non-space, space) strings
|
|
1195
|
+
parts = re.findall(r"\S*\s*", line)
|
|
1196
|
+
assert parts
|
|
1197
|
+
assert not parts[-1]
|
|
1198
|
+
parts.pop() # drop empty last part
|
|
1199
|
+
max_width2 = max_width
|
|
1200
|
+
current = ""
|
|
1201
|
+
for j, part in enumerate(parts):
|
|
1202
|
+
candidate = current + part
|
|
1203
|
+
if j == len(parts) - 1 and i == len(lines) - 1:
|
|
1204
|
+
max_width2 -= allowance
|
|
1205
|
+
if len(repr(candidate)) > max_width2:
|
|
1206
|
+
if current:
|
|
1207
|
+
chunks.append(repr(current))
|
|
1208
|
+
current = part
|
|
1209
|
+
else:
|
|
1210
|
+
current = candidate
|
|
1211
|
+
if current:
|
|
1212
|
+
chunks.append(repr(current))
|
|
1213
|
+
if len(chunks) == 1:
|
|
1214
|
+
write(rep)
|
|
1215
|
+
return
|
|
1216
|
+
if level == 1:
|
|
1217
|
+
write("(")
|
|
1218
|
+
for i, rep in enumerate(chunks):
|
|
1219
|
+
if i > 0:
|
|
1220
|
+
write("\n" + " " * indent)
|
|
1221
|
+
write(rep)
|
|
1222
|
+
if level == 1:
|
|
1223
|
+
write(")")
|
|
1224
|
+
|
|
1225
|
+
_dispatch[str.__repr__] = _pprint_str
|
|
1226
|
+
|
|
1227
|
+
def _pprint_bytes(self, object, stream, indent, allowance, context, level):
|
|
1228
|
+
write = stream.write
|
|
1229
|
+
if len(object) <= 4:
|
|
1230
|
+
write(repr(object))
|
|
1231
|
+
return
|
|
1232
|
+
parens = level == 1
|
|
1233
|
+
if parens:
|
|
1234
|
+
indent += 1
|
|
1235
|
+
allowance += 1
|
|
1236
|
+
write("(")
|
|
1237
|
+
delim = ""
|
|
1238
|
+
for rep in _wrap_bytes_repr(object, self._width - indent, allowance):
|
|
1239
|
+
write(delim)
|
|
1240
|
+
write(rep)
|
|
1241
|
+
if not delim:
|
|
1242
|
+
delim = "\n" + " " * indent
|
|
1243
|
+
if parens:
|
|
1244
|
+
write(")")
|
|
1245
|
+
|
|
1246
|
+
_dispatch[bytes.__repr__] = _pprint_bytes
|
|
1247
|
+
|
|
1248
|
+
def _pprint_bytearray(self, object, stream, indent, allowance, context, level):
|
|
1249
|
+
write = stream.write
|
|
1250
|
+
write("bytearray(")
|
|
1251
|
+
self._pprint_bytes(bytes(object), stream, indent + 10, allowance + 1, context, level + 1)
|
|
1252
|
+
write(")")
|
|
1253
|
+
|
|
1254
|
+
_dispatch[bytearray.__repr__] = _pprint_bytearray
|
|
1255
|
+
|
|
1256
|
+
def _pprint_mappingproxy(self, object, stream, indent, allowance, context, level):
|
|
1257
|
+
stream.write("mappingproxy(")
|
|
1258
|
+
self._format(object.copy(), stream, indent + 13, allowance + 1, context, level)
|
|
1259
|
+
stream.write(")")
|
|
1260
|
+
|
|
1261
|
+
_dispatch[_types.MappingProxyType.__repr__] = _pprint_mappingproxy
|
|
1262
|
+
|
|
1263
|
+
def _pprint_simplenamespace(self, object, stream, indent, allowance, context, level):
|
|
1264
|
+
if type(object) is _types.SimpleNamespace:
|
|
1265
|
+
# The SimpleNamespace repr is "namespace" instead of the class
|
|
1266
|
+
# name, so we do the same here. For subclasses; use the class name.
|
|
1267
|
+
cls_name = "namespace"
|
|
1268
|
+
else:
|
|
1269
|
+
cls_name = object.__class__.__name__
|
|
1270
|
+
indent += len(cls_name) + 1
|
|
1271
|
+
items = object.__dict__.items()
|
|
1272
|
+
stream.write(cls_name + "(")
|
|
1273
|
+
self._format_namespace_items(items, stream, indent, allowance, context, level)
|
|
1274
|
+
stream.write(")")
|
|
1275
|
+
|
|
1276
|
+
_dispatch[_types.SimpleNamespace.__repr__] = _pprint_simplenamespace
|
|
1277
|
+
|
|
1278
|
+
def _format_dict_items(self, items, stream, indent, allowance, context, level):
|
|
1279
|
+
write = stream.write
|
|
1280
|
+
indent += self._indent_per_level
|
|
1281
|
+
delimnl = ",\n" + " " * indent
|
|
1282
|
+
last_index = len(items) - 1
|
|
1283
|
+
for i, (key, ent) in enumerate(items):
|
|
1284
|
+
last = i == last_index
|
|
1285
|
+
rep = self._repr(key, context, level)
|
|
1286
|
+
write(rep)
|
|
1287
|
+
write(": ")
|
|
1288
|
+
self._format(ent, stream, indent + len(rep) + 2, allowance if last else 1, context, level)
|
|
1289
|
+
if not last:
|
|
1290
|
+
write(delimnl)
|
|
1291
|
+
|
|
1292
|
+
def _format_namespace_items(self, items, stream, indent, allowance, context, level):
|
|
1293
|
+
write = stream.write
|
|
1294
|
+
delimnl = ",\n" + " " * indent
|
|
1295
|
+
last_index = len(items) - 1
|
|
1296
|
+
for i, (key, ent) in enumerate(items):
|
|
1297
|
+
last = i == last_index
|
|
1298
|
+
write(key)
|
|
1299
|
+
write("=")
|
|
1300
|
+
if id(ent) in context:
|
|
1301
|
+
# Special-case representation of recursion to match standard
|
|
1302
|
+
# recursive dataclass repr.
|
|
1303
|
+
write("...")
|
|
1304
|
+
else:
|
|
1305
|
+
self._format(ent, stream, indent + len(key) + 1, allowance if last else 1, context, level)
|
|
1306
|
+
if not last:
|
|
1307
|
+
write(delimnl)
|
|
1308
|
+
|
|
1309
|
+
def _format_items(self, items, stream, indent, allowance, context, level):
|
|
1310
|
+
write = stream.write
|
|
1311
|
+
indent += self._indent_per_level
|
|
1312
|
+
if self._indent_per_level > 1:
|
|
1313
|
+
write((self._indent_per_level - 1) * " ")
|
|
1314
|
+
delimnl = ",\n" + " " * indent
|
|
1315
|
+
delim = ""
|
|
1316
|
+
width = max_width = self._width - indent + 1
|
|
1317
|
+
it = iter(items)
|
|
1318
|
+
try:
|
|
1319
|
+
next_ent = next(it)
|
|
1320
|
+
except StopIteration:
|
|
1321
|
+
return
|
|
1322
|
+
last = False
|
|
1323
|
+
while not last:
|
|
1324
|
+
ent = next_ent
|
|
1325
|
+
try:
|
|
1326
|
+
next_ent = next(it)
|
|
1327
|
+
except StopIteration:
|
|
1328
|
+
last = True
|
|
1329
|
+
max_width -= allowance
|
|
1330
|
+
width -= allowance
|
|
1331
|
+
if self._compact:
|
|
1332
|
+
rep = self._repr(ent, context, level)
|
|
1333
|
+
w = len(rep) + 2
|
|
1334
|
+
if width < w:
|
|
1335
|
+
width = max_width
|
|
1336
|
+
if delim:
|
|
1337
|
+
delim = delimnl
|
|
1338
|
+
if width >= w:
|
|
1339
|
+
width -= w
|
|
1340
|
+
write(delim)
|
|
1341
|
+
delim = ", "
|
|
1342
|
+
write(rep)
|
|
1343
|
+
continue
|
|
1344
|
+
write(delim)
|
|
1345
|
+
delim = delimnl
|
|
1346
|
+
self._format(ent, stream, indent, allowance if last else 1, context, level)
|
|
1347
|
+
|
|
1348
|
+
def _repr(self, object, context, level):
|
|
1349
|
+
repr, readable, recursive = self.format(object, context.copy(), self._depth, level)
|
|
1350
|
+
if not readable:
|
|
1351
|
+
self._readable = False
|
|
1352
|
+
if recursive:
|
|
1353
|
+
self._recursive = True
|
|
1354
|
+
return repr
|
|
1355
|
+
|
|
1356
|
+
def format(self, object, context, maxlevels, level):
|
|
1357
|
+
"""Format object for a specific context, returning a string
|
|
1358
|
+
and flags indicating whether the representation is 'readable'
|
|
1359
|
+
and whether the object represents a recursive construct.
|
|
1360
|
+
"""
|
|
1361
|
+
return self._safe_repr(object, context, maxlevels, level)
|
|
1362
|
+
|
|
1363
|
+
def _pprint_default_dict(self, object, stream, indent, allowance, context, level):
|
|
1364
|
+
if not len(object):
|
|
1365
|
+
stream.write(repr(object))
|
|
1366
|
+
return
|
|
1367
|
+
rdf = self._repr(object.default_factory, context, level)
|
|
1368
|
+
cls = object.__class__
|
|
1369
|
+
indent += len(cls.__name__) + 1
|
|
1370
|
+
stream.write("%s(%s,\n%s" % (cls.__name__, rdf, " " * indent))
|
|
1371
|
+
self._pprint_dict(object, stream, indent, allowance + 1, context, level)
|
|
1372
|
+
stream.write(")")
|
|
1373
|
+
|
|
1374
|
+
_dispatch[_collections.defaultdict.__repr__] = _pprint_default_dict
|
|
1375
|
+
|
|
1376
|
+
def _pprint_counter(self, object, stream, indent, allowance, context, level):
|
|
1377
|
+
if not len(object):
|
|
1378
|
+
stream.write(repr(object))
|
|
1379
|
+
return
|
|
1380
|
+
cls = object.__class__
|
|
1381
|
+
stream.write(cls.__name__ + "({")
|
|
1382
|
+
if self._indent_per_level > 1:
|
|
1383
|
+
stream.write((self._indent_per_level - 1) * " ")
|
|
1384
|
+
items = object.most_common()
|
|
1385
|
+
self._format_dict_items(items, stream, indent + len(cls.__name__) + 1, allowance + 2, context, level)
|
|
1386
|
+
stream.write("})")
|
|
1387
|
+
|
|
1388
|
+
_dispatch[_collections.Counter.__repr__] = _pprint_counter
|
|
1389
|
+
|
|
1390
|
+
def _pprint_chain_map(self, object, stream, indent, allowance, context, level):
|
|
1391
|
+
if not len(object.maps):
|
|
1392
|
+
stream.write(repr(object))
|
|
1393
|
+
return
|
|
1394
|
+
cls = object.__class__
|
|
1395
|
+
stream.write(cls.__name__ + "(")
|
|
1396
|
+
indent += len(cls.__name__) + 1
|
|
1397
|
+
for i, m in enumerate(object.maps):
|
|
1398
|
+
if i == len(object.maps) - 1:
|
|
1399
|
+
self._format(m, stream, indent, allowance + 1, context, level)
|
|
1400
|
+
stream.write(")")
|
|
1401
|
+
else:
|
|
1402
|
+
self._format(m, stream, indent, 1, context, level)
|
|
1403
|
+
stream.write(",\n" + " " * indent)
|
|
1404
|
+
|
|
1405
|
+
_dispatch[_collections.ChainMap.__repr__] = _pprint_chain_map
|
|
1406
|
+
|
|
1407
|
+
def _pprint_deque(self, object, stream, indent, allowance, context, level):
|
|
1408
|
+
if not len(object):
|
|
1409
|
+
stream.write(repr(object))
|
|
1410
|
+
return
|
|
1411
|
+
cls = object.__class__
|
|
1412
|
+
stream.write(cls.__name__ + "(")
|
|
1413
|
+
indent += len(cls.__name__) + 1
|
|
1414
|
+
stream.write("[")
|
|
1415
|
+
if object.maxlen is None:
|
|
1416
|
+
self._format_items(object, stream, indent, allowance + 2, context, level)
|
|
1417
|
+
stream.write("])")
|
|
1418
|
+
else:
|
|
1419
|
+
self._format_items(object, stream, indent, 2, context, level)
|
|
1420
|
+
rml = self._repr(object.maxlen, context, level)
|
|
1421
|
+
stream.write("],\n%smaxlen=%s)" % (" " * indent, rml))
|
|
1422
|
+
|
|
1423
|
+
_dispatch[_collections.deque.__repr__] = _pprint_deque
|
|
1424
|
+
|
|
1425
|
+
def _pprint_user_dict(self, object, stream, indent, allowance, context, level):
|
|
1426
|
+
self._format(object.data, stream, indent, allowance, context, level - 1)
|
|
1427
|
+
|
|
1428
|
+
_dispatch[_collections.UserDict.__repr__] = _pprint_user_dict
|
|
1429
|
+
|
|
1430
|
+
def _pprint_user_list(self, object, stream, indent, allowance, context, level):
|
|
1431
|
+
self._format(object.data, stream, indent, allowance, context, level - 1)
|
|
1432
|
+
|
|
1433
|
+
_dispatch[_collections.UserList.__repr__] = _pprint_user_list
|
|
1434
|
+
|
|
1435
|
+
def _pprint_user_string(self, object, stream, indent, allowance, context, level):
|
|
1436
|
+
self._format(object.data, stream, indent, allowance, context, level - 1)
|
|
1437
|
+
|
|
1438
|
+
_dispatch[_collections.UserString.__repr__] = _pprint_user_string
|
|
1439
|
+
|
|
1440
|
+
def _safe_repr(self, object, context, maxlevels, level):
|
|
1441
|
+
# Return triple (repr_string, isreadable, isrecursive).
|
|
1442
|
+
typ = type(object)
|
|
1443
|
+
if typ in _builtin_scalars:
|
|
1444
|
+
return repr(object), True, False
|
|
1445
|
+
|
|
1446
|
+
r = getattr(typ, "__repr__", None)
|
|
1447
|
+
|
|
1448
|
+
if issubclass(typ, int) and r is int.__repr__:
|
|
1449
|
+
if self._underscore_numbers:
|
|
1450
|
+
return f"{object:_d}", True, False
|
|
1451
|
+
else:
|
|
1452
|
+
return repr(object), True, False
|
|
1453
|
+
|
|
1454
|
+
if issubclass(typ, dict) and r is dict.__repr__:
|
|
1455
|
+
if not object:
|
|
1456
|
+
return "{}", True, False
|
|
1457
|
+
objid = id(object)
|
|
1458
|
+
if maxlevels and level >= maxlevels:
|
|
1459
|
+
return "{...}", False, objid in context
|
|
1460
|
+
if objid in context:
|
|
1461
|
+
return _recursion(object), False, True
|
|
1462
|
+
context[objid] = 1
|
|
1463
|
+
readable = True
|
|
1464
|
+
recursive = False
|
|
1465
|
+
components = []
|
|
1466
|
+
append = components.append
|
|
1467
|
+
level += 1
|
|
1468
|
+
if self._sort_dicts:
|
|
1469
|
+
items = sorted(object.items(), key=_safe_tuple)
|
|
1470
|
+
else:
|
|
1471
|
+
items = object.items()
|
|
1472
|
+
for k, v in items:
|
|
1473
|
+
krepr, kreadable, krecur = self.format(k, context, maxlevels, level)
|
|
1474
|
+
vrepr, vreadable, vrecur = self.format(v, context, maxlevels, level)
|
|
1475
|
+
append("%s: %s" % (krepr, vrepr))
|
|
1476
|
+
readable = readable and kreadable and vreadable
|
|
1477
|
+
if krecur or vrecur:
|
|
1478
|
+
recursive = True
|
|
1479
|
+
del context[objid]
|
|
1480
|
+
return "{%s}" % ", ".join(components), readable, recursive
|
|
1481
|
+
|
|
1482
|
+
if (issubclass(typ, list) and r is list.__repr__) or (issubclass(typ, tuple) and r is tuple.__repr__):
|
|
1483
|
+
if issubclass(typ, list):
|
|
1484
|
+
if not object:
|
|
1485
|
+
return "[]", True, False
|
|
1486
|
+
format = "[%s]"
|
|
1487
|
+
elif len(object) == 1:
|
|
1488
|
+
format = "(%s,)"
|
|
1489
|
+
else:
|
|
1490
|
+
if not object:
|
|
1491
|
+
return "()", True, False
|
|
1492
|
+
format = "(%s)"
|
|
1493
|
+
objid = id(object)
|
|
1494
|
+
if maxlevels and level >= maxlevels:
|
|
1495
|
+
return format % "...", False, objid in context
|
|
1496
|
+
if objid in context:
|
|
1497
|
+
return _recursion(object), False, True
|
|
1498
|
+
context[objid] = 1
|
|
1499
|
+
readable = True
|
|
1500
|
+
recursive = False
|
|
1501
|
+
components = []
|
|
1502
|
+
append = components.append
|
|
1503
|
+
level += 1
|
|
1504
|
+
for o in object:
|
|
1505
|
+
orepr, oreadable, orecur = self.format(o, context, maxlevels, level)
|
|
1506
|
+
append(orepr)
|
|
1507
|
+
if not oreadable:
|
|
1508
|
+
readable = False
|
|
1509
|
+
if orecur:
|
|
1510
|
+
recursive = True
|
|
1511
|
+
del context[objid]
|
|
1512
|
+
return format % ", ".join(components), readable, recursive
|
|
1513
|
+
|
|
1514
|
+
rep = repr(object)
|
|
1515
|
+
return rep, (rep and not rep.startswith("<")), False
|
|
1516
|
+
|
|
1517
|
+
|
|
1518
|
+
_builtin_scalars = frozenset({str, bytes, bytearray, float, complex, bool, type(None)})
|
|
1519
|
+
|
|
1520
|
+
|
|
1521
|
+
def _recursion(object):
|
|
1522
|
+
return "<Recursion on %s with id=%s>" % (type(object).__name__, id(object))
|
|
1523
|
+
|
|
1524
|
+
|
|
1525
|
+
def _wrap_bytes_repr(object, width, allowance):
|
|
1526
|
+
current = b""
|
|
1527
|
+
last = len(object) // 4 * 4
|
|
1528
|
+
for i in range(0, len(object), 4):
|
|
1529
|
+
part = object[i : i + 4]
|
|
1530
|
+
candidate = current + part
|
|
1531
|
+
if i == last:
|
|
1532
|
+
width -= allowance
|
|
1533
|
+
if len(repr(candidate)) > width:
|
|
1534
|
+
if current:
|
|
1535
|
+
yield repr(current)
|
|
1536
|
+
current = part
|
|
1537
|
+
else:
|
|
1538
|
+
current = candidate
|
|
1539
|
+
if current:
|
|
1540
|
+
yield repr(current)
|
|
1541
|
+
|