[Python-checkins] bpo-44353: Refactor typing.NewType into callable class (GH-27250) (#27258)
ambv
webhook-mailer at python.org
Tue Jul 20 11:25:06 EDT 2021
https://github.com/python/cpython/commit/c2f33dfc83ab270412bf243fb21f724037effa1a
commit: c2f33dfc83ab270412bf243fb21f724037effa1a
branch: 3.10
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: ambv <lukasz at langa.pl>
date: 2021-07-20T17:24:57+02:00
summary:
bpo-44353: Refactor typing.NewType into callable class (GH-27250) (#27258)
(cherry picked from commit 965dd76e9060e27e2253ba8c8d21a142b178720d)
Co-authored-by: Yurii Karabas <1998uriyyo at gmail.com>
files:
A Misc/NEWS.d/next/Library/2021-07-19-22-43-15.bpo-44353.HF81_Q.rst
M Lib/test/test_typing.py
M Lib/typing.py
diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py
index ad7f385e40794..3a28be1d7f56b 100644
--- a/Lib/test/test_typing.py
+++ b/Lib/test/test_typing.py
@@ -3690,6 +3690,26 @@ def test_errors(self):
class D(UserName):
pass
+ def test_or(self):
+ UserId = NewType('UserId', int)
+
+ self.assertEqual(UserId | int, Union[UserId, int])
+ self.assertEqual(int | UserId, Union[int, UserId])
+
+ self.assertEqual(get_args(UserId | int), (UserId, int))
+ self.assertEqual(get_args(int | UserId), (int, UserId))
+
+ def test_special_attrs(self):
+ UserId = NewType('UserId', int)
+
+ self.assertEqual(UserId.__name__, 'UserId')
+ self.assertEqual(UserId.__qualname__, 'UserId')
+ self.assertEqual(UserId.__module__, __name__)
+
+ def test_repr(self):
+ UserId = NewType('UserId', int)
+
+ self.assertEqual(repr(UserId), f'{__name__}.UserId')
class NamedTupleTests(BaseTestCase):
class NestedEmployee(NamedTuple):
diff --git a/Lib/typing.py b/Lib/typing.py
index cb70394bec36f..1606de91ac668 100644
--- a/Lib/typing.py
+++ b/Lib/typing.py
@@ -1373,6 +1373,12 @@ def _no_init(self, *args, **kwargs):
if type(self)._is_protocol:
raise TypeError('Protocols cannot be instantiated')
+def _callee(depth=2, default=None):
+ try:
+ return sys._getframe(depth).f_globals['__name__']
+ except (AttributeError, ValueError): # For platforms without _getframe()
+ return default
+
def _allow_reckless_class_checks(depth=3):
"""Allow instance and class checks for special stdlib modules.
@@ -2349,7 +2355,7 @@ class body be required.
TypedDict.__mro_entries__ = lambda bases: (_TypedDict,)
-def NewType(name, tp):
+class NewType:
"""NewType creates simple unique types with almost zero
runtime overhead. NewType(name, tp) is considered a subtype of tp
by static type checkers. At runtime, NewType(name, tp) returns
@@ -2368,12 +2374,23 @@ def name_by_id(user_id: UserId) -> str:
num = UserId(5) + 1 # type: int
"""
- def new_type(x):
+ def __init__(self, name, tp):
+ self.__name__ = name
+ self.__qualname__ = name
+ self.__module__ = _callee(default='typing')
+ self.__supertype__ = tp
+
+ def __repr__(self):
+ return f'{self.__module__}.{self.__qualname__}'
+
+ def __call__(self, x):
return x
- new_type.__name__ = name
- new_type.__supertype__ = tp
- return new_type
+ def __or__(self, other):
+ return Union[self, other]
+
+ def __ror__(self, other):
+ return Union[other, self]
# Python-version-specific alias (Python 2: unicode; Python 3: str)
diff --git a/Misc/NEWS.d/next/Library/2021-07-19-22-43-15.bpo-44353.HF81_Q.rst b/Misc/NEWS.d/next/Library/2021-07-19-22-43-15.bpo-44353.HF81_Q.rst
new file mode 100644
index 0000000000000..8a1e0f77b3177
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2021-07-19-22-43-15.bpo-44353.HF81_Q.rst
@@ -0,0 +1,2 @@
+Refactor ``typing.NewType`` from function into callable class. Patch
+provided by Yurii Karabas.
More information about the Python-checkins
mailing list