From: J. Alexander Treuman Date: Thu, 15 Jul 2010 21:12:53 +0000 (-0400) Subject: mpd.py: check if iterating before fetching response X-Git-Tag: v0.3.0~23 X-Git-Url: http://git.kaliko.me/?p=python-musicpd.git;a=commitdiff_plain;h=535e659098997d301a7176e45bfc806bbc5cedb4;ds=sidebyside mpd.py: check if iterating before fetching response If an iterator is currently in progress, all functions which fetch a response (such as () and fetch_()) will be disabled, as well as command lists. This makes iterators much more reliable by preventing code from reading a response while an iterator is trying to read another response. Previously this was allowed, and would corrupt the library state by providing false responses to both the iterator and the code trying to fetch a different response. --- diff --git a/mpd.py b/mpd.py index 32b51a1..8810fac 100644 --- a/mpd.py +++ b/mpd.py @@ -41,6 +41,9 @@ class CommandListError(MPDError): class PendingCommandError(MPDError): pass +class IteratingError(MPDError): + pass + class _NotConnected(object): def __getattr__(self, attr): @@ -159,6 +162,9 @@ class MPDClient(object): if self._command_list is not None: raise CommandListError("Cannot use fetch_%s in a command list" % command) + if self._iterating: + raise IteratingError("Cannot use fetch_%s while iterating" % + command) if not self._pending: raise PendingCommandError("No pending commands to fetch") if self._pending[0] != command: @@ -170,6 +176,8 @@ class MPDClient(object): return retval() def _execute(self, command, args): + if self._iterating: + raise IteratingError("Cannot execute %s while iterating" % command) if self._pending: raise PendingCommandError("Cannot execute %s with " "pending commands" % command) @@ -266,10 +274,16 @@ class MPDClient(object): self._command_list = None self._fetch_nothing() + def _iterator_wrapper(self, iterator): + self._iterating = True + for item in iterator: + yield item + self._iterating = False + def _wrap_iterator(self, iterator): if not self.iterate: return list(iterator) - return iterator + return self._iterator_wrapper(iterator) def _fetch_nothing(self): line = self._read_line() @@ -326,6 +340,7 @@ class MPDClient(object): def _reset(self): self.mpd_version = None + self._iterating = False self._pending = [] self._command_list = None self._sock = None @@ -392,6 +407,8 @@ class MPDClient(object): def command_list_ok_begin(self): if self._command_list is not None: raise CommandListError("Already in command list") + if self._iterating: + raise IteratingError("Cannot begin command list while iterating") if self._pending: raise PendingCommandError("Cannot begin command list " "with pending commands")