python-package-folder 5.1.4__tar.gz → 5.1.5__tar.gz

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.
Files changed (60) hide show
  1. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/PKG-INFO +1 -1
  2. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/coverage.svg +2 -2
  3. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/pyproject.toml +1 -1
  4. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/src/python_package_folder/subfolder_build.py +38 -27
  5. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/tests/test_exclude_patterns.py +56 -0
  6. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/.copier-answers.yml +0 -0
  7. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/.cursor/plans/optional_version_+_semantic-release_efed88a6.plan.md +0 -0
  8. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/.cursor/plans/replace_node.js_semantic-release_with_custom_python_implementation_64e05e1a.plan.md +0 -0
  9. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/.cursor/rules/general.mdc +0 -0
  10. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/.cursor/rules/python.mdc +0 -0
  11. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/.github/workflows/ci.yml +0 -0
  12. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/.github/workflows/publish.yml +0 -0
  13. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/.gitignore +0 -0
  14. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/.vscode/settings.json +0 -0
  15. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/LICENSE +0 -0
  16. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/MANIFEST.in +0 -0
  17. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/Makefile +0 -0
  18. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/README.md +0 -0
  19. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/development.md +0 -0
  20. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/docs/DEVELOPMENT.md +0 -0
  21. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/docs/INSTALLATION.md +0 -0
  22. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/docs/PUBLISHING.md +0 -0
  23. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/docs/REFERENCE.md +0 -0
  24. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/docs/USAGE.md +0 -0
  25. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/docs/VERSION_RESOLUTION.md +0 -0
  26. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/installation.md +0 -0
  27. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/publishing.md +0 -0
  28. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/src/python_package_folder/__init__.py +0 -0
  29. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/src/python_package_folder/__main__.py +0 -0
  30. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/src/python_package_folder/analyzer.py +0 -0
  31. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/src/python_package_folder/finder.py +0 -0
  32. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/src/python_package_folder/manager.py +0 -0
  33. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/src/python_package_folder/publisher.py +0 -0
  34. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/src/python_package_folder/py.typed +0 -0
  35. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/src/python_package_folder/python_package_folder.py +0 -0
  36. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/src/python_package_folder/types.py +0 -0
  37. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/src/python_package_folder/utils.py +0 -0
  38. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/src/python_package_folder/version.py +0 -0
  39. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/src/python_package_folder/version_calculator.py +0 -0
  40. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/tests/conftest.py +0 -0
  41. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/tests/folder_structure/some_globals.py +0 -0
  42. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/tests/folder_structure/subfolder_to_build/README.md +0 -0
  43. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/tests/folder_structure/subfolder_to_build/__init__.py +0 -0
  44. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/tests/folder_structure/subfolder_to_build/some_function.py +0 -0
  45. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/tests/folder_structure/subfolder_to_build/some_globals.py +0 -0
  46. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/tests/folder_structure/utility_folder/_SS/some_superseded_file.py +0 -0
  47. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/tests/folder_structure/utility_folder/some_utility.py +0 -0
  48. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/tests/test_build_with_external_deps.py +0 -0
  49. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/tests/test_linting.py +0 -0
  50. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/tests/test_preserve_directory_structure.py +0 -0
  51. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/tests/test_publisher.py +0 -0
  52. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/tests/test_shared_subdirectory_imports.py +0 -0
  53. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/tests/test_spreadsheet_creation_imports.py +0 -0
  54. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/tests/test_subfolder_build.py +0 -0
  55. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/tests/test_third_party_dependencies.py +0 -0
  56. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/tests/test_utils.py +0 -0
  57. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/tests/test_version_calculator.py +0 -0
  58. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/tests/test_version_manager.py +0 -0
  59. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/tests/tests.py +0 -0
  60. {python_package_folder-5.1.4 → python_package_folder-5.1.5}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-package-folder
3
- Version: 5.1.4
3
+ Version: 5.1.5
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>
@@ -14,7 +14,7 @@
14
14
  <g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
15
15
  <text x="31.5" y="15" fill="#010101" fill-opacity=".3">coverage</text>
16
16
  <text x="31.5" y="14">coverage</text>
17
- <text x="81" y="15" fill="#010101" fill-opacity=".3">66%</text>
18
- <text x="81" y="14">66%</text>
17
+ <text x="81" y="15" fill="#010101" fill-opacity=".3">68%</text>
18
+ <text x="81" y="14">68%</text>
19
19
  </g>
20
20
  </svg>
@@ -43,7 +43,7 @@ dependencies = [
43
43
 
44
44
  # ---- Dev dependencies ----
45
45
 
46
- version = "5.1.4"
46
+ version = "5.1.5"
47
47
  [dependency-groups]
48
48
  dev = [
49
49
  "pytest>=8.3.5",
@@ -694,44 +694,55 @@ class SubfolderBuildConfig:
694
694
  # Usually after [dependency-groups] or at the end
695
695
  insert_index = len(result)
696
696
  tool_section_exists = False
697
+ tool_section_start = -1
698
+ tool_section_end = -1
699
+
700
+ # First, search specifically for [tool.python-package-folder]
697
701
  for i, line in enumerate(result):
698
702
  if line.strip() == "[tool.python-package-folder]":
699
703
  tool_section_exists = True
700
- insert_index = i
701
- break
702
- elif line.strip().startswith("[tool.") and i > 0:
703
- # Insert before other tool sections
704
- insert_index = i
704
+ tool_section_start = i
705
+ # Find end of section (next [section] or end of file)
706
+ for j in range(i + 1, len(result)):
707
+ if result[j].strip().startswith("["):
708
+ tool_section_end = j
709
+ break
710
+ if tool_section_end == -1:
711
+ tool_section_end = len(result)
705
712
  break
713
+
714
+ # If not found, find a good insertion point before other [tool.*] sections
715
+ if not tool_section_exists:
716
+ for i, line in enumerate(result):
717
+ if line.strip().startswith("[tool.") and i > 0:
718
+ # Insert before other tool sections
719
+ insert_index = i
720
+ break
706
721
 
707
722
  # Format exclude patterns
708
723
  patterns_str = ", ".join(f'"{p}"' for p in exclude_patterns)
709
- exclude_lines = [
710
- "",
711
- "[tool.python-package-folder]",
712
- f'exclude-patterns = [{patterns_str}]',
713
- ]
714
724
 
715
725
  if tool_section_exists:
716
- # Replace or update existing section
717
- end_index = insert_index + 1
718
- while end_index < len(result) and not result[end_index].strip().startswith("["):
719
- end_index += 1
720
- # Check if exclude-patterns already exists
721
- has_exclude_patterns = any(
722
- "exclude-patterns" in result[i] for i in range(insert_index, end_index)
723
- )
724
- if has_exclude_patterns:
725
- # Update existing exclude-patterns line
726
- for i in range(insert_index, end_index):
727
- if "exclude-patterns" in result[i]:
728
- result[i] = f'exclude-patterns = [{patterns_str}]'
729
- break
730
- else:
731
- # Add exclude-patterns to existing section
732
- result.insert(end_index - 1, f'exclude-patterns = [{patterns_str}]')
726
+ # Update existing section
727
+ # Check if exclude-patterns already exists in the section
728
+ has_exclude_patterns = False
729
+ for i in range(tool_section_start + 1, tool_section_end):
730
+ if "exclude-patterns" in result[i]:
731
+ has_exclude_patterns = True
732
+ # Update the existing line
733
+ result[i] = f'exclude-patterns = [{patterns_str}]'
734
+ break
735
+
736
+ if not has_exclude_patterns:
737
+ # Add exclude-patterns to existing section (before the next section)
738
+ result.insert(tool_section_end, f'exclude-patterns = [{patterns_str}]')
733
739
  else:
734
740
  # Insert new section
741
+ exclude_lines = [
742
+ "",
743
+ "[tool.python-package-folder]",
744
+ f'exclude-patterns = [{patterns_str}]',
745
+ ]
735
746
  result[insert_index:insert_index] = exclude_lines
736
747
 
737
748
  return "\n".join(result)
@@ -211,4 +211,60 @@ class TestExcludePatternsInBuild:
211
211
  assert ".*_test.*" in content
212
212
  assert "sandbox" in content
213
213
 
214
+ # Verify there's only ONE [tool.python-package-folder] section (no duplicates)
215
+ sections = [line for line in content.split("\n") if line.strip() == "[tool.python-package-folder]"]
216
+ assert len(sections) == 1, f"Found {len(sections)} duplicate [tool.python-package-folder] sections"
217
+
218
+ config.restore()
219
+
220
+ def test_exclude_patterns_no_duplicate_section(self, tmp_path: Path) -> None:
221
+ """Test that exclude patterns don't create duplicate sections when original already has it."""
222
+ project_root = tmp_path / "test_project"
223
+ project_root.mkdir()
224
+
225
+ # Create pyproject.toml with existing [tool.python-package-folder] section
226
+ pyproject_content = """[project]
227
+ name = "test-package"
228
+ version = "0.1.0"
229
+
230
+ [build-system]
231
+ requires = ["hatchling"]
232
+ build-backend = "hatchling.build"
233
+
234
+ [tool.hatch.build.targets.wheel]
235
+ packages = ["src/test_package"]
236
+
237
+ [tool.python-package-folder]
238
+ exclude-patterns = ["_SS", ".*_test.*"]
239
+
240
+ [tool.pylint.'TYPECHECK']
241
+ generated-members = ["networkx.*"]
242
+ """
243
+ (project_root / "pyproject.toml").write_text(pyproject_content)
244
+
245
+ # Create source directory
246
+ src_dir = project_root / "src" / "test_package"
247
+ src_dir.mkdir(parents=True)
248
+ (src_dir / "__init__.py").write_text("")
249
+
250
+ config = SubfolderBuildConfig(
251
+ project_root=project_root,
252
+ src_dir=src_dir,
253
+ package_name="test-package",
254
+ version="1.0.0",
255
+ )
256
+
257
+ # Create temporary pyproject.toml
258
+ temp_pyproject = config.create_temp_pyproject()
259
+ assert temp_pyproject is not None
260
+
261
+ # Check that there's only ONE [tool.python-package-folder] section
262
+ content = temp_pyproject.read_text()
263
+ sections = [line for line in content.split("\n") if line.strip() == "[tool.python-package-folder]"]
264
+ assert len(sections) == 1, f"Found {len(sections)} duplicate [tool.python-package-folder] sections: {sections}"
265
+
266
+ # Verify exclude-patterns is present
267
+ assert "exclude-patterns" in content
268
+ assert "_SS" in content
269
+
214
270
  config.restore()