Author: Philip Jenvey <[email protected]>
Branch: py3k
Changeset: r60890:0a5251c5e487
Date: 2013-02-05 16:28 -0800
http://bitbucket.org/pypy/pypy/changeset/0a5251c5e487/

Log:    add _io Warnings

diff --git a/pypy/module/_io/interp_bufferedio.py 
b/pypy/module/_io/interp_bufferedio.py
--- a/pypy/module/_io/interp_bufferedio.py
+++ b/pypy/module/_io/interp_bufferedio.py
@@ -104,6 +104,9 @@
         rwbuffer.setslice(0, data)
         return space.wrap(len(data))
 
+    def _complain_about_max_buffer_size(self, space):
+        space.warn("max_buffer_size is deprecated", space.w_DeprecationWarning)
+
 W_BufferedIOBase.typedef = TypeDef(
     '_io._BufferedIOBase', W_IOBase.typedef,
     __new__ = generic_new_descr(W_BufferedIOBase),
@@ -316,6 +319,9 @@
         with self.lock:
             space.call_method(self.w_raw, "close")
 
+    def _dealloc_warn_w(self, space, w_source):
+        space.call_method(self.w_raw, "_dealloc_warn", w_source)
+
     def simple_flush_w(self, space):
         self._check_init(space)
         return space.call_method(self.w_raw, "flush")
@@ -810,14 +816,18 @@
     truncate = interp2app(W_BufferedReader.truncate_w),
     fileno = interp2app(W_BufferedReader.fileno_w),
     isatty = interp2app(W_BufferedReader.isatty_w),
+    _dealloc_warn = interp2app(W_BufferedReader._dealloc_warn_w),
     closed = GetSetProperty(W_BufferedReader.closed_get_w),
     name = GetSetProperty(W_BufferedReader.name_get_w),
     mode = GetSetProperty(W_BufferedReader.mode_get_w),
 )
 
 class W_BufferedWriter(BufferedMixin, W_BufferedIOBase):
-    @unwrap_spec(buffer_size=int)
-    def descr_init(self, space, w_raw, buffer_size=DEFAULT_BUFFER_SIZE):
+    @unwrap_spec(buffer_size=int, max_buffer_size=int)
+    def descr_init(self, space, w_raw, buffer_size=DEFAULT_BUFFER_SIZE,
+                   max_buffer_size=-234):
+        if max_buffer_size != -234:
+            self._complain_about_max_buffer_size(space)
         self.state = STATE_ZERO
         check_writable_w(space, w_raw)
 
@@ -851,6 +861,7 @@
     isatty = interp2app(W_BufferedWriter.isatty_w),
     detach = interp2app(W_BufferedWriter.detach_w),
     truncate = interp2app(W_BufferedWriter.truncate_w),
+    _dealloc_warn = interp2app(W_BufferedWriter._dealloc_warn_w),
     closed = GetSetProperty(W_BufferedWriter.closed_get_w),
     name = GetSetProperty(W_BufferedWriter.name_get_w),
     mode = GetSetProperty(W_BufferedWriter.mode_get_w),
@@ -876,10 +887,12 @@
     w_reader = None
     w_writer = None
 
-    @unwrap_spec(buffer_size=int)
+    @unwrap_spec(buffer_size=int, max_buffer_size=int)
     def descr_init(self, space, w_reader, w_writer, 
-                   buffer_size=DEFAULT_BUFFER_SIZE):
+                   buffer_size=DEFAULT_BUFFER_SIZE, max_buffer_size=-234):
         try:
+            if max_buffer_size != -234:
+                self._complain_about_max_buffer_size(space)
             self.w_reader = W_BufferedReader(space)
             self.w_reader.descr_init(space, w_reader, buffer_size)
             self.w_writer = W_BufferedWriter(space)
@@ -931,10 +944,13 @@
 )
 
 class W_BufferedRandom(BufferedMixin, W_BufferedIOBase):
-    @unwrap_spec(buffer_size=int)
-    def descr_init(self, space, w_raw, buffer_size=DEFAULT_BUFFER_SIZE):
+    @unwrap_spec(buffer_size=int, max_buffer_size=int)
+    def descr_init(self, space, w_raw, buffer_size=DEFAULT_BUFFER_SIZE,
+                   max_buffer_size=-234):
+        if max_buffer_size != -234:
+            self._complain_about_max_buffer_size(space)
+
         self.state = STATE_ZERO
-
         check_readable_w(space, w_raw)
         check_writable_w(space, w_raw)
         check_seekable_w(space, w_raw)
@@ -975,6 +991,7 @@
     truncate = interp2app(W_BufferedRandom.truncate_w),
     fileno = interp2app(W_BufferedRandom.fileno_w),
     isatty = interp2app(W_BufferedRandom.isatty_w),
+    _dealloc_warn = interp2app(W_BufferedRandom._dealloc_warn_w),
     closed = GetSetProperty(W_BufferedRandom.closed_get_w),
     name = GetSetProperty(W_BufferedRandom.name_get_w),
     mode = GetSetProperty(W_BufferedRandom.mode_get_w),
diff --git a/pypy/module/_io/interp_fileio.py b/pypy/module/_io/interp_fileio.py
--- a/pypy/module/_io/interp_fileio.py
+++ b/pypy/module/_io/interp_fileio.py
@@ -246,6 +246,16 @@
         self._close(space)
         W_RawIOBase.close_w(self, space)
 
+    def _dealloc_warn_w(self, space, w_source):
+        if self.fd >= 0 and self.closefd:
+            try:
+                r = space.unicode_w(space.repr(w_source))
+                space.warn("unclosed file %s" % r, space.w_ResourceWarning)
+            except OperationError as e:
+                # Spurious errors can appear at shutdown
+                if e.match(space, space.w_Warning):
+                    e.write_unraisable(space, '', space.wrap(self))
+
     def _dircheck(self, space, w_filename):
         # On Unix, fopen will succeed for directories.
         # In Python, there should be no file objects referring to
@@ -443,6 +453,7 @@
     seekable = interp2app(W_FileIO.seekable_w),
     fileno = interp2app(W_FileIO.fileno_w),
     isatty = interp2app(W_FileIO.isatty_w),
+    _dealloc_warn = interp2app(W_FileIO._dealloc_warn_w),
     name = interp_member_w('w_name', cls=W_FileIO),
     closefd = interp_attrproperty(
         'closefd', cls=W_FileIO,
diff --git a/pypy/module/_io/interp_iobase.py b/pypy/module/_io/interp_iobase.py
--- a/pypy/module/_io/interp_iobase.py
+++ b/pypy/module/_io/interp_iobase.py
@@ -71,7 +71,10 @@
             # 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")
+                try:
+                    self._dealloc_warn_w(space, space.wrap(self))
+                finally:
+                    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
@@ -109,6 +112,10 @@
             self.__IOBase_closed = True
             get_autoflushher(space).remove(self)
 
+    def _dealloc_warn_w(self, space, w_source):
+        """Called when the io is implicitly closed via the deconstructor"""
+        pass
+
     def flush_w(self, space):
         if self._CLOSED():
             raise OperationError(
diff --git a/pypy/module/_io/interp_textio.py b/pypy/module/_io/interp_textio.py
--- a/pypy/module/_io/interp_textio.py
+++ b/pypy/module/_io/interp_textio.py
@@ -503,6 +503,9 @@
             space.call_method(self, "flush")
             return space.call_method(self.w_buffer, "close")
 
+    def _dealloc_warn_w(self, space, w_source):
+        space.call_method(self.w_buffer, "_dealloc_warn", w_source)
+
     # _____________________________________________________________
     # read methods
 
@@ -1007,6 +1010,7 @@
     writable = interp2app(W_TextIOWrapper.writable_w),
     seekable = interp2app(W_TextIOWrapper.seekable_w),
     fileno = interp2app(W_TextIOWrapper.fileno_w),
+    _dealloc_warn = interp2app(W_TextIOWrapper._dealloc_warn_w),
     name = GetSetProperty(W_TextIOWrapper.name_get_w),
     buffer = interp_attrproperty_w("w_buffer", cls=W_TextIOWrapper),
     closed = GetSetProperty(W_TextIOWrapper.closed_get_w),
diff --git a/pypy/module/_io/test/test_bufferedio.py 
b/pypy/module/_io/test/test_bufferedio.py
--- a/pypy/module/_io/test/test_bufferedio.py
+++ b/pypy/module/_io/test/test_bufferedio.py
@@ -613,6 +613,31 @@
                 assert raw.getvalue() == b'1b\n2def\n3\n'
 
 
+class AppTestDeprecation:
+
+    def w_check_max_buffer_size_deprecation(self, test):
+        import _io
+        import _warnings
+        def simplefilter(action, category):
+            _warnings.filters.insert(0, (action, None, category, None, 0))
+        simplefilter('error', DeprecationWarning)
+        try:
+            test(_io.BytesIO(), 8, 12)
+        except DeprecationWarning as e:
+            assert 'max_buffer_size is deprecated' in str(e)
+        else:
+            assert False, 'Expected DeprecationWarning'
+        finally:
+            simplefilter('default', DeprecationWarning)
+
+    def test_max_buffer_size_deprecation(self):
+        import _io
+        self.check_max_buffer_size_deprecation(_io.BufferedWriter)
+        self.check_max_buffer_size_deprecation(_io.BufferedRandom)
+        self.check_max_buffer_size_deprecation(
+            lambda raw, *args: _io.BufferedRWPair(raw, raw, *args))
+
+
 class TestNonReentrantLock:
     spaceconfig = dict(usemodules=['thread'])
 
diff --git a/pypy/module/_io/test/test_io.py b/pypy/module/_io/test/test_io.py
--- a/pypy/module/_io/test/test_io.py
+++ b/pypy/module/_io/test/test_io.py
@@ -333,3 +333,21 @@
             assert res == "world\n"
             assert f.newlines == "\n"
             assert type(f.newlines) is str
+
+    def w__check_warn_on_dealloc(self, *args, **kwargs):
+        import gc
+        import warnings
+
+        f = open(*args, **kwargs)
+        r = repr(f)
+        with warnings.catch_warnings(record=True) as w:
+            warnings.simplefilter('always')
+            f = None
+            gc.collect()
+        assert len(w) == 1, len(w)
+        assert r in str(w[0])
+
+    def test_warn_on_dealloc(self):
+        self._check_warn_on_dealloc(self.tmpfile, 'wb', buffering=0)
+        self._check_warn_on_dealloc(self.tmpfile, 'wb')
+        self._check_warn_on_dealloc(self.tmpfile, 'w')
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to