@@ -1683,6 +1683,8 @@ class C(Generic[T]): pass
16831683 self .assertIn (get_args (Callable [P , int ]), [(P , int ), ([P ], int )])
16841684 self .assertEqual (get_args (Callable [Concatenate [int , P ], int ]),
16851685 (Concatenate [int , P ], int ))
1686+ self .assertEqual (get_args (Callable [Concatenate [int , ...], int ]),
1687+ (Concatenate [int , ...], int ))
16861688 self .assertEqual (get_args (Required [int ]), (int ,))
16871689 self .assertEqual (get_args (NotRequired [int ]), (int ,))
16881690 self .assertEqual (get_args (Unpack [Ts ]), (Ts ,))
@@ -5322,6 +5324,11 @@ class MyClass: ...
53225324
53235325 c = Concatenate [MyClass , P ]
53245326 self .assertNotEqual (c , Concatenate )
5327+
5328+ # Test Ellipsis Concatenation
5329+ d = Concatenate [MyClass , ...]
5330+ self .assertNotEqual (d , c )
5331+ self .assertNotEqual (d , Concatenate )
53255332
53265333 def test_valid_uses (self ):
53275334 P = ParamSpec ('P' )
@@ -5338,6 +5345,18 @@ def test_valid_uses(self):
53385345 C4 = collections .abc .Callable [Concatenate [int , T , P ], T ]
53395346 self .assertEqual (C3 .__origin__ , C4 .__origin__ )
53405347 self .assertNotEqual (C3 , C4 )
5348+
5349+ C5 = Callable [Concatenate [int , ...], int ]
5350+ C6 = Callable [Concatenate [int , T , ...], T ]
5351+ self .assertEqual (C5 .__origin__ , C6 .__origin__ )
5352+ self .assertNotEqual (C5 , C6 )
5353+
5354+ # Test collections.abc.Callable too.
5355+ if sys .version_info [:2 ] >= (3 , 9 ):
5356+ C7 = collections .abc .Callable [Concatenate [int , ...], int ]
5357+ C8 = collections .abc .Callable [Concatenate [int , T , ...], T ]
5358+ self .assertEqual (C7 .__origin__ , C8 .__origin__ )
5359+ self .assertNotEqual (C7 , C8 )
53415360
53425361 def test_invalid_uses (self ):
53435362 P = ParamSpec ('P' )
@@ -5351,7 +5370,7 @@ def test_invalid_uses(self):
53515370
53525371 with self .assertRaisesRegex (
53535372 TypeError ,
5354- 'The last parameter to Concatenate should be a ParamSpec variable' ,
5373+ 'The last parameter to Concatenate should be a ParamSpec variable or ellipsis ' ,
53555374 ):
53565375 Concatenate [P , T ]
53575376
@@ -5361,15 +5380,27 @@ def test_invalid_uses(self):
53615380 'each arg must be a type' ,
53625381 ):
53635382 Concatenate [1 , P ]
5383+
5384+ with self .assertRaisesRegex (
5385+ TypeError ,
5386+ 'each arg must be a type.' ,
5387+ ):
5388+ Concatenate [1 , ..., P ]
53645389
53655390 def test_basic_introspection (self ):
53665391 P = ParamSpec ('P' )
53675392 C1 = Concatenate [int , P ]
53685393 C2 = Concatenate [int , T , P ]
5394+ C3 = Concatenate [int , ...]
5395+ C4 = Concatenate [int , T , ...]
53695396 self .assertEqual (C1 .__origin__ , Concatenate )
53705397 self .assertEqual (C1 .__args__ , (int , P ))
53715398 self .assertEqual (C2 .__origin__ , Concatenate )
53725399 self .assertEqual (C2 .__args__ , (int , T , P ))
5400+ self .assertEqual (C3 .__origin__ , Concatenate )
5401+ self .assertEqual (C3 .__args__ , (int , Ellipsis ))
5402+ self .assertEqual (C4 .__origin__ , Concatenate )
5403+ self .assertEqual (C4 .__args__ , (int , T , Ellipsis ))
53735404
53745405 def test_eq (self ):
53755406 P = ParamSpec ('P' )
@@ -5379,6 +5410,13 @@ def test_eq(self):
53795410 self .assertEqual (C1 , C2 )
53805411 self .assertEqual (hash (C1 ), hash (C2 ))
53815412 self .assertNotEqual (C1 , C3 )
5413+
5414+ C4 = Concatenate [int , ...]
5415+ C5 = Concatenate [int , ...]
5416+ C6 = Concatenate [int , T , ...]
5417+ self .assertEqual (C4 , C5 )
5418+ self .assertEqual (hash (C4 ), hash (C5 ))
5419+ self .assertNotEqual (C4 , C6 )
53825420
53835421
53845422class TypeGuardTests (BaseTestCase ):
@@ -6050,7 +6088,7 @@ def test_typing_extensions_defers_when_possible(self):
60506088 if sys .version_info < (3 , 10 , 1 ):
60516089 exclude |= {"Literal" }
60526090 if sys .version_info < (3 , 11 ):
6053- exclude |= {'final' , 'Any' , 'NewType' , 'overload' }
6091+ exclude |= {'final' , 'Any' , 'NewType' , 'overload' , 'Concatenate' }
60546092 if sys .version_info < (3 , 12 ):
60556093 exclude |= {
60566094 'SupportsAbs' , 'SupportsBytes' ,
0 commit comments