abstract-utilities 0.2.2.449__py3-none-any.whl → 0.2.2.476__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 (68) hide show
  1. abstract_utilities/__init__.py +18 -44
  2. abstract_utilities/abstract_classes.py +49 -0
  3. abstract_utilities/class_utils.py +38 -3
  4. abstract_utilities/cmd_utils/imports/__init__.py +1 -0
  5. abstract_utilities/cmd_utils/imports/imports.py +10 -0
  6. abstract_utilities/cmd_utils/pexpect_utils.py +310 -0
  7. abstract_utilities/cmd_utils/user_utils.py +1 -1
  8. abstract_utilities/compare_utils/__init__.py +3 -0
  9. abstract_utilities/compare_utils/best_match.py +150 -0
  10. abstract_utilities/{compare_utils.py → compare_utils/compare_utils.py} +1 -1
  11. abstract_utilities/compare_utils/find_value.py +105 -0
  12. abstract_utilities/dynimport.py +7 -15
  13. abstract_utilities/env_utils/__init__.py +3 -0
  14. abstract_utilities/env_utils/abstractEnv.py +129 -0
  15. abstract_utilities/env_utils/envy_it.py +33 -0
  16. abstract_utilities/env_utils/imports/__init__.py +2 -0
  17. abstract_utilities/env_utils/imports/imports.py +8 -0
  18. abstract_utilities/env_utils/imports/utils.py +122 -0
  19. abstract_utilities/file_utils/__init__.py +3 -0
  20. abstract_utilities/file_utils/file_utils/__init__.py +8 -0
  21. abstract_utilities/file_utils/file_utils/file_filters.py +104 -0
  22. abstract_utilities/{robust_reader → file_utils/file_utils}/file_reader.py +5 -19
  23. abstract_utilities/{robust_readers/file_filters.py → file_utils/file_utils/file_utils.py} +5 -4
  24. abstract_utilities/{robust_readers → file_utils/file_utils}/filter_params.py +1 -38
  25. abstract_utilities/file_utils/file_utils/find_collect.py +154 -0
  26. abstract_utilities/file_utils/file_utils/imports/__init__.py +3 -0
  27. abstract_utilities/file_utils/file_utils/imports/constants.py +39 -0
  28. abstract_utilities/file_utils/file_utils/imports/file_functions.py +10 -0
  29. abstract_utilities/file_utils/file_utils/imports/imports.py +39 -0
  30. abstract_utilities/file_utils/file_utils/imports/module_imports.py +13 -0
  31. abstract_utilities/file_utils/file_utils/imports.py +10 -0
  32. abstract_utilities/file_utils/file_utils/map_utils.py +29 -0
  33. abstract_utilities/{robust_reader → file_utils/file_utils}/pdf_utils.py +1 -9
  34. abstract_utilities/file_utils/file_utils/type_checks.py +82 -0
  35. abstract_utilities/file_utils/imports/__init__.py +4 -0
  36. abstract_utilities/file_utils/imports/classes.py +381 -0
  37. abstract_utilities/file_utils/imports/clean_imps.py +158 -0
  38. abstract_utilities/file_utils/imports/constants.py +39 -0
  39. abstract_utilities/file_utils/imports/file_functions.py +10 -0
  40. abstract_utilities/file_utils/imports/imports.py +65 -0
  41. abstract_utilities/file_utils/imports/module_imports.py +13 -0
  42. abstract_utilities/file_utils/req.py +329 -0
  43. abstract_utilities/json_utils.py +35 -0
  44. abstract_utilities/log_utils.py +14 -3
  45. abstract_utilities/path_utils.py +90 -6
  46. abstract_utilities/read_write_utils.py +176 -154
  47. abstract_utilities/robust_reader/__init__.py +1 -1
  48. abstract_utilities/robust_reader/imports/__init__.py +1 -0
  49. abstract_utilities/robust_reader/imports/imports.py +3 -0
  50. abstract_utilities/robust_readers/__init__.py +0 -1
  51. abstract_utilities/robust_readers/import_utils/__init__.py +1 -0
  52. abstract_utilities/robust_readers/import_utils/clean_imports.py +175 -0
  53. abstract_utilities/robust_readers/imports.py +8 -0
  54. abstract_utilities/robust_readers/initFuncGen.py +92 -76
  55. abstract_utilities/safe_utils.py +133 -0
  56. abstract_utilities/ssh_utils/__init__.py +3 -0
  57. abstract_utilities/ssh_utils/classes.py +127 -0
  58. abstract_utilities/ssh_utils/imports.py +10 -0
  59. abstract_utilities/ssh_utils/pexpect_utils.py +315 -0
  60. abstract_utilities/ssh_utils/utils.py +188 -0
  61. abstract_utilities/string_clean.py +40 -1
  62. abstract_utilities/string_utils.py +48 -0
  63. abstract_utilities/type_utils.py +25 -2
  64. {abstract_utilities-0.2.2.449.dist-info → abstract_utilities-0.2.2.476.dist-info}/METADATA +15 -4
  65. abstract_utilities-0.2.2.476.dist-info/RECORD +92 -0
  66. {abstract_utilities-0.2.2.449.dist-info → abstract_utilities-0.2.2.476.dist-info}/WHEEL +1 -1
  67. abstract_utilities-0.2.2.449.dist-info/RECORD +0 -49
  68. {abstract_utilities-0.2.2.449.dist-info → abstract_utilities-0.2.2.476.dist-info}/top_level.txt +0 -0
@@ -1,115 +1,40 @@
1
1
  """
2
2
  read_write_utils.py
3
-
4
- This module, 'read_write_utils.py', provides utility functions for reading and writing to files.
5
- These include functions to:
3
+ -------------------
4
+ Unified read/write utility for safe file operations.
5
+ Supports:
6
+ - Writing content to a file
7
+ - Reading content from a file
8
+ - Creating and reading if missing
9
+ - Detecting file/content params via positional args or kwargs
6
10
 
7
11
  Usage:
8
- import abstract_utilities.read_write_utils as read_write_utils
9
-
10
- 1. Write content to a file.
11
- 2. Read content from a file.
12
- 3. Check if a string has a file extension.
13
- 4. Read from or write to a file depending on the number of arguments.
14
- 5. Create a file if it does not exist, then read from it.
12
+ from abstract_utilities.read_write_utils import *
13
+ """
15
14
 
16
- Each function includes a docstring to further explain its purpose, input parameters, and return values.
17
15
  import os
16
+ import shlex
17
+ from .ssh_utils.utils import run_cmd,get_print_sudo_cmd,run_local_cmd,run_remote_cmd
18
+ from .file_utils.file_utils.type_checks import is_file,is_dir
19
+ from .abstract_classes import run_pruned_func
20
+ _FILE_PATH_KEYS = ['file', 'filepath', 'file_path', 'path', 'directory', 'f', 'dst', 'dest']
21
+ _CONTENTS_KEYS = ['cont', 'content', 'contents', 'data', 'datas', 'dat', 'src', 'source']
18
22
 
19
- # File and Directory Operations
20
- os.rename(src, dst) # Rename a file or directory
21
- os.remove(path) # Remove a file
22
- os.unlink(path) # Alias for os.remove()
23
- os.rmdir(path) # Remove an empty directory
24
- os.makedirs(path) # Create directories recursively
25
- os.makedirs(path, exist_ok=True) # Create directories, ignore if exists
26
- os.mkdir(path) # Create a single directory
27
- os.listdir(path) # List files and directories in a path
28
- os.chdir(path) # Change current working directory
29
- os.getcwd() # Get current working directory
30
- os.stat(path) # Get file/directory information
31
- os.lstat(path) # Get symbolic link information
32
- os.symlink(src, dst) # Create a symbolic link
33
- os.readlink(path) # Read the target of a symbolic link
34
- os.getcwd() # Get current working directory
35
- os.chdir(path) # Change current working directory
36
-
37
- # File and Directory Information
38
- os.path.exists(path) # Check if a path exists
39
- os.path.isfile(path) # Check if a path points to a file
40
- os.path.isdir(path) # Check if a path points to a directory
41
- os.path.islink(path) # Check if a path points to a symbolic link
42
- os.path.abspath(path) # Get the absolute path of a file/directory
43
- os.path.basename(path) # Get the base name of a path
44
- os.path.dirname(path) # Get the directory name of a path
45
- os.path.join(path1, path2, ...) # Join path components into a single path
46
-
47
- # File Permissions
48
- os.chmod(path, mode) # Change file permissions
49
- os.access(path, mode) # Check if a file is accessible with given mode
50
-
51
- # File Times
52
- os.path.getatime(path) # Get last access time of a file
53
- os.path.getmtime(path) # Get last modification time of a file
54
- os.path.getctime(path) # Get creation time of a file
55
- os.utime(path, times) # Set access and modification times
56
-
57
- # Working with Paths
58
- os.path.split(path) # Split a path into (head, tail)
59
- os.path.splitext(path) # Split a path into (root, ext)
60
- os.path.normpath(path) # Normalize a path (e.g., convert slashes)
61
-
62
- # Other
63
- os.path.samefile(path1, path2) # Check if two paths refer to the same file
64
-
65
- # Directory Traversal
66
- for root, dirs, files in os.walk(top, topdown=True):
67
- # Traverse a directory tree, yielding root, dirs, and files lists
68
-
69
- # Temporary Files and Directories
70
- import tempfile
71
- tempfile.mkstemp() # Create a temporary file
72
- tempfile.mkdtemp() # Create a temporary directory
73
- tempfile.TemporaryFile() # Create a temporary file object
74
-
75
- # Environment Variables
76
- os.environ # Dictionary of environment variables
77
- os.environ['VAR_NAME'] # Access an environment variable
78
- os.environ.get('VAR_NAME') # Access an environment variable (with default)
79
-
80
- # Path Manipulation
81
- os.path.abspath(path) # Convert relative path to absolute path
82
- os.path.join(path1, path2, ...) # Join paths together
83
- os.path.split(path) # Split a path into directory and filename
84
- os.path.dirname(path) # Get the directory part of a path
85
- os.path.basename(path) # Get the filename part of a path
86
- os.path.exists(path) # Check if a path exists
87
- os.path.isfile(path) # Check if a path points to a file
88
- os.path.isdir(path) # Check if a path points to a directory
89
-
90
- # File Permissions
91
- os.chmod(path, mode) # Change file permissions
92
-
93
- # Miscellaneous
94
- os.getpid() # Get the current process ID
95
- os.getlogin() # Get the name of the logged-in user
96
-
97
- """
98
- import os
99
- def break_down_find_existing(path):
100
- test_path = ''
101
- for part in path.split(os.sep):
102
- test_path = os.path.join(test_path, part)
103
- if not os.path.exists(test_path):
104
- return test_path if test_path else None
105
- return test_path
106
23
 
24
+ # --- Helper utilities --------------------------------------------------------
107
25
  def string_in_keys(strings, kwargs):
108
- return next((key for key in kwargs if any(s.lower() in key.lower() for s in strings)), None)
26
+ """Find a matching keyword in kwargs that contains any of the given substrings."""
27
+ for key in kwargs:
28
+ for s in strings:
29
+ if s.lower() in key.lower():
30
+ return key
31
+ return None
32
+
109
33
 
110
34
  def get_path(paths):
35
+ """Return the first valid path among given paths."""
111
36
  for path in paths:
112
- if isinstance(path,str):
37
+ if isinstance(path, str):
113
38
  if os.path.isfile(path):
114
39
  return path
115
40
  dirname = os.path.dirname(path)
@@ -117,83 +42,180 @@ def get_path(paths):
117
42
  return path
118
43
  return None
119
44
 
45
+
46
+ def break_down_find_existing(path):
47
+ """Return the first non-existent subpath within a path chain."""
48
+ test_path = ''
49
+ for part in path.split(os.sep):
50
+ test_path = os.path.join(test_path, part)
51
+ if not os.path.exists(test_path):
52
+ return test_path if test_path else None
53
+ return test_path
54
+
55
+
56
+ # --- Parameter parsing --------------------------------------------------------
120
57
  def check_read_write_params(*args, **kwargs):
121
- file_path = kwargs.get('file_path', None)
122
- contents = kwargs.get('contents', None)
123
- if contents is None:
124
- contents = kwargs.get('data', None)
58
+ """
59
+ Determine file_path and contents from arguments.
60
+ Returns a tuple: (file_path, contents)
61
+ """
62
+ file_key = string_in_keys(_FILE_PATH_KEYS, kwargs)
63
+ content_key = string_in_keys(_CONTENTS_KEYS, kwargs)
125
64
 
126
- # Handle positional arguments
65
+ file_path = kwargs.get(file_key) if file_key else None
66
+ contents = kwargs.get(content_key) if content_key else None
67
+
68
+ # Handle positional args (fallback)
127
69
  if file_path is None and len(args) > 0:
128
70
  file_path = args[0]
129
71
  if contents is None and len(args) > 1:
130
72
  contents = args[1]
131
- elif contents is None and len(args) > 0 and file_path != args[0]:
132
- contents = args[0]
133
-
134
- if file_path is None or contents is None:
135
- raise ValueError("Both 'file_path' and 'contents' (or 'data') are required.")
136
73
 
74
+ if file_path is None:
75
+ raise ValueError("Missing file_path argument.")
137
76
  return file_path, contents
138
77
 
139
- def write_to_file(file_path=None, contents=None,*args, **kwargs):
78
+ def write_to_path(
79
+ file_path: str,
80
+ contents: str,
81
+ *,
82
+ user_at_host: str = None,
83
+ cwd: str | None = None,
84
+ password=None,
85
+ key=None,
86
+ env_path=None,
87
+ **kwargs
88
+ ) -> str:
140
89
  """
141
- Write contents to a file. If the file does not exist, it is created.
142
-
143
- Args:
144
- file_path: The path of the file to write to.
145
- contents: The content to write to the file.
146
-
147
- Returns:
148
- The contents that were written to the file.
90
+ Completely overwrite a file (locally or remotely).
91
+ Supports sudo and password-based remote execution.
149
92
  """
150
- params = check_read_write_params(file_path=file_path, contents=contents,*args, **kwargs)
151
- if params:
152
- with open(params[0], 'w', encoding='UTF-8') as f:
153
- f.write(params[1])
154
- return contents
155
93
 
156
-
157
- def read_from_file(file_path) -> str:
94
+ # sanitize for shell safety
95
+ quoted_path = shlex.quote(file_path)
96
+ quoted_data = shlex.quote(str(contents))
97
+
98
+ # shell command that fully overwrites
99
+ # (no append, replaces contents entirely)
100
+ base_cmd = f"echo {quoted_data} > {quoted_path}"
101
+
102
+ # optional sudo password injection
103
+ full_cmd = get_print_sudo_cmd(
104
+ cmd=base_cmd,
105
+ password=password,
106
+ key=key,
107
+ env_path=env_path
108
+ )
109
+
110
+ # local or remote dispatch
111
+ if user_at_host:
112
+ return run_remote_cmd(
113
+ user_at_host=user_at_host,
114
+ cmd=full_cmd,
115
+ cwd=cwd,
116
+ password=password,
117
+ key=key,
118
+ env_path=env_path,
119
+ **kwargs
120
+ )
121
+ else:
122
+ return run_local_cmd(
123
+ cmd=full_cmd,
124
+ cwd=cwd,
125
+ password=password,
126
+ key=key,
127
+ env_path=env_path,
128
+ **kwargs
129
+ )
130
+ ### --- Core functionality -------------------------------------------------------
131
+ ##def write_to_file(*args, **kwargs):
132
+ ## """
133
+ ## Write contents to a file (create if missing).
134
+ ##
135
+ ## Returns the file_path written.
136
+ ## """
137
+ ## file_path, contents = check_read_write_params(*args, **kwargs)
138
+ ## if contents is None:
139
+ ## raise ValueError("Missing contents to write.")
140
+ ##
141
+ ## os.makedirs(os.path.dirname(file_path) or ".", exist_ok=True)
142
+ ## with open(file_path, "w", encoding="utf-8") as f:
143
+ ## f.write(str(contents))
144
+ ## return file_path
145
+ # --- Core functionality -------------------------------------------------------
146
+ def write_to_file(*args, **kwargs):
158
147
  """
159
- Read the contents of a file.
160
-
161
- Args:
162
- file_path: The path of the file to read from.
163
-
164
- Returns:
165
- The contents of the file.
148
+ Write contents to a file (create if missing).
149
+
150
+ Returns the file_path written.
166
151
  """
167
- with open(file_path, 'r', encoding='UTF-8') as f:
152
+ file_path, contents = check_read_write_params(*args, **kwargs)
153
+ if contents is None:
154
+ raise ValueError("Missing contents to write.")
155
+ user_at_host = kwargs.get("user_at_host")
156
+ if user_at_host:
157
+ kwargs["cwd"] = kwargs.get('cwd') or os.path.dirname(file_path)
158
+ # sanitize for shell safety
159
+ quoted_path = shlex.quote(file_path)
160
+ quoted_data = shlex.quote(str(contents))
161
+ # shell command that fully overwrites
162
+ # (no append, replaces contents entirely)
163
+ kwargs["cmd"] = f"echo {quoted_data} > {quoted_path}"
164
+ return run_pruned_func(run_cmd,**kwargs)
165
+
166
+
167
+ os.makedirs(os.path.dirname(file_path) or ".", exist_ok=True)
168
+ with open(file_path, "w", encoding="utf-8") as f:
169
+ f.write(str(contents))
170
+ return file_path
171
+
172
+
173
+ def read_from_file(file_path,**kwargs):
174
+ user_at_host = kwargs.get("user_at_host")
175
+ if user_at_host:
176
+ kwargs["cwd"] = kwargs.get('cwd') or os.path.dirname(file_path)
177
+ basename = os.path.basename(file_path)
178
+ kwargs["cmd"] = f'cat {basename}'
179
+ return run_pruned_func(run_cmd,**kwargs)
180
+ """Read text content from a file."""
181
+ with open(file_path, "r", encoding="utf-8") as f:
168
182
  return f.read()
169
183
 
170
- def create_and_read_file(file_path=None, contents:str='',*args, **kwargs) -> str:
184
+
185
+ def create_and_read_file(*args, **kwargs):
171
186
  """
172
- Create a file if it does not exist, then read from it.
173
-
174
- Args:
175
- file_path: The path of the file to create and read from.
176
- contents: The content to write to the file if it does not exist.
177
-
178
- Returns:
179
- The contents of the file.
187
+ Create the file (if missing) and read contents from it.
180
188
  """
189
+ file_path, contents = check_read_write_params(*args, **kwargs)
181
190
  if not os.path.isfile(file_path):
182
- write_to_file(contents, file_path)
191
+ write_to_file(file_path, contents or "")
183
192
  return read_from_file(file_path)
193
+
194
+
184
195
  def is_file_extension(obj: str) -> bool:
185
- """
186
- Check if a string has a file extension.
187
-
188
- Args:
189
- obj: The string to check.
190
-
191
- Returns:
192
- True if the string has a file extension, False otherwise.
193
- """
194
- return len(obj) >= 4 and '.' in obj[-4:-3]
196
+ """Return True if obj looks like a filename with extension."""
197
+ if not isinstance(obj, str):
198
+ return False
199
+ root, ext = os.path.splitext(obj)
200
+ return bool(root and ext)
201
+
195
202
 
196
203
  def delete_file(file_path: str):
204
+ """Safely delete a file if it exists."""
197
205
  if os.path.isfile(file_path):
198
206
  os.remove(file_path)
207
+ return True
208
+ return False
209
+
199
210
 
211
+ def get_content_lines(*args, **kwargs):
212
+ """Return a list of lines from string or file path."""
213
+ file_path, contents = check_read_write_params(*args, **kwargs)
214
+ if os.path.isfile(file_path):
215
+ contents = read_from_file(filepath)
216
+
217
+ if isinstance(contents, str):
218
+ return contents.splitlines()
219
+ elif isinstance(contents, list):
220
+ return contents
221
+ return []
@@ -1,2 +1,2 @@
1
- from .file_reader import *
1
+ from ..file_utils import *
2
2
 
@@ -0,0 +1 @@
1
+ from .imports import *
@@ -0,0 +1,3 @@
1
+ from ...abstract_classes import SingletonMeta
2
+ from ..pdf_utils import *
3
+ from ...read_write_utils import *
@@ -1,3 +1,2 @@
1
- from .file_filters import *
2
1
  from .initFuncGen import *
3
2
  from .import_utils import *
@@ -4,3 +4,4 @@ from .import_utils import *
4
4
  from .sysroot_utils import *
5
5
  from .utils import *
6
6
  from .safe_import_utils import *
7
+ from .clean_imports import *
@@ -0,0 +1,175 @@
1
+ from ...read_write_utils import read_from_file,write_to_file
2
+ from ...string_clean import eatAll,eatElse,clean_line
3
+ from ...class_utils import get_caller_path
4
+ from ...list_utils import make_list
5
+ import os
6
+ import_tag = 'import '
7
+ from_tag = 'from '
8
+ def get_text_or_read(text=None,file_path=None):
9
+ text = text or ''
10
+ imports_js = {}
11
+ if not text and file_path and os.path.isfile(file_path):
12
+ text=read_from_file(file_path)
13
+ return text
14
+ def is_line_import(line):
15
+ if line and (line.startswith(from_tag) or line.startswith(import_tag)):
16
+ return True
17
+ return False
18
+ def is_line_group_import(line):
19
+ if line and (line.startswith(from_tag) and import_tag in line):
20
+ return True
21
+ return False
22
+ def get_import_pkg(line):
23
+ if is_line_group_import(line):
24
+ return clean_line(line.split(from_tag)[1].split(import_tag)[0])
25
+ def get_imports_from_import_pkg(line):
26
+ if is_line_group_import(line):
27
+ return get_cleaned_import_list(line,commaClean=True)
28
+
29
+ def add_imports_to_import_pkg_js(import_pkg,imports,import_pkg_js=None):
30
+ import_pkg_js = import_pkg_js or {}
31
+ imports = clean_imports(imports)
32
+ if import_pkg not in import_pkg_js:
33
+ i = len(import_pkg_js["nulines"])
34
+ import_pkg_js[import_pkg]={"imports":imports,"line":i}
35
+ import_line = f"from {import_pkg} import "
36
+ if import_pkg == "import":
37
+ import_line = import_tag
38
+ import_pkg_js["nulines"].append(import_line)
39
+ else:
40
+ import_pkg_js[import_pkg]["imports"]+=imports
41
+ return import_pkg_js
42
+ def update_import_pkg_js(line,import_pkg_js=None):
43
+ import_pkg_js = import_pkg_js or {}
44
+ if is_line_group_import(line):
45
+ import_pkg = get_import_pkg(line)
46
+ imports = get_imports_from_import_pkg(line)
47
+ import_pkg_js = add_imports_to_import_pkg_js(import_pkg,imports,import_pkg_js=import_pkg_js)
48
+ else:
49
+ if len(import_pkg_js["nulines"]) >0 and line == '' and is_line_import(import_pkg_js["nulines"][-1]):
50
+ pass
51
+ else:
52
+ import_pkg_js["nulines"].append(line)
53
+ return import_pkg_js
54
+ def is_from_line_group(line):
55
+ if line and line.startswith(from_tag) and import_tag in line and '(' in line:
56
+ import_spl = line.split(import_tag)[-1]
57
+ import_spl_clean = clean_line(line)
58
+ if not import_spl_clean.endswith(')'):
59
+ return True
60
+ return False
61
+ def clean_imports(imports,commaClean=True):
62
+ chars=["*"]
63
+ if not commaClean:
64
+ chars.append(',')
65
+ if isinstance(imports,str):
66
+ imports = imports.split(',')
67
+ return [eatElse(imp,chars=chars) for imp in imports if imp]
68
+ def get_cleaned_import_list(line,commaClean=True):
69
+ cleaned_import_list=[]
70
+ if import_tag in line:
71
+ imports = line.split(import_tag)[1]
72
+ cleaned_import_list+=clean_imports(imports,commaClean=commaClean)
73
+ return cleaned_import_list
74
+ def get_all_imports(text=None,file_path=None,import_pkg_js=None):
75
+ text = get_text_or_read(text=text,file_path=file_path)
76
+ lines = text.split('\n')
77
+ cleaned_import_list=[]
78
+ nu_lines = []
79
+ is_from_group = False
80
+ import_pkg_js = import_pkg_js or {}
81
+ if "nulines" not in import_pkg_js:
82
+ import_pkg_js["nulines"]=[]
83
+ if "file_path" not in import_pkg_js:
84
+ import_pkg_js["file_path"]=file_path
85
+ if "all_data" not in import_pkg_js:
86
+ import_pkg_js["all_data"]=[]
87
+ if file_path and file_path != import_pkg_js["file_path"]:
88
+ found=False
89
+ nu_data = {"file_path":import_pkg_js["file_path"],"nulines":import_pkg_js["nulines"]}
90
+ for i,data in enumerate(import_pkg_js["all_data"]):
91
+ if data.get('file_path') == import_pkg_js["file_path"]:
92
+ import_pkg_js["all_data"][i] = nu_data
93
+ found = True
94
+ break
95
+ if found == False:
96
+ import_pkg_js["all_data"].append(nu_data)
97
+ import_pkg_js["nulines"]=[]
98
+ import_pkg_js["file_path"]=file_path
99
+
100
+ for line in lines:
101
+ if line.startswith(import_tag) and ' from ' not in line:
102
+ cleaned_import_list = get_cleaned_import_list(line)
103
+ import_pkg_js = add_imports_to_import_pkg_js("import",cleaned_import_list,import_pkg_js=import_pkg_js)
104
+ else:
105
+ if is_from_group:
106
+ import_pkg=is_from_group
107
+ line = clean_line(line)
108
+ if line.endswith(')'):
109
+ is_from_group=False
110
+ line=line[:-1]
111
+ imports_from_import_pkg = clean_imports(line)
112
+ import_pkg_js = add_imports_to_import_pkg_js(import_pkg,imports_from_import_pkg,import_pkg_js=import_pkg_js)
113
+
114
+ else:
115
+ import_pkg_js=update_import_pkg_js(line,import_pkg_js=import_pkg_js)
116
+ if is_from_line_group(line) and is_from_group == False:
117
+ is_from_group=get_import_pkg(line)
118
+ return import_pkg_js
119
+ def clean_all_imports(text=None,file_path=None,import_pkg_js=None):
120
+ if not import_pkg_js:
121
+ import_pkg_js = get_all_imports(text=text,file_path=file_path)
122
+ nu_lines = import_pkg_js["nulines"]
123
+ for pkg,values in import_pkg_js.items():
124
+ comments = []
125
+ if pkg not in ["nulines","file_path","all_data"]:
126
+ line = values.get('line')
127
+ imports = values.get('imports')
128
+ for i,imp in enumerate(imports):
129
+ if '#' in imp:
130
+ imp_spl = imp.split('#')
131
+ comments.append(imp_spl[-1])
132
+ imports[i] = clean_line(imp_spl[0])
133
+ imports = list(set(imports))
134
+ if '*' in imports:
135
+ imports="*"
136
+ else:
137
+ imports=','.join(imports)
138
+ if comments:
139
+ comments=','.join(comments)
140
+ imports+=f" #{comments}"
141
+ import_pkg_js[pkg]["imports"]=imports
142
+ nu_lines[line] += imports
143
+ import_pkg_js["nulines"]=nu_lines
144
+ return import_pkg_js
145
+
146
+ def get_all_real_imps(file):
147
+ contents = read_from_file(file)
148
+ lines = contents.split('\n')
149
+ for line in lines:
150
+ if line.startswith('from '):
151
+ from_line = line.split('from ')[-1]
152
+ dot_fro = ""
153
+ dirname = file
154
+ for char in from_line:
155
+ if char != '.':
156
+ line = f"from {dot_fro}{eatAll(from_line,'.')}"
157
+ if line in all_imps:
158
+ line = ""
159
+ break
160
+ if dot_fro == "":
161
+ dot_fro = ""
162
+ dirname = os.path.dirname(dirname)
163
+ dirbase = os.path.basename(dirname)
164
+ dot_fro = f"{dirbase}.{dot_fro}"
165
+ if line:
166
+ all_imps.append(line)
167
+
168
+ return '\n'.join(all_imps)
169
+ def save_cleaned_imports(text=None,file_path=None,write=False,import_pkg_js=None):
170
+ import_pkg_js=get_all_imports(text=text,file_path=file_path,import_pkg_js=import_pkg_js)
171
+ import_pkg_js = clean_all_imports(text=text,file_path=file_path,import_pkg_js=import_pkg_js)
172
+ contents = '\n'.join(import_pkg_js["nulines"])
173
+ if file_path and write:
174
+ write_to_file(contents=contents,file_path=file_path)
175
+ return contents
@@ -0,0 +1,8 @@
1
+ from types import ModuleType
2
+ from typing import Iterable
3
+ from ..file_utils import get_caller_dir,get_caller_path,define_defaults,get_files_and_dirs
4
+ from ..read_write_utils import *
5
+ import textwrap, pkgutil, os, re, textwrap, sys, types, importlib, importlib.util
6
+ from typing import *
7
+ ABSPATH = os.path.abspath(__file__)
8
+ ABSROOT = os.path.dirname(ABSPATH)