Repository navigation
Fix fitscheck and checksums correction - #6571
Conversation
|
Hi there @saimn 👋 - thanks for the pull request! I'm just a friendly 🤖 that checks for issues related to the changelog and making sure that this pull request is milestoned and labelled correctly. This is mainly intended for the maintainers, so if you are not a maintainer you can ignore this, and a maintainer will let you know if any action is required on your part 😃. Everything looks good from my point of view! 👍 |
|
Could you refactor the removal of nonstandard into another PR? If yes, then this can go into 2.0.x, otherwise I would say 3.0 |
|
The Even though some test failures are unrelated some seem real, any idea why? |
|
For test failures, I think there is a bad interaction between logging and the capsys plugin. I'm trying another option to capture the output. |
|
Hmm, of course the subprocess way cannot work since entrypoints are not installed in the temporary directory... |
|
|
||
|
|
||
| class TestFitscheck(FitsTestCase): | ||
| # def setup(self): |
There was a problem hiding this comment.
Just as a reminder to remove this commented code again ... later.
There was a problem hiding this comment.
Oops yeah, once I find a proper way to capture stderr I will cleanup 😉
There was a problem hiding this comment.
That's what capsys do, but it was failing : there are issues specific to windows and capturing stderr (and it still fails with the last try), and probably a real failure on python 2 (on CircleCI).
There was a problem hiding this comment.
Ah, do you know which commit (test log would be interesting) that was?
There was a problem hiding this comment.
The commit using capsys is 316fef2 , and appveyor is linked below.
|
Most of the changes look fine, but I've skipped the docs for now. I'm really not sure what's a good way to check for emitted Maybe @astrofrog or @bsipocz know a more elegant way? |
|
@MSeifert04 - In case you are interested in the windows failures, this is the build when using It seems that redirecting stderr prevents the logger to work correctly. |
|
That's interesting because it seems to work with |
|
One difference with |
|
FWIW it does include API change, so maybe should just be in v3 (one more reason for people to upgrade). c/c @jaytmiller |
|
Oh, Windows .... Aside from the logging issue, there is also one with the |
|
I really don't know what's the problem there. It seems like a weird interaction between The interesting question is: Is that windows specific or a real issue? |
- Remove unused _checksum_comment and _datasum_comment attributes - Add _datasum_valid and _checksum_valid to store the validity flag computed when the file is opened. And use this to know if the checksums are valid or must be recomputed when writing.
|
Rebased and tests pass (I skipped the stderr based checks on win32), so please review @MSeifert04 (and @drdavella ?).
Not sure, there is clearly something specific to windows. When running tests with the pytest capture mode disable ( |
|
Re: Windows. Maybe I should test this on my Windows laptop before merge? |
| return 1 | ||
|
|
||
| for w in wlist: | ||
| if str(w.message).startswith(('Checksum verification failed', |
There was a problem hiding this comment.
This would maybe be a bit cleaner if we used a new warning subclass for all FITS checksum problems instead of just AstropyUserWarning. In that case the new warning class could be passed to catch_warnings above.
| if str(w.message).startswith(('Checksum verification failed', | ||
| 'Datasum verification failed')): | ||
| log.warning('BAD %r %s', filename, str(w.message)) | ||
| return 1 |
There was a problem hiding this comment.
I realize this is the same behavior as the old code, but wouldn't it be more useful to not fail immediately after the first problem is encountered so that all checksum problems are reported? The same goes for the loop above that looks for missing checksums.
| """ | ||
|
|
||
| hdulist = fits.open(filename, do_not_scale_image_data=True) | ||
| tmpfile = filename + '.bak' |
There was a problem hiding this comment.
Would python's tempfile module be useful here?
There was a problem hiding this comment.
No strong preference for me (I did that quickly to debug the windows issue). One advantage of not using /tmp is that it can avoid a copy to another disk, e.g. if your data is on a NFS share.
There was a problem hiding this comment.
It's really bugging me that we need a temporary file at all. Is there no way to run a complete check without actually writing it to a file? Or is the intention here to fix the problems?
Sorry I haven't had the chance to look into this more closely, but I'll do so next week.
There was a problem hiding this comment.
The goal here is to update the file with new checksums, and windows does not allow to overwrite the file while it is open.
There was a problem hiding this comment.
Then why not read, close then write?
There was a problem hiding this comment.
Because there is no nice way to force reading the data (you need to iterate on all HDUs and access the .data attribute). The other (better) option would be to use the update mode and .flush, I think it can handle the checksums, but there may be a good reason why it is not used. So, at least for now, the tmp file and replace solution seems the most straightforward.
| self._datasum_comment = self._header.comments['DATASUM'] | ||
|
|
||
| if not self.verify_datasum(blocking): | ||
| self._datasum_valid = self.verify_datasum() |
There was a problem hiding this comment.
The datasum gets computed twice since it is also computed within verify_checksum. It would be nice if there was a way to store the datasum value between calls so that it does not have to be recomputed.
| self._checksum_comment = self._header.comments['CHECKSUM'] | ||
| if not self.verify_checksum(blocking): | ||
| self._checksum_valid = self.verify_checksum() | ||
| if not self._checksum_valid: |
There was a problem hiding this comment.
The code is correct, and it's perfectly valid Python, but in terms of style and clarity it bothers me a little bit that _checksum_valid and _datasum_valid are being used as booleans, even though verify_checksumreturns integer values. It would be a little more explicit to have the line above be something like
self._checksum_valid = self._verify_checksum() == 1
Even better would to have named constants for the return values of verify_checksum and verify_datasum:
CHECKSUM_INVALID = 0
CHECKSUM_VALID = 1
CHECKSUM_MISSING = 2
| @@ -526,25 +526,13 @@ def _update_checksum(self, checksum, checksum_keyword='CHECKSUM', | |||
| del self._header[datasum_keyword] | |||
| elif (modified or self._new or | |||
| (checksum and ('CHECKSUM' not in self._header or | |||
There was a problem hiding this comment.
It's not really clear to me, but should 'CHECKSUM' and 'DATASUM' instead be checksum_keyword and datasum_keyword?
| # used by the utility script "fitscheck" to detect missing | ||
| # checksums. | ||
|
|
||
| if 'CHECKSUM' in self._header: |
There was a problem hiding this comment.
Not a big problem, but it would be nice to avoid doing this check more than once since it also happens in verify_checksum. This could potentially be refactored since verify_checksum will return 2 if the 'CHECKSUM' keyword is missing. Same goes for the check for 'DATASUM' below.
|
@saimn these changes look good and I don't think there are any issues that would block a merge. I have a lot of comments that are mostly unrelated to your changes but instead relate to the overall state of this code. Like most of the FITS code, it could stand to be improved. In general, I wonder if every PR that involves FITS code should be used as an opportunity to clean up the code that is being touched, even if it does not directly affect the issue being addressed. I realize this makes reviews more difficult, but if we don't make some attempt to incrementally improve this code, it is going to continue to be very difficult to maintain. |
That is a bit too ambitious. I propose that we table that thought until we have an official lead maintainer for |
|
@drdavella - Your remarks are valid, but I tried to stay close to the original code as the goal is to fix the bugs and test that it works. I was also hoping to backport this to v2.0.x (it should be feasible, not sure I will do it though). |
|
@saimn, if you want me to test this on my Windows laptop, just let me know. Sounds like this PR still might change, so I'll hold off for now. |
|
@pllim - Yes if you want to, it would be useful! (you need to remove the |
|
I'll also have a look at the windows issues (although next week). I don't think it's a particular problem with the PR. I suspect that |
|
So... I can't reproduce this on my Windows laptop. >>> import sys
>>> sys.platform
'win32'I changed And Let's wait and see what @MSeifert04 find on his side. |
|
@saimn, @pllim, you're both right of course; I was just trying to think of ways that we could possibly reduce the maintenance burden of I can approve the review if needed but maybe we should wait for @MSeifert04. |
|
@saimn Could you undo the |
|
Thanks for the test @pllim, interesting result! It may then be specific to appveyor. @MSeifert04 - I have only my phone until tomorrow, but I guess you could find the failing build in appveyor history, or you can update my branch if you prefer. But it may not be useful to spend too much time on this issue: fitscheck is tested on other platforms, and the checksum code is tested as well. My only worry is that testing only the error numbers is fragile, but it should be ok. |
|
As far as I can see there was no build with the |
MSeifert04
left a comment
There was a problem hiding this comment.
LGTM!
I still think the write to temporary and then replace is kind of ugly but I don't think it should hold up the PR. If you have an idea how it could be solved differently feel free to address this. Otherwise I'm also fine if we leave it as-is.
Oh great! You're right I probably didn't test this on Appveyor after fixing the file update.
Agreed about the ugliness, as said above I think |
|
It seems to work, good news 😂 ! And the test failure is not related (see #6604), so let's move forward ? ( @MSeifert04 - it seems you have new powers, if you want to press on the green button ? 🙏 ) |
|
Thanks @saimn ! I really like the |

Fix #6530, #5902, #5874, and replaces #5875
nonstandardoption (ref fitscheck checksum corrections don't work #6530 (comment))errormode also means that the files could not be opened without errors to be fixed. Then it was not possible to write new checksum replacing invalid one, so now I store the result of the verification to know if the checksum must be overwritten.It's mostly bugfixes, so should go to v2.0, but I also removed the
nonstandardoption, so not sure... thoughts @pllim @MSeifert04 @bsipocz ?