diff options
author | Fabian Pedregosa <fabian.pedregosa@inria.fr> | 2010-11-17 04:46:20 +0100 |
---|---|---|
committer | Stefan van der Walt <stefan@sun.ac.za> | 2010-11-18 09:56:01 +0200 |
commit | f26fdc9afe40e4be40fc566542ca7342e57d2909 (patch) | |
tree | ebcfa212ccafc695cf05bd4699e240be588a6fc5 /numpy/lib/npyio.py | |
parent | 9d1c386cb515617235d12006b1adfad9ccf45d52 (diff) | |
download | numpy-f26fdc9afe40e4be40fc566542ca7342e57d2909.tar.gz |
BUG: GzipFile wrapper objects are not garbage collected (closes ticket #1356).
The underlying problem is that classes monkey-patched via
new.instancemethod will only free memory correctly if they do _not_
implement the __del__ method, which is not the case for gzip.GzipFile.
My proposed solution is to inherit from gzip.GzipFile and override
relevant methods instead of monkey-patching.
Diffstat (limited to 'numpy/lib/npyio.py')
-rw-r--r-- | numpy/lib/npyio.py | 50 |
1 files changed, 24 insertions, 26 deletions
diff --git a/numpy/lib/npyio.py b/numpy/lib/npyio.py index 016a9d48f..c9c02518b 100644 --- a/numpy/lib/npyio.py +++ b/numpy/lib/npyio.py @@ -36,36 +36,35 @@ def seek_gzip_factory(f): """ import gzip - def seek(self, offset, whence=0): - # figure out new position (we can only seek forwards) - if whence == 1: - offset = self.offset + offset + class GzipFile(gzip.GzipFile): - if whence not in [0, 1]: - raise IOError, "Illegal argument" + def seek(self, offset, whence=0): + # figure out new position (we can only seek forwards) + if whence == 1: + offset = self.offset + offset - if offset < self.offset: - # for negative seek, rewind and do positive seek - self.rewind() - count = offset - self.offset - for i in range(count // 1024): - self.read(1024) - self.read(count % 1024) + if whence not in [0, 1]: + raise IOError, "Illegal argument" - def tell(self): - return self.offset + if offset < self.offset: + # for negative seek, rewind and do positive seek + self.rewind() + count = offset - self.offset + for i in range(count // 1024): + self.read(1024) + self.read(count % 1024) - if isinstance(f, str): - f = gzip.GzipFile(f) + def tell(self): + return self.offset - if sys.version_info[0] >= 3: - import types - f.seek = types.MethodType(seek, f) - f.tell = types.MethodType(tell, f) - else: - import new - f.seek = new.instancemethod(seek, f) - f.tell = new.instancemethod(tell, f) + + if isinstance(f, str): + f = GzipFile(f) + elif isinstance(f, gzip.GzipFile): + # cast if its a gzip.GzipFile + mode = f.mode + f = GzipFile(filename=f.filename, fileobj=f.fileobj) + f.mode = mode return f @@ -664,7 +663,6 @@ def loadtxt(fname, dtype=float, comments='#', delimiter=None, if _is_string_like(fname): own_fh = True if fname.endswith('.gz'): - import gzip fh = seek_gzip_factory(fname) elif fname.endswith('.bz2'): import bz2 |