Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MAINT: drop python 3.8 support #639

Merged
merged 4 commits into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions .github/workflows/ci_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion pyvo/auth/authsession.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class AuthSession:
"""

def __init__(self):
super(AuthSession, self).__init__()
super().__init__()
self.credentials = CredentialStore()
self._auth_urls = AuthURLs()

Expand Down
5 changes: 2 additions & 3 deletions pyvo/auth/authurls.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 = []
Expand Down
2 changes: 1 addition & 1 deletion pyvo/auth/credentialstore.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions pyvo/dal/adhoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -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_):
"""
Expand All @@ -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):
Expand Down Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions pyvo/dal/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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")
Expand Down
2 changes: 1 addition & 1 deletion pyvo/dal/mimetype.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
14 changes: 7 additions & 7 deletions pyvo/dal/params.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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])
Expand All @@ -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
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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):
Expand Down
12 changes: 6 additions & 6 deletions pyvo/dal/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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):
"""
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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()
Expand All @@ -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
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion pyvo/dal/sia2.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
28 changes: 14 additions & 14 deletions pyvo/dal/tap.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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()
Expand All @@ -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')
Expand Down Expand Up @@ -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()
Expand All @@ -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
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand All @@ -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
)
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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):
"""
Expand Down
Loading
Loading