]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-149609: Raise deprecation warnings for `abc.{abstractclassmethod,abstractstaticmet...
authorsobolevn <mail@sobolevn.me>
Sun, 31 May 2026 07:26:52 +0000 (10:26 +0300)
committerGitHub <noreply@github.com>
Sun, 31 May 2026 07:26:52 +0000 (07:26 +0000)
Doc/deprecations/pending-removal-in-3.21.rst
Doc/library/abc.rst
Doc/whatsnew/3.12.rst
Doc/whatsnew/3.13.rst
Doc/whatsnew/3.14.rst
Doc/whatsnew/3.15.rst
Doc/whatsnew/3.16.rst
Lib/abc.py
Lib/test/test_abc.py
Misc/NEWS.d/next/Library/2026-05-10-16-06-27.gh-issue-149609.yLKPXo.rst [new file with mode: 0644]

index 5d0c56612094ff4458b16723fe0b597ddf60b0d5..18b89a20e4a20827bbc611b45d1ce650f44124b9 100644 (file)
@@ -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``,
index 8112cfee7d204dbe96ab26f4ed95397848ece23f..904eff2e31e6ac2d072d4df178c1d6db79db1c98 100644 (file)
@@ -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.
index df6cc98eaf1c90a1b72c02b113ea6e30d5ba8595..0378ada72804c9eea9bbc45ad4dc7374b946b54b 100644 (file)
@@ -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:
index 4272c04d80868bb1d17bdd3c7fff6669765ee0fb..0db8ec55e5c9f8e53eafe9cee71d2ee0a0864579 100644 (file)
@@ -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
index 39d1d8da5367e5e0320b85fbf362b75851464d42..cd0d8b7cb006fee9a9b5b3658a2f0b7a1c3cfbec 100644 (file)
@@ -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
 
 
index 8e6b1faa523f68e7f61385d25a865ad4b1392071..1d27baf38906e9a4527a9fe30d6dd50f8f7df8ce 100644 (file)
@@ -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
index a6911b68c2eb756654fd576594f6076fa4743e22..9a0a0d3d8831f5f4096ca4eb79cb46e360a13883 100644 (file)
@@ -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
 ======================
index f8a4e11ce9c3b1e7a8afeae5626a73af81a7a208..08f708d1b89208576fb6f39d98a665f1b3e82357 100644 (file)
@@ -36,11 +36,15 @@ class abstractclassmethod(classmethod):
             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 abstractstaticmethod(staticmethod):
             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 abstractproperty(property):
             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,
index 80ee9e0ba56e754b70feb9a6f47fbd4820a37c8f..59a45a2eda07b00a284fd152282789a2b4693e2c 100644 (file)
@@ -11,20 +11,30 @@ import unittest
 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 test_factory(abc_ABCMeta, abc_get_cache_token):
             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 test_factory(abc_ABCMeta, abc_get_cache_token):
             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 test_factory(abc_ABCMeta, abc_get_cache_token):
             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,
diff --git a/Misc/NEWS.d/next/Library/2026-05-10-16-06-27.gh-issue-149609.yLKPXo.rst b/Misc/NEWS.d/next/Library/2026-05-10-16-06-27.gh-issue-149609.yLKPXo.rst
new file mode 100644 (file)
index 0000000..3acba7d
--- /dev/null
@@ -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.