Skip to content

Commit

Permalink
Add deprecation policy to CONTRIBUTING.md (#3191)
Browse files Browse the repository at this point in the history
* Add deprecation policy to CONTRIBUTING.md

As we've become better about stabilizing interfaces in terra we've
started deprecating features and APIs prior removal. This is necessary
step towards growing user trust that they can rely on terra moving
forward, so that code they write using it will continue to work in the
future. However it's not necessarily clear what the expectations are for
features and APIs when they become deprecated. This commit attempts to
address this by adding a deprecation policy to the CONTRIBUTING.md file
which clearly documents how deprecations are handled and establishes the
policy around their use. This way end users know what to expect when
dealing with deprecations and how long they have to adapt to changes.

* Apply suggestions from code review

Co-Authored-By: elfrocampeador <[email protected]>

* Apply suggestions from code review

Co-Authored-By: Kevin Krsulich <[email protected]>

* Add examples for deprecations

This commit adds additional sections to the deprecation policy with
examples on how to raise a warning, and write release notes for a
deprecation and a deprecation removal.

* Apply suggestions from code review

Co-Authored-By: Kevin Krsulich <[email protected]>

* Update deprecation warning example

This updates the warning based on the review discussion for how to best
advertise the removal date. The example deprecation warning now
indicates which release a deprecation was added in and mentions the
policy of a minimum of 3 months between deprecation in a release and
removal.
  • Loading branch information
mtreinish authored and kdk committed Oct 10, 2019
1 parent 043cff7 commit 8f70d2d
Showing 1 changed file with 119 additions and 0 deletions.
119 changes: 119 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,125 @@ the following steps:
The `stable/*` branches should only receive changes in the form of bug
fixes.

## Deprecation Policy

End users of Qiskit need to know if a feature or an API they are using and rely
on will still be supported by the software tomorrow. Users rely on existing
features, knowing under which conditions the project can remove (or change in a
backwards incompatible manner) a feature or API is important. To manage
expectations the following policy is how API and feature deprecation and removal
is handled by Qiskit:

1. Features, APIs or configuration options are marked deprecated in the code.
Appropriate `DeprecationWarning` class warnings will be sent to the user. The
deprecated code will be frozen and receive only minimal maintenance (just so
that it continues to work as-is).

2. A migration path will be documented for current users of the feature. This
will be outlined in the both the release notes adding the deprecation and the
release notes removing the feature at the completion of the deprecation cycle.
In addition, if feasible the warning message will also include the migration
path. A migration path might be "stop using that feature", but in such cases
it is necessary to first judge how widely used and/or important the feature
is to end users and decided an obsolescence date based on that.

3. An obsolescence date for the feature will be set. The feature must remain
intact and working (although with the proper warning being emitted) in all
releases pushed until after that obsolescence date. At the very minimum the
feature (or API, or configuration option) should be marked as deprecated (and
still be supported) for at least three months of linear time from the release
date of the first release to include the deprecation warning. For example, if a
feature were deprecated in the 0.9.0 release of terra, which was released on
August 22, 2019, then that feature should still appear in all releases until at
least November 22, 2019. Since releases do not occur at fixed time intervals
this may mean that a deprecation warning may only occur in one release prior to
removal.

Note that this delay is a minimum. For significant features, it is recommend
that the deprecated feature appears for at least double that time. Also, per
the stable branch policy, deprecation removals can only occur during minor
version releases, they are not appropriate for backporting.

### Deprecation Warnings

The proper way to raise a deprecation warning is to use the ``warn`` function
from the [`warnings` module](https://docs.python.org/3/library/warnings.html)
in the python standard library. The warning category class
should be a ``DeprecationWarning``. An example would be:

```python
import warnings
def foo(input):
warnings.warn('The qiskit.foo() function is deprecated as of 0.9.0, and '
'will be removed no earlier than 3 months after that release '
'date. You should use the qiskit.bar() function instead.',
DeprecationWarning, stacklevel=2)
```

One thing to note here is the `stack_level` kwarg on the warn() call. This
argument is used to specify which level in the call stack will be used as
the line initiating the warning. Typically `stack_level` should be set to 2
as this will show the line calling the context where the warning was raised.
In the above example it would be the caller of `foo()`. If you did not set this,
the warning would show that the warning was caused by the line in the foo()
function, which is not helpful for users when trying to determine the origin
of a deprecated call. This value may be adjust though depending on the call
stack and where `warn()` gets called from. For example, if the warning is always
raised by a private method that only has one caller `stack_level=3` might be
appropriate.

### Deprecation Release Notes

You can refer to the Release Notes section for the process of creating a
new release note. One thing to keep in mind for deprecation release notes
though is that we need to clearly document a migration path in that release note.
This should outline what the current deprecated behavior would look like and
how users will need to update their code when that deprecated feature is
removed. In addition it is also good to explain the reasoning behind why the
change was being made. This provides context for users as to why they want
to update their code using Qiskit. A simple example would be:

```yaml
deprecations:
- |
The function ``qiskit.foo()`` has been deprecated. An alternative function
``qiskit.bar()`` can be used instead to provide the same functionality.
This alternative function provides the exact same functionality but with
better performance and more thorough validity checking.
```

In addition the `Changelog: Deprecation` label should be applied to any PRs
adding deprecation warnings so that they are highlighted in the changelog for
the release.

#### Deprecation Removal Release Notes

When an obsolecense date has passed and it's been determined safe to remove a
deprecated feature from Qiskit we need to have an upgrade note in the release
notes. We can copy the migration path from the deprecation release
note but we should also indicate that the feature was deprecated and in which
release. For example, building off the example in the previous section, if
that deprecation occurred in the 0.9.0 release which occurred on August 22, 2019
and the removal occurred in the **hypothetical** 0.11.0 release on December 2nd,
2019 the release note would look like:

```yaml
upgrade:
- |
The previously deprecated function ``qiskit.foo()``, which was deprecated
in the 0.9.0 release, has been removed. The ``qiskit.bar()`` function
should be used instead. ``qiskit.bar()`` provides the exact same
functionality but with better performance and more thorough validity
checking.
```

Pull requests that remove a deprecated function will need to be tagged with the
`Changelog: Removal` label so that they get highlighted in the changelog for
the release.


## Stable Branch Policy

The stable branch is intended to be a safe source of fixes for high
Expand Down

0 comments on commit 8f70d2d

Please sign in to comment.