Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 13 commits into from
May 4, 2023
6 changes: 6 additions & 0 deletions Doc/library/collections.abc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.
hauntsaninja marked this conversation as resolved.
Show resolved Hide resolved
For use in typing, prefer a union, like ``bytes | bytearray``, or
:class:`collections.abc.Buffer`.
hauntsaninja marked this conversation as resolved.
Show resolved Hide resolved
For use as an ABC, prefer :class:`Sequence` or :class:`collections.abc.Buffer`.

.. class:: Set
MutableSet

Expand Down
3 changes: 1 addition & 2 deletions Doc/library/typing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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])

Expand Down
5 changes: 5 additions & 0 deletions Doc/whatsnew/3.12.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
hugovk marked this conversation as resolved.
Show resolved Hide resolved
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.

Expand Down
23 changes: 21 additions & 2 deletions Lib/_collections_abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
hauntsaninja marked this conversation as resolved.
Show resolved Hide resolved
"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):
hauntsaninja marked this conversation as resolved.
Show resolved Hide resolved
"""This unifies bytes and bytearray.

XXX Should add all their methods.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can also remove this comment.

Expand Down
19 changes: 15 additions & 4 deletions Lib/test/test_collections.py
Original file line number Diff line number Diff line change
Expand Up @@ -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]:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Deprecate :class:`collections.abc.ByteString`
hugovk marked this conversation as resolved.
Show resolved Hide resolved