How to iterate through maildir messages in python 3?

Chris Green cl at isbd.net
Fri Jun 25 04:19:49 EDT 2021


Greg Ewing <greg.ewing at canterbury.ac.nz> wrote:
> On 25/06/21 7:06 am, Chris Green wrote:
> > In python 2 one can do:-
> > 
> >     for msg in maildir:
> >            print msg      # or whatever you want to do with the message
> > 
> > 
> > However in python 3 this produces "TypeError: string argument
> > expected, got 'bytes'".
> > 
> > How should one iterate over a maildir in python3?
> 
> You're already iterating over it just fine. Your problem is
> actually how to *print* a mail message.
> 
> The answer to this will depend on what your purpose is. If
> you just want a rough-and-ready idea of what the message
> contains, you could do this:
> 
>     print(repr(msg))
> 
> However, that won't work very well if the message doesn't
> consist of mostly text in an ASCII-compatible encoding.
> 
> If you want something better, Python comes with some standard
> library code for dealing with mail messages. Check out the
> 'email' module.
> 
The error comes from the line "for msg in maildir:", not the print.

Here's the full program where I'm encountering the error (yes, I
should have posted this first time around) :-

    #!/usr/bin/python3

    import mailbox
    import sys
    import email


    #    open the existing maildir and the target mbox file
    maildir = mailbox.Maildir(sys.argv [-2], email.message_from_file)
    mbox = mailbox.mbox(sys.argv[-1])


    #    lock the mbox
    mbox.lock()


    #    iterate over messages in the maildir and add to the mbox
    for msg in maildir:
        mbox.add(msg)


    #    close and unlock
    mbox.close()
    maildir.close()

(... and it's not my coding style, just copied)


Here's the error trace:-

    chris$ ./md.py houseSitting fred
    Traceback (most recent call last):
      File "/home/chris/tmp/./md.py", line 18, in <module>
        for msg in maildir:
      File "/usr/lib/python3.9/mailbox.py", line 110, in itervalues
        value = self[key]
      File "/usr/lib/python3.9/mailbox.py", line 77, in __getitem__
        return self._factory(file)
      File "/usr/lib/python3.9/email/__init__.py", line 54, in message_from_file
        return Parser(*args, **kws).parse(fp)
      File "/usr/lib/python3.9/email/parser.py", line 56, in parse
        feedparser.feed(data)
      File "/usr/lib/python3.9/email/feedparser.py", line 175, in feed
        self._input.push(data)
      File "/usr/lib/python3.9/email/feedparser.py", line 103, in push
        self._partial.write(data)
    TypeError: string argument expected, got 'bytes'
    chris$ 


Line 18 is the "for msg in maildir:".

Presumably the program worked as posted under python 2, all I have
done is to change the shebang line to use python 3 (I no longer have
python 2 on my system, otherwise I'd have used it as this is only a
quick and dirty conversion script to be used once).

-- 
Chris Green
·


More information about the Python-list mailing list