diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 0b849bc..ccd55b2 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -91,7 +91,7 @@ jobs: - name: Run docexamples if: ${{ matrix.openmm == 'true' }} run: | - pytest --doctest-modules $PYTEST_ARGS $COV openff + pytest --doctest-modules $PYTEST_ARGS $COV openff --ignore=openff/units/tests - name: Codecov uses: codecov/codecov-action@v1 diff --git a/devtools/conda-envs/docs_env.yaml b/devtools/conda-envs/docs_env.yaml index 3df6bac..3393797 100644 --- a/devtools/conda-envs/docs_env.yaml +++ b/devtools/conda-envs/docs_env.yaml @@ -5,7 +5,7 @@ dependencies: - python - pip - numpy - - pint =0.19 + - pint >=0.20.1 - openff-utilities >=0.1.3 - sphinx >=4.5,<5 - myst-parser>=0.13.6 diff --git a/devtools/conda-envs/test_env.yaml b/devtools/conda-envs/test_env.yaml index 40d86a7..01b6853 100644 --- a/devtools/conda-envs/test_env.yaml +++ b/devtools/conda-envs/test_env.yaml @@ -6,7 +6,7 @@ dependencies: - python - pip - numpy - - pint =0.19 + - pint >=0.20.1 - openff-utilities >=0.1.3 # Tests diff --git a/openff/units/__init__.py b/openff/units/__init__.py index 196a006..c459025 100644 --- a/openff/units/__init__.py +++ b/openff/units/__init__.py @@ -1,8 +1,12 @@ -from pint import UnitRegistry - from openff.units._version import get_versions # type: ignore from openff.units.openmm import ensure_quantity -from openff.units.units import DEFAULT_UNIT_REGISTRY, Measurement, Quantity, Unit +from openff.units.units import ( + DEFAULT_UNIT_REGISTRY, + Measurement, + Quantity, + Unit, + UnitRegistry, +) __all__ = [ "unit", diff --git a/openff/units/data/defaults.txt b/openff/units/data/defaults.txt index 050eb85..a978d67 100644 --- a/openff/units/data/defaults.txt +++ b/openff/units/data/defaults.txt @@ -109,7 +109,8 @@ hertz = 1 / second = Hz reciprocal_centimeter = 1 / cm = cm_1 = kayser # Velocity -[velocity] = [length] / [time] = [speed] +# As of 0.20, derived dimensions cannot have aliases +[velocity] = [length] / [time] # Acceleration [acceleration] = [velocity] / [time] diff --git a/openff/units/elements.py b/openff/units/elements.py index 29ee4e8..29b55b5 100644 --- a/openff/units/elements.py +++ b/openff/units/elements.py @@ -36,7 +36,7 @@ "SYMBOLS", ] -MASSES: Dict[int, Quantity[float]] = { +MASSES: Dict[int, Quantity] = { index + 1: Quantity(mass, unit.dalton) for index, mass in enumerate( [ diff --git a/openff/units/openmm.py b/openff/units/openmm.py index 18c7236..b83b89a 100644 --- a/openff/units/openmm.py +++ b/openff/units/openmm.py @@ -211,6 +211,8 @@ def to_openmm_inner(quantity) -> "openmm_unit.Quantity": return value * openmm_unit_ + assert isinstance(quantity, Quantity) + try: return to_openmm_inner(quantity) except MissingOpenMMUnitError: @@ -262,7 +264,7 @@ def _ensure_openff_quantity( ) else: try: - return unit.Quantity( # type: ignore + return unit.Quantity( unknown_quantity, unit.dimensionless, ) diff --git a/openff/units/tests/test_units.py b/openff/units/tests/test_units.py index 9074ffe..b07cad2 100644 --- a/openff/units/tests/test_units.py +++ b/openff/units/tests/test_units.py @@ -36,14 +36,14 @@ def test_pickle_unit(self): assert x == y - def test_pick_quantity(self): + def test_pickle_quantity(self): x = 1.0 * unit.kelvin y = pickle.loads(pickle.dumps(x)) assert x == y @skip_if_missing("uncertainties") - def test_pickle_quantity(self): + def test_pickle_quantity_uncertainties(self): x = (1.0 * unit.kelvin).plus_minus(0.05) y = pickle.loads(pickle.dumps(x)) diff --git a/openff/units/units.py b/openff/units/units.py index 30cabfa..4ca257d 100644 --- a/openff/units/units.py +++ b/openff/units/units.py @@ -1,16 +1,16 @@ """ Core classes for OpenFF Units """ - import uuid import warnings -from typing import TYPE_CHECKING, TypeVar +from typing import TYPE_CHECKING import pint from openff.utilities import requires_package -from pint.measurement import _Measurement -from pint.quantity import _Quantity -from pint.unit import _Unit +from pint import Measurement as _Measurement +from pint import Quantity as _Quantity +from pint import Unit as _Unit +from pint import UnitRegistry as _UnitRegistry from openff.units.utilities import get_defaults_path @@ -24,45 +24,16 @@ "Unit", ] -DEFAULT_UNIT_REGISTRY = pint.UnitRegistry(get_defaults_path()) -"""The default unit registry provided by OpenFF Units""" - - -def _unpickle_quantity(cls, *args): - """Rebuild quantity upon unpickling using the application registry.""" - return pint._unpickle(DEFAULT_UNIT_REGISTRY.Quantity, *args) - - -def _unpickle_unit(cls, *args): - """Rebuild unit upon unpickling using the application registry.""" - return pint._unpickle(DEFAULT_UNIT_REGISTRY.Unit, *args) - - -def _unpickle_measurement(cls, *args): - """Rebuild measurement upon unpickling using the application registry.""" - return pint._unpickle(DEFAULT_UNIT_REGISTRY.Measurement, *args) - class Unit(_Unit): """A unit of measure.""" - _REGISTRY = DEFAULT_UNIT_REGISTRY - - def __reduce__(self): - return _unpickle_unit, (Unit, self._units) + pass -_MagnitudeType = TypeVar("_MagnitudeType") - - -class Quantity(_Quantity[_MagnitudeType]): +class Quantity(_Quantity): """A value with associated units.""" - _REGISTRY = DEFAULT_UNIT_REGISTRY - - def __reduce__(self): - return _unpickle_quantity, (Quantity, self.magnitude, self._units) - def __dask_tokenize__(self): return uuid.uuid4().hex @@ -88,11 +59,6 @@ def to_openmm(self) -> "OpenMMQuantity": class Measurement(_Measurement): """A value with associated units and uncertainty.""" - _REGISTRY = DEFAULT_UNIT_REGISTRY - - def __reduce__(self): - return _unpickle_measurement, (Measurement, self.magnitude, self._units) - def __dask_tokenize__(self): return uuid.uuid4().hex @@ -102,9 +68,17 @@ def _dask_finalize(results, func, args, units): return Measurement(values, units) -DEFAULT_UNIT_REGISTRY.Unit = Unit -DEFAULT_UNIT_REGISTRY.Quantity = Quantity -DEFAULT_UNIT_REGISTRY.Measurement = Measurement +class UnitRegistry(_UnitRegistry): + _quantity_class = Quantity + _unit_class = Unit + _measurement_class = Measurement + + +DEFAULT_UNIT_REGISTRY = UnitRegistry(get_defaults_path()) + +Unit: _Unit = DEFAULT_UNIT_REGISTRY.Unit # type: ignore[no-redef] +Quantity: _Quantity = DEFAULT_UNIT_REGISTRY.Quantity # type: ignore[no-redef] +Measurement: _Measurement = DEFAULT_UNIT_REGISTRY.Measurement # type: ignore[no-redef] pint.set_application_registry(DEFAULT_UNIT_REGISTRY) diff --git a/setup.cfg b/setup.cfg index 43ef0a5..1d15025 100644 --- a/setup.cfg +++ b/setup.cfg @@ -16,6 +16,8 @@ exclude_lines = [flake8] max-line-length = 119 ignore = E203,W503 +per-file-ignores = + openff/units/units.py:F811 [isort] multi_line_output=3 @@ -47,14 +49,8 @@ ignore_missing_imports = True [mypy-pint.*] ignore_missing_imports = True -[mypy-openff.utilities.*] -ignore_missing_imports = True - [mypy-openmm] ignore_missing_imports = True [mypy-openmm.unit] ignore_missing_imports = True - -[mypy-openmm.app.element] -ignore_missing_imports = True