dcicutils 8.8.3.1b4__py3-none-any.whl → 8.8.3.1b5__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.
- dcicutils/misc_utils.py +23 -0
- dcicutils/progress_bar.py +22 -3
- {dcicutils-8.8.3.1b4.dist-info → dcicutils-8.8.3.1b5.dist-info}/METADATA +1 -1
- {dcicutils-8.8.3.1b4.dist-info → dcicutils-8.8.3.1b5.dist-info}/RECORD +7 -7
- {dcicutils-8.8.3.1b4.dist-info → dcicutils-8.8.3.1b5.dist-info}/LICENSE.txt +0 -0
- {dcicutils-8.8.3.1b4.dist-info → dcicutils-8.8.3.1b5.dist-info}/WHEEL +0 -0
- {dcicutils-8.8.3.1b4.dist-info → dcicutils-8.8.3.1b5.dist-info}/entry_points.txt +0 -0
dcicutils/misc_utils.py
CHANGED
@@ -2548,6 +2548,29 @@ def normalize_spaces(value: str) -> str:
|
|
2548
2548
|
return re.sub(r"\s+", " ", value).strip()
|
2549
2549
|
|
2550
2550
|
|
2551
|
+
def find_nth_from_end(string: str, substring: str, nth: int) -> int:
|
2552
|
+
"""
|
2553
|
+
Returns the index of the nth occurrence of the given substring within
|
2554
|
+
the given string from the END of the given string; or -1 if not found.
|
2555
|
+
"""
|
2556
|
+
index = -1
|
2557
|
+
string = string[::-1]
|
2558
|
+
for i in range(0, nth):
|
2559
|
+
index = string.find(substring, index + 1)
|
2560
|
+
return len(string) - index - 1 if index >= 0 else -1
|
2561
|
+
|
2562
|
+
|
2563
|
+
def set_nth(string: str, nth: int, replacement: str) -> str:
|
2564
|
+
"""
|
2565
|
+
Sets the nth character of the given string to the given replacement string.
|
2566
|
+
"""
|
2567
|
+
if not isinstance(string, str) or not isinstance(nth, int) or not isinstance(replacement, str):
|
2568
|
+
return string
|
2569
|
+
if nth < 0:
|
2570
|
+
nth += len(string)
|
2571
|
+
return string[:nth] + replacement + string[nth + 1:] if 0 <= nth < len(string) else string
|
2572
|
+
|
2573
|
+
|
2551
2574
|
class JsonLinesReader:
|
2552
2575
|
|
2553
2576
|
def __init__(self, fp, padded=False, padding=None):
|
dcicutils/progress_bar.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
from collections import namedtuple
|
2
|
+
import re
|
2
3
|
from signal import signal, SIGINT
|
3
4
|
import sys
|
4
5
|
import threading
|
@@ -8,6 +9,7 @@ from types import FrameType as frame
|
|
8
9
|
from typing import Callable, List, Optional, Union
|
9
10
|
from contextlib import contextmanager
|
10
11
|
from dcicutils.command_utils import yes_or_no
|
12
|
+
from dcicutils.misc_utils import find_nth_from_end, set_nth
|
11
13
|
|
12
14
|
|
13
15
|
class TQDM(tqdm):
|
@@ -281,7 +283,7 @@ class ProgressBar:
|
|
281
283
|
# looks like it is from tqdm and we are disabled/done then do no output.
|
282
284
|
return
|
283
285
|
if sentinel_internal in text:
|
284
|
-
spinc = spina[spini % spinn] if not ("100%|" in text) else "
|
286
|
+
spinc = spina[spini % spinn] if not ("100%|" in text) else "✓" ; spini += 1 # noqa
|
285
287
|
text = replace_first(text, sentinel_internal, f" {spinc}")
|
286
288
|
text = replace_first(text, "%|", "% ◀|")
|
287
289
|
text = remove_extra_trailing_spaces(text)
|
@@ -290,9 +292,26 @@ class ProgressBar:
|
|
290
292
|
# the unit we gave, which is empty; idunno; just replace it here.
|
291
293
|
text = replace_first(text, "s/ ", "/s ")
|
292
294
|
sys_stdout_write(text)
|
293
|
-
if self._captured_output_for_testing is not None:
|
294
|
-
self._captured_output_for_testing.append(text)
|
295
295
|
sys.stdout.flush()
|
296
|
+
if self._captured_output_for_testing is not None:
|
297
|
+
# For testing only we replace vacilliting values in the out like rate,
|
298
|
+
# time elapsed, and ETA with static values; so that something like this:
|
299
|
+
# > Working / 20% ◀|█████████▌ | 1/5 | 536.00/s | 00:01 | ETA: 00:02
|
300
|
+
# becomes something more static like this after calling this function:
|
301
|
+
# > Working | 20% ◀|### | 1/5 | 0.0/s | 00:00 | ETA: 00:00
|
302
|
+
# This function obviously has intimate knowledge of the output; better here than in tests.
|
303
|
+
def replace_vacillating_values_with_static(text: str) -> str:
|
304
|
+
blocks = "\u2587|\u2588|\u2589|\u258a|\u258b|\u258c|\u258d|\u258e|\u258f"
|
305
|
+
if (n := find_nth_from_end(text, "|", 5)) >= 8:
|
306
|
+
pattern = re.compile(
|
307
|
+
rf"(\s*)(\d*%? ◀\|)(?:\s*{blocks}|#)*\s*(\|\s*\d+/\d+)?(\s*\|\s*)"
|
308
|
+
rf"(?:\d+\.?\d*|\?)(\/s\s*\|\s*)(?:\d+:\d+)?(\s*\|\s*ETA:\s*)(?:\d+:\d+|\?)?")
|
309
|
+
if match := pattern.match(text[n - 6:]):
|
310
|
+
if text[n - 8:n - 7] != "✓": text = set_nth(text, n - 8, "|") # noqa
|
311
|
+
return (text[0:n - 6].replace("\r", "") +
|
312
|
+
match.expand(rf"\g<1>\g<2>### \g<3>\g<4>0.0\g<5>00:00\g<6>00:00"))
|
313
|
+
return text
|
314
|
+
self._captured_output_for_testing.append(replace_vacillating_values_with_static(text))
|
296
315
|
def restore_stdout_write() -> None: # noqa
|
297
316
|
nonlocal sys_stdout_write
|
298
317
|
if sys_stdout_write is not None:
|
@@ -43,12 +43,12 @@ dcicutils/license_policies/park-lab-gpl-pipeline.jsonc,sha256=vLZkwm3Js-kjV44nug
|
|
43
43
|
dcicutils/license_policies/park-lab-pipeline.jsonc,sha256=9qlY0ASy3iUMQlr3gorVcXrSfRHnVGbLhkS427UaRy4,283
|
44
44
|
dcicutils/license_utils.py,sha256=d1cq6iwv5Ju-VjdoINi6q7CPNNL7Oz6rcJdLMY38RX0,46978
|
45
45
|
dcicutils/log_utils.py,sha256=7pWMc6vyrorUZQf-V-M3YC6zrPgNhuV_fzm9xqTPph0,10883
|
46
|
-
dcicutils/misc_utils.py,sha256=
|
46
|
+
dcicutils/misc_utils.py,sha256=a_grjJdiYgEMctwnXy7uDoFtDvCfAv1gjrLxdrOkptM,103041
|
47
47
|
dcicutils/obfuscation_utils.py,sha256=fo2jOmDRC6xWpYX49u80bVNisqRRoPskFNX3ymFAmjw,5963
|
48
48
|
dcicutils/opensearch_utils.py,sha256=V2exmFYW8Xl2_pGFixF4I2Cc549Opwe4PhFi5twC0M8,1017
|
49
49
|
dcicutils/portal_object_utils.py,sha256=gDXRgPsRvqCFwbC8WatsuflAxNiigOnqr0Hi93k3AgE,15422
|
50
50
|
dcicutils/portal_utils.py,sha256=Xm0IqL2dA9C2gx98cPEbvlo81V76bEmpUpxb_8S3VqM,30480
|
51
|
-
dcicutils/progress_bar.py,sha256=
|
51
|
+
dcicutils/progress_bar.py,sha256=BWd-a1Og7SL_FNtIQv8gAkGYMyp6VgwIwTlLClsl-8g,15988
|
52
52
|
dcicutils/project_utils.py,sha256=qPdCaFmWUVBJw4rw342iUytwdQC0P-XKpK4mhyIulMM,31250
|
53
53
|
dcicutils/qa_checkers.py,sha256=cdXjeL0jCDFDLT8VR8Px78aS10hwNISOO5G_Zv2TZ6M,20534
|
54
54
|
dcicutils/qa_utils.py,sha256=TT0SiJWiuxYvbsIyhK9VO4uV_suxhB6CpuC4qPacCzQ,160208
|
@@ -72,8 +72,8 @@ dcicutils/trace_utils.py,sha256=g8kwV4ebEy5kXW6oOrEAUsurBcCROvwtZqz9fczsGRE,1769
|
|
72
72
|
dcicutils/validation_utils.py,sha256=cMZIU2cY98FYtzK52z5WUYck7urH6JcqOuz9jkXpqzg,14797
|
73
73
|
dcicutils/variant_utils.py,sha256=2H9azNx3xAj-MySg-uZ2SFqbWs4kZvf61JnK6b-h4Qw,4343
|
74
74
|
dcicutils/zip_utils.py,sha256=rnjNv_k6L9jT2SjDSgVXp4BEJYLtz9XN6Cl2Fy-tqnM,2027
|
75
|
-
dcicutils-8.8.3.
|
76
|
-
dcicutils-8.8.3.
|
77
|
-
dcicutils-8.8.3.
|
78
|
-
dcicutils-8.8.3.
|
79
|
-
dcicutils-8.8.3.
|
75
|
+
dcicutils-8.8.3.1b5.dist-info/LICENSE.txt,sha256=qnwSmfnEWMl5l78VPDEzAmEbLVrRqQvfUQiHT0ehrOo,1102
|
76
|
+
dcicutils-8.8.3.1b5.dist-info/METADATA,sha256=Z9Not6bJDezXyZb3afrGADA6mRDuOd2QbETxSbht6DM,3356
|
77
|
+
dcicutils-8.8.3.1b5.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
|
78
|
+
dcicutils-8.8.3.1b5.dist-info/entry_points.txt,sha256=51Q4F_2V10L0282W7HFjP4jdzW4K8lnWDARJQVFy_hw,270
|
79
|
+
dcicutils-8.8.3.1b5.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|