Skip to content

pytest-ification #1828

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 41 commits into from
Jan 15, 2018
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
d4a4283
deprecation notes in testing functions
max-sixty Jan 13, 2018
0695dab
gitignore additions
max-sixty Jan 13, 2018
1ef5f17
self_assert from unittest2pytest
max-sixty Jan 14, 2018
88ab9cc
pytest.warns needs a warning
max-sixty Jan 14, 2018
51c1fd7
assert_equal
max-sixty Jan 14, 2018
7bdb888
future warnings
max-sixty Jan 14, 2018
5e3a857
assert identical
max-sixty Jan 14, 2018
72d3119
pytest warning fix
max-sixty Jan 14, 2018
286c0eb
revert assert_equal, as assert_array_equal needs to be separate
max-sixty Jan 14, 2018
075ad36
assert dataset & dataarray equal
max-sixty Jan 14, 2018
b7a086f
imports
max-sixty Jan 14, 2018
c06dd48
assertItemsEqual (but may need coercion to sets)
max-sixty Jan 14, 2018
6b67572
Revert "assertItemsEqual (but may need coercion to sets)"
max-sixty Jan 14, 2018
c336bbc
add back in assertitemsequal
max-sixty Jan 14, 2018
b9dfe05
self.assert_equal -> assert_equal
max-sixty Jan 14, 2018
04cd8a5
pytest.warns message matching
max-sixty Jan 14, 2018
c69b6aa
undo backend changes - too many errors
max-sixty Jan 14, 2018
145c013
a few triages
max-sixty Jan 14, 2018
3f286ba
another import
max-sixty Jan 14, 2018
62c22eb
can't deprecate importorskip yet
max-sixty Jan 14, 2018
ccfbff3
assert_array_equal
max-sixty Jan 14, 2018
66c9cd6
assert_identical half way in ufuncs
max-sixty Jan 14, 2018
4e32f96
backends merge
max-sixty Jan 14, 2018
71b34f9
lint v1
max-sixty Jan 14, 2018
362ed63
lint v2
max-sixty Jan 14, 2018
f94a0a9
autopep8 all the things
max-sixty Jan 14, 2018
2b89cbd
lint final
max-sixty Jan 14, 2018
80b921c
undo some of the yapf crazyness
max-sixty Jan 14, 2018
7e7c71d
@Zac-HD dtype
max-sixty Jan 15, 2018
bf60844
remove more yapf overeagerness
max-sixty Jan 15, 2018
a78169b
test_ufuncs normal again
max-sixty Jan 15, 2018
b1a6766
final lint normalize
max-sixty Jan 15, 2018
1ba00ee
a few left overs
max-sixty Jan 15, 2018
aa340ff
xarray-specific functions changed in backends
max-sixty Jan 15, 2018
c296f89
undo self.AllClose
max-sixty Jan 15, 2018
d2e3d16
remove some old xarray funcs
max-sixty Jan 15, 2018
ab59d04
assert_array_equal complete
max-sixty Jan 15, 2018
b2cf4e8
remove assertVariable*
max-sixty Jan 15, 2018
caed1bd
more parentheses please
max-sixty Jan 15, 2018
3938aa7
install pytest through pip in 3.4 CI
max-sixty Jan 15, 2018
ec9d88c
flake8 fails on 3.4 only without this?
max-sixty Jan 15, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ pip-log.txt
.tox
nosetests.xml
.cache
.ropeproject/

# Translations
*.mo
Expand All @@ -51,4 +52,7 @@ doc/_build
doc/generated
xarray/version.py

# Sync tools
Icon*

.ipynb_checkpoints
2 changes: 1 addition & 1 deletion xarray/conventions.py
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ def ensure_dtype_not_object(var, name=None):
fill_value = u''
else:
# insist on using float for numeric values
if not np.issubdtype(inferred_dtype, float):
if not np.issubdtype(inferred_dtype, np.floating):
inferred_dtype = np.dtype(float)
fill_value = inferred_dtype.type(np.nan)

Expand Down
6 changes: 4 additions & 2 deletions xarray/core/dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -1573,7 +1573,8 @@ def relevant_keys(mapping):
dim_name = dim
dim_coord = None

reordered = self.transpose(*(list(indexer_dims) + list(non_indexed_dims)))
reordered = self.transpose(
*(list(indexer_dims) + list(non_indexed_dims)))

variables = OrderedDict()

Expand Down Expand Up @@ -3383,7 +3384,8 @@ def rank(self, dim, pct=False, keep_attrs=False):
Variables that do not depend on `dim` are dropped.
"""
if dim not in self.dims:
raise ValueError('Dataset does not contain the dimension: %s' % dim)
raise ValueError(
'Dataset does not contain the dimension: %s' % dim)

variables = OrderedDict()
for name, var in iteritems(self.variables):
Expand Down
6 changes: 3 additions & 3 deletions xarray/core/dtypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ def maybe_promote(dtype):
fill_value : Valid missing value for the promoted dtype.
"""
# N.B. these casting rules should match pandas
if np.issubdtype(dtype, float):
if np.issubdtype(dtype, np.floating):
fill_value = np.nan
elif np.issubdtype(dtype, int):
elif np.issubdtype(dtype, np.signedinteger):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should also apply to unsigned integers, and the resulting dtype should be given as a numpy dtype. Plus, we can make this much more efficient for small integers:

elif np.issubdtype(dtype, np.integer):
    if dtype.itemsize <= 2:
        dtype = np.float32
    else:
        dtype = np.float64
    fill_value = np.nan

# convert to floating point so NaN is valid
dtype = float
fill_value = np.nan
elif np.issubdtype(dtype, complex):
elif np.issubdtype(dtype, np.complexfloating):
fill_value = np.nan + np.nan * 1j
elif np.issubdtype(dtype, np.datetime64):
fill_value = np.datetime64('NaT')
Expand Down
2 changes: 1 addition & 1 deletion xarray/core/indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -879,7 +879,7 @@ def __array__(self, dtype=None):
if isinstance(array, pd.PeriodIndex):
with suppress(AttributeError):
# this might not be public API
array = array.asobject
array = array.astype('object')
return np.asarray(array.values, dtype=dtype)

@property
Expand Down
3 changes: 3 additions & 0 deletions xarray/core/missing.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class NumpyInterpolator(BaseInterpolator):
--------
numpy.interp
'''

def __init__(self, xi, yi, method='linear', fill_value=None, **kwargs):

if method != 'linear':
Expand Down Expand Up @@ -83,6 +84,7 @@ class ScipyInterpolator(BaseInterpolator):
--------
scipy.interpolate.interp1d
'''

def __init__(self, xi, yi, method=None, fill_value=None,
assume_sorted=True, copy=False, bounds_error=False, **kwargs):
from scipy.interpolate import interp1d
Expand Down Expand Up @@ -118,6 +120,7 @@ class SplineInterpolator(BaseInterpolator):
--------
scipy.interpolate.UnivariateSpline
'''

def __init__(self, xi, yi, method='spline', fill_value=None, order=3,
**kwargs):
from scipy.interpolate import UnivariateSpline
Expand Down
1 change: 1 addition & 0 deletions xarray/core/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,7 @@ class HiddenKeyDict(MutableMapping):
Acts like a normal dictionary, but hides certain keys.
'''
# ``__init__`` method required to create instance from class.

def __init__(self, data, hidden_keys):
self._data = data
if type(hidden_keys) not in (list, tuple):
Expand Down
3 changes: 3 additions & 0 deletions xarray/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ def _importorskip(modname, minversion=None):


class TestCase(unittest.TestCase):
"""
These functions are all deprecated. Instead, use functions in xr.testing
"""
if PY3:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can remove from xarray.core.pycompat import PY3 in line 3.

# Python 3 assertCountEqual is roughly equivalent to Python 2
# assertItemsEqual
Expand Down
103 changes: 68 additions & 35 deletions xarray/tests/test_accessors.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
import numpy as np
import pandas as pd

from . import TestCase, requires_dask, raises_regex
from . import (TestCase, requires_dask, raises_regex, assert_equal,
assert_array_equal)


class TestDatetimeAccessor(TestCase):
Expand All @@ -17,29 +18,58 @@ def setUp(self):
lats = np.linspace(0, 20, 10)
self.times = pd.date_range(start="2000/01/01", freq='H', periods=nt)

self.data = xr.DataArray(data, coords=[lons, lats, self.times],
dims=['lon', 'lat', 'time'], name='data')
self.data = xr.DataArray(
data,
coords=[lons, lats, self.times],
dims=['lon', 'lat', 'time'],
name='data')

self.times_arr = np.random.choice(self.times, size=(10, 10, nt))
self.times_data = xr.DataArray(self.times_arr,
coords=[lons, lats, self.times],
dims=['lon', 'lat', 'time'],
name='data')
self.times_data = xr.DataArray(
self.times_arr,
coords=[lons, lats, self.times],
dims=['lon', 'lat', 'time'],
name='data')

def test_field_access(self):
years = xr.DataArray(self.times.year, name='year',
coords=[self.times, ], dims=['time', ])
months = xr.DataArray(self.times.month, name='month',
coords=[self.times, ], dims=['time', ])
days = xr.DataArray(self.times.day, name='day',
coords=[self.times, ], dims=['time', ])
hours = xr.DataArray(self.times.hour, name='hour',
coords=[self.times, ], dims=['time', ])

self.assertDataArrayEqual(years, self.data.time.dt.year)
self.assertDataArrayEqual(months, self.data.time.dt.month)
self.assertDataArrayEqual(days, self.data.time.dt.day)
self.assertDataArrayEqual(hours, self.data.time.dt.hour)
years = xr.DataArray(
self.times.year,
name='year',
coords=[
self.times,
],
dims=[
'time',
])
months = xr.DataArray(
self.times.month,
name='month',
coords=[
self.times,
],
dims=[
'time',
])
days = xr.DataArray(
self.times.day, name='day', coords=[
self.times,
], dims=[
'time',
])
hours = xr.DataArray(
self.times.hour,
name='hour',
coords=[
self.times,
],
dims=[
'time',
])

assert_equal(years, self.data.time.dt.year)
assert_equal(months, self.data.time.dt.month)
assert_equal(days, self.data.time.dt.day)
assert_equal(hours, self.data.time.dt.hour)

def test_not_datetime_type(self):
nontime_data = self.data.copy()
Expand All @@ -58,10 +88,11 @@ def test_dask_field_access(self):
days = self.times_data.dt.day

dask_times_arr = da.from_array(self.times_arr, chunks=(5, 5, 50))
dask_times_2d = xr.DataArray(dask_times_arr,
coords=self.data.coords,
dims=self.data.dims,
name='data')
dask_times_2d = xr.DataArray(
dask_times_arr,
coords=self.data.coords,
dims=self.data.dims,
name='data')
dask_year = dask_times_2d.dt.year
dask_month = dask_times_2d.dt.month
dask_day = dask_times_2d.dt.day
Expand All @@ -75,22 +106,24 @@ def test_dask_field_access(self):

# Double check that outcome chunksize is unchanged
dask_chunks = dask_times_2d.chunks
self.assertEqual(dask_year.data.chunks, dask_chunks)
self.assertEqual(dask_month.data.chunks, dask_chunks)
self.assertEqual(dask_day.data.chunks, dask_chunks)
self.assertEqual(dask_hour.data.chunks, dask_chunks)
assert dask_year.data.chunks == dask_chunks
assert dask_month.data.chunks == dask_chunks
assert dask_day.data.chunks == dask_chunks
assert dask_hour.data.chunks == dask_chunks

# Check the actual output from the accessors
self.assertDataArrayEqual(years, dask_year.compute())
self.assertDataArrayEqual(months, dask_month.compute())
self.assertDataArrayEqual(days, dask_day.compute())
self.assertDataArrayEqual(hours, dask_hour.compute())
assert_equal(years, dask_year.compute())
assert_equal(months, dask_month.compute())
assert_equal(days, dask_day.compute())
assert_equal(hours, dask_hour.compute())

def test_seasons(self):
dates = pd.date_range(start="2000/01/01", freq="M", periods=12)
dates = xr.DataArray(dates)
seasons = ["DJF", "DJF", "MAM", "MAM", "MAM", "JJA", "JJA", "JJA",
"SON", "SON", "SON", "DJF"]
seasons = [
"DJF", "DJF", "MAM", "MAM", "MAM", "JJA", "JJA", "JJA", "SON",
"SON", "SON", "DJF"
]
seasons = xr.DataArray(seasons)

self.assertArrayEqual(seasons.values, dates.dt.season.values)
assert_array_equal(seasons.values, dates.dt.season.values)
12 changes: 6 additions & 6 deletions xarray/tests/test_backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -2193,9 +2193,9 @@ def test_utm(self):

# Tests
expected = DataArray(data, dims=('band', 'y', 'x'), coords={
'band': [1, 2, 3],
'y': -np.arange(ny) * 2000 + 80000 + dy / 2,
'x': np.arange(nx) * 1000 + 5000 + dx / 2,
'band': [1, 2, 3],
'y': -np.arange(ny) * 2000 + 80000 + dy / 2,
'x': np.arange(nx) * 1000 + 5000 + dx / 2,
})
with xr.open_rasterio(tmp_file) as rioda:
assert_allclose(rioda, expected)
Expand Down Expand Up @@ -2362,9 +2362,9 @@ def test_caching(self):
# ref
expected = DataArray(
data, dims=('band', 'y', 'x'), coords={
'x': (np.arange(nx) * 0.5 + 1) + dx / 2,
'y': (-np.arange(ny) * 2 + 2) + dy / 2,
'band': [1, 2, 3]})
'x': (np.arange(nx) * 0.5 + 1) + dx / 2,
'y': (-np.arange(ny) * 2 + 2) + dy / 2,
'band': [1, 2, 3]})

# Cache is the default
with xr.open_rasterio(tmp_file) as actual:
Expand Down
Loading