55import re
66import sys
77from unittest import TestCase , main , SkipTest
8+ from copy import copy , deepcopy
89
910from typing import Any
1011from typing import TypeVar , AnyStr
@@ -141,8 +142,9 @@ def test_union_unique(self):
141142 self .assertEqual (Union [X , X ], X )
142143 self .assertNotEqual (Union [X , int ], Union [X ])
143144 self .assertNotEqual (Union [X , int ], Union [int ])
144- self .assertEqual (Union [X , int ].__union_params__ , (X , int ))
145- self .assertEqual (Union [X , int ].__union_set_params__ , {X , int })
145+ self .assertEqual (Union [X , int ].__args__ , (X , int ))
146+ self .assertEqual (Union [X , int ].__parameters__ , (X ,))
147+ self .assertIs (Union [X , int ].__origin__ , Union )
146148
147149 def test_union_constrained (self ):
148150 A = TypeVar ('A' , str , bytes )
@@ -308,8 +310,6 @@ def Elem(*args):
308310class TupleTests (BaseTestCase ):
309311
310312 def test_basics (self ):
311- with self .assertRaises (TypeError ):
312- issubclass (Tuple [int , str ], Tuple )
313313 with self .assertRaises (TypeError ):
314314 issubclass (Tuple , Tuple [int , str ])
315315 with self .assertRaises (TypeError ):
@@ -364,22 +364,6 @@ def test_eq_hash(self):
364364 self .assertNotEqual (Callable [[int ], int ], Callable [[], int ])
365365 self .assertNotEqual (Callable [[int ], int ], Callable )
366366
367- def test_cannot_subclass (self ):
368- with self .assertRaises (TypeError ):
369-
370- class C (Callable ):
371- pass
372-
373- with self .assertRaises (TypeError ):
374-
375- class C (type (Callable )):
376- pass
377-
378- with self .assertRaises (TypeError ):
379-
380- class C (Callable [[int ], int ]):
381- pass
382-
383367 def test_cannot_instantiate (self ):
384368 with self .assertRaises (TypeError ):
385369 Callable ()
@@ -506,6 +490,9 @@ def test_basics(self):
506490 Y [unicode , unicode ]
507491
508492 def test_generic_errors (self ):
493+ T = TypeVar ('T' )
494+ with self .assertRaises (TypeError ):
495+ Generic [T ]()
509496 with self .assertRaises (TypeError ):
510497 isinstance ([], List [int ])
511498 with self .assertRaises (TypeError ):
@@ -683,6 +670,124 @@ class D(C, List[T][U][V]): pass
683670 self .assertEqual (C .__orig_bases__ , (List [T ][U ][V ],))
684671 self .assertEqual (D .__orig_bases__ , (C , List [T ][U ][V ]))
685672
673+ def test_extended_generic_rules_eq (self ):
674+ T = TypeVar ('T' )
675+ U = TypeVar ('U' )
676+ self .assertEqual (Tuple [T , T ][int ], Tuple [int , int ])
677+ self .assertEqual (typing .Iterable [Tuple [T , T ]][T ], typing .Iterable [Tuple [T , T ]])
678+ with self .assertRaises (TypeError ):
679+ Tuple [T , int ][()]
680+ with self .assertRaises (TypeError ):
681+ Tuple [T , U ][T , ...]
682+
683+ self .assertEqual (Union [T , int ][int ], int )
684+ self .assertEqual (Union [T , U ][int , Union [int , str ]], Union [int , str ])
685+ class Base (object ): pass
686+ class Derived (Base ): pass
687+ self .assertEqual (Union [T , Base ][Derived ], Base )
688+ with self .assertRaises (TypeError ):
689+ Union [T , int ][1 ]
690+
691+ self .assertEqual (Callable [[T ], T ][KT ], Callable [[KT ], KT ])
692+ self .assertEqual (Callable [..., List [T ]][int ], Callable [..., List [int ]])
693+ with self .assertRaises (TypeError ):
694+ Callable [[T ], U ][..., int ]
695+ with self .assertRaises (TypeError ):
696+ Callable [[T ], U ][[], int ]
697+
698+ def test_extended_generic_rules_repr (self ):
699+ T = TypeVar ('T' )
700+ self .assertEqual (repr (Union [Tuple , Callable ]).replace ('typing.' , '' ),
701+ 'Union[Tuple, Callable]' )
702+ self .assertEqual (repr (Union [Tuple , Tuple [int ]]).replace ('typing.' , '' ),
703+ 'Tuple' )
704+ self .assertEqual (repr (Callable [..., Optional [T ]][int ]).replace ('typing.' , '' ),
705+ 'Callable[..., Union[int, NoneType]]' )
706+ self .assertEqual (repr (Callable [[], List [T ]][int ]).replace ('typing.' , '' ),
707+ 'Callable[[], List[int]]' )
708+
709+ def test_generic_forvard_ref (self ):
710+ LLT = List [List ['T' ]]
711+ T = TypeVar ('T' )
712+ self .assertEqual (typing ._eval_type (LLT , globals (), locals ()), List [List [T ]])
713+ TTE = Tuple [T , ...]
714+ self .assertIs (typing ._eval_type (TTE , globals (), locals ()), Tuple [T , ...])
715+
716+ def test_extended_generic_rules_subclassing (self ):
717+ class T1 (Tuple [T , KT ]): pass
718+ class T2 (Tuple [T , ...]): pass
719+ class C1 (Callable [[T ], T ]): pass
720+ class C2 (Callable [..., int ]):
721+ def __call__ (self ):
722+ return None
723+
724+ self .assertEqual (T1 .__parameters__ , (T , KT ))
725+ self .assertEqual (T1 [int , str ].__args__ , (int , str ))
726+ self .assertEqual (T1 [int , T ].__origin__ , T1 )
727+
728+ self .assertEqual (T2 .__parameters__ , (T ,))
729+ with self .assertRaises (TypeError ):
730+ T1 [int ]
731+ with self .assertRaises (TypeError ):
732+ T2 [int , str ]
733+
734+ self .assertEqual (repr (C1 [int ]).split ('.' )[- 1 ], 'C1[int]' )
735+ self .assertEqual (C2 .__parameters__ , ())
736+ self .assertIsInstance (C2 (), collections_abc .Callable )
737+ self .assertIsSubclass (C2 , collections_abc .Callable )
738+ self .assertIsSubclass (C1 , collections_abc .Callable )
739+ self .assertIsInstance (T1 (), tuple )
740+ self .assertIsSubclass (T2 , tuple )
741+ self .assertIsSubclass (Tuple [int , ...], typing .Sequence )
742+ self .assertIsSubclass (Tuple [int , ...], typing .Iterable )
743+
744+ def test_fail_with_bare_union (self ):
745+ with self .assertRaises (TypeError ):
746+ List [Union ]
747+ with self .assertRaises (TypeError ):
748+ Tuple [Optional ]
749+ with self .assertRaises (TypeError ):
750+ ClassVar [ClassVar ]
751+ with self .assertRaises (TypeError ):
752+ List [ClassVar [int ]]
753+
754+ def test_fail_with_bare_generic (self ):
755+ T = TypeVar ('T' )
756+ with self .assertRaises (TypeError ):
757+ List [Generic ]
758+ with self .assertRaises (TypeError ):
759+ Tuple [Generic [T ]]
760+ with self .assertRaises (TypeError ):
761+ List [typing ._Protocol ]
762+
763+ def test_type_erasure_special (self ):
764+ T = TypeVar ('T' )
765+ class MyTup (Tuple [T , T ]): pass
766+ self .assertIs (MyTup [int ]().__class__ , MyTup )
767+ self .assertIs (MyTup [int ]().__orig_class__ , MyTup [int ])
768+ class MyCall (Callable [..., T ]):
769+ def __call__ (self ): return None
770+ self .assertIs (MyCall [T ]().__class__ , MyCall )
771+ self .assertIs (MyCall [T ]().__orig_class__ , MyCall [T ])
772+ class MyDict (typing .Dict [T , T ]): pass
773+ self .assertIs (MyDict [int ]().__class__ , MyDict )
774+ self .assertIs (MyDict [int ]().__orig_class__ , MyDict [int ])
775+ class MyDef (typing .DefaultDict [str , T ]): pass
776+ self .assertIs (MyDef [int ]().__class__ , MyDef )
777+ self .assertIs (MyDef [int ]().__orig_class__ , MyDef [int ])
A3E2
code>778+
779+ def test_all_repr_eq_any (self ):
780+ objs = (getattr (typing , el ) for el in typing .__all__ )
781+ for obj in objs :
782+ self .assertNotEqual (repr (obj ), '' )
783+ self .assertEqual (obj , obj )
784+ if getattr (obj , '__parameters__' , None ) and len (obj .__parameters__ ) == 1 :
785+ self .assertEqual (obj [Any ].__args__ , (Any ,))
786+ if isinstance (obj , type ):
787+ for base in obj .__mro__ :
788+ self .assertNotEqual (repr (base ), '' )
789+ self .assertEqual (base , base )
790+
686791 def test_pickle (self ):
687792 global C # pickle wants to reference the class by name
688793 T = TypeVar ('T' )
@@ -702,6 +807,24 @@ class C(B[int]):
702807 self .assertEqual (x .foo , 42 )
703808 self .assertEqual (x .bar , 'abc' )
704809 self .assertEqual (x .__dict__ , {'foo' : 42 , 'bar' : 'abc' })
810+ simples = [Any , Union , Tuple , Callable , ClassVar , List , typing .Iterable ]
811+ for s in simples :
812+ for proto in range (pickle .HIGHEST_PROTOCOL + 1 ):
813+ z = pickle .dumps (s , proto )
814+ x = pickle .loads (z )
815+ self .assertEqual (s , x )
816+
817+ def test_copy_and_deepcopy (self ):
818+ T = TypeVar ('T' )
819+ class Node (Generic [T ]): pass
820+ things = [Any , Union [T , int ], Tuple [T , int ], Callable [..., T ], Callable [[int ], int ],
821+ Tuple [Any , Any ], Node [T ], Node [int ], Node [Any ], typing .Iterable [T ],
822+ typing .Iterable [Any ], typing .Iterable [int ], typing .Dict [int , str ],
823+ typing .Dict [T , Any ], ClassVar [int ], ClassVar [List [T ]], Tuple ['T' , 'T' ],
824+ Union ['T' , int ], List ['T' ], typing .Mapping ['T' , int ]]
825+ for t in things :
826+ self .assertEqual (t , deepcopy (t ))
827+ self .assertEqual (t , copy (t ))
705828
706829 def test_errors (self ):
707830 with self .assertRaises (TypeError ):
@@ -724,7 +847,7 @@ class C(Generic[T]):
724847 X = C [int ]
725848 self .assertEqual (X .__module__ , __name__ )
726849 if not PY32 :
727- self .assertEqual (X .__qualname__ , 'C' )
850+ self .assertTrue (X .__qualname__ . endswith ( '.<locals>.C' ) )
728851 self .assertEqual (repr (X ).split ('.' )[- 1 ], 'C[int]' )
729852
730853 class Y (C [int ]):
0 commit comments