>>>>> "ES" == Ellen Spertus <[EMAIL PROTECTED]> writes:
ES> I've been making some modifications to Mailman to support ES> dynamic sublists (http://javamlm.mills.edu). I'm still rather ES> new with Python and have a question about modifying fields ES> (dictionary elements) of the msg data structure. It's important to remember that the Message class is not a dictionary, even though it supports dictionary-like syntax. Python is funny in that there is no concrete interface specification, so we tend to say something is "mapping-like" or "file-like" if it supports common methods of those built-in types, but those similes don't really mean anything. But they are amorphous because "file-like" might mean the object supports a write() method with the same signature as a file object's write(), but what does that say about a "file-like" thing's read() method, etc.? Nothing, actually. :) Mapping-like is even more information-free. Usually a mapping-like object supports __getitem__(), and keys(), but does it support items(), values(), setdefault(), etc.? Who knows? <wink> When in doubt, we have to be concrete about what API a class provides or expects, e.g. /this/ method, or /that/ signature. ES> Specifically, I added the following code to change the ES> message's "To" field at the end of CookHeaders.py: | 1 if msgdata.get('dlist'): | 2 threadID = msgdata['thread_id'] | 3 syslog('info', "threadID = %d", threadID) | 4 to_line = '%s-%d@%s' % (mlist.real_name.lower(), | threadID, | mlist.host_name) | 5 syslog('info', "to_line = %s", to_line) | 6 del msg['To'] | 7 msg['To'] = to_line | 8 syslog('info', "Set msg['To'] to '%s'", msg['To']) ES> This correctly changes the "To" field of the message from ES> etest-new@hostname to etest-<threadID>@hostname, as shown by ES> the log: Mar 18 13:29:55 2002 (4600) threadID = 19 Mar 18 ES> 13:29:55 2002 (4600) to_line = [EMAIL PROTECTED] Mar ES> 18 13:29:55 2002 (4600) Set msg['To'] to ES> '[EMAIL PROTECTED]' ES> Similarly, the resulting email message that is sent has the ES> new 'To' field. ES> The problem is I don't see why line 6 above is necessary. Here's where the Message class has purposefully different semantics than a dictionary. Specifically, because email messages can have more than one of some kinds of headers, the Message class supports this as well. Therefore __setitem__() -- which is what "msg['to']" maps to -- does not delete existing To: headers. However, I didn't want __getitem__() -- aka msg['to'] -- to return anything but a string, so I decided that in the face of multiple headers, __getitem__() would return "one of them". Which one it returns is purposefully left undetermined. That's why Message.get_all() exists, so that you can get all the To: headers the message might have had. That's also why you must call del first -- aka __delitem__() -- if you want to overwrite all the To: headers. This is all spelled out in the module documentation: http://www.python.org/doc/current/lib/module-email.Message.html Aside: one of the reasons why I want this behavior is because I'd like the Message class (or a derived class possibly) to eventually enforce RFC 2822 rules on the number of specific headers a message can have. E.g. it can have many Received: headers, but only one Reply-To: header (although the latter allows for multiple addresses... go figure). I hope that helps, -Barry _______________________________________________ Mailman-Developers mailing list [EMAIL PROTECTED] http://mail.python.org/mailman/listinfo/mailman-developers