[Python-checkins] cpython: Issue #27033: The default value of the decode_data parameter for

serhiy.storchaka python-checkins at python.org
Mon May 16 02:37:00 EDT 2016


https://hg.python.org/cpython/rev/a31b9f353346
changeset:   101360:a31b9f353346
user:        Serhiy Storchaka <storchaka at gmail.com>
date:        Mon May 16 09:36:31 2016 +0300
summary:
  Issue #27033: The default value of the decode_data parameter for
smtpd.SMTPChannel and smtpd.SMTPServer constructors is changed to False.

files:
  Doc/library/smtpd.rst  |  50 ++++++++++++++++-------------
  Lib/smtpd.py           |  45 +++++++++------------------
  Lib/test/test_smtpd.py |  41 +++++++-----------------
  Misc/NEWS              |   3 +
  4 files changed, 57 insertions(+), 82 deletions(-)


diff --git a/Doc/library/smtpd.rst b/Doc/library/smtpd.rst
--- a/Doc/library/smtpd.rst
+++ b/Doc/library/smtpd.rst
@@ -29,7 +29,7 @@
 
 
 .. class:: SMTPServer(localaddr, remoteaddr, data_size_limit=33554432,\
-                      map=None, enable_SMTPUTF8=False, decode_data=True)
+                      map=None, enable_SMTPUTF8=False, decode_data=False)
 
    Create a new :class:`SMTPServer` object, which binds to local address
    *localaddr*.  It will treat *remoteaddr* as an upstream SMTP relayer.  It
@@ -45,20 +45,19 @@
    global socket map is used.
 
    *enable_SMTPUTF8* determins whether the ``SMTPUTF8`` extension (as defined
-   in :RFC:`6531`) should be enabled.  The default is ``False``.  If set to
-   ``True``, *decode_data* must be ``False`` (otherwise an error is raised).
+   in :RFC:`6531`) should be enabled.  The default is ``False``.
    When ``True``, ``SMTPUTF8`` is accepted as a parameter to the ``MAIL``
    command and when present is passed to :meth:`process_message` in the
-   ``kwargs['mail_options']`` list.
+   ``kwargs['mail_options']`` list.  *decode_data* and *enable_SMTPUTF8*
+   cannot be set to ``True`` at the same time.
 
    *decode_data* specifies whether the data portion of the SMTP transaction
-   should be decoded using UTF-8.  The default is ``True`` for backward
-   compatibility reasons, but will change to ``False`` in Python 3.6; specify
-   the keyword value explicitly to avoid the :exc:`DeprecationWarning`.  When
-   *decode_data* is set to ``False`` the server advertises the ``8BITMIME``
+   should be decoded using UTF-8.  The default is ``False``.  When
+   *decode_data* is not set to ``True`` the server advertises the ``8BITMIME``
    extension (:rfc:`6152`), accepts the ``BODY=8BITMIME`` parameter to
    the ``MAIL`` command, and when present passes it to :meth:`process_message`
-   in the ``kwargs['mail_options']`` list.
+   in the ``kwargs['mail_options']`` list. *decode_data* and *enable_SMTPUTF8*
+   cannot be set to ``True`` at the same time.
 
    .. method:: process_message(peer, mailfrom, rcpttos, data, **kwargs)
 
@@ -71,13 +70,12 @@
       format).
 
       If the *decode_data* constructor keyword is set to ``True``, the *data*
-      argument will be a unicode string.  If it is set to ``False``, it
+      parameter will be a unicode string.  If it is set to ``False``, it
       will be a bytes object.
 
       *kwargs* is a dictionary containing additional information. It is empty
-      unless at least one of ``decode_data=False`` or ``enable_SMTPUTF8=True``
-      was given as an init parameter, in which case it contains the following
-      keys:
+      if ``decode_data=True`` was given as an init argument, otherwise
+      it contains the following keys:
 
           *mail_options*:
              a list of all received parameters to the ``MAIL``
@@ -108,10 +106,13 @@
       *localaddr* and *remoteaddr* may now contain IPv6 addresses.
 
    .. versionadded:: 3.5
-      the *decode_data* and *enable_SMTPUTF8* constructor arguments, and the
-      *kwargs* argument to :meth:`process_message` when one or more of these is
+      The *decode_data* and *enable_SMTPUTF8* constructor parameters, and the
+      *kwargs* parameter to :meth:`process_message` when one or more of these is
       specified.
 
+   .. versionchanged:: 3.6
+      *decode_data* is now ``False`` by default.
+
 
 DebuggingServer Objects
 -----------------------
@@ -150,7 +151,7 @@
 -------------------
 
 .. class:: SMTPChannel(server, conn, addr, data_size_limit=33554432,\
-                       map=None, enable_SMTPUTF8=False, decode_data=True)
+                       map=None, enable_SMTPUTF8=False, decode_data=False)
 
    Create a new :class:`SMTPChannel` object which manages the communication
    between the server and a single SMTP client.
@@ -162,22 +163,25 @@
    limit.
 
    *enable_SMTPUTF8* determins whether the ``SMTPUTF8`` extension (as defined
-   in :RFC:`6531`) should be enabled.  The default is ``False``.  A
-   :exc:`ValueError` is raised if both *enable_SMTPUTF8* and *decode_data* are
-   set to ``True`` at the same time.
+   in :RFC:`6531`) should be enabled.  The default is ``False``.
+   *decode_data* and *enable_SMTPUTF8* cannot be set to ``True`` at the same
+   time.
 
    A dictionary can be specified in *map* to avoid using a global socket map.
 
    *decode_data* specifies whether the data portion of the SMTP transaction
-   should be decoded using UTF-8.  The default is ``True`` for backward
-   compatibility reasons, but will change to ``False`` in Python 3.6.  Specify
-   the keyword value explicitly to avoid the :exc:`DeprecationWarning`.
+   should be decoded using UTF-8.  The default is ``False``.
+   *decode_data* and *enable_SMTPUTF8* cannot be set to ``True`` at the same
+   time.
 
    To use a custom SMTPChannel implementation you need to override the
    :attr:`SMTPServer.channel_class` of your :class:`SMTPServer`.
 
    .. versionchanged:: 3.5
-      the *decode_data* and *enable_SMTPUTF8* arguments were added.
+      The *decode_data* and *enable_SMTPUTF8* parameters were added.
+
+   .. versionchanged:: 3.6
+      *decode_data* is now ``False`` by default.
 
    The :class:`SMTPChannel` has the following instance variables:
 
diff --git a/Lib/smtpd.py b/Lib/smtpd.py
--- a/Lib/smtpd.py
+++ b/Lib/smtpd.py
@@ -128,24 +128,17 @@
             return self.command_size_limit
 
     def __init__(self, server, conn, addr, data_size_limit=DATA_SIZE_DEFAULT,
-                 map=None, enable_SMTPUTF8=False, decode_data=None):
+                 map=None, enable_SMTPUTF8=False, decode_data=False):
         asynchat.async_chat.__init__(self, conn, map=map)
         self.smtp_server = server
         self.conn = conn
         self.addr = addr
         self.data_size_limit = data_size_limit
-        self.enable_SMTPUTF8 = enable_SMTPUTF8
-        if enable_SMTPUTF8:
-            if decode_data:
-                raise ValueError("decode_data and enable_SMTPUTF8 cannot"
-                                 " be set to True at the same time")
-            decode_data = False
-        if decode_data is None:
-            warn("The decode_data default of True will change to False in 3.6;"
-                 " specify an explicit value for this keyword",
-                 DeprecationWarning, 2)
-            decode_data = True
-        self._decode_data = decode_data
+        self.enable_SMTPUTF8 = enable_SMTPUTF8 = bool(enable_SMTPUTF8)
+        self._decode_data = decode_data = bool(decode_data)
+        if enable_SMTPUTF8 and decode_data:
+            raise ValueError("decode_data and enable_SMTPUTF8 cannot"
+                             " be set to True at the same time")
         if decode_data:
             self._emptystring = ''
             self._linesep = '\r\n'
@@ -635,23 +628,15 @@
 
     def __init__(self, localaddr, remoteaddr,
                  data_size_limit=DATA_SIZE_DEFAULT, map=None,
-                 enable_SMTPUTF8=False, decode_data=None):
+                 enable_SMTPUTF8=False, decode_data=False):
         self._localaddr = localaddr
         self._remoteaddr = remoteaddr
         self.data_size_limit = data_size_limit
-        self.enable_SMTPUTF8 = enable_SMTPUTF8
-        if enable_SMTPUTF8:
-            if decode_data:
-                raise ValueError("The decode_data and enable_SMTPUTF8"
-                                 " parameters cannot be set to True at the"
-                                 " same time.")
-            decode_data = False
-        if decode_data is None:
-            warn("The decode_data default of True will change to False in 3.6;"
-                 " specify an explicit value for this keyword",
-                 DeprecationWarning, 2)
-            decode_data = True
-        self._decode_data = decode_data
+        self.enable_SMTPUTF8 = enable_SMTPUTF8 = bool(enable_SMTPUTF8)
+        self._decode_data = decode_data = bool(decode_data)
+        if enable_SMTPUTF8 and decode_data:
+            raise ValueError("decode_data and enable_SMTPUTF8 cannot"
+                             " be set to True at the same time")
         asyncore.dispatcher.__init__(self, map=map)
         try:
             gai_results = socket.getaddrinfo(*localaddr,
@@ -698,9 +683,9 @@
         containing a `.' followed by other text has had the leading dot
         removed.
 
-        kwargs is a dictionary containing additional information. It is empty
-        unless decode_data=False or enable_SMTPUTF8=True was given as init
-        parameter, in which case ut will contain the following keys:
+        kwargs is a dictionary containing additional information.  It is
+        empty if decode_data=True was given as init parameter, otherwise
+        it will contain the following keys:
             'mail_options': list of parameters to the mail command.  All
                             elements are uppercase strings.  Example:
                             ['BODY=8BITMIME', 'SMTPUTF8'].
diff --git a/Lib/test/test_smtpd.py b/Lib/test/test_smtpd.py
--- a/Lib/test/test_smtpd.py
+++ b/Lib/test/test_smtpd.py
@@ -53,10 +53,6 @@
         write_line(b'DATA')
         self.assertRaises(NotImplementedError, write_line, b'spam\r\n.\r\n')
 
-    def test_decode_data_default_warns(self):
-        with self.assertWarns(DeprecationWarning):
-            smtpd.SMTPServer((support.HOST, 0), ('b', 0))
-
     def test_decode_data_and_enable_SMTPUTF8_raises(self):
         self.assertRaises(
             ValueError,
@@ -108,10 +104,9 @@
              """))
 
     def test_process_message_with_decode_data_false(self):
-        server = smtpd.DebuggingServer((support.HOST, 0), ('b', 0),
-                                       decode_data=False)
+        server = smtpd.DebuggingServer((support.HOST, 0), ('b', 0))
         conn, addr = server.accept()
-        channel = smtpd.SMTPChannel(server, conn, addr, decode_data=False)
+        channel = smtpd.SMTPChannel(server, conn, addr)
         with support.captured_stdout() as s:
             self.send_data(channel, b'From: test\n\nh\xc3\xa9llo\xff\n')
         stdout = s.getvalue()
@@ -175,13 +170,11 @@
 
     @unittest.skipUnless(support.IPV6_ENABLED, "IPv6 not enabled")
     def test_socket_uses_IPv6(self):
-        server = smtpd.SMTPServer((support.HOSTv6, 0), (support.HOST, 0),
-                                  decode_data=False)
+        server = smtpd.SMTPServer((support.HOSTv6, 0), (support.HOST, 0))
         self.assertEqual(server.socket.family, socket.AF_INET6)
 
     def test_socket_uses_IPv4(self):
-        server = smtpd.SMTPServer((support.HOST, 0), (support.HOSTv6, 0),
-                                  decode_data=False)
+        server = smtpd.SMTPServer((support.HOST, 0), (support.HOSTv6, 0))
         self.assertEqual(server.socket.family, socket.AF_INET)
 
 
@@ -204,18 +197,18 @@
         channel.handle_read()
 
     def test_params_rejected(self):
-        server = DummyServer((support.HOST, 0), ('b', 0), decode_data=False)
+        server = DummyServer((support.HOST, 0), ('b', 0))
         conn, addr = server.accept()
-        channel = smtpd.SMTPChannel(server, conn, addr, decode_data=False)
+        channel = smtpd.SMTPChannel(server, conn, addr)
         self.write_line(channel, b'EHLO example')
         self.write_line(channel, b'MAIL from: <foo at example.com> size=20')
         self.write_line(channel, b'RCPT to: <foo at example.com> foo=bar')
         self.assertEqual(channel.socket.last, self.error_response)
 
     def test_nothing_accepted(self):
-        server = DummyServer((support.HOST, 0), ('b', 0), decode_data=False)
+        server = DummyServer((support.HOST, 0), ('b', 0))
         conn, addr = server.accept()
-        channel = smtpd.SMTPChannel(server, conn, addr, decode_data=False)
+        channel = smtpd.SMTPChannel(server, conn, addr)
         self.write_line(channel, b'EHLO example')
         self.write_line(channel, b'MAIL from: <foo at example.com> size=20')
         self.write_line(channel, b'RCPT to: <foo at example.com>')
@@ -257,9 +250,9 @@
         self.assertEqual(channel.socket.last, b'250 OK\r\n')
 
     def test_with_decode_data_false(self):
-        server = DummyServer((support.HOST, 0), ('b', 0), decode_data=False)
+        server = DummyServer((support.HOST, 0), ('b', 0))
         conn, addr = server.accept()
-        channel = smtpd.SMTPChannel(server, conn, addr, decode_data=False)
+        channel = smtpd.SMTPChannel(server, conn, addr)
         self.write_line(channel, b'EHLO example')
         for line in [
             b'MAIL from: <foo at example.com> size=20 SMTPUTF8',
@@ -765,13 +758,6 @@
         with support.check_warnings(('', DeprecationWarning)):
             self.channel._SMTPChannel__addr = 'spam'
 
-    def test_decode_data_default_warning(self):
-        with self.assertWarns(DeprecationWarning):
-            server = DummyServer((support.HOST, 0), ('b', 0))
-        conn, addr = self.server.accept()
-        with self.assertWarns(DeprecationWarning):
-            smtpd.SMTPChannel(server, conn, addr)
-
 @unittest.skipUnless(support.IPV6_ENABLED, "IPv6 not enabled")
 class SMTPDChannelIPv6Test(SMTPDChannelTest):
     def setUp(self):
@@ -845,12 +831,9 @@
         smtpd.socket = asyncore.socket = mock_socket
         self.old_debugstream = smtpd.DEBUGSTREAM
         self.debug = smtpd.DEBUGSTREAM = io.StringIO()
-        self.server = DummyServer((support.HOST, 0), ('b', 0),
-                                  decode_data=False)
+        self.server = DummyServer((support.HOST, 0), ('b', 0))
         conn, addr = self.server.accept()
-        # Set decode_data to False
-        self.channel = smtpd.SMTPChannel(self.server, conn, addr,
-                decode_data=False)
+        self.channel = smtpd.SMTPChannel(self.server, conn, addr)
 
     def tearDown(self):
         asyncore.close_all()
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -277,6 +277,9 @@
 Library
 -------
 
+- Issue #27033: The default value of the decode_data parameter for
+  smtpd.SMTPChannel and smtpd.SMTPServer constructors is changed to False.
+
 - Issue #27034: Removed deprecated class asynchat.fifo.
 
 - Issue #26870: Added readline.set_auto_history(), which can stop entries

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list