Skip to content

Commit 3167c47

Browse files
author
Sylvain MARIE
committed
Added some content for issue #137
1 parent c1bf63c commit 3167c47

File tree

2 files changed

+69
-30
lines changed

2 files changed

+69
-30
lines changed

pytest_cases/plugin.py

Lines changed: 47 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
from .common_mini_six import string_types
3030
from .common_pytest_lazy_values import get_lazy_args
3131
from .common_pytest import get_pytest_nodeid, get_pytest_function_scopenum, is_function_node, get_param_names, \
32-
get_pytest_scopenum, get_param_argnames_as_list
32+
get_param_argnames_as_list
3333

3434
from .fixture_core1_unions import NOT_USED, is_fixture_union_params, UnionFixtureAlternative
3535

@@ -890,7 +890,20 @@ def _cleanup_calls_list(metafunc, fix_closure_tree, calls, nodes, pending):
890890
if nb_calls != len(nodes):
891891
raise ValueError("This should not happen !")
892892

893-
function_scope_num = get_pytest_function_scopenum()
893+
# create ref lists of fixtures per scope
894+
_not_always_used_func_scoped = []
895+
# _not_always_used_other_scoped = []
896+
_function_scope_num = get_pytest_function_scopenum()
897+
for fixture_name in fix_closure_tree.get_not_always_used():
898+
try:
899+
fixdef = metafunc._arg2fixturedefs[fixture_name] # noqa
900+
except KeyError:
901+
continue # dont raise any error here and let pytest say "not found" later
902+
else:
903+
if fixdef[-1].scopenum == _function_scope_num:
904+
_not_always_used_func_scoped.append(fixture_name)
905+
# else:
906+
# _not_always_used_other_scoped.append(fixture_name)
894907

895908
for i in range(nb_calls):
896909
c, n = calls[i], nodes[i]
@@ -921,39 +934,43 @@ def _cleanup_calls_list(metafunc, fix_closure_tree, calls, nodes, pending):
921934
#
922935
# For this we use a dirty hack: we add a parameter with they name in the callspec, it seems to be propagated
923936
# in the `request`. TODO is there a better way?
924-
for fixture_name in fix_closure_tree.get_not_always_used():
925-
# (a) retrieve fixture scope
926-
try:
927-
fixdef = metafunc._arg2fixturedefs[fixture_name] # noqa
928-
except KeyError:
929-
continue # dont raise any error here and let pytest say "not found"
930-
this_scopenum = fixdef[-1].scopenum
931-
932-
# (b) only do this for function-scoped fixtures, module or session scoped fixtures should remain active
933-
if this_scopenum == function_scope_num:
934-
if fixture_name not in c.params and fixture_name not in c.funcargs:
935-
if not n.requires(fixture_name):
936-
# explicitly add it as discarded by creating a parameter value for it.
937-
c.params[fixture_name] = NOT_USED
938-
c.indices[fixture_name] = 1
939-
c._arg2scopenum[fixture_name] = this_scopenum # get_pytest_scopenum(fixdef[-1].scope) # noqa
940-
else:
941-
# explicitly add it as active
942-
c.params[fixture_name] = 'used'
943-
c.indices[fixture_name] = 0
944-
c._arg2scopenum[fixture_name] = this_scopenum # get_pytest_scopenum(fixdef[-1].scope) # noqa
937+
for fixture_name in _not_always_used_func_scoped:
938+
if fixture_name not in c.params and fixture_name not in c.funcargs:
939+
if not n.requires(fixture_name):
940+
# explicitly add it as discarded by creating a parameter value for it.
941+
c.params[fixture_name] = NOT_USED
942+
c.indices[fixture_name] = 1
943+
c._arg2scopenum[fixture_name] = _function_scope_num # get_pytest_scopenum(fixdef[-1].scope) # noqa
944+
else:
945+
# explicitly add it as active
946+
c.params[fixture_name] = 'used'
947+
c.indices[fixture_name] = 0
948+
c._arg2scopenum[fixture_name] = _function_scope_num # get_pytest_scopenum(fixdef[-1].scope) # noqa
945949

946950
# finally, if there are some session or module-scoped fixtures that
947951
# are used in *none* of the calls, they could be deactivated too
948952
# (see https://github.com/smarie/python-pytest-cases/issues/137)
949953
#
950-
# for fixture_name in fix_closure_tree.get_not_always_used():
951-
# # (a) retrieve fixture scope
952-
# ...
953-
# # (b) for non function-scoped fixtures
954-
# if this_scopenum != function_scope_num:
955-
# # to do check if there is at least one call that actually uses the fixture and is not skipped...
956-
# # this seems a bit "too much" !! > WONT FIX
954+
# for fixture_name in _not_always_used_other_scoped:
955+
# _scopenum = metafunc._arg2fixturedefs[fixture_name][-1].scopenum
956+
#
957+
# # check if there is at least one call that actually uses the fixture and is not skipped...
958+
# # this seems a bit "too much" !! > WONT FIX
959+
# used = False
960+
# for i in range(nb_calls):
961+
# c, n = calls[i], nodes[i]
962+
# if fixture_name in c.params or fixture_name in c.funcargs or n.requires(fixture_name):
963+
# if not is_skipped_or_failed(c): # HOW can we implement this based on call (and not item) ???
964+
# used = True
965+
# break
966+
#
967+
# if not used:
968+
# # explicitly add it as discarded everywhere by creating a parameter value for it.
969+
# for i in range(nb_calls):
970+
# c = calls[i]
971+
# c.params[fixture_name] = NOT_USED
972+
# c.indices[fixture_name] = 0
973+
# c._arg2scopenum[fixture_name] = _scopenum # noqa
957974

958975

959976
# def get_calls_for_partition(metafunc, super_closure, p_idx, pending):
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# this test is known to fail.
2+
#
3+
# import pytest
4+
# from pytest_cases import fixture, parametrize, fixture_ref
5+
#
6+
#
7+
# @fixture(scope="module")
8+
# def a():
9+
# assert False, "a was used !"
10+
#
11+
#
12+
# @fixture(scope="module")
13+
# def b():
14+
# return "b"
15+
#
16+
#
17+
# @parametrize("fixture", [pytest.param(fixture_ref(b)),
18+
# pytest.param(fixture_ref(a), marks=pytest.mark.skipif("1 > 0")),
19+
# pytest.param(fixture_ref(b))
20+
# ])
21+
# def test(fixture):
22+
# assert fixture == "b"

0 commit comments

Comments
 (0)