PEP 702: Move to warnings, expand spec (#3442)
This commit is contained in:
parent
c972a76923
commit
00295ada36
|
@ -7,7 +7,7 @@ Type: Standards Track
|
|||
Topic: Typing
|
||||
Content-Type: text/x-rst
|
||||
Created: 30-Dec-2022
|
||||
Python-Version: 3.12
|
||||
Python-Version: 3.13
|
||||
Post-History: `01-Jan-2023 <https://mail.python.org/archives/list/typing-sig@python.org/thread/AKTFUYW3WDT7R7PGRIJQZMYHMDJNE4QH/>`__,
|
||||
`22-Jan-2023 <https://discuss.python.org/t/pep-702-marking-deprecations-using-the-type-system/23036>`__
|
||||
|
||||
|
@ -15,7 +15,7 @@ Post-History: `01-Jan-2023 <https://mail.python.org/archives/list/typing-sig@pyt
|
|||
Abstract
|
||||
========
|
||||
|
||||
This PEP adds an ``@typing.deprecated()`` decorator that marks a class or function
|
||||
This PEP adds an ``@warnings.deprecated()`` decorator that marks a class or function
|
||||
as deprecated, enabling static checkers to warn when it is used. By default, this
|
||||
decorator will also raise a runtime ``DeprecationWarning``.
|
||||
|
||||
|
@ -99,7 +99,7 @@ There are similar existing third-party tools:
|
|||
Specification
|
||||
=============
|
||||
|
||||
A new decorator ``@deprecated()`` is added to the :mod:`typing` module. This
|
||||
A new decorator ``@deprecated()`` is added to the :mod:`warnings` module. This
|
||||
decorator can be used on a class, function or method to mark it as deprecated.
|
||||
This includes :class:`typing.TypedDict` and :class:`typing.NamedTuple` definitions.
|
||||
With overloaded functions, the decorator may be applied to individual overloads,
|
||||
|
@ -132,16 +132,20 @@ For deprecated classes and functions, this includes:
|
|||
* If ``import *`` is used, usage of deprecated objects from the
|
||||
module (``from module import *; x = deprecated_object()``)
|
||||
* ``from`` imports (``from module import deprecated_object``)
|
||||
* Any syntax that indirectly triggers a call to the function. For example,
|
||||
if the ``__add__`` method of a class ``C`` is deprecated, then
|
||||
the code ``C() + C()`` should trigger a diagnostic. Similarly, if the
|
||||
setter of a property is marked deprecated, attempts to set the property
|
||||
should trigger a diagnostic.
|
||||
|
||||
There are some additional scenarios where deprecations could come into play:
|
||||
If a method is marked with the :func:`typing.override` decorator from :pep:`698`
|
||||
and the base class method it overrides is deprecated, the type checker should
|
||||
produce a diagnostic.
|
||||
|
||||
* An object implements a :class:`typing.Protocol`, but one of the methods
|
||||
required for protocol compliance is deprecated.
|
||||
* A class uses the ``@override`` decorator from :pep:`698` to assert that
|
||||
its method overrides a base class method, but the base class method is
|
||||
deprecated.
|
||||
|
||||
As these scenarios appear complex and relatively unlikely to come up in practice,
|
||||
There are additional scenarios where deprecations could come into play.
|
||||
For example, an object may implement a :class:`typing.Protocol`, but one
|
||||
of the methods required for protocol compliance is deprecated.
|
||||
As scenarios such as this one appear complex and relatively unlikely to come up in practice,
|
||||
this PEP does not mandate that type checkers detect them.
|
||||
|
||||
Example
|
||||
|
@ -151,7 +155,7 @@ As an example, consider this library stub named ``library.pyi``:
|
|||
|
||||
.. code-block:: python
|
||||
|
||||
from typing import deprecated
|
||||
from warnings import deprecated
|
||||
|
||||
@deprecated("Use Spam instead")
|
||||
class Ham: ...
|
||||
|
@ -165,6 +169,20 @@ As an example, consider this library stub named ``library.pyi``:
|
|||
@overload
|
||||
def foo(x: str) -> str: ...
|
||||
|
||||
class Spam:
|
||||
@deprecated("There is enough spam in the world")
|
||||
def __add__(self, other: object) -> object: ...
|
||||
|
||||
@property
|
||||
@deprecated("All spam will be equally greasy")
|
||||
def greasy(self) -> float: ...
|
||||
|
||||
@property
|
||||
def shape(self) -> str: ...
|
||||
@shape.setter
|
||||
@deprecated("Shapes are becoming immutable")
|
||||
def shape(self, value: str) -> None: ...
|
||||
|
||||
Here is how type checkers should handle usage of this library:
|
||||
|
||||
.. code-block:: python
|
||||
|
@ -181,6 +199,15 @@ Here is how type checkers should handle usage of this library:
|
|||
|
||||
ham = Ham() # no error (already reported above)
|
||||
|
||||
spam = library.Spam()
|
||||
spam + 1 # error: Use of deprecated method Spam.__add__. There is enough spam in the world.
|
||||
spam.greasy # error: Use of deprecated property Spam.greasy. All spam will be equally greasy.
|
||||
spam.shape # no error
|
||||
spam.shape = "cube" # error: Use of deprecated property setter Spam.shape. Shapes are becoming immutable.
|
||||
|
||||
The exact wording of the diagnostics is up to the type checker and is not part
|
||||
of the specification.
|
||||
|
||||
Runtime behavior
|
||||
----------------
|
||||
|
||||
|
@ -209,6 +236,7 @@ To accommodate runtime introspection, the decorator sets an attribute
|
|||
``__deprecated__`` on the object it is passed, as well as on the wrapper
|
||||
callables it generates for deprecated classes and functions.
|
||||
The value of the attribute is the message passed to the decorator.
|
||||
Decorating objecs that do not allow setting this attribute is not supported.
|
||||
|
||||
If a ``Protocol`` with the ``@runtime_checkable`` decorator is marked as deprecated,
|
||||
the ``__deprecated__`` attribute should not be considered a member of the protocol,
|
||||
|
@ -263,7 +291,8 @@ Reference implementation
|
|||
========================
|
||||
|
||||
A runtime implementation of the ``@deprecated`` decorator is
|
||||
`available <https://github.com/python/typing_extensions/pull/105>`__.
|
||||
available in the `typing-extensions <https://pypi.org/project/typing-extensions/>`_
|
||||
library since version 4.5.0.
|
||||
The ``pyanalyze`` type checker has
|
||||
`prototype support <https://github.com/quora/pyanalyze/pull/578>`__
|
||||
for emitting deprecation errors, as does
|
||||
|
@ -309,6 +338,15 @@ show that this feature is not commonly needed.
|
|||
Features for deprecating more kinds of objects could be added in a future
|
||||
PEP.
|
||||
|
||||
Placing the decorator in the ``typing`` module
|
||||
----------------------------------------------
|
||||
|
||||
An earlier version of this PEP proposed placing the ``@deprecated``
|
||||
decorator in the :mod:`typing` module. However, there was feedback
|
||||
that it would be unexpected for a decorator in the :mod:`typing` module
|
||||
to have runtime behavior. Therefore, the PEP now proposes adding the
|
||||
decorator the :mod:`warnings` module instead.
|
||||
|
||||
Acknowledgments
|
||||
===============
|
||||
|
||||
|
|
Loading…
Reference in New Issue