We are happy you have decided to contribute to twine.

Please see the GitHub repository for code and more documentation, and the official Python Packaging User Guide for user documentation. You can also join #pypa or #pypa-dev on Freenode, or the pypa-dev mailing list, to ask questions or get involved.

Getting started

We recommend you use a development environment. Using a virtualenv keeps your development environment isolated, so twine and its dependencies do not interfere with other packages installed on your machine. You can use virtualenv or pipenv to isolate your development environment.

Clone the twine repository from GitHub, and then make and activate a virtual environment that uses Python 3.6 or newer as the default Python. Example:

mkvirtualenv -p /usr/bin/python3.7 twine

Then, run the following command:

pip install -e /path/to/your/local/twine

Now, in your virtual environment, twine is pointing at your local copy, so when you make changes, you can easily see their effect.

Building the documentation

Additions and edits to twine’s documentation are welcome and appreciated.

We use tox to build docs. Activate your virtual environment, then install tox.

pip install tox

If you are using pipenv to manage your virtual environment, you may need the tox-pipenv plugin so that tox can use pipenv environments instead of virtualenvs.

After making docs changes, lint and build the docs locally, using tox, before making a pull request. Activate your virtual environment, then, in the root directory, run:

tox -e docs

The HTML of the docs will be visible in twine/docs/_build/.


Tests with twine are run using tox, and tested against Python versions 3.6, 3.7, and 3.8. To run these tests locally, you will need to have these versions of Python installed on your machine.

Either use tox to build against all supported Python versions (if you have them installed) or use tox -e py{version} to test against a specific version, e.g., tox -e py36 or tox -e py37.

Also, always run tox -e lint before submitting a pull request.

Submitting changes

  1. Fork the GitHub repository.
  2. Make a branch off of master and commit your changes to it.
  3. Run the tests with tox and lint any docs changes with tox -e docs.
  4. Ensure that your name is added to the end of the AUTHORS file using the format Name <> (url), where the (url) portion is optional.
  5. Submit a pull request to the master branch on GitHub.

Architectural overview

Twine is a command-line tool for interacting with PyPI securely over HTTPS. Its three purposes are to be:

  1. A user-facing tool for publishing on
  2. A user-facing tool for publishing on other Python package indexes (e.g., devpi instances)
  3. A useful API for other programs (e.g., zest.releaser) to call for publishing on any Python package index

Currently, twine has two principle functions: uploading new packages and registering new projects (register is no longer supported on PyPI, and is in Twine for use with other package indexes).

Its command line arguments are parsed in twine/ The code for registering new projects is in twine/commands/, and the code for uploading is in twine/commands/ The file twine/ contains a single class, PackageFile, which hashes the project files and extracts their metadata. The file twine/ contains the Repository class, whose methods control the URL the package is uploaded to (which the user can specify either as a default, in the .pypirc file, or pass on the command line), and the methods that upload the package securely to a URL.

Where Twine gets configuration and credentials

A user can set the repository URL, username, and/or password via command line, .pypirc files, environment variables, and keyring.

Adding a maintainer

A checklist for adding a new maintainer to the project.

  1. Add them as a Member in the GitHub repo settings. (This will also give them privileges on the Travis CI project.)
  2. Get them Test PyPI and canon PyPI usernames and add them as a Maintainer on our Test PyPI project and canon PyPI.

Making a new release

A checklist for creating, testing, and distributing a new version.

  1. Choose a version number, e.g. “1.15.0”
  2. Update the changelog:
    1. Add missing changes to docs/changelog.rst.
    2. Add a release line at the beginning referencing the release and the date of the release.
    3. Commit, push, ensure Travis build passes.
  3. Create a new git tag with git tag -m tag {number}.
  4. Push the new tag: git push upstream {number}.
  5. Watch the release in Travis.
  6. Send announcement email to pypa-dev mailing list and celebrate.

Future development

See our open issues.

In the future, pip and twine may merge into a single tool; see ongoing discussion.