]> granicus.if.org Git - python/commitdiff
[3.5] bpo-28556: Routine updates to typing (GH-1366) (#1417)
authorMariatta <Mariatta@users.noreply.github.com>
Wed, 3 May 2017 16:37:50 +0000 (09:37 -0700)
committerGitHub <noreply@github.com>
Wed, 3 May 2017 16:37:50 +0000 (09:37 -0700)
- Add NoReturn type
- Use WrapperDescriptorType (original PR by Jim Fasarakis-Hilliard)
- Minor bug-fixes
(cherry picked from commit f06e0218ef6007667f5d61184b85a81a0466d3ae)

Lib/test/test_typing.py
Lib/typing.py
Misc/NEWS

index f0070ec975791ac0afd5afc1f787efb9c2938745..b3cabda394497ecccbfa36604fef6763eb4d5820 100644 (file)
@@ -6,7 +6,7 @@ import sys
 from unittest import TestCase, main, skipUnless, SkipTest
 from copy import copy, deepcopy
 
-from typing import Any
+from typing import Any, NoReturn
 from typing import TypeVar, AnyStr
 from typing import T, KT, VT  # Not in __all__.
 from typing import Union, Optional
@@ -102,10 +102,6 @@ class AnyTests(BaseTestCase):
         with self.assertRaises(TypeError):
             type(Any)()
 
-    def test_cannot_subscript(self):
-        with self.assertRaises(TypeError):
-            Any[int]
-
     def test_any_works_with_alias(self):
         # These expressions must simply not fail.
         typing.Match[Any]
@@ -113,6 +109,40 @@ class AnyTests(BaseTestCase):
         typing.IO[Any]
 
 
+class NoReturnTests(BaseTestCase):
+
+    def test_noreturn_instance_type_error(self):
+        with self.assertRaises(TypeError):
+            isinstance(42, NoReturn)
+
+    def test_noreturn_subclass_type_error(self):
+        with self.assertRaises(TypeError):
+            issubclass(Employee, NoReturn)
+        with self.assertRaises(TypeError):
+            issubclass(NoReturn, Employee)
+
+    def test_repr(self):
+        self.assertEqual(repr(NoReturn), 'typing.NoReturn')
+
+    def test_not_generic(self):
+        with self.assertRaises(TypeError):
+            NoReturn[int]
+
+    def test_cannot_subclass(self):
+        with self.assertRaises(TypeError):
+            class A(NoReturn):
+                pass
+        with self.assertRaises(TypeError):
+            class A(type(NoReturn)):
+                pass
+
+    def test_cannot_instantiate(self):
+        with self.assertRaises(TypeError):
+            NoReturn()
+        with self.assertRaises(TypeError):
+            type(NoReturn)()
+
+
 class TypeVarTests(BaseTestCase):
 
     def test_basic_plain(self):
@@ -2273,6 +2303,14 @@ class XMethBad(NamedTuple):
         return 'no chance for this'
 """)
 
+        with self.assertRaises(AttributeError):
+            exec("""
+class XMethBad2(NamedTuple):
+    x: int
+    def _source(self):
+        return 'no chance for this as well'
+""")
+
     @skipUnless(PY36, 'Python 3.6 required')
     def test_namedtuple_keyword_usage(self):
         LocalEmployee = NamedTuple("LocalEmployee", name=str, age=int)
@@ -2420,6 +2458,9 @@ class AllTests(BaseTestCase):
         self.assertNotIn('sys', a)
         # Check that Text is defined.
         self.assertIn('Text', a)
+        # Check previously missing classes.
+        self.assertIn('SupportsBytes', a)
+        self.assertIn('SupportsComplex', a)
 
 
 if __name__ == '__main__':
index 9a0f49099a3114565947901e82f597b097a8be12..645bc6f8ae0eddf9dc835f245c330b00ebb85c2c 100644 (file)
@@ -11,9 +11,9 @@ try:
 except ImportError:
     import collections as collections_abc  # Fallback for PY3.2.
 try:
-    from types import SlotWrapperType, MethodWrapperType, MethodDescriptorType
+    from types import WrapperDescriptorType, MethodWrapperType, MethodDescriptorType
 except ImportError:
-    SlotWrapperType = type(object.__init__)
+    WrapperDescriptorType = type(object.__init__)
     MethodWrapperType = type(object().__str__)
     MethodDescriptorType = type(str.join)
 
@@ -63,6 +63,8 @@ __all__ = [
     # Structural checks, a.k.a. protocols.
     'Reversible',
     'SupportsAbs',
+    'SupportsBytes',
+    'SupportsComplex',
     'SupportsFloat',
     'SupportsInt',
     'SupportsRound',
@@ -420,6 +422,31 @@ class _Any(_FinalTypingBase, _root=True):
 Any = _Any(_root=True)
 
 
+class _NoReturn(_FinalTypingBase, _root=True):
+    """Special type indicating functions that never return.
+    Example::
+
+      from typing import NoReturn
+
+      def stop() -> NoReturn:
+          raise Exception('no way')
+
+    This type is invalid in other positions, e.g., ``List[NoReturn]``
+    will fail in static type checkers.
+    """
+
+    __slots__ = ()
+
+    def __instancecheck__(self, obj):
+        raise TypeError("NoReturn cannot be used with isinstance().")
+
+    def __subclasscheck__(self, cls):
+        raise TypeError("NoReturn cannot be used with issubclass().")
+
+
+NoReturn = _NoReturn(_root=True)
+
+
 class TypeVar(_TypingBase, _root=True):
     """Type variable.
 
@@ -1450,7 +1477,7 @@ def _get_defaults(func):
 
 _allowed_types = (types.FunctionType, types.BuiltinFunctionType,
                   types.MethodType, types.ModuleType,
-                  SlotWrapperType, MethodWrapperType, MethodDescriptorType)
+                  WrapperDescriptorType, MethodWrapperType, MethodDescriptorType)
 
 
 def get_type_hints(obj, globalns=None, localns=None):
@@ -2051,7 +2078,7 @@ _PY36 = sys.version_info[:2] >= (3, 6)
 # attributes prohibited to set in NamedTuple class syntax
 _prohibited = ('__new__', '__init__', '__slots__', '__getnewargs__',
                '_fields', '_field_defaults', '_field_types',
-               '_make', '_replace', '_asdict')
+               '_make', '_replace', '_asdict', '_source')
 
 _special = ('__module__', '__name__', '__qualname__', '__annotations__')
 
index c7d273c2414d21b602643099487c8d00a4ee5779..93bd30ffd374d99ebc0a3ab196b93df8dc0edd2e 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -49,6 +49,10 @@ Extension Modules
 Library
 -------
 
+- bpo-28556: Various updates to typing module: add typing.NoReturn type, use
+  WrapperDescriptorType, minor bug-fixes.  Original PRs by
+  Jim Fasarakis-Hilliard and Ivan Levkivskyi.
+
 - bpo-30205: Fix getsockname() for unbound AF_UNIX sockets on Linux.
 
 - bpo-30070: Fixed leaks and crashes in errors handling in the parser module.