Re: API thoughts

Barry Warsaw <[email protected]> Wed, 2 Mar 2011 15:46:24 -0500
Newsgroups gmane.comp.python.mime.devel
Organization Damn Crazy Followers of the Horn
Message-ID <[email protected]>
On Mar 01, 2011, at 03:40 PM, R. David Murray wrote:

>So, and here is the point of this email, how does the policy framework
>integrate into this design?
[...]
>This list breaks down into items that affect the Parser, ones that affect
>the Generator, and ones that affect both the Parser and the Message.
>(Well, the "how much transformation" affects all three in the sense that
>the data has to be preserved by both the Parser and the Message in order
>for the Generator to be able to implement it, but I think we can take
>it as a given that we are going to preserve that data.)
>
>The pieces that are shared between the Parser and the Message are really
>about the Message:  how are the sub-objects represented?  How are the
>structured headers represented?  So we could consider that the Parser
>is a *consumer* of those pieces of policy, but that they are defined on
>the Message, not on the Parser.
>
>What this means is that the policy controlling each of the major
>components (parser, message, generator) are in principle independent.
[...]
>Re-thinking it now, though, I think there are actually two distinct
>components here: the I/O policy(s), and the Message construction policy.
[...]
>So, I think the "policy framework" is actually two things:  the
>header/mime-types registry, and the Parser/Generator policies.  Let's have
>'policy' refer to only the I/O policy, and call the other the email
>class registry.

+1

This makes a lot of sense, and I'm glad you've been thinking about this more
deeply than I have since we last bandied it about.  At the time, I thought a
single policy hierarchy would probably be fine, but you've laid out a good
argument for keeping them separate, and in fact not even calling the latter a
'policy'.  Here's another distinction:

Policy objects should be composable.  This would allow for a standard library
of policies that could be mixed and matched for specific applications, and
might even include some higher level policies like 'CGI' or 'NNTP'.  E.g. my
applications might combine a standard 'don't-check-rfc-2047' policy with a
'use-only-CRNL' and 'die-on-defect'.

I wonder too, how sophisticated policy objects really need to be.  Are they
just bags of attributes with some defaults, properties for access, maybe some
validation, and composability?

As for the registry, I don't think you need anything near that.  You just need
to say "when you see this mime-type, create an object using this callable".
Multiple registrations might be useful, but I don't think composability is.

>The real meat of email6, then, is the header/mime-types registry, and
>the changes in the API of the resulting Message objects.  The parser
>currently accepts a _factory argument that specifies the object to be used
>in creating the Message.   I propose that we deprecate this argument,
>but that any code using it gets the old behavior of the parser (using
>_factory to create the class for any new sub-objects).  Then we introduce
>a new argument, 'factory'.  This new argument would expect a callable
>that takes a mime-type as its argument, and returns an appropriate class.
>The parser would be re-written so that it could use this factory, and
>the backward compatibility case would be trivial to implement.

+1.  The underscore name in _factory is a historical wart that's not needed
any more.  I'm not even sure it makes much sense any more in Message
subclasses.  It *does* still make sense in e.g. add_header() where there's a
potential name collision between the arguments and the **params.  We should
evaluate these more carefully given today's API and clean this up if possible
(modulo all b/c considerations).

>In theory the classes returned by the registry/factory are arbitrary,
>but in practice we will need to define the minimal API that they
>should provide.  By specifying the API separately from the concrete
>implementation in email6, we will allow third parties to write classes
>that can play well with programs expecting to operate on email6 Messages.
>This will allow, for example, an MUA to provide custom classes to enhance
>presentation, while still allowing the message to be submitted to smtplib
>for transmission.

+1

>I guess I'm proposing, then, that there be an API version definition,
>with two values as of Python3.3: email5 API, and email6 API.  We'll
>figure out how we name and interrogate these formally later.
>
>The Header registry in this vision is accessed through the Message class.
>I have various thoughts about how this will work, but I'm going to leave
>those for later, since this email is already long enough.  I also have
>some additional thoughts about backward compatibility, but it is going
>to require some experimentation to see if they are realistic.

Cool.  Really great stuff David.

-Barry
signature.asc (application/pgp-signature, 836 B)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)

iQIcBAEBCAAGBQJNbqyhAAoJEBJutWOnSwa/B6QQAKsnHf0cNha8QdKC13hpwHQc
Ey33J791sNVRYfjJf115s4DkGVv88u/qEwjcIi2u5lvSzMRRDFlYY3qwOotCTgkX
W1c6cEUW5hpJJLE6Oap8jwxfBfNU+QKLco5Q5r7L4OURlJk4Zn6J0fHmTXBtmRd8
cuhM9MM+P6PGJDCDoU5K78AfjS29EE7Z5Et835DWGk8rFXxQXDUVuvPisanRi5Tl
ar1FLWG21D+YXl6lv2XRE0nPql4cOhu5+1UoWsoEYK44HeGVdUv8XFzvOGNKjgpI
GCZkMtyESk5cJIsHELML0W5L1l29CYO4GF6/biZdr0mrOPkf3yPsCO/tDB842P6D
U/3QBdulJFHgCorMsbKpa5i++alA/kwgr0JQRm1xPuv7eo5Kk/XcDiP0/whAB6bO
98uod1TBULaLadvE2/203QbukoL0y2Gox0cpT+M9SCg/p/UpbDbsf8hbWpMafzTl
AexfZr8vvtyHoN+lggDgdRJ6iKS8y9nne8E3LJ+CfQ2qYy68ILvCHwnCx9+9NLhj
ds2S/QjrAOu+OSOiZWQ+D5s/K8cW6nMjk+lBnNwalpMjaCoHikYFL8M0X7fbLTp8
vjIzjmo4NF4fIBpExamthg4i8pFWd6jOHHe0dQqXX85Lrqlrxt3vNlNIgByTYyXD
coVppKONHJSpoMso07mS
=+5g7
-----END PGP SIGNATURE-----