https://github.com/python/cpython/commit/530ddd3e06a425b8bb9e8afb657dc7711a5aa2f9
commit: 530ddd3e06a425b8bb9e8afb657dc7711a5aa2f9
branch: main
author: Alex Waygood <[email protected]>
committer: AlexWaygood <[email protected]>
date: 2025-09-16T16:48:19+01:00
summary:
Revert "gh-118803: Remove `ByteString` from `typing` and `collections.abc`
(#118804)" (#138990)
files:
A Misc/NEWS.d/next/Library/2025-09-16-15-56-29.gh-issue-118803.aOPtmL.rst
M Doc/deprecations/pending-removal-in-3.14.rst
M Doc/deprecations/pending-removal-in-3.17.rst
M Doc/library/collections.abc.rst
M Doc/library/stdtypes.rst
M Doc/library/typing.rst
M Doc/whatsnew/3.12.rst
M Doc/whatsnew/3.14.rst
M Doc/whatsnew/3.5.rst
M Lib/_collections_abc.py
M Lib/test/test_collections.py
M Lib/test/test_typing.py
M Lib/typing.py
diff --git a/Doc/deprecations/pending-removal-in-3.14.rst
b/Doc/deprecations/pending-removal-in-3.14.rst
index 9aac10840a663f..171758156ab117 100644
--- a/Doc/deprecations/pending-removal-in-3.14.rst
+++ b/Doc/deprecations/pending-removal-in-3.14.rst
@@ -38,12 +38,6 @@ Pending removal in Python 3.14
is no current event loop set and it decides to create one.
(Contributed by Serhiy Storchaka and Guido van Rossum in :gh:`100160`.)
-* :mod:`collections.abc`: 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`.)
-
* :mod:`email`: Deprecated the *isdst* parameter in
:func:`email.utils.localtime`.
(Contributed by Alan Williams in :gh:`72346`.)
@@ -96,9 +90,6 @@ Pending removal in Python 3.14
if :ref:`named placeholders <sqlite3-placeholders>` are used and
*parameters* is a sequence instead of a :class:`dict`.
-* :mod:`typing`: :class:`!typing.ByteString`, deprecated since Python 3.9,
- now causes a :exc:`DeprecationWarning` to be emitted when it is used.
-
* :mod:`urllib`:
:class:`!urllib.parse.Quoter` is deprecated: it was not intended to be a
public API.
diff --git a/Doc/deprecations/pending-removal-in-3.17.rst
b/Doc/deprecations/pending-removal-in-3.17.rst
index 370b98307e5228..4fd4bde24d42b3 100644
--- a/Doc/deprecations/pending-removal-in-3.17.rst
+++ b/Doc/deprecations/pending-removal-in-3.17.rst
@@ -8,3 +8,15 @@ Pending removal in Python 3.17
but it has been retained for backward compatibility, with removal
scheduled for Python
3.17. Users should use documented introspection helpers like
:func:`typing.get_origin`
and :func:`typing.get_args` instead of relying on private implementation
details.
+ - :class:`typing.ByteString`, deprecated since Python 3.9, is scheduled for
removal in
+ Python 3.17. Prefer :class:`~collections.abc.Sequence` or
+ :class:`~collections.abc.Buffer`. For use in type annotations, prefer a
union, like
+ ``bytes | bytearray``, or :class:`collections.abc.Buffer`.
+ (Contributed by Shantanu Jain in :gh:`91896`.)
+
+* :mod:`collections.abc`:
+
+ - :class:`collections.abc.ByteString` is scheduled for removal in Python
3.17. Prefer
+ :class:`~collections.abc.Sequence` or :class:`~collections.abc.Buffer`.
For use in
+ type annotations, prefer a union, like ``bytes | bytearray``, or
+ :class:`collections.abc.Buffer`. (Contributed by Shantanu Jain in
:gh:`91896`.)
diff --git a/Doc/library/collections.abc.rst b/Doc/library/collections.abc.rst
index db9277ff09bdbf..9deaaee06a6bec 100644
--- a/Doc/library/collections.abc.rst
+++ b/Doc/library/collections.abc.rst
@@ -140,6 +140,9 @@ ABC Inherits from
Abstract Methods Mi
``__len__``,
``insert``
+:class:`ByteString` :class:`Sequence` ``__getitem__``,
Inherited :class:`Sequence` methods
+ ``__len__``
+
:class:`Set` :class:`Collection` ``__contains__``,
``__le__``, ``__lt__``, ``__eq__``, ``__ne__``,
``__iter__``,
``__gt__``, ``__ge__``, ``__and__``, ``__or__``,
``__len__``
``__sub__``, ``__rsub__``, ``__xor__``, ``__rxor__``
@@ -260,6 +263,7 @@ Collections Abstract Base Classes -- Detailed Descriptions
.. class:: Sequence
MutableSequence
+ ByteString
ABCs for read-only and mutable :term:`sequences <sequence>`.
@@ -285,6 +289,12 @@ Collections Abstract Base Classes -- Detailed Descriptions
The :meth:`~sequence.index` method gained support for
the *stop* and *start* arguments.
+ .. deprecated-removed:: 3.12 3.17
+ The :class:`ByteString` ABC has been deprecated.
+ For use in type annotations, 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/stdtypes.rst b/Doc/library/stdtypes.rst
index bc4036a6795a13..21fe35edc1bef8 100644
--- a/Doc/library/stdtypes.rst
+++ b/Doc/library/stdtypes.rst
@@ -5544,6 +5544,7 @@ list is non-exhaustive.
* :class:`collections.abc.MutableMapping`
* :class:`collections.abc.Sequence`
* :class:`collections.abc.MutableSequence`
+* :class:`collections.abc.ByteString`
* :class:`collections.abc.MappingView`
* :class:`collections.abc.KeysView`
* :class:`collections.abc.ItemsView`
diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst
index 022c76b084c08c..ef8752fea3bb6b 100644
--- a/Doc/library/typing.rst
+++ b/Doc/library/typing.rst
@@ -3788,6 +3788,14 @@ Aliases to container ABCs in :mod:`collections.abc`
:class:`collections.abc.Set` now supports subscripting (``[]``).
See :pep:`585` and :ref:`types-genericalias`.
+.. class:: ByteString(Sequence[int])
+
+ This type represents the types :class:`bytes`, :class:`bytearray`,
+ and :class:`memoryview` of byte sequences.
+
+ .. deprecated-removed:: 3.9 3.17
+ Prefer :class:`collections.abc.Buffer`, or a union like ``bytes |
bytearray | memoryview``.
+
.. class:: Collection(Sized, Iterable[T_co], Container[T_co])
Deprecated alias to :class:`collections.abc.Collection`.
@@ -4081,6 +4089,10 @@ convenience. This is subject to change, and not all
deprecations are listed.
- 3.9
- Undecided (see :ref:`deprecated-aliases` for more information)
- :pep:`585`
+ * - :class:`typing.ByteString`
+ - 3.9
+ - 3.17
+ - :gh:`91896`
* - :data:`typing.Text`
- 3.11
- Undecided
diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst
index 7cfdc287b7fad7..8e0cb652a73b03 100644
--- a/Doc/whatsnew/3.12.rst
+++ b/Doc/whatsnew/3.12.rst
@@ -1191,9 +1191,9 @@ Deprecated
replaced by :data:`calendar.JANUARY` and :data:`calendar.FEBRUARY`.
(Contributed by Prince Roshan in :gh:`103636`.)
-* :mod:`collections.abc`: Deprecated :class:`!collections.abc.ByteString`.
+* :mod:`collections.abc`: 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`.
+ For use in type annotations, prefer a union, like ``bytes | bytearray``, or
:class:`collections.abc.Buffer`.
(Contributed by Shantanu Jain in :gh:`91896`.)
* :mod:`datetime`: :class:`datetime.datetime`'s
:meth:`~datetime.datetime.utcnow` and
@@ -1301,7 +1301,7 @@ Deprecated
:class:`collections.abc.Hashable` and :class:`collections.abc.Sized`
respectively, are
deprecated. (:gh:`94309`.)
- * :class:`!typing.ByteString`, deprecated since Python 3.9, now causes a
+ * :class:`typing.ByteString`, deprecated since Python 3.9, now causes a
:exc:`DeprecationWarning` to be emitted when it is used.
(Contributed by Alex Waygood in :gh:`91896`.)
diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst
index 5462c5dc425e2e..e8695f1db33281 100644
--- a/Doc/whatsnew/3.14.rst
+++ b/Doc/whatsnew/3.14.rst
@@ -2560,15 +2560,6 @@ asyncio
blocking_code()
runner.run(operation_two())
-
-collections.abc
----------------
-
-* Remove :class:`!ByteString`, which has been deprecated since Python 3.12.
- (Contributed by Nikita Sobolev in :gh:`118803`.)
-
-
-
email
-----
@@ -2647,13 +2638,6 @@ sqlite3
(Contributed by Erlend E. Aasland in :gh:`118928` and :gh:`101693`.)
-typing
-------
-
-* Remove :class:`!ByteString`, which has been deprecated since Python 3.12.
- (Contributed by Nikita Sobolev in :gh:`118803`.)
-
-
urllib
------
diff --git a/Doc/whatsnew/3.5.rst b/Doc/whatsnew/3.5.rst
index 59e8ecebb10444..6009dd8a71eea5 100644
--- a/Doc/whatsnew/3.5.rst
+++ b/Doc/whatsnew/3.5.rst
@@ -936,7 +936,7 @@ methods to match the corresponding methods of :class:`str`.
collections.abc
---------------
-The :meth:`Sequence.index() <collections.abc.MutableSequence.index>` method now
+The :meth:`!Sequence.index` method now
accepts *start* and *stop* arguments to match the corresponding methods
of :class:`tuple`, :class:`list`, etc.
(Contributed by Devin Jeanpierre in :issue:`23086`.)
diff --git a/Lib/_collections_abc.py b/Lib/_collections_abc.py
index 51263d696a1777..28427077127890 100644
--- a/Lib/_collections_abc.py
+++ b/Lib/_collections_abc.py
@@ -49,7 +49,7 @@ def _f(): pass
"Mapping", "MutableMapping",
"MappingView", "KeysView", "ItemsView", "ValuesView",
"Sequence", "MutableSequence",
- "Buffer",
+ "ByteString", "Buffer",
]
# This module has been renamed from collections.abc to _collections_abc to
@@ -1061,6 +1061,37 @@ def count(self, value):
Sequence.register(range)
Sequence.register(memoryview)
+class _DeprecateByteStringMeta(ABCMeta):
+ def __new__(cls, name, bases, namespace, **kwargs):
+ if name != "ByteString":
+ import warnings
+
+ warnings._deprecated(
+ "collections.abc.ByteString",
+ remove=(3, 17),
+ )
+ return super().__new__(cls, name, bases, namespace, **kwargs)
+
+ def __instancecheck__(cls, instance):
+ import warnings
+
+ warnings._deprecated(
+ "collections.abc.ByteString",
+ remove=(3, 17),
+ )
+ return super().__instancecheck__(instance)
+
+class ByteString(Sequence, metaclass=_DeprecateByteStringMeta):
+ """This unifies bytes and bytearray.
+
+ XXX Should add all their methods.
+ """
+
+ __slots__ = ()
+
+ByteString.register(bytes)
+ByteString.register(bytearray)
+
class MutableSequence(Sequence):
"""All the operations on a read-write sequence.
diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py
index f33e4b3256a9b9..3dac736e0189b1 100644
--- a/Lib/test/test_collections.py
+++ b/Lib/test/test_collections.py
@@ -26,7 +26,7 @@
from collections.abc import Set, MutableSet
from collections.abc import Mapping, MutableMapping, KeysView, ItemsView,
ValuesView
from collections.abc import Sequence, MutableSequence
-from collections.abc import Buffer
+from collections.abc import ByteString, Buffer
class TestUserObjects(unittest.TestCase):
@@ -1934,6 +1934,28 @@ def assert_index_same(seq1, seq2, index_args):
assert_index_same(
nativeseq, seqseq, (letter, start, stop))
+ def test_ByteString(self):
+ for sample in [bytes, bytearray]:
+ with self.assertWarns(DeprecationWarning):
+ self.assertIsInstance(sample(), ByteString)
+ self.assertTrue(issubclass(sample, ByteString))
+ for sample in [str, list, tuple]:
+ with self.assertWarns(DeprecationWarning):
+ self.assertNotIsInstance(sample(), ByteString)
+ self.assertFalse(issubclass(sample, ByteString))
+ with self.assertWarns(DeprecationWarning):
+ self.assertNotIsInstance(memoryview(b""), ByteString)
+ self.assertFalse(issubclass(memoryview, ByteString))
+ 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]:
self.assertIsInstance(sample(b"x"), Buffer)
diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py
index d776a019795582..6ea1f2a35d615d 100644
--- a/Lib/test/test_typing.py
+++ b/Lib/test/test_typing.py
@@ -7499,6 +7499,16 @@ def test_mutablesequence(self):
self.assertIsInstance([], typing.MutableSequence)
self.assertNotIsInstance((), typing.MutableSequence)
+ def test_bytestring(self):
+ with self.assertWarns(DeprecationWarning):
+ self.assertIsInstance(b'', typing.ByteString)
+ with self.assertWarns(DeprecationWarning):
+ self.assertIsInstance(bytearray(b''), typing.ByteString)
+ with self.assertWarns(DeprecationWarning):
+ class Foo(typing.ByteString): ...
+ with self.assertWarns(DeprecationWarning):
+ class Bar(typing.ByteString, typing.Awaitable): ...
+
def test_list(self):
self.assertIsSubclass(list, typing.List)
@@ -10453,6 +10463,7 @@ def test_special_attrs(self):
typing.AsyncIterable: 'AsyncIterable',
typing.AsyncIterator: 'AsyncIterator',
typing.Awaitable: 'Awaitable',
+ typing.ByteString: 'ByteString',
typing.Callable: 'Callable',
typing.ChainMap: 'ChainMap',
typing.Collection: 'Collection',
diff --git a/Lib/typing.py b/Lib/typing.py
index 0554343c8e3a0e..a1bf2c9cb09747 100644
--- a/Lib/typing.py
+++ b/Lib/typing.py
@@ -65,6 +65,7 @@
# ABCs (from collections.abc).
'AbstractSet', # collections.abc.Set.
+ 'ByteString',
'Container',
'ContextManager',
'Hashable',
@@ -1602,6 +1603,21 @@ def __ror__(self, left):
return Union[left, self]
+class _DeprecatedGenericAlias(_SpecialGenericAlias, _root=True):
+ def __init__(
+ self, origin, nparams, *, removal_version, inst=True, name=None
+ ):
+ super().__init__(origin, nparams, inst=inst, name=name)
+ self._removal_version = removal_version
+
+ def __instancecheck__(self, inst):
+ import warnings
+ warnings._deprecated(
+ f"{self.__module__}.{self._name}", remove=self._removal_version
+ )
+ return super().__instancecheck__(inst)
+
+
class _CallableGenericAlias(_NotIterable, _GenericAlias, _root=True):
def __repr__(self):
assert self._name == 'Callable'
@@ -2789,6 +2805,9 @@ class Other(Leaf): # Error reported by type checker
MutableMapping = _alias(collections.abc.MutableMapping, 2)
Sequence = _alias(collections.abc.Sequence, 1)
MutableSequence = _alias(collections.abc.MutableSequence, 1)
+ByteString = _DeprecatedGenericAlias(
+ collections.abc.ByteString, 0, removal_version=(3, 17) # Not generic.
+)
# Tuple accepts variable number of parameters.
Tuple = _TupleType(tuple, -1, inst=False, name='Tuple')
Tuple.__doc__ = \
diff --git
a/Misc/NEWS.d/next/Library/2025-09-16-15-56-29.gh-issue-118803.aOPtmL.rst
b/Misc/NEWS.d/next/Library/2025-09-16-15-56-29.gh-issue-118803.aOPtmL.rst
new file mode 100644
index 00000000000000..0fa8f5c35c9ed3
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-09-16-15-56-29.gh-issue-118803.aOPtmL.rst
@@ -0,0 +1,3 @@
+Add back :class:`collections.abc.ByteString` and :class:`typing.ByteString`.
+Both had been removed in prior alpha, beta and release candidates for Python
+3.14, but their removal has now been postponed to Python 3.17.
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]