[Email-SIG] email6 and Python 3.3
R. David Murray
rdmurray at bitdance.com
Mon Feb 28 21:11:33 CET 2011
So, we've released Python3.2 with an email package that pretty much works.
There are some rough edges compared to Python2, mostly having to do with
what happens when you try to manipulate (as opposed to just transmit
unchanged) messages with unencoded 8bit characters in their headers.
The API isn't the elegant API that we envisioned (but hadn't quite worked
out) for email6, but it is informed by our discussions. The biggest
conceptual difference between the email6 work I did for the PSF grant
and email5.1 is actually, I think, a good one: in email5.1 you have
bytes and string input, and bytes and string output, unified by a
single model object that represents the abstract version of the Message.
How this is implemented internally is a detail, and I was, when I was
working on the header classes, getting distracted by the implementation
details, even though our originally discussions pretty much stuck to
the single-model view.
What email5.1 seriously lacks is a unified, consistent interface for
getting either bytes or strings out of the Message object when dealing
at any level below that of the whole Message. This is a serious defect
for doing more advanced applications.
3.2 has been released, and email works, and this is a good thing. Now,
however, we are constrained much more tightly to backward compatibility
when doing further development. Fortunately, the pathway along which we
were developing email6 lends itself to retaining backward compatibility
while allowing for improving both the API and the internal functioning
of the code.
The last email6 work I did under PSF grant funding was working on the
Policy framework. As you may or may not remember, after Barry's initial
suggestion the Policy framework evolved into a place where all of the
"adjustments" that could be made to the various email algorithms could
be collected, including acting as a registry for the classes used to
represent headers and MIME types.
So, here is a plan for moving forward with email6, with the intent
that whatever part of this is tested and stable will be shipped with
1) Add the "policy framework" to the email package. (Some of this
work has already been done as part of the original PSF grant work).
Most classes and methods will grow a 'policy' keyword-only argument that
accepts a policy object that will control the behavior of that object
or call. The default policy will implement the behavior of the current
5.1 email package, reusing most of its code but refactored to work
under the control of the policy. The biggest refactorings will take
place in the Parser and Generator classes.
2) Create the skeleton of the 'email6' Policy. This consists of new
Header and Message classes that have a different API than the email 5.1
classes. In particular, the Header class will be used to encapsulate
all email headers, and the new Message class will handle this correctly.
At this point we will have a functioning, minimalist prototype of the
3) Complete the Header subclasses that handle structured headers. Add
Message subclasses that implement improved APIs for various MIME types.
At this point the package will be ready for release on PyPI as a testable
prototype, and will be a suitable target for prototype application
development. From this point it will be a matter of fixing bugs (both
code bugs and API bugs) as they are discovered. New releases will be
made frequently on PyPI, with the goal of getting the package stable
by the time of the Python 3.3 release. Fairly early in that process,
however, the package should become a pretty stable development target,
because I think the API should settle down fairly early.
There is one tricky bit about this design, and that is that a library
that doesn't know what kind of Message object it is going to be handed
(email5 or email6) will have to have code to handle both if it wants to
retain backward compatibility with Python 3.2. Obviously the library
can detect the Message type and branch accordingly; however, there are
more elegant solutions. One option would be for email6 to provide
a wrapper class that exposes an email5-like API when wrapped around
an email6 Message.
Note that I currently envision working on email6 in an hg branch until
the Policy framework+5.1 compatibility is complete, and then merge that
branch with 3.3. At that point all the hooks are in place for any library
or application to customize email handling. That way even if my current
plans fall through for some reason and email6 isn't stable enough for 3.3,
the very-useful-by-itself policy framework will still be in place.
More information about the Email-SIG