dcicutils 8.13.3.1b13__py3-none-any.whl → 8.13.3.1b16__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 CHANGED
@@ -3,6 +3,7 @@ This file contains functions that might be generally useful.
3
3
  """
4
4
 
5
5
  from collections import namedtuple
6
+ from collections.abc import Iterable
6
7
  import appdirs
7
8
  from copy import deepcopy
8
9
  import concurrent.futures
@@ -997,6 +998,94 @@ def to_integer(value: str, fallback: Optional[Any] = None, strict: bool = False)
997
998
  return fallback
998
999
 
999
1000
 
1001
+ _MULTIPLIER_K = 1000
1002
+ _MULTIPLIER_M = 1000 * _MULTIPLIER_K
1003
+ _MULTIPLIER_G = 1000 * _MULTIPLIER_M
1004
+ _MULTIPLIER_T = 1000 * _MULTIPLIER_G
1005
+
1006
+ _MULTIPLIER_SUFFIXES = {
1007
+ "K": _MULTIPLIER_K,
1008
+ "Kb": _MULTIPLIER_K,
1009
+ "KB": _MULTIPLIER_K,
1010
+ "M": _MULTIPLIER_M,
1011
+ "Mb": _MULTIPLIER_M,
1012
+ "MB": _MULTIPLIER_M,
1013
+ "G": _MULTIPLIER_G,
1014
+ "Gb": _MULTIPLIER_G,
1015
+ "GB": _MULTIPLIER_G,
1016
+ "T": _MULTIPLIER_T,
1017
+ "Tb": _MULTIPLIER_T,
1018
+ "TB": _MULTIPLIER_T
1019
+ }
1020
+
1021
+
1022
+ def to_number(value: str,
1023
+ allow_commas: bool = False,
1024
+ allow_suffix: bool = False,
1025
+ allow_float: bool = False) -> Optional[Union[int, float]]:
1026
+
1027
+ """
1028
+ Converts the give string value to an int, or possibly float if allow_float is True.
1029
+ If allow_commas is True (default: False) then allow commas (only) every three digits.
1030
+ If allow_suffix is True (default: False) allow any of K, Kb, KB; or M, Mb, MB; or
1031
+ G, Gb, or GB; or T, Tb, TB, to mean multiply value by one thousand; one million;
1032
+ one billion; or one trillion; respectively. If allow_float is True (default: False)
1033
+ allow the value to be floating point (i.e. with a decimal point and a fractional part),
1034
+ in which case the returned value will be of type float rather than int.
1035
+ If the string is not well formated then returns None.
1036
+ """
1037
+ if not (isinstance(value, str) and (value := value.strip())):
1038
+ return value if isinstance(value, (int, float)) else None
1039
+
1040
+ value_multiplier = 1
1041
+ value_negative = False
1042
+ value_fraction = None
1043
+
1044
+ if value.startswith("-"):
1045
+ if not (value := value[1:].strip()):
1046
+ return None
1047
+ value_negative = True
1048
+ elif value.startswith("+"):
1049
+ if not (value := value[1:].strip()):
1050
+ return None
1051
+
1052
+ if allow_suffix is True:
1053
+ for suffix in _MULTIPLIER_SUFFIXES:
1054
+ if value.endswith(suffix):
1055
+ value_multiplier *= _MULTIPLIER_SUFFIXES[suffix]
1056
+ if not (value := value[:-len(suffix)].strip()):
1057
+ return None
1058
+ break
1059
+
1060
+ if allow_float is True:
1061
+ if dot_index := value.rindex("."):
1062
+ if value_fraction := value[dot_index + 1:].strip():
1063
+ try:
1064
+ value_fraction = float(f"0.{value_fraction}")
1065
+ except Exception:
1066
+ return None
1067
+ value = value[:dot_index].strip()
1068
+ pass
1069
+
1070
+ if allow_commas is True:
1071
+ if not re.fullmatch(r"(-?\d{1,3}(,\d{3})*)", value):
1072
+ return None
1073
+ value = value.replace(",", "")
1074
+
1075
+ if not value.isdigit():
1076
+ return None
1077
+
1078
+ result = int(value) * value_multiplier
1079
+
1080
+ if value_fraction:
1081
+ result += value_fraction
1082
+
1083
+ if value_negative:
1084
+ result = -result
1085
+
1086
+ return result
1087
+
1088
+
1000
1089
  def to_float(value: str, fallback: Optional[Any] = None) -> Optional[Any]:
1001
1090
  try:
1002
1091
  return float(value)
@@ -2782,6 +2871,6 @@ def create_short_uuid(length: Optional[int] = None, upper: bool = False):
2782
2871
  return value
2783
2872
 
2784
2873
 
2785
- def run_concurrently(functions: List[Callable], nthreads: int = 4) -> None:
2874
+ def run_concurrently(functions: Iterable[Callable], nthreads: int = 4) -> None:
2786
2875
  with concurrent.futures.ThreadPoolExecutor(max_workers=nthreads) as executor:
2787
- [_ for _ in concurrent.futures.as_completed([executor.submit(f) for f in functions])]
2876
+ concurrent.futures.as_completed([executor.submit(f) for f in functions])
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dcicutils
3
- Version: 8.13.3.1b13
3
+ Version: 8.13.3.1b16
4
4
  Summary: Utility package for interacting with the 4DN Data Portal and other 4DN resources
5
5
  Home-page: https://github.com/4dn-dcic/utils
6
6
  License: MIT
@@ -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=p4MagJymETX_j4h-jx4IjjVb_dYHekWopfUK8ytw2Xs,109772
48
+ dcicutils/misc_utils.py,sha256=6BM6V6ZVtVARpfvv8zEgymNlxLzW8z-qIS99D_z94no,112580
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.1b13.dist-info/LICENSE.txt,sha256=qnwSmfnEWMl5l78VPDEzAmEbLVrRqQvfUQiHT0ehrOo,1102
79
- dcicutils-8.13.3.1b13.dist-info/METADATA,sha256=on2VP4DUbgF3RJTd79fbyg7hWNtcXU-R09K8jTmg_v4,3440
80
- dcicutils-8.13.3.1b13.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
81
- dcicutils-8.13.3.1b13.dist-info/entry_points.txt,sha256=W6kEWdUJk9tQ4myAgpehPdebcwvCAZ7UgB-wyPgDUMg,335
82
- dcicutils-8.13.3.1b13.dist-info/RECORD,,
78
+ dcicutils-8.13.3.1b16.dist-info/LICENSE.txt,sha256=qnwSmfnEWMl5l78VPDEzAmEbLVrRqQvfUQiHT0ehrOo,1102
79
+ dcicutils-8.13.3.1b16.dist-info/METADATA,sha256=shc6O7nqhx1QAchJHbpNdQdeCNyO5-lDqGz6c9W9UqE,3440
80
+ dcicutils-8.13.3.1b16.dist-info/WHEEL,sha256=7Z8_27uaHI_UZAc4Uox4PpBhQ9Y5_modZXWMxtUi4NU,88
81
+ dcicutils-8.13.3.1b16.dist-info/entry_points.txt,sha256=W6kEWdUJk9tQ4myAgpehPdebcwvCAZ7UgB-wyPgDUMg,335
82
+ dcicutils-8.13.3.1b16.dist-info/RECORD,,