How to iterate through maildir messages in python 3?

Chris Green cl at isbd.net
Fri Jun 25 13:56:05 EDT 2021


Chris Angelico <rosuav at gmail.com> wrote:
> On Sat, Jun 26, 2021 at 12:28 AM Chris Green <cl at isbd.net> wrote:
> >
> > 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])
> >
> >     #    iterate over messages in the maildir and add to the mbox
> >     for msg in maildir:
> >         mbox.add(msg)
> >
> 
> Maildir says that the factory has to take a binary file object. It
> looks like email.message_from_file is expecting a text file object,
> but there's a very similar function message_from_binary_file that
> might be what you want.
> 
> Haven't tested it, but worth a try.
> 
Even simpler, just remove email.message_from_file! :-)

The following works fine:-


    #!/usr/bin/python3

    import mailbox
    import sys
    import email


    #    open the existing maildir and the target mbox file
    maildir = mailbox.Maildir(sys.argv [-2])
    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()


Thank you for pointing me in the right direction.


-- 
Chris Green
·


More information about the Python-list mailing list