Register a separate TestPyPI account, upload your build with twine upload --repository testpypi dist/*, then install it into a clean virtual environment using TestPyPI as the index. This rehearses the real release without touching PyPI. Mind the dependency trap described below.
What TestPyPI is
TestPyPI is a separate instance of the Python Package Index at test.pypi.org, meant for trying out distribution tools and processes without affecting the real index. It has its own database, so your PyPI login does not work there. The packaging guide also notes the database may be periodically pruned, so accounts and packages can disappear.
Steps
- Register at TestPyPI with a separate account and verify your email.
- Create an API token on TestPyPI. The tutorial walks through setting one up, and notes you only see the token once.
- Build with
python -m build. - Check with
twine check dist/*. - Upload.
python3 -m twine upload --repository testpypi dist/*
- Install in a clean environment.
python3 -m pip install --index-url https://test.pypi.org/simple/ --no-deps your-package
- Import and run a small test.
The dependency trap
The tutorial uses --no-deps for a reason. TestPyPI does not have the same packages as the real index, so installing dependencies from it may fail or fetch something unexpected. If your library has dependencies and you want to test the full install, the guide says to add the real index as an extra.
python3 -m pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ your-package
Be careful with this form. Mixing two indexes is how a test install can pull in something unexpected, which is the risk the tutorial warns about. For a hygienic rehearsal, install dependencies first from the real index, then install your package with --no-deps from TestPyPI.
Version numbers
TestPyPI follows the same filename rules as PyPI, so you cannot upload the same filename twice. Use a development or pre release version for rehearsals, such as a dev suffix, and keep your real version number for the real upload. The version specifiers spec describes dev, alpha, beta and release candidate segments.
What a rehearsal catches
- A README that fails to render.
- Missing files in the wheel.
- Wrong metadata, such as a missing Requires-Python.
- A broken entry point for a command line tool.
- Publishing workflow permission errors, if you use a trusted publisher on TestPyPI.
Rehearse the automation, not just the files
The packaging guide for GitHub Actions configures two trusted publishers, one for TestPyPI and one for PyPI, and uses separate environments named for each. That lets CI exercise the same workflow end to end. Our trusted publisher setup steps cover the mechanics.
Safeguard's SBOM and dependency scanning can be part of the same rehearsal. A free scan on the built project is an easy start.
Quick check
Do my PyPI credentials work on TestPyPI?
No. The two services have separate databases, so you need a separate account and token for TestPyPI.
Why does the tutorial use no-deps?
TestPyPI does not carry the same packages as PyPI, so installing dependencies from it can fail or pick up something unexpected.
Can I reuse a version I tested on TestPyPI?
On the real PyPI, yes, because it is a different index. Use a distinct pre release version for rehearsals to avoid confusion.
Sources
- Using TestPyPI, Python Packaging User Guide
- Packaging Python Projects, Python Packaging User Guide
- Publishing with GitHub Actions, Python Packaging User Guide
- Version specifiers, Python Packaging User Guide
Last reviewed: 19 October 2026.