abstract-utilities 0.2.2.507__py3-none-any.whl → 0.2.2.510__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.
Files changed (29) hide show
  1. abstract_utilities/__init__.py +1 -0
  2. abstract_utilities/circular_import_finder.py +222 -0
  3. abstract_utilities/circular_import_finder2.py +118 -0
  4. abstract_utilities/directory_utils/__init__.py +4 -0
  5. abstract_utilities/directory_utils/directory_utils.py +94 -0
  6. abstract_utilities/directory_utils/name_utils.py +43 -0
  7. abstract_utilities/directory_utils/size_utils.py +57 -0
  8. abstract_utilities/directory_utils/utils.py +116 -0
  9. abstract_utilities/env_utils/imports/imports.py +2 -1
  10. abstract_utilities/file_utils/imports/module_imports.py +1 -2
  11. abstract_utilities/file_utils/src/__init__.py +0 -1
  12. abstract_utilities/import_utils/src/clean_imports.py +0 -1
  13. abstract_utilities/json_utils/imports/module_imports.py +1 -1
  14. abstract_utilities/json_utils/json_utils.py +1 -1
  15. abstract_utilities/log_utils/imports/module_imports.py +1 -1
  16. abstract_utilities/path_utils/imports/__init__.py +1 -0
  17. abstract_utilities/path_utils/imports/module_imports.py +3 -2
  18. abstract_utilities/path_utils/path_utils.py +1 -465
  19. abstract_utilities/read_write_utils/imports/module_imports.py +2 -2
  20. abstract_utilities/safe_utils/imports/imports.py +1 -0
  21. abstract_utilities/safe_utils/safe_utils.py +6 -0
  22. abstract_utilities/ssh_utils/__init__.py +1 -0
  23. abstract_utilities/ssh_utils/imports/module_imports.py +4 -3
  24. abstract_utilities/ssh_utils/type_checks.py +92 -0
  25. abstract_utilities/string_utils/replace_utils.py +1 -1
  26. {abstract_utilities-0.2.2.507.dist-info → abstract_utilities-0.2.2.510.dist-info}/METADATA +1 -1
  27. {abstract_utilities-0.2.2.507.dist-info → abstract_utilities-0.2.2.510.dist-info}/RECORD +29 -21
  28. {abstract_utilities-0.2.2.507.dist-info → abstract_utilities-0.2.2.510.dist-info}/top_level.txt +0 -1
  29. {abstract_utilities-0.2.2.507.dist-info → abstract_utilities-0.2.2.510.dist-info}/WHEEL +0 -0
@@ -96,7 +96,6 @@ def get_clean_import_string(import_pkg_js,fill_nulines=False,get_locals=False):
96
96
  for key,values in import_pkg_js.items():
97
97
  if key not in ['context','nulines']:
98
98
  imports = None
99
- input(values)
100
99
  imp_values= values.get('imports')
101
100
  if key == 'import':
102
101
  imports = f'import {imp_values}'
@@ -1,5 +1,5 @@
1
1
  from ...read_write_utils import check_read_write_params, read_from_file, write_to_file
2
2
  from ...compare_utils import get_closest_match_from_list
3
- from ...path_utils import makeAllDirs
3
+ from ...directory_utils import makedirs
4
4
  from ...list_utils import make_list
5
5
  from ...class_utils import alias
@@ -530,7 +530,7 @@ def get_dict_from_string(string, file_path=None):
530
530
  if bracket_count == 0 and start_index is not None:
531
531
  json_data = safe_json_loads(string[start_index:i+1])
532
532
  if file_path:
533
- safe_dump_to_file(file_path=makeAllDirs(file_path), data=json_data)
533
+ safe_dump_to_file(file_path=mkdirs(file_path), data=json_data)
534
534
  return json_data
535
535
  return None
536
536
 
@@ -1,2 +1,2 @@
1
- from ...path_utils import mkdirs
1
+ from ...directory_utils import mkdirs
2
2
  from ...class_utils import SingletonMeta
@@ -1,2 +1,3 @@
1
1
  from .imports import *
2
2
  from .module_imports import *
3
+
@@ -1,6 +1,7 @@
1
1
  from ...string_utils import eatAll
2
2
  from ...list_utils import make_list
3
3
  from ...type_utils import get_media_exts, is_media_type,MIME_TYPES
4
- from ...safe_utils import safe_join
4
+ from ...safe_utils import safe_join,get_slash
5
5
  from ...class_utils import get_caller_path,get_caller_dir
6
-
6
+ from ...file_utils import is_file,is_dir,is_exists
7
+ from ...ssh_utils import is_file,is_dir,is_exists
@@ -24,405 +24,6 @@ Version: 0.1.2
24
24
  """
25
25
  from .imports import *
26
26
 
27
- def get_os_info():
28
- """
29
- Get Operating System Information
30
-
31
- This function retrieves information about the current operating system, including its name and bit size.
32
-
33
- Returns:
34
- - os_info (dict): A dictionary containing the operating system information.
35
- Keys:
36
- - "operating_system" (str): The name of the operating system (e.g., "Windows", "Linux", "Darwin").
37
- - "bit_size" (str): The bit size of the operating system (e.g., "32bit", "64bit").
38
-
39
- Example:
40
- os_info = get_os_info()
41
- print("Operating System:", os_info["operating_system"])
42
- print("Bit Size:", os_info["bit_size"])
43
- """
44
- os_name = platform.system()
45
- bit_size = platform.architecture()[0]
46
- return {"operating_system": os_name, "bit_size": bit_size}
47
- def get_dirs(path):
48
- """
49
- Get List of Immediate Subdirectories in a Path
50
-
51
- This function uses the os.walk method to traverse through a directory tree and returns a list of immediate subdirectories
52
- within the specified path.
53
-
54
- Parameters:
55
- - path (str): The path for which subdirectories need to be retrieved.
56
-
57
- Returns:
58
- - subdirectories (list): A list of immediate subdirectories within the specified path.
59
-
60
- Example:
61
- subdirs = get_dirs("/path/to/directory")
62
- print("Immediate Subdirectories:", subdirs)
63
- """
64
- from os import walk
65
- for (dirpath, dirnames, filenames) in walk(path):
66
- return dirnames
67
- def sanitize_filename(name: str):
68
- """
69
- Sanitize a filename by removing invalid characters.
70
-
71
- Args:
72
- name (str): Filename to sanitize.
73
-
74
- Returns:
75
- str: Sanitized filename.
76
- """
77
- return re.sub(r'[\\/*?:"<>|]', "", name)
78
- def get_directory(file_path: str) -> str:
79
- """
80
- Extracts and returns the directory path from a given file path.
81
-
82
- Args:
83
- file_path (str): A string representing the file path.
84
-
85
- Returns:
86
- str: The directory path extracted from the file path.
87
- """
88
- return file_path[:-len(get_base_name(file_path))]
89
-
90
- def get_base_name(file_path: str) -> str:
91
- """
92
- Extracts and returns the base name of a file from a given file path.
93
-
94
- Args:
95
- file_path (str): A string representing the file path.
96
-
97
- Returns:
98
- str: The base name of the file.
99
- """
100
- return os.path.basename(file_path)
101
- def split_text(string: str) -> tuple:
102
- """
103
- Splits a string into its base name and extension and returns them as a tuple.
104
-
105
- Args:
106
- string (str): A string to be split, typically representing a file name.
107
-
108
- Returns:
109
- tuple: A tuple containing the base name and extension of the input string.
110
- """
111
- return os.path.splitext(string)
112
- def get_ext(file_path: str) -> str:
113
- """
114
- Retrieves and returns the extension of a file from a given file path.
115
-
116
- Args:
117
- file_path (str): A string representing the file path.
118
-
119
- Returns:
120
- str: The extension of the file (including the dot).
121
- """
122
- return split_text(get_base_name(file_path))[1]
123
- def get_file_name(file_path: str) -> str:
124
- """
125
- Retrieves and returns the base name of a file from a given file path.
126
-
127
- Args:
128
- file_path (str): A string representing the file path.
129
-
130
- Returns:
131
- str: The base name of the file (without extension).
132
- """
133
- return split_text(get_base_name(file_path))[0]
134
- def get_slash():
135
- """
136
- Returns the appropriate file path separator depending on the current operating system.
137
- """
138
- slash = '/' # Assume a Unix-like system by default
139
- if slash not in get_current_path():
140
- slash = '\\' # Use backslash for Windows systems
141
- return slash
142
-
143
- def simple_path_join(path_A:str, path_B:str):
144
- """
145
- Join two paths using the appropriate file path separator.
146
-
147
- Args:
148
- path_A (str): The first path to join.
149
- path_B (str): The second path to join.
150
-
151
- Returns:
152
- str: The joined path.
153
- """
154
- return os.path.join(str(path_A), str(path_B))
155
-
156
- def path_join(path_A, path_B=None):
157
- """
158
- Joins two paths or a list of paths using the appropriate file path separator.
159
-
160
- Args:
161
- path_A (str or list): The first path or list of paths to join.
162
- path_B (str, optional): The second path to join. Defaults to None.
163
-
164
- Returns:
165
- str: The joined path.
166
- """
167
- if path_B is not None: # If path_B is provided, join path_A and path_B
168
- return simple_path_join(path_A, path_B)
169
- if isinstance(path_A, list): # If path_A is a list, join all paths in the list
170
- path = path_A[0]
171
- for k in range(1, len(path_A)):
172
- path = simple_path_join(path, path_A[k])
173
- return path
174
-
175
- def if_not_last_child_join(path:str,child:str):
176
- """
177
- Adds a child path to the given path if it's not already present at the end.
178
-
179
- Args:
180
- path (str): The parent path.
181
- child (str): The child path to add.
182
-
183
- Returns:
184
- str: The updated path.
185
- """
186
- if path.endswith(child):
187
- return path
188
- return simple_path_join(path, child)
189
-
190
- def get_current_path():
191
- """
192
- Returns the current working directory.
193
-
194
- Returns:
195
- str: The current working directory.
196
- """
197
- return os.getcwd()
198
-
199
- def get_home_folder():
200
- """
201
- Returns the path to the home directory of the current user.
202
-
203
- Returns:
204
- str: The path to the home directory.
205
- """
206
- return os.path.expanduser("~")
207
-
208
- def is_file(path: str) -> bool:
209
- """Checks if the provided path is a file.
210
-
211
- Args:
212
- path (str): The path to check.
213
-
214
- Returns:
215
- bool: True if the path is a file, False otherwise.
216
- """
217
- return os.path.isfile(path)
218
-
219
- def update_global_variable(name: str, value) -> None:
220
- """Updates the global variable with the provided name and value.
221
-
222
- Args:
223
- name (str): The name of the global variable.
224
- value: The value to assign to the global variable.
225
-
226
- Returns:
227
- None
228
- """
229
- globals()[name] = value
230
-
231
- def list_directory_contents(path: str) -> list:
232
- """Returns a list of directory contents or a list with a single file, if the path is a file.
233
-
234
- Args:
235
- path (str): The path of the directory or file.
236
-
237
- Returns:
238
- list: A list of directory contents or a list with a single file path.
239
- """
240
- if is_file(path):
241
- return [path]
242
- elif is_valid_path(path):
243
- return os.listdir(path)
244
- return [path]
245
-
246
- def trunc(a: float, x: int) -> float:
247
- """
248
- Truncates a float number to a specific number of decimal places.
249
-
250
- Args:
251
- a (float): The number to truncate.
252
- x (int): The number of decimal places to retain.
253
-
254
- Returns:
255
- float: The truncated float number.
256
- """
257
- temp = str(a)
258
- for i in range(len(temp)):
259
- if temp[i] == '.':
260
- try:
261
- return float(temp[:i+x+1])
262
- except:
263
- return float(temp)
264
- return float(temp)
265
-
266
- def mkGb(k) -> float:
267
- """
268
- Converts a value to Gigabytes (GB).
269
-
270
- Args:
271
- k (float): The value to convert to GB.
272
-
273
- Returns:
274
- float: The value converted to GB.
275
- """
276
- return float(float(k)*(10**9))
277
-
278
- def mkGbTrunk(k) -> float:
279
- """
280
- Converts a value to Gigabytes (GB) and truncates the result to five decimal places.
281
-
282
- Args:
283
- k (float): The value to convert to GB.
284
-
285
- Returns:
286
- float: The value converted to GB and truncated to five decimal places.
287
- """
288
- return trunc(mkGb(k), 5)
289
-
290
- def mkGbTrunFroPathTot(k) -> float:
291
- """
292
- Fetches the file size from a path, converts it to Gigabytes (GB) and truncates the result to five decimal places.
293
-
294
- Args:
295
- k (str): The file path.
296
-
297
- Returns:
298
- float: The file size converted to GB and truncated to five decimal places.
299
- """
300
- return trunc(mkGb(s.path.getsize(k)), 5)
301
-
302
-
303
- def get_abs_name_of_this():
304
- """
305
- Returns the absolute name of the current module.
306
-
307
- Returns:
308
- Path: The absolute name of the current module.
309
- """
310
- return os.path.abspath(__name__)
311
-
312
- def createFolds(ls: list) -> None:
313
- """
314
- Creates multiple directories.
315
-
316
- Args:
317
- ls (list): The list of directory paths to create.
318
- """
319
- for k in range(len(ls)):
320
- mkdirs(ls[k])
321
- def makeAllDirs(path: str) -> str:
322
- def make_list(obj):
323
- if not isinstance(obj,list):
324
- obj = [obj]
325
- return obj
326
-
327
- slash = get_slash()
328
- path_parts = path.split(slash)
329
- path=''
330
- if path_parts:
331
- last_part = path_parts[-1]
332
- for i,part in enumerate(path_parts):
333
- if part == '':
334
- part = slash
335
- path = os.path.join(path,part)
336
- if not os.path.exists(path):
337
- if '.' in part and abs(len(path_parts)-1) == i:
338
- return path
339
- os.makedirs(path)
340
- else:
341
- if os.path.isfile(path):
342
- return path
343
- return path
344
-
345
-
346
- def mkdirs(path: str) -> str:
347
- """
348
- Creates a directory and any necessary intermediate directories.
349
-
350
- Args:
351
- path (str): The directory path to create.
352
-
353
- Returns:
354
- str: The created directory path.
355
- """
356
- os.makedirs(path, exist_ok=True)
357
- return path
358
- def make_dirs(*paths):
359
- path = path_join(*paths)
360
- if not os.path.isfile(path):
361
- mkdirs(path)
362
- return path
363
- def file_exists(file_path: str) -> bool:
364
- """
365
- Checks if a file exists at the specified path.
366
-
367
- Args:
368
- file_path (str): The path to the file.
369
-
370
- Returns:
371
- bool: True if the file exists, False otherwise.
372
- """
373
- return os.path.exists(file_path)
374
-
375
- def dir_exists(path: str) -> bool:
376
- """
377
- Checks if a directory exists at the specified path.
378
-
379
- Args:
380
- path (str): The path to the directory.
381
-
382
- Returns:
383
- bool: True if the directory exists, False otherwise.
384
- """
385
- return os.path.isdir(path)
386
- def file_size(path:str):
387
- if is_file(path):
388
- return os.path.getsize(path)
389
- return 0
390
- def get_file_create_time(path):
391
- return os.path.getctime(path)
392
- def get_size(path: str) -> int:
393
- """
394
- Calculates the size of a file or a directory.
395
-
396
- Args:
397
- path (str): The path of the file or directory.
398
-
399
- Returns:
400
- int: The size of the file or directory in bytes.
401
- """
402
- total_size = file_size(path)
403
- if dir_exists(path):
404
- total_size = 0
405
- for dirpath, dirnames, filenames in os.walk(path):
406
- for file in filenames:
407
- total_size += file_size(simple_path_join(dirpath, file))
408
- return total_size
409
-
410
- def get_total_size(folder_path: str) -> int:
411
- """
412
- Calculates the total size of a directory and its subdirectories.
413
-
414
- Args:
415
- folder_path (str): The path of the directory.
416
-
417
- Returns:
418
- int: The total size of the directory and its subdirectories in bytes.
419
- """
420
- total_size = 0
421
- if os.path.exists(folder_path) and os.path.isdir(folder_path):
422
- for item in os.listdir(folder_path):
423
- item_path = os.path.join(folder_path, item)
424
- total_size += get_size(item_path)
425
- return total_size
426
27
 
427
28
  def get_files(directory):
428
29
  file_list = []
@@ -621,73 +222,7 @@ def create_base_dir(directory=None, child=None):
621
222
 
622
223
 
623
224
 
624
- # --- Individual path checks --------------------------------------------------
625
- def is_remote_file(path: str,*args, **kwargs) -> bool:
626
- """True if remote path is a file."""
627
- return _remote_test(path, "-f", **kwargs)
628
-
629
225
 
630
- def is_remote_dir(path: str,*args, **kwargs) -> bool:
631
- """True if remote path is a directory."""
632
- return _remote_test(path, "-d", **kwargs)
633
-
634
-
635
- def is_local_file(path: str) -> bool:
636
- """True if local path is a file."""
637
- return os.path.isfile(path)
638
-
639
-
640
- def is_local_dir(path: str) -> bool:
641
- """True if local path is a directory."""
642
- return os.path.isdir(path)
643
-
644
-
645
- # --- Unified interface -------------------------------------------------------
646
-
647
- def is_file(path: str,*args,**kwargs) -> bool:
648
- """Determine if path is a file (works local or remote)."""
649
- if get_user_pass_host_key(**kwargs):
650
- return is_remote_file(path, **kwargs)
651
- return is_local_file(path)
652
-
653
-
654
- def is_dir(path: str, *args,**kwargs) -> bool:
655
- """Determine if path is a directory (works local or remote)."""
656
- if get_user_pass_host_key(**kwargs):
657
- return is_remote_dir(path, **kwargs)
658
- return is_local_dir(path)
659
-
660
- def is_exists(path: str, *args,**kwargs) -> bool:
661
- if is_file(path,**kwargs):
662
- return True
663
- if is_dir(path,**kwargs):
664
- return True
665
- return False
666
- # --- Optional: keep your original all-in-one wrapper ------------------------
667
- def check_path_type(
668
- path: str,
669
- *args,
670
- **kwargs
671
- ) -> str:
672
- """
673
- Return 'file', 'directory', 'missing', or 'unknown'.
674
- Uses isolated is_file/is_dir functions.
675
- """
676
- if get_user_pass_host_key(**kwargs):
677
- if is_remote_file(path,**kwargs):
678
- return "file"
679
- elif is_remote_dir(path,**kwargs):
680
- return "directory"
681
- else:
682
- return "missing"
683
- else:
684
- if os.path.isfile(path):
685
- return "file"
686
- elif os.path.isdir(path):
687
- return "directory"
688
- elif not os.path.exists(path):
689
- return "missing"
690
- return "unknown"
691
226
 
692
227
  def get_file_parts(path):
693
228
 
@@ -713,3 +248,4 @@ def get_file_parts(path):
713
248
  "super_dirname":super_dirname,
714
249
  "super_dirbase":super_dirbase
715
250
  }
251
+
@@ -1,5 +1,5 @@
1
- from ...ssh_utils import get_user_pass_host_key,run_cmd,get_print_sudo_cmd,run_local_cmd,run_remote_cmd
1
+ from ...ssh_utils import is_file,is_dir,is_exists,get_user_pass_host_key,run_cmd,get_print_sudo_cmd,run_local_cmd,run_remote_cmd
2
2
  from ...class_utils import run_pruned_func
3
3
  from ...string_utils import *
4
- from ...path_utils import get_all_files,is_file,is_dir,is_exists
4
+
5
5
 
@@ -1 +1,2 @@
1
+ from ...imports import *
1
2
  from typing import *
@@ -128,3 +128,9 @@ def safe_get(
128
128
  return obj[key]
129
129
  except Exception:
130
130
  return obj if default is True else default if default else None
131
+ def get_slash(path):
132
+ if '/' in path:
133
+ return '/'
134
+ else:
135
+ return '//'
136
+ join_path=safe_join
@@ -2,3 +2,4 @@ from .imports import *
2
2
  from .classes import *
3
3
  from .cmd_utils import *
4
4
  from .pexpect_utils import *
5
+ from .type_checks import *
@@ -1,5 +1,6 @@
1
- from ...class_utils import SingletonMeta,run_pruned_func
2
- from ...string_utils import get_from_kwargs,eatOuter
1
+ from ...string_utils import get_from_kwargs,eatAll,eatOuter
3
2
  from ...type_utils import make_list # whatever you already have
4
3
  from ...time_utils import get_sleep
5
- from ...env_utils import *
4
+ from abstract_security import *
5
+
6
+ from ...class_utils import get_caller, get_caller_path, get_caller_dir,SingletonMeta,run_pruned_func
@@ -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"
@@ -22,6 +22,6 @@ def replace_all(string,*args,**kwargs):
22
22
  values,kwargs = get_from_kwargs('item','replace',**kwargs)
23
23
  if values:
24
24
  string = for_replace(string,**values)
25
- for item,replace in kwargs.items():
25
+ for item,rep in kwargs.items():
26
26
  string = for_replace(string,item,rep)
27
27
  return string
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: abstract_utilities
3
- Version: 0.2.2.507
3
+ Version: 0.2.2.510
4
4
  Summary: abstract_utilities is a collection of utility modules providing a variety of functions to aid in tasks such as data comparison, list manipulation, JSON handling, string manipulation, mathematical computations, and time operations.
5
5
  Home-page: https://github.com/AbstractEndeavors/abstract_utilities
6
6
  Author: putkoff