python-package-folder 1.2.3__tar.gz → 1.3.0__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 (41) hide show
  1. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/PKG-INFO +1 -1
  2. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/src/python_package_folder/manager.py +1 -0
  3. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/src/python_package_folder/publisher.py +12 -4
  4. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/tests/test_publisher.py +33 -3
  5. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/.copier-answers.yml +0 -0
  6. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/.cursor/rules/general.mdc +0 -0
  7. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/.cursor/rules/python.mdc +0 -0
  8. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/.github/workflows/ci.yml +0 -0
  9. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/.github/workflows/publish.yml +0 -0
  10. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/.gitignore +0 -0
  11. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/.vscode/settings.json +0 -0
  12. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/LICENSE +0 -0
  13. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/Makefile +0 -0
  14. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/README.md +0 -0
  15. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/coverage.svg +0 -0
  16. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/development.md +0 -0
  17. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/installation.md +0 -0
  18. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/publishing.md +0 -0
  19. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/pyproject.toml +0 -0
  20. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/src/python_package_folder/__init__.py +0 -0
  21. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/src/python_package_folder/__main__.py +0 -0
  22. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/src/python_package_folder/analyzer.py +0 -0
  23. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/src/python_package_folder/finder.py +0 -0
  24. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/src/python_package_folder/py.typed +0 -0
  25. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/src/python_package_folder/python_package_folder.py +0 -0
  26. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/src/python_package_folder/subfolder_build.py +0 -0
  27. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/src/python_package_folder/types.py +0 -0
  28. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/src/python_package_folder/utils.py +0 -0
  29. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/src/python_package_folder/version.py +0 -0
  30. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/tests/folder_structure/some_globals.py +0 -0
  31. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/tests/folder_structure/subfolder_to_build/README.md +0 -0
  32. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/tests/folder_structure/subfolder_to_build/some_function.py +0 -0
  33. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/tests/folder_structure/utility_folder/_SS/some_superseded_file.py +0 -0
  34. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/tests/folder_structure/utility_folder/some_utility.py +0 -0
  35. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/tests/test_build_with_external_deps.py +0 -0
  36. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/tests/test_linting.py +0 -0
  37. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/tests/test_subfolder_build.py +0 -0
  38. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/tests/test_utils.py +0 -0
  39. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/tests/test_version_manager.py +0 -0
  40. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/tests/tests.py +0 -0
  41. {python_package_folder-1.2.3 → python_package_folder-1.3.0}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-package-folder
3
- Version: 1.2.3
3
+ Version: 1.3.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>
@@ -677,6 +677,7 @@ class BuildManager:
677
677
  # Determine package name and version for filtering
678
678
  publish_package_name = None
679
679
  publish_version = version
680
+ publish_package_name = None
680
681
  is_subfolder_build = self._is_subfolder_build()
681
682
 
682
683
  if is_subfolder_build:
@@ -201,13 +201,21 @@ class Publisher:
201
201
  # Handle .tar.gz files
202
202
  stem = stem[:-4] # Remove .tar
203
203
 
204
- # Check if filename starts with any name variant followed by version
204
+ # Check if filename matches any name variant with exact version
205
205
  matches = False
206
206
  for name_variant in name_variants:
207
207
  # Pattern: {name}-{version} or {name}-{version}-{tag}
208
- if stem.startswith(f"{name_variant}-{version_str}"):
209
- matches = True
210
- break
208
+ # Use exact match: must start with name-version and next char (if any) must be - or end of string
209
+ expected_prefix = f"{name_variant}-{version_str}"
210
+ if stem.startswith(expected_prefix):
211
+ # Ensure exact version match (not a longer version like 1.0.10 matching 1.0.1)
212
+ # Check that after the version, we have either:
213
+ # - End of string (for source dists: name-version)
214
+ # - A hyphen followed by more characters (for wheels: name-version-tag)
215
+ remaining = stem[len(expected_prefix) :]
216
+ if not remaining or remaining.startswith("-"):
217
+ matches = True
218
+ break
211
219
 
212
220
  if matches:
213
221
  dist_files.append(f)
@@ -19,6 +19,9 @@ def test_dist_dir(tmp_path: Path) -> Path:
19
19
  # Create some distribution files
20
20
  (dist_dir / "package-1.0.0-py3-none-any.whl").write_text("fake wheel")
21
21
  (dist_dir / "package-1.0.0.tar.gz").write_text("fake source")
22
+ (dist_dir / "package-1.0.1-py3-none-any.whl").write_text("fake wheel")
23
+ (dist_dir / "package-1.0.1.tar.gz").write_text("fake source")
24
+ (dist_dir / "package-1.0.10-py3-none-any.whl").write_text("fake wheel")
22
25
  (dist_dir / "other-package-2.0.0-py3-none-any.whl").write_text("fake wheel")
23
26
 
24
27
  return dist_dir
@@ -125,6 +128,30 @@ class TestPublisher:
125
128
  assert all("package-1.0.0" in str(f) for f in file_args)
126
129
  assert not any("other-package" in str(f) for f in file_args)
127
130
 
131
+ def test_publish_filters_exact_version(self, test_dist_dir: Path) -> None:
132
+ """Test that publish filters files by exact version (not partial matches)."""
133
+ publisher = Publisher(
134
+ repository=Repository.PYPI,
135
+ dist_dir=test_dist_dir,
136
+ package_name="package",
137
+ version="1.0.1",
138
+ )
139
+
140
+ with patch("python_package_folder.publisher.subprocess.run") as mock_run:
141
+ mock_run.return_value = MagicMock(returncode=0)
142
+
143
+ with patch.object(publisher, "_get_credentials", return_value=("user", "pass")):
144
+ publisher.publish()
145
+
146
+ call_args = mock_run.call_args[0][0]
147
+ file_args = [arg for arg in call_args if str(test_dist_dir) in str(arg)]
148
+
149
+ # Should only include 1.0.1 files, not 1.0.0 or 1.0.10
150
+ assert all("1.0.1" in str(f) for f in file_args)
151
+ assert not any("1.0.0" in str(f) for f in file_args)
152
+ assert not any("1.0.10" in str(f) for f in file_args)
153
+ assert len(file_args) == 2 # wheel and source dist
154
+
128
155
  def test_publish_filters_by_version(self, test_dist_dir: Path) -> None:
129
156
  """Test that publish filters files by version."""
130
157
  publisher = Publisher(
@@ -143,8 +170,11 @@ class TestPublisher:
143
170
  call_args = mock_run.call_args[0][0]
144
171
  file_args = [arg for arg in call_args if str(test_dist_dir) in str(arg)]
145
172
 
146
- # Should only include 1.0.0 files, not 2.0.0
173
+ # Should only include 1.0.0 files, not 1.0.1, 1.0.10, or 2.0.0
147
174
  assert all("1.0.0" in str(f) for f in file_args)
175
+ assert not any("1.0.1" in str(f) for f in file_args)
176
+ assert not any("1.0.10" in str(f) for f in file_args)
177
+ assert not any("2.0.0" in str(f) for f in file_args)
148
178
 
149
179
  def test_publish_no_filtering(self, test_dist_dir: Path) -> None:
150
180
  """Test that publish includes all files when no filter specified."""
@@ -162,8 +192,8 @@ class TestPublisher:
162
192
  call_args = mock_run.call_args[0][0]
163
193
  file_args = [arg for arg in call_args if str(test_dist_dir) in str(arg)]
164
194
 
165
- # Should include all distribution files
166
- assert len(file_args) == 3
195
+ # Should include all distribution files (6 files: 4 wheels + 2 source dists)
196
+ assert len(file_args) == 6
167
197
 
168
198
  def test_publish_raises_when_no_files(self, tmp_path: Path) -> None:
169
199
  """Test that publish raises when no distribution files found."""