Skip to content
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

[3.5] bpo-28556: Routine updates to typing (GH-1366) #1417

Merged
merged 1 commit into from
May 3, 2017
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
51 changes: 46 additions & 5 deletions Lib/test/test_typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
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
Expand Down Expand Up @@ -102,17 +102,47 @@ def test_cannot_instantiate(self):
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]
typing.Pattern[Any]
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):
Expand Down Expand Up @@ -2273,6 +2303,14 @@ def _fields(self):
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)
Expand Down Expand Up @@ -2420,6 +2458,9 @@ def test_all(self):
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__':
Expand Down
35 changes: 31 additions & 4 deletions Lib/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
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)

Expand Down Expand Up @@ -63,6 +63,8 @@
# Structural checks, a.k.a. protocols.
'Reversible',
'SupportsAbs',
'SupportsBytes',
'SupportsComplex',
'SupportsFloat',
'SupportsInt',
'SupportsRound',
Expand Down Expand Up @@ -420,6 +422,31 @@ def __subclasscheck__(self, cls):
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.

Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -2051,7 +2078,7 @@ def _make_nmtuple(name, types):
# 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__')

Expand Down
4 changes: 4 additions & 0 deletions Misc/NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down