peek-python 25.0.1__tar.gz → 25.0.2.post0__tar.gz
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_python-25.0.1 → peek_python-25.0.2.post0}/PKG-INFO +61 -9
- {peek_python-25.0.1 → peek_python-25.0.2.post0}/README.md +59 -7
- {peek_python-25.0.1 → peek_python-25.0.2.post0}/peek/peek.py +111 -67
- {peek_python-25.0.1 → peek_python-25.0.2.post0}/peek_python.egg-info/PKG-INFO +61 -9
- {peek_python-25.0.1 → peek_python-25.0.2.post0}/pyproject.toml +1 -1
- {peek_python-25.0.1 → peek_python-25.0.2.post0}/tests/test_peek.py +22 -3
- {peek_python-25.0.1 → peek_python-25.0.2.post0}/license.txt +0 -0
- {peek_python-25.0.1 → peek_python-25.0.2.post0}/peek/__init__.py +0 -0
- {peek_python-25.0.1 → peek_python-25.0.2.post0}/peek_python.egg-info/SOURCES.txt +0 -0
- {peek_python-25.0.1 → peek_python-25.0.2.post0}/peek_python.egg-info/dependency_links.txt +0 -0
- {peek_python-25.0.1 → peek_python-25.0.2.post0}/peek_python.egg-info/requires.txt +0 -0
- {peek_python-25.0.1 → peek_python-25.0.2.post0}/peek_python.egg-info/top_level.txt +0 -0
- {peek_python-25.0.1 → peek_python-25.0.2.post0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: peek-python
|
|
3
|
-
Version: 25.0.
|
|
3
|
+
Version: 25.0.2.post0
|
|
4
4
|
Summary: peek - debugging and benchmarking made easy
|
|
5
5
|
Author-email: Ruud van der Ham <rt.van.der.ham@gmail.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/salabim/peek
|
|
@@ -46,13 +46,13 @@ And on top of that, you get some basic benchmarking functionality.
|
|
|
46
46
|
|
|
47
47
|
* [Use peek.print to use peek like print with extras](#use-peekprint-to-use-peek-like-print-with-extras)
|
|
48
48
|
|
|
49
|
+
* [Peeking locals and globals](#peeking-locals-and-globals)
|
|
50
|
+
|
|
49
51
|
* [Return a string instead of sending to output](#return-a-string-instead-of-sending-to-output)
|
|
50
52
|
|
|
51
53
|
* [Disabling peek's output](#disabling-peeks-output)
|
|
52
54
|
|
|
53
|
-
* [Using
|
|
54
|
-
|
|
55
|
-
* [Using color to control peek output](#using-color-to-control-peek-output)
|
|
55
|
+
* [Using filter to control peek output](#using-filter-to-control-peek-output)
|
|
56
56
|
|
|
57
57
|
* [Copying to the clipboard](#copying-to-the-clipboard)
|
|
58
58
|
|
|
@@ -173,7 +173,7 @@ for number in range(10):
|
|
|
173
173
|
|
|
174
174
|
This will result in:
|
|
175
175
|
|
|
176
|
-
<img src="https://www.salabim.org/peek/
|
|
176
|
+
<img src="https://www.salabim.org/peek/peek_picture1.png" width=50%>
|
|
177
177
|
|
|
178
178
|
# Inspect execution
|
|
179
179
|
|
|
@@ -658,8 +658,11 @@ d=
|
|
|
658
658
|
|
|
659
659
|
## color / col and color_value / colv
|
|
660
660
|
The color attribute is used to specify the color of the output.
|
|
661
|
-
|
|
662
|
-
|
|
661
|
+
|
|
662
|
+
There's a choice of `"black"`, `"white"`, `"red"`, `"green"`, `"blue"`, `"cyan"`, `"magenta"`, `"yellow"`, `" dark_black"`, `"dark_white"`, `"dark_red"`, `"dark_green"`, `"dark_blue"`, `"dark_cyan"`, `"dark_magenta"` and `"dark_yellow"`:
|
|
663
|
+
|
|
664
|
+
<img src="https://www.salabim.org/peek/peek_picture2.png" width=25%>
|
|
665
|
+
To set the color to 'nothing'", "use "-".
|
|
663
666
|
|
|
664
667
|
On top of that, color_value may be used to specify the value part of an output item. By specifying color_value as "" (the default), the value part will be displayed with the same color as the rest of the output.
|
|
665
668
|
|
|
@@ -677,7 +680,7 @@ peek(item1, item2, color="red", color_value="green")
|
|
|
677
680
|
|
|
678
681
|
will result in:
|
|
679
682
|
|
|
680
|
-
<img src="https://www.salabim.org/peek/
|
|
683
|
+
<img src="https://www.salabim.org/peek/peek_picture3.png" width=30%>
|
|
681
684
|
|
|
682
685
|
Of course, color and color_value may be specified in a peek.toml file, to make all peek output in a specified color.
|
|
683
686
|
|
|
@@ -1098,6 +1101,35 @@ peek.sep = "|" # sets the 'normal' peek separator
|
|
|
1098
1101
|
>
|
|
1099
1102
|
> `peek.print` does not obey the line length and will always return None (unless as_str is True).
|
|
1100
1103
|
|
|
1104
|
+
|
|
1105
|
+
# Peeking locals and globals
|
|
1106
|
+
It is possible to get the name and values of all local or global variables.
|
|
1107
|
+
|
|
1108
|
+
To do that, just put `locals` or `globals` in the call to peek, e.g.:
|
|
1109
|
+
|
|
1110
|
+
```
|
|
1111
|
+
def my_func():
|
|
1112
|
+
a = 10
|
|
1113
|
+
b = a * a
|
|
1114
|
+
peek(locals)
|
|
1115
|
+
my_func()
|
|
1116
|
+
```
|
|
1117
|
+
|
|
1118
|
+
will print all local variables, apart from those starting with `__`, so:
|
|
1119
|
+
```
|
|
1120
|
+
a=10, b=100
|
|
1121
|
+
```
|
|
1122
|
+
|
|
1123
|
+
Likewise,
|
|
1124
|
+
```
|
|
1125
|
+
peek(globals)
|
|
1126
|
+
```
|
|
1127
|
+
will print all global variables, apart from those starting with `__`
|
|
1128
|
+
|
|
1129
|
+
> [!IMPORTANT]
|
|
1130
|
+
>
|
|
1131
|
+
> You should not add parentheses after `locals` or `globals` for peek to work properly!
|
|
1132
|
+
|
|
1101
1133
|
# Return a string instead of sending to output
|
|
1102
1134
|
|
|
1103
1135
|
`peek(*args, as_str=True)` is like `peek(*args)` but the output is returned as a string instead
|
|
@@ -1115,6 +1147,23 @@ hello='world'
|
|
|
1115
1147
|
|
|
1116
1148
|
Note that if enabled=False, the call will return the null string (`""`).
|
|
1117
1149
|
|
|
1150
|
+
It is also possible to return a string with the embedded ANSI color escape strings, which can be useful to process the output in another program that supports ANSI colors, like salabim. This is done by setting the `as_colored_str` argument to True:
|
|
1151
|
+
```
|
|
1152
|
+
hello = "world"
|
|
1153
|
+
s = peek(hello, color="red", color_value="green", as_colored_str=True)
|
|
1154
|
+
print(repr(s), end="")
|
|
1155
|
+
```
|
|
1156
|
+
prints
|
|
1157
|
+
```
|
|
1158
|
+
"\x1b[1;31mhello=\x1b[1;32m'world'\x1b[1;31m\n\x1b[0m"
|
|
1159
|
+
```
|
|
1160
|
+
|
|
1161
|
+
> [!NOTE]
|
|
1162
|
+
>
|
|
1163
|
+
> Specifying both `as_str` and `as_colored_str` is not allowed.
|
|
1164
|
+
|
|
1165
|
+
|
|
1166
|
+
|
|
1118
1167
|
# Disabling peek's output
|
|
1119
1168
|
|
|
1120
1169
|
```
|
|
@@ -1423,6 +1472,7 @@ can show traceback yes no
|
|
|
1423
1472
|
can be used like print w/extras yes (with peek.print) no
|
|
1424
1473
|
allows non linefeed printing yes (via end parameter) requires patching
|
|
1425
1474
|
PEP8 (Pythonic) API yes no
|
|
1475
|
+
format specification optional no
|
|
1426
1476
|
sorts dicts no by default, optional *) yes
|
|
1427
1477
|
supports compact, indent,
|
|
1428
1478
|
and underscore_numbers
|
|
@@ -1432,9 +1482,11 @@ external configuration via toml file no
|
|
|
1432
1482
|
level control yes no
|
|
1433
1483
|
observes line_length correctly yes no
|
|
1434
1484
|
benchmarking functionality yes no
|
|
1485
|
+
can peek locals or globals yes no
|
|
1435
1486
|
suppress f-strings at left hand optional no
|
|
1436
1487
|
indentation 4 blanks (overridable) length of prefix
|
|
1437
1488
|
forking and cloning yes no
|
|
1489
|
+
handling of source problems peeks only the value warning issued
|
|
1438
1490
|
test script pytest unittest
|
|
1439
1491
|
colorize ***) yes, off by default yes, on by default
|
|
1440
1492
|
-----------------------------------------------------------------------------------------
|
|
@@ -26,13 +26,13 @@ And on top of that, you get some basic benchmarking functionality.
|
|
|
26
26
|
|
|
27
27
|
* [Use peek.print to use peek like print with extras](#use-peekprint-to-use-peek-like-print-with-extras)
|
|
28
28
|
|
|
29
|
+
* [Peeking locals and globals](#peeking-locals-and-globals)
|
|
30
|
+
|
|
29
31
|
* [Return a string instead of sending to output](#return-a-string-instead-of-sending-to-output)
|
|
30
32
|
|
|
31
33
|
* [Disabling peek's output](#disabling-peeks-output)
|
|
32
34
|
|
|
33
|
-
* [Using
|
|
34
|
-
|
|
35
|
-
* [Using color to control peek output](#using-color-to-control-peek-output)
|
|
35
|
+
* [Using filter to control peek output](#using-filter-to-control-peek-output)
|
|
36
36
|
|
|
37
37
|
* [Copying to the clipboard](#copying-to-the-clipboard)
|
|
38
38
|
|
|
@@ -153,7 +153,7 @@ for number in range(10):
|
|
|
153
153
|
|
|
154
154
|
This will result in:
|
|
155
155
|
|
|
156
|
-
<img src="https://www.salabim.org/peek/
|
|
156
|
+
<img src="https://www.salabim.org/peek/peek_picture1.png" width=50%>
|
|
157
157
|
|
|
158
158
|
# Inspect execution
|
|
159
159
|
|
|
@@ -638,8 +638,11 @@ d=
|
|
|
638
638
|
|
|
639
639
|
## color / col and color_value / colv
|
|
640
640
|
The color attribute is used to specify the color of the output.
|
|
641
|
-
|
|
642
|
-
|
|
641
|
+
|
|
642
|
+
There's a choice of `"black"`, `"white"`, `"red"`, `"green"`, `"blue"`, `"cyan"`, `"magenta"`, `"yellow"`, `" dark_black"`, `"dark_white"`, `"dark_red"`, `"dark_green"`, `"dark_blue"`, `"dark_cyan"`, `"dark_magenta"` and `"dark_yellow"`:
|
|
643
|
+
|
|
644
|
+
<img src="https://www.salabim.org/peek/peek_picture2.png" width=25%>
|
|
645
|
+
To set the color to 'nothing'", "use "-".
|
|
643
646
|
|
|
644
647
|
On top of that, color_value may be used to specify the value part of an output item. By specifying color_value as "" (the default), the value part will be displayed with the same color as the rest of the output.
|
|
645
648
|
|
|
@@ -657,7 +660,7 @@ peek(item1, item2, color="red", color_value="green")
|
|
|
657
660
|
|
|
658
661
|
will result in:
|
|
659
662
|
|
|
660
|
-
<img src="https://www.salabim.org/peek/
|
|
663
|
+
<img src="https://www.salabim.org/peek/peek_picture3.png" width=30%>
|
|
661
664
|
|
|
662
665
|
Of course, color and color_value may be specified in a peek.toml file, to make all peek output in a specified color.
|
|
663
666
|
|
|
@@ -1078,6 +1081,35 @@ peek.sep = "|" # sets the 'normal' peek separator
|
|
|
1078
1081
|
>
|
|
1079
1082
|
> `peek.print` does not obey the line length and will always return None (unless as_str is True).
|
|
1080
1083
|
|
|
1084
|
+
|
|
1085
|
+
# Peeking locals and globals
|
|
1086
|
+
It is possible to get the name and values of all local or global variables.
|
|
1087
|
+
|
|
1088
|
+
To do that, just put `locals` or `globals` in the call to peek, e.g.:
|
|
1089
|
+
|
|
1090
|
+
```
|
|
1091
|
+
def my_func():
|
|
1092
|
+
a = 10
|
|
1093
|
+
b = a * a
|
|
1094
|
+
peek(locals)
|
|
1095
|
+
my_func()
|
|
1096
|
+
```
|
|
1097
|
+
|
|
1098
|
+
will print all local variables, apart from those starting with `__`, so:
|
|
1099
|
+
```
|
|
1100
|
+
a=10, b=100
|
|
1101
|
+
```
|
|
1102
|
+
|
|
1103
|
+
Likewise,
|
|
1104
|
+
```
|
|
1105
|
+
peek(globals)
|
|
1106
|
+
```
|
|
1107
|
+
will print all global variables, apart from those starting with `__`
|
|
1108
|
+
|
|
1109
|
+
> [!IMPORTANT]
|
|
1110
|
+
>
|
|
1111
|
+
> You should not add parentheses after `locals` or `globals` for peek to work properly!
|
|
1112
|
+
|
|
1081
1113
|
# Return a string instead of sending to output
|
|
1082
1114
|
|
|
1083
1115
|
`peek(*args, as_str=True)` is like `peek(*args)` but the output is returned as a string instead
|
|
@@ -1095,6 +1127,23 @@ hello='world'
|
|
|
1095
1127
|
|
|
1096
1128
|
Note that if enabled=False, the call will return the null string (`""`).
|
|
1097
1129
|
|
|
1130
|
+
It is also possible to return a string with the embedded ANSI color escape strings, which can be useful to process the output in another program that supports ANSI colors, like salabim. This is done by setting the `as_colored_str` argument to True:
|
|
1131
|
+
```
|
|
1132
|
+
hello = "world"
|
|
1133
|
+
s = peek(hello, color="red", color_value="green", as_colored_str=True)
|
|
1134
|
+
print(repr(s), end="")
|
|
1135
|
+
```
|
|
1136
|
+
prints
|
|
1137
|
+
```
|
|
1138
|
+
"\x1b[1;31mhello=\x1b[1;32m'world'\x1b[1;31m\n\x1b[0m"
|
|
1139
|
+
```
|
|
1140
|
+
|
|
1141
|
+
> [!NOTE]
|
|
1142
|
+
>
|
|
1143
|
+
> Specifying both `as_str` and `as_colored_str` is not allowed.
|
|
1144
|
+
|
|
1145
|
+
|
|
1146
|
+
|
|
1098
1147
|
# Disabling peek's output
|
|
1099
1148
|
|
|
1100
1149
|
```
|
|
@@ -1403,6 +1452,7 @@ can show traceback yes no
|
|
|
1403
1452
|
can be used like print w/extras yes (with peek.print) no
|
|
1404
1453
|
allows non linefeed printing yes (via end parameter) requires patching
|
|
1405
1454
|
PEP8 (Pythonic) API yes no
|
|
1455
|
+
format specification optional no
|
|
1406
1456
|
sorts dicts no by default, optional *) yes
|
|
1407
1457
|
supports compact, indent,
|
|
1408
1458
|
and underscore_numbers
|
|
@@ -1412,9 +1462,11 @@ external configuration via toml file no
|
|
|
1412
1462
|
level control yes no
|
|
1413
1463
|
observes line_length correctly yes no
|
|
1414
1464
|
benchmarking functionality yes no
|
|
1465
|
+
can peek locals or globals yes no
|
|
1415
1466
|
suppress f-strings at left hand optional no
|
|
1416
1467
|
indentation 4 blanks (overridable) length of prefix
|
|
1417
1468
|
forking and cloning yes no
|
|
1469
|
+
handling of source problems peeks only the value warning issued
|
|
1418
1470
|
test script pytest unittest
|
|
1419
1471
|
colorize ***) yes, off by default yes, on by default
|
|
1420
1472
|
-----------------------------------------------------------------------------------------
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# | .__/ \___| \___||_|\_\
|
|
5
5
|
# |_| like print, but easy.
|
|
6
6
|
|
|
7
|
-
__version__ = "25.0.
|
|
7
|
+
__version__ = "25.0.2"
|
|
8
8
|
|
|
9
9
|
"""
|
|
10
10
|
See https://github.com/salabim/peek for details
|
|
@@ -98,33 +98,53 @@ class _Peek:
|
|
|
98
98
|
|
|
99
99
|
_fixed_perf_counter = None
|
|
100
100
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
101
|
+
_color_name_to_ANSI = dict(
|
|
102
|
+
dark_black="\033[0;30m",
|
|
103
|
+
dark_red="\033[0;31m",
|
|
104
|
+
dark_green="\033[0;32m",
|
|
105
|
+
dark_yellow="\033[0;33m",
|
|
106
|
+
dark_blue="\033[0;34m",
|
|
107
|
+
dark_magenta="\033[0;35m",
|
|
108
|
+
dark_cyan="\033[0;36m",
|
|
109
|
+
dark_white="\033[0;37m",
|
|
110
|
+
black="\033[1;30m",
|
|
111
|
+
red="\033[1;31m",
|
|
112
|
+
green="\033[1;32m",
|
|
113
|
+
yellow="\033[1;33m",
|
|
114
|
+
blue="\033[1;34m",
|
|
115
|
+
magenta="\033[1;35m",
|
|
116
|
+
cyan="\033[1;36m",
|
|
117
|
+
white="\033[1;37m",
|
|
118
|
+
reset="\033[0m",
|
|
110
119
|
)
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
"\033[
|
|
118
|
-
"\033[
|
|
119
|
-
"\033[
|
|
120
|
-
"\033[
|
|
121
|
-
"\033[
|
|
122
|
-
"\033[
|
|
123
|
-
"\033[
|
|
124
|
-
"\033[0;
|
|
120
|
+
_color_name_to_ANSI["-"] = _color_name_to_ANSI["reset"]
|
|
121
|
+
_color_name_to_ANSI[""] = _color_name_to_ANSI["reset"]
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
_ANSI_to_rgb = {
|
|
125
|
+
"\033[1;30m": (51, 51, 51),
|
|
126
|
+
"\033[1;31m": (255, 0, 0),
|
|
127
|
+
"\033[1;32m": (0, 255, 0),
|
|
128
|
+
"\033[1;33m": (255, 255, 0),
|
|
129
|
+
"\033[1;34m": (0, 178, 255),
|
|
130
|
+
"\033[1;35m": (255, 0, 255),
|
|
131
|
+
"\033[1;36m": (0, 255, 255),
|
|
132
|
+
"\033[1;37m": (255, 255, 255),
|
|
133
|
+
"\033[0;30m": (76, 76, 76),
|
|
134
|
+
"\033[0;31m": (178, 0, 0),
|
|
135
|
+
"\033[0;32m": (0, 178, 0),
|
|
136
|
+
"\033[0;33m": (178, 178, 0),
|
|
137
|
+
"\033[0;34m": (0, 89, 255),
|
|
138
|
+
"\033[0;35m": (178, 0, 178),
|
|
139
|
+
"\033[0;36m": (0, 178, 178),
|
|
140
|
+
"\033[0;37m": (178, 178, 178),
|
|
125
141
|
"\033[0m": (),
|
|
126
142
|
}
|
|
127
143
|
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
codes = {}
|
|
147
|
+
|
|
128
148
|
@staticmethod
|
|
129
149
|
def de_alias(name):
|
|
130
150
|
return _Peek.alias_name.get(name, name)
|
|
@@ -155,7 +175,7 @@ class _Peek:
|
|
|
155
175
|
return
|
|
156
176
|
|
|
157
177
|
if name in ("color", "color_value"):
|
|
158
|
-
if isinstance(value, str) and value.lower() in _Peek.
|
|
178
|
+
if isinstance(value, str) and value.lower() in _Peek._color_name_to_ANSI:
|
|
159
179
|
return
|
|
160
180
|
|
|
161
181
|
elif name == "delta":
|
|
@@ -232,9 +252,9 @@ class _Peek:
|
|
|
232
252
|
@staticmethod
|
|
233
253
|
def print_pythonista_color(s, end="\n"):
|
|
234
254
|
while s:
|
|
235
|
-
for ansi, rgb in _Peek.
|
|
255
|
+
for ansi, rgb in _Peek._ANSI_to_rgb.items():
|
|
236
256
|
if s.startswith(ansi):
|
|
237
|
-
console.set_color(
|
|
257
|
+
console.set_color(tuple(v/255 for v in rgb))
|
|
238
258
|
s = s[len(ansi) :]
|
|
239
259
|
break
|
|
240
260
|
else:
|
|
@@ -256,16 +276,6 @@ class _Peek:
|
|
|
256
276
|
def perf_counter():
|
|
257
277
|
return time.perf_counter() if _Peek._fixed_perf_counter is None else _Peek._fixed_perf_counter
|
|
258
278
|
|
|
259
|
-
@staticmethod
|
|
260
|
-
def no_source_error():
|
|
261
|
-
raise NotImplementedError(
|
|
262
|
-
"""
|
|
263
|
-
Failed to access the underlying source code for analysis. Possible causes:
|
|
264
|
-
- decorated function/method definition spawns more than one line
|
|
265
|
-
- used from a frozen application (e.g. packaged with PyInstaller)
|
|
266
|
-
- underlying source code was changed during execution"""
|
|
267
|
-
)
|
|
268
|
-
|
|
269
279
|
def __init__(self, parent=None, **kwargs):
|
|
270
280
|
self._attributes = _Peek.spec_to_attributes(**kwargs)
|
|
271
281
|
self._parent = parent
|
|
@@ -306,7 +316,7 @@ class _Peek:
|
|
|
306
316
|
return self.__getattribute__(item)
|
|
307
317
|
|
|
308
318
|
def __setattr__(self, item, value):
|
|
309
|
-
if item in ("_parent", "_is_context_manager", "_line_number_with_filename_and_parent", "_save_traceback", "_enter_time", "_as_str", "_attributes"):
|
|
319
|
+
if item in ("_parent", "_is_context_manager", "_line_number_with_filename_and_parent", "_save_traceback", "_enter_time", "_as_str", "_as_colored_str", "_attributes"):
|
|
310
320
|
return super().__setattr__(item, value)
|
|
311
321
|
self._attributes.update(_Peek.spec_to_attributes(**{item: value}))
|
|
312
322
|
|
|
@@ -331,18 +341,40 @@ class _Peek:
|
|
|
331
341
|
return False
|
|
332
342
|
return self.enabled
|
|
333
343
|
|
|
334
|
-
def print(self, *args, as_str=
|
|
344
|
+
def print(self, *args, as_str=None, as_colored_str=None, **kwargs):
|
|
335
345
|
if "print" in kwargs and "print_like" in kwargs:
|
|
336
346
|
raise AttributeError("both print_like and print specified")
|
|
337
347
|
if not "print" in kwargs and not "print_like" in kwargs:
|
|
338
348
|
kwargs["print_like"] = True
|
|
339
|
-
return self(*args, as_str=as_str, **kwargs)
|
|
349
|
+
return self(*args, as_str=as_str, as_colored_str=as_colored_str, **kwargs)
|
|
350
|
+
|
|
351
|
+
def __call__(self, *args, as_str=None, as_colored_str=None, _via_module=False, **kwargs):
|
|
352
|
+
def add_to_pairs(pairs, left, right):
|
|
353
|
+
if right in (locals, globals, vars):
|
|
354
|
+
frame = inspect.currentframe().f_back.f_back
|
|
355
|
+
if _via_module:
|
|
356
|
+
frame = frame.f_back
|
|
357
|
+
for name, value in {locals: frame.f_locals, globals: frame.f_globals, vars: frame.f_locals}[right].items():
|
|
358
|
+
if not (isinstance(value, _PeekModule) or name.startswith("__")):
|
|
359
|
+
pairs.append(Pair(left=name + this.equals_separator, right=value))
|
|
360
|
+
else:
|
|
361
|
+
pairs.append(Pair(left=left, right=right))
|
|
340
362
|
|
|
341
|
-
def __call__(self, *args, as_str=False, **kwargs):
|
|
342
363
|
any_args = bool(args)
|
|
343
364
|
this = self.fork(**kwargs)
|
|
344
365
|
|
|
366
|
+
if as_str is None:
|
|
367
|
+
as_str=False
|
|
368
|
+
if as_colored_str is None:
|
|
369
|
+
as_colored_str=False
|
|
370
|
+
else:
|
|
371
|
+
if as_colored_str is None:
|
|
372
|
+
as_colored_str=False
|
|
373
|
+
else:
|
|
374
|
+
raise ValueError("not allowed to use both as_str and as_colored_str")
|
|
375
|
+
|
|
345
376
|
this._as_str = as_str
|
|
377
|
+
this._as_colored_str = as_colored_str
|
|
346
378
|
|
|
347
379
|
if this.print_like:
|
|
348
380
|
seps = [name for name in ("sep", "separator") if name in kwargs]
|
|
@@ -354,8 +386,6 @@ class _Peek:
|
|
|
354
386
|
this.separator_print = this.separator
|
|
355
387
|
|
|
356
388
|
this.values_only = True
|
|
357
|
-
# this.show_enter = False
|
|
358
|
-
# this.show_exit = False
|
|
359
389
|
this.show_traceback = False
|
|
360
390
|
this.to_clipboard = False
|
|
361
391
|
this.return_none = True
|
|
@@ -363,7 +393,7 @@ class _Peek:
|
|
|
363
393
|
args = [this.separator_print.join(map(str, args))]
|
|
364
394
|
|
|
365
395
|
if len(args) != 0 and not this.do_show():
|
|
366
|
-
if as_str:
|
|
396
|
+
if as_str or as_colored_str:
|
|
367
397
|
return ""
|
|
368
398
|
else:
|
|
369
399
|
return _Peek.return_args(args, this.return_none)
|
|
@@ -405,10 +435,16 @@ class _Peek:
|
|
|
405
435
|
if filename not in _Peek.codes:
|
|
406
436
|
frame_info = inspect.getframeinfo(call_frame, context=1000000) # get the full source code
|
|
407
437
|
if frame_info.code_context is None:
|
|
408
|
-
_Peek.
|
|
409
|
-
|
|
438
|
+
_Peek.code[filename] = ""
|
|
439
|
+
else:
|
|
440
|
+
_Peek.codes[filename] = frame_info.code_context
|
|
441
|
+
|
|
410
442
|
code = _Peek.codes[filename]
|
|
411
443
|
frame_info = inspect.getframeinfo(call_frame, context=1)
|
|
444
|
+
if frame_info.code_context is None:
|
|
445
|
+
line_number = 0
|
|
446
|
+
else:
|
|
447
|
+
line_number = frame_info.lineno
|
|
412
448
|
|
|
413
449
|
# parent_function = frame_info.function
|
|
414
450
|
parent_function = executing.Source.executing(call_frame).code_qualname() # changed in version 1.3.10 to include class name
|
|
@@ -417,7 +453,6 @@ class _Peek:
|
|
|
417
453
|
parent_function = ""
|
|
418
454
|
else:
|
|
419
455
|
parent_function = f" in {parent_function}()"
|
|
420
|
-
line_number = frame_info.lineno
|
|
421
456
|
if 0 <= line_number - 1 < len(code):
|
|
422
457
|
this_line = code[line_number - 1].strip()
|
|
423
458
|
else:
|
|
@@ -427,8 +462,8 @@ class _Peek:
|
|
|
427
462
|
else:
|
|
428
463
|
this_line_prev = ""
|
|
429
464
|
if this_line.startswith("@") or this_line_prev.startswith("@"):
|
|
430
|
-
if as_str:
|
|
431
|
-
raise TypeError("as_str may not be True when peek used as decorator")
|
|
465
|
+
if as_str or as_colored_str:
|
|
466
|
+
raise TypeError("as_str or as_colored_str may not be True when peek used as decorator")
|
|
432
467
|
if any_args:
|
|
433
468
|
raise TypeError("non-keyword arguments are not allowed when peek used as decorator")
|
|
434
469
|
|
|
@@ -467,20 +502,18 @@ class _Peek:
|
|
|
467
502
|
|
|
468
503
|
return real_decorator
|
|
469
504
|
|
|
470
|
-
|
|
505
|
+
call_node = executing.Source.executing(call_frame).node
|
|
506
|
+
if call_node is None:
|
|
471
507
|
this._line_number_with_filename_and_parent = ""
|
|
472
508
|
else:
|
|
473
|
-
call_node = executing.Source.executing(call_frame).node
|
|
474
|
-
if call_node is None:
|
|
475
|
-
_Peek.no_source_error()
|
|
476
509
|
line_number = call_node.lineno
|
|
477
510
|
this_line = code[line_number - 1].strip()
|
|
478
511
|
|
|
479
512
|
this._line_number_with_filename_and_parent = f"#{line_number}{filename_name}{parent_function}"
|
|
480
513
|
|
|
481
514
|
if this_line.startswith("with ") or this_line.startswith("with\t"):
|
|
482
|
-
if as_str:
|
|
483
|
-
raise TypeError("as_str may not be True when peek used as context manager")
|
|
515
|
+
if as_str or as_colored_str:
|
|
516
|
+
raise TypeError("as_str or as_colored_str may not be True when peek used as context manager")
|
|
484
517
|
if any_args:
|
|
485
518
|
raise TypeError("non-keyword arguments are not allowed when peek used as context manager")
|
|
486
519
|
|
|
@@ -488,16 +521,16 @@ class _Peek:
|
|
|
488
521
|
return this
|
|
489
522
|
|
|
490
523
|
if not this.do_show():
|
|
491
|
-
if as_str:
|
|
524
|
+
if as_str or as_colored_str:
|
|
492
525
|
return ""
|
|
493
526
|
else:
|
|
494
527
|
return _Peek.return_args(args, this.return_none)
|
|
495
528
|
if args:
|
|
496
529
|
context = this.context()
|
|
497
530
|
pairs = []
|
|
498
|
-
if
|
|
531
|
+
if call_node is None or this.values_only:
|
|
499
532
|
for right in args:
|
|
500
|
-
pairs
|
|
533
|
+
add_to_pairs(pairs, "", right)
|
|
501
534
|
else:
|
|
502
535
|
source = executing.Source.for_frame(call_frame)
|
|
503
536
|
for node, right in zip(call_node.args, args):
|
|
@@ -523,7 +556,8 @@ class _Peek:
|
|
|
523
556
|
pass
|
|
524
557
|
if left:
|
|
525
558
|
left += this.equals_separator
|
|
526
|
-
pairs
|
|
559
|
+
add_to_pairs(pairs, left, right)
|
|
560
|
+
|
|
527
561
|
|
|
528
562
|
just_one_line = False
|
|
529
563
|
if not (len(pairs) > 1 and this.separator == ""):
|
|
@@ -590,6 +624,14 @@ class _Peek:
|
|
|
590
624
|
return out + this.end
|
|
591
625
|
else:
|
|
592
626
|
return ""
|
|
627
|
+
|
|
628
|
+
if as_colored_str:
|
|
629
|
+
if this.do_show():
|
|
630
|
+
return this._color_name_to_ANSI[this.color.lower()] + out + this.end + this._color_name_to_ANSI["-"]
|
|
631
|
+
else:
|
|
632
|
+
return ""
|
|
633
|
+
|
|
634
|
+
|
|
593
635
|
if this.to_clipboard:
|
|
594
636
|
peek.copy_to_clipboard(pairs[-1].right if "pairs" in locals() else "", confirm=False)
|
|
595
637
|
this.do_output(out)
|
|
@@ -637,10 +679,10 @@ class _Peek:
|
|
|
637
679
|
return self.prefix + context
|
|
638
680
|
|
|
639
681
|
def add_color_value(self, s):
|
|
640
|
-
if self.output != "stdout" or self._as_str:
|
|
682
|
+
if (self.output != "stdout" or self._as_str) and not self._as_colored_str:
|
|
641
683
|
return s
|
|
642
684
|
if self.color_value.lower() not in (self.color.lower(), ""):
|
|
643
|
-
return self.
|
|
685
|
+
return self._color_name_to_ANSI[self.color_value.lower()] + s + self._color_name_to_ANSI[self.color.lower()]
|
|
644
686
|
else:
|
|
645
687
|
return s
|
|
646
688
|
|
|
@@ -656,7 +698,8 @@ class _Peek:
|
|
|
656
698
|
print(s, file=sys.stderr, end=self.end)
|
|
657
699
|
elif self.output == "stdout":
|
|
658
700
|
if self.color not in ["", "-"]:
|
|
659
|
-
s = self.
|
|
701
|
+
s = self._color_name_to_ANSI[self.color.lower()] + s + self.end + self._color_name_to_ANSI["-"]
|
|
702
|
+
print("***",repr(s))
|
|
660
703
|
if Pythonista:
|
|
661
704
|
_Peek.print_pythonista_color(s, end="")
|
|
662
705
|
else:
|
|
@@ -713,9 +756,9 @@ class _Peek:
|
|
|
713
756
|
def serialize_kwargs(self, obj, width):
|
|
714
757
|
if self.format:
|
|
715
758
|
if isinstance(self.format, str):
|
|
716
|
-
iterator=iter([self.format])
|
|
759
|
+
iterator = iter([self.format])
|
|
717
760
|
else:
|
|
718
|
-
iterator=iter(self.format)
|
|
761
|
+
iterator = iter(self.format)
|
|
719
762
|
for sub_format in iterator:
|
|
720
763
|
format_string = "{" + sub_format + "}" if sub_format.startswith(":") or sub_format.startswith("!") else "{:" + sub_format + "}"
|
|
721
764
|
try:
|
|
@@ -744,9 +787,9 @@ peek = _peek_toml.new()
|
|
|
744
787
|
builtins.peek = peek
|
|
745
788
|
|
|
746
789
|
|
|
747
|
-
class
|
|
790
|
+
class _PeekModule(types.ModuleType):
|
|
748
791
|
def __call__(self, *args, **kwargs):
|
|
749
|
-
return peek(*args, **kwargs)
|
|
792
|
+
return peek(*args, **kwargs, _via_module=True)
|
|
750
793
|
|
|
751
794
|
def __setattr__(self, item, value):
|
|
752
795
|
setattr(peek, item, value)
|
|
@@ -762,4 +805,5 @@ class PeekModule(types.ModuleType):
|
|
|
762
805
|
|
|
763
806
|
|
|
764
807
|
if __name__ != "__main__":
|
|
765
|
-
sys.modules["peek"].__class__ =
|
|
808
|
+
sys.modules["peek"].__class__ = _PeekModule
|
|
809
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: peek-python
|
|
3
|
-
Version: 25.0.
|
|
3
|
+
Version: 25.0.2.post0
|
|
4
4
|
Summary: peek - debugging and benchmarking made easy
|
|
5
5
|
Author-email: Ruud van der Ham <rt.van.der.ham@gmail.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/salabim/peek
|
|
@@ -46,13 +46,13 @@ And on top of that, you get some basic benchmarking functionality.
|
|
|
46
46
|
|
|
47
47
|
* [Use peek.print to use peek like print with extras](#use-peekprint-to-use-peek-like-print-with-extras)
|
|
48
48
|
|
|
49
|
+
* [Peeking locals and globals](#peeking-locals-and-globals)
|
|
50
|
+
|
|
49
51
|
* [Return a string instead of sending to output](#return-a-string-instead-of-sending-to-output)
|
|
50
52
|
|
|
51
53
|
* [Disabling peek's output](#disabling-peeks-output)
|
|
52
54
|
|
|
53
|
-
* [Using
|
|
54
|
-
|
|
55
|
-
* [Using color to control peek output](#using-color-to-control-peek-output)
|
|
55
|
+
* [Using filter to control peek output](#using-filter-to-control-peek-output)
|
|
56
56
|
|
|
57
57
|
* [Copying to the clipboard](#copying-to-the-clipboard)
|
|
58
58
|
|
|
@@ -173,7 +173,7 @@ for number in range(10):
|
|
|
173
173
|
|
|
174
174
|
This will result in:
|
|
175
175
|
|
|
176
|
-
<img src="https://www.salabim.org/peek/
|
|
176
|
+
<img src="https://www.salabim.org/peek/peek_picture1.png" width=50%>
|
|
177
177
|
|
|
178
178
|
# Inspect execution
|
|
179
179
|
|
|
@@ -658,8 +658,11 @@ d=
|
|
|
658
658
|
|
|
659
659
|
## color / col and color_value / colv
|
|
660
660
|
The color attribute is used to specify the color of the output.
|
|
661
|
-
|
|
662
|
-
|
|
661
|
+
|
|
662
|
+
There's a choice of `"black"`, `"white"`, `"red"`, `"green"`, `"blue"`, `"cyan"`, `"magenta"`, `"yellow"`, `" dark_black"`, `"dark_white"`, `"dark_red"`, `"dark_green"`, `"dark_blue"`, `"dark_cyan"`, `"dark_magenta"` and `"dark_yellow"`:
|
|
663
|
+
|
|
664
|
+
<img src="https://www.salabim.org/peek/peek_picture2.png" width=25%>
|
|
665
|
+
To set the color to 'nothing'", "use "-".
|
|
663
666
|
|
|
664
667
|
On top of that, color_value may be used to specify the value part of an output item. By specifying color_value as "" (the default), the value part will be displayed with the same color as the rest of the output.
|
|
665
668
|
|
|
@@ -677,7 +680,7 @@ peek(item1, item2, color="red", color_value="green")
|
|
|
677
680
|
|
|
678
681
|
will result in:
|
|
679
682
|
|
|
680
|
-
<img src="https://www.salabim.org/peek/
|
|
683
|
+
<img src="https://www.salabim.org/peek/peek_picture3.png" width=30%>
|
|
681
684
|
|
|
682
685
|
Of course, color and color_value may be specified in a peek.toml file, to make all peek output in a specified color.
|
|
683
686
|
|
|
@@ -1098,6 +1101,35 @@ peek.sep = "|" # sets the 'normal' peek separator
|
|
|
1098
1101
|
>
|
|
1099
1102
|
> `peek.print` does not obey the line length and will always return None (unless as_str is True).
|
|
1100
1103
|
|
|
1104
|
+
|
|
1105
|
+
# Peeking locals and globals
|
|
1106
|
+
It is possible to get the name and values of all local or global variables.
|
|
1107
|
+
|
|
1108
|
+
To do that, just put `locals` or `globals` in the call to peek, e.g.:
|
|
1109
|
+
|
|
1110
|
+
```
|
|
1111
|
+
def my_func():
|
|
1112
|
+
a = 10
|
|
1113
|
+
b = a * a
|
|
1114
|
+
peek(locals)
|
|
1115
|
+
my_func()
|
|
1116
|
+
```
|
|
1117
|
+
|
|
1118
|
+
will print all local variables, apart from those starting with `__`, so:
|
|
1119
|
+
```
|
|
1120
|
+
a=10, b=100
|
|
1121
|
+
```
|
|
1122
|
+
|
|
1123
|
+
Likewise,
|
|
1124
|
+
```
|
|
1125
|
+
peek(globals)
|
|
1126
|
+
```
|
|
1127
|
+
will print all global variables, apart from those starting with `__`
|
|
1128
|
+
|
|
1129
|
+
> [!IMPORTANT]
|
|
1130
|
+
>
|
|
1131
|
+
> You should not add parentheses after `locals` or `globals` for peek to work properly!
|
|
1132
|
+
|
|
1101
1133
|
# Return a string instead of sending to output
|
|
1102
1134
|
|
|
1103
1135
|
`peek(*args, as_str=True)` is like `peek(*args)` but the output is returned as a string instead
|
|
@@ -1115,6 +1147,23 @@ hello='world'
|
|
|
1115
1147
|
|
|
1116
1148
|
Note that if enabled=False, the call will return the null string (`""`).
|
|
1117
1149
|
|
|
1150
|
+
It is also possible to return a string with the embedded ANSI color escape strings, which can be useful to process the output in another program that supports ANSI colors, like salabim. This is done by setting the `as_colored_str` argument to True:
|
|
1151
|
+
```
|
|
1152
|
+
hello = "world"
|
|
1153
|
+
s = peek(hello, color="red", color_value="green", as_colored_str=True)
|
|
1154
|
+
print(repr(s), end="")
|
|
1155
|
+
```
|
|
1156
|
+
prints
|
|
1157
|
+
```
|
|
1158
|
+
"\x1b[1;31mhello=\x1b[1;32m'world'\x1b[1;31m\n\x1b[0m"
|
|
1159
|
+
```
|
|
1160
|
+
|
|
1161
|
+
> [!NOTE]
|
|
1162
|
+
>
|
|
1163
|
+
> Specifying both `as_str` and `as_colored_str` is not allowed.
|
|
1164
|
+
|
|
1165
|
+
|
|
1166
|
+
|
|
1118
1167
|
# Disabling peek's output
|
|
1119
1168
|
|
|
1120
1169
|
```
|
|
@@ -1423,6 +1472,7 @@ can show traceback yes no
|
|
|
1423
1472
|
can be used like print w/extras yes (with peek.print) no
|
|
1424
1473
|
allows non linefeed printing yes (via end parameter) requires patching
|
|
1425
1474
|
PEP8 (Pythonic) API yes no
|
|
1475
|
+
format specification optional no
|
|
1426
1476
|
sorts dicts no by default, optional *) yes
|
|
1427
1477
|
supports compact, indent,
|
|
1428
1478
|
and underscore_numbers
|
|
@@ -1432,9 +1482,11 @@ external configuration via toml file no
|
|
|
1432
1482
|
level control yes no
|
|
1433
1483
|
observes line_length correctly yes no
|
|
1434
1484
|
benchmarking functionality yes no
|
|
1485
|
+
can peek locals or globals yes no
|
|
1435
1486
|
suppress f-strings at left hand optional no
|
|
1436
1487
|
indentation 4 blanks (overridable) length of prefix
|
|
1437
1488
|
forking and cloning yes no
|
|
1489
|
+
handling of source problems peeks only the value warning issued
|
|
1438
1490
|
test script pytest unittest
|
|
1439
1491
|
colorize ***) yes, off by default yes, on by default
|
|
1440
1492
|
-----------------------------------------------------------------------------------------
|
|
@@ -10,7 +10,7 @@ authors = [
|
|
|
10
10
|
{ name = "Ruud van der Ham", email = "rt.van.der.ham@gmail.com" },
|
|
11
11
|
]
|
|
12
12
|
description = "peek - debugging and benchmarking made easy"
|
|
13
|
-
version = "25.0.
|
|
13
|
+
version = "25.0.2.post0"
|
|
14
14
|
readme = "README.md"
|
|
15
15
|
requires-python = ">=3.6"
|
|
16
16
|
dependencies = [
|
|
@@ -15,7 +15,6 @@ sys.path.insert(0, file_folder + "/../peek")
|
|
|
15
15
|
|
|
16
16
|
import peek
|
|
17
17
|
|
|
18
|
-
|
|
19
18
|
peek = peek.new(ignore_toml=True, output="stdout_nocolor")
|
|
20
19
|
|
|
21
20
|
|
|
@@ -122,6 +121,7 @@ def test_time_delta():
|
|
|
122
121
|
time.sleep(0.1)
|
|
123
122
|
assert 10.05 < peek.delta < 11
|
|
124
123
|
|
|
124
|
+
|
|
125
125
|
|
|
126
126
|
def test_dynamic_prefix(capsys):
|
|
127
127
|
g.i = 0
|
|
@@ -144,6 +144,24 @@ def test_values_only():
|
|
|
144
144
|
s = peek(hello, as_str=True)
|
|
145
145
|
assert s == "'world'\n"
|
|
146
146
|
|
|
147
|
+
def test_locals(capsys):
|
|
148
|
+
def square(x):
|
|
149
|
+
result = x ** 2
|
|
150
|
+
peek(locals)
|
|
151
|
+
|
|
152
|
+
square(10)
|
|
153
|
+
out, err = capsys.readouterr()
|
|
154
|
+
assert out=='x=10, result=100\n'
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def test_globals(capsys):
|
|
158
|
+
def square(x):
|
|
159
|
+
result = x ** 2
|
|
160
|
+
peek(globals)
|
|
161
|
+
|
|
162
|
+
square(10)
|
|
163
|
+
out, err = capsys.readouterr()
|
|
164
|
+
assert 'pytest=<module' in out
|
|
147
165
|
|
|
148
166
|
def test_calls():
|
|
149
167
|
with pytest.raises(AttributeError):
|
|
@@ -307,7 +325,8 @@ def test_print(capsys):
|
|
|
307
325
|
|
|
308
326
|
result=peek.print(1,2)
|
|
309
327
|
assert result is None
|
|
310
|
-
|
|
328
|
+
out, err = capsys.readouterr()
|
|
329
|
+
assert out == "1 2\n"
|
|
311
330
|
|
|
312
331
|
with pytest.raises(AttributeError):
|
|
313
332
|
peek.print(sep="|", sepp="/")
|
|
@@ -431,7 +450,7 @@ def test_color(capsys):
|
|
|
431
450
|
peek(10 * 10, output="stdout")
|
|
432
451
|
peek(10 * 10, color="red", output="stdout")
|
|
433
452
|
out, err = capsys.readouterr()
|
|
434
|
-
assert out == "10 * 10=100\n\x1b[
|
|
453
|
+
assert out == "10 * 10=100\n\x1b[1;31m10 * 10=100\n\x1b[0m"
|
|
435
454
|
|
|
436
455
|
|
|
437
456
|
def test_incorrect_filter():
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|