J. Alexander Treuman [Mon, 29 Nov 2010 01:36:36 +0000 (20:36 -0500)]
mpd.py: updating _connect_tcp() with new socket code
_connect_tcp() is largely based on Python's socket.create_connection().
Previously, this code contained two bugs related to raising exceptions.
The first bug was introduced by my clumsy attempt to update the code to use
the new preferred method of raising exceptions (the same mistake was made
in the Python 3 port of the socket module). Instead of raising
socket.error with the value of the original exception, socket.error was
raised with the original exception as the value of the new exception, thus
nesting an exception within an exception. Python 3.1.3 fixed this by
simply re-raising the original exception.
The second bug is hit when getaddrinfo() returns an empty list. A
socket.error is raised with a single string as its argument, instead of a
2-tuple as required by its parent class, IOError. This bug continues to
persist in Python 3.1.3 as well as the latest svn tree.
This commit updates _connect_tcp() to be a nearly identical copy of the
Python 3.1.3 version of socket.create_connection(), except that
ConnectionError is raised when getaddrinfo() returns an empty list.
J. Alexander Treuman [Thu, 15 Jul 2010 21:52:54 +0000 (17:52 -0400)]
mpd.py: clear command list if an exception is raised
This fixes a very longstanding bug where an MPD command error would raise
an exception, but not clear the command list. This would prevent further
commands from being executed until the command list was completed, which
was impossible since the MPD command error broke out of the command list
on the server side.
J. Alexander Treuman [Thu, 15 Jul 2010 21:49:53 +0000 (17:49 -0400)]
mpd.py: unset iterating flag if an exception is raised
This fixes a bug where an MPD command error would raise an exception, but
leave the iterating flag set, preventing further commands from being
executed.
J. Alexander Treuman [Thu, 15 Jul 2010 21:12:53 +0000 (17:12 -0400)]
mpd.py: check if iterating before fetching response
If an iterator is currently in progress, all functions which fetch a
response (such as <cmd>() and fetch_<cmd>()) 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.
J. Alexander Treuman [Thu, 15 Jul 2010 17:52:40 +0000 (13:52 -0400)]
mpd.py: adding fileno() to export socket FD
This allows access to the socket FD for polling if it can be written
to/read from. This is useful with, for example, the idle command. Simply
call send_idle(), poll the socket FD with select/poll/etc to check if it's
ready for reading, and if it is, call fetch_idle() to see what changed.
Note that select et al. call fileno() on any objects you pass to them, so
you can simply pass the MPDClient instance itself to these functions
instead of the FD returned by fileno().
J. Alexander Treuman [Thu, 15 Jul 2010 17:19:57 +0000 (13:19 -0400)]
mpd.py: adding support for asynchronous commands
send_<cmd>/fetch_<cmd> may now be used to send/fetch the command <cmd>.
fetch_<cmd> may be called multiple times to queue up various commands, but
they must be fetched in the same order they were sent. This functionality
cannot be mixed with command lists.
J. Alexander Treuman [Sun, 7 Jun 2009 19:39:38 +0000 (15:39 -0400)]
preliminary unix socket support
If the host passed to connect() starts with a "/", then a connection
attempt is made to the unix socket at the specified path. The port
argument is currently still required, but will be ignored. Attempting to
connect to a unix socket on Windows will raise an AttributeError (because
socket.AF_UNIX isn't defined), however this will later be changed.
J. Alexander Treuman [Mon, 1 Jun 2009 22:16:54 +0000 (18:16 -0400)]
adding idle and noidle commands
Note that these commands aren't very usable in their current form. idle()
blocks while waiting for events, and will thus hang if none are received.
Calling noidle() from another thread will cause idle() to return, but
python-mpd isn't considered re-entrant, so sharing instances between
threads isn't recommended.
J. Alexander Treuman [Thu, 3 Apr 2008 04:23:36 +0000 (00:23 -0400)]
mpd.py: catch all exceptions raised by _hello()
I normally consider it bad form to catch all exceptions, since it can
result in lost KeyboardInterrupts. But in this case we re-raise the
exception after cleaning up, so it's ok.
While _hello() itself only raises socket.error or an MPDError subclass, a
KeyboardInterrupt would previously go uncaught. Since the connection was
never cleaned up, it could be left in an unusable state. So just
disconnect on all exceptions instead.
J. Alexander Treuman [Sun, 23 Mar 2008 20:47:06 +0000 (16:47 -0400)]
mpd.py: loop over addresses returned by getaddrinfo to connect to
This allows us to support IPv6 and multi-homed hostnames. getaddrinfo is
called with the same flags as libmpdclient uses, making address resolution
consistent between the two.
J. Alexander Treuman [Sun, 23 Mar 2008 19:50:48 +0000 (15:50 -0400)]
mpd.py: raise ConnectionError when trying to use an unconnected socket
ConnectionError will now be raised when trying to read from/write to a
socket before calling connect() or after calling disconnect(). In the past
it would try to complete the operation on the unconnected socket, resulting
in a socket.error exception.
J. Alexander Treuman [Sat, 1 Mar 2008 20:03:47 +0000 (15:03 -0500)]
mpd.py: making _getitem return None if no item is returned
update and addid should normally always return a single item, so previously
an exception was raised if we got nothing. However, when used in a
command_list, only the *last* call to update will return an item. So
return None instead of raising an exception if we get nothing.
J. Alexander Treuman [Mon, 25 Feb 2008 00:43:53 +0000 (19:43 -0500)]
remove argument checking/parsing TODO item
mpd already does a much better job of validating arguments than we ever
could, so no point in us doing it too. Parsing arguments is also rather
pointless, as all arguments are coerced to strings before escaping anyway.