11"""Unit tests for zero-argument super() & related machinery."""
22
3+ import copy
4+ import pickle
35import textwrap
46import threading
57import unittest
68from unittest .mock import patch
79from test .support import import_helper , threading_helper
810
911
10- ADAPTIVE_WARMUP_DELAY = 2
11-
12-
1312class A :
1413 def f (self ):
1514 return 'A'
@@ -91,8 +90,7 @@ def nested():
9190
9291 self .assertEqual (E ().f (), 'AE' )
9392
94- # TODO: RUSTPYTHON; SyntaxError: name '__class__' is assigned to before global declaration
95- '''
93+ @unittest .expectedFailure # TODO: RUSTPYTHON
9694 def test_various___class___pathologies (self ):
9795 # See issue #12370
9896 class X (A ):
@@ -114,20 +112,19 @@ def f():
114112 __class__""" , globals (), {})
115113 self .assertIs (type (e .exception ), NameError ) # Not UnboundLocalError
116114 class X :
117- global __class__
115+ # global __class__ # TODO: RUSTPYTHON; SyntaxError: name '__class__' is assigned to before global declaration
118116 __class__ = 42
119117 def f ():
120118 __class__
121119 self .assertEqual (globals ()["__class__" ], 42 )
122120 del globals ()["__class__" ]
123121 self .assertNotIn ("__class__" , X .__dict__ )
124122 class X :
125- nonlocal __class__
123+ # nonlocal __class__ # TODO: RUSTPYTHON; SyntaxError: name '__class__' is assigned to before nonlocal declaration
126124 __class__ = 42
127125 def f ():
128126 __class__
129127 self .assertEqual (__class__ , 42 )
130- '''
131128
132129 def test___class___instancemethod (self ):
133130 # See issue #14857
@@ -191,7 +188,7 @@ def f():
191188 B = type ("B" , (), test_namespace )
192189 self .assertIs (B .f (), B )
193190
194- @unittest .expectedFailure # TODO: RUSTPYTHON
191+ @unittest .expectedFailure # TODO: RUSTPYTHON
195192 def test___class___mro (self ):
196193 # See issue #23722
197194 test_class = None
@@ -449,7 +446,7 @@ def method(self):
449446
450447 self .assertEqual (C ().method (), super )
451448
452- @unittest .expectedFailure # TODO: RUSTPYTHON; TypeError: type 'super' is not an acceptable base type
449+ @unittest .expectedFailure # TODO: RUSTPYTHON; TypeError: type 'super' is not an acceptable base type
453450 def test_super_subclass___class__ (self ):
454451 class mysuper (super ):
455452 pass
@@ -469,7 +466,8 @@ def test(name):
469466 super (MyType , type (mytype )).__setattr__ (mytype , "bar" , 1 )
470467 self .assertEqual (mytype .bar , 1 )
471468
472- for _ in range (ADAPTIVE_WARMUP_DELAY ):
469+ _testinternalcapi = import_helper .import_module ("_testinternalcapi" )
470+ for _ in range (_testinternalcapi .SPECIALIZATION_THRESHOLD ):
473471 test ("foo1" )
474472
475473 def test_reassigned_new (self ):
@@ -488,7 +486,8 @@ class C(B):
488486 def __new__ (cls ):
489487 return super ().__new__ (cls )
490488
491- for _ in range (ADAPTIVE_WARMUP_DELAY ):
489+ _testinternalcapi = import_helper .import_module ("_testinternalcapi" )
490+ for _ in range (_testinternalcapi .SPECIALIZATION_THRESHOLD ):
492491 C ()
493492
494493 def test_mixed_staticmethod_hierarchy (self ):
@@ -508,7 +507,8 @@ class C(B):
508507 def some (cls ):
509508 return super ().some (cls )
510509
511- for _ in range (ADAPTIVE_WARMUP_DELAY ):
510+ _testinternalcapi = import_helper .import_module ("_testinternalcapi" )
511+ for _ in range (_testinternalcapi .SPECIALIZATION_THRESHOLD ):
512512 C .some (C )
513513
514514 @threading_helper .requires_working_threading ()
@@ -544,6 +544,74 @@ def work():
544544 for thread in threads :
545545 thread .join ()
546546
547+ def test_special_methods (self ):
548+ for e in E (), E :
549+ s = super (C , e )
550+ self .assertEqual (s .__reduce__ , e .__reduce__ )
551+ self .assertEqual (s .__reduce_ex__ , e .__reduce_ex__ )
552+ self .assertEqual (s .__getstate__ , e .__getstate__ )
553+ self .assertNotHasAttr (s , '__getnewargs__' )
554+ self .assertNotHasAttr (s , '__getnewargs_ex__' )
555+ self .assertNotHasAttr (s , '__setstate__' )
556+ self .assertNotHasAttr (s , '__copy__' )
557+ self .assertNotHasAttr (s , '__deepcopy__' )
558+
559+ def test_pickling (self ):
560+ e = E ()
561+ e .x = 1
562+ s = super (C , e )
563+ for proto in range (pickle .HIGHEST_PROTOCOL + 1 ):
564+ with self .subTest (proto = proto ):
565+ u = pickle .loads (pickle .dumps (s , proto ))
566+ self .assertEqual (u .f (), s .f ())
567+ self .assertIs (type (u ), type (s ))
568+ self .assertIs (type (u .__self__ ), E )
569+ self .assertEqual (u .__self__ .x , 1 )
570+ self .assertIs (u .__thisclass__ , C )
571+ self .assertIs (u .__self_class__ , E )
572+
573+ s = super (C , E )
574+ for proto in range (pickle .HIGHEST_PROTOCOL + 1 ):
575+ with self .subTest (proto = proto ):
576+ u = pickle .loads (pickle .dumps (s , proto ))
577+ self .assertEqual (u .cm (), s .cm ())
578+ self .assertEqual (u .f , s .f )
579+ self .assertIs (type (u ), type (s ))
580+ self .assertIs (u .__self__ , E )
581+ self .assertIs (u .__thisclass__ , C )
582+ self .assertIs (u .__self_class__ , E )
583+
584+ def test_shallow_copying (self ):
585+ s = super (C , E ())
586+ self .assertIs (copy .copy (s ), s )
587+ s = super (C , E )
588+ self .assertIs (copy .copy (s ), s )
589+
590+ def test_deep_copying (self ):
591+ e = E ()
592+ e .x = [1 ]
593+ s = super (C , e )
594+ u = copy .deepcopy (s )
595+ self .assertEqual (u .f (), s .f ())
596+ self .assertIs (type (u ), type (s ))
597+ self .assertIsNot (u , s )
598+ self .assertIs (type (u .__self__ ), E )
599+ self .assertIsNot (u .__self__ , e )
600+ self .assertIsNot (u .__self__ .x , e .x )
601+ self .assertEqual (u .__self__ .x , [1 ])
602+ self .assertIs (u .__thisclass__ , C )
603+ self .assertIs (u .__self_class__ , E )
604+
605+ s = super (C , E )
606+ u = copy .deepcopy (s )
607+ self .assertEqual (u .cm (), s .cm ())
608+ self .assertEqual (u .f , s .f )
609+ self .assertIsNot (u , s )
610+ self .assertIs (type (u ), type (s ))
611+ self .assertIs (u .__self__ , E )
612+ self .assertIs (u .__thisclass__ , C )
613+ self .assertIs (u .__self_class__ , E )
614+
547615
548616if __name__ == "__main__" :
549617 unittest .main ()
0 commit comments