python-package-folder 3.0.1__py3-none-any.whl → 3.1.0__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.
- python_package_folder/manager.py +43 -0
- python_package_folder/subfolder_build.py +88 -0
- {python_package_folder-3.0.1.dist-info → python_package_folder-3.1.0.dist-info}/METADATA +1 -1
- {python_package_folder-3.0.1.dist-info → python_package_folder-3.1.0.dist-info}/RECORD +7 -7
- {python_package_folder-3.0.1.dist-info → python_package_folder-3.1.0.dist-info}/WHEEL +0 -0
- {python_package_folder-3.0.1.dist-info → python_package_folder-3.1.0.dist-info}/entry_points.txt +0 -0
- {python_package_folder-3.0.1.dist-info → python_package_folder-3.1.0.dist-info}/licenses/LICENSE +0 -0
python_package_folder/manager.py
CHANGED
|
@@ -339,6 +339,13 @@ class BuildManager:
|
|
|
339
339
|
shutil.copy2(source, target)
|
|
340
340
|
self.copied_files.append(target)
|
|
341
341
|
print(f"Copied external file: {source} -> {target}")
|
|
342
|
+
# If copying a Python file, ensure parent directory has __init__.py
|
|
343
|
+
# This helps type checkers resolve imports correctly
|
|
344
|
+
if source.suffix == ".py" and target.parent != self.src_dir:
|
|
345
|
+
init_file = target.parent / "__init__.py"
|
|
346
|
+
if not init_file.exists():
|
|
347
|
+
init_file.write_text("", encoding="utf-8")
|
|
348
|
+
self.copied_files.append(init_file)
|
|
342
349
|
elif source.is_dir():
|
|
343
350
|
if target.exists():
|
|
344
351
|
shutil.rmtree(target)
|
|
@@ -354,6 +361,8 @@ class BuildManager:
|
|
|
354
361
|
Copy a directory tree, excluding certain patterns.
|
|
355
362
|
|
|
356
363
|
Excludes directories matching patterns like _SS, __SS, _sandbox, etc.
|
|
364
|
+
Ensures __init__.py files exist in directories containing Python files
|
|
365
|
+
so that type checkers can resolve imports correctly.
|
|
357
366
|
|
|
358
367
|
Args:
|
|
359
368
|
src: Source directory
|
|
@@ -385,6 +394,9 @@ class BuildManager:
|
|
|
385
394
|
# Create destination directory
|
|
386
395
|
dst.mkdir(parents=True, exist_ok=True)
|
|
387
396
|
|
|
397
|
+
has_python_files = False
|
|
398
|
+
copied_python_files = []
|
|
399
|
+
|
|
388
400
|
# Copy files and subdirectories, excluding patterns
|
|
389
401
|
for item in src.iterdir():
|
|
390
402
|
if should_exclude(item):
|
|
@@ -395,8 +407,39 @@ class BuildManager:
|
|
|
395
407
|
|
|
396
408
|
if src_item.is_file():
|
|
397
409
|
shutil.copy2(src_item, dst_item)
|
|
410
|
+
if src_item.suffix == ".py":
|
|
411
|
+
has_python_files = True
|
|
412
|
+
copied_python_files.append(dst_item)
|
|
398
413
|
elif src_item.is_dir():
|
|
399
414
|
self._copytree_excluding(src_item, dst_item)
|
|
415
|
+
# Check if the subdirectory has Python files
|
|
416
|
+
if any(dst_item.rglob("*.py")):
|
|
417
|
+
has_python_files = True
|
|
418
|
+
|
|
419
|
+
# Ensure __init__.py exists in directories containing Python files
|
|
420
|
+
# This is needed for type checkers to resolve imports correctly
|
|
421
|
+
# Also ensure all parent directories in the path have __init__.py
|
|
422
|
+
if has_python_files:
|
|
423
|
+
init_file = dst / "__init__.py"
|
|
424
|
+
if not init_file.exists():
|
|
425
|
+
# Create an empty __init__.py file
|
|
426
|
+
init_file.write_text("", encoding="utf-8")
|
|
427
|
+
self.copied_files.append(init_file)
|
|
428
|
+
|
|
429
|
+
# Ensure all parent directories up to src_dir also have __init__.py
|
|
430
|
+
# This helps type checkers resolve nested imports like:
|
|
431
|
+
# from empty_drawing_detection.models.Information_extraction._shared_ie.ie_enums import ...
|
|
432
|
+
current = dst
|
|
433
|
+
while current != self.src_dir and current.is_relative_to(self.src_dir):
|
|
434
|
+
parent_init = current.parent / "__init__.py"
|
|
435
|
+
if (
|
|
436
|
+
parent_init.parent != self.src_dir
|
|
437
|
+
and not parent_init.exists()
|
|
438
|
+
and any(current.parent.rglob("*.py"))
|
|
439
|
+
):
|
|
440
|
+
parent_init.write_text("", encoding="utf-8")
|
|
441
|
+
self.copied_files.append(parent_init)
|
|
442
|
+
current = current.parent
|
|
400
443
|
|
|
401
444
|
def _get_package_name_from_import(self, module_name: str) -> str | None:
|
|
402
445
|
"""
|
|
@@ -140,7 +140,9 @@ class SubfolderBuildConfig:
|
|
|
140
140
|
lines = content.split("\n")
|
|
141
141
|
result = []
|
|
142
142
|
in_hatch_build = False
|
|
143
|
+
in_hatch_build_section = False
|
|
143
144
|
packages_set = False
|
|
145
|
+
paths_exclude_set = False
|
|
144
146
|
|
|
145
147
|
for line in lines:
|
|
146
148
|
# Detect hatch build section
|
|
@@ -148,6 +150,10 @@ class SubfolderBuildConfig:
|
|
|
148
150
|
in_hatch_build = True
|
|
149
151
|
result.append(line)
|
|
150
152
|
continue
|
|
153
|
+
elif line.strip().startswith("[tool.hatch.build]"):
|
|
154
|
+
in_hatch_build_section = True
|
|
155
|
+
result.append(line)
|
|
156
|
+
continue
|
|
151
157
|
elif line.strip().startswith("[") and in_hatch_build:
|
|
152
158
|
# End of hatch build section, add packages if not set
|
|
153
159
|
if not packages_set and correct_packages_path:
|
|
@@ -155,6 +161,15 @@ class SubfolderBuildConfig:
|
|
|
155
161
|
result.append(f"packages = [{packages_str}]")
|
|
156
162
|
in_hatch_build = False
|
|
157
163
|
result.append(line)
|
|
164
|
+
elif line.strip().startswith("[") and in_hatch_build_section:
|
|
165
|
+
# End of hatch build section
|
|
166
|
+
in_hatch_build_section = False
|
|
167
|
+
result.append(line)
|
|
168
|
+
elif in_hatch_build_section:
|
|
169
|
+
# Track if paths-exclude already exists
|
|
170
|
+
if re.match(r"^\s*paths-exclude\s*=", line):
|
|
171
|
+
paths_exclude_set = True
|
|
172
|
+
result.append(line)
|
|
158
173
|
elif in_hatch_build:
|
|
159
174
|
# Modify packages path if found
|
|
160
175
|
if re.match(r"^\s*packages\s*=", line):
|
|
@@ -194,6 +209,43 @@ class SubfolderBuildConfig:
|
|
|
194
209
|
packages_str = f'"{correct_packages_path}"'
|
|
195
210
|
result.append(f"packages = [{packages_str}]")
|
|
196
211
|
|
|
212
|
+
# Add file exclusion patterns to prevent including non-package files
|
|
213
|
+
# Only add if paths-exclude wasn't already set (we merged it above)
|
|
214
|
+
if not paths_exclude_set:
|
|
215
|
+
result.append("")
|
|
216
|
+
result.append("[tool.hatch.build]")
|
|
217
|
+
result.append("paths-exclude = [")
|
|
218
|
+
result.append(' ".cursor/**",')
|
|
219
|
+
result.append(' ".github/**",')
|
|
220
|
+
result.append(' ".vscode/**",')
|
|
221
|
+
result.append(' ".idea/**",')
|
|
222
|
+
result.append(' "data/**",')
|
|
223
|
+
result.append(' "docs/**",')
|
|
224
|
+
result.append(' "references/**",')
|
|
225
|
+
result.append(' "reports/**",')
|
|
226
|
+
result.append(' "scripts/**",')
|
|
227
|
+
result.append(' "tests/**",')
|
|
228
|
+
result.append(' "test/**",')
|
|
229
|
+
result.append(' "dist/**",')
|
|
230
|
+
result.append(' "build/**",')
|
|
231
|
+
result.append(' "*.egg-info/**",')
|
|
232
|
+
result.append(' "__pycache__/**",')
|
|
233
|
+
result.append(' ".pytest_cache/**",')
|
|
234
|
+
result.append(' ".mypy_cache/**",')
|
|
235
|
+
result.append(' ".venv/**",')
|
|
236
|
+
result.append(' "venv/**",')
|
|
237
|
+
result.append(' ".git/**",')
|
|
238
|
+
result.append(' ".gitignore",')
|
|
239
|
+
result.append(' ".gitattributes",')
|
|
240
|
+
result.append(' "Dockerfile",')
|
|
241
|
+
result.append(' ".dockerignore",')
|
|
242
|
+
result.append(' ".pylintrc",')
|
|
243
|
+
result.append(' "pyrightconfig.json",')
|
|
244
|
+
result.append(' "git-filter-repo",')
|
|
245
|
+
result.append(' "pyproject.toml.original",')
|
|
246
|
+
result.append(' "README.md.backup",')
|
|
247
|
+
result.append("]")
|
|
248
|
+
|
|
197
249
|
return "\n".join(result)
|
|
198
250
|
|
|
199
251
|
def create_temp_pyproject(self) -> Path | None:
|
|
@@ -532,6 +584,42 @@ class SubfolderBuildConfig:
|
|
|
532
584
|
packages_str = ", ".join(f'"{p}"' for p in package_dirs)
|
|
533
585
|
result.append(f"packages = [{packages_str}]")
|
|
534
586
|
|
|
587
|
+
# Add file exclusion patterns to prevent including non-package files
|
|
588
|
+
# This ensures only the subfolder code is included, not project root files
|
|
589
|
+
result.append("")
|
|
590
|
+
result.append("[tool.hatch.build]")
|
|
591
|
+
result.append("paths-exclude = [")
|
|
592
|
+
result.append(' ".cursor/**",')
|
|
593
|
+
result.append(' ".github/**",')
|
|
594
|
+
result.append(' ".vscode/**",')
|
|
595
|
+
result.append(' ".idea/**",')
|
|
596
|
+
result.append(' "data/**",')
|
|
597
|
+
result.append(' "docs/**",')
|
|
598
|
+
result.append(' "references/**",')
|
|
599
|
+
result.append(' "reports/**",')
|
|
600
|
+
result.append(' "scripts/**",')
|
|
601
|
+
result.append(' "tests/**",')
|
|
602
|
+
result.append(' "test/**",')
|
|
603
|
+
result.append(' "dist/**",')
|
|
604
|
+
result.append(' "build/**",')
|
|
605
|
+
result.append(' "*.egg-info/**",')
|
|
606
|
+
result.append(' "__pycache__/**",')
|
|
607
|
+
result.append(' ".pytest_cache/**",')
|
|
608
|
+
result.append(' ".mypy_cache/**",')
|
|
609
|
+
result.append(' ".venv/**",')
|
|
610
|
+
result.append(' "venv/**",')
|
|
611
|
+
result.append(' ".git/**",')
|
|
612
|
+
result.append(' ".gitignore",')
|
|
613
|
+
result.append(' ".gitattributes",')
|
|
614
|
+
result.append(' "Dockerfile",')
|
|
615
|
+
result.append(' ".dockerignore",')
|
|
616
|
+
result.append(' ".pylintrc",')
|
|
617
|
+
result.append(' "pyrightconfig.json",')
|
|
618
|
+
result.append(' "git-filter-repo",')
|
|
619
|
+
result.append(' "pyproject.toml.original",')
|
|
620
|
+
result.append(' "README.md.backup",')
|
|
621
|
+
result.append("]")
|
|
622
|
+
|
|
535
623
|
# Add dependency group if specified
|
|
536
624
|
if dependency_group:
|
|
537
625
|
# Find where to insert dependency-groups section
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python-package-folder
|
|
3
|
-
Version: 3.0
|
|
3
|
+
Version: 3.1.0
|
|
4
4
|
Summary: Python package to automatically package and build a folder, fetching all relevant dependencies.
|
|
5
5
|
Project-URL: Repository, https://github.com/alelom/python-package-folder
|
|
6
6
|
Author-email: Alessio Lombardi <work@alelom.com>
|
|
@@ -2,16 +2,16 @@ python_package_folder/__init__.py,sha256=DQt-uldOEKfh0MUqCvKdeNKOnpuOvpb7blYvXMy
|
|
|
2
2
|
python_package_folder/__main__.py,sha256=a-__-VLhYw-J7S7CsHdhtEvQr3RiAZxiYDvKhKTgMX4,291
|
|
3
3
|
python_package_folder/analyzer.py,sha256=cmTNUDCWBIh3XZ_mShlQVG1P9NN_oe3FUBTirVtYfTQ,16709
|
|
4
4
|
python_package_folder/finder.py,sha256=RPidZ7LKCFuQ_KgCFIZdHWPXsZIDor3M4C0hKeYW7EI,11799
|
|
5
|
-
python_package_folder/manager.py,sha256=
|
|
5
|
+
python_package_folder/manager.py,sha256=kyULmS948uW3yWUcabc2EVK_Nic3wrWMj8qCs18jj2Q,43526
|
|
6
6
|
python_package_folder/publisher.py,sha256=TSjdOvxvnWLbJCnduTK_xZBRfvsrq9kpEH-sfebeWkU,13507
|
|
7
7
|
python_package_folder/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
8
|
python_package_folder/python_package_folder.py,sha256=RPsqRcIy_LjzzTHdp4qdtFJ4-4xhtR_0YLIC0RlUxFo,8841
|
|
9
|
-
python_package_folder/subfolder_build.py,sha256=
|
|
9
|
+
python_package_folder/subfolder_build.py,sha256=m9a7exvDEwtz_tuNlPF_bagXtcwNq9PHiJswVkbn2PM,39866
|
|
10
10
|
python_package_folder/types.py,sha256=3yeSRR5p_3PDKEAaehW_RJ7NwJHexOIeA08bGaT1iSY,2368
|
|
11
11
|
python_package_folder/utils.py,sha256=lIkWsFKeAYAJ9TDUM99T4pUBHJVbUvCdUgkWQN-LUho,3111
|
|
12
12
|
python_package_folder/version.py,sha256=kIDP6S9trEfs9gj7lBYGxrWm4RPssRla24UtlO9Jkh4,9111
|
|
13
|
-
python_package_folder-3.0.
|
|
14
|
-
python_package_folder-3.0.
|
|
15
|
-
python_package_folder-3.0.
|
|
16
|
-
python_package_folder-3.0.
|
|
17
|
-
python_package_folder-3.0.
|
|
13
|
+
python_package_folder-3.1.0.dist-info/METADATA,sha256=qNQ9k_yP2w7Tyxo6F8btfZRCckzheWU4HN78ETtGpaY,33282
|
|
14
|
+
python_package_folder-3.1.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
15
|
+
python_package_folder-3.1.0.dist-info/entry_points.txt,sha256=ttu4wAhoYSHGhWQNercLz9IVTTpXxhVlRA9vSTvaLe0,91
|
|
16
|
+
python_package_folder-3.1.0.dist-info/licenses/LICENSE,sha256=vNgRJh8YiecqZoZld7TtwPI5I72HIymKD9g32fiJjCE,1073
|
|
17
|
+
python_package_folder-3.1.0.dist-info/RECORD,,
|
|
File without changes
|
{python_package_folder-3.0.1.dist-info → python_package_folder-3.1.0.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{python_package_folder-3.0.1.dist-info → python_package_folder-3.1.0.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|