classification
Title: email: msg.items() returns different values before and after msg.as_string()
Type: behavior Stage: needs patch
Components: Documentation Versions: Python 3.2, Python 3.1, Python 2.7, Python 2.6
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: r.david.murray Nosy List: barry, georg.brandl, jnelson, r.david.murray (4)
Priority: normal Keywords

Created on 2009-10-13 18:58 by jnelson, last changed 2009-10-21 01:04 by r.david.murray.

Messages (3)
msg93935 - (view) Author: Jon Nelson (jnelson) Date: 2009-10-13 18:58
import os
try:
  from email.mime.multipart import MIMEMultipart
except ImportError:
  from email.MIMEMultipart import MIMEMultipart

m = MIMEMultipart('form-data')

print m.items()
m.as_string()
print m.items()


print out:

[('Content-Type', 'multipart/form-data'), ('MIME-Version', '1.0')]
[('Content-Type', 'multipart/form-data;
boundary="===============0836597002796039051=="'), ('MIME-Version', '1.0')]

The latter is correct, the former is not - it is missing the boundary!
items() should behave the same regardless of whether or not as_string()
has been called.


Confirmed in 2.4 and 2.6
msg94264 - (view) Author: R. David Murray (r.david.murray) Date: 2009-10-20 02:44
The problem here is that when you are constructing a message the
boundary is calculated "as needed", and returning the list of items is
not one of the times when the boundary is needed.  I agree that it is
not good design that as_string can mutate the object it is called on;
however the alternative (throwing away the calculated boundary after
message Generation) means that stringifying the same message twice would
produce two strings that are not equal...which also seems like bad
design.  But perhaps that would be less bad design.

The underlying problem here is that the things being returned by items
are strings, when they should be Header objects.  That problem isn't
going to be resolved until the email package rewrite happens.
msg94304 - (view) Author: R. David Murray (r.david.murray) Date: 2009-10-20 22:46
Thinking about this further, it seems to me that it is in fact more
important that turning a message into a string produces the same result
no matter how many times it is called on the same (otherwise unmutated)
object than that it avoid mutating the object tree itself.  (This is
called idempotence and it is an important interface concept in certain
circumstances, and I think this is one of them).

The documentation should make the expectations clear, however.
History
Date User Action Args
2009-10-21 01:04:56r.david.murraysetassignee: georg.brandl -> r.david.murray
2009-10-20 22:46:55r.david.murraysetnosy: + georg.brandl
messages: + msg94304

assignee: georg.brandl
components: + Documentation, - Library (Lib)
stage: test needed -> needs patch
2009-10-20 02:44:46r.david.murraysetpriority: normal
versions: + Python 3.1, Python 2.7, Python 3.2, - Python 2.5, Python 2.4
nosy: + barry, r.david.murray

messages: + msg94264

stage: test needed
2009-10-13 18:58:05jnelsoncreate