X Tutup
Skip to content

Commit 3edd22a

Browse files
committed
python#11731: simplify/enhance parser/generator API by introducing policy objects.
This new interface will also allow for future planned enhancements in control over the parser/generator without requiring any additional complexity in the parser/generator API. Patch reviewed by Éric Araujo and Barry Warsaw.
1 parent ce16be9 commit 3edd22a

File tree

13 files changed

+912
-81
lines changed

13 files changed

+912
-81
lines changed

Doc/library/email.generator.rst

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ Here are the public methods of the :class:`Generator` class, imported from the
3232
:mod:`email.generator` module:
3333

3434

35-
.. class:: Generator(outfp, mangle_from_=True, maxheaderlen=78)
35+
.. class:: Generator(outfp, mangle_from_=True, maxheaderlen=78, *, \
36+
policy=policy.default)
3637

3738
The constructor for the :class:`Generator` class takes a :term:`file-like object`
3839
called *outfp* for an argument. *outfp* must support the :meth:`write` method
@@ -53,10 +54,16 @@ Here are the public methods of the :class:`Generator` class, imported from the
5354
:class:`~email.header.Header` class. Set to zero to disable header wrapping.
5455
The default is 78, as recommended (but not required) by :rfc:`2822`.
5556

57+
The *policy* keyword specifies a :mod:`~email.policy` object that controls a
58+
number of aspects of the generator's operation. The default policy
59+
maintains backward compatibility.
60+
61+
.. versionchanged:: 3.3 Added the *policy* keyword.
62+
5663
The other public :class:`Generator` methods are:
5764

5865

59-
.. method:: flatten(msg, unixfrom=False, linesep='\\n')
66+
.. method:: flatten(msg, unixfrom=False, linesep=None)
6067

6168
Print the textual representation of the message object structure rooted at
6269
*msg* to the output file specified when the :class:`Generator` instance
@@ -72,12 +79,13 @@ Here are the public methods of the :class:`Generator` class, imported from the
7279
Note that for subparts, no envelope header is ever printed.
7380

7481
Optional *linesep* specifies the line separator character used to
75-
terminate lines in the output. It defaults to ``\n`` because that is
76-
the most useful value for Python application code (other library packages
77-
expect ``\n`` separated lines). ``linesep=\r\n`` can be used to
78-
generate output with RFC-compliant line separators.
82+
terminate lines in the output. If specified it overrides the value
83+
specified by the ``Generator``\'s ``policy``.
7984

80-
Messages parsed with a Bytes parser that have a
85+
Because strings cannot represent non-ASCII bytes, ``Generator`` ignores
86+
the value of the :attr:`~email.policy.Policy.must_be_7bit`
87+
:mod:`~email.policy` setting and operates as if it were set ``True``.
88+
This means that messages parsed with a Bytes parser that have a
8189
:mailheader:`Content-Transfer-Encoding` of 8bit will be converted to a
8290
use a 7bit Content-Transfer-Encoding. Non-ASCII bytes in the headers
8391
will be :rfc:`2047` encoded with a charset of `unknown-8bit`.
@@ -103,7 +111,8 @@ As a convenience, see the :class:`~email.message.Message` methods
103111
formatted string representation of a message object. For more detail, see
104112
:mod:`email.message`.
105113

106-
.. class:: BytesGenerator(outfp, mangle_from_=True, maxheaderlen=78)
114+
.. class:: BytesGenerator(outfp, mangle_from_=True, maxheaderlen=78, *, \
115+
policy=policy.default)
107116

108117
The constructor for the :class:`BytesGenerator` class takes a binary
109118
:term:`file-like object` called *outfp* for an argument. *outfp* must
@@ -125,19 +134,31 @@ formatted string representation of a message object. For more detail, see
125134
wrapping. The default is 78, as recommended (but not required) by
126135
:rfc:`2822`.
127136

137+
The *policy* keyword specifies a :mod:`~email.policy` object that controls a
138+
number of aspects of the generator's operation. The default policy
139+
maintains backward compatibility.
140+
141+
.. versionchanged:: 3.3 Added the *policy* keyword.
142+
128143
The other public :class:`BytesGenerator` methods are:
129144

130145

131-
.. method:: flatten(msg, unixfrom=False, linesep='\n')
146+
.. method:: flatten(msg, unixfrom=False, linesep=None)
132147

133148
Print the textual representation of the message object structure rooted
134149
at *msg* to the output file specified when the :class:`BytesGenerator`
135150
instance was created. Subparts are visited depth-first and the resulting
136-
text will be properly MIME encoded. If the input that created the *msg*
137-
contained bytes with the high bit set and those bytes have not been
138-
modified, they will be copied faithfully to the output, even if doing so
139-
is not strictly RFC compliant. (To produce strictly RFC compliant
140-
output, use the :class:`Generator` class.)
151+
text will be properly MIME encoded. If the :mod:`~email.policy` option
152+
:attr:`~email.policy.Policy.must_be_7bit` is ``False`` (the default),
153+
then any bytes with the high bit set in the original parsed message that
154+
have not been modified will be copied faithfully to the output. If
155+
``must_be_7bit`` is true, the bytes will be converted as needed using an
156+
ASCII content-transfer-encoding. In particular, RFC-invalid non-ASCII
157+
bytes in headers will be encoded using the MIME ``unknown-8bit``
158+
character set, thus rendering them RFC-compliant.
159+
160+
.. XXX: There should be a complementary option that just does the RFC
161+
compliance transformation but leaves CTE 8bit parts alone.
141162
142163
Messages parsed with a Bytes parser that have a
143164
:mailheader:`Content-Transfer-Encoding` of 8bit will be reconstructed
@@ -152,10 +173,8 @@ formatted string representation of a message object. For more detail, see
152173
Note that for subparts, no envelope header is ever printed.
153174

154175
Optional *linesep* specifies the line separator character used to
155-
terminate lines in the output. It defaults to ``\n`` because that is
156-
the most useful value for Python application code (other library packages
157-
expect ``\n`` separated lines). ``linesep=\r\n`` can be used to
158-
generate output with RFC-compliant line separators.
176+
terminate lines in the output. If specified it overrides the value
177+
specified by the ``Generator``\ 's ``policy``.
159178

160179
.. method:: clone(fp)
161180

Doc/library/email.parser.rst

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,18 @@ list of defects that it can find.
5858
Here is the API for the :class:`FeedParser`:
5959

6060

61-
.. class:: FeedParser(_factory=email.message.Message)
61+
.. class:: FeedParser(_factory=email.message.Message, *, policy=policy.default)
6262

6363
Create a :class:`FeedParser` instance. Optional *_factory* is a no-argument
6464
callable that will be called whenever a new message object is needed. It
6565
defaults to the :class:`email.message.Message` class.
6666

67+
The *policy* keyword specifies a :mod:`~email.policy` object that controls a
68+
number of aspects of the parser's operation. The default policy maintains
69+
backward compatibility.
70+
71+
.. versionchanged:: 3.3 Added the *policy* keyword.
72+
6773
.. method:: feed(data)
6874

6975
Feed the :class:`FeedParser` some more data. *data* should be a string
@@ -104,16 +110,21 @@ have the same API as the :class:`Parser` and :class:`BytesParser` classes.
104110
.. versionadded:: 3.3 BytesHeaderParser
105111

106112

107-
.. class:: Parser(_class=email.message.Message)
113+
.. class:: Parser(_class=email.message.Message, *, policy=policy.default)
108114

109115
The constructor for the :class:`Parser` class takes an optional argument
110116
*_class*. This must be a callable factory (such as a function or a class), and
111117
it is used whenever a sub-message object needs to be created. It defaults to
112118
:class:`~email.message.Message` (see :mod:`email.message`). The factory will
113119
be called without arguments.
114120

115-
.. versionchanged:: 3.2
116-
Removed the *strict* argument that was deprecated in 2.4.
121+
The *policy* keyword specifies a :mod:`~email.policy` object that controls a
122+
number of aspects of the parser's operation. The default policy maintains
123+
backward compatibility.
124+
125+
.. versionchanged:: 3.3
126+
Removed the *strict* argument that was deprecated in 2.4. Added the
127+
*policy* keyword.
117128

118129
The other public :class:`Parser` methods are:
119130

@@ -144,12 +155,18 @@ have the same API as the :class:`Parser` and :class:`BytesParser` classes.
144155
the entire contents of the file.
145156

146157

147-
.. class:: BytesParser(_class=email.message.Message, strict=None)
158+
.. class:: BytesParser(_class=email.message.Message, *, policy=policy.default)
148159

149160
This class is exactly parallel to :class:`Parser`, but handles bytes input.
150161
The *_class* and *strict* arguments are interpreted in the same way as for
151-
the :class:`Parser` constructor. *strict* is supported only to make porting
152-
code easier; it is deprecated.
162+
the :class:`Parser` constructor.
163+
164+
The *policy* keyword specifies a :mod:`~email.policy` object that
165+
controls a number of aspects of the parser's operation. The default
166+
policy maintains backward compatibility.
167+
168+
.. versionchanged:: 3.3
169+
Removed the *strict* argument. Added the *policy* keyword.
153170

154171
.. method:: parse(fp, headeronly=False)
155172

@@ -187,34 +204,43 @@ in the top-level :mod:`email` package namespace.
187204

188205
.. currentmodule:: email
189206

190-
.. function:: message_from_string(s, _class=email.message.Message, strict=None)
207+
.. function:: message_from_string(s, _class=email.message.Message, *, \
208+
policy=policy.default)
191209

192210
Return a message object structure from a string. This is exactly equivalent to
193-
``Parser().parsestr(s)``. Optional *_class* and *strict* are interpreted as
211+
``Parser().parsestr(s)``. *_class* and *policy* are interpreted as
194212
with the :class:`Parser` class constructor.
195213

214+
.. versionchanged:: removed *strict*, added *policy*
215+
196216
.. function:: message_from_bytes(s, _class=email.message.Message, strict=None)
197217

198218
Return a message object structure from a byte string. This is exactly
199219
equivalent to ``BytesParser().parsebytes(s)``. Optional *_class* and
200220
*strict* are interpreted as with the :class:`Parser` class constructor.
201221

202222
.. versionadded:: 3.2
223+
.. versionchanged:: 3.3 removed *strict*, added *policy*
203224

204-
.. function:: message_from_file(fp, _class=email.message.Message, strict=None)
225+
.. function:: message_from_file(fp, _class=email.message.Message, *, \
226+
policy=policy.default)
205227

206228
Return a message object structure tree from an open :term:`file object`.
207-
This is exactly equivalent to ``Parser().parse(fp)``. Optional *_class*
208-
and *strict* are interpreted as with the :class:`Parser` class constructor.
229+
This is exactly equivalent to ``Parser().parse(fp)``. *_class*
230+
and *policy* are interpreted as with the :class:`Parser` class constructor.
231+
232+
.. versionchanged:: 3.3 removed *strict*, added *policy*
209233

210-
.. function:: message_from_binary_file(fp, _class=email.message.Message, strict=None)
234+
.. function:: message_from_binary_file(fp, _class=email.message.Message, *, \
235+
policy=policy.default)
211236

212237
Return a message object structure tree from an open binary :term:`file
213238
object`. This is exactly equivalent to ``BytesParser().parse(fp)``.
214-
Optional *_class* and *strict* are interpreted as with the :class:`Parser`
239+
*_class* and *policy* are interpreted as with the :class:`Parser`
215240
class constructor.
216241

217242
.. versionadded:: 3.2
243+
.. versionchanged:: 3.3 removed *strict*, added *policy*
218244

219245
Here's an example of how you might use this at an interactive Python prompt::
220246

0 commit comments

Comments
 (0)
X Tutup