From 906f44b0f2597f16d17319d2520ff050aefc2af0 Mon Sep 17 00:00:00 2001 From: RondeauG Date: Mon, 6 Nov 2023 15:55:33 -0500 Subject: [PATCH] add Optional --- xscen/aggregate.py | 26 ++++++++++++------------ xscen/biasadjust.py | 18 ++++++++--------- xscen/catalog.py | 34 ++++++++++++++++--------------- xscen/catutils.py | 38 +++++++++++++++++------------------ xscen/diagnostics.py | 32 ++++++++++++++--------------- xscen/ensembles.py | 10 ++++----- xscen/extract.py | 46 +++++++++++++++++++++--------------------- xscen/indicators.py | 4 ++-- xscen/io.py | 36 +++++++++++++++++---------------- xscen/reduce.py | 4 ++-- xscen/regrid.py | 6 +++--- xscen/scripting.py | 26 +++++++++++++----------- xscen/spatial.py | 9 ++++++--- xscen/testing.py | 4 ++-- xscen/utils.py | 48 ++++++++++++++++++++++++-------------------- 15 files changed, 177 insertions(+), 164 deletions(-) diff --git a/xscen/aggregate.py b/xscen/aggregate.py index 5f0c596a..3d872fd0 100644 --- a/xscen/aggregate.py +++ b/xscen/aggregate.py @@ -44,10 +44,10 @@ def _(s): def climatological_mean( ds: xr.Dataset, *, - window: int = None, - min_periods: int = None, + window: Optional[int] = None, + min_periods: Optional[int] = None, interval: int = 1, - periods: Union[list[str], list[list[str]]] = None, + periods: Optional[Union[list[str], list[list[str]]]] = None, to_level: Optional[str] = "climatology", ) -> xr.Dataset: """Compute the mean over 'year' for given time periods, respecting the temporal resolution of ds. @@ -372,13 +372,13 @@ def spatial_mean( ds: xr.Dataset, method: str, *, - spatial_subset: bool = None, - call_clisops: bool = False, - region: Union[dict, str] = None, - kwargs: dict = None, - simplify_tolerance: float = None, - to_domain: str = None, - to_level: str = None, + spatial_subset: Optional[bool] = None, + call_clisops: Optional[bool] = False, + region: Optional[Union[dict, str]] = None, + kwargs: Optional[dict] = None, + simplify_tolerance: Optional[float] = None, + to_domain: Optional[str] = None, + to_level: Optional[str] = None, ) -> xr.Dataset: """Compute the spatial mean using a variety of available methods. @@ -703,10 +703,10 @@ def produce_horizon( ModuleType, ], *, - periods: Union[list[str], list[list[str]]] = None, - warminglevels: dict = None, + periods: Optional[Union[list[str], list[list[str]]]] = None, + warminglevels: Optional[dict] = None, to_level: Optional[str] = "horizons", - period: list = None, + period: Optional[list] = None, ) -> xr.Dataset: """Compute indicators, then the climatological mean, and finally unstack dates in order to have a single dataset with all indicators of different frequencies. diff --git a/xscen/biasadjust.py b/xscen/biasadjust.py index 37b7f60d..77e2eeae 100644 --- a/xscen/biasadjust.py +++ b/xscen/biasadjust.py @@ -60,12 +60,12 @@ def train( period: list[str], *, method: str = "DetrendedQuantileMapping", - group: Union[sdba.Grouper, str, dict] = None, - xclim_train_args: dict = None, + group: Optional[Union[sdba.Grouper, str, dict]] = None, + xclim_train_args: Optional[dict] = None, maximal_calendar: str = "noleap", - adapt_freq: dict = None, - jitter_under: dict = None, - jitter_over: dict = None, + adapt_freq: Optional[dict] = None, + jitter_under: Optional[dict] = None, + jitter_over: Optional[dict] = None, align_on: Optional[str] = "year", ) -> xr.Dataset: """ @@ -191,11 +191,11 @@ def adjust( dsim: xr.Dataset, periods: Union[list[str], list[list[str]]], *, - xclim_adjust_args: dict = None, + xclim_adjust_args: Optional[dict] = None, to_level: str = "biasadjusted", - bias_adjust_institution: str = None, - bias_adjust_project: str = None, - moving_yearly_window: dict = None, + bias_adjust_institution: Optional[str] = None, + bias_adjust_project: Optional[str] = None, + moving_yearly_window: Optional[dict] = None, align_on: Optional[str] = "year", ) -> xr.Dataset: """ diff --git a/xscen/catalog.py b/xscen/catalog.py index 2c81a911..4eb077ad 100644 --- a/xscen/catalog.py +++ b/xscen/catalog.py @@ -191,9 +191,9 @@ def __init__( def from_df( cls, data: Union[pd.DataFrame, os.PathLike, Sequence[os.PathLike]], - esmdata: Union[os.PathLike, dict] = None, + esmdata: Optional[Union[os.PathLike, dict]] = None, *, - read_csv_kwargs: Mapping[str, Any] = None, + read_csv_kwargs: Optional[Mapping[str, Any]] = None, name: str = "virtual", **intake_kwargs, ): @@ -255,7 +255,7 @@ def _find_unique(series): else: return data.apply(_find_unique, result_type="reduce").to_dict() - def unique(self, columns: Union[str, Sequence[str]] = None): + def unique(self, columns: Optional[Union[str, Sequence[str]]] = None): """Return a series of unique values in the catalog. Parameters @@ -396,7 +396,7 @@ def exists_in_cat(self, **columns) -> bool: def to_dataset( self, - concat_on: Union[list[str], str] = None, + concat_on: Optional[Union[list[str], str]] = None, create_ensemble_on: Optional[Union[list[str], str]] = None, calendar: Optional[str] = "standard", **kwargs, @@ -528,7 +528,7 @@ def create( cls, filename: Union[os.PathLike, str], *, - project: dict = None, + project: Optional[dict] = None, overwrite: bool = False, ): r"""Create a new project catalog from some project metadata. @@ -609,8 +609,8 @@ def __init__( df: Union[str, dict], *args, create: bool = False, - overwrite: bool = None, - project: dict = None, + overwrite: bool = False, + project: Optional[dict] = None, **kwargs, ): """Open or create a project catalog. @@ -622,7 +622,7 @@ def __init__( If dict, this must be a dict representation of an ESM catalog. See the notes below. create : bool If True, and if 'df' is a string, this will create an empty ProjectCatalog if none already exists. - overwrite : bool, optional + overwrite : bool If this and 'create' are True, this will overwrite any existing JSON and CSV file with an empty catalog. project : dict, optional Metadata to create the catalog, if required. @@ -647,12 +647,14 @@ def __init__( # TODO: Implement a way to easily destroy part of the catalog to "reset" some steps def update( self, - df: Union[ - DataCatalog, - intake_esm.esm_datastore, - pd.DataFrame, - pd.Series, - Sequence[pd.Series], + df: Optional[ + Union[ + DataCatalog, + intake_esm.esm_datastore, + pd.DataFrame, + pd.Series, + Sequence[pd.Series], + ] ] = None, ): """Update the catalog with new data and writes the new data to the csv file. @@ -736,7 +738,7 @@ def update_from_ds( self, ds: xarray.Dataset, path: Union[os.PathLike, str], - info_dict: dict = None, + info_dict: Optional[dict] = None, **info_kwargs, ): """Update the catalog with new data and writes the new data to the csv file. @@ -852,7 +854,7 @@ def _build_id(element: pd.Series, columns: list[str]): def generate_id( - df: Union[pd.DataFrame, xr.Dataset], id_columns: list = None + df: Union[pd.DataFrame, xr.Dataset], id_columns: Optional[list] = None ) -> pd.Series: """Create an ID from column entries. diff --git a/xscen/catutils.py b/xscen/catutils.py index 9a85f344..ae04e61e 100644 --- a/xscen/catutils.py +++ b/xscen/catutils.py @@ -13,7 +13,7 @@ from functools import partial, reduce from multiprocessing import Pool from pathlib import Path -from typing import Any, Union +from typing import Any, Optional, Union import cftime import netCDF4 @@ -109,7 +109,7 @@ def _find_assets( root: Union[str, os.PathLike], exts: set[str], lengths: set[int], - dirglob: str = None, + dirglob: Optional[str] = None, ): """Walk recursively over files in a directory, filtering according to a glob pattern, path depth and extensions. @@ -180,9 +180,9 @@ def _name_parser( path: Union[os.PathLike, str], root: Union[os.PathLike, str], patterns: list[Union[str, parse.Parser]], - read_from_file: Union[list[str], dict] = None, - attrs_map: dict = None, - xr_open_kwargs: dict = None, + read_from_file: Optional[Union[list[str], dict]] = None, + attrs_map: Optional[dict] = None, + xr_open_kwargs: Optional[dict] = None, ) -> Union[dict, None]: """Extract metadata information from the file path. @@ -255,11 +255,11 @@ def _name_parser( def _parse_dir( root: Union[os.PathLike, str], patterns: list[str], - dirglob: str = None, - checks: list[str] = None, - read_from_file: Union[list[str], dict] = None, - attrs_map: dict = None, - xr_open_kwargs: dict = None, + dirglob: Optional[str] = None, + checks: Optional[list[str]] = None, + read_from_file: Optional[Union[list[str], dict]] = None, + attrs_map: Optional[dict] = None, + xr_open_kwargs: Optional[dict] = None, progress: bool = False, ): """Iterate and parses files in a directory, filtering according to basic pattern properties and optional checks. @@ -436,21 +436,21 @@ def parse_directory( directories: list[Union[str, os.PathLike]], patterns: list[str], *, - id_columns: list[str] = None, + id_columns: Optional[list[str]] = None, read_from_file: Union[ bool, Sequence[str], tuple[Sequence[str], Sequence[str]], Sequence[tuple[Sequence[str], Sequence[str]]], ] = False, - homogenous_info: dict = None, - cvs: Union[str, os.PathLike, dict] = None, - dirglob: str = None, - xr_open_kwargs: Mapping[str, Any] = None, + homogenous_info: Optional[dict] = None, + cvs: Optional[Union[str, os.PathLike, dict]] = None, + dirglob: Optional[str] = None, + xr_open_kwargs: Optional[Mapping[str, Any]] = None, only_official_columns: bool = True, progress: bool = False, parallel_dirs: Union[bool, int] = False, - file_checks: list[str] = None, + file_checks: Optional[list[str]] = None, ) -> pd.DataFrame: r"""Parse files in a directory and return them as a pd.DataFrame. @@ -698,7 +698,7 @@ def parse_directory( def parse_from_ds( obj: Union[str, os.PathLike, xr.Dataset], names: Sequence[str], - attrs_map: Mapping[str, str] = None, + attrs_map: Optional[Mapping[str, str]] = None, **xrkwargs, ): """Parse a list of catalog fields from the file/dataset itself. @@ -1094,8 +1094,8 @@ def _build_path( @parse_config def build_path( data: Union[dict, xr.Dataset, xr.DataArray, pd.Series, DataCatalog, pd.DataFrame], - schemas: Union[str, os.PathLike, dict] = None, - root: Union[str, os.PathLike] = None, + schemas: Optional[Union[str, os.PathLike, dict]] = None, + root: Optional[Union[str, os.PathLike]] = None, **extra_facets, ) -> Union[Path, DataCatalog, pd.DataFrame]: r"""Parse the schema from a configuration and construct path using a dictionary of facets. diff --git a/xscen/diagnostics.py b/xscen/diagnostics.py index 72b87de4..b64042f6 100644 --- a/xscen/diagnostics.py +++ b/xscen/diagnostics.py @@ -6,7 +6,7 @@ from copy import deepcopy from pathlib import Path from types import ModuleType -from typing import Union +from typing import Optional, Union import numpy as np import xarray as xr @@ -45,18 +45,18 @@ def _(s): def health_checks( ds: Union[xr.Dataset, xr.DataArray], *, - structure: dict = None, - calendar: str = None, - start_date: str = None, - end_date: str = None, - variables_and_units: dict = None, - cfchecks: dict = None, - freq: str = None, - missing: Union[dict, str, list] = None, - flags: dict = None, - flags_kwargs: dict = None, + structure: Optional[dict] = None, + calendar: Optional[str] = None, + start_date: Optional[str] = None, + end_date: Optional[str] = None, + variables_and_units: Optional[dict] = None, + cfchecks: Optional[dict] = None, + freq: Optional[str] = None, + missing: Optional[Union[dict, str, list]] = None, + flags: Optional[dict] = None, + flags_kwargs: Optional[dict] = None, return_flags: bool = False, - raise_on: list = None, + raise_on: Optional[list] = None, ) -> Union[None, xr.Dataset]: """ Perform a series of health checks on the dataset. Be aware that missing data checks and flag checks can be slow. @@ -299,11 +299,11 @@ def properties_and_measures( Sequence[tuple[str, Indicator]], ModuleType, ], - period: list[str] = None, + period: Optional[list[str]] = None, unstack: bool = False, - rechunk: dict = None, - dref_for_measure: xr.Dataset = None, - change_units_arg: dict = None, + rechunk: Optional[dict] = None, + dref_for_measure: Optional[xr.Dataset] = None, + change_units_arg: Optional[dict] = None, to_level_prop: str = "diag-properties", to_level_meas: str = "diag-measures", ) -> tuple[xr.Dataset, xr.Dataset]: diff --git a/xscen/ensembles.py b/xscen/ensembles.py index aadc74dd..d72944c7 100644 --- a/xscen/ensembles.py +++ b/xscen/ensembles.py @@ -6,7 +6,7 @@ from copy import deepcopy from itertools import chain, groupby from pathlib import Path -from typing import Union +from typing import Optional, Union import numpy as np import xarray as xr @@ -27,8 +27,8 @@ def ensemble_stats( ], statistics: dict, *, - create_kwargs: dict = None, - weights: xr.DataArray = None, + create_kwargs: Optional[dict] = None, + weights: Optional[xr.DataArray] = None, common_attrs_only: bool = True, to_level: str = "ensemble", ) -> xr.Dataset: @@ -146,9 +146,9 @@ def generate_weights( *, independence_level: str = "model", balance_experiments: bool = False, - attribute_weights: dict = None, + attribute_weights: Optional[dict] = None, skipna: bool = True, - v_for_skipna: str = None, + v_for_skipna: Optional[str] = None, standardize: bool = False, experiment_weights: bool = False, ) -> xr.DataArray: diff --git a/xscen/extract.py b/xscen/extract.py index 1f7ae3b5..1ef34e62 100644 --- a/xscen/extract.py +++ b/xscen/extract.py @@ -82,14 +82,14 @@ def clisops_subset(ds: xr.Dataset, region: dict) -> xr.Dataset: def extract_dataset( catalog: DataCatalog, *, - variables_and_freqs: dict = None, - periods: Union[list[str], list[list[str]]] = None, - region: dict = None, + variables_and_freqs: Optional[dict] = None, + periods: Optional[Union[list[str], list[list[str]]]] = None, + region: Optional[dict] = None, to_level: str = "extracted", ensure_correct_time: bool = True, - xr_open_kwargs: dict = None, - xr_combine_kwargs: dict = None, - preprocess: Callable = None, + xr_open_kwargs: Optional[dict] = None, + xr_combine_kwargs: Optional[dict] = None, + preprocess: Optional[Callable] = None, resample_methods: Optional[dict] = None, mask: Union[bool, xr.Dataset, xr.DataArray] = False, ) -> dict: @@ -366,9 +366,9 @@ def resample( da: xr.DataArray, target_frequency: str, *, - ds: xr.Dataset = None, - method: str = None, - missing: Union[str, dict] = None, + ds: Optional[xr.Dataset] = None, + method: Optional[str] = None, + missing: Optional[Union[str, dict]] = None, ) -> xr.DataArray: """Aggregate variable to the target frequency. @@ -589,18 +589,18 @@ def search_data_catalogs( ], variables_and_freqs: dict, *, - other_search_criteria: dict = None, - exclusions: dict = None, + other_search_criteria: Optional[dict] = None, + exclusions: Optional[dict] = None, match_hist_and_fut: bool = False, - periods: Union[list[str], list[list[str]]] = None, - coverage_kwargs: dict = None, - id_columns: list[str] = None, + periods: Optional[Union[list[str], list[list[str]]]] = None, + coverage_kwargs: Optional[dict] = None, + id_columns: Optional[list[str]] = None, allow_resampling: bool = False, allow_conversion: bool = False, - conversion_yaml: str = None, - restrict_resolution: str = None, - restrict_members: dict = None, - restrict_warming_level: Union[dict, bool] = None, + conversion_yaml: Optional[str] = None, + restrict_resolution: Optional[str] = None, + restrict_members: Optional[dict] = None, + restrict_warming_level: Optional[Union[dict, bool]] = None, ) -> dict: """Search through DataCatalogs. @@ -920,9 +920,9 @@ def get_warming_level( wl: float, *, window: int = 20, - tas_baseline_period: list[str] = None, + tas_baseline_period: Optional[list[str]] = None, ignore_member: bool = False, - tas_csv: str = None, + tas_csv: Optional[str] = None, return_horizon: bool = True, ) -> Union[dict, list[str], str]: """Use the IPCC Atlas method to return the window of time over which the requested level of global warming is first reached. @@ -1181,7 +1181,7 @@ def subset_warming_level( def _dispatch_historical_to_future( - catalog: DataCatalog, id_columns: list[str] = None + catalog: DataCatalog, id_columns: Optional[list[str]] = None ) -> DataCatalog: """Update a DataCatalog by recopying each "historical" entry to its corresponding future experiments. @@ -1287,7 +1287,7 @@ def _dispatch_historical_to_future( def _restrict_by_resolution( - catalogs: dict, restrictions: str, id_columns: list[str] = None + catalogs: dict, restrictions: str, id_columns: Optional[list[str]] = None ) -> dict: """Update the results from search_data_catalogs by removing simulations with multiple resolutions available. @@ -1427,7 +1427,7 @@ def _restrict_by_resolution( def _restrict_multimembers( - catalogs: dict, restrictions: dict, id_columns: list[str] = None + catalogs: dict, restrictions: dict, id_columns: Optional[list[str]] = None ): """Update the results from search_data_catalogs by removing simulations with multiple members available. diff --git a/xscen/indicators.py b/xscen/indicators.py index 4a1a5869..bab6d28d 100644 --- a/xscen/indicators.py +++ b/xscen/indicators.py @@ -73,7 +73,7 @@ def compute_indicators( ModuleType, ], *, - periods: Union[list[str], list[list[str]]] = None, + periods: Optional[Union[list[str], list[list[str]]]] = None, restrict_years: bool = True, to_level: Optional[str] = "indicators", ) -> dict: @@ -241,7 +241,7 @@ def _infer_freq_from_meta(ind): def registry_from_module( module: ModuleType, - registry: DerivedVariableRegistry = None, + registry: Optional[DerivedVariableRegistry] = None, variable_column: str = "variable", ) -> DerivedVariableRegistry: """Convert a xclim virtual indicators module to an intake_esm Derived Variable Registry. diff --git a/xscen/io.py b/xscen/io.py index eb2af847..32bfa0f8 100644 --- a/xscen/io.py +++ b/xscen/io.py @@ -7,7 +7,7 @@ from collections.abc import Sequence from inspect import signature from pathlib import Path -from typing import Union +from typing import Optional, Union import h5py import netCDF4 @@ -350,10 +350,10 @@ def save_to_netcdf( ds: xr.Dataset, filename: Union[str, os.PathLike], *, - rechunk: dict = None, + rechunk: Optional[dict] = None, bitround: Union[bool, int, dict] = False, compute: bool = True, - netcdf_kwargs: dict = None, + netcdf_kwargs: Optional[dict] = None, ): """Save a Dataset to NetCDF, rechunking or compressing if requested. @@ -413,10 +413,10 @@ def save_to_zarr( ds: xr.Dataset, filename: Union[str, os.PathLike], *, - rechunk: dict = None, - zarr_kwargs: dict = None, + rechunk: Optional[dict] = None, + zarr_kwargs: Optional[dict] = None, compute: bool = True, - encoding: dict = None, + encoding: Optional[dict] = None, bitround: Union[bool, int, dict] = False, mode: str = "f", itervar: bool = False, @@ -620,9 +620,9 @@ def _to_dataframe( def to_table( ds: Union[xr.Dataset, xr.DataArray], *, - row: Union[str, Sequence[str]] = None, - column: Union[str, Sequence[str]] = None, - sheet: Union[str, Sequence[str]] = None, + row: Optional[Union[str, Sequence[str]]] = None, + column: Optional[Union[str, Sequence[str]]] = None, + sheet: Optional[Union[str, Sequence[str]]] = None, coords: Union[bool, str, Sequence[str]] = True, ) -> Union[pd.DataFrame, dict]: """Convert a dataset to a pandas DataFrame with support for multicolumns and multisheet. @@ -717,7 +717,9 @@ def _ensure_list(seq): return _to_dataframe(da, **table_kwargs) -def make_toc(ds: Union[xr.Dataset, xr.DataArray], loc: str = None) -> pd.DataFrame: +def make_toc( + ds: Union[xr.Dataset, xr.DataArray], loc: Optional[str] = None +) -> pd.DataFrame: """Make a table of content describing a dataset's variables. This return a simple DataFrame with variable names as index, the long_name as "description" and units. @@ -765,14 +767,14 @@ def make_toc(ds: Union[xr.Dataset, xr.DataArray], loc: str = None) -> pd.DataFra def save_to_table( ds: Union[xr.Dataset, xr.DataArray], filename: Union[str, os.PathLike], - output_format: str = None, + output_format: Optional[str] = None, *, - row: Union[str, Sequence[str]] = None, + row: Optional[Union[str, Sequence[str]]] = None, column: Union[None, str, Sequence[str]] = "variable", - sheet: Union[str, Sequence[str]] = None, + sheet: Optional[Union[str, Sequence[str]]] = None, coords: Union[bool, Sequence[str]] = True, col_sep: str = "_", - row_sep: str = None, + row_sep: Optional[str] = None, add_toc: Union[bool, pd.DataFrame] = False, **kwargs, ): @@ -910,10 +912,10 @@ def rechunk( path_in: Union[os.PathLike, str, xr.Dataset], path_out: Union[os.PathLike, str], *, - chunks_over_var: dict = None, - chunks_over_dim: dict = None, + chunks_over_var: Optional[dict] = None, + chunks_over_dim: Optional[dict] = None, worker_mem: str, - temp_store: Union[os.PathLike, str] = None, + temp_store: Optional[Union[os.PathLike, str]] = None, overwrite: bool = False, ) -> None: """Rechunk a dataset into a new zarr. diff --git a/xscen/reduce.py b/xscen/reduce.py index d0fa7471..b45b77d0 100644 --- a/xscen/reduce.py +++ b/xscen/reduce.py @@ -17,8 +17,8 @@ def build_reduction_data( datasets: Union[dict, list[xr.Dataset]], *, - xrfreqs: list[str] = None, - horizons: list[str] = None, + xrfreqs: Optional[list[str]] = None, + horizons: Optional[list[str]] = None, ) -> xr.DataArray: """Construct the input required for ensemble reduction. diff --git a/xscen/regrid.py b/xscen/regrid.py index 538c9609..6ed5dd05 100644 --- a/xscen/regrid.py +++ b/xscen/regrid.py @@ -1,4 +1,4 @@ -"""Regrid datasets using xESMF.""" +"""Functions to regrid datasets.""" import datetime import operator import os @@ -28,8 +28,8 @@ def regrid_dataset( ds_grid: xr.Dataset, weights_location: Union[str, os.PathLike], *, - regridder_kwargs: dict = None, - intermediate_grids: dict = None, + regridder_kwargs: Optional[dict] = None, + intermediate_grids: Optional[dict] = None, to_level: str = "regridded", ) -> xr.Dataset: """Regrid a dataset according to weights and a reference grid. diff --git a/xscen/scripting.py b/xscen/scripting.py index 78dad543..6e264ec2 100644 --- a/xscen/scripting.py +++ b/xscen/scripting.py @@ -42,7 +42,7 @@ def send_mail( *, subject: str, msg: str, - to: str = None, + to: Optional[str] = None, server: str = "127.0.0.1", port: int = 25, attachments: Optional[ @@ -159,9 +159,9 @@ def err_handler(self, *exc_info): @parse_config def send_mail_on_exit( *, - subject: str = None, - msg_ok: str = None, - msg_err: str = None, + subject: Optional[str] = None, + msg_ok: Optional[str] = None, + msg_err: Optional[str] = None, on_error_only: bool = False, skip_ctrlc: bool = True, **mail_kwargs, @@ -243,7 +243,7 @@ class measure_time: def __init__( self, - name: str = None, + name: Optional[str] = None, cpu: bool = False, logger: logging.Logger = logger, ): @@ -308,7 +308,9 @@ def _timeout_handler(signum, frame): @contextmanager -def skippable(seconds: int = 2, task: str = "", logger: logging.Logger = None): +def skippable( + seconds: int = 2, task: str = "", logger: Optional[logging.Logger] = None +): """Skippable context manager. When CTRL-C (SIGINT, KeyboardInterrupt) is sent within the context, @@ -350,11 +352,11 @@ def skippable(seconds: int = 2, task: str = "", logger: logging.Logger = None): def save_and_update( ds: xr.Dataset, pcat: ProjectCatalog, - path: Union[str, os.PathLike] = None, - file_format: str = None, - build_path_kwargs: dict = None, - save_kwargs: dict = None, - update_kwargs: dict = None, + path: Optional[Union[str, os.PathLike]] = None, + file_format: Optional[str] = None, + build_path_kwargs: Optional[dict] = None, + save_kwargs: Optional[dict] = None, + update_kwargs: Optional[dict] = None, ): """ Construct the path, save and delete. @@ -427,7 +429,7 @@ def save_and_update( def move_and_delete( moving: list[list[Union[str, os.PathLike]]], pcat: ProjectCatalog, - deleting: list[Union[str, os.PathLike]] = None, + deleting: Optional[list[Union[str, os.PathLike]]] = None, copy: bool = False, ): """ diff --git a/xscen/spatial.py b/xscen/spatial.py index ab48dde7..3618c546 100644 --- a/xscen/spatial.py +++ b/xscen/spatial.py @@ -4,6 +4,7 @@ import warnings from copy import deepcopy from pathlib import Path +from typing import Optional import clisops.core.subset import dask @@ -125,10 +126,12 @@ def _dot(arr, wei): def subset( ds: xr.Dataset, - region: dict = None, + region: Optional[dict] = None, *, - name: str = None, - method: str = None, # FIXME: Once the region argument is removed, this should be made mandatory. + name: Optional[str] = None, + method: Optional[ + str + ] = None, # FIXME: Once the region argument is removed, this should be made mandatory. tile_buffer: float = 0, **kwargs, ) -> xr.Dataset: diff --git a/xscen/testing.py b/xscen/testing.py index bb478dff..b59479fe 100644 --- a/xscen/testing.py +++ b/xscen/testing.py @@ -1,5 +1,5 @@ """Testing utilities for xscen.""" -from typing import Union +from typing import Optional, Union import numpy as np import pandas as pd @@ -20,7 +20,7 @@ def datablock_3d( y_step: float = 0.1, start: str = "7/1/2000", freq: str = "D", - units: str = None, + units: Optional[str] = None, as_dataset: bool = False, ) -> Union[xr.DataArray, xr.Dataset]: """Create a generic timeseries object based on pre-defined dictionaries of existing variables. diff --git a/xscen/utils.py b/xscen/utils.py index 7603f874..011cef6d 100644 --- a/xscen/utils.py +++ b/xscen/utils.py @@ -71,7 +71,7 @@ def update_attr( ds: Union[xr.Dataset, xr.DataArray], attr: str, new: str, - others: Sequence[Union[xr.Dataset, xr.DataArray]] = None, + others: Optional[Sequence[Union[xr.Dataset, xr.DataArray]]] = None, **fmt, ) -> Union[xr.Dataset, xr.DataArray]: """Format an attribute referencing itself in a translatable way. @@ -300,7 +300,7 @@ def stack_drop_nans( mask: xr.DataArray, *, new_dim: str = "loc", - to_file: str = None, + to_file: Optional[str] = None, ) -> xr.Dataset: """Stack dimensions into a single axis and drops indexes where the mask is false. @@ -373,7 +373,9 @@ def unstack_fill_nan( ds: xr.Dataset, *, dim: str = "loc", - coords: Union[str, os.PathLike, Sequence[Union[str, os.PathLike]], dict] = None, + coords: Optional[ + Union[str, os.PathLike, Sequence[Union[str, os.PathLike]], dict] + ] = None, ): """Unstack a Dataset that was stacked by :py:func:`stack_drop_nans`. @@ -531,8 +533,8 @@ def get_cat_attrs( @parse_config def maybe_unstack( ds: xr.Dataset, - coords: str = None, - rechunk: bool = None, + coords: Optional[str] = None, + rechunk: Optional[bool] = None, stack_drop_nans: bool = False, ) -> xr.Dataset: """If stack_drop_nans is True, unstack and rechunk. @@ -717,18 +719,20 @@ def change_units(ds: xr.Dataset, variables_and_units: dict) -> xr.Dataset: def clean_up( ds: xr.Dataset, *, - variables_and_units: dict = None, - convert_calendar_kwargs: dict = None, - missing_by_var: dict = None, - maybe_unstack_dict: dict = None, - round_var: dict = None, - common_attrs_only: Union[dict, list[Union[xr.Dataset, str, os.PathLike]]] = None, - common_attrs_open_kwargs: dict = None, - attrs_to_remove: dict = None, - remove_all_attrs_except: dict = None, - add_attrs: dict = None, - change_attr_prefix: str = None, - to_level: str = None, + variables_and_units: Optional[dict] = None, + convert_calendar_kwargs: Optional[dict] = None, + missing_by_var: Optional[dict] = None, + maybe_unstack_dict: Optional[dict] = None, + round_var: Optional[dict] = None, + common_attrs_only: Optional[ + Union[dict, list[Union[xr.Dataset, str, os.PathLike]]] + ] = None, + common_attrs_open_kwargs: Optional[dict] = None, + attrs_to_remove: Optional[dict] = None, + remove_all_attrs_except: Optional[dict] = None, + add_attrs: Optional[dict] = None, + change_attr_prefix: Optional[str] = None, + to_level: Optional[str] = None, ) -> xr.Dataset: """Clean up of the dataset. @@ -931,7 +935,7 @@ def _search(a, b): def publish_release_notes( - style: str = "md", file: Union[os.PathLike, StringIO, TextIO] = None + style: str = "md", file: Optional[Union[os.PathLike, StringIO, TextIO]] = None ) -> Optional[str]: """Format release history in Markdown or ReStructuredText. @@ -1005,7 +1009,7 @@ def publish_release_notes( def unstack_dates( ds: xr.Dataset, - seasons: dict[int, str] = None, + seasons: Optional[dict[int, str]] = None, new_dim: str = "season", winter_starts_year: bool = False, ): @@ -1161,8 +1165,8 @@ def reshape_da(da): def show_versions( - file: Union[os.PathLike, StringIO, TextIO] = None, - deps: list = None, + file: Optional[Union[os.PathLike, StringIO, TextIO]] = None, + deps: Optional[list] = None, ) -> Optional[str]: """Print the versions of xscen and its dependencies. @@ -1282,7 +1286,7 @@ def standardize_periods( return periods[0] -def season_sort_key(idx: pd.Index, name: str = None): +def season_sort_key(idx: pd.Index, name: Optional[str] = None): """Get a proper sort key for a "season" or "month" index to avoid alphabetical sorting. If any of the values in the index is not recognized as a 3-letter