Skip to content

Commit a91a5c7

Browse files
author
Sylvain MARIE
committed
Improvement: now only applying the "NOT_USED" parametrization if needed, that is, if at least one callspec does not use it.
1 parent 39fd754 commit a91a5c7

File tree

1 file changed

+31
-4
lines changed

1 file changed

+31
-4
lines changed

pytest_cases/plugin.py

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)