[Python-checkins] gh-91896: Deprecate collections.abc.ByteString (#102096)

JelleZijlstra webhook-mailer at python.org
Thu May 4 12:40:13 EDT 2023


https://github.com/python/cpython/commit/09b7695f12f2b44d2df6898407d7e68dd9493ed4
commit: 09b7695f12f2b44d2df6898407d7e68dd9493ed4
branch: main
author: Shantanu <12621235+hauntsaninja at users.noreply.github.com>
committer: JelleZijlstra <jelle.zijlstra at gmail.com>
date: 2023-05-04T09:39:33-07:00
summary:

gh-91896: Deprecate collections.abc.ByteString (#102096)

Co-authored-by: Alex Waygood <Alex.Waygood at Gmail.com>
Co-authored-by: Hugo van Kemenade <hugovk at users.noreply.github.com>

files:
A Misc/NEWS.d/next/Library/2023-03-08-02-45-46.gh-issue-91896.kgON_a.rst
M Doc/library/collections.abc.rst
M Doc/library/typing.rst
M Doc/whatsnew/3.12.rst
M Lib/_collections_abc.py
M Lib/test/test_collections.py

diff --git a/Doc/library/collections.abc.rst b/Doc/library/collections.abc.rst
index 669b7345499a..43a3286ba832 100644
--- a/Doc/library/collections.abc.rst
+++ b/Doc/library/collections.abc.rst
@@ -273,6 +273,12 @@ Collections Abstract Base Classes -- Detailed Descriptions
       The index() method added support for *stop* and *start*
       arguments.
 
+   .. deprecated-removed:: 3.12 3.14
+      The :class:`ByteString` ABC has been deprecated.
+      For use in typing, prefer a union, like ``bytes | bytearray``, or
+      :class:`collections.abc.Buffer`.
+      For use as an ABC, prefer :class:`Sequence` or :class:`collections.abc.Buffer`.
+
 .. class:: Set
            MutableSet
 
diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst
index c22fc0b28a50..162041fc7a84 100644
--- a/Doc/library/typing.rst
+++ b/Doc/library/typing.rst
@@ -2139,8 +2139,7 @@ Corresponding to collections in :mod:`collections.abc`
    annotate arguments of any of the types mentioned above.
 
    .. deprecated:: 3.9
-      :class:`collections.abc.ByteString` now supports subscripting (``[]``).
-      See :pep:`585` and :ref:`types-genericalias`.
+      Prefer :class:`collections.abc.Buffer`, or a union like ``bytes | bytearray | memoryview``.
 
 .. class:: Collection(Sized, Iterable[T_co], Container[T_co])
 
diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst
index 3fe3310a26e5..4a988bf4b993 100644
--- a/Doc/whatsnew/3.12.rst
+++ b/Doc/whatsnew/3.12.rst
@@ -792,6 +792,11 @@ Pending Removal in Python 3.14
 
   (Contributed by Jason R. Coombs and Hugo van Kemenade in :gh:`93963`.)
 
+* Deprecated :class:`collections.abc.ByteString`.
+  Prefer :class:`Sequence` or :class:`collections.abc.Buffer`.
+  For use in typing, prefer a union, like ``bytes | bytearray``, or :class:`collections.abc.Buffer`.
+  (Contributed by Shantanu Jain in :gh:`91896`.)
+
 * Creating immutable types (:data:`Py_TPFLAGS_IMMUTABLETYPE`) with mutable
   bases using the C API.
 
diff --git a/Lib/_collections_abc.py b/Lib/_collections_abc.py
index 2117190cf8b6..601107d2d867 100644
--- a/Lib/_collections_abc.py
+++ b/Lib/_collections_abc.py
@@ -1071,8 +1071,27 @@ def count(self, value):
 Sequence.register(range)
 Sequence.register(memoryview)
 
-
-class ByteString(Sequence):
+class _DeprecateByteStringMeta(ABCMeta):
+    def __new__(cls, name, bases, namespace, **kwargs):
+        if name != "ByteString":
+            import warnings
+
+            warnings._deprecated(
+                "collections.abc.ByteString",
+                remove=(3, 14),
+            )
+        return super().__new__(cls, name, bases, namespace, **kwargs)
+
+    def __instancecheck__(cls, instance):
+        import warnings
+
+        warnings._deprecated(
+            "collections.abc.ByteString",
+            remove=(3, 14),
+        )
+        return super().__instancecheck__(instance)
+
+class ByteString(Sequence, metaclass=_DeprecateByteStringMeta):
     """This unifies bytes and bytearray.
 
     XXX Should add all their methods.
diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py
index 8fc28a6bf98e..bb8b352518ef 100644
--- a/Lib/test/test_collections.py
+++ b/Lib/test/test_collections.py
@@ -1940,14 +1940,25 @@ def assert_index_same(seq1, seq2, index_args):
 
     def test_ByteString(self):
         for sample in [bytes, bytearray]:
-            self.assertIsInstance(sample(), ByteString)
+            with self.assertWarns(DeprecationWarning):
+                self.assertIsInstance(sample(), ByteString)
             self.assertTrue(issubclass(sample, ByteString))
         for sample in [str, list, tuple]:
-            self.assertNotIsInstance(sample(), ByteString)
+            with self.assertWarns(DeprecationWarning):
+                self.assertNotIsInstance(sample(), ByteString)
             self.assertFalse(issubclass(sample, ByteString))
-        self.assertNotIsInstance(memoryview(b""), ByteString)
+        with self.assertWarns(DeprecationWarning):
+            self.assertNotIsInstance(memoryview(b""), ByteString)
         self.assertFalse(issubclass(memoryview, ByteString))
-        self.validate_abstract_methods(ByteString, '__getitem__', '__len__')
+        with self.assertWarns(DeprecationWarning):
+            self.validate_abstract_methods(ByteString, '__getitem__', '__len__')
+
+        with self.assertWarns(DeprecationWarning):
+            class X(ByteString): pass
+
+        with self.assertWarns(DeprecationWarning):
+            # No metaclass conflict
+            class Z(ByteString, Awaitable): pass
 
     def test_Buffer(self):
         for sample in [bytes, bytearray, memoryview]:
diff --git a/Misc/NEWS.d/next/Library/2023-03-08-02-45-46.gh-issue-91896.kgON_a.rst b/Misc/NEWS.d/next/Library/2023-03-08-02-45-46.gh-issue-91896.kgON_a.rst
new file mode 100644
index 000000000000..b5282d3d6129
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-03-08-02-45-46.gh-issue-91896.kgON_a.rst
@@ -0,0 +1 @@
+Deprecate :class:`collections.abc.ByteString`



More information about the Python-checkins mailing list