11# -*- coding: utf-8 -*-
22
33from collections import namedtuple
4+
5+ from pytest_random_order .cache import FAILED_FIRST_LAST_FAILED_BUCKET_KEY
6+
47try :
58 from collections import OrderedDict
69except ImportError :
2326ItemKey .__new__ .__defaults__ = (None , None )
2427
2528
26- def _shuffle_items (items , bucket_key = None , disable = None , seed = None ):
29+ def _shuffle_items (items , bucket_key = None , disable = None , seed = None , session = None ):
2730 """
2831 Shuffles a list of `items` in place.
2932
@@ -52,11 +55,11 @@ def _shuffle_items(items, bucket_key=None, disable=None, seed=None):
5255 def get_full_bucket_key (item ):
5356 assert bucket_key or disable
5457 if bucket_key and disable :
55- return ItemKey (bucket = bucket_key (item ), disabled = disable (item ))
58+ return ItemKey (bucket = bucket_key (item , session ), disabled = disable (item , session ))
5659 elif disable :
57- return ItemKey (disabled = disable (item ))
60+ return ItemKey (disabled = disable (item , session ))
5861 else :
59- return ItemKey (bucket = bucket_key (item ))
62+ return ItemKey (bucket = bucket_key (item , session ))
6063
6164 # For a sequence of items A1, A2, B1, B2, C1, C2,
6265 # where key(A1) == key(A2) == key(C1) == key(C2),
@@ -69,15 +72,29 @@ def get_full_bucket_key(item):
6972 buckets [full_bucket_key ].append (item )
7073
7174 # Shuffle inside a bucket
72- for bucket in buckets .keys ():
73- if not bucket .disabled :
74- random .shuffle (buckets [bucket ])
7575
76- # Shuffle buckets
7776 bucket_keys = list (buckets .keys ())
78- random .shuffle (bucket_keys )
7977
80- items [:] = [item for bk in bucket_keys for item in buckets [bk ]]
78+ for full_bucket_key in buckets .keys ():
79+ if full_bucket_key .bucket == FAILED_FIRST_LAST_FAILED_BUCKET_KEY :
80+ # Do not shuffle the last failed bucket
81+ continue
82+
83+ if not full_bucket_key .disabled :
84+ random .shuffle (buckets [full_bucket_key ])
85+
86+ # Shuffle buckets
87+
88+ # Only the first bucket can be FAILED_FIRST_LAST_FAILED_BUCKET_KEY
89+ if bucket_keys and bucket_keys [0 ].bucket == FAILED_FIRST_LAST_FAILED_BUCKET_KEY :
90+ new_bucket_keys = list (buckets .keys ())[1 :]
91+ random .shuffle (new_bucket_keys )
92+ new_bucket_keys .insert (0 , bucket_keys [0 ])
93+ else :
94+ new_bucket_keys = list (buckets .keys ())
95+ random .shuffle (new_bucket_keys )
96+
97+ items [:] = [item for bk in new_bucket_keys for item in buckets [bk ]]
8198 return
8299
83100
@@ -89,7 +106,7 @@ def _get_set_of_item_ids(items):
89106 return s
90107
91108
92- def _disable (item ):
109+ def _disable (item , session ):
93110 marker = item .get_marker ('random_order' )
94111 if marker :
95112 is_disabled = marker .kwargs .get ('disabled' , False )
0 commit comments