[Python-checkins] python/nondist/sandbox/mailbox libmailbox.tex, 1.13, 1.14 mailbox.py, 1.14, 1.15 test_mailbox.py, 1.9, 1.10

gregorykjohnson@users.sourceforge.net gregorykjohnson at users.sourceforge.net
Mon Aug 22 22:19:39 CEST 2005


Update of /cvsroot/python/python/nondist/sandbox/mailbox
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15538
Modified Files:
	libmailbox.tex mailbox.py test_mailbox.py 
Log Message:
* Fix various things detected by pychecker.
* Fix various things detected by testing on Windows.
* Tests pass on Windows, but there are still some line-ending issues.
Index: libmailbox.tex
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/mailbox/libmailbox.tex,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- libmailbox.tex	21 Aug 2005 19:02:47 -0000	1.13
+++ libmailbox.tex	22 Aug 2005 20:19:27 -0000	1.14
@@ -261,6 +261,19 @@
 nesting is indicated using \character{.} to delimit levels, e.g.,
 "Archived.2005.07".
 
+\begin{notice}
+The Maildir specification requires the use of a colon (\character{:}) in
+certain message file names. Some operating systems do not permit this character
+in file names, however. If you wish to use a Maildir-like format on such an
+operating system, you should specify another character to use instead. The
+exclamation point (\character{!}) is a popular choice. For example:
+\begin{verbatim}
+import mailbox
+mailbox.Maildir.colon = '!'
+\end{verbatim}
+The \member{colon} attribute may also be set on a per-instance basis.
+\end{notice}
+
 \class{Maildir} instances have all of the methods of \class{Mailbox} in
 addition to the following:
 
Index: mailbox.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/mailbox/mailbox.py,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- mailbox.py	21 Aug 2005 21:17:53 -0000	1.14
+++ mailbox.py	22 Aug 2005 20:19:28 -0000	1.15
@@ -7,7 +7,6 @@
 import calendar
 import socket
 import errno
-import stat
 import copy
 import email
 import email.Message
@@ -64,7 +63,7 @@
 
 def __getitem__(self, key):
 """Return the keyed message; raise KeyError if it doesn't exist."""
- if self._factory is None:
+ if not self._factory:
 return self.get_message(key)
 else:
 return self._factory(self.get_file(key))
@@ -175,7 +174,7 @@
 """Lock the mailbox."""
 raise NotImplementedError('Method must be implemented by subclass')
 
- def unlock(self, f=None):
+ def unlock(self):
 """Unlock the mailbox if it is locked."""
 raise NotImplementedError('Method must be implemented by subclass')
 
@@ -190,7 +189,8 @@
 generator.flatten(message)
 elif isinstance(message, str):
 if mangle_from_:
- message = message.replace('\nFrom ', '\n>From ')
+ message = message.replace(os.linesep + 'From ',
+ os.linesep + '>From ')
 target.write(message)
 elif hasattr(message, 'read'):
 if mangle_from_:
@@ -214,6 +214,8 @@
 class Maildir(Mailbox):
 """A qmail-style Maildir mailbox."""
 
+ colon = ':'
+
 def __init__(self, dirname, factory=rfc822.Message, create=True):
 """Initialize a Maildir instance."""
 Mailbox.__init__(self, dirname, factory, create)
@@ -236,13 +238,13 @@
 tmp_file.close()
 if isinstance(message, MaildirMessage):
 subdir = message.get_subdir()
- suffix = ':' + message.get_info()
- if suffix == ':':
+ suffix = self.colon + message.get_info()
+ if suffix == self.colon:
 suffix = ''
 else:
 subdir = 'new'
 suffix = ''
- uniq = os.path.basename(tmp_file.name).split(':')[0]
+ uniq = os.path.basename(tmp_file.name).split(self.colon)[0]
 dest = os.path.join(self._path, subdir, uniq + suffix)
 os.rename(tmp_file.name, dest)
 if isinstance(message, MaildirMessage):
@@ -261,7 +263,7 @@
 except KeyError:
 pass
 except OSError, e:
- if errno == errno.ENOENT:
+ if e.errno == errno.ENOENT:
 pass
 else:
 raise 
@@ -278,8 +280,8 @@
 # temp's subdir and suffix were defaults from add().
 dominant_subpath = old_subpath
 subdir = os.path.dirname(dominant_subpath)
- if ':' in dominant_subpath:
- suffix = ':' + dominant_subpath.split(':')[-1]
+ if self.colon in dominant_subpath:
+ suffix = self.colon + dominant_subpath.split(self.colon)[-1]
 else:
 suffix = ''
 self.discard(key)
@@ -292,21 +294,21 @@
 def get_message(self, key):
 """Return a Message representation or raise a KeyError."""
 subpath = self._lookup(key)
- f = file(os.path.join(self._path, subpath), 'r')
+ f = file(os.path.join(self._path, subpath), 'rb')
 try:
 msg = MaildirMessage(f)
 finally:
 f.close()
 subdir, name = os.path.split(subpath)
 msg.set_subdir(subdir)
- if ':' in name:
- msg.set_info(name.split(':')[-1])
+ if self.colon in name:
+ msg.set_info(name.split(self.colon)[-1])
 msg.set_date(os.path.getmtime(os.path.join(self._path, subpath)))
 return msg
 
 def get_string(self, key):
 """Return a string representation or raise a KeyError."""
- f = file(os.path.join(self._path, self._lookup(key)), 'r')
+ f = file(os.path.join(self._path, self._lookup(key)), 'rb')
 try:
 return f.read()
 finally:
@@ -314,7 +316,7 @@
 
 def get_file(self, key):
 """Return a file-like representation or raise a KeyError."""
- f = file(os.path.join(self._path, self._lookup(key)), 'r')
+ f = file(os.path.join(self._path, self._lookup(key)), 'rb')
 return _ProxyFile(f)
 
 def iterkeys(self):
@@ -413,14 +415,14 @@
 if ':' in hostname:
 hostname = hostname.replace(':', r'072円')
 uniq = "%s.M%sP%sQ%s.%s" % (int(now), int(now % 1 * 1e6), os.getpid(),
- self._count, hostname)
+ Maildir._count, hostname)
 path = os.path.join(self._path, 'tmp', uniq)
 try:
 os.stat(path)
 except OSError, e:
 if e.errno == errno.ENOENT:
- self._count += 1
- return file(path, 'w+')
+ Maildir._count += 1
+ return file(path, 'wb+')
 else:
 raise
 else:
@@ -432,7 +434,7 @@
 self._toc = {}
 for subdir in ('new', 'cur'):
 for entry in os.listdir(os.path.join(self._path, subdir)):
- uniq = entry.split(':')[0]
+ uniq = entry.split(self.colon)[0]
 self._toc[uniq] = os.path.join(subdir, entry)
 
 def _lookup(self, key):
@@ -451,12 +453,15 @@
 # This method is for backward compatibility only.
 def next(self):
 """Return the next message in a one-time iteration."""
- if not hasattr(self, '_onetime_iterator'):
- self._onetime_iterator = self.itervalues()
- try:
- return self._onetime_iterator.next()
- except StopIteration:
- return None
+ if not hasattr(self, '_onetime_keys'):
+ self._onetime_keys = self.iterkeys()
+ while True:
+ try:
+ return self[self._onetime_keys.next()]
+ except StopIteration:
+ return None
+ except KeyError:
+ continue
 
 
 class _singlefileMailbox(Mailbox):
@@ -466,15 +471,15 @@
 """Initialize a single-file mailbox."""
 Mailbox.__init__(self, path, factory, create)
 try:
- f = file(self._path, 'r+')
+ f = file(self._path, 'rb+')
 except IOError, e:
 if e.errno == errno.ENOENT:
 if create:
- f = file(self._path, 'w+')
+ f = file(self._path, 'wb+')
 else:
 raise NoSuchMailboxError(self._path)
 elif e.errno == errno.EACCES:
- f = file(self._path, 'r')
+ f = file(self._path, 'rb')
 else:
 raise
 self._file = f
@@ -525,7 +530,7 @@
 _lock_file(self._file)
 self._locked = True
 
- def unlock(self, f=None):
+ def unlock(self):
 """Unlock the mailbox if it is locked."""
 if self._locked:
 _unlock_file(self._file)
@@ -567,7 +572,7 @@
 os.rename(new_file.name, self._path)
 else:
 raise
- self._file = file(self._path, 'r+')
+ self._file = file(self._path, 'rb+')
 self._toc = new_toc
 self._pending = False
 if self._locked:
@@ -624,7 +629,7 @@
 self._file.seek(start)
 from_line = self._file.readline()
 msg = self._message_factory(self._file.read(stop - self._file.tell()))
- msg.set_from(from_line[5:-1])
+ msg.set_from(from_line[5:-len(os.linesep)])
 return msg
 
 def get_string(self, key, from_=False):
@@ -661,7 +666,7 @@
 if from_line is None:
 from_line = 'From MAILER-DAEMON %s' % time.asctime(time.gmtime())
 start = self._file.tell()
- self._file.write('%s%s' % (from_line, os.linesep))
+ self._file.write(from_line + os.linesep)
 self._dump_message(message, self._file, self._mangle_from_)
 stop = self._file.tell()
 return (start, stop)
@@ -710,11 +715,11 @@
 
 def _pre_message_hook(self, f):
 """Called before writing each message to file f."""
- f.write('001円001円001円001円\n')
+ f.write('001円001円001円001円' + os.linesep)
 
 def _post_message_hook(self, f):
 """Called after writing each message to file f."""
- f.write('\n001円001円001円001円\n')
+ f.write(os.linesep + '001円001円001円001円' + os.linesep)
 
 def _generate_toc(self):
 """Generate key-to-(start, stop) table of contents."""
@@ -785,7 +790,7 @@
 """Remove the keyed message; raise KeyError if it doesn't exist."""
 path = os.path.join(self._path, str(key))
 try:
- f = file(path, 'r+')
+ f = file(path, 'rb+')
 except IOError, e:
 if e.errno == errno.ENOENT:
 raise KeyError('No message with key: %s' % key)
@@ -807,7 +812,7 @@
 """Replace the keyed message; raise KeyError if it doesn't exist."""
 path = os.path.join(self._path, str(key))
 try:
- f = file(path, 'r+')
+ f = file(path, 'rb+')
 except IOError, e:
 if e.errno == errno.ENOENT:
 raise KeyError('No message with key: %s' % key)
@@ -831,9 +836,9 @@
 """Return a Message representation or raise a KeyError."""
 try:
 if self._locked:
- f = file(os.path.join(self._path, str(key)), 'r+')
+ f = file(os.path.join(self._path, str(key)), 'rb+')
 else:
- f = file(os.path.join(self._path, str(key)), 'r')
+ f = file(os.path.join(self._path, str(key)), 'rb')
 except IOError, e:
 if e.errno == errno.ENOENT:
 raise KeyError('No message with key: %s' % key)
@@ -858,9 +863,9 @@
 """Return a string representation or raise a KeyError."""
 try:
 if self._locked:
- f = file(os.path.join(self._path, str(key)), 'r+')
+ f = file(os.path.join(self._path, str(key)), 'rb+')
 else:
- f = file(os.path.join(self._path, str(key)), 'r')
+ f = file(os.path.join(self._path, str(key)), 'rb')
 except IOError, e:
 if e.errno == errno.ENOENT:
 raise KeyError('No message with key: %s' % key)
@@ -873,14 +878,14 @@
 return f.read()
 finally:
 if self._locked:
- _unlock_file()
+ _unlock_file(f)
 finally:
 f.close()
 
 def get_file(self, key):
 """Return a file-like representation or raise a KeyError."""
 try:
- f = file(os.path.join(self._path, str(key)), 'r')
+ f = file(os.path.join(self._path, str(key)), 'rb')
 except IOError, e:
 if e.errno == errno.ENOENT:
 raise KeyError('No message with key: %s' % key)
@@ -904,11 +909,11 @@
 def lock(self):
 """Lock the mailbox."""
 if not self._locked:
- self._file = file(os.path.join(self._path, '.mh_sequences'), 'r+')
+ self._file = file(os.path.join(self._path, '.mh_sequences'), 'rb+')
 _lock_file(self._file)
 self._locked = True
 
- def unlock(self, f=None):
+ def unlock(self):
 """Unlock the mailbox if it is locked."""
 if self._locked:
 _unlock_file(self._file)
@@ -956,7 +961,7 @@
 def get_sequences(self):
 """Return a name-to-key-list dictionary to define each sequence."""
 results = {}
- f = file(os.path.join(self._path, '.mh_sequences'), 'r')
+ f = file(os.path.join(self._path, '.mh_sequences'), 'rb')
 try:
 all_keys = set(self.keys())
 for line in f:
@@ -982,7 +987,7 @@
 
 def set_sequences(self, sequences):
 """Set sequences using the given name-to-key-list dictionary."""
- f = file(os.path.join(self._path, '.mh_sequences'), 'r+')
+ f = file(os.path.join(self._path, '.mh_sequences'), 'rb+')
 try:
 os.close(os.open(f.name, os.O_WRONLY | os.O_TRUNC))
 for name, keys in sequences.iteritems():
@@ -1003,7 +1008,7 @@
 f.write(' %s' % key)
 prev = key
 if completing:
- f.write('%s%s' % (prev, os.linesep))
+ f.write(str(prev) + os.linesep)
 else:
 f.write(os.linesep)
 finally:
@@ -1017,7 +1022,7 @@
 for key in self.iterkeys():
 if key - 1 != prev:
 changes.append((key, prev + 1))
- f = file(os.path.join(self._path, str(key)), 'r+')
+ f = file(os.path.join(self._path, str(key)), 'rb+')
 try:
 if self._locked:
 _lock_file(f)
@@ -1039,7 +1044,6 @@
 self._next_key = prev + 1
 if len(changes) == 0:
 return
- keys = self.keys()
 for name, key_list in sequences.items():
 for old, new in changes:
 if old in key_list:
@@ -1176,16 +1180,17 @@
 
 def _pre_mailbox_hook(self, f):
 """Called before writing the mailbox to file f."""
- f.write('BABYL OPTIONS:\nVersion: 5\nLabels:%s\n037円' %
- ','.join(self.get_labels()))
+ f.write('BABYL OPTIONS:%sVersion: 5%sLabels:%s%s037円' %
+ (os.linesep, os.linesep, ','.join(self.get_labels()),
+ os.linesep))
 
 def _pre_message_hook(self, f):
 """Called before writing each message to file f."""
- f.write('014円\n')
+ f.write('014円' + os.linesep)
 
 def _post_message_hook(self, f):
 """Called after writing each message to file f."""
- f.write('\n037円')
+ f.write(os.linesep + '037円')
 
 def _install_message(self, message):
 """Write message contents and return (start, stop)."""
@@ -1204,9 +1209,9 @@
 self._file.write(',,')
 for label in labels:
 self._file.write(' ' + label + ',')
- self._file.write('\n')
+ self._file.write(os.linesep)
 else:
- self._file.write('1,,\n')
+ self._file.write('1,,' + os.linesep)
 if isinstance(message, email.Message.Message):
 pseudofile = StringIO.StringIO()
 ps_generator = email.Generator.Generator(pseudofile, False, 0)
@@ -1242,7 +1247,7 @@
 self._file.write(message[:body_start])
 self._file.write(message[body_start:])
 else:
- self._file.write('*** EOOH ***%s%s' % (os.linesep, os.linesep))
+ self._file.write('*** EOOH ***' + os.linesep + os.linesep)
 self._file.write(message)
 elif hasattr(message, 'readline'):
 original_pos = message.tell()
@@ -1486,7 +1491,7 @@
 try:
 message.set_date(calendar.timegm(time.strptime(maybe_date,
 '%a %b %d %H:%M:%S %Y')))
- except ValueError, OverflowError:
+ except (ValueError, OverflowError):
 pass
 elif isinstance(message, _mboxMMDFMessage):
 message.set_flags(self.get_flags())
@@ -1807,7 +1812,7 @@
 pre_lock = _create_temporary(f.name + '.lock')
 pre_lock.close()
 except IOError, e:
- if e.errno == errno.EACCESS:
+ if e.errno == errno.EACCES:
 return # Without write access, just skip dotlocking.
 else:
 raise
@@ -1846,7 +1851,7 @@
 """Create a file if it doesn't exist and open for reading and writing."""
 fd = os.open(path, os.O_CREAT | os.O_EXCL | os.O_RDWR)
 try:
- return file(path, 'r+')
+ return file(path, 'rb+')
 finally:
 os.close(fd)
 
Index: test_mailbox.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/mailbox/test_mailbox.py,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- test_mailbox.py	21 Aug 2005 21:17:53 -0000	1.9
+++ test_mailbox.py	22 Aug 2005 20:19:28 -0000	1.10
@@ -49,7 +49,7 @@
 class TestMailbox(TestBase):
 
 _factory = None # Overridden by subclasses to reuse tests
- _template = 'From: foo%s%s' % (os.linesep, os.linesep) + '%s'
+ _template = 'From: foo' + os.linesep + os.linesep + '%s'
 
 def setUp(self):
 self._path = test_support.TESTFN
@@ -457,14 +457,19 @@
 
 _factory = lambda self, path, factory=None: mailbox.Maildir(path, factory)
 
+ def setUp(self):
+ TestMailbox.setUp(self)
+ if os.name == 'nt':
+ self._box.colon = '!'
+
 def test_add_MM(self):
 # Add a MaildirMessage instance
 msg = mailbox.MaildirMessage(self._template % 0)
 msg.set_subdir('cur')
 msg.set_info('foo')
 key = self._box.add(msg)
- self.assert_(os.path.exists(os.path.join(self._path, 'cur',
- "%s:foo" % key)))
+ self.assert_(os.path.exists(os.path.join(self._path, 'cur', '%s%sfoo' %
+ (key, self._box.colon))))
 
 def test_get_MM(self):
 # Get a MaildirMessage instance
@@ -504,10 +509,10 @@
 # Initialize a non-existent mailbox
 self.tearDown()
 self._box = mailbox.Maildir(self._path)
- self._check_basics(factory=rfc822.Message, perms=True)
+ self._check_basics(factory=rfc822.Message)
 self._delete_recursively(self._path)
 self._box = self._factory(self._path, factory=None)
- self._check_basics(perms=True)
+ self._check_basics()
 
 def test_initialize_existing(self):
 # Initialize an existing mailbox
@@ -519,7 +524,7 @@
 self._box = mailbox.Maildir(self._path, factory=None)
 self._check_basics()
 
- def _check_basics(self, factory=None, perms=False):
+ def _check_basics(self, factory=None):
 # (Used by test_open_new() and test_open_existing().)
 self.assertEqual(self._box._path, os.path.abspath(self._path))
 self.assertEqual(self._box._factory, factory)
@@ -527,9 +532,6 @@
 path = os.path.join(self._path, subdir)
 mode = os.stat(path)[stat.ST_MODE]
 self.assert_(stat.S_ISDIR(mode), "Not a directory: '%s'" % path)
- if perms:
- self.assert_(stat.S_IMODE(mode) ^ 0700 == 0,
- "Accessible by group or other: '%s'" % path)
 
 def test_list_folders(self):
 # List folders
@@ -668,20 +670,23 @@
 class _TestMboxMMDF(TestMailbox):
 
 def tearDown(self):
+ self._box.close()
 self._delete_recursively(self._path)
 for lock_remnant in glob.glob(self._path + '.*'):
 os.remove(lock_remnant)
 
 def test_add_from_string(self):
 # Add a string starting with 'From ' to the mailbox
- key = self._box.add('From foo at bar blah\nFrom: foo\n\n0')
+ key = self._box.add('From foo at bar blah%sFrom: foo%s%s0' %
+ (os.linesep, os.linesep, os.linesep))
 self.assert_(self._box[key].get_from() == 'foo at bar blah')
 self.assert_(self._box[key].get_payload() == '0')
 
 def test_add_mbox_or_mmdf_message(self):
 # Add an mboxMessage or MMDFMessage
 for class_ in (mailbox.mboxMessage, mailbox.MMDFMessage):
- msg = class_('From foo at bar blah\nFrom: foo\n\n0')
+ msg = class_('From foo at bar blah%sFrom: foo%s%s0' %
+ (os.linesep, os.linesep, os.linesep))
 key = self._box.add(msg)
 
 def test_open_close_open(self):
@@ -708,7 +713,7 @@
 self._box._file.seek(0)
 contents = self._box._file.read()
 self._box.close()
- self.assert_(contents == file(self._path, 'r').read())
+ self.assert_(contents == file(self._path, 'rb').read())
 self._box = self._factory(self._path)
 
 
@@ -821,6 +826,12 @@
 
 _factory = lambda self, path, factory=None: mailbox.Babyl(path, factory)
 
+ def tearDown(self):
+ self._box.close()
+ self._delete_recursively(self._path)
+ for lock_remnant in glob.glob(self._path + '.*'):
+ os.remove(lock_remnant)
+
 def test_labels(self):
 # Get labels from the mailbox
 self.assert_(self._box.get_labels() == [])
@@ -1414,12 +1425,12 @@
 proxy.seek(0)
 self.assert_(proxy.readlines() == ['foo' + os.linesep,
 'bar' + os.linesep,
- 'fred' + os.linesep, 'bob'])
+ 'fred' + os.linesep, 'bob'])
 proxy.seek(0)
 self.assert_(proxy.readlines(2) == ['foo' + os.linesep])
 proxy.seek(3 + len(os.linesep))
- self.assert_(proxy.readlines(5) == ['bar' + os.linesep,
- 'fred' + os.linesep])
+ self.assert_(proxy.readlines(4 + len(os.linesep)) ==
+ ['bar' + os.linesep, 'fred' + os.linesep])
 proxy.seek(3)
 self.assert_(proxy.readlines(1000) == [os.linesep, 'bar' + os.linesep,
 'fred' + os.linesep, 'bob'])
@@ -1458,7 +1469,7 @@
 
 def setUp(self):
 self._path = test_support.TESTFN
- self._file = file(self._path, 'w+')
+ self._file = file(self._path, 'wb+')
 
 def tearDown(self):
 self._file.close()
@@ -1507,7 +1518,7 @@
 
 def setUp(self):
 self._path = test_support.TESTFN
- self._file = file(self._path, 'w+')
+ self._file = file(self._path, 'wb+')
 
 def tearDown(self):
 self._file.close()
@@ -1546,7 +1557,7 @@
 def test_seek_and_tell(self):
 self._file.write('(((foo%sbar%s$$$' % (os.linesep, os.linesep))
 self._test_seek_and_tell(mailbox._PartialFile(self._file, 3,
- 8 + 3 * len(os.linesep)))
+ 9 + 2 * len(os.linesep)))
 
 def test_close(self):
 self._file.write('&foo%sbar%s^' % (os.linesep, os.linesep))


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /