pydata / xarray

N-D labeled arrays and datasets in Python
https://xarray.dev
Apache License 2.0
3.56k stars 1.07k forks source link

Ugly error in constructor when no data passed #8860

Closed TomNicholas closed 5 months ago

TomNicholas commented 6 months ago

What happened?

Passing no data to the Dataset constructor can result in a very unhelpful "tuple index out of range" error when this is a clear case of malformed input that we should be able to catch.

What did you expect to happen?

An error more like "tuple must be of form (dims, data[, attrs])"

Minimal Complete Verifiable Example

xr.Dataset({"t": ()})

MVCE confirmation

Relevant log output

---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
Cell In[2], line 1
----> 1 xr.Dataset({"t": ()})

File ~/Documents/Work/Code/xarray/xarray/core/dataset.py:693, in Dataset.__init__(self, data_vars, coords, attrs)
    690 if isinstance(coords, Dataset):
    691     coords = coords._variables
--> 693 variables, coord_names, dims, indexes, _ = merge_data_and_coords(
    694     data_vars, coords
    695 )
    697 self._attrs = dict(attrs) if attrs else None
    698 self._close = None

File ~/Documents/Work/Code/xarray/xarray/core/dataset.py:422, in merge_data_and_coords(data_vars, coords)
    418     coords = create_coords_with_default_indexes(coords, data_vars)
    420 # exclude coords from alignment (all variables in a Coordinates object should
    421 # already be aligned together) and use coordinates' indexes to align data_vars
--> 422 return merge_core(
    423     [data_vars, coords],
    424     compat="broadcast_equals",
    425     join="outer",
    426     explicit_coords=tuple(coords),
    427     indexes=coords.xindexes,
    428     priority_arg=1,
    429     skip_align_args=[1],
    430 )

File ~/Documents/Work/Code/xarray/xarray/core/merge.py:718, in merge_core(objects, compat, join, combine_attrs, priority_arg, explicit_coords, indexes, fill_value, skip_align_args)
    715 for pos, obj in skip_align_objs:
    716     aligned.insert(pos, obj)
--> 718 collected = collect_variables_and_indexes(aligned, indexes=indexes)
    719 prioritized = _get_priority_vars_and_indexes(aligned, priority_arg, compat=compat)
    720 variables, out_indexes = merge_collected(
    721     collected, prioritized, compat=compat, combine_attrs=combine_attrs
    722 )

File ~/Documents/Work/Code/xarray/xarray/core/merge.py:358, in collect_variables_and_indexes(list_of_mappings, indexes)
    355     indexes_.pop(name, None)
    356     append_all(coords_, indexes_)
--> 358 variable = as_variable(variable, name=name, auto_convert=False)
    359 if name in indexes:
    360     append(name, variable, indexes[name])

File ~/Documents/Work/Code/xarray/xarray/core/variable.py:126, in as_variable(obj, name, auto_convert)
    124     obj = obj.copy(deep=False)
    125 elif isinstance(obj, tuple):
--> 126     if isinstance(obj[1], DataArray):
    127         raise TypeError(
    128             f"Variable {name!r}: Using a DataArray object to construct a variable is"
    129             " ambiguous, please extract the data using the .data property."
    130         )
    131     try:

IndexError: tuple index out of range

Anything else we need to know?

No response

Environment

Xarray main

daran9 commented 5 months ago

Hello! I would like to work on this if it's available.

TomNicholas commented 5 months ago

@daran9 go ahead! No need to ask permission - just submit a PR. See our contributing guide: https://docs.xarray.dev/en/stable/contributing.html