@@ -132,6 +132,7 @@ def test_basic_constrained(self):
132
132
def test_constrained_error (self ):
133
133
with self .assertRaises (TypeError ):
134
134
X = TypeVar ('X' , int )
135
+ X
135
136
136
137
def test_union_unique (self ):
137
138
X = TypeVar ('X' )
@@ -316,6 +317,7 @@ def test_union_instance_type_error(self):
316
317
def test_union_str_pattern (self ):
317
318
# Shouldn't crash; see http://bugs.python.org/issue25390
318
319
A = Union [str , Pattern ]
320
+ A
319
321
320
322
321
323
class TypeVarUnionTests (TestCase ):
@@ -478,7 +480,7 @@ def get(self, key, default=None):
478
480
pass
479
481
480
482
481
- class MySimpleMapping (SimpleMapping ):
483
+ class MySimpleMapping (SimpleMapping [ XK , XV ] ):
482
484
483
485
def __init__ (self ):
484
486
self .store = {}
@@ -533,14 +535,17 @@ def test_protocol_instance_type_error(self):
533
535
class GenericTests (TestCase ):
534
536
535
537
def test_basics (self ):
536
- X = SimpleMapping [unicode , Any ]
537
- Y = SimpleMapping [ XK , unicode ]
538
- X [ unicode , unicode ]
539
- Y [ unicode , unicode ]
538
+ X = SimpleMapping [str , Any ]
539
+ assert X . __parameters__ == ()
540
+ with self . assertRaises ( TypeError ):
541
+ X [ unicode ]
540
542
with self .assertRaises (TypeError ):
541
- X [int , unicode ]
543
+ X [unicode , unicode ]
544
+ Y = SimpleMapping [XK , unicode ]
545
+ assert Y .__parameters__ == (XK ,)
546
+ Y [unicode ]
542
547
with self .assertRaises (TypeError ):
543
- Y [unicode , bytes ]
548
+ Y [unicode , unicode ]
544
549
545
550
def test_init (self ):
546
551
T = TypeVar ('T' )
@@ -552,9 +557,33 @@ def test_init(self):
552
557
553
558
def test_repr (self ):
554
559
self .assertEqual (repr (SimpleMapping ),
555
- __name__ + '.' + 'SimpleMapping[ ~XK, ~XV] ' )
560
+ __name__ + '.' + 'SimpleMapping< ~XK, ~XV> ' )
556
561
self .assertEqual (repr (MySimpleMapping ),
557
- __name__ + '.' + 'MySimpleMapping[~XK, ~XV]' )
562
+ __name__ + '.' + 'MySimpleMapping<~XK, ~XV>' )
563
+
564
+ def test_chain_repr (self ):
565
+ T = TypeVar ('T' )
566
+ S = TypeVar ('S' )
567
+
568
+ class C (Generic [T ]):
569
+ pass
570
+
571
+ X = C [Tuple [S , T ]]
572
+ assert X == C [Tuple [S , T ]]
573
+ assert X != C [Tuple [T , S ]]
574
+
575
+ Y = X [T , int ]
576
+ assert Y == X [T , int ]
577
+ assert Y != X [S , int ]
578
+ assert Y != X [T , str ]
579
+
580
+ Z = Y [str ]
581
+ assert Z == Y [str ]
582
+ assert Z != Y [int ]
583
+ assert Z != Y [T ]
584
+
585
+ assert str (Z ).endswith (
586
+ '.C<~T>[typing.Tuple[~S, ~T]]<~S, ~T>[~T, int]<~T>[str]' )
558
587
559
588
def test_dict (self ):
560
589
T = TypeVar ('T' )
@@ -609,20 +638,20 @@ class C(Generic[T]):
609
638
assert C .__module__ == __name__
610
639
if not PY32 :
611
640
assert C .__qualname__ == 'GenericTests.test_repr_2.<locals>.C'
612
- assert repr (C ).split ('.' )[- 1 ] == 'C[~T] '
641
+ assert repr (C ).split ('.' )[- 1 ] == 'C<~T> '
613
642
X = C [int ]
614
643
assert X .__module__ == __name__
615
644
if not PY32 :
616
645
assert X .__qualname__ == 'C'
617
- assert repr (X ).split ('.' )[- 1 ] == 'C[int]'
646
+ assert repr (X ).split ('.' )[- 1 ] == 'C<~T> [int]'
618
647
619
648
class Y (C [int ]):
620
649
pass
621
650
622
651
assert Y .__module__ == __name__
623
652
if not PY32 :
624
653
assert Y .__qualname__ == 'GenericTests.test_repr_2.<locals>.Y'
625
- assert repr (Y ).split ('.' )[- 1 ] == 'Y[int] '
654
+ assert repr (Y ).split ('.' )[- 1 ] == 'Y'
626
655
627
656
def test_eq_1 (self ):
628
657
assert Generic == Generic
@@ -650,10 +679,40 @@ class A(Generic[T, VT]):
650
679
class B (Generic [KT , T ]):
651
680
pass
652
681
653
- class C (A , Generic [KT , VT ], B ):
682
+ class C (A [ T , VT ], Generic [VT , T , KT ], B [ KT , T ] ):
654
683
pass
655
684
656
- assert C .__parameters__ == (T , VT , KT )
685
+ assert C .__parameters__ == (VT , T , KT )
686
+
687
+ def test_nested (self ):
688
+
689
+ G = Generic
690
+
691
+ class Visitor (G [T ]):
692
+
693
+ a = None
694
+
695
+ def set (self , a ):
696
+ self .a = a
697
+
698
+ def get (self ):
699
+ return self .a
700
+
701
+ def visit (self ):
702
+ return self .a
703
+
704
+ V = Visitor [typing .List [int ]]
705
+
706
+ class IntListVisitor (V ):
707
+
708
+ def append (self , x ):
709
+ self .a .append (x )
710
+
711
+ a = IntListVisitor ()
712
+ a .set ([])
713
+ a .append (1 )
714
+ a .append (42 )
715
+ assert a .get () == [1 , 42 ]
657
716
658
717
def test_type_erasure (self ):
659
718
T = TypeVar ('T' )
@@ -679,6 +738,24 @@ def foo(x):
679
738
680
739
foo (42 )
681
740
741
+ def test_implicit_any (self ):
742
+ T = TypeVar ('T' )
743
+
744
+ class C (Generic [T ]):
745
+ pass
746
+
747
+ class D (C ):
748
+ pass
749
+
750
+ assert D .__parameters__ == ()
751
+
752
+ with self .assertRaises (Exception ):
753
+ D [int ]
754
+ with self .assertRaises (Exception ):
755
+ D [Any ]
756
+ with self .assertRaises (Exception ):
757
+ D [T ]
758
+
682
759
683
760
class VarianceTests (TestCase ):
684
761
@@ -988,6 +1065,15 @@ def test_basics(self):
988
1065
assert Emp ._fields == ('name' , 'id' )
989
1066
assert Emp ._field_types == dict (name = str , id = int )
990
1067
1068
+ def test_pickle (self ):
1069
+ global Emp # pickle wants to reference the class by name
1070
+ Emp = NamedTuple ('Emp' , [('name' , str ), ('id' , int )])
1071
+ jane = Emp ('jane' , 37 )
1072
+ for proto in range (pickle .HIGHEST_PROTOCOL + 1 ):
1073
+ z = pickle .dumps (jane , proto )
1074
+ jane2 = pickle .loads (z )
1075
+ self .assertEqual (jane2 , jane )
1076
+
991
1077
992
1078
class IOTests (TestCase ):
993
1079
0 commit comments