bump from imaplib2 v2.55 to v2.57

Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This commit is contained in:
Nicolas Sebrecht 2017-03-05 13:28:47 +01:00
parent fc079499e9
commit f9360ba2d7
1 changed files with 54 additions and 6 deletions

View File

@ -18,9 +18,9 @@ __all__ = ("IMAP4", "IMAP4_SSL", "IMAP4_stream",
"Internaldate2Time", "ParseFlags", "Time2Internaldate", "Internaldate2Time", "ParseFlags", "Time2Internaldate",
"Mon2num", "MonthNames", "InternalDate") "Mon2num", "MonthNames", "InternalDate")
__version__ = "2.55" __version__ = "2.57"
__release__ = "2" __release__ = "2"
__revision__ = "55" __revision__ = "57"
__credits__ = """ __credits__ = """
Authentication code contributed by Donn Cave <donn@u.washington.edu> June 1998. Authentication code contributed by Donn Cave <donn@u.washington.edu> June 1998.
String method conversion by ESR, February 2001. String method conversion by ESR, February 2001.
@ -109,6 +109,7 @@ Commands = {
'CREATE': ((AUTH, SELECTED), True), 'CREATE': ((AUTH, SELECTED), True),
'DELETE': ((AUTH, SELECTED), True), 'DELETE': ((AUTH, SELECTED), True),
'DELETEACL': ((AUTH, SELECTED), True), 'DELETEACL': ((AUTH, SELECTED), True),
'ENABLE': ((AUTH,), False),
'EXAMINE': ((AUTH, SELECTED), False), 'EXAMINE': ((AUTH, SELECTED), False),
'EXPUNGE': ((SELECTED,), True), 'EXPUNGE': ((SELECTED,), True),
'FETCH': ((SELECTED,), True), 'FETCH': ((SELECTED,), True),
@ -300,17 +301,18 @@ class IMAP4(object):
class readonly(abort): pass # Mailbox status changed to READ-ONLY class readonly(abort): pass # Mailbox status changed to READ-ONLY
# These must be encoded according to utf8 setting in _mode_xxx():
_literal = br'.*{(?P<size>\d+)}$'
_untagged_status = br'\* (?P<data>\d+) (?P<type>[A-Z-]+)( (?P<data2>.*))?'
continuation_cre = re.compile(r'\+( (?P<data>.*))?') continuation_cre = re.compile(r'\+( (?P<data>.*))?')
literal_cre = re.compile(r'.*{(?P<size>\d+)}$')
mapCRLF_cre = re.compile(r'\r\n|\r|\n') mapCRLF_cre = re.compile(r'\r\n|\r|\n')
# Need to quote "atom-specials" :- # Need to quote "atom-specials" :-
# "(" / ")" / "{" / SP / 0x00 - 0x1f / 0x7f / "%" / "*" / DQUOTE / "\" / "]" # "(" / ")" / "{" / SP / 0x00 - 0x1f / 0x7f / "%" / "*" / DQUOTE / "\" / "]"
# so match not the inverse set # so match not the inverse set
mustquote_cre = re.compile(r"[^!#$&'+,./0-9:;<=>?@A-Z\[^_`a-z|}~-]") mustquote_cre = re.compile(r"[^!#$&'+,./0-9:;<=>?@A-Z\[^_`a-z|}~-]")
response_code_cre = re.compile(r'\[(?P<type>[A-Z-]+)( (?P<data>[^\]]*))?\]') response_code_cre = re.compile(r'\[(?P<type>[A-Z-]+)( (?P<data>[^\]]*))?\]')
# sequence_set_cre = re.compile(r"^[0-9]+(:([0-9]+|\*))?(,[0-9]+(:([0-9]+|\*))?)*$")
untagged_response_cre = re.compile(r'\* (?P<type>[A-Z-]+)( (?P<data>.*))?') untagged_response_cre = re.compile(r'\* (?P<type>[A-Z-]+)( (?P<data>.*))?')
untagged_status_cre = re.compile(r'\* (?P<data>\d+) (?P<type>[A-Z-]+)( (?P<data2>.*))?')
def __init__(self, host=None, port=None, debug=None, debug_file=None, identifier=None, timeout=None, debug_buf_lvl=None): def __init__(self, host=None, port=None, debug=None, debug_file=None, identifier=None, timeout=None, debug_buf_lvl=None):
@ -342,6 +344,8 @@ class IMAP4(object):
+ self.tagpre + self.tagpre
+ r'\d+) (?P<type>[A-Z]+) (?P<data>.*)') + r'\d+) (?P<type>[A-Z]+) (?P<data>.*)')
self._mode_ascii() # Only option in py2
if __debug__: self._init_debug(debug, debug_file, debug_buf_lvl) if __debug__: self._init_debug(debug, debug_file, debug_buf_lvl)
self.resp_timeout = timeout # Timeout waiting for command response self.resp_timeout = timeout # Timeout waiting for command response
@ -428,6 +432,28 @@ class IMAP4(object):
raise AttributeError("Unknown IMAP4 command: '%s'" % attr) raise AttributeError("Unknown IMAP4 command: '%s'" % attr)
def _mode_ascii(self):
self.utf8_enabled = False
self._encoding = 'ascii'
if bytes != str:
self.literal_cre = re.compile(self._literal, re.ASCII)
self.untagged_status_cre = re.compile(self._untagged_status, re.ASCII)
else:
self.literal_cre = re.compile(self._literal)
self.untagged_status_cre = re.compile(self._untagged_status)
def _mode_utf8(self):
self.utf8_enabled = True
self._encoding = 'utf-8'
if bytes != str:
self.literal_cre = re.compile(self._literal)
self.untagged_status_cre = re.compile(self._untagged_status)
else:
self.literal_cre = re.compile(self._literal, re.UNICODE)
self.untagged_status_cre = re.compile(self._untagged_status, re.UNICODE)
# Overridable methods # Overridable methods
@ -676,7 +702,10 @@ class IMAP4(object):
date_time = Time2Internaldate(date_time) date_time = Time2Internaldate(date_time)
else: else:
date_time = None date_time = None
self.literal = self.mapCRLF_cre.sub(CRLF, message) literal = self.mapCRLF_cre.sub(CRLF, message)
if self.utf8_enabled:
literal = b'UTF8 (' + literal + b')'
self.literal = literal
try: try:
return self._simple_command(name, mailbox, flags, date_time, **kw) return self._simple_command(name, mailbox, flags, date_time, **kw)
finally: finally:
@ -774,6 +803,19 @@ class IMAP4(object):
return self._simple_command('DELETEACL', mailbox, who, **kw) return self._simple_command('DELETEACL', mailbox, who, **kw)
def enable(self, capability):
"""Send an RFC5161 enable string to the server.
(typ, [data]) = <intance>.enable(capability)
"""
if 'ENABLE' not in self.capabilities:
raise self.error("Server does not support ENABLE")
typ, data = self._simple_command('ENABLE', capability)
if typ == 'OK' and 'UTF8=ACCEPT' in capability.upper():
self._mode_utf8()
return typ, data
def examine(self, mailbox='INBOX', **kw): def examine(self, mailbox='INBOX', **kw):
"""(typ, [data]) = examine(mailbox='INBOX') """(typ, [data]) = examine(mailbox='INBOX')
Select a mailbox for READ-ONLY access. (Flushes all untagged responses.) Select a mailbox for READ-ONLY access. (Flushes all untagged responses.)
@ -1025,11 +1067,14 @@ class IMAP4(object):
def search(self, charset, *criteria, **kw): def search(self, charset, *criteria, **kw):
"""(typ, [data]) = search(charset, criterion, ...) """(typ, [data]) = search(charset, criterion, ...)
Search mailbox for matching messages. Search mailbox for matching messages.
If UTF8 is enabled, charset MUST be None.
'data' is space separated list of matching message numbers.""" 'data' is space separated list of matching message numbers."""
name = 'SEARCH' name = 'SEARCH'
kw['untagged_response'] = name kw['untagged_response'] = name
if charset: if charset:
if self.utf8_enabled:
raise self.error("Non-None charset not valid in UTF8 mode")
return self._simple_command(name, 'CHARSET', charset, *criteria, **kw) return self._simple_command(name, 'CHARSET', charset, *criteria, **kw)
return self._simple_command(name, *criteria, **kw) return self._simple_command(name, *criteria, **kw)
@ -1412,6 +1457,9 @@ class IMAP4(object):
if not ok: if not ok:
break break
if data == 'go ahead': # Apparently not uncommon broken IMAP4 server response to AUTHENTICATE command
data = ''
# Send literal # Send literal
if literator is not None: if literator is not None: