44import inspect
55import itertools
66import re
7- import warnings
87from collections import ChainMap , namedtuple
98from collections .abc import Hashable , Iterable , Mapping , MutableMapping , Sequence
109from datetime import datetime
1110from typing import (
1211 Any ,
1312 Callable ,
13+ Literal ,
1414 TypeVar ,
1515 Union ,
1616 cast ,
4848 _get_version ,
4949 _is_datetime_like ,
5050 always_iterable ,
51+ emit_user_level_warning ,
5152 invert_mappings ,
5253 parse_cell_methods_attr ,
5354 parse_cf_standard_name_table ,
@@ -107,7 +108,7 @@ def apply_mapper(
107108 """
108109
109110 if not isinstance (key , Hashable ):
110- if default is None :
111+ if default is None : # type: ignore[unreachable]
111112 raise ValueError (
112113 "`default` must be provided when `key` is not not a valid DataArray name (of hashable type)."
113114 )
@@ -224,7 +225,7 @@ def _get_custom_criteria(
224225 try :
225226 from regex import match as regex_match
226227 except ImportError :
227- from re import match as regex_match # type: ignore
228+ from re import match as regex_match # type: ignore[no-redef]
228229
229230 if isinstance (obj , DataArray ):
230231 obj = obj ._to_temp_dataset ()
@@ -363,8 +364,6 @@ def _get_measure(obj: DataArray | Dataset, key: str) -> list[str]:
363364 if key in measures :
364365 results .update ([measures [key ]])
365366
366- if isinstance (results , str ):
367- return [results ]
368367 return list (results )
369368
370369
@@ -471,7 +470,7 @@ def _get_all(obj: DataArray | Dataset, key: Hashable) -> list[Hashable]:
471470 """
472471 all_mappers : tuple [Mapper ] = (
473472 _get_custom_criteria ,
474- functools .partial (_get_custom_criteria , criteria = cf_role_criteria ), # type: ignore
473+ functools .partial (_get_custom_criteria , criteria = cf_role_criteria ), # type: ignore[assignment]
475474 functools .partial (_get_custom_criteria , criteria = grid_mapping_var_criteria ),
476475 _get_axis_coord ,
477476 _get_measure ,
@@ -653,10 +652,10 @@ def _getattr(
653652 ):
654653 raise AttributeError (
655654 f"{ obj .__class__ .__name__ + '.cf' !r} object has no attribute { attr !r} "
656- )
655+ ) from None
657656 raise AttributeError (
658657 f"{ attr !r} is not a valid attribute on the underlying xarray object."
659- )
658+ ) from None
660659
661660 if isinstance (attribute , Mapping ):
662661 if not attribute :
@@ -680,7 +679,7 @@ def _getattr(
680679 newmap .update (dict .fromkeys (inverted [key ], value ))
681680 newmap .update ({key : attribute [key ] for key in unused_keys })
682681
683- skip : dict [str , list [Hashable ] | None ] = {
682+ skip : dict [str , list [Literal [ "coords" , "measures" ] ] | None ] = {
684683 "data_vars" : ["coords" ],
685684 "coords" : None ,
686685 }
@@ -689,7 +688,7 @@ def _getattr(
689688 newmap [key ] = _getitem (accessor , key , skip = skip [attr ])
690689 return newmap
691690
692- elif isinstance (attribute , Callable ): # type: ignore
691+ elif isinstance (attribute , Callable ): # type: ignore[arg-type]
693692 func : Callable = attribute
694693
695694 else :
@@ -721,7 +720,7 @@ def wrapper(*args, **kwargs):
721720def _getitem (
722721 accessor : CFAccessor ,
723722 key : Hashable ,
724- skip : list [Hashable ] | None = None ,
723+ skip : list [Literal [ "coords" , "measures" ] ] | None = None ,
725724) -> DataArray :
726725 ...
727726
@@ -730,15 +729,15 @@ def _getitem(
730729def _getitem (
731730 accessor : CFAccessor ,
732731 key : Iterable [Hashable ],
733- skip : list [Hashable ] | None = None ,
732+ skip : list [Literal [ "coords" , "measures" ] ] | None = None ,
734733) -> Dataset :
735734 ...
736735
737736
738737def _getitem (
739- accessor ,
740- key ,
741- skip = None ,
738+ accessor : CFAccessor ,
739+ key : Hashable | Iterable [ Hashable ] ,
740+ skip : list [ Literal [ "coords" , "measures" ]] | None = None ,
742741):
743742 """
744743 Index into obj using key. Attaches CF associated variables.
@@ -789,7 +788,7 @@ def check_results(names, key):
789788 measures = accessor ._get_all_cell_measures ()
790789 except ValueError :
791790 measures = []
792- warnings . warn ("Ignoring bad cell_measures attribute." , UserWarning )
791+ emit_user_level_warning ("Ignoring bad cell_measures attribute." , UserWarning )
793792
794793 if isinstance (obj , Dataset ):
795794 grid_mapping_names = list (accessor .grid_mapping_names )
@@ -852,6 +851,7 @@ def check_results(names, key):
852851 )
853852 coords .extend (itertools .chain (* extravars .values ()))
854853
854+ ds : Dataset
855855 if isinstance (obj , DataArray ):
856856 ds = obj ._to_temp_dataset ()
857857 else :
@@ -860,7 +860,7 @@ def check_results(names, key):
860860 if scalar_key :
861861 if len (allnames ) == 1 :
862862 (name ,) = allnames
863- da : DataArray = ds .reset_coords ()[name ] # type: ignore
863+ da : DataArray = ds .reset_coords ()[name ]
864864 if name in coords :
865865 coords .remove (name )
866866 for k1 in coords :
@@ -877,26 +877,27 @@ def check_results(names, key):
877877
878878 ds = ds .reset_coords ()[varnames + coords ]
879879 if isinstance (obj , DataArray ):
880- if scalar_key and len (ds .variables ) == 1 :
881- # single dimension coordinates
882- assert coords
883- assert not varnames
880+ if scalar_key :
881+ if len (ds .variables ) == 1 : # type: ignore[unreachable]
882+ # single dimension coordinates
883+ assert coords
884+ assert not varnames
884885
885- return ds [coords [0 ]]
886+ return ds [coords [0 ]]
886887
887- elif scalar_key and len ( ds . variables ) > 1 :
888- raise NotImplementedError (
889- "Not sure what to return when given scalar key for DataArray and it has multiple values. "
890- "Please open an issue."
891- )
888+ else :
889+ raise NotImplementedError (
890+ "Not sure what to return when given scalar key for DataArray and it has multiple values. "
891+ "Please open an issue."
892+ )
892893
893894 return ds .set_coords (coords )
894895
895896 except KeyError :
896897 raise KeyError (
897898 f"{ kind } .cf does not understand the key { k !r} . "
898899 f"Use 'repr({ kind } .cf)' (or '{ kind } .cf' in a Jupyter environment) to see a list of key names that can be interpreted."
899- )
900+ ) from None
900901
901902
902903def _possible_x_y_plot (obj , key , skip = None ):
@@ -1135,7 +1136,7 @@ def _assert_valid_other_comparison(self, other):
11351136 )
11361137 return flag_dict
11371138
1138- def __eq__ (self , other ) -> DataArray : # type: ignore
1139+ def __eq__ (self , other ) -> DataArray : # type: ignore[override]
11391140 """
11401141 Compare flag values against ``other``.
11411142
@@ -1155,7 +1156,7 @@ def __eq__(self, other) -> DataArray: # type: ignore
11551156 """
11561157 return self ._extract_flags ([other ])[other ].rename (self ._obj .name )
11571158
1158- def __ne__ (self , other ) -> DataArray : # type: ignore
1159+ def __ne__ (self , other ) -> DataArray : # type: ignore[override]
11591160 """
11601161 Compare flag values against ``other``.
11611162
@@ -1328,7 +1329,7 @@ def curvefit(
13281329 coords_iter = coords
13291330 coords = [
13301331 apply_mapper (
1331- [_single (_get_coords )], self ._obj , v , error = False , default = [v ] # type: ignore
1332+ [_single (_get_coords )], self ._obj , v , error = False , default = [v ] # type: ignore[arg-type]
13321333 )[0 ]
13331334 for v in coords_iter
13341335 ]
@@ -1339,7 +1340,7 @@ def curvefit(
13391340 reduce_dims_iter = list (reduce_dims )
13401341 reduce_dims = [
13411342 apply_mapper (
1342- [_single (_get_dims )], self ._obj , v , error = False , default = [v ] # type: ignore
1343+ [_single (_get_dims )], self ._obj , v , error = False , default = [v ] # type: ignore[arg-type]
13431344 )[0 ]
13441345 for v in reduce_dims_iter
13451346 ]
@@ -1435,7 +1436,7 @@ def _rewrite_values(
14351436
14361437 # allow multiple return values here.
14371438 # these are valid for .sel, .isel, .coarsen
1438- all_mappers = ChainMap ( # type: ignore
1439+ all_mappers = ChainMap ( # type: ignore[misc]
14391440 key_mappers ,
14401441 dict .fromkeys (var_kws , (_get_all ,)),
14411442 )
@@ -1531,7 +1532,7 @@ def describe(self):
15311532 Print a string repr to screen.
15321533 """
15331534
1534- warnings . warn (
1535+ emit_user_level_warning (
15351536 "'obj.cf.describe()' will be removed in a future version. "
15361537 "Use instead 'repr(obj.cf)' or 'obj.cf' in a Jupyter environment." ,
15371538 DeprecationWarning ,
@@ -1695,10 +1696,9 @@ def cell_measures(self) -> dict[str, list[Hashable]]:
16951696 bad_vars = list (
16961697 as_dataset .filter_by_attrs (cell_measures = attr ).data_vars .keys ()
16971698 )
1698- warnings . warn (
1699+ emit_user_level_warning (
16991700 f"Ignoring bad cell_measures attribute: { attr } on { bad_vars } ." ,
17001701 UserWarning ,
1701- stacklevel = 2 ,
17021702 )
17031703 measures = {
17041704 key : self ._drop_missing_variables (_get_all (self ._obj , key )) for key in keys
@@ -1816,9 +1816,9 @@ def get_associated_variable_names(
18161816 except ValueError as e :
18171817 if error :
18181818 msg = e .args [0 ] + " Ignore this error by passing 'error=False'"
1819- raise ValueError (msg )
1819+ raise ValueError (msg ) from None
18201820 else :
1821- warnings . warn (
1821+ emit_user_level_warning (
18221822 f"Ignoring bad cell_measures attribute: { attrs_or_encoding ['cell_measures' ]} " ,
18231823 UserWarning ,
18241824 )
@@ -1850,7 +1850,7 @@ def get_associated_variable_names(
18501850 missing = set (allvars ) - set (self ._maybe_to_dataset ()._variables )
18511851 if missing :
18521852 if OPTIONS ["warn_on_missing_variables" ]:
1853- warnings . warn (
1853+ emit_user_level_warning (
18541854 f"Variables { missing !r} not found in object but are referred to in the CF attributes." ,
18551855 UserWarning ,
18561856 )
@@ -1963,7 +1963,7 @@ def get_renamer_and_conflicts(keydict):
19631963
19641964 # Rename and warn
19651965 if conflicts :
1966- warnings . warn (
1966+ emit_user_level_warning (
19671967 "Conflicting variables skipped:\n "
19681968 + "\n " .join (
19691969 [
@@ -2684,10 +2684,12 @@ def decode_vertical_coords(self, *, outnames=None, prefix=None):
26842684 try :
26852685 zname = outnames [dim ]
26862686 except KeyError :
2687- raise KeyError ("Your `outnames` need to include a key of `dim`." )
2687+ raise KeyError (
2688+ "Your `outnames` need to include a key of `dim`."
2689+ ) from None
26882690
26892691 else :
2690- warnings . warn (
2692+ emit_user_level_warning (
26912693 "`prefix` is being deprecated; use `outnames` instead." ,
26922694 DeprecationWarning ,
26932695 )
0 commit comments