@@ -75,6 +75,12 @@ def __init__(self, parent_node=None):
7575 self ._as_list = None
7676 self .all_fixture_defs = None
7777
78+ # ------ tree
79+ def get_leaves (self ):
80+ if self .has_split ():
81+ return [n for c in self .children .values () for n in c .get_leaves ()]
82+ else :
83+ return [self ]
7884 # ------
7985
8086 def to_str (self , indent_nb = 0 , with_children = True , with_discarded = True ):
@@ -341,6 +347,25 @@ def split_and_build(self,
341347 def has_split (self ):
342348 return self .split_fixture_name is not None
343349
350+ def get_not_always_used (self ):
351+ """Returns the list of fixtures used by this subtree, that are not always used"""
352+ results_list = []
353+
354+ # initial list is made of fixtures that are in the children
355+ initial_list = self .gather_all_required (include_parents = False )
356+
357+ for c in self .get_leaves ():
358+ j = 0
359+ for i in range (len (initial_list )):
360+ fixture_name = initial_list [j ]
361+ if fixture_name not in c .gather_all_required ():
362+ del initial_list [j ]
363+ results_list .append (fixture_name )
364+ else :
365+ j += 1
366+
367+ return results_list
368+
344369 def gather_all_required (self , include_children = True , include_parents = True ):
345370 """
346371 Returns a list of all fixtures required by the subtree at this node
@@ -696,7 +721,7 @@ def create_call_list_from_pending_parametrizations(self):
696721
697722 calls , nodes = self ._process_node (fix_closure_tree , pending .copy (), [])
698723
699- self ._cleanup_calls_list (calls , nodes , pending )
724+ self ._cleanup_calls_list (fix_closure_tree , calls , nodes , pending )
700725
701726 if _DEBUG :
702727 print ("\n " .join (["%s[%s]: funcargs=%s, params=%s" % (get_pytest_nodeid (self .metafunc ),
@@ -712,7 +737,7 @@ def create_call_list_from_pending_parametrizations(self):
712737 # forget about all parametrizations now - this wont happen again
713738 self ._pending = None
714739
715- def _cleanup_calls_list (self , calls , nodes , pending ):
740+ def _cleanup_calls_list (self , fix_closure_tree , calls , nodes , pending ):
716741 """
717742 Cleans the calls list so that all calls contain a value for all parameters. This is basically
718743 about adding "NOT_USED" parametrization everywhere relevant.
@@ -727,7 +752,7 @@ def _cleanup_calls_list(self, calls, nodes, pending):
727752 if nb_calls != len (nodes ):
728753 raise ValueError ("This should not happen !" )
729754
730- function_scope_num = get_pytest_function_scopenum ()
755+ # function_scope_num = get_pytest_function_scopenum()
731756
732757 for i in range (nb_calls ):
733758 c , n = calls [i ], nodes [i ]
@@ -759,7 +784,9 @@ def _cleanup_calls_list(self, calls, nodes, pending):
759784 # For this we use a dirty hack: we add a parameter with they name in the callspec, it seems to be propagated
760785 # in the `request`. TODO is there a better way?
761786 # for fixture in list(fix_closure_tree):
762- for fixture_name , fixdef in self .metafunc ._arg2fixturedefs .items ():
787+ # for fixture_name, fixdef in self.metafunc._arg2fixturedefs.items():
788+ for fixture_name in fix_closure_tree .get_not_always_used ():
789+ fixdef = self .metafunc ._arg2fixturedefs [fixture_name ]
763790 if fixture_name not in c .params and fixture_name not in c .funcargs :
764791 if not n .requires (fixture_name ):
765792 # explicitly add it as discarded by creating a parameter value for it.
0 commit comments