abstract-utilities 0.2.2.583__py3-none-any.whl → 0.2.2.627__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.
- abstract_utilities/__init__.py +11 -3
- abstract_utilities/class_utils/caller_utils.py +1 -0
- abstract_utilities/class_utils/global_utils.py +35 -21
- abstract_utilities/directory_utils/src/directory_utils.py +2 -0
- abstract_utilities/file_utils/imports/module_imports.py +1 -1
- abstract_utilities/file_utils/src/file_filters/ensure_utils.py +3 -1
- abstract_utilities/file_utils/src/file_filters/predicate_utils.py +23 -21
- abstract_utilities/file_utils/src/initFunctionsGen.py +36 -23
- abstract_utilities/file_utils/src/initFunctionsGens.py +280 -0
- abstract_utilities/import_utils/imports/module_imports.py +1 -1
- abstract_utilities/import_utils/src/extract_utils.py +2 -2
- abstract_utilities/import_utils/src/import_functions.py +33 -14
- abstract_utilities/import_utils/src/sysroot_utils.py +1 -1
- abstract_utilities/log_utils/log_file.py +73 -25
- abstract_utilities/parse_utils/parse_utils.py +23 -0
- abstract_utilities/read_write_utils/imports/imports.py +1 -1
- abstract_utilities/read_write_utils/read_write_utils.py +99 -31
- {abstract_utilities-0.2.2.583.dist-info → abstract_utilities-0.2.2.627.dist-info}/METADATA +1 -1
- {abstract_utilities-0.2.2.583.dist-info → abstract_utilities-0.2.2.627.dist-info}/RECORD +21 -20
- {abstract_utilities-0.2.2.583.dist-info → abstract_utilities-0.2.2.627.dist-info}/WHEEL +0 -0
- {abstract_utilities-0.2.2.583.dist-info → abstract_utilities-0.2.2.627.dist-info}/top_level.txt +0 -0
abstract_utilities/__init__.py
CHANGED
|
@@ -34,8 +34,7 @@ from .json_utils import (unified_json_loader,
|
|
|
34
34
|
get_result_from_data,
|
|
35
35
|
flatten_json
|
|
36
36
|
)
|
|
37
|
-
|
|
38
|
-
write_to_file)
|
|
37
|
+
|
|
39
38
|
from .directory_utils import *
|
|
40
39
|
from .path_utils import *
|
|
41
40
|
from .file_utils import *
|
|
@@ -108,7 +107,8 @@ from .parse_utils import (num_tokens_from_string,
|
|
|
108
107
|
chunk_any_to_tokens,
|
|
109
108
|
detect_language_from_text,
|
|
110
109
|
chunk_by_language_context,
|
|
111
|
-
search_code
|
|
110
|
+
search_code,
|
|
111
|
+
get_within_quotes)
|
|
112
112
|
|
|
113
113
|
from .log_utils import get_caller_info,get_logFile,print_or_log,get_json_call_response,initialize_call_log
|
|
114
114
|
from .error_utils import try_func
|
|
@@ -119,3 +119,11 @@ from .path_utils import *
|
|
|
119
119
|
from .file_utils import *
|
|
120
120
|
from .string_utils import *
|
|
121
121
|
from .import_utils import *
|
|
122
|
+
from .read_write_utils import (read_from_file,
|
|
123
|
+
write_to_file,
|
|
124
|
+
make_dirs,
|
|
125
|
+
make_dirs,
|
|
126
|
+
copy_files,
|
|
127
|
+
make_path,
|
|
128
|
+
run_cmd
|
|
129
|
+
)
|
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
import importlib, sys,os
|
|
2
|
+
from .caller_utils import get_initial_caller
|
|
3
|
+
def file_to_module_name(path):
|
|
4
|
+
path = os.path.realpath(path)
|
|
5
|
+
# Find a path that exists in sys.path
|
|
6
|
+
for base in sys.path:
|
|
7
|
+
base = os.path.realpath(base)
|
|
8
|
+
if path.startswith(base):
|
|
9
|
+
rel = os.path.relpath(path, base)
|
|
10
|
+
mod = os.path.splitext(rel)[0]
|
|
11
|
+
return mod.replace(os.sep, ".")
|
|
12
|
+
# fallback (never should be used)
|
|
13
|
+
return os.path.splitext(os.path.basename(path))[0]
|
|
14
|
+
def get_globals_from_path(module_path: str=None):
|
|
15
|
+
module_path = module_path or get_initial_caller()
|
|
16
|
+
module_name = file_to_module_name(module_path)
|
|
17
|
+
if module_name not in sys.modules:
|
|
18
|
+
importlib.import_module(module_name)
|
|
19
|
+
return sys.modules[module_name].__dict__
|
|
1
20
|
def global_registry(name:str,glob:dict):
|
|
2
21
|
global_ledger = if_none_default(string='global_ledger',glob=globals(),default={"registry_names":[],"registry_index":[]})
|
|
3
22
|
if name not in global_ledger['registry_names']:
|
|
@@ -31,27 +50,22 @@ def return_globals() -> dict:
|
|
|
31
50
|
dict: The global variables dictionary.
|
|
32
51
|
"""
|
|
33
52
|
return globals()
|
|
34
|
-
def
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
var (str): The name of the global variable.
|
|
40
|
-
val (any): The new value.
|
|
41
|
-
glob (dict, optional): The dictionary of global variables. Defaults to the current globals.
|
|
42
|
-
|
|
43
|
-
Returns:
|
|
44
|
-
any: The new value of the variable.
|
|
45
|
-
"""
|
|
53
|
+
def get_true_globals():
|
|
54
|
+
return sys.modules['__main__'].__dict__
|
|
55
|
+
def change_glob(var: str, val: any, glob: dict = None) -> any:
|
|
56
|
+
if glob is None:
|
|
57
|
+
glob = get_true_globals()
|
|
46
58
|
glob[var] = val
|
|
47
59
|
return val
|
|
48
|
-
def get_globes(string:str='',glob:dict=return_globals()):
|
|
49
|
-
if string in glob:
|
|
50
|
-
return glob[string]
|
|
51
|
-
def if_none_default(string:str, default:any,glob:dict=return_globals(),typ=None):
|
|
52
|
-
|
|
53
|
-
piece = get_globes(string=string,glob=glob)
|
|
54
|
-
if piece is None or (typ and not isinstance(piece,typ)):
|
|
55
|
-
piece = default
|
|
56
|
-
return change_glob(var=string,val=piece,glob=glob)
|
|
57
60
|
|
|
61
|
+
def get_globes(string: str='', glob: dict=None):
|
|
62
|
+
if glob is None:
|
|
63
|
+
glob = get_true_globals()
|
|
64
|
+
return glob.get(string)
|
|
65
|
+
def if_none_default(string: str, default: any, glob: dict=None, typ=None):
|
|
66
|
+
if glob is None:
|
|
67
|
+
glob = get_true_globals()
|
|
68
|
+
piece = get_globes(string=string, glob=glob)
|
|
69
|
+
if piece is None or (typ and not isinstance(piece, typ)):
|
|
70
|
+
piece = default
|
|
71
|
+
return change_glob(var=string, val=piece, glob=glob)
|
|
@@ -102,7 +102,9 @@ def raw_create_dirs(*paths):
|
|
|
102
102
|
current_path = safe_join(current_path, part)
|
|
103
103
|
os.makedirs(current_path, exist_ok=True)
|
|
104
104
|
return full_path
|
|
105
|
+
|
|
105
106
|
mkdirs=raw_create_dirs
|
|
106
107
|
makedirs = mkdirs
|
|
107
108
|
make_dirs = makedirs
|
|
109
|
+
makeAllDirs = raw_create_dirs
|
|
108
110
|
|
|
@@ -4,5 +4,5 @@ from ...ssh_utils import *
|
|
|
4
4
|
from ...env_utils import *
|
|
5
5
|
from ...read_write_utils import read_from_file,write_to_file
|
|
6
6
|
from ...log_utils import get_logFile
|
|
7
|
-
from ...class_utils import get_caller,get_initial_caller_dir, get_caller_path, get_caller_dir,SingletonMeta,run_pruned_func
|
|
7
|
+
from ...class_utils import if_none_default,if_none_change,get_caller,get_initial_caller_dir, get_caller_path, get_caller_dir,SingletonMeta,run_pruned_func
|
|
8
8
|
|
|
@@ -45,7 +45,9 @@ def ensure_directories(*args,**kwargs):
|
|
|
45
45
|
dirname = os.path.dirname(arg_str)
|
|
46
46
|
directories.append(dirname)
|
|
47
47
|
safe_directories = get_dir_filter_kwargs(**kwargs)
|
|
48
|
-
|
|
48
|
+
safe_dirs = safe_directories.get('directories')
|
|
49
|
+
safe_dirs = if_none_change(safe_dirs or None,get_initial_caller_dir())
|
|
50
|
+
directories+= make_list(safe_dirs)
|
|
49
51
|
return list(set([r for r in directories if r]))
|
|
50
52
|
def get_proper_type_str(string):
|
|
51
53
|
if not string:
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
from .ensure_utils import *
|
|
2
|
-
def get_allowed_predicate(allowed=None):
|
|
2
|
+
def get_allowed_predicate(allowed=None,cfg=None,**kwargs):
|
|
3
3
|
if allowed != False:
|
|
4
4
|
if allowed == True:
|
|
5
5
|
allowed = None
|
|
6
|
-
allowed = allowed or make_allowed_predicate()
|
|
6
|
+
allowed = allowed or make_allowed_predicate(cfg=cfg,**kwargs)
|
|
7
7
|
else:
|
|
8
8
|
def allowed(*args):
|
|
9
9
|
return True
|
|
10
10
|
allowed = allowed
|
|
11
11
|
return allowed
|
|
12
|
-
def get_globs(items,recursive: bool = True,allowed=None):
|
|
12
|
+
def get_globs(items,recursive: bool = True,allowed=None,cfg=None,**kwargs):
|
|
13
13
|
glob_paths = []
|
|
14
|
+
allowed = get_allowed_predicate(allowed=allowed,cfg=cfg,**kwargs)
|
|
14
15
|
items = [item for item in make_list(items) if item]
|
|
15
16
|
for item in items:
|
|
16
17
|
pattern = os.path.join(item, "**/*") # include all files recursively\n
|
|
@@ -19,42 +20,43 @@ def get_globs(items,recursive: bool = True,allowed=None):
|
|
|
19
20
|
nuItems = [nuItem for nuItem in nuItems if nuItem and allowed(nuItem)]
|
|
20
21
|
glob_paths += nuItems
|
|
21
22
|
return glob_paths
|
|
22
|
-
def get_allowed_files(items,allowed=True):
|
|
23
|
-
allowed = get_allowed_predicate(allowed=allowed)
|
|
23
|
+
def get_allowed_files(items,allowed=True,cfg=None,**kwargs):
|
|
24
|
+
allowed = get_allowed_predicate(allowed=allowed,cfg=cfg,**kwargs)
|
|
24
25
|
return [item for item in items if item and os.path.isfile(item) and allowed(item)]
|
|
25
|
-
def get_allowed_dirs(items,allowed=False):
|
|
26
|
-
allowed = get_allowed_predicate(allowed=allowed)
|
|
26
|
+
def get_allowed_dirs(items,allowed=False,cfg=None,**kwargs):
|
|
27
|
+
allowed = get_allowed_predicate(allowed=allowed,cfg=cfg,**kwargs)
|
|
27
28
|
return [item for item in items if item and os.path.isdir(item) and allowed(item)]
|
|
28
29
|
|
|
29
30
|
def get_filtered_files(items,allowed=None,files = []):
|
|
30
|
-
allowed = get_allowed_predicate(allowed=allowed)
|
|
31
|
-
glob_paths = get_globs(items)
|
|
31
|
+
allowed = get_allowed_predicate(allowed=allowed,cfg=cfg,**kwargs)
|
|
32
|
+
glob_paths = get_globs(items,allowed=allowed,cfg=cfg,**kwargs)
|
|
32
33
|
return [glob_path for glob_path in glob_paths if glob_path and os.path.isfile(glob_path) and glob_path not in files and allowed(glob_path)]
|
|
33
|
-
def get_filtered_dirs(items,allowed=None,dirs = []):
|
|
34
|
-
allowed = get_allowed_predicate(allowed=allowed)
|
|
35
|
-
glob_paths = get_globs(items)
|
|
34
|
+
def get_filtered_dirs(items,allowed=None,dirs = [],cfg=None,**kwargs):
|
|
35
|
+
allowed = get_allowed_predicate(allowed=allowed,cfg=cfg,**kwargs)
|
|
36
|
+
glob_paths = get_globs(items,allowed=allowed,cfg=cfg,**kwargs)
|
|
36
37
|
return [glob_path for glob_path in glob_paths if glob_path and os.path.isdir(glob_path) and glob_path not in dirs and allowed(glob_path)]
|
|
37
38
|
|
|
38
|
-
def get_all_allowed_files(items,allowed=None):
|
|
39
|
-
dirs = get_all_allowed_dirs(items)
|
|
40
|
-
files = get_allowed_files(items)
|
|
39
|
+
def get_all_allowed_files(items,allowed=None,cfg=None,**kwargs):
|
|
40
|
+
dirs = get_all_allowed_dirs(items,allowed=allowed,cfg=cfg,**kwargs)
|
|
41
|
+
files = get_allowed_files(items,allowed=allowed,cfg=cfg,**kwargs)
|
|
41
42
|
nu_files = []
|
|
42
43
|
for directory in dirs:
|
|
43
|
-
files += get_filtered_files(directory,allowed=allowed,files=files)
|
|
44
|
+
files += get_filtered_files(directory,allowed=allowed,files=files,cfg=cfg,**kwargs)
|
|
44
45
|
return files
|
|
45
|
-
def get_all_allowed_dirs(items,allowed=None):
|
|
46
|
-
allowed = get_allowed_predicate(allowed=allowed)
|
|
47
|
-
dirs = get_allowed_dirs(items)
|
|
46
|
+
def get_all_allowed_dirs(items,allowed=None,cfg=None,**kwargs):
|
|
47
|
+
allowed = get_allowed_predicate(allowed=allowed,cfg=cfg,**kwargs)
|
|
48
|
+
dirs = get_allowed_dirs(items,allowed=allowed,cfg=cfg,**kwargs)
|
|
48
49
|
nu_dirs=[]
|
|
49
50
|
for directory in dirs:
|
|
50
|
-
nu_dirs += get_filtered_dirs(directory,allowed=allowed,dirs=nu_dirs)
|
|
51
|
+
nu_dirs += get_filtered_dirs(directory,allowed=allowed,dirs=nu_dirs,cfg=cfg,**kwargs)
|
|
51
52
|
return nu_dirs
|
|
52
53
|
|
|
53
|
-
def make_allowed_predicate(cfg: ScanConfig) -> Callable[[str], bool]:
|
|
54
|
+
def make_allowed_predicate(cfg: ScanConfig=None,**kwargs) -> Callable[[str], bool]:
|
|
54
55
|
"""
|
|
55
56
|
Build a predicate that returns True if a given path is considered allowed
|
|
56
57
|
under the given ScanConfig. Applies allowed_* and exclude_* logic symmetrically.
|
|
57
58
|
"""
|
|
59
|
+
cfg=cfg or define_defaults(**kwargs)
|
|
58
60
|
def allowed(path: str=None,p=None) -> bool:
|
|
59
61
|
p = p or Path(path)
|
|
60
62
|
name = p.name.lower()
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# attach_functions.py — single helper you can import anywhere
|
|
2
2
|
# attach_dynamic.py
|
|
3
3
|
from __future__ import annotations
|
|
4
|
-
from .find_collect import
|
|
4
|
+
from .find_collect import get_files_and_dirs
|
|
5
5
|
from ..imports import *
|
|
6
|
+
ABSPATH = os.path.abspath(__file__)
|
|
7
|
+
ABSROOT = os.path.dirname(ABSPATH)
|
|
6
8
|
|
|
7
9
|
def caller_path():
|
|
8
10
|
frame = inspect.stack()[1]
|
|
@@ -209,28 +211,37 @@ def get_for_all_tabs(root = None):
|
|
|
209
211
|
root = root or caller_path()
|
|
210
212
|
if os.path.isfile(root):
|
|
211
213
|
root = os.path.dirname(root)
|
|
212
|
-
all_tabs =
|
|
214
|
+
all_tabs = get_files_and_dirs(root,allowed_patterns='*Tab')[0]
|
|
215
|
+
|
|
213
216
|
for ROOT in all_tabs:
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
else:
|
|
219
|
-
apply_inits(ROOT)
|
|
217
|
+
if os.path.isdir(ROOT):
|
|
218
|
+
[apply_inits(os.path.join(ROOT,func)) for func in os.listdir(ROOT) if 'functions' == os.path.splitext(func)[0]]
|
|
219
|
+
|
|
220
|
+
|
|
220
221
|
|
|
221
222
|
|
|
222
223
|
def apply_inits(ROOT):
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
224
|
+
filepaths=[ROOT]
|
|
225
|
+
TAB_DIR = os.path.dirname(ROOT)
|
|
226
|
+
INIT_FUNCS_PAPTH = os.path.join(TAB_DIR, "initFuncs.py")
|
|
227
|
+
if_fun_dir=False
|
|
228
|
+
## if os.path.isfile(ROOT):
|
|
229
|
+
## dirname= os.path.dirname(ROOT)
|
|
230
|
+
## basename= os.path.basename(ROOT)
|
|
231
|
+
## functions_dir = os.path.join(dirname,'functions')
|
|
232
|
+
## functions_path = os.path.join(functions_dir,basename)
|
|
233
|
+
## input(get_clean_imports(ROOT))
|
|
234
|
+
##
|
|
235
|
+
## os.makedirs(functions_dir,exist_ok=True)
|
|
236
|
+
## shutil.move(ROOT,functions_path)
|
|
237
|
+
## ROOT=functions_dir
|
|
238
|
+
if os.path.isdir(ROOT):
|
|
239
|
+
INIT_PATH = os.path.join(ROOT, "__init__.py")
|
|
231
240
|
|
|
232
|
-
|
|
233
|
-
|
|
241
|
+
filepaths = get_files_and_dirs(directory=ROOT,allowed_exts='py',add=True)[-1]
|
|
242
|
+
if_fun_dir=True
|
|
243
|
+
|
|
244
|
+
|
|
234
245
|
|
|
235
246
|
# Parse top-level def names
|
|
236
247
|
def extract_funcs(path: str):
|
|
@@ -240,7 +251,7 @@ def apply_inits(ROOT):
|
|
|
240
251
|
if m:
|
|
241
252
|
funcs.append(m.group(1))
|
|
242
253
|
return funcs
|
|
243
|
-
|
|
254
|
+
|
|
244
255
|
# Build functions/__init__.py that re-exports all discovered functions
|
|
245
256
|
import_lines = []
|
|
246
257
|
all_funcs = []
|
|
@@ -252,7 +263,7 @@ def apply_inits(ROOT):
|
|
|
252
263
|
all_funcs.extend(funcs)
|
|
253
264
|
if if_fun_dir:
|
|
254
265
|
functions_init = "\n".join(import_lines) + ("\n" if import_lines else "")
|
|
255
|
-
write_to_file(contents=functions_init, file_path=
|
|
266
|
+
write_to_file(contents=functions_init, file_path=INIT_PATH)
|
|
256
267
|
|
|
257
268
|
# Prepare the tuple literal of function names for import + loop
|
|
258
269
|
uniq_funcs = sorted(set(all_funcs))
|
|
@@ -261,9 +272,10 @@ def apply_inits(ROOT):
|
|
|
261
272
|
# Generate apiConsole/initFuncs.py using the safer setattr-loop
|
|
262
273
|
init_funcs_src = textwrap.dedent(f"""\
|
|
263
274
|
|
|
264
|
-
|
|
275
|
+
|
|
276
|
+
from abstract_utilities import get_logFile
|
|
265
277
|
from .functions import ({func_tuple})
|
|
266
|
-
|
|
278
|
+
logger=get_logFile(__name__)
|
|
267
279
|
def initFuncs(self):
|
|
268
280
|
try:
|
|
269
281
|
for f in ({func_tuple}):
|
|
@@ -273,8 +285,9 @@ def apply_inits(ROOT):
|
|
|
273
285
|
return self
|
|
274
286
|
""")
|
|
275
287
|
|
|
276
|
-
write_to_file(contents=init_funcs_src, file_path=
|
|
288
|
+
write_to_file(contents=init_funcs_src, file_path=INIT_FUNCS_PAPTH)
|
|
277
289
|
|
|
278
290
|
def call_for_all_tabs():
|
|
279
291
|
root = get_caller_dir(2)
|
|
292
|
+
|
|
280
293
|
get_for_all_tabs(root)
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
# attach_functions.py — single helper you can import anywhere
|
|
2
|
+
# attach_dynamic.py
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
from .find_collect import *
|
|
5
|
+
from ..imports import *
|
|
6
|
+
|
|
7
|
+
def caller_path():
|
|
8
|
+
frame = inspect.stack()[1]
|
|
9
|
+
return os.path.abspath(frame.filename)
|
|
10
|
+
def _is_defined_here(mod: types.ModuleType, obj: object) -> bool:
|
|
11
|
+
try:
|
|
12
|
+
return inspect.getmodule(obj) is mod
|
|
13
|
+
except Exception:
|
|
14
|
+
return False
|
|
15
|
+
|
|
16
|
+
def _collect_callables(mod: types.ModuleType) -> Dict[str, Callable]:
|
|
17
|
+
out: Dict[str, Callable] = {}
|
|
18
|
+
names = getattr(mod, "__all__", None)
|
|
19
|
+
if names:
|
|
20
|
+
# trust the author's export list
|
|
21
|
+
for n in names:
|
|
22
|
+
fn = getattr(mod, n, None)
|
|
23
|
+
if callable(fn):
|
|
24
|
+
out[n] = fn
|
|
25
|
+
return out
|
|
26
|
+
# otherwise, discover top-level callables defined in this module
|
|
27
|
+
for n in dir(mod):
|
|
28
|
+
if n.startswith("_"):
|
|
29
|
+
continue
|
|
30
|
+
obj = getattr(mod, n, None)
|
|
31
|
+
if callable(obj) and _is_defined_here(mod, obj):
|
|
32
|
+
out[n] = obj
|
|
33
|
+
return out
|
|
34
|
+
|
|
35
|
+
def _import_module_by_name(name: str) -> Optional[types.ModuleType]:
|
|
36
|
+
try:
|
|
37
|
+
return importlib.import_module(name)
|
|
38
|
+
except Exception:
|
|
39
|
+
return None
|
|
40
|
+
|
|
41
|
+
def _import_module_by_path(pkg_name: str, base_dir: str, filename: str) -> Optional[types.ModuleType]:
|
|
42
|
+
mod_name = f"{pkg_name}.functions"
|
|
43
|
+
path = os.path.join(base_dir, filename)
|
|
44
|
+
spec = importlib.util.spec_from_file_location(mod_name, path)
|
|
45
|
+
if not spec or not spec.loader:
|
|
46
|
+
return None
|
|
47
|
+
mod = importlib.util.module_from_spec(spec)
|
|
48
|
+
sys.modules[mod_name] = mod
|
|
49
|
+
spec.loader.exec_module(mod)
|
|
50
|
+
return mod
|
|
51
|
+
|
|
52
|
+
def _walk_functions_package(pkg_name: str, pkg_mod: types.ModuleType) -> List[types.ModuleType]:
|
|
53
|
+
"""Import all immediate submodules in the functions/ package."""
|
|
54
|
+
mods: List[types.ModuleType] = [pkg_mod]
|
|
55
|
+
pkg_dir = os.path.dirname(pkg_mod.__file__ or "")
|
|
56
|
+
for info in pkgutil.iter_modules([pkg_dir]):
|
|
57
|
+
# only import direct children (no recursion here; easy to add if you need)
|
|
58
|
+
child_name = f"{pkg_mod.__name__}.{info.name}"
|
|
59
|
+
m = _import_module_by_name(child_name)
|
|
60
|
+
if m:
|
|
61
|
+
mods.append(m)
|
|
62
|
+
return mods
|
|
63
|
+
|
|
64
|
+
def _discover_functions(base_pkg: str, *, hot_reload: bool) -> List[Tuple[str, Callable, str]]:
|
|
65
|
+
"""
|
|
66
|
+
Returns a list of (export_name, callable, module_basename).
|
|
67
|
+
Works if you have base_pkg.functions.py or base_pkg/functions/ package.
|
|
68
|
+
"""
|
|
69
|
+
# Prefer normal import of '<base_pkg>.functions'
|
|
70
|
+
fqn = f"{base_pkg}.functions"
|
|
71
|
+
mod = _import_module_by_name(fqn)
|
|
72
|
+
|
|
73
|
+
if mod is None:
|
|
74
|
+
# fallback: sibling functions.py, even without being a package
|
|
75
|
+
base = _import_module_by_name(base_pkg)
|
|
76
|
+
if not base or not getattr(base, "__file__", None):
|
|
77
|
+
return []
|
|
78
|
+
base_dir = os.path.dirname(base.__file__)
|
|
79
|
+
if os.path.isfile(os.path.join(base_dir, "functions.py")):
|
|
80
|
+
mod = _import_module_by_path(base_pkg, base_dir, "functions.py")
|
|
81
|
+
else:
|
|
82
|
+
return []
|
|
83
|
+
|
|
84
|
+
if hot_reload:
|
|
85
|
+
try:
|
|
86
|
+
mod = importlib.reload(mod) # type: ignore[arg-type]
|
|
87
|
+
except Exception:
|
|
88
|
+
pass
|
|
89
|
+
|
|
90
|
+
results: List[Tuple[str, Callable, str]] = []
|
|
91
|
+
modules: List[types.ModuleType]
|
|
92
|
+
|
|
93
|
+
if hasattr(mod, "__path__"): # it's a package: import children
|
|
94
|
+
modules = _walk_functions_package(base_pkg, mod)
|
|
95
|
+
else:
|
|
96
|
+
modules = [mod]
|
|
97
|
+
|
|
98
|
+
for m in modules:
|
|
99
|
+
exported = _collect_callables(m)
|
|
100
|
+
module_basename = m.__name__.split(".")[-1]
|
|
101
|
+
for name, fn in exported.items():
|
|
102
|
+
results.append((name, fn, module_basename))
|
|
103
|
+
return results
|
|
104
|
+
|
|
105
|
+
def attach_functions(
|
|
106
|
+
obj_or_cls,
|
|
107
|
+
base_pkg: str | None = None,
|
|
108
|
+
hot_reload: bool = True,
|
|
109
|
+
prefix_with_module: bool = False,
|
|
110
|
+
include_private: bool = True,
|
|
111
|
+
only_defined_here: bool = True, # don't attach stuff imported from elsewhere
|
|
112
|
+
) -> list[str]:
|
|
113
|
+
"""
|
|
114
|
+
Attach all free functions found in <base_pkg>.functions (module or package)
|
|
115
|
+
to the *class* of obj_or_cls. Returns the list of attached attribute names.
|
|
116
|
+
"""
|
|
117
|
+
cls = obj_or_cls if inspect.isclass(obj_or_cls) else obj_or_cls.__class__
|
|
118
|
+
# Derive "<package>.functions" from the class's module unless you pass base_pkg
|
|
119
|
+
caller_mod = cls.__module__
|
|
120
|
+
pkg_root = (base_pkg or caller_mod.rsplit(".", 1)[0]).rstrip(".")
|
|
121
|
+
funcs_pkg_name = f"{pkg_root}.functions"
|
|
122
|
+
|
|
123
|
+
def _import(name: str) -> ModuleType | None:
|
|
124
|
+
try:
|
|
125
|
+
if hot_reload and name in sys.modules:
|
|
126
|
+
return importlib.reload(sys.modules[name])
|
|
127
|
+
return importlib.import_module(name)
|
|
128
|
+
except Exception:
|
|
129
|
+
return None
|
|
130
|
+
|
|
131
|
+
def _is_pkg(m: ModuleType) -> bool:
|
|
132
|
+
return hasattr(m, "__path__")
|
|
133
|
+
|
|
134
|
+
mod = _import(funcs_pkg_name)
|
|
135
|
+
if mod is None:
|
|
136
|
+
# Nothing to attach (no functions.py or functions/ next to your class)
|
|
137
|
+
setattr(cls, "_attached_functions", tuple())
|
|
138
|
+
return []
|
|
139
|
+
|
|
140
|
+
modules: list[ModuleType] = [mod]
|
|
141
|
+
if _is_pkg(mod):
|
|
142
|
+
# attach from every submodule under functions/
|
|
143
|
+
for it in pkgutil.iter_modules(mod.__path__):
|
|
144
|
+
sub = _import(f"{funcs_pkg_name}.{it.name}")
|
|
145
|
+
if sub is not None:
|
|
146
|
+
modules.append(sub)
|
|
147
|
+
|
|
148
|
+
attached: list[str] = []
|
|
149
|
+
for m in modules:
|
|
150
|
+
for name, obj in vars(m).items():
|
|
151
|
+
# only callables (skip classes), and keep them sane
|
|
152
|
+
if not callable(obj) or isinstance(obj, type):
|
|
153
|
+
continue
|
|
154
|
+
if only_defined_here and getattr(obj, "__module__", None) != m.__name__:
|
|
155
|
+
continue
|
|
156
|
+
if not include_private and name.startswith("_"):
|
|
157
|
+
continue
|
|
158
|
+
if name.startswith("__") and name.endswith("__"):
|
|
159
|
+
continue
|
|
160
|
+
attr = f"{m.__name__.rsplit('.', 1)[-1]}__{name}" if prefix_with_module else name
|
|
161
|
+
try:
|
|
162
|
+
setattr(cls, attr, obj) # set on CLASS → becomes bound method on instances
|
|
163
|
+
attached.append(attr)
|
|
164
|
+
except Exception:
|
|
165
|
+
# don't explode if one name collides; keep going
|
|
166
|
+
continue
|
|
167
|
+
|
|
168
|
+
# handy for debugging
|
|
169
|
+
try:
|
|
170
|
+
setattr(cls, "_attached_functions", tuple(attached))
|
|
171
|
+
except Exception:
|
|
172
|
+
pass
|
|
173
|
+
return attached
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def isTab(item):
|
|
179
|
+
item_lower = item.lower()
|
|
180
|
+
for key in ['console','tab']:
|
|
181
|
+
if item_lower.endswith(key):
|
|
182
|
+
return True
|
|
183
|
+
return False
|
|
184
|
+
def get_dir(root,item):
|
|
185
|
+
if None in [root]:
|
|
186
|
+
return None
|
|
187
|
+
path = root
|
|
188
|
+
if item != None:
|
|
189
|
+
path = os.path.join(path,item)
|
|
190
|
+
return path
|
|
191
|
+
def isDir(root,item=None):
|
|
192
|
+
path = get_dir(root,item)
|
|
193
|
+
if path:
|
|
194
|
+
return os.path.isdir(path)
|
|
195
|
+
def check_dir_item(root,item=None):
|
|
196
|
+
return (item and isTab(item) and isDir(root,item))
|
|
197
|
+
def get_dirs(root = None):
|
|
198
|
+
root = root or ABSROOT
|
|
199
|
+
dirpaths = [get_dir(root,item) for item in os.listdir(root) if check_dir_item(root,item)]
|
|
200
|
+
return dirpaths
|
|
201
|
+
def ifFunctionsInFile(root):
|
|
202
|
+
items = [os.path.join(root, "functions"),os.path.join(root, "functions.py")]
|
|
203
|
+
for item in items:
|
|
204
|
+
if os.path.exists(item):
|
|
205
|
+
return item
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
def get_for_all_tabs(root = None):
|
|
209
|
+
root = root or get_initial_caller_dir()
|
|
210
|
+
if os.path.isfile(root):
|
|
211
|
+
root = os.path.dirname(root)
|
|
212
|
+
all_tabs = get_dirs(root = root)
|
|
213
|
+
for ROOT in all_tabs:
|
|
214
|
+
FUNCS_DIR = ifFunctionsInFile(ROOT)
|
|
215
|
+
if FUNCS_DIR == None:
|
|
216
|
+
for ROOT in get_dirs(root = ROOT):
|
|
217
|
+
apply_inits(ROOT)
|
|
218
|
+
else:
|
|
219
|
+
apply_inits(ROOT)
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
def apply_inits(ROOT):
|
|
223
|
+
FUNCS_DIR = ifFunctionsInFile(ROOT)
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
if_fun_dir = isDir(FUNCS_DIR)
|
|
227
|
+
if if_fun_dir != None:
|
|
228
|
+
|
|
229
|
+
if if_fun_dir:
|
|
230
|
+
filepaths = collect_filepaths(FUNCS_DIR,allowed_exts='.py',add=True)
|
|
231
|
+
|
|
232
|
+
else:
|
|
233
|
+
filepaths = [FUNCS_DIR]
|
|
234
|
+
|
|
235
|
+
# Parse top-level def names
|
|
236
|
+
def extract_funcs(path: str):
|
|
237
|
+
funcs = []
|
|
238
|
+
for line in read_from_file(path).splitlines():
|
|
239
|
+
m = re.match(r"^def\s+([A-Za-z_]\w*)\s*\(self", line)
|
|
240
|
+
if m:
|
|
241
|
+
funcs.append(m.group(1))
|
|
242
|
+
return funcs
|
|
243
|
+
|
|
244
|
+
# Build functions/__init__.py that re-exports all discovered functions
|
|
245
|
+
import_lines = []
|
|
246
|
+
all_funcs = []
|
|
247
|
+
for fp in filepaths:
|
|
248
|
+
module = os.path.splitext(os.path.basename(fp))[0]
|
|
249
|
+
funcs = extract_funcs(fp)
|
|
250
|
+
if funcs:
|
|
251
|
+
import_lines.append(f"from .{module} import ({', '.join(funcs)})")
|
|
252
|
+
all_funcs.extend(funcs)
|
|
253
|
+
if if_fun_dir:
|
|
254
|
+
functions_init = "\n".join(import_lines) + ("\n" if import_lines else "")
|
|
255
|
+
write_to_file(contents=functions_init, file_path=os.path.join(FUNCS_DIR, "__init__.py"))
|
|
256
|
+
|
|
257
|
+
# Prepare the tuple literal of function names for import + loop
|
|
258
|
+
uniq_funcs = sorted(set(all_funcs))
|
|
259
|
+
func_tuple = ", ".join(uniq_funcs) + ("," if len(uniq_funcs) == 1 else "")
|
|
260
|
+
|
|
261
|
+
# Generate apiConsole/initFuncs.py using the safer setattr-loop
|
|
262
|
+
init_funcs_src = textwrap.dedent(f"""\
|
|
263
|
+
|
|
264
|
+
from abstract_utilities import get_logFile
|
|
265
|
+
from .functions import ({func_tuple})
|
|
266
|
+
logger=get_logFile(__name__)
|
|
267
|
+
def initFuncs(self):
|
|
268
|
+
try:
|
|
269
|
+
for f in ({func_tuple}):
|
|
270
|
+
setattr(self, f.__name__, f)
|
|
271
|
+
except Exception as e:
|
|
272
|
+
logger.info(f"{{e}}")
|
|
273
|
+
return self
|
|
274
|
+
""")
|
|
275
|
+
|
|
276
|
+
write_to_file(contents=init_funcs_src, file_path=os.path.join(ROOT, "initFuncs.py"))
|
|
277
|
+
|
|
278
|
+
def call_for_all_tabs():
|
|
279
|
+
root = get_initial_caller_dir()
|
|
280
|
+
get_for_all_tabs(root)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from ...read_write_utils import read_from_file,write_to_file,get_text_or_read
|
|
2
2
|
from ...string_utils import eatAll,eatInner,eatElse,clean_line
|
|
3
|
-
from ...class_utils import get_caller_path,get_caller_dir,if_none_default
|
|
3
|
+
from ...class_utils import if_none_change,if_none_default,get_true_globals,get_initial_caller_dir,get_caller_path,get_caller_dir,if_none_default
|
|
4
4
|
from ...list_utils import make_list
|
|
5
5
|
from ...path_utils import get_file_parts
|
|
6
6
|
from ...type_utils import is_number,make_list
|
|
@@ -40,7 +40,7 @@ def extract_class(path: str):
|
|
|
40
40
|
if m:
|
|
41
41
|
funcs.append(m.group(1))
|
|
42
42
|
return funcs
|
|
43
|
-
def get_all_py_file_paths(
|
|
44
|
-
globs = collect_globs(
|
|
43
|
+
def get_all_py_file_paths(directory,*args,**kwargs):
|
|
44
|
+
globs = collect_globs(directory,*args,allowed_exts='.py',**kwargs)
|
|
45
45
|
globs = [glo for glo in globs.get('files') if glo]
|
|
46
46
|
return globs
|
|
@@ -56,22 +56,17 @@ def dynamic_import(module_path: str, namespace: dict, all_imports = None):
|
|
|
56
56
|
from module_path import *
|
|
57
57
|
but includes private (_xxx) names too.
|
|
58
58
|
"""
|
|
59
|
-
all_imports =
|
|
59
|
+
all_imports = if_none_change(all_imports,True)
|
|
60
60
|
if module_path:
|
|
61
61
|
module = importlib.import_module(module_path)
|
|
62
|
-
|
|
63
62
|
# Import literally everything except dunders, unless you want them too.
|
|
64
63
|
names = [n for n in dir(module) if n and ((not all_imports and not n.startswith("_")) or all_imports)]
|
|
65
|
-
|
|
66
|
-
|
|
67
64
|
for name in names:
|
|
68
65
|
namespace[name] = getattr(module, name)
|
|
69
|
-
|
|
70
66
|
return module
|
|
71
|
-
|
|
72
|
-
|
|
73
67
|
def get_monorepo_root(directory=None,files=None):
|
|
74
68
|
directory = directory or get_initial_caller_dir()
|
|
69
|
+
|
|
75
70
|
py_files = get_all_py_file_paths(directory,add=True)
|
|
76
71
|
sysroots = get_all_py_sysroots(directory=directory,files=py_files)
|
|
77
72
|
monorepo_root = get_common_root(sysroots)
|
|
@@ -80,12 +75,36 @@ def switch_to_monorepo_root(directory=None,files=None):
|
|
|
80
75
|
monorepo_root = get_monorepo_root(directory=directory,files=files)
|
|
81
76
|
if str(monorepo_root) not in sys.path:
|
|
82
77
|
sys.path.insert(0, str(monorepo_root))
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
78
|
+
return str(monorepo_root)
|
|
79
|
+
def get_all_imports(directory=None,sysroot=None,globs=None):
|
|
80
|
+
globs = globs or get_true_globals() or globals()
|
|
81
|
+
directory = directory or get_initial_caller_dir()
|
|
82
|
+
files = collect_globs(directory=directory,allowed_exts='.py').get('files')
|
|
83
|
+
sysroot = sysroot or switch_to_monorepo_root(directory=directory,files=files)
|
|
84
|
+
for glo in files:
|
|
89
85
|
imp = get_import_with_sysroot(glo, sysroot)
|
|
90
|
-
dynamic_import(imp,
|
|
86
|
+
dynamic_import(imp, globs)
|
|
87
|
+
def get_all_imports_for_class(self, directory=None, sysroot=None, include_private=True):
|
|
88
|
+
"""
|
|
89
|
+
Load all modules under `directory` and assign their exports as attributes
|
|
90
|
+
on the class instance (self).
|
|
91
|
+
"""
|
|
92
|
+
directory = directory or get_initial_caller_dir()
|
|
93
|
+
files = collect_globs(directory=directory, allowed_exts='.py').get("files")
|
|
94
|
+
|
|
95
|
+
# Compute sysroot (monorepo root)
|
|
96
|
+
sysroot = sysroot or switch_to_monorepo_root(directory=directory, files=files)
|
|
97
|
+
|
|
98
|
+
for glo in files:
|
|
99
|
+
mod_path = get_import_with_sysroot(glo, sysroot)
|
|
100
|
+
module = importlib.import_module(mod_path)
|
|
101
|
+
|
|
102
|
+
for name in dir(module):
|
|
103
|
+
if name.startswith("__"):
|
|
104
|
+
continue
|
|
105
|
+
if not include_private and name.startswith("_"):
|
|
106
|
+
continue
|
|
107
|
+
|
|
108
|
+
setattr(self, name, getattr(module, name))
|
|
91
109
|
|
|
110
|
+
return self
|
|
@@ -2,7 +2,7 @@ from ..imports import *
|
|
|
2
2
|
from .dot_utils import *
|
|
3
3
|
from .extract_utils import get_all_py_file_paths
|
|
4
4
|
def get_py_files(directory=None):
|
|
5
|
-
directory = directory or
|
|
5
|
+
directory = directory or get_initial_caller_dir()
|
|
6
6
|
return get_all_py_file_paths(directory,add=True)
|
|
7
7
|
def ensure_on_path(p: Path):
|
|
8
8
|
s = str(p)
|
|
@@ -1,42 +1,90 @@
|
|
|
1
1
|
from .imports import *
|
|
2
|
-
|
|
2
|
+
import os, sys, inspect, logging
|
|
3
|
+
from logging.handlers import RotatingFileHandler
|
|
4
|
+
|
|
5
|
+
PACKAGE_NAME = "abstract_utilities" # ← update if needed
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def _resolve_log_root():
|
|
3
9
|
"""
|
|
4
|
-
|
|
5
|
-
|
|
10
|
+
Returns a safe writable logging directory depending on environment:
|
|
11
|
+
- If running in a virtualenv → <venv>/.logs/<package>
|
|
12
|
+
- Else if user writable → ~/.cache/<package>/logs
|
|
13
|
+
- Else → /var/log/<package>
|
|
14
|
+
"""
|
|
15
|
+
# 1) Virtualenv or Conda environment
|
|
16
|
+
venv = os.getenv("VIRTUAL_ENV") or os.getenv("CONDA_PREFIX")
|
|
17
|
+
if venv:
|
|
18
|
+
root = os.path.join(venv, ".logs", PACKAGE_NAME)
|
|
19
|
+
os.makedirs(root, exist_ok=True)
|
|
20
|
+
return root
|
|
21
|
+
|
|
22
|
+
# 2) User home cache folder
|
|
23
|
+
home = os.path.expanduser("~")
|
|
24
|
+
user_cache_root = os.path.join(home, ".cache", PACKAGE_NAME, "logs")
|
|
25
|
+
try:
|
|
26
|
+
os.makedirs(user_cache_root, exist_ok=True)
|
|
27
|
+
return user_cache_root
|
|
28
|
+
except PermissionError:
|
|
29
|
+
pass
|
|
30
|
+
|
|
31
|
+
# 3) Last resort: system log dir (requires correct service user permissions)
|
|
32
|
+
system_root = f"/var/log/{PACKAGE_NAME}"
|
|
33
|
+
try:
|
|
34
|
+
os.makedirs(system_root, exist_ok=True)
|
|
35
|
+
return system_root
|
|
36
|
+
except PermissionError:
|
|
37
|
+
# Fail-safe fallback to /tmp
|
|
38
|
+
fallback = f"/tmp/{PACKAGE_NAME}/logs"
|
|
39
|
+
os.makedirs(fallback, exist_ok=True)
|
|
40
|
+
return fallback
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
LOG_ROOT = _resolve_log_root()
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def get_logFile(bpName=None, maxBytes=100_000, backupCount=3):
|
|
47
|
+
"""
|
|
48
|
+
A logger that always writes to a safe OS-appropriate path.
|
|
49
|
+
Works even when installed through pip.
|
|
6
50
|
"""
|
|
7
51
|
if bpName is None:
|
|
8
|
-
# Find the first frame outside logging_utils.py
|
|
9
52
|
frame_idx = _find_caller_frame_index()
|
|
10
53
|
frame_info = inspect.stack()[frame_idx]
|
|
11
|
-
caller_path = frame_info.filename
|
|
54
|
+
caller_path = frame_info.filename
|
|
12
55
|
bpName = os.path.splitext(os.path.basename(caller_path))[0]
|
|
13
56
|
del frame_info
|
|
14
57
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
logger = logging.getLogger(bpName)
|
|
58
|
+
logger = logging.getLogger(f"{PACKAGE_NAME}.{bpName}")
|
|
18
59
|
logger.setLevel(logging.INFO)
|
|
19
60
|
|
|
20
61
|
if not logger.handlers:
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
logger.addHandler(console)
|
|
36
|
-
except Exception as e:
|
|
37
|
-
print(f"{e}")
|
|
62
|
+
log_file = os.path.join(LOG_ROOT, f"{bpName}.log")
|
|
63
|
+
handler = RotatingFileHandler(log_file, maxBytes=maxBytes, backupCount=backupCount)
|
|
64
|
+
|
|
65
|
+
fmt = "%(asctime)s - %(levelname)s - %(pathname)s:%(lineno)d - %(message)s"
|
|
66
|
+
formatter = logging.Formatter(fmt)
|
|
67
|
+
handler.setFormatter(formatter)
|
|
68
|
+
|
|
69
|
+
logger.addHandler(handler)
|
|
70
|
+
|
|
71
|
+
# Console handler (optional; can disable for gunicorn)
|
|
72
|
+
console = logging.StreamHandler(sys.stdout)
|
|
73
|
+
console.setFormatter(formatter)
|
|
74
|
+
logger.addHandler(console)
|
|
75
|
+
|
|
38
76
|
return logger
|
|
39
77
|
|
|
78
|
+
|
|
79
|
+
def _find_caller_frame_index():
|
|
80
|
+
"""Find the correct caller module outside this logger."""
|
|
81
|
+
for idx, frame_info in enumerate(inspect.stack()):
|
|
82
|
+
if idx == 0:
|
|
83
|
+
continue
|
|
84
|
+
module = inspect.getmodule(frame_info.frame)
|
|
85
|
+
if module and module.__name__ not in (__name__, "logging"):
|
|
86
|
+
return idx
|
|
87
|
+
return 1
|
|
40
88
|
def _find_caller_frame_index():
|
|
41
89
|
"""
|
|
42
90
|
Scan up the call stack until we find a frame whose module is NOT logging_utils.
|
|
@@ -64,6 +64,29 @@ def detect_language_from_text(text: str):
|
|
|
64
64
|
|
|
65
65
|
likely = [lang for lang, score in scores.items() if score == max_score]
|
|
66
66
|
return likely[0] if len(likely) == 1 else 'uncertain'
|
|
67
|
+
def get_tripple_string(string):
|
|
68
|
+
nustring = ''
|
|
69
|
+
for i in range(3):
|
|
70
|
+
nustring +=string
|
|
71
|
+
return nustring
|
|
72
|
+
def get_within_quotes(text,quotes=None):
|
|
73
|
+
quotes_strings = quotes or ["'",'"']
|
|
74
|
+
in_quotes = []
|
|
75
|
+
for quotes_string in quotes_strings:
|
|
76
|
+
if not isinstance(quotes_string,list):
|
|
77
|
+
tripple= get_tripple_string(quotes_string)
|
|
78
|
+
texts = [text]
|
|
79
|
+
if tripple in text:
|
|
80
|
+
texts= text.split(tripple)
|
|
81
|
+
for text_part in texts:
|
|
82
|
+
quote_count = len(text_part) - len(text_part.replace(quotes_string,''))
|
|
83
|
+
quote_spl = text_part.split(quotes_string)
|
|
84
|
+
in_quotes+=[quote_spl[i] for i in range(quote_count) if ((i == 1 or i%2 != float(0)) and len(quote_spl) > i)]
|
|
85
|
+
else:
|
|
86
|
+
texts= text.split(quotes_string[0])
|
|
87
|
+
for text in texts:
|
|
88
|
+
in_quotes.append(text.split(quotes_string[1])[0])
|
|
89
|
+
return in_quotes
|
|
67
90
|
|
|
68
91
|
def search_code(code_languages, parts):
|
|
69
92
|
return [data for datas in parts for data in make_list(datas)
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
from ...imports import os,shlex
|
|
2
|
-
|
|
2
|
+
import base64
|
|
@@ -194,44 +194,112 @@ def write_to_path(
|
|
|
194
194
|
## f.write(str(contents))
|
|
195
195
|
## return file_path
|
|
196
196
|
# --- Core functionality -------------------------------------------------------
|
|
197
|
-
def write_to_file(*args, **kwargs):
|
|
197
|
+
##def write_to_file(*args, **kwargs):
|
|
198
|
+
## """
|
|
199
|
+
## Write contents to a file (create if missing).
|
|
200
|
+
##
|
|
201
|
+
## Returns the file_path written.
|
|
202
|
+
## """
|
|
203
|
+
## file_path, contents = check_read_write_params(*args, **kwargs)
|
|
204
|
+
## values,kwargs = get_from_kwargs(['file_path','contents'],del_kwarg=True,**kwargs)
|
|
205
|
+
## dirname = os.path.dirname(file_path)
|
|
206
|
+
##
|
|
207
|
+
## if contents is None:
|
|
208
|
+
## raise ValueError("Missing contents to write.")
|
|
209
|
+
## user_at_host = kwargs.get("user_at_host")
|
|
210
|
+
## if get_user_pass_host_key(**kwargs):
|
|
211
|
+
## make_dirs(dirname, exist_ok=True,**kwargs)
|
|
212
|
+
## kwargs["cwd"] = kwargs.get('cwd') or os.path.dirname(file_path)
|
|
213
|
+
## # sanitize for shell safety
|
|
214
|
+
## quoted_path = shlex.quote(file_path)
|
|
215
|
+
## quoted_data = shlex.quote(str(contents))
|
|
216
|
+
## # shell command that fully overwrites
|
|
217
|
+
## # (no append, replaces contents entirely)
|
|
218
|
+
## kwargs["cmd"] = f'sh -c "echo {quoted_data} > {quoted_path}"'
|
|
219
|
+
## if not kwargs.get('password') and not kwargs.get('key'):
|
|
220
|
+
## kwargs["cmd"]=f'sudo {kwargs["cmd"]}'
|
|
221
|
+
## result = run_pruned_func(run_cmd,**kwargs)
|
|
222
|
+
## if 'file_path' in kwargs:
|
|
223
|
+
## del kwargs['file_path']
|
|
224
|
+
## if not is_file(file_path,**kwargs) or str(contents) != read_from_file(file_path,**kwargs):
|
|
225
|
+
## kwargs["cmd"]=f'sudo {kwargs["cmd"]}'
|
|
226
|
+
## result = run_pruned_func(run_cmd,**kwargs)
|
|
227
|
+
## return result
|
|
228
|
+
##
|
|
229
|
+
## make_dirs(dirname or ".", exist_ok=True)
|
|
230
|
+
## with open(file_path, "w", encoding="utf-8") as f:
|
|
231
|
+
## f.write(str(contents))
|
|
232
|
+
## return file_path
|
|
233
|
+
|
|
234
|
+
def _should_use_remote(**kwargs) -> bool:
|
|
235
|
+
"""
|
|
236
|
+
Only use remote mode IF:
|
|
237
|
+
- user_at_host is provided
|
|
238
|
+
- AND password/key is provided
|
|
239
|
+
Otherwise: local write.
|
|
198
240
|
"""
|
|
199
|
-
|
|
241
|
+
user = kwargs.get("user_at_host")
|
|
242
|
+
if not user:
|
|
243
|
+
return False # not remote
|
|
200
244
|
|
|
201
|
-
|
|
245
|
+
# If user_at_host is provided, then password or key MUST be present
|
|
246
|
+
if kwargs.get("password") or kwargs.get("key"):
|
|
247
|
+
return True
|
|
248
|
+
|
|
249
|
+
return False # user provided but no auth → treat as local
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
def _write_to_file(contents: str, file_path: str, **kwargs) -> str:
|
|
202
253
|
"""
|
|
203
|
-
|
|
204
|
-
|
|
254
|
+
Universal safe writer for any file content.
|
|
255
|
+
Works locally and remotely without breaking quotes.
|
|
256
|
+
"""
|
|
257
|
+
|
|
258
|
+
# --- Decode mode selection ---
|
|
259
|
+
remote = _should_use_remote(**kwargs)
|
|
260
|
+
|
|
261
|
+
# Create directory path
|
|
205
262
|
dirname = os.path.dirname(file_path)
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
if get_user_pass_host_key(**kwargs):
|
|
211
|
-
make_dirs(dirname, exist_ok=True,**kwargs)
|
|
212
|
-
kwargs["cwd"] = kwargs.get('cwd') or os.path.dirname(file_path)
|
|
213
|
-
# sanitize for shell safety
|
|
214
|
-
quoted_path = shlex.quote(file_path)
|
|
215
|
-
quoted_data = shlex.quote(str(contents))
|
|
216
|
-
# shell command that fully overwrites
|
|
217
|
-
# (no append, replaces contents entirely)
|
|
218
|
-
kwargs["cmd"] = f'sh -c "echo {quoted_data} > {quoted_path}"'
|
|
219
|
-
if not kwargs.get('password') and not kwargs.get('key'):
|
|
220
|
-
kwargs["cmd"]=f'sudo {kwargs["cmd"]}'
|
|
221
|
-
result = run_pruned_func(run_cmd,**kwargs)
|
|
222
|
-
if 'file_path' in kwargs:
|
|
223
|
-
del kwargs['file_path']
|
|
224
|
-
if not is_file(file_path,**kwargs) or str(contents) != read_from_file(file_path,**kwargs):
|
|
225
|
-
kwargs["cmd"]=f'sudo {kwargs["cmd"]}'
|
|
226
|
-
result = run_pruned_func(run_cmd,**kwargs)
|
|
227
|
-
return result
|
|
263
|
+
make_dirs(dirname, exist_ok=True, **kwargs)
|
|
264
|
+
|
|
265
|
+
# Base64 encoding ensures zero escaping issues
|
|
266
|
+
b64 = base64.b64encode(contents.encode("utf-8")).decode("utf-8")
|
|
228
267
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
f
|
|
232
|
-
|
|
268
|
+
# Build decode + tee command
|
|
269
|
+
cmd = (
|
|
270
|
+
f"echo '{b64}' | base64 -d | "
|
|
271
|
+
f"sudo tee {shlex.quote(file_path)} > /dev/null"
|
|
272
|
+
)
|
|
233
273
|
|
|
274
|
+
# --- Local write ---
|
|
275
|
+
if not remote:
|
|
276
|
+
return run_pruned_func(
|
|
277
|
+
run_local_cmd,
|
|
278
|
+
cmd=cmd,
|
|
279
|
+
**kwargs
|
|
280
|
+
)
|
|
281
|
+
|
|
282
|
+
# --- Remote write ---
|
|
283
|
+
return run_pruned_func(
|
|
284
|
+
run_remote_cmd,
|
|
285
|
+
user_at_host=kwargs["user_at_host"],
|
|
286
|
+
cmd=cmd,
|
|
287
|
+
**kwargs
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
def write_to_file(*, contents: str, file_path: str, **kwargs):
|
|
292
|
+
"""
|
|
293
|
+
Error-handled wrapper.
|
|
294
|
+
"""
|
|
295
|
+
|
|
296
|
+
try:
|
|
297
|
+
result = _write_to_file(contents=contents, file_path=file_path, **kwargs)
|
|
298
|
+
return result
|
|
234
299
|
|
|
300
|
+
except Exception as e:
|
|
301
|
+
print("WRITE ERROR:", e)
|
|
302
|
+
raise RuntimeError(f"Failed writing: {file_path}")
|
|
235
303
|
def read_from_file(file_path,**kwargs):
|
|
236
304
|
if get_user_pass_host_key(**kwargs):
|
|
237
305
|
kwargs["cwd"] = kwargs.get('cwd') or os.path.dirname(file_path)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: abstract_utilities
|
|
3
|
-
Version: 0.2.2.
|
|
3
|
+
Version: 0.2.2.627
|
|
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,4 +1,4 @@
|
|
|
1
|
-
abstract_utilities/__init__.py,sha256=
|
|
1
|
+
abstract_utilities/__init__.py,sha256=YfuG1LFHMOGUuxDyDzq24gfmeAvErfyGaUu8X6nyjfA,5220
|
|
2
2
|
abstract_utilities/abstract_classes.py,sha256=A6-FNDQb2P_jcyt01Kc5SuY2QawLVKNjQ-rDGfsn4rA,2461
|
|
3
3
|
abstract_utilities/circular_import_finder.py,sha256=bs1O4NjSDrJ2cC8whPfZPouNDr1oxdMCFKUIfRyIEB4,8415
|
|
4
4
|
abstract_utilities/circular_import_finder2.py,sha256=n6OFjiIsxxw2u_bf8wcQ81fzQzXhsD4VYWzOC9pDYXw,3869
|
|
@@ -28,10 +28,10 @@ abstract_utilities/type_utils.py,sha256=XaaAel9hUKeOzBqSCqJsIC6UiPMXUlhtmU77jOHz
|
|
|
28
28
|
abstract_utilities/utils.py,sha256=SCa_-x_wsWrcokQXKwlhalxndxLn5Wg25-zqRdJUmag,185049
|
|
29
29
|
abstract_utilities/class_utils/__init__.py,sha256=FbEui_psjSFhwwYkyKEGePbLVij8GZOm69nGBnx-Zfc,196
|
|
30
30
|
abstract_utilities/class_utils/abstract_classes.py,sha256=2qgVUiI1O_7gNYJAk5eb32IaHtULIXo0OasLGb045E8,2470
|
|
31
|
-
abstract_utilities/class_utils/caller_utils.py,sha256=
|
|
31
|
+
abstract_utilities/class_utils/caller_utils.py,sha256=QFbMBBQMPkIHMrN0zEUINp4ODk8IwNIvoSyC1gMemmU,1516
|
|
32
32
|
abstract_utilities/class_utils/class_utils.py,sha256=An-pTLzvDb7WPB2JZoEm2MEDops5HrWPNlR6dco6h5g,4033
|
|
33
33
|
abstract_utilities/class_utils/function_utils.py,sha256=sP_qSrWGhvzU2XoWGk9Np1B4WPUpzrSf1f0Ywu6bzt0,5775
|
|
34
|
-
abstract_utilities/class_utils/global_utils.py,sha256=
|
|
34
|
+
abstract_utilities/class_utils/global_utils.py,sha256=ZIX4i4dvoA36njUn9PVhuJj0koeVyM0BIcZHi8DJzFQ,2908
|
|
35
35
|
abstract_utilities/class_utils/module_utils.py,sha256=EumlwSc5PJZwqqcFEzMOCtsFJUHNuqEQAJGJlywuqyY,1516
|
|
36
36
|
abstract_utilities/class_utils/imports/__init__.py,sha256=LVIEQXKiAmaKKWxPxfSJKe7JGWi4RDt4eatm_VG-WUI,44
|
|
37
37
|
abstract_utilities/class_utils/imports/imports.py,sha256=_F7UpONRaGnFNNUYH-baSv4H5NQXQOZeD-jW3pSoiiA,87
|
|
@@ -55,7 +55,7 @@ abstract_utilities/directory_utils/imports/__init__.py,sha256=sUUAr6PY1SMtVjSTsb
|
|
|
55
55
|
abstract_utilities/directory_utils/imports/imports.py,sha256=R7rno0pnzOU9XpzPhco0Wp9aIR73w_BGqCLdYpAHowI,32
|
|
56
56
|
abstract_utilities/directory_utils/imports/module_imports.py,sha256=v9jovq8n9EOS9lmjRonYu4pdKEDS-mw4ejgtRrAGYX0,69
|
|
57
57
|
abstract_utilities/directory_utils/src/__init__.py,sha256=cKlenOq451R2VqV86AD5ZEh1qGX5FfJwwsohgL0fQU4,104
|
|
58
|
-
abstract_utilities/directory_utils/src/directory_utils.py,sha256=
|
|
58
|
+
abstract_utilities/directory_utils/src/directory_utils.py,sha256=3uuiGfC_P_K6Cue4BBdSgxBZQDU4vozButm8yhJ1d_k,3271
|
|
59
59
|
abstract_utilities/directory_utils/src/name_utils.py,sha256=Lz4RoeI9Ux6CC4I7UCZj7K6GoIm4HpYeRyjJl9b_6FY,1136
|
|
60
60
|
abstract_utilities/directory_utils/src/size_utils.py,sha256=6huRLt-UGhukGfq-3KtBM5qH_SjNCaBzWVP9Vc-EiiU,1758
|
|
61
61
|
abstract_utilities/directory_utils/src/utils.py,sha256=FIxL_HcIoL0PzE6G7_qcgCNcelxX33J76gzkXJo3VUg,3206
|
|
@@ -94,7 +94,7 @@ abstract_utilities/file_utils/imports/clean_imps.py,sha256=DB_NEKR8YLla5qCkTMuNs
|
|
|
94
94
|
abstract_utilities/file_utils/imports/constants.py,sha256=uPsIYVRs1Rf0SQ4pRdAke-tuc28LtgaSHSDS4_seaMk,5997
|
|
95
95
|
abstract_utilities/file_utils/imports/file_functions.py,sha256=brQha7TV9DaJe-hZSuHoFZBUI_45hxrGOIBTAojPWU8,297
|
|
96
96
|
abstract_utilities/file_utils/imports/imports.py,sha256=OQKsPec2raa55hxGUeTo0yDqzw-xBsshljFxG69rHk0,1504
|
|
97
|
-
abstract_utilities/file_utils/imports/module_imports.py,sha256=
|
|
97
|
+
abstract_utilities/file_utils/imports/module_imports.py,sha256=Mol48vj-m2204MCJgStUyAw8DbH-HFVs21rnGpx5HyI,420
|
|
98
98
|
abstract_utilities/file_utils/src/__init__.py,sha256=kgjkZ6IWDR_fQJTAQTinUBKUPLurekgdZ15ZT1wm20E,203
|
|
99
99
|
abstract_utilities/file_utils/src/file_filters.py,sha256=n8efrxxJRRd6dT4E5PbGoyGGKe1LU1cYy-b443XhqAo,6355
|
|
100
100
|
abstract_utilities/file_utils/src/file_reader.py,sha256=9fZ2dEXFRYhJNUsUYQO3hGs2uWrHu2o4FacVhfhdefE,22320
|
|
@@ -102,15 +102,16 @@ abstract_utilities/file_utils/src/file_utils.py,sha256=jgxMKeOAhYB2dxoqtudo4DKXc
|
|
|
102
102
|
abstract_utilities/file_utils/src/filter_params.py,sha256=tO5PJvYpd3bHQejulDVGHandR-_8w3VPnjiCayrLW9g,6774
|
|
103
103
|
abstract_utilities/file_utils/src/find_collect.py,sha256=wV6u9AsVeJxMCHwyf3NGvzA-QbA_OgLRfQUhjSrLjew,5796
|
|
104
104
|
abstract_utilities/file_utils/src/find_content.py,sha256=3UI8HsTHR0UnuqybeYW4rxHvER7-SK42_hNZih-LfUU,6806
|
|
105
|
-
abstract_utilities/file_utils/src/initFunctionsGen.py,sha256=
|
|
105
|
+
abstract_utilities/file_utils/src/initFunctionsGen.py,sha256=WyWv3Gt33QzvI8IxZCGLqAqsramAyoRbpvMTiuJeSTE,10418
|
|
106
|
+
abstract_utilities/file_utils/src/initFunctionsGens.py,sha256=A-I2dL2G58LfpCSI6c_aLbDtAsYvG0wwY37joYnqGcw,9804
|
|
106
107
|
abstract_utilities/file_utils/src/map_utils.py,sha256=7GYntXbMz3vYrXWE-TxLuZRcQudlDA6vAWGErzVv1mk,1044
|
|
107
108
|
abstract_utilities/file_utils/src/pdf_utils.py,sha256=F-xzOMFK7Um_7ODTqJ8MsdgAOyupi1ijuB1zHv76bUw,10336
|
|
108
109
|
abstract_utilities/file_utils/src/type_checks.py,sha256=THVaH23DYdPYuj6baC-KJOfWDsfEqWqxsVa_N7e8aEI,2890
|
|
109
110
|
abstract_utilities/file_utils/src/file_filters/__init__.py,sha256=sHdfkZ6JrSlK8I6sNrzbGEUGz0ZUDTnFmXwaBMNxNLY,116
|
|
110
|
-
abstract_utilities/file_utils/src/file_filters/ensure_utils.py,sha256=
|
|
111
|
+
abstract_utilities/file_utils/src/file_filters/ensure_utils.py,sha256=JrJZPaoh9K5rD_DDA1r-az4lLgv_gcoBvKpUfNYAWdI,4268
|
|
111
112
|
abstract_utilities/file_utils/src/file_filters/filter_params.py,sha256=RazBjD0Zl4fjXvmXl0YUrqAacwKn8w1EUaqKqunTB9Y,2993
|
|
112
113
|
abstract_utilities/file_utils/src/file_filters/filter_utils.py,sha256=epi9V1OkYDAJb2O5LzkqQBtBoDtkCidGBvuXsUFCxaw,2916
|
|
113
|
-
abstract_utilities/file_utils/src/file_filters/predicate_utils.py,sha256=
|
|
114
|
+
abstract_utilities/file_utils/src/file_filters/predicate_utils.py,sha256=E5JEfl0ytbBF3AvlR1WVhS7QRtwc1YKqVNB6md1rfpI,5040
|
|
114
115
|
abstract_utilities/file_utils/src/reader_utils/__init__.py,sha256=GLUNbm2lK_2ZVk9EGQ6KNr5k1NR52tT3QBhzH93FqWo,112
|
|
115
116
|
abstract_utilities/file_utils/src/reader_utils/directory_reader.py,sha256=qHZuhwIsrVkJkFT8kFwzkCH-6kmR1hyr7TFAGg9vcOw,2366
|
|
116
117
|
abstract_utilities/file_utils/src/reader_utils/file_reader.py,sha256=FwDFIGCz5mMksvmLFJSkTLS2evBkUnN0kND7E_9b45g,22292
|
|
@@ -151,17 +152,17 @@ abstract_utilities/import_utils/circular_import_finder2.py,sha256=n6OFjiIsxxw2u_
|
|
|
151
152
|
abstract_utilities/import_utils/imports/__init__.py,sha256=hiUo2P3qSWtgQHPdz5b2pe2AI3QXZlKJUSe2NUW5Cd4,99
|
|
152
153
|
abstract_utilities/import_utils/imports/constants.py,sha256=UCSr0_KTu7atqanliMEv8u-XKjM4x0wdm4oySOK7APc,42
|
|
153
154
|
abstract_utilities/import_utils/imports/imports.py,sha256=Qc9IoIDAJUuNOQJqZbOEqQfGI45EVhBBeuTm61K6PvI,143
|
|
154
|
-
abstract_utilities/import_utils/imports/module_imports.py,sha256=
|
|
155
|
+
abstract_utilities/import_utils/imports/module_imports.py,sha256=HrMpc0o4kBhbvxHyKZqbQ1U4LK03zaLJaLqMRg6LO9w,534
|
|
155
156
|
abstract_utilities/import_utils/imports/utils.py,sha256=wgTzs8SpOe8jVdw0cCPNypYCo2X-BreeJuNW3N3_d8Q,961
|
|
156
157
|
abstract_utilities/import_utils/src/__init__.py,sha256=KPF8T-ZQae2st8EKR7qIAt1jENGlQkwHRJDC8uupm48,197
|
|
157
158
|
abstract_utilities/import_utils/src/clean_imports.py,sha256=awpVFI-DMd8oOtx3JcUiz4xbOdhLE4X04ZwdMKR1mMU,10447
|
|
158
159
|
abstract_utilities/import_utils/src/dot_utils.py,sha256=oahEkVmexO-a2F3DKYQP5IrCvKJi9tjM_rjCImM_KCY,2793
|
|
159
|
-
abstract_utilities/import_utils/src/extract_utils.py,sha256=
|
|
160
|
-
abstract_utilities/import_utils/src/import_functions.py,sha256=
|
|
160
|
+
abstract_utilities/import_utils/src/extract_utils.py,sha256=YuDVWbCKDrVDh9M7aZHdsrEoh_infJ3BUv46J6K-UYg,1705
|
|
161
|
+
abstract_utilities/import_utils/src/import_functions.py,sha256=5GxFh32e-DWDZ5IR-LnQTOiEmv15tjb3Fn_yhgnu7q8,4408
|
|
161
162
|
abstract_utilities/import_utils/src/import_utils.py,sha256=NvryqWqsoyufTKYEoGgnorl9awRbgVWcOroHJza_srM,11827
|
|
162
163
|
abstract_utilities/import_utils/src/package_utils.py,sha256=9qjBzIApDhV7kOdSRgZA9k-EncBNAg3mZZodgsiUNM4,5861
|
|
163
164
|
abstract_utilities/import_utils/src/pkg_utils.py,sha256=tSLaqFgitwswSuGhv-UnONT3rpri9DjK9ALt_0t5I30,7617
|
|
164
|
-
abstract_utilities/import_utils/src/sysroot_utils.py,sha256=
|
|
165
|
+
abstract_utilities/import_utils/src/sysroot_utils.py,sha256=k9sNVvp3zYrPV62rsaFLfCzXhaIQc61XJreog0RvOIc,3696
|
|
165
166
|
abstract_utilities/import_utils/src/package_utils/__init__.py,sha256=xV_XKJSLcXf4qRQSRseWLV_iqCqijPm4zvrs-tjNb2M,4618
|
|
166
167
|
abstract_utilities/import_utils/src/package_utils/context_utils.py,sha256=8USSB6LR047k8fqge8J2jEM_StPEZ3cI1OKB3UENN8w,1177
|
|
167
168
|
abstract_utilities/import_utils/src/package_utils/import_collectors.py,sha256=kueQead4CW6FGmHHiXpQilE8spbnt2mSK93dJ3bpeW4,2365
|
|
@@ -185,7 +186,7 @@ abstract_utilities/list_utils/imports/module_imports.py,sha256=47DEQpj8HBSa-_TIm
|
|
|
185
186
|
abstract_utilities/log_utils/__init__.py,sha256=QzmY8RLyegJsq9Id06dHMiJAit5jxUzwhkY5-qgqxBU,141
|
|
186
187
|
abstract_utilities/log_utils/abstractLogManager.py,sha256=EF4GkNbeCUh_RStN2Sf_PmxgyUmxeB5RJT7P-SHGZ3w,2823
|
|
187
188
|
abstract_utilities/log_utils/call_response.py,sha256=E_QdT6R5REuXxeUuEXLwjUh8D0Lk0vair2ryRj4zocY,2518
|
|
188
|
-
abstract_utilities/log_utils/log_file.py,sha256=
|
|
189
|
+
abstract_utilities/log_utils/log_file.py,sha256=5W3Ia5RLGho6WbQNnqZTmQbRiEzUqGYIMlbEyzKElQg,3769
|
|
189
190
|
abstract_utilities/log_utils/logger_callable.py,sha256=9STZtZrmUlXmakxhwmXNPpCSQC10aCTMNjXbhaWZ7_8,1629
|
|
190
191
|
abstract_utilities/log_utils/imports/__init__.py,sha256=sUUAr6PY1SMtVjSTsb08dFU6mF-Ug4usnbh908q4Jq0,53
|
|
191
192
|
abstract_utilities/log_utils/imports/imports.py,sha256=TGhATFGyhvovFFKYH-CbCnEQK0WCkmA1C5LqvmmzlrQ,189
|
|
@@ -196,7 +197,7 @@ abstract_utilities/math_utils/imports/__init__.py,sha256=sUUAr6PY1SMtVjSTsb08dFU
|
|
|
196
197
|
abstract_utilities/math_utils/imports/imports.py,sha256=IIGHGPK61piV3IKDaLVRvUPIkxznkKqYGIQV_QFpCZs,57
|
|
197
198
|
abstract_utilities/math_utils/imports/module_imports.py,sha256=xt-zuDypjLnq2FBacEeho9LpDwfQHngT9tT1GxEUFbU,47
|
|
198
199
|
abstract_utilities/parse_utils/__init__.py,sha256=7Ubmny6MOJibdI3B22_iLaHH6iobrwii0fjRAUzewEU,50
|
|
199
|
-
abstract_utilities/parse_utils/parse_utils.py,sha256=
|
|
200
|
+
abstract_utilities/parse_utils/parse_utils.py,sha256=0bYFLOzhTTEW0eqAEPRCEqcamInUJF7iAQlf7ZoHrp4,19120
|
|
200
201
|
abstract_utilities/parse_utils/imports/__init__.py,sha256=ba1PFyO4a5Qjp35ZjGesaVoZJ7mV9l2OnTK_7M9tGis,78
|
|
201
202
|
abstract_utilities/parse_utils/imports/constants.py,sha256=PsYAIKIwg_-oxO_rgPrT554B7yLPsFF1dvmyHF6cibQ,227
|
|
202
203
|
abstract_utilities/parse_utils/imports/imports.py,sha256=HSPmM0Y9GCFEIPbovNh79ayKjdNWMC-m-8QYa1JEpDk,76
|
|
@@ -207,9 +208,9 @@ abstract_utilities/path_utils/imports/__init__.py,sha256=wBNCq8vHWdl7DleRNq0UK_-
|
|
|
207
208
|
abstract_utilities/path_utils/imports/imports.py,sha256=R7rno0pnzOU9XpzPhco0Wp9aIR73w_BGqCLdYpAHowI,32
|
|
208
209
|
abstract_utilities/path_utils/imports/module_imports.py,sha256=bPhfxar3bk4PjEfHdBK7Q6VSODpXyTXNLO2GKnHr2AE,376
|
|
209
210
|
abstract_utilities/read_write_utils/__init__.py,sha256=MYC2oSY2NEbnu-iwX55t9m_rFRVxwILY_oUbBCpGJkw,32
|
|
210
|
-
abstract_utilities/read_write_utils/read_write_utils.py,sha256=
|
|
211
|
+
abstract_utilities/read_write_utils/read_write_utils.py,sha256=sbz4jWcFjYG-WywOsPizMS-oRRs-l_57RQ-Ow9A8xfo,12685
|
|
211
212
|
abstract_utilities/read_write_utils/imports/__init__.py,sha256=sUUAr6PY1SMtVjSTsb08dFU6mF-Ug4usnbh908q4Jq0,53
|
|
212
|
-
abstract_utilities/read_write_utils/imports/imports.py,sha256=
|
|
213
|
+
abstract_utilities/read_write_utils/imports/imports.py,sha256=zN1zEfAJ-UbJB34wxm2oVuAiDmyqS12dSoIzojUrsiM,46
|
|
213
214
|
abstract_utilities/read_write_utils/imports/module_imports.py,sha256=cwmzuy1RKPyq2rQtMU6KSMSjDE9jUhPzHPjRTdTXcto,204
|
|
214
215
|
abstract_utilities/robust_reader/__init__.py,sha256=4i6qW4lwhdYuoO5-p9Xbt8Lpmr3hzCh9Rgb9y19QJwk,28
|
|
215
216
|
abstract_utilities/robust_reader/file_reader2.py,sha256=U-5opkLu-bct091Eb-5CiNBTf0UFoSITYi8zR-Sz38w,25077
|
|
@@ -271,7 +272,7 @@ abstract_utilities/type_utils/imports/__init__.py,sha256=sUUAr6PY1SMtVjSTsb08dFU
|
|
|
271
272
|
abstract_utilities/type_utils/imports/imports.py,sha256=C_ZAQO-y7R31BYxTuaHJCEQE9IZSU1JgCtdHNWxZKhY,77
|
|
272
273
|
abstract_utilities/type_utils/imports/module_imports.py,sha256=sxF9YJQhUFUivgslnU-4Y5GG_J1IHR7kunUefIYZ0Lk,36
|
|
273
274
|
imports/__init__.py,sha256=2PSEAwZY88J2NHt98XCO5drFNok5ctiJ8LE02kwABP4,944
|
|
274
|
-
abstract_utilities-0.2.2.
|
|
275
|
-
abstract_utilities-0.2.2.
|
|
276
|
-
abstract_utilities-0.2.2.
|
|
277
|
-
abstract_utilities-0.2.2.
|
|
275
|
+
abstract_utilities-0.2.2.627.dist-info/METADATA,sha256=ZLU9D2LYyLcu0fXp2TXt2QRxMy5B8FELrZc2x-6Susc,28108
|
|
276
|
+
abstract_utilities-0.2.2.627.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
277
|
+
abstract_utilities-0.2.2.627.dist-info/top_level.txt,sha256=BF0GZ0xVFfN1K-hFIWPO3viNsOs1sSF86n1vHBg39FM,19
|
|
278
|
+
abstract_utilities-0.2.2.627.dist-info/RECORD,,
|
|
File without changes
|
{abstract_utilities-0.2.2.583.dist-info → abstract_utilities-0.2.2.627.dist-info}/top_level.txt
RENAMED
|
File without changes
|