@@ -406,8 +406,8 @@ def test_basics(self):
406
406
issubclass (tuple , Tuple [int , str ])
407
407
408
408
class TP (tuple ): ...
409
- self .assertTrue ( issubclass ( tuple , Tuple ) )
410
- self .assertTrue ( issubclass ( TP , Tuple ) )
409
+ self .assertIsSubclass ( tuple , Tuple )
410
+ self .assertIsSubclass ( TP , Tuple )
411
411
412
412
def test_equality (self ):
413
413
self .assertEqual (Tuple [int ], Tuple [int ])
@@ -418,7 +418,7 @@ def test_equality(self):
418
418
def test_tuple_subclass (self ):
419
419
class MyTuple (tuple ):
420
420
pass
421
- self .assertTrue ( issubclass ( MyTuple , Tuple ) )
421
+ self .assertIsSubclass ( MyTuple , Tuple )
422
422
423
423
def test_tuple_instance_type_error (self ):
424
424
with self .assertRaises (TypeError ):
@@ -439,23 +439,28 @@ def test_errors(self):
439
439
issubclass (42 , Tuple [int ])
440
440
441
441
442
- class CallableTests ( BaseTestCase ) :
442
+ class BaseCallableTests :
443
443
444
444
def test_self_subclass (self ):
445
+ Callable = self .Callable
445
446
with self .assertRaises (TypeError ):
446
- self . assertTrue ( issubclass (type ( lambda x : x ) , Callable [[int ], int ]) )
447
- self .assertTrue ( issubclass ( type ( lambda x : x ) , Callable ) )
447
+ issubclass (types . FunctionType , Callable [[int ], int ])
448
+ self .assertIsSubclass ( types . FunctionType , Callable )
448
449
449
450
def test_eq_hash (self ):
450
- self .assertEqual (Callable [[int ], int ], Callable [[int ], int ])
451
- self .assertEqual (len ({Callable [[int ], int ], Callable [[int ], int ]}), 1 )
452
- self .assertNotEqual (Callable [[int ], int ], Callable [[int ], str ])
453
- self .assertNotEqual (Callable [[int ], int ], Callable [[str ], int ])
454
- self .assertNotEqual (Callable [[int ], int ], Callable [[int , int ], int ])
455
- self .assertNotEqual (Callable [[int ], int ], Callable [[], int ])
456
- self .assertNotEqual (Callable [[int ], int ], Callable )
451
+ Callable = self .Callable
452
+ C = Callable [[int ], int ]
453
+ self .assertEqual (C , Callable [[int ], int ])
454
+ self .assertEqual (len ({C , Callable [[int ], int ]}), 1 )
455
+ self .assertNotEqual (C , Callable [[int ], str ])
456
+ self .assertNotEqual (C , Callable [[str ], int ])
457
+ self .assertNotEqual (C , Callable [[int , int ], int ])
458
+ self .assertNotEqual (C , Callable [[], int ])
459
+ self .assertNotEqual (C , Callable [..., int ])
460
+ self .assertNotEqual (C , Callable )
457
461
458
462
def test_cannot_instantiate (self ):
463
+ Callable = self .Callable
459
464
with self .assertRaises (TypeError ):
460
465
Callable ()
461
466
with self .assertRaises (TypeError ):
@@ -467,16 +472,19 @@ def test_cannot_instantiate(self):
467
472
type (c )()
468
473
469
474
def test_callable_wrong_forms (self ):
475
+ Callable = self .Callable
470
476
with self .assertRaises (TypeError ):
471
477
Callable [int ]
472
478
473
479
def test_callable_instance_works (self ):
480
+ Callable = self .Callable
474
481
def f ():
475
482
pass
476
483
self .assertIsInstance (f , Callable )
477
484
self .assertNotIsInstance (None , Callable )
478
485
479
486
def test_callable_instance_type_error (self ):
487
+ Callable = self .Callable
480
488
def f ():
481
489
pass
482
490
with self .assertRaises (TypeError ):
@@ -489,28 +497,142 @@ def f():
489
497
self .assertNotIsInstance (None , Callable [[], Any ])
490
498
491
499
def test_repr (self ):
500
+ Callable = self .Callable
501
+ fullname = f'{ Callable .__module__ } .Callable'
492
502
ct0 = Callable [[], bool ]
493
- self .assertEqual (repr (ct0 ), 'typing.Callable [[], bool]' )
503
+ self .assertEqual (repr (ct0 ), f' { fullname } [[], bool]' )
494
504
ct2 = Callable [[str , float ], int ]
495
- self .assertEqual (repr (ct2 ), 'typing.Callable [[str, float], int]' )
505
+ self .assertEqual (repr (ct2 ), f' { fullname } [[str, float], int]' )
496
506
ctv = Callable [..., str ]
497
- self .assertEqual (repr (ctv ), 'typing.Callable [..., str]' )
507
+ self .assertEqual (repr (ctv ), f' { fullname } [..., str]' )
498
508
ct3 = Callable [[str , float ], list [int ]]
499
- self .assertEqual (repr (ct3 ), 'typing.Callable [[str, float], list[int]]' )
509
+ self .assertEqual (repr (ct3 ), f' { fullname } [[str, float], list[int]]' )
500
510
501
511
def test_callable_with_ellipsis (self ):
502
-
512
+ Callable = self . Callable
503
513
def foo (a : Callable [..., T ]):
504
514
pass
505
515
506
516
self .assertEqual (get_type_hints (foo , globals (), locals ()),
507
517
{'a' : Callable [..., T ]})
508
518
509
519
def test_ellipsis_in_generic (self ):
520
+ Callable = self .Callable
510
521
# Shouldn't crash; see https://github.com/python/typing/issues/259
511
522
typing .List [Callable [..., str ]]
512
523
513
524
525
+ def test_basic (self ):
526
+ Callable = self .Callable
527
+ alias = Callable [[int , str ], float ]
528
+ if Callable is collections .abc .Callable :
529
+ self .assertIsInstance (alias , types .GenericAlias )
530
+ self .assertIs (alias .__origin__ , collections .abc .Callable )
531
+ self .assertEqual (alias .__args__ , (int , str , float ))
532
+ self .assertEqual (alias .__parameters__ , ())
533
+
534
+ def test_weakref (self ):
535
+ Callable = self .Callable
536
+ alias = Callable [[int , str ], float ]
537
+ self .assertEqual (weakref .ref (alias )(), alias )
538
+
539
+ def test_pickle (self ):
540
+ Callable = self .Callable
541
+ alias = Callable [[int , str ], float ]
542
+ for proto in range (pickle .HIGHEST_PROTOCOL + 1 ):
543
+ s = pickle .dumps (alias , proto )
544
+ loaded = pickle .loads (s )
545
+ self .assertEqual (alias .__origin__ , loaded .__origin__ )
546
+ self .assertEqual (alias .__args__ , loaded .__args__ )
547
+ self .assertEqual (alias .__parameters__ , loaded .__parameters__ )
548
+
549
+ def test_var_substitution (self ):
550
+ Callable = self .Callable
551
+ fullname = f"{ Callable .__module__ } .Callable"
552
+ C1 = Callable [[int , T ], T ]
553
+ C2 = Callable [[KT , T ], VT ]
554
+ C3 = Callable [..., T ]
555
+ self .assertEqual (C1 [str ], Callable [[int , str ], str ])
556
+ self .assertEqual (C2 [int , float , str ], Callable [[int , float ], str ])
557
+ self .assertEqual (C3 [int ], Callable [..., int ])
558
+
559
+ # multi chaining
560
+ C4 = C2 [int , VT , str ]
561
+ self .assertEqual (repr (C4 ), f"{ fullname } [[int, ~VT], str]" )
562
+ self .assertEqual (repr (C4 [dict ]), f"{ fullname } [[int, dict], str]" )
563
+ self .assertEqual (C4 [dict ], Callable [[int , dict ], str ])
564
+
565
+ # substitute a nested GenericAlias (both typing and the builtin
566
+ # version)
567
+ C5 = Callable [[typing .List [T ], tuple [KT , T ], VT ], int ]
568
+ self .assertEqual (C5 [int , str , float ],
569
+ Callable [[typing .List [int ], tuple [str , int ], float ], int ])
570
+
571
+ def test_type_erasure (self ):
572
+ Callable = self .Callable
573
+ class C1 (Callable ):
574
+ def __call__ (self ):
575
+ return None
576
+ a = C1 [[int ], T ]
577
+ self .assertIs (a ().__class__ , C1 )
578
+ self .assertEqual (a ().__orig_class__ , C1 [[int ], T ])
579
+
580
+ def test_paramspec (self ):
581
+ Callable = self .Callable
582
+ fullname = f"{ Callable .__module__ } .Callable"
583
+ P = ParamSpec ('P' )
584
+ C1 = Callable [P , T ]
585
+ # substitution
586
+ self .assertEqual (C1 [int , str ], Callable [[int ], str ])
587
+ self .assertEqual (C1 [[int , str ], str ], Callable [[int , str ], str ])
588
+ self .assertEqual (repr (C1 ), f"{ fullname } [~P, ~T]" )
589
+ self .assertEqual (repr (C1 [int , str ]), f"{ fullname } [[int], str]" )
590
+
591
+ C2 = Callable [P , int ]
592
+ # special case in PEP 612 where
593
+ # X[int, str, float] == X[[int, str, float]]
594
+ self .assertEqual (C2 [int , str , float ], C2 [[int , str , float ]])
595
+ self .assertEqual (repr (C2 ), f"{ fullname } [~P, int]" )
596
+ self .assertEqual (repr (C2 [int , str ]), f"{ fullname } [[int, str], int]" )
597
+
598
+ def test_concatenate (self ):
599
+ Callable = self .Callable
600
+ fullname = f"{ Callable .__module__ } .Callable"
601
+ P = ParamSpec ('P' )
602
+ C1 = Callable [typing .Concatenate [int , P ], int ]
603
+ self .assertEqual (repr (C1 ),
604
+ f"{ fullname } [typing.Concatenate[int, ~P], int]" )
605
+
606
+ def test_errors (self ):
607
+ Callable = self .Callable
608
+ alias = Callable [[int , str ], float ]
609
+ with self .assertRaisesRegex (TypeError , "is not a generic class" ):
610
+ alias [int ]
611
+ P = ParamSpec ('P' )
612
+ C1 = Callable [P , T ]
613
+ with self .assertRaisesRegex (TypeError , "many arguments for" ):
614
+ C1 [int , str , str ]
615
+ with self .assertRaisesRegex (TypeError , "few arguments for" ):
616
+ C1 [int ]
617
+
618
+ class TypingCallableTests (BaseCallableTests , BaseTestCase ):
619
+ Callable = typing .Callable
620
+
621
+ def test_consistency (self ):
622
+ # bpo-42195
623
+ # Testing collections.abc.Callable's consistency with typing.Callable
624
+ c1 = typing .Callable [[int , str ], dict ]
625
+ c2 = collections .abc .Callable [[int , str ], dict ]
626
+ self .assertEqual (c1 .__args__ , c2 .__args__ )
627
+ self .assertEqual (hash (c1 .__args__ ), hash (c2 .__args__ ))
628
+
629
+ test_errors = skip ("known bug #44793" )(BaseCallableTests .test_errors )
630
+
631
+
632
+ class CollectionsCallableTests (BaseCallableTests , BaseTestCase ):
633
+ Callable = collections .abc .Callable
634
+
635
+
514
636
class LiteralTests (BaseTestCase ):
515
637
def test_basics (self ):
516
638
# All of these are allowed.
@@ -4496,13 +4618,6 @@ class Z(Generic[P]):
4496
4618
self .assertEqual (G5 .__parameters__ , G6 .__parameters__ )
4497
4619
self .assertEqual (G5 , G6 )
4498
4620
4499
- def test_var_substitution (self ):
4500
- T = TypeVar ("T" )
4501
- P = ParamSpec ("P" )
4502
- C1 = Callable [P , T ]
4503
- self .assertEqual (C1 [int , str ], Callable [[int ], str ])
4504
- self .assertEqual (C1 [[int , str , dict ], float ], Callable [[int , str , dict ], float ])
4505
-
4506
4621
def test_no_paramspec_in__parameters__ (self ):
4507
4622
# ParamSpec should not be found in __parameters__
4508
4623
# of generics. Usages outside Callable, Concatenate
0 commit comments