How to use makefun - 10 common examples

To help you get started, we’ve selected a few makefun examples, based on popular ways it is used in public projects.

Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.

github smarie / python-pytest-steps / pytest_steps / steps_parametrizer.py View on Github external
@with_signature(new_sig)
def depends_on(*steps, **kwargs):
    """
    Decorates a test step object so as to automatically mark it as skipped (default) or failed if the dependency
    has not succeeded.

    :param steps: a list of test steps that this step depends on. They can be anything, but typically they are non-test
        (not prefixed with 'test') functions.
    :param fail_instead_of_skip: if set to True, the test will be marked as failed instead of skipped when the
        dependencies have not succeeded.
    :return:
    """
    # python 2 compatibility: no keyword arguments can follow an *args.
    fail_instead_of_skip = kwargs.pop('fail_instead_of_skip', _FAIL_INSTEAD_OF_SKIP_DEFAULT)
    if len(kwargs) > 0:
        raise ValueError("Invalid argument(s): " + str(kwargs.keys()))
github smarie / python-pytest-cases / pytest_cases / main_fixtures.py View on Github external
    @with_signature("%s(%s)" % (root_fixture_name, argnames))
    def _root_fixture(**kwargs):
        return tuple(kwargs[k] for k in argnames_lst)
github smarie / python-pytest-cases / pytest_cases / main_fixtures.py View on Github external
    @with_signature("%s(%s, request)" % (name, ', '.join(f_names_args)))
    def _new_fixture(request, **all_fixtures):
        if not is_used_request(request):
            return NOT_USED
        else:
            alternative = request.param
            if isinstance(alternative, UnionFixtureAlternative):
                fixture_to_use = alternative.fixture_name
                return all_fixtures[fixture_to_use]
            else:
                raise TypeError("Union Fixture %s received invalid parameter type: %s. Please report this issue."
                                "" % (name, alternative.__class__))
github smarie / python-pytest-cases / pytest_cases / fixture_core2.py View on Github external
    @with_signature("%s(%s)" % (root_fixture_name, argnames))
    def _root_fixture(**_kwargs):
        return tuple(_kwargs[k] for k in argnames_lst)
github smarie / python-pytest-steps / pytest_steps / steps_generator.py View on Github external
def one_fixture_per_step_decorate(fixture_fun):
    """ Implementation of the @one_fixture_per_step decorator, for manual decoration"""

    def _check_scope(request):
        scope = get_scope(request)
        if scope != 'function':
            # session- or module-scope
            raise Exception("The `@one_fixture_per_step` decorator is only useful for function-scope fixtures. `%s`"
                            " seems to have scope='%s'. Consider removing `@one_fixture_per_step` or changing "
                            "the scope to 'function'." % (fixture_fun, scope))

    # We will expose a new signature with additional arguments
    orig_sig = signature(fixture_fun)
    func_needs_request = 'request' in orig_sig.parameters
    if not func_needs_request:
        new_sig = add_signature_parameters(orig_sig, first=Parameter('request', kind=Parameter.POSITIONAL_OR_KEYWORD))
    else:
        new_sig = orig_sig

    if not isgeneratorfunction(fixture_fun):
        @wraps(fixture_fun, new_sig=new_sig)
        def _steps_aware_decorated_function(*args, **kwargs):
            request = kwargs['request'] if func_needs_request else kwargs.pop('request')
            _check_scope(request)
            res = fixture_fun(*args, **kwargs)
            return _OnePerStepFixtureProxy(res)
    else:
        @wraps(fixture_fun, new_sig=new_sig)
        def _steps_aware_decorated_function(*args, **kwargs):
            request = kwargs['request'] if func_needs_request else kwargs.pop('request')
            _check_scope(request)
            gen = fixture_fun(*args, **kwargs)
github smarie / python-pytest-cases / pytest_cases / main_fixtures.py View on Github external
# note: the function automatically registers it in the module
            # note 2: idstyle is set to None because we provide an explicit enough list of ids
            big_param_fixture = _fixture_union(caller_module, fixture_union_name, fixtures_to_union, idstyle=None,
                                               ids=fixtures_to_union_names_for_ids, hook=hook)

            # --create the new test function's signature that we want to expose to pytest
            # it is the same than existing, except that we want to replace all parameters with the new fixture
            # first check where we should insert the new parameters (where is the first param we remove)
            for _first_idx, _n in enumerate(old_sig.parameters):
                if _n in all_param_names:
                    break
            # then remove all parameters that will be replaced by the new fixture
            new_sig = remove_signature_parameters(old_sig, *all_param_names)
            # finally insert the new fixture in that position. Indeed we can not insert first or last, because
            # 'self' arg (case of test class methods) should stay first and exec order should be preserved when possible
            new_sig = add_signature_parameters(new_sig, custom_idx=_first_idx,
                                               custom=Parameter(fixture_union_name, kind=Parameter.POSITIONAL_OR_KEYWORD))

            # --Finally create the fixture function, a wrapper of user-provided fixture with the new signature
            def replace_paramfixture_with_values(kwargs):
                # remove the created fixture value
                encompassing_fixture = kwargs.pop(fixture_union_name)
                # and add instead the parameter values
                if nb_params > 1:
                    for i, p in enumerate(all_param_names):
                        kwargs[p] = encompassing_fixture[i]
                else:
                    kwargs[all_param_names[0]] = encompassing_fixture
                # return
                return kwargs

            if not isgeneratorfunction(test_func):
github smarie / python-pytest-steps / pytest_steps / steps_generator.py View on Github external
# Transform the steps into ids if needed
        step_ids = [create_pytest_param_str_id(f) for f in steps]

        # Create the container that will hold all execution monitors for this function
        # TODO maybe have later a single 'monitor' instance at plugin level... like in pytest-benchmark
        all_monitors = StepMonitorsContainer(test_func, step_ids)

        # Create the function wrapper.
        # We will expose a new signature with additional 'request' arguments if needed, and the test step
        orig_sig = signature(test_func)
        func_needs_request = 'request' in orig_sig.parameters
        additional_params = (Parameter(test_step_argname, kind=Parameter.POSITIONAL_OR_KEYWORD), ) \
                            + ((Parameter('request', kind=Parameter.POSITIONAL_OR_KEYWORD), )
                               if not func_needs_request else ())
        # add request parameter last, as first may be 'self'
        new_sig = add_signature_parameters(orig_sig, last=additional_params)

        # -- first create the logic
        @wraps(test_func, new_sig=new_sig)
        def wrapped_test_function(*args, **kwargs):
            step_name = kwargs.pop(test_step_argname)
            request = kwargs['request'] if func_needs_request else kwargs.pop('request')
            if request is None:
                # we are manually called outside of pytest. let's execute all steps at nce
                if step_name is None:
                    # print("@test_steps - decorated function '%s' is being called manually. The `%s` parameter is set "
                    #       "to None so all steps will be executed in order" % (f, test_step_argname))
                    step_names = step_ids
                else:
                    # print("@test_steps - decorated function '%s' is being called manually. The `%s` parameter is set "
                    #       "to %s so only these steps will be executed in order. Note that the order should be feasible"
                    #       "" % (f, test_step_argname, step_name))
github smarie / python-pytest-cases / pytest_cases / main_fixtures.py View on Github external
raise ValueError("Internal error related to fixture parametrization- please report")

    # (4) wrap the fixture function so as to remove the parameter names and add 'request' if needed
    all_param_names = tuple(v for l in params_names_or_name_combinations for v in l)

    # --create the new signature that we want to expose to pytest
    old_sig = signature(fixture_func)
    for p in all_param_names:
        if p not in old_sig.parameters:
            raise ValueError("parameter '%s' not found in fixture signature '%s%s'"
                             "" % (p, fixture_func.__name__, old_sig))
    new_sig = remove_signature_parameters(old_sig, *all_param_names)
    # add request if needed
    func_needs_request = 'request' in old_sig.parameters
    if not func_needs_request:
        new_sig = add_signature_parameters(new_sig, first=Parameter('request', kind=Parameter.POSITIONAL_OR_KEYWORD))

    # --common routine used below. Fills kwargs with the appropriate names and values from fixture_params
    def _get_arguments(*args, **kwargs):
        request = kwargs['request'] if func_needs_request else kwargs.pop('request')

        # populate the parameters
        if len(params_names_or_name_combinations) == 1:
            _params = [request.param]  # remove the simplification
        else:
            _params = request.param
        for p_names, fixture_param_value in zip(params_names_or_name_combinations, _params):
            if len(p_names) == 1:
                # a single parameter for that generated fixture (@pytest.mark.parametrize with a single name)
                kwargs[p_names[0]] = fixture_param_value
            else:
                # several parameters for that generated fixture (@pytest.mark.parametrize with several names)
github smarie / python-pytest-steps / pytest_steps / steps.py View on Github external
Implementation of the @cross_steps_fixture decorator, for manual decoration

    :param fixture_fun:
    :param step_param_names: a singleton or iterable containing the names of the test step parameters used in the
        tests. By default the list is `[GENERATOR_MODE_STEP_ARGNAME, TEST_STEP_ARGNAME_DEFAULT]` to cover both
        generator-mode and legacy manual mode.
    :return:
    """
    ref_dct = dict()

    # Create the function wrapper.
    # We will expose a new signature with additional 'request' arguments if needed, and the test step
    orig_sig = signature(fixture_fun)
    func_needs_request = 'request' in orig_sig.parameters
    if not func_needs_request:
        new_sig = add_signature_parameters(orig_sig, first=Parameter('request', kind=Parameter.POSITIONAL_OR_KEYWORD))
    else:
        new_sig = orig_sig

    def _init_and_check(request):
        """
        Checks that the current request is not session but a specific node.
        :param request:
        :return:
        """
        scope = get_scope(request)
        if scope == 'function':
            # function-scope: ok
            id_without_steps = get_pytest_node_hash_id(request.node,
                                                       params_to_ignore=_get_step_param_names_or_default(
                                                       step_param_names))
            return id_without_steps
github smarie / python-pytest-cases / pytest_cases / fixture_core2.py View on Github external
raise ValueError("Internal error related to fixture parametrization- please report")

    # (4) wrap the fixture function so as to remove the parameter names and add 'request' if needed
    all_param_names = tuple(v for pnames in params_names_or_name_combinations for v in pnames)

    # --create the new signature that we want to expose to pytest
    old_sig = signature(fixture_func)
    for p in all_param_names:
        if p not in old_sig.parameters:
            raise ValueError("parameter '%s' not found in fixture signature '%s%s'"
                             "" % (p, fixture_func.__name__, old_sig))
    new_sig = remove_signature_parameters(old_sig, *all_param_names)
    # add request if needed
    func_needs_request = 'request' in old_sig.parameters
    if not func_needs_request:
        new_sig = add_signature_parameters(new_sig, first=Parameter('request', kind=Parameter.POSITIONAL_OR_KEYWORD))

    # --common routine used below. Fills kwargs with the appropriate names and values from fixture_params
    def _map_arguments(*_args, **_kwargs):
        request = _kwargs['request'] if func_needs_request else _kwargs.pop('request')

        # populate the parameters
        if len(params_names_or_name_combinations) == 1:
            _params = [request.param]  # remove the simplification
        else:
            _params = request.param
        for p_names, fixture_param_value in zip(params_names_or_name_combinations, _params):
            if len(p_names) == 1:
                # a single parameter for that generated fixture (@pytest.mark.parametrize with a single name)
                _kwargs[p_names[0]] = get_lazy_args(fixture_param_value)
            else:
                # several parameters for that generated fixture (@pytest.mark.parametrize with several names)