abstract-utilities 0.2.2.442__py3-none-any.whl → 0.2.2.688__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

Files changed (236) hide show
  1. abstract_utilities/__init__.py +25 -16
  2. abstract_utilities/circular_import_finder.py +222 -0
  3. abstract_utilities/circular_import_finder2.py +118 -0
  4. abstract_utilities/class_utils/__init__.py +7 -0
  5. abstract_utilities/class_utils/abstract_classes.py +144 -0
  6. abstract_utilities/class_utils/caller_utils.py +92 -0
  7. abstract_utilities/class_utils/class_utils.py +109 -0
  8. abstract_utilities/class_utils/function_utils.py +153 -0
  9. abstract_utilities/class_utils/global_utils.py +71 -0
  10. abstract_utilities/class_utils/imports/__init__.py +2 -0
  11. abstract_utilities/class_utils/imports/imports.py +2 -0
  12. abstract_utilities/class_utils/imports/utils.py +40 -0
  13. abstract_utilities/class_utils/module_utils.py +63 -0
  14. abstract_utilities/class_utils.py +0 -1
  15. abstract_utilities/directory_utils/__init__.py +2 -0
  16. abstract_utilities/directory_utils/directory_utils.py +94 -0
  17. abstract_utilities/directory_utils/imports/__init__.py +2 -0
  18. abstract_utilities/directory_utils/imports/imports.py +1 -0
  19. abstract_utilities/directory_utils/imports/module_imports.py +2 -0
  20. abstract_utilities/directory_utils/name_utils.py +43 -0
  21. abstract_utilities/directory_utils/size_utils.py +57 -0
  22. abstract_utilities/directory_utils/src/__init__.py +4 -0
  23. abstract_utilities/directory_utils/src/directory_utils.py +110 -0
  24. abstract_utilities/directory_utils/src/name_utils.py +43 -0
  25. abstract_utilities/directory_utils/src/size_utils.py +57 -0
  26. abstract_utilities/directory_utils/src/utils.py +116 -0
  27. abstract_utilities/directory_utils/utils.py +116 -0
  28. abstract_utilities/dynimport.py +1 -1
  29. abstract_utilities/env_utils/imports/imports.py +5 -3
  30. abstract_utilities/error_utils/__init__.py +2 -0
  31. abstract_utilities/error_utils/error_utils.py +25 -0
  32. abstract_utilities/error_utils/imports/__init__.py +2 -0
  33. abstract_utilities/error_utils/imports/imports.py +1 -0
  34. abstract_utilities/error_utils/imports/module_imports.py +1 -0
  35. abstract_utilities/file_utils/__init__.py +1 -2
  36. abstract_utilities/file_utils/file_utils/__init__.py +2 -0
  37. abstract_utilities/file_utils/file_utils/file_utils.py +3 -3
  38. abstract_utilities/file_utils/file_utils/find_collect.py +154 -0
  39. abstract_utilities/file_utils/file_utils/imports/__init__.py +3 -0
  40. abstract_utilities/file_utils/file_utils/imports/constants.py +39 -0
  41. abstract_utilities/file_utils/file_utils/imports/file_functions.py +10 -0
  42. abstract_utilities/file_utils/file_utils/imports/imports.py +39 -0
  43. abstract_utilities/file_utils/file_utils/imports/module_imports.py +14 -0
  44. abstract_utilities/file_utils/file_utils/imports.py +9 -0
  45. abstract_utilities/file_utils/file_utils/type_checks.py +92 -0
  46. abstract_utilities/file_utils/imports/__init__.py +1 -2
  47. abstract_utilities/file_utils/imports/classes.py +59 -55
  48. abstract_utilities/file_utils/imports/clean_imps.py +158 -0
  49. abstract_utilities/file_utils/imports/constants.py +84 -4
  50. abstract_utilities/file_utils/imports/file_functions.py +1 -1
  51. abstract_utilities/file_utils/imports/imports.py +40 -8
  52. abstract_utilities/file_utils/imports/module_imports.py +4 -5
  53. abstract_utilities/file_utils/module_imports.py +12 -0
  54. abstract_utilities/file_utils/src/__init__.py +7 -0
  55. abstract_utilities/file_utils/src/file_filters/__init__.py +1 -0
  56. abstract_utilities/file_utils/src/file_filters/ensure_utils.py +490 -0
  57. abstract_utilities/file_utils/src/file_filters/filter_params.py +150 -0
  58. abstract_utilities/file_utils/src/file_filters/filter_utils.py +78 -0
  59. abstract_utilities/file_utils/src/file_filters/predicate_utils.py +44 -0
  60. abstract_utilities/file_utils/src/file_filters.py +177 -0
  61. abstract_utilities/file_utils/src/file_reader.py +543 -0
  62. abstract_utilities/file_utils/src/file_utils.py +156 -0
  63. abstract_utilities/file_utils/src/filter_params.py +197 -0
  64. abstract_utilities/file_utils/src/find_collect.py +200 -0
  65. abstract_utilities/file_utils/src/find_content.py +210 -0
  66. abstract_utilities/file_utils/src/initFunctionsGen.py +293 -0
  67. abstract_utilities/file_utils/src/initFunctionsGens.py +280 -0
  68. abstract_utilities/file_utils/src/map_utils.py +29 -0
  69. abstract_utilities/file_utils/src/pdf_utils.py +300 -0
  70. abstract_utilities/file_utils/src/reader_utils/__init__.py +4 -0
  71. abstract_utilities/file_utils/src/reader_utils/directory_reader.py +53 -0
  72. abstract_utilities/file_utils/src/reader_utils/file_reader.py +543 -0
  73. abstract_utilities/file_utils/src/reader_utils/file_readers.py +376 -0
  74. abstract_utilities/file_utils/src/reader_utils/imports.py +18 -0
  75. abstract_utilities/file_utils/src/reader_utils/pdf_utils.py +300 -0
  76. abstract_utilities/file_utils/src/type_checks.py +91 -0
  77. abstract_utilities/file_utils (2)/__init__.py +2 -0
  78. abstract_utilities/file_utils (2)/imports/__init__.py +2 -0
  79. abstract_utilities/file_utils (2)/imports/constants.py +118 -0
  80. abstract_utilities/file_utils (2)/imports/imports/__init__.py +3 -0
  81. abstract_utilities/file_utils (2)/imports/imports/constants.py +119 -0
  82. abstract_utilities/file_utils (2)/imports/imports/imports.py +46 -0
  83. abstract_utilities/file_utils (2)/imports/imports/module_imports.py +8 -0
  84. abstract_utilities/file_utils (2)/imports/utils/__init__.py +3 -0
  85. abstract_utilities/file_utils (2)/imports/utils/classes.py +379 -0
  86. abstract_utilities/file_utils (2)/imports/utils/clean_imps.py +155 -0
  87. abstract_utilities/file_utils (2)/imports/utils/filter_utils.py +341 -0
  88. abstract_utilities/file_utils (2)/src/__init__.py +8 -0
  89. abstract_utilities/file_utils (2)/src/file_filters.py +155 -0
  90. abstract_utilities/file_utils (2)/src/file_reader.py +604 -0
  91. abstract_utilities/file_utils (2)/src/find_collect.py +258 -0
  92. abstract_utilities/file_utils (2)/src/initFunctionsGen.py +286 -0
  93. abstract_utilities/file_utils (2)/src/map_utils.py +28 -0
  94. abstract_utilities/file_utils (2)/src/pdf_utils.py +300 -0
  95. abstract_utilities/hash_utils/__init__.py +2 -0
  96. abstract_utilities/hash_utils/hash_utils.py +5 -0
  97. abstract_utilities/hash_utils/imports/__init__.py +2 -0
  98. abstract_utilities/hash_utils/imports/imports.py +1 -0
  99. abstract_utilities/hash_utils/imports/module_imports.py +0 -0
  100. abstract_utilities/history_utils/__init__.py +2 -0
  101. abstract_utilities/history_utils/history_utils.py +37 -0
  102. abstract_utilities/history_utils/imports/__init__.py +2 -0
  103. abstract_utilities/history_utils/imports/imports.py +1 -0
  104. abstract_utilities/history_utils/imports/module_imports.py +0 -0
  105. abstract_utilities/import_utils/__init__.py +2 -0
  106. abstract_utilities/import_utils/circular_import_finder.py +222 -0
  107. abstract_utilities/import_utils/circular_import_finder2.py +118 -0
  108. abstract_utilities/import_utils/imports/__init__.py +4 -0
  109. abstract_utilities/import_utils/imports/constants.py +2 -0
  110. abstract_utilities/import_utils/imports/imports.py +4 -0
  111. abstract_utilities/import_utils/imports/init_imports.py +3 -0
  112. abstract_utilities/import_utils/imports/module_imports.py +9 -0
  113. abstract_utilities/import_utils/imports/utils.py +30 -0
  114. abstract_utilities/import_utils/src/__init__.py +8 -0
  115. abstract_utilities/import_utils/src/clean_imports.py +278 -0
  116. abstract_utilities/import_utils/src/dot_utils.py +80 -0
  117. abstract_utilities/import_utils/src/extract_utils.py +46 -0
  118. abstract_utilities/import_utils/src/import_functions.py +110 -0
  119. abstract_utilities/import_utils/src/import_utils.py +349 -0
  120. abstract_utilities/import_utils/src/layze_import_utils/__init__.py +2 -0
  121. abstract_utilities/import_utils/src/layze_import_utils/lazy_utils.py +41 -0
  122. abstract_utilities/import_utils/src/layze_import_utils/nullProxy.py +37 -0
  123. abstract_utilities/import_utils/src/nullProxy.py +30 -0
  124. abstract_utilities/import_utils/src/package_utils/__init__.py +139 -0
  125. abstract_utilities/import_utils/src/package_utils/context_utils.py +27 -0
  126. abstract_utilities/import_utils/src/package_utils/import_collectors.py +53 -0
  127. abstract_utilities/import_utils/src/package_utils/path_utils.py +28 -0
  128. abstract_utilities/import_utils/src/package_utils/safe_import.py +27 -0
  129. abstract_utilities/import_utils/src/package_utils.py +140 -0
  130. abstract_utilities/import_utils/src/package_utilss/__init__.py +139 -0
  131. abstract_utilities/import_utils/src/package_utilss/context_utils.py +27 -0
  132. abstract_utilities/import_utils/src/package_utilss/import_collectors.py +53 -0
  133. abstract_utilities/import_utils/src/package_utilss/path_utils.py +28 -0
  134. abstract_utilities/import_utils/src/package_utilss/safe_import.py +27 -0
  135. abstract_utilities/import_utils/src/pkg_utils.py +194 -0
  136. abstract_utilities/import_utils/src/sysroot_utils.py +112 -0
  137. abstract_utilities/imports.py +21 -0
  138. abstract_utilities/json_utils/__init__.py +2 -0
  139. abstract_utilities/json_utils/imports/__init__.py +2 -0
  140. abstract_utilities/json_utils/imports/imports.py +2 -0
  141. abstract_utilities/json_utils/imports/module_imports.py +5 -0
  142. abstract_utilities/json_utils/json_utils.py +777 -0
  143. abstract_utilities/list_utils/__init__.py +2 -0
  144. abstract_utilities/list_utils/imports/__init__.py +2 -0
  145. abstract_utilities/list_utils/imports/imports.py +1 -0
  146. abstract_utilities/list_utils/imports/module_imports.py +0 -0
  147. abstract_utilities/list_utils/list_utils.py +202 -0
  148. abstract_utilities/log_utils/__init__.py +5 -0
  149. abstract_utilities/log_utils/abstractLogManager.py +64 -0
  150. abstract_utilities/log_utils/call_response.py +68 -0
  151. abstract_utilities/log_utils/imports/__init__.py +2 -0
  152. abstract_utilities/log_utils/imports/imports.py +7 -0
  153. abstract_utilities/log_utils/imports/module_imports.py +2 -0
  154. abstract_utilities/log_utils/log_file.py +162 -0
  155. abstract_utilities/log_utils/logger_callable.py +49 -0
  156. abstract_utilities/math_utils/__init__.py +2 -0
  157. abstract_utilities/math_utils/imports/__init__.py +2 -0
  158. abstract_utilities/math_utils/imports/imports.py +2 -0
  159. abstract_utilities/math_utils/imports/module_imports.py +1 -0
  160. abstract_utilities/math_utils/math_utils.py +208 -0
  161. abstract_utilities/parse_utils/__init__.py +2 -0
  162. abstract_utilities/parse_utils/imports/__init__.py +3 -0
  163. abstract_utilities/parse_utils/imports/constants.py +10 -0
  164. abstract_utilities/parse_utils/imports/imports.py +2 -0
  165. abstract_utilities/parse_utils/imports/module_imports.py +4 -0
  166. abstract_utilities/parse_utils/parse_utils.py +539 -0
  167. abstract_utilities/path_utils/__init__.py +2 -0
  168. abstract_utilities/path_utils/imports/__init__.py +3 -0
  169. abstract_utilities/path_utils/imports/imports.py +1 -0
  170. abstract_utilities/path_utils/imports/module_imports.py +8 -0
  171. abstract_utilities/path_utils/path_utils.py +248 -0
  172. abstract_utilities/path_utils.py +95 -14
  173. abstract_utilities/read_write_utils/__init__.py +1 -0
  174. abstract_utilities/read_write_utils/imports/__init__.py +2 -0
  175. abstract_utilities/read_write_utils/imports/imports.py +2 -0
  176. abstract_utilities/read_write_utils/imports/module_imports.py +5 -0
  177. abstract_utilities/read_write_utils/read_write_utils.py +439 -0
  178. abstract_utilities/read_write_utils.py +218 -10
  179. abstract_utilities/robust_reader/imports/imports.py +0 -9
  180. abstract_utilities/robust_readers/import_utils/__init__.py +1 -0
  181. abstract_utilities/robust_readers/import_utils/clean_imports.py +175 -0
  182. abstract_utilities/robust_readers/initFuncGen.py +10 -2
  183. abstract_utilities/safe_utils/__init__.py +2 -0
  184. abstract_utilities/safe_utils/imports/__init__.py +3 -0
  185. abstract_utilities/safe_utils/imports/imports.py +2 -0
  186. abstract_utilities/safe_utils/imports/module_imports.py +2 -0
  187. abstract_utilities/safe_utils/safe_utils.py +166 -0
  188. abstract_utilities/ssh_utils/__init__.py +3 -1
  189. abstract_utilities/ssh_utils/classes.py +0 -1
  190. abstract_utilities/ssh_utils/cmd_utils.py +207 -0
  191. abstract_utilities/ssh_utils/imports/__init__.py +3 -0
  192. abstract_utilities/ssh_utils/imports/imports.py +5 -0
  193. abstract_utilities/ssh_utils/imports/module_imports.py +6 -0
  194. abstract_utilities/ssh_utils/imports/utils.py +189 -0
  195. abstract_utilities/ssh_utils/imports.py +1 -2
  196. abstract_utilities/ssh_utils/pexpect_utils.py +11 -18
  197. abstract_utilities/ssh_utils/type_checks.py +92 -0
  198. abstract_utilities/string_clean.py +40 -1
  199. abstract_utilities/string_utils/__init__.py +4 -0
  200. abstract_utilities/string_utils/clean_utils.py +28 -0
  201. abstract_utilities/string_utils/eat_utils.py +103 -0
  202. abstract_utilities/string_utils/imports/__init__.py +3 -0
  203. abstract_utilities/string_utils/imports/imports.py +2 -0
  204. abstract_utilities/string_utils/imports/module_imports.py +2 -0
  205. abstract_utilities/string_utils/imports/utils.py +81 -0
  206. abstract_utilities/string_utils/replace_utils.py +27 -0
  207. abstract_utilities/string_utils.py +51 -0
  208. abstract_utilities/thread_utils/__init__.py +2 -0
  209. abstract_utilities/thread_utils/imports/__init__.py +2 -0
  210. abstract_utilities/thread_utils/imports/imports.py +2 -0
  211. abstract_utilities/thread_utils/imports/module_imports.py +2 -0
  212. abstract_utilities/thread_utils/thread_utils.py +140 -0
  213. abstract_utilities/time_utils/__init__.py +2 -0
  214. abstract_utilities/time_utils/imports/__init__.py +2 -0
  215. abstract_utilities/time_utils/imports/imports.py +3 -0
  216. abstract_utilities/time_utils/imports/module_imports.py +1 -0
  217. abstract_utilities/time_utils/time_utils.py +392 -0
  218. abstract_utilities/type_utils/__init__.py +7 -0
  219. abstract_utilities/type_utils/alpha_utils.py +59 -0
  220. abstract_utilities/type_utils/get_type.py +120 -0
  221. abstract_utilities/type_utils/imports/__init__.py +3 -0
  222. abstract_utilities/type_utils/imports/constants.py +134 -0
  223. abstract_utilities/type_utils/imports/imports.py +4 -0
  224. abstract_utilities/type_utils/imports/module_imports.py +25 -0
  225. abstract_utilities/type_utils/is_type.py +455 -0
  226. abstract_utilities/type_utils/make_type.py +126 -0
  227. abstract_utilities/type_utils/mime_types.py +68 -0
  228. abstract_utilities/type_utils/num_utils.py +19 -0
  229. abstract_utilities/type_utils/type_utils.py +104 -0
  230. abstract_utilities/type_utils.py +25 -1
  231. {abstract_utilities-0.2.2.442.dist-info → abstract_utilities-0.2.2.688.dist-info}/METADATA +1 -1
  232. abstract_utilities-0.2.2.688.dist-info/RECORD +288 -0
  233. imports/__init__.py +36 -0
  234. abstract_utilities-0.2.2.442.dist-info/RECORD +0 -82
  235. {abstract_utilities-0.2.2.442.dist-info → abstract_utilities-0.2.2.688.dist-info}/WHEEL +0 -0
  236. {abstract_utilities-0.2.2.442.dist-info → abstract_utilities-0.2.2.688.dist-info}/top_level.txt +0 -0
@@ -1,11 +1,6 @@
1
- import re,threading,os,shutil,requests,asyncio,time,subprocess,json,glob,sys,logging
2
- from datetime import timedelta
3
- from datetime import datetime
4
- from typing import *
1
+ from .imports import *
5
2
  from .hash_utils import *
6
3
  ##from .dynimport import get_abstract_import,import_symbols_to_parent,call_for_all_tabs
7
- from .robust_readers import *
8
- from .dynimport import get_abstract_import
9
4
  from .json_utils import (unified_json_loader,
10
5
  find_keys,
11
6
  get_key_values_from_path,
@@ -37,10 +32,11 @@ from .json_utils import (unified_json_loader,
37
32
  safe_write_to_file,
38
33
  safe_save_updated_json_data,
39
34
  get_result_from_data,
40
- flatten_json
35
+ flatten_json,
36
+ to_json_safe
41
37
  )
42
- from .read_write_utils import (read_from_file,
43
- write_to_file)
38
+
39
+ from .directory_utils import *
44
40
  from .path_utils import *
45
41
  from .file_utils import *
46
42
  from .list_utils import (get_highest_value_obj,
@@ -50,7 +46,9 @@ from .list_utils import (get_highest_value_obj,
50
46
  compare_lists,
51
47
  get_symetric_difference,
52
48
  list_set,
53
- make_list_it)
49
+ make_list_it,
50
+ get_single_from_list
51
+ )
54
52
  from .time_utils import (get_time_stamp,
55
53
  get_sleep,
56
54
  sleep_count_down,
@@ -61,7 +59,7 @@ from .time_utils import (get_time_stamp,
61
59
  parse_timestamp,
62
60
  get_time_now_iso,
63
61
  is_valid_time)
64
- from .string_clean import (eatInner,
62
+ from .string_utils import (eatInner,
65
63
  eatAll,
66
64
  eatOuter,
67
65
  url_join,
@@ -88,7 +86,8 @@ from .type_utils import (make_bool,
88
86
  get_numbers_comp,
89
87
  is_any_instance,
90
88
  break_string,
91
- MIME_TYPES
89
+ MIME_TYPES,
90
+ get_if_None
92
91
  )
93
92
  get_media_types = get_all_types = get_all_file_types
94
93
  from .math_utils import (convert_to_percentage,
@@ -106,19 +105,29 @@ from .compare_utils import (create_new_name,
106
105
  best_match)
107
106
  from .thread_utils import ThreadManager
108
107
  from .history_utils import HistoryManager
109
- from .abstract_classes import *
108
+
110
109
  from .parse_utils import (num_tokens_from_string,
111
110
  chunk_source_code,
112
111
  chunk_any_to_tokens,
113
112
  detect_language_from_text,
114
113
  chunk_by_language_context,
115
- search_code)
114
+ search_code,
115
+ get_within_quotes)
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
119
+ from .class_utils import *
120
120
  from .ssh_utils import *
121
121
  from .env_utils import *
122
122
  from .path_utils import *
123
123
  from .file_utils import *
124
- from .file_utils import call_for_all_tabs
124
+ from .string_utils import *
125
+ from .import_utils import *
126
+ from .read_write_utils import (read_from_file,
127
+ write_to_file,
128
+ make_dirs,
129
+ make_dirs,
130
+ copy_files,
131
+ make_path,
132
+ run_cmd
133
+ )
@@ -0,0 +1,222 @@
1
+ from abstract_utilities import *
2
+ from collections import defaultdict
3
+ def clean_line(line):
4
+ return eatAll(line,[' ','','\t','\n'])
5
+ def is_from_line_group(line):
6
+ if line and line.startswith(FROM_TAG) and IMPORT_TAG in line and '(' in line:
7
+ import_spl = line.split(IMPORT_TAG)[-1]
8
+ import_spl_clean = clean_line(line)
9
+ if not import_spl_clean.endswith(')'):
10
+ return True
11
+ return False
12
+ def clean_imports(text=None,file_path=None,import_pkg_js=None,fill_nulines=False):
13
+ if text and os.path.isfile(text):
14
+ file_path = text
15
+ input(file_path)
16
+ text = read_from_file(file_path)
17
+ if not import_pkg_js:
18
+ import_pkg_js = get_all_imports(text=text,file_path=file_path)
19
+ import_pkg_js = ensure_import_pkg_js(import_pkg_js,file_path=file_path)
20
+ nu_lines = import_pkg_js["context"]["nulines"]
21
+ for pkg,values in import_pkg_js.items():
22
+ comments = []
23
+ if pkg not in ["context"]:
24
+
25
+ imports = values.get('imports')
26
+ for i,imp in enumerate(imports):
27
+ if '#' in imp:
28
+ imp_spl = imp.split('#')
29
+ comments.append(imp_spl[-1])
30
+ imports[i] = clean_line(imp_spl[0])
31
+ imports = list(set(imports))
32
+ if '*' in imports:
33
+ imports="*"
34
+ else:
35
+ imports=','.join(imports)
36
+ if comments:
37
+ comments=','.join(comments)
38
+ imports+=f" #{comments}"
39
+ import_pkg_js[pkg]["imports"]=imports
40
+ if fill_nulines:
41
+ line = values.get('line')
42
+ if len(nu_lines) >= line:
43
+ nu_lines[line] += imports
44
+ return import_pkg_js
45
+ def get_all_imports(text=None,file_path=None,import_pkg_js=None):
46
+ if text and os.path.isfile(text):
47
+
48
+ try:
49
+ text = read_from_file(text)
50
+ except:
51
+ pass
52
+ file_path = text
53
+ text = get_text_or_read(text=text,file_path=file_path)
54
+ lines = text.split('\n')
55
+ cleaned_import_list=[]
56
+ nu_lines = []
57
+ is_from_group = False
58
+ import_pkg_js = ensure_import_pkg_js(import_pkg_js,file_path=file_path)
59
+ for line in lines:
60
+ if line.startswith(IMPORT_TAG) and ' from ' not in line:
61
+ cleaned_import_list = get_cleaned_import_list(line)
62
+ import_pkg_js = add_imports_to_import_pkg_js("import",cleaned_import_list,import_pkg_js=import_pkg_js)
63
+ else:
64
+ if is_from_group:
65
+ import_pkg=is_from_group
66
+ line = clean_line(line)
67
+ if line.endswith(')'):
68
+ is_from_group=False
69
+ line=line[:-1]
70
+ imports_from_import_pkg = clean_imports(line)
71
+ import_pkg_js = add_imports_to_import_pkg_js(import_pkg,imports_from_import_pkg,import_pkg_js=import_pkg_js)
72
+
73
+ else:
74
+ import_pkg_js=update_import_pkg_js(line,import_pkg_js=import_pkg_js)
75
+ if is_from_line_group(line) and is_from_group == False:
76
+ is_from_group=get_import_pkg(line)
77
+ return import_pkg_js
78
+ def get_path_or_init(pkg_info):
79
+ root_dirname = pkg_info.get("root_dirname")
80
+ pkg = pkg_info.get("pkg")
81
+ rel_path = pkg.replace('.','/')
82
+ dirname = os.path.dirname(root_dirname)
83
+ pkg_path = os.path.join(dirname,rel_path)
84
+ pkg_py_path = f"{pkg_path}.py"
85
+ if os.path.isfile(pkg_py_path):
86
+ return pkg_py_path
87
+ pkg_init_path = os.path.join(pkg_path,'__init__.py')
88
+ if os.path.isdir(pkg_path):
89
+ if os.path.isfile(pkg_init_path):
90
+ return pkg_init_path
91
+ #input(f"nnot found == {pkg_info}")
92
+ def get_dot_fro_line(line,dirname=None,file_path=None,get_info=False):
93
+ info_js = {"nuline":line,"og_line":line,"pkg":line,"dirname":dirname,"file_path":file_path,"root_dirname":None,"local":False}
94
+ if dirname and is_file(dirname):
95
+ file_path=dirname
96
+ dirname = os.path.dirname(dirname)
97
+ info_js["file_path"]=file_path
98
+ info_js["dirname"]=dirname
99
+ from_line = line.split(FROM_TAG)[-1]
100
+ dot_fro = ""
101
+ for char in from_line:
102
+ if char != '.':
103
+ pkg = f"{dot_fro}{eatAll(from_line,'.')}"
104
+ nuline=f"from {pkg}"
105
+ info_js["nuline"]=nuline
106
+ info_js["pkg"]=pkg
107
+ break
108
+ if dirname:
109
+ info_js["root_dirname"]=dirname
110
+ dirbase = os.path.basename(dirname)
111
+ dirname = os.path.dirname(dirname)
112
+
113
+ dot_fro = f"{dirbase}.{dot_fro}"
114
+ if get_info:
115
+ if dot_fro and os.path.isdir(info_js["root_dirname"]):
116
+ info_js["local"]=True
117
+ info_js["pkg_path"]=get_path_or_init(info_js)
118
+ return info_js
119
+ return line
120
+ def get_top_level_imp(line,dirname=None):
121
+ imp = get_dot_fro_line(line,dirname)
122
+ return imp.split('.')[0]
123
+ def return_local_imps(file_path):
124
+ local_imps = []
125
+ dirname = os.path.dirname(file_path)
126
+ imports_js = get_all_imports(file_path)
127
+ for pkg,imps in imports_js.items():
128
+ if pkg not in ['context','nulines']:
129
+ full_imp_info = get_dot_fro_line(pkg,dirname,file_path=file_path,get_info=True)
130
+ if full_imp_info.get("local") == True:
131
+ local_imps.append(full_imp_info)
132
+ return local_imps
133
+ def get_all_pkg_paths(file_path):
134
+ pkg_paths = []
135
+ local_imps = return_local_imps(file_path)
136
+ for local_imp in local_imps:
137
+ curr_file_path = local_imp.get('file_path')
138
+ pkg_path = local_imp.get('pkg_path')
139
+ if pkg_path != None:
140
+ pkg_paths.append(pkg_path)
141
+ return pkg_paths
142
+ def get_cir_dir(pkg_path):
143
+ dirname = os.path.dirname(pkg_path)
144
+ dirbase = os.path.basename(dirname)
145
+ while True:
146
+ if dirname == "/home/flerb/Documents/pythonTools/modules/src/modules/abstract_utilities/src/abstract_utilities":
147
+ break
148
+ dirbase = os.path.basename(dirname)
149
+ dirname = os.path.dirname(dirname)
150
+ #input(f"{dirbase} is circular")
151
+ return dirbase
152
+ def is_circular(pkg_path):
153
+ pkg_paths = get_all_pkg_paths(pkg_path)
154
+ if pkg_path in pkg_paths:
155
+ return pkg_path
156
+ def are_circular(pkg_path,cir_dirs = None):
157
+ cir_dirs = cir_dirs or []
158
+ pkg_path = is_circular(pkg_path)
159
+ if pkg_path:
160
+ if pkg_path not in cir_dirs:
161
+ cir_dirs.append(pkg_path)
162
+ return cir_dirs
163
+
164
+
165
+ def build_dependency_graph(main_directory):
166
+ """Map each file to all local imports (by resolved pkg_path)."""
167
+ graph = defaultdict(list)
168
+ dirs, all_local_scripts = get_files_and_dirs(
169
+ main_directory,
170
+ allowed_exts='.py',
171
+ exclude_dirs=['depriciate', 'junk'],
172
+ files_only=True
173
+ )
174
+ for file_path in all_local_scripts:
175
+ deps = get_all_pkg_paths(file_path)
176
+ for dep in deps:
177
+ if dep and os.path.isfile(dep):
178
+ graph[file_path].append(dep)
179
+ return graph
180
+
181
+
182
+ def find_circular_chains(graph):
183
+ """Detect circular imports and return their full dependency paths."""
184
+ visited, cycles = set(), []
185
+
186
+ def dfs(node, path):
187
+ visited.add(node)
188
+ path.append(node)
189
+ for dep in graph.get(node, []):
190
+ if dep not in path:
191
+ dfs(dep, path.copy())
192
+ else:
193
+ # Found a circular import
194
+ cycle_start = path.index(dep)
195
+ cycle = path[cycle_start:] + [dep]
196
+ if cycle not in cycles:
197
+ cycles.append(cycle)
198
+ return
199
+
200
+ for start in graph:
201
+ dfs(start, [])
202
+ return cycles
203
+
204
+
205
+ def explain_circular_imports(cycles):
206
+ """Pretty-print circular import chains with file names and import lines."""
207
+ for i, cycle in enumerate(cycles, 1):
208
+ print(f"\n🔁 Circular import {i}:")
209
+ for j in range(len(cycle) - 1):
210
+ src, dst = cycle[j], cycle[j + 1]
211
+ print(f" {os.path.basename(src)} → {os.path.basename(dst)}")
212
+ print(f" ^ back to {os.path.basename(cycle[0])}")
213
+ main_directory = "/home/flerb/Documents/pythonTools/modules/src/modules/abstract_utilities/src/abstract_utilities"
214
+
215
+ graph = build_dependency_graph(main_directory)
216
+ cycles = find_circular_chains(graph)
217
+
218
+ if not cycles:
219
+ print("✅ No circular imports found.")
220
+ else:
221
+ print(f"❌ Found {len(cycles)} circular import(s).")
222
+ explain_circular_imports(cycles)
@@ -0,0 +1,118 @@
1
+ from abstract_utilities import *
2
+ import os
3
+ from collections import defaultdict
4
+
5
+ def get_path_or_init(pkg_info):
6
+ root_dirname = pkg_info.get("root_dirname")
7
+ pkg = pkg_info.get("pkg")
8
+ rel_path = pkg.replace('.', '/')
9
+ dirname = os.path.dirname(root_dirname)
10
+ pkg_path = os.path.join(dirname, rel_path)
11
+ pkg_py_path = f"{pkg_path}.py"
12
+ if os.path.isfile(pkg_py_path):
13
+ return pkg_py_path
14
+ pkg_init_path = os.path.join(pkg_path, '__init__.py')
15
+ if os.path.isdir(pkg_path) and os.path.isfile(pkg_init_path):
16
+ return pkg_init_path
17
+ # optional: silence instead of blocking input()
18
+ print(f"⚠️ not found == {pkg_info}")
19
+ return None
20
+
21
+
22
+ def get_dot_fro_line(line, dirname=None, file_path=None, get_info=False):
23
+ info_js = {"nuline": line, "og_line": line, "pkg": line, "dirname": dirname,
24
+ "file_path": file_path, "root_dirname": None, "local": False}
25
+ if dirname and is_file(dirname):
26
+ file_path = dirname
27
+ dirname = os.path.dirname(dirname)
28
+ info_js["file_path"] = file_path
29
+ info_js["dirname"] = dirname
30
+
31
+ from_line = line.split(FROM_TAG)[-1]
32
+ dot_fro = ""
33
+ for char in from_line:
34
+ if char != '.':
35
+ pkg = f"{dot_fro}{eatAll(from_line, '.')}"
36
+ nuline = f"from {pkg}"
37
+ info_js["nuline"] = nuline
38
+ info_js["pkg"] = pkg
39
+ break
40
+ if dirname:
41
+ info_js["root_dirname"] = dirname
42
+ dirbase = os.path.basename(dirname)
43
+ dirname = os.path.dirname(dirname)
44
+ dot_fro = f"{dirbase}.{dot_fro}"
45
+
46
+ if get_info:
47
+ if dot_fro and os.path.isdir(info_js.get("root_dirname") or ""):
48
+ info_js["local"] = True
49
+ info_js["pkg_path"] = get_path_or_init(info_js)
50
+ return info_js
51
+ return line
52
+
53
+
54
+ def return_local_imps(file_path):
55
+ local_imps = []
56
+ dirname = os.path.dirname(file_path)
57
+ imports_js = get_all_imports(file_path)
58
+ for pkg, imps in imports_js.items():
59
+ if pkg not in ['context', 'nulines']:
60
+ full_imp_info = get_dot_fro_line(pkg, dirname, file_path=file_path, get_info=True)
61
+ if full_imp_info.get("local"):
62
+ local_imps.append(full_imp_info)
63
+ return local_imps
64
+
65
+
66
+ def get_all_pkg_paths(file_path):
67
+ pkg_paths = []
68
+ local_imps = return_local_imps(file_path)
69
+ for local_imp in local_imps:
70
+ pkg_path = local_imp.get('pkg_path')
71
+ if pkg_path:
72
+ pkg_paths.append(pkg_path)
73
+ return pkg_paths
74
+
75
+
76
+ # --- NEW: Build dependency graph and detect circular imports ---
77
+
78
+ def build_graph(main_directory):
79
+ dirs, all_local_scripts = get_files_and_dirs(main_directory, allowd_exts='.py', files_only=True)
80
+ graph = defaultdict(set)
81
+ for file_path in all_local_scripts:
82
+ deps = get_all_pkg_paths(file_path)
83
+ for dep in deps:
84
+ if dep: # only valid files
85
+ graph[file_path].add(dep)
86
+ return graph
87
+
88
+
89
+ def find_cycles(graph):
90
+ visited, stack, cycles = set(), [], []
91
+
92
+ def dfs(node, path):
93
+ visited.add(node)
94
+ path.append(node)
95
+ for dep in graph.get(node, []):
96
+ if dep not in visited:
97
+ dfs(dep, path.copy())
98
+ elif dep in path:
99
+ cycle_start = path.index(dep)
100
+ cycles.append(path[cycle_start:] + [dep])
101
+
102
+ for node in graph:
103
+ if node not in visited:
104
+ dfs(node, [])
105
+ return cycles
106
+
107
+
108
+ if __name__ == "__main__":
109
+ main_directory = "/home/flerb/Documents/pythonTools/modules/src/modules/abstract_utilities/src/abstract_utilities"
110
+ graph = build_graph(main_directory)
111
+ cycles = find_cycles(graph)
112
+
113
+ if not cycles:
114
+ print("✅ No circular imports found.")
115
+ else:
116
+ print("❌ Circular imports detected:")
117
+ for cycle in cycles:
118
+ print(" → ".join(cycle))
@@ -0,0 +1,7 @@
1
+ from .imports import *
2
+ from .abstract_classes import *
3
+ from .caller_utils import *
4
+ from .class_utils import *
5
+ from .function_utils import *
6
+ from .module_utils import *
7
+ from .global_utils import *
@@ -0,0 +1,144 @@
1
+ from .imports import *
2
+ class SingletonMeta(type):
3
+ _instances = {}
4
+ def __call__(cls, *args, **kwargs):
5
+ if cls not in cls._instances:
6
+ cls._instances[cls] = super(SingletonMeta, cls).__call__(*args, **kwargs)
7
+ return cls._instances[cls]
8
+
9
+ def get_inputs(cls, *args, **kwargs):
10
+ """
11
+ Dynamically construct a dataclass instance from args and kwargs,
12
+ filling missing values from defaults in the dataclass.
13
+ """
14
+ fields = list(cls.__annotations__.keys())
15
+ values = {}
16
+
17
+ args = list(args)
18
+ for field in fields:
19
+ if field in kwargs:
20
+ values[field] = kwargs[field]
21
+ elif args:
22
+ values[field] = args.pop(0)
23
+ else:
24
+ values[field] = getattr(cls(), field) # default from dataclass
25
+
26
+ return cls(**values)
27
+
28
+
29
+ from abstract_utilities import *
30
+ class SingletonMeta(type):
31
+ _instances = {}
32
+ def __call__(cls, *args, **kwargs):
33
+ if cls not in cls._instances:
34
+ cls._instances[cls] = super(SingletonMeta, cls).__call__(*args, **kwargs)
35
+ return cls._instances[cls]
36
+
37
+ def get_inputs(cls, *args, **kwargs):
38
+ """
39
+ Dynamically construct a dataclass instance from args and kwargs,
40
+ filling missing values from defaults in the dataclass.
41
+ """
42
+ fields = list(cls.__annotations__.keys())
43
+ values = {}
44
+
45
+ args = list(args)
46
+ for field in fields:
47
+ if field in kwargs:
48
+ values[field] = kwargs[field]
49
+ elif args:
50
+ values[field] = args.pop(0)
51
+ else:
52
+ values[field] = getattr(cls(), field) # default from dataclass
53
+
54
+ return cls(*args,**values)
55
+ def get_input_params(func):
56
+ sig = inspect.signature(func)
57
+ return sig.parameters
58
+ def get_args(func, *args,**kwargs):
59
+ parameters = get_input_params(func)
60
+ parameters = dict(parameters)
61
+ for key,value in parameters.items():
62
+ value = str(value)
63
+ if value.startswith('**'):
64
+ kwargs_key = key
65
+ elif value.startswith('*'):
66
+ args_key = key
67
+ kwargs_copy = kwargs.copy()
68
+ for k_key,k_value in kwargs.items():
69
+ if args_key == k_key and isinstance(k_value,list or tuple or set):
70
+ args = args | tuple(k_value)
71
+ del kwargs[k_key]
72
+ return args,kwargs
73
+
74
+ def prune_inputs(func, *args, **kwargs):
75
+ """
76
+ Smart argument adapter:
77
+ - Detects if func accepts *args or **kwargs
78
+ - Builds new positional arguments from kwargs when appropriate
79
+ - Handles explicit {"args": [...]} convention
80
+ """
81
+
82
+ sig = inspect.signature(func)
83
+ params = sig.parameters
84
+
85
+ has_varargs = any(p.kind == inspect.Parameter.VAR_POSITIONAL for p in params.values())
86
+ has_varkw = any(p.kind == inspect.Parameter.VAR_KEYWORD for p in params.values())
87
+
88
+ new_args = list(args)
89
+ new_kwargs = dict(kwargs)
90
+
91
+ # -----------------------------------------------------------
92
+ # 1. If user provided explicit args: {"args": [...]}
93
+ # -----------------------------------------------------------
94
+ if "args" in new_kwargs:
95
+ explicit_args = new_kwargs.pop("args")
96
+ if isinstance(explicit_args, (list, tuple)):
97
+ new_args.extend(explicit_args)
98
+ else:
99
+ new_args.append(explicit_args)
100
+
101
+ # -----------------------------------------------------------
102
+ # 2. If function has *args, infer which kwargs belong there
103
+ # -----------------------------------------------------------
104
+ if has_varargs:
105
+
106
+ # Heuristic rules for upgrading kwargs to args:
107
+ # - if the function has NO named params, treat all scalar kwargs as positional
108
+ # - common param names like "file_path" also qualify
109
+ preferred_as_args = {"path", "file", "file_path", "filename", "value"}
110
+
111
+ positional_candidates = []
112
+
113
+ for k in list(new_kwargs.keys()):
114
+ v = new_kwargs[k]
115
+
116
+ # candidate rules:
117
+ if k in preferred_as_args:
118
+ positional_candidates.append(v)
119
+ del new_kwargs[k]
120
+
121
+ # scalars but not mappings/lists (optional)
122
+ elif isinstance(v, (str, int, float)) and len(positional_candidates) == 0:
123
+ positional_candidates.append(v)
124
+ del new_kwargs[k]
125
+
126
+ new_args.extend(positional_candidates)
127
+
128
+ # -----------------------------------------------------------
129
+ # 3. If function does NOT accept **kwargs → strip extras
130
+ # -----------------------------------------------------------
131
+ if not has_varkw:
132
+ allowed = {
133
+ name for name, p in params.items()
134
+ if p.kind in (
135
+ inspect.Parameter.POSITIONAL_OR_KEYWORD,
136
+ inspect.Parameter.KEYWORD_ONLY
137
+ )
138
+ }
139
+ new_kwargs = {k: v for k, v in new_kwargs.items() if k in allowed}
140
+
141
+ return tuple(new_args), new_kwargs
142
+ def run_pruned_func(func, *args, **kwargs):
143
+ args,kwargs = prune_inputs(func, *args, **kwargs)
144
+ return func(*args, **kwargs)
@@ -0,0 +1,92 @@
1
+ from .imports import *
2
+
3
+ def get_initial_caller() -> str:
4
+ """
5
+ Return the TRUE original caller: the entrypoint script that launched the program.
6
+ """
7
+ main_mod = sys.modules.get('__main__')
8
+
9
+ # interactive environments (REPL) may have no __file__
10
+ if not main_mod or not hasattr(main_mod, '__file__'):
11
+ return None
12
+
13
+ return os.path.realpath(main_mod.__file__)
14
+ def get_initial_caller_dir() -> str:
15
+ """
16
+ Return the directory of the TRUE original entrypoint script.
17
+ """
18
+ caller = get_initial_caller()
19
+ return os.path.dirname(caller) if caller else None
20
+
21
+ def get_caller(i: Optional[int] = None) -> str:
22
+ """
23
+ Return the filename of the calling frame.
24
+
25
+ Args:
26
+ i: Optional stack depth offset.
27
+ None = immediate caller (depth 1).
28
+
29
+ Returns:
30
+ Absolute path of the file for the stack frame.
31
+ """
32
+ depth = 1 if i is None else int(i)
33
+ stack = inspect.stack()
34
+ if depth >= len(stack):
35
+ depth = len(stack) - 1
36
+ return stack[depth].filename
37
+
38
+
39
+ def get_caller_path(i: Optional[int] = None) -> str:
40
+ """
41
+ Return the absolute path of the caller's file.
42
+ """
43
+ depth = 1 if i is None else int(i)
44
+ file_path = get_caller(depth + 1)
45
+ return os.path.realpath(file_path)
46
+
47
+
48
+ def get_caller_dir(i: Optional[int] = None) -> str:
49
+ """
50
+ Return the absolute directory of the caller's file.
51
+ """
52
+ depth = 1 if i is None else int(i)
53
+ abspath = get_caller_path(depth + 1)
54
+ return os.path.dirname(abspath)
55
+
56
+
57
+ def get_original_caller_dir(levels_up: int = None) -> Path:
58
+ """
59
+ Return the directory of the *original* caller in the call stack.
60
+
61
+ levels_up:
62
+ - None → automatically goes to the bottom-most user-level caller.
63
+ - N → manually walk up N frames for custom behavior.
64
+
65
+ Returns:
66
+ Path object pointing to caller's directory.
67
+ """
68
+
69
+ stack = inspect.stack()
70
+
71
+ # If the user specifies an exact depth
72
+ if levels_up is not None:
73
+ target = min(levels_up + 1, len(stack) - 1)
74
+ frame = stack[target]
75
+ return Path(frame.filename).resolve().parent
76
+
77
+ # Otherwise, auto-detect the FIRST file that isn't inside site-packages or abstract_* utilities
78
+ for frameinfo in reversed(stack):
79
+ file_path = Path(frameinfo.filename).resolve()
80
+
81
+ # Skip internal interpreter/frame files
82
+ if "site-packages" in str(file_path):
83
+ continue
84
+ if "abstract_" in file_path.name:
85
+ continue
86
+ if file_path.name.startswith("<"):
87
+ continue
88
+
89
+ return file_path.parent
90
+
91
+ # Fallback: last entry in the stack
92
+ return Path(stack[-1].filename).resolve().parent