PEP 387 – Backwards Compatibility Policy | peps.python.org (original) (raw)

Author:

Benjamin Peterson

PEP-Delegate:

Brett Cannon

Status:

Active

Type:

Process

Created:

18-Jun-2009

Post-History:

19-Jun-2009,12-Jun-2020,19-Dec-2022,16-Jun-2023

Replaces:

291


Table of Contents

Abstract

This PEP outlines Python’s backwards compatibility policy.

Rationale

As one of the most used programming languages today [1], the Python core language and its standard library play a critical role in millions of applications and libraries. This is fantastic. However, it means the development team must be very careful not to break this existing 3rd party code with new releases.

This PEP takes the perspective that “backwards incompatibility” means preexisting code ceases to comparatively function after a change. It is acknowledged that this is not a concrete definition, but the expectation is people in general understand what is meant by “backwards incompatibility”, and if they are unsure they may ask the Python development team and/or steering council for guidance.

Backwards Compatibility Rules

This policy applies to all public APIs. These include:

Others are explicitly not part of the public API. They can change or be removed at any time in any way. These include:

Basic policy for backwards compatibility

Soft Deprecation

A soft deprecation can be used when using an API which should no longer be used to write new code, but it remains safe to continue using it in existing code. The API remains documented and tested, but will not be developed further (no enhancement).

The main difference between a “soft” and a (regular) “hard” deprecation is that the soft deprecation does not imply scheduling the removal of the deprecated API.

Another difference is that a soft deprecation does not issue a warning: it’s only mentioned in the documentation, whereas usually a “hard” deprecation issues a DeprecationWarning warning at runtime. The documentation of a soft deprecation should explain why the API should be avoided, and if possible propose a replacement.

If the decision is made to deprecate (in the regular sense) a feature that is currently soft deprecated, the deprecation must follow theBackwards Compatibility Rules (i.e., there is no exception because the feature is already soft deprecated).

Making Incompatible Changes

Making an incompatible change is a gradual process performed over several releases:

  1. Discuss the change. Depending on the degree of incompatibility, this could be on the bug tracker, python-dev, python-list, or the appropriate SIG. A PEP or similar document may be written. Hopefully users of the affected API will pipe up to comment.
  2. Add a warning to the current main branch. If behavior is changing, the API may gain a new function or method to perform the new behavior; old usage should raise the warning. If an API is being removed, simply warn whenever it is entered. DeprecationWarning is the usual warning category to use, but PendingDeprecationWarning may be used in special cases where the old and new versions of the API will coexist for many releases [2]. The warning message should include the release the incompatibility is expected to become the default and a link to an issue that users can post feedback to. When feasible, also change typeshedto add the @deprecated decorator (see PEP 702) to the deprecated API, so that users of static type checkers have another way to learn about the deprecation.
    For C API, a compiler warning generated by the Py_DEPRECATED macro is also acceptable.
  3. Wait for the warning to appear in at least two minor Python versions of the same major version, or one minor version in an older major version (e.g., for a warning in Python 3.10.0, you either wait until at least Python 3.12 or Python 4.0 to make the change). It is preferred, though, to wait 5 years before removal (e.g., warn starting in Python 3.10, removal in 3.15; this happens to coincide with the current lifetime of a minor release of Python).
    • If the expected maintenance overhead and security risk of the deprecated behavior is small (e.g. an old function is reimplemented in terms of a new, more general one), it can stay indefinitely (or until the situation changes).
    • If the deprecated feature is replaced by a new one, it should generally be removed only after the last Python version_without_ the new feature reaches end of support.
  4. See if there’s any feedback. Users not involved in the original discussions may comment now after seeing the warning. Perhaps reconsider.
  5. The behavior change or feature removal may now be made default or permanent having reached the declared version. Remove the old version and warning.
  6. If a warning cannot be provided to users, consult with the steering council.

Changelog

References

This document has been placed in the public domain.