Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 4658682

Browse files
committed
Subject: bug fixes for imaplib.py
From: Piers Lauder <[email protected]> To: Python List <[email protected]> Date: Mon, 18 May 1998 09:51:53 +1000 Following is a context diff for imaplib.py in the Python1.5.1 distribution. It fixes 2 bugs. One to do with argument quoting, and the other to do with caching of un-tagged responses. Apologies for its size.
1 parent 7beaad4 commit 4658682

1 file changed

Lines changed: 48 additions & 35 deletions

File tree

Lib/imaplib.py

Lines changed: 48 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,7 @@ def append(self, mailbox, flags, date_time, message):
172172
date_time = Time2Internaldate(date_time)
173173
else:
174174
date_time = None
175-
tag = self._command(name, mailbox, flags, date_time, message)
176-
return self._command_complete(name, tag)
175+
return self._simple_command(name, mailbox, flags, date_time, message)
177176

178177

179178
def authenticate(self, func):
@@ -314,6 +313,8 @@ def lsub(self, directory='""', pattern='*'):
314313
def recent(self):
315314
"""Prompt server for an update.
316315
316+
Flush all untagged responses.
317+
317318
(typ, [data]) = <instance>.recent()
318319
319320
'data' is None if no new messages,
@@ -323,6 +324,7 @@ def recent(self):
323324
typ, dat = self._untagged_response('OK', name)
324325
if dat[-1]:
325326
return typ, dat
327+
self.untagged_responses = {}
326328
typ, dat = self._simple_command('NOOP')
327329
return self._untagged_response(typ, name)
328330

@@ -338,9 +340,11 @@ def rename(self, oldmailbox, newmailbox):
338340
def response(self, code):
339341
"""Return data for response 'code' if received, or None.
340342
343+
Old value for response 'code' is cleared.
344+
341345
(code, [data]) = <instance>.response(code)
342346
"""
343-
return code, self.untagged_responses.get(code, [None])
347+
return self._untagged_response(code, code)
344348

345349

346350
def search(self, charset, criteria):
@@ -360,15 +364,14 @@ def search(self, charset, criteria):
360364
def select(self, mailbox='INBOX', readonly=None):
361365
"""Select a mailbox.
362366
367+
Flush all untagged responses.
368+
363369
(typ, [data]) = <instance>.select(mailbox='INBOX', readonly=None)
364370
365371
'data' is count of messages in mailbox ('EXISTS' response).
366372
"""
367373
# Mandated responses are ('FLAGS', 'EXISTS', 'RECENT', 'UIDVALIDITY')
368-
# Remove immediately interesting responses
369-
for r in ('EXISTS', 'READ-WRITE'):
370-
if self.untagged_responses.has_key(r):
371-
del self.untagged_responses[r]
374+
self.untagged_responses = {} # Flush old responses.
372375
if readonly:
373376
name = 'EXAMINE'
374377
else:
@@ -400,8 +403,7 @@ def store(self, message_set, command, flag_list):
400403
401404
(typ, [data]) = <instance>.store(message_set, command, flag_list)
402405
"""
403-
command = '%s %s' % (command, flag_list)
404-
typ, dat = self._simple_command('STORE', message_set, command)
406+
typ, dat = self._simple_command('STORE', message_set, command, flag_list)
405407
return self._untagged_response(typ, 'FETCH')
406408

407409

@@ -413,16 +415,16 @@ def subscribe(self, mailbox):
413415
return self._simple_command('SUBSCRIBE', mailbox)
414416

415417

416-
def uid(self, command, args):
417-
"""Execute "command args" with messages identified by UID,
418+
def uid(self, command, *args):
419+
"""Execute "command arg ..." with messages identified by UID,
418420
rather than message number.
419421
420-
(typ, [data]) = <instance>.uid(command, args)
422+
(typ, [data]) = <instance>.uid(command, arg1, arg2, ...)
421423
422424
Returns response appropriate to 'command'.
423425
"""
424426
name = 'UID'
425-
typ, dat = self._simple_command('UID', command, args)
427+
typ, dat = apply(self._simple_command, ('UID', command) + args)
426428
if command == 'SEARCH':
427429
name = 'SEARCH'
428430
else:
@@ -440,15 +442,15 @@ def unsubscribe(self, mailbox):
440442
return self._simple_command('UNSUBSCRIBE', mailbox)
441443

442444

443-
def xatom(self, name, arg1=None, arg2=None):
445+
def xatom(self, name, *args):
444446
"""Allow simple extension commands
445447
notified by server in CAPABILITY response.
446448
447-
(typ, [data]) = <instance>.xatom(name, arg1=None, arg2=None)
449+
(typ, [data]) = <instance>.xatom(name, arg, ...)
448450
"""
449451
if name[0] != 'X' or not name in self.capabilities:
450452
raise self.error('unknown extension command: %s' % name)
451-
return self._simple_command(name, arg1, arg2)
453+
return apply(self._simple_command, (name,) + args)
452454

453455

454456

@@ -475,7 +477,15 @@ def _command(self, name, dat1=None, dat2=None, dat3=None, literal=None):
475477
tag = self._new_tag()
476478
data = '%s %s' % (tag, name)
477479
for d in (dat1, dat2, dat3):
478-
if d is not None: data = '%s %s' % (data, d)
480+
if d is None: continue
481+
if type(d) is type(''):
482+
l = len(string.split(d))
483+
else:
484+
l = 1
485+
if l == 0 or l > 1 and (d[0],d[-1]) not in (('(',')'),('"','"')):
486+
data = '%s "%s"' % (data, d)
487+
else:
488+
data = '%s %s' % (data, d)
479489
if literal is not None:
480490
data = '%s {%s}' % (data, len(literal))
481491

@@ -529,11 +539,9 @@ def _get_response(self):
529539
# Read response and store.
530540
#
531541
# Returns None for continuation responses,
532-
# otherwise first response line received
542+
# otherwise first response line received.
533543

534-
# Protocol mandates all lines terminated by CRLF.
535-
536-
resp = self._get_line()[:-2]
544+
resp = self._get_line()
537545

538546
# Command completion response?
539547

@@ -584,7 +592,7 @@ def _get_response(self):
584592

585593
# Read trailer - possibly containing another literal
586594

587-
dat = self._get_line()[:-2]
595+
dat = self._get_line()
588596

589597
self._append_untagged(typ, dat)
590598

@@ -614,8 +622,9 @@ def _get_line(self):
614622

615623
# Protocol mandates all lines terminated by CRLF
616624

625+
line = line[:-2]
617626
if __debug__ and self.debug >= 4:
618-
print '\t< %s' % line[:-2]
627+
print '\t< %s' % line
619628
return line
620629

621630

@@ -638,16 +647,18 @@ def _new_tag(self):
638647
return tag
639648

640649

641-
def _simple_command(self, name, dat1=None, dat2=None):
650+
def _simple_command(self, name, *args):
642651

643-
return self._command_complete(name, self._command(name, dat1, dat2))
652+
return self._command_complete(name, apply(self._command, (name,) + args))
644653

645654

646655
def _untagged_response(self, typ, name):
647656

648657
if not self.untagged_responses.has_key(name):
649658
return typ, [None]
650659
data = self.untagged_responses[name]
660+
if __debug__ and self.debug >= 5:
661+
print '\tuntagged_responses[%s] => %.20s..' % (name, `data`)
651662
del self.untagged_responses[name]
652663
return typ, data
653664

@@ -755,25 +766,25 @@ def Time2Internaldate(date_time):
755766

756767
test_seq1 = (
757768
('login', (USER, PASSWD)),
758-
('create', ('/tmp/xxx',)),
759-
('rename', ('/tmp/xxx', '/tmp/yyy')),
760-
('CREATE', ('/tmp/yyz',)),
761-
('append', ('/tmp/yyz', None, None, 'From: [email protected]\n\ndata...')),
762-
('select', ('/tmp/yyz',)),
763-
('recent', ()),
769+
('create', ('/tmp/xxx 1',)),
770+
('rename', ('/tmp/xxx 1', '/tmp/yyy')),
771+
('CREATE', ('/tmp/yyz 2',)),
772+
('append', ('/tmp/yyz 2', None, None, 'From: [email protected]\n\ndata...')),
773+
('select', ('/tmp/yyz 2',)),
764774
('uid', ('SEARCH', 'ALL')),
765775
('fetch', ('1', '(INTERNALDATE RFC822)')),
766776
('store', ('1', 'FLAGS', '(\Deleted)')),
767777
('expunge', ()),
778+
('recent', ()),
768779
('close', ()),
769780
)
770781

771782
test_seq2 = (
772783
('select', ()),
773784
('response',('UIDVALIDITY',)),
774785
('uid', ('SEARCH', 'ALL')),
775-
('recent', ()),
776786
('response', ('EXISTS',)),
787+
('recent', ()),
777788
('logout', ()),
778789
)
779790

@@ -790,7 +801,9 @@ def run(cmd, args):
790801
run(cmd, args)
791802

792803
for ml in run('list', ('/tmp/', 'yy%')):
793-
path = string.split(ml)[-1]
804+
mo = re.match(r'.*"([^"]+)"$', ml)
805+
if mo: path = mo.group(1)
806+
else: path = string.split(ml)[-1]
794807
run('delete', (path,))
795808

796809
for cmd,args in test_seq2:
@@ -800,5 +813,5 @@ def run(cmd, args):
800813
continue
801814

802815
uid = string.split(dat[0])[-1]
803-
run('uid', ('FETCH',
804-
'%s (FLAGS INTERNALDATE RFC822.SIZE RFC822.HEADER RFC822)' % uid))
816+
run('uid', ('FETCH', '%s' % uid,
817+
'(FLAGS INTERNALDATE RFC822.SIZE RFC822.HEADER RFC822)'))

0 commit comments

Comments
 (0)