11# Some simple queue module tests, plus some failure conditions
22# to ensure the Queue locks remain stable.
3+ import itertools
34import random
45import threading
56import time
@@ -1016,27 +1017,12 @@ def setUp(self):
10161017 self .type2test = self .queue ._PySimpleQueue
10171018 super ().setUp ()
10181019
1019- def test_sizeof (self ):
1020+ def test_pysimplequeue_sizeof_constant (self ):
10201021 q = self .type2test ()
1021-
1022- empty_size = q .__sizeof__ ()
1023- self .assertGreater (empty_size , 0 )
1024-
1025- for i in range (8 ):
1022+ size0 = q .__sizeof__ ()
1023+ for _ in range (1000 ):
10261024 q .put (object ())
1027-
1028- size_after_8 = q .__sizeof__ ()
1029-
1030- q .put (object ()) # Now 9 items
1031- size_after_9 = q .__sizeof__ ()
1032- self .assertGreaterEqual (size_after_9 , size_after_8 )
1033-
1034- large_q = self .type2test ()
1035- for i in range (1000 ):
1036- large_q .put (object ())
1037-
1038- large_size = large_q .__sizeof__ ()
1039- self .assertGreater (large_size , 0 )
1025+ self .assertEqual (q .__sizeof__ (), size0 )
10401026
10411027
10421028@need_c_queue
@@ -1048,30 +1034,60 @@ def setUp(self):
10481034 self .type2test = self .queue .SimpleQueue
10491035 super ().setUp ()
10501036
1051- def test_sizeof (self ):
1037+ def test_simplequeue_sizeof_grow (self ):
10521038 q = self .type2test ()
1053-
10541039 empty_size = q .__sizeof__ ()
1055- self .assertGreater (empty_size , 0 )
1056-
1057- for i in range (8 ):
1040+ for _ in range (8 ):
10581041 q .put (object ())
1059-
10601042 size_after_8 = q .__sizeof__ ()
1061-
1062- q .put (object ()) # Now 9 items - should trigger ring buffer growth
1043+ q .put (object ()) # 9th item triggers ring buffer growth 8 -> 16
10631044 size_after_9 = q .__sizeof__ ()
1045+ self .assertGreaterEqual (size_after_8 , empty_size )
10641046 self .assertGreater (size_after_9 , size_after_8 )
10651047
1066- large_q = self .type2test ()
1067- for i in range (1000 ):
1068- large_q .put (object ())
1048+ def test_simplequeue_sizeof_shrink (self ):
1049+ q = self .type2test ()
1050+ for _ in range (9 ):
1051+ q .put (object ()) # grow to capacity 16
1052+ # Drain until 3 remain (< 16/4), then next get triggers shrink to 8
1053+ while q .qsize () > 3 :
1054+ q .get ()
1055+ size_before = q .__sizeof__ ()
1056+ q .get ()
1057+ size_after = q .__sizeof__ ()
1058+ self .assertLess (size_after , size_before )
1059+
1060+ def test_is_default (self ):
1061+ self .assertIs (self .type2test , self .queue .SimpleQueue )
1062+ self .assertIs (self .type2test , self .queue .SimpleQueue )
1063+
1064+ def test_reentrancy (self ):
1065+ # bpo-14976: put() may be called reentrantly in an asynchronous
1066+ # callback.
1067+ q = self .q
1068+ gen = itertools .count ()
1069+ N = 10000
1070+ results = []
1071+
1072+ # This test exploits the fact that __del__ in a reference cycle
1073+ # can be called any time the GC may run.
10691074
1070- large_size = large_q .__sizeof__ ()
1075+ class Circular (object ):
1076+ def __init__ (self ):
1077+ self .circular = self
10711078
1072- self .assertGreater (large_size , empty_size )
1079+ def __del__ (self ):
1080+ q .put (next (gen ))
1081+
1082+ while True :
1083+ o = Circular ()
1084+ q .put (next (gen ))
1085+ del o
1086+ results .append (q .get ())
1087+ if results [- 1 ] >= N :
1088+ break
10731089
1074- self .assertGreater ( large_size , empty_size * 2 )
1090+ self .assertEqual ( results , list ( range ( N + 1 )) )
10751091
10761092
10771093if __name__ == "__main__" :
0 commit comments