|
19 | 19 | Any,
|
20 | 20 | Final,
|
21 | 21 | Literal,
|
| 22 | + TypeVar, |
22 | 23 | Union,
|
23 | 24 | cast,
|
24 | 25 | overload,
|
|
45 | 46 | from xarray.core.datatree import DataTree
|
46 | 47 | from xarray.core.indexes import Index
|
47 | 48 | from xarray.core.treenode import group_subtrees
|
48 |
| -from xarray.core.types import NetcdfWriteModes, ZarrWriteModes |
49 |
| -from xarray.core.utils import is_remote_uri |
| 49 | +from xarray.core.types import NetcdfWriteModes, ReadBuffer, ZarrWriteModes |
| 50 | +from xarray.core.utils import emit_user_level_warning, is_remote_uri |
50 | 51 | from xarray.namedarray.daskmanager import DaskManager
|
51 | 52 | from xarray.namedarray.parallelcompat import guess_chunkmanager
|
52 | 53 | from xarray.structure.chunks import _get_chunk, _maybe_chunk
|
|
73 | 74 | from xarray.core.types import (
|
74 | 75 | CombineAttrsOptions,
|
75 | 76 | CompatOptions,
|
| 77 | + ErrorOptionsWithWarn, |
76 | 78 | JoinOptions,
|
77 | 79 | NestedSequence,
|
78 | 80 | ReadBuffer,
|
@@ -1459,6 +1461,28 @@ def open_groups(
|
1459 | 1461 | return groups
|
1460 | 1462 |
|
1461 | 1463 |
|
| 1464 | +_FLike = TypeVar("_FLike", bound=Union[str, ReadBuffer]) |
| 1465 | + |
| 1466 | + |
| 1467 | +def _remove_path( |
| 1468 | + paths: NestedSequence[_FLike], paths_to_remove: set[_FLike] |
| 1469 | +) -> NestedSequence[_FLike]: |
| 1470 | + # Initialize an empty list to store the result |
| 1471 | + result: list[Union[_FLike, NestedSequence[_FLike]]] = [] |
| 1472 | + |
| 1473 | + for item in paths: |
| 1474 | + if isinstance(item, list): |
| 1475 | + # If the current item is a list, recursively call remove_elements on it |
| 1476 | + nested_result = _remove_path(item, paths_to_remove) |
| 1477 | + if nested_result: # Only add non-empty lists to avoid adding empty lists |
| 1478 | + result.append(nested_result) |
| 1479 | + elif item not in paths_to_remove: |
| 1480 | + # Add the item to the result if it is not in the set of elements to remove |
| 1481 | + result.append(item) |
| 1482 | + |
| 1483 | + return result |
| 1484 | + |
| 1485 | + |
1462 | 1486 | def open_mfdataset(
|
1463 | 1487 | paths: str
|
1464 | 1488 | | os.PathLike
|
@@ -1487,6 +1511,7 @@ def open_mfdataset(
|
1487 | 1511 | join: JoinOptions | CombineKwargDefault = _JOIN_DEFAULT,
|
1488 | 1512 | attrs_file: str | os.PathLike | None = None,
|
1489 | 1513 | combine_attrs: CombineAttrsOptions = "override",
|
| 1514 | + errors: ErrorOptionsWithWarn = "raise", |
1490 | 1515 | **kwargs,
|
1491 | 1516 | ) -> Dataset:
|
1492 | 1517 | """Open multiple files as a single dataset.
|
@@ -1613,6 +1638,12 @@ def open_mfdataset(
|
1613 | 1638 |
|
1614 | 1639 | If a callable, it must expect a sequence of ``attrs`` dicts and a context object
|
1615 | 1640 | as its only parameters.
|
| 1641 | + errors : {"raise", "warn", "ignore"}, default: "raise" |
| 1642 | + String indicating how to handle errors in opening dataset. |
| 1643 | +
|
| 1644 | + - "raise": invalid dataset will raise an exception. |
| 1645 | + - "warn": a warning will be issued for each invalid dataset. |
| 1646 | + - "ignore": invalid dataset will be ignored. |
1616 | 1647 | **kwargs : optional
|
1617 | 1648 | Additional arguments passed on to :py:func:`xarray.open_dataset`. For an
|
1618 | 1649 | overview of some of the possible options, see the documentation of
|
@@ -1705,7 +1736,32 @@ def open_mfdataset(
|
1705 | 1736 | open_ = open_dataset
|
1706 | 1737 | getattr_ = getattr
|
1707 | 1738 |
|
1708 |
| - datasets = [open_(p, **open_kwargs) for p in paths1d] |
| 1739 | + if errors not in ("raise", "warn", "ignore"): |
| 1740 | + raise ValueError( |
| 1741 | + f"'errors' must be 'raise', 'warn' or 'ignore', got '{errors}'" |
| 1742 | + ) |
| 1743 | + |
| 1744 | + datasets = [] |
| 1745 | + invalid_paths = set() |
| 1746 | + for p in paths1d: |
| 1747 | + try: |
| 1748 | + ds = open_(p, **open_kwargs) |
| 1749 | + datasets.append(ds) |
| 1750 | + except Exception as e: |
| 1751 | + if errors == "raise": |
| 1752 | + raise |
| 1753 | + elif errors == "warn": |
| 1754 | + emit_user_level_warning(f"Could not open {p} due to {e}. Ignoring.") |
| 1755 | + # remove invalid paths |
| 1756 | + invalid_paths.add(p) |
| 1757 | + |
| 1758 | + if invalid_paths: |
| 1759 | + paths = _remove_path(paths, invalid_paths) |
| 1760 | + if combine == "nested": |
| 1761 | + # Create new ids and paths based on removed items |
| 1762 | + combined_ids_paths = _infer_concat_order_from_positions(paths) |
| 1763 | + ids = list(combined_ids_paths.keys()) |
| 1764 | + |
1709 | 1765 | closers = [getattr_(ds, "_close") for ds in datasets]
|
1710 | 1766 | if preprocess is not None:
|
1711 | 1767 | datasets = [preprocess(ds) for ds in datasets]
|
|
0 commit comments