@@ -411,6 +411,10 @@ def test_cannot_be_called(self):
411
411
412
412
class TypeVarTupleTests (BaseTestCase ):
413
413
414
+ def assertEndsWith (self , string , tail ):
415
+ if not string .endswith (tail ):
416
+ self .fail (f"String { string !r} does not end with { tail !r} " )
417
+
414
418
def test_instance_is_equal_to_itself (self ):
415
419
Ts = TypeVarTuple ('Ts' )
416
420
self .assertEqual (Ts , Ts )
@@ -457,6 +461,56 @@ def test_tuple_args_and_parameters_are_correct(self):
457
461
self .assertEqual (t2 .__args__ , (Unpack [Ts ],))
458
462
self .assertEqual (t2 .__parameters__ , (Ts ,))
459
463
464
+ def test_var_substitution (self ):
465
+ Ts = TypeVarTuple ('Ts' )
466
+ T = TypeVar ('T' )
467
+ T2 = TypeVar ('T2' )
468
+ class G (Generic [Unpack [Ts ]]): pass
469
+
470
+ for A in G , Tuple :
471
+ B = A [Unpack [Ts ]]
472
+ if A != Tuple :
473
+ self .assertEqual (B [()], A [()])
474
+ self .assertEqual (B [float ], A [float ])
475
+ self .assertEqual (B [float , str ], A [float , str ])
476
+
477
+ C = List [A [Unpack [Ts ]]]
478
+ if A != Tuple :
479
+ self .assertEqual (C [()], List [A [()]])
480
+ self .assertEqual (C [float ], List [A [float ]])
481
+ self .assertEqual (C [float , str ], List [A [float , str ]])
482
+
483
+ D = A [T , Unpack [Ts ], T2 ]
484
+ with self .assertRaises (TypeError ):
485
+ D [()]
486
+ with self .assertRaises (TypeError ):
487
+ D [float ]
488
+ self .assertEqual (D [float , str ], A [float , str ])
489
+ self .assertEqual (D [float , str , int ], A [float , str , int ])
490
+ self .assertEqual (D [float , str , int , bytes ], A [float , str , int , bytes ])
491
+
492
+ E = Tuple [List [T ], A [Unpack [Ts ]], List [T2 ]]
493
+ with self .assertRaises (TypeError ):
494
+ E [()]
495
+ with self .assertRaises (TypeError ):
496
+ E [float ]
497
+ if A != Tuple :
498
+ self .assertEqual (E [float , str ],
499
+ Tuple [List [float ], A [()], List [str ]])
500
+ self .assertEqual (E [float , str , int ],
501
+ Tuple [List [float ], A [str ], List [int ]])
502
+ self .assertEqual (E [float , str , int , bytes ],
503
+ Tuple [List [float ], A [str , int ], List [bytes ]])
504
+
505
+ def test_repr_is_correct (self ):
506
+ Ts = TypeVarTuple ('Ts' )
507
+ self .assertEqual (repr (Ts ), 'Ts' )
508
+ self .assertEqual (repr (Unpack [Ts ]), '*Ts' )
509
+ self .assertEqual (repr (tuple [Unpack [Ts ]]), 'tuple[*Ts]' )
510
+ self .assertEqual (repr (Tuple [Unpack [Ts ]]), 'typing.Tuple[*Ts]' )
511
+ self .assertEqual (repr (Unpack [tuple [Unpack [Ts ]]]), '*tuple[*Ts]' )
512
+ self .assertEqual (repr (Unpack [Tuple [Unpack [Ts ]]]), '*typing.Tuple[*Ts]' )
513
+
460
514
def test_repr_is_correct (self ):
461
515
Ts = TypeVarTuple ('Ts' )
462
516
self .assertEqual (repr (Ts ), 'Ts' )
@@ -470,78 +524,51 @@ def test_variadic_class_repr_is_correct(self):
470
524
Ts = TypeVarTuple ('Ts' )
471
525
class A (Generic [Unpack [Ts ]]): pass
472
526
473
- self .assertTrue (repr (A [()]).endswith ('A[()]' ))
474
- self .assertTrue (repr (A [float ]).endswith ('A[float]' ))
475
- self .assertTrue (repr (A [float , str ]).endswith ('A[float, str]' ))
476
- self .assertTrue (repr (
477
- A [Unpack [tuple [int , ...]]]
478
- ).endswith (
479
- 'A[*tuple[int, ...]]'
480
- ))
481
- self .assertTrue (repr (
482
- A [float , Unpack [tuple [int , ...]]]
483
- ).endswith (
484
- 'A[float, *tuple[int, ...]]'
485
- ))
486
- self .assertTrue (repr (
487
- A [Unpack [tuple [int , ...]], str ]
488
- ).endswith (
489
- 'A[*tuple[int, ...], str]'
490
- ))
491
- self .assertTrue (repr (
492
- A [float , Unpack [tuple [int , ...]], str ]
493
- ).endswith (
494
- 'A[float, *tuple[int, ...], str]'
495
- ))
527
+ self .assertEndsWith (repr (A [()]), 'A[()]' )
528
+ self .assertEndsWith (repr (A [float ]), 'A[float]' )
529
+ self .assertEndsWith (repr (A [float , str ]), 'A[float, str]' )
530
+ self .assertEndsWith (repr (A [Unpack [tuple [int , ...]]]),
531
+ 'A[*tuple[int, ...]]' )
532
+ self .assertEndsWith (repr (A [float , Unpack [tuple [int , ...]]]),
533
+ 'A[float, *tuple[int, ...]]' )
534
+ self .assertEndsWith (repr (A [Unpack [tuple [int , ...]], str ]),
535
+ 'A[*tuple[int, ...], str]' )
536
+ self .assertEndsWith (repr (A [float , Unpack [tuple [int , ...]], str ]),
537
+ 'A[float, *tuple[int, ...], str]' )
496
538
497
539
def test_variadic_class_alias_repr_is_correct (self ):
498
540
Ts = TypeVarTuple ('Ts' )
499
541
class A (Generic [Unpack [Ts ]]): pass
500
542
501
543
B = A [Unpack [Ts ]]
502
- self .assertTrue (repr (B ).endswith ('A[*Ts]' ))
503
- with self .assertRaises (NotImplementedError ):
504
- B [()]
505
- with self .assertRaises (NotImplementedError ):
506
- B [float ]
507
- with self .assertRaises (NotImplementedError ):
508
- B [float , str ]
544
+ self .assertEndsWith (repr (B ), 'A[*Ts]' )
545
+ self .assertEndsWith (repr (B [()]), 'A[()]' )
546
+ self .assertEndsWith (repr (B [float ]), 'A[float]' )
547
+ self .assertEndsWith (repr (B [float , str ]), 'A[float, str]' )
509
548
510
549
C = A [Unpack [Ts ], int ]
511
- self .assertTrue (repr (C ).endswith ('A[*Ts, int]' ))
512
- with self .assertRaises (NotImplementedError ):
513
- C [()]
514
- with self .assertRaises (NotImplementedError ):
515
- C [float ]
516
- with self .assertRaises (NotImplementedError ):
517
- C [float , str ]
550
+ self .assertEndsWith (repr (C ), 'A[*Ts, int]' )
551
+ self .assertEndsWith (repr (C [()]), 'A[int]' )
552
+ self .assertEndsWith (repr (C [float ]), 'A[float, int]' )
553
+ self .assertEndsWith (repr (C [float , str ]), 'A[float, str, int]' )
518
554
519
555
D = A [int , Unpack [Ts ]]
520
- self .assertTrue (repr (D ).endswith ('A[int, *Ts]' ))
521
- with self .assertRaises (NotImplementedError ):
522
- D [()]
523
- with self .assertRaises (NotImplementedError ):
524
- D [float ]
525
- with self .assertRaises (NotImplementedError ):
526
- D [float , str ]
556
+ self .assertEndsWith (repr (D ), 'A[int, *Ts]' )
557
+ self .assertEndsWith (repr (D [()]), 'A[int]' )
558
+ self .assertEndsWith (repr (D [float ]), 'A[int, float]' )
559
+ self .assertEndsWith (repr (D [float , str ]), 'A[int, float, str]' )
527
560
528
561
E = A [int , Unpack [Ts ], str ]
529
- self .assertTrue (repr (E ).endswith ('A[int, *Ts, str]' ))
530
- with self .assertRaises (NotImplementedError ):
531
- E [()]
532
- with self .assertRaises (NotImplementedError ):
533
- E [float ]
534
- with self .assertRaises (NotImplementedError ):
535
- E [float , bool ]
562
+ self .assertEndsWith (repr (E ), 'A[int, *Ts, str]' )
563
+ self .assertEndsWith (repr (E [()]), 'A[int, str]' )
564
+ self .assertEndsWith (repr (E [float ]), 'A[int, float, str]' )
565
+ self .assertEndsWith (repr (E [float , str ]), 'A[int, float, str, str]' )
536
566
537
567
F = A [Unpack [Ts ], Unpack [tuple [str , ...]]]
538
- self .assertTrue (repr (F ).endswith ('A[*Ts, *tuple[str, ...]]' ))
539
- with self .assertRaises (NotImplementedError ):
540
- F [()]
541
- with self .assertRaises (NotImplementedError ):
542
- F [float ]
543
- with self .assertRaises (NotImplementedError ):
544
- F [float , int ]
568
+ self .assertEndsWith (repr (F ), 'A[*Ts, *tuple[str, ...]]' )
569
+ self .assertEndsWith (repr (F [()]), 'A[*tuple[str, ...]]' )
570
+ self .assertEndsWith (repr (F [float ]), 'A[float, *tuple[str, ...]]' )
571
+ self .assertEndsWith (repr (F [float , str ]), 'A[float, str, *tuple[str, ...]]' )
545
572
546
573
def test_cannot_subclass_class (self ):
547
574
with self .assertRaises (TypeError ):
0 commit comments