Skip to content

Commit d3f6db9

Browse files
crusaderkyshoyer
authored andcommitted
WIP: typing for DataArray/Dataset (pydata#2929)
* typing for DataArray/Dataset (incomplete) * Finished dataarray.py * Bugfixes * Bugfixes * trivial * Dataset (partial) * Bugfixes * Minor tweaks * final changes to dataset & dataarray for mypy * mypy str conflict * remove temp ptw setting * OrderedDict-related fixes * fix tests re dict * fix mypy re dict * merge issue re encoding kwarg * weird python35 syntax error * Hashable -> Any for Dicts * DataArray names as Hashable * resolve some __default vs None issues * whats-new * just specify Tuple at the moment * remove unneeded cast, make arg formatting more black-like * adjust init args based on @shoyer review * add Tuple[Tuple] to dataset init types * tuples not all the way down
1 parent 6b33ad8 commit d3f6db9

15 files changed

+557
-381
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ pip-log.txt
3535
.tox
3636
nosetests.xml
3737
.cache
38+
.dmypy.json
3839
.mypy_cache
3940
.ropeproject/
4041
.tags*

doc/whats-new.rst

+4
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ Enhancements
8888
that allows ignoring errors if a passed label or dimension is not in the dataset
8989
(:issue:`2994`).
9090
By `Andrew Ross <https://github.com/andrew-c-ross>`_.
91+
- Argument and return types are added to most methods on ``DataArray`` and ``Dataset``,
92+
allowing static type checking both within xarray and external libraries.
93+
Type checking with ``mypy`` is enabled in CI (though not required yet).
94+
By `Guido Imperiale <https://github.com/crusaderky>`_ and `Maximilian Roos <https://github.com/max-sixty>`_.
9195

9296

9397
Bug fixes

setup.cfg

+1-1
Original file line numberDiff line numberDiff line change
@@ -111,4 +111,4 @@ tag_prefix = v
111111
parentdir_prefix = xarray-
112112

113113
[aliases]
114-
test = pytest
114+
test = pytest

xarray/core/common.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
from . import dtypes, duck_array_ops, formatting, ops
1212
from .arithmetic import SupportsArithmetic
13+
from .npcompat import DTypeLike
1314
from .options import _get_keep_attrs
1415
from .pycompat import dask_array_type
1516
from .rolling_exp import RollingExp
@@ -100,8 +101,7 @@ def __int__(self: Any) -> int:
100101
def __complex__(self: Any) -> complex:
101102
return complex(self.values)
102103

103-
def __array__(self: Any, dtype: Union[str, np.dtype, None] = None
104-
) -> np.ndarray:
104+
def __array__(self: Any, dtype: Optional[DTypeLike] = None) -> np.ndarray:
105105
return np.asarray(self.values, dtype=dtype)
106106

107107
def __repr__(self) -> str:
@@ -997,7 +997,7 @@ def __exit__(self, exc_type, exc_value, traceback) -> None:
997997
self.close()
998998

999999

1000-
def full_like(other, fill_value, dtype: Union[str, np.dtype, None] = None):
1000+
def full_like(other, fill_value, dtype: Optional[DTypeLike] = None):
10011001
"""Return a new object with the same shape and type as a given object.
10021002
10031003
Parameters
@@ -1038,7 +1038,7 @@ def full_like(other, fill_value, dtype: Union[str, np.dtype, None] = None):
10381038

10391039

10401040
def _full_like_variable(other, fill_value,
1041-
dtype: Union[str, np.dtype, None] = None):
1041+
dtype: Optional[DTypeLike] = None):
10421042
"""Inner function of full_like, where other must be a variable
10431043
"""
10441044
from .variable import Variable
@@ -1055,19 +1055,19 @@ def _full_like_variable(other, fill_value,
10551055
return Variable(dims=other.dims, data=data, attrs=other.attrs)
10561056

10571057

1058-
def zeros_like(other, dtype: Union[str, np.dtype, None] = None):
1058+
def zeros_like(other, dtype: Optional[DTypeLike] = None):
10591059
"""Shorthand for full_like(other, 0, dtype)
10601060
"""
10611061
return full_like(other, 0, dtype)
10621062

10631063

1064-
def ones_like(other, dtype: Union[str, np.dtype, None] = None):
1064+
def ones_like(other, dtype: Optional[DTypeLike] = None):
10651065
"""Shorthand for full_like(other, 1, dtype)
10661066
"""
10671067
return full_like(other, 1, dtype)
10681068

10691069

1070-
def is_np_datetime_like(dtype: Union[str, np.dtype]) -> bool:
1070+
def is_np_datetime_like(dtype: DTypeLike) -> bool:
10711071
"""Check if a dtype is a subclass of the numpy datetime types
10721072
"""
10731073
return (np.issubdtype(dtype, np.datetime64) or

xarray/core/computation.py

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import functools
55
import itertools
66
import operator
7-
import typing
87
from collections import Counter, OrderedDict
98
from distutils.version import LooseVersion
109
from typing import (

xarray/core/coordinates.py

+10-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import collections.abc
22
from collections import OrderedDict
33
from contextlib import contextmanager
4+
from typing import Hashable, Iterable, Iterator, Union
45

56
import pandas as pd
67

@@ -9,6 +10,11 @@
910
expand_and_merge_variables, merge_coords, merge_coords_for_inplace_math)
1011
from .utils import Frozen, ReprObject, either_dict_or_kwargs
1112
from .variable import Variable
13+
from .pycompat import TYPE_CHECKING
14+
15+
if TYPE_CHECKING:
16+
from .dataarray import DataArray
17+
from .dataset import Dataset
1218

1319
# Used as the key corresponding to a DataArray's variable when converting
1420
# arbitrary DataArray objects to datasets
@@ -258,21 +264,20 @@ def _ipython_key_completions_(self):
258264
return self._data._ipython_key_completions_()
259265

260266

261-
class LevelCoordinatesSource:
267+
class LevelCoordinatesSource(Iterable[Hashable]):
262268
"""Iterator for MultiIndex level coordinates.
263269
264270
Used for attribute style lookup with AttrAccessMixin. Not returned directly
265271
by any public methods.
266272
"""
267-
268-
def __init__(self, data_object):
273+
def __init__(self, data_object: 'Union[DataArray, Dataset]'):
269274
self._data = data_object
270275

271276
def __getitem__(self, key):
272277
# not necessary -- everything here can already be found in coords.
273-
raise KeyError
278+
raise KeyError()
274279

275-
def __iter__(self):
280+
def __iter__(self) -> Iterator[Hashable]:
276281
return iter(self._data._level_coords)
277282

278283

0 commit comments

Comments
 (0)