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.
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: peek-python
3
- Version: 25.0.1
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 level to control peek output](#using-level-to-control-peek-output)
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/peek_colors1.png">
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
- There's a choice of black, white, red, green, blue, cyan, magenta and yellow.
662
- To set the color to 'nothing', use "-".
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/peek_colors2.png">
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 level to control peek output](#using-level-to-control-peek-output)
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/peek_colors1.png">
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
- There's a choice of black, white, red, green, blue, cyan, magenta and yellow.
642
- To set the color to 'nothing', use "-".
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/peek_colors2.png">
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.1"
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
- colors = dict(
102
- black="\033[0;30m",
103
- red="\033[0;31m",
104
- green="\033[0;32m",
105
- yellow="\033[0;33m",
106
- blue="\033[0;34m",
107
- magenta="\033[0;35m",
108
- cyan="\033[0;36m",
109
- white="\033[0;37m",
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
- colors["-"] = "\033[0m"
112
- colors[""] = "\033[0m"
113
-
114
- codes = {}
115
-
116
- ansi_to_rgb = {
117
- "\033[0;30m": (0, 0, 0),
118
- "\033[0;31m": (1, 0, 0),
119
- "\033[0;32m": (0, 1, 0),
120
- "\033[0;33m": (1, 1, 0),
121
- "\033[0;34m": (0, 0.7, 1),
122
- "\033[0;35m": (1, 0, 1),
123
- "\033[0;36m": (0, 1, 1),
124
- "\033[0;37m": (1, 1, 1),
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.colors:
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.ansi_to_rgb.items():
255
+ for ansi, rgb in _Peek._ANSI_to_rgb.items():
236
256
  if s.startswith(ansi):
237
- console.set_color(*rgb)
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=False, **kwargs):
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.no_source_error()
409
- _Peek.codes[filename] = frame_info.code_context
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
- if filename in ("<stdin>", "<string>"):
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 filename in ("<stdin>", "<string>") or this.values_only:
531
+ if call_node is None or this.values_only:
499
532
  for right in args:
500
- pairs.append(Pair(left="", right=right))
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.append(Pair(left=left, right=right))
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.colors[self.color_value.lower()] + s + self.colors[self.color.lower()]
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.colors[self.color.lower()] + s + self.end + self.colors["-"]
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 PeekModule(types.ModuleType):
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__ = PeekModule
808
+ sys.modules["peek"].__class__ = _PeekModule
809
+
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: peek-python
3
- Version: 25.0.1
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 level to control peek output](#using-level-to-control-peek-output)
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/peek_colors1.png">
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
- There's a choice of black, white, red, green, blue, cyan, magenta and yellow.
662
- To set the color to 'nothing', use "-".
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/peek_colors2.png">
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.1"
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[0;31m10 * 10=100\n\x1b[0m"
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():