# ---------------------------------------------------------------------------
# dataclass construction helper  (get_inputs)
# ---------------------------------------------------------------------------
def get_inputs(cls, *args, **kwargs):
    """
    Dynamically construct a (data)class instance from ``args``/``kwargs``,
    filling any missing values from the class's own defaults.
    """
    fields = list(cls.__annotations__.keys())
    values = {}

    args = list(args)
    for field in fields:
        if field in kwargs:
            values[field] = kwargs[field]
        elif args:
            values[field] = args.pop(0)
        else:
            values[field] = getattr(cls(), field)  # default from the class

    return cls(**values)
def makeParams(*arg, **kwargs):
    arg = make_list(arg)
    arg.append({k: v for k, v in kwargs.items() if v is not None})
    return arg


def prune_inputs(func, *args, **kwargs):
    sig = inspect.signature(func)
    params = sig.parameters
    has_varargs = any(p.kind == inspect.Parameter.VAR_POSITIONAL for p in params.values())
    has_varkw = any(p.kind == inspect.Parameter.VAR_KEYWORD for p in params.values())
    new_args = list(args)
    new_kwargs = dict(kwargs)
    if "args" in new_kwargs:
        explicit_args = new_kwargs.pop("args")
        if isinstance(explicit_args, (list, tuple)):
            new_args.extend(explicit_args)
        else:
            new_args.append(explicit_args)
    if has_varargs:
        preferred_as_args = {"path", "file", "file_path", "filename", "value"}
        positional_candidates = []
        for k in list(new_kwargs.keys()):
            v = new_kwargs[k]
            if k in preferred_as_args:
                positional_candidates.append(v)
                del new_kwargs[k]
            elif isinstance(v, (str, int, float)) and len(positional_candidates) == 0:
                positional_candidates.append(v)
                del new_kwargs[k]
        new_args.extend(positional_candidates)
    if not has_varkw:
        allowed = {
            name for name, p in params.items()
            if p.kind in (inspect.Parameter.POSITIONAL_OR_KEYWORD, inspect.Parameter.KEYWORD_ONLY)
        }
        new_kwargs = {k: v for k, v in new_kwargs.items() if k in allowed}
    return tuple(new_args), new_kwargs


def run_pruned_func(func, *args, **kwargs):
    args, kwargs = prune_inputs(func, *args, **kwargs)
    return func(*args, **kwargs)
