Minmax function alongside min and max

If I can, I have a modification to your solution:

_sentinel = object()

def minmax(*args, key=None):
    args_len = len(args)
    
    if args_len == 0:
        fname = minmax.__name__
        raise ValueError(f"{fname}() expected 1 argument, got 0")
    elif args_len == 1:
        seq = args[0]
    else:
        seq = args
    
    it = iter(seq)

    vmax = vmin = next(it, _sentinel)
    
    if vmax is _sentinel:
        fname = minmax.__name__
        raise ValueError(f"{fname}() arg is an empty sequence")
    
    if key is None:
        for val in it:
            if val > vmax:
                vmax = val
            elif val < vmin:
                vmin = val
    else:
        fmax = fmin = key(vmax)
        
        for val in it:
            fval = key(val)
            
            if fval > fmax:
                fmax = fval
                vmax = val
            elif fval < fmin:
                fmin = fval
                vmin = val
    
    return (vmin, vmax)

I know, it’s more verbose and less elegant, but I think it’s more fast for the majority of cases, ie key=None.

PS: no default. What must it returns, (default, default)? Or we have to define a default_min and a default_max? Overcomplicated IMHO.