peek-python 1.7.0__tar.gz → 1.8.0.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
1
  Metadata-Version: 2.1
2
2
  Name: peek-python
3
- Version: 1.7.0
3
+ Version: 1.8.0.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
@@ -338,6 +338,7 @@ underscore_numbers un False
338
338
  enabled e True
339
339
  line_length ll 160
340
340
  color col ""
341
+ color_value colv ""
341
342
  level l 0
342
343
  compact c False
343
344
  indent i 1
@@ -634,23 +635,33 @@ d=
634
635
  'a3': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}
635
636
  ```
636
637
 
637
- ## color / col
638
- This attribute is used to specify the colour of the output.
638
+ ## color / col and color_value / colv
639
+ The color attribute is used to specify the colour of the output.
639
640
  There's a choice of black, white, red, green, blue, cyan, magenta and yellow.
640
- To reset the color to 'nothing', use the null string ("").
641
+ To set the color to 'nothing', use the null string ("").
642
+
643
+ 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.
644
+
645
+ For instance:
641
646
 
642
647
  ```
643
- peek.color = "red"
644
- peek("text in red")
645
- peek("text in green", color="green")
646
- peek("plain text", color="")
648
+ x = "x"
649
+ y = "y"
650
+ peek(x, y)
651
+ peek(x, y, color_value="green")
652
+ peek(x, y, color="red")
653
+ peek(x, y, color="red", color_value="green")
647
654
  ```
648
655
 
649
- Of course, the colour can be specified in a peek.toml file, to make all peek output in a specified color.
656
+ will result in:
657
+
658
+ <img src="https://www.salabim.org/peek/peek_colors.png">
659
+
660
+ Of course, color and color_value may be specified in a peek.toml file, to make all peek output in a specified color.
650
661
 
651
662
  > [!NOTE]
652
663
  >
653
- > The color attribute is only applied when using stdout as output.
664
+ > The color and color_value attributes are only applied when using stdout as output.
654
665
 
655
666
  ## compact / c
656
667
  This attribute is used to specify the compact parameter for `pformat` (see the pprint documentation
@@ -1006,22 +1017,6 @@ peek("warning", level=2)
1006
1017
 
1007
1018
  With `peek.show_level()` the program may select which level(s) to show or not.
1008
1019
 
1009
- This is done with a string that specifies which level(s) to show. The string consist of one or more specifiers seperated by a `,`.
1010
- Each specifier may be simple value or a pair of values, separated by a `-` .
1011
- Valid strings are
1012
-
1013
- * `peek.show_level("0")` ==> 0
1014
-
1015
- * `peek.show_level("0, 1, 2")` ==> 0, 1, 2
1016
-
1017
- * `peek.show_level("1-3")` ==> 1, 2, 3
1018
-
1019
- * `peek.show_level("1-")` ==> 1, 2, 3, 4, ...
1020
-
1021
- * `peek.show_level("-2")` ==> 0, 1, 2
1022
-
1023
- * `peek.show_level("-")` ==> 0, 1, 2, 3, ... (this is the default)
1024
-
1025
1020
  Notice that a level matches if any of the specifiers conditions is met.
1026
1021
 
1027
1022
  `peek.show_level("")` disables peek output completely.
@@ -1045,16 +1040,63 @@ peek0 = peek.fork(color="red", level=0)
1045
1040
  peek1 = peek.fork(color="yellow", level=1)
1046
1041
  peek2 = peek.fork(color="green", level=2)
1047
1042
  ```
1043
+
1048
1044
  If level of a peek statement is the null string, peek will never print. That can be useful to disable peek debug info on a per peek instance basis, e.g.:
1049
1045
 
1050
1046
  ```peek_cond = peek.new()
1051
- peek_connd = peek.new()
1047
+ peek_cond = peek.new()
1052
1048
  peek_cond(1)
1053
1049
  peek_cond.level = ""
1054
1050
  peek_cond(2)
1055
1051
  ```
1052
+
1056
1053
  This will print only 1.
1057
1054
 
1055
+ The most easy form for `peek.show_level` is just a simple value as argument, like `peek.show.level(2)`, which will make only level 2 peeks to work.
1056
+
1057
+ `peek.show_level` can have a number (usually 1) of arguments.
1058
+
1059
+ Each parameter may be:
1060
+
1061
+ * a float value or
1062
+
1063
+ - a string with the format *from* - *to*
1064
+ , where both *from* and *to* are optional. If *from* is omitted, -1E30 is assumed. If *to* is omitted, 1E30 is assumed.
1065
+ Negative values have to be parenthesized.
1066
+
1067
+ Examples:
1068
+
1069
+ - `peek.show_level (1)` ==> show level 1
1070
+ - `peek.show_level (1, -3)` ==> show level 1 and level -3
1071
+ - `peek.show_level ("1-2")` ==> show level between 1 and 2
1072
+ - `peek.show_level("-")` ==> show all levels
1073
+ - `peek.show_level("")` ==> show no levels
1074
+ - `peek.show_level("1-")`==> show all levels >= 1
1075
+ - `peek.show_level("-10.2")`==> show all levels <=10.2
1076
+ - `peek.show_level(1, 2, "5-7", "10-")` ==> show levels 1, 2, between 5 and 7 (inclusive) and >= 10
1077
+ - `peek.show_level((-3)-3")` ==> show levels between -3 and 3 (inclusive)
1078
+ - `peek.show_level()` ==> returns the current show_level
1079
+
1080
+ `show_level` can also be called with a minimum and/or a maximum value, e.g.
1081
+
1082
+ - `peek.show_level(min=1)` ==> show all levels >= 1
1083
+ - `peek.show_level(max=10.2)` ==> show all levels <= 10.2
1084
+ - `peek.show_level(min=1, max=10)` ==> show all levels between 1 and 10 (inclusive)
1085
+
1086
+ Note that min or max cannot be combined with a specifier as above
1087
+
1088
+ `show_level` can also be used as a context managerl:
1089
+
1090
+ ```
1091
+ with peek.show_level(1):
1092
+ peek(1, level=1)
1093
+ peek(2, level=2)
1094
+ ```
1095
+
1096
+ This will print one line with`1` only.
1097
+
1098
+
1099
+
1058
1100
  # Interpreting the line number information
1059
1101
 
1060
1102
  When `show_line_number` is True or peek() is used without any parameters, the output will contain the line number like:
@@ -319,6 +319,7 @@ underscore_numbers un False
319
319
  enabled e True
320
320
  line_length ll 160
321
321
  color col ""
322
+ color_value colv ""
322
323
  level l 0
323
324
  compact c False
324
325
  indent i 1
@@ -615,23 +616,33 @@ d=
615
616
  'a3': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}
616
617
  ```
617
618
 
618
- ## color / col
619
- This attribute is used to specify the colour of the output.
619
+ ## color / col and color_value / colv
620
+ The color attribute is used to specify the colour of the output.
620
621
  There's a choice of black, white, red, green, blue, cyan, magenta and yellow.
621
- To reset the color to 'nothing', use the null string ("").
622
+ To set the color to 'nothing', use the null string ("").
623
+
624
+ 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.
625
+
626
+ For instance:
622
627
 
623
628
  ```
624
- peek.color = "red"
625
- peek("text in red")
626
- peek("text in green", color="green")
627
- peek("plain text", color="")
629
+ x = "x"
630
+ y = "y"
631
+ peek(x, y)
632
+ peek(x, y, color_value="green")
633
+ peek(x, y, color="red")
634
+ peek(x, y, color="red", color_value="green")
628
635
  ```
629
636
 
630
- Of course, the colour can be specified in a peek.toml file, to make all peek output in a specified color.
637
+ will result in:
638
+
639
+ <img src="https://www.salabim.org/peek/peek_colors.png">
640
+
641
+ Of course, color and color_value may be specified in a peek.toml file, to make all peek output in a specified color.
631
642
 
632
643
  > [!NOTE]
633
644
  >
634
- > The color attribute is only applied when using stdout as output.
645
+ > The color and color_value attributes are only applied when using stdout as output.
635
646
 
636
647
  ## compact / c
637
648
  This attribute is used to specify the compact parameter for `pformat` (see the pprint documentation
@@ -987,22 +998,6 @@ peek("warning", level=2)
987
998
 
988
999
  With `peek.show_level()` the program may select which level(s) to show or not.
989
1000
 
990
- This is done with a string that specifies which level(s) to show. The string consist of one or more specifiers seperated by a `,`.
991
- Each specifier may be simple value or a pair of values, separated by a `-` .
992
- Valid strings are
993
-
994
- * `peek.show_level("0")` ==> 0
995
-
996
- * `peek.show_level("0, 1, 2")` ==> 0, 1, 2
997
-
998
- * `peek.show_level("1-3")` ==> 1, 2, 3
999
-
1000
- * `peek.show_level("1-")` ==> 1, 2, 3, 4, ...
1001
-
1002
- * `peek.show_level("-2")` ==> 0, 1, 2
1003
-
1004
- * `peek.show_level("-")` ==> 0, 1, 2, 3, ... (this is the default)
1005
-
1006
1001
  Notice that a level matches if any of the specifiers conditions is met.
1007
1002
 
1008
1003
  `peek.show_level("")` disables peek output completely.
@@ -1026,16 +1021,63 @@ peek0 = peek.fork(color="red", level=0)
1026
1021
  peek1 = peek.fork(color="yellow", level=1)
1027
1022
  peek2 = peek.fork(color="green", level=2)
1028
1023
  ```
1024
+
1029
1025
  If level of a peek statement is the null string, peek will never print. That can be useful to disable peek debug info on a per peek instance basis, e.g.:
1030
1026
 
1031
1027
  ```peek_cond = peek.new()
1032
- peek_connd = peek.new()
1028
+ peek_cond = peek.new()
1033
1029
  peek_cond(1)
1034
1030
  peek_cond.level = ""
1035
1031
  peek_cond(2)
1036
1032
  ```
1033
+
1037
1034
  This will print only 1.
1038
1035
 
1036
+ The most easy form for `peek.show_level` is just a simple value as argument, like `peek.show.level(2)`, which will make only level 2 peeks to work.
1037
+
1038
+ `peek.show_level` can have a number (usually 1) of arguments.
1039
+
1040
+ Each parameter may be:
1041
+
1042
+ * a float value or
1043
+
1044
+ - a string with the format *from* - *to*
1045
+ , where both *from* and *to* are optional. If *from* is omitted, -1E30 is assumed. If *to* is omitted, 1E30 is assumed.
1046
+ Negative values have to be parenthesized.
1047
+
1048
+ Examples:
1049
+
1050
+ - `peek.show_level (1)` ==> show level 1
1051
+ - `peek.show_level (1, -3)` ==> show level 1 and level -3
1052
+ - `peek.show_level ("1-2")` ==> show level between 1 and 2
1053
+ - `peek.show_level("-")` ==> show all levels
1054
+ - `peek.show_level("")` ==> show no levels
1055
+ - `peek.show_level("1-")`==> show all levels >= 1
1056
+ - `peek.show_level("-10.2")`==> show all levels <=10.2
1057
+ - `peek.show_level(1, 2, "5-7", "10-")` ==> show levels 1, 2, between 5 and 7 (inclusive) and >= 10
1058
+ - `peek.show_level((-3)-3")` ==> show levels between -3 and 3 (inclusive)
1059
+ - `peek.show_level()` ==> returns the current show_level
1060
+
1061
+ `show_level` can also be called with a minimum and/or a maximum value, e.g.
1062
+
1063
+ - `peek.show_level(min=1)` ==> show all levels >= 1
1064
+ - `peek.show_level(max=10.2)` ==> show all levels <= 10.2
1065
+ - `peek.show_level(min=1, max=10)` ==> show all levels between 1 and 10 (inclusive)
1066
+
1067
+ Note that min or max cannot be combined with a specifier as above
1068
+
1069
+ `show_level` can also be used as a context managerl:
1070
+
1071
+ ```
1072
+ with peek.show_level(1):
1073
+ peek(1, level=1)
1074
+ peek(2, level=2)
1075
+ ```
1076
+
1077
+ This will print one line with`1` only.
1078
+
1079
+
1080
+
1039
1081
  # Interpreting the line number information
1040
1082
 
1041
1083
  When `show_line_number` is True or peek() is used without any parameters, the output will contain the line number like:
@@ -4,7 +4,7 @@
4
4
  # | .__/ \___| \___||_|\_\
5
5
  # |_| like print, but easy.
6
6
 
7
- __version__ = "1.7.0"
7
+ __version__ = "1.8.0"
8
8
 
9
9
  """
10
10
  See https://github.com/salabim/peek for details
@@ -56,30 +56,51 @@ def perf_counter():
56
56
 
57
57
 
58
58
  colors = dict(
59
- black=("\033[0;30m", "#000000"),
60
- red=("\033[0;31m", "#FF0000"),
61
- green=("\033[0;32m", "#00FF00"),
62
- yellow=("\033[0;33m", "#A52A2A"),
63
- blue=("\033[0;34m", "#0000FF"),
64
- magenta=("\033[0;35m", "#800080"),
65
- cyan=("\033[0;36m", "#00FFFF"),
66
- white=("\033[0;37m", "#D3D3D3"),
59
+ black="\033[0;30m",
60
+ red="\033[0;31m",
61
+ green="\033[0;32m",
62
+ yellow="\033[0;33m",
63
+ blue="\033[0;34m",
64
+ magenta="\033[0;35m",
65
+ cyan="\033[0;36m",
66
+ white="\033[0;37m",
67
67
  )
68
+ colors[""] = "\033[0m"
69
+
70
+
71
+ ansi_to_hexa = {
72
+ "\033[0;30m": "#000000",
73
+ "\033[0;31m": "#FF0000",
74
+ "\033[0;32m": "#00FF00",
75
+ "\033[0;33m": "#FFFF00",
76
+ "\033[0;34m": "#0080FF",
77
+ "\033[0;35m": "#FF00FF",
78
+ "\033[0;36m": "#00FFFF",
79
+ "\033[0;37m": "#FFFFFF",
80
+ "\033[0m": "",
81
+ }
68
82
 
69
83
 
70
- def colorname_to_rgb(colorname):
71
- return tuple(int(colors[colorname.lower()][1][i : i + 2], 16) / 255 for i in range(1, 7, 2))
84
+ def flatten(x):
85
+ for item in x:
86
+ if isinstance(item, str):
87
+ yield item
88
+ else:
89
+ try:
90
+ yield from flatten(item)
91
+ except TypeError:
92
+ yield item
72
93
 
73
94
 
74
- def colorname_to_ansi(colorname):
75
- return colors[colorname.lower()][0]
95
+ # def colorname_to_rgb(colorname):
96
+ # return tuple(int(ansito_rgb[colorname.lower()][i : i + 2], 16) / 255 for i in range(1, 7, 2))
76
97
 
77
98
 
78
99
  def check_validity(item, value, message=""):
79
100
  if value is None:
80
101
  return
81
102
 
82
- if item == "color":
103
+ if item in ("color", "color_value"):
83
104
  if not value or (isinstance(value, str) and value.lower() in colors):
84
105
  return
85
106
 
@@ -108,56 +129,83 @@ def check_validity(item, value, message=""):
108
129
  raise ValueError(f"incorrect {item}: {value}{message}")
109
130
 
110
131
 
111
- def show_level_evaluate(value, message=""):
112
- if isinstance(value, str) and value.strip() == "":
113
- expression = "False"
114
- else:
115
- result = []
116
- if isinstance(value, numbers.Number):
117
- result.append(f"level == {value}")
118
- else:
119
- if not isinstance(value, str):
120
- raise ValueError(f"incorrect show_level spec: {value} {message}")
121
-
122
- if value.strip():
123
- elements = value.strip().split(",")
124
- for element in elements:
125
- if element == "":
126
- return True
127
- if "-" in element:
128
- part0, part1 = element.split("-", 1)
129
- part0 = part0.strip()
130
- part1 = part1.strip()
131
- if part0 == "":
132
- part0 = "-1e30"
133
- if part1 == "":
134
- part1 = "1e30"
135
- try:
136
- float(part0)
137
- float(part1)
138
- except ValueError as e:
139
- raise ValueError(f"incorrect show_level spec: {element} in {value} {message}") from None
140
- if float(part0) > float(part1):
141
- raise ValueError(f"incorrect show_level spec: {element} in {value} {message}")
142
- result.append(f"{part0} <= level <= {part1}")
143
- else:
144
- try:
145
- float(element)
146
- except ValueError as e:
147
- raise ValueError(f"incorrect show_level spec: {element} in {value} {message}") from None
148
- result.append(f"level == {element}")
132
+ class show_level:
133
+ def __new__(cls, *values, min=None, max=None, message=""):
134
+ if len(values) == 0 and min is None and max is None:
135
+ return _show_level
136
+ return super().__new__(cls)
137
+
138
+ def __init__(self, *values, min=None, max=None, message=""):
139
+ result = ["False"]
140
+ if min is not None or max is not None:
141
+ if values:
142
+ raise ValueError(f"min or max cannot be combined with other specifiers (={values})")
143
+ if min is not None and max is not None and min > max:
144
+ raise ValueError(f"min (={min}) > max (={max})")
145
+ if min is None:
146
+ min = ""
147
+ else:
148
+ if min < 0:
149
+ min = f"({min})"
150
+ if max is None:
151
+ max = ""
149
152
  else:
150
- result.append("True")
153
+ if max < 0:
154
+ max = f"({max})"
155
+ values = [f"{min}-{max}"]
156
+
157
+ valuex = tuple(flatten(values))
158
+ for element in valuex:
159
+ if isinstance(element, numbers.Number):
160
+ result.append(f"level == {element}")
161
+ elif element is None:
162
+ ...
163
+ elif isinstance(element, str):
164
+ elementx = element.strip().replace("(-", "$$$").replace(")", "").replace("-", "/").replace("$$$", "-")
165
+ if elementx.lower() == "all":
166
+ elementx = "/"
167
+ if elementx == "":
168
+ ...
169
+ elif "/" in elementx:
170
+ part0, part1 = elementx.split("/", 1)
171
+ if part0 == "":
172
+ part0 = "-1e30"
173
+ if part1 == "":
174
+ part1 = "1e30"
175
+ try:
176
+ float(part0)
177
+ float(part1)
178
+ except ValueError as e:
179
+ raise ValueError(f"incorrect show_level spec: {element} in {values} {message}") from None
180
+ if float(part0) > float(part1):
181
+ raise ValueError(f"incorrect order in show_level spec: {element} in {values} {message}")
182
+ result.append(f"{part0} <= level <= {part1}")
183
+ else:
184
+ try:
185
+ float(elementx)
186
+ except ValueError as e:
187
+ raise ValueError(f"incorrect show_level spec: {element} in {values} {message}") from None
188
+ result.append(f"level == {element}")
189
+ else:
190
+ raise ValueError(f"incorrect show_level spec: {element} in {values} {message}")
151
191
 
152
192
  expression = f"level != '' and ({' or '.join(result)})"
153
- global _show_level
154
- global _show_level_expression
155
- _show_level = value
156
- _show_level_expression = expression
157
193
 
194
+ global _show_level
195
+ global _show_level_expression
196
+ self.saved_show_level = _show_level
197
+ self.saved_show_level_expression = _show_level_expression
198
+ _show_level = values[0] if len(values) == 1 else values
199
+ _show_level_expression = expression
200
+
201
+ def __enter__(self):
202
+ ...
158
203
 
159
- def do_show_level(level):
160
- return eval(_show_level_expression, dict(level=level))
204
+ def __exit__(self, exc_type, exc_value, exc_tb):
205
+ global _show_level
206
+ global _show_level_expression
207
+ _show_level = self.saved_show_level
208
+ _show_level_expression = self.saved_show_level_expression
161
209
 
162
210
 
163
211
  def peek_pformat(obj, width, compact, indent, depth, sort_dicts, underscore_numbers):
@@ -190,7 +238,10 @@ def change_path(new_path): # used in tests
190
238
 
191
239
  _fixed_perf_counter = None
192
240
 
193
- show_level_evaluate("-")
241
+ _show_level = "-"
242
+ _show_level_expression = "True"
243
+
244
+ attrs = set() # ***
194
245
 
195
246
 
196
247
  def fix_perf_counter(val): # for tests
@@ -222,6 +273,7 @@ shortcut_to_name = {
222
273
  "voff": "values_only_for_fstrings",
223
274
  "rn": "return_none",
224
275
  "col": "color",
276
+ "colv": "color_value",
225
277
  "l": "level",
226
278
  "ell": "enforce_line_length",
227
279
  "dl": "delta",
@@ -253,6 +305,7 @@ def set_defaults():
253
305
  default.values_only_for_fstrings = False
254
306
  default.return_none = False
255
307
  default.color = ""
308
+ default.color_value = ""
256
309
  default.level = 0
257
310
  default.enforce_line_length = False
258
311
  default.one_line_per_pairenforce_line_length = False
@@ -272,7 +325,7 @@ def apply_toml():
272
325
  setattr(default, k, v)
273
326
  else:
274
327
  if k == "show_level":
275
- show_level_evaluate(v, " in peek.toml file")
328
+ show_level(v, " in peek.toml file")
276
329
  elif k == "delta":
277
330
  setattr(default, "start_time", perf_counter() - v)
278
331
  else:
@@ -337,6 +390,7 @@ class _Peek:
337
390
  values_only_for_fstrings=nv,
338
391
  return_none=nv,
339
392
  color=nv,
393
+ color_value=nv,
340
394
  level=nv,
341
395
  enforce_line_length=nv,
342
396
  delta=nv,
@@ -392,13 +446,17 @@ class _Peek:
392
446
  if value is not None:
393
447
  value = perf_counter() - value
394
448
  check_validity(item, value)
449
+ if item == "show_level":
450
+ raise NameError("reassigning show_level not allowed")
451
+
395
452
  if item in ["_attributes"]:
396
453
  super(_Peek, self).__setattr__(item, value)
397
454
  else:
398
- if item == "show_level":
399
- show_level_evaluate(value)
400
455
  self._attributes[item] = value
401
456
 
457
+ def do_show(self):
458
+ return eval(_show_level_expression, dict(level=self.level)) and self.enabled
459
+
402
460
  def assign(self, shortcuts, source, func):
403
461
  for key, value in shortcuts.items():
404
462
  if key in shortcut_to_name:
@@ -447,6 +505,7 @@ class _Peek:
447
505
  values_only_for_fstrings = kwargs.pop("values_only_for_fstrings", nv)
448
506
  return_none = kwargs.pop("return_none", nv)
449
507
  color = kwargs.pop("color", nv)
508
+ color_value = kwargs.pop("color_value", nv)
450
509
  level = kwargs.pop("level", nv)
451
510
  enforce_line_length = kwargs.pop("enforce_line_length", nv)
452
511
  delta = kwargs.pop("delta", nv)
@@ -460,13 +519,19 @@ class _Peek:
460
519
  as_str = False if as_str is nv else bool(as_str)
461
520
  provided = True if provided is nv else bool(provided)
462
521
 
522
+ this = self.fork()
523
+ this.assign(kwargs, locals(), func="__call__")
524
+
525
+ if len(args) != 0 and not this.do_show():
526
+ if as_str:
527
+ return ""
528
+ else:
529
+ return return_args(args, this.return_none)
530
+
463
531
  self.is_context_manager = False
464
532
 
465
533
  Pair = collections.namedtuple("Pair", "left right")
466
534
 
467
- this = self.fork()
468
- this.assign(kwargs, locals(), func="__call__")
469
-
470
535
  if not provided:
471
536
  this.enabled = False
472
537
 
@@ -525,7 +590,7 @@ class _Peek:
525
590
  this_line_prev = code[line_number - 2].strip()
526
591
  else:
527
592
  this_line_prev = ""
528
- if len(args) == 0 and (this_line.startswith("@") or this_line_prev.startswith("@")):
593
+ if this_line.startswith("@") or this_line_prev.startswith("@"):
529
594
  if as_str:
530
595
  raise TypeError("as_str may not be True when peek used as decorator")
531
596
 
@@ -569,6 +634,9 @@ class _Peek:
569
634
 
570
635
  return wrapper
571
636
 
637
+ if not this.do_show():
638
+ return lambda x: x
639
+
572
640
  return real_decorator
573
641
 
574
642
  if filename in ("<stdin>", "<string>"):
@@ -584,7 +652,7 @@ class _Peek:
584
652
  line_number=line_number, filename_name=filename_name, parent_function=parent_function
585
653
  )
586
654
 
587
- if len(args) == 0 and (this_line.startswith("with ") or this_line.startswith("with\t")):
655
+ if this_line.startswith("with ") or this_line.startswith("with\t"):
588
656
  if as_str:
589
657
  raise TypeError("as_str may not be True when peek used as context manager")
590
658
  if args:
@@ -593,9 +661,11 @@ class _Peek:
593
661
  this.is_context_manager = True
594
662
  return this
595
663
 
596
- if not this.enabled and do_show_level(this.level) and not as_str:
597
- return return_args(args, this.return_none)
598
-
664
+ if not this.do_show():
665
+ if as_str:
666
+ return ""
667
+ else:
668
+ return return_args(args, this.return_none)
599
669
  if args:
600
670
  context = this.context()
601
671
  pairs = []
@@ -689,7 +759,7 @@ class _Peek:
689
759
  out += this.traceback()
690
760
 
691
761
  if as_str:
692
- if this.enabled and do_show_level(this.level):
762
+ if this.do_show():
693
763
  if this.enforce_line_length:
694
764
  out = "\n".join(line[: this.line_length] for line in out.splitlines())
695
765
  return out + "\n"
@@ -725,6 +795,7 @@ class _Peek:
725
795
  values_only_for_fstrings=nv,
726
796
  return_none=nv,
727
797
  color=nv,
798
+ color_value=nv,
728
799
  level=nv,
729
800
  enforce_line_length=nv,
730
801
  delta=nv,
@@ -766,6 +837,7 @@ class _Peek:
766
837
  values_only_for_fstrings=nv,
767
838
  return_none=nv,
768
839
  color=nv,
840
+ color_value=nv,
769
841
  level=nv,
770
842
  enforce_line_length=nv,
771
843
  delta=nv,
@@ -778,7 +850,7 @@ class _Peek:
778
850
  return this
779
851
 
780
852
  def assert_(self, condition):
781
- if self.enabled and do_show_level(self.level):
853
+ if self.do_show():
782
854
  assert condition
783
855
 
784
856
  @contextlib.contextmanager
@@ -822,28 +894,40 @@ class _Peek:
822
894
 
823
895
  return (self.prefix() if callable(self.prefix) else self.prefix) + context
824
896
 
897
+ def add_color_value(self, s):
898
+ if self.output != "stdout" or self.color_value == "" or self.as_str:
899
+ return s
900
+ return colors[self.color_value] + s + colors[self.color]
901
+
825
902
  def do_output(self, s):
826
903
  if self.enforce_line_length:
827
904
  s = "\n".join(line[: self.line_length] for line in s.splitlines())
828
- if self.enabled and do_show_level(self.level):
905
+ if self.do_show():
829
906
  if callable(self.output):
830
907
  self.output(s)
831
908
  elif self.output == "stderr":
832
909
  print(s, file=sys.stderr)
833
910
  elif self.output == "stdout":
834
- if self.color:
835
- if Pythonista:
836
- console.set_color(*colorname_to_rgb(self.color))
837
- else:
838
- colorama.init()
839
- print(colorname_to_ansi(self.color), end="")
840
- print(s, file=sys.stdout)
841
- if self.color:
842
- if Pythonista:
843
- console.set_color()
844
- else:
845
- print("\033[0m", end="")
846
- colorama.deinit()
911
+ s = colors[self.color] + s + colors[""]
912
+ if Pythonista:
913
+ while s:
914
+ for ansi, hexa in ansi_to_hexa.items():
915
+ if s.startswith(ansi):
916
+ if hexa == "":
917
+ console.set_color()
918
+ else:
919
+ rgb = tuple(int(hexa[i : i + 2], 16) / 255 for i in range(1, 7, 2))
920
+ console.set_color(*rgb)
921
+ s = s[len(ansi) :]
922
+ break
923
+ else:
924
+ print(s[0], end="", file=sys.stdout)
925
+ s = s[1:]
926
+ print()
927
+ else:
928
+ colorama.init()
929
+ print(s, file=sys.stdout)
930
+ colorama.deinit()
847
931
 
848
932
  elif self.output == "logging.debug":
849
933
  logging.debug(s)
@@ -906,7 +990,7 @@ class _Peek:
906
990
  if "width" in inspect.signature(self.serialize).parameters:
907
991
  kwargs["width"] = width
908
992
 
909
- return self.serialize(obj, **kwargs).replace("\\n", "\n")
993
+ return self.add_color_value(self.serialize(obj, **kwargs).replace("\\n", "\n"))
910
994
 
911
995
 
912
996
  codes = {}
@@ -932,3 +1016,4 @@ class PeekModule(types.ModuleType):
932
1016
 
933
1017
  if __name__ != "__main__":
934
1018
  sys.modules["peek"].__class__ = PeekModule
1019
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: peek-python
3
- Version: 1.7.0
3
+ Version: 1.8.0.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
@@ -338,6 +338,7 @@ underscore_numbers un False
338
338
  enabled e True
339
339
  line_length ll 160
340
340
  color col ""
341
+ color_value colv ""
341
342
  level l 0
342
343
  compact c False
343
344
  indent i 1
@@ -634,23 +635,33 @@ d=
634
635
  'a3': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}
635
636
  ```
636
637
 
637
- ## color / col
638
- This attribute is used to specify the colour of the output.
638
+ ## color / col and color_value / colv
639
+ The color attribute is used to specify the colour of the output.
639
640
  There's a choice of black, white, red, green, blue, cyan, magenta and yellow.
640
- To reset the color to 'nothing', use the null string ("").
641
+ To set the color to 'nothing', use the null string ("").
642
+
643
+ 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.
644
+
645
+ For instance:
641
646
 
642
647
  ```
643
- peek.color = "red"
644
- peek("text in red")
645
- peek("text in green", color="green")
646
- peek("plain text", color="")
648
+ x = "x"
649
+ y = "y"
650
+ peek(x, y)
651
+ peek(x, y, color_value="green")
652
+ peek(x, y, color="red")
653
+ peek(x, y, color="red", color_value="green")
647
654
  ```
648
655
 
649
- Of course, the colour can be specified in a peek.toml file, to make all peek output in a specified color.
656
+ will result in:
657
+
658
+ <img src="https://www.salabim.org/peek/peek_colors.png">
659
+
660
+ Of course, color and color_value may be specified in a peek.toml file, to make all peek output in a specified color.
650
661
 
651
662
  > [!NOTE]
652
663
  >
653
- > The color attribute is only applied when using stdout as output.
664
+ > The color and color_value attributes are only applied when using stdout as output.
654
665
 
655
666
  ## compact / c
656
667
  This attribute is used to specify the compact parameter for `pformat` (see the pprint documentation
@@ -1006,22 +1017,6 @@ peek("warning", level=2)
1006
1017
 
1007
1018
  With `peek.show_level()` the program may select which level(s) to show or not.
1008
1019
 
1009
- This is done with a string that specifies which level(s) to show. The string consist of one or more specifiers seperated by a `,`.
1010
- Each specifier may be simple value or a pair of values, separated by a `-` .
1011
- Valid strings are
1012
-
1013
- * `peek.show_level("0")` ==> 0
1014
-
1015
- * `peek.show_level("0, 1, 2")` ==> 0, 1, 2
1016
-
1017
- * `peek.show_level("1-3")` ==> 1, 2, 3
1018
-
1019
- * `peek.show_level("1-")` ==> 1, 2, 3, 4, ...
1020
-
1021
- * `peek.show_level("-2")` ==> 0, 1, 2
1022
-
1023
- * `peek.show_level("-")` ==> 0, 1, 2, 3, ... (this is the default)
1024
-
1025
1020
  Notice that a level matches if any of the specifiers conditions is met.
1026
1021
 
1027
1022
  `peek.show_level("")` disables peek output completely.
@@ -1045,16 +1040,63 @@ peek0 = peek.fork(color="red", level=0)
1045
1040
  peek1 = peek.fork(color="yellow", level=1)
1046
1041
  peek2 = peek.fork(color="green", level=2)
1047
1042
  ```
1043
+
1048
1044
  If level of a peek statement is the null string, peek will never print. That can be useful to disable peek debug info on a per peek instance basis, e.g.:
1049
1045
 
1050
1046
  ```peek_cond = peek.new()
1051
- peek_connd = peek.new()
1047
+ peek_cond = peek.new()
1052
1048
  peek_cond(1)
1053
1049
  peek_cond.level = ""
1054
1050
  peek_cond(2)
1055
1051
  ```
1052
+
1056
1053
  This will print only 1.
1057
1054
 
1055
+ The most easy form for `peek.show_level` is just a simple value as argument, like `peek.show.level(2)`, which will make only level 2 peeks to work.
1056
+
1057
+ `peek.show_level` can have a number (usually 1) of arguments.
1058
+
1059
+ Each parameter may be:
1060
+
1061
+ * a float value or
1062
+
1063
+ - a string with the format *from* - *to*
1064
+ , where both *from* and *to* are optional. If *from* is omitted, -1E30 is assumed. If *to* is omitted, 1E30 is assumed.
1065
+ Negative values have to be parenthesized.
1066
+
1067
+ Examples:
1068
+
1069
+ - `peek.show_level (1)` ==> show level 1
1070
+ - `peek.show_level (1, -3)` ==> show level 1 and level -3
1071
+ - `peek.show_level ("1-2")` ==> show level between 1 and 2
1072
+ - `peek.show_level("-")` ==> show all levels
1073
+ - `peek.show_level("")` ==> show no levels
1074
+ - `peek.show_level("1-")`==> show all levels >= 1
1075
+ - `peek.show_level("-10.2")`==> show all levels <=10.2
1076
+ - `peek.show_level(1, 2, "5-7", "10-")` ==> show levels 1, 2, between 5 and 7 (inclusive) and >= 10
1077
+ - `peek.show_level((-3)-3")` ==> show levels between -3 and 3 (inclusive)
1078
+ - `peek.show_level()` ==> returns the current show_level
1079
+
1080
+ `show_level` can also be called with a minimum and/or a maximum value, e.g.
1081
+
1082
+ - `peek.show_level(min=1)` ==> show all levels >= 1
1083
+ - `peek.show_level(max=10.2)` ==> show all levels <= 10.2
1084
+ - `peek.show_level(min=1, max=10)` ==> show all levels between 1 and 10 (inclusive)
1085
+
1086
+ Note that min or max cannot be combined with a specifier as above
1087
+
1088
+ `show_level` can also be used as a context managerl:
1089
+
1090
+ ```
1091
+ with peek.show_level(1):
1092
+ peek(1, level=1)
1093
+ peek(2, level=2)
1094
+ ```
1095
+
1096
+ This will print one line with`1` only.
1097
+
1098
+
1099
+
1058
1100
  # Interpreting the line number information
1059
1101
 
1060
1102
  When `show_line_number` is True or peek() is used without any parameters, the output will contain the line number like:
@@ -8,7 +8,7 @@ authors = [
8
8
  {name = "Ruud van der Ham", email = "rt.van.der.ham@gmail.com"}
9
9
  ]
10
10
  description = "peek - debugging and benchmarking made easy"
11
- version = "1.7.0"
11
+ version = "1.8.0-0"
12
12
  readme = "README.md"
13
13
  requires-python = ">=3.6"
14
14
  dependencies = ["colorama","six","executing","asttokens","tomli"]
@@ -336,11 +336,6 @@ lines=
336
336
  def test_decorator(capsys):
337
337
  peek.fix_perf_counter(0)
338
338
 
339
- with pytest.raises(TypeError):
340
-
341
- @peek
342
- def mul(x, y):
343
- return x * y
344
339
 
345
340
  @peek()
346
341
  def div(x, y):
@@ -718,16 +713,18 @@ def test_enabled2(capsys):
718
713
 
719
714
  def test_level(capsys):
720
715
  def peeks(show_level):
721
- peek.show_level=show_level
722
- peek(0,peek.show_level,level=0)
723
- peek(2,peek.show_level,level=2)
724
- peek(4,peek.show_level,l=4)
716
+ peek.show_level(show_level)
717
+ peek(-1,peek.show_level(),level=-1)
718
+ peek(0,peek.show_level(),level=0)
719
+ peek(2,peek.show_level(),level=2)
720
+ peek(4,peek.show_level(),l=4)
725
721
 
726
- assert peek.level==0
727
- peeks("-")
728
722
  peeks("2")
729
- peeks("2,3")
730
- peeks("-0,2-")
723
+ peeks((2,3))
724
+ peeks(("-0","2-"))
725
+ peeks("(-2)")
726
+ peeks("(-2)-")
727
+ peeks("(-2)-(-1)")
731
728
  peeks(" 4 ")
732
729
  peeks(" -2 ")
733
730
  peeks(" ")
@@ -736,38 +733,66 @@ def test_level(capsys):
736
733
  peek.level=0
737
734
  peek(0)
738
735
  peek(0,level="")
736
+
737
+ def peeks1(min=None,max=None):
738
+ peek.show_level(min=min,max=max)
739
+ peek(-1,peek.show_level(),level=-1)
740
+ peek(0,peek.show_level(),level=0)
741
+ peek(2,peek.show_level(),level=2)
742
+ peek(4,peek.show_level(),l=4)
743
+
744
+ peeks1(max=0)
745
+ peeks1(min=0)
746
+ peeks1(min=0,max=2)
739
747
 
740
748
  out, err = capsys.readouterr()
741
749
  assert out=="""\
742
- 0, peek.show_level='-'
743
- 2, peek.show_level='-'
744
- 4, peek.show_level='-'
745
- 2, peek.show_level='2'
746
- 2, peek.show_level='2,3'
747
- 0, peek.show_level='-0,2-'
748
- 2, peek.show_level='-0,2-'
749
- 4, peek.show_level='-0,2-'
750
- 4, peek.show_level=' 4 '
751
- 0, peek.show_level=' -2 '
752
- 2, peek.show_level=' -2 '
753
- 0, peek.show_level='-5'
754
- 2, peek.show_level='-5'
755
- 4, peek.show_level='-5'
756
- 0, peek.show_level=0
750
+ 2, peek.show_level()='2'
751
+ 2, peek.show_level()=(2, 3)
752
+ -1, peek.show_level()=('-0', '2-')
753
+ 0, peek.show_level()=('-0', '2-')
754
+ 2, peek.show_level()=('-0', '2-')
755
+ 4, peek.show_level()=('-0', '2-')
756
+ -1, peek.show_level()='(-2)-'
757
+ 0, peek.show_level()='(-2)-'
758
+ 2, peek.show_level()='(-2)-'
759
+ 4, peek.show_level()='(-2)-'
760
+ -1, peek.show_level()='(-2)-(-1)'
761
+ 4, peek.show_level()=' 4 '
762
+ -1, peek.show_level()=' -2 '
763
+ 0, peek.show_level()=' -2 '
764
+ 2, peek.show_level()=' -2 '
765
+ -1, peek.show_level()='-5'
766
+ 0, peek.show_level()='-5'
767
+ 2, peek.show_level()='-5'
768
+ 4, peek.show_level()='-5'
769
+ 0, peek.show_level()=0
757
770
  0
771
+ -1, peek.show_level()='-0'
772
+ 0, peek.show_level()='-0'
773
+ 0, peek.show_level()='0-'
774
+ 2, peek.show_level()='0-'
775
+ 4, peek.show_level()='0-'
776
+ 0, peek.show_level()='0-2'
777
+ 2, peek.show_level()='0-2'
758
778
  """
759
779
  with pytest.raises(ValueError):
760
780
  peek.level="a"
761
781
  with pytest.raises(ValueError):
762
- peek.show_level="a"
763
- with pytest.raises(ValueError):
764
- peek.show_level=(1,2)
782
+ peek.show_level("a")
765
783
  peek.level=0
766
784
  x=peek("a", level=0, as_str=True)
767
785
  y=peek("a", enabled=False, as_str=True)
768
786
  assert x=="'a'\n"
769
787
  assert y== ""
770
788
 
789
+ with pytest.raises(ValueError):
790
+ peek.show_level(1,min=2)
791
+ with pytest.raises(ValueError):
792
+ peek.show_level(1,max=3)
793
+ with pytest.raises(ValueError):
794
+ peek.show_level(1,min=2,max=0)
795
+
771
796
 
772
797
  def test_multiple_as():
773
798
  with pytest.raises(TypeError):
File without changes