From e97a24d06a09bfda5b1bec41ecbbbeff63a9e492 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Sun, 21 Oct 2012 14:09:05 +0200 Subject: [PATCH] Issue #16220: wsgiref now always calls close() on an iterable response. Patch by Brent Tubbs. --- Lib/test/test_wsgiref.py | 50 +++++++++++++++------------------------- Lib/wsgiref/handlers.py | 12 ++++++---- Misc/ACKS | 1 + Misc/NEWS | 3 +++ 4 files changed, 30 insertions(+), 36 deletions(-) diff --git a/Lib/test/test_wsgiref.py b/Lib/test/test_wsgiref.py index 45ca620c3a..123eae8b30 100644 --- a/Lib/test/test_wsgiref.py +++ b/Lib/test/test_wsgiref.py @@ -591,40 +591,28 @@ class HandlerTests(TestCase): (stdpat%(version,sw), h.stdout.getvalue()) ) -# This epilogue is needed for compatibility with the Python 2.5 regrtest module + def testCloseOnError(self): + side_effects = {'close_called': False} + MSG = b"Some output has been sent" + def error_app(e,s): + s("200 OK",[])(MSG) + class CrashyIterable(object): + def __iter__(self): + while True: + yield b'blah' + raise AssertionError("This should be caught by handler") + + def close(self): + side_effects['close_called'] = True + return CrashyIterable() + + h = ErrorHandler() + h.run(error_app) + self.assertEqual(side_effects['close_called'], True) + def test_main(): test_support.run_unittest(__name__) if __name__ == "__main__": test_main() - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# the above lines intentionally left blank diff --git a/Lib/wsgiref/handlers.py b/Lib/wsgiref/handlers.py index ae1e8cc437..8cb57e223a 100644 --- a/Lib/wsgiref/handlers.py +++ b/Lib/wsgiref/handlers.py @@ -122,11 +122,13 @@ class BaseHandler: in the event loop to iterate over the data, and to call 'self.close()' once the response is finished. """ - if not self.result_is_file() or not self.sendfile(): - for data in self.result: - self.write(data) - self.finish_content() - self.close() + try: + if not self.result_is_file() or not self.sendfile(): + for data in self.result: + self.write(data) + self.finish_content() + finally: + self.close() def get_scheme(self): diff --git a/Misc/ACKS b/Misc/ACKS index ecd52e0bf6..958951f0f5 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -985,6 +985,7 @@ Richard Townsend Laurence Tratt John Tromp Jason Trowbridge +Brent Tubbs Anthony Tuininga David Turner Stephen Turner diff --git a/Misc/NEWS b/Misc/NEWS index d87b9ed7dc..7e91943cea 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -122,6 +122,9 @@ Core and Builtins Library ------- +- Issue #16220: wsgiref now always calls close() on an iterable response. + Patch by Brent Tubbs. + - Issue #16176: Properly identify Windows 8 via platform.platform() - Issue #15756: subprocess.poll() now properly handles errno.ECHILD to -- 2.49.0