This guide shows how to release a new version of rrhfoem04-lib to PyPI from Linux.
- PyPI account (and optionally a TestPyPI account)
- API token(s) created in your PyPI/TestPyPI account
- Python 3.12+
Edit pyproject.toml:
[project]
name = "rrhfoem04-lib"
version = "X.Y.Z" # <- bump thisCommit the change:
git add pyproject.toml
git commit -m "chore(release): bump version to X.Y.Z"Notes:
- PyPI rejects reusing an existing version. Always bump
X.Y.Z. - If you keep a CHANGELOG, update it here.
python3 -m pip install --upgrade build twine
rm -rf dist build ./*.egg-infopython3 -m buildThis creates source and wheel artifacts in dist/.
Optionally validate metadata:
python3 -m twine check dist/*Create a TestPyPI token and export it in your shell:
export TWINE_USERNAME="__token__"
export TWINE_PASSWORD="pypi-TEST-...your-token..."
python3 -m twine upload --repository testpypi dist/*Verify install from TestPyPI in a clean venv:
python3 -m venv .venv-test
source .venv-test/bin/activate
python3 -m pip install --index-url https://test.pypi.org/simple/ --no-deps rrhfoem04-lib==X.Y.Z
python3 -c "import rrhfoem04; print(rrhfoem04.__name__)"
deactivateUse a real PyPI token:
export TWINE_USERNAME="__token__"
export TWINE_PASSWORD="pypi-...your-token..."
python3 -m twine upload dist/*git tag -a vX.Y.Z -m "vX.Y.Z"
git push origin vX.Y.Z- 400: File already exists — You didn’t bump
version. Updatepyproject.tomland rebuild. - 403/401: Invalid credentials — Ensure the token starts with
pypi-and you used__token__as username. - README/description rendering issues —
pyproject.tomlalready pointsreadme = "README.md". - Python version constraints — This project sets
requires-python = ">=3.12"; users on older Python versions cannot install it. - Missing or extra files — Check
dist/contents and your package include rules if you customize them.
Instead of env vars, create ~/.pypirc:
[pypi]
username = __token__
password = pypi-...your-token...
[testpypi]
repository = https://test.pypi.org/legacy/
username = __token__
password = pypi-TEST-...your-token...Then upload without exporting env vars:
python3 -m twine upload dist/*