# Buggy code
def wrapper(*args, **kwargs):
    bound_args = signature(func).bind(*args, **kwargs)
    bound_args.apply_defaults()

    # Search for DataArray with valid latitude and longitude coordinates to find grid
    # deltas and any other needed parameter
    dataarray_arguments = [
        value
        for value in bound_args.arguments.values()
        if isinstance(value, xr.DataArray)
    ]
    grid_prototype = None
    for da in dataarray_arguments:
        if hasattr(da.metpy, "latitude") and hasattr(da.metpy, "longitude"):
            grid_prototype = da
            break

    # Fill in x_dim/y_dim
    if (
        grid_prototype is not None
        and "x_dim" in bound_args.arguments
        and "y_dim" in bound_args.arguments
    ):
        try:
            bound_args.arguments["x_dim"] = grid_prototype.metpy.find_axis_number("x")
            bound_args.arguments["y_dim"] = grid_prototype.metpy.find_axis_number("y")
        except AttributeError:
            # If axis number not found, fall back to default but warn.
            warnings.warn(
                "Horizontal dimension numbers not found. Defaulting to "
                "(..., Y, X) order."
            )

    # Fill in vertical_dim
    if grid_prototype is not None and "vertical_dim" in bound_args.arguments:
        try:
            bound_args.arguments["vertical_dim"] = (
                grid_prototype.metpy.find_axis_number("vertical")
            )
        except AttributeError:
            # If axis number not found, fall back to default but warn.
            warnings.warn(
                "Vertical dimension number not found. Defaulting to (..., Z, Y, X) order."
            )

    # Fill in dz
    if (
        grid_prototype is not None
        and "dz" in bound_args.arguments
        and bound_args.arguments["dz"] is None
    ):
        try:
            vertical_coord = grid_prototype.metpy.vertical
            bound_args.arguments["dz"] = np.diff(vertical_coord.metpy.unit_array)
        except (AttributeError, ValueError):
            # Skip, since this only comes up in advection, where dz is optional (may not
            # need vertical at all)
            pass

    # Fill in dx/dy
    if (
        "dx" in bound_args.arguments
        and bound_args.arguments["dx"] is None
        and "dy" in bound_args.arguments
        and bound_args.arguments["dy"] is None
    ):
        if grid_prototype is not None:
            bound_args.arguments["dx"], bound_args.arguments["dy"] = (
                grid_deltas_from_dataarray(grid_prototype, kind="actual")
            )
        elif "dz" in bound_args.arguments:
            # Handle advection case, allowing dx/dy to be None but dz to not be None
            if bound_args.arguments["dz"] is None:
                raise ValueError(
                    "Must provide dx, dy, and/or dz arguments or input DataArray with "
                    "proper coordinates."
                )
        else:
            raise ValueError(
                "Must provide dx/dy arguments or input DataArray with "
                "latitude/longitude coordinates."
            )

    # Fill in latitude
    if "latitude" in bound_args.arguments and bound_args.arguments["latitude"] is None:
        if grid_prototype is not None:
            bound_args.arguments["latitude"] = grid_prototype.metpy.latitude
        else:
            raise ValueError(
                "Must provide latitude argument or input DataArray with "
                "latitude/longitude coordinates."
            )

    return func(*bound_args.args, **bound_args.kwargs)


# Traceback (ValueError)
Traceback (most recent call last):
File "moist_4panel.py", line 168, in <module>
pw[x,y] = mpcalc.precipitable_water(ds['P'].isel(latitude=x,longitude=y),ds['TD'].isel(latitude=x,longitude=y),bottom=pbot,top=ptop).m
File "/d1/anaconda3/envs/era5/lib/python3.8/site-packages/metpy/xarray.py", line 1174, in wrapper
return wrapping(result, match)
File "/d1/anaconda3/envs/era5/lib/python3.8/site-packages/metpy/xarray.py", line 1214, in _wrap_output_like_not_matching_units
xr.DataArray(result, coords=match.coords, dims=match.dims) if output_xarray
File "/d1/anaconda3/envs/era5/lib/python3.8/site-packages/xarray/core/dataarray.py", line 344, in __init__
coords, dims = _infer_coords_and_dims(data.shape, coords, dims)
File "/d1/anaconda3/envs/era5/lib/python3.8/site-packages/xarray/core/dataarray.py", line 121, in _infer_coords_and_dims
raise ValueError(
ValueError: different number of dimensions on data and dims: 0 vs 1

# Fixed code
def wrapper(*args, **kwargs):
    bound_args = signature(func).bind(*args, **kwargs)
    bound_args.apply_defaults()

    # Search for DataArray with valid latitude and longitude coordinates to find grid
    # deltas and any other needed parameter
    grid_prototype = None
    for da in dataarray_arguments(bound_args):
        if hasattr(da.metpy, "latitude") and hasattr(da.metpy, "longitude"):
            grid_prototype = da
            break

    # Fill in x_dim/y_dim
    if (
        grid_prototype is not None
        and "x_dim" in bound_args.arguments
        and "y_dim" in bound_args.arguments
    ):
        try:
            bound_args.arguments["x_dim"] = grid_prototype.metpy.find_axis_number("x")
            bound_args.arguments["y_dim"] = grid_prototype.metpy.find_axis_number("y")
        except AttributeError:
            # If axis number not found, fall back to default but warn.
            warnings.warn(
                "Horizontal dimension numbers not found. Defaulting to "
                "(..., Y, X) order."
            )

    # Fill in vertical_dim
    if grid_prototype is not None and "vertical_dim" in bound_args.arguments:
        try:
            bound_args.arguments["vertical_dim"] = (
                grid_prototype.metpy.find_axis_number("vertical")
            )
        except AttributeError:
            # If axis number not found, fall back to default but warn.
            warnings.warn(
                "Vertical dimension number not found. Defaulting to (..., Z, Y, X) order."
            )

    # Fill in dz
    if (
        grid_prototype is not None
        and "dz" in bound_args.arguments
        and bound_args.arguments["dz"] is None
    ):
        try:
            vertical_coord = grid_prototype.metpy.vertical
            bound_args.arguments["dz"] = np.diff(vertical_coord.metpy.unit_array)
        except (AttributeError, ValueError):
            # Skip, since this only comes up in advection, where dz is optional (may not
            # need vertical at all)
            pass

    # Fill in dx/dy
    if (
        "dx" in bound_args.arguments
        and bound_args.arguments["dx"] is None
        and "dy" in bound_args.arguments
        and bound_args.arguments["dy"] is None
    ):
        if grid_prototype is not None:
            bound_args.arguments["dx"], bound_args.arguments["dy"] = (
                grid_deltas_from_dataarray(grid_prototype, kind="actual")
            )
        elif "dz" in bound_args.arguments:
            # Handle advection case, allowing dx/dy to be None but dz to not be None
            if bound_args.arguments["dz"] is None:
                raise ValueError(
                    "Must provide dx, dy, and/or dz arguments or input DataArray with "
                    "proper coordinates."
                )
        else:
            raise ValueError(
                "Must provide dx/dy arguments or input DataArray with "
                "latitude/longitude coordinates."
            )

    # Fill in latitude
    if "latitude" in bound_args.arguments and bound_args.arguments["latitude"] is None:
        if grid_prototype is not None:
            bound_args.arguments["latitude"] = grid_prototype.metpy.latitude
        else:
            raise ValueError(
                "Must provide latitude argument or input DataArray with "
                "latitude/longitude coordinates."
            )

    return func(*bound_args.args, **bound_args.kwargs)