Skip to content

Remove implicit use of CRS in code base - #1020

Closed
luseverin wants to merge 68 commits into
developfrom
feature/remove_implicit_use_crs
Closed

Remove implicit use of CRS in code base#1020
luseverin wants to merge 68 commits into
developfrom
feature/remove_implicit_use_crs

Remove outdated test for raise of ValueError when check_antimeridian …

fbcb163
Select commit
Loading
Failed to load commit list.
Sign in for the full log view
This check has been archived and is scheduled for deletion. Learn more about checks retention
GitHub Actions / Petals / Unit Test Results (3.11) failed Jun 19, 2025 in 0s

3 fail, 3 skipped, 226 pass in 4m 50s

232 tests   226 ✅  4m 50s ⏱️
  1 suites    3 💤
  1 files      3 ❌

Results for commit fbcb163.

Annotations

Check warning on line 0 in climada_petals.hazard.copernicus_interface.test.test_seasonal_statistics.TestSeasonalStatistics

See this annotation in the file changed.

@github-actions github-actions / Petals / Unit Test Results (3.11)

test_tmax_calculation (climada_petals.hazard.copernicus_interface.test.test_seasonal_statistics.TestSeasonalStatistics) failed

climada_petals/tests_xml/tests.xml [took 0s]
Raw output
ValueError: Failed to decode variable 'step': failed to prevent overwriting existing key dtype in attrs on variable 'step'. This is probably an encoding field used by xarray to describe how a variable is serialized. To proceed, remove this key from the variable's attributes manually.
variables = Frozen({'t2m_mean': <xarray.Variable (number: 3, step: 3, latitude: 2, longitude: 2)> Size: 288B
[36 values with dtype...values with dtype=int64]
Attributes:
    units:     days since 2023-01-01 00:00:00
    calendar:  proleptic_gregorian})
attributes = Frozen({}), concat_characters = True, mask_and_scale = True
decode_times = True, decode_coords = True, drop_variables = set()
use_cftime = None, decode_timedelta = None

    def decode_cf_variables(
        variables: T_Variables,
        attributes: T_Attrs,
        concat_characters: bool | Mapping[str, bool] = True,
        mask_and_scale: bool | Mapping[str, bool] = True,
        decode_times: bool | CFDatetimeCoder | Mapping[str, bool | CFDatetimeCoder] = True,
        decode_coords: bool | Literal["coordinates", "all"] = True,
        drop_variables: T_DropVariables = None,
        use_cftime: bool | Mapping[str, bool] | None = None,
        decode_timedelta: bool
        | CFTimedeltaCoder
        | Mapping[str, bool | CFTimedeltaCoder]
        | None = None,
    ) -> tuple[T_Variables, T_Attrs, set[Hashable]]:
        """
        Decode several CF encoded variables.
    
        See: decode_cf_variable
        """
        # Only emit one instance of the decode_timedelta default change
        # FutureWarning. This can be removed once this change is made.
        warnings.filterwarnings("once", "decode_timedelta", FutureWarning)
    
        dimensions_used_by = defaultdict(list)
        for v in variables.values():
            for d in v.dims:
                dimensions_used_by[d].append(v)
    
        def stackable(dim: Hashable) -> bool:
            # figure out if a dimension can be concatenated over
            if dim in variables:
                return False
            for v in dimensions_used_by[dim]:
                if v.dtype.kind != "S" or dim != v.dims[-1]:
                    return False
            return True
    
        coord_names = set()
    
        if isinstance(drop_variables, str):
            drop_variables = [drop_variables]
        elif drop_variables is None:
            drop_variables = []
        drop_variables = set(drop_variables)
    
        # Time bounds coordinates might miss the decoding attributes
        if decode_times:
            _update_bounds_attributes(variables)
    
        new_vars = {}
        for k, v in variables.items():
            if k in drop_variables:
                continue
            stack_char_dim = (
                _item_or_default(concat_characters, k, True)
                and v.dtype == "S1"
                and v.ndim > 0
                and stackable(v.dims[-1])
            )
            try:
>               new_vars[k] = decode_cf_variable(
                    k,
                    v,
                    concat_characters=_item_or_default(concat_characters, k, True),
                    mask_and_scale=_item_or_default(mask_and_scale, k, True),
                    decode_times=_item_or_default(decode_times, k, True),
                    stack_char_dim=stack_char_dim,
                    use_cftime=_item_or_default(use_cftime, k, None),
                    decode_timedelta=_item_or_default(decode_timedelta, k, None),
                )

../../../../micromamba/envs/climada_env_3.11/lib/python3.11/site-packages/xarray/conventions.py:404: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../../../../micromamba/envs/climada_env_3.11/lib/python3.11/site-packages/xarray/conventions.py:214: in decode_cf_variable
    var = decode_timedelta.decode(var, name=name)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
../../../../micromamba/envs/climada_env_3.11/lib/python3.11/site-packages/xarray/coding/times.py:1512: in decode
    dtype = pop_to(attrs, encoding, "dtype", name=name)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
../../../../micromamba/envs/climada_env_3.11/lib/python3.11/site-packages/xarray/coding/common.py:127: in pop_to
    safe_setitem(dest, key, value, name=name)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

dest = {'_FillValue': -9223372036854775808, 'blosc': False, 'bzip2': False, 'chunksizes': None, ...}
key = 'dtype', value = 'timedelta64[ns]', name = 'step'

    def safe_setitem(dest, key: Hashable, value, name: T_Name = None):
        if key in dest:
            var_str = f" on variable {name!r}" if name else ""
>           raise ValueError(
                f"failed to prevent overwriting existing key {key} in attrs{var_str}. "
                "This is probably an encoding field used by xarray to describe "
                "how a variable is serialized. To proceed, remove this key from "
                "the variable's attributes manually."
            )
E           ValueError: failed to prevent overwriting existing key dtype in attrs on variable 'step'. This is probably an encoding field used by xarray to describe how a variable is serialized. To proceed, remove this key from the variable's attributes manually.

../../../../micromamba/envs/climada_env_3.11/lib/python3.11/site-packages/xarray/coding/common.py:108: ValueError

The above exception was the direct cause of the following exception:

self = <test_seasonal_statistics.TestSeasonalStatistics testMethod=test_tmax_calculation>

    def test_tmax_calculation(self):
        """Test if 'Tmax' index is computed correctly."""
>       ds_daily, _, _ = calculate_heat_indices_metrics(self.test_file, "Tmax")
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

climada_petals/hazard/copernicus_interface/test/test_seasonal_statistics.py:176: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
climada_petals/hazard/copernicus_interface/seasonal_statistics.py:155: in calculate_heat_indices_metrics
    raise e
climada_petals/hazard/copernicus_interface/seasonal_statistics.py:96: in calculate_heat_indices_metrics
    with xr.open_dataset(input_file_name, engine=engine) as daily_ds:
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
../../../../micromamba/envs/climada_env_3.11/lib/python3.11/site-packages/xarray/backends/api.py:687: in open_dataset
    backend_ds = backend.open_dataset(
../../../../micromamba/envs/climada_env_3.11/lib/python3.11/site-packages/xarray/backends/netCDF4_.py:681: in open_dataset
    ds = store_entrypoint.open_dataset(
../../../../micromamba/envs/climada_env_3.11/lib/python3.11/site-packages/xarray/backends/store.py:47: in open_dataset
    vars, attrs, coord_names = conventions.decode_cf_variables(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

variables = Frozen({'t2m_mean': <xarray.Variable (number: 3, step: 3, latitude: 2, longitude: 2)> Size: 288B
[36 values with dtype...values with dtype=int64]
Attributes:
    units:     days since 2023-01-01 00:00:00
    calendar:  proleptic_gregorian})
attributes = Frozen({}), concat_characters = True, mask_and_scale = True
decode_times = True, decode_coords = True, drop_variables = set()
use_cftime = None, decode_timedelta = None

    def decode_cf_variables(
        variables: T_Variables,
        attributes: T_Attrs,
        concat_characters: bool | Mapping[str, bool] = True,
        mask_and_scale: bool | Mapping[str, bool] = True,
        decode_times: bool | CFDatetimeCoder | Mapping[str, bool | CFDatetimeCoder] = True,
        decode_coords: bool | Literal["coordinates", "all"] = True,
        drop_variables: T_DropVariables = None,
        use_cftime: bool | Mapping[str, bool] | None = None,
        decode_timedelta: bool
        | CFTimedeltaCoder
        | Mapping[str, bool | CFTimedeltaCoder]
        | None = None,
    ) -> tuple[T_Variables, T_Attrs, set[Hashable]]:
        """
        Decode several CF encoded variables.
    
        See: decode_cf_variable
        """
        # Only emit one instance of the decode_timedelta default change
        # FutureWarning. This can be removed once this change is made.
        warnings.filterwarnings("once", "decode_timedelta", FutureWarning)
    
        dimensions_used_by = defaultdict(list)
        for v in variables.values():
            for d in v.dims:
                dimensions_used_by[d].append(v)
    
        def stackable(dim: Hashable) -> bool:
            # figure out if a dimension can be concatenated over
            if dim in variables:
                return False
            for v in dimensions_used_by[dim]:
                if v.dtype.kind != "S" or dim != v.dims[-1]:
                    return False
            return True
    
        coord_names = set()
    
        if isinstance(drop_variables, str):
            drop_variables = [drop_variables]
        elif drop_variables is None:
            drop_variables = []
        drop_variables = set(drop_variables)
    
        # Time bounds coordinates might miss the decoding attributes
        if decode_times:
            _update_bounds_attributes(variables)
    
        new_vars = {}
        for k, v in variables.items():
            if k in drop_variables:
                continue
            stack_char_dim = (
                _item_or_default(concat_characters, k, True)
                and v.dtype == "S1"
                and v.ndim > 0
                and stackable(v.dims[-1])
            )
            try:
                new_vars[k] = decode_cf_variable(
                    k,
                    v,
                    concat_characters=_item_or_default(concat_characters, k, True),
                    mask_and_scale=_item_or_default(mask_and_scale, k, True),
                    decode_times=_item_or_default(decode_times, k, True),
                    stack_char_dim=stack_char_dim,
                    use_cftime=_item_or_default(use_cftime, k, None),
                    decode_timedelta=_item_or_default(decode_timedelta, k, None),
                )
            except Exception as e:
>               raise type(e)(f"Failed to decode variable {k!r}: {e}") from e
E               ValueError: Failed to decode variable 'step': failed to prevent overwriting existing key dtype in attrs on variable 'step'. This is probably an encoding field used by xarray to describe how a variable is serialized. To proceed, remove this key from the variable's attributes manually.

../../../../micromamba/envs/climada_env_3.11/lib/python3.11/site-packages/xarray/conventions.py:415: ValueError

Check warning on line 0 in climada_petals.hazard.copernicus_interface.test.test_seasonal_statistics.TestSeasonalStatistics

See this annotation in the file changed.

@github-actions github-actions / Petals / Unit Test Results (3.11)

test_tmean_calculation (climada_petals.hazard.copernicus_interface.test.test_seasonal_statistics.TestSeasonalStatistics) failed

climada_petals/tests_xml/tests.xml [took 0s]
Raw output
ValueError: Failed to decode variable 'step': failed to prevent overwriting existing key dtype in attrs on variable 'step'. This is probably an encoding field used by xarray to describe how a variable is serialized. To proceed, remove this key from the variable's attributes manually.
variables = Frozen({'t2m_mean': <xarray.Variable (number: 3, step: 3, latitude: 2, longitude: 2)> Size: 288B
[36 values with dtype...values with dtype=int64]
Attributes:
    units:     days since 2023-01-01 00:00:00
    calendar:  proleptic_gregorian})
attributes = Frozen({}), concat_characters = True, mask_and_scale = True
decode_times = True, decode_coords = True, drop_variables = set()
use_cftime = None, decode_timedelta = None

    def decode_cf_variables(
        variables: T_Variables,
        attributes: T_Attrs,
        concat_characters: bool | Mapping[str, bool] = True,
        mask_and_scale: bool | Mapping[str, bool] = True,
        decode_times: bool | CFDatetimeCoder | Mapping[str, bool | CFDatetimeCoder] = True,
        decode_coords: bool | Literal["coordinates", "all"] = True,
        drop_variables: T_DropVariables = None,
        use_cftime: bool | Mapping[str, bool] | None = None,
        decode_timedelta: bool
        | CFTimedeltaCoder
        | Mapping[str, bool | CFTimedeltaCoder]
        | None = None,
    ) -> tuple[T_Variables, T_Attrs, set[Hashable]]:
        """
        Decode several CF encoded variables.
    
        See: decode_cf_variable
        """
        # Only emit one instance of the decode_timedelta default change
        # FutureWarning. This can be removed once this change is made.
        warnings.filterwarnings("once", "decode_timedelta", FutureWarning)
    
        dimensions_used_by = defaultdict(list)
        for v in variables.values():
            for d in v.dims:
                dimensions_used_by[d].append(v)
    
        def stackable(dim: Hashable) -> bool:
            # figure out if a dimension can be concatenated over
            if dim in variables:
                return False
            for v in dimensions_used_by[dim]:
                if v.dtype.kind != "S" or dim != v.dims[-1]:
                    return False
            return True
    
        coord_names = set()
    
        if isinstance(drop_variables, str):
            drop_variables = [drop_variables]
        elif drop_variables is None:
            drop_variables = []
        drop_variables = set(drop_variables)
    
        # Time bounds coordinates might miss the decoding attributes
        if decode_times:
            _update_bounds_attributes(variables)
    
        new_vars = {}
        for k, v in variables.items():
            if k in drop_variables:
                continue
            stack_char_dim = (
                _item_or_default(concat_characters, k, True)
                and v.dtype == "S1"
                and v.ndim > 0
                and stackable(v.dims[-1])
            )
            try:
>               new_vars[k] = decode_cf_variable(
                    k,
                    v,
                    concat_characters=_item_or_default(concat_characters, k, True),
                    mask_and_scale=_item_or_default(mask_and_scale, k, True),
                    decode_times=_item_or_default(decode_times, k, True),
                    stack_char_dim=stack_char_dim,
                    use_cftime=_item_or_default(use_cftime, k, None),
                    decode_timedelta=_item_or_default(decode_timedelta, k, None),
                )

../../../../micromamba/envs/climada_env_3.11/lib/python3.11/site-packages/xarray/conventions.py:404: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../../../../micromamba/envs/climada_env_3.11/lib/python3.11/site-packages/xarray/conventions.py:214: in decode_cf_variable
    var = decode_timedelta.decode(var, name=name)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
../../../../micromamba/envs/climada_env_3.11/lib/python3.11/site-packages/xarray/coding/times.py:1512: in decode
    dtype = pop_to(attrs, encoding, "dtype", name=name)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
../../../../micromamba/envs/climada_env_3.11/lib/python3.11/site-packages/xarray/coding/common.py:127: in pop_to
    safe_setitem(dest, key, value, name=name)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

dest = {'_FillValue': -9223372036854775808, 'blosc': False, 'bzip2': False, 'chunksizes': None, ...}
key = 'dtype', value = 'timedelta64[ns]', name = 'step'

    def safe_setitem(dest, key: Hashable, value, name: T_Name = None):
        if key in dest:
            var_str = f" on variable {name!r}" if name else ""
>           raise ValueError(
                f"failed to prevent overwriting existing key {key} in attrs{var_str}. "
                "This is probably an encoding field used by xarray to describe "
                "how a variable is serialized. To proceed, remove this key from "
                "the variable's attributes manually."
            )
E           ValueError: failed to prevent overwriting existing key dtype in attrs on variable 'step'. This is probably an encoding field used by xarray to describe how a variable is serialized. To proceed, remove this key from the variable's attributes manually.

../../../../micromamba/envs/climada_env_3.11/lib/python3.11/site-packages/xarray/coding/common.py:108: ValueError

The above exception was the direct cause of the following exception:

self = <test_seasonal_statistics.TestSeasonalStatistics testMethod=test_tmean_calculation>

    def test_tmean_calculation(self):
        """Test if 'Tmean' index is computed correctly."""
>       ds_daily, _, _ = calculate_heat_indices_metrics(self.test_file, "Tmean")
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

climada_petals/hazard/copernicus_interface/test/test_seasonal_statistics.py:160: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
climada_petals/hazard/copernicus_interface/seasonal_statistics.py:155: in calculate_heat_indices_metrics
    raise e
climada_petals/hazard/copernicus_interface/seasonal_statistics.py:96: in calculate_heat_indices_metrics
    with xr.open_dataset(input_file_name, engine=engine) as daily_ds:
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
../../../../micromamba/envs/climada_env_3.11/lib/python3.11/site-packages/xarray/backends/api.py:687: in open_dataset
    backend_ds = backend.open_dataset(
../../../../micromamba/envs/climada_env_3.11/lib/python3.11/site-packages/xarray/backends/netCDF4_.py:681: in open_dataset
    ds = store_entrypoint.open_dataset(
../../../../micromamba/envs/climada_env_3.11/lib/python3.11/site-packages/xarray/backends/store.py:47: in open_dataset
    vars, attrs, coord_names = conventions.decode_cf_variables(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

variables = Frozen({'t2m_mean': <xarray.Variable (number: 3, step: 3, latitude: 2, longitude: 2)> Size: 288B
[36 values with dtype...values with dtype=int64]
Attributes:
    units:     days since 2023-01-01 00:00:00
    calendar:  proleptic_gregorian})
attributes = Frozen({}), concat_characters = True, mask_and_scale = True
decode_times = True, decode_coords = True, drop_variables = set()
use_cftime = None, decode_timedelta = None

    def decode_cf_variables(
        variables: T_Variables,
        attributes: T_Attrs,
        concat_characters: bool | Mapping[str, bool] = True,
        mask_and_scale: bool | Mapping[str, bool] = True,
        decode_times: bool | CFDatetimeCoder | Mapping[str, bool | CFDatetimeCoder] = True,
        decode_coords: bool | Literal["coordinates", "all"] = True,
        drop_variables: T_DropVariables = None,
        use_cftime: bool | Mapping[str, bool] | None = None,
        decode_timedelta: bool
        | CFTimedeltaCoder
        | Mapping[str, bool | CFTimedeltaCoder]
        | None = None,
    ) -> tuple[T_Variables, T_Attrs, set[Hashable]]:
        """
        Decode several CF encoded variables.
    
        See: decode_cf_variable
        """
        # Only emit one instance of the decode_timedelta default change
        # FutureWarning. This can be removed once this change is made.
        warnings.filterwarnings("once", "decode_timedelta", FutureWarning)
    
        dimensions_used_by = defaultdict(list)
        for v in variables.values():
            for d in v.dims:
                dimensions_used_by[d].append(v)
    
        def stackable(dim: Hashable) -> bool:
            # figure out if a dimension can be concatenated over
            if dim in variables:
                return False
            for v in dimensions_used_by[dim]:
                if v.dtype.kind != "S" or dim != v.dims[-1]:
                    return False
            return True
    
        coord_names = set()
    
        if isinstance(drop_variables, str):
            drop_variables = [drop_variables]
        elif drop_variables is None:
            drop_variables = []
        drop_variables = set(drop_variables)
    
        # Time bounds coordinates might miss the decoding attributes
        if decode_times:
            _update_bounds_attributes(variables)
    
        new_vars = {}
        for k, v in variables.items():
            if k in drop_variables:
                continue
            stack_char_dim = (
                _item_or_default(concat_characters, k, True)
                and v.dtype == "S1"
                and v.ndim > 0
                and stackable(v.dims[-1])
            )
            try:
                new_vars[k] = decode_cf_variable(
                    k,
                    v,
                    concat_characters=_item_or_default(concat_characters, k, True),
                    mask_and_scale=_item_or_default(mask_and_scale, k, True),
                    decode_times=_item_or_default(decode_times, k, True),
                    stack_char_dim=stack_char_dim,
                    use_cftime=_item_or_default(use_cftime, k, None),
                    decode_timedelta=_item_or_default(decode_timedelta, k, None),
                )
            except Exception as e:
>               raise type(e)(f"Failed to decode variable {k!r}: {e}") from e
E               ValueError: Failed to decode variable 'step': failed to prevent overwriting existing key dtype in attrs on variable 'step'. This is probably an encoding field used by xarray to describe how a variable is serialized. To proceed, remove this key from the variable's attributes manually.

../../../../micromamba/envs/climada_env_3.11/lib/python3.11/site-packages/xarray/conventions.py:415: ValueError

Check warning on line 0 in climada_petals.hazard.copernicus_interface.test.test_seasonal_statistics.TestSeasonalStatistics

See this annotation in the file changed.

@github-actions github-actions / Petals / Unit Test Results (3.11)

test_tmin_calculation (climada_petals.hazard.copernicus_interface.test.test_seasonal_statistics.TestSeasonalStatistics) failed

climada_petals/tests_xml/tests.xml [took 0s]
Raw output
ValueError: Failed to decode variable 'step': failed to prevent overwriting existing key dtype in attrs on variable 'step'. This is probably an encoding field used by xarray to describe how a variable is serialized. To proceed, remove this key from the variable's attributes manually.
variables = Frozen({'t2m_mean': <xarray.Variable (number: 3, step: 3, latitude: 2, longitude: 2)> Size: 288B
[36 values with dtype...values with dtype=int64]
Attributes:
    units:     days since 2023-01-01 00:00:00
    calendar:  proleptic_gregorian})
attributes = Frozen({}), concat_characters = True, mask_and_scale = True
decode_times = True, decode_coords = True, drop_variables = set()
use_cftime = None, decode_timedelta = None

    def decode_cf_variables(
        variables: T_Variables,
        attributes: T_Attrs,
        concat_characters: bool | Mapping[str, bool] = True,
        mask_and_scale: bool | Mapping[str, bool] = True,
        decode_times: bool | CFDatetimeCoder | Mapping[str, bool | CFDatetimeCoder] = True,
        decode_coords: bool | Literal["coordinates", "all"] = True,
        drop_variables: T_DropVariables = None,
        use_cftime: bool | Mapping[str, bool] | None = None,
        decode_timedelta: bool
        | CFTimedeltaCoder
        | Mapping[str, bool | CFTimedeltaCoder]
        | None = None,
    ) -> tuple[T_Variables, T_Attrs, set[Hashable]]:
        """
        Decode several CF encoded variables.
    
        See: decode_cf_variable
        """
        # Only emit one instance of the decode_timedelta default change
        # FutureWarning. This can be removed once this change is made.
        warnings.filterwarnings("once", "decode_timedelta", FutureWarning)
    
        dimensions_used_by = defaultdict(list)
        for v in variables.values():
            for d in v.dims:
                dimensions_used_by[d].append(v)
    
        def stackable(dim: Hashable) -> bool:
            # figure out if a dimension can be concatenated over
            if dim in variables:
                return False
            for v in dimensions_used_by[dim]:
                if v.dtype.kind != "S" or dim != v.dims[-1]:
                    return False
            return True
    
        coord_names = set()
    
        if isinstance(drop_variables, str):
            drop_variables = [drop_variables]
        elif drop_variables is None:
            drop_variables = []
        drop_variables = set(drop_variables)
    
        # Time bounds coordinates might miss the decoding attributes
        if decode_times:
            _update_bounds_attributes(variables)
    
        new_vars = {}
        for k, v in variables.items():
            if k in drop_variables:
                continue
            stack_char_dim = (
                _item_or_default(concat_characters, k, True)
                and v.dtype == "S1"
                and v.ndim > 0
                and stackable(v.dims[-1])
            )
            try:
>               new_vars[k] = decode_cf_variable(
                    k,
                    v,
                    concat_characters=_item_or_default(concat_characters, k, True),
                    mask_and_scale=_item_or_default(mask_and_scale, k, True),
                    decode_times=_item_or_default(decode_times, k, True),
                    stack_char_dim=stack_char_dim,
                    use_cftime=_item_or_default(use_cftime, k, None),
                    decode_timedelta=_item_or_default(decode_timedelta, k, None),
                )

../../../../micromamba/envs/climada_env_3.11/lib/python3.11/site-packages/xarray/conventions.py:404: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../../../../micromamba/envs/climada_env_3.11/lib/python3.11/site-packages/xarray/conventions.py:214: in decode_cf_variable
    var = decode_timedelta.decode(var, name=name)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
../../../../micromamba/envs/climada_env_3.11/lib/python3.11/site-packages/xarray/coding/times.py:1512: in decode
    dtype = pop_to(attrs, encoding, "dtype", name=name)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
../../../../micromamba/envs/climada_env_3.11/lib/python3.11/site-packages/xarray/coding/common.py:127: in pop_to
    safe_setitem(dest, key, value, name=name)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

dest = {'_FillValue': -9223372036854775808, 'blosc': False, 'bzip2': False, 'chunksizes': None, ...}
key = 'dtype', value = 'timedelta64[ns]', name = 'step'

    def safe_setitem(dest, key: Hashable, value, name: T_Name = None):
        if key in dest:
            var_str = f" on variable {name!r}" if name else ""
>           raise ValueError(
                f"failed to prevent overwriting existing key {key} in attrs{var_str}. "
                "This is probably an encoding field used by xarray to describe "
                "how a variable is serialized. To proceed, remove this key from "
                "the variable's attributes manually."
            )
E           ValueError: failed to prevent overwriting existing key dtype in attrs on variable 'step'. This is probably an encoding field used by xarray to describe how a variable is serialized. To proceed, remove this key from the variable's attributes manually.

../../../../micromamba/envs/climada_env_3.11/lib/python3.11/site-packages/xarray/coding/common.py:108: ValueError

The above exception was the direct cause of the following exception:

self = <test_seasonal_statistics.TestSeasonalStatistics testMethod=test_tmin_calculation>

    def test_tmin_calculation(self):
        """Test if 'Tmin' index is computed correctly."""
>       ds_daily, _, _ = calculate_heat_indices_metrics(self.test_file, "Tmin")
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

climada_petals/hazard/copernicus_interface/test/test_seasonal_statistics.py:168: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
climada_petals/hazard/copernicus_interface/seasonal_statistics.py:155: in calculate_heat_indices_metrics
    raise e
climada_petals/hazard/copernicus_interface/seasonal_statistics.py:96: in calculate_heat_indices_metrics
    with xr.open_dataset(input_file_name, engine=engine) as daily_ds:
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
../../../../micromamba/envs/climada_env_3.11/lib/python3.11/site-packages/xarray/backends/api.py:687: in open_dataset
    backend_ds = backend.open_dataset(
../../../../micromamba/envs/climada_env_3.11/lib/python3.11/site-packages/xarray/backends/netCDF4_.py:681: in open_dataset
    ds = store_entrypoint.open_dataset(
../../../../micromamba/envs/climada_env_3.11/lib/python3.11/site-packages/xarray/backends/store.py:47: in open_dataset
    vars, attrs, coord_names = conventions.decode_cf_variables(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

variables = Frozen({'t2m_mean': <xarray.Variable (number: 3, step: 3, latitude: 2, longitude: 2)> Size: 288B
[36 values with dtype...values with dtype=int64]
Attributes:
    units:     days since 2023-01-01 00:00:00
    calendar:  proleptic_gregorian})
attributes = Frozen({}), concat_characters = True, mask_and_scale = True
decode_times = True, decode_coords = True, drop_variables = set()
use_cftime = None, decode_timedelta = None

    def decode_cf_variables(
        variables: T_Variables,
        attributes: T_Attrs,
        concat_characters: bool | Mapping[str, bool] = True,
        mask_and_scale: bool | Mapping[str, bool] = True,
        decode_times: bool | CFDatetimeCoder | Mapping[str, bool | CFDatetimeCoder] = True,
        decode_coords: bool | Literal["coordinates", "all"] = True,
        drop_variables: T_DropVariables = None,
        use_cftime: bool | Mapping[str, bool] | None = None,
        decode_timedelta: bool
        | CFTimedeltaCoder
        | Mapping[str, bool | CFTimedeltaCoder]
        | None = None,
    ) -> tuple[T_Variables, T_Attrs, set[Hashable]]:
        """
        Decode several CF encoded variables.
    
        See: decode_cf_variable
        """
        # Only emit one instance of the decode_timedelta default change
        # FutureWarning. This can be removed once this change is made.
        warnings.filterwarnings("once", "decode_timedelta", FutureWarning)
    
        dimensions_used_by = defaultdict(list)
        for v in variables.values():
            for d in v.dims:
                dimensions_used_by[d].append(v)
    
        def stackable(dim: Hashable) -> bool:
            # figure out if a dimension can be concatenated over
            if dim in variables:
                return False
            for v in dimensions_used_by[dim]:
                if v.dtype.kind != "S" or dim != v.dims[-1]:
                    return False
            return True
    
        coord_names = set()
    
        if isinstance(drop_variables, str):
            drop_variables = [drop_variables]
        elif drop_variables is None:
            drop_variables = []
        drop_variables = set(drop_variables)
    
        # Time bounds coordinates might miss the decoding attributes
        if decode_times:
            _update_bounds_attributes(variables)
    
        new_vars = {}
        for k, v in variables.items():
            if k in drop_variables:
                continue
            stack_char_dim = (
                _item_or_default(concat_characters, k, True)
                and v.dtype == "S1"
                and v.ndim > 0
                and stackable(v.dims[-1])
            )
            try:
                new_vars[k] = decode_cf_variable(
                    k,
                    v,
                    concat_characters=_item_or_default(concat_characters, k, True),
                    mask_and_scale=_item_or_default(mask_and_scale, k, True),
                    decode_times=_item_or_default(decode_times, k, True),
                    stack_char_dim=stack_char_dim,
                    use_cftime=_item_or_default(use_cftime, k, None),
                    decode_timedelta=_item_or_default(decode_timedelta, k, None),
                )
            except Exception as e:
>               raise type(e)(f"Failed to decode variable {k!r}: {e}") from e
E               ValueError: Failed to decode variable 'step': failed to prevent overwriting existing key dtype in attrs on variable 'step'. This is probably an encoding field used by xarray to describe how a variable is serialized. To proceed, remove this key from the variable's attributes manually.

../../../../micromamba/envs/climada_env_3.11/lib/python3.11/site-packages/xarray/conventions.py:415: ValueError