From d5df951ca4c35364779a02d2afca0df67d216771 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brigitta=20Sip=C5=91cz?= Date: Thu, 28 Nov 2024 04:44:55 -0800 Subject: [PATCH 01/24] BUG: fix StringIO uploads --- pyvo/dal/query.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyvo/dal/query.py b/pyvo/dal/query.py index 2bb187ad..91dba556 100644 --- a/pyvo/dal/query.py +++ b/pyvo/dal/query.py @@ -27,7 +27,7 @@ import re import requests from collections.abc import Mapping -from io import BytesIO +from io import BytesIO, StringIO import collections @@ -1042,7 +1042,7 @@ def fileobj(self): return fileobj - elif isinstance(self._content, BytesIO): + elif isinstance(self._content, (BytesIO, StringIO)): return self._content elif isinstance(self._content, DALResults): From 09f75bdc205e98dcf83275d5c1bd71d3e74ddfac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Dec 2024 20:35:48 +0000 Subject: [PATCH 02/24] Bump codecov/codecov-action from 4.6.0 to 5.0.7 in the actions group Bumps the actions group with 1 update: [codecov/codecov-action](https://github.com/codecov/codecov-action). Updates `codecov/codecov-action` from 4.6.0 to 5.0.7 - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238...015f24e6818733317a2da2edd6290ab26238649a) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions ... Signed-off-by: dependabot[bot] --- .github/workflows/ci_devtests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci_devtests.yml b/.github/workflows/ci_devtests.yml index 846a1356..ea8a2ccd 100644 --- a/.github/workflows/ci_devtests.yml +++ b/.github/workflows/ci_devtests.yml @@ -32,7 +32,7 @@ jobs: run: tox -e py312-test-devdeps-alldeps-cov - name: Upload coverage to codecov - uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4.6.0 + uses: codecov/codecov-action@015f24e6818733317a2da2edd6290ab26238649a # v5.0.7 with: file: ./coverage.xml verbose: true From 98a1710aa84778a8d24dedd98f1857d5ff39ddd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brigitta=20Sip=C5=91cz?= Date: Tue, 10 Dec 2024 13:34:04 -0800 Subject: [PATCH 03/24] TST: adding remote testing upload test, inherited from astroquery --- pyvo/dal/tests/test_tap.py | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/pyvo/dal/tests/test_tap.py b/pyvo/dal/tests/test_tap.py index 0c22dc84..3e075974 100644 --- a/pyvo/dal/tests/test_tap.py +++ b/pyvo/dal/tests/test_tap.py @@ -6,7 +6,7 @@ from contextlib import ExitStack import datetime import re -from io import BytesIO +from io import BytesIO, StringIO from urllib.parse import parse_qsl import tempfile @@ -802,3 +802,37 @@ def test_get_endpoint_candidates(): "http://astroweb.projects.phys.ucl.ac.uk:8000/capabilities" ] assert svc._get_endpoint_candidates("capabilities") == expected_urls + + +@pytest.mark.remote_data +@pytest.mark.parametrize('stream_type', [BytesIO, StringIO]) +def test_tap_upload_remote(stream_type): + tmp_table = (''' + + + + + external URI for the physical artifact + + + + + + + + +
2013.1.01365.S
+
+
''') + + if stream_type == BytesIO: + tmp_table = tmp_table.encode() + query = ('select top 3 proposal_id from ivoa.ObsCore oc join ' + 'TAP_UPLOAD.proj_codes pc on oc.proposal_id=pc.prop_id') + service = TAPService('https://almascience.nrao.edu/tap') + + res = service.search(query, uploads={'proj_codes': stream_type(tmp_table)}) + assert len(res) == 3 + for row in res: + assert row['proposal_id'] == '2013.1.01365.S' From a9ac8606d8336ed39e7c4859d5eb6f5c472fdbbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brigitta=20Sip=C5=91cz?= Date: Mon, 16 Dec 2024 09:45:26 -0800 Subject: [PATCH 04/24] DOC: using shorter ellipse --- docs/dal/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dal/index.rst b/docs/dal/index.rst index 7d30145f..e1f0c23d 100644 --- a/docs/dal/index.rst +++ b/docs/dal/index.rst @@ -212,7 +212,7 @@ to see the tables available on the Simbad TAP service, say: >>> simbad = vo.dal.TAPService("http://simbad.cds.unistra.fr/simbad/sim-tap") >>> print([tab_name for tab_name in simbad.tables.keys()]) # doctest: +IGNORE_WARNINGS - ['TAP_SCHEMA.schemas', 'TAP_SCHEMA.tables', 'TAP_SCHEMA.columns', 'TAP_SCHEMA.keys', ... 'mesVelocities', 'mesXmm', 'otypedef', 'otypes', 'ref'] + ['TAP_SCHEMA.schemas', 'TAP_SCHEMA.tables', ... 'otypedef', 'otypes', 'ref'] If you know a TAP service's access URL, you can directly pass it to From 86e52deb3b70400512835556c1711f3db9779607 Mon Sep 17 00:00:00 2001 From: ChuanmingMao Date: Mon, 23 Dec 2024 00:50:30 +0100 Subject: [PATCH 05/24] added "detail:min" parameter --- pyvo/dal/tap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyvo/dal/tap.py b/pyvo/dal/tap.py index ad6d2399..3380c46f 100644 --- a/pyvo/dal/tap.py +++ b/pyvo/dal/tap.py @@ -149,7 +149,7 @@ def tables(self): if self._tables is None: tables_url = '{}/tables'.format(self.baseurl) - response = self._session.get(tables_url, stream=True) + response = self._session.get(tables_url, params={"detail":"min"}, stream=True) try: response.raise_for_status() From b126c3a52e89780ac40554429cc11498e5f8c5d0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Jan 2025 20:48:39 +0000 Subject: [PATCH 06/24] Bump codecov/codecov-action from 5.0.7 to 5.1.2 in the actions group Bumps the actions group with 1 update: [codecov/codecov-action](https://github.com/codecov/codecov-action). Updates `codecov/codecov-action` from 5.0.7 to 5.1.2 - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/015f24e6818733317a2da2edd6290ab26238649a...1e68e06f1dbfde0e4cefc87efeba9e4643565303) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-minor dependency-group: actions ... Signed-off-by: dependabot[bot] --- .github/workflows/ci_devtests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci_devtests.yml b/.github/workflows/ci_devtests.yml index ea8a2ccd..4f9afba2 100644 --- a/.github/workflows/ci_devtests.yml +++ b/.github/workflows/ci_devtests.yml @@ -32,7 +32,7 @@ jobs: run: tox -e py312-test-devdeps-alldeps-cov - name: Upload coverage to codecov - uses: codecov/codecov-action@015f24e6818733317a2da2edd6290ab26238649a # v5.0.7 + uses: codecov/codecov-action@1e68e06f1dbfde0e4cefc87efeba9e4643565303 # v5.1.2 with: file: ./coverage.xml verbose: true From f7f9f7e7cd4ec21f9fc06deb293ca41b21322b89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brigitta=20Sip=C5=91cz?= Date: Wed, 8 Jan 2025 23:37:21 -0800 Subject: [PATCH 07/24] MAINT: update URLs for gavo dc results --- docs/dal/index.rst | 11 ++++++----- docs/registry/index.rst | 2 +- pyvo/discover/tests/test_imagediscovery.py | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/dal/index.rst b/docs/dal/index.rst index e1f0c23d..47384808 100644 --- a/docs/dal/index.rst +++ b/docs/dal/index.rst @@ -264,7 +264,7 @@ starting it, it creates a new object :py:class:`~pyvo.dal.AsyncTAPJob`. .. doctest-remote-data:: >>> job.url - 'http://dc.zah.uni-heidelberg.de/__system__/tap/run/async/...' + 'http://dc.g-vo.org/__system__/tap/run/async/0nh4f2pt' The job URL mentioned before is available in the ``url`` attribute. Clicking on the URL leads you to the query itself, where you can check @@ -819,10 +819,11 @@ previews: >>> for dl in rows.iter_datalinks(): # doctest: +IGNORE_WARNINGS ... print(next(dl.bysemantics("#preview"))["access_url"]) http://dc.zah.uni-heidelberg.de/getproduct/califa/datadr3/V1200/IC5376.V1200.rscube.fits?preview=True - http://dc.zah.uni-heidelberg.de/getproduct/califa/datadr3/COMB/IC5376.COMB.rscube.fits?preview=True - http://dc.zah.uni-heidelberg.de/getproduct/califa/datadr3/V500/IC5376.V500.rscube.fits?preview=True - http://dc.zah.uni-heidelberg.de/getproduct/califa/datadr3/COMB/UGC00005.COMB.rscube.fits?preview=True - http://dc.zah.uni-heidelberg.de/getproduct/califa/datadr3/V1200/UGC00005.V1200.rscube.fits?preview=True + http://dc.g-vo.org/getproduct/califa/datadr3/V1200/IC5376.V1200.rscube.fits?preview=True + http://dc.g-vo.org/getproduct/califa/datadr3/COMB/IC5376.COMB.rscube.fits?preview=True + http://dc.g-vo.org/getproduct/califa/datadr3/V500/IC5376.V500.rscube.fits?preview=True + http://dc.g-vo.org/getproduct/califa/datadr3/COMB/UGC00005.COMB.rscube.fits?preview=True + http://dc.g-vo.org/getproduct/califa/datadr3/V1200/UGC00005.V1200.rscube.fits?preview=True The call to ``next`` in this example picks the first link marked *preview*. For previews, this may be enough, but in general there can diff --git a/docs/registry/index.rst b/docs/registry/index.rst index bcc95063..8e50a7f0 100644 --- a/docs/registry/index.rst +++ b/docs/registry/index.rst @@ -600,7 +600,7 @@ RegTAP services using: >>> res = registry.search(datamodel="regtap") >>> print("\n".join(sorted(r.get_interface(service_type="tap", lax=True).access_url ... for r in res))) - http://dc.zah.uni-heidelberg.de/tap + http://dc.g-vo.org/tap http://gavo.aip.de/tap http://voparis-rr.obspm.fr/tap https://vao.stsci.edu/RegTAP/TapService.aspx diff --git a/pyvo/discover/tests/test_imagediscovery.py b/pyvo/discover/tests/test_imagediscovery.py index 4b57f697..ef8de94c 100644 --- a/pyvo/discover/tests/test_imagediscovery.py +++ b/pyvo/discover/tests/test_imagediscovery.py @@ -201,7 +201,7 @@ def test_single_sia1(): assert abs(im.s_dec+29) < 2 assert im.instrument_name == 'Robotic Bochum Twin Telescope (RoBoTT)' assert "BGDS GDS_" in im.obs_title - assert "dc.zah.uni-heidelberg.de/getproduct/bgds/data" in im.access_url + assert "dc.g-vo.org/getproduct/bgds/data" in im.access_url @pytest.mark.remote_data From 55bfc16d5456d3b9582ad0787a39084fdc758e48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brigitta=20Sip=C5=91cz?= Date: Wed, 8 Jan 2025 23:13:03 -0800 Subject: [PATCH 08/24] MAINT: ignoring IERS warnings for now to pass tests on old python where there are no more updates --- setup.cfg | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/setup.cfg b/setup.cfg index a31efda2..f51901a8 100644 --- a/setup.cfg +++ b/setup.cfg @@ -17,6 +17,10 @@ filterwarnings = # Numpy 2.0 deprecations triggered by upstream libraries. # Exact warning messages differ, thus using a super generic filter. ignore:numpy.core:DeprecationWarning +# Added for python 3.8, cleanup once old python version support is removed +# (adding it to conftest is ineffective as the PrototypeWarning line above already +# triggers this warning at the time of collection + ignore::astropy.utils.iers.iers.IERSStaleWarning # We need to ignore this module level warning to not cause issues at collection time. # Remove it once warning is removed from code (in 1.7). ignore:pyvo.discover:pyvo.utils.prototype.PrototypeWarning From 651e46499c72b0cc4f31bdc8f339ce1cfd6e955a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brigitta=20Sip=C5=91cz?= Date: Thu, 9 Jan 2025 09:22:19 -0800 Subject: [PATCH 09/24] MAINT: ignoring ErfaWarnings for now, too --- setup.cfg | 3 +++ 1 file changed, 3 insertions(+) diff --git a/setup.cfg b/setup.cfg index f51901a8..492a65ab 100644 --- a/setup.cfg +++ b/setup.cfg @@ -21,6 +21,9 @@ filterwarnings = # (adding it to conftest is ineffective as the PrototypeWarning line above already # triggers this warning at the time of collection ignore::astropy.utils.iers.iers.IERSStaleWarning +# These two are also needed for python 3.8 + ignore:Importing ErfaWarning:astropy.utils.exceptions.AstropyDeprecationWarning + ignore::astropy.utils.exceptions.ErfaWarning # We need to ignore this module level warning to not cause issues at collection time. # Remove it once warning is removed from code (in 1.7). ignore:pyvo.discover:pyvo.utils.prototype.PrototypeWarning From 890b9905f564787c7493b04f04f9a92dd3664210 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brigitta=20Sip=C5=91cz?= Date: Thu, 9 Jan 2025 14:11:48 -0800 Subject: [PATCH 10/24] DOC: some more g-vo fix that was missed earlier --- docs/dal/index.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/dal/index.rst b/docs/dal/index.rst index 47384808..832b39e3 100644 --- a/docs/dal/index.rst +++ b/docs/dal/index.rst @@ -264,7 +264,7 @@ starting it, it creates a new object :py:class:`~pyvo.dal.AsyncTAPJob`. .. doctest-remote-data:: >>> job.url - 'http://dc.g-vo.org/__system__/tap/run/async/0nh4f2pt' + 'http://dc.g-vo.org/__system__/tap/run/async/...' The job URL mentioned before is available in the ``url`` attribute. Clicking on the URL leads you to the query itself, where you can check @@ -818,7 +818,6 @@ previews: ... ).run_sync("select top 5 * from califadr3.cubes order by califaid") >>> for dl in rows.iter_datalinks(): # doctest: +IGNORE_WARNINGS ... print(next(dl.bysemantics("#preview"))["access_url"]) - http://dc.zah.uni-heidelberg.de/getproduct/califa/datadr3/V1200/IC5376.V1200.rscube.fits?preview=True http://dc.g-vo.org/getproduct/califa/datadr3/V1200/IC5376.V1200.rscube.fits?preview=True http://dc.g-vo.org/getproduct/califa/datadr3/COMB/IC5376.COMB.rscube.fits?preview=True http://dc.g-vo.org/getproduct/califa/datadr3/V500/IC5376.V500.rscube.fits?preview=True From b039b1dd10c29b1628adf20e4cbd6cb552805cdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brigitta=20Sip=C5=91cz?= Date: Fri, 3 Jan 2025 15:22:04 -0800 Subject: [PATCH 11/24] MAINT: moving the str input validation out to avoid astropy deprecation --- pyvo/dal/params.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pyvo/dal/params.py b/pyvo/dal/params.py index 89c1b1e9..fce246dc 100644 --- a/pyvo/dal/params.py +++ b/pyvo/dal/params.py @@ -367,12 +367,16 @@ def _validate_pos(self, pos): self._validate_ra(m) def _validate_ra(self, ra): + if isinstance(ra, str): + ra = Unit(ra) if not isinstance(ra, Quantity): ra = ra * u.deg if ra.to(u.deg).value < 0 or ra.to(u.deg).value > 360.0: raise ValueError('Invalid ra: {}'.format(ra)) def _validate_dec(self, dec): + if isinstance(dec, str): + dec = Unit(dec) if not isinstance(dec, Quantity): dec = dec * u.deg if dec.to(u.deg).value < -90.0 or dec.to(u.deg).value > 90.0: @@ -414,9 +418,13 @@ def get_dal_format(self, val): raise ValueError('Invalid interval: min({}) > max({})'.format( low, high)) if self._unit: + if isinstance(low, str): + low = Unit(low) if not isinstance(low, Quantity): low = low * self._unit low = low.to(self._unit, equivalencies=self._equivalencies).value + if isinstance(high, str): + high = Unit(high) if not isinstance(high, Quantity): high = high * self._unit high = high.to(self._unit, equivalencies=self._equivalencies).value From 3075ab6d22de2fabe2d7522df5a4a330a7656f44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brigitta=20Sip=C5=91cz?= Date: Thu, 9 Jan 2025 21:29:43 -0800 Subject: [PATCH 12/24] MAINT: refactor to use more Quantities based on PR review --- pyvo/dal/params.py | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/pyvo/dal/params.py b/pyvo/dal/params.py index fce246dc..b6ebbca2 100644 --- a/pyvo/dal/params.py +++ b/pyvo/dal/params.py @@ -367,18 +367,12 @@ def _validate_pos(self, pos): self._validate_ra(m) def _validate_ra(self, ra): - if isinstance(ra, str): - ra = Unit(ra) - if not isinstance(ra, Quantity): - ra = ra * u.deg + ra = Quantity(ra, u.deg) if ra.to(u.deg).value < 0 or ra.to(u.deg).value > 360.0: raise ValueError('Invalid ra: {}'.format(ra)) def _validate_dec(self, dec): - if isinstance(dec, str): - dec = Unit(dec) - if not isinstance(dec, Quantity): - dec = dec * u.deg + dec = Quantity(dec, u.deg) if dec.to(u.deg).value < -90.0 or dec.to(u.deg).value > 90.0: raise ValueError('Invalid dec: {}'.format(dec)) @@ -418,15 +412,12 @@ def get_dal_format(self, val): raise ValueError('Invalid interval: min({}) > max({})'.format( low, high)) if self._unit: - if isinstance(low, str): - low = Unit(low) if not isinstance(low, Quantity): - low = low * self._unit + low = u.Quantity(low, self._unit) low = low.to(self._unit, equivalencies=self._equivalencies).value - if isinstance(high, str): - high = Unit(high) + if not isinstance(high, Quantity): - high = high * self._unit + high = Quantity(high, self._unit) high = high.to(self._unit, equivalencies=self._equivalencies).value if low > high: From 06d36a726f1fecd7713f186eb8f8ea161cecff59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brigitta=20Sip=C5=91cz?= Date: Thu, 9 Jan 2025 21:33:22 -0800 Subject: [PATCH 13/24] MAINT: dropping python 3.8 support --- .github/workflows/ci_tests.yml | 20 ++++++++++---------- setup.cfg | 9 +-------- tox.ini | 2 +- 3 files changed, 12 insertions(+), 19 deletions(-) diff --git a/.github/workflows/ci_tests.yml b/.github/workflows/ci_tests.yml index 79f786e3..77180b52 100644 --- a/.github/workflows/ci_tests.yml +++ b/.github/workflows/ci_tests.yml @@ -24,12 +24,12 @@ jobs: fail-fast: false matrix: include: - - name: py38 oldest dependencies, Linux - python-version: '3.8' - tox_env: py38-test-oldestdeps-alldeps - - name: py39 mandatory dependencies only, Linux + - name: py39 oldest dependencies, Linux python-version: '3.9' - tox_env: py39-test + tox_env: py39-test-oldestdeps-alldeps + - name: py310 mandatory dependencies only, Linux + python-version: '3.10' + tox_env: py310-test - name: py311 with online tests, Linux python-version: '3.11' tox_env: py311-test-alldeps-online @@ -63,11 +63,11 @@ jobs: - name: Set up Python uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 with: - python-version: '3.10' + python-version: '3.12' - name: Install tox run: python -m pip install --upgrade tox - - name: Python 3.10 with latest astropy - run: tox -e py310-test-alldeps + - name: Python 3.12 with latest astropy + run: tox -e py312-test-alldeps stylecheck: @@ -76,10 +76,10 @@ jobs: fail-fast: false steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - name: Set up Python 3.8 + - name: Set up Python 3.12 uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 with: - python-version: 3.8 + python-version: '3.12' - name: Install tox run: python -m pip install --upgrade tox - name: Check codestyle diff --git a/setup.cfg b/setup.cfg index 492a65ab..c373d014 100644 --- a/setup.cfg +++ b/setup.cfg @@ -17,13 +17,6 @@ filterwarnings = # Numpy 2.0 deprecations triggered by upstream libraries. # Exact warning messages differ, thus using a super generic filter. ignore:numpy.core:DeprecationWarning -# Added for python 3.8, cleanup once old python version support is removed -# (adding it to conftest is ineffective as the PrototypeWarning line above already -# triggers this warning at the time of collection - ignore::astropy.utils.iers.iers.IERSStaleWarning -# These two are also needed for python 3.8 - ignore:Importing ErfaWarning:astropy.utils.exceptions.AstropyDeprecationWarning - ignore::astropy.utils.exceptions.ErfaWarning # We need to ignore this module level warning to not cause issues at collection time. # Remove it once warning is removed from code (in 1.7). ignore:pyvo.discover:pyvo.utils.prototype.PrototypeWarning @@ -74,7 +67,7 @@ setup_requires = setuptools_scm install_requires = astropy>=4.1 requests -python_requires = >=3.8 +python_requires = >=3.9 [options.extras_require] all = diff --git a/tox.ini b/tox.ini index 52963bd4..a072f18e 100644 --- a/tox.ini +++ b/tox.ini @@ -3,7 +3,7 @@ # as oldestdeps and devastropy might not support the full python range # listed here envlist = - py{38,39,310,311,312,313}-test{,-alldeps,-oldestdeps,-devdeps}{,-online}{,-cov} + py{39,310,311,312,313}-test{,-alldeps,-oldestdeps,-devdeps}{,-online}{,-cov} linkcheck codestyle build_docs From be9c0b94720e470e3941bd873bf005f2d02023b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brigitta=20Sip=C5=91cz?= Date: Thu, 9 Jan 2025 21:40:42 -0800 Subject: [PATCH 14/24] MAINT: running pyupgrade after dropping py38 support --- pyvo/auth/authsession.py | 2 +- pyvo/auth/authurls.py | 5 ++- pyvo/auth/credentialstore.py | 2 +- pyvo/dal/adhoc.py | 6 ++-- pyvo/dal/exceptions.py | 6 ++-- pyvo/dal/mimetype.py | 2 +- pyvo/dal/params.py | 14 ++++---- pyvo/dal/query.py | 12 +++---- pyvo/dal/sia2.py | 2 +- pyvo/dal/tap.py | 28 ++++++++-------- pyvo/dal/tests/test_tap.py | 6 ++-- pyvo/dal/vosi.py | 4 +-- pyvo/discover/image.py | 39 +++++++++++----------- pyvo/discover/tests/test_imagediscovery.py | 4 +-- pyvo/io/uws/tree.py | 2 +- pyvo/io/vosi/endpoint.py | 2 +- pyvo/io/vosi/exceptions.py | 5 ++- pyvo/io/vosi/tapregext.py | 18 +++++----- pyvo/io/vosi/vodataservice.py | 2 +- pyvo/io/vosi/voresource.py | 4 +-- pyvo/mivot/features/sky_coord_builder.py | 2 +- pyvo/mivot/utils/dict_utils.py | 6 ++-- pyvo/mivot/utils/json_encoder.py | 2 +- pyvo/mivot/utils/mivot_utils.py | 2 +- pyvo/mivot/viewer/mivot_instance.py | 4 +-- pyvo/registry/regtap.py | 16 ++++----- pyvo/registry/rtcons.py | 24 ++++++------- pyvo/utils/prototype.py | 5 +-- pyvo/utils/vocabularies.py | 4 +-- pyvo/utils/xml/exceptions.py | 2 +- 30 files changed, 116 insertions(+), 116 deletions(-) diff --git a/pyvo/auth/authsession.py b/pyvo/auth/authsession.py index b60d6ebe..76e2ff9b 100644 --- a/pyvo/auth/authsession.py +++ b/pyvo/auth/authsession.py @@ -22,7 +22,7 @@ class AuthSession: """ def __init__(self): - super(AuthSession, self).__init__() + super().__init__() self.credentials = CredentialStore() self._auth_urls = AuthURLs() diff --git a/pyvo/auth/authurls.py b/pyvo/auth/authurls.py index 0a658eb9..f5b48b91 100644 --- a/pyvo/auth/authurls.py +++ b/pyvo/auth/authurls.py @@ -100,10 +100,9 @@ def sort_by_len(x): # the longest URLs (the most specific ones, if # there is a tie) are used to determine the # auth method. - for url, method in sorted(self.base_urls.items(), + yield from sorted(self.base_urls.items(), key=sort_by_len, - reverse=True): - yield url, method + reverse=True) def __repr__(self): urls = [] diff --git a/pyvo/auth/credentialstore.py b/pyvo/auth/credentialstore.py index 20dbbdde..fad8d999 100644 --- a/pyvo/auth/credentialstore.py +++ b/pyvo/auth/credentialstore.py @@ -7,7 +7,7 @@ __all__ = ["CredentialStore"] -class CredentialStore(object): +class CredentialStore: """ The credential store takes user credentials, and uses them to create appropriate requests sessions for dispatching diff --git a/pyvo/dal/adhoc.py b/pyvo/dal/adhoc.py index 78c55cd9..d7572039 100644 --- a/pyvo/dal/adhoc.py +++ b/pyvo/dal/adhoc.py @@ -142,7 +142,7 @@ def get_adhocservice_by_ivoid(self, ivo_id): ): return adhocservice raise DALServiceError( - "No Adhoc Service with ivo-id {}!".format(ivo_id)) + f"No Adhoc Service with ivo-id {ivo_id}!") def get_adhocservice_by_id(self, id_): """ @@ -162,7 +162,7 @@ def get_adhocservice_by_id(self, id_): if adhocservice.ID == id_: return adhocservice raise DALServiceError( - "No Adhoc Service with service_def id {}!".format(id_)) + f"No Adhoc Service with service_def id {id_}!") class DatalinkResultsMixin(AdhocServiceResultsMixin): @@ -683,7 +683,7 @@ def bysemantics(self, semantics, *, include_narrower=True): additional_terms.extend(voc["terms"][term]["narrower"]) core_terms = core_terms + additional_terms - semantics = set("#" + term for term in core_terms) | set(other_terms) + semantics = {"#" + term for term in core_terms} | set(other_terms) for record in self: if record.semantics in semantics: yield record diff --git a/pyvo/dal/exceptions.py b/pyvo/dal/exceptions.py index b86fee74..01eb521c 100644 --- a/pyvo/dal/exceptions.py +++ b/pyvo/dal/exceptions.py @@ -50,7 +50,7 @@ def __str__(self): return self._reason def __repr__(self): - return "{}: {}".format(self._typeName(self), self._reason) + return f"{self._typeName(self)}: {self._reason}" @property def reason(self): @@ -188,13 +188,13 @@ def from_except(cls, exc, url=None): code = response.status_code content_type = response.headers.get('content-type', None) if content_type and 'text/plain' in content_type: - message = '{} for {}'.format(response.text, url) + message = f'{response.text} for {url}' # TODO votable handling return DALServiceError(message, code, exc, url) elif isinstance(exc, Exception): - return DALServiceError("{}: {}".format(cls._typeName(exc), str(exc)), + return DALServiceError(f"{cls._typeName(exc)}: {str(exc)}", cause=exc, url=url) else: raise TypeError("from_except: expected Exception") diff --git a/pyvo/dal/mimetype.py b/pyvo/dal/mimetype.py index 036231e0..2e18cd1d 100644 --- a/pyvo/dal/mimetype.py +++ b/pyvo/dal/mimetype.py @@ -88,7 +88,7 @@ def mime_object_maker(url, mimetype, *, session=None): params = pp[1:] mtype = [x.strip() for x in full_type.split('/')] if '/' in full_type else None if not mtype or len(mtype) > 2: - raise ValueError("Can't parse mimetype \"{}\"".format(full_type)) + raise ValueError(f"Can't parse mimetype \"{full_type}\"") if mtype[0] == 'text': return session.get(url).text diff --git a/pyvo/dal/params.py b/pyvo/dal/params.py index 89c1b1e9..15f0f3a9 100644 --- a/pyvo/dal/params.py +++ b/pyvo/dal/params.py @@ -32,7 +32,7 @@ def find_param_by_keyword(keyword, params): if keyword in params: return params[keyword] - raise KeyError('No param named {} defined'.format(keyword)) + raise KeyError(f'No param named {keyword} defined') registry = dict() @@ -332,7 +332,7 @@ def _validate_pos(self, pos): else: radius = pos[1] if radius <= 0 * u.deg or radius.to(u.deg) > 90 * u.deg: - raise ValueError('Invalid circle radius: {}'.format(radius)) + raise ValueError(f'Invalid circle radius: {radius}') elif len(pos) == 3: self._validate_ra(pos[0]) self._validate_dec(pos[1]) @@ -341,7 +341,7 @@ def _validate_pos(self, pos): else: radius = pos[2] if radius <= 0 * u.deg or radius.to(u.deg) > 90 * u.deg: - raise ValueError('Invalid circle radius: {}'.format(radius)) + raise ValueError(f'Invalid circle radius: {radius}') elif len(pos) == 4: ra_min = pos[0] if isinstance(pos[0], Quantity) else pos[0] * u.deg ra_max = pos[1] if isinstance(pos[1], Quantity) else pos[1] * u.deg @@ -370,13 +370,13 @@ def _validate_ra(self, ra): if not isinstance(ra, Quantity): ra = ra * u.deg if ra.to(u.deg).value < 0 or ra.to(u.deg).value > 360.0: - raise ValueError('Invalid ra: {}'.format(ra)) + raise ValueError(f'Invalid ra: {ra}') def _validate_dec(self, dec): if not isinstance(dec, Quantity): dec = dec * u.deg if dec.to(u.deg).value < -90.0 or dec.to(u.deg).value > 90.0: - raise ValueError('Invalid dec: {}'.format(dec)) + raise ValueError(f'Invalid dec: {dec}') class IntervalQueryParam(AbstractDalQueryParam): @@ -425,7 +425,7 @@ def get_dal_format(self, val): # interval could become invalid during transform (e.g. GHz->m) low, high = high, low - return '{} {}'.format(low, high) + return f'{low} {high}' class TimeQueryParam(AbstractDalQueryParam): @@ -454,7 +454,7 @@ def get_dal_format(self, val): raise ValueError('Invalid time interval: min({}) > max({})'.format( min_time, max_time )) - return '{} {}'.format(min_time.mjd, max_time.mjd) + return f'{min_time.mjd} {max_time.mjd}' class EnumQueryParam(AbstractDalQueryParam): diff --git a/pyvo/dal/query.py b/pyvo/dal/query.py index 91dba556..b56e9caf 100644 --- a/pyvo/dal/query.py +++ b/pyvo/dal/query.py @@ -129,7 +129,7 @@ def describe(self): """ describe the general information about the DAL service """ - print('DAL Service at {}'.format(self.baseurl)) + print(f'DAL Service at {self.baseurl}') class DALQuery(dict): @@ -551,7 +551,7 @@ def getcolumn(self, name): return self.resultstable.array[name] except KeyError: - raise KeyError("No such column: {}".format(name)) + raise KeyError(f"No such column: {name}") def getrecord(self, index): """ @@ -686,7 +686,7 @@ def __getitem__(self, key): return self._mapping[key] except KeyError: - raise KeyError("No such column: {}".format(key)) + raise KeyError(f"No such column: {key}") def __iter__(self): return iter(self._mapping) @@ -889,7 +889,7 @@ def make_dataset_filename(self, *, dir=".", base=None, ext=None): if not os.path.exists(dir): os.mkdir(dir) if not os.path.isdir(dir): - raise ValueError("{}: not a directory".format(dir)) + raise ValueError(f"{dir}: not a directory") if not base: base = self.suggest_dataset_basename() @@ -904,7 +904,7 @@ def make_dataset_filename(self, *, dir=".", base=None, ext=None): n = self._dsname_no def mkpath(i): - return os.path.join(dir, "{}-{}.{}".format(base, i, ext)) + return os.path.join(dir, f"{base}-{i}.{ext}") if n > 0: # find the last file written of the form, base-n.ext @@ -914,7 +914,7 @@ def mkpath(i): n += 1 if n == 0: # never wrote a file of form, base-n.ext; try base.ext - path = os.path.join(dir, "{}.{}".format(base, ext)) + path = os.path.join(dir, f"{base}.{ext}") if not os.path.exists(path): return path n += 1 diff --git a/pyvo/dal/sia2.py b/pyvo/dal/sia2.py index d9fd0873..fab3391e 100644 --- a/pyvo/dal/sia2.py +++ b/pyvo/dal/sia2.py @@ -339,7 +339,7 @@ def __init__(self, url, pos=None, *, band=None, time=None, pol=None, custom_arg = [] for kw in _tolist(value): if isinstance(kw, tuple): - val = '{} {}'.format(kw[0], kw[1]) + val = f'{kw[0]} {kw[1]}' else: val = str(kw) custom_arg.append(val) diff --git a/pyvo/dal/tap.py b/pyvo/dal/tap.py index ad6d2399..99defe8c 100644 --- a/pyvo/dal/tap.py +++ b/pyvo/dal/tap.py @@ -147,7 +147,7 @@ def tables(self): returns tables as a dict-like object """ if self._tables is None: - tables_url = '{}/tables'.format(self.baseurl) + tables_url = f'{self.baseurl}/tables' response = self._session.get(tables_url, stream=True) @@ -201,7 +201,7 @@ def examples(self): returns examples as a list of TAPQuery objects """ if self._examples is None: - examples_url = '{}/examples'.format(self.baseurl) + examples_url = f'{self.baseurl}/examples' self._examples = self._parse_examples(examples_url) return self._examples @@ -443,7 +443,7 @@ def get_job_list(self, *, phases=None, after=None, last=None, after = _from_ivoa_format(after) params['AFTER'] = after.strftime(IVOA_DATETIME_FORMAT) - response = self._session.get('{}/async'.format(self.baseurl), + response = self._session.get(f'{self.baseurl}/async', params=params, stream=True) response.raw.read = partial(response.raw.read, decode_content=True) @@ -508,7 +508,7 @@ def create_table(self, name, definition, *, format='VOSITable'): format(format, ' '.join(TABLE_DEF_FORMAT.keys()))) headers = {'Content-Type': TABLE_DEF_FORMAT[format]} - response = self._session.put('{}/tables/{}'.format(self.baseurl, name), + response = self._session.put(f'{self.baseurl}/tables/{name}', headers=headers, data=definition) response.raise_for_status() @@ -530,7 +530,7 @@ def remove_table(self, name): format(name)) response = self._session.delete( - '{}/tables/{}'.format(self.baseurl, name)) + f'{self.baseurl}/tables/{name}') response.raise_for_status() @prototype_feature('cadc-tb-upload') @@ -559,7 +559,7 @@ def load_table(self, name, source, *, format='tsv'): headers = {'Content-Type': TABLE_UPLOAD_FORMAT[format]} response = self._session.post( - '{}/load/{}'.format(self.baseurl, name), + f'{self.baseurl}/load/{name}', headers=headers, data=source) response.raise_for_status() @@ -583,7 +583,7 @@ def create_index(self, table_name, column_name, *, unique=False): 'table and column names are required in index: {}/{}'. format(table_name, column_name)) - result = self._session.post('{}/table-update'.format(self.baseurl), + result = self._session.post(f'{self.baseurl}/table-update', data={'table': table_name, 'index': column_name, 'unique': 'true' if unique @@ -736,7 +736,7 @@ def execution_duration(self): def execution_duration(self, value): try: response = self._session.post( - "{}/executionduration".format(self.url), + f"{self.url}/executionduration", data={"EXECUTIONDURATION": str(value)}) response.raise_for_status() except requests.RequestException as ex: @@ -769,7 +769,7 @@ def destruction(self, value): try: response = self._session.post( - "{}/destruction".format(self.url), + f"{self.url}/destruction", data={"DESTRUCTION": value.strftime(IVOA_DATETIME_FORMAT)}) response.raise_for_status() except requests.RequestException as ex: @@ -808,7 +808,7 @@ def query(self): def query(self, query): try: response = self._session.post( - '{}/parameters'.format(self.url), + f'{self.url}/parameters', data={"QUERY": query}) response.raise_for_status() except requests.RequestException as ex: @@ -829,7 +829,7 @@ def upload(self, **kwargs): try: response = self._session.post( - '{}/parameters'.format(self.url), + f'{self.url}/parameters', data={'UPLOAD': uploads.param()}, files=files ) @@ -900,7 +900,7 @@ def run(self): """ try: response = self._session.post( - '{}/phase'.format(self.url), data={"PHASE": "RUN"}) + f'{self.url}/phase', data={"PHASE": "RUN"}) response.raise_for_status() except requests.RequestException as ex: raise DALServiceError.from_except(ex, self.url) @@ -913,7 +913,7 @@ def abort(self): """ try: response = self._session.post( - '{}/phase'.format(self.url), data={"PHASE": "ABORT"}) + f'{self.url}/phase', data={"PHASE": "ABORT"}) response.raise_for_status() except requests.RequestException as ex: raise DALServiceError.from_except(ex, self.url) @@ -1079,7 +1079,7 @@ def queryurl(self): queries. """ - return '{baseurl}/{mode}'.format(baseurl=self.baseurl, mode=self._mode) + return f'{self.baseurl}/{self._mode}' def execute_stream(self, *, post=False): """ diff --git a/pyvo/dal/tests/test_tap.py b/pyvo/dal/tests/test_tap.py index 3e075974..2e69b7bb 100644 --- a/pyvo/dal/tests/test_tap.py +++ b/pyvo/dal/tests/test_tap.py @@ -198,7 +198,7 @@ def create(self, request, context): context.status_code = 303 context.reason = 'See other' context.headers['Location'] = ( - 'http://example.com/tap/async/{}'.format(newid)) + f'http://example.com/tap/async/{newid}') self._jobs[newid] = job @@ -279,7 +279,7 @@ def parameters(self, request, context): uploads1.update(uploads2) param.content = ';'.join([ - '{}={}'.format(key, value) for key, value + f'{key}={value}' for key, value in uploads1.items() ]) @@ -767,7 +767,7 @@ def test_missing_featurelist(self, tapservice): def test_get_featurelist(self, tapservice): features = tapservice.get_tap_capability().get_adql().get_feature_list( "ivo://ivoa.net/std/TAPRegExt#features-adqlgeo") - assert set(f.form for f in features) == { + assert {f.form for f in features} == { 'CENTROID', 'CONTAINS', 'COORD1', 'POLYGON', 'INTERSECTS', 'COORD2', 'BOX', 'AREA', 'DISTANCE', 'REGION', 'CIRCLE', 'POINT'} diff --git a/pyvo/dal/vosi.py b/pyvo/dal/vosi.py index 6b7805f4..c5367f0c 100644 --- a/pyvo/dal/vosi.py +++ b/pyvo/dal/vosi.py @@ -113,7 +113,7 @@ def _tables(self): tables_urls = (_.value for _ in accessurls) except StopIteration: tables_urls = [ - '{}/tables'.format(self.baseurl), + f'{self.baseurl}/tables', url_sibling(self.baseurl, 'tables') ] @@ -167,7 +167,7 @@ def _get_table(self, name): table = self._vosi_tables.get_table_by_name(name) if not table.columns and not table.foreignkeys: - tables_url = '{}/{}'.format(self._endpoint_url, name) + tables_url = f'{self._endpoint_url}/{name}' response = self._get_table_file(tables_url) try: diff --git a/pyvo/discover/image.py b/pyvo/discover/image.py index 820dae3b..79363c9a 100644 --- a/pyvo/discover/image.py +++ b/pyvo/discover/image.py @@ -36,7 +36,8 @@ # imports for type hints -from typing import Callable, Generator, List, Optional, Set, Tuple +from typing import Callable, List, Optional, Set, Tuple +from collections.abc import Generator from astropy.units import quantity __all__ = ["ImageFound", "ImageDiscoverer", "images_globally"] @@ -78,7 +79,7 @@ def __repr__(self): return str(self) -@functools.lru_cache(maxsize=None) +@functools.cache def obscore_column_names(): """returns the names of obscore columns. @@ -152,7 +153,7 @@ def from_sia1_recs(cls, origin_service, sia1_result, filter_func): yield cls(origin_service, mapped) -def _clean_for(records: List[Queriable], ivoids_to_remove: Set[str]): +def _clean_for(records: list[Queriable], ivoids_to_remove: set[str]): """returns the Queriables in records the ivoids of which are not in ivoids_to_remove. """ @@ -210,10 +211,10 @@ def __init__(self, *, self.inclusive = inclusive self.already_queried, self.failed_services = 0, 0 - self.results: List[obscore.ObsCoreMetadata] = [] + self.results: list[obscore.ObsCoreMetadata] = [] self.watcher = watcher - self.log_messages: List[str] = [] - self.known_access_urls: Set[str] = set() + self.log_messages: list[str] = [] + self.known_access_urls: set[str] = set() self._service_list_lock = threading.Lock() with self._service_list_lock: @@ -239,7 +240,7 @@ def _purge_redundant_services(self): services from our current services lists. """ def ids(recs): - return set(r.ivoid for r in recs) + return {r.ivoid for r in recs} self.sia1_recs = _clean_for(self.sia1_recs, ids(self.sia2_recs) | ids(self.obscore_recs)) @@ -272,7 +273,7 @@ def ids(recs): self._log(f"Skipping {rec['ivoid']} because" f" it is served by {rec['related_id']}") - collections_to_remove = set(r["ivoid"] for r in services_for) + collections_to_remove = {r["ivoid"] for r in services_for} self.sia1_recs = _clean_for(self.sia1_recs, collections_to_remove) self.sia2_recs = _clean_for(self.sia2_recs, collections_to_remove) self.obscore_recs = _clean_for(self.obscore_recs, collections_to_remove) @@ -295,12 +296,12 @@ def _discover_obscore_services(self, *constraints): new_style_access_urls = set() for rec in obscore_services: - new_style_access_urls |= set( - i.access_url for i in rec.list_interfaces("tap")) + new_style_access_urls |= { + i.access_url for i in rec.list_interfaces("tap")} for tap_rec in tap_services_with_obscore: - access_urls = set( - i.baseurl for i in rec.list_services("tap")) + access_urls = { + i.baseurl for i in rec.list_services("tap")} if new_style_access_urls.isdisjoint(access_urls): obscore_services.append(obscore_services) @@ -334,11 +335,11 @@ def discover_services(self): with self._service_list_lock: self.sia1_recs = [Queriable(r) for r in registry.search( registry.Servicetype("sia"), *constraints)] - self._info("Found {} SIA1 service(s)".format(len(self.sia1_recs))) + self._info(f"Found {len(self.sia1_recs)} SIA1 service(s)") self.sia2_recs = [Queriable(r) for r in registry.search( registry.Servicetype("sia2"), *constraints)] - self._info("Found {} SIA2 service(s)".format(len(self.sia2_recs))) + self._info(f"Found {len(self.sia2_recs)} SIA2 service(s)") self.obscore_recs = self._discover_obscore_services(*constraints) self._info("Found {} Obscore service(s)".format( @@ -436,7 +437,7 @@ def non_spatial_filter(sia1_rec): return False return True - self._info("Querying SIA1 {}...".format(rec.title)) + self._info(f"Querying SIA1 {rec.title}...") svc = rec.res_rec.get_service("sia", session=self.session, lax=True) n_found = self._add_records( ImageFound.from_sia1_recs( @@ -471,7 +472,7 @@ def _query_sia1(self): def _query_one_sia2(self, rec: Queriable): """runs our query against a SIA2 capability of rec. """ - self._info("Querying SIA2 {}...".format(rec.title)) + self._info(f"Querying SIA2 {rec.title}...") svc = rec.res_rec.get_service("sia2", session=self.session, lax=True) constraints = {} @@ -505,7 +506,7 @@ def _query_sia2(self): def _query_one_obscore(self, rec: Queriable, where_clause: str): """runs our query against a Obscore capability of rec. """ - self._info("Querying Obscore {}...".format(rec.title)) + self._info(f"Querying Obscore {rec.title}...") svc = rec.res_rec.get_service("tap", session=self.session, lax=True) n_found = self._add_records( @@ -575,14 +576,14 @@ def query_services(self): def images_globally( *, - space: Optional[Tuple[float, float, float]] = None, + space: Optional[tuple[float, float, float]] = None, spectrum: Optional[quantity.Quantity] = None, time: Optional[time.Time] = None, inclusive: bool = False, watcher: Optional[Callable[['ImageDiscoverer', str], None]] = None, timeout: float = 20, services: Optional[registry.RegistryResults] = None)\ - -> Tuple[List[obscore.ObsCoreMetadata], List[str]]: + -> tuple[list[obscore.ObsCoreMetadata], list[str]]: """returns a collection of ObsCoreMetadata-s matching certain constraints and a list of log lines. diff --git a/pyvo/discover/tests/test_imagediscovery.py b/pyvo/discover/tests/test_imagediscovery.py index ef8de94c..cffff081 100644 --- a/pyvo/discover/tests/test_imagediscovery.py +++ b/pyvo/discover/tests/test_imagediscovery.py @@ -105,7 +105,7 @@ def test_sia2(self): time.Time("1970-10-13T17:00:00"))) d._query_one_sia2(queriable) - assert set(queriable.search_kwargs) == set(["time"]) + assert set(queriable.search_kwargs) == {"time"} assert abs(queriable.search_kwargs["time"][0].utc.value - 40872.54166667) < 1e-8 @@ -115,7 +115,7 @@ def test_sia2_nointerval(self): time=time.Time("1970-10-13T13:00:00")) d._query_one_sia2(queriable) - assert set(queriable.search_kwargs) == set(["time"]) + assert set(queriable.search_kwargs) == {"time"} assert abs(queriable.search_kwargs["time"][0].utc.value - 40872.54166667) < 1e-8 assert abs(queriable.search_kwargs["time"][1].utc.value diff --git a/pyvo/io/uws/tree.py b/pyvo/io/uws/tree.py index 15ee75cb..3b64ece2 100644 --- a/pyvo/io/uws/tree.py +++ b/pyvo/io/uws/tree.py @@ -27,7 +27,7 @@ def XSInDate(val): except ValueError: pass - raise ValueError('Cannot parse datetime {}'.format(val)) + raise ValueError(f'Cannot parse datetime {val}') InDuration = partial(TimeDelta, format='sec') diff --git a/pyvo/io/vosi/endpoint.py b/pyvo/io/vosi/endpoint.py index 59c064cb..00095b0a 100644 --- a/pyvo/io/vosi/endpoint.py +++ b/pyvo/io/vosi/endpoint.py @@ -311,7 +311,7 @@ def get_table_by_name(self, name): for table in self.iter_tables(): if table.name == name: return table - raise KeyError("No table with name {} found".format(name)) + raise KeyError(f"No table with name {name} found") class CapabilitiesFile(Element, HomogeneousList): diff --git a/pyvo/io/vosi/exceptions.py b/pyvo/io/vosi/exceptions.py index 5da39bc0..1cab8937 100644 --- a/pyvo/io/vosi/exceptions.py +++ b/pyvo/io/vosi/exceptions.py @@ -1,5 +1,4 @@ # Licensed under a 3-clause BSD style license - see LICENSE.rst -# -*- coding: utf-8 -*- """ .. _warnings: Warnings @@ -26,8 +25,8 @@ from ...utils.xml.exceptions import XMLWarning __all__ = ["VOSIWarning"] -__all__ += ["W{:0>2}".format(i) for i in range(1, 36)] -__all__ += ["E{:0>2}".format(i) for i in range(1, 10)] +__all__ += [f"W{i:0>2}" for i in range(1, 36)] +__all__ += [f"E{i:0>2}" for i in range(1, 10)] class VOSIWarning(AstropyWarning): diff --git a/pyvo/io/vosi/tapregext.py b/pyvo/io/vosi/tapregext.py index 3ef40530..5b501bfa 100644 --- a/pyvo/io/vosi/tapregext.py +++ b/pyvo/io/vosi/tapregext.py @@ -39,7 +39,7 @@ def describe(self): """ Prints out a human readable description """ - print("Datamodel {}".format(self.content)) + print(f"Datamodel {self.content}") print(indent(self.ivo_id, INDENT)) print() @@ -71,7 +71,7 @@ def describe(self): """ Prints out a human readable description """ - print('Output format {}'.format(self.mime)) + print(f'Output format {self.mime}') if self.aliases: print(indent('Also available as {}'.format(', '.join(self.aliases)), @@ -100,7 +100,7 @@ def __init__(self, config=None, pos=None, **kwargs): self.ivo_id = ivo_id def __repr__(self): - return ''.format(self.ivo_id) + return f'' def describe(self): """ @@ -232,13 +232,13 @@ def __init__(self, config=None, pos=None, **kwargs): self._languagefeaturelists = HomogeneousList(LanguageFeatureList) def __repr__(self): - return '{}'.format(self.name) + return f'{self.name}' def describe(self): """ Prints out a human readable description """ - print("Language {}".format(self.name)) + print(f"Language {self.name}") for languagefeaturelist in self.languagefeaturelists: print(indent(languagefeaturelist.type, INDENT)) @@ -470,16 +470,16 @@ def describe(self): if self.retentionperiod: print("Time a job is kept (in seconds)") - print(indent("Default {}".format(self.retentionperiod.default), INDENT)) + print(indent(f"Default {self.retentionperiod.default}", INDENT)) if self.retentionperiod.hard: - print(indent("Maximum {}".format(self.retentionperiod.hard), INDENT)) + print(indent(f"Maximum {self.retentionperiod.hard}", INDENT)) print() if self.executionduration: print("Maximal run time of a job") - print(indent("Default {}".format(self.executionduration.default), INDENT)) + print(indent(f"Default {self.executionduration.default}", INDENT)) if self.executionduration.hard: - print(indent("Maximum {}".format(self.executionduration.hard), INDENT)) + print(indent(f"Maximum {self.executionduration.hard}", INDENT)) print() if self.outputlimit: diff --git a/pyvo/io/vosi/vodataservice.py b/pyvo/io/vosi/vodataservice.py index ef98a2da..50c3e136 100644 --- a/pyvo/io/vosi/vodataservice.py +++ b/pyvo/io/vosi/vodataservice.py @@ -492,7 +492,7 @@ def __init__(self, config=None, pos=None, _name='', **kwargs): self._utype = None def __repr__(self): - return ''.format(self.name) + return f'' @xmlelement(plain=True, multiple_exc=W05) def name(self): diff --git a/pyvo/io/vosi/voresource.py b/pyvo/io/vosi/voresource.py index dd87b35f..d5bc5447 100644 --- a/pyvo/io/vosi/voresource.py +++ b/pyvo/io/vosi/voresource.py @@ -239,7 +239,7 @@ def describe(self): """ Prints out a human readable description """ - print('Interface {}'.format(self._xsi_type)) + print(f'Interface {self._xsi_type}') accessurls = '\n'.join( accessurl.content for accessurl in self.accessurls) @@ -370,7 +370,7 @@ def describe(self): """ Prints out a human readable description """ - print("Capability {}".format(self.standardid)) + print(f"Capability {self.standardid}") print() if self.description: diff --git a/pyvo/mivot/features/sky_coord_builder.py b/pyvo/mivot/features/sky_coord_builder.py index 7bdf4877..ef690c8c 100644 --- a/pyvo/mivot/features/sky_coord_builder.py +++ b/pyvo/mivot/features/sky_coord_builder.py @@ -37,7 +37,7 @@ class MangoRoles: MangoRoles.RADIAL_VELOCITY: 'radial_velocity', MangoRoles.EPOCH: 'obstime'} -class SkyCoordBuilder(object): +class SkyCoordBuilder: ''' Utility generating SkyCoord instances from MIVOT annotations diff --git a/pyvo/mivot/utils/dict_utils.py b/pyvo/mivot/utils/dict_utils.py index 679c55a2..1bdb3789 100644 --- a/pyvo/mivot/utils/dict_utils.py +++ b/pyvo/mivot/utils/dict_utils.py @@ -27,13 +27,13 @@ def read_dict_from_file(filename, fatal=False): try: logging.debug("Reading json from %s", filename) from collections import OrderedDict - with open(filename, 'r') as file: + with open(filename) as file: return json.load(file, object_pairs_hook=OrderedDict) except Exception as exception: if fatal: - raise MivotError("reading {}".format(filename)) + raise MivotError(f"reading {filename}") else: - logging.error("{} reading {}".format(exception, filename)) + logging.error(f"{exception} reading {filename}") @staticmethod def _get_pretty_json(dictionary): diff --git a/pyvo/mivot/utils/json_encoder.py b/pyvo/mivot/utils/json_encoder.py index 37ccf748..1fe4e80b 100644 --- a/pyvo/mivot/utils/json_encoder.py +++ b/pyvo/mivot/utils/json_encoder.py @@ -27,4 +27,4 @@ def default(self, obj): elif isinstance(obj, numpy.ndarray): return obj.tolist() else: - return super(MivotJsonEncoder, self).default(obj) + return super().default(obj) diff --git a/pyvo/mivot/utils/mivot_utils.py b/pyvo/mivot/utils/mivot_utils.py index df6925f7..da26778f 100644 --- a/pyvo/mivot/utils/mivot_utils.py +++ b/pyvo/mivot/utils/mivot_utils.py @@ -5,7 +5,7 @@ import numpy -class MivotUtils(object): +class MivotUtils: @staticmethod def xml_to_dict(element): """ diff --git a/pyvo/mivot/viewer/mivot_instance.py b/pyvo/mivot/viewer/mivot_instance.py index 47cfacde..85b58bdf 100644 --- a/pyvo/mivot/viewer/mivot_instance.py +++ b/pyvo/mivot/viewer/mivot_instance.py @@ -194,9 +194,9 @@ def _get_class_dict(self, obj, classkey=None, slim=False): elif hasattr(obj, "__iter__") and not isinstance(obj, str): return [self._get_class_dict(v, classkey, slim=slim) for v in obj] elif hasattr(obj, "__dict__"): - data = dict([(key, obj._get_class_dict(value, classkey, slim=slim)) + data = {key: obj._get_class_dict(value, classkey, slim=slim) for key, value in obj.__dict__.items() - if not callable(value) and not key.startswith('_')]) + if not callable(value) and not key.startswith('_')} # remove the house keeping parameters if slim is True: # data is atomic value (e.g. float): the type be hidden diff --git a/pyvo/registry/regtap.py b/pyvo/registry/regtap.py index ca40c53e..e6c99004 100644 --- a/pyvo/registry/regtap.py +++ b/pyvo/registry/regtap.py @@ -318,15 +318,15 @@ def get_summary(self): "Resource description", "Access modes offered")) - @functools.lru_cache(maxsize=None) + @functools.cache def _get_ivo_index(self): - return dict((r.ivoid, index) - for index, r in enumerate(self)) + return {r.ivoid: index + for index, r in enumerate(self)} - @functools.lru_cache(maxsize=None) + @functools.cache def _get_short_name_index(self): - return dict((r.short_name, index) - for index, r in enumerate(self)) + return {r.short_name: index + for index, r in enumerate(self)} def __getitem__(self, item): """ @@ -728,10 +728,10 @@ def access_modes(self): This will ignore VOSI (infrastructure) services. """ - return set(shorten_stdid(intf.standard_id) or "web" + return {shorten_stdid(intf.standard_id) or "web" for intf in self.interfaces if (intf.standard_id or intf.type == "vr:webbrowser") - and not intf.is_vosi) + and not intf.is_vosi} def get_interface(self, *, service_type: str, diff --git a/pyvo/registry/rtcons.py b/pyvo/registry/rtcons.py index 0f37db65..65f86d1a 100644 --- a/pyvo/registry/rtcons.py +++ b/pyvo/registry/rtcons.py @@ -32,7 +32,7 @@ # corresponding standards. This is mostly to keep legacy APIs. # In the future, preferably rely on shorten_stdid and expand_stdid # from regtap. -SERVICE_TYPE_MAP = dict((k, "ivo://ivoa.net/std/" + v) +SERVICE_TYPE_MAP = {k: "ivo://ivoa.net/std/" + v for k, v in [ ("image", "sia"), ("sia", "sia"), @@ -48,7 +48,7 @@ ("slap", "slap"), ("table", "tap"), ("tap", "tap"), -]) +]} class RegTAPFeatureMissing(dalq.DALQueryError): @@ -106,7 +106,7 @@ def make_sql_literal(value): return f'{value}' elif isinstance(value, datetime.datetime): - return "'{}'".format(value.isoformat()) + return f"'{value.isoformat()}'" else: raise ValueError("Cannot format {} as a SQL literal" @@ -289,8 +289,8 @@ def _get_union_condition(self, service): self._fillers, subqueries = {}, [] for index, word in enumerate(self.words): - parname = "fulltext{}".format(index) - parpatname = "fulltextpar{}".format(index) + parname = f"fulltext{index}" + parpatname = f"fulltextpar{index}" self._fillers[parname] = word self._fillers[parpatname] = '%' + word + '%' args = locals() @@ -310,8 +310,8 @@ def _get_or_condition(self, service): self._fillers, conditions = {}, [] for index, word in enumerate(self.words): - parname = "fulltext{}".format(index) - parpatname = "fulltextpar{}".format(index) + parname = f"fulltext{index}" + parpatname = f"fulltextpar{index}" self._fillers[parname] = word self._fillers[parpatname] = '%' + word + '%' args = locals() @@ -456,8 +456,8 @@ def include_auxiliary_services(self): This is a convenience to maintain registry.search's signature. """ expanded = self.clone() - expanded.stdids |= set( - std + '#aux' for std in expanded.stdids) + expanded.stdids |= { + std + '#aux' for std in expanded.stdids} if "standard_id like 'ivo://ivoa.net/std/sia#query-2.%'" in expanded.extra_fragments: expanded.extra_fragments.append( "standard_id like 'ivo://ivoa.net/std/sia#query-aux-2.%'") @@ -633,8 +633,8 @@ def __init__(self, *patterns): """ self._condition = " OR ".join( f"ucd LIKE {{ucd{i}}}" for i in range(len(patterns))) - self._fillers = dict((f"ucd{index}", pattern) - for index, pattern in enumerate(patterns)) + self._fillers = {f"ucd{index}": pattern + for index, pattern in enumerate(patterns)} class Spatial(SubqueriedConstraint): @@ -728,7 +728,7 @@ def __init__(self, geom_spec, self.inclusive = inclusive def tomoc(s): - return _AsIs("MOC({}, {})".format(order, s)) + return _AsIs(f"MOC({order}, {s})") if isinstance(geom_spec, str): geom = _AsIs("MOC({})".format( diff --git a/pyvo/utils/prototype.py b/pyvo/utils/prototype.py index 659789d7..8fbb32b7 100644 --- a/pyvo/utils/prototype.py +++ b/pyvo/utils/prototype.py @@ -1,14 +1,15 @@ import inspect import warnings from functools import wraps -from typing import Dict, Iterable +from typing import Dict +from collections.abc import Iterable from .protofeature import Feature from pyvo.dal.exceptions import PyvoUserWarning __all__ = ['features', 'prototype_feature', 'activate_features', 'PrototypeWarning', 'PrototypeError'] -features: Dict[str, "Feature"] = { +features: dict[str, "Feature"] = { 'cadc-tb-upload': Feature('cadc-tb-upload', 'https://wiki.ivoa.net/twiki/bin/view/IVOA/TAP-1_1-Next', False), diff --git a/pyvo/utils/vocabularies.py b/pyvo/utils/vocabularies.py index 9b67ca5e..6ea8087d 100644 --- a/pyvo/utils/vocabularies.py +++ b/pyvo/utils/vocabularies.py @@ -26,7 +26,7 @@ class VocabularyError(Exception): """ -@functools.lru_cache() +@functools.lru_cache def get_vocabulary(voc_name, force_update=False): """returns an IVOA vocabulary in its "desise" form. @@ -61,7 +61,7 @@ def get_vocabulary(voc_name, force_update=False): f" {voc_name} failed: {msg}", category=PyvoUserWarning) - with open(src_name, "r", encoding="utf-8") as f: + with open(src_name, encoding="utf-8") as f: return json.load(f) diff --git a/pyvo/utils/xml/exceptions.py b/pyvo/utils/xml/exceptions.py index 6ba3beba..53b08b82 100644 --- a/pyvo/utils/xml/exceptions.py +++ b/pyvo/utils/xml/exceptions.py @@ -12,7 +12,7 @@ def _format_message(message, name, config=None, pos=None): pos = ('?', '?') filename = config.get('filename', '?') - return '{}:{}:{}: {}: {}'.format(filename, pos[0], pos[1], name, message) + return f'{filename}:{pos[0]}:{pos[1]}: {name}: {message}' class XMLWarning(AstropyWarning): From d1fa2bbdeebbfb48863e23a7966f03d6993442f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brigitta=20Sip=C5=91cz?= Date: Thu, 9 Jan 2025 21:49:15 -0800 Subject: [PATCH 15/24] MAINT: changing error type to match TypeError raised by astropy.units --- pyvo/dal/tests/test_adhoc.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyvo/dal/tests/test_adhoc.py b/pyvo/dal/tests/test_adhoc.py index 540040b7..914b48e2 100644 --- a/pyvo/dal/tests/test_adhoc.py +++ b/pyvo/dal/tests/test_adhoc.py @@ -62,7 +62,7 @@ class TestClass(dict, AxisParamMixin): # errors test_obj.pos.pop() - with pytest.raises(ValueError): + with pytest.raises(TypeError): test_obj.pos.add(('A', 2, 3)) with pytest.raises(ValueError): test_obj.pos.add((-2, 7, 3)) @@ -116,7 +116,7 @@ class TestClass(dict, AxisParamMixin): test_obj.band.add(()) with pytest.raises(ValueError): test_obj.band.add((1, 2, 3)) - with pytest.raises(ValueError): + with pytest.raises(TypeError): test_obj.band.add(('INVALID', 6)) with pytest.raises(ValueError): test_obj.band.add((3, 1)) @@ -216,7 +216,7 @@ def test_soda_query(): assert not hasattr(test_obj, '_range') # error cases - with pytest.raises(ValueError): + with pytest.raises(TypeError): test_obj.circle = ('A', 1, 2) with pytest.raises(ValueError): test_obj.circle = (1, 1, 2, 2) From cdb4a32a1d93f951701ecbfa7d9f52db3496b584 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brigitta=20Sip=C5=91cz?= Date: Thu, 9 Jan 2025 22:10:13 -0800 Subject: [PATCH 16/24] MAINT: dropping astropy 4.1 support --- setup.cfg | 2 +- tox.ini | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/setup.cfg b/setup.cfg index c373d014..7af3be4b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -65,7 +65,7 @@ packages = find: zip_safe = False setup_requires = setuptools_scm install_requires = - astropy>=4.1 + astropy>=4.2 requests python_requires = >=3.9 diff --git a/tox.ini b/tox.ini index a072f18e..43482c47 100644 --- a/tox.ini +++ b/tox.ini @@ -39,10 +39,10 @@ deps = # astropy doesn't yet have a 3.13 compatible release py313: astropy>=0.0dev0 - oldestdeps: astropy==4.1 + oldestdeps: astropy==4.2 # We set a suitably old numpy along with an old astropy, no need to pick up # deprecations and errors due to their unmatching versions - oldestdeps: numpy==1.19 + oldestdeps: numpy==1.20 online: pytest-rerunfailures From ef41929cf15ac84269feacc9d77780fd8043702a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brigitta=20Sip=C5=91cz?= Date: Thu, 9 Jan 2025 22:30:06 -0800 Subject: [PATCH 17/24] Fix style issues --- pyvo/discover/image.py | 3 ++- pyvo/registry/rtcons.py | 30 +++++++++++++++--------------- pyvo/utils/prototype.py | 1 - 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/pyvo/discover/image.py b/pyvo/discover/image.py index 79363c9a..24aa7092 100644 --- a/pyvo/discover/image.py +++ b/pyvo/discover/image.py @@ -36,7 +36,7 @@ # imports for type hints -from typing import Callable, List, Optional, Set, Tuple +from typing import Callable, Optional from collections.abc import Generator from astropy.units import quantity @@ -67,6 +67,7 @@ class Queriable: They are constructed with a resource record. """ + def __init__(self, res_rec): self.res_rec = res_rec self.ivoid = res_rec.ivoid diff --git a/pyvo/registry/rtcons.py b/pyvo/registry/rtcons.py index 65f86d1a..c55534c3 100644 --- a/pyvo/registry/rtcons.py +++ b/pyvo/registry/rtcons.py @@ -34,21 +34,21 @@ # from regtap. SERVICE_TYPE_MAP = {k: "ivo://ivoa.net/std/" + v for k, v in [ - ("image", "sia"), - ("sia", "sia"), - ("sia1", "sia"), - # SIA2 is irregular - # funky scheme used by SIA2 without breaking everything else - ("spectrum", "ssa"), - ("ssap", "ssa"), - ("ssa", "ssa"), - ("scs", "conesearch"), - ("conesearch", "conesearch"), - ("line", "slap"), - ("slap", "slap"), - ("table", "tap"), - ("tap", "tap"), -]} + ("image", "sia"), + ("sia", "sia"), + ("sia1", "sia"), + # SIA2 is irregular + # funky scheme used by SIA2 without breaking everything else + ("spectrum", "ssa"), + ("ssap", "ssa"), + ("ssa", "ssa"), + ("scs", "conesearch"), + ("conesearch", "conesearch"), + ("line", "slap"), + ("slap", "slap"), + ("table", "tap"), + ("tap", "tap"), + ]} class RegTAPFeatureMissing(dalq.DALQueryError): diff --git a/pyvo/utils/prototype.py b/pyvo/utils/prototype.py index 8fbb32b7..d39589ad 100644 --- a/pyvo/utils/prototype.py +++ b/pyvo/utils/prototype.py @@ -1,7 +1,6 @@ import inspect import warnings from functools import wraps -from typing import Dict from collections.abc import Iterable from .protofeature import Feature From 63b744350851d28b0d4f1701b8ae39d78513fee8 Mon Sep 17 00:00:00 2001 From: ChuanmingMao Date: Tue, 14 Jan 2025 21:22:12 +0100 Subject: [PATCH 18/24] fixed style problem --- pyvo/dal/tap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyvo/dal/tap.py b/pyvo/dal/tap.py index 3380c46f..b1ff21f8 100644 --- a/pyvo/dal/tap.py +++ b/pyvo/dal/tap.py @@ -149,7 +149,7 @@ def tables(self): if self._tables is None: tables_url = '{}/tables'.format(self.baseurl) - response = self._session.get(tables_url, params={"detail":"min"}, stream=True) + response = self._session.get(tables_url, params={"detail": "min"}, stream=True) try: response.raise_for_status() From 08a1bdbee822ca3ef0bda054a03655cff07d30dc Mon Sep 17 00:00:00 2001 From: ChuanmingMao Date: Tue, 14 Jan 2025 21:29:55 +0100 Subject: [PATCH 19/24] Add bug fix description in changes.rst --- CHANGES.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index fef5c8da..8494a44b 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -19,6 +19,8 @@ Bug Fixes - Fix string literal generation for SQL query when using numpy >=2.0. [#624] +- Try minimal VOSI tables downloads by default for TAP metadata [#634] + 1.6 (2024-11-01) ================ From b5b8d7833ffa0516110daa5a688c5152ce2a6204 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brigitta=20Sip=C5=91cz?= Date: Tue, 14 Jan 2025 13:01:53 -0800 Subject: [PATCH 20/24] DOC: Rephrase changelog --- CHANGES.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 8494a44b..c8d278c8 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -19,7 +19,7 @@ Bug Fixes - Fix string literal generation for SQL query when using numpy >=2.0. [#624] -- Try minimal VOSI tables downloads by default for TAP metadata [#634] +- Switch to do minimal VOSI tables downloads for TAP metadata. [#634] 1.6 (2024-11-01) From 22429c6235e884f6af0188e0c79258328eacb609 Mon Sep 17 00:00:00 2001 From: Stelios Voutsinas Date: Thu, 16 Jan 2025 12:28:20 -0700 Subject: [PATCH 21/24] Make deleting TAP jobs optional, defaulting to True --- pyvo/dal/tap.py | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/pyvo/dal/tap.py b/pyvo/dal/tap.py index 1b2de6d7..80db62be 100644 --- a/pyvo/dal/tap.py +++ b/pyvo/dal/tap.py @@ -282,7 +282,7 @@ def run_sync( def run_async( self, query, *, language="ADQL", maxrec=None, uploads=None, - **keywords): + delete=True, **keywords): """ runs async query and returns its result @@ -297,6 +297,8 @@ def run_async( the maximum records to return. defaults to the service default uploads : dict a mapping from table names to objects containing a votable + delete : bool + delete the job after fetching the results Returns ------- @@ -323,7 +325,9 @@ def run_async( job = job.run().wait() job.raise_if_error() result = job.fetch_result() - job.delete() + + if delete: + job.delete() return result @@ -643,7 +647,7 @@ def create( job = cls(response.url, session=session) return job - def __init__(self, url, *, session=None): + def __init__(self, url, *, session=None, delete=True): """ initialize the job object with the given url and fetch remote values @@ -651,9 +655,14 @@ def __init__(self, url, *, session=None): ---------- url : str the job url + session : object, optional + session to use for network requests + delete : bool, optional + whether to delete the job when exiting (default: True) """ self._url = url self._session = use_session(session) + self._delete_on_exit = delete self._update() def __enter__(self): @@ -664,12 +673,15 @@ def __enter__(self): def __exit__(self, exc_type, exc_val, exc_tb): """ - Exits the context. The job is silently deleted. + Exits the context. Unless delete=False was set at initialization, + the job is deleted. Any deletion errors are silently ignored + to ensure proper context exit. """ - try: - self.delete() - except Exception: - pass + if self._delete_on_exit: + try: + self.delete() + except Exception: + pass def _update(self, wait_for_statechange=False, timeout=10.): """ From f5dd6ff9e63f0461ad90fabc3968e1467dfd97f2 Mon Sep 17 00:00:00 2001 From: Stelios Voutsinas Date: Thu, 16 Jan 2025 13:21:22 -0700 Subject: [PATCH 22/24] Change broad Exception to DALServiceError in AsyncTAPJob __exit__ --- pyvo/dal/tap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyvo/dal/tap.py b/pyvo/dal/tap.py index 80db62be..5e4a2d38 100644 --- a/pyvo/dal/tap.py +++ b/pyvo/dal/tap.py @@ -680,7 +680,7 @@ def __exit__(self, exc_type, exc_val, exc_tb): if self._delete_on_exit: try: self.delete() - except Exception: + except DALServiceError: pass def _update(self, wait_for_statechange=False, timeout=10.): From 201a22ed9c30d277d4af7a9ca1f1c61e7b2f39ab Mon Sep 17 00:00:00 2001 From: Stelios Voutsinas Date: Thu, 16 Jan 2025 14:15:39 -0700 Subject: [PATCH 23/24] Add changelog entry --- CHANGES.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.rst b/CHANGES.rst index c8d278c8..5aab5cd4 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,6 +4,7 @@ Enhancements and Fixes ---------------------- +- Make deletion of TAP jobs optional via a delete flag. Default: True Deprecations and Removals ------------------------- From f765128c60f10c11907db6b81b1fe1544ee4d917 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brigitta=20Sip=C5=91cz?= Date: Thu, 16 Jan 2025 13:30:58 -0800 Subject: [PATCH 24/24] DOC: Add PR number to changelog --- CHANGES.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 5aab5cd4..db02e8af 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,7 +4,7 @@ Enhancements and Fixes ---------------------- -- Make deletion of TAP jobs optional via a delete flag. Default: True +- Make deletion of TAP jobs optional via a new ``delete`` kwarg. [#640] Deprecations and Removals -------------------------