@@ -426,22 +426,16 @@ class _CallableGenericAlias(GenericAlias):
426426 __slots__ = ()
427427
428428 def __new__ (cls , origin , args ):
429- return cls .__create_ga (origin , args )
430-
431- @classmethod
432- def __create_ga (cls , origin , args ):
433- if not isinstance (args , tuple ) or len (args ) != 2 :
429+ if not (isinstance (args , tuple ) and len (args ) == 2 ):
434430 raise TypeError (
435431 "Callable must be used as Callable[[arg, ...], result]." )
436432 t_args , t_result = args
437- if isinstance (t_args , (list , tuple )):
438- ga_args = tuple (t_args ) + (t_result ,)
439- # This relaxes what t_args can be on purpose to allow things like
440- # PEP 612 ParamSpec. Responsibility for whether a user is using
441- # Callable[...] properly is deferred to static type checkers.
442- else :
443- ga_args = args
444- return super ().__new__ (cls , origin , ga_args )
433+ if isinstance (t_args , list ):
434+ args = (* t_args , t_result )
435+ elif not _is_param_expr (t_args ):
436+ raise TypeError (f"Expected a list of types, an ellipsis, "
437+ f"ParamSpec, or Concatenate. Got { t_args } " )
438+ return super ().__new__ (cls , origin , args )
445439
446440 @property
447441 def __parameters__ (self ):
@@ -456,15 +450,15 @@ def __parameters__(self):
456450 return tuple (dict .fromkeys (params ))
457451
458452 def __repr__ (self ):
459- if _has_special_args (self .__args__ ):
453+ if len (self .__args__ ) == 2 and _is_param_expr ( self . __args__ [ 0 ] ):
460454 return super ().__repr__ ()
461455 return (f'collections.abc.Callable'
462456 f'[[{ ", " .join ([_type_repr (a ) for a in self .__args__ [:- 1 ]])} ], '
463457 f'{ _type_repr (self .__args__ [- 1 ])} ]' )
464458
465459 def __reduce__ (self ):
466460 args = self .__args__
467- if not _has_special_args ( args ):
461+ if not ( len ( args ) == 2 and _is_param_expr ( args [ 0 ]) ):
468462 args = list (args [:- 1 ]), args [- 1 ]
469463 return _CallableGenericAlias , (Callable , args )
470464
@@ -479,10 +473,11 @@ def __getitem__(self, item):
479473 param_len = len (self .__parameters__ )
480474 if param_len == 0 :
481475 raise TypeError (f'{ self } is not a generic class' )
482- if (param_len == 1
483- and isinstance (item , (tuple , list ))
484- and len (item ) > 1 ) or not isinstance (item , tuple ):
476+ if not isinstance (item , tuple ):
485477 item = (item ,)
478+ if (param_len == 1 and _is_param_expr (self .__parameters__ [0 ])
479+ and item and not _is_param_expr (item [0 ])):
480+ item = (list (item ),)
486481 item_len = len (item )
487482 if item_len != param_len :
488483 raise TypeError (f'Too { "many" if item_len > param_len else "few" } '
@@ -492,7 +487,13 @@ def __getitem__(self, item):
492487 new_args = []
493488 for arg in self .__args__ :
494489 if _is_typevarlike (arg ):
495- arg = subst [arg ]
490+ if _is_param_expr (arg ):
491+ arg = subst [arg ]
492+ if not _is_param_expr (arg ):
493+ raise TypeError (f"Expected a list of types, an ellipsis, "
494+ f"ParamSpec, or Concatenate. Got { arg } " )
495+ else :
496+ arg = subst [arg ]
496497 # Looks like a GenericAlias
497498 elif hasattr (arg , '__parameters__' ) and isinstance (arg .__parameters__ , tuple ):
498499 subparams = arg .__parameters__
@@ -502,32 +503,31 @@ def __getitem__(self, item):
502503 new_args .append (arg )
503504
504505 # args[0] occurs due to things like Z[[int, str, bool]] from PEP 612
505- if not isinstance (new_args [0 ], ( tuple , list ) ):
506+ if not isinstance (new_args [0 ], list ):
506507 t_result = new_args [- 1 ]
507508 t_args = new_args [:- 1 ]
508509 new_args = (t_args , t_result )
509510 return _CallableGenericAlias (Callable , tuple (new_args ))
510511
512+
511513def _is_typevarlike (arg ):
512514 obj = type (arg )
513515 # looks like a TypeVar/ParamSpec
514516 return (obj .__module__ == 'typing'
515517 and obj .__name__ in {'ParamSpec' , 'TypeVar' })
516518
517- def _has_special_args ( args ):
518- """Checks if args[0] matches either ``...``, ``ParamSpec`` or
519+ def _is_param_expr ( obj ):
520+ """Checks if obj matches either a list of types, ``...``, ``ParamSpec`` or
519521 ``_ConcatenateGenericAlias`` from typing.py
520522 """
521- if len (args ) != 2 :
522- return False
523- obj = args [0 ]
524523 if obj is Ellipsis :
525524 return True
525+ if isinstance (obj , list ):
526+ return True
526527 obj = type (obj )
527528 names = ('ParamSpec' , '_ConcatenateGenericAlias' )
528529 return obj .__module__ == 'typing' and any (obj .__name__ == name for name in names )
529530
530-
531531def _type_repr (obj ):
532532 """Return the repr() of an object, special-casing types (internal helper).
533533
0 commit comments