[pypy-svn] r78145 - in pypy/branch/fast-forward/pypy/module/_io: . test

afa at codespeak.net afa at codespeak.net
Wed Oct 20 18:24:24 CEST 2010


Author: afa
Date: Wed Oct 20 18:24:22 2010
New Revision: 78145

Modified:
   pypy/branch/fast-forward/pypy/module/_io/interp_iobase.py
   pypy/branch/fast-forward/pypy/module/_io/test/test_io.py
Log:
Add finalizer for IOBase (and all subclasses)


Modified: pypy/branch/fast-forward/pypy/module/_io/interp_iobase.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/_io/interp_iobase.py	(original)
+++ pypy/branch/fast-forward/pypy/module/_io/interp_iobase.py	Wed Oct 20 18:24:22 2010
@@ -16,6 +16,7 @@
         # XXX: IOBase thinks it has to maintain its own internal state in
         # `__IOBase_closed` and call flush() by itself, but it is redundant
         # with whatever behaviour a non-trivial derived class will implement.
+        self.space = space
         self.__IOBase_closed = False
 
     def _closed(self, space):
@@ -26,6 +27,20 @@
             return True
         return False
 
+    def __del__(self):
+        space = self.space
+        w_closed = space.findattr(self, space.wrap('closed'))
+        try:
+            # If `closed` doesn't exist or can't be evaluated as bool, then
+            # the object is probably in an unusable state, so ignore.
+            if w_closed is not None and not space.is_true(w_closed):
+                space.call_method(self, "close")
+        except OperationError:
+            # Silencing I/O errors is bad, but printing spurious tracebacks is
+            # equally as bad, and potentially more frequent (because of
+            # shutdown issues).
+            pass
+
     def _CLOSED(self):
         # Use this macro whenever you want to check the internal `closed`
         # status of the IOBase object rather than the virtual `closed`

Modified: pypy/branch/fast-forward/pypy/module/_io/test/test_io.py
==============================================================================
--- pypy/branch/fast-forward/pypy/module/_io/test/test_io.py	(original)
+++ pypy/branch/fast-forward/pypy/module/_io/test/test_io.py	Wed Oct 20 18:24:22 2010
@@ -42,6 +42,25 @@
         import _io
         e = _io.UnsupportedOperation("seek")
 
+    def test_destructor(self):
+        import io
+        io.IOBase()
+
+        record = []
+        class MyIO(io.IOBase):
+            def __del__(self):
+                record.append(1)
+                super(MyIO, self).__del__()
+            def close(self):
+                record.append(2)
+                super(MyIO, self).close()
+            def flush(self):
+                record.append(3)
+                super(MyIO, self).flush()
+        MyIO()
+        import gc; gc.collect()
+        assert record == [1, 2, 3]
+
 class AppTestOpen:
     def setup_class(cls):
         tmpfile = udir.join('tmpfile').ensure()



More information about the Pypy-commit mailing list