Skip to content

Commit

Permalink
Merge pull request #115 from ngoldbaum/deps-update
Browse files Browse the repository at this point in the history
Add support for latest versions of h5py, sympy, numpy, and pytest
  • Loading branch information
ngoldbaum authored Jan 10, 2020
2 parents a2645f8 + 4d1e9cf commit 34550a4
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 38 deletions.
9 changes: 5 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,11 @@ before_install:
- export PYENV_ROOT="$HOME/.pyenv"
- export PATH="$HOME/.pyenv/bin:$PATH"
- eval "$(pyenv init -)"
- pyenv install -s 3.5.5
- pyenv install -s 3.6.5
- pyenv install -s 3.7.1
- pyenv local 3.5.5 3.6.5 3.7.1
- pyenv install -s 3.5.7
- pyenv install -s 3.6.9
- pyenv install -s 3.7.5
- pyenv install -s 3.8.0
- pyenv local 3.5.7 3.6.9 3.7.5 3.8.0
- pip install tox tox-pyenv codecov twine

# Command to run tests, e.g. python setup.py test
Expand Down
2 changes: 1 addition & 1 deletion docs/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1057,7 +1057,7 @@ HDF5 Files

The :mod:`unyt` library provides a hook for writing data both to a new HDF5 file and an existing file and then subsequently reading that data back in to restore the array. This works via the :meth:`unyt_array.write_hdf5 <unyt.array.unyt_array.write_hdf5>` and :meth:`unyt_array.from_hdf5 <unyt.array.unyt_array.from_hdf5>` methods. The simplest way to use these functions is to write data to a file that does not exist yet:

>>> from unyt import cm, unyt_array
>>> from unyt import cm
>>> import os
>>> data = [1, 2, 3]*cm
>>> data.write_hdf5('my_data.h5')
Expand Down
22 changes: 12 additions & 10 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
[tox]
envlist = py36-docs,begin,py35-dependencies,py35-versions,py{35,36,37},end
envlist = py36-docs,begin,py35-dependencies,py35-versions,py{35,36,37,38},end

[travis]
python =
3.8: py38
3.7: py37
3.6: py36, py36-docs
3.5: py35, py35-dependencies, py35-versions

[testenv]
setenv =
PYTHONPATH = {toxinidir}
recreate = true
depends = begin
deps =
pytest<5.1
pytest
sympy
numpy
h5py
pint
astropy
coverage
coverage<5.0
pytest-cov
pytest-doctestplus
flake8
Expand All @@ -30,13 +32,13 @@ commands =

[testenv:py35-versions]
deps =
pytest<5.1
pytest
sympy==1.2
numpy==1.13.3
h5py==2.6.0
pint==0.6
astropy==1.3.3
coverage
coverage<5.0
pytest-cov
pytest-doctestplus
commands =
Expand All @@ -46,10 +48,10 @@ commands =

[testenv:py35-dependencies]
deps =
pytest<5.1
pytest
sympy
numpy
coverage
coverage<5.0
pytest-cov
pytest-doctestplus
depends = begin
Expand Down Expand Up @@ -77,13 +79,13 @@ commands =
depends =
skip_install = true
deps =
coverage
coverage<5.0

[testenv:end]
commands =
coverage report --omit='.tox/*'
coverage html --omit='.tox/*'
skip_install = true
depends = py{35,36,37}
depends = py{35,36,37,38}
deps =
coverage
coverage<5.0
2 changes: 1 addition & 1 deletion unyt/_parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def _auto_positive_symbol(tokens, local_dict, global_dict):
"sqrt": sqrt,
}

unit_text_transform = (_auto_positive_symbol, rationalize, auto_number)
unit_text_transform = (_auto_positive_symbol, auto_number, rationalize)


def parse_unyt_expr(unit_expr):
Expand Down
60 changes: 46 additions & 14 deletions unyt/array.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,13 @@
from unyt.equivalencies import equivalence_registry
from unyt._on_demand_imports import _astropy, _pint
from unyt._pint_conversions import convert_pint_units
from unyt._unit_lookup_table import default_unit_symbol_lut
from unyt.unit_object import _check_em_conversion, _em_conversion, Unit
from unyt.unit_registry import _sanitize_unit_system, UnitRegistry
from unyt.unit_registry import (
_sanitize_unit_system,
UnitRegistry,
default_unit_registry,
)

NULL_UNIT = Unit()
POWER_SIGN_MAPPING = {multiply: 1, divide: -1}
Expand Down Expand Up @@ -321,6 +326,8 @@ def _sanitize_units_convert(possible_units, registry):

trigonometric_operators = (sin, cos, tan)

multiple_output_operators = {modf: 2, frexp: 2, divmod_: 2}

LARGE_INPUT = {4: 16777217, 8: 9007199254740993}


Expand Down Expand Up @@ -1317,12 +1324,16 @@ def write_hdf5(self, filename, dataset_name=None, info=None, group_name=None):
info = {}

info["units"] = str(self.units)
info["unit_registry"] = np.void(pickle.dumps(self.units.registry.lut))
lut = {}
for k, v in self.units.registry.lut.items():
if k not in default_unit_registry.lut:
lut[k] = v
info["unit_registry"] = np.void(pickle.dumps(lut))

if dataset_name is None:
dataset_name = "array_data"

f = h5py.File(filename)
f = h5py.File(filename, "a")
if group_name is not None:
if group_name in f:
g = f[group_name]
Expand Down Expand Up @@ -1372,15 +1383,17 @@ def from_hdf5(cls, filename, dataset_name=None, group_name=None):
if dataset_name is None:
dataset_name = "array_data"

f = h5py.File(filename)
f = h5py.File(filename, "r")
if group_name is not None:
g = f[group_name]
else:
g = f
dataset = g[dataset_name]
data = dataset[:]
units = dataset.attrs.get("units", "")
unit_lut = pickle.loads(dataset.attrs["unit_registry"].tostring())
unit_lut = default_unit_symbol_lut.copy()
unit_lut_load = pickle.loads(dataset.attrs["unit_registry"].tostring())
unit_lut.update(unit_lut_load)
f.close()
registry = UnitRegistry(lut=unit_lut, add_default_symbols=False)
return cls(data, units, registry=registry)
Expand Down Expand Up @@ -1584,18 +1597,29 @@ def __getitem__(self, item):
def __array_ufunc__(self, ufunc, method, *inputs, **kwargs):
func = getattr(ufunc, method)
if "out" not in kwargs:
out = None
out_func = None
if ufunc in multiple_output_operators:
out = (None,) * multiple_output_operators[ufunc]
out_func = out
else:
out = None
out_func = None
else:
# we need to get both the actual "out" object and a view onto it
# in case we need to do in-place operations
out = kwargs.pop("out")[0]
if out.dtype.kind in ("u", "i"):
new_dtype = "f" + str(out.dtype.itemsize)
float_values = out.astype(new_dtype)
out.dtype = new_dtype
np.copyto(out, float_values)
out_func = out.view(np.ndarray)
out = kwargs.pop("out")
if ufunc in multiple_output_operators:
out_func = []
for arr in out:
out_func.append(arr.view(np.ndarray))
out_func = tuple(out_func)
else:
out = out[0]
if out.dtype.kind in ("u", "i"):
new_dtype = "f" + str(out.dtype.itemsize)
float_values = out.astype(new_dtype)
out.dtype = new_dtype
np.copyto(out, float_values)
out_func = out.view(np.ndarray)
if len(inputs) == 1:
# Unary ufuncs
inp = inputs[0]
Expand Down Expand Up @@ -1775,6 +1799,14 @@ def __array_ufunc__(self, ufunc, method, *inputs, **kwargs):
except AttributeError:
# out_arr is an ndarray
out.units = Unit("", registry=self.units.registry)
elif isinstance(out, tuple):
for o, oa in zip(out, out_arr):
if o is None:
continue
try:
o.units = oa.units
except AttributeError:
o.units = Unit("", registry=self.units.registry)
if mul == 1:
return out_arr
return mul * out_arr
Expand Down
22 changes: 15 additions & 7 deletions unyt/tests/test_unyt_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -1010,7 +1010,10 @@ def unary_ufunc_comparison(ufunc, a):


def binary_ufunc_comparison(ufunc, a, b):
out = b.copy()
if ufunc in [np.divmod]:
out = (b.copy(), b.copy())
else:
out = b.copy()
if ufunc in yield_np_ufuncs(
[
"add",
Expand Down Expand Up @@ -1073,7 +1076,10 @@ def binary_ufunc_comparison(ufunc, a, b):
):
assert not isinstance(ret, unyt_array) and isinstance(ret, np.ndarray)
if isinstance(ret, tuple):
assert_array_equal(ret[0], out)
assert isinstance(out, tuple)
assert len(out) == len(ret)
for o, r in zip(out, ret):
assert_array_equal(r, o)
else:
assert_array_equal(ret, out)
if ufunc in (np.divide, np.true_divide, np.arctan2) and (
Expand Down Expand Up @@ -1353,6 +1359,10 @@ def test_astropy():


def test_pint():
def assert_pint_array_equal(arr1, arr2):
assert_array_equal(arr1.magnitude, arr2.magnitude)
assert str(arr1.units) == str(arr2.units)

if isinstance(_pint.UnitRegistry, NotAModule):
return
ureg = _pint.UnitRegistry()
Expand All @@ -1365,13 +1375,11 @@ def test_pint():
yt_quan = unyt_quantity(10.0, "sqrt(g)/mm**3")
yt_quan2 = unyt_quantity.from_pint(p_quan)

assert_array_equal(p_arr, yt_arr.to_pint())
assert_equal(p_quan, yt_quan.to_pint())
assert_pint_array_equal(p_arr, yt_arr.to_pint())
assert_array_equal(yt_arr, unyt_array.from_pint(p_arr))
assert_array_equal(yt_arr, yt_arr2)

assert_equal(p_quan.magnitude, yt_quan.to_pint().magnitude)
assert_equal(p_quan, yt_quan.to_pint())
assert_pint_array_equal(p_quan, yt_quan.to_pint())
assert_equal(yt_quan, unyt_quantity.from_pint(p_quan))
assert_equal(yt_quan, yt_quan2)

Expand Down Expand Up @@ -1477,7 +1485,7 @@ def test_h5_io():

# write to a group that does exist

with _h5py.File("test.h5") as f:
with _h5py.File("test.h5", "a") as f:
f.create_group("/arrays/test_group")

warr.write_hdf5(
Expand Down
2 changes: 1 addition & 1 deletion unyt/unit_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def _get_latex_representation(expr, registry):
l_expr = expr
if isinstance(expr, Mul):
coeffs = expr.as_coeff_Mul()
if coeffs[0] == 1 or not isinstance(coeffs[0], Float):
if coeffs[0] == 1 or not isinstance(coeffs[0], Number):
l_expr = coeffs[1]
else:
l_expr = coeffs[1]
Expand Down

0 comments on commit 34550a4

Please sign in to comment.