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

Ensure file is closed promptly in case of error #35587

Merged
merged 1 commit into from
Sep 13, 2020
Merged

Ensure file is closed promptly in case of error #35587

merged 1 commit into from
Sep 13, 2020

Conversation

rxxg
Copy link
Contributor

@rxxg rxxg commented Aug 6, 2020

Fixes #35566. Replaces #35567.

@rxxg
Copy link
Contributor Author

rxxg commented Aug 6, 2020

Not quite sure how the test failure is going to work in this case: previous issues (e.g. #13932) mention ResourceWarnings but I don't have time to set up a full local build environment to duplicate the tests. @jreback do you have any insight from a few years back?

@simonjayhawkins simonjayhawkins added Bug IO SAS SAS: read_sas labels Aug 6, 2020
@simonjayhawkins simonjayhawkins added this to the 1.1.1 milestone Aug 6, 2020
@simonjayhawkins
Copy link
Member

copied the milestone from #35567. feel free to amend as appropriate.

Copy link
Contributor

@jreback jreback left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add a whatsnew note in 1.2, bug fix section for I/O

@simonjayhawkins simonjayhawkins modified the milestones: 1.1.1, 1.2 Aug 7, 2020
@pep8speaks
Copy link

pep8speaks commented Aug 7, 2020

Hello @rxxg! Thanks for updating this PR. We checked the lines you've touched for PEP 8 issues, and found:

There are currently no PEP 8 issues detected in this Pull Request. Cheers! 🍻

Comment last updated at 2020-09-05 11:01:11 UTC

@rxxg
Copy link
Contributor Author

rxxg commented Aug 7, 2020

Added the What's New note.
I also added a try/except to ensure correctness under more circumstances, but it raised two PEP8 flags (which I silenced). Happy to discuss my justification.

self._read_header()
try:
self._read_header()
except: # noqa: E722 OK because exception re-raised
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

never use bare exceptions, use

try:
   ....
except Exception:
   # close on error reading header...
   ....

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can do that, but what about errors that don't inherit from Exception?
I note that the PEP says:

A good rule of thumb is to limit use of bare 'except' clauses to two cases:
If the exception handler will be printing out or logging the traceback; at least the user will be aware that an error has occurred.
If the code needs to do some cleanup work, but then lets the exception propagate upwards with raise. try...finally can be a better way to handle this case.

(try...finally obviously isn't applicable here since we only want to close on error)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

simply use Exception

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I note that exceptions that don't inherit from Exception are supposed to be system-exiting, so we can suppose some higher-level process will clean up for us in this case.

@rxxg rxxg requested a review from jreback August 31, 2020 14:11
@rxxg rxxg requested a review from WillAyd September 8, 2020 06:13
@WillAyd
Copy link
Member

WillAyd commented Sep 8, 2020

/azp run

@azure-pipelines
Copy link
Contributor

Azure Pipelines successfully started running 1 pipeline(s).

@jbrockmendel
Copy link
Member

I'm fine with this implementation, but curious: wouldnt the idiomatic way to do this be with a contextmanager?

reader.close()
return data
try:
return reader.read()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this needed that you are catching error (and closing) at the lower level? maybe only catch here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The close at the lower level (sas7bdat.py, sas_xport.py) is to match with the get_filepath_or_buffer call 10 lines earlier, and also with various calls to close scatter around those files.
It is possible (if both 'lower level' file are only ever used via sasreader.py) that all close calls are unnecessary lower down, but I don't think they do any harm so I would prefer to leave the code symmetrical for the moment (open/close) and potentially get rid of all the close calls in a separate PR.
What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok fair enough

Copy link
Contributor

@jreback jreback left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks @rxxg happy to take a followup to see if you can remove the lower level try/excepts

reader.close()
return data
try:
return reader.read()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok fair enough

@jreback jreback merged commit 5ad15f8 into pandas-dev:master Sep 13, 2020
kesmit13 pushed a commit to kesmit13/pandas that referenced this pull request Nov 2, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug IO SAS SAS: read_sas
Projects
None yet
Development

Successfully merging this pull request may close these issues.

BUG: corrupted SAS datasets retain file handles
6 participants