Skip to content
Shantanu edited this page Oct 18, 2023 · 11 revisions

This documents the release process for mypy 1.1 and later releases.

Release process

We aim to publish a mypy feature release roughly once per month (but this is not strict).

This is a very short summary of the mypy release process:

  • A release manager (RM) is selected to oversee the release process of a feature release and the related point releases.
  • The RM creates a release planning issue with a tentative schedule and the version number.
  • The RM ensures that typeshed has been synced in the last week or two, and after the previous feature release.
  • The RM creates a release branch.
  • The RM tests a revision on the release branch internally at Dropbox for at least a few days. This doesn't need to be the final released version.
  • The RM cherry-picks low-risk changes to the release branch.
  • The RM writes a blog post and publishes the release to PyPI.
  • The RM (or any other contributor with access to the PyPI project) can optionally make one or more point releases.

Versioning scheme

Mypy version numbers are of form x.y.z. Rules:

  • The major release number (x) is incremented if a feature release includes a significant backward incompatible change that affects a significant fraction of users.
  • The minor release number (y) is incremented on each feature release. Minor releases include updated typeshed stubs.
  • The point release number (z) is incremented when there are fixes only.

Mypy doesn't use SemVer, since most minor releases have backward incompatible changes in typeshed, at the very least. Each new type annotation in typeshed risks breaking backward compatibility, even if the annotation is correct. Also, many type checking features find new legitimate issues in code. These are not considered backward incompatible changes, unless the number of new errors is very high.

Major releases

A major release includes a significant backward incompatible change. The release manager decides whether a particular change is big enough for a major release after discussing this with other contributors. A change is significant if it is expected to require changes (even trial ones) for a large fraction of mypy users. As an exception, reporting new legitimate errors is fine in a minor release, as long as the false positive rate is low.

Here are some features from previous mypy releases which would now require a major release:

  • No implicit optional types for arguments (mypy 0.990)
  • Splitting off third-party library stubs to separate PyPI packages (mypy 0.900)
  • Strict optional checking enabled by default (mypy 0.600)

Minor releases

Any release that includes new features or a typeshed sync is a minor (feature) release. It's fine to have some backward incompatible changes, especially if these just generate new legitimate errors without many false positives.

Point releases

Point releases only include fixes, or in rare cases minor new features that are necessary to properly fix a critical issue. We don't include all bug fixes in point releases. These fixes are potentially fine to include, from the highest priority to the lowest priority:

  1. Any fixes to regressions (including regressions in typeshed and performance regressions)
  2. Fixes for wheel builds
  3. Any fixes to features added in the latest feature release (including usability fixes)
  4. Documentation changes relevant to the release
  5. Optionally, fixes to other critical bugs, even if not a regression (e.g. frequent crashes)
  6. Rarely, other low-risk bug fixes

We usually release one or two point releases for each feature release, but this not a requirement. Usually only a handful of changes get included in each point release. Point releases typically do not generate new mypy_primer errors, unless there are fixes to false negatives.

Normally we don't release bug fixes to older feature releases, but we can make exceptions for very serious issues (e.g. some use case is completely broken, or there are many false negatives). These must be decided on a case by case basis.

Anybody who has been onboarded to make releases (this includes all release managers and others with PyPI upload access) can volunteer to publish a new bugfix release by leaving a comment in the release planning GitHub issue with the suggested list of fixes to include.

If there are no concerns, the release can be uploaded the following day. It's best to avoid publishing releases over the weekend, unless there is a big regression.

We don't normally publish blog posts for feature releases, unless there are many or very serious regressions. The RM can decide whether to publish a separate blog post for a point release.

Policy for backward incompatible changes

After mypy 1.0, any significant backward incompatible change must be announced in the blog post for the previous feature release, before making the change. The previous release must also provide a flag to enable or disable the new behavior (whenever practical), so that users will be able to prepare for the changes and report issues. We should keep the feature flag for at least a few releases after we've switched the default. Often we'll keep the feature flag indefinitely, if it's not expensive to maintain.

This process must be followed for all changes that trigger a major feature release, but it's also recommended to do this for smaller changes.

For example, let's consider a new check that that can generate false positives but is still considered useful enough to enable by default. It can be introduced with a dedicated error code that is disabled by default. In the next release (at the earliest) we can turn the error code on by default, if the switch has been announced in an earlier release.

This policy doesn't apply to typeshed changes, the plugin API, experimental features, mypyc, stubgen or stubtest.

More information

Making a patch release

  1. Bump the version on the release branch and add "+dev" to it
  2. Cherry pick whatever changes
  3. Remove "+dev" from version
  4. Add a git tag for the release
  5. Push tag and commits upstream
  6. Wait about an hour for mypyc wheel builds to finish
  7. Run python misc/upload-pypi.py (consider using --dry-run)