예제 #1
0
    def test_typevar_bound(self):
        T = TypeVar('T', bound=Parent)

        def foo(a: T, b: T):
            assert check_argument_types()

        foo(Child(), Child())
예제 #2
0
    def test_typevar_contravariant(self):
        T = TypeVar('T', contravariant=True)

        def foo(a: T, b: T):
            assert check_argument_types()

        foo(Child(), Parent())
예제 #3
0
    def test_typevar_constraints(self, values):
        T = TypeVar('T', int, str)

        def foo(a: T, b: T):
            assert check_argument_types()

        foo(*values)
예제 #4
0
    def test_generic(self):
        T_Foo = TypeVar('T_Foo')

        class FooGeneric(Generic[T_Foo]):
            pass

        def foo(a: FooGeneric[str]):
            assert check_argument_types()

        foo(FooGeneric[str]())
예제 #5
0
    def test_typevar_contravariant_fail(self):
        T = TypeVar('T', contravariant=True)

        def foo(a: T, b: T):
            assert check_argument_types()

        exc = pytest.raises(TypeError, foo, Parent(), Child())
        assert str(exc.value) == (
            'type of argument "b" must be test_typeguard.Parent or one of '
            'its superclasses; got test_typeguard.Child instead')
예제 #6
0
    def test_typevar_invariant_fail(self):
        T = TypeVar('T', int, str)

        def foo(a: T, b: T):
            assert check_argument_types()

        exc = pytest.raises(TypeError, foo, 2, 3.6)
        assert str(
            exc.value
        ) == 'type of argument "b" must be exactly int; got float instead'
예제 #7
0
    def test_typevar_bound_fail(self):
        T = TypeVar('T', bound=Child)

        def foo(a: T, b: T):
            assert check_argument_types()

        exc = pytest.raises(TypeError, foo, Parent(), Parent())
        assert str(exc.value) == (
            'type of argument "a" must be test_typeguard.Child or one of '
            'its subclasses; got test_typeguard.Parent instead')
예제 #8
0
    def test_typevar_constraints_fail(self):
        T = TypeVar('T', int, str)

        def foo(a: T, b: T):
            assert check_argument_types()

        exc = pytest.raises(TypeError, foo, 2.5, 'aa')
        assert str(exc.value) == (
            'type of argument "a" must be one of (int, str); got float '
            'instead')
예제 #9
0
    def test_typechecked_return_typevar_fail(self):
        T = TypeVar('T', int, float)

        @typechecked
        def foo(a: T, b: T) -> T:
            return 'a'

        exc = pytest.raises(TypeError, foo, 4, 2)
        assert str(
            exc.value
        ) == 'type of the return value must be exactly int; got str instead'
예제 #10
0
from pytypes import util, typelogger, type_util

try:
    from backports.typing import Any, TypeVar
except ImportError:
    from typing import Any, TypeVar

py3 = False
force = False
silent = False
indent = '    '
stub_open_mode = "U"
stub_descr = (".pyi", stub_open_mode, imp.PY_SOURCE)
_implicit_globals = set()
# This behavior changed with Python 3.6:
_tpvar_is_class = inspect.isclass(TypeVar('_test'))


def _print(line):
    if not silent:
        print(line)


def _typestring(_types, argspecs, slf_or_clsm=False, assumed_globals=None):
    if _types[0] is Any:
        argstr = '...'
    else:
        args = type_util._preprocess_typecheck(_types[0], argspecs,
                                               slf_or_clsm)
        argstr = typelogger._prepare_arg_types_str(
            args,
def testfunc_Generator_arg(gen):
    # type: (Generator[int, Union[str, None], Any]) -> List[int]
    # should raise error because of illegal use of typing.Generator
    lst = ('ab', 'nmrs', 'u')
    res = [gen.send(x) for x in lst]
    return res


def testfunc_Generator_ret():
    # type: () -> Generator[int, Union[str, None], Any]
    # should raise error because of illegal use of typing.Generator
    res = testfunc_Generator()
    return res


T_1 = TypeVar('T_1')


class Custom_Generic(Generic[T_1]):
    def __init__(self, val):
        # type: (T_1) -> None
        self.val = val

    def v(self):
        # type: () -> T_1
        return self.val


def testfunc_Generic_arg(x):
    # type: (Custom_Generic[str]) -> str
    return x.v()
예제 #12
0
def testfunc_Generator_arg(
        gen: Generator[int, Union[str, None], Any]) -> List[int]:
    # should raise error because of illegal use of typing.Generator
    lst = ('ab', 'nmrs', 'u')
    res = [gen.send(x) for x in lst]
    return res


@typechecked
def testfunc_Generator_ret() -> Generator[int, Union[str, None], Any]:
    # should raise error because of illegal use of typing.Generator
    res = testfunc_Generator()
    return res


T_1_py3 = TypeVar('T_1_py3')


class Custom_Generic(Generic[T_1_py3]):
    def __init__(self, val: T_1_py3) -> None:
        self.val = val

    def v(self) -> T_1_py3:
        return self.val


@typechecked
def testfunc_Generic_arg(x: Custom_Generic[str]) -> str:
    return x.v()

예제 #13
0
    from backports.typing import (Any, AnyStr, Callable, Dict, Generic, Mapping, Optional, Pattern,
                                  Tuple, TypeVar, Union)
except ImportError:
    from typing import (Any, AnyStr, Callable, Dict, Generic, Mapping, Optional, Pattern,
                        Tuple, TypeVar, Union)

try:
    from backports.typing import Type
except ImportError:
    try:
        from typing import Type
    except ImportError:
        Type = None


T = TypeVar('T')
U = TypeVar('U', covariant=True)
V = TypeVar('V', contravariant=True)


class A:
    def get_type(self):
        return type(self)


class B(Generic[T]):
    pass


class Slotted:
    __slots__ = ()
        elif s == 'ret_fail':
            return 'bad return'
        s = yield len(s)

def testfunc_Generator_arg(gen: Generator[int, Union[str, None], Any]) -> List[int]:
    # should raise error because of illegal use of typing.Generator
    lst = ('ab', 'nmrs', 'u')
    res = [gen.send(x) for x in lst]
    return res

def testfunc_Generator_ret() -> Generator[int, Union[str, None], Any]:
    # should raise error because of illegal use of typing.Generator
    res = testfunc_Generator()
    return res

T_1_py3 = TypeVar('T_1_py3')
class Custom_Generic(Generic[T_1_py3]):
    
    def __init__(self, val: T_1_py3) -> None:
        self.val = val

    def v(self) -> T_1_py3:
        return self.val

def testfunc_Generic_arg(x: Custom_Generic[str]) -> str:
    return x.v()

def testfunc_Generic_ret(x: int) -> Custom_Generic[int]:
    return Custom_Generic[int](x)

def testfunc_Generic_ret_err(x: int) -> Custom_Generic[int]:
예제 #15
0
class TestTypeChecked:
    def test_typechecked(self):
        @typechecked
        def foo(a: int, b: str) -> str:
            return 'abc'

        assert foo(4, 'abc') == 'abc'

    def test_typechecked_always(self):
        @typechecked(always=True)
        def foo(a: int, b: str) -> str:
            return 'abc'

        assert foo(4, 'abc') == 'abc'

    def test_typechecked_arguments_fail(self):
        @typechecked
        def foo(a: int, b: str) -> str:
            return 'abc'

        exc = pytest.raises(TypeError, foo, 4, 5)
        assert str(
            exc.value) == 'type of argument "b" must be str; got int instead'

    def test_typechecked_return_type_fail(self):
        @typechecked
        def foo(a: int, b: str) -> str:
            return 6

        exc = pytest.raises(TypeError, foo, 4, 'abc')
        assert str(exc.value
                   ) == 'type of the return value must be str; got int instead'

    def test_typechecked_return_typevar_fail(self):
        T = TypeVar('T', int, float)

        @typechecked
        def foo(a: T, b: T) -> T:
            return 'a'

        exc = pytest.raises(TypeError, foo, 4, 2)
        assert str(
            exc.value
        ) == 'type of the return value must be exactly int; got str instead'

    def test_typechecked_no_annotations(self, recwarn):
        def foo(a, b):
            pass

        typechecked(foo)

        func_name = function_name(foo)
        assert len(recwarn) == 1
        assert str(recwarn[0].message) == (
            'no type annotations present -- not typechecking {}'.format(
                func_name))

    def test_return_type_none(self):
        """Check that a declared return type of None is respected."""
        @typechecked
        def foo() -> None:
            return 'a'

        exc = pytest.raises(TypeError, foo)
        assert str(
            exc.value
        ) == 'type of the return value must be NoneType; got str instead'

    @pytest.mark.parametrize('typehint', [Callable[..., int], Callable],
                             ids=['parametrized', 'unparametrized'])
    def test_callable(self, typehint):
        @typechecked
        def foo(a: typehint):
            pass

        def some_callable() -> int:
            pass

        foo(some_callable)

    @pytest.mark.parametrize('typehint', [
        List[int],
        List,
        list,
    ],
                             ids=['parametrized', 'unparametrized', 'plain'])
    def test_list(self, typehint):
        @typechecked
        def foo(a: typehint):
            pass

        foo([1, 2])

    @pytest.mark.parametrize('typehint', [Dict[str, int], Dict, dict],
                             ids=['parametrized', 'unparametrized', 'plain'])
    def test_dict(self, typehint):
        @typechecked
        def foo(a: typehint):
            pass

        foo({'x': 2})

    @pytest.mark.parametrize('typehint', [Sequence[str], Sequence],
                             ids=['parametrized', 'unparametrized'])
    @pytest.mark.parametrize('value', [('a', 'b'), ['a', 'b'], 'abc'],
                             ids=['tuple', 'list', 'str'])
    def test_sequence(self, typehint, value):
        @typechecked
        def foo(a: typehint):
            pass

        foo(value)

    @pytest.mark.parametrize('typehint', [Iterable[str], Iterable],
                             ids=['parametrized', 'unparametrized'])
    @pytest.mark.parametrize('value', [('a', 'b'), ['a', 'b'], 'abc'],
                             ids=['tuple', 'list', 'str'])
    def test_iterable(self, typehint, value):
        @typechecked
        def foo(a: typehint):
            pass

        foo(value)

    @pytest.mark.parametrize('typehint', [Container[str], Container],
                             ids=['parametrized', 'unparametrized'])
    @pytest.mark.parametrize('value', [('a', 'b'), ['a', 'b'], 'abc'],
                             ids=['tuple', 'list', 'str'])
    def test_container(self, typehint, value):
        @typechecked
        def foo(a: typehint):
            pass

        foo(value)

    @pytest.mark.parametrize('typehint', [Set[int], Set, set],
                             ids=['parametrized', 'unparametrized', 'plain'])
    @pytest.mark.parametrize('value', [set(), {6}])
    def test_set(self, typehint, value):
        @typechecked
        def foo(a: typehint):
            pass

        foo(value)

    @pytest.mark.parametrize(
        'typehint', [Tuple[int, int], Tuple[int, ...], Tuple, tuple],
        ids=['parametrized', 'ellipsis', 'unparametrized', 'plain'])
    def test_tuple(self, typehint):
        @typechecked
        def foo(a: typehint):
            pass

        foo((1, 2))

    @pytest.mark.skipif(Type is List,
                        reason='typing.Type could not be imported')
    @pytest.mark.parametrize('typehint', [
        Type[Parent], Type[TypeVar('UnboundType')], Type[TypeVar(
            'BoundType', bound=Parent)], Type, type
    ],
                             ids=[
                                 'parametrized', 'unbound-typevar',
                                 'bound-typevar', 'unparametrized', 'plain'
                             ])
    def test_class(self, typehint):
        @typechecked
        def foo(a: typehint):
            pass

        foo(Child)

    @pytest.mark.skipif(Type is List,
                        reason='typing.Type could not be imported')
    def test_class_not_a_class(self):
        @typechecked
        def foo(a: Type[dict]):
            pass

        exc = pytest.raises(TypeError, foo, 1)
        exc.match('type of argument "a" must be a type; got int instead')
예제 #16
0
    # actually (Generator[int, Union[str, None], Any]) -> List[int]
    # should raise error because of illegal use of typing.Generator
    lst = ('ab', 'nmrs', 'u')
    res = [gen.send(x) for x in lst]
    return res


@typechecked
def testfunc_Generator_ret_py2():
    # actually () -> Generator[int, Union[str, None], Any]
    # should raise error because of illegal use of typing.Generator
    res = testfunc_Generator_py2()
    return res


T_1_py2 = TypeVar('T_1_py2')


class Custom_Generic_py2(Generic[T_1_py2]):
    def __init__(self, val):
        # type: (T_1_py2) -> None
        self.val = val

    def v(self):
        # type: () -> T_1_py2
        return self.val


@typechecked
def testfunc_Generic_arg_py2(x):
    # actually (Custom_Generic_py2[str]) -> str