Skip to content
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

Moving function quantity_allclose #7235 #7252

Merged
merged 12 commits into from
Apr 16, 2018
9 changes: 9 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,11 @@ astropy.table
astropy.tests
^^^^^^^^^^^^^

- The function ``quantity_allclose`` was moved to the ``units`` package with
the new, shorter name ``allclose``. This eliminates a runtime dependency on
``pytest`` which was causing issues for some affiliated packages. The old
import will continue to work but may be deprecated in the future. [#7252]

astropy.time
^^^^^^^^^^^^

Expand All @@ -342,6 +347,10 @@ astropy.units

- ``u.quantity_input`` no longer errors if the return annotation for a function is ``None``. [#7336]

- Added a units-aware ``allclose`` function (this was previously available in
the ``tests`` module as ``quantity_allclose``). To complement ``allclose``,
a new ``isclose`` function is also added and backported. [#7252]

astropy.utils
^^^^^^^^^^^^^

Expand Down
2 changes: 1 addition & 1 deletion astropy/coordinates/tests/accuracy/test_ecliptic.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import numpy as np

from ....tests.helper import quantity_allclose
from ....units import allclose as quantity_allclose
from .... import units as u
from ... import SkyCoord
from ...builtin_frames import FK5, ICRS, GCRS, GeocentricTrueEcliptic, BarycentricTrueEcliptic, HeliocentricTrueEcliptic
Expand Down
4 changes: 2 additions & 2 deletions astropy/coordinates/tests/test_api_ape5.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
from numpy.random import randn
from numpy import testing as npt

from ...tests.helper import (raises, quantity_allclose as allclose,
assert_quantity_allclose as assert_allclose)
from ...tests.helper import raises, assert_quantity_allclose as assert_allclose
from ... import units as u
from ... import time
from ... import coordinates as coords
from ...units import allclose

try:
import scipy # pylint: disable=W0611
Expand Down
5 changes: 2 additions & 3 deletions astropy/coordinates/tests/test_celestial_transformations.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@
from ..builtin_frames import (ICRS, FK5, FK4, FK4NoETerms, Galactic,
Supergalactic, Galactocentric, HCRS, GCRS, LSR)
from .. import SkyCoord
from ...tests.helper import (quantity_allclose as allclose,
assert_quantity_allclose as assert_allclose)
from ...tests.helper import assert_quantity_allclose as assert_allclose
from .. import EarthLocation, CartesianRepresentation
from ...time import Time

from ...units import allclose

# used below in the next parametrized test
m31_sys = [ICRS, FK5, FK4, Galactic]
Expand Down
2 changes: 1 addition & 1 deletion astropy/coordinates/tests/test_distance.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from numpy import testing as npt

from ... import units as u
from ...tests.helper import quantity_allclose
from ...units import allclose as quantity_allclose
from .. import Longitude, Latitude, Distance, CartesianRepresentation
from ..builtin_frames import ICRS, Galactic

Expand Down
2 changes: 1 addition & 1 deletion astropy/coordinates/tests/test_earth.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

from ..earth import EarthLocation, ELLIPSOIDS
from ..angles import Longitude, Latitude
from ...tests.helper import quantity_allclose
from ...units import allclose as quantity_allclose
from ... import units as u
from ...time import Time
from ... import constants
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import pytest
import numpy as np
from ...tests.helper import quantity_allclose
from ...units import allclose as quantity_allclose

from ... import units as u
from ... import constants
Expand Down
5 changes: 3 additions & 2 deletions astropy/coordinates/tests/test_frames.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@
import numpy as np

from ... import units as u
from ...tests.helper import (catch_warnings,
pytest, quantity_allclose as allclose,
from ...tests.helper import (catch_warnings, pytest,
assert_quantity_allclose as assert_allclose)
from ...utils import OrderedDescriptorContainer
from ...utils.compat import NUMPY_LT_1_14
from ...utils.exceptions import AstropyWarning
from .. import representation as r
from ..representation import REPRESENTATION_CLASSES
from ...units import allclose


from .test_representation import unitphysics # this fixture is used below

Expand Down
2 changes: 1 addition & 1 deletion astropy/coordinates/tests/test_frames_with_velocity.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from ... import units as u
from ..builtin_frames import ICRS, Galactic, Galactocentric
from .. import builtin_frames as bf
from ...tests.helper import quantity_allclose
from ...units import allclose as quantity_allclose
from ..errors import ConvertError
from .. import representation as r

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
import numpy as np

from ... import units as u
from ...tests.helper import (quantity_allclose as allclose,
assert_quantity_allclose as assert_allclose)
from ...tests.helper import (assert_quantity_allclose as assert_allclose)
from ...time import Time
from .. import (EarthLocation, get_sun, ICRS, GCRS, CIRS, ITRS, AltAz,
PrecessedGeocentric, CartesianRepresentation, SkyCoord,
Expand All @@ -21,6 +20,7 @@
from .utils import randomly_sample_sphere
from ..builtin_frames.utils import get_jd12
from .. import solar_system_ephemeris
from ...units import allclose

try:
import jplephem # pylint: disable=W0611
Expand Down
3 changes: 2 additions & 1 deletion astropy/coordinates/tests/test_regression.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@
from ...utils import iers
from ...table import Table

from ...tests.helper import assert_quantity_allclose, catch_warnings, quantity_allclose
from ...tests.helper import assert_quantity_allclose, catch_warnings
from .test_matching import HAS_SCIPY, OLDER_SCIPY
from ...units import allclose as quantity_allclose

try:
import yaml # pylint: disable=W0611
Expand Down
3 changes: 2 additions & 1 deletion astropy/coordinates/tests/test_sites.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@

import pytest

from ...tests.helper import assert_quantity_allclose, quantity_allclose
from ...tests.helper import assert_quantity_allclose
from ...units import allclose as quantity_allclose
from ... import units as u
from .. import Longitude, Latitude, EarthLocation
from ..sites import get_builtin_sites, get_downloaded_sites, SiteRegistry
Expand Down
3 changes: 2 additions & 1 deletion astropy/coordinates/tests/test_sky_coord.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import numpy.testing as npt

from ... import units as u
from ...tests.helper import (catch_warnings, quantity_allclose,
from ...tests.helper import (catch_warnings,
assert_quantity_allclose as assert_allclose)
from ..representation import REPRESENTATION_CLASSES
from ...coordinates import (ICRS, FK4, FK5, Galactic, SkyCoord, Angle,
Expand All @@ -26,6 +26,7 @@
from ...utils import minversion, isiterable
from ...utils.compat import NUMPY_LT_1_14
from ...utils.exceptions import AstropyDeprecationWarning
from ...units import allclose as quantity_allclose

RA = 1.0 * u.deg
DEC = 2.0 * u.deg
Expand Down
3 changes: 2 additions & 1 deletion astropy/coordinates/tests/test_solar_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
_apparent_position_in_true_coordinates,
get_body_barycentric, get_body_barycentric_posvel)
from ..funcs import get_sun
from ...tests.helper import assert_quantity_allclose, quantity_allclose
from ...tests.helper import assert_quantity_allclose
from ...units import allclose as quantity_allclose

try:
import jplephem # pylint: disable=W0611
Expand Down
3 changes: 2 additions & 1 deletion astropy/coordinates/tests/test_transformations.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@
from .. import representation as r
from ..baseframe import frame_transform_graph
from ...tests.helper import (assert_quantity_allclose as assert_allclose,
quantity_allclose, catch_warnings)
catch_warnings)
from ...time import Time
from ...units import allclose as quantity_allclose


# Coordinates just for these tests.
Expand Down
2 changes: 1 addition & 1 deletion astropy/cosmology/tests/test_cosmology.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import numpy as np

from .. import core, funcs
from ...tests.helper import quantity_allclose as allclose
from ...units import allclose
from ...utils.compat import NUMPY_LT_1_14
from ... import units as u

Expand Down
4 changes: 2 additions & 2 deletions astropy/io/ascii/tests/test_ecsv.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
from ....table.table_helpers import simple_table
from ....coordinates import SkyCoord, Latitude, Longitude, Angle, EarthLocation
from ....time import Time, TimeDelta
from ....tests.helper import quantity_allclose
from ....units.quantity import QuantityInfo
from ....units import allclose as quantity_allclose
from ....units import QuantityInfo

from ..ecsv import DELIMITERS
from ... import ascii
Expand Down
2 changes: 1 addition & 1 deletion astropy/io/fits/tests/test_connect.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

from ....coordinates import SkyCoord, Latitude, Longitude, Angle, EarthLocation
from ....time import Time, TimeDelta
from ....tests.helper import quantity_allclose
from ....units import allclose as quantity_allclose
from ....units.quantity import QuantityInfo

try:
Expand Down
56 changes: 6 additions & 50 deletions astropy/tests/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@
This module provides the tools used to internally run the astropy test suite
from the installed astropy. It makes use of the `pytest` testing framework.
"""

import os
import sys
import types
import pickle
import warnings
import functools

import pytest

try:
Expand All @@ -21,6 +19,7 @@
except ImportError:
pass

from ..units import allclose as _quantity_allclose
from ..utils.exceptions import (AstropyDeprecationWarning,
AstropyPendingDeprecationWarning)

Expand Down Expand Up @@ -460,53 +459,10 @@ def assert_quantity_allclose(actual, desired, rtol=1.e-7, atol=None,
This is a :class:`~astropy.units.Quantity`-aware version of
:func:`numpy.testing.assert_allclose`.
"""
import numpy as np
np.testing.assert_allclose(*_unquantify_allclose_arguments(actual, desired,
Copy link
Member

Choose a reason for hiding this comment

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

It seems this line, which was reinstated because of a comment by @mhvk got deleted again in the sphinx fixes. @pllim can we put this back in your second PR, to fix @cdeil's problem?

Copy link
Member

Choose a reason for hiding this comment

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

Ops. I only saw Tom's comment. Sorry. I'll fix this shortly.

rtol, atol),
**kwargs)


def quantity_allclose(a, b, rtol=1.e-5, atol=None, **kwargs):
"""
Returns True if two arrays are element-wise equal within a tolerance.

This is a :class:`~astropy.units.Quantity`-aware version of
:func:`numpy.allclose`.
"""
import numpy as np
return np.allclose(*_unquantify_allclose_arguments(a, b, rtol, atol),
**kwargs)
assert _quantity_allclose(actual, desired, rtol=rtol, atol=atol, **kwargs)

# TODO: This is a workaround to preserve API compatibility for the bugfix
def quantity_allclose(*args, **kwargs):
return _quantity_allclose(*args, **kwargs)

def _unquantify_allclose_arguments(actual, desired, rtol, atol):
from .. import units as u

actual = u.Quantity(actual, subok=True, copy=False)

desired = u.Quantity(desired, subok=True, copy=False)
try:
desired = desired.to(actual.unit)
except u.UnitsError:
raise u.UnitsError("Units for 'desired' ({0}) and 'actual' ({1}) "
"are not convertible"
.format(desired.unit, actual.unit))

if atol is None:
# by default, we assume an absolute tolerance of 0
atol = u.Quantity(0)
else:
atol = u.Quantity(atol, subok=True, copy=False)
try:
atol = atol.to(actual.unit)
except u.UnitsError:
raise u.UnitsError("Units for 'atol' ({0}) and 'actual' ({1}) "
"are not convertible"
.format(atol.unit, actual.unit))

rtol = u.Quantity(rtol, subok=True, copy=False)
try:
rtol = rtol.to(u.dimensionless_unscaled)
except Exception:
raise u.UnitsError("`rtol` should be dimensionless")

return actual.value, desired.value, rtol.value, atol.value
quantity_allclose.__doc__ = _quantity_allclose.__doc__
60 changes: 59 additions & 1 deletion astropy/units/quantity.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
check_output)

__all__ = ["Quantity", "SpecificTypeQuantity",
"QuantityInfoBase", "QuantityInfo"]
"QuantityInfoBase", "QuantityInfo", "allclose", "isclose"]


# We don't want to run doctests in the docstrings we inherit from Numpy
Expand Down Expand Up @@ -1722,3 +1722,61 @@ def _set_unit(self, unit):
", so cannot set it to '{0}'.".format(unit)))

super()._set_unit(unit)


def isclose(a, b, rtol=1.e-5, atol=None, **kwargs):
Copy link
Contributor

Choose a reason for hiding this comment

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

This now definitely is getting in the terrain of making more sense as a separate module/file! quantity_helper is an option, but perhaps better would be quantity_utils. But can be another PR.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, let's defer moving it to separate module in a separate PR.

"""
Notes
-----
Returns True if two arrays are element-wise equal within a tolerance.

This is a :class:`~astropy.units.Quantity`-aware version of
:func:`numpy.isclose`.
"""
return np.isclose(*_unquantify_allclose_arguments(a, b, rtol, atol),
**kwargs)


def allclose(a, b, rtol=1.e-5, atol=None, **kwargs):
"""
Notes
-----
Returns True if two arrays are element-wise equal within a tolerance.

This is a :class:`~astropy.units.Quantity`-aware version of
:func:`numpy.allclose`.
"""
return np.allclose(*_unquantify_allclose_arguments(a, b, rtol, atol),
**kwargs)


def _unquantify_allclose_arguments(actual, desired, rtol, atol):
actual = Quantity(actual, subok=True, copy=False)

desired = Quantity(desired, subok=True, copy=False)
try:
desired = desired.to(actual.unit)
except UnitsError:
raise UnitsError("Units for 'desired' ({0}) and 'actual' ({1}) "
"are not convertible"
.format(desired.unit, actual.unit))

if atol is None:
# by default, we assume an absolute tolerance of 0
atol = Quantity(0)
else:
atol = Quantity(atol, subok=True, copy=False)
try:
atol = atol.to(actual.unit)
except UnitsError:
raise UnitsError("Units for 'atol' ({0}) and 'actual' ({1}) "
"are not convertible"
.format(atol.unit, actual.unit))

rtol = Quantity(rtol, subok=True, copy=False)
try:
rtol = rtol.to(dimensionless_unscaled)
except Exception:
raise UnitsError("`rtol` should be dimensionless")

return actual.value, desired.value, rtol.value, atol.value