peek-python 1.4.2__tar.gz → 1.4.3.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-1.4.2 → peek_python-1.4.3.post0}/PKG-INFO +199 -203
- {peek_python-1.4.2 → peek_python-1.4.3.post0}/README.md +198 -202
- peek_python-1.4.3.post0/peek/__init__.py +2 -0
- {peek_python-1.4.2 → peek_python-1.4.3.post0}/peek/peek.py +10 -664
- {peek_python-1.4.2 → peek_python-1.4.3.post0}/peek_python.egg-info/PKG-INFO +199 -203
- {peek_python-1.4.2 → peek_python-1.4.3.post0}/peek_python.egg-info/SOURCES.txt +2 -1
- {peek_python-1.4.2 → peek_python-1.4.3.post0}/pyproject.toml +1 -1
- peek_python-1.4.3.post0/tests/test_peek.py +1201 -0
- peek_python-1.4.2/tests/test_peek.py → peek_python-1.4.3.post0/tests/test_peek1.py +96 -86
- peek_python-1.4.2/peek/__init__.py +0 -3
- {peek_python-1.4.2 → peek_python-1.4.3.post0}/license.txt +0 -0
- {peek_python-1.4.2 → peek_python-1.4.3.post0}/peek_python.egg-info/dependency_links.txt +0 -0
- {peek_python-1.4.2 → peek_python-1.4.3.post0}/peek_python.egg-info/top_level.txt +0 -0
- {peek_python-1.4.2 → peek_python-1.4.3.post0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: peek-python
|
|
3
|
-
Version: 1.4.
|
|
3
|
+
Version: 1.4.3.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/ycecream
|
|
@@ -16,13 +16,16 @@ License-File: license.txt
|
|
|
16
16
|
|
|
17
17
|
# Introduction
|
|
18
18
|
|
|
19
|
-
Do you
|
|
19
|
+
Do you use `print()` or `log()` to debug your code?
|
|
20
|
+
If so, peek will make printing debug information really easy.
|
|
20
21
|
And on top of that, you get some basic benchmarking functionality.
|
|
21
22
|
|
|
22
23
|
# Table of contents
|
|
23
24
|
|
|
24
25
|
* [Installation](#installation)
|
|
25
26
|
|
|
27
|
+
* [Importing peek](#importing-peek)
|
|
28
|
+
|
|
26
29
|
* [Inspect variables and expressions](#inspect-variables-and-expressions)
|
|
27
30
|
|
|
28
31
|
* [Inspect execution](#inspect-execution)
|
|
@@ -83,6 +86,14 @@ Alternatively, peek.py can be juist copied into you current work directory from
|
|
|
83
86
|
|
|
84
87
|
No dependencies!
|
|
85
88
|
|
|
89
|
+
# Importing peek
|
|
90
|
+
|
|
91
|
+
All you need is:
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
from peek import peek
|
|
95
|
+
```
|
|
96
|
+
|
|
86
97
|
|
|
87
98
|
# Inspect variables and expressions
|
|
88
99
|
|
|
@@ -98,17 +109,15 @@ or the more thorough
|
|
|
98
109
|
```
|
|
99
110
|
print("add2(1000)", add2(1000)))
|
|
100
111
|
```
|
|
101
|
-
or
|
|
112
|
+
or:
|
|
102
113
|
```
|
|
103
|
-
print(f"{add2(1000)
|
|
114
|
+
print(f"{add2(1000)=}")
|
|
104
115
|
```
|
|
105
116
|
|
|
106
117
|
then `peek()` is here to help. With arguments, `peek()` inspects itself and prints
|
|
107
118
|
both its own arguments and the values of those arguments.
|
|
108
119
|
|
|
109
120
|
```
|
|
110
|
-
import peek
|
|
111
|
-
|
|
112
121
|
def add2(i):
|
|
113
122
|
return i + 2
|
|
114
123
|
|
|
@@ -117,13 +126,12 @@ peek(add2(1000))
|
|
|
117
126
|
|
|
118
127
|
prints
|
|
119
128
|
```
|
|
120
|
-
|
|
129
|
+
add2(1000)=1002
|
|
121
130
|
```
|
|
122
131
|
|
|
123
132
|
Similarly,
|
|
124
133
|
|
|
125
134
|
```
|
|
126
|
-
import peek
|
|
127
135
|
class X:
|
|
128
136
|
a = 3
|
|
129
137
|
world = {"EN": "world", "NL": "wereld", "FR": "monde", "DE": "Welt"}
|
|
@@ -133,7 +141,7 @@ peek(world, X.a)
|
|
|
133
141
|
|
|
134
142
|
prints
|
|
135
143
|
```
|
|
136
|
-
|
|
144
|
+
world={"EN": "world ", "NL": "wereld", "FR": "monde", "DE": "Welt"}, X.a: 3
|
|
137
145
|
```
|
|
138
146
|
Just give `peek()` a variable or expression and you're done. Sweet, isn't it?
|
|
139
147
|
|
|
@@ -155,7 +163,6 @@ then `peek()` helps here, too. Without arguments, `peek()` inspects itself and
|
|
|
155
163
|
prints the calling line number and -if applicable- the file name and parent function.
|
|
156
164
|
|
|
157
165
|
```
|
|
158
|
-
import peek
|
|
159
166
|
def add2(i):
|
|
160
167
|
peek()
|
|
161
168
|
result = i + 2
|
|
@@ -166,9 +173,9 @@ peek(add2(1000))
|
|
|
166
173
|
|
|
167
174
|
prints something like
|
|
168
175
|
```
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
176
|
+
#3 in add2()
|
|
177
|
+
#5 in add2()
|
|
178
|
+
add2(1000)=1002
|
|
172
179
|
```
|
|
173
180
|
Just call `peek()` and you're done. Isn't that sweet?
|
|
174
181
|
|
|
@@ -179,7 +186,6 @@ Just call `peek()` and you're done. Isn't that sweet?
|
|
|
179
186
|
pre-existing code.
|
|
180
187
|
|
|
181
188
|
```
|
|
182
|
-
import peek
|
|
183
189
|
def add2(i):
|
|
184
190
|
return i + 2
|
|
185
191
|
b = peek(add2(1000))
|
|
@@ -187,8 +193,8 @@ peek(b)
|
|
|
187
193
|
```
|
|
188
194
|
prints
|
|
189
195
|
```
|
|
190
|
-
|
|
191
|
-
|
|
196
|
+
add2(1000): 1002
|
|
197
|
+
b: 1002
|
|
192
198
|
```
|
|
193
199
|
# Debug entry and exit of function calls
|
|
194
200
|
|
|
@@ -196,7 +202,6 @@ When you apply `peek()` as a decorator to a function or method, both the entry a
|
|
|
196
202
|
The (keyword) arguments passed will be shown and upon return, the return value.
|
|
197
203
|
|
|
198
204
|
```
|
|
199
|
-
import peek
|
|
200
205
|
@peek()
|
|
201
206
|
def mul(x, peek):
|
|
202
207
|
return x * peek
|
|
@@ -205,15 +210,14 @@ print(mul(5, 7))
|
|
|
205
210
|
```
|
|
206
211
|
prints
|
|
207
212
|
```
|
|
208
|
-
|
|
209
|
-
|
|
213
|
+
called mul(5, 7)
|
|
214
|
+
returned 35 from mul(5, 7) in 0.000006 seconds
|
|
210
215
|
35
|
|
211
216
|
```
|
|
212
217
|
It is possible to suppress the print-out of either the enter or the exit information with
|
|
213
218
|
the show_enter and show_exit parameters, like:
|
|
214
219
|
|
|
215
220
|
```
|
|
216
|
-
import peek
|
|
217
221
|
@peek(show_exit=False)
|
|
218
222
|
def mul(x, peek):
|
|
219
223
|
return x * peek
|
|
@@ -222,7 +226,7 @@ print(mul(5, 7))
|
|
|
222
226
|
```
|
|
223
227
|
prints
|
|
224
228
|
```
|
|
225
|
-
|
|
229
|
+
called mul(5, 7)
|
|
226
230
|
35
|
|
227
231
|
```
|
|
228
232
|
Note that it is possible to use `peek` as a decorator without the parentheses, like
|
|
@@ -240,7 +244,6 @@ If you decorate a function or method with peek, you will be offered the duration
|
|
|
240
244
|
|
|
241
245
|
That opens the door to simple benchmarking, like:
|
|
242
246
|
```
|
|
243
|
-
import peek
|
|
244
247
|
import time
|
|
245
248
|
|
|
246
249
|
@peek(show_enter=False,show_line_number=True)
|
|
@@ -254,14 +257,14 @@ for i in range(8):
|
|
|
254
257
|
```
|
|
255
258
|
the ouput will show the effects of the population size on the sort speed:
|
|
256
259
|
```
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
260
|
+
#5 ==> returned ' 1' from do_sort(0) in 0.000027 seconds
|
|
261
|
+
#5 ==> returned ' 10' from do_sort(1) in 0.000060 seconds
|
|
262
|
+
#5 ==> returned ' 100' from do_sort(2) in 0.000748 seconds
|
|
263
|
+
#5 ==> returned ' 1000' from do_sort(3) in 0.001897 seconds
|
|
264
|
+
#5 ==> returned ' 10000' from do_sort(4) in 0.002231 seconds
|
|
265
|
+
#5 ==> returned ' 100000' from do_sort(5) in 0.024014 seconds
|
|
266
|
+
#5 ==> returned ' 1000000' from do_sort(6) in 0.257504 seconds
|
|
267
|
+
#5 ==> returned ' 10000000' from do_sort(7) in 1.553495 seconds
|
|
265
268
|
```
|
|
266
269
|
|
|
267
270
|
It is also possible to time any code by using peek as a context manager, e.g.
|
|
@@ -271,8 +274,8 @@ with peek():
|
|
|
271
274
|
```
|
|
272
275
|
wil print something like
|
|
273
276
|
```
|
|
274
|
-
|
|
275
|
-
|
|
277
|
+
enter
|
|
278
|
+
exit in 1.000900 seconds
|
|
276
279
|
```
|
|
277
280
|
You can include parameters here as well:
|
|
278
281
|
```
|
|
@@ -281,8 +284,8 @@ with peek(show_context=True, show_time=True):
|
|
|
281
284
|
```
|
|
282
285
|
will print somethink like:
|
|
283
286
|
```
|
|
284
|
-
|
|
285
|
-
|
|
287
|
+
#8 @ 13:20:32.605903 ==> enter
|
|
288
|
+
#8 @ 13:20:33.609519 ==> exit in 1.003358 seconds
|
|
286
289
|
```
|
|
287
290
|
|
|
288
291
|
Finally, to help with timing code, you can request the current delta with
|
|
@@ -302,7 +305,7 @@ peek(duration)
|
|
|
302
305
|
```
|
|
303
306
|
might print:
|
|
304
307
|
```
|
|
305
|
-
|
|
308
|
+
duration=1.0001721999999997
|
|
306
309
|
```
|
|
307
310
|
|
|
308
311
|
# Configuration
|
|
@@ -314,8 +317,8 @@ a number of configuration attributes:
|
|
|
314
317
|
------------------------------------------------------
|
|
315
318
|
attribute alternative default
|
|
316
319
|
------------------------------------------------------
|
|
317
|
-
prefix pr "
|
|
318
|
-
output o "
|
|
320
|
+
prefix pr ""
|
|
321
|
+
output o "stdout"
|
|
319
322
|
serialize pprint.pformat
|
|
320
323
|
show_line_number sln False
|
|
321
324
|
show_time st False
|
|
@@ -333,7 +336,7 @@ depth de 1000000
|
|
|
333
336
|
wrap_indent wi " "
|
|
334
337
|
separator sep ", "
|
|
335
338
|
context_separator cs " ==> "
|
|
336
|
-
equals_separator es "
|
|
339
|
+
equals_separator es "="
|
|
337
340
|
values_only vo False
|
|
338
341
|
value_only_for_fstrings voff False
|
|
339
342
|
return_none rn False
|
|
@@ -352,7 +355,6 @@ print(peek.prefix)
|
|
|
352
355
|
But, it is also possible to apply configuration directly in the call to `peek`:
|
|
353
356
|
So, it is possible to say
|
|
354
357
|
```
|
|
355
|
-
import peek
|
|
356
358
|
peek(12, prefix="==> ")
|
|
357
359
|
```
|
|
358
360
|
, which will print
|
|
@@ -402,7 +404,6 @@ After this `peek1` and `peek2` will behave similarly (but they are not the same!
|
|
|
402
404
|
|
|
403
405
|
## prefix / pr
|
|
404
406
|
```
|
|
405
|
-
import peek
|
|
406
407
|
peek('world', prefix='hello -> ')
|
|
407
408
|
```
|
|
408
409
|
prints
|
|
@@ -414,7 +415,6 @@ hello -> 'world'
|
|
|
414
415
|
|
|
415
416
|
```
|
|
416
417
|
import time
|
|
417
|
-
import peek
|
|
418
418
|
def unix_timestamp():
|
|
419
419
|
return f"{int(time.time())} "
|
|
420
420
|
hello = "world"
|
|
@@ -423,11 +423,11 @@ peek(hello)
|
|
|
423
423
|
```
|
|
424
424
|
prints
|
|
425
425
|
```
|
|
426
|
-
1613635601 hello
|
|
426
|
+
1613635601 hello='world'
|
|
427
427
|
```
|
|
428
428
|
|
|
429
429
|
## output / o
|
|
430
|
-
This will allow the output to be handled by something else than the default (output being written to
|
|
430
|
+
This will allow the output to be handled by something else than the default (output being written to stdout).
|
|
431
431
|
|
|
432
432
|
The `output` attribute can be
|
|
433
433
|
|
|
@@ -437,7 +437,6 @@ The `output` attribute can be
|
|
|
437
437
|
|
|
438
438
|
In the example below,
|
|
439
439
|
```
|
|
440
|
-
import peek
|
|
441
440
|
import sys
|
|
442
441
|
peek(1, output=print)
|
|
443
442
|
peek(2, output=sys.stdout
|
|
@@ -445,14 +444,13 @@ with open("test", "a+") as f:
|
|
|
445
444
|
peek(3, output=f)
|
|
446
445
|
peek(4, output="")
|
|
447
446
|
```
|
|
448
|
-
* `
|
|
449
|
-
* `
|
|
450
|
-
* `
|
|
451
|
-
* `
|
|
447
|
+
* `1` will be printed to stdout
|
|
448
|
+
* `2` will be printed to stdout
|
|
449
|
+
* `3` will be appended to the file test
|
|
450
|
+
* `4` will *disappear*
|
|
452
451
|
|
|
453
452
|
As `output` may be any callable, you can even use this to automatically log any `peek` output:
|
|
454
453
|
```
|
|
455
|
-
import peek
|
|
456
454
|
import logging
|
|
457
455
|
logging.basicConfig(level="INFO")
|
|
458
456
|
log = logging.getLogger("demo")
|
|
@@ -462,10 +460,10 @@ peek(a)
|
|
|
462
460
|
a.remove(4)
|
|
463
461
|
peek(a)
|
|
464
462
|
```
|
|
465
|
-
will print to
|
|
463
|
+
will print to stdout:
|
|
466
464
|
```
|
|
467
|
-
INFO:demo:
|
|
468
|
-
INFO:demo:
|
|
465
|
+
INFO:demo:a={1, 2, 3, 4, 5}
|
|
466
|
+
INFO:demo:a={1, 2, 3, 5}
|
|
469
467
|
```
|
|
470
468
|
Finally, you can specify the following strings:
|
|
471
469
|
```
|
|
@@ -480,7 +478,6 @@ Finally, you can specify the following strings:
|
|
|
480
478
|
```
|
|
481
479
|
E.g.
|
|
482
480
|
```
|
|
483
|
-
import peek
|
|
484
481
|
import sys
|
|
485
482
|
peek.configure(output="stdout")
|
|
486
483
|
```
|
|
@@ -492,8 +489,8 @@ serialized to displayable strings. The default is pformat (from pprint), but thi
|
|
|
492
489
|
for example, to handle non-standard datatypes in a custom fashion.
|
|
493
490
|
The serialize function should accept at least one parameter.
|
|
494
491
|
The function can optionally accept the keyword arguments `width` and `sort_dicts`, `compact`, `indent`, `underscore_numbers` and `depth`.
|
|
492
|
+
|
|
495
493
|
```
|
|
496
|
-
import peek
|
|
497
494
|
def add_len(obj):
|
|
498
495
|
if hasattr(obj, "__len__"):
|
|
499
496
|
add = f" [len={len(obj)}]"
|
|
@@ -501,20 +498,19 @@ def add_len(obj):
|
|
|
501
498
|
add = ""
|
|
502
499
|
return f"{repr(obj)}{add}"
|
|
503
500
|
|
|
504
|
-
|
|
501
|
+
l7 = list(range(7))
|
|
505
502
|
hello = "world"
|
|
506
|
-
peek(7, hello,
|
|
503
|
+
peek(7, hello, l7, serialize=add_len)
|
|
507
504
|
```
|
|
508
505
|
prints
|
|
509
506
|
```
|
|
510
|
-
|
|
507
|
+
7, hello='world' [len=5], l7=[0, 1, 2, 3, 4, 5, 6] [len=7]
|
|
511
508
|
```
|
|
512
509
|
|
|
513
510
|
## show_line_number / sln
|
|
514
511
|
If True, adds the `peek()` call's line number and possible the filename and parent function to `peek()`'s output.
|
|
515
512
|
|
|
516
513
|
```
|
|
517
|
-
import peek
|
|
518
514
|
peek.configure(show_line_number=True)
|
|
519
515
|
def shout():
|
|
520
516
|
hello="world"
|
|
@@ -523,12 +519,11 @@ shout()
|
|
|
523
519
|
```
|
|
524
520
|
prints something like
|
|
525
521
|
```
|
|
526
|
-
|
|
522
|
+
#5 in shout() ==> hello='world'
|
|
527
523
|
```
|
|
528
524
|
|
|
529
525
|
If "no parent" or "n", the parent function will not be shown.
|
|
530
526
|
```
|
|
531
|
-
import peek
|
|
532
527
|
peek.configure(show_line_number="n")
|
|
533
528
|
def shout():
|
|
534
529
|
hello="world"
|
|
@@ -537,7 +532,7 @@ shout()
|
|
|
537
532
|
```
|
|
538
533
|
prints something like
|
|
539
534
|
```
|
|
540
|
-
|
|
535
|
+
#5 ==> hello='world'
|
|
541
536
|
```
|
|
542
537
|
Note that if you call `peek` without any arguments, the line number is always shown, regardless of the status `show_line_number`.
|
|
543
538
|
|
|
@@ -547,20 +542,18 @@ See below for an explanation of the information provided.
|
|
|
547
542
|
If True, adds the current time to `peek()`'s output.
|
|
548
543
|
|
|
549
544
|
```
|
|
550
|
-
import peek
|
|
551
545
|
peek.configure(show_time=True)
|
|
552
546
|
hello="world"
|
|
553
547
|
peek(hello)
|
|
554
548
|
```
|
|
555
549
|
prints something like
|
|
556
550
|
```
|
|
557
|
-
|
|
551
|
+
@ 13:01:47.588125 ==> hello='world'
|
|
558
552
|
```
|
|
559
553
|
|
|
560
554
|
## show_delta / sd
|
|
561
555
|
If True, adds the number of seconds since the start of the program to `peek()`'s output.
|
|
562
556
|
```
|
|
563
|
-
import peek
|
|
564
557
|
import time
|
|
565
558
|
peek.configure(show_delta=True)
|
|
566
559
|
french = "bonjour le monde"
|
|
@@ -571,8 +564,8 @@ peek(french)
|
|
|
571
564
|
```
|
|
572
565
|
prints something like
|
|
573
566
|
```
|
|
574
|
-
|
|
575
|
-
|
|
567
|
+
delta=0.088 ==> english='hallo world'
|
|
568
|
+
delta=1.091 ==> french='bonjour le monde'
|
|
576
569
|
```
|
|
577
570
|
|
|
578
571
|
## show_enter / se
|
|
@@ -591,8 +584,8 @@ With `show_exit=False` this line can be suppressed.
|
|
|
591
584
|
## show_traceback / stb
|
|
592
585
|
When show_traceback is True, the ordinary output of peek() will be followed by a printout of the
|
|
593
586
|
traceback, similar to an error traceback.
|
|
587
|
+
|
|
594
588
|
```
|
|
595
|
-
import peek
|
|
596
589
|
peek.show_traceback=True
|
|
597
590
|
def x():
|
|
598
591
|
peek()
|
|
@@ -602,13 +595,13 @@ x()
|
|
|
602
595
|
```
|
|
603
596
|
prints
|
|
604
597
|
```
|
|
605
|
-
|
|
598
|
+
#4 in x()
|
|
606
599
|
Traceback (most recent call last)
|
|
607
600
|
File "c:\Users\Ruud\Dropbox (Personal)\Apps\Python Ruud\peek\x.py", line 6, in <module>
|
|
608
601
|
x()
|
|
609
602
|
File "c:\Users\Ruud\Dropbox (Personal)\Apps\Python Ruud\peek\x.py", line 4, in x
|
|
610
603
|
peek()
|
|
611
|
-
|
|
604
|
+
#4 in x()
|
|
612
605
|
Traceback (most recent call last)
|
|
613
606
|
File "c:\Users\Ruud\Dropbox (Personal)\Apps\Python Ruud\peek\x.py", line 7, in <module>
|
|
614
607
|
x()
|
|
@@ -620,6 +613,7 @@ The `show_traceback` functionality is also available when peek is used as a deco
|
|
|
620
613
|
## line_length / ll
|
|
621
614
|
This attribute is used to specify the line length (for wrapping). The default is 80.
|
|
622
615
|
Peek always tries to keep all output on one line, but if it can't it will wrap:
|
|
616
|
+
|
|
623
617
|
```
|
|
624
618
|
d = dict(a1=1,a2=dict(a=1,b=1,c=3),a3=list(range(10)))
|
|
625
619
|
peek(d)
|
|
@@ -632,12 +626,13 @@ peek|
|
|
|
632
626
|
{'a1': 1,
|
|
633
627
|
'a2': {'a': 1, 'b': 1, 'c': 3},
|
|
634
628
|
'a3': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}
|
|
635
|
-
|
|
629
|
+
d: {'a1': 1, 'a2': {'a': 1, 'b': 1, 'c': 3}, 'a3': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}
|
|
636
630
|
```
|
|
637
631
|
|
|
638
632
|
## compact / c
|
|
639
633
|
This attribute is used to specify the compact parameter for `pformat` (see the pprint documentation
|
|
640
634
|
for details). `compact` is False by default.
|
|
635
|
+
|
|
641
636
|
```
|
|
642
637
|
a = 9 * ["0123456789"]
|
|
643
638
|
peek(a)
|
|
@@ -645,26 +640,25 @@ peek(a, compact=True)
|
|
|
645
640
|
```
|
|
646
641
|
prints
|
|
647
642
|
```
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
['0123456789', '0123456789', '0123456789', '0123456789', '0123456789',
|
|
662
|
-
'0123456789', '0123456789', '0123456789', '0123456789']
|
|
643
|
+
a=
|
|
644
|
+
['0123456789',
|
|
645
|
+
'0123456789',
|
|
646
|
+
'0123456789',
|
|
647
|
+
'0123456789',
|
|
648
|
+
'0123456789',
|
|
649
|
+
'0123456789',
|
|
650
|
+
'0123456789',
|
|
651
|
+
'0123456789',
|
|
652
|
+
'0123456789']
|
|
653
|
+
a=
|
|
654
|
+
['0123456789', '0123456789', '0123456789', '0123456789', '0123456789',
|
|
655
|
+
'0123456789', '0123456789', '0123456789', '0123456789']
|
|
663
656
|
```
|
|
664
657
|
|
|
665
658
|
## indent / i
|
|
666
659
|
This attribute is used to specify the indent parameter for `pformat` (see the pprint documentation
|
|
667
660
|
for details). `indent` is 1 by default.
|
|
661
|
+
|
|
668
662
|
```
|
|
669
663
|
s = "01234567890012345678900123456789001234567890"
|
|
670
664
|
peek( [s, [s]])
|
|
@@ -672,19 +666,18 @@ peek( [s, [s]], indent=4)
|
|
|
672
666
|
```
|
|
673
667
|
prints
|
|
674
668
|
```
|
|
675
|
-
|
|
676
|
-
[
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
[ '01234567890012345678900123456789001234567890',
|
|
682
|
-
['01234567890012345678900123456789001234567890']]
|
|
669
|
+
[s, [s]]=
|
|
670
|
+
['01234567890012345678900123456789001234567890',
|
|
671
|
+
['01234567890012345678900123456789001234567890']]
|
|
672
|
+
[s, [s]]=
|
|
673
|
+
[ '01234567890012345678900123456789001234567890',
|
|
674
|
+
['01234567890012345678900123456789001234567890']]
|
|
683
675
|
```
|
|
684
676
|
|
|
685
677
|
## depth / de
|
|
686
678
|
This attribute is used to specify the depth parameter for `pformat` (see the pprint documentation
|
|
687
679
|
for details). `depth` is `1000000` by default.
|
|
680
|
+
|
|
688
681
|
```
|
|
689
682
|
s = "01234567890012345678900123456789001234567890"
|
|
690
683
|
peek([s,[s,[s,[s,s]]]])
|
|
@@ -692,18 +685,16 @@ peek([s,[s,[s,[s,s]]]], depth=3)
|
|
|
692
685
|
```
|
|
693
686
|
prints
|
|
694
687
|
```
|
|
695
|
-
|
|
696
|
-
[
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
['01234567890012345678900123456789001234567890',
|
|
706
|
-
['01234567890012345678900123456789001234567890', [...]]]]
|
|
688
|
+
[s,[s,[s,[s,s]]]]=
|
|
689
|
+
['01234567890012345678900123456789001234567890',
|
|
690
|
+
['01234567890012345678900123456789001234567890',
|
|
691
|
+
['01234567890012345678900123456789001234567890',
|
|
692
|
+
['01234567890012345678900123456789001234567890',
|
|
693
|
+
'01234567890012345678900123456789001234567890']]]]
|
|
694
|
+
[s,[s,[s,[s,s]]]]=
|
|
695
|
+
['01234567890012345678900123456789001234567890',
|
|
696
|
+
['01234567890012345678900123456789001234567890',
|
|
697
|
+
['01234567890012345678900123456789001234567890', [...]]]]
|
|
707
698
|
```
|
|
708
699
|
|
|
709
700
|
## wrap_indent / wi
|
|
@@ -720,28 +711,23 @@ peek(d, wrap_indent=2)
|
|
|
720
711
|
```
|
|
721
712
|
prints
|
|
722
713
|
```
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
....
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
{'a1': 1,
|
|
736
|
-
'a2': {'a': 1, 'b': 1, 'c': 3},
|
|
737
|
-
'a3': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}
|
|
714
|
+
d=
|
|
715
|
+
{'a1': 1,
|
|
716
|
+
'a2': {'a': 1, 'b': 1, 'c': 3},
|
|
717
|
+
'a3': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}
|
|
718
|
+
d=
|
|
719
|
+
....{'a1': 1,
|
|
720
|
+
.... 'a2': {'a': 1, 'b': 1, 'c': 3},
|
|
721
|
+
.... 'a3': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}
|
|
722
|
+
d=
|
|
723
|
+
{'a1': 1,
|
|
724
|
+
'a2': {'a': 1, 'b': 1, 'c': 3},
|
|
725
|
+
'a3': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}
|
|
738
726
|
```
|
|
739
727
|
|
|
740
728
|
## enabled / e
|
|
741
729
|
Can be used to disable the output:
|
|
742
730
|
```
|
|
743
|
-
import peek
|
|
744
|
-
|
|
745
731
|
peek.configure(enabled=False)
|
|
746
732
|
s = 'the world is '
|
|
747
733
|
peek(s + 'perfect.')
|
|
@@ -750,7 +736,7 @@ peek(s + 'on fire.')
|
|
|
750
736
|
```
|
|
751
737
|
prints
|
|
752
738
|
```
|
|
753
|
-
|
|
739
|
+
s + 'on fire.'='the world is on fire.'
|
|
754
740
|
```
|
|
755
741
|
and nothing about a perfect world.
|
|
756
742
|
|
|
@@ -766,13 +752,16 @@ peek(world, sort_dicts=True)
|
|
|
766
752
|
```
|
|
767
753
|
prints
|
|
768
754
|
```
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
755
|
+
world={'EN': 'world', 'NL': 'wereld', 'FR': 'monde', 'DE': 'Welt'}
|
|
756
|
+
world={'EN': 'world', 'NL': 'wereld', 'FR': 'monde', 'DE': 'Welt'}
|
|
757
|
+
world={'DE': 'Welt', 'EN': 'world', 'FR': 'monde', 'NL': 'wereld'}
|
|
772
758
|
```
|
|
773
759
|
|
|
760
|
+
Note that under Python <=3.7, dicts are always printed sorted.
|
|
761
|
+
|
|
774
762
|
## underscore_numbers / un
|
|
775
|
-
|
|
763
|
+
|
|
764
|
+
By default, peek does not add underscores in big numbers (printed by pprint). However, it is possible to get the
|
|
776
765
|
default pprint behaviour with the underscore_numbers attribute:
|
|
777
766
|
|
|
778
767
|
```
|
|
@@ -783,14 +772,16 @@ peek(numbers, un=False)
|
|
|
783
772
|
```
|
|
784
773
|
prints
|
|
785
774
|
```
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
775
|
+
numbers={'one': 1, 'thousand': 1000, 'million': 1000000, 'x1234567890': 1234567890}
|
|
776
|
+
numbers={'one': 1, 'thousand': 1_000, 'million': 1_000_000, 'x1234567890': 1_234_567_890}
|
|
777
|
+
numbers={'one': 1, 'thousand': 1000, 'million': 1000000, 'x1234567890': 1234567890}
|
|
789
778
|
```
|
|
790
779
|
|
|
791
|
-
##
|
|
780
|
+
## seperator / sep
|
|
781
|
+
|
|
792
782
|
By default, pairs (on one line) are separated by `, `.
|
|
793
783
|
It is possible to change this with the attribute ` separator`:
|
|
784
|
+
|
|
794
785
|
```
|
|
795
786
|
a="abcd"
|
|
796
787
|
b=1
|
|
@@ -801,10 +792,13 @@ peek(a,(b,c),d, separator=" | ")
|
|
|
801
792
|
```
|
|
802
793
|
prints
|
|
803
794
|
```
|
|
804
|
-
|
|
805
|
-
|
|
795
|
+
a='abcd', (b,c)=(1, 1000), d=['peek', 'c', 'e', 'c', 'r', 'e', 'a', 'm']
|
|
796
|
+
a='abcd' | (b,c)=(1, 1000) | d=['peek', 'c', 'e', 'c', 'r', 'e', 'a', 'm']
|
|
806
797
|
```
|
|
798
|
+
Note that under Python <=3.7, numbers are never printed with underscores.
|
|
799
|
+
|
|
807
800
|
## context_separator / cs
|
|
801
|
+
|
|
808
802
|
By default the line_number, time and/or delta are followed by ` ==> `.
|
|
809
803
|
It is possible to change this with the attribute `context_separator`:
|
|
810
804
|
```
|
|
@@ -814,12 +808,13 @@ peek(a, show_time=True, context_separator = ' \u279c ')
|
|
|
814
808
|
```
|
|
815
809
|
prints:
|
|
816
810
|
```
|
|
817
|
-
|
|
818
|
-
|
|
811
|
+
@ 12:56:11.341650 ==> a='abcd'
|
|
812
|
+
@ 12:56:11.485567 ➜ a='abcd'
|
|
819
813
|
```
|
|
820
814
|
## equals_separator / es
|
|
821
815
|
By default name of a variable and its value are separated by `: `.
|
|
822
816
|
It is possible to change this with the attribute `equals_separator`:
|
|
817
|
+
|
|
823
818
|
```
|
|
824
819
|
a="abcd"
|
|
825
820
|
peek(a)
|
|
@@ -827,8 +822,8 @@ peek(a, equals_separator = ' == ")
|
|
|
827
822
|
```
|
|
828
823
|
prints:
|
|
829
824
|
```
|
|
830
|
-
|
|
831
|
-
|
|
825
|
+
a='abcd'
|
|
826
|
+
a == 'abcd'
|
|
832
827
|
```
|
|
833
828
|
|
|
834
829
|
## values_only / vo
|
|
@@ -841,8 +836,8 @@ peek(hello, 2 * hello, values_only=True)
|
|
|
841
836
|
```
|
|
842
837
|
prints
|
|
843
838
|
```
|
|
844
|
-
|
|
845
|
-
|
|
839
|
+
hello='world', 2 * hello='worldworld'
|
|
840
|
+
'world', 'worldworld'
|
|
846
841
|
```
|
|
847
842
|
The values=True version of peek can be seen as a supercharged print/pprint.
|
|
848
843
|
|
|
@@ -851,6 +846,7 @@ The values=True version of peek can be seen as a supercharged print/pprint.
|
|
|
851
846
|
If False (the default), both the original f-string and the
|
|
852
847
|
value will be printed for f-strings.
|
|
853
848
|
If True, the left_hand side will be suppressed in case of an f-string:
|
|
849
|
+
|
|
854
850
|
```
|
|
855
851
|
x = 12.3
|
|
856
852
|
peek(f"{x:0.3e}")
|
|
@@ -859,8 +855,8 @@ peek(f"{x:0.3e}")
|
|
|
859
855
|
```
|
|
860
856
|
prints
|
|
861
857
|
```
|
|
862
|
-
|
|
863
|
-
|
|
858
|
+
f"{x:0.3e}"='1.230e+01'
|
|
859
|
+
'1.230e+01'
|
|
864
860
|
```
|
|
865
861
|
Note that if `values_only` is True, f-string will be suppressed, regardless of `values_only_for_fstrings`.
|
|
866
862
|
|
|
@@ -876,15 +872,14 @@ print(peek(a, a + 1))
|
|
|
876
872
|
```
|
|
877
873
|
prints
|
|
878
874
|
```
|
|
879
|
-
peek| (3, 4)
|
|
880
875
|
(3, 4)
|
|
881
|
-
|
|
876
|
+
(3, 4)
|
|
877
|
+
(3, 4)
|
|
882
878
|
None
|
|
883
879
|
```
|
|
884
880
|
|
|
885
881
|
## enforce_line_length / ell
|
|
886
|
-
If enforce_line_length is True, all output lines are
|
|
887
|
-
line_length, even those that are not truncated by pformat.
|
|
882
|
+
If enforce_line_length is True, all output lines are explicitly truncated to the given line_length, even those that are not truncated by pformat.
|
|
888
883
|
|
|
889
884
|
## delta / dl
|
|
890
885
|
The delta attribute can be used to (re)set the current delta, e.g.
|
|
@@ -906,8 +901,8 @@ specify `decorator=True`. E.g.
|
|
|
906
901
|
>>>def add2(x):
|
|
907
902
|
>>> return x + 2
|
|
908
903
|
>>>print(add2(10))
|
|
909
|
-
|
|
910
|
-
|
|
904
|
+
called add2(10)
|
|
905
|
+
returned 12 from add2(10) in 0.000548 seconds
|
|
911
906
|
12
|
|
912
907
|
```
|
|
913
908
|
|
|
@@ -938,8 +933,8 @@ specify `context_manager=True`. E.g.
|
|
|
938
933
|
```
|
|
939
934
|
>>>with peek(context_manager=True)
|
|
940
935
|
>>> pass
|
|
941
|
-
|
|
942
|
-
|
|
936
|
+
enter
|
|
937
|
+
exit in 0.008644 seconds
|
|
943
938
|
```
|
|
944
939
|
|
|
945
940
|
The `context_manager` attribute is also required when using `peek():` as a context manager
|
|
@@ -977,14 +972,13 @@ should print
|
|
|
977
972
|
of written to output.
|
|
978
973
|
|
|
979
974
|
```
|
|
980
|
-
import peek
|
|
981
975
|
hello = "world"
|
|
982
976
|
s = peek(hello, as_str=True)
|
|
983
977
|
print(s, end="")
|
|
984
978
|
```
|
|
985
979
|
prints
|
|
986
980
|
```
|
|
987
|
-
|
|
981
|
+
hello='world'
|
|
988
982
|
```
|
|
989
983
|
|
|
990
984
|
Note that if enabled=False, the call will return the null string (`""`).
|
|
@@ -992,7 +986,6 @@ Note that if enabled=False, the call will return the null string (`""`).
|
|
|
992
986
|
# Disabling peek's output
|
|
993
987
|
|
|
994
988
|
```
|
|
995
|
-
import peek
|
|
996
989
|
peek1 = peek.fork(show_delta=True)
|
|
997
990
|
peek(1)
|
|
998
991
|
peek1(2)
|
|
@@ -1006,10 +999,10 @@ print(peek1.enabled)
|
|
|
1006
999
|
```
|
|
1007
1000
|
prints
|
|
1008
1001
|
```
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1002
|
+
1
|
|
1003
|
+
delta=0.011826 ==> 2
|
|
1004
|
+
5
|
|
1005
|
+
delta=0.044893 ==> 6
|
|
1013
1006
|
True
|
|
1014
1007
|
```
|
|
1015
1008
|
Of course `peek()` continues to return its arguments when disabled, of course.
|
|
@@ -1082,15 +1075,15 @@ Note that with the attribute propagation method, you can in effect have a layere
|
|
|
1082
1075
|
|
|
1083
1076
|
When `show_line_number` is True or peek() is used without any parameters, the output will contain the line number like:
|
|
1084
1077
|
```
|
|
1085
|
-
|
|
1078
|
+
#3 ==> a='abcd'
|
|
1086
1079
|
```
|
|
1087
1080
|
If the line resides in another file than the main file, the filename (without the path) will be shown as well:
|
|
1088
1081
|
```
|
|
1089
|
-
|
|
1082
|
+
#30[foo.py] ==> foo='Foo'
|
|
1090
1083
|
```
|
|
1091
1084
|
And finally when used in a function or method, that function/method will be shown as well:
|
|
1092
1085
|
```
|
|
1093
|
-
|
|
1086
|
+
#456[foo.py] in square_root ==> x=123
|
|
1094
1087
|
```
|
|
1095
1088
|
The parent function can be suppressed by setting `show_line_number` or `sln` to `"n"` or `"no parent"`.
|
|
1096
1089
|
|
|
@@ -1099,9 +1092,10 @@ The parent function can be suppressed by setting `show_line_number` or `sln` to
|
|
|
1099
1092
|
It can be useful to configure peek at import time. This can be done by providing a `peek.json` file which
|
|
1100
1093
|
can contain any attribute configuration overriding the standard settings.
|
|
1101
1094
|
E.g. if there is an `peek.json` file with the following contents
|
|
1095
|
+
|
|
1102
1096
|
```
|
|
1103
1097
|
{
|
|
1104
|
-
"o": "
|
|
1098
|
+
"o": "stderr",
|
|
1105
1099
|
"show_time": true,
|
|
1106
1100
|
"line_length": 120`
|
|
1107
1101
|
'compact' : true
|
|
@@ -1109,13 +1103,12 @@ E.g. if there is an `peek.json` file with the following contents
|
|
|
1109
1103
|
```
|
|
1110
1104
|
in the same folder as the application, this program:
|
|
1111
1105
|
```
|
|
1112
|
-
import peek
|
|
1113
1106
|
hello = "world"
|
|
1114
1107
|
peek(hello)
|
|
1115
1108
|
```
|
|
1116
|
-
will print to
|
|
1109
|
+
will print to stderr (rather than stdout):
|
|
1117
1110
|
```
|
|
1118
|
-
|
|
1111
|
+
@ 14:53:41.392190 ==> hello='world'
|
|
1119
1112
|
```
|
|
1120
1113
|
At import time the sys.path will be searched for, in that order, to find an `peek.json` file and use that. This mean that
|
|
1121
1114
|
you can place an `peek.json` file in the site-packages folder where `peek` is installed to always use
|
|
@@ -1165,7 +1158,6 @@ In either case, attributes can be added to override the default ones.
|
|
|
1165
1158
|
|
|
1166
1159
|
### Example
|
|
1167
1160
|
```
|
|
1168
|
-
import peek
|
|
1169
1161
|
peek_with_line_number = peek.fork(show_line_number=True)
|
|
1170
1162
|
peek_with_new_prefix = peek.new(prefix="==> ")
|
|
1171
1163
|
peek_with_new_prefix_and_time = peek_with_new_prefix.clone(show_time=True)
|
|
@@ -1183,16 +1175,16 @@ with peek(prefix="peek_cm ") as peek_cm:
|
|
|
1183
1175
|
```
|
|
1184
1176
|
prints something like
|
|
1185
1177
|
```
|
|
1186
|
-
|
|
1187
|
-
==> hello
|
|
1188
|
-
==> @
|
|
1189
|
-
|
|
1190
|
-
==> hello
|
|
1191
|
-
==> @
|
|
1178
|
+
#28 ==> hello='world'
|
|
1179
|
+
==> hello='world'
|
|
1180
|
+
==> @ 09:55:52.122818 ==> hello='world'
|
|
1181
|
+
#32 ==> hello == 'world'
|
|
1182
|
+
==> hello='world'
|
|
1183
|
+
==> @ 09:55:52.125928 ==> hello='world'
|
|
1192
1184
|
peek_cm enter
|
|
1193
|
-
peek_cm hello
|
|
1194
|
-
|
|
1195
|
-
peek_cm exit in 0.
|
|
1185
|
+
peek_cm hello == 'world'
|
|
1186
|
+
hello == 'world'
|
|
1187
|
+
peek_cm exit in 0.001843 seconds
|
|
1196
1188
|
```
|
|
1197
1189
|
|
|
1198
1190
|
## ignore_json
|
|
@@ -1214,9 +1206,9 @@ peek_ignore_json(hello)
|
|
|
1214
1206
|
```
|
|
1215
1207
|
prints
|
|
1216
1208
|
```
|
|
1217
|
-
==>hello
|
|
1218
|
-
==>hello
|
|
1219
|
-
|
|
1209
|
+
==>hello='world'
|
|
1210
|
+
==>hello='world'
|
|
1211
|
+
hello='world'
|
|
1220
1212
|
```
|
|
1221
1213
|
|
|
1222
1214
|
# Test script
|
|
@@ -1233,7 +1225,7 @@ Peek may be used in a REPL, but with limited functionality:
|
|
|
1233
1225
|
```
|
|
1234
1226
|
>> hello = "world"
|
|
1235
1227
|
>>> peek(hello, hello * 2)
|
|
1236
|
-
|
|
1228
|
+
'hello', 'hellohello'
|
|
1237
1229
|
('hello', 'hellohello')
|
|
1238
1230
|
```
|
|
1239
1231
|
* line numbers are never shown
|
|
@@ -1248,7 +1240,7 @@ In that case, it is possible to use p instead
|
|
|
1248
1240
|
```
|
|
1249
1241
|
from peek import p
|
|
1250
1242
|
```
|
|
1251
|
-
The `p` object is a *fork* of peek
|
|
1243
|
+
The `p` object is a *fork* of peek. That means that attributes of `peek` are propagated to `p`, unless overridden.
|
|
1252
1244
|
|
|
1253
1245
|
# Alternative installation
|
|
1254
1246
|
|
|
@@ -1268,7 +1260,7 @@ It is not possible to use peek:
|
|
|
1268
1260
|
# Implementation details
|
|
1269
1261
|
|
|
1270
1262
|
Although not important for using the package, here are some implementation details:
|
|
1271
|
-
* peek.py contains the complete source of the asttokens and
|
|
1263
|
+
* peek.py contains the complete source of the asttokens, executing and six packages, in
|
|
1272
1264
|
order to offer the required source lookups, without any dependencies
|
|
1273
1265
|
* peek.py contains the complete source of pprint as of Python 3.13 in order to support the sort_dicts and underscore_numbers parameter
|
|
1274
1266
|
* in order to support using peek() as a decorator and a context manager, peek caches the complete source of
|
|
@@ -1296,32 +1288,36 @@ The peek package is a rebrand of the **ycecream** package, with enhancements.
|
|
|
1296
1288
|
The peek module was originally a fork of **IceCream**, but has many differences:
|
|
1297
1289
|
|
|
1298
1290
|
```
|
|
1299
|
-
|
|
1300
|
-
characteristic peek
|
|
1301
|
-
|
|
1302
|
-
default name peek
|
|
1303
|
-
import method import peek
|
|
1304
|
-
dependencies none
|
|
1305
|
-
number of files 1
|
|
1306
|
-
usable without installation yes
|
|
1307
|
-
can be used as a decorator yes
|
|
1308
|
-
can be used as a context manager yes
|
|
1309
|
-
can show traceback yes
|
|
1310
|
-
PEP8 (Pythonic) API yes
|
|
1311
|
-
sorts dicts no by default, optional yes
|
|
1291
|
+
-------------------------------------------------------------------------------------------
|
|
1292
|
+
characteristic peek IceCream
|
|
1293
|
+
-------------------------------------------------------------------------------------------
|
|
1294
|
+
default name peek ic
|
|
1295
|
+
import method from peek import peek from icecream import ic
|
|
1296
|
+
dependencies none many
|
|
1297
|
+
number of files 1 several
|
|
1298
|
+
usable without installation yes no
|
|
1299
|
+
can be used as a decorator yes no
|
|
1300
|
+
can be used as a context manager yes no
|
|
1301
|
+
can show traceback yes no
|
|
1302
|
+
PEP8 (Pythonic) API yes no
|
|
1303
|
+
sorts dicts no by default, optional *) yes
|
|
1312
1304
|
supports compact, indent,
|
|
1313
1305
|
and underscore_numbers
|
|
1314
|
-
parameters of pprint yes
|
|
1315
|
-
use from a REPL limited functionality
|
|
1316
|
-
external configuration via json file
|
|
1317
|
-
observes line_length correctly yes
|
|
1318
|
-
benchmarking functionality yes
|
|
1319
|
-
suppress f-strings at left hand optional
|
|
1320
|
-
indentation 4 blanks (overridable)
|
|
1321
|
-
forking and cloning yes
|
|
1322
|
-
test script pytest
|
|
1323
|
-
colourize no
|
|
1324
|
-
|
|
1306
|
+
parameters of pprint yes **) no
|
|
1307
|
+
use from a REPL limited functionality no
|
|
1308
|
+
external configuration via json file no
|
|
1309
|
+
observes line_length correctly yes no
|
|
1310
|
+
benchmarking functionality yes no
|
|
1311
|
+
suppress f-strings at left hand optional no
|
|
1312
|
+
indentation 4 blanks (overridable) dependent on length of prefix
|
|
1313
|
+
forking and cloning yes no
|
|
1314
|
+
test script pytest unittest
|
|
1315
|
+
colourize no yes (can be disabled)
|
|
1316
|
+
-------------------------------------------------------------------------------------------
|
|
1317
|
+
*) under Python <= 3.7, dicts are always sorted (regardless of the sort_dicts attribute
|
|
1318
|
+
**) under Python <= 3.7, numbers are never underscored (regardless of the underscore_numnbers attribute
|
|
1319
|
+
|
|
1320
|
+
|
|
1325
1321
|
```
|
|
1326
1322
|
  
|
|
1327
1323
|
|