Years later, but for anyone landing here from Google, I ran into a similar (or identical) issue to the OP.
TL;DR: search by X-GM-LABELS
instead of using imap.select(label)
The concise way to remove a label (as pointed out by Changneng) is:
imap.store(item, '-X-GM-LABELS', label)
However, since Gmail treats labels and folders somewhat interchangeably, but doesn't include the label on the copy of the message in a label's folder, the above won't work if you fetched the message using:
imap.select(label)
ok, data = imap.search(None, "ALL")
...
imap.fetch(item, "(RFC822)")
imap.store(item, '-X-GM-LABELS', label) # <-- Effectively a no-op
Using -X-GM-LABELS
to remove the label won't work in that case, since the label isn't actually attached to the copy placed in that folder. Instead, you'll have to look up the copy of the email that's in the inbox (or presumably any other folder), and remove it from that id. For most intents and purposes, this method of loading messages should serve as a replacement for selecting the label's folder:
imap.select('inbox')
ok, data = imap.search(None, 'X-GM-LABELS', label)
...
imap.fetch(item, "RFC822")
imap.store(item, '-X-GM-LABELS', label) # <-- Will now remove the label!
The copy in the inbox folder will have all custom labels attached, and removing the label from that id (item
) will remove the label, and remove the message from the label's folder in one shot.
Also, just a note, the above code will fail if your label has a space in it, in that case it needs to be wrapped in quotes, e.g. replace label
with f'"{label}"'
.