prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  PyPI sends emails with unicode in header
  **Describe the bug**
  <!-- A clear and concise description the bug -->
  I created a new account on pypi.org, but I am not receiving any email verification link by email - not after accouunt creation and also not after resending the verification link (even if pypi.org claims "Verification email for nicolas@seita.nl resent").
  
  test.pypi.org works for me, using the same account name and email address. I deleted and recreated the account on both pypi.org and test.pypi.org - same behaviour (well, the initial email did sometimes not arrive on test.pypi.org, but the the verification resend always arrived right away).
  
  **Expected behavior**
  <!-- A clear and concise description of what you expected to happen -->
  I should get an email token after registering, and also when I resend the verification mail from the account page. I know it might take a while, but I am experiencing this since Friday.
  
  **To Reproduce**
  <!-- Steps to reproduce the bug, or a link to PyPI where the bug is visible -->
  Register on pypi.org, wait for email. Resend the verification email from the account settings page, wait again.
  
  **My Platform**
  <!--
      Any details about your specific platform:
      * If the problem is in the browser, what browser, version, and OS?
      * If the problem is with a command-line tool, what version of that tool?
      * If the problem is with connecting to PyPI, include some details about
        your network, including SSL/TLS implementation in use, internet service
        provider, and if there are any firewalls or proxies in use.
  -->
  Firefox 52
  
  
  </issue>
  <code>
  [start of warehouse/email/services.py]
  1 # Licensed under the Apache License, Version 2.0 (the "License");
  2 # you may not use this file except in compliance with the License.
  3 # You may obtain a copy of the License at
  4 #
  5 # http://www.apache.org/licenses/LICENSE-2.0
  6 #
  7 # Unless required by applicable law or agreed to in writing, software
  8 # distributed under the License is distributed on an "AS IS" BASIS,
  9 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10 # See the License for the specific language governing permissions and
  11 # limitations under the License.
  12 
  13 from email.headerregistry import Address
  14 from email.utils import parseaddr
  15 
  16 from pyramid_mailer import get_mailer
  17 from pyramid_mailer.message import Message
  18 from zope.interface import implementer
  19 
  20 from warehouse.email.interfaces import IEmailSender
  21 from warehouse.email.ses.models import EmailMessage
  22 
  23 
  24 def _format_sender(sitename, sender):
  25     if sender is not None:
  26         return str(Address(sitename, addr_spec=sender))
  27 
  28 
  29 @implementer(IEmailSender)
  30 class SMTPEmailSender:
  31     def __init__(self, mailer, sender=None):
  32         self.mailer = mailer
  33         self.sender = sender
  34 
  35     @classmethod
  36     def create_service(cls, context, request):
  37         sitename = request.registry.settings["site.name"]
  38         sender = _format_sender(sitename, request.registry.settings.get("mail.sender"))
  39         return cls(get_mailer(request), sender=sender)
  40 
  41     def send(self, subject, body, *, recipient):
  42         message = Message(
  43             subject=subject, body=body, recipients=[recipient], sender=self.sender
  44         )
  45         self.mailer.send_immediately(message)
  46 
  47 
  48 @implementer(IEmailSender)
  49 class SESEmailSender:
  50     def __init__(self, client, *, sender=None, db):
  51         self._client = client
  52         self._sender = sender
  53         self._db = db
  54 
  55     @classmethod
  56     def create_service(cls, context, request):
  57         sitename = request.registry.settings["site.name"]
  58         sender = _format_sender(sitename, request.registry.settings.get("mail.sender"))
  59 
  60         aws_session = request.find_service(name="aws.session")
  61 
  62         return cls(
  63             aws_session.client(
  64                 "ses", region_name=request.registry.settings.get("mail.region")
  65             ),
  66             sender=sender,
  67             db=request.db,
  68         )
  69 
  70     def send(self, subject, body, *, recipient):
  71         resp = self._client.send_email(
  72             Source=self._sender,
  73             Destination={"ToAddresses": [recipient]},
  74             Message={
  75                 "Subject": {"Data": subject, "Charset": "UTF-8"},
  76                 "Body": {"Text": {"Data": body, "Charset": "UTF-8"}},
  77             },
  78         )
  79 
  80         self._db.add(
  81             EmailMessage(
  82                 message_id=resp["MessageId"],
  83                 from_=parseaddr(self._sender)[1],
  84                 to=parseaddr(recipient)[1],
  85                 subject=subject,
  86             )
  87         )
  88
  [end of warehouse/email/services.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/warehouse/email/services.py b/warehouse/email/services.py
  --- a/warehouse/email/services.py
  +++ b/warehouse/email/services.py
  @@ -11,7 +11,9 @@
   # limitations under the License.
   
   from email.headerregistry import Address
  -from email.utils import parseaddr
  +from email.mime.multipart import MIMEMultipart
  +from email.mime.text import MIMEText
  +from email.utils import parseaddr, formataddr
   
   from pyramid_mailer import get_mailer
   from pyramid_mailer.message import Message
  @@ -68,13 +70,25 @@
           )
   
       def send(self, subject, body, *, recipient):
  -        resp = self._client.send_email(
  +        message = MIMEMultipart("mixed")
  +        message["Subject"] = subject
  +        message["From"] = self._sender
  +
  +        # The following is necessary to support friendly names with Unicode characters,
  +        # otherwise the entire value will get encoded and will not be accepted by SES:
  +        #
  +        #   >>> parseaddr("Fööbar <foo@bar.com>")
  +        #   ('Fööbar', 'foo@bar.com')
  +        #   >>> formataddr(_)
  +        #   '=?utf-8?b?RsO2w7ZiYXI=?= <foo@bar.com>'
  +        message["To"] = formataddr(parseaddr(recipient))
  +
  +        message.attach(MIMEText(body, "plain", "utf-8"))
  +
  +        resp = self._client.send_raw_email(
               Source=self._sender,
  -            Destination={"ToAddresses": [recipient]},
  -            Message={
  -                "Subject": {"Data": subject, "Charset": "UTF-8"},
  -                "Body": {"Text": {"Data": body, "Charset": "UTF-8"}},
  -            },
  +            Destinations=[recipient],
  +            RawMessage={"Data": message.as_string()},
           )
   
           self._db.add(
  
verification_info: {"golden_diff": "diff --git a/warehouse/email/services.py b/warehouse/email/services.py\n--- a/warehouse/email/services.py\n+++ b/warehouse/email/services.py\n@@ -11,7 +11,9 @@\n # limitations under the License.\n \n from email.headerregistry import Address\n-from email.utils import parseaddr\n+from email.mime.multipart import MIMEMultipart\n+from email.mime.text import MIMEText\n+from email.utils import parseaddr, formataddr\n \n from pyramid_mailer import get_mailer\n from pyramid_mailer.message import Message\n@@ -68,13 +70,25 @@\n         )\n \n     def send(self, subject, body, *, recipient):\n-        resp = self._client.send_email(\n+        message = MIMEMultipart(\"mixed\")\n+        message[\"Subject\"] = subject\n+        message[\"From\"] = self._sender\n+\n+        # The following is necessary to support friendly names with Unicode characters,\n+        # otherwise the entire value will get encoded and will not be accepted by SES:\n+        #\n+        #   >>> parseaddr(\"F\u00f6\u00f6bar <foo@bar.com>\")\n+        #   ('F\u00f6\u00f6bar', 'foo@bar.com')\n+        #   >>> formataddr(_)\n+        #   '=?utf-8?b?RsO2w7ZiYXI=?= <foo@bar.com>'\n+        message[\"To\"] = formataddr(parseaddr(recipient))\n+\n+        message.attach(MIMEText(body, \"plain\", \"utf-8\"))\n+\n+        resp = self._client.send_raw_email(\n             Source=self._sender,\n-            Destination={\"ToAddresses\": [recipient]},\n-            Message={\n-                \"Subject\": {\"Data\": subject, \"Charset\": \"UTF-8\"},\n-                \"Body\": {\"Text\": {\"Data\": body, \"Charset\": \"UTF-8\"}},\n-            },\n+            Destinations=[recipient],\n+            RawMessage={\"Data\": message.as_string()},\n         )\n \n         self._db.add(\n", "issue": "PyPI sends emails with unicode in header\n**Describe the bug**\r\n<!-- A clear and concise description the bug -->\r\nI created a new account on pypi.org, but I am not receiving any email verification link by email - not after accouunt creation and also not after resending the verification link (even if pypi.org claims \"Verification email for nicolas@seita.nl resent\").\r\n\r\ntest.pypi.org works for me, using the same account name and email address. I deleted and recreated the account on both pypi.org and test.pypi.org - same behaviour (well, the initial email did sometimes not arrive on test.pypi.org, but the the verification resend always arrived right away).\r\n\r\n**Expected behavior**\r\n<!-- A clear and concise description of what you expected to happen -->\r\nI should get an email token after registering, and also when I resend the verification mail from the account page. I know it might take a while, but I am experiencing this since Friday.\r\n\r\n**To Reproduce**\r\n<!-- Steps to reproduce the bug, or a link to PyPI where the bug is visible -->\r\nRegister on pypi.org, wait for email. Resend the verification email from the account settings page, wait again.\r\n\r\n**My Platform**\r\n<!--\r\n    Any details about your specific platform:\r\n    * If the problem is in the browser, what browser, version, and OS?\r\n    * If the problem is with a command-line tool, what version of that tool?\r\n    * If the problem is with connecting to PyPI, include some details about\r\n      your network, including SSL/TLS implementation in use, internet service\r\n      provider, and if there are any firewalls or proxies in use.\r\n-->\r\nFirefox 52\r\n\n", "before_files": [{"content": "# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nfrom email.headerregistry import Address\nfrom email.utils import parseaddr\n\nfrom pyramid_mailer import get_mailer\nfrom pyramid_mailer.message import Message\nfrom zope.interface import implementer\n\nfrom warehouse.email.interfaces import IEmailSender\nfrom warehouse.email.ses.models import EmailMessage\n\n\ndef _format_sender(sitename, sender):\n    if sender is not None:\n        return str(Address(sitename, addr_spec=sender))\n\n\n@implementer(IEmailSender)\nclass SMTPEmailSender:\n    def __init__(self, mailer, sender=None):\n        self.mailer = mailer\n        self.sender = sender\n\n    @classmethod\n    def create_service(cls, context, request):\n        sitename = request.registry.settings[\"site.name\"]\n        sender = _format_sender(sitename, request.registry.settings.get(\"mail.sender\"))\n        return cls(get_mailer(request), sender=sender)\n\n    def send(self, subject, body, *, recipient):\n        message = Message(\n            subject=subject, body=body, recipients=[recipient], sender=self.sender\n        )\n        self.mailer.send_immediately(message)\n\n\n@implementer(IEmailSender)\nclass SESEmailSender:\n    def __init__(self, client, *, sender=None, db):\n        self._client = client\n        self._sender = sender\n        self._db = db\n\n    @classmethod\n    def create_service(cls, context, request):\n        sitename = request.registry.settings[\"site.name\"]\n        sender = _format_sender(sitename, request.registry.settings.get(\"mail.sender\"))\n\n        aws_session = request.find_service(name=\"aws.session\")\n\n        return cls(\n            aws_session.client(\n                \"ses\", region_name=request.registry.settings.get(\"mail.region\")\n            ),\n            sender=sender,\n            db=request.db,\n        )\n\n    def send(self, subject, body, *, recipient):\n        resp = self._client.send_email(\n            Source=self._sender,\n            Destination={\"ToAddresses\": [recipient]},\n            Message={\n                \"Subject\": {\"Data\": subject, \"Charset\": \"UTF-8\"},\n                \"Body\": {\"Text\": {\"Data\": body, \"Charset\": \"UTF-8\"}},\n            },\n        )\n\n        self._db.add(\n            EmailMessage(\n                message_id=resp[\"MessageId\"],\n                from_=parseaddr(self._sender)[1],\n                to=parseaddr(recipient)[1],\n                subject=subject,\n            )\n        )\n", "path": "warehouse/email/services.py"}]}