[Python-checkins] bpo-38291: DeprecationWarning when importing typing.{io, re} (#26719)

gvanrossum webhook-mailer at python.org
Sat Jun 19 13:31:28 EDT 2021


https://github.com/python/cpython/commit/09eb81711597725f853e4f3b659ce185488b0d8c
commit: 09eb81711597725f853e4f3b659ce185488b0d8c
branch: main
author: Sebastian Rittau <srittau at rittau.biz>
committer: gvanrossum <gvanrossum at gmail.com>
date: 2021-06-19T10:31:18-07:00
summary:

bpo-38291: DeprecationWarning when importing typing.{io,re} (#26719)

files:
A Misc/NEWS.d/next/Library/2021-06-14-14-19-11.bpo-38291.ee4cSX.rst
M Lib/importlib/resources.py
M Lib/test/test_typing.py
M Lib/typing.py

diff --git a/Lib/importlib/resources.py b/Lib/importlib/resources.py
index 8a98663ff8e6d..bb5c354d9f00a 100644
--- a/Lib/importlib/resources.py
+++ b/Lib/importlib/resources.py
@@ -11,8 +11,7 @@
 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
 
diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py
index 79c5c3a910407..06df3e23264cb 100644
--- a/Lib/test/test_typing.py
+++ b/Lib/test/test_typing.py
@@ -3,6 +3,7 @@
 import pickle
 import re
 import sys
+import warnings
 from unittest import TestCase, main, skipUnless, skip
 from copy import copy, deepcopy
 
@@ -1976,7 +1977,7 @@ def test_weakref_all(self):
         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 @@ def stuff(a: BinaryIO) -> bytes:
         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 @@ def test_repr(self):
         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:
diff --git a/Lib/typing.py b/Lib/typing.py
index 8fadb571f41dc..00a0df591cbfc 100644
--- a/Lib/typing.py
+++ b/Lib/typing.py
@@ -28,6 +28,7 @@
 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 @@ def __enter__(self) -> 'TextIO':
         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 @@ class 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
index 0000000000000..7fb891dd4bc0c
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2021-06-14-14-19-11.bpo-38291.ee4cSX.rst
@@ -0,0 +1 @@
+Importing typing.io or typing.re now prints a `DeprecationWarning`.



More information about the Python-checkins mailing list