Ignore:
Timestamp:
Mar 19, 2014, 11:31:01 PM (11 years ago)
Author:
dmik
Message:

python: Merge vendor 2.7.6 to trunk.

Location:
python/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • python/trunk

  • python/trunk/Lib/smtplib.py

    r2 r391  
    5050from sys import stderr
    5151
    52 __all__ = ["SMTPException","SMTPServerDisconnected","SMTPResponseException",
    53            "SMTPSenderRefused","SMTPRecipientsRefused","SMTPDataError",
    54            "SMTPConnectError","SMTPHeloError","SMTPAuthenticationError",
    55            "quoteaddr","quotedata","SMTP"]
     52__all__ = ["SMTPException", "SMTPServerDisconnected", "SMTPResponseException",
     53           "SMTPSenderRefused", "SMTPRecipientsRefused", "SMTPDataError",
     54           "SMTPConnectError", "SMTPHeloError", "SMTPAuthenticationError",
     55           "quoteaddr", "quotedata", "SMTP"]
    5656
    5757SMTP_PORT = 25
    5858SMTP_SSL_PORT = 465
    59 CRLF="\r\n"
     59CRLF = "\r\n"
    6060
    6161OLDSTYLE_AUTH = re.compile(r"auth=(.*)", re.I)
     62
    6263
    6364# Exception classes used by this module.
     
    110111    def __init__(self, recipients):
    111112        self.recipients = recipients
    112         self.args = ( recipients,)
     113        self.args = (recipients,)
    113114
    114115
     
    128129    combination provided.
    129130    """
     131
    130132
    131133def quoteaddr(addr):
     
    139141    except AttributeError:
    140142        pass
    141     if m == (None, None): # Indicates parse failure or AttributeError
     143    if m == (None, None):  # Indicates parse failure or AttributeError
    142144        # something weird here.. punt -ddm
    143145        return "<%s>" % addr
     
    148150        return "<%s>" % m
    149151
     152def _addr_only(addrstring):
     153    displayname, addr = email.utils.parseaddr(addrstring)
     154    if (displayname, addr) == ('', ''):
     155        # parseaddr couldn't parse it, so use it as is.
     156        return addrstring
     157    return addr
     158
    150159def quotedata(data):
    151160    """Quote data for email.
     
    176185            while chr != "\n":
    177186                chr = self.sslobj.read(1)
    178                 if not chr: break
     187                if not chr:
     188                    break
    179189                str += chr
    180190            return str
     
    220230    ehlo_resp = None
    221231    does_esmtp = 0
     232    default_port = SMTP_PORT
    222233
    223234    def __init__(self, host='', port=0, local_hostname=None,
     
    227238        If specified, `host' is the name of the remote host to which to
    228239        connect.  If specified, `port' specifies the port to which to connect.
    229         By default, smtplib.SMTP_PORT is used.  An SMTPConnectError is raised
    230         if the specified `host' doesn't respond correctly.  If specified,
    231         `local_hostname` is used as the FQDN of the local host.  By default,
    232         the local hostname is found using socket.getfqdn().
     240        By default, smtplib.SMTP_PORT is used.  If a host is specified the
     241        connect method is called, and if it returns anything other than a
     242        success code an SMTPConnectError is raised.  If specified,
     243        `local_hostname` is used as the FQDN of the local host for the
     244        HELO/EHLO command.  Otherwise, the local hostname is found using
     245        socket.getfqdn().
    233246
    234247        """
    235248        self.timeout = timeout
    236249        self.esmtp_features = {}
    237         self.default_port = SMTP_PORT
    238250        if host:
    239251            (code, msg) = self.connect(host, port)
     
    267279        self.debuglevel = debuglevel
    268280
    269     def _get_socket(self, port, host, timeout):
     281    def _get_socket(self, host, port, timeout):
    270282        # This makes it simpler for SMTP_SSL to use the SMTP connect code
    271283        # and just alter the socket connection bit.
    272         if self.debuglevel > 0: print>>stderr, 'connect:', (host, port)
    273         return socket.create_connection((port, host), timeout)
    274 
    275     def connect(self, host='localhost', port = 0):
     284        if self.debuglevel > 0:
     285            print>>stderr, 'connect:', (host, port)
     286        return socket.create_connection((host, port), timeout)
     287
     288    def connect(self, host='localhost', port=0):
    276289        """Connect to a host on a given port.
    277290
     
    287300            i = host.rfind(':')
    288301            if i >= 0:
    289                 host, port = host[:i], host[i+1:]
    290                 try: port = int(port)
     302                host, port = host[:i], host[i + 1:]
     303                try:
     304                    port = int(port)
    291305                except ValueError:
    292306                    raise socket.error, "nonnumeric port"
    293         if not port: port = self.default_port
    294         if self.debuglevel > 0: print>>stderr, 'connect:', (host, port)
     307        if not port:
     308            port = self.default_port
     309        if self.debuglevel > 0:
     310            print>>stderr, 'connect:', (host, port)
    295311        self.sock = self._get_socket(host, port, self.timeout)
    296312        (code, msg) = self.getreply()
    297         if self.debuglevel > 0: print>>stderr, "connect:", msg
     313        if self.debuglevel > 0:
     314            print>>stderr, "connect:", msg
    298315        return (code, msg)
    299316
    300317    def send(self, str):
    301318        """Send `str' to the server."""
    302         if self.debuglevel > 0: print>>stderr, 'send:', repr(str)
     319        if self.debuglevel > 0:
     320            print>>stderr, 'send:', repr(str)
    303321        if hasattr(self, 'sock') and self.sock:
    304322            try:
     
    331349        Raises SMTPServerDisconnected if end-of-file is reached.
    332350        """
    333         resp=[]
     351        resp = []
    334352        if self.file is None:
    335353            self.file = self.sock.makefile('rb')
    336354        while 1:
    337             line = self.file.readline()
     355            try:
     356                line = self.file.readline()
     357            except socket.error as e:
     358                self.close()
     359                raise SMTPServerDisconnected("Connection unexpectedly closed: "
     360                                             + str(e))
    338361            if line == '':
    339362                self.close()
    340363                raise SMTPServerDisconnected("Connection unexpectedly closed")
    341             if self.debuglevel > 0: print>>stderr, 'reply:', repr(line)
     364            if self.debuglevel > 0:
     365                print>>stderr, 'reply:', repr(line)
    342366            resp.append(line[4:].strip())
    343             code=line[:3]
     367            code = line[:3]
    344368            # Check that the error code is syntactically correct.
    345369            # Don't attempt to read a continuation line if it is broken.
     
    350374                break
    351375            # Check if multiline response.
    352             if line[3:4]!="-":
     376            if line[3:4] != "-":
    353377                break
    354378
    355379        errmsg = "\n".join(resp)
    356380        if self.debuglevel > 0:
    357             print>>stderr, 'reply: retcode (%s); Msg: %s' % (errcode,errmsg)
     381            print>>stderr, 'reply: retcode (%s); Msg: %s' % (errcode, errmsg)
    358382        return errcode, errmsg
    359383
    360384    def docmd(self, cmd, args=""):
    361385        """Send a command, and return its response code."""
    362         self.putcmd(cmd,args)
     386        self.putcmd(cmd, args)
    363387        return self.getreply()
    364388
     
    370394        """
    371395        self.putcmd("helo", name or self.local_hostname)
    372         (code,msg)=self.getreply()
    373         self.helo_resp=msg
    374         return (code,msg)
     396        (code, msg) = self.getreply()
     397        self.helo_resp = msg
     398        return (code, msg)
    375399
    376400    def ehlo(self, name=''):
     
    381405        self.esmtp_features = {}
    382406        self.putcmd(self.ehlo_msg, name or self.local_hostname)
    383         (code,msg)=self.getreply()
     407        (code, msg) = self.getreply()
    384408        # According to RFC1869 some (badly written)
    385409        # MTA's will disconnect on an ehlo. Toss an exception if
     
    388412            self.close()
    389413            raise SMTPServerDisconnected("Server not connected")
    390         self.ehlo_resp=msg
     414        self.ehlo_resp = msg
    391415        if code != 250:
    392             return (code,msg)
    393         self.does_esmtp=1
     416            return (code, msg)
     417        self.does_esmtp = 1
    394418        #parse the ehlo response -ddm
    395         resp=self.ehlo_resp.split('\n')
     419        resp = self.ehlo_resp.split('\n')
    396420        del resp[0]
    397421        for each in resp:
     
    413437            # parameters, but were not going to check for that here.  Note
    414438            # that the space isn't present if there are no parameters.
    415             m=re.match(r'(?P<feature>[A-Za-z0-9][A-Za-z0-9\-]*) ?',each)
     439            m = re.match(r'(?P<feature>[A-Za-z0-9][A-Za-z0-9\-]*) ?', each)
    416440            if m:
    417                 feature=m.group("feature").lower()
    418                 params=m.string[m.end("feature"):].strip()
     441                feature = m.group("feature").lower()
     442                params = m.string[m.end("feature"):].strip()
    419443                if feature == "auth":
    420444                    self.esmtp_features[feature] = self.esmtp_features.get(feature, "") \
    421445                            + " " + params
    422446                else:
    423                     self.esmtp_features[feature]=params
    424         return (code,msg)
     447                    self.esmtp_features[feature] = params
     448        return (code, msg)
    425449
    426450    def has_extn(self, opt):
     
    442466        return self.docmd("noop")
    443467
    444     def mail(self,sender,options=[]):
     468    def mail(self, sender, options=[]):
    445469        """SMTP 'mail' command -- begins mail xfer session."""
    446470        optionlist = ''
    447471        if options and self.does_esmtp:
    448472            optionlist = ' ' + ' '.join(options)
    449         self.putcmd("mail", "FROM:%s%s" % (quoteaddr(sender) ,optionlist))
     473        self.putcmd("mail", "FROM:%s%s" % (quoteaddr(sender), optionlist))
    450474        return self.getreply()
    451475
    452     def rcpt(self,recip,options=[]):
     476    def rcpt(self, recip, options=[]):
    453477        """SMTP 'rcpt' command -- indicates 1 recipient for this mail."""
    454478        optionlist = ''
    455479        if options and self.does_esmtp:
    456480            optionlist = ' ' + ' '.join(options)
    457         self.putcmd("rcpt","TO:%s%s" % (quoteaddr(recip),optionlist))
     481        self.putcmd("rcpt", "TO:%s%s" % (quoteaddr(recip), optionlist))
    458482        return self.getreply()
    459483
    460     def data(self,msg):
     484    def data(self, msg):
    461485        """SMTP 'DATA' command -- sends message data to server.
    462486
     
    467491        """
    468492        self.putcmd("data")
    469         (code,repl)=self.getreply()
    470         if self.debuglevel >0 : print>>stderr, "data:", (code,repl)
     493        (code, repl) = self.getreply()
     494        if self.debuglevel > 0:
     495            print>>stderr, "data:", (code, repl)
    471496        if code != 354:
    472             raise SMTPDataError(code,repl)
     497            raise SMTPDataError(code, repl)
    473498        else:
    474499            q = quotedata(msg)
     
    477502            q = q + "." + CRLF
    478503            self.send(q)
    479             (code,msg)=self.getreply()
    480             if self.debuglevel >0 : print>>stderr, "data:", (code,msg)
    481             return (code,msg)
     504            (code, msg) = self.getreply()
     505            if self.debuglevel > 0:
     506                print>>stderr, "data:", (code, msg)
     507            return (code, msg)
    482508
    483509    def verify(self, address):
    484510        """SMTP 'verify' command -- checks for address validity."""
    485         self.putcmd("vrfy", quoteaddr(address))
     511        self.putcmd("vrfy", _addr_only(address))
    486512        return self.getreply()
    487513    # a.k.a.
    488     vrfy=verify
     514    vrfy = verify
    489515
    490516    def expn(self, address):
    491517        """SMTP 'expn' command -- expands a mailing list."""
    492         self.putcmd("expn", quoteaddr(address))
     518        self.putcmd("expn", _addr_only(address))
    493519        return self.getreply()
    494520
     
    590616        return (code, resp)
    591617
    592     def starttls(self, keyfile = None, certfile = None):
     618    def starttls(self, keyfile=None, certfile=None):
    593619        """Puts the connection to the SMTP server into TLS mode.
    594620
     
    693719                esmtp_opts.append(option)
    694720
    695         (code,resp) = self.mail(from_addr, esmtp_opts)
     721        (code, resp) = self.mail(from_addr, esmtp_opts)
    696722        if code != 250:
    697723            self.rset()
    698724            raise SMTPSenderRefused(code, resp, from_addr)
    699         senderrs={}
     725        senderrs = {}
    700726        if isinstance(to_addrs, basestring):
    701727            to_addrs = [to_addrs]
    702728        for each in to_addrs:
    703             (code,resp)=self.rcpt(each, rcpt_options)
     729            (code, resp) = self.rcpt(each, rcpt_options)
    704730            if (code != 250) and (code != 251):
    705                 senderrs[each]=(code,resp)
    706         if len(senderrs)==len(to_addrs):
     731                senderrs[each] = (code, resp)
     732        if len(senderrs) == len(to_addrs):
    707733            # the server refused all our recipients
    708734            self.rset()
    709735            raise SMTPRecipientsRefused(senderrs)
    710         (code,resp) = self.data(msg)
     736        (code, resp) = self.data(msg)
    711737        if code != 250:
    712738            self.rset()
     
    735761
    736762    class SMTP_SSL(SMTP):
    737         """ This is a subclass derived from SMTP that connects over an SSL encrypted
    738         socket (to use this class you need a socket module that was compiled with SSL
    739         support). If host is not specified, '' (the local host) is used. If port is
    740         omitted, the standard SMTP-over-SSL port (465) is used. keyfile and certfile
    741         are also optional - they can contain a PEM formatted private key and
    742         certificate chain file for the SSL connection.
    743         """
     763        """ This is a subclass derived from SMTP that connects over an SSL
     764        encrypted socket (to use this class you need a socket module that was
     765        compiled with SSL support). If host is not specified, '' (the local
     766        host) is used. If port is omitted, the standard SMTP-over-SSL port
     767        (465) is used.  local_hostname has the same meaning as it does in the
     768        SMTP class.  keyfile and certfile are also optional - they can contain
     769        a PEM formatted private key and certificate chain file for the SSL
     770        connection.
     771
     772        """
     773
     774        default_port = SMTP_SSL_PORT
     775
    744776        def __init__(self, host='', port=0, local_hostname=None,
    745777                     keyfile=None, certfile=None,
     
    748780            self.certfile = certfile
    749781            SMTP.__init__(self, host, port, local_hostname, timeout)
    750             self.default_port = SMTP_SSL_PORT
    751782
    752783        def _get_socket(self, host, port, timeout):
    753             if self.debuglevel > 0: print>>stderr, 'connect:', (host, port)
     784            if self.debuglevel > 0:
     785                print>>stderr, 'connect:', (host, port)
    754786            new_socket = socket.create_connection((host, port), timeout)
    755787            new_socket = ssl.wrap_socket(new_socket, self.keyfile, self.certfile)
     
    768800
    769801    The LMTP protocol, which is very similar to ESMTP, is heavily based
    770     on the standard SMTP client. It's common to use Unix sockets for LMTP,
    771     so our connect() method must support that as well as a regular
    772     host:port server. To specify a Unix socket, you must use an absolute
     802    on the standard SMTP client. It's common to use Unix sockets for
     803    LMTP, so our connect() method must support that as well as a regular
     804    host:port server.  local_hostname has the same meaning as it does in
     805    the SMTP class.  To specify a Unix socket, you must use an absolute
    773806    path as the host, starting with a '/'.
    774807
     
    779812    ehlo_msg = "lhlo"
    780813
    781     def __init__(self, host = '', port = LMTP_PORT, local_hostname = None):
     814    def __init__(self, host='', port=LMTP_PORT, local_hostname=None):
    782815        """Initialize a new instance."""
    783816        SMTP.__init__(self, host, port, local_hostname)
    784817
    785     def connect(self, host = 'localhost', port = 0):
     818    def connect(self, host='localhost', port=0):
    786819        """Connect to the LMTP daemon, on either a Unix or a TCP socket."""
    787820        if host[0] != '/':
     
    792825            self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
    793826            self.sock.connect(host)
    794         except socket.error, msg:
    795             if self.debuglevel > 0: print>>stderr, 'connect fail:', host
     827        except socket.error:
     828            if self.debuglevel > 0:
     829                print>>stderr, 'connect fail:', host
    796830            if self.sock:
    797831                self.sock.close()
    798832            self.sock = None
    799             raise socket.error, msg
     833            raise
    800834        (code, msg) = self.getreply()
    801         if self.debuglevel > 0: print>>stderr, "connect:", msg
     835        if self.debuglevel > 0:
     836            print>>stderr, "connect:", msg
    802837        return (code, msg)
    803838
     
    813848
    814849    fromaddr = prompt("From")
    815     toaddrs  = prompt("To").split(',')
     850    toaddrs = prompt("To").split(',')
    816851    print "Enter message, end with ^D:"
    817852    msg = ''
Note: See TracChangeset for help on using the changeset viewer.