abstract-utilities 0.2.2.480__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 (215) hide show
  1. abstract_utilities/__init__.py +24 -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/directory_utils/__init__.py +2 -0
  15. abstract_utilities/directory_utils/directory_utils.py +94 -0
  16. abstract_utilities/directory_utils/imports/__init__.py +2 -0
  17. abstract_utilities/directory_utils/imports/imports.py +1 -0
  18. abstract_utilities/directory_utils/imports/module_imports.py +2 -0
  19. abstract_utilities/directory_utils/name_utils.py +43 -0
  20. abstract_utilities/directory_utils/size_utils.py +57 -0
  21. abstract_utilities/directory_utils/src/__init__.py +4 -0
  22. abstract_utilities/directory_utils/src/directory_utils.py +110 -0
  23. abstract_utilities/directory_utils/src/name_utils.py +43 -0
  24. abstract_utilities/directory_utils/src/size_utils.py +57 -0
  25. abstract_utilities/directory_utils/src/utils.py +116 -0
  26. abstract_utilities/directory_utils/utils.py +116 -0
  27. abstract_utilities/env_utils/imports/imports.py +5 -3
  28. abstract_utilities/error_utils/__init__.py +2 -0
  29. abstract_utilities/error_utils/error_utils.py +25 -0
  30. abstract_utilities/error_utils/imports/__init__.py +2 -0
  31. abstract_utilities/error_utils/imports/imports.py +1 -0
  32. abstract_utilities/error_utils/imports/module_imports.py +1 -0
  33. abstract_utilities/file_utils/__init__.py +1 -2
  34. abstract_utilities/file_utils/file_utils/type_checks.py +2 -1
  35. abstract_utilities/file_utils/imports/classes.py +59 -55
  36. abstract_utilities/file_utils/imports/constants.py +84 -4
  37. abstract_utilities/file_utils/imports/imports.py +2 -21
  38. abstract_utilities/file_utils/imports/module_imports.py +3 -8
  39. abstract_utilities/file_utils/module_imports.py +12 -0
  40. abstract_utilities/file_utils/src/__init__.py +7 -0
  41. abstract_utilities/file_utils/src/file_filters/__init__.py +1 -0
  42. abstract_utilities/file_utils/src/file_filters/ensure_utils.py +490 -0
  43. abstract_utilities/file_utils/src/file_filters/filter_params.py +150 -0
  44. abstract_utilities/file_utils/src/file_filters/filter_utils.py +78 -0
  45. abstract_utilities/file_utils/src/file_filters/predicate_utils.py +44 -0
  46. abstract_utilities/file_utils/src/file_filters.py +177 -0
  47. abstract_utilities/file_utils/src/file_reader.py +543 -0
  48. abstract_utilities/file_utils/src/file_utils.py +156 -0
  49. abstract_utilities/file_utils/src/filter_params.py +197 -0
  50. abstract_utilities/file_utils/src/find_collect.py +200 -0
  51. abstract_utilities/file_utils/src/find_content.py +210 -0
  52. abstract_utilities/file_utils/src/initFunctionsGen.py +293 -0
  53. abstract_utilities/file_utils/src/initFunctionsGens.py +280 -0
  54. abstract_utilities/file_utils/src/map_utils.py +29 -0
  55. abstract_utilities/file_utils/src/pdf_utils.py +300 -0
  56. abstract_utilities/file_utils/src/reader_utils/__init__.py +4 -0
  57. abstract_utilities/file_utils/src/reader_utils/directory_reader.py +53 -0
  58. abstract_utilities/file_utils/src/reader_utils/file_reader.py +543 -0
  59. abstract_utilities/file_utils/src/reader_utils/file_readers.py +376 -0
  60. abstract_utilities/file_utils/src/reader_utils/imports.py +18 -0
  61. abstract_utilities/file_utils/src/reader_utils/pdf_utils.py +300 -0
  62. abstract_utilities/file_utils/src/type_checks.py +91 -0
  63. abstract_utilities/file_utils (2)/__init__.py +2 -0
  64. abstract_utilities/file_utils (2)/imports/__init__.py +2 -0
  65. abstract_utilities/file_utils (2)/imports/constants.py +118 -0
  66. abstract_utilities/file_utils (2)/imports/imports/__init__.py +3 -0
  67. abstract_utilities/file_utils (2)/imports/imports/constants.py +119 -0
  68. abstract_utilities/file_utils (2)/imports/imports/imports.py +46 -0
  69. abstract_utilities/file_utils (2)/imports/imports/module_imports.py +8 -0
  70. abstract_utilities/file_utils (2)/imports/utils/__init__.py +3 -0
  71. abstract_utilities/file_utils (2)/imports/utils/classes.py +379 -0
  72. abstract_utilities/file_utils (2)/imports/utils/clean_imps.py +155 -0
  73. abstract_utilities/file_utils (2)/imports/utils/filter_utils.py +341 -0
  74. abstract_utilities/file_utils (2)/src/__init__.py +8 -0
  75. abstract_utilities/file_utils (2)/src/file_filters.py +155 -0
  76. abstract_utilities/file_utils (2)/src/file_reader.py +604 -0
  77. abstract_utilities/file_utils (2)/src/find_collect.py +258 -0
  78. abstract_utilities/file_utils (2)/src/initFunctionsGen.py +286 -0
  79. abstract_utilities/file_utils (2)/src/map_utils.py +28 -0
  80. abstract_utilities/file_utils (2)/src/pdf_utils.py +300 -0
  81. abstract_utilities/hash_utils/__init__.py +2 -0
  82. abstract_utilities/hash_utils/hash_utils.py +5 -0
  83. abstract_utilities/hash_utils/imports/__init__.py +2 -0
  84. abstract_utilities/hash_utils/imports/imports.py +1 -0
  85. abstract_utilities/hash_utils/imports/module_imports.py +0 -0
  86. abstract_utilities/history_utils/__init__.py +2 -0
  87. abstract_utilities/history_utils/history_utils.py +37 -0
  88. abstract_utilities/history_utils/imports/__init__.py +2 -0
  89. abstract_utilities/history_utils/imports/imports.py +1 -0
  90. abstract_utilities/history_utils/imports/module_imports.py +0 -0
  91. abstract_utilities/import_utils/__init__.py +2 -0
  92. abstract_utilities/import_utils/circular_import_finder.py +222 -0
  93. abstract_utilities/import_utils/circular_import_finder2.py +118 -0
  94. abstract_utilities/import_utils/imports/__init__.py +4 -0
  95. abstract_utilities/import_utils/imports/constants.py +2 -0
  96. abstract_utilities/import_utils/imports/imports.py +4 -0
  97. abstract_utilities/import_utils/imports/init_imports.py +3 -0
  98. abstract_utilities/import_utils/imports/module_imports.py +9 -0
  99. abstract_utilities/import_utils/imports/utils.py +30 -0
  100. abstract_utilities/import_utils/src/__init__.py +8 -0
  101. abstract_utilities/import_utils/src/clean_imports.py +278 -0
  102. abstract_utilities/import_utils/src/dot_utils.py +80 -0
  103. abstract_utilities/import_utils/src/extract_utils.py +46 -0
  104. abstract_utilities/import_utils/src/import_functions.py +110 -0
  105. abstract_utilities/import_utils/src/import_utils.py +349 -0
  106. abstract_utilities/import_utils/src/layze_import_utils/__init__.py +2 -0
  107. abstract_utilities/import_utils/src/layze_import_utils/lazy_utils.py +41 -0
  108. abstract_utilities/import_utils/src/layze_import_utils/nullProxy.py +37 -0
  109. abstract_utilities/import_utils/src/nullProxy.py +30 -0
  110. abstract_utilities/import_utils/src/package_utils/__init__.py +139 -0
  111. abstract_utilities/import_utils/src/package_utils/context_utils.py +27 -0
  112. abstract_utilities/import_utils/src/package_utils/import_collectors.py +53 -0
  113. abstract_utilities/import_utils/src/package_utils/path_utils.py +28 -0
  114. abstract_utilities/import_utils/src/package_utils/safe_import.py +27 -0
  115. abstract_utilities/import_utils/src/package_utils.py +140 -0
  116. abstract_utilities/import_utils/src/package_utilss/__init__.py +139 -0
  117. abstract_utilities/import_utils/src/package_utilss/context_utils.py +27 -0
  118. abstract_utilities/import_utils/src/package_utilss/import_collectors.py +53 -0
  119. abstract_utilities/import_utils/src/package_utilss/path_utils.py +28 -0
  120. abstract_utilities/import_utils/src/package_utilss/safe_import.py +27 -0
  121. abstract_utilities/import_utils/src/pkg_utils.py +194 -0
  122. abstract_utilities/import_utils/src/sysroot_utils.py +112 -0
  123. abstract_utilities/imports.py +21 -0
  124. abstract_utilities/json_utils/__init__.py +2 -0
  125. abstract_utilities/json_utils/imports/__init__.py +2 -0
  126. abstract_utilities/json_utils/imports/imports.py +2 -0
  127. abstract_utilities/json_utils/imports/module_imports.py +5 -0
  128. abstract_utilities/json_utils/json_utils.py +777 -0
  129. abstract_utilities/list_utils/__init__.py +2 -0
  130. abstract_utilities/list_utils/imports/__init__.py +2 -0
  131. abstract_utilities/list_utils/imports/imports.py +1 -0
  132. abstract_utilities/list_utils/imports/module_imports.py +0 -0
  133. abstract_utilities/list_utils/list_utils.py +202 -0
  134. abstract_utilities/log_utils/__init__.py +5 -0
  135. abstract_utilities/log_utils/abstractLogManager.py +64 -0
  136. abstract_utilities/log_utils/call_response.py +68 -0
  137. abstract_utilities/log_utils/imports/__init__.py +2 -0
  138. abstract_utilities/log_utils/imports/imports.py +7 -0
  139. abstract_utilities/log_utils/imports/module_imports.py +2 -0
  140. abstract_utilities/log_utils/log_file.py +162 -0
  141. abstract_utilities/log_utils/logger_callable.py +49 -0
  142. abstract_utilities/math_utils/__init__.py +2 -0
  143. abstract_utilities/math_utils/imports/__init__.py +2 -0
  144. abstract_utilities/math_utils/imports/imports.py +2 -0
  145. abstract_utilities/math_utils/imports/module_imports.py +1 -0
  146. abstract_utilities/math_utils/math_utils.py +208 -0
  147. abstract_utilities/parse_utils/__init__.py +2 -0
  148. abstract_utilities/parse_utils/imports/__init__.py +3 -0
  149. abstract_utilities/parse_utils/imports/constants.py +10 -0
  150. abstract_utilities/parse_utils/imports/imports.py +2 -0
  151. abstract_utilities/parse_utils/imports/module_imports.py +4 -0
  152. abstract_utilities/parse_utils/parse_utils.py +539 -0
  153. abstract_utilities/path_utils/__init__.py +2 -0
  154. abstract_utilities/path_utils/imports/__init__.py +3 -0
  155. abstract_utilities/path_utils/imports/imports.py +1 -0
  156. abstract_utilities/path_utils/imports/module_imports.py +8 -0
  157. abstract_utilities/path_utils/path_utils.py +248 -0
  158. abstract_utilities/path_utils.py +95 -14
  159. abstract_utilities/read_write_utils/__init__.py +1 -0
  160. abstract_utilities/read_write_utils/imports/__init__.py +2 -0
  161. abstract_utilities/read_write_utils/imports/imports.py +2 -0
  162. abstract_utilities/read_write_utils/imports/module_imports.py +5 -0
  163. abstract_utilities/read_write_utils/read_write_utils.py +439 -0
  164. abstract_utilities/read_write_utils.py +113 -62
  165. abstract_utilities/safe_utils/__init__.py +2 -0
  166. abstract_utilities/safe_utils/imports/__init__.py +3 -0
  167. abstract_utilities/safe_utils/imports/imports.py +2 -0
  168. abstract_utilities/safe_utils/imports/module_imports.py +2 -0
  169. abstract_utilities/safe_utils/safe_utils.py +166 -0
  170. abstract_utilities/ssh_utils/__init__.py +3 -1
  171. abstract_utilities/ssh_utils/classes.py +0 -1
  172. abstract_utilities/ssh_utils/cmd_utils.py +207 -0
  173. abstract_utilities/ssh_utils/imports/__init__.py +3 -0
  174. abstract_utilities/ssh_utils/imports/imports.py +5 -0
  175. abstract_utilities/ssh_utils/imports/module_imports.py +6 -0
  176. abstract_utilities/ssh_utils/imports/utils.py +189 -0
  177. abstract_utilities/ssh_utils/pexpect_utils.py +11 -18
  178. abstract_utilities/ssh_utils/type_checks.py +92 -0
  179. abstract_utilities/string_utils/__init__.py +4 -0
  180. abstract_utilities/string_utils/clean_utils.py +28 -0
  181. abstract_utilities/string_utils/eat_utils.py +103 -0
  182. abstract_utilities/string_utils/imports/__init__.py +3 -0
  183. abstract_utilities/string_utils/imports/imports.py +2 -0
  184. abstract_utilities/string_utils/imports/module_imports.py +2 -0
  185. abstract_utilities/string_utils/imports/utils.py +81 -0
  186. abstract_utilities/string_utils/replace_utils.py +27 -0
  187. abstract_utilities/string_utils.py +1 -1
  188. abstract_utilities/thread_utils/__init__.py +2 -0
  189. abstract_utilities/thread_utils/imports/__init__.py +2 -0
  190. abstract_utilities/thread_utils/imports/imports.py +2 -0
  191. abstract_utilities/thread_utils/imports/module_imports.py +2 -0
  192. abstract_utilities/thread_utils/thread_utils.py +140 -0
  193. abstract_utilities/time_utils/__init__.py +2 -0
  194. abstract_utilities/time_utils/imports/__init__.py +2 -0
  195. abstract_utilities/time_utils/imports/imports.py +3 -0
  196. abstract_utilities/time_utils/imports/module_imports.py +1 -0
  197. abstract_utilities/time_utils/time_utils.py +392 -0
  198. abstract_utilities/type_utils/__init__.py +7 -0
  199. abstract_utilities/type_utils/alpha_utils.py +59 -0
  200. abstract_utilities/type_utils/get_type.py +120 -0
  201. abstract_utilities/type_utils/imports/__init__.py +3 -0
  202. abstract_utilities/type_utils/imports/constants.py +134 -0
  203. abstract_utilities/type_utils/imports/imports.py +4 -0
  204. abstract_utilities/type_utils/imports/module_imports.py +25 -0
  205. abstract_utilities/type_utils/is_type.py +455 -0
  206. abstract_utilities/type_utils/make_type.py +126 -0
  207. abstract_utilities/type_utils/mime_types.py +68 -0
  208. abstract_utilities/type_utils/num_utils.py +19 -0
  209. abstract_utilities/type_utils/type_utils.py +104 -0
  210. {abstract_utilities-0.2.2.480.dist-info → abstract_utilities-0.2.2.688.dist-info}/METADATA +1 -1
  211. abstract_utilities-0.2.2.688.dist-info/RECORD +288 -0
  212. imports/__init__.py +36 -0
  213. abstract_utilities-0.2.2.480.dist-info/RECORD +0 -92
  214. {abstract_utilities-0.2.2.480.dist-info → abstract_utilities-0.2.2.688.dist-info}/WHEEL +0 -0
  215. {abstract_utilities-0.2.2.480.dist-info → abstract_utilities-0.2.2.688.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,27 @@
1
+ import inspect, importlib
2
+ from .context_utils import ensure_caller_package
3
+
4
+ def safe_import(
5
+ name: str,
6
+ *,
7
+ member: str | None = None,
8
+ package: str | None = None,
9
+ file: str | None = None,
10
+ caller_globals: dict | None = None,
11
+ ):
12
+ """
13
+ Safe dynamic import that resolves relative imports when run as a script.
14
+ """
15
+ if file is None:
16
+ frame = inspect.currentframe()
17
+ assert frame is not None
18
+ outer = frame.f_back
19
+ caller_file = (outer.f_globals.get("__file__") if outer else None) or __file__
20
+ else:
21
+ caller_file = file
22
+
23
+ if name.startswith(".") and not package:
24
+ package = ensure_caller_package(caller_file, caller_globals=caller_globals)
25
+
26
+ mod = importlib.import_module(name, package=package)
27
+ return getattr(mod, member) if member else mod
@@ -0,0 +1,194 @@
1
+ # safe_import_utils.py
2
+ from ..imports import *
3
+ from .import_functions import *
4
+ from ...safe_utils import *
5
+ from .sysroot_utils import get_import_with_sysroot
6
+ def try_is_file(file_path):
7
+ try:
8
+ return os.path.isfile(file_path)
9
+ except:
10
+ return False
11
+ def try_is_dir(file_path):
12
+ try:
13
+ return os.path.isdir(file_path)
14
+ except:
15
+ return False
16
+ def try_join(*args):
17
+ try:
18
+ return safe_join(*args)
19
+ except:
20
+ return False
21
+ def get_pkg_or_init(pkg_path):
22
+ if pkg_path:
23
+ if try_is_file(pkg_path):
24
+ return pkg_path
25
+ pkg_py_path = f"{pkg_path}.py"
26
+ if try_is_file(pkg_py_path):
27
+ return pkg_py_path
28
+ pkg_init_path = try_join(pkg_path,'__init__.py')
29
+ if try_is_dir(pkg_path):
30
+ if os.path.isfile(pkg_init_path):
31
+ return pkg_init_path
32
+
33
+
34
+
35
+ def ensure_import_pkg_js(import_pkg_js,file_path=None):
36
+ import_pkg_js = import_pkg_js or {"context":{}}
37
+ if "context" not in import_pkg_js:
38
+ import_pkg_js["context"]={}
39
+ for key in ["nulines","file_path","all_data"]:
40
+ if key not in import_pkg_js["context"]:
41
+ import_pkg_js["context"][key]=[]
42
+ if file_path and file_path != import_pkg_js["context"]["file_path"]:
43
+ found=False
44
+ nu_data = {"file_path":import_pkg_js["context"]["file_path"],"nulines":import_pkg_js["context"]["nulines"]}
45
+ for i,data in enumerate(import_pkg_js["context"]["all_data"]):
46
+ if data.get('file_path') == import_pkg_js["context"]["file_path"]:
47
+ import_pkg_js["context"]["all_data"][i] = nu_data
48
+ found = True
49
+ break
50
+ if found == False:
51
+ import_pkg_js["context"]["all_data"].append(nu_data)
52
+ import_pkg_js["context"]["nulines"]=[]
53
+ import_pkg_js["context"]["file_path"]=file_path
54
+ return import_pkg_js
55
+ def ensure_package_context(file: str):
56
+ """
57
+ Ensure that running this file directly still gives it the correct package.
58
+ Sets sys.path and __package__ based on the __init__.py chain.
59
+ """
60
+ file = file or os.getcwd()
61
+ here = Path(file).resolve()
62
+ top_pkg_dir = find_top_pkg_dir(here)
63
+ if not top_pkg_dir:
64
+ raise RuntimeError(f"No package context above {here}. Add __init__.py files up the tree.")
65
+
66
+ sysroot = top_pkg_dir.parent # dir ABOVE the top package (e.g., .../src)
67
+ if str(sysroot) not in sys.path:
68
+ sys.path.insert(0, str(sysroot))
69
+
70
+ # Compute this module's package (exclude the filename)
71
+ parts = here.with_suffix("").relative_to(sysroot).parts
72
+ pkg_name = ".".join(parts[:-1]) # e.g. abstract_ide.consoles.launcherWindowTab
73
+
74
+ # When run as a script, __package__ is empty -> set it
75
+ if (__name__ == "__main__") and (not globals().get("__package__")):
76
+ globals()["__package__"] = pkg_name
77
+ # --- tiny utils ---
78
+ def find_top_package_dir(p: Path) -> Path | None:
79
+ p = p.resolve()
80
+ if p.is_file():
81
+ p = p.parent
82
+ top = None
83
+ while (p / "__init__.py").exists():
84
+ top = p
85
+ if p.parent == p:
86
+ break
87
+ p = p.parent
88
+ return top
89
+
90
+ def derive_package_for_file(file: str) -> tuple[str, Path]:
91
+ """Return (pkg_name, sysroot) for the module file."""
92
+ here = Path(file).resolve()
93
+ top_pkg_dir = find_top_pkg_dir(here)
94
+ if not top_pkg_dir:
95
+ raise RuntimeError(f"No package context above {here}. Add __init__.py up the tree.")
96
+ sysroot = top_pkg_dir.parent
97
+ if str(sysroot) not in sys.path:
98
+ sys.path.insert(0, str(sysroot))
99
+ parts = here.with_suffix("").relative_to(sysroot).parts
100
+ pkg_name = ".".join(parts[:-1]) # package of the module (drop the filename)
101
+ return pkg_name, sysroot
102
+
103
+ def ensure_caller_package(caller_file: str, caller_globals: dict | None = None) -> str:
104
+ """
105
+ Ensure sysroot is on sys.path and return the caller's dotted package.
106
+ Optionally set caller_globals['__package__'] when running as a script.
107
+ """
108
+ pkg, _ = derive_package_for_file(caller_file)
109
+ if caller_globals and caller_globals.get("__name__") == "__main__" and not caller_globals.get("__package__"):
110
+ caller_globals["__package__"] = pkg
111
+ return pkg
112
+ def get_init_dots(import_pkg):
113
+ count = 0
114
+ for char in import_pkg:
115
+ if char != '.':
116
+ break
117
+ count+=1
118
+ return count
119
+ def make_relative_pkg(import_pkg,file_path):
120
+ full_pkg = eatAll(import_pkg,'.')
121
+ if file_path:
122
+ dirname = file_path
123
+ dot_count = get_init_dots(import_pkg)
124
+ for i in range(dot_count):
125
+ dirname = os.path.dirname(dirname)
126
+ dirbase = os.path.basename(dirname)
127
+ full_pkg=f"{dirbase}.{full_pkg}"
128
+ return full_pkg
129
+ def is_local_import(import_pkg,file_path=None):
130
+ relative_pkg = get_module_from_import(import_pkg,file_path)
131
+ if get_pkg_or_init(relative_pkg):
132
+ return True
133
+ return False
134
+ def get_import_pkg(line):
135
+ if is_line_group_import(line):
136
+ return clean_line(line.split(FROM_TAG)[1].split(IMPORT_TAG)[0])
137
+ def get_imports_from_import_pkg(line):
138
+ if is_line_group_import(line):
139
+ return get_cleaned_import_list(line,commaClean=True)
140
+ def add_imports_to_import_pkg_js(import_pkg,imports,import_pkg_js=None,file_path=None):
141
+ import_pkg_js = ensure_import_pkg_js(import_pkg_js)
142
+ imports = clean_imports(imports)
143
+ pkg_path = get_module_from_import(import_pkg,file_path)
144
+ local_import = get_pkg_or_init(pkg_path)
145
+ if import_pkg not in import_pkg_js:
146
+ i = len(import_pkg_js["context"]["nulines"])
147
+ import_pkg_js[import_pkg]={"imports":imports,"line":i,"file_path":file_path,"local_import":local_import,"is_local":is_local_import(import_pkg,file_path=file_path)}
148
+ import_line = f"from {import_pkg} import "
149
+ if import_pkg == "import":
150
+ import_line = IMPORT_TAG
151
+ import_pkg_js["context"]["nulines"].append(import_line)
152
+ else:
153
+ import_pkg_js[import_pkg]["imports"]+=imports
154
+ return import_pkg_js
155
+ def update_import_pkg_js(line,import_pkg_js=None,file_path=None):
156
+ import_pkg_js = ensure_import_pkg_js(import_pkg_js)
157
+ if is_line_group_import(line):
158
+ import_pkg = get_import_pkg(line)
159
+ imports = get_imports_from_import_pkg(line)
160
+ import_pkg_js = add_imports_to_import_pkg_js(import_pkg,imports,import_pkg_js=import_pkg_js,file_path=file_path)
161
+ else:
162
+ if len(import_pkg_js["context"]["nulines"]) >0 and line == '' and is_line_import(import_pkg_js["context"]["nulines"][-1]):
163
+ pass
164
+ else:
165
+ import_pkg_js["context"]["nulines"].append(line)
166
+ return import_pkg_js
167
+ # --- public API ---
168
+ def safe_import(
169
+ name: str,
170
+ *,
171
+ member: str | None = None,
172
+ package: str | None = None,
173
+ file: str | None = None,
174
+ caller_globals: dict | None = None,
175
+ ):
176
+ """
177
+ Import `name` (relative or absolute).
178
+ - If `name` is relative and `package` is missing, derive it from `file` (or caller).
179
+ - If running the caller as a script, we can set its __package__ when caller_globals is provided.
180
+ """
181
+ if file is None:
182
+ # best-effort: use the immediate caller's file
183
+ frame = inspect.currentframe()
184
+ assert frame is not None
185
+ outer = frame.f_back
186
+ caller_file = (outer.f_globals.get("__file__") if outer else None) or __file__
187
+ else:
188
+ caller_file = file
189
+
190
+ if name.startswith(".") and not package:
191
+ package = ensure_caller_package(caller_file, caller_globals=caller_globals)
192
+
193
+ mod = importlib.import_module(name, package=package)
194
+ return getattr(mod, member) if member else mod
@@ -0,0 +1,112 @@
1
+ from ..imports import *
2
+ from .dot_utils import *
3
+ from .extract_utils import get_all_py_file_paths
4
+ def get_py_files(directory=None):
5
+ directory = directory or get_initial_caller_dir()
6
+ return get_all_py_file_paths(directory,add=True)
7
+ def ensure_on_path(p: Path):
8
+ s = str(p)
9
+ if s not in sys.path:
10
+ sys.path.insert(0, s)
11
+ def get_sysroot(filepath,i):
12
+ for j in range(i):
13
+ filepath = os.path.dirname(filepath)
14
+ return filepath
15
+
16
+ def get_dot_range_sysroot(filepath):
17
+ sysroot = filepath
18
+ while True:
19
+ dot_range = get_dot_range(is_import_or_init(sysroot))
20
+ if dot_range == 0:
21
+ break
22
+ sysroot = get_sysroot(sysroot,dot_range)
23
+
24
+ return sysroot
25
+ def get_import_with_sysroot(file_path, sysroot):
26
+ """
27
+ Rewrite imports like:
28
+ from imports.constants import *
29
+ into:
30
+ from <relative_path>.imports.constants import *
31
+ Where <relative_path> is computed relative to sysroot.
32
+ """
33
+
34
+
35
+ # Absolute paths
36
+ file_dir = os.path.dirname(os.path.abspath(file_path))
37
+ sysroot = os.path.abspath(sysroot)
38
+
39
+ # Compute relative path
40
+ relpath = os.path.relpath(file_dir, sysroot)
41
+
42
+ bare_rel = eatAll(relpath,'.')
43
+
44
+ # Turn filesystem path into dotted python path
45
+ if relpath == ".":
46
+ dotted = ""
47
+ else:
48
+ dotted = ".".join(part for part in relpath.split(os.sep) if part)
49
+ if bare_rel.startswith('/') and dotted.startswith('.'):
50
+ dotted = dotted[1:]
51
+
52
+
53
+ # Build final rewritten import
54
+ return dotted
55
+ def get_all_sysroots(files):
56
+ sysroots=[]
57
+ for glo in files:
58
+ imp = compute_dotted_and_sysroot(glo)
59
+ sysroots.append(imp[-1])
60
+ return sysroots
61
+ def get_shortest_sysroot(files):
62
+ sysroots = get_all_sysroots(files)
63
+ return get_shortest_path(*sysroots)
64
+ def get_all_py_sysroots(directory=None,files=None):
65
+ py_files = files or get_py_files(directory=directory)
66
+ return [compute_dotted_and_sysroot(glo)[1] for glo in py_files]
67
+
68
+ def get__imports(directory=None, sysroot=None):
69
+ directory = directory or get_caller_dir(1)
70
+ globs = collect_globs(directory, allowed_exts='.py')
71
+ globs = [glo for glo in globs.get('files') if glo]
72
+ sysroots = [compute_dotted_and_sysroot(glo)[1] for glo in globs]
73
+ # ⭐ Get unified monorepo root
74
+ monorepo_root = get_common_root(sysroots)
75
+ if str(monorepo_root) not in sys.path:
76
+ sys.path.insert(0, str(monorepo_root))
77
+ get_all_imports(directory=directory, sysroot=monorepo_root)
78
+ def is_import_or_init(sysroot,likely=None):
79
+ file_data = get_file_parts(sysroot)
80
+ nuroot = sysroot
81
+ dirname = file_data.get('dirname')
82
+ if os.path.isdir(sysroot):
83
+ dirname = sysroot
84
+ ext = file_data.get('ext')
85
+ filename = file_data.get('filename')
86
+
87
+ candidates = []
88
+ if likely:
89
+ candidates += [os.path.join(dirname,f"{likely}.py"),os.path.join(dirname,likely)]
90
+ candidates += [os.path.join(dirname,f"{filename}.py"),os.path.join(dirname,filename)]
91
+ files: List[Path] = []
92
+ for item in candidates:
93
+
94
+ if os.path.exists(item):
95
+ if os.path.isdir(item):
96
+
97
+ nuroot=None
98
+ init_name = '__init__.py'
99
+ rootList = os.listdir(item)
100
+ for basename in rootList:
101
+ if get_file_parts(basename,'filename') == filename:
102
+ nuroot = os.path.join(item,basename)
103
+ break
104
+ if init_name in rootList:
105
+ nuroot = os.path.join(item,init_name)
106
+ break
107
+
108
+ else:
109
+ nuroot=sysroot
110
+ break
111
+
112
+ return nuroot
@@ -0,0 +1,21 @@
1
+ from __future__ import annotations
2
+ import re,pexpect,shlex,ezodf,tiktoken,geopandas as gpd,os,PyPDF2,json,tempfile,requests
3
+ import textwrap,pdfplumber,math,hashlib,pandas as pd,platform,textwrap as tw,glob,asyncio
4
+ import fnmatch,importlib,shutil,sys,time,threading,posixpath,importlib.util,types, logging
5
+ import subprocess,pytesseract,queue,logging,functools,pathlib,pkgutil,inspect
6
+ from typing import *
7
+ from datetime import timedelta,datetime
8
+ from flask import jsonify
9
+ from logging.handlers import RotatingFileHandler
10
+ from pathlib import Path
11
+ from functools import reduce,lru_cache
12
+ from types import MethodType,ModuleType
13
+ from werkzeug.utils import secure_filename
14
+ from werkzeug.datastructures import FileStorage
15
+ from pdf2image import convert_from_path # only used for OCR fallback
16
+ from dataclasses import dataclass,field,asdict
17
+ from pprint import pprint
18
+ from dotenv import load_dotenv
19
+ from types import MethodType
20
+ from datetime import datetime, date
21
+ from decimal import Decimal
@@ -0,0 +1,2 @@
1
+ from .imports import *
2
+ from .json_utils import *
@@ -0,0 +1,2 @@
1
+ from .imports import *
2
+ from .module_imports import *
@@ -0,0 +1,2 @@
1
+ from ...imports import *
2
+ from typing import *
@@ -0,0 +1,5 @@
1
+ from ...read_write_utils import check_read_write_params, read_from_file, write_to_file
2
+ from ...compare_utils import get_closest_match_from_list
3
+ from ...directory_utils import makedirs
4
+ from ...list_utils import make_list
5
+ from ...class_utils import alias