]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-38291: DeprecationWarning when importing typing.{io,re} (#26719)
authorSebastian Rittau <srittau@rittau.biz>
Sat, 19 Jun 2021 17:31:18 +0000 (19:31 +0200)
committerGitHub <noreply@github.com>
Sat, 19 Jun 2021 17:31:18 +0000 (10:31 -0700)
Lib/importlib/resources.py
Lib/test/test_typing.py
Lib/typing.py
Misc/NEWS.d/next/Library/2021-06-14-14-19-11.bpo-38291.ee4cSX.rst [new file with mode: 0644]

index 8a98663ff8e6d5e9c53b4cb292778fe2ff95fd30..bb5c354d9f00ab7ab76e62a81995415e09efa94e 100644 (file)
@@ -11,8 +11,7 @@ from io import BytesIO, TextIOWrapper
 from pathlib import Path
 from types import ModuleType
 from typing import ContextManager, Iterable, Union
-from typing import cast
-from typing.io import BinaryIO, TextIO
+from typing import cast, BinaryIO, TextIO
 from collections.abc import Sequence
 from functools import singledispatch
 
index 79c5c3a910407500c32cf3c6eb1690aceb53427e..06df3e23264cb2455aefee1ef08d8ae6ea21fcc1 100644 (file)
@@ -3,6 +3,7 @@ import collections
 import pickle
 import re
 import sys
+import warnings
 from unittest import TestCase, main, skipUnless, skip
 from copy import copy, deepcopy
 
@@ -1976,7 +1977,7 @@ class GenericTests(BaseTestCase):
         T = TypeVar('T')
         things = [Any, Union[T, int], Callable[..., T], Tuple[Any, Any],
                   Optional[List[int]], typing.Mapping[int, str],
-                  typing.re.Match[bytes], typing.Iterable['whatever']]
+                  typing.Match[bytes], typing.Iterable['whatever']]
         for t in things:
             self.assertEqual(weakref.ref(t)(), t)
 
@@ -3996,12 +3997,14 @@ class IOTests(BaseTestCase):
         self.assertEqual(a.__parameters__, ())
 
     def test_io_submodule(self):
-        from typing.io import IO, TextIO, BinaryIO, __all__, __name__
-        self.assertIs(IO, typing.IO)
-        self.assertIs(TextIO, typing.TextIO)
-        self.assertIs(BinaryIO, typing.BinaryIO)
-        self.assertEqual(set(__all__), set(['IO', 'TextIO', 'BinaryIO']))
-        self.assertEqual(__name__, 'typing.io')
+        with warnings.catch_warnings(record=True) as w:
+            from typing.io import IO, TextIO, BinaryIO, __all__, __name__
+            self.assertIs(IO, typing.IO)
+            self.assertIs(TextIO, typing.TextIO)
+            self.assertIs(BinaryIO, typing.BinaryIO)
+            self.assertEqual(set(__all__), set(['IO', 'TextIO', 'BinaryIO']))
+            self.assertEqual(__name__, 'typing.io')
+            self.assertEqual(len(w), 1)
 
 
 class RETests(BaseTestCase):
@@ -4048,11 +4051,13 @@ class RETests(BaseTestCase):
         self.assertEqual(repr(Match[bytes]), 'typing.Match[bytes]')
 
     def test_re_submodule(self):
-        from typing.re import Match, Pattern, __all__, __name__
-        self.assertIs(Match, typing.Match)
-        self.assertIs(Pattern, typing.Pattern)
-        self.assertEqual(set(__all__), set(['Match', 'Pattern']))
-        self.assertEqual(__name__, 'typing.re')
+        with warnings.catch_warnings(record=True) as w:
+            from typing.re import Match, Pattern, __all__, __name__
+            self.assertIs(Match, typing.Match)
+            self.assertIs(Pattern, typing.Pattern)
+            self.assertEqual(set(__all__), set(['Match', 'Pattern']))
+            self.assertEqual(__name__, 'typing.re')
+            self.assertEqual(len(w), 1)
 
     def test_cannot_subclass(self):
         with self.assertRaises(TypeError) as ex:
index 8fadb571f41dc2d8fc7a0a0565ce3901b1b752ac..00a0df591cbfccd5c120314c0626a3d588913379 100644 (file)
@@ -28,6 +28,7 @@ import operator
 import re as stdlib_re  # Avoid confusion with the re we export.
 import sys
 import types
+import warnings
 from types import WrapperDescriptorType, MethodWrapperType, MethodDescriptorType, GenericAlias
 
 # Please keep __all__ alphabetized within each category.
@@ -2512,7 +2513,20 @@ class TextIO(IO[str]):
         pass
 
 
-class io:
+class _DeprecatedType(type):
+    def __getattribute__(cls, name):
+        if name != "__dict__" and name in cls.__dict__:
+            warnings.warn(
+                f"{cls.__name__} is deprecated, import directly "
+                f"from typing instead. {cls.__name__} will be removed "
+                "in Python 3.12.",
+                DeprecationWarning,
+                stacklevel=2,
+            )
+        return super().__getattribute__(name)
+
+
+class io(metaclass=_DeprecatedType):
     """Wrapper namespace for IO generic classes."""
 
     __all__ = ['IO', 'TextIO', 'BinaryIO']
@@ -2527,7 +2541,7 @@ sys.modules[io.__name__] = io
 Pattern = _alias(stdlib_re.Pattern, 1)
 Match = _alias(stdlib_re.Match, 1)
 
-class re:
+class re(metaclass=_DeprecatedType):
     """Wrapper namespace for re type aliases."""
 
     __all__ = ['Pattern', 'Match']
diff --git a/Misc/NEWS.d/next/Library/2021-06-14-14-19-11.bpo-38291.ee4cSX.rst b/Misc/NEWS.d/next/Library/2021-06-14-14-19-11.bpo-38291.ee4cSX.rst
new file mode 100644 (file)
index 0000000..7fb891d
--- /dev/null
@@ -0,0 +1 @@
+Importing typing.io or typing.re now prints a `DeprecationWarning`.