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

Skip to content

Commit cb448cf

Browse files
committed
#12586: Expand What's New email entry with provisional policy features.
1 parent 4322c17 commit cb448cf

1 file changed

Lines changed: 96 additions & 0 deletions

File tree

Doc/whatsnew/3.3.rst

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,9 @@ in the `Porting Python code`_ section of this document.
558558
New Email Package Features
559559
==========================
560560

561+
Policy Framework
562+
----------------
563+
561564
The email package now has a :mod:`~email.policy` framework. A
562565
:class:`~email.policy.Policy` is an object with several methods and properties
563566
that control how the email package behaves. The primary policy for Python 3.3
@@ -610,6 +613,99 @@ policy instances for your different cases, and pass those in when you create
610613
the ``generator``.
611614

612615

616+
Provisional Policy with New Header API
617+
--------------------------------------
618+
619+
While the policy framework is worthwhile all by itself, the main motivation for
620+
introducing it is to allow the creation of new policies that implement new
621+
features for the email package in a way that maintains backward compatibility
622+
for those who do not use the new policies. Because the new policies introduce a
623+
new API, we are releasing them in Python 3.3 as a :term:`provisional policy
624+
<provisional package>`. Backwards incompatible changes (up to and including
625+
removal of the code) may occur if deemed necessary by the core developers.
626+
627+
The new policies are instances of :class:`~email.policy.EmailPolicy`,
628+
and add the following additional controls:
629+
630+
=============== =======================================================
631+
refold_source Controls whether or not headers parsed by a
632+
:mod:`~email.parser` are refolded by the
633+
:mod:`~email.generator`. It can be ``none``, ``long``,
634+
or ``all``. The default is ``long``, which means that
635+
source headers with a line longer than
636+
``max_line_length`` get refolded. ``none`` means no
637+
line get refolded, and ``all`` means that all lines
638+
get refolded.
639+
640+
header_factory A callable that take a ``name`` and ``value`` and
641+
produces a custom header object.
642+
=============== =======================================================
643+
644+
The ``header_factory`` is the key to the new features provided by the new
645+
policies. When one of the new policies is used, any header retrieved from
646+
a ``Message`` object is an object produced by the ``header_factory``, and any
647+
time you set a header on a ``Message`` it becomes an object produced by
648+
``header_factory``. All such header objects have a ``name`` attribute equal
649+
to the header name. Address and Date headers have additional attributes
650+
that give you access to the parsed data of the header. This means you can now
651+
do things like this::
652+
653+
>>> m = Message(policy=SMTP)
654+
>>> m['To'] = 'Éric <[email protected]>'
655+
>>> m['to']
656+
657+
>>> m['to'].addresses
658+
(Address(display_name='Éric', username='foo', domain='example.com'),)
659+
>>> m['to'].addresses[0].username
660+
'foo'
661+
>>> m['to'].addresses[0].display_name
662+
'Éric'
663+
>>> m['Date'] = email.utils.localtime()
664+
>>> m['Date'].datetime
665+
datetime.datetime(2012, 5, 25, 21, 39, 24, 465484, tzinfo=datetime.timezone(datetime.timedelta(-1, 72000), 'EDT'))
666+
>>> m['Date']
667+
'Fri, 25 May 2012 21:44:27 -0400'
668+
>>> print(m)
669+
To: =?utf-8?q?=C3=89ric?= <[email protected]>
670+
Date: Fri, 25 May 2012 21:44:27 -0400
671+
672+
You will note that the unicode display name is automatically encoded as
673+
``utf-8`` when the message is serialized, but that when the header is accessed
674+
directly, you get the unicode version. This eliminates any need to deal with
675+
the :mod:`email.header` :meth:`~email.header.decode_header` or
676+
:meth:`~email.header.make_header` functions.
677+
678+
You can also create addresses from parts::
679+
680+
>>> m['cc'] = [Group('pals', [Address('Bob', 'bob', 'example.com'),
681+
... Address('Sally', 'sally', 'example.com')]),
682+
... Address('Bonzo', addr_spec='[email protected]')]
683+
>>> print(m)
684+
To: =?utf-8?q?=C3=89ric?= <[email protected]>
685+
Date: Fri, 25 May 2012 21:44:27 -0400
686+
cc: pals: Bob <[email protected]>, Sally <[email protected]>;, Bonzo <[email protected]>
687+
688+
Decoding to unicode is done automatically::
689+
690+
>>> m2 = message_from_string(str(m))
691+
>>> m2['to']
692+
693+
694+
When you parse a message, you can use the ``addresses`` and ``groups``
695+
attributes of the header objects to access the groups and individual
696+
addresses::
697+
698+
>>> m2['cc'].addresses
699+
(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'))
700+
>>> m2['cc'].groups
701+
(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'),))
702+
703+
In summary, if you use one of the new policies, header manipulation works the
704+
way it ought to: your application works with unicode strings, and the email
705+
package transparently encodes and decodes the unicode to and from the RFC
706+
standard Content Transfer Encodings.
707+
708+
613709
Other Language Changes
614710
======================
615711

0 commit comments

Comments
 (0)