dcicutils 8.13.3.1b12__py3-none-any.whl → 8.13.3.1b15__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 +94 -0
- {dcicutils-8.13.3.1b12.dist-info → dcicutils-8.13.3.1b15.dist-info}/METADATA +1 -1
- {dcicutils-8.13.3.1b12.dist-info → dcicutils-8.13.3.1b15.dist-info}/RECORD +6 -6
- {dcicutils-8.13.3.1b12.dist-info → dcicutils-8.13.3.1b15.dist-info}/LICENSE.txt +0 -0
- {dcicutils-8.13.3.1b12.dist-info → dcicutils-8.13.3.1b15.dist-info}/WHEEL +0 -0
- {dcicutils-8.13.3.1b12.dist-info → dcicutils-8.13.3.1b15.dist-info}/entry_points.txt +0 -0
dcicutils/misc_utils.py
CHANGED
@@ -5,6 +5,7 @@ This file contains functions that might be generally useful.
|
|
5
5
|
from collections import namedtuple
|
6
6
|
import appdirs
|
7
7
|
from copy import deepcopy
|
8
|
+
import concurrent.futures
|
8
9
|
import contextlib
|
9
10
|
import datetime
|
10
11
|
import functools
|
@@ -996,6 +997,94 @@ def to_integer(value: str, fallback: Optional[Any] = None, strict: bool = False)
|
|
996
997
|
return fallback
|
997
998
|
|
998
999
|
|
1000
|
+
_MULTIPLIER_K = 1000
|
1001
|
+
_MULTIPLIER_M = 1000 * _MULTIPLIER_K
|
1002
|
+
_MULTIPLIER_G = 1000 * _MULTIPLIER_M
|
1003
|
+
_MULTIPLIER_T = 1000 * _MULTIPLIER_G
|
1004
|
+
|
1005
|
+
_MULTIPLIER_SUFFIXES = {
|
1006
|
+
"K": _MULTIPLIER_K,
|
1007
|
+
"Kb": _MULTIPLIER_K,
|
1008
|
+
"KB": _MULTIPLIER_K,
|
1009
|
+
"M": _MULTIPLIER_M,
|
1010
|
+
"Mb": _MULTIPLIER_M,
|
1011
|
+
"MB": _MULTIPLIER_M,
|
1012
|
+
"G": _MULTIPLIER_G,
|
1013
|
+
"Gb": _MULTIPLIER_G,
|
1014
|
+
"GB": _MULTIPLIER_G,
|
1015
|
+
"T": _MULTIPLIER_T,
|
1016
|
+
"Tb": _MULTIPLIER_T,
|
1017
|
+
"TB": _MULTIPLIER_T
|
1018
|
+
}
|
1019
|
+
|
1020
|
+
|
1021
|
+
def to_number(value: str,
|
1022
|
+
allow_commas: bool = False,
|
1023
|
+
allow_suffix: bool = False,
|
1024
|
+
allow_float: bool = False) -> Optional[Union[int, float]]:
|
1025
|
+
|
1026
|
+
"""
|
1027
|
+
Converts the give string value to an int, or possibly float if allow_float is True.
|
1028
|
+
If allow_commas is True (default: False) then allow commas (only) every three digits.
|
1029
|
+
If allow_suffix is True (default: False) allow any of K, Kb, KB; or M, Mb, MB; or
|
1030
|
+
G, Gb, or GB; or T, Tb, TB, to mean multiply value by one thousand; one million;
|
1031
|
+
one billion; or one trillion; respectively. If allow_float is True (default: False)
|
1032
|
+
allow the value to be floating point (i.e. with a decimal point and a fractional part),
|
1033
|
+
in which case the returned value will be of type float rather than int.
|
1034
|
+
If the string is not well formated then returns None.
|
1035
|
+
"""
|
1036
|
+
if not (isinstance(value, str) and (value := value.strip())):
|
1037
|
+
return value if isinstance(value, (int, float)) else None
|
1038
|
+
|
1039
|
+
value_multiplier = 1
|
1040
|
+
value_negative = False
|
1041
|
+
value_fraction = None
|
1042
|
+
|
1043
|
+
if value.startswith("-"):
|
1044
|
+
if not (value := value[1:].strip()):
|
1045
|
+
return None
|
1046
|
+
value_negative = True
|
1047
|
+
elif value.startswith("+"):
|
1048
|
+
if not (value := value[1:].strip()):
|
1049
|
+
return None
|
1050
|
+
|
1051
|
+
if allow_suffix is True:
|
1052
|
+
for suffix in _MULTIPLIER_SUFFIXES:
|
1053
|
+
if value.endswith(suffix):
|
1054
|
+
value_multiplier *= _MULTIPLIER_SUFFIXES[suffix]
|
1055
|
+
if not (value := value[:-len(suffix)].strip()):
|
1056
|
+
return None
|
1057
|
+
break
|
1058
|
+
|
1059
|
+
if allow_float is True:
|
1060
|
+
if dot_index := value.rindex("."):
|
1061
|
+
if value_fraction := value[dot_index + 1:].strip():
|
1062
|
+
try:
|
1063
|
+
value_fraction = float(f"0.{value_fraction}")
|
1064
|
+
except Exception:
|
1065
|
+
return None
|
1066
|
+
value = value[:dot_index].strip()
|
1067
|
+
pass
|
1068
|
+
|
1069
|
+
if allow_commas is True:
|
1070
|
+
if not re.fullmatch(r"(-?\d{1,3}(,\d{3})*)", value):
|
1071
|
+
return None
|
1072
|
+
value = value.replace(",", "")
|
1073
|
+
|
1074
|
+
if not value.isdigit():
|
1075
|
+
return None
|
1076
|
+
|
1077
|
+
result = int(value) * value_multiplier
|
1078
|
+
|
1079
|
+
if value_fraction:
|
1080
|
+
result += value_fraction
|
1081
|
+
|
1082
|
+
if value_negative:
|
1083
|
+
result = -result
|
1084
|
+
|
1085
|
+
return result
|
1086
|
+
|
1087
|
+
|
999
1088
|
def to_float(value: str, fallback: Optional[Any] = None) -> Optional[Any]:
|
1000
1089
|
try:
|
1001
1090
|
return float(value)
|
@@ -2779,3 +2868,8 @@ def create_short_uuid(length: Optional[int] = None, upper: bool = False):
|
|
2779
2868
|
if upper is True:
|
2780
2869
|
value = value.upper()
|
2781
2870
|
return value
|
2871
|
+
|
2872
|
+
|
2873
|
+
def run_concurrently(functions: List[Callable], nthreads: int = 4) -> None:
|
2874
|
+
with concurrent.futures.ThreadPoolExecutor(max_workers=nthreads) as executor:
|
2875
|
+
[_ for _ in concurrent.futures.as_completed([executor.submit(f) for f in functions])]
|
@@ -45,7 +45,7 @@ dcicutils/license_policies/park-lab-gpl-pipeline.jsonc,sha256=vLZkwm3Js-kjV44nug
|
|
45
45
|
dcicutils/license_policies/park-lab-pipeline.jsonc,sha256=9qlY0ASy3iUMQlr3gorVcXrSfRHnVGbLhkS427UaRy4,283
|
46
46
|
dcicutils/license_utils.py,sha256=2Yxnh1T1iuMe6wluwbvpFO_zYSGPxB4-STAMc-vz-YM,47202
|
47
47
|
dcicutils/log_utils.py,sha256=7pWMc6vyrorUZQf-V-M3YC6zrPgNhuV_fzm9xqTPph0,10883
|
48
|
-
dcicutils/misc_utils.py,sha256=
|
48
|
+
dcicutils/misc_utils.py,sha256=CePW842RmwVNlkkIRKWl4vXbt9Eohxr8NpOz5X1XLhM,112552
|
49
49
|
dcicutils/obfuscation_utils.py,sha256=fo2jOmDRC6xWpYX49u80bVNisqRRoPskFNX3ymFAmjw,5963
|
50
50
|
dcicutils/opensearch_utils.py,sha256=V2exmFYW8Xl2_pGFixF4I2Cc549Opwe4PhFi5twC0M8,1017
|
51
51
|
dcicutils/portal_object_utils.py,sha256=Az3n1aL-PQkN5gOFE6ZqC2XkYsqiwKlq7-tZggs1QN4,11062
|
@@ -75,8 +75,8 @@ dcicutils/trace_utils.py,sha256=g8kwV4ebEy5kXW6oOrEAUsurBcCROvwtZqz9fczsGRE,1769
|
|
75
75
|
dcicutils/validation_utils.py,sha256=cMZIU2cY98FYtzK52z5WUYck7urH6JcqOuz9jkXpqzg,14797
|
76
76
|
dcicutils/variant_utils.py,sha256=2H9azNx3xAj-MySg-uZ2SFqbWs4kZvf61JnK6b-h4Qw,4343
|
77
77
|
dcicutils/zip_utils.py,sha256=_Y9EmL3D2dUZhxucxHvrtmmlbZmK4FpSsHEb7rGSJLU,3265
|
78
|
-
dcicutils-8.13.3.
|
79
|
-
dcicutils-8.13.3.
|
80
|
-
dcicutils-8.13.3.
|
81
|
-
dcicutils-8.13.3.
|
82
|
-
dcicutils-8.13.3.
|
78
|
+
dcicutils-8.13.3.1b15.dist-info/LICENSE.txt,sha256=qnwSmfnEWMl5l78VPDEzAmEbLVrRqQvfUQiHT0ehrOo,1102
|
79
|
+
dcicutils-8.13.3.1b15.dist-info/METADATA,sha256=r_RWtfslkmVCYwYL72MIApwsPYqaQzIutzsiY8hXs1o,3440
|
80
|
+
dcicutils-8.13.3.1b15.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
|
81
|
+
dcicutils-8.13.3.1b15.dist-info/entry_points.txt,sha256=W6kEWdUJk9tQ4myAgpehPdebcwvCAZ7UgB-wyPgDUMg,335
|
82
|
+
dcicutils-8.13.3.1b15.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|