Skip to content

Commit

Permalink
add new FITSFormatError and raise for missing XTENSION
Browse files Browse the repository at this point in the history
can add more cases over time
  • Loading branch information
esheldon committed Aug 7, 2023
1 parent 429a023 commit 415132c
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 5 deletions.
10 changes: 10 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
version 1.2.1 (not yet released)
-------------

Changes

- raise new fitsio.FITSFormatError exception when we detect format
errors in a FITS file. Currently this only raises when extensions
are not properly marked with XTENSION but we can expand this over time


version 1.2.0
--------------

Expand Down
2 changes: 2 additions & 0 deletions fitsio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,5 @@

from . import util
from .util import cfitsio_version, FITSRuntimeWarning

from .fits_exceptions import FITSFormatError
10 changes: 10 additions & 0 deletions fitsio/fits_exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class FITSFormatError(Exception):
"""
Format error in FITS file
"""
def __init__(self, value):
super(FITSFormatError, self).__init__(value)
self.value = value

def __str__(self):
return str(self.value)
44 changes: 40 additions & 4 deletions fitsio/fitslib.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
ImageHDU, AsciiTableHDU, TableHDU,
_table_npy2fits_form, _npy2fits, _hdu_type_map)

from .fits_exceptions import FITSFormatError

# for python3 compat
if IS_PY3:
xrange = range
Expand Down Expand Up @@ -540,15 +542,33 @@ def movabs_ext(self, ext):
In general, it is not necessary to use this method explicitly.
"""
return self._FITS.movabs_hdu(ext+1)
return self.movabs_hdu(ext+1)

def movabs_hdu(self, hdunum):
"""
Move to the indicated one-offset hdu number.
In general, it is not necessary to use this method explicitly.
"""
return self._FITS.movabs_hdu(hdunum)

format_err = False

try:
hdu_type = self._FITS.movabs_hdu(hdunum)
except IOError as err:
# to support python 2 we can't use exception chaining.
# do this to avoid "During handling of the above exception, another
# exception occurred:"
serr = str(err)
if 'first keyword not XTENSION' in serr:
format_err = True
else:
raise

if format_err:
raise FITSFormatError(serr)

return hdu_type

def movnam_ext(self, extname, hdutype=ANY_HDU, extver=0):
"""
Expand All @@ -570,8 +590,24 @@ def movnam_hdu(self, extname, hdutype=ANY_HDU, extver=0):
returns the one-offset extension number
"""
format_err = False

extname = mks(extname)
hdu = self._FITS.movnam_hdu(hdutype, extname, extver)
try:
hdu = self._FITS.movnam_hdu(hdutype, extname, extver)
except IOError as err:
# to support python 2 we can't use exception chaining.
# do this to avoid "During handling of the above exception, another
# exception occurred:"
serr = str(err)
if 'first keyword not XTENSION' in serr:
format_err = True
else:
raise

if format_err:
raise FITSFormatError(serr)

return hdu

def reopen(self):
Expand Down Expand Up @@ -1302,7 +1338,7 @@ def _append_hdu_info(self, ext):
"""

# raised IOError if not found
hdu_type = self._FITS.movabs_hdu(ext+1)
hdu_type = self.movabs_ext(ext)

if hdu_type == IMAGE_HDU:
hdu = ImageHDU(self._FITS, ext)
Expand Down
23 changes: 22 additions & 1 deletion fitsio/tests/test_header_junk.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import os
import tempfile
from ..fitslib import read_header
import pytest
from ..fitslib import read_header, FITS
from ..fits_exceptions import FITSFormatError


def test_header_junk():
Expand Down Expand Up @@ -43,3 +45,22 @@ def test_Header_Junk_Non_Ascii():

h = read_header(fname)
assert h["@_@_"] is None


def test_missing_xtension_keyword():
"""
Misformatted header with extension not properly marked with
XTENSION
"""

data=b"""SIMPLE = T / This is a FITS file BITPIX = 8 / NAXIS = 0 / EXTEND = T / This file may contain FITS extensions NEXTEND = 7 / Number of extensions END SIMPLE = T / file does conform to FITS standard BITPIX = 32 / number of bits per data pixel NAXIS = 2 / number of data axes NAXIS1 = 30 / length of data axis 1 NAXIS2 = 30 / length of data axis 2 EXTEND = T / FITS dataset may contain extensions END """ # noqa

with tempfile.TemporaryDirectory() as tmpdir:
fname = os.path.join(tmpdir, 'test.fits')

with open(fname, 'wb') as fobj:
fobj.write(data)

with pytest.raises(FITSFormatError):
with FITS(fname) as fits:
print(fits)

0 comments on commit 415132c

Please sign in to comment.