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
@@ -0,0 +1,39 @@
1
+ from .imports import *
2
+ from .module_imports import *
3
+ @dataclass
4
+ class ScanConfig:
5
+ allowed_exts: Set[str]
6
+ unallowed_exts: Set[str]
7
+ exclude_types: Set[str]
8
+ exclude_dirs: List[str] = field(default_factory=list)
9
+ exclude_patterns: List[str] = field(default_factory=list)
10
+ DEFAULT_ALLOWED_EXTS: Set[str] = {
11
+ ".py", ".pyw", # python
12
+ ".js", ".jsx", ".ts", ".tsx", ".mjs", # JS/TS
13
+ ".html", ".htm", ".xml", # markup
14
+ ".css", ".scss", ".sass", ".less", # styles
15
+ ".json", ".yaml", ".yml", ".toml", ".ini", # configs
16
+ ".cfg", ".md", ".markdown", ".rst", # docs
17
+ ".sh", ".bash", ".env", # scripts/env
18
+ ".txt" # plain text
19
+ }
20
+
21
+ DEFAULT_EXCLUDE_TYPES: Set[str] = {
22
+ "image", "video", "audio", "presentation",
23
+ "spreadsheet", "archive", "executable"
24
+ }
25
+
26
+ # never want these—even if they sneak into ALLOWED
27
+ _unallowed = set(get_media_exts(DEFAULT_EXCLUDE_TYPES)) | {'.bak', '.shp', '.cpg', '.dbf', '.shx','.geojson',".pyc",'.shx','.geojson','.prj','.sbn','.sbx'}
28
+ DEFAULT_UNALLOWED_EXTS = {e for e in _unallowed if e not in DEFAULT_ALLOWED_EXTS}
29
+
30
+ DEFAULT_EXCLUDE_DIRS: Set[str] = {
31
+ "node_modules", "old","__pycache__", "backups", "backup", "backs", "trash", "depriciated", "old", "__init__"
32
+ }
33
+
34
+ DEFAULT_EXCLUDE_PATTERNS: Set[str] = {
35
+ "__init__*", "*.tmp", "*.log", "*.lock", "*.zip","*~"
36
+ }
37
+ REMOTE_RE = re.compile(r"^(?P<host>[^:\s]+@[^:\s]+):(?P<path>/.*)$")
38
+ AllowedPredicate = Optional[Callable[[str], bool]]
39
+ DEFAULT_EXCLUDE_FILE_PATTERNS=DEFAULT_EXCLUDE_PATTERNS
@@ -0,0 +1,10 @@
1
+ from .imports import *
2
+ def get_caller_path():
3
+ i = i or 1
4
+ frame = inspect.stack()[i]
5
+ return os.path.abspath(frame.filename)
6
+ def get_caller_dir(i=None):
7
+ i = i or 1
8
+ frame = inspect.stack()[i]
9
+ abspath = os.path.abspath(frame.filename)
10
+ return os.path.dirname(abspath)
@@ -0,0 +1,39 @@
1
+ # ============================================================
2
+ # abstract_utilities/imports/imports.py
3
+ # Global imports hub — everything imported here will be
4
+ # automatically available to any module that does:
5
+ # from ..imports import *
6
+ # ============================================================
7
+ # ---- Core standard library modules -------------------------
8
+ import os, sys, re, shlex, glob, platform, textwrap, subprocess, inspect, json, time
9
+ import tempfile, shutil, logging, pathlib, fnmatch, importlib, importlib.util, types
10
+ from pathlib import Path
11
+ from datetime import datetime
12
+ from types import ModuleType
13
+
14
+ # ---- Dataclasses and typing --------------------------------
15
+ from dataclasses import dataclass, field
16
+ from typing import (
17
+ Any, Optional, List, Dict, Set, Tuple,
18
+ Iterable, Callable, Literal, Union, TypeVar
19
+ )
20
+
21
+ # ---- Common 3rd-party dependencies --------------------------
22
+ import pandas as pd
23
+ import geopandas as gpd
24
+ import pytesseract
25
+ import pdfplumber
26
+ import PyPDF2
27
+ import ezodf
28
+ from pdf2image import convert_from_path
29
+ from werkzeug.utils import secure_filename
30
+ from werkzeug.datastructures import FileStorage
31
+
32
+ # ---- Helpers ------------------------------------------------
33
+ import textwrap as tw
34
+ from pprint import pprint
35
+
36
+ # ============================================================
37
+ # AUTO-EXPORT ALL NON-PRIVATE NAMES
38
+ # ============================================================
39
+ __all__ = [name for name in globals() if not name.startswith("_")]
@@ -0,0 +1,14 @@
1
+ from .imports import *
2
+ from ....string_clean import eatAll
3
+ from ....list_utils import make_list
4
+ from ....type_utils import get_media_exts, is_media_type, MIME_TYPES, is_str
5
+ from ....ssh_utils import *
6
+ from ....env_utils import *
7
+ from ....read_write_utils import *
8
+ from ....abstract_classes import SingletonMeta
9
+ from ....string_utils import get_from_kwargs
10
+ from ....abstract_classes import run_pruned_func
11
+ from ....class_utils import get_caller, get_caller_path, get_caller_dir
12
+
13
+
14
+ __all__ = [name for name in globals() if not name.startswith("_")]
@@ -1 +1,10 @@
1
1
  from ..imports import *
2
+ from typing import *
3
+ from dataclasses import dataclass, field
4
+ @dataclass
5
+ class ScanConfig:
6
+ allowed_exts: Set[str]
7
+ unallowed_exts: Set[str]
8
+ exclude_types: Set[str]
9
+ exclude_dirs: List[str] = field(default_factory=list)
10
+ exclude_patterns: List[str] = field(default_factory=list)
@@ -0,0 +1,92 @@
1
+ from .imports import *
2
+
3
+ def get_user_pass_host_key(**kwargs):
4
+ args = ['password','user_at_host','host','key','user']
5
+ kwargs['del_kwarg']=kwargs.get('del_kwarg',False)
6
+ values,kwargs = get_from_kwargs(*args,**kwargs)
7
+ return values
8
+
9
+ # --- Base remote checker -----------------------------------------------------
10
+ def _remote_test(path: str, test_flag: str, timeout: int = 5,*args, **kwargs) -> bool:
11
+ """
12
+ Run a remote shell test (e.g. -f, -d) via SSH.
13
+ Returns True if test succeeds, False otherwise.
14
+ """
15
+ try:
16
+ kwargs['cmd']=f"[ {test_flag} {shlex.quote(path)} ] && echo 1 || echo 0"
17
+ kwargs['text']=True
18
+ kwargs['timeout']=timeout
19
+ kwargs['stderr']=subprocess.DEVNULL
20
+ result = run_pruned_func(run_cmd,**kwargs)
21
+ return result.strip() == "1"
22
+ except Exception:
23
+ return False
24
+
25
+
26
+ # --- Individual path checks --------------------------------------------------
27
+ def is_remote_file(path: str,*args, **kwargs) -> bool:
28
+ """True if remote path is a file."""
29
+ return _remote_test(path, "-f", **kwargs)
30
+
31
+
32
+ def is_remote_dir(path: str,*args, **kwargs) -> bool:
33
+ """True if remote path is a directory."""
34
+ return _remote_test(path, "-d", **kwargs)
35
+
36
+
37
+ def is_local_file(path: str) -> bool:
38
+ """True if local path is a file."""
39
+ return os.path.isfile(path)
40
+
41
+
42
+ def is_local_dir(path: str) -> bool:
43
+ """True if local path is a directory."""
44
+ return os.path.isdir(path)
45
+
46
+
47
+ # --- Unified interface -------------------------------------------------------
48
+
49
+ def is_file(path: str,*args,**kwargs) -> bool:
50
+ """Determine if path is a file (works local or remote)."""
51
+ if get_user_pass_host_key(**kwargs):
52
+ return is_remote_file(path, **kwargs)
53
+ return is_local_file(path)
54
+
55
+
56
+ def is_dir(path: str, *args,**kwargs) -> bool:
57
+ """Determine if path is a directory (works local or remote)."""
58
+ if get_user_pass_host_key(**kwargs):
59
+ return is_remote_dir(path, **kwargs)
60
+ return is_local_dir(path)
61
+
62
+ def is_exists(path: str, *args,**kwargs) -> bool:
63
+ if is_file(path,**kwargs):
64
+ return True
65
+ if is_dir(path,**kwargs):
66
+ return True
67
+ return False
68
+ # --- Optional: keep your original all-in-one wrapper ------------------------
69
+ def check_path_type(
70
+ path: str,
71
+ *args,
72
+ **kwargs
73
+ ) -> str:
74
+ """
75
+ Return 'file', 'directory', 'missing', or 'unknown'.
76
+ Uses isolated is_file/is_dir functions.
77
+ """
78
+ if get_user_pass_host_key(**kwargs):
79
+ if is_remote_file(path,**kwargs):
80
+ return "file"
81
+ elif is_remote_dir(path,**kwargs):
82
+ return "directory"
83
+ else:
84
+ return "missing"
85
+ else:
86
+ if os.path.isfile(path):
87
+ return "file"
88
+ elif os.path.isdir(path):
89
+ return "directory"
90
+ elif not os.path.exists(path):
91
+ return "missing"
92
+ return "unknown"
@@ -1,5 +1,4 @@
1
1
  from .constants import *
2
- from .imports import *
3
2
  from .module_imports import *
4
3
  from .classes import *
5
- from .file_functions import *
4
+ from .imports import *
@@ -50,19 +50,20 @@ def is_file(
50
50
  env_path=None,
51
51
  **kwargs
52
52
  ):
53
- contingencies = list(set([user_at_host,password,key,env_path]))
54
- len_contingencies = len(contingencies)
55
- is_potential = (len_contingencies >1 or (None not in contingencies))
56
- if not is_potential:
57
- return os.path.isfile(path)
58
- cmd = get_item_check_cmd(path,file=True)
59
- return run_cmd(cmd=cmd,
60
- user_at_host=user_at_host,
61
- password=password,
62
- key=key,
63
- env_path=env_path,
64
- **kwargs
65
- )
53
+ if path:
54
+ contingencies = list(set([user_at_host,password,key,env_path]))
55
+ len_contingencies = len(contingencies)
56
+ is_potential = (len_contingencies >1 or (None not in contingencies))
57
+ if not is_potential:
58
+ return os.path.isfile(path)
59
+ cmd = get_item_check_cmd(path,file=True)
60
+ return run_cmd(cmd=cmd,
61
+ user_at_host=user_at_host,
62
+ password=password,
63
+ key=key,
64
+ env_path=env_path,
65
+ **kwargs
66
+ )
66
67
  def is_dir(
67
68
  path,
68
69
  user_at_host=None,
@@ -71,34 +72,13 @@ def is_dir(
71
72
  env_path=None,
72
73
  **kwargs
73
74
  ):
74
- contingencies = list(set([user_at_host,password,key,env_path]))
75
- len_contingencies = len(contingencies)
76
- is_potential = (len_contingencies >1 or (None not in contingencies))
77
- if not is_potential:
78
- return os.path.isdir(path)
79
- cmd = get_item_check_cmd(path,file=False,directory=True)
80
- return run_cmd(cmd=cmd,
81
- user_at_host=user_at_host,
82
- password=password,
83
- key=key,
84
- env_path=env_path,
85
- **kwargs
86
- )
87
- def is_exists(
88
- path,
89
- user_at_host=None,
90
- password=None,
91
- key=None,
92
- env_path=None,
93
- **kwargs
94
- ):
95
- contingencies = list(set([user_at_host,password,key,env_path]))
96
- len_contingencies = len(contingencies)
97
- is_potential = (len_contingencies >1 or (None not in contingencies))
98
- if not is_potential:
99
- return os.path.exists(path)
100
- if is_potential == True:
101
- cmd = get_item_check_cmd(path,exists=True)
75
+ if path:
76
+ contingencies = list(set([user_at_host,password,key,env_path]))
77
+ len_contingencies = len(contingencies)
78
+ is_potential = (len_contingencies >1 or (None not in contingencies))
79
+ if not is_potential:
80
+ return os.path.isdir(path)
81
+ cmd = get_item_check_cmd(path,file=False,directory=True)
102
82
  return run_cmd(cmd=cmd,
103
83
  user_at_host=user_at_host,
104
84
  password=password,
@@ -106,7 +86,7 @@ def is_exists(
106
86
  env_path=env_path,
107
87
  **kwargs
108
88
  )
109
- def is_any(
89
+ def is_exists(
110
90
  path,
111
91
  user_at_host=None,
112
92
  password=None,
@@ -114,25 +94,49 @@ def is_any(
114
94
  env_path=None,
115
95
  **kwargs
116
96
  ):
117
- contingencies = list(set([user_at_host,password,key,env_path]))
118
- len_contingencies = len(contingencies)
119
- is_potential = (len_contingencies >1 or (None not in contingencies))
120
- if not is_potential:
121
- return os.path.exists(path)
122
- if is_potential == True:
123
- out_js = get_all_item_check_cmd(path,file=True,directory=True,exists=True)
124
- for typ,cmd in out_js.items():
125
- response = run_cmd(cmd=cmd,
97
+ if path:
98
+ contingencies = list(set([user_at_host,password,key,env_path]))
99
+ len_contingencies = len(contingencies)
100
+ is_potential = (len_contingencies >1 or (None not in contingencies))
101
+ if not is_potential:
102
+ return os.path.exists(path)
103
+ if is_potential == True:
104
+ cmd = get_item_check_cmd(path,exists=True)
105
+ return run_cmd(cmd=cmd,
126
106
  user_at_host=user_at_host,
127
107
  password=password,
128
108
  key=key,
129
109
  env_path=env_path,
130
110
  **kwargs
131
111
  )
132
- result = "__OK__" in (response or "")
133
- if result:
134
- return typ
135
- return None
112
+ def is_any(
113
+ path,
114
+ user_at_host=None,
115
+ password=None,
116
+ key=None,
117
+ env_path=None,
118
+ **kwargs
119
+ ):
120
+ if path:
121
+ contingencies = list(set([user_at_host,password,key,env_path]))
122
+ len_contingencies = len(contingencies)
123
+ is_potential = (len_contingencies >1 or (None not in contingencies))
124
+ if not is_potential:
125
+ return os.path.exists(path)
126
+ if is_potential == True:
127
+ out_js = get_all_item_check_cmd(path,file=True,directory=True,exists=True)
128
+ for typ,cmd in out_js.items():
129
+ response = run_cmd(cmd=cmd,
130
+ user_at_host=user_at_host,
131
+ password=password,
132
+ key=key,
133
+ env_path=env_path,
134
+ **kwargs
135
+ )
136
+ result = "__OK__" in (response or "")
137
+ if result:
138
+ return typ
139
+
136
140
  class PathBackend(Protocol):
137
141
  def join(self, *parts: str) -> str: ...
138
142
  def isfile(self, path: str) -> bool: ...
@@ -0,0 +1,158 @@
1
+ from abstract_utilities import read_from_file, eatAll
2
+ import os, sys, re, inspect
3
+ from typing import *
4
+
5
+ # ============================================================
6
+ # Constants
7
+ # ============================================================
8
+ import_tag = 'import '
9
+ from_tag = 'from '
10
+
11
+ # ============================================================
12
+ # Helpers
13
+ # ============================================================
14
+ def get_caller_path(i=None):
15
+ i = i or 1
16
+ frame = inspect.stack()[i]
17
+ return os.path.abspath(frame.filename)
18
+
19
+ def make_list(obj: any) -> list:
20
+ if isinstance(obj, str) and ',' in obj:
21
+ obj = obj.split(',')
22
+ if isinstance(obj, (set, tuple)):
23
+ return list(obj)
24
+ if isinstance(obj, list):
25
+ return obj
26
+ return [obj]
27
+
28
+ def eatElse(stringObj, chars=None):
29
+ chars = make_list(chars or []) + list('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_')
30
+ while stringObj:
31
+ if stringObj and stringObj[0] not in chars:
32
+ stringObj = stringObj[1:]
33
+ continue
34
+ if stringObj and stringObj[-1] not in chars:
35
+ stringObj = stringObj[:-1]
36
+ continue
37
+ break
38
+ return stringObj
39
+
40
+ def clean_line(line):
41
+ return eatAll(line, [' ', '', '\t', '\n'])
42
+
43
+ def is_line_import(line):
44
+ return bool(line and line.startswith(import_tag) and 'from ' not in line)
45
+
46
+ def is_line_from_import(line):
47
+ return bool(line and line.startswith(from_tag) and ' import ' in line)
48
+
49
+ def is_from_group_start(line):
50
+ return bool(line and line.startswith(from_tag) and 'import' in line and '(' in line and not line.rstrip().endswith(')'))
51
+
52
+ def is_from_group_end(line):
53
+ return bool(line and ')' in line)
54
+
55
+ def clean_imports(imports):
56
+ if isinstance(imports, str):
57
+ imports = imports.split(',')
58
+ return [eatElse(imp.strip()) for imp in imports if imp.strip()]
59
+
60
+ # ============================================================
61
+ # Combine lone import statements
62
+ # ============================================================
63
+ def combine_lone_imports(text=None, file_path=None):
64
+ text = text or ''
65
+ if file_path and os.path.isfile(file_path):
66
+ text += read_from_file(file_path)
67
+ lines = text.split('\n')
68
+
69
+ cleaned_import_list = []
70
+ nu_lines = []
71
+ j = None
72
+
73
+ for i, line in enumerate(lines):
74
+ if is_line_import(line):
75
+ if j is None:
76
+ nu_lines.append(import_tag)
77
+ j = i
78
+ cleaned_import_list += clean_imports(line.split(import_tag)[1])
79
+ else:
80
+ nu_lines.append(line)
81
+
82
+ if j is None:
83
+ return '\n'.join(nu_lines)
84
+ cleaned_import_list = sorted(set(cleaned_import_list))
85
+ nu_lines[j] += ', '.join(cleaned_import_list)
86
+ return '\n'.join(nu_lines)
87
+
88
+ # ============================================================
89
+ # Merge repeated 'from pkg import ...' (1-line only)
90
+ # Preserve multi-line grouped imports
91
+ # ============================================================
92
+ def merge_from_import_groups(text=None, file_path=None):
93
+ if file_path and os.path.isfile(file_path):
94
+ text = read_from_file(file_path)
95
+ text = text or ''
96
+ lines = text.split('\n')
97
+
98
+ pkg_to_imports: Dict[str, Set[str]] = {}
99
+ pkg_to_line_index: Dict[str, int] = {}
100
+ nu_lines: List[str] = []
101
+
102
+ in_group = False
103
+ for i, line in enumerate(lines):
104
+ stripped = line.strip()
105
+
106
+ # preserve multi-line grouped blocks intact
107
+ if in_group:
108
+ nu_lines.append(line)
109
+ if is_from_group_end(line):
110
+ in_group = False
111
+ continue
112
+
113
+ if is_from_group_start(line):
114
+ in_group = True
115
+ nu_lines.append(line)
116
+ continue
117
+
118
+ if is_line_from_import(line):
119
+ try:
120
+ pkg_part, imps_part = line.split(' import ', 1)
121
+ pkg_name = pkg_part.replace('from ', '').strip()
122
+ imps = clean_imports(imps_part)
123
+ except Exception:
124
+ nu_lines.append(line)
125
+ continue
126
+
127
+ if pkg_name not in pkg_to_imports:
128
+ pkg_to_imports[pkg_name] = set(imps)
129
+ pkg_to_line_index[pkg_name] = len(nu_lines)
130
+ nu_lines.append(line)
131
+ else:
132
+ pkg_to_imports[pkg_name].update(imps)
133
+ else:
134
+ nu_lines.append(line)
135
+
136
+ # Rewrite first occurrences
137
+ for pkg, idx in pkg_to_line_index.items():
138
+ all_imps = sorted(pkg_to_imports[pkg])
139
+ nu_lines[idx] = f"from {pkg} import {', '.join(all_imps)}"
140
+
141
+ return '\n'.join(nu_lines)
142
+
143
+ # ============================================================
144
+ # Pipeline
145
+ # ============================================================
146
+ def clean_imports_pipeline(path: str):
147
+ raw = read_from_file(path)
148
+ step1 = combine_lone_imports(text=raw)
149
+ step2 = merge_from_import_groups(text=step1)
150
+ return step2
151
+
152
+ # ============================================================
153
+ # Standalone Run
154
+ # ============================================================
155
+ if __name__ == "__main__":
156
+ abs_path = "/home/flerb/Documents/pythonTools/modules/src/modules/abstract_utilities/src/abstract_utilities/file_utils/imports/imports.py"
157
+ cleaned = clean_imports_pipeline(abs_path)
158
+ print(cleaned)
@@ -1,12 +1,40 @@
1
1
  from .imports import *
2
2
  from .module_imports import *
3
+ # -------------------------
4
+ # Config dataclass
5
+ # -------------------------
6
+
3
7
  @dataclass
4
8
  class ScanConfig:
5
9
  allowed_exts: Set[str]
6
- unallowed_exts: Set[str]
10
+ exclude_exts: Set[str]
11
+ allowed_types: Set[str]
7
12
  exclude_types: Set[str]
13
+ allowed_dirs: List[str] = field(default_factory=list)
8
14
  exclude_dirs: List[str] = field(default_factory=list)
15
+ allowed_patterns: List[str] = field(default_factory=list)
9
16
  exclude_patterns: List[str] = field(default_factory=list)
17
+
18
+ @dataclass
19
+ class SearchParams(ScanConfig):
20
+ directories: List[str] = field(default_factory=list)
21
+ add: bool = False
22
+ recursive: bool = True
23
+ strings: List[str] = field(default_factory=list)
24
+ total_strings: bool = False
25
+ parse_lines: bool = False
26
+ spec_line: Union[bool, int] = False
27
+ get_lines: bool = False
28
+
29
+ @dataclass
30
+ class AllParams(SearchParams):
31
+ cfg = None
32
+ allowed: Optional[Callable[[str], bool]] = None
33
+ include_files: bool = True
34
+ recursive: bool = True
35
+ # -------------------------
36
+ # Default sets
37
+ # -------------------------
10
38
  DEFAULT_ALLOWED_EXTS: Set[str] = {
11
39
  ".py", ".pyw", # python
12
40
  ".js", ".jsx", ".ts", ".tsx", ".mjs", # JS/TS
@@ -24,11 +52,15 @@ DEFAULT_EXCLUDE_TYPES: Set[str] = {
24
52
  }
25
53
 
26
54
  # never want these—even if they sneak into ALLOWED
27
- _unallowed = set(get_media_exts(DEFAULT_EXCLUDE_TYPES)) | {'.bak', '.shp', '.cpg', '.dbf', '.shx','.geojson',".pyc",'.shx','.geojson','.prj','.sbn','.sbx'}
28
- DEFAULT_UNALLOWED_EXTS = {e for e in _unallowed if e not in DEFAULT_ALLOWED_EXTS}
55
+ _unallowed = set(get_media_exts(DEFAULT_EXCLUDE_TYPES)) | {
56
+ ".bak", ".shp", ".cpg", ".dbf", ".shx", ".geojson",
57
+ ".pyc", ".prj", ".sbn", ".sbx"
58
+ }
59
+ DEFAULT_EXCLUDE_EXTS = {e.split('.')[-1] for e in _unallowed if e not in DEFAULT_ALLOWED_EXTS}
29
60
 
30
61
  DEFAULT_EXCLUDE_DIRS: Set[str] = {
31
- "node_modules", "old","__pycache__", "backups", "backup", "backs", "trash", "depriciated", "old", "__init__"
62
+ "node_modules", "old","__pycache__", "backups", "backup",
63
+ "backs", "trash", "depriciated", "old", "__init__"
32
64
  }
33
65
 
34
66
  DEFAULT_EXCLUDE_PATTERNS: Set[str] = {
@@ -37,3 +69,51 @@ DEFAULT_EXCLUDE_PATTERNS: Set[str] = {
37
69
  REMOTE_RE = re.compile(r"^(?P<host>[^:\s]+@[^:\s]+):(?P<path>/.*)$")
38
70
  AllowedPredicate = Optional[Callable[[str], bool]]
39
71
  DEFAULT_EXCLUDE_FILE_PATTERNS=DEFAULT_EXCLUDE_PATTERNS
72
+ DEFAULT_ALLOWED_PATTERNS: List[str] = ["*"]
73
+ DEFAULT_ALLOWED_DIRS: List[str] = ["*"]
74
+ DEFAULT_ALLOWED_TYPES: List[str] = ["*"]
75
+ CANONICAL_MAP = {
76
+ "directories": ["directory", "directories", "dir","dirs","directory","directories","d","dirname", "paths", "path","roots","root"],
77
+ "files":["file","filepath","file_path","files","filepaths","file_paths","paths", "path","f"],
78
+ "allowed_exts": ["allow_ext", "allowed_ext", "include_ext", "include_exts", "exts_allowed"],
79
+ "exclude_exts": ["exclude_ext", "excluded_ext", "excluded_exts", "unallowed_ext", "unallowed_exts"],
80
+ "allowed_types": ["allow_type", "allowed_type", "include_type", "include_types", "types_allowed"],
81
+ "exclude_types": ["exclude_type", "excluded_type", "excluded_types", "unallowed_type", "unallowed_types"],
82
+ "allowed_dirs": ["allow_dir", "allowed_dir", "include_dir", "include_dirs", "dirs_allowed"],
83
+ "exclude_dirs": ["exclude_dir", "excluded_dir", "excluded_dirs", "unallowed_dir", "unallowed_dirs"],
84
+ "allowed_patterns": ["allow_pattern", "allowed_pattern", "include_pattern", "include_patterns", "patterns_allowed"],
85
+ "exclude_patterns": ["exclude_pattern", "excluded_pattern", "excluded_patterns", "unallowed_pattern", "unallowed_patterns"],
86
+ "add":["add"],
87
+ "cfg":["cfg"],
88
+ "recursive":["recursive"],
89
+ "strings":["strings"],
90
+ "total_strings":["total_strings"],
91
+ "parse_lines":["parse_lines"],
92
+ "spec_line":["spec_line"],
93
+ "get_lines":["get_lines"]
94
+ }
95
+ DEFAULT_ALLOWED_EXCLUDE_MAP={
96
+ "allowed_exts": {"default":DEFAULT_ALLOWED_EXTS,"type":type(DEFAULT_ALLOWED_EXTS),"canonical":CANONICAL_MAP.get("allowed_exts")},
97
+ "exclude_exts": {"default":DEFAULT_EXCLUDE_EXTS,"type":type(DEFAULT_EXCLUDE_EXTS),"canonical":CANONICAL_MAP.get("exclude_exts")},
98
+ "allowed_types": {"default":DEFAULT_ALLOWED_TYPES,"type":type(DEFAULT_ALLOWED_TYPES),"canonical":CANONICAL_MAP.get("allowed_types")},
99
+ "exclude_types": {"default":DEFAULT_EXCLUDE_TYPES,"type":type(DEFAULT_EXCLUDE_TYPES),"canonical":CANONICAL_MAP.get("exclude_types")},
100
+ "allowed_dirs": {"default":DEFAULT_ALLOWED_DIRS,"type":type(DEFAULT_ALLOWED_DIRS),"canonical":CANONICAL_MAP.get("allowed_dirs")},
101
+ "exclude_dirs": {"default":DEFAULT_EXCLUDE_DIRS,"type":type(DEFAULT_EXCLUDE_DIRS),"canonical":CANONICAL_MAP.get("exclude_dirs")},
102
+ "allowed_patterns": {"default":DEFAULT_ALLOWED_PATTERNS,"type":type(DEFAULT_ALLOWED_PATTERNS),"canonical":CANONICAL_MAP.get("allowed_patterns")},
103
+ "exclude_patterns": {"default":DEFAULT_EXCLUDE_PATTERNS,"type":type(DEFAULT_EXCLUDE_PATTERNS),"canonical":CANONICAL_MAP.get("exclude_patterns")},
104
+ }
105
+ DEFAULT_CANONICAL_MAP={
106
+ "directories":{"default":[],"type":list,"canonical":CANONICAL_MAP.get("directories")},
107
+ "files":{"default":[],"type":list,"canonical":CANONICAL_MAP.get("files")},
108
+ **DEFAULT_ALLOWED_EXCLUDE_MAP,
109
+ "allowed":{"default":None,"type":bool,"canonical":CANONICAL_MAP.get("allowed")},
110
+ "add":{"default":False,"type":bool,"canonical":CANONICAL_MAP.get("add")},
111
+ "recursive":{"default":True,"type":bool,"canonical":CANONICAL_MAP.get("recursive")},
112
+ "strings":{"default":None,"type":list,"canonical":CANONICAL_MAP.get("strings")},
113
+ "total_strings":{"default":False,"type":bool,"canonical":CANONICAL_MAP.get("total_strings")},
114
+ "parse_lines":{"default":False,"type":bool,"canonical":CANONICAL_MAP.get("parse_lines")},
115
+ "spec_line":{"default":False,"type":bool,"canonical":CANONICAL_MAP.get("spec_line")},
116
+ "get_lines":{"default":False,"type":bool,"canonical":CANONICAL_MAP.get("get_lines")},
117
+ }
118
+
119
+
@@ -1,5 +1,5 @@
1
1
  from .imports import *
2
- def get_caller_path():
2
+ def get_caller_path(i=None):
3
3
  i = i or 1
4
4
  frame = inspect.stack()[i]
5
5
  return os.path.abspath(frame.filename)