diff --git a/astroquery/esa/euclid/core.py b/astroquery/esa/euclid/core.py index aea9b1a227..ac73d2ff42 100644 --- a/astroquery/esa/euclid/core.py +++ b/astroquery/esa/euclid/core.py @@ -605,23 +605,20 @@ def get_status_messages(self, verbose=False): flag to display information about the process """ - try: - sub_context = self.EUCLID_MESSAGES - conn_handler = self._TapPlus__getconnhandler() - response = conn_handler.execute_tapget(sub_context, verbose=verbose) - if response.status == 200: - if isinstance(response, Iterable): - for line in response: - - try: - print(line.decode("utf-8").split('=', 1)[1]) - except ValueError as e: - print(e) - except IndexError: - print("Archive down for maintenance") - - except OSError: - print("Status messages could not be retrieved") + sub_context = self.EUCLID_MESSAGES + conn_handler = self._TapPlus__getconnhandler() + response = conn_handler.execute_tapget(sub_context, verbose=verbose) + if response.status == 200: + if isinstance(response, Iterable): + for line in response: + + try: + print(line.decode("utf-8").split('=', 1)[1]) + except ValueError as e: + print(e) + except IndexError: + print("Archive down for maintenance") + @staticmethod def __set_dirs(output_file, observation_id): @@ -1443,4 +1440,4 @@ def get_scientific_product_list(self, *, observation_id=None, tile_index=None, c return job.get_results() -Euclid = EuclidClass() +Euclid = EuclidClass(show_server_messages=False) diff --git a/astroquery/esa/euclid/tests/test_euclidtap.py b/astroquery/esa/euclid/tests/test_euclidtap.py index 5f8c2ff4bc..0a297739b3 100644 --- a/astroquery/esa/euclid/tests/test_euclidtap.py +++ b/astroquery/esa/euclid/tests/test_euclidtap.py @@ -125,25 +125,25 @@ def column_attrs(): def test_load_environments(): - tap = EuclidClass(environment='PDR') + tap = EuclidClass(environment='PDR', show_server_messages=False) assert tap is not None - tap = EuclidClass(environment='IDR') + tap = EuclidClass(environment='IDR', show_server_messages=False) assert tap is not None - tap = EuclidClass(environment='OTF') + tap = EuclidClass(environment='OTF', show_server_messages=False) assert tap is not None - tap = EuclidClass(environment='REG') + tap = EuclidClass(environment='REG', show_server_messages=False) assert tap is not None environment = 'WRONG' try: - tap = EuclidClass(environment='WRONG') + tap = EuclidClass(environment='WRONG', show_server_messages=False) except Exception as e: assert str(e).startswith(f"Invalid environment {environment}. Valid values: {list(conf.ENVIRONMENTS.keys())}") @@ -637,7 +637,7 @@ def test_get_product_list_by_tile_index(): def test_get_product_list_errors(): - tap = EuclidClass() + tap = EuclidClass(show_server_messages=False) with pytest.raises(ValueError, match="Missing required argument: 'product_type'"): tap.get_product_list(observation_id='13', product_type=None) @@ -1105,7 +1105,7 @@ def test_get_scientific_data_product_list(): def test_get_scientific_data_product_list_exceptions(): - eculid = EuclidClass() + eculid = EuclidClass(show_server_messages=False) with pytest.raises(ValueError, match="Include a valid parameter to retrieve a LE3 product."): eculid.get_scientific_product_list(observation_id=None, tile_index=None, category=None, group=None, diff --git a/astroquery/esa/hubble/core.py b/astroquery/esa/hubble/core.py index fdb554913a..bdb9c88396 100644 --- a/astroquery/esa/hubble/core.py +++ b/astroquery/esa/hubble/core.py @@ -940,16 +940,13 @@ def get_status_messages(self): the status of eHST TAP """ - try: - subContext = conf.EHST_MESSAGES - connHandler = self._tap._TapPlus__getconnhandler() - response = connHandler.execute_tapget(subContext, verbose=False) - if response.status == 200: - for line in response: - string_message = line.decode("utf-8") - print(string_message[string_message.index('=') + 1:]) - except OSError: - print("Status messages could not be retrieved") + subContext = conf.EHST_MESSAGES + connHandler = self._tap._TapPlus__getconnhandler() + response = connHandler.execute_tapget(subContext, verbose=False) + if response.status == 200: + for line in response: + string_message = line.decode("utf-8") + print(string_message[string_message.index('=') + 1:]) def get_columns(self, table_name, *, only_names=True, verbose=False): """Get the available columns for a table in EHST TAP service @@ -1061,4 +1058,4 @@ def get_datalabs_path(self, filename, default_volume=None): return full_path -ESAHubble = ESAHubbleClass() +ESAHubble = ESAHubbleClass(show_messages=False) diff --git a/astroquery/esa/hubble/tests/test_esa_hubble_remote.py b/astroquery/esa/hubble/tests/test_esa_hubble_remote.py index abbe5ea050..06d0a7ea4b 100644 --- a/astroquery/esa/hubble/tests/test_esa_hubble_remote.py +++ b/astroquery/esa/hubble/tests/test_esa_hubble_remote.py @@ -18,7 +18,8 @@ from astroquery.esa.hubble import ESAHubble from astropy import coordinates -esa_hubble = ESAHubble() +# don't show messages during test: it creates a remote call +esa_hubble = ESAHubble(show_messages=False) def data_path(filename): diff --git a/astroquery/esa/jwst/core.py b/astroquery/esa/jwst/core.py index b9347e5f4d..c1b29ae053 100644 --- a/astroquery/esa/jwst/core.py +++ b/astroquery/esa/jwst/core.py @@ -694,16 +694,13 @@ def get_status_messages(self): the status of JWST TAP """ - try: - subContext = conf.JWST_MESSAGES - connHandler = self.__jwsttap._TapPlus__getconnhandler() - response = connHandler.execute_tapget(subContext, verbose=False) - if response.status == 200: - for line in response: - string_message = line.decode("utf-8") - print(string_message[string_message.index('=') + 1:]) - except OSError: - print("Status messages could not be retrieved") + subContext = conf.JWST_MESSAGES + connHandler = self.__jwsttap._TapPlus__getconnhandler() + response = connHandler.execute_tapget(subContext, verbose=False) + if response.status == 200: + for line in response: + string_message = line.decode("utf-8") + print(string_message[string_message.index('=') + 1:]) def get_product_list(self, *, observation_id=None, cal_level="ALL", @@ -1275,4 +1272,4 @@ def get_decoded_string(str): return str -Jwst = JwstClass() +Jwst = JwstClass(show_messages=False) diff --git a/astroquery/gaia/core.py b/astroquery/gaia/core.py index 8aa9f06f58..1d9058e9f2 100644 --- a/astroquery/gaia/core.py +++ b/astroquery/gaia/core.py @@ -1168,23 +1168,19 @@ def get_status_messages(self): """Retrieve the messages to inform users about the status of Gaia TAP """ - try: - sub_context = self.GAIA_MESSAGES - conn_handler = self._TapPlus__getconnhandler() - response = conn_handler.execute_tapget(sub_context, verbose=False) - if response.status == 200: - if isinstance(response, Iterable): - for line in response: - - try: - print(line.decode("utf-8").split('=', 1)[1]) - except ValueError as e: - print(e) - except IndexError: - print("Archive down for maintenance") - - except OSError: - print("Status messages could not be retrieved") - - -Gaia = GaiaClass() + sub_context = self.GAIA_MESSAGES + conn_handler = self._TapPlus__getconnhandler() + response = conn_handler.execute_tapget(sub_context, verbose=False) + if response.status == 200: + if isinstance(response, Iterable): + for line in response: + + try: + print(line.decode("utf-8").split('=', 1)[1]) + except ValueError as e: + print(e) + except IndexError: + print("Archive down for maintenance") + + +Gaia = GaiaClass(show_server_messages=False) diff --git a/astroquery/tests/test_imports.py b/astroquery/tests/test_imports.py new file mode 100644 index 0000000000..85c0f921e0 --- /dev/null +++ b/astroquery/tests/test_imports.py @@ -0,0 +1,101 @@ +# Licensed under a 3-clause BSD style license - see LICENSE.rst +import sys +import importlib +import pytest +import socket +from unittest.mock import patch +from pytest_remotedata.disable_internet import no_internet +from pytest_remotedata.disable_internet import INTERNET_OFF + +# List of all astroquery modules to test +ASTROQUERY_MODULES = [ + 'astroquery.alma', + 'astroquery.astrometry_net', + 'astroquery.besancon', + 'astroquery.cadc', + 'astroquery.cosmosim', + 'astroquery.esa', + 'astroquery.esasky', + 'astroquery.eso', + 'astroquery.exoplanet_orbit_database', + 'astroquery.fermi', + 'astroquery.gaia', + 'astroquery.gama', + 'astroquery.gemini', + 'astroquery.heasarc', + 'astroquery.hitran', + 'astroquery.ipac.irsa.ibe', + 'astroquery.hips2fits', + 'astroquery.image_cutouts', + 'astroquery.imcce', + 'astroquery.ipac', + 'astroquery.ipac.irsa', + 'astroquery.ipac.irsa.irsa_dust', + 'astroquery.ipac.ned', + 'astroquery.ipac.nexsci.nasa_exoplanet_archive', + 'astroquery.jplhorizons', + 'astroquery.jplsbdb', + 'astroquery.jplspec', + 'astroquery.linelists', + 'astroquery.magpis', + 'astroquery.mast', + 'astroquery.mocserver', + 'astroquery.mpc', + 'astroquery.nasa_ads', + 'astroquery.nist', + 'astroquery.nvas', + 'astroquery.oac', + 'astroquery.ogle', + 'astroquery.open_exoplanet_catalogue', + 'astroquery.sdss', + 'astroquery.simbad', + 'astroquery.skyview', + 'astroquery.solarsystem', + 'astroquery.splatalogue', + 'astroquery.svo_fps', + 'astroquery.utils', + 'astroquery.vamdc', + 'astroquery.vo_conesearch', + 'astroquery.vizier', + 'astroquery.vsa', + 'astroquery.wfau', + 'astroquery.xmatch', +] + +class SocketTracker: + def __init__(self): + self.socket_attempts = [] + + def __call__(self, *args, **kwargs): + # Record the attempt + self.socket_attempts.append((args, kwargs)) + # Raise a clear error to indicate socket creation + raise RuntimeError("Socket creation attempted during import") + + +@pytest.mark.parametrize("module_name", ASTROQUERY_MODULES) +def test_no_http_calls_during_import(module_name): + """ + Test that importing astroquery modules does not make any remote calls. + + This is a regression test for 3343, and the error that raises is not + properly caught by the framework below, but that's an unrelated issue. + + This is the error shown if Gaia(show_server_messages=True) is called: + ``` + E TypeError: isinstance() arg 2 must be a type, a tuple of types, or a union + ``` + """ + with no_internet(): + if module_name in sys.modules: + del sys.modules[module_name] + + tracker = SocketTracker() + with patch('socket.socket', tracker): + importlib.import_module(module_name) + + assert not tracker.socket_attempts, ( + f"Module {module_name} attempted to create {len(tracker.socket_attempts)} " + f"socket(s) during import:\n" + + "\n".join(f" - {args} {kwargs}" for args, kwargs in tracker.socket_attempts) + ) \ No newline at end of file