@@ -400,8 +400,8 @@ def test_basics(self):
400
400
issubclass (tuple , Tuple [int , str ])
401
401
402
402
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 )
405
405
406
406
def test_equality (self ):
407
407
self .assertEqual (Tuple [int ], Tuple [int ])
@@ -412,7 +412,7 @@ def test_equality(self):
412
412
def test_tuple_subclass (self ):
413
413
class MyTuple (tuple ):
414
414
pass
415
- self .assertTrue ( issubclass ( MyTuple , Tuple ) )
415
+ self .assertIsSubclass ( MyTuple , Tuple )
416
416
417
417
def test_tuple_instance_type_error (self ):
418
418
with self .assertRaises (TypeError ):
@@ -433,23 +433,28 @@ def test_errors(self):
433
433
issubclass (42 , Tuple [int ])
434
434
435
435
436
- class CallableTests ( BaseTestCase ) :
436
+ class BaseCallableTests :
437
437
438
438
def test_self_subclass (self ):
439
+ Callable = self .Callable
439
440
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 )
442
443
443
444
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 )
451
455
452
456
def test_cannot_instantiate (self ):
457
+ Callable = self .Callable
453
458
with self .assertRaises (TypeError ):
454
459
Callable ()
455
460
with self .assertRaises (TypeError ):
@@ -461,16 +466,19 @@ def test_cannot_instantiate(self):
461
466
type (c )()
462
467
463
468
def test_callable_wrong_forms (self ):
469
+ Callable = self .Callable
464
470
with self .assertRaises (TypeError ):
465
471
Callable [int ]
466
472
467
473
def test_callable_instance_works (self ):
474
+ Callable = self .Callable
468
475
def f ():
469
476
pass
470
477
self .assertIsInstance (f , Callable )
471
478
self .assertNotIsInstance (None , Callable )
472
479
473
480
def test_callable_instance_type_error (self ):
481
+ Callable = self .Callable
474
482
def f ():
475
483
pass
476
484
with self .assertRaises (TypeError ):
@@ -483,28 +491,142 @@ def f():
483
491
self .assertNotIsInstance (None , Callable [[], Any ])
484
492
485
493
def test_repr (self ):
494
+ Callable = self .Callable
495
+ fullname = f'{ Callable .__module__ } .Callable'
486
496
ct0 = Callable [[], bool ]
487
- self .assertEqual (repr (ct0 ), 'typing.Callable [[], bool]' )
497
+ self .assertEqual (repr (ct0 ), f' { fullname } [[], bool]' )
488
498
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]' )
490
500
ctv = Callable [..., str ]
491
- self .assertEqual (repr (ctv ), 'typing.Callable [..., str]' )
501
+ self .assertEqual (repr (ctv ), f' { fullname } [..., str]' )
492
502
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]]' )
494
504
495
505
def test_callable_with_ellipsis (self ):
496
-
506
+ Callable = self . Callable
497
507
def foo (a : Callable [..., T ]):
498
508
pass
499
509
500
510
self .assertEqual (get_type_hints (foo , globals (), locals ()),
501
511
{'a' : Callable [..., T ]})
502
512
503
513
def test_ellipsis_in_generic (self ):
514
+ Callable = self .Callable
504
515
# Shouldn't crash; see https://github.com/python/typing/issues/259
505
516
typing .List [Callable [..., str ]]
506
517
507
518
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
+
508
630
class LiteralTests (BaseTestCase ):
509
631
def test_basics (self ):
510
632
# All of these are allowed.
@@ -4456,13 +4578,6 @@ class Z(Generic[P]):
4456
4578
self .assertEqual (G5 .__parameters__ , G6 .__parameters__ )
4457
4579
self .assertEqual (G5 , G6 )
4458
4580
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
-
4466
4581
def test_no_paramspec_in__parameters__ (self ):
4467
4582
# ParamSpec should not be found in __parameters__
4468
4583
# of generics. Usages outside Callable, Concatenate
0 commit comments