diff mercurial/mail.py @ 43076:2372284d9457

formatting: blacken the codebase This is using my patch to black (https://github.com/psf/black/pull/826) so we don't un-wrap collection literals. Done with: hg files 'set:**.py - mercurial/thirdparty/** - "contrib/python-zstandard/**"' | xargs black -S # skip-blame mass-reformatting only # no-check-commit reformats foo_bar functions Differential Revision: https://phab.mercurial-scm.org/D6971
author Augie Fackler <augie@google.com>
date Sun, 06 Oct 2019 09:45:02 -0400
parents 2cc453284d5c
children 687b865b95ad
line wrap: on
line diff
--- a/mercurial/mail.py	Sat Oct 05 10:29:34 2019 -0400
+++ b/mercurial/mail.py	Sun Oct 06 09:45:02 2019 -0400
@@ -31,11 +31,13 @@
     stringutil,
 )
 
+
 class STARTTLS(smtplib.SMTP):
     '''Derived class to verify the peer certificate for STARTTLS.
 
     This class allows to pass any keyword arguments to SSL socket creation.
     '''
+
     def __init__(self, ui, host=None, **kwargs):
         smtplib.SMTP.__init__(self, **kwargs)
         self._ui = ui
@@ -47,9 +49,13 @@
             raise smtplib.SMTPException(msg)
         (resp, reply) = self.docmd("STARTTLS")
         if resp == 220:
-            self.sock = sslutil.wrapsocket(self.sock, keyfile, certfile,
-                                           ui=self._ui,
-                                           serverhostname=self._host)
+            self.sock = sslutil.wrapsocket(
+                self.sock,
+                keyfile,
+                certfile,
+                ui=self._ui,
+                serverhostname=self._host,
+            )
             self.file = smtplib.SSLFakeFile(self.sock)
             self.helo_resp = None
             self.ehlo_resp = None
@@ -57,13 +63,14 @@
             self.does_esmtp = 0
         return (resp, reply)
 
+
 class SMTPS(smtplib.SMTP):
     '''Derived class to verify the peer certificate for SMTPS.
 
     This class allows to pass any keyword arguments to SSL socket creation.
     '''
-    def __init__(self, ui, keyfile=None, certfile=None, host=None,
-                 **kwargs):
+
+    def __init__(self, ui, keyfile=None, certfile=None, host=None, **kwargs):
         self.keyfile = keyfile
         self.certfile = certfile
         smtplib.SMTP.__init__(self, **kwargs)
@@ -75,22 +82,28 @@
         if self.debuglevel > 0:
             self._ui.debug('connect: %r\n' % ((host, port),))
         new_socket = socket.create_connection((host, port), timeout)
-        new_socket = sslutil.wrapsocket(new_socket,
-                                        self.keyfile, self.certfile,
-                                        ui=self._ui,
-                                        serverhostname=self._host)
+        new_socket = sslutil.wrapsocket(
+            new_socket,
+            self.keyfile,
+            self.certfile,
+            ui=self._ui,
+            serverhostname=self._host,
+        )
         self.file = new_socket.makefile(r'rb')
         return new_socket
 
+
 def _pyhastls():
     """Returns true iff Python has TLS support, false otherwise."""
     try:
         import ssl
+
         getattr(ssl, 'HAS_TLS', False)
         return True
     except ImportError:
         return False
 
+
 def _smtp(ui):
     '''build an smtp connection and return a function to send mail'''
     local_hostname = ui.config('smtp', 'local_hostname')
@@ -115,8 +128,7 @@
     else:
         defaultport = 25
     mailport = util.getport(ui.config('smtp', 'port', defaultport))
-    ui.note(_('sending mail: smtp host %s, port %d\n') %
-            (mailhost, mailport))
+    ui.note(_('sending mail: smtp host %s, port %d\n') % (mailhost, mailport))
     s.connect(host=mailhost, port=mailport)
     if starttls:
         ui.note(_('(using starttls)\n'))
@@ -131,8 +143,7 @@
     if username and not password:
         password = ui.getpass()
     if username and password:
-        ui.note(_('(authenticating to mail server as %s)\n') %
-                  (username))
+        ui.note(_('(authenticating to mail server as %s)\n') % username)
         try:
             s.login(username, password)
         except smtplib.SMTPException as inst:
@@ -149,21 +160,31 @@
 
     return send
 
+
 def _sendmail(ui, sender, recipients, msg):
     '''send mail using sendmail.'''
     program = ui.config('email', 'method')
     stremail = lambda x: (
-        procutil.quote(stringutil.email(encoding.strtolocal(x))))
-    cmdline = '%s -f %s %s' % (program, stremail(sender),
-                               ' '.join(map(stremail, recipients)))
+        procutil.quote(stringutil.email(encoding.strtolocal(x)))
+    )
+    cmdline = '%s -f %s %s' % (
+        program,
+        stremail(sender),
+        ' '.join(map(stremail, recipients)),
+    )
     ui.note(_('sending mail: %s\n') % cmdline)
     fp = procutil.popen(cmdline, 'wb')
     fp.write(util.tonativeeol(msg))
     ret = fp.close()
     if ret:
-        raise error.Abort('%s %s' % (
-            os.path.basename(program.split(None, 1)[0]),
-            procutil.explainexit(ret)))
+        raise error.Abort(
+            '%s %s'
+            % (
+                os.path.basename(program.split(None, 1)[0]),
+                procutil.explainexit(ret),
+            )
+        )
+
 
 def _mbox(mbox, sender, recipients, msg):
     '''write mails to mbox'''
@@ -171,12 +192,15 @@
     # Should be time.asctime(), but Windows prints 2-characters day
     # of month instead of one. Make them print the same thing.
     date = time.strftime(r'%a %b %d %H:%M:%S %Y', time.localtime())
-    fp.write('From %s %s\n' % (encoding.strtolocal(sender),
-                               encoding.strtolocal(date)))
+    fp.write(
+        'From %s %s\n'
+        % (encoding.strtolocal(sender), encoding.strtolocal(date))
+    )
     fp.write(msg)
     fp.write('\n\n')
     fp.close()
 
+
 def connect(ui, mbox=None):
     '''make a mail connection. return a function to send mail.
     call as sendmail(sender, list-of-recipients, msg).'''
@@ -187,21 +211,30 @@
         return _smtp(ui)
     return lambda s, r, m: _sendmail(ui, s, r, m)
 
+
 def sendmail(ui, sender, recipients, msg, mbox=None):
     send = connect(ui, mbox=mbox)
     return send(sender, recipients, msg)
 
+
 def validateconfig(ui):
     '''determine if we have enough config data to try sending email.'''
     method = ui.config('email', 'method')
     if method == 'smtp':
         if not ui.config('smtp', 'host'):
-            raise error.Abort(_('smtp specified as email transport, '
-                               'but no smtp host configured'))
+            raise error.Abort(
+                _(
+                    'smtp specified as email transport, '
+                    'but no smtp host configured'
+                )
+            )
     else:
         if not procutil.findexe(method):
-            raise error.Abort(_('%r specified as email transport, '
-                               'but not in PATH') % method)
+            raise error.Abort(
+                _('%r specified as email transport, ' 'but not in PATH')
+                % method
+            )
+
 
 def codec2iana(cs):
     ''''''
@@ -212,6 +245,7 @@
         return "iso-" + cs[3:]
     return cs
 
+
 def mimetextpatch(s, subtype='plain', display=False):
     '''Return MIME message suitable for a patch.
     Charset will be detected by first trying to decode as us-ascii, then utf-8,
@@ -231,6 +265,7 @@
 
     return mimetextqp(s, subtype, "iso-8859-1")
 
+
 def mimetextqp(body, subtype, charset):
     '''Return MIME message.
     Quoted-printable transfer encoding will be used if necessary.
@@ -255,16 +290,21 @@
 
     return msg
 
+
 def _charsets(ui):
     '''Obtains charsets to send mail parts not containing patches.'''
     charsets = [cs.lower() for cs in ui.configlist('email', 'charsets')]
-    fallbacks = [encoding.fallbackencoding.lower(),
-                 encoding.encoding.lower(), 'utf-8']
-    for cs in fallbacks: # find unique charsets while keeping order
+    fallbacks = [
+        encoding.fallbackencoding.lower(),
+        encoding.encoding.lower(),
+        'utf-8',
+    ]
+    for cs in fallbacks:  # find unique charsets while keeping order
         if cs not in charsets:
             charsets.append(cs)
     return [cs for cs in charsets if not cs.endswith('ascii')]
 
+
 def _encode(ui, s, charsets):
     '''Returns (converted) string, charset tuple.
     Finds out best charset by cycling through sendcharsets in descending
@@ -307,6 +347,7 @@
     # if ascii, or all conversion attempts fail, send (broken) ascii
     return s, 'us-ascii'
 
+
 def headencode(ui, s, charsets=None, display=False):
     '''Returns RFC-2047 compliant header from given string.'''
     if not display:
@@ -315,6 +356,7 @@
         return str(email.header.Header(s, cs))
     return s
 
+
 def _addressencode(ui, name, addr, charsets=None):
     assert isinstance(addr, bytes)
     name = headencode(ui, name, charsets)
@@ -332,7 +374,9 @@
         except UnicodeDecodeError:
             raise error.Abort(_('invalid local address: %s') % addr)
     return pycompat.bytesurl(
-        email.utils.formataddr((name, encoding.strfromlocal(addr))))
+        email.utils.formataddr((name, encoding.strfromlocal(addr)))
+    )
+
 
 def addressencode(ui, address, charsets=None, display=False):
     '''Turns address into RFC-2047 compliant header.'''
@@ -341,23 +385,26 @@
     name, addr = email.utils.parseaddr(encoding.strfromlocal(address))
     return _addressencode(ui, name, encoding.strtolocal(addr), charsets)
 
+
 def addrlistencode(ui, addrs, charsets=None, display=False):
     '''Turns a list of addresses into a list of RFC-2047 compliant headers.
     A single element of input list may contain multiple addresses, but output
     always has one address per item'''
     for a in addrs:
-        assert isinstance(a, bytes), (r'%r unexpectedly not a bytestr' % a)
+        assert isinstance(a, bytes), r'%r unexpectedly not a bytestr' % a
     if display:
         return [a.strip() for a in addrs if a.strip()]
 
     result = []
     for name, addr in email.utils.getaddresses(
-            [encoding.strfromlocal(a) for a in addrs]):
+        [encoding.strfromlocal(a) for a in addrs]
+    ):
         if name or addr:
             r = _addressencode(ui, name, encoding.strtolocal(addr), charsets)
             result.append(r)
     return result
 
+
 def mimeencode(ui, s, charsets=None, display=False):
     '''creates mime text object, encodes it if needed, and sets
     charset and transfer-encoding accordingly.'''
@@ -366,23 +413,30 @@
         s, cs = _encode(ui, s, charsets)
     return mimetextqp(s, 'plain', cs)
 
+
 if pycompat.ispy3:
+
     def parse(fp):
         ep = email.parser.Parser()
         # disable the "universal newlines" mode, which isn't binary safe.
         # I have no idea if ascii/surrogateescape is correct, but that's
         # what the standard Python email parser does.
-        fp = io.TextIOWrapper(fp, encoding=r'ascii',
-                              errors=r'surrogateescape', newline=chr(10))
+        fp = io.TextIOWrapper(
+            fp, encoding=r'ascii', errors=r'surrogateescape', newline=chr(10)
+        )
         try:
             return ep.parse(fp)
         finally:
             fp.detach()
+
+
 else:
+
     def parse(fp):
         ep = email.parser.Parser()
         return ep.parse(fp)
 
+
 def headdecode(s):
     '''Decodes RFC-2047 header'''
     uparts = []