Skip to content

Commit cf7ba5d

Browse files
ilevkivskyigvanrossum
authored andcommitted
Prohibit Callable[[...], X] (#320)
1 parent 3777afc commit cf7ba5d

File tree

4 files changed

+32
-27
lines changed

4 files changed

+32
-27
lines changed

python2/test_typing.py

+8
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,14 @@ def test_cannot_instantiate(self):
375375
with self.assertRaises(TypeError):
376376
type(c)()
377377

378+
def test_callable_wrong_forms(self):
379+
with self.assertRaises(TypeError):
380+
Callable[(), int]
381+
with self.assertRaises(TypeError):
382+
Callable[[()], int]
383+
with self.assertRaises(TypeError):
384+
Callable[[int, 1], 2]
385+
378386
def test_callable_instance_works(self):
379387
def f():
380388
pass

python2/typing.py

+6-13
Original file line numberDiff line numberDiff line change
@@ -1281,14 +1281,12 @@ def _tree_repr(self, tree):
12811281
# super(CallableMeta, self)._tree_repr() for nice formatting.
12821282
arg_list = []
12831283
for arg in tree[1:]:
1284-
if arg == ():
1285-
arg_list.append('[]')
1286-
elif not isinstance(arg, tuple):
1284+
if not isinstance(arg, tuple):
12871285
arg_list.append(_type_repr(arg))
12881286
else:
12891287
arg_list.append(arg[0]._tree_repr(arg))
1290-
if len(arg_list) == 2:
1291-
return repr(tree[0]) + '[%s]' % ', '.join(arg_list)
1288+
if arg_list[0] == '...':
1289+
return repr(tree[0]) + '[..., %s]' % arg_list[1]
12921290
return (repr(tree[0]) +
12931291
'[[%s], %s]' % (', '.join(arg_list[:-1]), arg_list[-1]))
12941292

@@ -1305,25 +1303,20 @@ def __getitem__(self, parameters):
13051303
args, result = parameters
13061304
if args is Ellipsis:
13071305
parameters = (Ellipsis, result)
1308-
elif args == []:
1309-
parameters = ((), result)
13101306
else:
13111307
if not isinstance(args, list):
13121308
raise TypeError("Callable[args, result]: args must be a list."
13131309
" Got %.100r." % (args,))
1314-
parameters = tuple(args) + (result,)
1310+
parameters = (tuple(args), result)
13151311
return self.__getitem_inner__(parameters)
13161312

13171313
@_tp_cache
13181314
def __getitem_inner__(self, parameters):
1319-
args = parameters[:-1]
1320-
result = parameters[-1]
1315+
args, result = parameters
13211316
msg = "Callable[args, result]: result must be a type."
13221317
result = _type_check(result, msg)
1323-
if args == (Ellipsis,):
1318+
if args is Ellipsis:
13241319
return super(CallableMeta, self).__getitem__((_TypingEllipsis, result))
1325-
if args == ((),):
1326-
return super(CallableMeta, self).__getitem__((_TypingEmpty, result))
13271320
msg = "Callable[[arg, ...], result]: each arg must be a type."
13281321
args = tuple(_type_check(arg, msg) for arg in args)
13291322
parameters = args + (result,)

src/test_typing.py

+10
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,16 @@ def test_cannot_instantiate(self):
378378
with self.assertRaises(TypeError):
379379
type(c)()
380380

381+
def test_callable_wrong_forms(self):
382+
with self.assertRaises(TypeError):
383+
Callable[[...], int]
384+
with self.assertRaises(TypeError):
385+
Callable[(), int]
386+
with self.assertRaises(TypeError):
387+
Callable[[()], int]
388+
with self.assertRaises(TypeError):
389+
Callable[[int, 1], 2]
390+
381391
def test_callable_instance_works(self):
382392
def f():
383393
pass

src/typing.py

+8-14
Original file line numberDiff line numberDiff line change
@@ -1192,14 +1192,12 @@ def _tree_repr(self, tree):
11921192
# super()._tree_repr() for nice formatting.
11931193
arg_list = []
11941194
for arg in tree[1:]:
1195-
if arg == ():
1196-
arg_list.append('[]')
1197-
elif not isinstance(arg, tuple):
1195+
if not isinstance(arg, tuple):
11981196
arg_list.append(_type_repr(arg))
11991197
else:
12001198
arg_list.append(arg[0]._tree_repr(arg))
1201-
if len(arg_list) == 2:
1202-
return repr(tree[0]) + '[%s]' % ', '.join(arg_list)
1199+
if arg_list[0] == '...':
1200+
return repr(tree[0]) + '[..., %s]' % arg_list[1]
12031201
return (repr(tree[0]) +
12041202
'[[%s], %s]' % (', '.join(arg_list[:-1]), arg_list[-1]))
12051203

@@ -1214,26 +1212,22 @@ def __getitem__(self, parameters):
12141212
raise TypeError("Callable must be used as "
12151213
"Callable[[arg, ...], result].")
12161214
args, result = parameters
1217-
if args is ...:
1218-
parameters = (..., result)
1219-
elif args == []:
1220-
parameters = ((), result)
1215+
if args is Ellipsis:
1216+
parameters = (Ellipsis, result)
12211217
else:
12221218
if not isinstance(args, list):
12231219
raise TypeError("Callable[args, result]: args must be a list."
12241220
" Got %.100r." % (args,))
1225-
parameters = tuple(args) + (result,)
1221+
parameters = (tuple(args), result)
12261222
return self.__getitem_inner__(parameters)
12271223

12281224
@_tp_cache
12291225
def __getitem_inner__(self, parameters):
1230-
*args, result = parameters
1226+
args, result = parameters
12311227
msg = "Callable[args, result]: result must be a type."
12321228
result = _type_check(result, msg)
1233-
if args == [...,]:
1229+
if args is Ellipsis:
12341230
return super().__getitem__((_TypingEllipsis, result))
1235-
if args == [(),]:
1236-
return super().__getitem__((_TypingEmpty, result))
12371231
msg = "Callable[[arg, ...], result]: each arg must be a type."
12381232
args = tuple(_type_check(arg, msg) for arg in args)
12391233
parameters = args + (result,)

0 commit comments

Comments
 (0)