Addressing the review comments by Antoine Pitrou for smtplib.py and test_smtplib.py. Review comments by Ezio Melotti for smtplib.rst
This commit is contained in:
parent
3fc5868a1d
commit
b351a48eee
@ -31,9 +31,9 @@ Protocol) and :rfc:`1869` (SMTP Service Extensions).
|
|||||||
like the connection attempt (if not specified, the global default timeout
|
like the connection attempt (if not specified, the global default timeout
|
||||||
setting will be used). The optional source_address parameter allows to bind to some
|
setting will be used). The optional source_address parameter allows to bind to some
|
||||||
specific source address in a machine with multiple network interfaces,
|
specific source address in a machine with multiple network interfaces,
|
||||||
and/or to some specific source tcp port. It takes a 2-tuple (host, port),
|
and/or to some specific source TCP port. It takes a 2-tuple (host, port),
|
||||||
for the socket to bind to as its source address before connecting. If
|
for the socket to bind to as its source address before connecting. If
|
||||||
ommited (or if host or port are '' and/or 0 respectively) the OS default
|
omitted (or if host or port are ``''`` and/or 0 respectively) the OS default
|
||||||
behavior will be used.
|
behavior will be used.
|
||||||
|
|
||||||
For normal use, you should only require the initialization/connect,
|
For normal use, you should only require the initialization/connect,
|
||||||
@ -53,8 +53,8 @@ Protocol) and :rfc:`1869` (SMTP Service Extensions).
|
|||||||
.. versionchanged:: 3.3
|
.. versionchanged:: 3.3
|
||||||
Support for the :keyword:`with` statement was added.
|
Support for the :keyword:`with` statement was added.
|
||||||
|
|
||||||
.. versionadded:: 3.3
|
.. versionchanged:: 3.3
|
||||||
source_address parameter.
|
source_address argument was added.
|
||||||
|
|
||||||
.. class:: SMTP_SSL(host='', port=0, local_hostname=None, keyfile=None, certfile=None[, timeout], context=None, source_address=None)
|
.. class:: SMTP_SSL(host='', port=0, local_hostname=None, keyfile=None, certfile=None[, timeout], context=None, source_address=None)
|
||||||
|
|
||||||
@ -73,14 +73,14 @@ Protocol) and :rfc:`1869` (SMTP Service Extensions).
|
|||||||
specific source address in a machine with multiple network interfaces,
|
specific source address in a machine with multiple network interfaces,
|
||||||
and/or to some specific source tcp port. It takes a 2-tuple (host, port),
|
and/or to some specific source tcp port. It takes a 2-tuple (host, port),
|
||||||
for the socket to bind to as its source address before connecting. If
|
for the socket to bind to as its source address before connecting. If
|
||||||
ommited (or if host or port are '' and/or 0 respectively) the OS default
|
omitted (or if host or port are ``''`` and/or 0 respectively) the OS default
|
||||||
behavior will be used.
|
behavior will be used.
|
||||||
|
|
||||||
.. versionchanged:: 3.3
|
.. versionchanged:: 3.3
|
||||||
*context* was added.
|
*context* was added.
|
||||||
|
|
||||||
.. versionadded:: 3.3
|
.. versionchanged:: 3.3
|
||||||
source_address parameter.
|
source_address argument was added.
|
||||||
|
|
||||||
|
|
||||||
.. class:: LMTP(host='', port=LMTP_PORT, local_hostname=None, source_address=None)
|
.. class:: LMTP(host='', port=LMTP_PORT, local_hostname=None, source_address=None)
|
||||||
@ -88,8 +88,8 @@ Protocol) and :rfc:`1869` (SMTP Service Extensions).
|
|||||||
The LMTP protocol, which is very similar to ESMTP, is heavily based on the
|
The LMTP protocol, which is very similar to ESMTP, is heavily based on the
|
||||||
standard SMTP client. It's common to use Unix sockets for LMTP, so our
|
standard SMTP client. It's common to use Unix sockets for LMTP, so our
|
||||||
:meth:`connect` method must support that as well as a regular host:port
|
:meth:`connect` method must support that as well as a regular host:port
|
||||||
server. The optional parameters local_hostname and source_address has the
|
server. The optional arguments local_hostname and source_address have the
|
||||||
same meaning as that of SMTP client.To specify a Unix socket, you must use
|
same meaning as that of SMTP client. To specify a Unix socket, you must use
|
||||||
an absolute path for *host*, starting with a '/'.
|
an absolute path for *host*, starting with a '/'.
|
||||||
|
|
||||||
Authentication is supported, using the regular SMTP mechanism. When using a Unix
|
Authentication is supported, using the regular SMTP mechanism. When using a Unix
|
||||||
|
@ -282,7 +282,8 @@ class SMTP:
|
|||||||
# This makes it simpler for SMTP_SSL to use the SMTP connect code
|
# This makes it simpler for SMTP_SSL to use the SMTP connect code
|
||||||
# and just alter the socket connection bit.
|
# and just alter the socket connection bit.
|
||||||
if self.debuglevel > 0:
|
if self.debuglevel > 0:
|
||||||
print('connect: to', (host, port), self.source_address, file=stderr)
|
print('connect: to', (host, port), self.source_address,
|
||||||
|
file=stderr)
|
||||||
return socket.create_connection((host, port), timeout,
|
return socket.create_connection((host, port), timeout,
|
||||||
self.source_address)
|
self.source_address)
|
||||||
|
|
||||||
@ -297,7 +298,10 @@ class SMTP:
|
|||||||
specified during instantiation.
|
specified during instantiation.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if source_address: self.source_address = source_address
|
|
||||||
|
if source_address:
|
||||||
|
self.source_address = source_address
|
||||||
|
|
||||||
if not port and (host.find(':') == host.rfind(':')):
|
if not port and (host.find(':') == host.rfind(':')):
|
||||||
i = host.rfind(':')
|
i = host.rfind(':')
|
||||||
if i >= 0:
|
if i >= 0:
|
||||||
@ -381,7 +385,8 @@ class SMTP:
|
|||||||
|
|
||||||
errmsg = b"\n".join(resp)
|
errmsg = b"\n".join(resp)
|
||||||
if self.debuglevel > 0:
|
if self.debuglevel > 0:
|
||||||
print('reply: retcode (%s); Msg: %s' % (errcode, errmsg), file=stderr)
|
print('reply: retcode (%s); Msg: %s' % (errcode, errmsg),
|
||||||
|
file=stderr)
|
||||||
return errcode, errmsg
|
return errcode, errmsg
|
||||||
|
|
||||||
def docmd(self, cmd, args=""):
|
def docmd(self, cmd, args=""):
|
||||||
@ -788,7 +793,8 @@ class SMTP:
|
|||||||
# TODO implement heuristics to guess the correct Resent-* block with an
|
# TODO implement heuristics to guess the correct Resent-* block with an
|
||||||
# option allowing the user to enable the heuristics. (It should be
|
# option allowing the user to enable the heuristics. (It should be
|
||||||
# possible to guess correctly almost all of the time.)
|
# possible to guess correctly almost all of the time.)
|
||||||
resent =msg.get_all('Resent-Date')
|
|
||||||
|
resent = msg.get_all('Resent-Date')
|
||||||
if resent is None:
|
if resent is None:
|
||||||
header_prefix = ''
|
header_prefix = ''
|
||||||
elif len(resent) == 1:
|
elif len(resent) == 1:
|
||||||
@ -797,13 +803,13 @@ class SMTP:
|
|||||||
raise ValueError("message has more than one 'Resent-' header block")
|
raise ValueError("message has more than one 'Resent-' header block")
|
||||||
if from_addr is None:
|
if from_addr is None:
|
||||||
# Prefer the sender field per RFC 2822:3.6.2.
|
# Prefer the sender field per RFC 2822:3.6.2.
|
||||||
from_addr = (msg[header_prefix+'Sender']
|
from_addr = (msg[header_prefix + 'Sender']
|
||||||
if (header_prefix+'Sender') in msg
|
if (header_prefix + 'Sender') in msg
|
||||||
else msg[header_prefix+'From'])
|
else msg[header_prefix + 'From'])
|
||||||
if to_addrs is None:
|
if to_addrs is None:
|
||||||
addr_fields = [f for f in (msg[header_prefix+'To'],
|
addr_fields = [f for f in (msg[header_prefix + 'To'],
|
||||||
msg[header_prefix+'Bcc'],
|
msg[header_prefix + 'Bcc'],
|
||||||
msg[header_prefix+'Cc']) if f is not None]
|
msg[header_prefix + 'Cc']) if f is not None]
|
||||||
to_addrs = [a[1] for a in email.utils.getaddresses(addr_fields)]
|
to_addrs = [a[1] for a in email.utils.getaddresses(addr_fields)]
|
||||||
# Make a local copy so we can delete the bcc headers.
|
# Make a local copy so we can delete the bcc headers.
|
||||||
msg_copy = copy.copy(msg)
|
msg_copy = copy.copy(msg)
|
||||||
@ -899,13 +905,13 @@ class LMTP(SMTP):
|
|||||||
def __init__(self, host='', port=LMTP_PORT, local_hostname=None,
|
def __init__(self, host='', port=LMTP_PORT, local_hostname=None,
|
||||||
source_address=None):
|
source_address=None):
|
||||||
"""Initialize a new instance."""
|
"""Initialize a new instance."""
|
||||||
SMTP.__init__(self, host, port, local_hostname = local_hostname,
|
SMTP.__init__(self, host, port, local_hostname=local_hostname,
|
||||||
source_address = source_address)
|
source_address=source_address)
|
||||||
|
|
||||||
def connect(self, host='localhost', port=0, source_address=None):
|
def connect(self, host='localhost', port=0, source_address=None):
|
||||||
"""Connect to the LMTP daemon, on either a Unix or a TCP socket."""
|
"""Connect to the LMTP daemon, on either a Unix or a TCP socket."""
|
||||||
if host[0] != '/':
|
if host[0] != '/':
|
||||||
return SMTP.connect(self, host, port, source_address = source_address)
|
return SMTP.connect(self, host, port, source_address=source_address)
|
||||||
|
|
||||||
# Handle Unix-domain sockets.
|
# Handle Unix-domain sockets.
|
||||||
try:
|
try:
|
||||||
|
@ -216,12 +216,17 @@ class DebuggingServerTests(unittest.TestCase):
|
|||||||
|
|
||||||
def testSourceAddress(self):
|
def testSourceAddress(self):
|
||||||
# connect
|
# connect
|
||||||
smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=3,
|
port = support.find_unused_port()
|
||||||
source_address=('127.0.0.1', 19876))
|
try:
|
||||||
self.assertEqual(smtp.source_address, ('127.0.0.1', 19876))
|
smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost',
|
||||||
self.assertEqual(smtp.local_hostname, 'localhost')
|
timeout=3, source_address=('127.0.0.1', port))
|
||||||
print(dir(smtp))
|
self.assertEqual(smtp.source_address, ('127.0.0.1', port))
|
||||||
smtp.quit()
|
self.assertEqual(smtp.local_hostname, 'localhost')
|
||||||
|
smtp.quit()
|
||||||
|
except IOError as e:
|
||||||
|
if e.errno == errno.EADDRINUSE:
|
||||||
|
self.skipTest("couldn't bind to port %d" % port)
|
||||||
|
raise
|
||||||
|
|
||||||
def testNOOP(self):
|
def testNOOP(self):
|
||||||
smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=3)
|
smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=3)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user