Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Don't close GzipFile before it is used #3893

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

Merged
merged 1 commit into from
Dec 12, 2014
Merged

Don't close GzipFile before it is used #3893

merged 1 commit into from
Dec 12, 2014

Conversation

cgohlke
Copy link
Contributor

@cgohlke cgohlke commented Dec 4, 2014

Fixes issue #1883 for me on Windows.

Consider the code at https://github.com/matplotlib/matplotlib/blob/master/lib/matplotlib/backends/backend_cairo.py#L478:

            if format == 'svgz':
                filename = fo
                if is_string_like(fo):
                    fo = open(fo, 'wb')
                    close = True
                else:
                    close = False
                try:
                    fo = gzip.GzipFile(None, 'wb', fileobj=fo)
                finally:
                    if close:
                        fo.close()

In case the GzipFile is created from the open file created with fo = open(fo, 'wb'):

  1. The GzipFile is always closed in the finally clause. Even though the GzipFile is closed, the open file passed to GzipFile as fileobj stays open. Later writes will be uncompressed (see https://docs.python.org/2/library/gzip.html#gzip.GzipFile). Does this produce valid svgz files?
  2. When the GzipFile is closed there is no reference to the open file left. Python can/will close the file at any time. Maybe that is the reason why on Windows the file is closed while on Linux it is still open.

The proposed changes should close all GzipFile and open file instances when/if necessary.

fo = gzip.GzipFile(None, 'wb', fileobj=fo)
finally:
if close:
fo.close()
surface = cairo.SVGSurface (fo, width_in_points, height_in_points)
Copy link
Member

Choose a reason for hiding this comment

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

while you are tinkering around in here, could you fix this extraneous space?

Copy link
Member

Choose a reason for hiding this comment

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

eh, on second thought, I am seeing a bunch of them in this file... maybe it needs a separate PEP8 PR

@WeatherGod
Copy link
Member

In general, I think this is fine. It would be nice to have some sort of with-clause use, but I don't see that being easy to do at the moment. I am just utterly flummox in how this code even worked in the past.
My only (slight) concern is in losing the reference to the original file object when passing it as a fileobj to GzipFile. I think, though, that GzipFile assumes all responsibility for the file object at that point, though.

@tacaswell tacaswell added this to the v1.4.3 milestone Dec 5, 2014
@tacaswell
Copy link
Member

@mdboom Added this code in 2011 in 4cb2aaa so I assume there was a good reason for it.

This looks like it is windows problem as I could not reproduce the original bug report. It still runs correctly on linux with py3.4.

[edit to correct word-salad]

tacaswell added a commit that referenced this pull request Dec 12, 2014
BUG : Don't close GzipFile before it is used
@tacaswell tacaswell merged commit edd4f86 into matplotlib:master Dec 12, 2014
@tacaswell
Copy link
Member

Looking at the gzip docs, https://docs.python.org/2/library/gzip.html#gzip.GzipFile, it looks like the close does not actually close the file, it just closes the compressed part. So it 'worked' on linux is that you still had an open file, but was sort of missing the point.

I think we are still leaking a file handle, but that should be dealt with separately.

tacaswell added a commit that referenced this pull request Dec 12, 2014
BUG : Don't close GzipFile before it is used
@tacaswell
Copy link
Member

cherry-picked as c02a515

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants