encommon 0.6.0__py3-none-any.whl → 0.7.0__py3-none-any.whl
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.
- encommon/utils/__init__.py +2 -0
- encommon/utils/stdout.py +212 -0
- encommon/utils/test/test_stdout.py +151 -0
- encommon/version.txt +1 -1
- {encommon-0.6.0.dist-info → encommon-0.7.0.dist-info}/METADATA +1 -1
- {encommon-0.6.0.dist-info → encommon-0.7.0.dist-info}/RECORD +9 -9
- {encommon-0.6.0.dist-info → encommon-0.7.0.dist-info}/LICENSE +0 -0
- {encommon-0.6.0.dist-info → encommon-0.7.0.dist-info}/WHEEL +0 -0
- {encommon-0.6.0.dist-info → encommon-0.7.0.dist-info}/top_level.txt +0 -0
encommon/utils/__init__.py
CHANGED
@@ -14,6 +14,7 @@ from .paths import resolve_paths
|
|
14
14
|
from .paths import stats_path
|
15
15
|
from .sample import load_sample
|
16
16
|
from .sample import prep_sample
|
17
|
+
from .stdout import array_ansi
|
17
18
|
from .stdout import kvpair_ansi
|
18
19
|
from .stdout import make_ansi
|
19
20
|
from .stdout import print_ansi
|
@@ -22,6 +23,7 @@ from .stdout import strip_ansi
|
|
22
23
|
|
23
24
|
|
24
25
|
__all__ = [
|
26
|
+
'array_ansi',
|
25
27
|
'fuzz_match',
|
26
28
|
'kvpair_ansi',
|
27
29
|
'load_sample',
|
encommon/utils/stdout.py
CHANGED
@@ -7,11 +7,18 @@ is permitted, for more information consult the project license file.
|
|
7
7
|
|
8
8
|
|
9
9
|
|
10
|
+
from dataclasses import dataclass
|
10
11
|
from re import compile
|
11
12
|
from re import sub as re_sub
|
12
13
|
from sys import stdout
|
13
14
|
from typing import Any
|
14
15
|
from typing import Literal
|
16
|
+
from typing import Optional
|
17
|
+
from typing import Union
|
18
|
+
|
19
|
+
from encommon.times import Duration
|
20
|
+
from encommon.times import Times
|
21
|
+
from encommon.types import Empty
|
15
22
|
|
16
23
|
from .common import JOINABLE
|
17
24
|
|
@@ -20,6 +27,40 @@ from .common import JOINABLE
|
|
20
27
|
ANSICODE = compile(
|
21
28
|
r'\x1b\[[^A-Za-z]*[A-Za-z]')
|
22
29
|
|
30
|
+
ANSIARRAL = Union[
|
31
|
+
list[Any],
|
32
|
+
tuple[Any, ...],
|
33
|
+
set[Any]]
|
34
|
+
|
35
|
+
ANSIARRAD = dict[Any, Any]
|
36
|
+
|
37
|
+
ANSIARRAY = Union[
|
38
|
+
ANSIARRAL,
|
39
|
+
ANSIARRAD]
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
@dataclass(frozen=True)
|
44
|
+
class ArrayColors:
|
45
|
+
"""
|
46
|
+
Colors used to colorize the provided array like object.
|
47
|
+
"""
|
48
|
+
|
49
|
+
label: int = 37
|
50
|
+
key: int = 97
|
51
|
+
|
52
|
+
bool: int = 93
|
53
|
+
none: int = 33
|
54
|
+
str: int = 92
|
55
|
+
num: int = 93
|
56
|
+
|
57
|
+
times: int = 96
|
58
|
+
empty: int = 36
|
59
|
+
other: int = 91
|
60
|
+
|
61
|
+
colon: int = 37
|
62
|
+
hyphen: int = 37
|
63
|
+
|
23
64
|
|
24
65
|
|
25
66
|
def print_ansi(
|
@@ -121,3 +162,174 @@ def strip_ansi(
|
|
121
162
|
""" # noqa: D301 LIT102
|
122
163
|
|
123
164
|
return re_sub(ANSICODE, '', string)
|
165
|
+
|
166
|
+
|
167
|
+
|
168
|
+
def array_ansi( # noqa: CFQ001, CFQ004
|
169
|
+
source: ANSIARRAY,
|
170
|
+
*,
|
171
|
+
indent: int = 0,
|
172
|
+
colors: ArrayColors = ArrayColors(),
|
173
|
+
) -> str:
|
174
|
+
"""
|
175
|
+
Print the ANSI colorized iterable to the standard output.
|
176
|
+
|
177
|
+
.. note::
|
178
|
+
This massive function should be refactored, possibly
|
179
|
+
into a class with methods where there are functions.
|
180
|
+
|
181
|
+
:param source: Value in supported and iterable formats.
|
182
|
+
:param indent: How many levels for initial indentation.
|
183
|
+
:param colors: Determine colors used with different types.
|
184
|
+
:returns: ANSI colorized string using inline directives.
|
185
|
+
"""
|
186
|
+
|
187
|
+
output: list[str] = []
|
188
|
+
|
189
|
+
repeat = f'<c{colors.other}>REPEAT<c0>'
|
190
|
+
|
191
|
+
|
192
|
+
def _append(
|
193
|
+
prefix: str,
|
194
|
+
value: Any, # noqa: ANN401
|
195
|
+
indent: int,
|
196
|
+
refers: set[int],
|
197
|
+
) -> None:
|
198
|
+
|
199
|
+
if id(value) in refers:
|
200
|
+
return output.append(
|
201
|
+
f'{prefix} {repeat}')
|
202
|
+
|
203
|
+
refers.add(id(value))
|
204
|
+
|
205
|
+
|
206
|
+
types = {
|
207
|
+
'dict': dict,
|
208
|
+
'list': list,
|
209
|
+
'tuple': tuple,
|
210
|
+
'set': set}
|
211
|
+
|
212
|
+
for name, _type in types.items():
|
213
|
+
|
214
|
+
if not isinstance(value, _type):
|
215
|
+
continue
|
216
|
+
|
217
|
+
output.append(
|
218
|
+
f'{prefix} '
|
219
|
+
f'<c{colors.label}>{name}<c0>')
|
220
|
+
|
221
|
+
return _process(
|
222
|
+
source=value,
|
223
|
+
indent=indent + 2,
|
224
|
+
refers=refers)
|
225
|
+
|
226
|
+
|
227
|
+
value = _concrete(value)
|
228
|
+
|
229
|
+
output.append(
|
230
|
+
f'{prefix} {value}')
|
231
|
+
|
232
|
+
|
233
|
+
def _concrete(
|
234
|
+
source: Any, # noqa: ANN401
|
235
|
+
) -> str:
|
236
|
+
|
237
|
+
color = colors.other
|
238
|
+
|
239
|
+
if isinstance(source, bool):
|
240
|
+
color = colors.bool
|
241
|
+
|
242
|
+
if isinstance(source, int | float):
|
243
|
+
color = colors.num
|
244
|
+
|
245
|
+
elif isinstance(source, str):
|
246
|
+
color = colors.str
|
247
|
+
|
248
|
+
elif source is None:
|
249
|
+
color = colors.none
|
250
|
+
|
251
|
+
elif isinstance(source, Duration):
|
252
|
+
color = colors.times
|
253
|
+
|
254
|
+
elif isinstance(source, Times):
|
255
|
+
color = colors.times
|
256
|
+
|
257
|
+
elif source is Empty:
|
258
|
+
color = colors.empty
|
259
|
+
|
260
|
+
string = f'<c{color}>{source}<c0>'
|
261
|
+
|
262
|
+
if isinstance(source, str):
|
263
|
+
string = f"'{string}'"
|
264
|
+
|
265
|
+
return string
|
266
|
+
|
267
|
+
|
268
|
+
def _dict(
|
269
|
+
source: ANSIARRAD,
|
270
|
+
indent: int,
|
271
|
+
refers: Optional[set[int]] = None,
|
272
|
+
) -> None:
|
273
|
+
|
274
|
+
assert isinstance(source, dict)
|
275
|
+
|
276
|
+
for key, value in source.items():
|
277
|
+
|
278
|
+
prefix = (
|
279
|
+
f'{" " * indent}'
|
280
|
+
f'<c{colors.key}>{key}'
|
281
|
+
f'<c{colors.colon}>:<c0>')
|
282
|
+
|
283
|
+
_append(
|
284
|
+
prefix, value, indent,
|
285
|
+
refers=refers or set())
|
286
|
+
|
287
|
+
|
288
|
+
def _list(
|
289
|
+
source: ANSIARRAL,
|
290
|
+
indent: int,
|
291
|
+
refers: Optional[set[int]] = None,
|
292
|
+
) -> None:
|
293
|
+
|
294
|
+
assert isinstance(
|
295
|
+
source, (list, tuple, set))
|
296
|
+
|
297
|
+
for value in source:
|
298
|
+
|
299
|
+
prefix = (
|
300
|
+
f'{" " * indent}'
|
301
|
+
f'<c{colors.hyphen}>-<c0>')
|
302
|
+
|
303
|
+
_append(
|
304
|
+
prefix, value, indent,
|
305
|
+
refers=refers or set())
|
306
|
+
|
307
|
+
|
308
|
+
def _process(
|
309
|
+
source: ANSIARRAD | ANSIARRAL,
|
310
|
+
**kwargs: Any,
|
311
|
+
) -> None:
|
312
|
+
|
313
|
+
if isinstance(source, dict):
|
314
|
+
return _dict(source, **kwargs)
|
315
|
+
|
316
|
+
return _list(source, **kwargs)
|
317
|
+
|
318
|
+
|
319
|
+
if isinstance(source, dict):
|
320
|
+
_dict(source, indent)
|
321
|
+
|
322
|
+
elif isinstance(source, list):
|
323
|
+
_list(source, indent)
|
324
|
+
|
325
|
+
elif isinstance(source, tuple):
|
326
|
+
_list(source, indent)
|
327
|
+
|
328
|
+
elif isinstance(source, set):
|
329
|
+
_list(source, indent)
|
330
|
+
|
331
|
+
|
332
|
+
_output = [
|
333
|
+
make_ansi(x) for x in output]
|
334
|
+
|
335
|
+
return '\n'.join(_output)
|
@@ -9,10 +9,15 @@ is permitted, for more information consult the project license file.
|
|
9
9
|
|
10
10
|
from _pytest.capture import CaptureFixture
|
11
11
|
|
12
|
+
from ..stdout import array_ansi
|
12
13
|
from ..stdout import kvpair_ansi
|
13
14
|
from ..stdout import make_ansi
|
14
15
|
from ..stdout import print_ansi
|
15
16
|
from ..stdout import strip_ansi
|
17
|
+
from ...times import Duration
|
18
|
+
from ...times import Times
|
19
|
+
from ...times.common import UNIXMPOCH
|
20
|
+
from ...types import Empty
|
16
21
|
|
17
22
|
|
18
23
|
|
@@ -78,3 +83,149 @@ def test_strip_ansi() -> None:
|
|
78
83
|
output = '\x1b[0;31mtest\x1b[0;0m'
|
79
84
|
|
80
85
|
assert strip_ansi(output) == 'test'
|
86
|
+
|
87
|
+
|
88
|
+
|
89
|
+
def test_array_ansi() -> None: # noqa: CFQ001
|
90
|
+
"""
|
91
|
+
Perform various tests associated with relevant routines.
|
92
|
+
"""
|
93
|
+
|
94
|
+
simple = {
|
95
|
+
'str': 'value',
|
96
|
+
'list': [1, 2],
|
97
|
+
'bool': False}
|
98
|
+
|
99
|
+
repeat = {
|
100
|
+
'dict': simple | {
|
101
|
+
'dict': simple}}
|
102
|
+
|
103
|
+
source = {
|
104
|
+
'str': 'value',
|
105
|
+
'int': 1,
|
106
|
+
'float': 1.0,
|
107
|
+
'complex': complex(3, 1),
|
108
|
+
'list': [simple],
|
109
|
+
'tuple': (simple,),
|
110
|
+
'range': range(1, 3),
|
111
|
+
'dict1': simple,
|
112
|
+
'dict2': simple,
|
113
|
+
'dict3': simple,
|
114
|
+
'set': {1, 2, 3},
|
115
|
+
'frozenset': {1, 2, 3},
|
116
|
+
'bool': True,
|
117
|
+
'none': None,
|
118
|
+
'_private': None,
|
119
|
+
'repeat': repeat,
|
120
|
+
'Empty': Empty,
|
121
|
+
'Duration': Duration(190802),
|
122
|
+
'Times': Times(0)}
|
123
|
+
|
124
|
+
|
125
|
+
output = strip_ansi(
|
126
|
+
array_ansi(simple))
|
127
|
+
|
128
|
+
assert output == (
|
129
|
+
"str: 'value'\n"
|
130
|
+
'list: list\n'
|
131
|
+
' - 1\n'
|
132
|
+
' - 2\n'
|
133
|
+
'bool: False')
|
134
|
+
|
135
|
+
|
136
|
+
output = strip_ansi(
|
137
|
+
array_ansi([simple]))
|
138
|
+
|
139
|
+
assert output == (
|
140
|
+
'- dict\n'
|
141
|
+
" str: 'value'\n"
|
142
|
+
' list: list\n'
|
143
|
+
' - 1\n'
|
144
|
+
' - 2\n'
|
145
|
+
' bool: False')
|
146
|
+
|
147
|
+
|
148
|
+
output = strip_ansi(
|
149
|
+
array_ansi((1, 2, 3)))
|
150
|
+
|
151
|
+
assert output == (
|
152
|
+
'- 1\n'
|
153
|
+
'- 2\n'
|
154
|
+
'- 3')
|
155
|
+
|
156
|
+
|
157
|
+
output = strip_ansi(
|
158
|
+
array_ansi({1, 2, 3}))
|
159
|
+
|
160
|
+
assert output == (
|
161
|
+
'- 1\n'
|
162
|
+
'- 2\n'
|
163
|
+
'- 3')
|
164
|
+
|
165
|
+
|
166
|
+
output = strip_ansi(
|
167
|
+
array_ansi(source))
|
168
|
+
|
169
|
+
assert output == (
|
170
|
+
"str: 'value'\n"
|
171
|
+
'int: 1\n'
|
172
|
+
'float: 1.0\n'
|
173
|
+
'complex: (3+1j)\n'
|
174
|
+
'list: list\n'
|
175
|
+
' - dict\n'
|
176
|
+
" str: 'value'\n"
|
177
|
+
' list: list\n'
|
178
|
+
' - 1\n'
|
179
|
+
' - 2\n'
|
180
|
+
' bool: False\n'
|
181
|
+
'tuple: tuple\n'
|
182
|
+
' - dict\n'
|
183
|
+
" str: 'value'\n"
|
184
|
+
' list: list\n'
|
185
|
+
' - 1\n'
|
186
|
+
' - 2\n'
|
187
|
+
' bool: False\n'
|
188
|
+
'range: range(1, 3)\n'
|
189
|
+
'dict1: dict\n'
|
190
|
+
" str: 'value'\n"
|
191
|
+
' list: list\n'
|
192
|
+
' - 1\n'
|
193
|
+
' - 2\n'
|
194
|
+
' bool: False\n'
|
195
|
+
'dict2: dict\n'
|
196
|
+
" str: 'value'\n"
|
197
|
+
' list: list\n'
|
198
|
+
' - 1\n'
|
199
|
+
' - 2\n'
|
200
|
+
' bool: False\n'
|
201
|
+
'dict3: dict\n'
|
202
|
+
" str: 'value'\n"
|
203
|
+
' list: list\n'
|
204
|
+
' - 1\n'
|
205
|
+
' - 2\n'
|
206
|
+
' bool: False\n'
|
207
|
+
'set: set\n'
|
208
|
+
' - 1\n'
|
209
|
+
' - 2\n'
|
210
|
+
' - 3\n'
|
211
|
+
'frozenset: set\n'
|
212
|
+
' - 1\n'
|
213
|
+
' - 2\n'
|
214
|
+
' - 3\n'
|
215
|
+
'bool: True\n'
|
216
|
+
'none: None\n'
|
217
|
+
'_private: None\n'
|
218
|
+
'repeat: dict\n'
|
219
|
+
' dict: dict\n'
|
220
|
+
" str: 'value'\n"
|
221
|
+
' list: list\n'
|
222
|
+
' - 1\n'
|
223
|
+
' - 2\n'
|
224
|
+
' bool: False\n'
|
225
|
+
' dict: dict\n'
|
226
|
+
' str: REPEAT\n'
|
227
|
+
' list: REPEAT\n'
|
228
|
+
' bool: REPEAT\n'
|
229
|
+
'Empty: Empty\n'
|
230
|
+
'Duration: 2d5h\n'
|
231
|
+
f'Times: {UNIXMPOCH}')
|
encommon/version.txt
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.7.0
|
@@ -1,7 +1,7 @@
|
|
1
1
|
encommon/__init__.py,sha256=VoXUcphq-gcXCraaU47EtXBftF6UVuQPMGr0fuCTt9A,525
|
2
2
|
encommon/conftest.py,sha256=z5BMi6KjNuactDRgbh8J8w81V08Ptf6QK2o_bJANRs4,880
|
3
3
|
encommon/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
|
-
encommon/version.txt,sha256=
|
4
|
+
encommon/version.txt,sha256=ln2a-xATRmZxZvLnboGRC8GQSI19QdUMoAcunZLwDjI,6
|
5
5
|
encommon/config/__init__.py,sha256=2ic7tK2lOQvqWmmQnMozqxCJcbyQ_sSEHmOUDUFan2U,710
|
6
6
|
encommon/config/common.py,sha256=gaKBgkF7b7UIAhd0ESio0KpG8JfdRpz5BxNgKRptd6A,2041
|
7
7
|
encommon/config/config.py,sha256=-wIkyA6YQGAly0WuXLaOYXENjZYRYgWk_VdUN8mMe8Q,4853
|
@@ -44,19 +44,19 @@ encommon/types/test/__init__.py,sha256=PjrnBYT0efyvbaGeNx94dm3tP3EVHUHSVs-VGeLEv
|
|
44
44
|
encommon/types/test/test_dicts.py,sha256=UHMvrWKnz-bPscq0Vp2uoLLFv4slvQQL2sobe5WUZ7U,2673
|
45
45
|
encommon/types/test/test_empty.py,sha256=YUn0ROFhrWLQ30uROVqroHW4BsnFbzUZjACs3aEvrrI,981
|
46
46
|
encommon/types/test/test_strings.py,sha256=WHXf1dnK6Qs2_0UyGYztJxpS29bnR8WKjKsvVO2WCi4,407
|
47
|
-
encommon/utils/__init__.py,sha256=
|
47
|
+
encommon/utils/__init__.py,sha256=bBiDsBz8j-fHJ-P-AM4rZKqfiLNv5Q8KID8GfcvpWLA,833
|
48
48
|
encommon/utils/common.py,sha256=UrowELh3PtDzpSS48nGhsAxTS_QUk96-KEJa4MlxiMA,466
|
49
49
|
encommon/utils/match.py,sha256=4L2d2Cvr7vp3odkRCdNQ10OIW8DkEP55_NbQ6bdsReo,2462
|
50
50
|
encommon/utils/paths.py,sha256=4EeaPsVwpv3pzoHeWmiSSGYZEud6hkD27kvbvgSpOPs,3236
|
51
51
|
encommon/utils/sample.py,sha256=hOhS6A2aB9a5kXfrst7gUSQkxuqEo2J1AFyBsJZQhHE,3169
|
52
|
-
encommon/utils/stdout.py,sha256=
|
52
|
+
encommon/utils/stdout.py,sha256=pPL68iE2oGk-hE3KGZjWE1vnOF6hflaarYPVZQnefHQ,7142
|
53
53
|
encommon/utils/test/__init__.py,sha256=PjrnBYT0efyvbaGeNx94dm3tP3EVHUHSVs-VGeLEv5g,218
|
54
54
|
encommon/utils/test/test_match.py,sha256=QagKpTFdRo23-Y55fSaJrSMpt5jIebScKbz0h8tivrI,1124
|
55
55
|
encommon/utils/test/test_paths.py,sha256=0ls9gWJ2B487Dr1fHDDFCZPA7gxtv56nFEYHrTkNX-U,1892
|
56
56
|
encommon/utils/test/test_sample.py,sha256=iNV9IxXmA5KJat3jKRiZH3iutHrT6bsibwti60AhICk,1464
|
57
|
-
encommon/utils/test/test_stdout.py,sha256=
|
58
|
-
encommon-0.
|
59
|
-
encommon-0.
|
60
|
-
encommon-0.
|
61
|
-
encommon-0.
|
62
|
-
encommon-0.
|
57
|
+
encommon/utils/test/test_stdout.py,sha256=U3YD8XIfVjjh_vNxN1UJqOWyp7_OFtJVl2K5oMziPu8,4878
|
58
|
+
encommon-0.7.0.dist-info/LICENSE,sha256=otnXKCtMjPlbHs0wgZ_BWULrp3g_2dWQJ6icRk9nkgg,1071
|
59
|
+
encommon-0.7.0.dist-info/METADATA,sha256=as7cVGwmjhknmAnTKkAOi6hrVIXU07tWU0t83L4Fn_4,2671
|
60
|
+
encommon-0.7.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
61
|
+
encommon-0.7.0.dist-info/top_level.txt,sha256=bP8q7-5tLDNm-3XPlqn_bDENfYNug5801H_xfz3BEAM,9
|
62
|
+
encommon-0.7.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|