merge heads

This commit is contained in:
Gregory P. Smith 2012-09-29 13:51:00 -07:00
commit 9f4e796742
1 changed files with 151 additions and 151 deletions

View File

@ -687,157 +687,6 @@ consideration when updating code for Python 3.3, and thus should be read about
in the `Porting Python code`_ section of this document.
New Email Package Features
==========================
Policy Framework
----------------
The email package now has a :mod:`~email.policy` framework. A
:class:`~email.policy.Policy` is an object with several methods and properties
that control how the email package behaves. The primary policy for Python 3.3
is the :class:`~email.policy.Compat32` policy, which provides backward
compatibility with the email package in Python 3.2. A ``policy`` can be
specified when an email message is parsed by a :mod:`~email.parser`, or when a
:class:`~email.message.Message` object is created, or when an email is
serialized using a :mod:`~email.generator`. Unless overridden, a policy passed
to a ``parser`` is inherited by all the ``Message`` object and sub-objects
created by the ``parser``. By default a ``generator`` will use the policy of
the ``Message`` object it is serializing. The default policy is
:data:`~email.policy.compat32`.
The minimum set of controls implemented by all ``policy`` objects are:
=============== =======================================================
max_line_length The maximum length, excluding the linesep character(s),
individual lines may have when a ``Message`` is
serialized. Defaults to 78.
linesep The character used to separate individual lines when a
``Message`` is serialized. Defaults to ``\n``.
cte_type ``7bit`` or ``8bit``. ``8bit`` applies only to a
``Bytes`` ``generator``, and means that non-ASCII may
be used where allowed by the protocol (or where it
exists in the original input).
raise_on_defect Causes a ``parser`` to raise error when defects are
encountered instead of adding them to the ``Message``
object's ``defects`` list.
=============== =======================================================
A new policy instance, with new settings, is created using the
:meth:`~email.policy.Policy.clone` method of policy objects. ``clone`` takes
any of the above controls as keyword arguments. Any control not specified in
the call retains its default value. Thus you can create a policy that uses
``\r\n`` linesep characters like this::
mypolicy = compat32.clone(linesep='\r\n')
Policies can be used to make the generation of messages in the format needed by
your application simpler. Instead of having to remember to specify
``linesep='\r\n'`` in all the places you call a ``generator``, you can specify
it once, when you set the policy used by the ``parser`` or the ``Message``,
whichever your program uses to create ``Message`` objects. On the other hand,
if you need to generate messages in multiple forms, you can still specify the
parameters in the appropriate ``generator`` call. Or you can have custom
policy instances for your different cases, and pass those in when you create
the ``generator``.
Provisional Policy with New Header API
--------------------------------------
While the policy framework is worthwhile all by itself, the main motivation for
introducing it is to allow the creation of new policies that implement new
features for the email package in a way that maintains backward compatibility
for those who do not use the new policies. Because the new policies introduce a
new API, we are releasing them in Python 3.3 as a :term:`provisional policy
<provisional package>`. Backwards incompatible changes (up to and including
removal of the code) may occur if deemed necessary by the core developers.
The new policies are instances of :class:`~email.policy.EmailPolicy`,
and add the following additional controls:
=============== =======================================================
refold_source Controls whether or not headers parsed by a
:mod:`~email.parser` are refolded by the
:mod:`~email.generator`. It can be ``none``, ``long``,
or ``all``. The default is ``long``, which means that
source headers with a line longer than
``max_line_length`` get refolded. ``none`` means no
line get refolded, and ``all`` means that all lines
get refolded.
header_factory A callable that take a ``name`` and ``value`` and
produces a custom header object.
=============== =======================================================
The ``header_factory`` is the key to the new features provided by the new
policies. When one of the new policies is used, any header retrieved from
a ``Message`` object is an object produced by the ``header_factory``, and any
time you set a header on a ``Message`` it becomes an object produced by
``header_factory``. All such header objects have a ``name`` attribute equal
to the header name. Address and Date headers have additional attributes
that give you access to the parsed data of the header. This means you can now
do things like this::
>>> m = Message(policy=SMTP)
>>> m['To'] = 'Éric <foo@example.com>'
>>> m['to']
'Éric <foo@example.com>'
>>> m['to'].addresses
(Address(display_name='Éric', username='foo', domain='example.com'),)
>>> m['to'].addresses[0].username
'foo'
>>> m['to'].addresses[0].display_name
'Éric'
>>> m['Date'] = email.utils.localtime()
>>> m['Date'].datetime
datetime.datetime(2012, 5, 25, 21, 39, 24, 465484, tzinfo=datetime.timezone(datetime.timedelta(-1, 72000), 'EDT'))
>>> m['Date']
'Fri, 25 May 2012 21:44:27 -0400'
>>> print(m)
To: =?utf-8?q?=C3=89ric?= <foo@example.com>
Date: Fri, 25 May 2012 21:44:27 -0400
You will note that the unicode display name is automatically encoded as
``utf-8`` when the message is serialized, but that when the header is accessed
directly, you get the unicode version. This eliminates any need to deal with
the :mod:`email.header` :meth:`~email.header.decode_header` or
:meth:`~email.header.make_header` functions.
You can also create addresses from parts::
>>> m['cc'] = [Group('pals', [Address('Bob', 'bob', 'example.com'),
... Address('Sally', 'sally', 'example.com')]),
... Address('Bonzo', addr_spec='bonz@laugh.com')]
>>> print(m)
To: =?utf-8?q?=C3=89ric?= <foo@example.com>
Date: Fri, 25 May 2012 21:44:27 -0400
cc: pals: Bob <bob@example.com>, Sally <sally@example.com>;, Bonzo <bonz@laugh.com>
Decoding to unicode is done automatically::
>>> m2 = message_from_string(str(m))
>>> m2['to']
'Éric <foo@example.com>'
When you parse a message, you can use the ``addresses`` and ``groups``
attributes of the header objects to access the groups and individual
addresses::
>>> m2['cc'].addresses
(Address(display_name='Bob', username='bob', domain='example.com'), Address(display_name='Sally', username='sally', domain='example.com'), Address(display_name='Bonzo', username='bonz', domain='laugh.com'))
>>> m2['cc'].groups
(Group(display_name='pals', addresses=(Address(display_name='Bob', username='bob', domain='example.com'), Address(display_name='Sally', username='sally', domain='example.com')), Group(display_name=None, addresses=(Address(display_name='Bonzo', username='bonz', domain='laugh.com'),))
In summary, if you use one of the new policies, header manipulation works the
way it ought to: your application works with unicode strings, and the email
package transparently encodes and decodes the unicode to and from the RFC
standard Content Transfer Encodings.
Other Language Changes
======================
@ -1226,6 +1075,157 @@ API changes
is deprecated.
email
-----
Policy Framework
~~~~~~~~~~~~~~~~
The email package now has a :mod:`~email.policy` framework. A
:class:`~email.policy.Policy` is an object with several methods and properties
that control how the email package behaves. The primary policy for Python 3.3
is the :class:`~email.policy.Compat32` policy, which provides backward
compatibility with the email package in Python 3.2. A ``policy`` can be
specified when an email message is parsed by a :mod:`~email.parser`, or when a
:class:`~email.message.Message` object is created, or when an email is
serialized using a :mod:`~email.generator`. Unless overridden, a policy passed
to a ``parser`` is inherited by all the ``Message`` object and sub-objects
created by the ``parser``. By default a ``generator`` will use the policy of
the ``Message`` object it is serializing. The default policy is
:data:`~email.policy.compat32`.
The minimum set of controls implemented by all ``policy`` objects are:
=============== =======================================================
max_line_length The maximum length, excluding the linesep character(s),
individual lines may have when a ``Message`` is
serialized. Defaults to 78.
linesep The character used to separate individual lines when a
``Message`` is serialized. Defaults to ``\n``.
cte_type ``7bit`` or ``8bit``. ``8bit`` applies only to a
``Bytes`` ``generator``, and means that non-ASCII may
be used where allowed by the protocol (or where it
exists in the original input).
raise_on_defect Causes a ``parser`` to raise error when defects are
encountered instead of adding them to the ``Message``
object's ``defects`` list.
=============== =======================================================
A new policy instance, with new settings, is created using the
:meth:`~email.policy.Policy.clone` method of policy objects. ``clone`` takes
any of the above controls as keyword arguments. Any control not specified in
the call retains its default value. Thus you can create a policy that uses
``\r\n`` linesep characters like this::
mypolicy = compat32.clone(linesep='\r\n')
Policies can be used to make the generation of messages in the format needed by
your application simpler. Instead of having to remember to specify
``linesep='\r\n'`` in all the places you call a ``generator``, you can specify
it once, when you set the policy used by the ``parser`` or the ``Message``,
whichever your program uses to create ``Message`` objects. On the other hand,
if you need to generate messages in multiple forms, you can still specify the
parameters in the appropriate ``generator`` call. Or you can have custom
policy instances for your different cases, and pass those in when you create
the ``generator``.
Provisional Policy with New Header API
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
While the policy framework is worthwhile all by itself, the main motivation for
introducing it is to allow the creation of new policies that implement new
features for the email package in a way that maintains backward compatibility
for those who do not use the new policies. Because the new policies introduce a
new API, we are releasing them in Python 3.3 as a :term:`provisional policy
<provisional package>`. Backwards incompatible changes (up to and including
removal of the code) may occur if deemed necessary by the core developers.
The new policies are instances of :class:`~email.policy.EmailPolicy`,
and add the following additional controls:
=============== =======================================================
refold_source Controls whether or not headers parsed by a
:mod:`~email.parser` are refolded by the
:mod:`~email.generator`. It can be ``none``, ``long``,
or ``all``. The default is ``long``, which means that
source headers with a line longer than
``max_line_length`` get refolded. ``none`` means no
line get refolded, and ``all`` means that all lines
get refolded.
header_factory A callable that take a ``name`` and ``value`` and
produces a custom header object.
=============== =======================================================
The ``header_factory`` is the key to the new features provided by the new
policies. When one of the new policies is used, any header retrieved from
a ``Message`` object is an object produced by the ``header_factory``, and any
time you set a header on a ``Message`` it becomes an object produced by
``header_factory``. All such header objects have a ``name`` attribute equal
to the header name. Address and Date headers have additional attributes
that give you access to the parsed data of the header. This means you can now
do things like this::
>>> m = Message(policy=SMTP)
>>> m['To'] = 'Éric <foo@example.com>'
>>> m['to']
'Éric <foo@example.com>'
>>> m['to'].addresses
(Address(display_name='Éric', username='foo', domain='example.com'),)
>>> m['to'].addresses[0].username
'foo'
>>> m['to'].addresses[0].display_name
'Éric'
>>> m['Date'] = email.utils.localtime()
>>> m['Date'].datetime
datetime.datetime(2012, 5, 25, 21, 39, 24, 465484, tzinfo=datetime.timezone(datetime.timedelta(-1, 72000), 'EDT'))
>>> m['Date']
'Fri, 25 May 2012 21:44:27 -0400'
>>> print(m)
To: =?utf-8?q?=C3=89ric?= <foo@example.com>
Date: Fri, 25 May 2012 21:44:27 -0400
You will note that the unicode display name is automatically encoded as
``utf-8`` when the message is serialized, but that when the header is accessed
directly, you get the unicode version. This eliminates any need to deal with
the :mod:`email.header` :meth:`~email.header.decode_header` or
:meth:`~email.header.make_header` functions.
You can also create addresses from parts::
>>> m['cc'] = [Group('pals', [Address('Bob', 'bob', 'example.com'),
... Address('Sally', 'sally', 'example.com')]),
... Address('Bonzo', addr_spec='bonz@laugh.com')]
>>> print(m)
To: =?utf-8?q?=C3=89ric?= <foo@example.com>
Date: Fri, 25 May 2012 21:44:27 -0400
cc: pals: Bob <bob@example.com>, Sally <sally@example.com>;, Bonzo <bonz@laugh.com>
Decoding to unicode is done automatically::
>>> m2 = message_from_string(str(m))
>>> m2['to']
'Éric <foo@example.com>'
When you parse a message, you can use the ``addresses`` and ``groups``
attributes of the header objects to access the groups and individual
addresses::
>>> m2['cc'].addresses
(Address(display_name='Bob', username='bob', domain='example.com'), Address(display_name='Sally', username='sally', domain='example.com'), Address(display_name='Bonzo', username='bonz', domain='laugh.com'))
>>> m2['cc'].groups
(Group(display_name='pals', addresses=(Address(display_name='Bob', username='bob', domain='example.com'), Address(display_name='Sally', username='sally', domain='example.com')), Group(display_name=None, addresses=(Address(display_name='Bonzo', username='bonz', domain='laugh.com'),))
In summary, if you use one of the new policies, header manipulation works the
way it ought to: your application works with unicode strings, and the email
package transparently encodes and decodes the unicode to and from the RFC
standard Content Transfer Encodings.
ftplib
------