Skip to content

Commit ac7153c

Browse files
author
Sylvain MARIE
committed
Fixed issues with offsets used to find the caller module, now that there are two aliases for each decorator @parametrize_plus and @fixture_plus
1 parent c3309ed commit ac7153c

File tree

2 files changed

+55
-7
lines changed

2 files changed

+55
-7
lines changed

pytest_cases/main_fixtures.py

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,12 @@ def pytest_fixture_plus(*args,
436436
**kwargs):
437437
warn("`pytest_fixture_plus` is deprecated. Please use the new alias `fixture_plus`. "
438438
"See https://github.com/pytest-dev/pytest/issues/6475")
439-
return fixture_plus(*args, **kwargs)
439+
if len(args) == 1:
440+
if callable(args[0]):
441+
return _decorate_fixture_plus(args[0], _caller_module_offset_when_unpack=2, **kwargs)
442+
def _fixture_plus(f):
443+
return _decorate_fixture_plus(f, *args, _caller_module_offset_when_unpack=2, **kwargs)
444+
return _fixture_plus
440445

441446

442447
@function_decorator
@@ -448,6 +453,45 @@ def fixture_plus(scope="function",
448453
**kwargs):
449454
""" decorator to mark a fixture factory function.
450455
456+
Identical to `@pytest.fixture` decorator, except that
457+
458+
- it supports multi-parametrization with `@pytest.mark.parametrize` as requested in
459+
https://github.com/pytest-dev/pytest/issues/3960. As a consequence it does not support the `params` and `ids`
460+
arguments anymore.
461+
462+
- it supports a new argument `unpack_into` where you can provide names for fixtures where to unpack this fixture
463+
into.
464+
465+
:param scope: the scope for which this fixture is shared, one of
466+
"function" (default), "class", "module" or "session".
467+
:param autouse: if True, the fixture func is activated for all tests that
468+
can see it. If False (the default) then an explicit
469+
reference is needed to activate the fixture.
470+
:param name: the name of the fixture. This defaults to the name of the
471+
decorated function. Note: If a fixture is used in the same module in
472+
which it is defined, the function name of the fixture will be
473+
shadowed by the function arg that requests the fixture; one way
474+
to resolve this is to name the decorated function
475+
``fixture_<fixturename>`` and then use
476+
``@pytest.fixture(name='<fixturename>')``.
477+
:param unpack_into: an optional iterable of names, or string containing coma-separated names, for additional
478+
fixtures to create to represent parts of this fixture. See `unpack_fixture` for details.
479+
:param kwargs: other keyword arguments for `@pytest.fixture`
480+
"""
481+
# the offset is 3 because of @function_decorator (decopatch library)
482+
return _decorate_fixture_plus(fixture_func, scope=scope, autouse=autouse, name=name, unpack_into=unpack_into,
483+
_caller_module_offset_when_unpack=3, **kwargs)
484+
485+
486+
def _decorate_fixture_plus(fixture_func,
487+
scope="function",
488+
autouse=False,
489+
name=None,
490+
unpack_into=None,
491+
_caller_module_offset_when_unpack=3,
492+
**kwargs):
493+
""" decorator to mark a fixture factory function.
494+
451495
Identical to `@pytest.fixture` decorator, except that
452496
453497
- it supports multi-parametrization with `@pytest.mark.parametrize` as requested in
@@ -489,7 +533,7 @@ def fixture_plus(scope="function",
489533
name = fixture_func.__name__
490534

491535
# get caller module to create the symbols
492-
caller_module = get_caller_module(frame_offset=2)
536+
caller_module = get_caller_module(frame_offset=_caller_module_offset_when_unpack)
493537
_unpack_fixture(caller_module, unpack_into, name)
494538

495539
# (1) Collect all @pytest.mark.parametrize markers (including those created by usage of @cases_data)
@@ -995,10 +1039,10 @@ def __init__(self, fixture):
9951039
# See https://github.com/pytest-dev/pytest/issues/6475
9961040
@pytest.hookimpl(optionalhook=True)
9971041
def pytest_parametrize_plus(*args,
998-
**kwargs):
1042+
**kwargs):
9991043
warn("`parametrize_plus` is deprecated. Please use the new alias `parametrize_plus`. "
10001044
"See https://github.com/pytest-dev/pytest/issues/6475")
1001-
return parametrize_plus(*args, **kwargs)
1045+
return _parametrize_plus(*args, **kwargs)
10021046

10031047

10041048
def parametrize_plus(argnames, argvalues, indirect=False, ids=None, scope=None, **kwargs):
@@ -1018,6 +1062,10 @@ def parametrize_plus(argnames, argvalues, indirect=False, ids=None, scope=None,
10181062
:param kwargs:
10191063
:return:
10201064
"""
1065+
return _parametrize_plus(argnames, argvalues, indirect=indirect, ids=ids, scope=scope, **kwargs)
1066+
1067+
1068+
def _parametrize_plus(argnames, argvalues, indirect=False, ids=None, scope=None, _frame_offset=2, **kwargs):
10211069
# make sure that we do not destroy the argvalues if it is provided as an iterator
10221070
try:
10231071
argvalues = list(argvalues)
@@ -1061,7 +1109,7 @@ def parametrize_plus(argnames, argvalues, indirect=False, ids=None, scope=None,
10611109
return pytest.mark.parametrize(argnames, argvalues, indirect=indirect, ids=ids, scope=scope, **kwargs)
10621110
else:
10631111
# there are fixture references: we have to create a specific decorator
1064-
caller_module = get_caller_module()
1112+
caller_module = get_caller_module(frame_offset=_frame_offset)
10651113

10661114
def _create_param_fixture(from_i, to_i, p_names, test_func_name):
10671115
""" Routine that will be used to create a parameter fixture for argvalues between prev_i and i"""

pytest_cases/tests/fixtures/test_fixture_unpacking2.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import pytest
2-
from pytest_cases import pytest_fixture_plus, fixture_union
2+
from pytest_cases import fixture_plus, pytest_fixture_plus, fixture_union
33

44

5-
@pytest_fixture_plus(unpack_into="a,b")
5+
@fixture_plus(unpack_into="a,b")
66
@pytest.mark.parametrize("o", ['hello', 'world'])
77
def root1(o):
88
return o, o[0]

0 commit comments

Comments
 (0)