[Python-Dev] Why does IOBase.__del__ call .close?

Benjamin Peterson benjamin at python.org
Fri Jun 13 07:27:49 CEST 2014


On Thu, Jun 12, 2014, at 18:06, Nikolaus Rath wrote:
> Consider this simple example:
> 
> $ cat test.py 
> import io
> import warnings
> 
> class StridedStream(io.IOBase):
>     def __init__(self, name, stride=2):
>         super().__init__()
>         self.fh = open(name, 'rb')
>         self.stride = stride
> 
>     def read(self, len_):
>         return self.fh.read(self.stride*len_)[::self.stride]
> 
>     def close(self):
>         self.fh.close()
> 
> class FixedStridedStream(StridedStream):
>     def __del__(self):
>         # Prevent IOBase.__del__ frombeing called.
>         pass
> 
> warnings.resetwarnings()
> warnings.simplefilter('error')
> 
> print('Creating & loosing StridedStream..')
> r = StridedStream('/dev/zero')
> del r
> 
> print('Creating & loosing FixedStridedStream..')
> r = FixedStridedStream('/dev/zero')
> del r
> 
> $ python3 test.py 
> Creating & loosing StridedStream..
> Creating & loosing FixedStridedStream..
> Exception ignored in: <_io.FileIO name='/dev/zero' mode='rb'>
> ResourceWarning: unclosed file <_io.BufferedReader name='/dev/zero'>
> 
> In the first case, the destructor inherited from IOBase actually
> prevents the ResourceWarning from being emitted.

Ah, I see. I don't see any good ways to fix it, though, besides setting
some flag if close() is called from __del__.


More information about the Python-Dev mailing list