@@ -400,8 +400,8 @@ def test_basics(self):
400400 issubclass (tuple , Tuple [int , str ])
401401
402402 class TP (tuple ): ...
403- self .assertTrue ( issubclass ( tuple , Tuple ) )
404- self .assertTrue ( issubclass ( TP , Tuple ) )
403+ self .assertIsSubclass ( tuple , Tuple )
404+ self .assertIsSubclass ( TP , Tuple )
405405
406406 def test_equality (self ):
407407 self .assertEqual (Tuple [int ], Tuple [int ])
@@ -412,7 +412,7 @@ def test_equality(self):
412412 def test_tuple_subclass (self ):
413413 class MyTuple (tuple ):
414414 pass
415- self .assertTrue ( issubclass ( MyTuple , Tuple ) )
415+ self .assertIsSubclass ( MyTuple , Tuple )
416416
417417 def test_tuple_instance_type_error (self ):
418418 with self .assertRaises (TypeError ):
@@ -433,23 +433,28 @@ def test_errors(self):
433433 issubclass (42 , Tuple [int ])
434434
435435
436- class CallableTests ( BaseTestCase ) :
436+ class BaseCallableTests :
437437
438438 def test_self_subclass (self ):
439+ Callable = self .Callable
439440 with self .assertRaises (TypeError ):
440- self . assertTrue ( issubclass (type ( lambda x : x ) , Callable [[int ], int ]) )
441- self .assertTrue ( issubclass ( type ( lambda x : x ) , Callable ) )
441+ issubclass (types . FunctionType , Callable [[int ], int ])
442+ self .assertIsSubclass ( types . FunctionType , Callable )
442443
443444 def test_eq_hash (self ):
444- self .assertEqual (Callable [[int ], int ], Callable [[int ], int ])
445- self .assertEqual (len ({Callable [[int ], int ], Callable [[int ], int ]}), 1 )
446- self .assertNotEqual (Callable [[int ], int ], Callable [[int ], str ])
447- self .assertNotEqual (Callable [[int ], int ], Callable [[str ], int ])
448- self .assertNotEqual (Callable [[int ], int ], Callable [[int , int ], int ])
449- self .assertNotEqual (Callable [[int ], int ], Callable [[], int ])
450- self .assertNotEqual (Callable [[int ], int ], Callable )
445+ Callable = self .Callable
446+ C = Callable [[int ], int ]
447+ self .assertEqual (C , Callable [[int ], int ])
448+ self .assertEqual (len ({C , Callable [[int ], int ]}), 1 )
449+ self .assertNotEqual (C , Callable [[int ], str ])
450+ self .assertNotEqual (C , Callable [[str ], int ])
451+ self .assertNotEqual (C , Callable [[int , int ], int ])
452+ self .assertNotEqual (C , Callable [[], int ])
453+ self .assertNotEqual (C , Callable [..., int ])
454+ self .assertNotEqual (C , Callable )
451455
452456 def test_cannot_instantiate (self ):
457+ Callable = self .Callable
453458 with self .assertRaises (TypeError ):
454459 Callable ()
455460 with self .assertRaises (TypeError ):
@@ -461,16 +466,19 @@ def test_cannot_instantiate(self):
461466 type (c )()
462467
463468 def test_callable_wrong_forms (self ):
469+ Callable = self .Callable
464470 with self .assertRaises (TypeError ):
465471 Callable [int ]
466472
467473 def test_callable_instance_works (self ):
474+ Callable = self .Callable
468475 def f ():
469476 pass
470477 self .assertIsInstance (f , Callable )
471478 self .assertNotIsInstance (None , Callable )
472479
473480 def test_callable_instance_type_error (self ):
481+ Callable = self .Callable
474482 def f ():
475483 pass
476484 with self .assertRaises (TypeError ):
@@ -483,28 +491,142 @@ def f():
483491 self .assertNotIsInstance (None , Callable [[], Any ])
484492
485493 def test_repr (self ):
494+ Callable = self .Callable
495+ fullname = f'{ Callable .__module__ } .Callable'
486496 ct0 = Callable [[], bool ]
487- self .assertEqual (repr (ct0 ), 'typing.Callable [[], bool]' )
497+ self .assertEqual (repr (ct0 ), f' { fullname } [[], bool]' )
488498 ct2 = Callable [[str , float ], int ]
489- self .assertEqual (repr (ct2 ), 'typing.Callable [[str, float], int]' )
499+ self .assertEqual (repr (ct2 ), f' { fullname } [[str, float], int]' )
490500 ctv = Callable [..., str ]
491- self .assertEqual (repr (ctv ), 'typing.Callable [..., str]' )
501+ self .assertEqual (repr (ctv ), f' { fullname } [..., str]' )
492502 ct3 = Callable [[str , float ], list [int ]]
493- self .assertEqual (repr (ct3 ), 'typing.Callable [[str, float], list[int]]' )
503+ self .assertEqual (repr (ct3 ), f' { fullname } [[str, float], list[int]]' )
494504
495505 def test_callable_with_ellipsis (self ):
496-
506+ Callable = self . Callable
497507 def foo (a : Callable [..., T ]):
498508 pass
499509
500510 self .assertEqual (get_type_hints (foo , globals (), locals ()),
501511 {'a' : Callable [..., T ]})
502512
503513 def test_ellipsis_in_generic (self ):
514+ Callable = self .Callable
504515 # Shouldn't crash; see https://github.com/python/typing/issues/259
505516 typing .List [Callable [..., str ]]
506517
507518
519+ def test_basic (self ):
520+ Callable = self .Callable
521+ alias = Callable [[int , str ], float ]
522+ if Callable is collections .abc .Callable :
523+ self .assertIsInstance (alias , types .GenericAlias )
524+ self .assertIs (alias .__origin__ , collections .abc .Callable )
525+ self .assertEqual (alias .__args__ , (int , str , float ))
526+ self .assertEqual (alias .__parameters__ , ())
527+
528+ def test_weakref (self ):
529+ Callable = self .Callable
530+ alias = Callable [[int , str ], float ]
531+ self .assertEqual (weakref .ref (alias )(), alias )
532+
533+ def test_pickle (self ):
534+ Callable = self .Callable
535+ alias = Callable [[int , str ], float ]
536+ for proto in range (pickle .HIGHEST_PROTOCOL + 1 ):
537+ s = pickle .dumps (alias , proto )
538+ loaded = pickle .loads (s )
539+ self .assertEqual (alias .__origin__ , loaded .__origin__ )
540+ self .assertEqual (alias .__args__ , loaded .__args__ )
541+ self .assertEqual (alias .__parameters__ , loaded .__parameters__ )
542+
543+ def test_var_substitution (self ):
544+ Callable = self .Callable
545+ fullname = f"{ Callable .__module__ } .Callable"
546+ C1 = Callable [[int , T ], T ]
547+ C2 = Callable [[KT , T ], VT ]
548+ C3 = Callable [..., T ]
549+ self .assertEqual (C1 [str ], Callable [[int , str ], str ])
550+ self .assertEqual (C2 [int , float , str ], Callable [[int , float ], str ])
551+ self .assertEqual (C3 [int ], Callable [..., int ])
552+
553+ # multi chaining
554+ C4 = C2 [int , VT , str ]
555+ self .assertEqual (repr (C4 ), f"{ fullname } [[int, ~VT], str]" )
556+ self .assertEqual (repr (C4 [dict ]), f"{ fullname } [[int, dict], str]" )
557+ self .assertEqual (C4 [dict ], Callable [[int , dict ], str ])
558+
559+ # substitute a nested GenericAlias (both typing and the builtin
560+ # version)
561+ C5 = Callable [[typing .List [T ], tuple [KT , T ], VT ], int ]
562+ self .assertEqual (C5 [int , str , float ],
563+ Callable [[typing .List [int ], tuple [str , int ], float ], int ])
564+
565+ def test_type_erasure (self ):
566+ Callable = self .Callable
567+ class C1 (Callable ):
568+ def __call__ (self ):
569+ return None
570+ a = C1 [[int ], T ]
571+ self .assertIs (a ().__class__ , C1 )
572+ self .assertEqual (a ().__orig_class__ , C1 [[int ], T ])
573+
574+ def test_paramspec (self ):
575+ Callable = self .Callable
576+ fullname = f"{ Callable .__module__ } .Callable"
577+ P = ParamSpec ('P' )
578+ C1 = Callable [P , T ]
579+ # substitution
580+ self .assertEqual (C1 [int , str ], Callable [[int ], str ])
581+ self .assertEqual (C1 [[int , str ], str ], Callable [[int , str ], str ])
582+ self .assertEqual (repr (C1 ), f"{ fullname } [~P, ~T]" )
583+ self .assertEqual (repr (C1 [int , str ]), f"{ fullname } [[int], str]" )
584+
585+ C2 = Callable [P , int ]
586+ # special case in PEP 612 where
587+ # X[int, str, float] == X[[int, str, float]]
588+ self .assertEqual (C2 [int , str , float ], C2 [[int , str , float ]])
589+ self .assertEqual (repr (C2 ), f"{ fullname } [~P, int]" )
590+ self .assertEqual (repr (C2 [int , str ]), f"{ fullname } [[int, str], int]" )
591+
592+ def test_concatenate (self ):
593+ Callable = self .Callable
594+ fullname = f"{ Callable .__module__ } .Callable"
595+ P = ParamSpec ('P' )
596+ C1 = Callable [typing .Concatenate [int , P ], int ]
597+ self .assertEqual (repr (C1 ),
598+ f"{ fullname } [typing.Concatenate[int, ~P], int]" )
599+
600+ def test_errors (self ):
601+ Callable = self .Callable
602+ alias = Callable [[int , str ], float ]
603+ with self .assertRaisesRegex (TypeError , "is not a generic class" ):
604+ alias [int ]
605+ P = ParamSpec ('P' )
606+ C1 = Callable [P , T ]
607+ with self .assertRaisesRegex (TypeError , "many arguments for" ):
608+ C1 [int , str , str ]
609+ with self .assertRaisesRegex (TypeError , "few arguments for" ):
610+ C1 [int ]
611+
612+ class TypingCallableTests (BaseCallableTests , BaseTestCase ):
613+ Callable = typing .Callable
614+
615+ def test_consistency (self ):
616+ # bpo-42195
617+ # Testing collections.abc.Callable's consistency with typing.Callable
618+ c1 = typing .Callable [[int , str ], dict ]
619+ c2 = collections .abc .Callable [[int , str ], dict ]
620+ self .assertEqual (c1 .__args__ , c2 .__args__ )
621+ self .assertEqual (hash (c1 .__args__ ), hash (c2 .__args__ ))
622+
623+ test_errors = skip ("known bug #44793" )(BaseCallableTests .test_errors )
624+
625+
626+ class CollectionsCallableTests (BaseCallableTests , BaseTestCase ):
627+ Callable = collections .abc .Callable
628+
629+
508630class LiteralTests (BaseTestCase ):
509631 def test_basics (self ):
510632 # All of these are allowed.
@@ -4456,13 +4578,6 @@ class Z(Generic[P]):
44564578 self .assertEqual (G5 .__parameters__ , G6 .__parameters__ )
44574579 self .assertEqual (G5 , G6 )
44584580
4459- def test_var_substitution (self ):
4460- T = TypeVar ("T" )
4461- P = ParamSpec ("P" )
4462- C1 = Callable [P , T ]
4463- self .assertEqual (C1 [int , str ], Callable [[int ], str ])
4464- self .assertEqual (C1 [[int , str , dict ], float ], Callable [[int , str , dict ], float ])
4465-
44664581 def test_no_paramspec_in__parameters__ (self ):
44674582 # ParamSpec should not be found in __parameters__
44684583 # of generics. Usages outside Callable, Concatenate
0 commit comments