peek-python 24.0.0__tar.gz → 24.0.1__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-24.0.0 → peek_python-24.0.1}/PKG-INFO +22 -25
- {peek_python-24.0.0 → peek_python-24.0.1}/README.md +21 -24
- {peek_python-24.0.0 → peek_python-24.0.1}/peek/peek.py +98 -96
- {peek_python-24.0.0 → peek_python-24.0.1}/peek_python.egg-info/PKG-INFO +22 -25
- {peek_python-24.0.0 → peek_python-24.0.1}/pyproject.toml +1 -1
- {peek_python-24.0.0 → peek_python-24.0.1}/tests/test_peek.py +10 -10
- {peek_python-24.0.0 → peek_python-24.0.1}/license.txt +0 -0
- {peek_python-24.0.0 → peek_python-24.0.1}/peek/__init__.py +0 -0
- {peek_python-24.0.0 → peek_python-24.0.1}/peek_python.egg-info/SOURCES.txt +0 -0
- {peek_python-24.0.0 → peek_python-24.0.1}/peek_python.egg-info/dependency_links.txt +0 -0
- {peek_python-24.0.0 → peek_python-24.0.1}/peek_python.egg-info/requires.txt +0 -0
- {peek_python-24.0.0 → peek_python-24.0.1}/peek_python.egg-info/top_level.txt +0 -0
- {peek_python-24.0.0 → peek_python-24.0.1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: peek-python
|
|
3
|
-
Version: 24.0.
|
|
3
|
+
Version: 24.0.1
|
|
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
|
|
@@ -18,7 +18,8 @@ Requires-Dist: pyperclip>=1.9.0
|
|
|
18
18
|
Requires-Dist: six>=1.17.0
|
|
19
19
|
Requires-Dist: tomli>=2.2.1
|
|
20
20
|
|
|
21
|
-
<img src="https://www.salabim.org/peek/peek_logo1.png">
|
|
21
|
+
- [ ] <img src="https://www.salabim.org/peek/peek_logo1.png">
|
|
22
|
+
|
|
22
23
|
|
|
23
24
|
# Introduction
|
|
24
25
|
|
|
@@ -48,9 +49,7 @@ And on top of that, you get some basic benchmarking functionality.
|
|
|
48
49
|
|
|
49
50
|
* [Disabling peek's output](#disabling-peeks-output)
|
|
50
51
|
|
|
51
|
-
* [Using
|
|
52
|
-
|
|
53
|
-
* [Using color to control peek output](#Using-color-to-control-peek-output)
|
|
52
|
+
* [Using filter to control peek output](#Using-filter-to-control-peek-output)
|
|
54
53
|
|
|
55
54
|
* [Copying to the clipboard](#Copying-to-the-clipboard)
|
|
56
55
|
|
|
@@ -66,12 +65,8 @@ And on top of that, you get some basic benchmarking functionality.
|
|
|
66
65
|
|
|
67
66
|
* [Alternative to `peek`](#alternative-to-peek)
|
|
68
67
|
|
|
69
|
-
* [Alternative installation](#alternative-installation)
|
|
70
|
-
|
|
71
68
|
* [Limitations](#limitations)
|
|
72
69
|
|
|
73
|
-
* [Implementation details](#implementation-details)
|
|
74
|
-
|
|
75
70
|
* [Acknowledgement](#acknowledgement)
|
|
76
71
|
|
|
77
72
|
* [Changelog](#changelog)
|
|
@@ -92,7 +87,7 @@ pip install peek-python --upgrade
|
|
|
92
87
|
|
|
93
88
|
Alternatively, peek.py can be just copied into you current work directory from GitHub (https://github.com/salabim/peek).
|
|
94
89
|
|
|
95
|
-
Note that peek requires the `asttokens`, `colorama`, `executing`. `six`, tomli and pyperclip` modules, all of which will be automatically installed.
|
|
90
|
+
Note that peek requires the `asttokens`, `colorama`, `executing`. `six`, `tomli` and `pyperclip` modules, all of which will be automatically installed with pip.
|
|
96
91
|
|
|
97
92
|
# Importing peek
|
|
98
93
|
|
|
@@ -108,8 +103,9 @@ import peek
|
|
|
108
103
|
from peek import peek
|
|
109
104
|
```
|
|
110
105
|
|
|
111
|
-
|
|
112
|
-
|
|
106
|
+
> [!NOTE]
|
|
107
|
+
>
|
|
108
|
+
> After this, `peek` is automatically a builtin and can thus be used in any module without importing it there.
|
|
113
109
|
|
|
114
110
|
# Inspect variables and expressions
|
|
115
111
|
|
|
@@ -326,7 +322,7 @@ a number of configuration attributes:
|
|
|
326
322
|
attribute alternative default
|
|
327
323
|
------------------------------------------------------
|
|
328
324
|
color col "-"
|
|
329
|
-
color_value
|
|
325
|
+
color_value col_val "-"
|
|
330
326
|
context_separator cs " ==> "
|
|
331
327
|
compact - False
|
|
332
328
|
depth - 1000000
|
|
@@ -366,6 +362,7 @@ print(peek.prefix)
|
|
|
366
362
|
|
|
367
363
|
But, it is also possible to apply configuration directly, only here, in the call to `peek`:
|
|
368
364
|
So, it is possible to say
|
|
365
|
+
|
|
369
366
|
```
|
|
370
367
|
peek(12, prefix="==> ")
|
|
371
368
|
```
|
|
@@ -640,7 +637,7 @@ d=
|
|
|
640
637
|
'a3': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}
|
|
641
638
|
```
|
|
642
639
|
|
|
643
|
-
## color / col and color_value /
|
|
640
|
+
## color / col and color_value / col_val
|
|
644
641
|
The color attribute is used to specify the color of the output.
|
|
645
642
|
There's a choice of black, white, red, green, blue, cyan, magenta and yellow.
|
|
646
643
|
To set the color to 'nothing', use "-".
|
|
@@ -668,7 +665,7 @@ Of course, color and color_value may be specified in a peek.toml file, to make a
|
|
|
668
665
|
>
|
|
669
666
|
> The color and color_value attributes are only applied when using stdout as output.
|
|
670
667
|
>
|
|
671
|
-
> Colors can be ignored completely by using `peek.output = "stdout_nocolor`.
|
|
668
|
+
> Colors can be ignored completely by using `peek.output = "stdout_nocolor"`.
|
|
672
669
|
|
|
673
670
|
## compact
|
|
674
671
|
This attribute is used to specify the compact parameter for `pformat` (see the pprint documentation
|
|
@@ -1017,7 +1014,7 @@ It is possible to use more than one attribute, like
|
|
|
1017
1014
|
```
|
|
1018
1015
|
peek.filter = "color == 'blue' and delta > 5"
|
|
1019
1016
|
```
|
|
1020
|
-
As an alternative to `enabled` we can
|
|
1017
|
+
As an alternative to `enabled` we can also say
|
|
1021
1018
|
```
|
|
1022
1019
|
peek.filter = "False"
|
|
1023
1020
|
```
|
|
@@ -1139,7 +1136,7 @@ Normally, only the `peek` object is used.
|
|
|
1139
1136
|
It can be useful to have multiple instances, e.g. when some of the debugging has to be done with context information
|
|
1140
1137
|
and others requires an alternative prefix.
|
|
1141
1138
|
|
|
1142
|
-
|
|
1139
|
+
There are several ways to obtain a new instance of peek:
|
|
1143
1140
|
|
|
1144
1141
|
* by using `peek.new()`
|
|
1145
1142
|
|
|
@@ -1147,7 +1144,7 @@ THere are several ways to obtain a new instance of peek:
|
|
|
1147
1144
|
and possibly peek.toml overrides.
|
|
1148
1145
|
* by using `peek.new(ignore_toml=True)`
|
|
1149
1146
|
|
|
1150
|
-
With this a new
|
|
1147
|
+
With this a new peek object is created with the default attributes. Any peek.toml files are ignored.
|
|
1151
1148
|
* by using `peek.fork()`
|
|
1152
1149
|
|
|
1153
1150
|
With this a new peek object is created with the same attributes as the object it is created ('the parent') from. Note that any non set attributes are copied (propagated) from the parent.
|
|
@@ -1274,9 +1271,9 @@ The peek package is a rebrand of the **ycecream** package, with enhancements.
|
|
|
1274
1271
|
The peek module was originally a fork of **IceCream**, but has many differences:
|
|
1275
1272
|
|
|
1276
1273
|
```
|
|
1277
|
-
|
|
1274
|
+
-----------------------------------------------------------------------------------------
|
|
1278
1275
|
characteristic peek IceCream
|
|
1279
|
-
|
|
1276
|
+
-----------------------------------------------------------------------------------------
|
|
1280
1277
|
default name peek ic
|
|
1281
1278
|
import method import peek from icecream import ic
|
|
1282
1279
|
number of files 1 several
|
|
@@ -1295,14 +1292,14 @@ level control yes no
|
|
|
1295
1292
|
observes line_length correctly yes no
|
|
1296
1293
|
benchmarking functionality yes no
|
|
1297
1294
|
suppress f-strings at left hand optional no
|
|
1298
|
-
indentation 4 blanks (overridable)
|
|
1295
|
+
indentation 4 blanks (overridable) length of prefix
|
|
1299
1296
|
forking and cloning yes no
|
|
1300
1297
|
test script pytest unittest
|
|
1301
1298
|
colorize ***) yes, off by default yes, on by default
|
|
1302
|
-
|
|
1303
|
-
*) under Python <= 3.7, dicts are always sorted
|
|
1304
|
-
**) under Python <= 3.7, numbers are never underscored
|
|
1305
|
-
***) peek allows selection of a color, whereas IceCream does coloring based on contents
|
|
1299
|
+
-----------------------------------------------------------------------------------------
|
|
1300
|
+
*) under Python <= 3.7, dicts are always sorted
|
|
1301
|
+
**) under Python <= 3.7, numbers are never underscored
|
|
1302
|
+
***) peek allows selection of a color, whereas IceCream does coloring based on contents
|
|
1306
1303
|
|
|
1307
1304
|
```
|
|
1308
1305
|
  
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
<img src="https://www.salabim.org/peek/peek_logo1.png">
|
|
1
|
+
- [ ] <img src="https://www.salabim.org/peek/peek_logo1.png">
|
|
2
|
+
|
|
2
3
|
|
|
3
4
|
# Introduction
|
|
4
5
|
|
|
@@ -28,9 +29,7 @@ And on top of that, you get some basic benchmarking functionality.
|
|
|
28
29
|
|
|
29
30
|
* [Disabling peek's output](#disabling-peeks-output)
|
|
30
31
|
|
|
31
|
-
* [Using
|
|
32
|
-
|
|
33
|
-
* [Using color to control peek output](#Using-color-to-control-peek-output)
|
|
32
|
+
* [Using filter to control peek output](#Using-filter-to-control-peek-output)
|
|
34
33
|
|
|
35
34
|
* [Copying to the clipboard](#Copying-to-the-clipboard)
|
|
36
35
|
|
|
@@ -46,12 +45,8 @@ And on top of that, you get some basic benchmarking functionality.
|
|
|
46
45
|
|
|
47
46
|
* [Alternative to `peek`](#alternative-to-peek)
|
|
48
47
|
|
|
49
|
-
* [Alternative installation](#alternative-installation)
|
|
50
|
-
|
|
51
48
|
* [Limitations](#limitations)
|
|
52
49
|
|
|
53
|
-
* [Implementation details](#implementation-details)
|
|
54
|
-
|
|
55
50
|
* [Acknowledgement](#acknowledgement)
|
|
56
51
|
|
|
57
52
|
* [Changelog](#changelog)
|
|
@@ -72,7 +67,7 @@ pip install peek-python --upgrade
|
|
|
72
67
|
|
|
73
68
|
Alternatively, peek.py can be just copied into you current work directory from GitHub (https://github.com/salabim/peek).
|
|
74
69
|
|
|
75
|
-
Note that peek requires the `asttokens`, `colorama`, `executing`. `six`, tomli and pyperclip` modules, all of which will be automatically installed.
|
|
70
|
+
Note that peek requires the `asttokens`, `colorama`, `executing`. `six`, `tomli` and `pyperclip` modules, all of which will be automatically installed with pip.
|
|
76
71
|
|
|
77
72
|
# Importing peek
|
|
78
73
|
|
|
@@ -88,8 +83,9 @@ import peek
|
|
|
88
83
|
from peek import peek
|
|
89
84
|
```
|
|
90
85
|
|
|
91
|
-
|
|
92
|
-
|
|
86
|
+
> [!NOTE]
|
|
87
|
+
>
|
|
88
|
+
> After this, `peek` is automatically a builtin and can thus be used in any module without importing it there.
|
|
93
89
|
|
|
94
90
|
# Inspect variables and expressions
|
|
95
91
|
|
|
@@ -306,7 +302,7 @@ a number of configuration attributes:
|
|
|
306
302
|
attribute alternative default
|
|
307
303
|
------------------------------------------------------
|
|
308
304
|
color col "-"
|
|
309
|
-
color_value
|
|
305
|
+
color_value col_val "-"
|
|
310
306
|
context_separator cs " ==> "
|
|
311
307
|
compact - False
|
|
312
308
|
depth - 1000000
|
|
@@ -346,6 +342,7 @@ print(peek.prefix)
|
|
|
346
342
|
|
|
347
343
|
But, it is also possible to apply configuration directly, only here, in the call to `peek`:
|
|
348
344
|
So, it is possible to say
|
|
345
|
+
|
|
349
346
|
```
|
|
350
347
|
peek(12, prefix="==> ")
|
|
351
348
|
```
|
|
@@ -620,7 +617,7 @@ d=
|
|
|
620
617
|
'a3': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}
|
|
621
618
|
```
|
|
622
619
|
|
|
623
|
-
## color / col and color_value /
|
|
620
|
+
## color / col and color_value / col_val
|
|
624
621
|
The color attribute is used to specify the color of the output.
|
|
625
622
|
There's a choice of black, white, red, green, blue, cyan, magenta and yellow.
|
|
626
623
|
To set the color to 'nothing', use "-".
|
|
@@ -648,7 +645,7 @@ Of course, color and color_value may be specified in a peek.toml file, to make a
|
|
|
648
645
|
>
|
|
649
646
|
> The color and color_value attributes are only applied when using stdout as output.
|
|
650
647
|
>
|
|
651
|
-
> Colors can be ignored completely by using `peek.output = "stdout_nocolor`.
|
|
648
|
+
> Colors can be ignored completely by using `peek.output = "stdout_nocolor"`.
|
|
652
649
|
|
|
653
650
|
## compact
|
|
654
651
|
This attribute is used to specify the compact parameter for `pformat` (see the pprint documentation
|
|
@@ -997,7 +994,7 @@ It is possible to use more than one attribute, like
|
|
|
997
994
|
```
|
|
998
995
|
peek.filter = "color == 'blue' and delta > 5"
|
|
999
996
|
```
|
|
1000
|
-
As an alternative to `enabled` we can
|
|
997
|
+
As an alternative to `enabled` we can also say
|
|
1001
998
|
```
|
|
1002
999
|
peek.filter = "False"
|
|
1003
1000
|
```
|
|
@@ -1119,7 +1116,7 @@ Normally, only the `peek` object is used.
|
|
|
1119
1116
|
It can be useful to have multiple instances, e.g. when some of the debugging has to be done with context information
|
|
1120
1117
|
and others requires an alternative prefix.
|
|
1121
1118
|
|
|
1122
|
-
|
|
1119
|
+
There are several ways to obtain a new instance of peek:
|
|
1123
1120
|
|
|
1124
1121
|
* by using `peek.new()`
|
|
1125
1122
|
|
|
@@ -1127,7 +1124,7 @@ THere are several ways to obtain a new instance of peek:
|
|
|
1127
1124
|
and possibly peek.toml overrides.
|
|
1128
1125
|
* by using `peek.new(ignore_toml=True)`
|
|
1129
1126
|
|
|
1130
|
-
With this a new
|
|
1127
|
+
With this a new peek object is created with the default attributes. Any peek.toml files are ignored.
|
|
1131
1128
|
* by using `peek.fork()`
|
|
1132
1129
|
|
|
1133
1130
|
With this a new peek object is created with the same attributes as the object it is created ('the parent') from. Note that any non set attributes are copied (propagated) from the parent.
|
|
@@ -1254,9 +1251,9 @@ The peek package is a rebrand of the **ycecream** package, with enhancements.
|
|
|
1254
1251
|
The peek module was originally a fork of **IceCream**, but has many differences:
|
|
1255
1252
|
|
|
1256
1253
|
```
|
|
1257
|
-
|
|
1254
|
+
-----------------------------------------------------------------------------------------
|
|
1258
1255
|
characteristic peek IceCream
|
|
1259
|
-
|
|
1256
|
+
-----------------------------------------------------------------------------------------
|
|
1260
1257
|
default name peek ic
|
|
1261
1258
|
import method import peek from icecream import ic
|
|
1262
1259
|
number of files 1 several
|
|
@@ -1275,14 +1272,14 @@ level control yes no
|
|
|
1275
1272
|
observes line_length correctly yes no
|
|
1276
1273
|
benchmarking functionality yes no
|
|
1277
1274
|
suppress f-strings at left hand optional no
|
|
1278
|
-
indentation 4 blanks (overridable)
|
|
1275
|
+
indentation 4 blanks (overridable) length of prefix
|
|
1279
1276
|
forking and cloning yes no
|
|
1280
1277
|
test script pytest unittest
|
|
1281
1278
|
colorize ***) yes, off by default yes, on by default
|
|
1282
|
-
|
|
1283
|
-
*) under Python <= 3.7, dicts are always sorted
|
|
1284
|
-
**) under Python <= 3.7, numbers are never underscored
|
|
1285
|
-
***) peek allows selection of a color, whereas IceCream does coloring based on contents
|
|
1279
|
+
-----------------------------------------------------------------------------------------
|
|
1280
|
+
*) under Python <= 3.7, dicts are always sorted
|
|
1281
|
+
**) under Python <= 3.7, numbers are never underscored
|
|
1282
|
+
***) peek allows selection of a color, whereas IceCream does coloring based on contents
|
|
1286
1283
|
|
|
1287
1284
|
```
|
|
1288
1285
|
  
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# | .__/ \___| \___||_|\_\
|
|
5
5
|
# |_| like print, but easy.
|
|
6
6
|
|
|
7
|
-
__version__ = "24.0.
|
|
7
|
+
__version__ = "24.0.1"
|
|
8
8
|
|
|
9
9
|
"""
|
|
10
10
|
See https://github.com/salabim/peek for details
|
|
@@ -42,6 +42,7 @@ if Pythonista:
|
|
|
42
42
|
import clipboard
|
|
43
43
|
else:
|
|
44
44
|
import colorama
|
|
45
|
+
colorama.just_fix_windows_console()
|
|
45
46
|
import pyperclip
|
|
46
47
|
|
|
47
48
|
try:
|
|
@@ -67,28 +68,28 @@ colors = dict(
|
|
|
67
68
|
colors["-"] = "\033[0m"
|
|
68
69
|
|
|
69
70
|
|
|
70
|
-
|
|
71
|
-
"\033[0;30m":
|
|
72
|
-
"\033[0;31m":
|
|
73
|
-
"\033[0;32m":
|
|
74
|
-
"\033[0;33m":
|
|
75
|
-
"\033[0;34m":
|
|
76
|
-
"\033[0;35m":
|
|
77
|
-
"\033[0;36m":
|
|
78
|
-
"\033[0;37m":
|
|
79
|
-
"\033[0m":
|
|
71
|
+
ansi_to_rgb = {
|
|
72
|
+
"\033[0;30m": (0, 0, 0),
|
|
73
|
+
"\033[0;31m": (1, 0, 0),
|
|
74
|
+
"\033[0;32m": (0, 1, 0),
|
|
75
|
+
"\033[0;33m": (1, 1, 0),
|
|
76
|
+
"\033[0;34m": (0, 0.7, 1),
|
|
77
|
+
"\033[0;35m": (1, 0, 1),
|
|
78
|
+
"\033[0;36m": (0, 1, 1),
|
|
79
|
+
"\033[0;37m": (1, 1, 1),
|
|
80
|
+
"\033[0m": (),
|
|
80
81
|
}
|
|
81
82
|
|
|
82
83
|
|
|
83
|
-
def
|
|
84
|
+
def de_alias(name):
|
|
84
85
|
return alias_name.get(name, name)
|
|
85
86
|
|
|
86
87
|
|
|
87
|
-
def check_validity(name, value
|
|
88
|
+
def check_validity(name, value):
|
|
88
89
|
name_org = name
|
|
89
|
-
name =
|
|
90
|
+
name = de_alias(name)
|
|
90
91
|
if name not in name_default:
|
|
91
|
-
raise
|
|
92
|
+
raise AttributeError(f"attribute {name} not allowed{in_read_toml_message}")
|
|
92
93
|
|
|
93
94
|
if value is None:
|
|
94
95
|
return
|
|
@@ -102,7 +103,7 @@ def check_validity(name, value, message=""):
|
|
|
102
103
|
return
|
|
103
104
|
except Exception:
|
|
104
105
|
pass
|
|
105
|
-
raise
|
|
106
|
+
raise AttributeError("output should be a callable, str, Path or open text file.")
|
|
106
107
|
|
|
107
108
|
if name == "serialize":
|
|
108
109
|
if callable(value):
|
|
@@ -114,6 +115,10 @@ def check_validity(name, value, message=""):
|
|
|
114
115
|
if isinstance(value, str) and value.lower() in colors:
|
|
115
116
|
return
|
|
116
117
|
|
|
118
|
+
elif name == "delta":
|
|
119
|
+
if isinstance(value, numbers.Number):
|
|
120
|
+
return
|
|
121
|
+
|
|
117
122
|
elif name == "enforce_line_length":
|
|
118
123
|
if value:
|
|
119
124
|
if isinstance(value, numbers.Number) and value > 0:
|
|
@@ -152,7 +157,7 @@ def check_validity(name, value, message=""):
|
|
|
152
157
|
else:
|
|
153
158
|
return
|
|
154
159
|
|
|
155
|
-
raise
|
|
160
|
+
raise AttributeError(f"incorrect {name_org}: {repr(value)}{in_read_toml_message}")
|
|
156
161
|
|
|
157
162
|
|
|
158
163
|
class Source(executing.Source):
|
|
@@ -173,24 +178,31 @@ def change_path(new_path): # used in tests
|
|
|
173
178
|
_fixed_perf_counter = None
|
|
174
179
|
|
|
175
180
|
|
|
181
|
+
def spec_to_attributes(d):
|
|
182
|
+
result = {}
|
|
183
|
+
for name, value in d.items():
|
|
184
|
+
check_validity(name, value)
|
|
185
|
+
name = de_alias(name)
|
|
186
|
+
if name == "delta" and value is not None:
|
|
187
|
+
result["perf_counter"] = perf_counter()
|
|
188
|
+
result[name] = value
|
|
189
|
+
return result
|
|
190
|
+
|
|
191
|
+
|
|
176
192
|
def read_toml():
|
|
193
|
+
global in_read_toml_message
|
|
177
194
|
this_path = Path(".").resolve()
|
|
178
|
-
|
|
179
195
|
for i in range(len(this_path.parts), 0, -1):
|
|
180
196
|
toml_file = Path(this_path.parts[0]).joinpath(*this_path.parts[1:i], "peek.toml")
|
|
181
197
|
if toml_file.is_file():
|
|
198
|
+
in_read_toml_message = f" in reading {toml_file}"
|
|
182
199
|
with open(toml_file, "r") as f:
|
|
183
200
|
config_as_str = f.read()
|
|
184
|
-
|
|
185
|
-
for name, value in config.items():
|
|
186
|
-
check_validity(name, value, message=f" while processing {toml_file}")
|
|
187
|
-
return config
|
|
188
|
-
break
|
|
201
|
+
return tomlib.loads(config_as_str)
|
|
189
202
|
return {}
|
|
190
203
|
|
|
191
204
|
|
|
192
205
|
def no_source_error():
|
|
193
|
-
|
|
194
206
|
raise NotImplementedError(
|
|
195
207
|
"""
|
|
196
208
|
Failed to access the underlying source code for analysis. Possible causes:
|
|
@@ -212,28 +224,36 @@ def return_args(args, return_none):
|
|
|
212
224
|
|
|
213
225
|
class _Peek:
|
|
214
226
|
def __init__(self, parent=None, **kwargs):
|
|
215
|
-
self._attributes =
|
|
216
|
-
for name, value in kwargs.items():
|
|
217
|
-
check_validity(name, value)
|
|
218
|
-
setattr(self, name, value)
|
|
227
|
+
self._attributes = spec_to_attributes(kwargs)
|
|
219
228
|
self._parent = parent
|
|
220
229
|
|
|
221
|
-
def
|
|
222
|
-
|
|
223
|
-
|
|
230
|
+
def new(self, ignore_toml=False, **kwargs):
|
|
231
|
+
if ignore_toml:
|
|
232
|
+
return _Peek(**kwargs, parent=peek_no_toml)
|
|
233
|
+
else:
|
|
234
|
+
return _Peek(**kwargs, parent=peek_toml)
|
|
224
235
|
|
|
225
|
-
def
|
|
226
|
-
|
|
227
|
-
_fixed_perf_counter = val
|
|
236
|
+
def fork(self, **kwargs):
|
|
237
|
+
return _Peek(**kwargs, parent=self)
|
|
228
238
|
|
|
229
|
-
def
|
|
230
|
-
|
|
231
|
-
|
|
239
|
+
def clone(self, **kwargs):
|
|
240
|
+
clone = _Peek(parent=self._parent)
|
|
241
|
+
clone._attributes = {**self._attributes, **spec_to_attributes(kwargs)}
|
|
242
|
+
return clone
|
|
243
|
+
|
|
244
|
+
def configure(self, **kwargs):
|
|
245
|
+
self._attributes.update(spec_to_attributes(kwargs))
|
|
246
|
+
|
|
247
|
+
def __getattr__(self, item, spec=False):
|
|
248
|
+
item = de_alias(item)
|
|
249
|
+
if item in name_default or item == "perf_counter":
|
|
232
250
|
node = self
|
|
233
251
|
while not item in node._attributes or node._attributes[item] is None:
|
|
234
252
|
node = node._parent
|
|
235
253
|
if item == "delta":
|
|
236
|
-
return perf_counter() - node._attributes[
|
|
254
|
+
return perf_counter() - node._attributes["perf_counter"] + node._attributes["delta"]
|
|
255
|
+
elif item == "perf_counter":
|
|
256
|
+
return node._attributes["delta"]
|
|
237
257
|
else:
|
|
238
258
|
return node._attributes[item]
|
|
239
259
|
else:
|
|
@@ -242,18 +262,23 @@ class _Peek:
|
|
|
242
262
|
def __setattr__(self, item, value):
|
|
243
263
|
if item in ("_parent", "is_context_manager", "line_number_with_filename_and_parent", "save_traceback", "enter_time", "as_str", "_attributes"):
|
|
244
264
|
return super().__setattr__(item, value)
|
|
265
|
+
self._attributes.update(spec_to_attributes({item: value}))
|
|
245
266
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
267
|
+
def __repr__(self):
|
|
268
|
+
pairs = [
|
|
269
|
+
str(name) + "=" + repr(getattr(self, "perf_counter") if name == "delta" else getattr(self, name)) for name in name_default if name != "serialize"
|
|
270
|
+
]
|
|
271
|
+
return "peek.new(" + ", ".join(pairs) + ")"
|
|
251
272
|
|
|
252
|
-
|
|
253
|
-
|
|
273
|
+
def __str__(self):
|
|
274
|
+
pairs = [
|
|
275
|
+
str(name) + "=" + repr(getattr(self, "perf_counter") if name == "delta" else getattr(self, name)) for name in name_default if name != "serialize"
|
|
276
|
+
]
|
|
277
|
+
return "peek with attributes:\n " + "\n ".join(pairs) + ")"
|
|
254
278
|
|
|
255
|
-
|
|
256
|
-
|
|
279
|
+
def fix_perf_counter(self, val): # for tests
|
|
280
|
+
global _fixed_perf_counter
|
|
281
|
+
_fixed_perf_counter = val
|
|
257
282
|
|
|
258
283
|
def do_show(self):
|
|
259
284
|
if self.filter.strip() != "":
|
|
@@ -261,14 +286,6 @@ class _Peek:
|
|
|
261
286
|
return False
|
|
262
287
|
return self.enabled
|
|
263
288
|
|
|
264
|
-
def copy_to_clipboard(self, value, confirm=True):
|
|
265
|
-
if Pythonista:
|
|
266
|
-
clipboard.set(str(value))
|
|
267
|
-
else:
|
|
268
|
-
pyperclip.copy(str(value))
|
|
269
|
-
if confirm:
|
|
270
|
-
print(f"copied to clipboard: {value}")
|
|
271
|
-
|
|
272
289
|
def __call__(self, *args, as_str=False, **kwargs):
|
|
273
290
|
codes = {}
|
|
274
291
|
this = self.fork(**kwargs)
|
|
@@ -507,28 +524,6 @@ class _Peek:
|
|
|
507
524
|
|
|
508
525
|
return return_args(args, this.return_none)
|
|
509
526
|
|
|
510
|
-
def configure(self, **kwargs):
|
|
511
|
-
for name, value in kwargs.items():
|
|
512
|
-
check_validity(name, value)
|
|
513
|
-
self._attributes[name] = value
|
|
514
|
-
return self
|
|
515
|
-
|
|
516
|
-
def new(self, ignore_toml=False, **kwargs):
|
|
517
|
-
if ignore_toml:
|
|
518
|
-
return _Peek(**kwargs, parent=peek_no_toml)
|
|
519
|
-
else:
|
|
520
|
-
return _Peek(**kwargs, parent=peek_toml)
|
|
521
|
-
|
|
522
|
-
def fork(self, **kwargs):
|
|
523
|
-
return _Peek(**kwargs, parent=self)
|
|
524
|
-
|
|
525
|
-
def clone(self, **kwargs):
|
|
526
|
-
clone = _Peek(parent=self._parent)
|
|
527
|
-
clone._attributes=self._attributes.copy()
|
|
528
|
-
for name,value in kwargs:
|
|
529
|
-
setattr(clone,name,value)
|
|
530
|
-
return clone
|
|
531
|
-
|
|
532
527
|
@contextlib.contextmanager
|
|
533
528
|
def preserve(self):
|
|
534
529
|
save = dict(self._attributes)
|
|
@@ -567,7 +562,7 @@ class _Peek:
|
|
|
567
562
|
if not omit_context_separator and context:
|
|
568
563
|
context += self.context_separator
|
|
569
564
|
|
|
570
|
-
return (self.prefix() if callable(self.prefix) else self.prefix) + context
|
|
565
|
+
return str(self.prefix() if callable(self.prefix) else self.prefix) + context
|
|
571
566
|
|
|
572
567
|
def add_color_value(self, s):
|
|
573
568
|
if self.output != "stdout" or self.as_str:
|
|
@@ -590,17 +585,13 @@ class _Peek:
|
|
|
590
585
|
s = colors[self.color.lower()] + s + colors["-"]
|
|
591
586
|
if Pythonista:
|
|
592
587
|
while s:
|
|
593
|
-
for ansi,
|
|
588
|
+
for ansi, rgb in ansi_to_rgb.items():
|
|
594
589
|
if s.startswith(ansi):
|
|
595
|
-
|
|
596
|
-
console.set_color()
|
|
597
|
-
else:
|
|
598
|
-
rgb = tuple(int(hexa[i : i + 2], 16) / 255 for i in range(1, 7, 2))
|
|
599
|
-
console.set_color(*rgb)
|
|
590
|
+
console.set_color(*rgb)
|
|
600
591
|
s = s[len(ansi) :]
|
|
601
592
|
break
|
|
602
593
|
else:
|
|
603
|
-
print(s[0], end=""
|
|
594
|
+
print(s[0], end="")
|
|
604
595
|
s = s[1:]
|
|
605
596
|
print()
|
|
606
597
|
else:
|
|
@@ -630,6 +621,14 @@ class _Peek:
|
|
|
630
621
|
else:
|
|
631
622
|
print(s, file=self.output)
|
|
632
623
|
|
|
624
|
+
def copy_to_clipboard(self, value, confirm=True):
|
|
625
|
+
if Pythonista:
|
|
626
|
+
clipboard.set(str(value))
|
|
627
|
+
else:
|
|
628
|
+
pyperclip.copy(str(value))
|
|
629
|
+
if confirm:
|
|
630
|
+
print(f"copied to clipboard: {value}")
|
|
631
|
+
|
|
633
632
|
def traceback(self):
|
|
634
633
|
if self.show_traceback:
|
|
635
634
|
if isinstance(self.wrap_indent, numbers.Number):
|
|
@@ -660,11 +659,12 @@ class _Peek:
|
|
|
660
659
|
return self.add_color_value(self.serialize(obj, **kwargs).replace("\\n", "\n"))
|
|
661
660
|
|
|
662
661
|
|
|
662
|
+
store_perf_counter = perf_counter()
|
|
663
663
|
name_alias_default = (
|
|
664
664
|
("color", "col", "-"),
|
|
665
|
-
("color_value", "
|
|
666
|
-
("context_separator", "cs", " ==> "),
|
|
665
|
+
("color_value", "col_val", ""),
|
|
667
666
|
("compact", "", False),
|
|
667
|
+
("context_separator", "cs", " ==> "),
|
|
668
668
|
("delta", "", 0),
|
|
669
669
|
("depth", "", 1000000),
|
|
670
670
|
("enabled", "", True),
|
|
@@ -689,26 +689,22 @@ name_alias_default = (
|
|
|
689
689
|
("sort_dicts", "", False),
|
|
690
690
|
("to_clipboard", "clip", False),
|
|
691
691
|
("underscore_numbers", "un", False),
|
|
692
|
-
("wrap_indent", "", " "),
|
|
693
692
|
("values_only", "vo", False),
|
|
694
693
|
("values_only_for_fstrings", "voff", False),
|
|
694
|
+
("wrap_indent", "", " "),
|
|
695
695
|
)
|
|
696
|
-
|
|
697
696
|
alias_name = {alias: name for (name, alias, default) in name_alias_default if alias}
|
|
698
697
|
name_default = {name: default for (name, alias, default) in name_alias_default}
|
|
699
698
|
alias_default = {alias: default for (name, alias, default) in name_alias_default if alias}
|
|
700
699
|
name_and_alias_default = {**name_default, **alias_default}
|
|
701
700
|
|
|
701
|
+
in_read_toml_message = ""
|
|
702
702
|
peek_no_toml = _Peek(**name_default)
|
|
703
|
-
peek_toml =
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
# setattr(peek_toml,name,value)
|
|
707
|
-
|
|
708
|
-
peek=peek_toml.new()
|
|
703
|
+
peek_toml = _Peek(**{**name_default, **read_toml()})
|
|
704
|
+
in_read_toml_message = ""
|
|
705
|
+
peek = peek_toml.new()
|
|
709
706
|
builtins.peek = peek
|
|
710
707
|
|
|
711
|
-
|
|
712
708
|
class PeekModule(types.ModuleType):
|
|
713
709
|
def __call__(self, *args, **kwargs):
|
|
714
710
|
return peek(*args, **kwargs)
|
|
@@ -719,6 +715,12 @@ class PeekModule(types.ModuleType):
|
|
|
719
715
|
def __getattr__(self, item):
|
|
720
716
|
return getattr(peek, item)
|
|
721
717
|
|
|
718
|
+
def __repr__(self):
|
|
719
|
+
return repr(peek)
|
|
720
|
+
|
|
721
|
+
def __str__(self):
|
|
722
|
+
return str(peek)
|
|
723
|
+
|
|
722
724
|
|
|
723
725
|
if __name__ != "__main__":
|
|
724
726
|
sys.modules["peek"].__class__ = PeekModule
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: peek-python
|
|
3
|
-
Version: 24.0.
|
|
3
|
+
Version: 24.0.1
|
|
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
|
|
@@ -18,7 +18,8 @@ Requires-Dist: pyperclip>=1.9.0
|
|
|
18
18
|
Requires-Dist: six>=1.17.0
|
|
19
19
|
Requires-Dist: tomli>=2.2.1
|
|
20
20
|
|
|
21
|
-
<img src="https://www.salabim.org/peek/peek_logo1.png">
|
|
21
|
+
- [ ] <img src="https://www.salabim.org/peek/peek_logo1.png">
|
|
22
|
+
|
|
22
23
|
|
|
23
24
|
# Introduction
|
|
24
25
|
|
|
@@ -48,9 +49,7 @@ And on top of that, you get some basic benchmarking functionality.
|
|
|
48
49
|
|
|
49
50
|
* [Disabling peek's output](#disabling-peeks-output)
|
|
50
51
|
|
|
51
|
-
* [Using
|
|
52
|
-
|
|
53
|
-
* [Using color to control peek output](#Using-color-to-control-peek-output)
|
|
52
|
+
* [Using filter to control peek output](#Using-filter-to-control-peek-output)
|
|
54
53
|
|
|
55
54
|
* [Copying to the clipboard](#Copying-to-the-clipboard)
|
|
56
55
|
|
|
@@ -66,12 +65,8 @@ And on top of that, you get some basic benchmarking functionality.
|
|
|
66
65
|
|
|
67
66
|
* [Alternative to `peek`](#alternative-to-peek)
|
|
68
67
|
|
|
69
|
-
* [Alternative installation](#alternative-installation)
|
|
70
|
-
|
|
71
68
|
* [Limitations](#limitations)
|
|
72
69
|
|
|
73
|
-
* [Implementation details](#implementation-details)
|
|
74
|
-
|
|
75
70
|
* [Acknowledgement](#acknowledgement)
|
|
76
71
|
|
|
77
72
|
* [Changelog](#changelog)
|
|
@@ -92,7 +87,7 @@ pip install peek-python --upgrade
|
|
|
92
87
|
|
|
93
88
|
Alternatively, peek.py can be just copied into you current work directory from GitHub (https://github.com/salabim/peek).
|
|
94
89
|
|
|
95
|
-
Note that peek requires the `asttokens`, `colorama`, `executing`. `six`, tomli and pyperclip` modules, all of which will be automatically installed.
|
|
90
|
+
Note that peek requires the `asttokens`, `colorama`, `executing`. `six`, `tomli` and `pyperclip` modules, all of which will be automatically installed with pip.
|
|
96
91
|
|
|
97
92
|
# Importing peek
|
|
98
93
|
|
|
@@ -108,8 +103,9 @@ import peek
|
|
|
108
103
|
from peek import peek
|
|
109
104
|
```
|
|
110
105
|
|
|
111
|
-
|
|
112
|
-
|
|
106
|
+
> [!NOTE]
|
|
107
|
+
>
|
|
108
|
+
> After this, `peek` is automatically a builtin and can thus be used in any module without importing it there.
|
|
113
109
|
|
|
114
110
|
# Inspect variables and expressions
|
|
115
111
|
|
|
@@ -326,7 +322,7 @@ a number of configuration attributes:
|
|
|
326
322
|
attribute alternative default
|
|
327
323
|
------------------------------------------------------
|
|
328
324
|
color col "-"
|
|
329
|
-
color_value
|
|
325
|
+
color_value col_val "-"
|
|
330
326
|
context_separator cs " ==> "
|
|
331
327
|
compact - False
|
|
332
328
|
depth - 1000000
|
|
@@ -366,6 +362,7 @@ print(peek.prefix)
|
|
|
366
362
|
|
|
367
363
|
But, it is also possible to apply configuration directly, only here, in the call to `peek`:
|
|
368
364
|
So, it is possible to say
|
|
365
|
+
|
|
369
366
|
```
|
|
370
367
|
peek(12, prefix="==> ")
|
|
371
368
|
```
|
|
@@ -640,7 +637,7 @@ d=
|
|
|
640
637
|
'a3': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}
|
|
641
638
|
```
|
|
642
639
|
|
|
643
|
-
## color / col and color_value /
|
|
640
|
+
## color / col and color_value / col_val
|
|
644
641
|
The color attribute is used to specify the color of the output.
|
|
645
642
|
There's a choice of black, white, red, green, blue, cyan, magenta and yellow.
|
|
646
643
|
To set the color to 'nothing', use "-".
|
|
@@ -668,7 +665,7 @@ Of course, color and color_value may be specified in a peek.toml file, to make a
|
|
|
668
665
|
>
|
|
669
666
|
> The color and color_value attributes are only applied when using stdout as output.
|
|
670
667
|
>
|
|
671
|
-
> Colors can be ignored completely by using `peek.output = "stdout_nocolor`.
|
|
668
|
+
> Colors can be ignored completely by using `peek.output = "stdout_nocolor"`.
|
|
672
669
|
|
|
673
670
|
## compact
|
|
674
671
|
This attribute is used to specify the compact parameter for `pformat` (see the pprint documentation
|
|
@@ -1017,7 +1014,7 @@ It is possible to use more than one attribute, like
|
|
|
1017
1014
|
```
|
|
1018
1015
|
peek.filter = "color == 'blue' and delta > 5"
|
|
1019
1016
|
```
|
|
1020
|
-
As an alternative to `enabled` we can
|
|
1017
|
+
As an alternative to `enabled` we can also say
|
|
1021
1018
|
```
|
|
1022
1019
|
peek.filter = "False"
|
|
1023
1020
|
```
|
|
@@ -1139,7 +1136,7 @@ Normally, only the `peek` object is used.
|
|
|
1139
1136
|
It can be useful to have multiple instances, e.g. when some of the debugging has to be done with context information
|
|
1140
1137
|
and others requires an alternative prefix.
|
|
1141
1138
|
|
|
1142
|
-
|
|
1139
|
+
There are several ways to obtain a new instance of peek:
|
|
1143
1140
|
|
|
1144
1141
|
* by using `peek.new()`
|
|
1145
1142
|
|
|
@@ -1147,7 +1144,7 @@ THere are several ways to obtain a new instance of peek:
|
|
|
1147
1144
|
and possibly peek.toml overrides.
|
|
1148
1145
|
* by using `peek.new(ignore_toml=True)`
|
|
1149
1146
|
|
|
1150
|
-
With this a new
|
|
1147
|
+
With this a new peek object is created with the default attributes. Any peek.toml files are ignored.
|
|
1151
1148
|
* by using `peek.fork()`
|
|
1152
1149
|
|
|
1153
1150
|
With this a new peek object is created with the same attributes as the object it is created ('the parent') from. Note that any non set attributes are copied (propagated) from the parent.
|
|
@@ -1274,9 +1271,9 @@ The peek package is a rebrand of the **ycecream** package, with enhancements.
|
|
|
1274
1271
|
The peek module was originally a fork of **IceCream**, but has many differences:
|
|
1275
1272
|
|
|
1276
1273
|
```
|
|
1277
|
-
|
|
1274
|
+
-----------------------------------------------------------------------------------------
|
|
1278
1275
|
characteristic peek IceCream
|
|
1279
|
-
|
|
1276
|
+
-----------------------------------------------------------------------------------------
|
|
1280
1277
|
default name peek ic
|
|
1281
1278
|
import method import peek from icecream import ic
|
|
1282
1279
|
number of files 1 several
|
|
@@ -1295,14 +1292,14 @@ level control yes no
|
|
|
1295
1292
|
observes line_length correctly yes no
|
|
1296
1293
|
benchmarking functionality yes no
|
|
1297
1294
|
suppress f-strings at left hand optional no
|
|
1298
|
-
indentation 4 blanks (overridable)
|
|
1295
|
+
indentation 4 blanks (overridable) length of prefix
|
|
1299
1296
|
forking and cloning yes no
|
|
1300
1297
|
test script pytest unittest
|
|
1301
1298
|
colorize ***) yes, off by default yes, on by default
|
|
1302
|
-
|
|
1303
|
-
*) under Python <= 3.7, dicts are always sorted
|
|
1304
|
-
**) under Python <= 3.7, numbers are never underscored
|
|
1305
|
-
***) peek allows selection of a color, whereas IceCream does coloring based on contents
|
|
1299
|
+
-----------------------------------------------------------------------------------------
|
|
1300
|
+
*) under Python <= 3.7, dicts are always sorted
|
|
1301
|
+
**) under Python <= 3.7, numbers are never underscored
|
|
1302
|
+
***) peek allows selection of a color, whereas IceCream does coloring based on contents
|
|
1306
1303
|
|
|
1307
1304
|
```
|
|
1308
1305
|
  
|
|
@@ -144,15 +144,15 @@ def test_values_only():
|
|
|
144
144
|
|
|
145
145
|
|
|
146
146
|
def test_calls():
|
|
147
|
-
with pytest.raises(
|
|
147
|
+
with pytest.raises(AttributeError):
|
|
148
148
|
peek.new(a=1)
|
|
149
|
-
with pytest.raises(
|
|
149
|
+
with pytest.raises(AttributeError):
|
|
150
150
|
peek.clone(a=1)
|
|
151
|
-
with pytest.raises(
|
|
151
|
+
with pytest.raises(AttributeError):
|
|
152
152
|
peek.configure(a=1)
|
|
153
|
-
with pytest.raises(
|
|
153
|
+
with pytest.raises(AttributeError):
|
|
154
154
|
peek(12, a=1)
|
|
155
|
-
with pytest.raises(
|
|
155
|
+
with pytest.raises(AttributeError):
|
|
156
156
|
peek(a=1)
|
|
157
157
|
|
|
158
158
|
|
|
@@ -208,7 +208,7 @@ def test_output(capsys, tmpdir):
|
|
|
208
208
|
with path.open("a+") as f:
|
|
209
209
|
peek(hello, output=f)
|
|
210
210
|
|
|
211
|
-
with pytest.raises(
|
|
211
|
+
with pytest.raises(AttributeError): # closed file
|
|
212
212
|
peek(hello, output=f)
|
|
213
213
|
out, err = capsys.readouterr()
|
|
214
214
|
assert out == ""
|
|
@@ -216,7 +216,7 @@ def test_output(capsys, tmpdir):
|
|
|
216
216
|
with path.open("r") as f:
|
|
217
217
|
assert f.read() == "hello='world'\n"
|
|
218
218
|
|
|
219
|
-
with pytest.raises(
|
|
219
|
+
with pytest.raises(AttributeError):
|
|
220
220
|
peek(hello, output=1)
|
|
221
221
|
|
|
222
222
|
peek(hello, output=my_output)
|
|
@@ -382,10 +382,10 @@ def test_color(capsys):
|
|
|
382
382
|
|
|
383
383
|
|
|
384
384
|
def test_incorrect_filter():
|
|
385
|
-
with pytest.raises(
|
|
385
|
+
with pytest.raises(AttributeError):
|
|
386
386
|
peek.filter="color='blue'"
|
|
387
387
|
|
|
388
|
-
with pytest.raises(
|
|
388
|
+
with pytest.raises(AttributeError):
|
|
389
389
|
peek.filter="colour=='blue'"
|
|
390
390
|
|
|
391
391
|
def test_decorator(capsys):
|
|
@@ -762,7 +762,7 @@ def test_traceback(capsys):
|
|
|
762
762
|
assert out.count("traceback") == 2
|
|
763
763
|
|
|
764
764
|
|
|
765
|
-
|
|
765
|
+
@pytest.mark.skipif(Pythonista, reason="Pythonista problem")
|
|
766
766
|
def test_enforce_line_length(capsys):
|
|
767
767
|
s = 80 * "*"
|
|
768
768
|
with peek.preserve():
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|