Issue #20729: Restored the use of lazy iterkeys()/itervalues()/iteritems()

in the mailbox module.  This is partial rollback of changeset f340cb045bf9.
This commit is contained in:
Serhiy Storchaka 2014-08-13 09:35:21 +03:00
parent 4d58897fdb
commit cd3aacf525
3 changed files with 17 additions and 14 deletions

View File

@ -103,7 +103,7 @@ class Mailbox:
def itervalues(self): def itervalues(self):
"""Return an iterator over all messages.""" """Return an iterator over all messages."""
for key in self.keys(): for key in self.iterkeys():
try: try:
value = self[key] value = self[key]
except KeyError: except KeyError:
@ -119,7 +119,7 @@ class Mailbox:
def iteritems(self): def iteritems(self):
"""Return an iterator over (key, message) tuples.""" """Return an iterator over (key, message) tuples."""
for key in self.keys(): for key in self.iterkeys():
try: try:
value = self[key] value = self[key]
except KeyError: except KeyError:
@ -154,7 +154,7 @@ class Mailbox:
def popitem(self): def popitem(self):
"""Delete an arbitrary (key, message) pair and return it.""" """Delete an arbitrary (key, message) pair and return it."""
for key in self.keys(): for key in self.iterkeys():
return (key, self.pop(key)) # This is only run once. return (key, self.pop(key)) # This is only run once.
else: else:
raise KeyError('No messages in mailbox') raise KeyError('No messages in mailbox')
@ -162,7 +162,7 @@ class Mailbox:
def update(self, arg=None): def update(self, arg=None):
"""Change the messages that correspond to certain keys.""" """Change the messages that correspond to certain keys."""
if hasattr(arg, 'iteritems'): if hasattr(arg, 'iteritems'):
source = arg.items() source = arg.iteritems()
elif hasattr(arg, 'items'): elif hasattr(arg, 'items'):
source = arg.items() source = arg.items()
else: else:
@ -559,7 +559,7 @@ class Maildir(Mailbox):
def next(self): def next(self):
"""Return the next message in a one-time iteration.""" """Return the next message in a one-time iteration."""
if not hasattr(self, '_onetime_keys'): if not hasattr(self, '_onetime_keys'):
self._onetime_keys = iter(self.keys()) self._onetime_keys = self.iterkeys()
while True: while True:
try: try:
return self[next(self._onetime_keys)] return self[next(self._onetime_keys)]
@ -1078,7 +1078,7 @@ class MH(Mailbox):
def __len__(self): def __len__(self):
"""Return a count of messages in the mailbox.""" """Return a count of messages in the mailbox."""
return len(list(self.keys())) return len(list(self.iterkeys()))
def lock(self): def lock(self):
"""Lock the mailbox.""" """Lock the mailbox."""
@ -1192,7 +1192,7 @@ class MH(Mailbox):
sequences = self.get_sequences() sequences = self.get_sequences()
prev = 0 prev = 0
changes = [] changes = []
for key in self.keys(): for key in self.iterkeys():
if key - 1 != prev: if key - 1 != prev:
changes.append((key, prev + 1)) changes.append((key, prev + 1))
if hasattr(os, 'link'): if hasattr(os, 'link'):

View File

@ -300,7 +300,7 @@ class TestMailbox(TestBase):
def test_iterkeys(self): def test_iterkeys(self):
# Get keys using iterkeys() # Get keys using iterkeys()
self._check_iteration(self._box.keys, do_keys=True, do_values=False) self._check_iteration(self._box.iterkeys, do_keys=True, do_values=False)
def test_keys(self): def test_keys(self):
# Get keys using keys() # Get keys using keys()
@ -308,7 +308,7 @@ class TestMailbox(TestBase):
def test_itervalues(self): def test_itervalues(self):
# Get values using itervalues() # Get values using itervalues()
self._check_iteration(self._box.values, do_keys=False, self._check_iteration(self._box.itervalues, do_keys=False,
do_values=True) do_values=True)
def test_iter(self): def test_iter(self):
@ -322,7 +322,7 @@ class TestMailbox(TestBase):
def test_iteritems(self): def test_iteritems(self):
# Get keys and values using iteritems() # Get keys and values using iteritems()
self._check_iteration(self._box.items, do_keys=True, self._check_iteration(self._box.iteritems, do_keys=True,
do_values=True) do_values=True)
def test_items(self): def test_items(self):
@ -564,12 +564,12 @@ class TestMailboxSuperclass(TestBase, unittest.TestCase):
self.assertRaises(NotImplementedError, lambda: box.__delitem__('')) self.assertRaises(NotImplementedError, lambda: box.__delitem__(''))
self.assertRaises(NotImplementedError, lambda: box.discard('')) self.assertRaises(NotImplementedError, lambda: box.discard(''))
self.assertRaises(NotImplementedError, lambda: box.__setitem__('', '')) self.assertRaises(NotImplementedError, lambda: box.__setitem__('', ''))
self.assertRaises(NotImplementedError, lambda: box.iterkeys())
self.assertRaises(NotImplementedError, lambda: box.keys()) self.assertRaises(NotImplementedError, lambda: box.keys())
self.assertRaises(NotImplementedError, lambda: box.keys()) self.assertRaises(NotImplementedError, lambda: box.itervalues().__next__())
self.assertRaises(NotImplementedError, lambda: box.values().__next__())
self.assertRaises(NotImplementedError, lambda: box.__iter__().__next__()) self.assertRaises(NotImplementedError, lambda: box.__iter__().__next__())
self.assertRaises(NotImplementedError, lambda: box.values()) self.assertRaises(NotImplementedError, lambda: box.values())
self.assertRaises(NotImplementedError, lambda: box.items().next()) self.assertRaises(NotImplementedError, lambda: box.iteritems().__next__())
self.assertRaises(NotImplementedError, lambda: box.items()) self.assertRaises(NotImplementedError, lambda: box.items())
self.assertRaises(NotImplementedError, lambda: box.get('')) self.assertRaises(NotImplementedError, lambda: box.get(''))
self.assertRaises(NotImplementedError, lambda: box.__getitem__('')) self.assertRaises(NotImplementedError, lambda: box.__getitem__(''))
@ -1020,7 +1020,7 @@ class _TestMboxMMDF(_TestSingleFile):
mtime = os.path.getmtime(self._path) mtime = os.path.getmtime(self._path)
self._box = self._factory(self._path) self._box = self._factory(self._path)
self.assertEqual(len(self._box), 3) self.assertEqual(len(self._box), 3)
for key in self._box.keys(): for key in self._box.iterkeys():
self.assertIn(self._box.get_string(key), values) self.assertIn(self._box.get_string(key), values)
self._box.close() self._box.close()
self.assertEqual(mtime, os.path.getmtime(self._path)) self.assertEqual(mtime, os.path.getmtime(self._path))

View File

@ -27,6 +27,9 @@ Core and Builtins
Library Library
------- -------
- Issue #20729: Restored the use of lazy iterkeys()/itervalues()/iteritems()
in the mailbox module.
- Issue #21448: Changed FeedParser feed() to avoid O(N**2) behavior when - Issue #21448: Changed FeedParser feed() to avoid O(N**2) behavior when
parsing long line. Original patch by Raymond Hettinger. parsing long line. Original patch by Raymond Hettinger.