Why does it work ?

Steven Taschuk staschuk at telusplanet.net
Tue Jul 1 22:03:43 CEST 2003


Quoth Michel Combe:
> I'm trying to send a mail with an attached file. 
> I use the following code and *it works* but I don't understand why and I 
> hate that.
> 
> for filename in os.listdir(dir):
>     path = os.path.join(dir, filename)
>     if not os.path.isfile(path):
>         continue
>     ctype, encoding = mimetypes.guess_type(path)
>     if ctype is None or encoding is not None:
>         ctype = 'application/octet-stream'
>     maintype, subtype = ctype.split('/', 1)
>     if maintype == 'text':
>         fp = open(path)
>         msg = MIMEText(fp.read(), _subtype=subtype)
>         fp.close()
>     msg.add_header('Content-Disposition', 'attachment', filename=filename)
>     outer.attach(msg)

Note, btw, that this code does not set msg on all paths to its use
at the end of the for loop.  If the first file is not text/*, an
UnboundLocalError will be raised.  If a later file n is not
text/*, the file n-1 will be attached twice.

You probably want:

    if maintype == 'text':
        fp = open(path)
        try:
            msg = MIMEText(fp.read(), _subtype=subtype)
        finally:
            fp.close()
        msg.add_header('Content-Disposition', 'attachment', filename=filename)
        outer.attach(msg)

(I've also put the fp.close() in a finally block, where it
belongs.)

I also wonder about the 'encoding is not None' test.  But on to
your question:

> In the "dir" directory, I have 2 text files :
> - "texte.txt" which is the text I want inside the body of the message and 
> - "fichier.txt" which is the file I want attached.
> 
> Why is "texte.txt" the only file that I find in the body of the message. 
> Both files are text, so the MIMEText instruction shoud be executed for both 
> files, No ?
> Also add_header should be executed for both files resulting in 2 attached 
> files ?

You can find out for sure by, for example, adding print statements:

    if maintype == 'text':
        print >>sys.stderr, "%s is text" % path
        fp = open(path)
        msg = MIMEText(fp.read(), _subtype=subtype)
        fp.close()
    print >>sys.stderr, "attaching %s" % filename
    msg.add_header('Content-Disposition', 'attachment', filename=filename)

> Which instruction says what is included in the body and what is attached to 
> the mail ?

They're all attachments with the code as written.

-- 
Steven Taschuk                            staschuk at telusplanet.net
"Our analysis begins with two outrageous benchmarks."
  -- "Implementation strategies for continuations", Clinger et al.





More information about the Python-list mailing list