mirror of
https://github.com/python/cpython.git
synced 2025-09-27 18:59:43 +00:00
gh-91896: Improve visibility of ByteString
deprecation warnings (#104294)
This commit is contained in:
parent
a0a98ddb31
commit
f0f5bb3204
5 changed files with 85 additions and 12 deletions
|
@ -1,3 +1,12 @@
|
||||||
from _collections_abc import *
|
from _collections_abc import *
|
||||||
from _collections_abc import __all__
|
from _collections_abc import __all__
|
||||||
from _collections_abc import _CallableGenericAlias
|
from _collections_abc import _CallableGenericAlias
|
||||||
|
|
||||||
|
_deprecated_ByteString = globals().pop("ByteString")
|
||||||
|
|
||||||
|
def __getattr__(attr):
|
||||||
|
if attr == "ByteString":
|
||||||
|
import warnings
|
||||||
|
warnings._deprecated("collections.abc.ByteString", remove=(3, 14))
|
||||||
|
return _deprecated_ByteString
|
||||||
|
raise AttributeError(f"module 'collections.abc' has no attribute {attr!r}")
|
||||||
|
|
|
@ -48,6 +48,8 @@ def dash_R(ns, test_name, test_func):
|
||||||
else:
|
else:
|
||||||
zdc = zipimport._zip_directory_cache.copy()
|
zdc = zipimport._zip_directory_cache.copy()
|
||||||
abcs = {}
|
abcs = {}
|
||||||
|
# catch and ignore collections.abc.ByteString deprecation
|
||||||
|
with warnings.catch_warnings(action='ignore', category=DeprecationWarning):
|
||||||
for abc in [getattr(collections.abc, a) for a in collections.abc.__all__]:
|
for abc in [getattr(collections.abc, a) for a in collections.abc.__all__]:
|
||||||
if not isabstract(abc):
|
if not isabstract(abc):
|
||||||
continue
|
continue
|
||||||
|
@ -173,6 +175,8 @@ def dash_R_cleanup(fs, ps, pic, zdc, abcs):
|
||||||
zipimport._zip_directory_cache.update(zdc)
|
zipimport._zip_directory_cache.update(zdc)
|
||||||
|
|
||||||
# Clear ABC registries, restoring previously saved ABC registries.
|
# Clear ABC registries, restoring previously saved ABC registries.
|
||||||
|
# ignore deprecation warning for collections.abc.ByteString
|
||||||
|
with warnings.catch_warnings(action='ignore', category=DeprecationWarning):
|
||||||
abs_classes = [getattr(collections.abc, a) for a in collections.abc.__all__]
|
abs_classes = [getattr(collections.abc, a) for a in collections.abc.__all__]
|
||||||
abs_classes = filter(isabstract, abs_classes)
|
abs_classes = filter(isabstract, abs_classes)
|
||||||
for abc in abs_classes:
|
for abc in abs_classes:
|
||||||
|
|
|
@ -11,6 +11,7 @@ from itertools import product, chain, combinations
|
||||||
import string
|
import string
|
||||||
import sys
|
import sys
|
||||||
from test import support
|
from test import support
|
||||||
|
from test.support.import_helper import import_fresh_module
|
||||||
import types
|
import types
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
|
@ -25,7 +26,7 @@ from collections.abc import Sized, Container, Callable, Collection
|
||||||
from collections.abc import Set, MutableSet
|
from collections.abc import Set, MutableSet
|
||||||
from collections.abc import Mapping, MutableMapping, KeysView, ItemsView, ValuesView
|
from collections.abc import Mapping, MutableMapping, KeysView, ItemsView, ValuesView
|
||||||
from collections.abc import Sequence, MutableSequence
|
from collections.abc import Sequence, MutableSequence
|
||||||
from collections.abc import ByteString, Buffer
|
from collections.abc import Buffer
|
||||||
|
|
||||||
|
|
||||||
class TestUserObjects(unittest.TestCase):
|
class TestUserObjects(unittest.TestCase):
|
||||||
|
@ -1939,6 +1940,8 @@ class TestCollectionABCs(ABCTestCase):
|
||||||
nativeseq, seqseq, (letter, start, stop))
|
nativeseq, seqseq, (letter, start, stop))
|
||||||
|
|
||||||
def test_ByteString(self):
|
def test_ByteString(self):
|
||||||
|
with self.assertWarns(DeprecationWarning):
|
||||||
|
from collections.abc import ByteString
|
||||||
for sample in [bytes, bytearray]:
|
for sample in [bytes, bytearray]:
|
||||||
with self.assertWarns(DeprecationWarning):
|
with self.assertWarns(DeprecationWarning):
|
||||||
self.assertIsInstance(sample(), ByteString)
|
self.assertIsInstance(sample(), ByteString)
|
||||||
|
@ -1960,6 +1963,11 @@ class TestCollectionABCs(ABCTestCase):
|
||||||
# No metaclass conflict
|
# No metaclass conflict
|
||||||
class Z(ByteString, Awaitable): pass
|
class Z(ByteString, Awaitable): pass
|
||||||
|
|
||||||
|
def test_ByteString_attribute_access(self):
|
||||||
|
collections_abc = import_fresh_module("collections.abc")
|
||||||
|
with self.assertWarns(DeprecationWarning):
|
||||||
|
collections_abc.ByteString
|
||||||
|
|
||||||
def test_Buffer(self):
|
def test_Buffer(self):
|
||||||
for sample in [bytes, bytearray, memoryview]:
|
for sample in [bytes, bytearray, memoryview]:
|
||||||
self.assertIsInstance(sample(b"x"), Buffer)
|
self.assertIsInstance(sample(b"x"), Buffer)
|
||||||
|
|
|
@ -8,6 +8,7 @@ import pickle
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import warnings
|
import warnings
|
||||||
|
from test.support.import_helper import import_fresh_module
|
||||||
from unittest import TestCase, main, skipUnless, skip
|
from unittest import TestCase, main, skipUnless, skip
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
from copy import copy, deepcopy
|
from copy import copy, deepcopy
|
||||||
|
@ -3908,7 +3909,14 @@ class GenericTests(BaseTestCase):
|
||||||
self.assertEqual(MyChain[int]().__orig_class__, MyChain[int])
|
self.assertEqual(MyChain[int]().__orig_class__, MyChain[int])
|
||||||
|
|
||||||
def test_all_repr_eq_any(self):
|
def test_all_repr_eq_any(self):
|
||||||
objs = (getattr(typing, el) for el in typing.__all__)
|
typing = import_fresh_module("typing")
|
||||||
|
with warnings.catch_warnings(record=True) as wlog:
|
||||||
|
warnings.filterwarnings('always', '', DeprecationWarning)
|
||||||
|
objs = [getattr(typing, el) for el in typing.__all__]
|
||||||
|
self.assertEqual(
|
||||||
|
[str(w.message) for w in wlog],
|
||||||
|
["'typing.ByteString' is deprecated and slated for removal in Python 3.14"]
|
||||||
|
)
|
||||||
for obj in objs:
|
for obj in objs:
|
||||||
self.assertNotEqual(repr(obj), '')
|
self.assertNotEqual(repr(obj), '')
|
||||||
self.assertEqual(obj, obj)
|
self.assertEqual(obj, obj)
|
||||||
|
@ -5996,8 +6004,16 @@ class CollectionsAbcTests(BaseTestCase):
|
||||||
self.assertNotIsInstance((), typing.MutableSequence)
|
self.assertNotIsInstance((), typing.MutableSequence)
|
||||||
|
|
||||||
def test_bytestring(self):
|
def test_bytestring(self):
|
||||||
self.assertIsInstance(b'', typing.ByteString)
|
with self.assertWarns(DeprecationWarning):
|
||||||
self.assertIsInstance(bytearray(b''), typing.ByteString)
|
from typing import ByteString
|
||||||
|
with self.assertWarns(DeprecationWarning):
|
||||||
|
self.assertIsInstance(b'', ByteString)
|
||||||
|
with self.assertWarns(DeprecationWarning):
|
||||||
|
self.assertIsInstance(bytearray(b''), ByteString)
|
||||||
|
with self.assertWarns(DeprecationWarning):
|
||||||
|
class Foo(ByteString): ...
|
||||||
|
with self.assertWarns(DeprecationWarning):
|
||||||
|
class Bar(ByteString, typing.Awaitable): ...
|
||||||
|
|
||||||
def test_list(self):
|
def test_list(self):
|
||||||
self.assertIsSubclass(list, typing.List)
|
self.assertIsSubclass(list, typing.List)
|
||||||
|
@ -8293,6 +8309,10 @@ SpecialAttrsT = typing.TypeVar('SpecialAttrsT', int, float, complex)
|
||||||
class SpecialAttrsTests(BaseTestCase):
|
class SpecialAttrsTests(BaseTestCase):
|
||||||
|
|
||||||
def test_special_attrs(self):
|
def test_special_attrs(self):
|
||||||
|
with warnings.catch_warnings(
|
||||||
|
action='ignore', category=DeprecationWarning
|
||||||
|
):
|
||||||
|
typing_ByteString = typing.ByteString
|
||||||
cls_to_check = {
|
cls_to_check = {
|
||||||
# ABC classes
|
# ABC classes
|
||||||
typing.AbstractSet: 'AbstractSet',
|
typing.AbstractSet: 'AbstractSet',
|
||||||
|
@ -8301,7 +8321,7 @@ class SpecialAttrsTests(BaseTestCase):
|
||||||
typing.AsyncIterable: 'AsyncIterable',
|
typing.AsyncIterable: 'AsyncIterable',
|
||||||
typing.AsyncIterator: 'AsyncIterator',
|
typing.AsyncIterator: 'AsyncIterator',
|
||||||
typing.Awaitable: 'Awaitable',
|
typing.Awaitable: 'Awaitable',
|
||||||
typing.ByteString: 'ByteString',
|
typing_ByteString: 'ByteString',
|
||||||
typing.Callable: 'Callable',
|
typing.Callable: 'Callable',
|
||||||
typing.ChainMap: 'ChainMap',
|
typing.ChainMap: 'ChainMap',
|
||||||
typing.Collection: 'Collection',
|
typing.Collection: 'Collection',
|
||||||
|
@ -8626,6 +8646,8 @@ class AllTests(BaseTestCase):
|
||||||
getattr(v, '__module__', None) == typing.__name__
|
getattr(v, '__module__', None) == typing.__name__
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
# Deprecated; added dynamically via module __getattr__
|
||||||
|
computed_all.add("ByteString")
|
||||||
self.assertSetEqual(computed_all, actual_all)
|
self.assertSetEqual(computed_all, actual_all)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1599,6 +1599,22 @@ class _SpecialGenericAlias(_NotIterable, _BaseGenericAlias, _root=True):
|
||||||
def __ror__(self, left):
|
def __ror__(self, left):
|
||||||
return Union[left, self]
|
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):
|
class _CallableGenericAlias(_NotIterable, _GenericAlias, _root=True):
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
assert self._name == 'Callable'
|
assert self._name == 'Callable'
|
||||||
|
@ -2756,7 +2772,6 @@ Mapping = _alias(collections.abc.Mapping, 2)
|
||||||
MutableMapping = _alias(collections.abc.MutableMapping, 2)
|
MutableMapping = _alias(collections.abc.MutableMapping, 2)
|
||||||
Sequence = _alias(collections.abc.Sequence, 1)
|
Sequence = _alias(collections.abc.Sequence, 1)
|
||||||
MutableSequence = _alias(collections.abc.MutableSequence, 1)
|
MutableSequence = _alias(collections.abc.MutableSequence, 1)
|
||||||
ByteString = _alias(collections.abc.ByteString, 0) # Not generic
|
|
||||||
# Tuple accepts variable number of parameters.
|
# Tuple accepts variable number of parameters.
|
||||||
Tuple = _TupleType(tuple, -1, inst=False, name='Tuple')
|
Tuple = _TupleType(tuple, -1, inst=False, name='Tuple')
|
||||||
Tuple.__doc__ = \
|
Tuple.__doc__ = \
|
||||||
|
@ -3556,3 +3571,18 @@ def override(method: F, /) -> F:
|
||||||
# read-only property, TypeError if it's a builtin class.
|
# read-only property, TypeError if it's a builtin class.
|
||||||
pass
|
pass
|
||||||
return method
|
return method
|
||||||
|
|
||||||
|
|
||||||
|
def __getattr__(attr):
|
||||||
|
if attr == "ByteString":
|
||||||
|
import warnings
|
||||||
|
warnings._deprecated("typing.ByteString", remove=(3, 14))
|
||||||
|
with warnings.catch_warnings(
|
||||||
|
action="ignore", category=DeprecationWarning
|
||||||
|
):
|
||||||
|
# Not generic
|
||||||
|
ByteString = globals()["ByteString"] = _DeprecatedGenericAlias(
|
||||||
|
collections.abc.ByteString, 0, removal_version=(3, 14)
|
||||||
|
)
|
||||||
|
return ByteString
|
||||||
|
raise AttributeError(f"module 'typing' has no attribute {attr!r}")
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue