Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit cbcc2fd

Browse files
Issue #27033: The default value of the decode_data parameter for
smtpd.SMTPChannel and smtpd.SMTPServer constructors is changed to False.
1 parent 4ecfa45 commit cbcc2fd

4 files changed

Lines changed: 57 additions & 82 deletions

File tree

Doc/library/smtpd.rst

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ SMTPServer Objects
2929

3030

3131
.. class:: SMTPServer(localaddr, remoteaddr, data_size_limit=33554432,\
32-
map=None, enable_SMTPUTF8=False, decode_data=True)
32+
map=None, enable_SMTPUTF8=False, decode_data=False)
3333

3434
Create a new :class:`SMTPServer` object, which binds to local address
3535
*localaddr*. It will treat *remoteaddr* as an upstream SMTP relayer. It
@@ -45,20 +45,19 @@ SMTPServer Objects
4545
global socket map is used.
4646

4747
*enable_SMTPUTF8* determins whether the ``SMTPUTF8`` extension (as defined
48-
in :RFC:`6531`) should be enabled. The default is ``False``. If set to
49-
``True``, *decode_data* must be ``False`` (otherwise an error is raised).
48+
in :RFC:`6531`) should be enabled. The default is ``False``.
5049
When ``True``, ``SMTPUTF8`` is accepted as a parameter to the ``MAIL``
5150
command and when present is passed to :meth:`process_message` in the
52-
``kwargs['mail_options']`` list.
51+
``kwargs['mail_options']`` list. *decode_data* and *enable_SMTPUTF8*
52+
cannot be set to ``True`` at the same time.
5353

5454
*decode_data* specifies whether the data portion of the SMTP transaction
55-
should be decoded using UTF-8. The default is ``True`` for backward
56-
compatibility reasons, but will change to ``False`` in Python 3.6; specify
57-
the keyword value explicitly to avoid the :exc:`DeprecationWarning`. When
58-
*decode_data* is set to ``False`` the server advertises the ``8BITMIME``
55+
should be decoded using UTF-8. The default is ``False``. When
56+
*decode_data* is not set to ``True`` the server advertises the ``8BITMIME``
5957
extension (:rfc:`6152`), accepts the ``BODY=8BITMIME`` parameter to
6058
the ``MAIL`` command, and when present passes it to :meth:`process_message`
61-
in the ``kwargs['mail_options']`` list.
59+
in the ``kwargs['mail_options']`` list. *decode_data* and *enable_SMTPUTF8*
60+
cannot be set to ``True`` at the same time.
6261

6362
.. method:: process_message(peer, mailfrom, rcpttos, data, **kwargs)
6463

@@ -71,13 +70,12 @@ SMTPServer Objects
7170
format).
7271

7372
If the *decode_data* constructor keyword is set to ``True``, the *data*
74-
argument will be a unicode string. If it is set to ``False``, it
73+
parameter will be a unicode string. If it is set to ``False``, it
7574
will be a bytes object.
7675

7776
*kwargs* is a dictionary containing additional information. It is empty
78-
unless at least one of ``decode_data=False`` or ``enable_SMTPUTF8=True``
79-
was given as an init parameter, in which case it contains the following
80-
keys:
77+
if ``decode_data=True`` was given as an init argument, otherwise
78+
it contains the following keys:
8179

8280
*mail_options*:
8381
a list of all received parameters to the ``MAIL``
@@ -108,10 +106,13 @@ SMTPServer Objects
108106
*localaddr* and *remoteaddr* may now contain IPv6 addresses.
109107

110108
.. versionadded:: 3.5
111-
the *decode_data* and *enable_SMTPUTF8* constructor arguments, and the
112-
*kwargs* argument to :meth:`process_message` when one or more of these is
109+
The *decode_data* and *enable_SMTPUTF8* constructor parameters, and the
110+
*kwargs* parameter to :meth:`process_message` when one or more of these is
113111
specified.
114112

113+
.. versionchanged:: 3.6
114+
*decode_data* is now ``False`` by default.
115+
115116

116117
DebuggingServer Objects
117118
-----------------------
@@ -150,7 +151,7 @@ SMTPChannel Objects
150151
-------------------
151152

152153
.. class:: SMTPChannel(server, conn, addr, data_size_limit=33554432,\
153-
map=None, enable_SMTPUTF8=False, decode_data=True)
154+
map=None, enable_SMTPUTF8=False, decode_data=False)
154155

155156
Create a new :class:`SMTPChannel` object which manages the communication
156157
between the server and a single SMTP client.
@@ -162,22 +163,25 @@ SMTPChannel Objects
162163
limit.
163164

164165
*enable_SMTPUTF8* determins whether the ``SMTPUTF8`` extension (as defined
165-
in :RFC:`6531`) should be enabled. The default is ``False``. A
166-
:exc:`ValueError` is raised if both *enable_SMTPUTF8* and *decode_data* are
167-
set to ``True`` at the same time.
166+
in :RFC:`6531`) should be enabled. The default is ``False``.
167+
*decode_data* and *enable_SMTPUTF8* cannot be set to ``True`` at the same
168+
time.
168169

169170
A dictionary can be specified in *map* to avoid using a global socket map.
170171

171172
*decode_data* specifies whether the data portion of the SMTP transaction
172-
should be decoded using UTF-8. The default is ``True`` for backward
173-
compatibility reasons, but will change to ``False`` in Python 3.6. Specify
174-
the keyword value explicitly to avoid the :exc:`DeprecationWarning`.
173+
should be decoded using UTF-8. The default is ``False``.
174+
*decode_data* and *enable_SMTPUTF8* cannot be set to ``True`` at the same
175+
time.
175176

176177
To use a custom SMTPChannel implementation you need to override the
177178
:attr:`SMTPServer.channel_class` of your :class:`SMTPServer`.
178179

179180
.. versionchanged:: 3.5
180-
the *decode_data* and *enable_SMTPUTF8* arguments were added.
181+
The *decode_data* and *enable_SMTPUTF8* parameters were added.
182+
183+
.. versionchanged:: 3.6
184+
*decode_data* is now ``False`` by default.
181185

182186
The :class:`SMTPChannel` has the following instance variables:
183187

Lib/smtpd.py

Lines changed: 15 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -128,24 +128,17 @@ def max_command_size_limit(self):
128128
return self.command_size_limit
129129

130130
def __init__(self, server, conn, addr, data_size_limit=DATA_SIZE_DEFAULT,
131-
map=None, enable_SMTPUTF8=False, decode_data=None):
131+
map=None, enable_SMTPUTF8=False, decode_data=False):
132132
asynchat.async_chat.__init__(self, conn, map=map)
133133
self.smtp_server = server
134134
self.conn = conn
135135
self.addr = addr
136136
self.data_size_limit = data_size_limit
137-
self.enable_SMTPUTF8 = enable_SMTPUTF8
138-
if enable_SMTPUTF8:
139-
if decode_data:
140-
raise ValueError("decode_data and enable_SMTPUTF8 cannot"
141-
" be set to True at the same time")
142-
decode_data = False
143-
if decode_data is None:
144-
warn("The decode_data default of True will change to False in 3.6;"
145-
" specify an explicit value for this keyword",
146-
DeprecationWarning, 2)
147-
decode_data = True
148-
self._decode_data = decode_data
137+
self.enable_SMTPUTF8 = enable_SMTPUTF8 = bool(enable_SMTPUTF8)
138+
self._decode_data = decode_data = bool(decode_data)
139+
if enable_SMTPUTF8 and decode_data:
140+
raise ValueError("decode_data and enable_SMTPUTF8 cannot"
141+
" be set to True at the same time")
149142
if decode_data:
150143
self._emptystring = ''
151144
self._linesep = '\r\n'
@@ -635,23 +628,15 @@ class SMTPServer(asyncore.dispatcher):
635628

636629
def __init__(self, localaddr, remoteaddr,
637630
data_size_limit=DATA_SIZE_DEFAULT, map=None,
638-
enable_SMTPUTF8=False, decode_data=None):
631+
enable_SMTPUTF8=False, decode_data=False):
639632
self._localaddr = localaddr
640633
self._remoteaddr = remoteaddr
641634
self.data_size_limit = data_size_limit
642-
self.enable_SMTPUTF8 = enable_SMTPUTF8
643-
if enable_SMTPUTF8:
644-
if decode_data:
645-
raise ValueError("The decode_data and enable_SMTPUTF8"
646-
" parameters cannot be set to True at the"
647-
" same time.")
648-
decode_data = False
649-
if decode_data is None:
650-
warn("The decode_data default of True will change to False in 3.6;"
651-
" specify an explicit value for this keyword",
652-
DeprecationWarning, 2)
653-
decode_data = True
654-
self._decode_data = decode_data
635+
self.enable_SMTPUTF8 = enable_SMTPUTF8 = bool(enable_SMTPUTF8)
636+
self._decode_data = decode_data = bool(decode_data)
637+
if enable_SMTPUTF8 and decode_data:
638+
raise ValueError("decode_data and enable_SMTPUTF8 cannot"
639+
" be set to True at the same time")
655640
asyncore.dispatcher.__init__(self, map=map)
656641
try:
657642
gai_results = socket.getaddrinfo(*localaddr,
@@ -698,9 +683,9 @@ def process_message(self, peer, mailfrom, rcpttos, data, **kwargs):
698683
containing a `.' followed by other text has had the leading dot
699684
removed.
700685
701-
kwargs is a dictionary containing additional information. It is empty
702-
unless decode_data=False or enable_SMTPUTF8=True was given as init
703-
parameter, in which case ut will contain the following keys:
686+
kwargs is a dictionary containing additional information. It is
687+
empty if decode_data=True was given as init parameter, otherwise
688+
it will contain the following keys:
704689
'mail_options': list of parameters to the mail command. All
705690
elements are uppercase strings. Example:
706691
['BODY=8BITMIME', 'SMTPUTF8'].

Lib/test/test_smtpd.py

Lines changed: 12 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,6 @@ def write_line(line):
5353
write_line(b'DATA')
5454
self.assertRaises(NotImplementedError, write_line, b'spam\r\n.\r\n')
5555

56-
def test_decode_data_default_warns(self):
57-
with self.assertWarns(DeprecationWarning):
58-
smtpd.SMTPServer((support.HOST, 0), ('b', 0))
59-
6056
def test_decode_data_and_enable_SMTPUTF8_raises(self):
6157
self.assertRaises(
6258
ValueError,
@@ -108,10 +104,9 @@ def test_process_message_with_decode_data_true(self):
108104
"""))
109105

110106
def test_process_message_with_decode_data_false(self):
111-
server = smtpd.DebuggingServer((support.HOST, 0), ('b', 0),
112-
decode_data=False)
107+
server = smtpd.DebuggingServer((support.HOST, 0), ('b', 0))
113108
conn, addr = server.accept()
114-
channel = smtpd.SMTPChannel(server, conn, addr, decode_data=False)
109+
channel = smtpd.SMTPChannel(server, conn, addr)
115110
with support.captured_stdout() as s:
116111
self.send_data(channel, b'From: test\n\nh\xc3\xa9llo\xff\n')
117112
stdout = s.getvalue()
@@ -175,13 +170,11 @@ def tearDown(self):
175170

176171
@unittest.skipUnless(support.IPV6_ENABLED, "IPv6 not enabled")
177172
def test_socket_uses_IPv6(self):
178-
server = smtpd.SMTPServer((support.HOSTv6, 0), (support.HOST, 0),
179-
decode_data=False)
173+
server = smtpd.SMTPServer((support.HOSTv6, 0), (support.HOST, 0))
180174
self.assertEqual(server.socket.family, socket.AF_INET6)
181175

182176
def test_socket_uses_IPv4(self):
183-
server = smtpd.SMTPServer((support.HOST, 0), (support.HOSTv6, 0),
184-
decode_data=False)
177+
server = smtpd.SMTPServer((support.HOST, 0), (support.HOSTv6, 0))
185178
self.assertEqual(server.socket.family, socket.AF_INET)
186179

187180

@@ -204,18 +197,18 @@ def write_line(self, channel, line):
204197
channel.handle_read()
205198

206199
def test_params_rejected(self):
207-
server = DummyServer((support.HOST, 0), ('b', 0), decode_data=False)
200+
server = DummyServer((support.HOST, 0), ('b', 0))
208201
conn, addr = server.accept()
209-
channel = smtpd.SMTPChannel(server, conn, addr, decode_data=False)
202+
channel = smtpd.SMTPChannel(server, conn, addr)
210203
self.write_line(channel, b'EHLO example')
211204
self.write_line(channel, b'MAIL from: <[email protected]> size=20')
212205
self.write_line(channel, b'RCPT to: <[email protected]> foo=bar')
213206
self.assertEqual(channel.socket.last, self.error_response)
214207

215208
def test_nothing_accepted(self):
216-
server = DummyServer((support.HOST, 0), ('b', 0), decode_data=False)
209+
server = DummyServer((support.HOST, 0), ('b', 0))
217210
conn, addr = server.accept()
218-
channel = smtpd.SMTPChannel(server, conn, addr, decode_data=False)
211+
channel = smtpd.SMTPChannel(server, conn, addr)
219212
self.write_line(channel, b'EHLO example')
220213
self.write_line(channel, b'MAIL from: <[email protected]> size=20')
221214
self.write_line(channel, b'RCPT to: <[email protected]>')
@@ -257,9 +250,9 @@ def test_with_decode_data_true(self):
257250
self.assertEqual(channel.socket.last, b'250 OK\r\n')
258251

259252
def test_with_decode_data_false(self):
260-
server = DummyServer((support.HOST, 0), ('b', 0), decode_data=False)
253+
server = DummyServer((support.HOST, 0), ('b', 0))
261254
conn, addr = server.accept()
262-
channel = smtpd.SMTPChannel(server, conn, addr, decode_data=False)
255+
channel = smtpd.SMTPChannel(server, conn, addr)
263256
self.write_line(channel, b'EHLO example')
264257
for line in [
265258
b'MAIL from: <[email protected]> size=20 SMTPUTF8',
@@ -765,13 +758,6 @@ def test_attribute_deprecations(self):
765758
with support.check_warnings(('', DeprecationWarning)):
766759
self.channel._SMTPChannel__addr = 'spam'
767760

768-
def test_decode_data_default_warning(self):
769-
with self.assertWarns(DeprecationWarning):
770-
server = DummyServer((support.HOST, 0), ('b', 0))
771-
conn, addr = self.server.accept()
772-
with self.assertWarns(DeprecationWarning):
773-
smtpd.SMTPChannel(server, conn, addr)
774-
775761
@unittest.skipUnless(support.IPV6_ENABLED, "IPv6 not enabled")
776762
class SMTPDChannelIPv6Test(SMTPDChannelTest):
777763
def setUp(self):
@@ -845,12 +831,9 @@ def setUp(self):
845831
smtpd.socket = asyncore.socket = mock_socket
846832
self.old_debugstream = smtpd.DEBUGSTREAM
847833
self.debug = smtpd.DEBUGSTREAM = io.StringIO()
848-
self.server = DummyServer((support.HOST, 0), ('b', 0),
849-
decode_data=False)
834+
self.server = DummyServer((support.HOST, 0), ('b', 0))
850835
conn, addr = self.server.accept()
851-
# Set decode_data to False
852-
self.channel = smtpd.SMTPChannel(self.server, conn, addr,
853-
decode_data=False)
836+
self.channel = smtpd.SMTPChannel(self.server, conn, addr)
854837

855838
def tearDown(self):
856839
asyncore.close_all()

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,9 @@ Core and Builtins
277277
Library
278278
-------
279279

280+
- Issue #27033: The default value of the decode_data parameter for
281+
smtpd.SMTPChannel and smtpd.SMTPServer constructors is changed to False.
282+
280283
- Issue #27034: Removed deprecated class asynchat.fifo.
281284

282285
- Issue #26870: Added readline.set_auto_history(), which can stop entries

0 commit comments

Comments
 (0)