On Fri, 2006-03-10 at 11:25 -0600, Ian Bicking wrote:
> I'm not really making any actionable proposal here, so maybe this is 
> off-topic; if so, sorry.
> 
> Back during the defaultdict discussion I proposed a multidict object 
> (http://mail.python.org/pipermail/python-dev/2006-February/061264.html) 
> -- right now I need to implement one to represent web form submissions. 
>   It would also be ordered in that case.

FWIW, the email package's Message class implements something similar in
its mapping API, to represent message headers.  I'm not saying that it's
a good general approach to the problem, but I do think the way we solved
it works well for Messages.  The implementation is also probably not
very good for general purposes, since it can involve linear searches of
lists, but for Messages, which don't typically have that many headers, I
think it's fine.

Messages keep track of the order in which the headers are added, and you
may have multiple values for each header.  If you delete a header and
re-add it, it gets added to the end.  So iterating over the headers
gives you each header in order, including duplicates.  __getitem__()
however will return only one of those headers; which exactly you get is
technically undefined.  get() has the same semantics.

There's a new get_all() method that takes a key and returns a list of
all the values for that key (header).  __delitem__() removes all
matching keys.

> * Does __getitem__ return a list of all matching keys (never a KeyError, 
> though possibly returning []), or does it return the first matching key?

See above -- it returns one matching key, but the spec doesn't specify
which one (see the implementation for the obvious answer ;).  One other
semantic difference with Messages is that __getitem__() on a missing
header returns None -- it does not raise a KeyError.  Practicality beats
purity.

> * Either way, I assume there will be another method, like getfirst or 
> getall, that will present the other choice.  What would it be named? 
> Should it have a default?

In Message, it's called get_all() and it does take an optional default,
just like get().

> * Should there be a method to get a single value, that implicitly 
> asserts that there is only one matching key?

Message doesn't have this.

> * Should the default for .get() be None, or something else?

Message.get() defaults to None.

> * Does __setitem__ overwrite any or all values with matching keys?

Message's __setitem__() appends the header (there's a separate
add_header() method that takes a bunch of arguments specific to email
headers) but it does not overwrite any existing header.  The idiom used
to replace a header is usually:

del msg['some-header']
msg['Some-Header'] = 'Wizzy Mailerified'

Oh yeah, keys are case-preserving but case-insensitive because in email
messages 'Some-Header: Foo' is the same as 'some-header: Foo', but we
want to be as idempotent as possible.

> * If so, there should be another method like .add(key, value) which does 
> not overwrite.  Or, if __setitem__ does not overwrite, then there should 
> be a method that does.

Message.replace_header() preserves header order, and it replaces the
value for the first header found.

> * Does __delitem__ raise a KeyError if the key is not found?

For Message, the answer is "no".

> * Does .keys() return all unique keys, or all keys in order (meaning a 
> key may show up more than once in the list)?

Message.keys() returns them in order.  Likewise .values() and .items().

> I really could go either way on all of these questions, though I think 
> there's constraints -- answer one of the questions and another becomes 
> obvious.  But you can answer them in whatever order you want.

Cool, thanks!  For simplicity, I've answered them in the order they were
asked, just like Message would. :)

-Barry

Attachment: signature.asc
Description: This is a digitally signed message part

_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to