diff --git a/CHANGES.rst b/CHANGES.rst
index ff5b438..e6b9149 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -4,6 +4,12 @@ Changelog
 4.10 (unreleased)
 -----------------
 
+- We depend on ``zope.sendmail >= 5.1``.
+
+- Support messages with explicit ``Content-Transfer-Encoding: 8bit``
+  (`#30 <https://github.com/zopefoundation/Products.MailHost/issues/30>`_).
+  
+
 
 4.9 (2020-02-12)
 ----------------
diff --git a/setup.py b/setup.py
index efa9766..752e054 100644
--- a/setup.py
+++ b/setup.py
@@ -69,7 +69,7 @@ setup(
         'Zope >= 4.0b4',
         'zope.deferredimport',
         'zope.interface',
-        'zope.sendmail >= 5',
+        'zope.sendmail >= 5.1',
     ],
     extras_require={
         'genericsetup': ['Products.GenericSetup >= 2.0b1'],
diff --git a/src/Products/MailHost/MailHost.py b/src/Products/MailHost/MailHost.py
index 716180f..359aa9c 100644
--- a/src/Products/MailHost/MailHost.py
+++ b/src/Products/MailHost/MailHost.py
@@ -203,14 +203,15 @@ class MailBase(Implicit, Item, RoleManager):
              immediate=False,
              charset=None,
              msg_type=None):
-        messageText, mto, mfrom = _mungeHeaders(messageText, mto, mfrom,
-                                                subject, charset, msg_type)
-        # This encode step is mainly for BBB, encoding should be
-        # automatic if charset is passed.  The automated charset-based
-        # encoding will be preferred if both encode and charset are
-        # provided.
-        messageText = _encode(messageText, encode)
-        self._send(mfrom, mto, messageText, immediate)
+        """send *messageText* modified by the other parameters.
+
+        *messageText* can either be an ``email.message.Message``
+        or a string.
+        """
+        msg, mto, mfrom = _mungeHeaders(messageText, mto, mfrom,
+                                        subject, charset, msg_type,
+                                        encode)
+        self._send(mfrom, mto, msg, immediate)
 
     # This is here for backwards compatibility only. Possibly it could
     # be used to send messages at a scheduled future time, or via a mail queue?
@@ -351,28 +352,8 @@ ENCODERS = {
 }
 
 
-def _encode(body, encode=None):
-    """Manually sets an encoding and encodes the message if not
-    already encoded."""
-    if encode is None:
-        return body
-    mo = message_from_string(body)
-    current_coding = mo['Content-Transfer-Encoding']
-    if current_coding == encode:
-        # already encoded correctly, may have been automated
-        return body
-    if mo['Content-Transfer-Encoding'] not in ['7bit', None]:
-        raise MailHostError('Message already encoded')
-    if encode in ENCODERS:
-        ENCODERS[encode](mo)
-        if not mo['Content-Transfer-Encoding']:
-            mo['Content-Transfer-Encoding'] = encode
-        if not mo['Mime-Version']:
-            mo['Mime-Version'] = '1.0'
-    return mo.as_string()
-
-
 def _string_transform(text, charset=None):
+    """converts *text* to a native string."""
     if six.PY2 and isinstance(text, six.text_type):
         # Unicode under Python 2
         return _try_encode(text, charset)
@@ -385,10 +366,16 @@ def _string_transform(text, charset=None):
 
 
 def _mungeHeaders(messageText, mto=None, mfrom=None, subject=None,
-                  charset=None, msg_type=None):
+                  charset=None, msg_type=None, encode=None):
     """Sets missing message headers, and deletes Bcc.
-       returns fixed message, fixed mto and fixed mfrom"""
-    messageText = _string_transform(messageText, charset)
+       returns fixed message, fixed mto and fixed mfrom.
+
+       *messageText* can be either a ``Message`` or a
+       string representation for a message.
+       In the latter case, the representation is converted to
+       a native string using *charset*, if necessary, and then
+       parsed into a ``Message`` object.
+    """
     mto = _string_transform(mto, charset)
     mfrom = _string_transform(mfrom, charset)
     subject = _string_transform(subject, charset)
@@ -398,7 +385,7 @@ def _mungeHeaders(messageText, mto=None, mfrom=None, subject=None,
         mo = deepcopy(messageText)
     else:
         # Otherwise parse the input message
-        mo = message_from_string(messageText)
+        mo = message_from_string(_string_transform(messageText, charset))
 
     if msg_type and not mo.get('Content-Type'):
         # we don't use get_content_type because that has a default
@@ -422,7 +409,10 @@ def _mungeHeaders(messageText, mto=None, mfrom=None, subject=None,
     if mto:
         if isinstance(mto, six.string_types):
             mto = [formataddr(addr) for addr in getaddresses((mto, ))]
-        if not mo.get('To'):
+        # this violates what is said above (parameters always override)
+        # if not mo.get('To'):
+        if mto:
+            del mo['To']
             mo['To'] = ', '.join(str(_encode_address_string(e, charset))
                                  for e in mto)
     else:
@@ -451,7 +441,21 @@ def _mungeHeaders(messageText, mto=None, mfrom=None, subject=None,
     if not mo.get('Date'):
         mo['Date'] = DateTime().rfc822()
 
-    return mo.as_string(), mto, mfrom
+    if encode:
+        current_coding = mo['Content-Transfer-Encoding']
+        if current_coding == encode:
+            # already encoded correctly, may have been automated
+            pass
+        elif mo['Content-Transfer-Encoding'] not in ['7bit', None]:
+            raise MailHostError('Message already encoded')
+        elif encode in ENCODERS:
+            ENCODERS[encode](mo)
+            if not mo['Content-Transfer-Encoding']:
+                mo['Content-Transfer-Encoding'] = encode
+            if not mo['Mime-Version']:
+                mo['Mime-Version'] = '1.0'
+
+    return as_bytes(mo), mto, mfrom
 
 
 def _set_recursive_charset(payload, charset=None):
@@ -515,3 +519,50 @@ def _encode_address_string(text, charset):
     # We again replace rather than raise an error or pass an 8bit string
     header.append(formataddr((name, addr)), errors='replace')
     return header
+
+
+if six.PY2:
+    def as_bytes(msg):
+        return msg.as_string()
+else:  # Python 3
+    def as_bytes(msg):
+        return msg.as_bytes()
+
+    # work around "https://bugs.python.org/issue41307"
+    from copy import copy
+    from email._policybase import Compat32
+    from email.generator import BytesGenerator
+    from email.generator import _has_surrogates
+    from functools import partial
+    from io import BytesIO
+
+    class FixedBytesGenerator(BytesGenerator):
+        def _handle_text(self, msg):
+            payload = msg._payload
+            if payload is None:
+                return
+            charset = msg.get_param('charset', 'utf-8')
+            if (  charset is not None  # noqa: E201
+                  and not self.policy.cte_type == '7bit'
+                  and not _has_surrogates(payload)):
+                msg = copy(msg)
+                msg._payload = payload.encode(charset).decode(
+                    'ascii', 'surrogateescape')
+            super()._handle_text(msg)
+
+        _writeBody = _handle_text
+
+    class FixedMessage(Message):
+        def as_bytes(self, unixfrom=False, policy=None):
+            policy = self.policy if policy is None else policy
+            fp = BytesIO()
+            g = FixedBytesGenerator(fp, mangle_from_=False, policy=policy)
+            g.flatten(self, unixfrom=unixfrom)
+            return fp.getvalue()
+
+    if hasattr(Compat32, 'message_factory'):
+        fixed_policy = Compat32(message_factory=FixedMessage)
+    else:
+        fixed_policy = Compat32()  # 3.5 -- some tests will fail
+
+    message_from_string = partial(message_from_string, policy=fixed_policy)
diff --git a/tox.ini b/tox.ini
index 5302261..24af4f3 100644
--- a/tox.ini
+++ b/tox.ini
@@ -43,7 +43,7 @@ commands =
     - flake8 --format=html --doctests src setup.py
     flake8 --doctests src setup.py
 deps =
-    isort
+    isort < 5
     flake8
     # helper to generate HTML reports:
     flake8-html

UTF-8 encoded mails are not sent
According to the documentation in `smptlib.sendmail`,

        msg may be a string containing characters in the ASCII range, or a byte
        string.  A string is encoded to bytes using the ascii codec, and lone
        \\r and \\n characters are converted to \\r\\n characters.

Since switching to Zope 4, we are unable to send mails that have a UTF-8 encoded body - Even if we transform it to bytes ourselves, `Products.MailHost` converts it back to strings before sending it to `zope.sendmail` and smptlib fails to encode the passed message using ASCII during the second phase of the two phase commit. Our quick fix was to change `zope.sendmail` to encode the message using `utf-8` before passing it to `smtplib.sendmail`.

A really clean way would probably be to inspect the headers (which should be ASCII) and check for a `Content-Type` and `Content-Transfer-Encoding`. Maybe it is even possible to have a multipart message with different encodings (not sure). But since UTF-8 is such a popular choice, we used that for now.

I am not sure if the fix should happen in `zope.sendmail` or somewhere further up like `Products.MailHost`. If it should be `zope.sendmail`, I could try to supply a PR. Otherwise I would need to be pointed to the right direction.
diff --git a/src/Products/MailHost/tests/testMailHost.py b/src/Products/MailHost/tests/testMailHost.py
index e73cc74..41b730f 100644
--- a/src/Products/MailHost/tests/testMailHost.py
+++ b/src/Products/MailHost/tests/testMailHost.py
@@ -15,9 +15,12 @@
 
 import os.path
 import shutil
+import sys
 import tempfile
 import unittest
 from email import message_from_string
+from email.mime.multipart import MIMEMultipart
+from email.mime.text import MIMEText
 
 import six
 
@@ -34,8 +37,13 @@ from .dummy import FakeContent
 # Appease flake8
 if six.PY2:
     unicode = unicode  # noqa: F821
+    parse_message = message_from_string
 else:
     unicode = str
+    from email import message_from_bytes
+    parse_message = message_from_bytes
+
+PY36 = sys.version_info[0:2] >= (3, 6)
 
 
 class TestMailHost(unittest.TestCase):
@@ -47,9 +55,10 @@ class TestMailHost(unittest.TestCase):
         return self._getTargetClass()(*args, **kw)
 
     def test_z3interfaces(self):
-        from Products.MailHost.interfaces import IMailHost
         from zope.interface.verify import verifyClass
 
+        from Products.MailHost.interfaces import IMailHost
+
         verifyClass(IMailHost, self._getTargetClass())
 
     def testAllHeaders(self):
@@ -159,6 +168,8 @@ This is the message body."""
 
         mailhost = self._makeOne('MailHost')
         mailhost.send(msg)
+        if six.PY3:
+            msg = msg.encode()
         self.assertEqual(mailhost.sent, msg)
 
     def testSendWithArguments(self):
@@ -167,7 +178,7 @@ Date: Sun, 27 Aug 2006 17:00:00 +0200
 
 This is the message body."""
 
-        outmsg = """\
+        outmsg = b"""\
 Date: Sun, 27 Aug 2006 17:00:00 +0200
 Subject: This is the subject
 To: "Name, Nick" <recipient@example.com>, Foo Bar <foo@example.com>
@@ -189,7 +200,7 @@ Date: Sun, 27 Aug 2006 17:00:00 +0200
 
 This is the message body."""
 
-        outmsg = """\
+        outmsg = b"""\
 Date: Sun, 27 Aug 2006 17:00:00 +0200
 Subject: This is the subject
 To: "Name, Nick" <recipient@example.com>, Foo Bar <foo@example.com>
@@ -251,7 +262,7 @@ This is the message body."""
                           '"Foo Bar" <foo@example.com>',
                       mfrom='sender@example.com',
                       subject='This is the subject')
-        out = message_from_string(mailhost.sent)
+        out = parse_message(mailhost.sent)
         self.assertEqual(out.get_payload(), msg)
         self.assertEqual(
             out['To'],
@@ -272,7 +283,7 @@ This is the message body."""
                       mfrom='sender@example.com',
                       subject='This is the subject',
                       charset='utf-8')
-        out = message_from_string(mailhost.sent)
+        out = parse_message(mailhost.sent)
         self.assertEqual(
             out['To'],
             '"Name, Nick" <recipient@example.com>, Foo Bar <foo@example.com>')
@@ -294,7 +305,7 @@ This is the message body."""
         mailhost = self._makeOne('MailHost')
         mailhost.send(messageText='A message.', mto=mto, mfrom=mfrom,
                       subject=subject, charset='utf-8')
-        out = message_from_string(mailhost.sent)
+        out = parse_message(mailhost.sent)
         self.assertEqual(
             out['To'],
             '=?utf-8?q?Ferran_Adri=C3=A0?= <ferran@example.com>')
@@ -328,10 +339,13 @@ wqFVbiB0cnVjbyA8c3Ryb25nPmZhbnTDoXN0aWNvPC9zdHJvbmc+IQ=3D=3D
 """
         mailhost = self._makeOne('MailHost')
         mailhost.send(messageText=msg)
-        self.assertEqual(mailhost.sent, msg)
+        outmsg = msg
+        if six.PY3:
+            outmsg = outmsg.encode()
+        self.assertEqual(mailhost.sent, outmsg)
         mailhost.send(messageText=msg, msg_type='text/plain')
         # The msg_type is ignored if already set
-        self.assertEqual(mailhost.sent, msg)
+        self.assertEqual(mailhost.sent, outmsg)
 
     def testAlreadyEncodedMessageWithCharset(self):
         # If the message already specifies encodings, it is
@@ -357,7 +371,7 @@ wqFVbiB0cnVjbyA8c3Ryb25nPmZhbnTDoXN0aWNvPC9zdHJvbmc+IQ=3D=3D
         # The charset for the body should remain the same, but any
         # headers passed into the method will be encoded using the
         # specified charset
-        out = message_from_string(mailhost.sent)
+        out = parse_message(mailhost.sent)
         self.assertEqual(out['Content-Type'], 'text/html; charset="utf-8"')
         self.assertEqual(out['Content-Transfer-Encoding'], 'base64')
         # Headers set by parameter will be set using charset parameter
@@ -380,7 +394,7 @@ wqFVbiB0cnVjbyA8c3Ryb25nPmZhbnTDoXN0aWNvPC9zdHJvbmc+IQ=3D=3D
                       mto='"Name, Nick" <recipient@example.com>',
                       mfrom=mfrom, subject=subject, charset='utf-8',
                       msg_type='text/html')
-        out = message_from_string(mailhost.sent)
+        out = parse_message(mailhost.sent)
         self.assertEqual(
             out['To'], '"Name, Nick" <recipient@example.com>')
         self.assertEqual(
@@ -423,14 +437,14 @@ Here's some unencoded <strong>text</strong>."""
                       mfrom=u'Foo Bar <foo@example.com>', subject=subject)
         out = mailhost.sent
         # Ensure the results are not unicode
-        self.assertEqual(out, """\
+        self.assertEqual(out, b"""\
 Date: Sun, 27 Aug 2006 17:00:00 +0200
 Subject: Andres!
 To: "Name, Nick" <recipient@example.com>
 From: Foo Bar <foo@example.com>
 
 Here's some unencoded <strong>text</strong>.""")
-        self.assertEqual(type(out), str)
+        self.assertEqual(type(out), bytes)
 
     def testSendMessageObject(self):
         # send will accept an email.Message.Message object directly
@@ -447,14 +461,14 @@ wqFVbiB0cnVjbyA8c3Ryb25nPmZhbnTDoXN0aWNvPC9zdHJvbmc+IQ=3D=3D
 """)
         mailhost = self._makeOne('MailHost')
         mailhost.send(msg)
-        out = message_from_string(mailhost.sent)
+        out = parse_message(mailhost.sent)
         self.assertEqual(out.as_string(), msg.as_string())
 
         # we can even alter a from and subject headers without affecting the
         # original object
         mailhost.send(msg,
                       mfrom='Foo Bar <foo@example.com>', subject='Changed!')
-        out = message_from_string(mailhost.sent)
+        out = parse_message(mailhost.sent)
 
         # We need to make sure we didn't mutate the message we were passed
         self.assertNotEqual(out.as_string(), msg.as_string())
@@ -468,6 +482,49 @@ wqFVbiB0cnVjbyA8c3Ryb25nPmZhbnTDoXN0aWNvPC9zdHJvbmc+IQ=3D=3D
         self.assertEqual(msg['Subject'],
                          '=?utf-8?q?=C2=BFEsferificaci=C3=B3n=3F?=')
 
+    def testSendMultipartMessageObject(self):
+        TO = 'Name, Nick <recipient@example.com>'
+        FROM = 'sender@example.com'
+
+        outer = MIMEMultipart()
+        outer['Subject'] = 'This is the subject'
+        outer['To'] = TO
+        outer['From'] = FROM
+        outer.preamble = 'This is a MIME encoded multipart message.\n'
+        outer.epilogue = ''
+        body = 'This is the message body.'
+        msg = MIMEText(body, _subtype='text', _charset='utf-8')
+        outer.attach(msg)
+        outer.set_boundary('===============8011890429167670482==')
+
+        mailhost = self._makeOne('MailHost')
+        mailhost.send(
+            outer.as_string(),
+            mto=TO,
+            mfrom=FROM,
+        )
+        # date_pattern matches e.g. `Tue, 21 Jul 2020 08:50:04 +0200`
+        date_pattern = b'[a-zA-Z]{2,3}, [0-9]{1,2} [a-zA-Z]{3} [0-9]{4} [0-9]{2}:[0-9]{2}:[0-9]{2} [+-]{1}[0-9]{4}'  # noqa: E501
+        pattern = (
+            b'Content-Type: multipart/mixed; '
+            b'boundary="===============8011890429167670482=="\n'
+            b'MIME-Version: 1.0\n'
+            b'Subject: This is the subject\n'
+            b'To: Name, Nick <recipient@example.com>\n'
+            b'From: sender@example.com\n'
+            b'Date: %s\n\n'
+            b'This is a MIME encoded multipart message.\n\n'
+            b'--===============8011890429167670482==\n'
+            b'Content-Type: text/text; charset="utf-8"\n'
+            b'MIME-Version: 1.0\n'
+            b'Content-Transfer-Encoding: quoted-printable\n\n'
+            b'This is the message body.\n'
+            b'--===============8011890429167670482==--\n' % date_pattern)  # noqa: E501
+        if six.PY2:
+            self.assertRegexpMatches(mailhost.sent, pattern)
+        else:  # PY3
+            self.assertRegex(mailhost.sent, pattern)
+
     def testExplicitBase64Encoding(self):
         mailhost = self._makeOne('MailHost')
         mailhost.send('Date: Sun, 27 Aug 2006 17:00:00 +0200\n\nA Message',
@@ -475,7 +532,7 @@ wqFVbiB0cnVjbyA8c3Ryb25nPmZhbnTDoXN0aWNvPC9zdHJvbmc+IQ=3D=3D
                       mto='Foo Bar <foo@example.com>', encode='base64')
         # Explicitly stripping the output here since the base64 encoder
         # in Python 3 adds a line break at the end.
-        self.assertEqual(mailhost.sent.strip(), """\
+        self.assertEqual(mailhost.sent.strip(), b"""\
 Date: Sun, 27 Aug 2006 17:00:00 +0200
 Subject: [No Subject]
 To: Foo Bar <foo@example.com>
@@ -490,7 +547,7 @@ QSBNZXNzYWdl""")
         mailhost.send('Date: Sun, 27 Aug 2006 17:00:00 +0200\n\nA Message',
                       mfrom='sender@example.com',
                       mto='Foo Bar <foo@example.com>', encode='7bit')
-        self.assertEqual(mailhost.sent, """\
+        self.assertEqual(mailhost.sent, b"""\
 Date: Sun, 27 Aug 2006 17:00:00 +0200
 Subject: [No Subject]
 To: Foo Bar <foo@example.com>
@@ -500,6 +557,7 @@ Mime-Version: 1.0
 
 A Message""")
 
+    @unittest.skipUnless(PY36, 'requires Python 3.6+')
     def testExplicit8bitEncoding(self):
         mailhost = self._makeOne('MailHost')
         # We pass an encoded string with unspecified charset, it should be
@@ -508,7 +566,10 @@ A Message""")
                       'A M\xc3\xa9ssage',
                       mfrom='sender@example.com',
                       mto='Foo Bar <foo@example.com>', encode='8bit')
-        self.assertEqual(mailhost.sent, """\
+        msg = mailhost.sent
+        if six.PY3:
+            msg = msg.decode()
+        self.assertEqual(msg, """\
 Date: Sun, 27 Aug 2006 17:00:00 +0200
 Subject: [No Subject]
 To: Foo Bar <foo@example.com>
@@ -573,8 +634,10 @@ Content-Transfer-Encoding: quoted-printable
         mailhost.send(msg, charset='utf-8')
         # There is a one newline difference in the output between
         # zope.sendmail versions.
+        if six.PY3:
+            msg = msg.encode()
         self.assertEqual(mailhost.sent[:677], msg[:677])
-        self.assertTrue(mailhost.sent.endswith('==0490954888==--\n'))
+        self.assertTrue(mailhost.sent.endswith(b'==0490954888==--\n'))
 
     def testSendMultiPartMixedMessage(self):
         msg = ("""\
@@ -629,6 +692,8 @@ D=EDt =EFs =E9=E9n test
         # effects in the case of multipart mails.
         # (TypeError: expected string or buffer)
         mailhost.send(msg, charset='utf-8')
+        if six.PY3:
+            msg = msg.encode()
         self.assertEqual(mailhost.sent, msg)
 
     def test_manage_makeChanges(self):
@@ -692,6 +757,25 @@ class TestMailHostQueuing(unittest.TestCase):
         md = zope.sendmail.maildir.Maildir(self.smtp_queue_directory)
         self.assertEqual(len(list(md)), 1)
 
+    @unittest.skipUnless(PY36, 'requires Python 3.6+')
+    def test_8bit_special(self):
+        mh = self._makeOne('MailHost')
+        mh.send(u"""\
+Mime-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+\u00e4
+""",
+                mto='user@example.com',
+                mfrom='zope@example.com',
+                subject='Hello world',
+                charset='utf-8')
+        transaction.commit()
+        self.assertTrue(mh.started_queue_processor_thread)
+        md = zope.sendmail.maildir.Maildir(self.smtp_queue_directory)
+        self.assertEqual(len(list(md)), 1)
+
     def testNotStartQueueProcessorThread(self):
         os.environ['MAILHOST_QUEUE_ONLY'] = '1'
         try:
diff --git a/src/Products/MailHost/tests/test_SendMailTag.py b/src/Products/MailHost/tests/test_SendMailTag.py
index cfebcd5..9848170 100644
--- a/src/Products/MailHost/tests/test_SendMailTag.py
+++ b/src/Products/MailHost/tests/test_SendMailTag.py
@@ -74,9 +74,9 @@ class SendMailTagTests(unittest.TestCase):
                             '</dtml-sendmail>'))
         self.app.testing(client=self.app)
         self.assertEqual(self.app.MailHost.sent,
-                         ('To: person@their.machine.com\n'
-                          'From: me@mymachine.net\n'
-                          'Subject: just called to say...\n'
-                          'Date: Thu, 16 May 2019 16:04:14 -0500\n'
-                          '\n'
-                          'boy howdy!\n'))
+                         (b'To: person@their.machine.com\n'
+                          b'From: me@mymachine.net\n'
+                          b'Subject: just called to say...\n'
+                          b'Date: Thu, 16 May 2019 16:04:14 -0500\n'
+                          b'\n'
+                          b'boy howdy!\n'))

pip install -e .[genericsetup]
parse_log_pytest
pytest
pytest
3.9
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
AccessControl==7.2
Acquisition==6.1
AuthEncoding==6.0
beautifulsoup4==4.13.3
BTrees==6.1
cffi==1.17.1
Chameleon==4.6.0
DateTime==5.5
DocumentTemplate==4.6
exceptiongroup @ file:///croot/exceptiongroup_1706031385326/work
ExtensionClass==6.0
five.localsitemanager==5.0
importlib_metadata==8.6.1
iniconfig @ file:///home/linux1/recipes/ci/iniconfig_1610983019677/work
Missing==5.0
MultiMapping==5.0
multipart==1.2.1
packaging @ file:///croot/packaging_1734472117206/work
PasteDeploy==3.1.0
Persistence==5.1
persistent==6.1.1
pluggy @ file:///croot/pluggy_1733169602837/work
Products.GenericSetup==5.0.0
-e git+https://github.com/zopefoundation/Products.MailHost.git@e848f00e922ebded3eec35a8a345cbfd31068cdd#egg=Products.MailHost
Products.PythonScripts==5.1
Products.ZCatalog==7.1
pycparser==2.22
pytest @ file:///croot/pytest_1738938843180/work
python-gettext==5.0
pytz==2025.2
Record==4.1
RestrictedPython==8.1a1.dev0
roman==5.0
six==1.17.0
soupsieve==2.6
tomli @ file:///opt/conda/conda-bld/tomli_1657175507142/work
transaction==5.0
typing_extensions==4.13.0
waitress==3.0.2
WebOb==1.8.9
WebTest==3.0.4
WSGIProxy2==0.5.1
z3c.pt==4.5
zc.lockfile==3.0.post1
ZConfig==4.2
zExceptions==5.0
zipp==3.21.0
ZODB==6.0
zodbpickle==4.2
Zope==5.13
zope.annotation==5.1
zope.browser==3.1
zope.browsermenu==5.1
zope.browserpage==5.0
zope.browserresource==5.2
zope.cachedescriptors==5.1
zope.component==6.0
zope.configuration==6.0
zope.container==6.1
zope.contentprovider==6.0
zope.contenttype==5.2
zope.datetime==5.1
zope.deferredimport==5.0
zope.deprecation==5.1
zope.dottedname==6.0
zope.event==5.0
zope.exceptions==5.2
zope.filerepresentation==6.1
zope.globalrequest==2.0
zope.hookable==7.0
zope.i18n==5.2
zope.i18nmessageid==7.0
zope.interface==7.2
zope.lifecycleevent==5.1
zope.location==5.1
zope.pagetemplate==5.1
zope.processlifetime==3.1
zope.proxy==6.1
zope.ptresource==5.1
zope.publisher==7.3
zope.schema==7.0.1
zope.security==7.3
zope.sendmail==6.2
zope.sequencesort==5.1
zope.site==5.1
zope.size==5.1
zope.structuredtext==5.0
zope.tal==5.1
zope.tales==6.1
zope.testbrowser==7.0.1
zope.testing==5.1
zope.traversing==5.1
zope.viewlet==5.1

name: Products.MailHost
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - exceptiongroup=1.2.0=py39h06a4308_0
  - iniconfig=1.1.1=pyhd3eb1b0_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - packaging=24.2=py39h06a4308_0
  - pip=25.0=py39h06a4308_0
  - pluggy=1.5.0=py39h06a4308_0
  - pytest=8.3.4=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tomli=2.0.1=py39h06a4308_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - accesscontrol==7.2
      - acquisition==6.1
      - authencoding==6.0
      - beautifulsoup4==4.13.3
      - btrees==6.1
      - cffi==1.17.1
      - chameleon==4.6.0
      - datetime==5.5
      - documenttemplate==4.6
      - extensionclass==6.0
      - five-localsitemanager==5.0
      - importlib-metadata==8.6.1
      - missing==5.0
      - multimapping==5.0
      - multipart==1.2.1
      - pastedeploy==3.1.0
      - persistence==5.1
      - persistent==6.1.1
      - products-genericsetup==5.0.0
      - products-pythonscripts==5.1
      - products-zcatalog==7.1
      - pycparser==2.22
      - python-gettext==5.0
      - pytz==2025.2
      - record==4.1
      - restrictedpython==8.1a1.dev0
      - roman==5.0
      - six==1.17.0
      - soupsieve==2.6
      - transaction==5.0
      - typing-extensions==4.13.0
      - waitress==3.0.2
      - webob==1.8.9
      - webtest==3.0.4
      - wsgiproxy2==0.5.1
      - z3c-pt==4.5
      - zc-lockfile==3.0.post1
      - zconfig==4.2
      - zexceptions==5.0
      - zipp==3.21.0
      - zodb==6.0
      - zodbpickle==4.2
      - zope==5.13
      - zope-annotation==5.1
      - zope-browser==3.1
      - zope-browsermenu==5.1
      - zope-browserpage==5.0
      - zope-browserresource==5.2
      - zope-cachedescriptors==5.1
      - zope-component==6.0
      - zope-configuration==6.0
      - zope-container==6.1
      - zope-contentprovider==6.0
      - zope-contenttype==5.2
      - zope-datetime==5.1
      - zope-deferredimport==5.0
      - zope-deprecation==5.1
      - zope-dottedname==6.0
      - zope-event==5.0
      - zope-exceptions==5.2
      - zope-filerepresentation==6.1
      - zope-globalrequest==2.0
      - zope-hookable==7.0
      - zope-i18n==5.2
      - zope-i18nmessageid==7.0
      - zope-interface==7.2
      - zope-lifecycleevent==5.1
      - zope-location==5.1
      - zope-pagetemplate==5.1
      - zope-processlifetime==3.1
      - zope-proxy==6.1
      - zope-ptresource==5.1
      - zope-publisher==7.3
      - zope-schema==7.0.1
      - zope-security==7.3
      - zope-sendmail==6.2
      - zope-sequencesort==5.1
      - zope-site==5.1
      - zope-size==5.1
      - zope-structuredtext==5.0
      - zope-tal==5.1
      - zope-tales==6.1
      - zope-testbrowser==7.0.1
      - zope-testing==5.1
      - zope-traversing==5.1
      - zope-viewlet==5.1
prefix: /opt/conda/envs/Products.MailHost

src/Products/MailHost/tests/testMailHost.py::TestMailHost::testAlreadyEncodedMessage src/Products/MailHost/tests/testMailHost.py::TestMailHost::testAlreadyEncodedMessageWithCharset src/Products/MailHost/tests/testMailHost.py::TestMailHost::testEncodedHeaders src/Products/MailHost/tests/testMailHost.py::TestMailHost::testExplicit7bitEncoding src/Products/MailHost/tests/testMailHost.py::TestMailHost::testExplicit8bitEncoding src/Products/MailHost/tests/testMailHost.py::TestMailHost::testExplicitBase64Encoding src/Products/MailHost/tests/testMailHost.py::TestMailHost::testSendBodyWithUrl src/Products/MailHost/tests/testMailHost.py::TestMailHost::testSendEncodedBody src/Products/MailHost/tests/testMailHost.py::TestMailHost::testSendMessageObject src/Products/MailHost/tests/testMailHost.py::TestMailHost::testSendMessageOnly src/Products/MailHost/tests/testMailHost.py::TestMailHost::testSendMultiPartAlternativeMessage src/Products/MailHost/tests/testMailHost.py::TestMailHost::testSendMultiPartMixedMessage src/Products/MailHost/tests/testMailHost.py::TestMailHost::testSendMultipartMessageObject src/Products/MailHost/tests/testMailHost.py::TestMailHost::testSendWithArguments src/Products/MailHost/tests/testMailHost.py::TestMailHost::testSendWithMtoList src/Products/MailHost/tests/testMailHost.py::TestMailHost::testUnicodeDefaultEncoding src/Products/MailHost/tests/test_SendMailTag.py::SendMailTagTests::test_dtml_var
src/Products/MailHost/tests/testMailHost.py::TestMailHost::testAddressParser src/Products/MailHost/tests/testMailHost.py::TestMailHost::testAllHeaders src/Products/MailHost/tests/testMailHost.py::TestMailHost::testBCCHeader src/Products/MailHost/tests/testMailHost.py::TestMailHost::testMissingHeaders src/Products/MailHost/tests/testMailHost.py::TestMailHost::testNoHeaders src/Products/MailHost/tests/testMailHost.py::TestMailHost::testSendImmediate src/Products/MailHost/tests/testMailHost.py::TestMailHost::testSendTemplate src/Products/MailHost/tests/testMailHost.py::TestMailHost::testSimpleSend src/Products/MailHost/tests/testMailHost.py::TestMailHost::test__getThreadKey_uses_fspath src/Products/MailHost/tests/testMailHost.py::TestMailHost::test_manage_makeChanges src/Products/MailHost/tests/testMailHost.py::TestMailHost::test_z3interfaces src/Products/MailHost/tests/testMailHost.py::TestMailHostQueuing::testNotStartQueueProcessorThread src/Products/MailHost/tests/testMailHost.py::TestMailHostQueuing::testStartQueueProcessorThread src/Products/MailHost/tests/testMailHost.py::TestMailHostQueuing::test_8bit_special src/Products/MailHost/tests/test_SendMailTag.py::SendMailTagTests::test_instantiation src/Products/MailHost/tests/test_SendMailTag.py::SendMailTagTests::test_instantiation_full
setup.py tox.ini src/Products/MailHost/MailHost.py CHANGES.rst
setup.py tox.ini src/Products/MailHost/MailHost.py CHANGES.rst