Source code for behave_kit.steps.conditional

"""`@when_if` — run a step only when a condition holds, skip silently otherwise."""

from __future__ import annotations

import functools
import unittest
from collections.abc import Callable
from typing import Concatenate, ParamSpec, TypeVar, cast

from behave_kit._core.boolutil import as_bool as _as_bool
from behave_kit._core.errors import BehaveKitError
from behave_kit._core.types import Context

P = ParamSpec("P")
R = TypeVar("R")


[docs] def when_if( condition: Callable[[Context], object], ) -> Callable[ [Callable[Concatenate[Context, P], R]], Callable[Concatenate[Context, P], R], ]: """Decorator: execute the step only if ``condition(context)`` is true. When the condition is false, the step is skipped (via `unittest.SkipTest`) rather than executed or failed. """ def decorator( func: Callable[Concatenate[Context, P], R], ) -> Callable[Concatenate[Context, P], R]: """Wrap ``func`` to run only when ``condition`` is true.""" if not callable(func): raise BehaveKitError( "@when_if was applied without parentheses", suggestion="Use @when_if(lambda ctx: ...) or @when_if(my_condition)", ) @functools.wraps(func) def wrapper(context: Context, *args: P.args, **kwargs: P.kwargs) -> R: """Skip the step when ``condition(context)`` is false.""" if not _as_bool(condition(context)): raise unittest.SkipTest("Skipped: when_if condition was false") return func(context, *args, **kwargs) return cast("Callable[Concatenate[Context, P], R]", wrapper) return decorator