Import _isstring() from the compatibility layer.

_handle_text(): Use _isstring() for stringiness test.

_handle_multipart(): Add a test before the ListType test, checking for
stringiness of the payload.  String payloads for multitypes means a
message with broken MIME chrome was parsed by a lax parser.  Instead
of raising a BoundaryError in those cases, the entire body is assigned
to the message payload (but since the content type is still
multipart/*, the Generator needs to be updated too).
diff --git a/Lib/email/Generator.py b/Lib/email/Generator.py
index 8ce3807..e8bce10 100644
--- a/Lib/email/Generator.py
+++ b/Lib/email/Generator.py
@@ -8,11 +8,17 @@
 import re
 import random
 
-from types import ListType, StringType
+from types import ListType
 from cStringIO import StringIO
 
 from email.Header import Header
 
+try:
+    from email._compat22 import _isstring
+except SyntaxError:
+    from email._compat21 import _isstring
+
+
 EMPTYSTRING = ''
 SEMISPACE = '; '
 BAR = '|'
@@ -187,7 +193,7 @@
         cset = msg.get_charset()
         if cset is not None:
             payload = cset.body_encode(payload)
-        if not isinstance(payload, StringType):
+        if not _isstring(payload):
             raise TypeError, 'string payload expected: %s' % type(payload)
         if self._mangle_from_:
             payload = fcre.sub('>From ', payload)
@@ -209,6 +215,10 @@
             print >> self._fp, '\n'
             print >> self._fp, '--' + boundary + '--'
             return
+        elif _isstring(subparts):
+            # e.g. a non-strict parse of a message with no starting boundary.
+            self._fp.write(subparts)
+            return
         elif not isinstance(subparts, ListType):
             # Scalar payload
             subparts = [subparts]