abstract-utilities 0.2.2.486__py3-none-any.whl → 0.2.2.540__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.

Potentially problematic release.


This version of abstract-utilities might be problematic. Click here for more details.

Files changed (188) hide show
  1. abstract_utilities/__init__.py +6 -10
  2. abstract_utilities/circular_import_finder.py +222 -0
  3. abstract_utilities/circular_import_finder2.py +118 -0
  4. abstract_utilities/class_utils/__init__.py +7 -0
  5. abstract_utilities/class_utils/abstract_classes.py +74 -0
  6. abstract_utilities/class_utils/caller_utils.py +35 -0
  7. abstract_utilities/class_utils/class_utils.py +109 -0
  8. abstract_utilities/class_utils/function_utils.py +153 -0
  9. abstract_utilities/class_utils/global_utils.py +56 -0
  10. abstract_utilities/class_utils/imports/__init__.py +2 -0
  11. abstract_utilities/class_utils/imports/imports.py +2 -0
  12. abstract_utilities/class_utils/imports/utils.py +40 -0
  13. abstract_utilities/class_utils/module_utils.py +63 -0
  14. abstract_utilities/directory_utils/__init__.py +2 -0
  15. abstract_utilities/directory_utils/directory_utils.py +94 -0
  16. abstract_utilities/directory_utils/imports/__init__.py +2 -0
  17. abstract_utilities/directory_utils/imports/imports.py +1 -0
  18. abstract_utilities/directory_utils/imports/module_imports.py +2 -0
  19. abstract_utilities/directory_utils/name_utils.py +43 -0
  20. abstract_utilities/directory_utils/size_utils.py +57 -0
  21. abstract_utilities/directory_utils/src/__init__.py +4 -0
  22. abstract_utilities/directory_utils/src/directory_utils.py +92 -0
  23. abstract_utilities/directory_utils/src/name_utils.py +43 -0
  24. abstract_utilities/directory_utils/src/size_utils.py +57 -0
  25. abstract_utilities/directory_utils/src/utils.py +116 -0
  26. abstract_utilities/directory_utils/utils.py +116 -0
  27. abstract_utilities/env_utils/imports/imports.py +5 -3
  28. abstract_utilities/error_utils/__init__.py +2 -0
  29. abstract_utilities/error_utils/error_utils.py +25 -0
  30. abstract_utilities/error_utils/imports/__init__.py +2 -0
  31. abstract_utilities/error_utils/imports/imports.py +1 -0
  32. abstract_utilities/error_utils/imports/module_imports.py +1 -0
  33. abstract_utilities/file_utils/__init__.py +1 -2
  34. abstract_utilities/file_utils/file_utils/type_checks.py +2 -1
  35. abstract_utilities/file_utils/imports/constants.py +84 -4
  36. abstract_utilities/file_utils/imports/imports.py +3 -18
  37. abstract_utilities/file_utils/imports/module_imports.py +2 -7
  38. abstract_utilities/file_utils/module_imports.py +12 -0
  39. abstract_utilities/file_utils/src/__init__.py +8 -0
  40. abstract_utilities/file_utils/src/file_filters.py +177 -0
  41. abstract_utilities/file_utils/src/file_reader.py +544 -0
  42. abstract_utilities/file_utils/src/file_utils.py +156 -0
  43. abstract_utilities/file_utils/src/filter_params.py +197 -0
  44. abstract_utilities/file_utils/src/find_collect.py +266 -0
  45. abstract_utilities/file_utils/src/initFunctionsGen.py +280 -0
  46. abstract_utilities/file_utils/src/map_utils.py +29 -0
  47. abstract_utilities/file_utils/src/pdf_utils.py +300 -0
  48. abstract_utilities/file_utils/src/type_checks.py +91 -0
  49. abstract_utilities/file_utils (2)/__init__.py +2 -0
  50. abstract_utilities/file_utils (2)/imports/__init__.py +2 -0
  51. abstract_utilities/file_utils (2)/imports/constants.py +118 -0
  52. abstract_utilities/file_utils (2)/imports/imports/__init__.py +3 -0
  53. abstract_utilities/file_utils (2)/imports/imports/constants.py +119 -0
  54. abstract_utilities/file_utils (2)/imports/imports/imports.py +46 -0
  55. abstract_utilities/file_utils (2)/imports/imports/module_imports.py +8 -0
  56. abstract_utilities/file_utils (2)/imports/utils/__init__.py +3 -0
  57. abstract_utilities/file_utils (2)/imports/utils/classes.py +379 -0
  58. abstract_utilities/file_utils (2)/imports/utils/clean_imps.py +155 -0
  59. abstract_utilities/file_utils (2)/imports/utils/filter_utils.py +341 -0
  60. abstract_utilities/file_utils (2)/src/__init__.py +8 -0
  61. abstract_utilities/file_utils (2)/src/file_filters.py +155 -0
  62. abstract_utilities/file_utils (2)/src/file_reader.py +604 -0
  63. abstract_utilities/file_utils (2)/src/find_collect.py +258 -0
  64. abstract_utilities/file_utils (2)/src/initFunctionsGen.py +286 -0
  65. abstract_utilities/file_utils (2)/src/map_utils.py +28 -0
  66. abstract_utilities/file_utils (2)/src/pdf_utils.py +300 -0
  67. abstract_utilities/hash_utils/__init__.py +2 -0
  68. abstract_utilities/hash_utils/hash_utils.py +5 -0
  69. abstract_utilities/hash_utils/imports/__init__.py +2 -0
  70. abstract_utilities/hash_utils/imports/imports.py +1 -0
  71. abstract_utilities/hash_utils/imports/module_imports.py +0 -0
  72. abstract_utilities/history_utils/__init__.py +2 -0
  73. abstract_utilities/history_utils/history_utils.py +37 -0
  74. abstract_utilities/history_utils/imports/__init__.py +2 -0
  75. abstract_utilities/history_utils/imports/imports.py +1 -0
  76. abstract_utilities/history_utils/imports/module_imports.py +0 -0
  77. abstract_utilities/import_utils/__init__.py +2 -0
  78. abstract_utilities/import_utils/imports/__init__.py +4 -0
  79. abstract_utilities/import_utils/imports/constants.py +2 -0
  80. abstract_utilities/import_utils/imports/imports.py +4 -0
  81. abstract_utilities/import_utils/imports/module_imports.py +6 -0
  82. abstract_utilities/import_utils/imports/utils.py +30 -0
  83. abstract_utilities/import_utils/src/__init__.py +7 -0
  84. abstract_utilities/import_utils/src/clean_imports.py +147 -0
  85. abstract_utilities/import_utils/src/dot_utils.py +69 -0
  86. abstract_utilities/import_utils/src/extract_utils.py +42 -0
  87. abstract_utilities/import_utils/src/import_functions.py +46 -0
  88. abstract_utilities/import_utils/src/import_utils.py +299 -0
  89. abstract_utilities/import_utils/src/package_utils/__init__.py +139 -0
  90. abstract_utilities/import_utils/src/package_utils/context_utils.py +27 -0
  91. abstract_utilities/import_utils/src/package_utils/import_collectors.py +53 -0
  92. abstract_utilities/import_utils/src/package_utils/path_utils.py +28 -0
  93. abstract_utilities/import_utils/src/package_utils/safe_import.py +27 -0
  94. abstract_utilities/import_utils/src/package_utils.py +140 -0
  95. abstract_utilities/import_utils/src/package_utilss/__init__.py +139 -0
  96. abstract_utilities/import_utils/src/package_utilss/context_utils.py +27 -0
  97. abstract_utilities/import_utils/src/package_utilss/import_collectors.py +53 -0
  98. abstract_utilities/import_utils/src/package_utilss/path_utils.py +28 -0
  99. abstract_utilities/import_utils/src/package_utilss/safe_import.py +27 -0
  100. abstract_utilities/import_utils/src/pkg_utils.py +140 -0
  101. abstract_utilities/import_utils/src/sysroot_utils.py +57 -0
  102. abstract_utilities/imports.py +18 -0
  103. abstract_utilities/json_utils/__init__.py +2 -0
  104. abstract_utilities/json_utils/imports/__init__.py +2 -0
  105. abstract_utilities/json_utils/imports/imports.py +2 -0
  106. abstract_utilities/json_utils/imports/module_imports.py +5 -0
  107. abstract_utilities/json_utils/json_utils.py +743 -0
  108. abstract_utilities/list_utils/__init__.py +2 -0
  109. abstract_utilities/list_utils/imports/__init__.py +2 -0
  110. abstract_utilities/list_utils/imports/imports.py +1 -0
  111. abstract_utilities/list_utils/imports/module_imports.py +0 -0
  112. abstract_utilities/list_utils/list_utils.py +199 -0
  113. abstract_utilities/log_utils/__init__.py +5 -0
  114. abstract_utilities/log_utils/abstractLogManager.py +64 -0
  115. abstract_utilities/log_utils/call_response.py +68 -0
  116. abstract_utilities/log_utils/imports/__init__.py +2 -0
  117. abstract_utilities/log_utils/imports/imports.py +7 -0
  118. abstract_utilities/log_utils/imports/module_imports.py +2 -0
  119. abstract_utilities/log_utils/log_file.py +58 -0
  120. abstract_utilities/log_utils/logger_callable.py +49 -0
  121. abstract_utilities/math_utils/__init__.py +2 -0
  122. abstract_utilities/math_utils/imports/__init__.py +2 -0
  123. abstract_utilities/math_utils/imports/imports.py +2 -0
  124. abstract_utilities/math_utils/imports/module_imports.py +1 -0
  125. abstract_utilities/math_utils/math_utils.py +208 -0
  126. abstract_utilities/parse_utils/__init__.py +2 -0
  127. abstract_utilities/parse_utils/imports/__init__.py +3 -0
  128. abstract_utilities/parse_utils/imports/constants.py +10 -0
  129. abstract_utilities/parse_utils/imports/imports.py +2 -0
  130. abstract_utilities/parse_utils/imports/module_imports.py +4 -0
  131. abstract_utilities/parse_utils/parse_utils.py +516 -0
  132. abstract_utilities/path_utils/__init__.py +2 -0
  133. abstract_utilities/path_utils/imports/__init__.py +3 -0
  134. abstract_utilities/path_utils/imports/imports.py +1 -0
  135. abstract_utilities/path_utils/imports/module_imports.py +8 -0
  136. abstract_utilities/path_utils/path_utils.py +251 -0
  137. abstract_utilities/path_utils.py +95 -14
  138. abstract_utilities/read_write_utils/__init__.py +1 -0
  139. abstract_utilities/read_write_utils/imports/__init__.py +2 -0
  140. abstract_utilities/read_write_utils/imports/imports.py +2 -0
  141. abstract_utilities/read_write_utils/imports/module_imports.py +5 -0
  142. abstract_utilities/read_write_utils/read_write_utils.py +338 -0
  143. abstract_utilities/read_write_utils.py +110 -60
  144. abstract_utilities/safe_utils/__init__.py +2 -0
  145. abstract_utilities/safe_utils/imports/__init__.py +3 -0
  146. abstract_utilities/safe_utils/imports/imports.py +2 -0
  147. abstract_utilities/safe_utils/imports/module_imports.py +2 -0
  148. abstract_utilities/safe_utils/safe_utils.py +136 -0
  149. abstract_utilities/ssh_utils/__init__.py +3 -1
  150. abstract_utilities/ssh_utils/classes.py +0 -1
  151. abstract_utilities/ssh_utils/cmd_utils.py +207 -0
  152. abstract_utilities/ssh_utils/imports/__init__.py +3 -0
  153. abstract_utilities/ssh_utils/imports/imports.py +5 -0
  154. abstract_utilities/ssh_utils/imports/module_imports.py +6 -0
  155. abstract_utilities/ssh_utils/imports/utils.py +189 -0
  156. abstract_utilities/ssh_utils/pexpect_utils.py +11 -18
  157. abstract_utilities/ssh_utils/type_checks.py +92 -0
  158. abstract_utilities/string_utils/__init__.py +4 -0
  159. abstract_utilities/string_utils/clean_utils.py +28 -0
  160. abstract_utilities/string_utils/eat_utils.py +103 -0
  161. abstract_utilities/string_utils/imports/__init__.py +3 -0
  162. abstract_utilities/string_utils/imports/imports.py +2 -0
  163. abstract_utilities/string_utils/imports/module_imports.py +2 -0
  164. abstract_utilities/string_utils/imports/utils.py +81 -0
  165. abstract_utilities/string_utils/replace_utils.py +27 -0
  166. abstract_utilities/thread_utils/__init__.py +2 -0
  167. abstract_utilities/thread_utils/imports/__init__.py +2 -0
  168. abstract_utilities/thread_utils/imports/imports.py +2 -0
  169. abstract_utilities/thread_utils/imports/module_imports.py +2 -0
  170. abstract_utilities/thread_utils/thread_utils.py +140 -0
  171. abstract_utilities/time_utils/__init__.py +2 -0
  172. abstract_utilities/time_utils/imports/__init__.py +2 -0
  173. abstract_utilities/time_utils/imports/imports.py +3 -0
  174. abstract_utilities/time_utils/imports/module_imports.py +1 -0
  175. abstract_utilities/time_utils/time_utils.py +392 -0
  176. abstract_utilities/type_utils/__init__.py +3 -0
  177. abstract_utilities/type_utils/alpha_utils.py +59 -0
  178. abstract_utilities/type_utils/imports/__init__.py +2 -0
  179. abstract_utilities/type_utils/imports/imports.py +4 -0
  180. abstract_utilities/type_utils/imports/module_imports.py +1 -0
  181. abstract_utilities/type_utils/num_utils.py +19 -0
  182. abstract_utilities/type_utils/type_utils.py +981 -0
  183. {abstract_utilities-0.2.2.486.dist-info → abstract_utilities-0.2.2.540.dist-info}/METADATA +1 -1
  184. abstract_utilities-0.2.2.540.dist-info/RECORD +263 -0
  185. imports/__init__.py +36 -0
  186. abstract_utilities-0.2.2.486.dist-info/RECORD +0 -92
  187. {abstract_utilities-0.2.2.486.dist-info → abstract_utilities-0.2.2.540.dist-info}/WHEEL +0 -0
  188. {abstract_utilities-0.2.2.486.dist-info → abstract_utilities-0.2.2.540.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,92 @@
1
+ from .imports import *
2
+
3
+ def get_user_pass_host_key(**kwargs):
4
+ args = ['password','user_at_host','host','key','user']
5
+ kwargs['del_kwarg']=kwargs.get('del_kwarg',False)
6
+ values,kwargs = get_from_kwargs(*args,**kwargs)
7
+ return values
8
+
9
+ # --- Base remote checker -----------------------------------------------------
10
+ def _remote_test(path: str, test_flag: str, timeout: int = 5,*args, **kwargs) -> bool:
11
+ """
12
+ Run a remote shell test (e.g. -f, -d) via SSH.
13
+ Returns True if test succeeds, False otherwise.
14
+ """
15
+ try:
16
+ kwargs['cmd']=f"[ {test_flag} {shlex.quote(path)} ] && echo 1 || echo 0"
17
+ kwargs['text']=True
18
+ kwargs['timeout']=timeout
19
+ kwargs['stderr']=subprocess.DEVNULL
20
+ result = run_pruned_func(run_cmd,**kwargs)
21
+ return result.strip() == "1"
22
+ except Exception:
23
+ return False
24
+
25
+
26
+ # --- Individual path checks --------------------------------------------------
27
+ def is_remote_file(path: str,*args, **kwargs) -> bool:
28
+ """True if remote path is a file."""
29
+ return _remote_test(path, "-f", **kwargs)
30
+
31
+
32
+ def is_remote_dir(path: str,*args, **kwargs) -> bool:
33
+ """True if remote path is a directory."""
34
+ return _remote_test(path, "-d", **kwargs)
35
+
36
+
37
+ def is_local_file(path: str) -> bool:
38
+ """True if local path is a file."""
39
+ return os.path.isfile(path)
40
+
41
+
42
+ def is_local_dir(path: str) -> bool:
43
+ """True if local path is a directory."""
44
+ return os.path.isdir(path)
45
+
46
+
47
+ # --- Unified interface -------------------------------------------------------
48
+
49
+ def is_file(path: str,*args,**kwargs) -> bool:
50
+ """Determine if path is a file (works local or remote)."""
51
+ if get_user_pass_host_key(**kwargs):
52
+ return is_remote_file(path, **kwargs)
53
+ return is_local_file(path)
54
+
55
+
56
+ def is_dir(path: str, *args,**kwargs) -> bool:
57
+ """Determine if path is a directory (works local or remote)."""
58
+ if get_user_pass_host_key(**kwargs):
59
+ return is_remote_dir(path, **kwargs)
60
+ return is_local_dir(path)
61
+
62
+ def is_exists(path: str, *args,**kwargs) -> bool:
63
+ if is_file(path,**kwargs):
64
+ return True
65
+ if is_dir(path,**kwargs):
66
+ return True
67
+ return False
68
+ # --- Optional: keep your original all-in-one wrapper ------------------------
69
+ def check_path_type(
70
+ path: str,
71
+ *args,
72
+ **kwargs
73
+ ) -> str:
74
+ """
75
+ Return 'file', 'directory', 'missing', or 'unknown'.
76
+ Uses isolated is_file/is_dir functions.
77
+ """
78
+ if get_user_pass_host_key(**kwargs):
79
+ if is_remote_file(path,**kwargs):
80
+ return "file"
81
+ elif is_remote_dir(path,**kwargs):
82
+ return "directory"
83
+ else:
84
+ return "missing"
85
+ else:
86
+ if os.path.isfile(path):
87
+ return "file"
88
+ elif os.path.isdir(path):
89
+ return "directory"
90
+ elif not os.path.exists(path):
91
+ return "missing"
92
+ return "unknown"
@@ -0,0 +1,4 @@
1
+ from .imports import *
2
+ from .clean_utils import *
3
+ from .eat_utils import *
4
+ from .replace_utils import *
@@ -0,0 +1,28 @@
1
+ from .eat_utils import eatAll
2
+ def clean_spaces(obj: str) -> str:
3
+ """
4
+ Removes leading spaces and tabs from a string.
5
+
6
+ Args:
7
+ obj (str): The input string.
8
+
9
+ Returns:
10
+ str: The string with leading spaces and tabs removed.
11
+ """
12
+ if len(obj) == 0:
13
+ return obj
14
+ while obj[0] in [' ', '\t']:
15
+ obj = obj[1:]
16
+ return obj
17
+ def clean_line(line):
18
+ return eatAll(line,[' ','','\t','\n'])
19
+ def url_join(*paths):
20
+ final_url = os.path.join(*paths)
21
+ for i,path in enumerate(paths):
22
+ if i == 0:
23
+ final_path = path # Note: Fixed bug; original code had `final_path = paths`
24
+ else:
25
+ final_path = eatOuter(final_path, '/')
26
+ path = eatInner(path, '/')
27
+ final_path = f"{final_path}/{path}"
28
+ return final_path
@@ -0,0 +1,103 @@
1
+ from .imports import *
2
+ def eatInner(string: str, list_objects:(str or list)) -> any:
3
+ """
4
+ Removes characters from the inner part of a string or list.
5
+
6
+ Args:
7
+ x (str or list): The input string or list.
8
+ ls (list): The list of characters to remove.
9
+
10
+ Returns:
11
+ any: The modified string or list.
12
+ """
13
+ if not isinstance(list_objects,list):
14
+ list_objects = [list_objects]
15
+ if not isinstance(string,str):
16
+ string = str(string)
17
+ if string and list_objects:
18
+ for char in string:
19
+ if string:
20
+ if char not in list_objects:
21
+ return string
22
+ string = string[1:]
23
+ return string
24
+
25
+
26
+ def eatOuter(string: str, list_objects:(str or list)) -> any:
27
+ """
28
+ Removes characters from the outer part of a string or list.
29
+
30
+ Args:
31
+ x (str or list): The input string or list.
32
+ ls (list): The list of characters to remove.
33
+
34
+ Returns:
35
+ any: The modified string or list.
36
+ """
37
+ if not isinstance(list_objects,list):
38
+ list_objects = [list_objects]
39
+ if not isinstance(string,str):
40
+ string = str(string)
41
+ if string and list_objects:
42
+ for i in range(len(string)):
43
+ if string:
44
+ if string[-1] not in list_objects:
45
+ return string
46
+ string = string[:-1]
47
+ return string
48
+ def eatAll(string: str, list_objects:(str or list)) -> any:
49
+ """
50
+ Removes characters from both the inner and outer parts of a string or list.
51
+
52
+ Args:
53
+ x (str or list): The input string or list.
54
+ ls (list): The list of characters to remove.
55
+
56
+ Returns:
57
+ any: The modified string or list.
58
+ """
59
+ if not isinstance(list_objects,list):
60
+ list_objects = [list_objects]
61
+ if not isinstance(string,str):
62
+ string = str(string)
63
+ if string and list_objects:
64
+ string = eatInner(string, list_objects)
65
+ if string and list_objects:
66
+ string = eatOuter(string, list_objects)
67
+ return string
68
+
69
+
70
+
71
+ def eatElse(
72
+ stringObj,
73
+ chars=None,
74
+ ints=True,
75
+ alpha=True,
76
+ lower=True,
77
+ capitalize=True,
78
+ string=True,
79
+ listObj=True
80
+ ):
81
+ alpha_ints = get_alpha_ints(
82
+ ints=True,
83
+ alpha=True,
84
+ lower=True,
85
+ capitalize=True,
86
+ string=True,
87
+ listObj=True
88
+ )
89
+ chars = make_list(chars or [])+alpha_ints
90
+
91
+ while True:
92
+ if stringObj:
93
+ str_0 = stringObj[0] not in chars
94
+ str_1 = stringObj[-1] not in chars
95
+ str_eat = str_0 or str_1
96
+ if not str_eat:
97
+ return stringObj
98
+ if stringObj and str_0:
99
+ stringObj = stringObj[1:] if len(stringObj) !=1 else ""
100
+ if stringObj and str_1:
101
+ stringObj = stringObj[:-1] if len(stringObj) !=1 else ""
102
+ else:
103
+ return stringObj
@@ -0,0 +1,3 @@
1
+ from .imports import *
2
+ from .module_imports import *
3
+ from .utils import *
@@ -0,0 +1,2 @@
1
+ from typing import *
2
+ from ...imports import os
@@ -0,0 +1,2 @@
1
+ from ...list_utils import make_list
2
+ from ...type_utils import get_alpha_ints
@@ -0,0 +1,81 @@
1
+ def quoteIt(st: str, ls: list) -> str:
2
+ """
3
+ Quotes specific elements in a string.
4
+
5
+ Args:
6
+ st (str): The input string.
7
+ ls (list): The list of elements to quote.
8
+
9
+ Returns:
10
+ str: The modified string with quoted elements.
11
+ """
12
+ lsQ = ["'", '"']
13
+ for i in range(len(ls)):
14
+ for k in range(2):
15
+ if lsQ[k] + ls[i] in st:
16
+ st = st.replace(lsQ[k] + ls[i], ls[i])
17
+ if ls[i] + lsQ[k] in st:
18
+ st = st.replace(ls[i] + lsQ[k], ls[i])
19
+ st = st.replace(ls[i], '"' + str(ls[i]) + '"')
20
+ return st
21
+
22
+ def truncate_text(text, max_chars):
23
+ """
24
+ Truncates a text to a specified maximum number of characters, preserving the last complete sentence or word.
25
+
26
+ Args:
27
+ text (str): The input text.
28
+ max_chars (int): The maximum number of characters.
29
+
30
+ Returns:
31
+ str: The truncated text.
32
+ """
33
+ if len(text) <= max_chars:
34
+ return text
35
+ truncated = text[:max_chars]
36
+ # Find the last complete sentence
37
+ last_sentence_end = max(truncated.rfind('.'), truncated.rfind('!'), truncated.rfind('?'))
38
+ # If a complete sentence is found, truncate up to its end
39
+ if last_sentence_end != -1:
40
+ truncated = truncated[:last_sentence_end + 1]
41
+ else:
42
+ # If no complete sentence is found, find the last complete word
43
+ last_word_end = truncated.rfind(' ')
44
+
45
+ # If a complete word is found, truncate up to its end
46
+ if last_word_end != -1:
47
+ truncated = truncated[:last_word_end]
48
+ return truncated
49
+ def capitalize(string):
50
+ return string[:1].upper() + string[1:].lower() if string else string
51
+ def get_from_kwargs(*args,**kwargs):
52
+ del_kwarg = kwargs.get('del_kwargs',False)
53
+ values = {}
54
+ for key in args:
55
+ if key:
56
+ key = str(key)
57
+ if key in kwargs:
58
+ values[key] = kwargs.get(key)
59
+ if del_kwarg:
60
+ del kwargs[key]
61
+ return values,kwargs
62
+ def get_lines(string,strip=True):
63
+ lines = string.split('\n')
64
+ if strip:
65
+ lines = [line for line in lines if line]
66
+ return lines
67
+ def clean_spaces(obj: str) -> str:
68
+ """
69
+ Removes leading spaces and tabs from a string.
70
+
71
+ Args:
72
+ obj (str): The input string.
73
+
74
+ Returns:
75
+ str: The string with leading spaces and tabs removed.
76
+ """
77
+ if len(obj) == 0:
78
+ return obj
79
+ while obj[0] in [' ', '\t']:
80
+ obj = obj[1:]
81
+ return obj
@@ -0,0 +1,27 @@
1
+ from .imports import *
2
+ def replace_it(string,item,rep):
3
+ if item in string:
4
+ string = string.replace(item,rep)
5
+ return string
6
+ def while_replace(string,item,rep):
7
+ while True:
8
+ string = replace_it(string,item,rep)
9
+ if item not in string or item in rep:
10
+ return string
11
+ def for_replace(string,item,replace):
12
+ replace = make_list(replace)
13
+ for rep in replace:
14
+ string = while_replace(string,item,rep)
15
+ return string
16
+ def replace_all(string,*args,**kwargs):
17
+ for items in args:
18
+ if items and isinstance(items,list):
19
+ item = items[0]
20
+ replace = items[1:] if len(items)>1 else items[-1]
21
+ string = for_replace(string,item,replace)
22
+ values,kwargs = get_from_kwargs('item','replace',**kwargs)
23
+ if values:
24
+ string = for_replace(string,**values)
25
+ for item,rep in kwargs.items():
26
+ string = for_replace(string,item,rep)
27
+ return string
@@ -0,0 +1,2 @@
1
+ from .imports import *
2
+ from .thread_utils import *
@@ -0,0 +1,2 @@
1
+ from .imports import *
2
+ from .module_imports import *
@@ -0,0 +1,2 @@
1
+ from ...imports import threading
2
+ from ...imports import queue
@@ -0,0 +1,2 @@
1
+ from ...compare_utils import create_new_name,get_last_comp_list
2
+
@@ -0,0 +1,140 @@
1
+ """
2
+ thread_utils.py - Thread Utilities Module
3
+
4
+ This module provides utility functions for working with threads in Python.
5
+
6
+ Usage:
7
+ import abstract_utilities.thread_utils as thread_utils
8
+
9
+ Example:
10
+ # Creating a thread
11
+ my_thread = thread_utils.get_thread(target=my_function, args=(arg1, arg2), daemon=True)
12
+
13
+ # Starting the thread
14
+ thread_utils.start_thread(my_thread)
15
+
16
+ # Verifying if a given object is a valid thread
17
+ is_valid = thread_utils.verify_thread(my_thread)
18
+
19
+ # Checking if a thread is alive
20
+ if thread_utils.thread_alive(my_thread):
21
+ print("Thread is alive")
22
+ else:
23
+ print("Thread is not alive")
24
+
25
+ This module is part of the `abstract_utilities` package.
26
+
27
+ Author: putkoff
28
+ Date: 10/25/2023
29
+ Version: 0.1.2
30
+ """
31
+ from .imports import *
32
+ class ThreadedEvent:
33
+ def __init__(self, target_function,termination_result=None,function_args={},daemon=True):
34
+ self._event = threading.Event()
35
+ self._queue = queue.Queue() # Add a queue for return values
36
+ self._thread = threading.Thread(target=self._run, args=(target_function,termination_result,function_args),daemon=daemon)
37
+ def _run(self, target_function, termination_result, function_args):
38
+ print(f"Thread starting with event status: {self._event.is_set()}")
39
+ while not self._event.is_set():
40
+ print(f"In loop. Event status: {self._event.is_set()}")
41
+ result = target_function(**function_args)
42
+ if result:
43
+ self._queue.put(result) # Store the return value in the queue
44
+ self._event.wait(1) # This will wait for 1 second or until interrupted by calling `stop`.
45
+ print(f"Thread {self._thread.name} is exiting.")
46
+ def get_result(self):
47
+ """Retrieve the result from the queue. Returns None if no result available."""
48
+ if not self._queue.empty():
49
+ return self._queue.get()
50
+ return None
51
+ def start(self):
52
+ """Starts the thread."""
53
+ self._thread.start()
54
+ def stop(self):
55
+ print(f"Attempting to stop thread {self._thread.name}")
56
+ self._event.set()
57
+ # # Optionally, you can wait for the thread to finish.
58
+ def wait(self,n=0):
59
+ self._thread.wait(n)
60
+ def join(self):
61
+ self._thread.join()
62
+ def is_alive(self):
63
+ """Returns whether the thread is still running."""
64
+ return self._thread.is_alive()
65
+ class ThreadManager:
66
+ def __init__(self):
67
+ self.threads = {}
68
+ self.thread_name_list=[]
69
+ def add_thread(self,name=None,target_function=None,termination_result=None,function_args={},overwrite=False,make_default=True,daemon=True):
70
+ if name == None:
71
+ if make_default:
72
+ name = 'Default_Thread_name'
73
+ else:
74
+ return
75
+ if target_function == None:
76
+ return
77
+ if overwrite==False:
78
+ name=create_new_name(name=name,names_list=self.all_thread_names())
79
+ if name in self.thread_name_list:
80
+ self.thread_name_list.remove(name)
81
+ self.thread_name_list.append(name)
82
+ """Add a thread with a name and target function."""
83
+ self.threads[name] = ThreadedEvent(target_function=target_function,termination_result=termination_result,function_args=function_args,daemon=daemon)
84
+ return name
85
+ def start(self, name,overwrite=False):
86
+ """Start a specific thread by name."""
87
+ if self.is_alive(name)==False:
88
+ self.threads[name].start()
89
+ def wait(self,name,n=0):
90
+ self.threads[name].wait(n)
91
+ def join(self,name):
92
+ self.threads[name].join()
93
+ def stop(self, name, result=None):
94
+ if self.check_name(name):
95
+ if result:
96
+ self.threads[name]._queue.put(result)
97
+ self.threads[name].stop()
98
+ return True
99
+ def stop_last(self,name=None,result=None):
100
+ str_name = f"for {name}" if name else ""
101
+ if name ==None:
102
+ name=get_last_comp_list(name,self.all_thread_names())
103
+ if self.check_name(name):
104
+ return self.stop(name,result=result)
105
+ return False
106
+ def start_all(self):
107
+ """Start all threads."""
108
+ for thread in self.threads.values():
109
+ thread.start()
110
+
111
+ def stop_all(self):
112
+ """Stop all threads."""
113
+ for thread in self.threads.values():
114
+ thread.stop()
115
+
116
+ def is_alive(self, name):
117
+ """Check if a specific thread is alive by name."""
118
+ if self.check_name(name):
119
+ status = self.threads[name].is_alive()
120
+ return status
121
+ return False
122
+ def all_alive(self):
123
+ """Return a dictionary indicating if each thread is alive."""
124
+ return {name: thread.is_alive() for name, thread in self.threads.items()}
125
+ def all_thread_names(self):
126
+ return self.threads.keys()
127
+ def get_last_result(self,name=None):
128
+ str_name = f"for {name}" if name else ""
129
+ result = None
130
+ if name:
131
+ result_name=get_last_comp_list(name,self.all_thread_names())
132
+ if self.check_name(name):
133
+ result = self.threads[result_name].get_result()
134
+ elif len(self.thread_name_list)>0:
135
+ result = self.threads[self.thread_name_list[-1]].get_result()
136
+ return result
137
+ def check_name(self,name):
138
+ if name in self.all_thread_names():
139
+ return True
140
+ return False
@@ -0,0 +1,2 @@
1
+ from .imports import *
2
+ from .time_utils import *
@@ -0,0 +1,2 @@
1
+ from .imports import *
2
+ from .module_imports import *
@@ -0,0 +1,3 @@
1
+ from ...imports import os,time
2
+ from typing import *
3
+ from datetime import datetime, timedelta
@@ -0,0 +1 @@
1
+ from ...type_utils import is_number,make_list