diff --git a/CHANGES.rst b/CHANGES.rst
index 2d7c44689d..fbb075d01d 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -189,6 +189,8 @@ Infrastructure, Utility and Other Changes and Additions
- Removed deprecated function ``utils.download_list_of_fitsfiles()``. [#2594]
+- Versions of astropy <4.2.1 and numpy <1.18 are no longer supported. [#2602]
+
0.4.6 (2022-03-22)
diff --git a/README.rst b/README.rst
index eab5562b4a..2f51ed3481 100644
--- a/README.rst
+++ b/README.rst
@@ -43,7 +43,7 @@ Installation and Requirements
-----------------------------
Astroquery works with Python 3.7 or later.
-As an `astropy`_ affiliate, astroquery requires `astropy`_ version 4.0 or later.
+As an `astropy`_ affiliate, astroquery requires `astropy`_ version 4.2.1 or later.
astroquery uses the `requests `_
module to communicate with the internet. `BeautifulSoup
diff --git a/astroquery/alma/core.py b/astroquery/alma/core.py
index c24cb8af7e..255cd96334 100644
--- a/astroquery/alma/core.py
+++ b/astroquery/alma/core.py
@@ -579,11 +579,7 @@ def get_data_info(self, uids, *, expand_tarfiles=False,
datalink_service_def_dict[adhoc_service.ID] = adhoc_service
temp = res.to_table()
- if commons.ASTROPY_LT_4_1:
- # very annoying
- for col in [x for x in temp.colnames
- if x not in ['content_length', 'readable']]:
- temp[col] = temp[col].astype(str)
+
result = temp if result is None else vstack([result, temp])
to_delete = []
for index, rr in enumerate(result):
@@ -1214,10 +1210,8 @@ def get_project_metadata(self, projectid, *, cache=True):
result = self.query_tap(
"select distinct proposal_abstract from "
"ivoa.obscore where proposal_id='{}'".format(projectid))
- if commons.ASTROPY_LT_4_1:
- return [result[0]['proposal_abstract'].astype(str)]
- else:
- return [result[0]['proposal_abstract']]
+
+ return [result[0]['proposal_abstract']]
Alma = AlmaClass()
diff --git a/astroquery/alma/tests/test_alma_remote.py b/astroquery/alma/tests/test_alma_remote.py
index e641f23ae6..cfd10c27c4 100644
--- a/astroquery/alma/tests/test_alma_remote.py
+++ b/astroquery/alma/tests/test_alma_remote.py
@@ -17,7 +17,6 @@
pass
from astroquery.exceptions import CorruptDataWarning
-from astroquery.utils.commons import ASTROPY_LT_4_1
from .. import Alma
# ALMA tests involving staging take too long, leading to travis timeouts
@@ -283,14 +282,10 @@ def test_doc_example(self, tmp_path, alma):
content_length_column_name = 'content_length'
uids = np.unique(m83_data['Member ous id'])
- if ASTROPY_LT_4_1:
- assert b'uid://A001/X11f/X30' in uids
- X30 = (m83_data['Member ous id'] == b'uid://A001/X11f/X30')
- X31 = (m83_data['Member ous id'] == b'uid://A002/X3216af/X31')
- else:
- assert 'uid://A001/X11f/X30' in uids
- X30 = (m83_data['Member ous id'] == 'uid://A001/X11f/X30')
- X31 = (m83_data['Member ous id'] == 'uid://A002/X3216af/X31')
+
+ assert 'uid://A001/X11f/X30' in uids
+ X30 = (m83_data['Member ous id'] == 'uid://A001/X11f/X30')
+ X31 = (m83_data['Member ous id'] == 'uid://A002/X3216af/X31')
assert X30.sum() == 4 # Jul 13, 2020
assert X31.sum() == 4 # Jul 13, 2020
diff --git a/astroquery/alma/utils.py b/astroquery/alma/utils.py
index b8293e24a2..f551115ed5 100644
--- a/astroquery/alma/utils.py
+++ b/astroquery/alma/utils.py
@@ -5,7 +5,6 @@
from astropy import units as u
from astropy.coordinates import SkyCoord
-from astroquery.utils.commons import ASTROPY_LT_4_1
__all__ = ['parse_frequency_support', 'footprint_to_reg', 'approximate_primary_beam_sizes']
@@ -48,8 +47,7 @@ def footprint_to_reg(footprint):
-28.694332 266.521332 -28.699778'
Some of them have *additional* polygons
"""
- if ASTROPY_LT_4_1:
- footprint = footprint.decode('utf-8')
+
if footprint[:7] != 'Polygon' and footprint[:6] != 'Circle':
raise ValueError("Unrecognized footprint type")
diff --git a/astroquery/cadc/core.py b/astroquery/cadc/core.py
index fe2de62e75..10f4a20564 100644
--- a/astroquery/cadc/core.py
+++ b/astroquery/cadc/core.py
@@ -457,8 +457,7 @@ def get_image_list(self, query_result, coordinates, radius):
session=self.cadcdatalink._session)
for service_def in datalink.bysemantics('#cutout'):
access_url = service_def.access_url
- if isinstance(access_url, bytes): # ASTROPY_LT_4_1
- access_url = access_url.decode('ascii')
+
if '/sync' in access_url:
service_params = service_def.input_params
input_params = {param.name: param.value
diff --git a/astroquery/cadc/tests/test_cadctap.py b/astroquery/cadc/tests/test_cadctap.py
index 89a214a7ca..8b06a7c262 100644
--- a/astroquery/cadc/tests/test_cadctap.py
+++ b/astroquery/cadc/tests/test_cadctap.py
@@ -206,7 +206,7 @@ def get(*args, **kwargs):
class CapsResponse:
def __init__(self):
self.status_code = 200
- self.content = b''
+ self.content = ''
def raise_for_status(self):
pass
@@ -286,7 +286,7 @@ def get(*args, **kwargs):
class CapsResponse:
def __init__(self):
self.status_code = 200
- self.content = b''
+ self.content = ''
def raise_for_status(self):
pass
@@ -308,13 +308,13 @@ def __init__(self, **param_dict):
service_def1 = Mock()
service_def1.access_url = \
- b'https://www.cadc-ccda.hia-iha.nrc-cnrc.gc.ca/caom2ops/sync'
+ 'https://www.cadc-ccda.hia-iha.nrc-cnrc.gc.ca/caom2ops/sync'
service_def1.input_params = [Params(name='ID', value=uri),
Params(name='RUNID', value=run_id)]
service_def2 = Mock()
service_def2.access_url = \
- b'https://www.cadc-ccda.hia-iha.nrc-cnrc.gc.ca/caom2ops/async'
+ 'https://www.cadc-ccda.hia-iha.nrc-cnrc.gc.ca/caom2ops/async'
service_def2.input_params = [Params(name='ID', value=uri),
Params(name='RUNID', value=run_id)]
diff --git a/astroquery/gaia/tests/test_gaiatap.py b/astroquery/gaia/tests/test_gaiatap.py
index 1ec977a4ee..7beb21b62c 100644
--- a/astroquery/gaia/tests/test_gaiatap.py
+++ b/astroquery/gaia/tests/test_gaiatap.py
@@ -30,7 +30,6 @@
import astropy.units as u
from astropy.coordinates.sky_coordinate import SkyCoord
import numpy as np
-from astroquery.utils import ASTROPY_LT_4_1
from astroquery.utils.tap.xmlparser import utils
from astroquery.utils.tap.core import TapPlus
from astroquery.utils.tap import taputils
@@ -50,8 +49,8 @@ def column_attrs():
"table1_oid": np.int32
}
columns = {k: Column(name=k, description=k, dtype=v) for k, v in dtypes.items()}
- if not ASTROPY_LT_4_1:
- columns["source_id"].meta = {"_votable_string_dtype": "char"}
+
+ columns["source_id"].meta = {"_votable_string_dtype": "char"}
return columns
diff --git a/astroquery/ipac/nexsci/nasa_exoplanet_archive/core.py b/astroquery/ipac/nexsci/nasa_exoplanet_archive/core.py
index 192d74dca0..89f5612627 100644
--- a/astroquery/ipac/nexsci/nasa_exoplanet_archive/core.py
+++ b/astroquery/ipac/nexsci/nasa_exoplanet_archive/core.py
@@ -115,10 +115,9 @@ def get_tap_tables():
"""Tables accessed by API are gradually migrating to TAP service. Generate current list of tables in TAP."""
tap = pyvo.dal.tap.TAPService(baseurl=conf.url_tap)
response = tap.search(query="select * from TAP_SCHEMA.tables", language="ADQL")
- if not commons.ASTROPY_LT_4_1:
- tables = [table for table in response["table_name"].data if "TAP_SCHEMA." not in table]
- else:
- tables = [table.decode() for table in response["table_name"].data if b"TAP_SCHEMA." not in table]
+
+ tables = [table for table in response["table_name"].data if "TAP_SCHEMA." not in table]
+
return tables
diff --git a/astroquery/simbad/tests/test_simbad.py b/astroquery/simbad/tests/test_simbad.py
index 4f26ffd229..87f0b2efe7 100644
--- a/astroquery/simbad/tests/test_simbad.py
+++ b/astroquery/simbad/tests/test_simbad.py
@@ -10,7 +10,6 @@
from ... import simbad
from astroquery.utils.mocks import MockResponse
-from ...utils import commons
from ...query import AstroQuery
from ...exceptions import TableParseError
from .test_simbad_remote import multicoords
@@ -440,6 +439,6 @@ def test_regression_issue388():
response.content = f.read()
parsed_table = simbad.Simbad._parse_result(response,
simbad.core.SimbadVOTableResult)
- truth = b'M 1' if commons.ASTROPY_LT_4_1 else 'M 1'
+ truth = 'M 1'
assert parsed_table['MAIN_ID'][0] == truth
assert len(parsed_table) == 1
diff --git a/astroquery/utils/__init__.py b/astroquery/utils/__init__.py
index 58280b3fc0..67d12b717b 100644
--- a/astroquery/utils/__init__.py
+++ b/astroquery/utils/__init__.py
@@ -6,7 +6,7 @@
from .progressbar import chunk_report, chunk_read
from .class_or_instance import class_or_instance
from .commons import (parse_coordinates, TableList, suppress_vo_warnings,
- validate_email, ASTROPY_LT_4_1, ASTROPY_LT_4_3, ASTROPY_LT_5_0,
+ validate_email, ASTROPY_LT_4_3, ASTROPY_LT_5_0,
ASTROPY_LT_5_1)
from .process_asyncs import async_to_sync
from .docstr_chompers import prepend_docstr_nosections
@@ -19,7 +19,6 @@
'TableList',
'suppress_vo_warnings',
'validate_email',
- 'ASTROPY_LT_4_1',
'ASTROPY_LT_4_3',
'ASTROPY_LT_5_0',
'ASTROPY_LT_5_1',
diff --git a/astroquery/utils/commons.py b/astroquery/utils/commons.py
index 2415c4c8cc..55acc9a313 100644
--- a/astroquery/utils/commons.py
+++ b/astroquery/utils/commons.py
@@ -29,12 +29,10 @@
'TableList',
'suppress_vo_warnings',
'validate_email',
- 'ASTROPY_LT_4_1',
'ASTROPY_LT_4_3',
'ASTROPY_LT_5_0',
'ASTROPY_LT_5_1']
-ASTROPY_LT_4_1 = not minversion('astropy', '4.1')
ASTROPY_LT_4_3 = not minversion('astropy', '4.3')
ASTROPY_LT_5_0 = not minversion('astropy', '5.0')
diff --git a/astroquery/vo_conesearch/validator/tstquery.py b/astroquery/vo_conesearch/validator/tstquery.py
index e6d2fb65be..7cb9715e96 100644
--- a/astroquery/vo_conesearch/validator/tstquery.py
+++ b/astroquery/vo_conesearch/validator/tstquery.py
@@ -18,16 +18,12 @@
from astropy.utils.data import get_readable_fileobj
from astropy.utils.exceptions import AstropyUserWarning
-# LOCAL
-from astroquery.utils.commons import ASTROPY_LT_4_1
__all__ = ['parse_cs']
def parse_cs(ivoid, cap_index=1):
"""Return test query pars as dict for given IVO ID and capability index."""
- if isinstance(ivoid, bytes): # ASTROPY_LT_4_1
- ivoid = ivoid.decode('ascii')
# Production server.
url = ("https://vao.stsci.edu/regtap/tapservice.aspx/sync?lang=adql&"
@@ -53,20 +49,10 @@ def parse_cs(ivoid, cap_index=1):
if not urls_failed:
try:
xpath = t_query['detail_xpath']
- if ASTROPY_LT_4_1:
- ra = float(
- t_query[xpath == b'/capability/testQuery/ra']['detail_value'])
- dec = float(
- t_query[xpath == b'/capability/testQuery/dec']['detail_value'])
- sr = float(
- t_query[xpath == b'/capability/testQuery/sr']['detail_value'])
- else:
- ra = float(
- t_query[xpath == '/capability/testQuery/ra']['detail_value'])
- dec = float(
- t_query[xpath == '/capability/testQuery/dec']['detail_value'])
- sr = float(
- t_query[xpath == '/capability/testQuery/sr']['detail_value'])
+
+ ra = float(t_query[xpath == '/capability/testQuery/ra']['detail_value'])
+ dec = float(t_query[xpath == '/capability/testQuery/dec']['detail_value'])
+ sr = float(t_query[xpath == '/capability/testQuery/sr']['detail_value'])
# Handle big SR returning too big a table for some queries, causing
# tests to fail due to timeout.
diff --git a/astroquery/vo_conesearch/validator/validate.py b/astroquery/vo_conesearch/validator/validate.py
index f4fc211f68..640b83f71f 100644
--- a/astroquery/vo_conesearch/validator/validate.py
+++ b/astroquery/vo_conesearch/validator/validate.py
@@ -23,7 +23,6 @@
InvalidValidationAttribute)
from ..exceptions import VOSError
from ..vos_catalog import VOSDatabase, vo_tab_parse
-from ...utils.commons import ASTROPY_LT_4_1
from ...utils.timer import timefunc
# Import configurable items declared in __init__.py
@@ -129,16 +128,10 @@ def check_conesearch_sites(destdir=os.curdir, verbose=True, parallel=True,
# Validate only a subset of the services.
if url_list is not None:
# Make sure URL is unique and fixed.
- if ASTROPY_LT_4_1:
- url_list = set(map(
- unescape_all,
- [cur_url.encode('utf-8') if isinstance(cur_url, str) else cur_url
- for cur_url in url_list]))
- else:
- url_list = set(map(
- unescape_all,
- [cur_url if isinstance(cur_url, str) else cur_url
- for cur_url in url_list]))
+ url_list = set(map(
+ unescape_all,
+ [cur_url if isinstance(cur_url, str) else cur_url
+ for cur_url in url_list]))
uniq_rows = len(url_list)
url_list_processed = [] # To track if given URL is valid in registry
if verbose:
@@ -151,48 +144,26 @@ def check_conesearch_sites(destdir=os.curdir, verbose=True, parallel=True,
key_lookup_by_url = {}
# Process each catalog in the registry.
- if ASTROPY_LT_4_1:
- for cur_key, cur_cat in js_mstr.get_catalogs():
- cur_url = cur_cat['url'].encode('utf-8')
-
- # Skip if:
- # a. not a Cone Search service
- # b. not in given subset, if any
- if ((cur_cat['cap_type'] != b'conesearch')
- or (url_list is not None and cur_url not in url_list)):
- continue
-
- # Use testQuery to return non-empty VO table with max verbosity.
- testquery_pars = parse_cs(cur_cat['ivoid'], cur_cat['cap_index'])
- cs_pars_arr = ['{}={}'.format(key, testquery_pars[key]).encode('utf-8')
- for key in testquery_pars]
- cs_pars_arr += [b'VERB=3']
-
- # Track the service.
- key_lookup_by_url[cur_url + b'&'.join(cs_pars_arr)] = cur_key
- if url_list is not None:
- url_list_processed.append(cur_url)
- else:
- for cur_key, cur_cat in js_mstr.get_catalogs():
- cur_url = cur_cat['url']
-
- # Skip if:
- # a. not a Cone Search service
- # b. not in given subset, if any
- if ((cur_cat['cap_type'] != 'conesearch')
- or (url_list is not None and cur_url not in url_list)):
- continue
-
- # Use testQuery to return non-empty VO table with max verbosity.
- testquery_pars = parse_cs(cur_cat['ivoid'], cur_cat['cap_index'])
- cs_pars_arr = ['{}={}'.format(key, testquery_pars[key])
- for key in testquery_pars]
- cs_pars_arr += ['VERB=3']
-
- # Track the service.
- key_lookup_by_url[cur_url + '&'.join(cs_pars_arr)] = cur_key
- if url_list is not None:
- url_list_processed.append(cur_url)
+ for cur_key, cur_cat in js_mstr.get_catalogs():
+ cur_url = cur_cat['url']
+
+ # Skip if:
+ # a. not a Cone Search service
+ # b. not in given subset, if any
+ if ((cur_cat['cap_type'] != 'conesearch')
+ or (url_list is not None and cur_url not in url_list)):
+ continue
+
+ # Use testQuery to return non-empty VO table with max verbosity.
+ testquery_pars = parse_cs(cur_cat['ivoid'], cur_cat['cap_index'])
+ cs_pars_arr = ['{}={}'.format(key, testquery_pars[key])
+ for key in testquery_pars]
+ cs_pars_arr += ['VERB=3']
+
+ # Track the service.
+ key_lookup_by_url[cur_url + '&'.join(cs_pars_arr)] = cur_key
+ if url_list is not None:
+ url_list_processed.append(cur_url)
# Give warning if any of the user given subset is not in the registry.
if url_list is not None:
@@ -207,10 +178,8 @@ def check_conesearch_sites(destdir=os.curdir, verbose=True, parallel=True,
all_urls = list(key_lookup_by_url)
timeout = data.conf.remote_timeout
- if ASTROPY_LT_4_1:
- map_args = [(out_dir, url, timeout) for url in all_urls]
- else:
- map_args = [(out_dir, url.encode('utf-8'), timeout) for url in all_urls]
+
+ map_args = [(out_dir, url.encode('utf-8'), timeout) for url in all_urls]
# Validate URLs
if parallel:
@@ -225,20 +194,12 @@ def check_conesearch_sites(destdir=os.curdir, verbose=True, parallel=True,
mp_list = map(_do_validation, map_args)
# Categorize validation results
- if ASTROPY_LT_4_1:
- for r in mp_list:
- db_key = r['out_db_name']
- cat_key = key_lookup_by_url[r.url]
- cur_cat = js_mstr.get_catalog(cat_key)
- _copy_r_to_cat(r, cur_cat)
- js_tree[db_key].add_catalog(cat_key, cur_cat)
- else:
- for r in mp_list:
- db_key = r['out_db_name']
- cat_key = key_lookup_by_url[r.url.decode('utf-8')]
- cur_cat = js_mstr.get_catalog(cat_key)
- _copy_r_to_cat(r, cur_cat)
- js_tree[db_key].add_catalog(cat_key, cur_cat)
+ for r in mp_list:
+ db_key = r['out_db_name']
+ cat_key = key_lookup_by_url[r.url.decode('utf-8')]
+ cur_cat = js_mstr.get_catalog(cat_key)
+ _copy_r_to_cat(r, cur_cat)
+ js_tree[db_key].add_catalog(cat_key, cur_cat)
# Write to HTML
html_subsets = result.get_result_subsets(mp_list, out_dir)
diff --git a/astroquery/vo_conesearch/vos_catalog.py b/astroquery/vo_conesearch/vos_catalog.py
index 61150d9ee3..901c969474 100644
--- a/astroquery/vo_conesearch/vos_catalog.py
+++ b/astroquery/vo_conesearch/vos_catalog.py
@@ -597,19 +597,12 @@ def from_registry(cls, registry_url, timeout=60, **kwargs):
cur_title = arr['res_title']
title_counter[cur_title] += 1 # Starts with 1
- if isinstance(cur_title, bytes): # ASTROPY_LT_4_1
- cur_key = title_fmt.format(cur_title.decode('utf-8'),
- title_counter[cur_title])
- else:
- cur_key = title_fmt.format(cur_title,
- title_counter[cur_title])
+ cur_key = title_fmt.format(cur_title, title_counter[cur_title])
# Special handling of title and access URL,
# otherwise no change.
if field == 'access_url':
s = unescape_all(arr['access_url'])
- if isinstance(s, bytes): # ASTROPY_LT_4_1
- s = s.decode('utf-8')
cur_cat['url'] = s
elif field == 'res_title':
cur_cat['title'] = arr[field]
diff --git a/docs/index.rst b/docs/index.rst
index 7e0432bee1..3b81f706ce 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -84,8 +84,8 @@ Astroquery works with Python 3.7 or later.
The following packages are required for astroquery installation & use:
-* `numpy `_ >= 1.16
-* `astropy `__ (>=4)
+* `numpy `_ >= 1.18
+* `astropy `__ (>=4.2.1)
* `pyVO`_ (>=1.1)
* `requests `_
* `keyring `_
diff --git a/setup.cfg b/setup.cfg
index 206e8a1924..fff76ae20f 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -67,8 +67,6 @@ filterwarnings =
ignore:leap-second auto-update failed:astropy.utils.exceptions.AstropyWarning
# Should ignore these for astropy<5.0
ignore:getName|currentThread:DeprecationWarning:astropy
-# This should be cleared once we requre astropy>=4.1
- ignore:tostring\(\) is deprecated. Use tobytes:DeprecationWarning:astropy
markers =
bigdata: marks tests that are expected to trigger a large download (deselect with '-m "not bigdata"')
noautofixt: disabling fixture autouse
@@ -161,8 +159,8 @@ omit =
python_requires = >=3.7
install_requires=
- numpy>=1.16
- astropy>=4.0
+ numpy>=1.18
+ astropy>=4.2.1
requests>=2.4.3
beautifulsoup4>=4.3.2
html5lib>=0.999
diff --git a/tox.ini b/tox.ini
index b0c0c82a19..8f11d5cd05 100644
--- a/tox.ini
+++ b/tox.ini
@@ -31,8 +31,8 @@ deps =
# mpl while not a dependency, it's required for the tests, and would pull up a newer numpy version if not pinned.
- oldestdeps: astropy==4.0
- oldestdeps: numpy==1.16
+ oldestdeps: astropy==4.2.1
+ oldestdeps: numpy==1.18
oldestdeps: matplotlib==3.3.*
oldestdeps: pyvo==1.1
cov: codecov