don' reconnect for each if progressprogress(ix+ len(msgnums)server dele(msgnumfinallychanges msgnumsreload server quit(def deletemessagessafely(selfmsgnumssynchheadersprogress=none)""delete multiple msgs off serverbut use top fetches to check for match on each msg' header part before deletingassumes the email server supports the top interface of popelse raises topnotsupported client may call deletemessagesuse if the mail server might change the inbox since the email index was last fetchedthereby changing pop relative message numbersthis can happen if email is deleted in different clientsome isps may also move mail from inbox to the undeliverable box in response to failed downloadsynchheaders must be list of already loaded mail hdrs textcorresponding to selected msgnums (requires state)raises exception if any out of synch with the email serverinbox is locked until quitso it should not change between top check and actual deletesynch check must occur herenot in callermay be enough to call checksyncherror+deletemessagesbut check each msg here in case deletes and inserts in middle of inbox""if not self srvrhastopraise topnotsupported('safe delete cancelled'self trace('deleting mails safely'errmsg 'message % out of synch with server \nerrmsg +'delete terminated at this message \nerrmsg +'mail client may require restart or reload server self connect(locks inbox till quit trydon' reconnect for each (msgcountmsgbytesserver stat(inbox size on server for (ixmsgnumin enumerate(msgnums)if progressprogress(ix+ len(msgnums)if msgnum msgcountmsgs deleted raise deletesyncherror(errmsg msgnumresphdrlinesrespsz server top(msgnum hdrs only hdrlines self decodefulltext(hdrlinesmsghdrs '\njoin(hdrlinesif not self headersmatch(msghdrssynchheaders[msgnum- ])raise deletesyncherror(errmsg msgnumelseserver dele(msgnumsafe to delete this msg finallychanges msgnumsreload server quit(unlock inbox on way out def checksyncherror(selfsynchheaders)""check to see if already loaded hdrs text in synchheaders the mailtools utility package