Rev 2594: Guard test_email_message in try/finally block (John) in http://sourcefrog.net/bzr/email_message

Martin Pool mbp at sourcefrog.net
Mon Jul 9 05:43:14 BST 2007


At http://sourcefrog.net/bzr/email_message

------------------------------------------------------------
revno: 2594
revision-id: mbp at sourcefrog.net-20070709044312-ltf0i26brexb8i2d
parent: pqm at pqm.ubuntu.com-20070706141845-sije5bdx8pjw2fhk
parent: dato at net.com.org.es-20070626194921-oe28hho9833mvb23
committer: Martin Pool <mbp at sourcefrog.net>
branch nick: email_message
timestamp: Mon 2007-07-09 14:43:12 +1000
message:
  Guard test_email_message in try/finally block (John)
added:
  bzrlib/email_message.py        email_message.py-20070619201106-2k56zg9cd41qp3nh-1
  bzrlib/tests/test_email_message.py test_email_message.p-20070623010619-pwqqa7nqzs4ir22r-1
modified:
  bzrlib/merge_directive.py      merge_directive.py-20070228184838-ja62280spt1g7f4x-1
  bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
    ------------------------------------------------------------
    revno: 2540.3.11
    revision-id: dato at net.com.org.es-20070626194921-oe28hho9833mvb23
    parent: dato at net.com.org.es-20070626194145-46tnigtb6nozawuy
    committer: Adeodato Simó <dato at net.com.org.es>
    branch nick: bzr.email_message
    timestamp: Tue 2007-06-26 21:49:21 +0200
    message:
      Add a mime_subtype parameter to add_inline_attachment.
    modified:
      bzrlib/email_message.py        email_message.py-20070619201106-2k56zg9cd41qp3nh-1
      bzrlib/tests/test_email_message.py test_email_message.p-20070623010619-pwqqa7nqzs4ir22r-1
    ------------------------------------------------------------
    revno: 2540.3.10
    revision-id: dato at net.com.org.es-20070626194145-46tnigtb6nozawuy
    parent: dato at net.com.org.es-20070626185652-tp5gnqi07dw33dgj
    committer: Adeodato Simó <dato at net.com.org.es>
    branch nick: bzr.email_message
    timestamp: Tue 2007-06-26 21:41:45 +0200
    message:
      Rename add_text_attachment to add_inline_attachment.
    modified:
      bzrlib/email_message.py        email_message.py-20070619201106-2k56zg9cd41qp3nh-1
      bzrlib/tests/test_email_message.py test_email_message.p-20070623010619-pwqqa7nqzs4ir22r-1
    ------------------------------------------------------------
    revno: 2540.3.9
    revision-id: dato at net.com.org.es-20070626185652-tp5gnqi07dw33dgj
    parent: dato at net.com.org.es-20070626184538-bj2hide8beo01iw9
    committer: Adeodato Simó <dato at net.com.org.es>
    branch nick: bzr.email_message
    timestamp: Tue 2007-06-26 20:56:52 +0200
    message:
      Add static method EmailMessage.send().
    modified:
      bzrlib/email_message.py        email_message.py-20070619201106-2k56zg9cd41qp3nh-1
      bzrlib/tests/test_email_message.py test_email_message.p-20070623010619-pwqqa7nqzs4ir22r-1
    ------------------------------------------------------------
    revno: 2540.3.8
    revision-id: dato at net.com.org.es-20070626184538-bj2hide8beo01iw9
    parent: dato at net.com.org.es-20070626183801-dl0yi40gpcqc5e60
    parent: pqm at pqm.ubuntu.com-20070626061722-8m49gdqd8cb8zc0c
    committer: Adeodato Simó <dato at net.com.org.es>
    branch nick: bzr.email_message
    timestamp: Tue 2007-06-26 20:45:38 +0200
    message:
      Merge bzr.dev.
    added:
      bzrlib/smtp_connection.py      smtp_connection.py-20070618204456-nu6wag1ste4biuk2-1
      bzrlib/tests/blackbox/test_lsprof.py test_lsprof.py-20070622025641-nbsm2svy8anvj9df-1
      bzrlib/tests/test_smtp_connection.py test_smtp_connection-20070618204509-wuyxc0r0ztrecv7e-1
      doc/developers/bundles.txt     bundles.txt-20070621030528-qkjnugd7iyud6ow3-1
      doc/developers/dirstate.txt    dirstate.txt-20070618020404-cdhv0ecgrukomemg-2
      doc/developers/scratch.txt     scratch.txt-20070618020404-cdhv0ecgrukomemg-3
      doc/developers/uncommit.txt    uncommit.txt-20070621042721-4clw8ucb9u9yda2h-1
    renamed:
      doc/developers/performance-commit.txt => doc/developers/commit.txt performancecommit.tx-20070606061633-4y4rawskx5ejb99w-1
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      README                         README-20050309040720-8f368abf9f346b9d
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/bundle/serializer/__init__.py __init__.py-20051118175413-86b97db0b618feef
      bzrlib/commands.py             bzr.py-20050309040720-d10f4714595cf8c3
      bzrlib/commit.py               commit.py-20050511101309-79ec1a0168e0e825
      bzrlib/deprecated_graph.py     graph.py-20050905070950-b47dce53236c5e48
      bzrlib/errors.py               errors.py-20050309040759-20512168c4e14fbd
      bzrlib/graph.py                graph_walker.py-20070525030359-y852guab65d4wtn0-1
      bzrlib/inventory.py            inventory.py-20050309040759-6648b84ca2005b37
      bzrlib/knit.py                 knit.py-20051212171256-f056ac8f0fbe1bd9
      bzrlib/merge.py                merge.py-20050513021216-953b65a438527106
      bzrlib/missing.py              missing.py-20050812153334-097f7097e2a8bcd1
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/repofmt/knitrepo.py     knitrepo.py-20070206081537-pyy4a00xdas0j4pf-1
      bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
      bzrlib/revision.py             revision.py-20050309040759-e77802c08f3999d5
      bzrlib/status.py               status.py-20050505062338-431bfa63ec9b19e6
      bzrlib/tests/HTTPTestUtil.py   HTTPTestUtil.py-20050914180604-247d3aafb7a43343
      bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
      bzrlib/tests/blackbox/__init__.py __init__.py-20051128053524-eba30d8255e08dc3
      bzrlib/tests/blackbox/test_merge_directive.py test_merge_directive-20070302012039-zh7uhy39biairtn0-1
      bzrlib/tests/repository_implementations/__init__.py __init__.py-20060131092037-9564957a7d4a841b
      bzrlib/tests/repository_implementations/test_repository.py test_repository.py-20060131092128-ad07f494f5c9d26c
      bzrlib/tests/test_graph.py     test_graph_walker.py-20070525030405-enq4r60hhi9xrujc-1
      bzrlib/tests/test_http.py      testhttp.py-20051018020158-b2eef6e867c514d9
      bzrlib/tests/test_tsort.py     testtsort.py-20051025073946-27da871c394d5be4
      bzrlib/tests/test_versionedfile.py test_versionedfile.py-20060222045249-db45c9ed14a1c2e5
      bzrlib/transport/http/_urllib2_wrappers.py _urllib2_wrappers.py-20060913231729-ha9ugi48ktx481ao-1
      bzrlib/tsort.py                tsort.py-20051025073946-7808f6aaf7d07208
      bzrlib/versionedfile.py        versionedfile.py-20060222045106-5039c71ee3b65490
      bzrlib/weave.py                knit.py-20050627021749-759c29984154256b
      doc/configuration.txt          configuration.txt-20060314161707-868350809502af01
      doc/developers/index.txt       index.txt-20070508041241-qznziunkg0nffhiw-1
      doc/developers/performance-roadmap.txt performanceroadmap.t-20070507174912-mwv3xv517cs4sisd-2
      doc/developers/performance-use-case-analysis.txt performanceusecasean-20070508045640-zneiu1yzbci574c6-2
      doc/developers/profiling.txt   profiling.txt-20070531045713-j15mxufywgzwdeu8-1
      doc/developers/commit.txt      performancecommit.tx-20070606061633-4y4rawskx5ejb99w-1
    ------------------------------------------------------------
    revno: 2540.3.7
    revision-id: dato at net.com.org.es-20070626183801-dl0yi40gpcqc5e60
    parent: dato at net.com.org.es-20070623025543-v0iqs0f5vmb64dwu
    committer: Adeodato Simó <dato at net.com.org.es>
    branch nick: bzr.email_message
    timestamp: Tue 2007-06-26 20:38:01 +0200
    message:
      Use email.Utils.formataddr().
    modified:
      bzrlib/email_message.py        email_message.py-20070619201106-2k56zg9cd41qp3nh-1
      bzrlib/tests/test_email_message.py test_email_message.p-20070623010619-pwqqa7nqzs4ir22r-1
    ------------------------------------------------------------
    revno: 2540.3.6
    revision-id: dato at net.com.org.es-20070623025543-v0iqs0f5vmb64dwu
    parent: dato at net.com.org.es-20070623014118-64brc5uvuq7s5bbh
    committer: Adeodato Simó <dato at net.com.org.es>
    branch nick: bzr.email_message
    timestamp: Sat 2007-06-23 03:55:43 +0100
    message:
      Add tests.
    added:
      bzrlib/tests/test_email_message.py test_email_message.p-20070623010619-pwqqa7nqzs4ir22r-1
    modified:
      bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
    ------------------------------------------------------------
    revno: 2540.3.5
    revision-id: dato at net.com.org.es-20070623014118-64brc5uvuq7s5bbh
    parent: dato at net.com.org.es-20070621152422-p7qtkzhsmd6i3l4r
    committer: Adeodato Simó <dato at net.com.org.es>
    branch nick: bzr.email_message
    timestamp: Sat 2007-06-23 02:41:18 +0100
    message:
      Use safe_unicode() instead of custom code; drop unneeded NonAsciiString.
    modified:
      bzrlib/email_message.py        email_message.py-20070619201106-2k56zg9cd41qp3nh-1
      bzrlib/errors.py               errors.py-20050309040759-20512168c4e14fbd
    ------------------------------------------------------------
    revno: 2540.3.4
    revision-id: dato at net.com.org.es-20070621152422-p7qtkzhsmd6i3l4r
    parent: dato at net.com.org.es-20070620164356-xlee43rgy811s1z0
    committer: Adeodato Simó <dato at net.com.org.es>
    branch nick: bzr.email_message
    timestamp: Thu 2007-06-21 16:24:22 +0100
    message:
      Add User-Agent header.
    modified:
      bzrlib/email_message.py        email_message.py-20070619201106-2k56zg9cd41qp3nh-1
    ------------------------------------------------------------
    revno: 2540.3.3
    revision-id: dato at net.com.org.es-20070620164356-xlee43rgy811s1z0
    parent: dato at net.com.org.es-20070620163936-cvoeo1q4xcip4odr
    committer: Adeodato Simó <dato at net.com.org.es>
    branch nick: bzr.email_message
    timestamp: Wed 2007-06-20 17:43:56 +0100
    message:
      Always set Content-Disposition.
    modified:
      bzrlib/email_message.py        email_message.py-20070619201106-2k56zg9cd41qp3nh-1
    ------------------------------------------------------------
    revno: 2540.3.2
    revision-id: dato at net.com.org.es-20070620163936-cvoeo1q4xcip4odr
    parent: dato at net.com.org.es-20070620162906-nyy3iplz1aaojs6b
    committer: Adeodato Simó <dato at net.com.org.es>
    branch nick: bzr.email_message
    timestamp: Wed 2007-06-20 17:39:36 +0100
    message:
      Do not inherit from object.
    modified:
      bzrlib/email_message.py        email_message.py-20070619201106-2k56zg9cd41qp3nh-1
    ------------------------------------------------------------
    revno: 2540.3.1
    revision-id: dato at net.com.org.es-20070620162906-nyy3iplz1aaojs6b
    parent: pqm at pqm.ubuntu.com-20070620092141-cniojlk01bdec2a1
    committer: Adeodato Simó <dato at net.com.org.es>
    branch nick: bzr.email_message
    timestamp: Wed 2007-06-20 17:29:06 +0100
    message:
      New EmailMessage class, derived from the original SMTPConnection in bzr-email.
    added:
      bzrlib/email_message.py        email_message.py-20070619201106-2k56zg9cd41qp3nh-1
    modified:
      bzrlib/errors.py               errors.py-20050309040759-20512168c4e14fbd
      bzrlib/merge_directive.py      merge_directive.py-20070228184838-ja62280spt1g7f4x-1
=== added file 'bzrlib/email_message.py'
--- a/bzrlib/email_message.py	1970-01-01 00:00:00 +0000
+++ b/bzrlib/email_message.py	2007-06-26 19:49:21 +0000
@@ -0,0 +1,120 @@
+# Copyright (C) 2007 Canonical Ltd
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+"""A convenience class around email.MIMEMultipart."""
+
+from email import (
+    Header,
+    MIMEMultipart,
+    MIMEText,
+    Utils,
+    )
+
+from bzrlib import __version__ as _bzrlib_version
+from bzrlib.osutils import safe_unicode
+from bzrlib.smtp_connection import SMTPConnection
+
+
+class EmailMessage(MIMEMultipart.MIMEMultipart):
+    """A MIME Multipart email message."""
+
+    def __init__(self, from_address, to_address, subject, body=None):
+        """Create an email message.
+
+        :param from_address: The origin address, to be put on the From header.
+        :param to_address: The destination address of the message, to be put in
+            the To header. Can also be a list of addresses.
+        :param subject: The subject of the message.
+        :param body: If given, the body of the message.
+
+        All four parameters can be unicode strings or byte strings, but for the
+        addresses and subject byte strings must be encoded in UTF-8. For the
+        body any byte string will be accepted, but no guessing of the encoding
+        will be done (the charset will be set to '8-bit').
+        """
+        MIMEMultipart.MIMEMultipart.__init__(self)
+        self['From'] = self.address_to_encoded_header(from_address)
+        self['User-Agent'] = 'Bazaar (%s)' % _bzrlib_version
+
+        if isinstance(to_address, basestring):
+            to_address = [to_address]
+
+        to_addresses = []
+        for addr in to_address:
+            to_addresses.append(self.address_to_encoded_header(addr))
+        self['To'] = ', '.join(to_addresses)
+
+        self['Subject'] = Header.Header(safe_unicode(subject))
+
+        if body is not None:
+            self.add_inline_attachment(body)
+
+    def add_inline_attachment(self, body, filename=None, mime_subtype='plain'):
+        """Add an inline attachment to the message.
+
+        :param body: A text to attach. Can be an unicode string, and it'll be
+            sent as utf-8, or a byte string, and it'll be sent as 8-bit.
+        :param filename: The name for the attachment. This will give a default
+            name for email programs to save the attachment.
+        :param mime_subtype: MIME subtype of the attachment (eg. 'plain' for
+            text/plain [default]).
+
+        The attachment body will be displayed inline, so do not use this
+        function to attach binary attachments.
+        """
+        if isinstance(body, unicode):
+            payload = MIMEText.MIMEText(body.encode('utf-8'), mime_subtype,
+                                        'utf-8')
+        else:
+            payload = MIMEText.MIMEText(body, mime_subtype, '8-bit')
+
+        if filename is not None:
+            content_type = payload['Content-Type']
+            content_type += '; name="%s"' % filename
+            payload.replace_header('Content-Type', content_type)
+
+        payload['Content-Disposition'] = 'inline'
+        self.attach(payload)
+
+    @staticmethod
+    def send(config, from_address, to_address, subject, body, attachment=None,
+            attachment_filename=None):
+        """Create an email message and send it with SMTPConnection.
+
+        See SMTPConnection.__init__(), EmailMessage.__init__() and
+        EmailMessage.add_inline_attachment() for an explanation of the
+        parameters.
+        """
+        msg = EmailMessage(from_address, to_address, subject, body)
+        if attachment is not None:
+            msg.add_inline_attachment(attachment, attachment_filename)
+        SMTPConnection(config).send_email(msg)
+
+    @staticmethod
+    def address_to_encoded_header(address):
+        """RFC2047-encode an address if necessary.
+
+        :param address: An unicode string, or UTF-8 byte string.
+        :return: A string.
+        """
+        # Can't call Header over all the address, because that encodes both the
+        # name and the email address, which is not permitted by RFCs.
+        user, email = Utils.parseaddr(address)
+        if not user:
+            return email
+        else:
+            return Utils.formataddr((str(Header.Header(safe_unicode(user))),
+                email))

=== added file 'bzrlib/tests/test_email_message.py'
--- a/bzrlib/tests/test_email_message.py	1970-01-01 00:00:00 +0000
+++ b/bzrlib/tests/test_email_message.py	2007-07-09 04:43:12 +0000
@@ -0,0 +1,150 @@
+# Copyright (C) 2007 Canonical Ltd
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+from email.Header import decode_header
+
+from bzrlib import __version__ as _bzrlib_version
+from bzrlib.email_message import EmailMessage
+from bzrlib.errors import BzrBadParameterNotUnicode
+from bzrlib.smtp_connection import SMTPConnection
+from bzrlib.tests import TestCase
+
+
+BOUNDARY = '=====123456=='
+
+_DICT = { 'version': _bzrlib_version, 'boundary': BOUNDARY }
+
+_HEAD = '''\
+Content-Type: multipart/mixed; boundary="%(boundary)s"
+MIME-Version: 1.0
+From: from at from.com
+User-Agent: Bazaar (%(version)s)
+To: to at to.com
+Subject: subject
+
+--%(boundary)s
+Content-Type: text/plain; charset="%%s"
+MIME-Version: 1.0
+Content-Transfer-Encoding: base64
+Content-Disposition: inline
+
+YsOzZHk=
+
+''' % _DICT
+
+SIMPLE_MESSAGE = _HEAD + '--%(boundary)s--' % _DICT
+
+COMPOUND_MESSAGE = _HEAD + '''\
+--%(boundary)s
+Content-Type: text/%%s; charset="utf-8"; name="lines.txt"
+MIME-Version: 1.0
+Content-Transfer-Encoding: base64
+Content-Disposition: inline
+
+YQpiCmMKZAplCg==
+
+--%(boundary)s--''' % _DICT
+
+
+class TestEmailMessage(TestCase):
+
+    def test_simple_mail(self):
+        msg = EmailMessage('from at from.com', 'to at to.com', 'subject', u'b\xf3dy')
+        msg.set_boundary(BOUNDARY)
+        self.assertEqualDiff(SIMPLE_MESSAGE % 'utf-8', msg.as_string())
+
+        # now separately specifying the body
+        msg = EmailMessage('from at from.com', 'to at to.com', 'subject')
+        msg.set_boundary(BOUNDARY)
+        msg.add_inline_attachment(u'b\xf3dy')
+        self.assertEqualDiff(SIMPLE_MESSAGE % 'utf-8', msg.as_string())
+
+    def test_body_accepts_8bit(self):
+        msg = EmailMessage('from at from.com', 'to at to.com', 'subject',
+                'b\xc3\xb3dy')
+        msg.set_boundary(BOUNDARY)
+        self.assertEqualDiff(SIMPLE_MESSAGE % '8-bit', msg.as_string())
+
+    def test_utf8_accepted(self):
+        utf8 = 'Pepe P\xc3\xa9red <pperez at ejemplo.com>'
+        EmailMessage(utf8, utf8, utf8) # no exception raised
+
+    def test_non_utf8_rejected(self):
+        for i in range(3): # from_address, to_address, subject
+            x = [ '"J. Random Developer" <jrandom at example.com>' ] * 3
+            x[i] = 'Pepe P\xe9rez <pperez at ejemplo.com>'
+            self.assertRaises(BzrBadParameterNotUnicode, EmailMessage, *x)
+
+    def test_multiple_destinations(self):
+        to_addresses = ['to1 at to.com', 'to2 at to.com', 'to3 at to.com' ]
+        msg = EmailMessage('from at from.com', to_addresses, 'subject')
+        self.assertEqual(', '.join(to_addresses), msg['To'])
+
+    def test_add_inline_attachment(self):
+        msg = EmailMessage('from at from.com', 'to at to.com', 'subject', u'b\xf3dy')
+        msg.set_boundary(BOUNDARY)
+        msg.add_inline_attachment(u'a\nb\nc\nd\ne\n', 'lines.txt', 'x-subtype')
+        self.assertEqualDiff(COMPOUND_MESSAGE % ('utf-8', 'x-subtype'),
+                msg.as_string())
+
+    def test_send(self):
+        class FakeConfig:
+            def get_user_option(self, option):
+                return None
+
+        def send_email(msg):
+            msg.set_boundary(BOUNDARY)
+            self.assertEqualDiff(COMPOUND_MESSAGE % ('utf-8', 'plain'),
+                    msg.as_string())
+
+        old_send_email = SMTPConnection.send_email
+        try:
+            EmailMessage.send(FakeConfig(), 'from at from.com', 'to at to.com',
+                    'subject', u'b\xf3dy', u'a\nb\nc\nd\ne\n', 'lines.txt')
+        finally:
+            SMTPConnection.send_email = old_send_email
+
+    def test_address_to_encoded_header(self):
+        def decode(s):
+            """Convert a RFC2047-encoded string to a unicode string."""
+            return ' '.join([chunk.decode(encoding or 'ascii')
+                             for chunk, encoding in decode_header(s)])
+
+        address = 'jrandom at example.com'
+        encoded = EmailMessage.address_to_encoded_header(address)
+        self.assertEqual(address, encoded)
+
+        address = 'J Random Developer <jrandom at example.com>'
+        encoded = EmailMessage.address_to_encoded_header(address)
+        self.assertEqual(address, encoded)
+
+        address = '"J. Random Developer" <jrandom at example.com>'
+        encoded = EmailMessage.address_to_encoded_header(address)
+        self.assertEqual(address, encoded)
+
+        address = u'Pepe P\xe9rez <pperez at ejemplo.com>' # unicode ok
+        encoded = EmailMessage.address_to_encoded_header(address)
+        self.assert_('pperez at ejemplo.com' in encoded) # addr must be unencoded
+        self.assertEquals(address, decode(encoded))
+
+        address = 'Pepe P\xc3\xa9red <pperez at ejemplo.com>' # UTF-8 ok
+        encoded = EmailMessage.address_to_encoded_header(address)
+        self.assert_('pperez at ejemplo.com' in encoded)
+        self.assertEquals(address, decode(encoded).encode('utf-8'))
+
+        address = 'Pepe P\xe9rez <pperez at ejemplo.com>' # ISO-8859-1 not ok
+        self.assertRaises(BzrBadParameterNotUnicode,
+                EmailMessage.address_to_encoded_header, address)

=== modified file 'bzrlib/merge_directive.py'
--- a/bzrlib/merge_directive.py	2007-06-19 21:22:56 +0000
+++ b/bzrlib/merge_directive.py	2007-06-20 16:29:06 +0000
@@ -15,7 +15,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
 
-from email import Message
 from StringIO import StringIO
 
 from bzrlib import (
@@ -31,6 +30,7 @@
 from bzrlib.bundle import (
     serializer as bundle_serializer,
     )
+from bzrlib.email_message import EmailMessage
 
 
 class MergeDirective(object):
@@ -163,19 +163,16 @@
         :return: an email message
         """
         mail_from = branch.get_config().username()
-        message = Message.Message()
-        message['To'] = mail_to
-        message['From'] = mail_from
         if self.message is not None:
-            message['Subject'] = self.message
+            subject = self.message
         else:
             revision = branch.repository.get_revision(self.revision_id)
-            message['Subject'] = revision.message
+            subject = revision.message
         if sign:
             body = self.to_signed(branch)
         else:
             body = ''.join(self.to_lines())
-        message.set_payload(body)
+        message = EmailMessage(mail_from, mail_to, subject, body)
         return message
 
     @classmethod

=== modified file 'bzrlib/tests/__init__.py'
--- a/bzrlib/tests/__init__.py	2007-07-05 00:12:25 +0000
+++ b/bzrlib/tests/__init__.py	2007-07-09 04:43:12 +0000
@@ -2294,6 +2294,7 @@
                    'bzrlib.tests.test_deprecated_graph',
                    'bzrlib.tests.test_diff',
                    'bzrlib.tests.test_dirstate',
+                   'bzrlib.tests.test_email_message',
                    'bzrlib.tests.test_errors',
                    'bzrlib.tests.test_escaped_store',
                    'bzrlib.tests.test_extract',




More information about the bazaar-commits mailing list