Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/pytest_cases/common_pytest_marks.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
PYTEST6_OR_GREATER = PYTEST_VERSION >= Version('6.0.0')
PYTEST7_OR_GREATER = PYTEST_VERSION >= Version('7.0.0')
PYTEST71_OR_GREATER = PYTEST_VERSION >= Version('7.1.0')
PYTEST8_OR_GREATER = PYTEST_VERSION >= Version('8.0.0')


def get_param_argnames_as_list(argnames):
Expand Down
74 changes: 46 additions & 28 deletions src/pytest_cases/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

from .common_mini_six import string_types
from .common_pytest_lazy_values import get_lazy_args
from .common_pytest_marks import PYTEST35_OR_GREATER, PYTEST46_OR_GREATER, PYTEST37_OR_GREATER, PYTEST7_OR_GREATER
from .common_pytest_marks import PYTEST35_OR_GREATER, PYTEST46_OR_GREATER, PYTEST37_OR_GREATER, PYTEST7_OR_GREATER, PYTEST8_OR_GREATER
from .common_pytest import get_pytest_nodeid, get_pytest_function_scopeval, is_function_node, get_param_names, \
get_param_argnames_as_list, has_function_scope, set_callspec_arg_scope_to_function

Expand Down Expand Up @@ -753,38 +753,56 @@ def remove_all(self, values):
self._update_fixture_defs()


def getfixtureclosure(fm, fixturenames, parentnode, ignore_args=()):
"""
Replaces pytest's getfixtureclosure method to handle unions.
"""
if PYTEST8_OR_GREATER:
def getfixtureclosure(fm, parentnode, initialnames, ignore_args):
"""
Replaces pytest's getfixtureclosure method to handle unions.
"""
# (1) first retrieve the normal pytest output for comparison
ref_fixturenames, ref_arg2fixturedefs = fm.__class__.getfixtureclosure(fm, parentnode, initialnames, ignore_args)

# (1) first retrieve the normal pytest output for comparison
kwargs = dict()
if PYTEST46_OR_GREATER:
# new argument "ignore_args" in 4.6+
kwargs['ignore_args'] = ignore_args
# (2) now let's do it by ourselves to support fixture unions
_init_fixnames, super_closure, arg2fixturedefs = create_super_closure(fm, parentnode, ref_fixturenames, ignore_args)

if PYTEST37_OR_GREATER:
# three outputs
initial_names, ref_fixturenames, ref_arg2fixturedefs = \
fm.__class__.getfixtureclosure(fm, fixturenames, parentnode, **kwargs)
else:
# two outputs
ref_fixturenames, ref_arg2fixturedefs = fm.__class__.getfixtureclosure(fm, fixturenames, parentnode)
# Compare with the previous behaviour TODO remove when in 'production' ?
# NOTE different order happens all the time because of our "prepend" strategy in the closure building
# which makes much more sense/intuition than pytest default
assert set(super_closure) == set(ref_fixturenames)
assert dict(arg2fixturedefs) == ref_arg2fixturedefs
return super_closure, arg2fixturedefs
else:
def getfixtureclosure(fm, fixturenames, parentnode, ignore_args=()):
"""
Replaces pytest's getfixtureclosure method to handle unions.
"""

# (2) now let's do it by ourselves to support fixture unions
_init_fixnames, super_closure, arg2fixturedefs = create_super_closure(fm, parentnode, fixturenames, ignore_args)
# (1) first retrieve the normal pytest output for comparison
kwargs = dict()
if PYTEST46_OR_GREATER:
# new argument "ignore_args" in 4.6+
kwargs['ignore_args'] = ignore_args

# Compare with the previous behaviour TODO remove when in 'production' ?
# NOTE different order happens all the time because of our "prepend" strategy in the closure building
# which makes much more sense/intuition than pytest default
assert set(super_closure) == set(ref_fixturenames)
assert dict(arg2fixturedefs) == ref_arg2fixturedefs
if PYTEST37_OR_GREATER:
# three outputs
initial_names, ref_fixturenames, ref_arg2fixturedefs = \
fm.__class__.getfixtureclosure(fm, fixturenames, parentnode, **kwargs)
else:
# two outputs
ref_fixturenames, ref_arg2fixturedefs = fm.__class__.getfixtureclosure(fm, fixturenames, parentnode)

if PYTEST37_OR_GREATER:
return _init_fixnames, super_closure, arg2fixturedefs
else:
return super_closure, arg2fixturedefs
# (2) now let's do it by ourselves to support fixture unions
_init_fixnames, super_closure, arg2fixturedefs = create_super_closure(fm, parentnode, fixturenames, ignore_args)

# Compare with the previous behaviour TODO remove when in 'production' ?
# NOTE different order happens all the time because of our "prepend" strategy in the closure building
# which makes much more sense/intuition than pytest default
assert set(super_closure) == set(ref_fixturenames)
assert dict(arg2fixturedefs) == ref_arg2fixturedefs

if PYTEST37_OR_GREATER:
return _init_fixnames, super_closure, arg2fixturedefs
else:
return super_closure, arg2fixturedefs


def create_super_closure(fm,
Expand Down