@@ -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 )
9971041def 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
10041048def 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"""
0 commit comments