From 1326cafffe5fa634efd237f17f30a6bf7fb6ce5a Mon Sep 17 00:00:00 2001 From: Andrew Rigby Date: Wed, 19 Jul 2023 15:38:42 +0100 Subject: [PATCH 1/4] Fix for changes between astropy 5.2.2 and 5.3.1 --- astrodendro/analysis.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/astrodendro/analysis.py b/astrodendro/analysis.py index 2993d2e..e0657a8 100644 --- a/astrodendro/analysis.py +++ b/astrodendro/analysis.py @@ -322,7 +322,7 @@ def major_sigma(self): computed from the intensity weighted second moment in direction of greatest elongation in the PP plane. """ - dx = self.spatial_scale or u.pixel + dx = self.spatial_scale if self.spatial_scale is not None else u.pixel a, b = self._sky_paxes() # We need to multiply the second moment by two to get the major axis # rather than the half-major axis. @@ -335,7 +335,7 @@ def minor_sigma(self): computed from the intensity weighted second moment perpendicular to the major axis in the PP plane. """ - dx = self.spatial_scale or u.pixel + dx = self.spatial_scale if self.spatial_scale is not None else u.pixel a, b = self._sky_paxes() # We need to multiply the second moment by two to get the minor axis # rather than the half-minor axis. @@ -484,7 +484,7 @@ def area_exact(self): """ The exact area of the structure on the sky. """ - dx = self.spatial_scale or u.pixel + dx = self.spatial_scale if self.spatial_scale is not None else u.pixel indices = zip(*tuple(self.stat.indices[i] for i in range(3) if i != self.vaxis)) return len(set(indices)) * dx ** 2 @@ -562,7 +562,7 @@ def area_exact(self): """ The exact area of the structure on the sky. """ - dx = self.spatial_scale or u.pixel + dx = self.spatial_scale if self.spatial_scale is not None else u.pixel return self.stat.count() * dx ** 2 From 197a803bb84852c4fecf49801eeefa2492b90710 Mon Sep 17 00:00:00 2001 From: Thomas Robitaille Date: Mon, 7 Aug 2023 10:36:01 +0100 Subject: [PATCH 2/4] Updates to infrastructure to fix compatibility with tox 4, and bump minimum Python version --- .github/workflows/main.yml | 6 +++--- astrodendro/analysis.py | 2 +- astrodendro/io/util.py | 2 +- astrodendro/tests/test_analysis.py | 12 +----------- astrodendro/tests/test_flux.py | 31 +++++++++--------------------- astrodendro/tests/test_index.py | 4 ++-- setup.cfg | 10 +++++----- tox.ini | 11 +++++------ 8 files changed, 27 insertions(+), 51 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 8656544..000b26f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -11,9 +11,9 @@ jobs: envs: | - linux: codestyle pytest: false - - linux: py37-test-oldestdeps - - macos: py38-test + - linux: py38-test-oldestdeps + - macos: py39-test - windows: py39-test - linux: py310-test - - linux: py310-test-devdeps + - linux: py311-test-devdeps coverage: 'codecov' diff --git a/astrodendro/analysis.py b/astrodendro/analysis.py index e0657a8..350505f 100644 --- a/astrodendro/analysis.py +++ b/astrodendro/analysis.py @@ -462,7 +462,7 @@ def v_rms(self): 0 following the Numpy convention - the third axis in the FITS convention). """ - dv = self.velocity_scale or u.pixel + dv = self.velocity_scale if self.velocity_scale is not None else u.pixel ax = [0, 0, 0] ax[self.vaxis] = 1 return dv * np.sqrt(self.stat.mom2_along(tuple(ax))) diff --git a/astrodendro/io/util.py b/astrodendro/io/util.py index fe01422..050eec5 100644 --- a/astrodendro/io/util.py +++ b/astrodendro/io/util.py @@ -91,7 +91,7 @@ def _construct_tree(repr): idx = int(idx) structure_indices = indices_by_structure[idx] f = flux_by_structure[idx] - if type(repr[idx]) == tuple: + if type(repr[idx]) is tuple: sub_structures_repr = repr[idx][0] # Parsed representation of sub structures sub_structures = _construct_tree(sub_structures_repr) for i in sub_structures: diff --git a/astrodendro/tests/test_analysis.py b/astrodendro/tests/test_analysis.py index 682bc4c..e9c1903 100644 --- a/astrodendro/tests/test_analysis.py +++ b/astrodendro/tests/test_analysis.py @@ -6,7 +6,7 @@ from numpy.testing import assert_allclose import astropy.units as u from astropy.wcs import WCS - +from astropy.tests.helper import assert_quantity_allclose as assert_allclose_quantity from ._testdata import data from ..analysis import (ScalarStatistic, PPVStatistic, ppv_catalog, @@ -14,16 +14,6 @@ from .. import Dendrogram, periodic_neighbours from ..structure import Structure - -def assert_allclose_quantity(a, b): - if not isinstance(a, u.Quantity): - raise TypeError("a is not a quantity") - if not isinstance(b, u.Quantity): - raise TypeError("b is not a quantity") - assert_allclose(a.value, b.value) - assert a.unit == b.unit - - wcs_2d = WCS(header=dict(cdelt1=1, crval1=0, crpix1=1, cdelt2=2, crval2=0, crpix2=1)) wcs_3d = WCS(header=dict(cdelt1=1, crval1=0, crpix1=1, diff --git a/astrodendro/tests/test_flux.py b/astrodendro/tests/test_flux.py index 355d877..09e3b2d 100644 --- a/astrodendro/tests/test_flux.py +++ b/astrodendro/tests/test_flux.py @@ -6,10 +6,6 @@ from ..flux import compute_flux -def strip_parentheses(string): - return string.replace('(', '').replace(')', '') - - COMBINATIONS = \ [ (np.array([1, 2, 3]) * u.Jy, u.Jy, {}, 6 * u.Jy), @@ -31,50 +27,41 @@ def test_compute_flux(input_quantities, output_unit, keywords, output): def test_monochromatic_wav_missing(): - with pytest.raises(ValueError) as exc: + with pytest.raises(ValueError, match='wavelength is needed to convert from erg'): compute_flux(np.array([1, 2, 3]) * u.erg / u.cm ** 2 / u.s / u.micron, u.Jy) - assert exc.value.args[0] == 'wavelength is needed to convert from erg / (cm2 micron s) to Jy' def test_monochromatic_wav_invalid_units(): - with pytest.raises(ValueError) as exc: + with pytest.raises(ValueError, match='wavelength should be a physical length'): compute_flux(np.array([1, 2, 3]) * u.erg / u.cm ** 2 / u.s / u.micron, u.Jy, wavelength=3 * u.L) - assert exc.value.args[0] == 'wavelength should be a physical length' def test_surface_brightness_scale_missing(): - with pytest.raises(ValueError) as exc: + with pytest.raises(ValueError, match='spatial_scale is needed to convert from Jy'): compute_flux(np.array([1, 2, 3]) * u.Jy / u.arcsec ** 2, u.Jy) - assert strip_parentheses(exc.value.args[0]) == 'spatial_scale is needed to convert from Jy / arcsec2 to Jy' def test_surface_brightness_invalid_units(): - with pytest.raises(ValueError) as exc: + with pytest.raises(ValueError, match='spatial_scale should be an angle'): compute_flux(np.array([1, 2, 3]) * u.Jy / u.arcsec ** 2, u.Jy, spatial_scale=3 * u.m) - assert exc.value.args[0] == 'spatial_scale should be an angle' def test_per_beam_scale_missing(): - with pytest.raises(ValueError) as exc: + with pytest.raises(ValueError, match='spatial_scale is needed to convert from Jy / beam to Jy'): compute_flux(np.array([1, 2, 3]) * u.Jy / u.beam, u.Jy, beam_major=3 * u.arcsec, beam_minor=2. * u.arcsec) - assert strip_parentheses(exc.value.args[0]) == 'spatial_scale is needed to convert from Jy / beam to Jy' - with pytest.raises(ValueError) as exc: + with pytest.raises(ValueError, match='beam_major is needed to convert from Jy / beam to Jy'): compute_flux(np.array([1, 2, 3]) * u.Jy / u.beam, u.Jy, spatial_scale=3 * u.arcsec, beam_minor=2. * u.arcsec) - assert strip_parentheses(exc.value.args[0]) == 'beam_major is needed to convert from Jy / beam to Jy' - with pytest.raises(ValueError) as exc: + with pytest.raises(ValueError, match='beam_minor is needed to convert from Jy / beam to Jy'): compute_flux(np.array([1, 2, 3]) * u.Jy / u.beam, u.Jy, spatial_scale=3 * u.arcsec, beam_major=2. * u.arcsec) - assert strip_parentheses(exc.value.args[0]) == 'beam_minor is needed to convert from Jy / beam to Jy' def test_per_beam_invalid_units(): - with pytest.raises(ValueError) as exc: + with pytest.raises(ValueError, match='beam_major should be an angle'): compute_flux(np.array([1, 2, 3]) * u.Jy / u.beam, u.Jy, spatial_scale=3 * u.arcsec, beam_major=3 * u.m, beam_minor=2. * u.arcsec) - assert exc.value.args[0] == 'beam_major should be an angle' - with pytest.raises(ValueError) as exc: + with pytest.raises(ValueError, match='beam_minor should be an angle'): compute_flux(np.array([1, 2, 3]) * u.Jy / u.beam, u.Jy, spatial_scale=3 * u.arcsec, beam_major=3 * u.arcsec, beam_minor=2. * u.m) - assert exc.value.args[0] == 'beam_minor should be an angle' diff --git a/astrodendro/tests/test_index.py b/astrodendro/tests/test_index.py index 7828b12..3ae0e49 100644 --- a/astrodendro/tests/test_index.py +++ b/astrodendro/tests/test_index.py @@ -8,10 +8,10 @@ def assert_permuted_fancyindex(x, y): """ Assert that two fancy indices (tuples of integer ndarrays) are permutations of each other """ - if not isinstance(x, tuple) or not(isinstance(x[0], np.ndarray)): + if not isinstance(x, tuple) or not (isinstance(x[0], np.ndarray)): raise TypeError("First argument not a fancy index: %s" % x) - if not isinstance(y, tuple) or not(isinstance(y[0], np.ndarray)): + if not isinstance(y, tuple) or not (isinstance(y[0], np.ndarray)): raise TypeError("Second argument not a fancy index: %s" % y) dtype = [('%i' % i, 'i') for i in range(len(x))] diff --git a/setup.cfg b/setup.cfg index 5a806d8..36af53e 100644 --- a/setup.cfg +++ b/setup.cfg @@ -14,13 +14,13 @@ github_project = dendrograms/astrodendro [options] zip_safe = False packages = find: -python_requires = >=3.7 +python_requires = >=3.8 setup_requires = setuptools_scm install_requires = - numpy>1.16 - astropy>4 - matplotlib>3 - h5py>3 + numpy>=1.20 + astropy>=5.0 + matplotlib>=3.3 + h5py>=3 [options.extras_require] test = diff --git a/tox.ini b/tox.ini index 3f00022..3298357 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] envlist = - py{37,38,39,310}-test{,-alldeps,-devdeps}{,-cov} + py{38,39,310,311}-test{,-alldeps,-devdeps}{,-cov} build_docs linkcheck codestyle @@ -12,8 +12,7 @@ isolated_build = true [testenv] setenv = MPLBACKEND=agg - devdeps: PIP_EXTRA_INDEX_URL = https://pypi.anaconda.org/astropy/simple https://pypi.anaconda.org/scipy-wheels-nightly/simple -passenv = HOME WINDIR LC_ALL LC_CTYPE CC CI TRAVIS + devdeps: PIP_EXTRA_INDEX_URL = https://pypi.anaconda.org/astropy/simple https://pypi.anaconda.org/scientific-python-nightly-wheels/ changedir = .tmp/{envname} description = run tests @@ -26,10 +25,10 @@ deps = cov: coverage devdeps: numpy>=0.0.dev0 devdeps: astropy>=0.0.dev0 - oldestdeps: astropy==4.0.* + oldestdeps: astropy==5.0.* oldestdeps: h5py==3.0.* - oldestdeps: matplotlib==3.0.* - oldestdeps: numpy==1.16.* + oldestdeps: matplotlib==3.3.* + oldestdeps: numpy==1.20.* extras = test From 3dededde580b55dcf00a3c2e40e54a4833f7891a Mon Sep 17 00:00:00 2001 From: Thomas Robitaille Date: Mon, 7 Aug 2023 10:40:39 +0100 Subject: [PATCH 3/4] Bump Python in RTD config --- .readthedocs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.readthedocs.yml b/.readthedocs.yml index b8353db..f410fc7 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -3,7 +3,7 @@ version: 2 build: os: ubuntu-20.04 tools: - python: '3.7' + python: '3.8' python: install: From 8dac4ad0e3e209a8fc8e8c47efd82186a2f81b17 Mon Sep 17 00:00:00 2001 From: Thomas Robitaille Date: Mon, 7 Aug 2023 10:50:09 +0100 Subject: [PATCH 4/4] Pin Sphinx<7 to fix issue with theme --- setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index 36af53e..4636d14 100644 --- a/setup.cfg +++ b/setup.cfg @@ -27,7 +27,7 @@ test = pytest pytest-cov docs = - sphinx + sphinx<7 numpydoc sphinx-astropy aplpy