Ver código fonte

Handle case where fileno() raises UnsupportedOperation on Python 3

Mike Naberezny 10 anos atrás
pai
commit
87b5ab3d93
2 arquivos alterados com 18 adições e 3 exclusões
  1. 9 3
      supervisor/loggers.py
  2. 9 0
      supervisor/tests/test_loggers.py

+ 9 - 3
supervisor/loggers.py

@@ -72,9 +72,15 @@ class Handler:
     def close(self):
         if not self.closed:
             if hasattr(self.stream, 'fileno'):
-                fd = self.stream.fileno()
-                if fd < 3: # don't ever close stdout or stderr
-                    return
+                try:
+                    fd = self.stream.fileno()
+                except IOError:
+                    # on python 3, io.IOBase objects always have fileno()
+                    # but calling it may raise io.UnsupportedOperation
+                    pass
+                else:
+                    if fd < 3: # don't ever close stdout or stderr
+                        return
             self.stream.close()
             self.closed = True
 

+ 9 - 0
supervisor/tests/test_loggers.py

@@ -9,6 +9,7 @@ import syslog
 
 from supervisor.compat import PY3
 from supervisor.compat import as_string
+from supervisor.compat import StringIO
 
 from supervisor.tests.base import mock
 from supervisor.tests.base import DummyStream
@@ -78,6 +79,14 @@ class BareHandlerTests(HandlerTests, unittest.TestCase):
         self.assertFalse(inst.closed)
         self.assertFalse(inst.stream.closed)
 
+    def test_close_stream_handles_fileno_unsupported_operation(self):
+        # on python 2, StringIO does not have fileno()
+        # on python 3, StringIO has fileno() but calling it raises
+        stream = StringIO()
+        inst = self._makeOne(stream=stream)
+        inst.close() # shouldn't raise
+        self.assertTrue(inst.closed)
+
     def test_emit_gardenpath(self):
         stream = DummyStream()
         inst = self._makeOne(stream=stream)