Skip to content

gh-92871: Remove typing.{io,re} namespaces #92873

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

Merged
merged 8 commits into from
May 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 0 additions & 11 deletions Doc/library/typing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2074,10 +2074,6 @@ Other concrete types
represent the types of I/O streams such as returned by
:func:`open`.

.. deprecated-removed:: 3.8 3.13
The ``typing.io`` namespace is deprecated and will be removed.
These types should be directly imported from ``typing`` instead.

.. class:: Pattern
Match

Expand All @@ -2088,10 +2084,6 @@ Other concrete types
``Pattern[str]``, ``Pattern[bytes]``, ``Match[str]``, or
``Match[bytes]``.

.. deprecated-removed:: 3.8 3.13
The ``typing.re`` namespace is deprecated and will be removed.
These types should be directly imported from ``typing`` instead.

.. deprecated:: 3.9
Classes ``Pattern`` and ``Match`` from :mod:`re` now support ``[]``.
See :pep:`585` and :ref:`types-genericalias`.
Expand Down Expand Up @@ -2981,9 +2973,6 @@ convenience. This is subject to change, and not all deprecations are listed.
+----------------------------------+---------------+-------------------+----------------+
| Feature | Deprecated in | Projected removal | PEP/issue |
+==================================+===============+===================+================+
| ``typing.io`` and ``typing.re`` | 3.8 | 3.13 | :issue:`38291` |
| submodules | | | |
+----------------------------------+---------------+-------------------+----------------+
| ``typing`` versions of standard | 3.9 | Undecided | :pep:`585` |
| collections | | | |
+----------------------------------+---------------+-------------------+----------------+
Expand Down
3 changes: 3 additions & 0 deletions Doc/whatsnew/3.13.rst
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ Removed
`Exscript <https://pypi.org/project/Exscript/>`_ instead.
(Contributed by Victor Stinner in :gh:`104773`.)

* Namespaces ``typing.io`` and ``typing.re``, deprecated in Python 3.8,
are now removed. The items in those namespaces can be imported directly
from :mod:`typing`. (Contributed by Sebastian Rittau in :gh:`92871`.)

Porting to Python 3.13
======================
Expand Down
24 changes: 1 addition & 23 deletions Lib/test/test_typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -7529,17 +7529,6 @@ def stuff(a: BinaryIO) -> bytes:
a = stuff.__annotations__['a']
self.assertEqual(a.__parameters__, ())

def test_io_submodule(self):
with warnings.catch_warnings(record=True) as w:
warnings.filterwarnings("default", category=DeprecationWarning)
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):
# Much of this is really testing _TypeAlias.
Expand Down Expand Up @@ -7584,16 +7573,6 @@ def test_repr(self):
self.assertEqual(repr(Match[str]), 'typing.Match[str]')
self.assertEqual(repr(Match[bytes]), 'typing.Match[bytes]')

def test_re_submodule(self):
with warnings.catch_warnings(record=True) as w:
warnings.filterwarnings("default", category=DeprecationWarning)
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.assertRaisesRegex(
TypeError,
Expand Down Expand Up @@ -8765,7 +8744,7 @@ def test_all(self):
# Context managers.
self.assertIn('ContextManager', a)
self.assertIn('AsyncContextManager', a)
# Check that io and re are not exported.
# Check that former namespaces io and re are not exported.
self.assertNotIn('io', a)
self.assertNotIn('re', a)
# Spot-check that stdlib modules aren't exported.
Expand All @@ -8785,7 +8764,6 @@ def test_all_exported_names(self):
if k in actual_all or (
# avoid private names
not k.startswith('_') and
k not in {'io', 're'} and
# there's a few types and metaclasses that aren't exported
not k.endswith(('Meta', '_contra', '_co')) and
not k.upper() == k and
Expand Down
43 changes: 1 addition & 42 deletions Lib/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
no_type_check_decorator.
* Generic aliases for collections.abc ABCs and few additional protocols.
* Special types: NewType, NamedTuple, TypedDict.
* Wrapper submodules for re and io related types.
"""

from abc import abstractmethod, ABCMeta
Expand All @@ -27,7 +26,7 @@
import contextlib
import functools
import operator
import re as stdlib_re # Avoid confusion with the re we export.
import re as stdlib_re # Avoid confusion with the typing.re namespace on <=3.11
import sys
import types
import warnings
Expand Down Expand Up @@ -158,10 +157,6 @@
'Unpack',
]

# The pseudo-submodules 're' and 'io' are part of the public
# namespace, but excluded from __all__ because they might stomp on
# legitimate imports of those modules.


def _type_convert(arg, module=None, *, allow_special_forms=False):
"""For converting None to type(None), and strings to ForwardRef."""
Expand Down Expand Up @@ -3150,45 +3145,9 @@ def __enter__(self) -> 'TextIO':
pass


class _DeprecatedType(type):
def __getattribute__(cls, name):
if name not in ("__dict__", "__module__") 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']
IO = IO
TextIO = TextIO
BinaryIO = BinaryIO


io.__name__ = __name__ + '.io'
sys.modules[io.__name__] = io

Pattern = _alias(stdlib_re.Pattern, 1)
Match = _alias(stdlib_re.Match, 1)

class re(metaclass=_DeprecatedType):
"""Wrapper namespace for re type aliases."""

__all__ = ['Pattern', 'Match']
Pattern = Pattern
Match = Match


re.__name__ = __name__ + '.re'
sys.modules[re.__name__] = re


def reveal_type[T](obj: T, /) -> T:
"""Reveal the inferred type of a variable.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Remove the ``typing.io`` and ``typing.re`` namespaces, deprecated since Python
3.8. All items are still available from the main :mod:`typing` module.