From 78cfd163ce37e8b55bd1d2cb2a5671370a804c3e Mon Sep 17 00:00:00 2001 From: Mark Piper Date: Thu, 10 Oct 2024 09:19:31 -0600 Subject: [PATCH] Update for latest version of gimli.units (#169) * Remove duplicate install of testing dependencies * Require latest version of model_metadata * Remove obsolete esmpy requirement * Don't install components for testing The subsequent call to `mamba install` updates *shapely* to 2.0, which breaks the <1.9 requirement from #164. * import UnitSystem from gimli.units * remove redundant gimli.units unit tests * checkout gimli.units raises UdunitsError * Consolidate requirements in one install step * Fix typos * Roll back model_metadata for older models --------- Co-authored-by: mcflugen --- .github/workflows/test-notebooks.yml | 10 +- .github/workflows/test.yml | 20 +-- pymt/__init__.py | 2 +- requirements.txt | 2 +- tests/framework/test_bmi_var_units.py | 6 +- tests/test_units.py | 213 -------------------------- 6 files changed, 17 insertions(+), 236 deletions(-) diff --git a/.github/workflows/test-notebooks.yml b/.github/workflows/test-notebooks.yml index 2654532a..670d7a1b 100644 --- a/.github/workflows/test-notebooks.yml +++ b/.github/workflows/test-notebooks.yml @@ -38,18 +38,16 @@ jobs: - name: Install requirements run: | - mamba install --file=requirements.txt + mamba install \ + --file=requirements.txt \ + --file=requirements-testing.txt \ + --file=requirements-notebooks.txt mamba list - name: Build and install package run: | pip install -e . - - name: Install testing dependencies - run: | - mamba install --file=requirements-testing.txt - mamba install --file=requirements-notebooks.txt - - name: Test jupyter notebooks timeout-minutes: 30 run: | diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index aafd94de..ac7474ba 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -41,24 +41,20 @@ jobs: mamba install --file=requirements.txt --file=requirements-testing.txt mamba list - - name: Install Windows requirements - if: matrix.os == 'windows-latest' - run: | - mamba install pymt_child pymt_hydrotrend pymt_permamodel + # - name: Install Windows requirements + # if: matrix.os == 'windows-latest' + # run: | + # mamba install pymt_child pymt_hydrotrend pymt_permamodel - - name: Install Unix requirements - if: matrix.os == 'ubuntu-latest' || matrix.os == 'macos-latest' - run: | - mamba install esmpy - mamba install pymt_cem pymt_child pymt_hydrotrend pymt_permamodel + # - name: Install Unix requirements + # if: matrix.os == 'ubuntu-latest' || matrix.os == 'macos-latest' + # run: | + # mamba install pymt_cem pymt_child pymt_hydrotrend pymt_permamodel - name: Build and install package run: | pip install -e . - - name: Install testing dependencies - run: mamba install --file=requirements-testing.txt - - name: Test run: | python -c 'import pymt; print(pymt.__version__)' diff --git a/pymt/__init__.py b/pymt/__init__.py index 7f79f3f1..fd150e83 100644 --- a/pymt/__init__.py +++ b/pymt/__init__.py @@ -1,4 +1,4 @@ -from gimli import UnitSystem +from gimli.units import UnitSystem from ._version import __version__ from .model_collection import ModelCollection diff --git a/requirements.txt b/requirements.txt index 2476dac6..77c11d1e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ gimli.units>=0.3.2 jinja2 landlab>=2 matplotlib -model_metadata>=0.7 +model_metadata<0.8 netcdf4 pyyaml scipy<1.9 # see #162 diff --git a/tests/framework/test_bmi_var_units.py b/tests/framework/test_bmi_var_units.py index d3d5a98d..bd85015a 100644 --- a/tests/framework/test_bmi_var_units.py +++ b/tests/framework/test_bmi_var_units.py @@ -1,6 +1,6 @@ import numpy as np import pytest -from gimli import IncompatibleUnitsError, UnitNameError +from gimli._udunits2 import UdunitsError from numpy.testing import assert_array_equal from pymt.framework.bmi_bridge import BmiTimeInterpolator, GridMapperMixIn, _BmiCap @@ -64,12 +64,12 @@ def test_unit_conversion(): def test_incompatible_units(): """Test wrapping BMI time methods.""" bmi = Bmi() - with pytest.raises(IncompatibleUnitsError): + with pytest.raises(UdunitsError): bmi.get_value("elevation", units="kg") def test_bad_units(): """Test wrapping BMI time methods.""" bmi = Bmi() - with pytest.raises(UnitNameError): + with pytest.raises(UdunitsError): bmi.get_value("elevation", units="not_real_units") diff --git a/tests/test_units.py b/tests/test_units.py index 61066a10..945e0829 100644 --- a/tests/test_units.py +++ b/tests/test_units.py @@ -1,222 +1,9 @@ -import os -import random - import numpy as np import pytest -from gimli import IncompatibleUnitsError, UnitFormatting, UnitNameError, UnitStatus -from pymt import UnitSystem from pymt.units import transform_azimuth_to_math, transform_math_to_azimuth -@pytest.fixture -def system(): - os.environ.pop("UDUNITS2_XML_PATH", None) - return UnitSystem() - - -def test_get_xml(): - os.environ.pop("UDUNITS2_XML_PATH", None) - path, status = UnitSystem.get_xml_path() - assert path.is_file() - assert status == UnitStatus.OPEN_DEFAULT - - path, status = UnitSystem.get_xml_path(path) - assert path.is_file() - assert status == UnitStatus.OPEN_ARG - - os.environ["UDUNITS2_XML_PATH"] = str(path) - path, status = UnitSystem.get_xml_path() - assert path.is_file() - assert status == UnitStatus.OPEN_ENV - - -def test_default_system(): - os.environ.pop("UDUNITS2_XML_PATH", None) - system = UnitSystem() - assert system.status == "default" - assert system.database.is_file() - - -def test_user_system(): - path = UnitSystem().database - system = UnitSystem(path) - assert system.status == "user" - assert system.database.is_file() - assert system == UnitSystem() - assert UnitSystem(path) == UnitSystem(str(path)) - - -def test_env_system(system): - os.environ["UDUNITS2_XML_PATH"] = str(system.database) - env_system = UnitSystem() - - assert env_system.status == "env" - assert env_system.database.is_file() - assert str(env_system) == str(system) - assert env_system.database.samefile(system.database) - assert env_system == system - - -def test_system_dimensionless(system): - assert system.dimensionless_unit() == system.Unit("1") - assert str(system.dimensionless_unit()) == "1" - - -def test_system_unit_by_name(system): - assert system.unit_by_name("meter") == system.Unit("m") - assert system.unit_by_name("meters") == system.Unit("m") - assert system.unit_by_name("m") is None - assert system.unit_by_name("meter2") is None - assert system.unit_by_name("not_a_name") is None - - -def test_system_unit_by_symbol(system): - assert system.unit_by_symbol("m") == system.Unit("m") - assert system.unit_by_symbol("km") is None - assert system.unit_by_symbol("meter") is None - assert system.unit_by_symbol("m s-2") is None - assert system.unit_by_symbol("not_a_symbol") is None - - -def test_unit_formatting(system): - unit = system.Unit("0.1 lg(re m/(5 s)^2) @ 50") - assert ( - unit.format(encoding="ascii", formatting=UnitFormatting.NAMES) - == "0.1 lg(re 0.04 meter-second^-2) from 50" - ) - assert ( - unit.format(encoding="ascii", formatting=UnitFormatting.DEFINITIONS) - == "0.1 lg(re 0.04 m.s-2) @ 50" - ) - - assert ( - unit.format(encoding="iso-8859-1", formatting=UnitFormatting.NAMES) - == "0.1 lg(re 0.04 meter/second²) from 50" - ) - assert ( - unit.format(encoding="iso-8859-1", formatting=UnitFormatting.DEFINITIONS) - == "0.1 lg(re 0.04 m/s²) @ 50" - ) - - assert ( - unit.format(encoding="latin-1", formatting=UnitFormatting.NAMES) - == "0.1 lg(re 0.04 meter/second²) from 50" - ) - assert ( - unit.format(encoding="latin-1", formatting=UnitFormatting.DEFINITIONS) - == "0.1 lg(re 0.04 m/s²) @ 50" - ) - - assert ( - unit.format(encoding="utf-8", formatting=UnitFormatting.NAMES) - == "0.1 lg(re 0.04 meter·second⁻²) from 50" - ) - assert ( - unit.format(encoding="utf-8", formatting=UnitFormatting.DEFINITIONS) - == "0.1 lg(re 0.04 m·s⁻²) @ 50" - ) - - -@pytest.mark.parametrize( - ("lhs", "cmp_", "rhs"), - [ - ("m", "lt", "km"), - ("m", "le", "km"), - ("m", "le", "m"), - ("m", "eq", "m"), - ("m", "ne", "km"), - ("km", "ge", "m"), - ("km", "ge", "km"), - ("km", "gt", "m"), - ], -) -def test_unit_comparisons(system, lhs, cmp_, rhs): - compare = getattr(system.Unit(lhs), f"__{cmp_}__") - assert compare(system.Unit(rhs)) - with pytest.raises(TypeError): - compare(rhs) - - -def test_unit_symbol(system): - meters = system.Unit("m") - assert meters.symbol == "m" - - km = system.Unit("km") - assert km.symbol is None - - -def test_unit_name(system): - meters = system.Unit("m") - assert meters.name == "meter" - - km = system.Unit("km") - assert km.name is None - - -def test_unit_is_dimensionless(system): - assert not system.Unit("m").is_dimensionless - assert system.Unit("1").is_dimensionless - assert system.Unit("rad").is_dimensionless - - -def test_unit_is_convertible(system): - assert system.Unit("m").is_convertible_to(system.Unit("km")) - assert not system.Unit("m").is_convertible_to(system.Unit("kg")) - - with pytest.raises(TypeError): - system.Unit("m").is_convertible_to("km") - - -def test_unit_converter_length(system): - meters = system.Unit("m") - km = system.Unit("km") - - assert meters.to(km)(1.0) == pytest.approx(1e-3) - with pytest.raises(TypeError): - meters.to("km") - - m_to_km = meters.to(km) - assert m_to_km(1.0) == pytest.approx(1e-3) - - -def test_unit_converter_time(system): - hours = system.Unit("h") - seconds = system.Unit("s") - hours_to_seconds = hours.to(seconds) - assert hours_to_seconds(1.0) == pytest.approx(3600.0) - - with pytest.raises(TypeError): - hours.to("s") - - -def test_unit_converter_same_units(system): - hours = system.Unit("h") - hours_to_hours = hours.to(system.Unit("h")) - assert hours_to_hours(1.0) == pytest.approx(1.0) - - -@pytest.mark.parametrize( - ("to_", "from_"), - [("not_a_unit", "m"), ("m", "not_a_unit"), ("not_a_unit", "not_a_unit")], -) -def test_unit_converter_bad_from_units(system, to_, from_): - with pytest.raises(UnitNameError): - system.Unit(from_).to(system.Unit(to_)) - - -def test_unit_converter_incompatible_units(system): - with pytest.raises(IncompatibleUnitsError): - system.Unit("s").to(system.Unit("m")) - - -def test_unit_converter_inverse(system): - val = random.random() - seconds_to_hours = system.Unit("s").to(system.Unit("h")) - hours_to_seconds = system.Unit("h").to(system.Unit("s")) - assert hours_to_seconds(seconds_to_hours(val)) == pytest.approx(val) - - def test_math_to_azimuth(): angle = transform_math_to_azimuth(np.pi * 0.5, "rad") assert angle == pytest.approx(0.0)