"""
    locals: Dict[str, Any]
    """
    Variables scoped to this call and any sub-calls. Usually used with
    GetLocalVar() and PutLocalVar(). Care should be taken when placing mutable
    objects in locals, as they will be shared between parallel sub-calls.
    """
    max_concurrency: Optional[int]
    """
    Maximum number of parallel calls to make. If not provided, defaults to 
    ThreadPoolExecutor's default. This is ignored if an executor is provided.
    """
    recursion_limit: int
    """
    Maximum number of times a call can recurse. If not provided, defaults to 10.
    """
[docs]def ensure_config(config: Optional[RunnableConfig] = None) -> RunnableConfig:
    empty = RunnableConfig(
        tags=[],
        metadata={},
        callbacks=None,
        locals={},
        recursion_limit=10,
    )
    if config is not None:
        empty.update(
            cast(RunnableConfig, {k: v for k, v in config.items() if v is not None})
        )
    return empty
[docs]def get_config_list(
    config: Optional[Union[RunnableConfig, List[RunnableConfig]]], length: int
) -> List[RunnableConfig]:
    """
    Helper method to get a list of configs from a single config or a list of
    configs, useful for subclasses overriding batch() or abatch().
    """
    if length < 0:
        raise ValueError(f"length must be >= 0, but got {length}")
    if isinstance(config, list) and len(config) != length:
        raise ValueError(
            f"config must be a list of the same length as inputs, "