Commit fdb23c2f authored by R David Murray's avatar R David Murray

#20098: add mangle_from_ policy option.

This defaults to True in the compat32 policy for backward compatibility,
but to False for all new policies.

Patch by Milan Oberkirch, with a few tweaks.
parent 224ef3ec
......@@ -187,6 +187,18 @@ added matters. To illustrate::
:const:`False` (the default), defects will be passed to the
:meth:`register_defect` method.
.. attribute:: mangle_from\_
If :const:`True`, lines starting with *"From "* in the body are
escaped by putting a ``>`` in front of them. This parameter is used when
the message is being serialized by a generator.
Default: :const:`False`.
.. versionadded:: 3.5
The *mangle_from_* parameter.
The following :class:`Policy` method is intended to be called by code using
the email library to create policy instances with custom settings:
......@@ -319,6 +331,13 @@ added matters. To illustrate::
:const:`compat32`, that is used as the default policy. Thus the default
behavior of the email package is to maintain compatibility with Python 3.2.
The following attributes have values that are different from the
:class:`Policy` default:
.. attribute:: mangle_from_
The default is ``True``.
The class provides the following concrete implementations of the
abstract methods of :class:`Policy`:
......@@ -356,6 +375,14 @@ added matters. To illustrate::
line breaks and any (RFC invalid) binary data it may contain.
An instance of :class:`Compat32` is provided as a module constant:
.. data:: compat32
An instance of :class:`Compat32`, providing backward compatibility with the
behavior of the email package in Python 3.2.
.. note::
The documentation below describes new policies that are included in the
......
......@@ -351,6 +351,12 @@ doctest
email
-----
* A new policy option :attr:`~email.policy.Policy.mangle_from_` controls
whether or not lines that start with "From " in email bodies are prefixed with
a '>' character by generators. The default is ``True`` for
:attr:`~email.policy.compat32` and ``False`` for all other policies.
(Contributed by Milan Oberkirch in :issue:`20098`.)
* A new method :meth:`~email.message.Message.get_content_disposition` provides
easy access to a canonical value for the :mailheader:`Content-Disposition`
header (``None`` if there is no such header). (Contributed by Abhilash Raj
......
......@@ -149,12 +149,18 @@ class Policy(_PolicyBase, metaclass=abc.ABCMeta):
during serialization. None or 0 means no line
wrapping is done. Default is 78.
mangle_from_ -- a flag that, when True escapes From_ lines in the
body of the message by putting a `>' in front of
them. This is used when the message is being
serialized by a generator. Default: True.
"""
raise_on_defect = False
linesep = '\n'
cte_type = '8bit'
max_line_length = 78
mangle_from_ = False
def handle_defect(self, obj, defect):
"""Based on policy, either raise defect or call register_defect.
......@@ -266,6 +272,8 @@ class Compat32(Policy):
replicates the behavior of the email package version 5.1.
"""
mangle_from_ = True
def _sanitize_header(self, name, value):
# If the header value contains surrogates, return a Header using
# the unknown-8bit charset to encode the bytes as encoded words.
......
......@@ -32,16 +32,16 @@ class Generator:
# Public interface
#
def __init__(self, outfp, mangle_from_=True, maxheaderlen=None, *,
def __init__(self, outfp, mangle_from_=None, maxheaderlen=None, *,
policy=None):
"""Create the generator for message flattening.
outfp is the output file-like object for writing the message to. It
must have a write() method.
Optional mangle_from_ is a flag that, when True (the default), escapes
From_ lines in the body of the message by putting a `>' in front of
them.
Optional mangle_from_ is a flag that, when True (the default if policy
is not set), escapes From_ lines in the body of the message by putting
a `>' in front of them.
Optional maxheaderlen specifies the longest length for a non-continued
header. When a header line is longer (in characters, with tabs
......@@ -56,6 +56,9 @@ class Generator:
flatten method is used.
"""
if mangle_from_ is None:
mangle_from_ = True if policy is None else policy.mangle_from_
self._fp = outfp
self._mangle_from_ = mangle_from_
self.maxheaderlen = maxheaderlen
......@@ -449,7 +452,7 @@ class DecodedGenerator(Generator):
Like the Generator base class, except that non-text parts are substituted
with a format string representing the part.
"""
def __init__(self, outfp, mangle_from_=True, maxheaderlen=78, fmt=None):
def __init__(self, outfp, mangle_from_=None, maxheaderlen=78, fmt=None):
"""Like Generator.__init__() except that an additional optional
argument is allowed.
......
......@@ -140,6 +140,28 @@ class TestGeneratorBase:
g.flatten(msg, linesep='\n')
self.assertEqual(s.getvalue(), self.typ(expected))
def test_set_mangle_from_via_policy(self):
source = textwrap.dedent("""\
Subject: test that
from is mangeld in the body!
From time to time I write a rhyme.
""")
variants = (
(None, True),
(policy.compat32, True),
(policy.default, False),
(policy.default.clone(mangle_from_=True), True),
)
for p, mangle in variants:
expected = source.replace('From ', '>From ') if mangle else source
with self.subTest(policy=p, mangle_from_=mangle):
msg = self.msgmaker(self.typ(source))
s = self.ioclass()
g = self.genclass(s, policy=p)
g.flatten(msg)
self.assertEqual(s.getvalue(), self.typ(expected))
class TestGenerator(TestGeneratorBase, TestEmailBase):
......
......@@ -22,6 +22,7 @@ class PolicyAPITests(unittest.TestCase):
'linesep': '\n',
'cte_type': '8bit',
'raise_on_defect': False,
'mangle_from_': True,
}
# These default values are the ones set on email.policy.default.
# If any of these defaults change, the docs must be updated.
......@@ -32,6 +33,7 @@ class PolicyAPITests(unittest.TestCase):
'header_factory': email.policy.EmailPolicy.header_factory,
'refold_source': 'long',
'content_manager': email.policy.EmailPolicy.content_manager,
'mangle_from_': False,
})
# For each policy under test, we give here what we expect the defaults to
......
......@@ -47,6 +47,9 @@ Core and Builtins
Library
-------
- Issue #20098: New mangle_from_ policy option for email, default True
for compat32, but False for all other policies.
- Issue #24211: The email library now supports RFC 6532: it can generate
headers using utf-8 instead of encoded words.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment