Skip to content

Commit f032596

Browse files
authored
Merge pull request #2339 from bsipocz/atomic_fix_default_values
Fix atomic caching infinite loop
2 parents f91c955 + 9163f29 commit f032596

File tree

1 file changed

+32
-30
lines changed

1 file changed

+32
-30
lines changed

astroquery/atomic/core.py

+32-30
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def __init__(self):
2929
super(AtomicLineListClass, self).__init__()
3030
self.__default_form_values = None
3131

32-
def query_object(self, wavelength_range=None, wavelength_type=None, wavelength_accuracy=None, element_spectrum=None,
32+
def query_object(self, *, wavelength_range=None, wavelength_type=None, wavelength_accuracy=None, element_spectrum=None,
3333
minimal_abundance=None, depl_factor=None, lower_level_energy_range=None,
3434
upper_level_energy_range=None, nmax=None, multiplet=None, transitions=None,
3535
show_fine_structure=None, show_auto_ionizing_transitions=None,
@@ -161,12 +161,13 @@ def query_object(self, wavelength_range=None, wavelength_type=None, wavelength_a
161161
output_columns=output_columns, cache=cache,
162162
get_query_payload=get_query_payload)
163163
if get_query_payload:
164-
return input
164+
return response
165+
165166
table = self._parse_result(response)
166167
return table
167168

168169
@prepend_docstr_nosections(query_object.__doc__)
169-
def query_object_async(self, wavelength_range=None, wavelength_type='', wavelength_accuracy=None,
170+
def query_object_async(self, *, wavelength_range=None, wavelength_type='', wavelength_accuracy=None,
170171
element_spectrum=None, minimal_abundance=None, depl_factor=None,
171172
lower_level_energy_range=None, upper_level_energy_range=None, nmax=None, multiplet=None,
172173
transitions=None, show_fine_structure=None, show_auto_ionizing_transitions=None,
@@ -178,7 +179,7 @@ def query_object_async(self, wavelength_range=None, wavelength_type='', waveleng
178179
response : `requests.Response`
179180
The HTTP response returned from the service.
180181
"""
181-
default_values = self._default_form_values
182+
default_values = self._default_form_values()
182183
wltype = (wavelength_type or default_values.get('air', '')).lower()
183184
if wltype in ('air', 'vacuum'):
184185
air = wltype.capitalize()
@@ -196,8 +197,8 @@ def query_object_async(self, wavelength_range=None, wavelength_type='', waveleng
196197
raise ValueError('Invalid parameter "transitions": {0!r}'
197198
.format(transitions))
198199
if transitions is None:
199-
_type = self._default_form_values.get('type')
200-
type2 = self._default_form_values.get('type2')
200+
_type = default_values.get('type')
201+
type2 = default_values.get('type2')
201202
else:
202203
s = str(transitions)
203204
if len(s.split(',')) > 1:
@@ -219,7 +220,7 @@ def query_object_async(self, wavelength_range=None, wavelength_type='', waveleng
219220
if upper_level_erange is not None:
220221
upper_level_erange = upper_level_erange.to(
221222
u.cm ** -1, equivalencies=u.spectral()).value
222-
input = {
223+
input_payload = {
223224
'wavl': ' '.join(map(str, wlrange_in_angstroms)),
224225
'wave': 'Angstrom',
225226
'air': air,
@@ -241,12 +242,12 @@ def query_object_async(self, wavelength_range=None, wavelength_type='', waveleng
241242
'tptype': 'as_a',
242243
}
243244
if get_query_payload:
244-
return input
245-
response = self._submit_form(input, cache=cache)
245+
return input_payload
246+
response = self._submit_form(input_payload, cache=cache)
246247
return response
247248

248249
def _parse_result(self, response):
249-
data = StringIO(BeautifulSoup(response.text, 'html5').find('pre').text.strip())
250+
data = StringIO(BeautifulSoup(response.text, features='html5lib').find('pre').text.strip())
250251
# `header` is e.g.:
251252
# "u'-LAMBDA-VAC-ANG-|-SPECTRUM--|TT|--------TERM---------|---J-J---|----LEVEL-ENERGY--CM-1----'"
252253
# `colnames` is then
@@ -258,7 +259,7 @@ def _parse_result(self, response):
258259
colnames = [colname.strip('-').replace('-', ' ')
259260
for colname in header.split('|') if colname.strip()]
260261
indices = [i for i, c in enumerate(header) if c == '|']
261-
input = []
262+
result_data = []
262263
for line in data:
263264
row = []
264265
for start, end in zip([0] + indices, indices + [None]):
@@ -271,45 +272,46 @@ def _parse_result(self, response):
271272
# maintain table dimensions when data missing
272273
row.append('None')
273274
if row:
274-
input.append('\t'.join(row))
275-
if input:
276-
return ascii.read(input, data_start=0, delimiter='\t',
275+
result_data.append('\t'.join(row))
276+
if result_data:
277+
return ascii.read(result_data, data_start=0, delimiter='\t',
277278
names=colnames, fast_reader=False)
278279
else:
279280
# return an empty table if the query yielded no results
280281
return Table()
281282

282-
def _submit_form(self, input=None, cache=True):
283+
def _submit_form(self, input_data=None, cache=True):
283284
"""Fill out the form of the SkyView site and submit it with the
284-
values given in `input` (a dictionary where the keys are the form
285+
values given in ``input_data`` (a dictionary where the keys are the form
285286
element's names and the values are their respective values).
286287
287288
"""
288-
if input is None:
289-
input = {}
290-
# only overwrite payload's values if the `input` value is not None
289+
if input_data is None:
290+
input_data = {}
291+
# only overwrite payload's values if the ``input_data`` value is not None
291292
# to avoid overwriting of the form's default values
292-
payload = self._default_form_values.copy()
293-
for k, v in input.items():
293+
payload = self._default_form_values().copy()
294+
for k, v in input_data.items():
294295
if v is not None:
295296
payload[k] = v
296-
url = urlparse.urljoin(self.FORM_URL, self._default_form.get('action'))
297+
url = self._form_action_url
297298
log.debug(f"final payload = {payload} from url={url}")
298299
response = self._request("POST", url=url, data=payload,
299300
timeout=self.TIMEOUT, cache=cache)
300301
log.debug("Retrieved data from POST request")
301302
return response
302303

303-
@property
304304
def _default_form_values(self):
305-
306305
if self.__default_form_values is None:
307-
response = self._request("GET", url=self.FORM_URL, data={},
308-
timeout=self.TIMEOUT, cache=True)
309-
bs = BeautifulSoup(response.text, 'html5')
310-
self._default_form = form = bs.find('form')
311-
self.__default_form_values = self._get_default_form_values(form)
312-
306+
response = self._request("GET", url=self.FORM_URL, params={},
307+
timeout=self.TIMEOUT, cache=False)
308+
bs = BeautifulSoup(response.text, features='html5lib')
309+
form = bs.find('form')
310+
default_form_values = self._get_default_form_values(form)
311+
self._form_action_url = urlparse.urljoin(self.FORM_URL, form.get('action'))
312+
self.__default_form_values = default_form_values
313+
else:
314+
raise ValueError(self.__default_form_values)
313315
return self.__default_form_values
314316

315317
def _get_default_form_values(self, form):

0 commit comments

Comments
 (0)