How to Mock Twine Upload to TestPyPI in Python

Simulate a twine upload to TestPyPI with a dry-run mock function that validates distribution files and prints the intended upload action without any network call.

Easy Python 3.9+ Aug 9, 2026 Modern tooling 12 views 0 copies

Python code

15 lines
Python 3.9+
import subprocess
import sys

# Mock twine upload to TestPyPI using subprocess dry-run
def mock_twine_upload(dist_file: str, repo_url: str = "https://test.pypi.org/legacy/") -> None:
    """Simulate twine upload by checking dist file and printing intended action."""
    if not dist_file.endswith((".whl", ".tar.gz")):
        raise ValueError(f"Invalid distribution file: {dist_file}. Must be .whl or .tar.gz")
    print(f"Checking existing distribution file: {dist_file}")
    print(f"Would upload to repository: {repo_url}")
    print(f"Running twine upload --repository-url {repo_url} {dist_file}")
    print("Mock upload successful (no actual network call performed)")

if __name__ == "__main__":
    mock_twine_upload("dist/mypackage-0.1.0-py3-none-any.whl")

Output

stdout
Checking existing distribution file: dist/mypackage-0.1.0-py3-none-any.whl
Would upload to repository: https://test.pypi.org/legacy/
Running twine upload --repository-url https://test.pypi.org/legacy/ dist/mypackage-0.1.0-py3-none-any.whl
Mock upload successful (no actual network call performed)

How it works

The function mock_twine_upload validates that the distribution file ends with a wheel or source archive extension, raising a ValueError otherwise. It then prints the would-be twine command and repository URL, mimicking the upload flow without touching the network. This is useful in CI pipelines or local testing to confirm packaging output before actually publishing. The __main__ guard runs the mock against a sample wheel file, demonstrating the expected output exactly.

Common mistakes

  • Forgetting to escape f-string braces when printing the twine command
  • Not checking the file extension before mocking the upload
  • Assuming the mock actually uploads — it only simulates the dry-run

Variations

  1. Use `--dry-run` with actual twine if available to avoid network calls
  2. Wrap the mock with a CLI parser like argparse to accept dist paths dynamically

Real-world use cases

  • Verify package build output in CI before triggering an actual PyPI publish.
  • Test package publishing scripts locally without hitting the real test server.
  • Simulate release workflows in feature branches to catch filename or repo misconfigurations.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Modern tooling

Related tutorials and quizzes for this topic.