diff --git a/python2/test_typing.py b/python2/test_typing.py index 5de042a3..1b4377e8 100644 --- a/python2/test_typing.py +++ b/python2/test_typing.py @@ -375,6 +375,14 @@ def test_cannot_instantiate(self): with self.assertRaises(TypeError): type(c)() + def test_callable_wrong_forms(self): + with self.assertRaises(TypeError): + Callable[(), int] + with self.assertRaises(TypeError): + Callable[[()], int] + with self.assertRaises(TypeError): + Callable[[int, 1], 2] + def test_callable_instance_works(self): def f(): pass diff --git a/python2/typing.py b/python2/typing.py index 5df0062a..3242be84 100644 --- a/python2/typing.py +++ b/python2/typing.py @@ -1281,14 +1281,12 @@ def _tree_repr(self, tree): # super(CallableMeta, self)._tree_repr() for nice formatting. arg_list = [] for arg in tree[1:]: - if arg == (): - arg_list.append('[]') - elif not isinstance(arg, tuple): + if not isinstance(arg, tuple): arg_list.append(_type_repr(arg)) else: arg_list.append(arg[0]._tree_repr(arg)) - if len(arg_list) == 2: - return repr(tree[0]) + '[%s]' % ', '.join(arg_list) + if arg_list[0] == '...': + return repr(tree[0]) + '[..., %s]' % arg_list[1] return (repr(tree[0]) + '[[%s], %s]' % (', '.join(arg_list[:-1]), arg_list[-1])) @@ -1305,25 +1303,20 @@ def __getitem__(self, parameters): args, result = parameters if args is Ellipsis: parameters = (Ellipsis, result) - elif args == []: - parameters = ((), result) else: if not isinstance(args, list): raise TypeError("Callable[args, result]: args must be a list." " Got %.100r." % (args,)) - parameters = tuple(args) + (result,) + parameters = (tuple(args), result) return self.__getitem_inner__(parameters) @_tp_cache def __getitem_inner__(self, parameters): - args = parameters[:-1] - result = parameters[-1] + args, result = parameters msg = "Callable[args, result]: result must be a type." result = _type_check(result, msg) - if args == (Ellipsis,): + if args is Ellipsis: return super(CallableMeta, self).__getitem__((_TypingEllipsis, result)) - if args == ((),): - return super(CallableMeta, self).__getitem__((_TypingEmpty, result)) msg = "Callable[[arg, ...], result]: each arg must be a type." args = tuple(_type_check(arg, msg) for arg in args) parameters = args + (result,) diff --git a/src/test_typing.py b/src/test_typing.py index 3f702139..9b658f14 100644 --- a/src/test_typing.py +++ b/src/test_typing.py @@ -378,6 +378,16 @@ def test_cannot_instantiate(self): with self.assertRaises(TypeError): type(c)() + def test_callable_wrong_forms(self): + with self.assertRaises(TypeError): + Callable[[...], int] + with self.assertRaises(TypeError): + Callable[(), int] + with self.assertRaises(TypeError): + Callable[[()], int] + with self.assertRaises(TypeError): + Callable[[int, 1], 2] + def test_callable_instance_works(self): def f(): pass diff --git a/src/typing.py b/src/typing.py index 6c123962..5df1b45f 100644 --- a/src/typing.py +++ b/src/typing.py @@ -1194,14 +1194,12 @@ def _tree_repr(self, tree): # super()._tree_repr() for nice formatting. arg_list = [] for arg in tree[1:]: - if arg == (): - arg_list.append('[]') - elif not isinstance(arg, tuple): + if not isinstance(arg, tuple): arg_list.append(_type_repr(arg)) else: arg_list.append(arg[0]._tree_repr(arg)) - if len(arg_list) == 2: - return repr(tree[0]) + '[%s]' % ', '.join(arg_list) + if arg_list[0] == '...': + return repr(tree[0]) + '[..., %s]' % arg_list[1] return (repr(tree[0]) + '[[%s], %s]' % (', '.join(arg_list[:-1]), arg_list[-1])) @@ -1216,26 +1214,22 @@ def __getitem__(self, parameters): raise TypeError("Callable must be used as " "Callable[[arg, ...], result].") args, result = parameters - if args is ...: - parameters = (..., result) - elif args == []: - parameters = ((), result) + if args is Ellipsis: + parameters = (Ellipsis, result) else: if not isinstance(args, list): raise TypeError("Callable[args, result]: args must be a list." " Got %.100r." % (args,)) - parameters = tuple(args) + (result,) + parameters = (tuple(args), result) return self.__getitem_inner__(parameters) @_tp_cache def __getitem_inner__(self, parameters): - *args, result = parameters + args, result = parameters msg = "Callable[args, result]: result must be a type." result = _type_check(result, msg) - if args == [...,]: + if args is Ellipsis: return super().__getitem__((_TypingEllipsis, result)) - if args == [(),]: - return super().__getitem__((_TypingEmpty, result)) msg = "Callable[[arg, ...], result]: each arg must be a type." args = tuple(_type_check(arg, msg) for arg in args) parameters = args + (result,)