Deprecation-Richtlinie#
Viele Benutzer und andere Pakete hängen von verschiedenen Teilen von Qiskit ab. Wir müssen daher sicherstellen, dass wir den Benutzern bei jeder Änderung des Codes ausreichend Zeit geben, notwendige Anpassungen durchzuführen, damit ihr bereits geschriebener Code weiter funktioniert.
Wichtig ist: Ändern Sie keine Schnittstelle, die öffentlich zugänglich ist, es sei denn, wir müssen es unbedingt tun. Hinzufügen ist in Ordnung, Dinge wegnehmen ist lästig für Benutzer, kann aber mit viel Vorsicht gehandhabt werden. Aber das Ändern des Verhaltens einer Schnittstelle bedeutet in der Regel, dass Benutzer keinen Code schreiben können, der mit zwei späteren Versionen von Qiskit funktioniert, was nicht akzeptabel ist.
Beachten Sie, dass Benutzer häufig Funktionen, Klassen und Methoden verwenden werden, die wir, die Qiskit-Entwickler, als intern oder nicht weit verbreitet ansehen. Gehen Sie nicht davon aus, dass diese Funktionen etc so versteckt sind, dass sie niemand verwenden wird; wenn sie öffentlich sind, unterliegen sie den üblichen Regeln. Die einzigen Ausnahmen sind hier Funktionen und Module, die explizit intern sind, d. h. diejenigen, deren Namen mit einem führenden Unterstrich beginnen (_
).
Die Leitprinzipien sind:
wir dürfen mindestens drei Monate oder zwei vollständige Versionszyklen lang keinen Code ohne aktive Warnungen entfernen oder ändern;
es muss immer eine Möglichkeit geben, gültige Ziele zu erreichen, die keine Warnungen auslösen;
gehen Sie nicht davon aus, dass eine Funktion, die nicht ausdrücklich intern ist, nicht verwendet wird;
alle Abkündigungen, Änderungen und Entfernungen werden als API-Änderungen betrachtet und können nur in untergeordneten Versionen, nicht in Patch-Versionen auftreten, gemäß der :ref:` stable branch policy <stable_branch_policy>`.
Eine Funktion entfernen#
Beim Entfernen einer Funktion (z. B. einer Klasse, einer Funktion oder eines Funktionsparameters) folgen wir dieser Prozedur:
Der alternative Pfad muss für eine untergeordnetete Version vorhanden sein, bevor Warnungen ausgegeben werden. Zum Beispiel, wenn wir die Funktion
foo()
durchbar()
ersetzen wollen, müssen wir mindestens eine Version mit beiden Funktionen veröffentlichen, bevor wir infoo()
Warnungen ausgeben. Du kannstPendingDeprecationWarning
s von den alten Pfaden auch sofort anzeigen lassen.Grund: Wir müssen den Benutzern Zeit zum Anpassen geben, ohne ihren Code unbrauchbar zu machen, sobald sie aktualisieren.
Nachdem der alternative Pfad für mindestens eine kleine Version vorhanden ist, gibt die Deprecation Warnungen aus. Füge eine Versionsnotiz mit einem
deprecations
Hinweis hinzu, die alle veralteten Pfade, ihre Alternativen und den Grund für die Deprecation auflistet. :ref:`Aktualisiere die Tests, um die Warnungen <testing-deprecated-functionality> ` zu testen.Grund: Entfernungen müssen für mindestens eine Version sehr sichtbar sein, um die Überraschung für Benutzer zu minimieren, wenn die Entfernungen dann tatsächlich durchgeführt wurden.
Legen Sie ein Entfernungsdatum für das alte Feature fest und entfernen Sie es (und die Warnungen), wenn das Datum erreicht ist. Dies muss mindestens drei Monate nach der ersten Veröffentlichung der Version mit den Warnungen geschehen und kann nicht die untergeordnete Version nach den Warnungen sein. Füge eine
Upgrade
Release Notiz hinzu, die alle Entfernungen auflistet. Wenn zum Beispiel der alternative Pfad in0.19.0
angegeben wurde und die Warnungen in0.20.0
hinzugefügt wurden. 0.0``, dann ist die früheste Version für das Entfernen die Version0.22.0
, auch wenn0.21.0
mehr als drei Monate nach0.20.0
veröffentlicht wurde.Bemerkung
Dies sind Mindest Anforderungen. Um signifikante oder Kernfunktionen zu entfernen, geben Sie den Benutzern mindestens eine zusätzliche untergeordnete Version Zeit, oder sogar länger.
Grund: Es muss Zeit für die Benutzer geben, diese Nachrichten zu sehen und ihnen Zeit für die Anpassung zu geben. Nicht alle Benutzer werden ihre Version von Qiskit sofort aktualisieren, und einige könnten kleinere Versionen überspringen.
Wenn eine Funktion als veraltet markiert wird, ist sie zur Entfernung vorgemerkt, aber die Benutzer sollten sich trotzdem darauf verlassen können, dass sie noch korrekt funktioniert. Wir betrachten eine mit „veraltet“ markierte Funktion als eingefroren. Wir verpflichten uns, weiterhin kritische Fehlerkorrekturen für die Funktion durchzuführen, bis sie entfernt wird. Wir werden aber keine neuen Funktionen mit ihr zusammenführen.
Verhaltensweise#
Eine Verhaltensweise ohne Entfernung ist besonders schwer zu handhaben, weil wir beide Optionen für zwei Versionen haben und in der Lage sein müssen, Warnungen auszusprechen. Zum Beispiel bedeutet das Ändern des Typs des Rückgabewerts von einer Funktion fast ausnahmslos einen API-Bruch, was für Benutzer frustrierend ist und es ihnen erschwert, Qiskit zu verwenden.
Die beste Lösung ist hier oftmals, eine neue Funktion zu erstellen und dann die Prozeduren für das Entfernen von Funktionen zu verwenden.
Wenn Sie unbedingt das Verhalten von existierendem Code ändern müssen (abgesehen von der Beseitigung von Fehlern), müssen Sie nach bestem Wissen und Gewissen vorgehen, um die Richtlinien vom Anfang dieses Dokuments anzuwenden. Die am besten geeignete Warnung für Veränderungen der Funktionsweise ist normalerweise FutureWarning
. Einige Möglichkeiten, wie man eine Änderung durchführen kann:
Wenn Sie das Standardverhalten einer Funktion ändern, sollten Sie ein Keyword-Argument hinzufügen, um zwischen altem und neuem Verhalten zu wählen. Beim Aufruf der Funktion kann eine
FutureWarning
ausgegeben, werden, wenn das Keyword-Argument nicht angegeben wird (z.B. wenn esNone
ist) mit dem Hinweis, dass der neue Wert bald zur Standardeinstellung wird. Sie müssen die normale Deprecation Periode durchlaufen, um das Keyword-Argument zu entfernen, nachdem Sie die Änderung der Funktionsweise vorgenommen haben. Dies wird mindestens sechs Monate dauern, bis beide Zyklen durchlaufen sind.Wenn Sie den Rückgabetyp einer Funktion ändern möchten, sollten Sie eine neue Funktion hinzufügen, die den neuen Typ zurückgibt, und folgen Sie dann den Prozeduren für das Entfernen der alten Funktion.
Wenn Sie eine neue Eingabe akzeptieren müssen, die Sie wegen ihres Typs nicht von einer bestehenden Möglichkeit unterscheiden können, sollten Sie die Eingabe durch ein anderes Keyword-Argument erwägen oder eine zweite Funktion hinzuzufügen, die nur das neue Formular akzeptiert.
Ausgabe von Warnhinweisen zur Abkündigung#
The proper way to raise a deprecation warning is to use the decorators @deprecate_arg
and
@deprecate_func
from qiskit.utils.deprecation
. These will generate a standardized message and
and add the deprecation to that function’s docstring so that it shows up in the docs.
from qiskit.utils.deprecation import deprecate_arg, deprecate_func
@deprecate_func(since="0.24.0", additional_msg="No replacement is provided.")
def deprecated_func():
pass
@deprecate_arg("bad_arg", new_alias="new_name", since="0.24.0")
def another_func(bad_arg: str, new_name: str):
pass
Usually, you should set additional_msg: str `` with the format ``"Instead, use ..."
so that
people know how to migrate. Read those functions‘ docstrings for additional arguments like
pending: bool
and predicate
.
If you are deprecating outside the main Qiskit repo, set package_name
to match your package.
Alternatively, if you prefer to use your own decorator helpers, then have them call
add_deprecation_to_docstring
from qiskit.utils.deprecation
.
If @deprecate_func
and @deprecate_arg
cannot handle your use case, consider improving
them. Otherwise, you can directly call the warn
function
from the warnings module in the Python standard library, using the category
DeprecationWarning
. For example:
import warnings
def deprecated_function():
warnings.warn(
"The function qiskit.deprecated_function() is deprecated since "
"Qiskit Terra 0.20.0, and will be removed 3 months or more later. "
"Instead, you should use qiskit.other_function().",
category=DeprecationWarning,
stacklevel=2,
)
# ... the rest of the function ...
Vergewissern Sie sich, dass Sie die Version des Pakets mit einbeziehen, die die Deprecation-Warnung einführte (damit die Betreuer leichter sehen können, wann es möglich ist, das Paket zu entfernen) und was der alternative Pfad ist.
Beachten Sie das stacklevel
Argument. Damit wird gesteuert, welche Funktion abgekündigt wird. stacklevel=1
(der Standard) bedeutet, dass die Warnung die warn
Funktion selbst betrifft, während stacklevel=2
die enthaltene Funktion korrekt angibt. Es ist ungewöhnlich, den Wert auf etwas anderes als 2
zu setzen, kann aber nützlich sein, wenn Sie eine Helfer-Funktion verwenden, um die gleiche Warnung an mehreren Orten auszulösen.
Testen veralteter Funktionen#
Immer wenn Sie Warnhinweise auf Abkündigung einer Funktion hinzufügen, müssen Sie die Tests aktualisieren, die die Funktionalität betreffen. Die Testsuite sollte andernfalls wegen der neuen Warnungen fehlschlagen. Die veraltete Funktionalität muss auch während der Abkündigungsperiode getestet werden, um sicherzustellen, dass sie weiterhin funktioniert.
Um die Tests zu aktualisieren, müssen Sie jeden Aufruf veralteter Funktionsverhalten in einen eigenen „assertion“-Block platzieren. Für Unterklassen von unittest.TestCase
(was alle Qiskit-Testfälle sind), geschieht dies durch:
class MyTestSuite(QiskitTestCase):
def test_deprecated_function(self):
with self.assertWarns(DeprecationWarning):
output = deprecated_function()
# ... do some things with output ...
self.assertEqual(output, expected)
Dokumentation von Abkündigungen und grundlegenden Änderungen#
It is important to warn the user when your breaking changes are coming.
@deprecate_arg
and @deprecate_func
will automatically add the deprecation to the docstring
for the function so that it shows up in docs.
If you are not using those decorators, you should directly add a Sphinx deprecated directive
.. code-block:: python
- def deprecated_function():
„““ Short description of the deprecated function.
Veraltet ab Version 0.20.0: The function qiskit.deprecated_function() is deprecated since Qiskit Terra 0.20.0, and will be removed 3 months or more later. Instead, you should use qiskit.other_function().
<rest of the docstring> „““ # … the rest of the function …
You should also document the deprecation in the changelog by using Reno. Explain the deprecation and how to migrate.
In particular situations where a deprecation or change might be a major disruptor for users, a
migration guide might be needed. Once the migration guide is written and published, deprecation
messages and documentation should link to it (use the additional_msg: str
argument for
@deprecate_arg
and @deprecate_func
).