abstract-utilities 0.2.2.468__py3-none-any.whl → 0.2.2.488__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.
@@ -116,10 +116,10 @@ from .parse_utils import (num_tokens_from_string,
116
116
 
117
117
  from .log_utils import get_caller_info,get_logFile,print_or_log,get_json_call_response,initialize_call_log
118
118
  from .error_utils import try_func
119
- from .class_utils import alias,get_class_inputs,get_set_attr
120
119
  from .ssh_utils import *
121
120
  from .env_utils import *
122
121
  from .path_utils import *
123
122
  from .file_utils import *
124
123
  from .file_utils import call_for_all_tabs
125
124
  from .string_utils import *
125
+ from .class_utils import alias,get_class_inputs,get_set_attr,get_caller_path,get_caller_dir
@@ -405,4 +405,3 @@ def get_caller_dir(i: Optional[int] = None) -> str:
405
405
  abspath = get_caller_path(depth + 1)
406
406
  return os.path.dirname(abspath)
407
407
 
408
-
@@ -1,5 +1,3 @@
1
1
  from .constants import *
2
-
3
- from .file_functions import *
4
2
  from .imports import *
5
3
  from ..imports import *
@@ -6,7 +6,8 @@ from ....ssh_utils import *
6
6
  from ....env_utils import *
7
7
  from ....read_write_utils import *
8
8
  from ....abstract_classes import SingletonMeta
9
-
9
+ from ....string_utils import get_from_kwargs
10
+ from ....abstract_classes import run_pruned_func
10
11
  from ....class_utils import get_caller, get_caller_path, get_caller_dir
11
12
 
12
13
 
@@ -1,34 +1,37 @@
1
1
  from .imports import *
2
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
3
8
 
4
9
  # --- Base remote checker -----------------------------------------------------
5
- def _remote_test(path: str, test_flag: str, user_at_host: str, timeout: int = 5) -> bool:
10
+ def _remote_test(path: str, test_flag: str, timeout: int = 5,*args, **kwargs) -> bool:
6
11
  """
7
12
  Run a remote shell test (e.g. -f, -d) via SSH.
8
13
  Returns True if test succeeds, False otherwise.
9
14
  """
10
- cmd = f"[ {test_flag} {shlex.quote(path)} ] && echo 1 || echo 0"
11
15
  try:
12
- result = subprocess.check_output(
13
- ["ssh", user_at_host, cmd],
14
- stderr=subprocess.DEVNULL,
15
- text=True,
16
- timeout=timeout
17
- ).strip()
18
- return result == "1"
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"
19
22
  except Exception:
20
23
  return False
21
24
 
22
25
 
23
26
  # --- Individual path checks --------------------------------------------------
24
- def is_remote_file(path: str, user_at_host: str) -> bool:
27
+ def is_remote_file(path: str,*args, **kwargs) -> bool:
25
28
  """True if remote path is a file."""
26
- return _remote_test(path, "-f", user_at_host)
29
+ return _remote_test(path, "-f", **kwargs)
27
30
 
28
31
 
29
- def is_remote_dir(path: str, user_at_host: str) -> bool:
32
+ def is_remote_dir(path: str,*args, **kwargs) -> bool:
30
33
  """True if remote path is a directory."""
31
- return _remote_test(path, "-d", user_at_host)
34
+ return _remote_test(path, "-d", **kwargs)
32
35
 
33
36
 
34
37
  def is_local_file(path: str) -> bool:
@@ -42,33 +45,40 @@ def is_local_dir(path: str) -> bool:
42
45
 
43
46
 
44
47
  # --- Unified interface -------------------------------------------------------
45
- def is_file(path: str,*args, user_at_host: Optional[str] = None,**kwargs) -> bool:
48
+
49
+ def is_file(path: str,*args,**kwargs) -> bool:
46
50
  """Determine if path is a file (works local or remote)."""
47
- if user_at_host:
48
- return is_remote_file(path, user_at_host)
51
+ if get_user_pass_host_key(**kwargs):
52
+ return is_remote_file(path, **kwargs)
49
53
  return is_local_file(path)
50
54
 
51
55
 
52
- def is_dir(path: str, *args,user_at_host: Optional[str] = None,**kwargs) -> bool:
56
+ def is_dir(path: str, *args,**kwargs) -> bool:
53
57
  """Determine if path is a directory (works local or remote)."""
54
- if user_at_host:
55
- return is_remote_dir(path, user_at_host)
58
+ if get_user_pass_host_key(**kwargs):
59
+ return is_remote_dir(path, **kwargs)
56
60
  return is_local_dir(path)
57
61
 
58
-
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
59
68
  # --- Optional: keep your original all-in-one wrapper ------------------------
60
69
  def check_path_type(
61
70
  path: str,
62
- user_at_host: Optional[str] = None,
71
+ *args,
72
+ **kwargs
63
73
  ) -> str:
64
74
  """
65
75
  Return 'file', 'directory', 'missing', or 'unknown'.
66
76
  Uses isolated is_file/is_dir functions.
67
77
  """
68
- if user_at_host:
69
- if is_remote_file(path, user_at_host):
78
+ if get_user_pass_host_key(**kwargs):
79
+ if is_remote_file(path,**kwargs):
70
80
  return "file"
71
- elif is_remote_dir(path, user_at_host):
81
+ elif is_remote_dir(path,**kwargs):
72
82
  return "directory"
73
83
  else:
74
84
  return "missing"
@@ -1,5 +1,4 @@
1
1
  from .constants import *
2
2
  from .module_imports import *
3
3
  from .classes import *
4
- from .file_functions import *
5
4
  from .imports import *
@@ -62,205 +62,4 @@ from pprint import pprint
62
62
  # AUTO-EXPORT ALL NON-PRIVATE NAMES
63
63
  # ============================================================
64
64
  __all__ = [name for name in globals() if not name.startswith("_")]
65
- from abstract_utilities import read_from_file,eatAll,inspect, os
66
- import_tag = 'import '
67
- from_tag = 'from '
68
- def get_caller_path(i=None):
69
- i = i or 1
70
- frame = inspect.stack()[i]
71
- return os.path.abspath(frame.filename)
72
- def make_list(obj:any) -> list:
73
- """
74
- Converts the input object to a list. If the object is already a list, it is returned as is.
75
-
76
- Args:
77
- obj: The object to convert.
78
-
79
- Returns:
80
- list: The object as a list.
81
- """
82
- if isinstance(obj,str):
83
- if ',' in obj:
84
- obj = obj.split(',')
85
- if isinstance(obj,set) or isinstance(obj,tuple):
86
- return list(obj)
87
- if isinstance(obj, list):
88
- return obj
89
- return [obj]
90
- def getAlphas(lower=True,capitalize=False,listObj=False):
91
- obj = ''
92
- alphas = 'abcdefghijklmoprstuvwxyz'
93
- if lower:
94
- obj+=alphas
95
- if capitalize:
96
- obj+=alphas.upper()
97
- if listObj:
98
- obj = list(obj)
99
- return obj
100
- def getInts(string=False,listObj=False):
101
- obj=12345678909
102
- if string:
103
- obj = str(obj)
104
- if listObj:
105
- obj = list(obj)
106
- return obj
107
- def get_alpha_ints(ints=True,alpha=True,lower=True,capitalize=True,string=True,listObj=True):
108
- objs = [] if listObj else ""
109
- if ints:
110
- objs+=getInts(string=string,listObj=listObj)
111
- if alpha:
112
- objs+=getAlphas(lower=lower,capitalize=capitalize,listObj=listObj)
113
- return objs
114
- def eatElse(
115
- stringObj,
116
- chars=None,
117
- ints=True,
118
- alpha=True,
119
- lower=True,
120
- capitalize=True,
121
- string=True,
122
- listObj=True
123
- ):
124
- alpha_ints = get_alpha_ints(
125
- ints=True,
126
- alpha=True,
127
- lower=True,
128
- capitalize=True,
129
- string=True,
130
- listObj=True
131
- )
132
- chars = make_list(chars or [])+alpha_ints
133
65
 
134
- while True:
135
- if stringObj:
136
- str_0 = stringObj[0] not in chars
137
- str_1 = stringObj[-1] not in chars
138
- str_eat = str_0 or str_1
139
- if not str_eat:
140
- return stringObj
141
- if stringObj and str_0:
142
- stringObj = stringObj[1:] if len(stringObj) !=1 else ""
143
- if stringObj and str_1:
144
- stringObj = stringObj[:-1] if len(stringObj) !=1 else ""
145
- else:
146
- return stringObj
147
- def clean_line(line):
148
- return eatAll(line,[' ','','\t','\n'])
149
- def is_line_import(line):
150
- if line and (line.startswith(from_tag) or line.startswith(import_tag)):
151
- return True
152
- return False
153
- def is_line_group_import(line):
154
- if line and (line.startswith(from_tag) and import_tag in line):
155
- return True
156
- return False
157
- def get_import_pkg(line):
158
- if is_line_group_import(line):
159
-
160
- return clean_line(line.split(from_tag)[1].split(import_tag)[0])
161
- def get_imports_from_import_pkg(line):
162
- if is_line_group_import(line):
163
- return get_cleaned_import_list(line,commaClean=True)
164
- def add_imports_to_import_pkg_js(import_pkg,imports,import_pkg_js=None):
165
- import_pkg_js = import_pkg_js or {}
166
- imports = clean_imports(imports)
167
- if import_pkg not in import_pkg_js:
168
- i = len(import_pkg_js["nulines"])
169
- import_pkg_js[import_pkg]={"imports":imports,"line":i}
170
- import_line = f"from {import_pkg} import "
171
- if import_pkg == "import":
172
- import_line = import_tag
173
- import_pkg_js["nulines"].append(import_line)
174
- else:
175
- import_pkg_js[import_pkg]["imports"]+=imports
176
- return import_pkg_js
177
- def update_import_pkg_js(line,import_pkg_js=None):
178
- import_pkg_js = import_pkg_js or {}
179
- if is_line_group_import(line):
180
- import_pkg = get_import_pkg(line)
181
- imports = get_imports_from_import_pkg(line)
182
- import_pkg_js = add_imports_to_import_pkg_js(import_pkg,imports,import_pkg_js=import_pkg_js)
183
- else:
184
- if len(import_pkg_js["nulines"]) >0 and line == '' and is_line_import(import_pkg_js["nulines"][-1]):
185
- pass
186
- else:
187
- import_pkg_js["nulines"].append(line)
188
- return import_pkg_js
189
- def is_from_line_group(line):
190
- if line and line.startswith(from_tag) and import_tag in line and '(' in line:
191
- import_spl = line.split(import_tag)[-1]
192
- import_spl_clean = clean_line(line)
193
- if not import_spl_clean.endswith(')'):
194
- return True
195
- return False
196
- def clean_imports(imports,commaClean=True):
197
- chars=["*"]
198
- if not commaClean:
199
- chars.append(',')
200
- if isinstance(imports,str):
201
- imports = imports.split(',')
202
- return [eatElse(imp,chars=chars) for imp in imports if imp]
203
- def get_cleaned_import_list(line,commaClean=True):
204
- cleaned_import_list=[]
205
- if import_tag in line:
206
- imports = line.split(import_tag)[1]
207
- cleaned_import_list+=clean_imports(imports,commaClean=commaClean)
208
- return cleaned_import_list
209
- def combine_lone_imports(text=None,file_path=None,write=False):
210
- text = text or ''
211
- imports_js = {}
212
- if file_path and os.path.isfile(file_path):
213
- text+=read_from_file(file_path)
214
- lines = text.split('\n')
215
- cleaned_import_list=[]
216
- nu_lines = []
217
- j=None
218
- is_from_group = False
219
- import_pkg_js={"nulines":[]}
220
- for line in lines:
221
- if line.startswith(import_tag) and ' from ' not in line:
222
- cleaned_import_list = get_cleaned_import_list(line)
223
- import_pkg_js = add_imports_to_import_pkg_js("import",cleaned_import_list,import_pkg_js=import_pkg_js)
224
- else:
225
- if is_from_group:
226
- import_pkg=is_from_group
227
- line = clean_line(line)
228
- if line.endswith(')'):
229
- is_from_group=False
230
- line=line[:-1]
231
- imports_from_import_pkg = clean_imports(line)
232
- import_pkg_js = add_imports_to_import_pkg_js(import_pkg,imports_from_import_pkg,import_pkg_js=import_pkg_js)
233
-
234
- else:
235
- import_pkg_js=update_import_pkg_js(line,import_pkg_js=import_pkg_js)
236
- if is_from_line_group(line) and is_from_group == False:
237
-
238
- is_from_group=get_import_pkg(line)
239
- nu_lines = import_pkg_js["nulines"]
240
- for pkg,values in import_pkg_js.items():
241
- comments = []
242
- if pkg != "nulines":
243
- line = values.get('line')
244
- imports = values.get('imports')
245
- for i,imp in enumerate(imports):
246
- if '#' in imp:
247
- imp_spl = imp.split('#')
248
- comments.append(imp_spl[-1])
249
- imports[i] = clean_line(imp_spl[0])
250
- imports = list(set(imports))
251
- if '*' in imports:
252
- imports="*"
253
- else:
254
- imports=','.join(imports)
255
- if comments:
256
- comments=','.join(comments)
257
- imports+=f" #{comments}"
258
-
259
- nu_lines[line] += imports
260
- contents = '\n'.join(nu_lines)
261
- if file_path and write:
262
- write_to_file(contents=contents,file_path=file_path)
263
- return contents
264
- abs_path = get_caller_path()
265
- nu_contents = combine_lone_imports(file_path=abs_path)
266
- input(nu_contents)
@@ -15,12 +15,13 @@ Usage:
15
15
  import os
16
16
  import shlex
17
17
  from .ssh_utils.utils import run_cmd,get_print_sudo_cmd,run_local_cmd,run_remote_cmd
18
- from .file_utils.file_utils.type_checks import is_file,is_dir
18
+ from .file_utils.file_utils.type_checks import is_file,is_dir,get_user_pass_host_key,is_exists
19
19
  from .abstract_classes import run_pruned_func
20
+ from .string_utils import get_from_kwargs
20
21
  _FILE_PATH_KEYS = ['file', 'filepath', 'file_path', 'path', 'directory', 'f', 'dst', 'dest']
21
22
  _CONTENTS_KEYS = ['cont', 'content', 'contents', 'data', 'datas', 'dat', 'src', 'source']
22
23
 
23
-
24
+
24
25
  # --- Helper utilities --------------------------------------------------------
25
26
  def string_in_keys(strings, kwargs):
26
27
  """Find a matching keyword in kwargs that contains any of the given substrings."""
@@ -30,25 +31,60 @@ def string_in_keys(strings, kwargs):
30
31
  return key
31
32
  return None
32
33
 
33
-
34
- def get_path(paths):
34
+ def make_dirs(path,exist_ok=True,**kwargs):
35
+ if exist_ok or (not exist_ok and not is_dir(path,**kwargs)):
36
+ if get_user_pass_host_key(**kwargs):
37
+ kwargs['cmd']=f"mkdir {path}"
38
+ run_pruned_func(run_cmd,**kwargs)
39
+ else:
40
+ os.makedirs(path,exist_ok=exist_ok)
41
+ return path
42
+ def path_join(*args):
43
+ path = None
44
+ for i,arg in enumerate(args):
45
+ if arg:
46
+ if i == 0:
47
+ path = arg
48
+ else:
49
+ path = os.path.join(path,arg)
50
+ return path
51
+ def make_path(path,home_dir=None,file=None,**kwargs):
52
+ if path:
53
+ basename = os.path.basename(path)
54
+ parts = path.split('/')
55
+ parts = [part for part in parts if part]
56
+
57
+ full_dir = home_dir or ''
58
+ if file == True or (file == None and ('.' in basename)):
59
+ pieces = parts[:-1] if len(parts) > 1 else []
60
+ else:
61
+ pieces=parts
62
+ basename=None
63
+ for piece in pieces:
64
+ full_dir = os.path.join(full_dir,piece)
65
+ make_dirs(full_dir,exist_ok=True,**kwargs)
66
+ if basename:
67
+ full_dir=path_join(full_dir,basename)
68
+ print(f"full_dir == {full_dir}")
69
+ return full_dir
70
+ def get_path(paths,**kwargs):
35
71
  """Return the first valid path among given paths."""
36
72
  for path in paths:
37
73
  if isinstance(path, str):
38
- if os.path.isfile(path):
74
+ if is_file(path,**kwargs):
39
75
  return path
40
76
  dirname = os.path.dirname(path)
41
- if os.path.exists(dirname):
77
+ if is_exists(dirname,**kwargs):
42
78
  return path
43
79
  return None
44
80
 
45
81
 
46
- def break_down_find_existing(path):
82
+ def break_down_find_existing(path,**kwargs):
47
83
  """Return the first non-existent subpath within a path chain."""
48
84
  test_path = ''
49
85
  for part in path.split(os.sep):
50
86
  test_path = os.path.join(test_path, part)
51
- if not os.path.exists(test_path):
87
+ if not is_exists(test_path,**kwargs):
52
88
  return test_path if test_path else None
53
89
  return test_path
54
90
 
@@ -97,8 +133,8 @@ def write_to_path(
97
133
 
98
134
  # shell command that fully overwrites
99
135
  # (no append, replaces contents entirely)
100
- base_cmd = f"echo {quoted_data} > {quoted_path}"
101
-
136
+ base_cmd = f'sudo sh -c "echo {quoted_data} > {quoted_path}"'
137
+ input(base_cmd)
102
138
  # optional sudo password injection
103
139
  full_cmd = get_print_sudo_cmd(
104
140
  cmd=base_cmd,
@@ -150,29 +186,37 @@ def write_to_file(*args, **kwargs):
150
186
  Returns the file_path written.
151
187
  """
152
188
  file_path, contents = check_read_write_params(*args, **kwargs)
189
+ values,kwargs = get_from_kwargs(['file_path','contents'],del_kwarg=True,**kwargs)
190
+ dirname = os.path.dirname(file_path)
191
+
153
192
  if contents is None:
154
193
  raise ValueError("Missing contents to write.")
155
194
  user_at_host = kwargs.get("user_at_host")
156
- if user_at_host:
195
+ if get_user_pass_host_key(**kwargs):
196
+ make_dirs(dirname, exist_ok=True,**kwargs)
157
197
  kwargs["cwd"] = kwargs.get('cwd') or os.path.dirname(file_path)
158
198
  # sanitize for shell safety
159
199
  quoted_path = shlex.quote(file_path)
160
200
  quoted_data = shlex.quote(str(contents))
161
201
  # shell command that fully overwrites
162
202
  # (no append, replaces contents entirely)
163
- kwargs["cmd"] = f"echo {quoted_data} > {quoted_path}"
164
- return run_pruned_func(run_cmd,**kwargs)
165
-
166
-
167
- os.makedirs(os.path.dirname(file_path) or ".", exist_ok=True)
203
+ kwargs["cmd"] = f'sh -c "echo {quoted_data} > {quoted_path}"'
204
+ if not kwargs.get('password') and not kwargs.get('key'):
205
+ kwargs["cmd"]=f'sudo {kwargs["cmd"]}'
206
+ result = run_pruned_func(run_cmd,**kwargs)
207
+ if not is_file(file_path,**kwargs) or str(contents) != read_from_file(file_path,**kwargs):
208
+ kwargs["cmd"]=f'sudo {kwargs["cmd"]}'
209
+ result = run_pruned_func(run_cmd,**kwargs)
210
+ return result
211
+
212
+ make_dirs(dirname or ".", exist_ok=True)
168
213
  with open(file_path, "w", encoding="utf-8") as f:
169
214
  f.write(str(contents))
170
215
  return file_path
171
216
 
172
217
 
173
218
  def read_from_file(file_path,**kwargs):
174
- user_at_host = kwargs.get("user_at_host")
175
- if user_at_host:
219
+ if get_user_pass_host_key(**kwargs):
176
220
  kwargs["cwd"] = kwargs.get('cwd') or os.path.dirname(file_path)
177
221
  basename = os.path.basename(file_path)
178
222
  kwargs["cmd"] = f'cat {basename}'
@@ -180,7 +224,36 @@ def read_from_file(file_path,**kwargs):
180
224
  """Read text content from a file."""
181
225
  with open(file_path, "r", encoding="utf-8") as f:
182
226
  return f.read()
183
-
227
+ def get_rel_path(src,src_rel,directory):
228
+ if src.startswith(src_rel):
229
+ src = src[len(src_rel):]
230
+ rel_path = os.path.join(directory,src)
231
+ return rel_path
232
+ def make_relative_path(src,src_rel,dst,**kwargs):
233
+ print(f"src == {src}\nsrc_rel == {src_rel}\dst == {dst}")
234
+ if src.startswith(src_rel):
235
+ rel_path = get_rel_path(src,src_rel,dst)
236
+ path = make_path(src,home_dir=rel_path,**kwargs)
237
+ print(f"path == {path}")
238
+ return path
239
+ def copy_dirs(dirs,dst,src_rel=None,**kwargs):
240
+ for src in dirs:
241
+ if rel_path:
242
+ dst = make_relative_path(src,src_rel,dst,**kwargs)
243
+ make_path(dst,**kwargs)
244
+
245
+ def copy_file(src,dst,rel_path=None,**kwargs):
246
+ if rel_path:
247
+ dst = make_relative_path(src,rel_path,dst,**kwargs)
248
+ if get_user_pass_host_key(**kwargs):
249
+ contents=read_from_file(src,**kwargs)
250
+ write_to_file(contents=contents,file_path=dst,**kwargs)
251
+ else:
252
+ shutil.copy(src,dst)
253
+ return dst
254
+ def copy_files(files,dst,rel_path=None,**kwargs):
255
+ for file in files:
256
+ copy_file(src=file,dst=dst,rel_path=rel_path,**kwargs)
184
257
 
185
258
  def create_and_read_file(*args, **kwargs):
186
259
  """
@@ -1,87 +1,16 @@
1
- from abstract_utilities import read_from_file,eatAll,inspect, os
1
+ from ...read_write_utils import read_from_file,write_to_file
2
+ from ...string_clean import eatAll,eatElse,clean_line
3
+ from ...class_utils import get_caller_path
4
+ from ...list_utils import make_list
5
+ import os
2
6
  import_tag = 'import '
3
7
  from_tag = 'from '
4
- def get_caller_path(i=None):
5
- i = i or 1
6
- frame = inspect.stack()[i]
7
- return os.path.abspath(frame.filename)
8
- def make_list(obj:any) -> list:
9
- """
10
- Converts the input object to a list. If the object is already a list, it is returned as is.
11
-
12
- Args:
13
- obj: The object to convert.
14
-
15
- Returns:
16
- list: The object as a list.
17
- """
18
- if isinstance(obj,str):
19
- if ',' in obj:
20
- obj = obj.split(',')
21
- if isinstance(obj,set) or isinstance(obj,tuple):
22
- return list(obj)
23
- if isinstance(obj, list):
24
- return obj
25
- return [obj]
26
- def getAlphas(lower=True,capitalize=False,listObj=False):
27
- obj = ''
28
- alphas = 'abcdefghijklmoprstuvwxyz'
29
- if lower:
30
- obj+=alphas
31
- if capitalize:
32
- obj+=alphas.upper()
33
- if listObj:
34
- obj = list(obj)
35
- return obj
36
- def getInts(string=False,listObj=False):
37
- obj=12345678909
38
- if string:
39
- obj = str(obj)
40
- if listObj:
41
- obj = list(obj)
42
- return obj
43
- def get_alpha_ints(ints=True,alpha=True,lower=True,capitalize=True,string=True,listObj=True):
44
- objs = [] if listObj else ""
45
- if ints:
46
- objs+=getInts(string=string,listObj=listObj)
47
- if alpha:
48
- objs+=getAlphas(lower=lower,capitalize=capitalize,listObj=listObj)
49
- return objs
50
- def eatElse(
51
- stringObj,
52
- chars=None,
53
- ints=True,
54
- alpha=True,
55
- lower=True,
56
- capitalize=True,
57
- string=True,
58
- listObj=True
59
- ):
60
- alpha_ints = get_alpha_ints(
61
- ints=True,
62
- alpha=True,
63
- lower=True,
64
- capitalize=True,
65
- string=True,
66
- listObj=True
67
- )
68
- chars = make_list(chars or [])+alpha_ints
69
-
70
- while True:
71
- if stringObj:
72
- str_0 = stringObj[0] not in chars
73
- str_1 = stringObj[-1] not in chars
74
- str_eat = str_0 or str_1
75
- if not str_eat:
76
- return stringObj
77
- if stringObj and str_0:
78
- stringObj = stringObj[1:] if len(stringObj) !=1 else ""
79
- if stringObj and str_1:
80
- stringObj = stringObj[:-1] if len(stringObj) !=1 else ""
81
- else:
82
- return stringObj
83
- def clean_line(line):
84
- return eatAll(line,[' ','','\t','\n'])
8
+ def get_text_or_read(text=None,file_path=None):
9
+ text = text or ''
10
+ imports_js = {}
11
+ if not text and file_path and os.path.isfile(file_path):
12
+ text=read_from_file(file_path)
13
+ return text
85
14
  def is_line_import(line):
86
15
  if line and (line.startswith(from_tag) or line.startswith(import_tag)):
87
16
  return True
@@ -92,27 +21,11 @@ def is_line_group_import(line):
92
21
  return False
93
22
  def get_import_pkg(line):
94
23
  if is_line_group_import(line):
95
-
96
24
  return clean_line(line.split(from_tag)[1].split(import_tag)[0])
97
25
  def get_imports_from_import_pkg(line):
98
26
  if is_line_group_import(line):
99
27
  return get_cleaned_import_list(line,commaClean=True)
100
- ##def is_local_or_import(pkg_name,file_path):
101
- ## dirname = os.path.dirname(file_path)
102
- ## parts = part for part in dirname.split('/') if part]
103
- ## i=0
104
- ## pkg = pkg_name
105
- ## while True:
106
- ## if pkg and pkg.startswith('.'):
107
- ## i +=1
108
- ## pkg=pkg[1:] if len(pkg)>1 else ""
109
- ## else:
110
- ## if i > 1 and len(parts)>=i:
111
- ## pkg = '.'.join(parts[:-i])
112
- ## .{pkg}"
113
- ## parts
114
-
115
-
28
+
116
29
  def add_imports_to_import_pkg_js(import_pkg,imports,import_pkg_js=None):
117
30
  import_pkg_js = import_pkg_js or {}
118
31
  imports = clean_imports(imports)
@@ -158,17 +71,32 @@ def get_cleaned_import_list(line,commaClean=True):
158
71
  imports = line.split(import_tag)[1]
159
72
  cleaned_import_list+=clean_imports(imports,commaClean=commaClean)
160
73
  return cleaned_import_list
161
- def clean_imports(text=None,file_path=None,write=False):
162
- text = text or ''
163
- imports_js = {}
164
- if file_path and os.path.isfile(file_path):
165
- text+=read_from_file(file_path)
74
+ def get_all_imports(text=None,file_path=None,import_pkg_js=None):
75
+ text = get_text_or_read(text=text,file_path=file_path)
166
76
  lines = text.split('\n')
167
77
  cleaned_import_list=[]
168
78
  nu_lines = []
169
- j=None
170
79
  is_from_group = False
171
- import_pkg_js={"nulines":[],"file_path":file_path}
80
+ import_pkg_js = import_pkg_js or {}
81
+ if "nulines" not in import_pkg_js:
82
+ import_pkg_js["nulines"]=[]
83
+ if "file_path" not in import_pkg_js:
84
+ import_pkg_js["file_path"]=file_path
85
+ if "all_data" not in import_pkg_js:
86
+ import_pkg_js["all_data"]=[]
87
+ if file_path and file_path != import_pkg_js["file_path"]:
88
+ found=False
89
+ nu_data = {"file_path":import_pkg_js["file_path"],"nulines":import_pkg_js["nulines"]}
90
+ for i,data in enumerate(import_pkg_js["all_data"]):
91
+ if data.get('file_path') == import_pkg_js["file_path"]:
92
+ import_pkg_js["all_data"][i] = nu_data
93
+ found = True
94
+ break
95
+ if found == False:
96
+ import_pkg_js["all_data"].append(nu_data)
97
+ import_pkg_js["nulines"]=[]
98
+ import_pkg_js["file_path"]=file_path
99
+
172
100
  for line in lines:
173
101
  if line.startswith(import_tag) and ' from ' not in line:
174
102
  cleaned_import_list = get_cleaned_import_list(line)
@@ -186,12 +114,15 @@ def clean_imports(text=None,file_path=None,write=False):
186
114
  else:
187
115
  import_pkg_js=update_import_pkg_js(line,import_pkg_js=import_pkg_js)
188
116
  if is_from_line_group(line) and is_from_group == False:
189
-
190
117
  is_from_group=get_import_pkg(line)
118
+ return import_pkg_js
119
+ def clean_all_imports(text=None,file_path=None,import_pkg_js=None):
120
+ if not import_pkg_js:
121
+ import_pkg_js = get_all_imports(text=text,file_path=file_path)
191
122
  nu_lines = import_pkg_js["nulines"]
192
123
  for pkg,values in import_pkg_js.items():
193
124
  comments = []
194
- if pkg not in ["nulines","file_path"]:
125
+ if pkg not in ["nulines","file_path","all_data"]:
195
126
  line = values.get('line')
196
127
  imports = values.get('imports')
197
128
  for i,imp in enumerate(imports):
@@ -207,9 +138,38 @@ def clean_imports(text=None,file_path=None,write=False):
207
138
  if comments:
208
139
  comments=','.join(comments)
209
140
  imports+=f" #{comments}"
210
-
141
+ import_pkg_js[pkg]["imports"]=imports
211
142
  nu_lines[line] += imports
212
- contents = '\n'.join(nu_lines)
143
+ import_pkg_js["nulines"]=nu_lines
144
+ return import_pkg_js
145
+
146
+ def get_all_real_imps(file):
147
+ contents = read_from_file(file)
148
+ lines = contents.split('\n')
149
+ for line in lines:
150
+ if line.startswith('from '):
151
+ from_line = line.split('from ')[-1]
152
+ dot_fro = ""
153
+ dirname = file
154
+ for char in from_line:
155
+ if char != '.':
156
+ line = f"from {dot_fro}{eatAll(from_line,'.')}"
157
+ if line in all_imps:
158
+ line = ""
159
+ break
160
+ if dot_fro == "":
161
+ dot_fro = ""
162
+ dirname = os.path.dirname(dirname)
163
+ dirbase = os.path.basename(dirname)
164
+ dot_fro = f"{dirbase}.{dot_fro}"
165
+ if line:
166
+ all_imps.append(line)
167
+
168
+ return '\n'.join(all_imps)
169
+ def save_cleaned_imports(text=None,file_path=None,write=False,import_pkg_js=None):
170
+ import_pkg_js=get_all_imports(text=text,file_path=file_path,import_pkg_js=import_pkg_js)
171
+ import_pkg_js = clean_all_imports(text=text,file_path=file_path,import_pkg_js=import_pkg_js)
172
+ contents = '\n'.join(import_pkg_js["nulines"])
213
173
  if file_path and write:
214
174
  write_to_file(contents=contents,file_path=file_path)
215
175
  return contents
@@ -22,6 +22,8 @@ Date: 05/31/2023
22
22
  Version: 0.1.2
23
23
  """
24
24
  import os
25
+ from .list_utils import make_list
26
+ from .type_utils import get_alpha_ints
25
27
  def quoteIt(st: str, ls: list) -> str:
26
28
  """
27
29
  Quotes specific elements in a string.
@@ -110,6 +112,42 @@ def eatAll(string: str, list_objects:(str or list)) -> any:
110
112
  if string and list_objects:
111
113
  string = eatOuter(string, list_objects)
112
114
  return string
115
+
116
+
117
+
118
+ def eatElse(
119
+ stringObj,
120
+ chars=None,
121
+ ints=True,
122
+ alpha=True,
123
+ lower=True,
124
+ capitalize=True,
125
+ string=True,
126
+ listObj=True
127
+ ):
128
+ alpha_ints = get_alpha_ints(
129
+ ints=True,
130
+ alpha=True,
131
+ lower=True,
132
+ capitalize=True,
133
+ string=True,
134
+ listObj=True
135
+ )
136
+ chars = make_list(chars or [])+alpha_ints
137
+
138
+ while True:
139
+ if stringObj:
140
+ str_0 = stringObj[0] not in chars
141
+ str_1 = stringObj[-1] not in chars
142
+ str_eat = str_0 or str_1
143
+ if not str_eat:
144
+ return stringObj
145
+ if stringObj and str_0:
146
+ stringObj = stringObj[1:] if len(stringObj) !=1 else ""
147
+ if stringObj and str_1:
148
+ stringObj = stringObj[:-1] if len(stringObj) !=1 else ""
149
+ else:
150
+ return stringObj
113
151
  def safe_split(obj, ls):
114
152
  """
115
153
  Safely splits a string using multiple delimiters.
@@ -185,6 +223,7 @@ def url_join(*paths):
185
223
  final_path = f"{final_path}/{path}"
186
224
  return final_path
187
225
 
188
-
226
+ def clean_line(line):
227
+ return eatAll(line,[' ','','\t','\n'])
189
228
  def capitalize(string):
190
229
  return string[:1].upper() + string[1:].lower() if string else string
@@ -1,3 +1,42 @@
1
+ from .list_utils import make_list
2
+ def get_from_kwargs(*args,**kwargs):
3
+ del_kwarg = kwargs.get('del_kwargs',False)
4
+ values = {}
5
+ for key in args:
6
+ if key:
7
+ key = str(key)
8
+ if key in kwargs:
9
+ values[key] = kwargs.get(key)
10
+ if del_kwarg:
11
+ del kwargs[key]
12
+ return values,kwargs
13
+
14
+ def replace_it(string,item,rep):
15
+ if item in string:
16
+ string = string.replace(item,rep)
17
+ return string
18
+ def while_replace(string,item,rep):
19
+ while True:
20
+ string = replace_it(string,item,rep)
21
+ if item not in string or item in rep:
22
+ return string
23
+ def for_replace(string,item,replace):
24
+ replace = make_list(replace)
25
+ for rep in replace:
26
+ string = while_replace(string,item,rep)
27
+ return string
28
+ def replace_all(string,*args,**kwargs):
29
+ for items in args:
30
+ if items and isinstance(items,list):
31
+ item = items[0]
32
+ replace = items[1:] if len(items)>1 else items[-1]
33
+ string = for_replace(string,item,replace)
34
+ values,kwargs = get_from_kwargs('item','replace',**kwargs)
35
+ if values:
36
+ string = for_replace(string,**values)
37
+ for item,replace in kwargs.items():
38
+ string = for_replace(string,item,rep)
39
+ return string
1
40
  def get_lines(string,strip=True):
2
41
  lines = string.split('\n')
3
42
  if strip:
@@ -60,6 +60,7 @@ import os
60
60
  from pathlib import Path
61
61
  from typing import Union
62
62
  from .list_utils import make_list
63
+
63
64
  # A big, but by no means exhaustive, map of extensions to mime‐types by category:
64
65
  MIME_TYPES = {
65
66
  'image': {
@@ -936,7 +937,30 @@ def is_any_instance(value):
936
937
  for each in [dict, list, int, float]:
937
938
  if is_instance(value, each):
938
939
  return True
939
-
940
+ def getAlphas(lower=True,capitalize=False,listObj=False):
941
+ obj = ''
942
+ alphas = 'abcdefghijklmoprstuvwxyz'
943
+ if lower:
944
+ obj+=alphas
945
+ if capitalize:
946
+ obj+=alphas.upper()
947
+ if listObj:
948
+ obj = list(obj)
949
+ return obj
950
+ def getInts(string=False,listObj=False):
951
+ obj=12345678909
952
+ if string:
953
+ obj = str(obj)
954
+ if listObj:
955
+ obj = list(obj)
956
+ return obj
957
+ def get_alpha_ints(ints=True,alpha=True,lower=True,capitalize=True,string=True,listObj=True):
958
+ objs = [] if listObj else ""
959
+ if ints:
960
+ objs+=getInts(string=string,listObj=listObj)
961
+ if alpha:
962
+ objs+=getAlphas(lower=lower,capitalize=capitalize,listObj=listObj)
963
+ return objs
940
964
  # Function: is_number
941
965
  # Function: is_str
942
966
  # Function: is_int
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: abstract_utilities
3
- Version: 0.2.2.468
3
+ Version: 0.2.2.488
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
@@ -1,6 +1,6 @@
1
- abstract_utilities/__init__.py,sha256=aLWUTfocuGa7qoz3Czzvuz0xUNoy7DojHhp2MN5vyPk,5198
1
+ abstract_utilities/__init__.py,sha256=OWG_j_7hFAoQXmi_hwHQg8vSufDSAatj8iax78ZYAJc,5229
2
2
  abstract_utilities/abstract_classes.py,sha256=A6-FNDQb2P_jcyt01Kc5SuY2QawLVKNjQ-rDGfsn4rA,2461
3
- abstract_utilities/class_utils.py,sha256=YMQgeTHSMo2C13G0JRgQIgbx131jb-PHdDrIqt71FsE,13664
3
+ abstract_utilities/class_utils.py,sha256=AJe6kIiAwmr_is458EkKsjH2c0pyIiZNkah2gBXzXAE,13663
4
4
  abstract_utilities/collator_utils.py,sha256=9exNoZAr9rABGYTwZOn7hdLbpnMtRd2AgfU7yjZrXGw,2348
5
5
  abstract_utilities/doit.py,sha256=a1zkyMJbSGPvE-OmCQcH_dQyLME392UfvQmGztOWyhE,1646
6
6
  abstract_utilities/dynimport.py,sha256=BTX33OXfUq4LAuT1RAzLhbtxqf7CTm5WHYdvVAH83nc,6584
@@ -14,14 +14,14 @@ abstract_utilities/log_utils.py,sha256=W74Y-CmdQP4Kj88HmAgejVxWgyWlvgCKMwLvOfyFf
14
14
  abstract_utilities/math_utils.py,sha256=0o1ls1En03UAkYmxTBildCCJDfHygmNuvVnrNrLYtK0,6578
15
15
  abstract_utilities/parse_utils.py,sha256=Z5OGRwHuzCzY91fz0JJojk1BPAo1XF2quNNLuBF4_Vk,18602
16
16
  abstract_utilities/path_utils.py,sha256=X_U9cPBbNu5Wi0F3hQE0gXQX1gfhzxhxALbairTEOZU,19252
17
- abstract_utilities/read_write_utils.py,sha256=S8Sj0mtErRze9uOOzdWl2ZreREdXKKQMbyQKC75c_Vc,6921
17
+ abstract_utilities/read_write_utils.py,sha256=9jW-eQojjXGAtyeCQp2m_1Rx6KgDGp3GHN0jwdqZlcA,9941
18
18
  abstract_utilities/safe_utils.py,sha256=_uoZny6dJjopVakOiaf0UIZcvRRXMh51FpfDUooe0xY,3733
19
- abstract_utilities/string_clean.py,sha256=-gY9i2yqjX5UClvSaKsSrzA4GjR7eaNI3GnFjZpt2bo,5923
20
- abstract_utilities/string_utils.py,sha256=02xdIEDySWEexrtY3skBYOdeDmr3XgE5j1nqAeAv7w8,352
19
+ abstract_utilities/string_clean.py,sha256=oQv85J-mA4sP2NJwbTI-1k0RXw7V0AmqZolYaAZvex4,6916
20
+ abstract_utilities/string_utils.py,sha256=PnII0wFQBchVzFjhvEHP9ej1zxLehsRKodtc8Qol4-8,1645
21
21
  abstract_utilities/tetsts.py,sha256=PrejTUew5dAAqNb4erMJwfdSHxDyuuHGWY2fMlWk5hk,21
22
22
  abstract_utilities/thread_utils.py,sha256=LhE1ylSuOKkkMErBf6SjZprjO_vfh3IKfvNKJQiCxho,5460
23
23
  abstract_utilities/time_utils.py,sha256=yikMjn7i-OBKfmOujfNtDz4R0VTMgi3dfQNrCIZUbQU,13052
24
- abstract_utilities/type_utils.py,sha256=1gpwfG5ze8dTUi7IXnMc65vHrw8XgI0F8m6x4esZavI,26977
24
+ abstract_utilities/type_utils.py,sha256=XaaAel9hUKeOzBqSCqJsIC6UiPMXUlhtmU77jOHz8Ek,27676
25
25
  abstract_utilities/utils.py,sha256=SCa_-x_wsWrcokQXKwlhalxndxLn5Wg25-zqRdJUmag,185049
26
26
  abstract_utilities/cmd_utils/__init__.py,sha256=StTaaB9uzJexvr4TFGVqp_o0_s9T6rQlE3fOZtb_y_0,51
27
27
  abstract_utilities/cmd_utils/cmd_utils.py,sha256=n2DEo91J8LWuIJoSoDkWdApUY_8mHrUW3kjEjjF34Io,7876
@@ -50,18 +50,18 @@ abstract_utilities/file_utils/file_utils/find_collect.py,sha256=bPM7EDrNHlvwZx7C
50
50
  abstract_utilities/file_utils/file_utils/imports.py,sha256=rF3zdWY98UKuSPwzEzhG0H4cfIVjLqCW3FwsGqFeakE,319
51
51
  abstract_utilities/file_utils/file_utils/map_utils.py,sha256=B_MlkLP8s-o0yU0R3Y2LcTpBntBzysJO18qq181xz9c,1043
52
52
  abstract_utilities/file_utils/file_utils/pdf_utils.py,sha256=D_wg8h-SapCvqinxRIKxMri1jWZNpr5jGvKq9EJePfY,10335
53
- abstract_utilities/file_utils/file_utils/type_checks.py,sha256=S1k5lDM1Qd5g1FE_KqIE1aWexsFI0Af9droRI6qVb30,2576
54
- abstract_utilities/file_utils/file_utils/imports/__init__.py,sha256=HfwhvZsAnwy9J5jF1QXsxhN60v9EzMBSZXZx7H9PR6Q,103
53
+ abstract_utilities/file_utils/file_utils/type_checks.py,sha256=XuKDtdYJFNHATZX3VcWLatqqcvyxl7is-bEZKxWglpE,2890
54
+ abstract_utilities/file_utils/file_utils/imports/__init__.py,sha256=Mip2n-nY1PLvaWtwTeVs0rdVd6J3_jfwKmIyGYxf9Vo,72
55
55
  abstract_utilities/file_utils/file_utils/imports/constants.py,sha256=eIeSj48vtfa8CTYKuuZXbgJQepBrMracfVguaSuN41U,1626
56
56
  abstract_utilities/file_utils/file_utils/imports/file_functions.py,sha256=25yta20DDsdgenXYjpm4Ma3Fd6WK9Q16EjyhcZubDFg,291
57
57
  abstract_utilities/file_utils/file_utils/imports/imports.py,sha256=nLtDCj-E9htQ1rbbISevHSqviUGCxgCoTZ7KTAQrCpU,1488
58
- abstract_utilities/file_utils/file_utils/imports/module_imports.py,sha256=pvRkjtWxQ9R4TisCKMQ9asDak63Y9eMGbpCB7DsEyqs,453
59
- abstract_utilities/file_utils/imports/__init__.py,sha256=T-vdIj87HUj6H9tWMA67gNoEwLjnkMmEJpX5fN144fI,131
58
+ abstract_utilities/file_utils/file_utils/imports/module_imports.py,sha256=BG_eTb_lnOOHCye_aXYc0CoESzFtXw_8qMMEH3CPLmU,546
59
+ abstract_utilities/file_utils/imports/__init__.py,sha256=PRJBiiPT7oElD3RvHTW80Xd5rIIMdzGN23FD5IkszDI,101
60
60
  abstract_utilities/file_utils/imports/classes.py,sha256=zw16D_h5AxJiks4ydbqkWkXVfvgmE-BpiC4eKInY_KI,12259
61
61
  abstract_utilities/file_utils/imports/clean_imps.py,sha256=DB_NEKR8YLla5qCkTMuNscMoTnipEm3nCWnaH8wqQDc,5287
62
62
  abstract_utilities/file_utils/imports/constants.py,sha256=eIeSj48vtfa8CTYKuuZXbgJQepBrMracfVguaSuN41U,1626
63
63
  abstract_utilities/file_utils/imports/file_functions.py,sha256=brQha7TV9DaJe-hZSuHoFZBUI_45hxrGOIBTAojPWU8,297
64
- abstract_utilities/file_utils/imports/imports.py,sha256=xsxfaNE7uvdJH8WKUMk1RNTq8CpIC6adAwno96Dmvuc,9147
64
+ abstract_utilities/file_utils/imports/imports.py,sha256=eDvLMtTQlExI1z7ddnPYoXWyrYtp48JuiAzBPqL5wWA,2057
65
65
  abstract_utilities/file_utils/imports/module_imports.py,sha256=BROjglIl217zEuU0kwRilkK9vLrYC9e44AS5HS8HwD0,513
66
66
  abstract_utilities/robust_reader/__init__.py,sha256=4i6qW4lwhdYuoO5-p9Xbt8Lpmr3hzCh9Rgb9y19QJwk,28
67
67
  abstract_utilities/robust_reader/file_reader2.py,sha256=U-5opkLu-bct091Eb-5CiNBTf0UFoSITYi8zR-Sz38w,25077
@@ -73,7 +73,7 @@ abstract_utilities/robust_readers/__init__.py,sha256=_1vhOG1FJnfrRK0ubkT1v6U6udH
73
73
  abstract_utilities/robust_readers/imports.py,sha256=FtNxdPoLeeNycDnl-6rBGxBfYjhQ7VhmI5guj8XKFcU,355
74
74
  abstract_utilities/robust_readers/initFuncGen.py,sha256=nrQn1KpSlPNKoOngN1uizVwNMA4llrcd8aGKqlzpXzI,5436
75
75
  abstract_utilities/robust_readers/import_utils/__init__.py,sha256=0XaHXUzvgMjSV-4VXcBB-sLcXzL3U3ssHZ95YkvgS9w,195
76
- abstract_utilities/robust_readers/import_utils/clean_imports.py,sha256=kl6Ne06YVZDPHgs59qek3m-KmF3xfWWZbJchv0FS8Q4,7483
76
+ abstract_utilities/robust_readers/import_utils/clean_imports.py,sha256=eQo7UvO9jiMY7ncFpHyT-BFLNvov6QA4IRoP7MITuls,7228
77
77
  abstract_utilities/robust_readers/import_utils/dot_utils.py,sha256=pmwnY461mOnDjIjgHD6H9MhQXFaF-q8kWerJDgJ1DuI,2364
78
78
  abstract_utilities/robust_readers/import_utils/function_utils.py,sha256=Q9NKvRov3uAaz2Aal3d6fb_opWNXHF9C8GSKOjgfO8Y,1622
79
79
  abstract_utilities/robust_readers/import_utils/import_utils.py,sha256=l0GYdtj5FEYX2yknL-8ru7_U2Sp9Hi1NpegqWPLRMc8,11705
@@ -86,7 +86,7 @@ abstract_utilities/ssh_utils/classes.py,sha256=3Q9BfLpyagNFYyiF4bt-5UCezeUJv9NK9
86
86
  abstract_utilities/ssh_utils/imports.py,sha256=oX8WAv-pkhizzko_h3fIUp9Vhsse4nR7RN2vwONxIx0,317
87
87
  abstract_utilities/ssh_utils/pexpect_utils.py,sha256=JBdOIXBTXAqE5TrsFjmPWJgwSaWyRJN8rbJ6y3_zKPY,10556
88
88
  abstract_utilities/ssh_utils/utils.py,sha256=smUWAx3nW1h0etTndJ_te9bkUX5YzQ8kYd9_gD1TXLk,4882
89
- abstract_utilities-0.2.2.468.dist-info/METADATA,sha256=9hAVfrsbxq20y58SW5cZC5ORLn4tvmi0-KB59Y2al50,28108
90
- abstract_utilities-0.2.2.468.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
91
- abstract_utilities-0.2.2.468.dist-info/top_level.txt,sha256=BF0GZ0xVFfN1K-hFIWPO3viNsOs1sSF86n1vHBg39FM,19
92
- abstract_utilities-0.2.2.468.dist-info/RECORD,,
89
+ abstract_utilities-0.2.2.488.dist-info/METADATA,sha256=rta42TF8pwLWyBz2dR-dx085mU_Sd-HOpzQLVpeLYro,28108
90
+ abstract_utilities-0.2.2.488.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
91
+ abstract_utilities-0.2.2.488.dist-info/top_level.txt,sha256=BF0GZ0xVFfN1K-hFIWPO3viNsOs1sSF86n1vHBg39FM,19
92
+ abstract_utilities-0.2.2.488.dist-info/RECORD,,