python-package-folder 1.2.1__tar.gz → 1.2.2__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.1 → python_package_folder-1.2.2}/PKG-INFO +18 -7
  2. {python_package_folder-1.2.1 → python_package_folder-1.2.2}/README.md +17 -6
  3. {python_package_folder-1.2.1 → python_package_folder-1.2.2}/coverage.svg +2 -2
  4. {python_package_folder-1.2.1 → python_package_folder-1.2.2}/src/python_package_folder/publisher.py +39 -34
  5. {python_package_folder-1.2.1 → python_package_folder-1.2.2}/.copier-answers.yml +0 -0
  6. {python_package_folder-1.2.1 → python_package_folder-1.2.2}/.cursor/rules/general.mdc +0 -0
  7. {python_package_folder-1.2.1 → python_package_folder-1.2.2}/.cursor/rules/python.mdc +0 -0
  8. {python_package_folder-1.2.1 → python_package_folder-1.2.2}/.github/workflows/ci.yml +0 -0
  9. {python_package_folder-1.2.1 → python_package_folder-1.2.2}/.github/workflows/publish.yml +0 -0
  10. {python_package_folder-1.2.1 → python_package_folder-1.2.2}/.gitignore +0 -0
  11. {python_package_folder-1.2.1 → python_package_folder-1.2.2}/.vscode/settings.json +0 -0
  12. {python_package_folder-1.2.1 → python_package_folder-1.2.2}/LICENSE +0 -0
  13. {python_package_folder-1.2.1 → python_package_folder-1.2.2}/Makefile +0 -0
  14. {python_package_folder-1.2.1 → python_package_folder-1.2.2}/development.md +0 -0
  15. {python_package_folder-1.2.1 → python_package_folder-1.2.2}/installation.md +0 -0
  16. {python_package_folder-1.2.1 → python_package_folder-1.2.2}/publishing.md +0 -0
  17. {python_package_folder-1.2.1 → python_package_folder-1.2.2}/pyproject.toml +0 -0
  18. {python_package_folder-1.2.1 → python_package_folder-1.2.2}/src/python_package_folder/__init__.py +0 -0
  19. {python_package_folder-1.2.1 → python_package_folder-1.2.2}/src/python_package_folder/__main__.py +0 -0
  20. {python_package_folder-1.2.1 → python_package_folder-1.2.2}/src/python_package_folder/analyzer.py +0 -0
  21. {python_package_folder-1.2.1 → python_package_folder-1.2.2}/src/python_package_folder/finder.py +0 -0
  22. {python_package_folder-1.2.1 → python_package_folder-1.2.2}/src/python_package_folder/manager.py +0 -0
  23. {python_package_folder-1.2.1 → python_package_folder-1.2.2}/src/python_package_folder/py.typed +0 -0
  24. {python_package_folder-1.2.1 → python_package_folder-1.2.2}/src/python_package_folder/python_package_folder.py +0 -0
  25. {python_package_folder-1.2.1 → python_package_folder-1.2.2}/src/python_package_folder/subfolder_build.py +0 -0
  26. {python_package_folder-1.2.1 → python_package_folder-1.2.2}/src/python_package_folder/types.py +0 -0
  27. {python_package_folder-1.2.1 → python_package_folder-1.2.2}/src/python_package_folder/utils.py +0 -0
  28. {python_package_folder-1.2.1 → python_package_folder-1.2.2}/src/python_package_folder/version.py +0 -0
  29. {python_package_folder-1.2.1 → python_package_folder-1.2.2}/tests/folder_structure/some_globals.py +0 -0
  30. {python_package_folder-1.2.1 → python_package_folder-1.2.2}/tests/folder_structure/subfolder_to_build/README.md +0 -0
  31. {python_package_folder-1.2.1 → python_package_folder-1.2.2}/tests/folder_structure/subfolder_to_build/some_function.py +0 -0
  32. {python_package_folder-1.2.1 → python_package_folder-1.2.2}/tests/folder_structure/utility_folder/_SS/some_superseded_file.py +0 -0
  33. {python_package_folder-1.2.1 → python_package_folder-1.2.2}/tests/folder_structure/utility_folder/some_utility.py +0 -0
  34. {python_package_folder-1.2.1 → python_package_folder-1.2.2}/tests/test_build_with_external_deps.py +0 -0
  35. {python_package_folder-1.2.1 → python_package_folder-1.2.2}/tests/test_linting.py +0 -0
  36. {python_package_folder-1.2.1 → python_package_folder-1.2.2}/tests/test_publisher.py +0 -0
  37. {python_package_folder-1.2.1 → python_package_folder-1.2.2}/tests/test_subfolder_build.py +0 -0
  38. {python_package_folder-1.2.1 → python_package_folder-1.2.2}/tests/test_utils.py +0 -0
  39. {python_package_folder-1.2.1 → python_package_folder-1.2.2}/tests/test_version_manager.py +0 -0
  40. {python_package_folder-1.2.1 → python_package_folder-1.2.2}/tests/tests.py +0 -0
  41. {python_package_folder-1.2.1 → python_package_folder-1.2.2}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-package-folder
3
- Version: 1.2.1
3
+ Version: 1.2.2
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>
@@ -229,8 +229,8 @@ python-package-folder --project-root /path/to/project --src-dir /path/to/src --b
229
229
  1. **Build Verification**: Ensures distribution files exist in the `dist/` directory
230
230
  2. **File Filtering**: Automatically filters distribution files to only include those matching the current package name and version (prevents uploading old artifacts)
231
231
  3. **Credential Management**:
232
- - Prompts for credentials if not provided
233
- - Uses `keyring` for secure storage (if available)
232
+ - Prompts for credentials if not provided via command-line arguments
233
+ - Credentials are not stored - you'll be prompted each time (unless provided via `--username` and `--password`)
234
234
  - Supports both username/password and API tokens
235
235
  - Auto-detects API tokens and uses `__token__` as username
236
236
  4. **Repository Configuration**: Configures the target repository (PyPI, TestPyPI, or Azure)
@@ -639,11 +639,22 @@ publisher.publish()
639
639
 
640
640
  ### Credential Storage
641
641
 
642
- The package uses the `keyring` library (if installed) to securely store credentials. Credentials are stored per repository and will be reused on subsequent runs.
642
+ **Note**: The package does not store credentials by default. Credentials must be provided via command-line arguments (`--username` and `--password`) or will be prompted each time you run the publish command. This ensures credentials are not persisted and must be entered fresh each time.
643
643
 
644
- Install keyring for secure credential storage:
645
- ```bash
646
- pip install keyring
644
+ If you previously used an older version that stored credentials in keyring, you can clear them using:
645
+
646
+ ```python
647
+ from python_package_folder import Publisher, Repository
648
+
649
+ publisher = Publisher(repository=Repository.AZURE)
650
+ publisher.clear_stored_credentials()
651
+ ```
652
+
653
+ Or manually using Python:
654
+ ```python
655
+ import keyring
656
+ keyring.delete_password("python-package-folder-azure", "username")
657
+ # Also delete the password if you know the username
647
658
  ```
648
659
 
649
660
  ## Command Line Options
@@ -209,8 +209,8 @@ python-package-folder --project-root /path/to/project --src-dir /path/to/src --b
209
209
  1. **Build Verification**: Ensures distribution files exist in the `dist/` directory
210
210
  2. **File Filtering**: Automatically filters distribution files to only include those matching the current package name and version (prevents uploading old artifacts)
211
211
  3. **Credential Management**:
212
- - Prompts for credentials if not provided
213
- - Uses `keyring` for secure storage (if available)
212
+ - Prompts for credentials if not provided via command-line arguments
213
+ - Credentials are not stored - you'll be prompted each time (unless provided via `--username` and `--password`)
214
214
  - Supports both username/password and API tokens
215
215
  - Auto-detects API tokens and uses `__token__` as username
216
216
  4. **Repository Configuration**: Configures the target repository (PyPI, TestPyPI, or Azure)
@@ -619,11 +619,22 @@ publisher.publish()
619
619
 
620
620
  ### Credential Storage
621
621
 
622
- The package uses the `keyring` library (if installed) to securely store credentials. Credentials are stored per repository and will be reused on subsequent runs.
622
+ **Note**: The package does not store credentials by default. Credentials must be provided via command-line arguments (`--username` and `--password`) or will be prompted each time you run the publish command. This ensures credentials are not persisted and must be entered fresh each time.
623
623
 
624
- Install keyring for secure credential storage:
625
- ```bash
626
- pip install keyring
624
+ If you previously used an older version that stored credentials in keyring, you can clear them using:
625
+
626
+ ```python
627
+ from python_package_folder import Publisher, Repository
628
+
629
+ publisher = Publisher(repository=Repository.AZURE)
630
+ publisher.clear_stored_credentials()
631
+ ```
632
+
633
+ Or manually using Python:
634
+ ```python
635
+ import keyring
636
+ keyring.delete_password("python-package-folder-azure", "username")
637
+ # Also delete the password if you know the username
627
638
  ```
628
639
 
629
640
  ## Command Line Options
@@ -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">68%</text>
18
- <text x="81" y="14">68%</text>
17
+ <text x="81" y="15" fill="#010101" fill-opacity=".3">67%</text>
18
+ <text x="81" y="14">67%</text>
19
19
  </g>
20
20
  </svg>
@@ -41,12 +41,15 @@ class Publisher:
41
41
  This class manages the publishing process, including credential handling
42
42
  and repository configuration. It uses twine under the hood for actual publishing.
43
43
 
44
+ Credentials are not stored - they must be provided via command-line arguments
45
+ or will be prompted each time. This ensures credentials are not persisted.
46
+
44
47
  Attributes:
45
48
  repository: Target repository for publishing
46
49
  dist_dir: Directory containing built distribution files
47
50
  repository_url: Custom repository URL (for Azure or custom PyPI servers)
48
- username: Username for authentication (optional, can be prompted)
49
- password: Password/token for authentication (optional, can be prompted)
51
+ username: Username for authentication (optional, will be prompted if not provided)
52
+ password: Password/token for authentication (optional, will be prompted if not provided)
50
53
  """
51
54
 
52
55
  def __init__(
@@ -109,8 +112,9 @@ class Publisher:
109
112
  """
110
113
  Get credentials for publishing.
111
114
 
112
- Prompts for username and password/token if not already provided.
113
- Uses keyring if available to store/retrieve credentials securely.
115
+ Always prompts for username and password/token if not already provided.
116
+ Does not use keyring to store/retrieve credentials - credentials must be
117
+ provided via command-line arguments or will be prompted each time.
114
118
 
115
119
  Returns:
116
120
  Tuple of (username, password/token)
@@ -118,24 +122,8 @@ class Publisher:
118
122
  username = self.username
119
123
  password = self.password
120
124
 
121
- # Try to get from keyring if available
122
- if keyring and not username:
123
- try:
124
- username = keyring.get_password(
125
- f"python-package-folder-{self.repository.value}", "username"
126
- )
127
- except Exception:
128
- pass
129
-
130
- if keyring and not password:
131
- try:
132
- password = keyring.get_password(
133
- f"python-package-folder-{self.repository.value}", username or "token"
134
- )
135
- except Exception:
136
- pass
137
-
138
- # Prompt if still not available
125
+ # Always prompt if not provided via command-line arguments
126
+ # We don't use keyring to avoid storing credentials
139
127
  if not username:
140
128
  username = input(f"Enter username for {self.repository.value}: ").strip()
141
129
  if not username:
@@ -160,18 +148,7 @@ class Publisher:
160
148
  )
161
149
  username = "__token__"
162
150
 
163
- # Store in keyring if available
164
- if keyring:
165
- try:
166
- keyring.set_password(
167
- f"python-package-folder-{self.repository.value}", "username", username
168
- )
169
- keyring.set_password(
170
- f"python-package-folder-{self.repository.value}", username, password
171
- )
172
- except Exception:
173
- # Keyring storage is optional, continue if it fails
174
- pass
151
+ # Do not store in keyring - credentials are not persisted
175
152
 
176
153
  return username, password
177
154
 
@@ -253,6 +230,9 @@ class Publisher:
253
230
  cmd = ["twine", "upload"]
254
231
  if skip_existing:
255
232
  cmd.append("--skip-existing")
233
+ # Always use verbose for Azure Artifacts to get better error details
234
+ if self.repository == Repository.AZURE:
235
+ cmd.append("--verbose")
256
236
  cmd.extend(["--repository-url", repo_url])
257
237
  cmd.extend(["--username", username])
258
238
  cmd.extend(["--password", password])
@@ -284,6 +264,31 @@ class Publisher:
284
264
  self.password = None
285
265
  self.publish(skip_existing=skip_existing)
286
266
 
267
+ def clear_stored_credentials(self) -> None:
268
+ """
269
+ Clear any stored credentials from keyring for this repository.
270
+
271
+ This method can be used to remove previously stored credentials.
272
+ Note: The current implementation does not store credentials, but this
273
+ method is provided for compatibility and to clear any old stored credentials.
274
+ """
275
+ if keyring:
276
+ try:
277
+ service_name = f"python-package-folder-{self.repository.value}"
278
+ # Try to get and delete stored username
279
+ stored_username = keyring.get_password(service_name, "username")
280
+ if stored_username:
281
+ try:
282
+ keyring.delete_password(service_name, stored_username)
283
+ except Exception:
284
+ pass
285
+ try:
286
+ keyring.delete_password(service_name, "username")
287
+ except Exception:
288
+ pass
289
+ except Exception:
290
+ pass
291
+
287
292
 
288
293
  def get_repository_help() -> str:
289
294
  """