Repository navigation
Ignore errors about invalid headers when extra data are found at EOF - #11285
Conversation
|
Hello, thank you for the PR! I'm taking a look at it. |
|
Here's a way you can write a test for this that doesn't rely on # write some arbitrary data to a FITS file
fits.writeto(self.temp('temp.fits'), np.arange(100))
# append some arbitrary number of zeros to the end
with open(self.temp('temp.fits'), 'ab') as fobj:
fobj.write(b'\x00' * 1234)
# try to read the file
fits.info(self.temp('temp.fits'))This will reproduce the problem--please try rewriting the test something like that. |
| fits.open( | ||
| 'https://dataverse.harvard.edu/api/access/datafile/2439198', | ||
| cache=False | ||
| ) |
There was a problem hiding this comment.
The reason this test works for you interactively but not in the test suite, as that fits.open() doesn't actually immediately try to read the whole file (it is lazy).
When you do this at the interactive prompt it tries to represent the resulting HDUList object; i.e. it is the calling the equivalent of
_ = fits.open('...')
repr(_)
whereas here the return value of fits.open is simply ignored and not used. Try instead calling something that will force it to read the full file, like fits.info(). See also my earlier comment on how you can rewrite this test to reproduce the problem with an arbitrary file.
There was a problem hiding this comment.
Update: It turns out, ironically, calling fits.info() when the file contains trailing bytes does not reproduce the error, and instead results in the warning we want. I have to find out what is happening differently when calling fits.info().
There was a problem hiding this comment.
It turns out fits.info() passes ignore_missing_end=True by default, so it doesn't reproduce the error. Instead, try something like len(fits.open(self.temp('temp.fits'))). That does the trick.
There was a problem hiding this comment.
Thank you very much for all your explanations. I have modified the test accordingly.
There was a problem hiding this comment.
I have modified a bit your suggestion because in my previous version (without the with block), a RessourceWarning was thrown (the file wasn't closed).
| block = encode_ascii(block) | ||
|
|
||
| if not end_found and is_eof and endcard: | ||
| if not end_found and is_eof and endcard and is_header: |
There was a problem hiding this comment.
This is a perfect interpretation of what I wrote in #4351, though I think what I wrote there is not quite correct. Normally SIMPLE = is only in the first header of a FITS file. So if we were dealing with something like an accidentally truncated FITS file, the more likely thing you would see at the beginning of another header would be XTENSION =.
But I think I found a simpler solution to this problem. Instead of what you did, try moving the lines a bit below this:
header_str = ''.join(read_blocks)
_check_padding(header_str, actual_block_size, is_eof,
check_block_size=padding)to just before this line. As far as I can tell that also solves the problem, and doesn't break any existing tests. Please try out that solution and double-check me.
There was a problem hiding this comment.
Normally
SIMPLE =is only in the first header of a FITS file. So if we were dealing with something like an accidentally truncated FITS file, the more likely thing you would see at the beginning of another header would beXTENSION =.
You are right. I should have thought about that! Anyway, moving the check before the if statement works like a charm.
|
@cmarmo Thanks, looks good! Just needs a changelog entry, but if you'd like I can add that. |
|
@cmarmo - Could you please rebase on master ? This should fix the CI jobs. |
b7b9670 to
90625cb
Compare
|
I see that #11319 has been merged. Should I rebase to make the "32-bit and parallel" check pass? Thanks! |
|
@cmarmo - The failing test has been xfailed so I don't think we need to run again the CI. Looks good to me, so let's merge. Thanks for the useful contribution! |
Ignore errors about invalid headers when extra data are found at EOF
Ignore errors about invalid headers when extra data are found at EOF
|
Update: The backport of this cause CI failure in v4.2.x but surprisingly not v4.0.x. @saimn is investigating. |
With the backport of astropy#11285 on v4.2, a new warning is rasied and turned into an error. This doesn't happen on v4.0 because the way to catch warning changed (using pytest) and does not happen on master/4.3 because some new code was added to detect if the file is a valid FITS file.
Fix test failing after backport of #11285
Description
This pull request checks if extra data at the end of file contain the SIMPLE keyword, following @embray suggestion in the corresponding issue.
If extra data are not an header a warning is thrown
Fixes #4351
Additional information
I have added a test but:
https://dataverse.harvard.edu/api/access/datafile/2439198) and marked the test as remote_datagives the expected result. I'm clearly missing something about the way test are written or run...