"""The ``@step`` decorator and related helpers.The decorator stores ``StepInfo`` metadata on the decorated function. Whenmultiple decorators are stacked on the same function, each call appends anew ``StepInfo`` entry to ``fn.__steplib_steps__``."""from__future__importannotationsfromcollections.abcimportCallablefromtypingimportAnyfromsteplib.core.metadataimportStepInfofromsteplib.core.paramsimportParam# Attribute name used to store step metadata on decorated functions._STEPLIB_ATTR="__steplib_steps__"
[docs]defstep(pattern:str,*,category:str,backend:str|None=None,description:str|None=None,parameters:list[Param]|None=None,example:str|None=None,tags:list[str]|None=None,version:str|None=None,deprecated:bool|str=False,i18n:dict[str,str]|None=None,requires:list[str]|None=None,)->Callable[[Callable[...,Any]],Callable[...,Any]]:"""Attach ``StepInfo`` metadata to a step function. Can be stacked to register multiple patterns (e.g. for i18n or alternative backends) on the same implementation function. Args: pattern: The behave matching pattern (e.g. ``"I send a {method} request to {url}"``). category: Module/domain category (e.g. ``"api"``, ``"web"``). backend: Underlying technology (e.g. ``"httpx"``, ``"requests"``). description: Human-readable description; defaults to the function docstring. parameters: Typed parameter descriptors. example: Example usage in Gherkin. tags: Tags for grouping/filtering in the CLI. version: Semver of the step. deprecated: ``True``, a deprecation message, or ``False``. i18n: Translations of the pattern keyed by language code. requires: Context attributes the step needs (e.g. ``["steplib.api.client"]``). Returns: A decorator that records the metadata and returns the function unchanged. """defdecorator(fn:Callable[...,Any])->Callable[...,Any]:info=StepInfo(pattern=pattern,category=category,func=fn,backend=backend,description=descriptionorfn.__doc__,parameters=parametersor[],example=example,tags=tagsor[],version=version,deprecated=deprecated,i18n=i18nor{},requires=requiresor[],)existing:list[StepInfo]=getattr(fn,_STEPLIB_ATTR,[])# Create a new list to avoid mutating a shared parent list.new_list=list(existing)new_list.append(info)setattr(fn,_STEPLIB_ATTR,new_list)returnfnreturndecorator
[docs]defget_step_infos(fn:Callable[...,Any])->list[StepInfo]:"""Return all ``StepInfo`` entries attached to a decorated function. Args: fn: A function decorated with ``@step``. Returns: A list of ``StepInfo`` objects (empty if the function is not a steplib step). """returnlist(getattr(fn,_STEPLIB_ATTR,[]))