Skip to content

Commit 12efe8c

Browse files
author
Sylvain MARIE
committed
Added support for the new Scopes enum in pytest 7: fixdef.scopenum and callspec._arg2scopenum are now fixdef._scope and callspec._arg2scope and contain a Scope. Sorting of fixture defs is now done according to the reversed order of Scope enum instances. Not yet tested with pytest-7.0.0rc1. (hopefully) Fixed #241
1 parent e03973f commit 12efe8c

File tree

3 files changed

+50
-21
lines changed

3 files changed

+50
-21
lines changed

src/pytest_cases/common_pytest.py

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -521,18 +521,37 @@ def get_pytest_nodeid(metafunc):
521521

522522

523523
try:
524-
from _pytest.fixtures import scopes as pt_scopes
524+
# pytest 7+ : scopes is an enum
525+
from _pytest.scope import Scope
526+
527+
def get_pytest_function_scopeval():
528+
return Scope.Function
529+
530+
def has_function_scope(fixdef):
531+
return fixdef._scope is Scope.Function
532+
533+
def set_callspec_arg_scope_to_function(callspec, arg_name):
534+
callspec._arg2scope[arg_name] = Scope.Function
535+
525536
except ImportError:
526-
# pytest 2
527-
from _pytest.python import scopes as pt_scopes, Metafunc # noqa
537+
try:
538+
# pytest 3+
539+
from _pytest.fixtures import scopes as pt_scopes
540+
except ImportError:
541+
# pytest 2
542+
from _pytest.python import scopes as pt_scopes
528543

544+
# def get_pytest_scopenum(scope_str):
545+
# return pt_scopes.index(scope_str)
529546

530-
def get_pytest_scopenum(scope_str):
531-
return pt_scopes.index(scope_str)
547+
def get_pytest_function_scopeval():
548+
return pt_scopes.index("function")
532549

550+
def has_function_scope(fixdef):
551+
return fixdef.scopenum == get_pytest_function_scopeval()
533552

534-
def get_pytest_function_scopenum():
535-
return pt_scopes.index("function")
553+
def set_callspec_arg_scope_to_function(callspec, arg_name):
554+
callspec._arg2scopenum[arg_name] = get_pytest_function_scopeval() # noqa
536555

537556

538557
from _pytest.python import _idval # noqa

src/pytest_cases/common_pytest_marks.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
PYTEST54_OR_GREATER = PYTEST_VERSION >= LooseVersion('5.4.0')
4242
PYTEST421_OR_GREATER = PYTEST_VERSION >= LooseVersion('4.2.1')
4343
PYTEST6_OR_GREATER = PYTEST_VERSION >= LooseVersion('6.0.0')
44+
PYTEST7_OR_GREATER = PYTEST_VERSION >= LooseVersion('7.0.0')
4445

4546

4647
def get_param_argnames_as_list(argnames):

src/pytest_cases/plugin.py

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@
2828

2929
from .common_mini_six import string_types
3030
from .common_pytest_lazy_values import get_lazy_args
31-
from .common_pytest_marks import PYTEST35_OR_GREATER, PYTEST46_OR_GREATER, PYTEST37_OR_GREATER
32-
from .common_pytest import get_pytest_nodeid, get_pytest_function_scopenum, is_function_node, get_param_names, \
33-
get_param_argnames_as_list
31+
from .common_pytest_marks import PYTEST35_OR_GREATER, PYTEST46_OR_GREATER, PYTEST37_OR_GREATER, PYTEST7_OR_GREATER
32+
from .common_pytest import get_pytest_nodeid, get_pytest_function_scopeval, is_function_node, get_param_names, \
33+
get_param_argnames_as_list, has_function_scope, set_callspec_arg_scope_to_function
3434

3535
from .fixture_core1_unions import NOT_USED, USED, is_fixture_union_params, UnionFixtureAlternative
3636

@@ -187,12 +187,22 @@ def get_all_fixture_defs(self, drop_fake_fixtures=True, try_to_sort=True):
187187
items = self.gen_all_fixture_defs(drop_fake_fixtures=drop_fake_fixtures)
188188

189189
# sort by scope as in pytest fixture closure creator (pytest did not do it in early versions, align with this)
190-
if try_to_sort and PYTEST35_OR_GREATER:
191-
f_scope = get_pytest_function_scopenum()
192-
def sort_by_scope(kv_pair): # noqa
193-
fixture_name, fixture_defs = kv_pair
194-
return fixture_defs[-1].scopenum if fixture_defs is not None else f_scope
195-
items = sorted(list(items), key=sort_by_scope)
190+
if try_to_sort:
191+
if PYTEST7_OR_GREATER:
192+
# Scope is an enum, values are in reversed order, and the field is _scope
193+
f_scope = get_pytest_function_scopeval()
194+
def sort_by_scope(kv_pair):
195+
fixture_name, fixture_defs = kv_pair
196+
return fixture_defs[-1]._scope if fixture_defs is not None else f_scope
197+
items = sorted(list(items), key=sort_by_scope, reverse=True)
198+
199+
elif PYTEST35_OR_GREATER:
200+
# scopes is a list, values are indices in the list, and the field is scopenum
201+
f_scope = get_pytest_function_scopeval()
202+
def sort_by_scope(kv_pair): # noqa
203+
fixture_name, fixture_defs = kv_pair
204+
return fixture_defs[-1].scopenum if fixture_defs is not None else f_scope
205+
items = sorted(list(items), key=sort_by_scope)
196206

197207
return OrderedDict(items)
198208

@@ -562,7 +572,7 @@ def _update_fixture_defs(self):
562572

563573
# # also sort all partitions (note that we cannot rely on the order in all_fixture_defs when scopes are same!)
564574
# if LooseVersion(pytest.__version__) >= LooseVersion('3.5.0'):
565-
# f_scope = get_pytest_function_scopenum()
575+
# f_scope = get_pytest_function_scopeval()
566576
# for p in self.partitions:
567577
# def sort_by_scope2(fixture_name): # noqa
568578
# fixture_defs = all_fixture_defs[fixture_name]
@@ -1031,14 +1041,13 @@ def _cleanup_calls_list(metafunc,
10311041
# create ref lists of fixtures per scope
10321042
_not_always_used_func_scoped = []
10331043
# _not_always_used_other_scoped = []
1034-
_function_scope_num = get_pytest_function_scopenum()
10351044
for fixture_name in fix_closure_tree.get_not_always_used():
10361045
try:
10371046
fixdef = metafunc._arg2fixturedefs[fixture_name] # noqa
10381047
except KeyError:
10391048
continue # dont raise any error here and let pytest say "not found" later
10401049
else:
1041-
if fixdef[-1].scopenum == _function_scope_num:
1050+
if has_function_scope(fixdef[-1]):
10421051
_not_always_used_func_scoped.append(fixture_name)
10431052
# else:
10441053
# _not_always_used_other_scoped.append(fixture_name)
@@ -1078,12 +1087,12 @@ def _cleanup_calls_list(metafunc,
10781087
# explicitly add it as discarded by creating a parameter value for it.
10791088
c.params[fixture_name] = NOT_USED
10801089
c.indices[fixture_name] = 1
1081-
c._arg2scopenum[fixture_name] = _function_scope_num # get_pytest_scopenum(fixdef[-1].scope) # noqa
1090+
set_callspec_arg_scope_to_function(c, fixture_name)
10821091
else:
10831092
# explicitly add it as active
10841093
c.params[fixture_name] = USED
10851094
c.indices[fixture_name] = 0
1086-
c._arg2scopenum[fixture_name] = _function_scope_num # get_pytest_scopenum(fixdef[-1].scope) # noqa
1095+
set_callspec_arg_scope_to_function(c, fixture_name)
10871096

10881097
# finally, if there are some session or module-scoped fixtures that
10891098
# are used in *none* of the calls, they could be deactivated too

0 commit comments

Comments
 (0)