#14925: email now registers a defect for missing header/body separator.

This patch also deprecates the MalformedHeaderDefect.  My best guess is that
this defect was rendered obsolete by a refactoring of the parser, and the
corresponding defect for the new parser (which this patch introduces) was
overlooked.
diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py
index ac6ee65..c04952c 100644
--- a/Lib/test/test_email/test_email.py
+++ b/Lib/test/test_email/test_email.py
@@ -1960,15 +1960,27 @@
     # test_parser.TestMessageDefectDetectionBase
     def test_first_line_is_continuation_header(self):
         eq = self.assertEqual
-        m = ' Line 1\nLine 2\nLine 3'
+        m = ' Line 1\nSubject: test\n\nbody'
         msg = email.message_from_string(m)
-        eq(msg.keys(), [])
-        eq(msg.get_payload(), 'Line 2\nLine 3')
+        eq(msg.keys(), ['Subject'])
+        eq(msg.get_payload(), 'body')
         eq(len(msg.defects), 1)
-        self.assertTrue(isinstance(msg.defects[0],
-                                   errors.FirstHeaderLineIsContinuationDefect))
+        self.assertDefectsEqual(msg.defects,
+                                 [errors.FirstHeaderLineIsContinuationDefect])
         eq(msg.defects[0].line, ' Line 1\n')
 
+    # test_parser.TestMessageDefectDetectionBase
+    def test_missing_header_body_separator(self):
+        # Our heuristic if we see a line that doesn't look like a header (no
+        # leading whitespace but no ':') is to assume that the blank line that
+        # separates the header from the body is missing, and to stop parsing
+        # headers and start parsing the body.
+        msg = self._str_msg('Subject: test\nnot a header\nTo: abc\n\nb\n')
+        self.assertEqual(msg.keys(), ['Subject'])
+        self.assertEqual(msg.get_payload(), 'not a header\nTo: abc\n\nb\n')
+        self.assertDefectsEqual(msg.defects,
+                                [errors.MissingHeaderBodySeparatorDefect])
+
 
 # Test RFC 2047 header encoding and decoding
 class TestRFC2047(TestEmailBase):
diff --git a/Lib/test/test_email/test_parser.py b/Lib/test/test_email/test_parser.py
index 864e4c1..f58e7c1 100644
--- a/Lib/test/test_email/test_parser.py
+++ b/Lib/test/test_email/test_parser.py
@@ -237,17 +237,33 @@
                           policy=self.policy.clone(raise_on_defect=True))
 
     def test_first_line_is_continuation_header(self):
-        msg = self._str_msg(' Line 1\nLine 2\nLine 3')
-        self.assertEqual(msg.keys(), [])
-        self.assertEqual(msg.get_payload(), 'Line 2\nLine 3')
+        msg = self._str_msg(' Line 1\nSubject: test\n\nbody')
+        self.assertEqual(msg.keys(), ['Subject'])
+        self.assertEqual(msg.get_payload(), 'body')
         self.assertEqual(len(self.get_defects(msg)), 1)
-        self.assertTrue(isinstance(self.get_defects(msg)[0],
-                                   errors.FirstHeaderLineIsContinuationDefect))
+        self.assertDefectsEqual(self.get_defects(msg),
+                                 [errors.FirstHeaderLineIsContinuationDefect])
         self.assertEqual(self.get_defects(msg)[0].line, ' Line 1\n')
 
     def test_first_line_is_continuation_header_raise_on_defect(self):
         with self.assertRaises(errors.FirstHeaderLineIsContinuationDefect):
-            self._str_msg(' Line 1\nLine 2\nLine 3',
+            self._str_msg(' Line 1\nSubject: test\n\nbody\n',
+                          policy=self.policy.clone(raise_on_defect=True))
+
+    def test_missing_header_body_separator(self):
+        # Our heuristic if we see a line that doesn't look like a header (no
+        # leading whitespace but no ':') is to assume that the blank line that
+        # separates the header from the body is missing, and to stop parsing
+        # headers and start parsing the body.
+        msg = self._str_msg('Subject: test\nnot a header\nTo: abc\n\nb\n')
+        self.assertEqual(msg.keys(), ['Subject'])
+        self.assertEqual(msg.get_payload(), 'not a header\nTo: abc\n\nb\n')
+        self.assertDefectsEqual(self.get_defects(msg),
+                                [errors.MissingHeaderBodySeparatorDefect])
+
+    def test_missing_header_body_separator_raise_on_defect(self):
+        with self.assertRaises(errors.MissingHeaderBodySeparatorDefect):
+            self._str_msg('Subject: test\nnot a header\nTo: abc\n\nb\n',
                           policy=self.policy.clone(raise_on_defect=True))