@@ -44,7 +44,7 @@ def pytest_configure(config):
4444 )
4545 config .addinivalue_line ("markers" , config_line )
4646
47- if config .getoption ("indulgent-ordering " ):
47+ if config .getoption ("indulgent_ordering " ):
4848 # We need to dynamically add this `tryfirst` decorator to the plugin:
4949 # only when the CLI option is present should the decorator be added.
5050 # Thus, we manually run the decorator on the class function and
@@ -65,14 +65,18 @@ def pytest_addoption(parser):
6565 """Set up CLI option for pytest"""
6666 group = parser .getgroup ("ordering" )
6767 group .addoption ("--indulgent-ordering" , action = "store_true" ,
68- dest = "indulgent-ordering " ,
68+ dest = "indulgent_ordering " ,
6969 help = "Request that the sort order provided by "
7070 "pytest-order be applied before other sorting, "
7171 "allowing the other sorting to have priority" )
7272 group .addoption ("--order-scope" , action = "store" ,
73- dest = "order-scope " ,
73+ dest = "order_scope " ,
7474 help = "Defines the scope used for ordering. Possible values"
7575 "are 'session' (default), 'module', and 'class'" )
76+ group .addoption ("--sparse-ordering" , action = "store_true" ,
77+ dest = "sparse_ordering" ,
78+ help = "If there are gaps between ordinals they are filled "
79+ "with unordered tests." )
7680
7781
7882class OrderingPlugin (object ):
@@ -126,14 +130,6 @@ def mark_binning(item, keys, start, end, before, after, unordered):
126130 return False
127131
128132
129- def insert (items , sort ):
130- if isinstance (items , tuple ):
131- list_items = items [1 ]
132- else :
133- list_items = items
134- sort += list_items
135-
136-
137133def insert_before (name , items , sort ):
138134 regex_name = re .escape (name ) + r"(:?\.\w+)?$"
139135 for pos , item in enumerate (sort ):
@@ -160,7 +156,7 @@ def insert_after(name, items, sort):
160156 return False
161157
162158
163- def do_modify_items (items ):
159+ def do_modify_items (items , sparse_ordering ):
164160 before_item = {}
165161 after_item = {}
166162 start_item = {}
@@ -174,13 +170,8 @@ def do_modify_items(items):
174170 start_item = sorted (start_item .items ())
175171 end_item = sorted (end_item .items ())
176172
177- sorted_list = []
178-
179- for entries in start_item :
180- insert (entries , sorted_list )
181- insert (unordered_list , sorted_list )
182- for entries in end_item :
183- insert (entries , sorted_list )
173+ sorted_list = sort_numbered_items (start_item , end_item , unordered_list ,
174+ sparse_ordering )
184175
185176 still_left = 0
186177 length = len (before_item ) + len (after_item )
@@ -216,24 +207,51 @@ def do_modify_items(items):
216207 return sorted_list
217208
218209
210+ def sort_numbered_items (start_item , end_item , unordered_list , sparse_ordering ):
211+ sorted_list = []
212+ index = 0
213+ for entries in start_item :
214+ if sparse_ordering :
215+ while entries [0 ] > index and unordered_list :
216+ sorted_list .append (unordered_list .pop (0 ))
217+ index += 1
218+ sorted_list += entries [1 ]
219+ index += len (entries [1 ])
220+ mid_index = len (sorted_list )
221+ index = - 1
222+ for entries in reversed (end_item ):
223+ if sparse_ordering :
224+ while entries [0 ] < index and unordered_list :
225+ sorted_list .insert (mid_index , unordered_list .pop ())
226+ index -= 1
227+ for item in reversed (entries [1 ]):
228+ sorted_list .insert (mid_index , item )
229+ index += len (entries [1 ])
230+ for unordered_item in reversed (unordered_list ):
231+ sorted_list .insert (mid_index , unordered_item )
232+ return sorted_list
233+
234+
219235def modify_items (session , config , items ):
220- scope = config .getoption ("order-scope" )
236+ sparse_ordering = config .getoption ("sparse_ordering" )
237+ scope = config .getoption ("order_scope" )
221238 if scope not in ("session" , "module" , "class" ):
222239 if scope is not None :
223240 warn ("Unknown order scope '{}', ignoring it. "
224241 "Valid scopes are 'session', 'module' and 'class'."
225242 .format (scope ))
226243 scope = "session"
227244 if scope == "session" :
228- sorted_list = do_modify_items (items )
245+ sorted_list = do_modify_items (items , sparse_ordering )
229246 elif scope == "module" :
230247 module_items = OrderedDict ()
231248 for item in items :
232249 module_path = item .nodeid [:item .nodeid .index ("::" )]
233250 module_items .setdefault (module_path , []).append (item )
234251 sorted_list = []
235252 for module_item_list in module_items .values ():
236- sorted_list .extend (do_modify_items (module_item_list ))
253+ sorted_list .extend (do_modify_items (
254+ module_item_list , sparse_ordering ))
237255 else : # class scope
238256 class_items = OrderedDict ()
239257 for item in items :
@@ -244,6 +262,7 @@ def modify_items(session, config, items):
244262 class_items .setdefault (class_path , []).append (item )
245263 sorted_list = []
246264 for class_item_list in class_items .values ():
247- sorted_list .extend (do_modify_items (class_item_list ))
265+ sorted_list .extend (do_modify_items (
266+ class_item_list , sparse_ordering ))
248267
249268 items [:] = sorted_list
0 commit comments