]> granicus.if.org Git - python/commitdiff
#21476: Unwrap fp in BytesParser so the file isn't unexpectedly closed.
authorR David Murray <rdmurray@bitdance.com>
Thu, 26 Jun 2014 17:31:43 +0000 (13:31 -0400)
committerR David Murray <rdmurray@bitdance.com>
Thu, 26 Jun 2014 17:31:43 +0000 (13:31 -0400)
This makes the behavior match that of Parser.  Patch by Vajrasky Kok.

Lib/email/parser.py
Lib/test/test_email/test_email.py
Misc/NEWS

index 9f5f95dfba4721f1737bc702d9fccd7bffbe4b97..8c9bc9e44e24a75a85d9f16b874d3ed875fe5fc9 100644 (file)
@@ -106,8 +106,10 @@ class BytesParser:
         meaning it parses the entire contents of the file.
         """
         fp = TextIOWrapper(fp, encoding='ascii', errors='surrogateescape')
-        with fp:
+        try:
             return self.parser.parse(fp, headersonly)
+        finally:
+            fp.detach()
 
 
     def parsebytes(self, text, headersonly=False):
index 2f89a10e0a736153553aaf8efaf37fa74ff1f8dd..af8bc7bf9526bdc4c86074a0998cf675d3ad1043 100644 (file)
@@ -3390,6 +3390,31 @@ class TestParsers(TestEmailBase):
         self.assertIsInstance(msg.get_payload(), str)
         self.assertIsInstance(msg.get_payload(decode=True), bytes)
 
+    def test_bytes_parser_does_not_close_file(self):
+        with openfile('msg_02.txt', 'rb') as fp:
+            email.parser.BytesParser().parse(fp)
+            self.assertFalse(fp.closed)
+
+    def test_bytes_parser_on_exception_does_not_close_file(self):
+        with openfile('msg_15.txt', 'rb') as fp:
+            bytesParser = email.parser.BytesParser
+            self.assertRaises(email.errors.StartBoundaryNotFoundDefect,
+                              bytesParser(policy=email.policy.strict).parse,
+                              fp)
+            self.assertFalse(fp.closed)
+
+    def test_parser_does_not_close_file(self):
+        with openfile('msg_02.txt', 'r') as fp:
+            email.parser.Parser().parse(fp)
+            self.assertFalse(fp.closed)
+
+    def test_parser_on_exception_does_not_close_file(self):
+        with openfile('msg_15.txt', 'r') as fp:
+            parser = email.parser.Parser
+            self.assertRaises(email.errors.StartBoundaryNotFoundDefect,
+                              parser(policy=email.policy.strict).parse, fp)
+            self.assertFalse(fp.closed)
+
     def test_whitespace_continuation(self):
         eq = self.assertEqual
         # This message contains a line after the Subject: header that has only
index 487799c917fd2f05bc73ff999324b13bb88daf44..b5a5fa6f376764762ab370a3bcd16716a5d77937 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -27,6 +27,9 @@ Core and Builtins
 Library
 -------
 
+- Issue #21476: Make sure the email.parser.BytesParser TextIOWrapper is
+  discarded after parsing, so the input file isn't unexpectedly closed.
+
 - Issue #21729: Used the "with" statement in the dbm.dumb module to ensure
   files closing.  Patch by Claudiu Popa.