mirror of
https://github.com/python/cpython.git
synced 2026-06-04 16:50:51 +00:00
gh-149609: Raise deprecation warnings for abc.{abstractclassmethod,abstractstaticmethod,abstractproperty} (#149636)
This commit is contained in:
parent
73d8e9a47c
commit
90c1d86f34
10 changed files with 107 additions and 18 deletions
|
|
@ -1,6 +1,15 @@
|
|||
Pending removal in Python 3.21
|
||||
------------------------------
|
||||
|
||||
* :mod:`abc`
|
||||
|
||||
* Soft-deprecated since Python 3.3 :class:`abc.abstractclassmethod`,
|
||||
:class:`abc.abstractstaticmethod`, and :class:`abc.abstractproperty`
|
||||
now raise a :exc:`DeprecationWarning`.
|
||||
These classes will be removed in Python 3.21, instead
|
||||
use :func:`abc.abstractmethod` with :func:`classmethod`,
|
||||
:func:`staticmethod`, and :class:`property` respectively.
|
||||
|
||||
* :mod:`ast`:
|
||||
|
||||
* Classes ``slice``, ``Index``, ``ExtSlice``, ``Suite``, ``Param``,
|
||||
|
|
|
|||
|
|
@ -237,7 +237,7 @@ The :mod:`!abc` module also supports the following legacy decorators:
|
|||
.. decorator:: abstractclassmethod
|
||||
|
||||
.. versionadded:: 3.2
|
||||
.. deprecated:: 3.3
|
||||
.. deprecated-removed:: 3.3 3.21
|
||||
It is now possible to use :class:`classmethod` with
|
||||
:func:`abstractmethod`, making this decorator redundant.
|
||||
|
||||
|
|
@ -258,7 +258,7 @@ The :mod:`!abc` module also supports the following legacy decorators:
|
|||
.. decorator:: abstractstaticmethod
|
||||
|
||||
.. versionadded:: 3.2
|
||||
.. deprecated:: 3.3
|
||||
.. deprecated-removed:: 3.3 3.21
|
||||
It is now possible to use :class:`staticmethod` with
|
||||
:func:`abstractmethod`, making this decorator redundant.
|
||||
|
||||
|
|
@ -278,7 +278,7 @@ The :mod:`!abc` module also supports the following legacy decorators:
|
|||
|
||||
.. decorator:: abstractproperty
|
||||
|
||||
.. deprecated:: 3.3
|
||||
.. deprecated-removed:: 3.3 3.21
|
||||
It is now possible to use :class:`property`, :meth:`property.getter`,
|
||||
:meth:`property.setter` and :meth:`property.deleter` with
|
||||
:func:`abstractmethod`, making this decorator redundant.
|
||||
|
|
|
|||
|
|
@ -1367,6 +1367,8 @@ Deprecated
|
|||
|
||||
.. include:: ../deprecations/pending-removal-in-3.20.rst
|
||||
|
||||
.. include:: ../deprecations/pending-removal-in-3.21.rst
|
||||
|
||||
.. include:: ../deprecations/pending-removal-in-future.rst
|
||||
|
||||
.. _whatsnew312-removed:
|
||||
|
|
|
|||
|
|
@ -2031,6 +2031,8 @@ New Deprecations
|
|||
|
||||
.. include:: ../deprecations/pending-removal-in-3.20.rst
|
||||
|
||||
.. include:: ../deprecations/pending-removal-in-3.21.rst
|
||||
|
||||
.. include:: ../deprecations/pending-removal-in-future.rst
|
||||
|
||||
CPython Bytecode Changes
|
||||
|
|
|
|||
|
|
@ -2748,6 +2748,8 @@ New deprecations
|
|||
|
||||
.. include:: ../deprecations/pending-removal-in-3.20.rst
|
||||
|
||||
.. include:: ../deprecations/pending-removal-in-3.21.rst
|
||||
|
||||
.. include:: ../deprecations/pending-removal-in-future.rst
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2335,6 +2335,8 @@ New deprecations
|
|||
|
||||
.. include:: ../deprecations/pending-removal-in-3.20.rst
|
||||
|
||||
.. include:: ../deprecations/pending-removal-in-3.21.rst
|
||||
|
||||
.. include:: ../deprecations/pending-removal-in-future.rst
|
||||
|
||||
.. include:: ../deprecations/soft-deprecations.rst
|
||||
|
|
|
|||
|
|
@ -215,6 +215,15 @@ tarfile
|
|||
Deprecated
|
||||
==========
|
||||
|
||||
* :mod:`abc`
|
||||
|
||||
* Soft-deprecated since Python 3.3 :class:`abc.abstractclassmethod`,
|
||||
:class:`abc.abstractstaticmethod`, and :class:`abc.abstractproperty`
|
||||
now raise a :exc:`DeprecationWarning`.
|
||||
These classes will be removed in Python 3.21, instead
|
||||
use :func:`abc.abstractmethod` with :func:`classmethod`,
|
||||
:func:`staticmethod`, and :class:`property` respectively.
|
||||
|
||||
* :mod:`ast`:
|
||||
|
||||
* Classes ``slice``, ``Index``, ``ExtSlice``, ``Suite``, ``Param``,
|
||||
|
|
@ -228,6 +237,14 @@ Deprecated
|
|||
|
||||
.. Add deprecations above alphabetically, not here at the end.
|
||||
|
||||
.. include:: ../deprecations/pending-removal-in-3.17.rst
|
||||
|
||||
.. include:: ../deprecations/pending-removal-in-3.19.rst
|
||||
|
||||
.. include:: ../deprecations/pending-removal-in-3.20.rst
|
||||
|
||||
.. include:: ../deprecations/pending-removal-in-future.rst
|
||||
|
||||
|
||||
Porting to Python 3.16
|
||||
======================
|
||||
|
|
|
|||
21
Lib/abc.py
21
Lib/abc.py
|
|
@ -36,11 +36,15 @@ class C(ABC):
|
|||
def my_abstract_classmethod(cls, ...):
|
||||
...
|
||||
|
||||
.. deprecated-removed: 3.3 3.21
|
||||
|
||||
"""
|
||||
|
||||
__isabstractmethod__ = True
|
||||
|
||||
def __init__(self, callable):
|
||||
import warnings
|
||||
warnings._deprecated('abc.abstractclassmethod', remove=(3, 21))
|
||||
callable.__isabstractmethod__ = True
|
||||
super().__init__(callable)
|
||||
|
||||
|
|
@ -56,11 +60,15 @@ class C(ABC):
|
|||
def my_abstract_staticmethod(...):
|
||||
...
|
||||
|
||||
.. deprecated-removed: 3.3 3.21
|
||||
|
||||
"""
|
||||
|
||||
__isabstractmethod__ = True
|
||||
|
||||
def __init__(self, callable):
|
||||
import warnings
|
||||
warnings._deprecated('abc.abstractstaticmethod', remove=(3, 21))
|
||||
callable.__isabstractmethod__ = True
|
||||
super().__init__(callable)
|
||||
|
||||
|
|
@ -76,10 +84,23 @@ class C(ABC):
|
|||
def my_abstract_property(self):
|
||||
...
|
||||
|
||||
.. deprecated-removed: 3.3 3.21
|
||||
|
||||
"""
|
||||
|
||||
__isabstractmethod__ = True
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
fget=None,
|
||||
fset=None,
|
||||
fdel=None,
|
||||
doc=None,
|
||||
):
|
||||
import warnings
|
||||
warnings._deprecated('abc.abstractproperty', remove=(3, 21))
|
||||
super().__init__(fget, fset, fdel, doc)
|
||||
|
||||
|
||||
try:
|
||||
from _abc import (get_cache_token, _abc_init, _abc_register,
|
||||
|
|
|
|||
|
|
@ -11,20 +11,30 @@
|
|||
import abc
|
||||
import _py_abc
|
||||
from inspect import isabstract
|
||||
from test.support import warnings_helper
|
||||
|
||||
def test_factory(abc_ABCMeta, abc_get_cache_token):
|
||||
class TestLegacyAPI(unittest.TestCase):
|
||||
|
||||
def test_abstractproperty_basics(self):
|
||||
@abc.abstractproperty
|
||||
def foo(self): pass
|
||||
with self.assertWarnsRegex(
|
||||
DeprecationWarning,
|
||||
'abstractproperty',
|
||||
):
|
||||
@abc.abstractproperty
|
||||
def foo(self): pass
|
||||
|
||||
self.assertTrue(foo.__isabstractmethod__)
|
||||
def bar(self): pass
|
||||
self.assertNotHasAttr(bar, "__isabstractmethod__")
|
||||
|
||||
class C(metaclass=abc_ABCMeta):
|
||||
@abc.abstractproperty
|
||||
def foo(self): return 3
|
||||
with self.assertWarnsRegex(
|
||||
DeprecationWarning,
|
||||
'abstractproperty',
|
||||
):
|
||||
class C(metaclass=abc_ABCMeta):
|
||||
@abc.abstractproperty
|
||||
def foo(self): return 3
|
||||
self.assertRaises(TypeError, C)
|
||||
class D(C):
|
||||
@property
|
||||
|
|
@ -33,16 +43,26 @@ def foo(self): return super().foo
|
|||
self.assertFalse(getattr(D.foo, "__isabstractmethod__", False))
|
||||
|
||||
def test_abstractclassmethod_basics(self):
|
||||
@abc.abstractclassmethod
|
||||
def foo(cls): pass
|
||||
with self.assertWarnsRegex(
|
||||
DeprecationWarning,
|
||||
'abstractclassmethod',
|
||||
):
|
||||
@abc.abstractclassmethod
|
||||
def foo(cls): pass
|
||||
|
||||
self.assertTrue(foo.__isabstractmethod__)
|
||||
@classmethod
|
||||
def bar(cls): pass
|
||||
self.assertFalse(getattr(bar, "__isabstractmethod__", False))
|
||||
|
||||
class C(metaclass=abc_ABCMeta):
|
||||
@abc.abstractclassmethod
|
||||
def foo(cls): return cls.__name__
|
||||
with self.assertWarnsRegex(
|
||||
DeprecationWarning,
|
||||
'abstractclassmethod',
|
||||
):
|
||||
class C(metaclass=abc_ABCMeta):
|
||||
@abc.abstractclassmethod
|
||||
def foo(cls): return cls.__name__
|
||||
|
||||
self.assertRaises(TypeError, C)
|
||||
class D(C):
|
||||
@classmethod
|
||||
|
|
@ -51,16 +71,26 @@ def foo(cls): return super().foo()
|
|||
self.assertEqual(D().foo(), 'D')
|
||||
|
||||
def test_abstractstaticmethod_basics(self):
|
||||
@abc.abstractstaticmethod
|
||||
def foo(): pass
|
||||
with self.assertWarnsRegex(
|
||||
DeprecationWarning,
|
||||
'abstractstaticmethod',
|
||||
):
|
||||
@abc.abstractstaticmethod
|
||||
def foo(): pass
|
||||
|
||||
self.assertTrue(foo.__isabstractmethod__)
|
||||
@staticmethod
|
||||
def bar(): pass
|
||||
self.assertFalse(getattr(bar, "__isabstractmethod__", False))
|
||||
|
||||
class C(metaclass=abc_ABCMeta):
|
||||
@abc.abstractstaticmethod
|
||||
def foo(): return 3
|
||||
with self.assertWarnsRegex(
|
||||
DeprecationWarning,
|
||||
'abstractstaticmethod',
|
||||
):
|
||||
class C(metaclass=abc_ABCMeta):
|
||||
@abc.abstractstaticmethod
|
||||
def foo(): return 3
|
||||
|
||||
self.assertRaises(TypeError, C)
|
||||
class D(C):
|
||||
@staticmethod
|
||||
|
|
@ -168,6 +198,7 @@ def method_two(self):
|
|||
msg = r"class C without an implementation for abstract methods 'method_one', 'method_two'"
|
||||
self.assertRaisesRegex(TypeError, msg, C)
|
||||
|
||||
@warnings_helper.ignore_warnings(category=DeprecationWarning)
|
||||
def test_abstractmethod_integration(self):
|
||||
for abstractthing in [abc.abstractmethod, abc.abstractproperty,
|
||||
abc.abstractclassmethod,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
Raise :exc:`DeprecationWarning` on using :class:`abc.abstractclassmethod`,
|
||||
:class:`abc.abstractstaticmethod`, and :class:`abc.abstractproperty`,
|
||||
schedule its removal for Python 3.21.
|
||||
Loading…
Add table
Add a link
Reference in a new issue