
commit c350257b05455509ab99c9019747e63553a668d5 Author: Damian Johnson <atagar@torproject.org> Date: Tue Jun 5 08:25:48 2012 -0700 Converting stem.socket to reStructuredText --- docs/index.rst | 5 ++ stem/control.py | 2 + stem/socket.py | 209 +++++++++++++++++++++++++------------------------------ 3 files changed, 101 insertions(+), 115 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index 2cf68fd..c3cd4d9 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -18,6 +18,11 @@ Connecting and authenticating to a Tor process. Provides the :class:`stem.control.Controller` class which, as the name implies, is used for talking with and controlling a Tor instance. As a user this is the primary class that you'll need. +:mod:`stem.socket` +------------------ + +Base classes for communicating with a tor control socket. + :mod:`stem.process` ------------------- diff --git a/stem/control.py b/stem/control.py index 7b56194..dbad4da 100644 --- a/stem/control.py +++ b/stem/control.py @@ -5,6 +5,8 @@ Controllers are a wrapper around a ControlSocket, retaining many of its methods (connect, close, is_alive, etc) in addition to providing its own for interacting at a higher level. +**Module Overview:** + :: from_port - Provides a Controller based on a port connection. diff --git a/stem/socket.py b/stem/socket.py index 68cc7e4..2a9e737 100644 --- a/stem/socket.py +++ b/stem/socket.py @@ -1,31 +1,35 @@ """ Supports message based communication with sockets speaking the tor control protocol. This lets users send messages as basic strings and receive responses -as instances of the ControlMessage class. +as instances of the :class:`stem.response.ControlMessage` class. -ControlSocket - Socket wrapper that speaks the tor control protocol. - |- ControlPort - Control connection via a port. - | |- get_address - provides the ip address of our socket - | +- get_port - provides the port of our socket - | - |- ControlSocketFile - Control connection via a local file socket. - | +- get_socket_path - provides the path of the socket we connect to - | - |- send - sends a message to the socket - |- recv - receives a ControlMessage from the socket - |- is_alive - reports if the socket is known to be closed - |- connect - connects a new socket - |- close - shuts down the socket - +- __enter__ / __exit__ - manages socket connection +**Module Overview:** -send_message - Writes a message to a control socket. -recv_message - Reads a ControlMessage from a control socket. -send_formatting - Performs the formatting expected from sent messages. +:: -ControllerError - Base exception raised when using the controller. - |- ProtocolError - Malformed socket data. - +- SocketError - Communication with the socket failed. - +- SocketClosed - Socket has been shut down. + ControlSocket - Socket wrapper that speaks the tor control protocol. + |- ControlPort - Control connection via a port. + | |- get_address - provides the ip address of our socket + | +- get_port - provides the port of our socket + | + |- ControlSocketFile - Control connection via a local file socket. + | +- get_socket_path - provides the path of the socket we connect to + | + |- send - sends a message to the socket + |- recv - receives a ControlMessage from the socket + |- is_alive - reports if the socket is known to be closed + |- connect - connects a new socket + |- close - shuts down the socket + +- __enter__ / __exit__ - manages socket connection + + send_message - Writes a message to a control socket. + recv_message - Reads a ControlMessage from a control socket. + send_formatting - Performs the formatting expected from sent messages. + + ControllerError - Base exception raised when using the controller. + |- ProtocolError - Malformed socket data. + +- SocketError - Communication with the socket failed. + +- SocketClosed - Socket has been shut down. """ from __future__ import absolute_import @@ -37,18 +41,6 @@ import stem.response import stem.util.enum import stem.util.log as log -class ControllerError(Exception): - "Base error for controller communication issues." - -class ProtocolError(ControllerError): - "Malformed content from the control socket." - -class SocketError(ControllerError): - "Error arose while communicating with the control socket." - -class SocketClosed(SocketError): - "Control socket was closed before completing the message." - class ControlSocket: """ Wrapper for a socket connection that speaks the Tor control protocol. To the @@ -56,7 +48,7 @@ class ControlSocket: receiving complete messages. All methods are thread safe. Callers should not instantiate this class directly, but rather use subclasses - which are expected to implement the _make_socket method. + which are expected to implement the ``_make_socket()`` method. """ def __init__(self): @@ -73,16 +65,14 @@ class ControlSocket: def send(self, message, raw = False): """ Formats and sends a message to the control socket. For more information see - the stem.socket.send_message function. + the :func:`stem.socket.send_message` function. - Arguments: - message (str) - message to be formatted and sent to the socket - raw (bool) - leaves the message formatting untouched, passing it to - the socket as-is + :param str message: message to be formatted and sent to the socket + :param bool raw: leaves the message formatting untouched, passing it to the socket as-is - Raises: - stem.socket.SocketError if a problem arises in using the socket - stem.socket.SocketClosed if the socket is known to be shut down + :raises: + * :class:`stem.socket.SocketError` if a problem arises in using the socket + * :class:`stem.socket.SocketClosed` if the socket is known to be shut down """ with self._send_lock: @@ -98,15 +88,13 @@ class ControlSocket: def recv(self): """ Receives a message from the control socket, blocking until we've received - one. For more information see the stem.socket.recv_message function. + one. For more information see the :func:`stem.socket.recv_message` function. - Returns: - stem.response.ControlMessage for the message received + :returns: :class:`stem.response.ControlMessage` for the message received - Raises: - stem.socket.ProtocolError the content from the socket is malformed - stem.socket.SocketClosed if the socket closes before we receive a - complete message + :raises: + * :class:`stem.socket.ProtocolError` the content from the socket is malformed + * :class:`stem.socket.SocketClosed` if the socket closes before we receive a complete message """ with self._recv_lock: @@ -146,15 +134,14 @@ class ControlSocket: until we either use it or have explicitily shut it down. In practice a socket derived from a port knows about its disconnection - after a failed recv() call. Socket file derived connections know after - either a send() or recv(). + after a failed ``recv()`` call. Socket file derived connections know after + either a ``send()`` or ``recv()``. This means that to have reliable detection for when we're disconnected you need to continually pull from the socket (which is part of what the - BaseController does). + :class:`stem.control.BaseController` does). - Returns: - bool that's True if we're known to be shut down and False otherwise + :returns: bool that's True if we're known to be shut down and False otherwise """ return self._is_alive @@ -164,8 +151,7 @@ class ControlSocket: Connects to a new socket, closing our previous one if we're already attached. - Raises: - stem.socket.SocketError if unable to make a socket + :raises: :class:`stem.socket.SocketError` if unable to make a socket """ with self._send_lock: @@ -233,9 +219,7 @@ class ControlSocket: because it's used to lock connect() / close(), and by extension our is_alive() state changes. - Returns: - threading.RLock that governs sending messages to our socket and state - changes + :returns: threading.RLock that governs sending messages to our socket and state changes """ return self._send_lock @@ -264,12 +248,11 @@ class ControlSocket: """ Constructs and connects new socket. This is implemented by subclasses. - Returns: - socket.socket for our configuration + :returns: socket.socket for our configuration - Raises: - stem.socket.SocketError if unable to make a socket - NotImplementedError if not implemented by a subclass + :raises: + * :class:`stem.socket.SocketError` if unable to make a socket + * NotImplementedError if not implemented by a subclass """ raise NotImplementedError("Unsupported Operation: this should be implemented by the ControlSocket subclass") @@ -284,15 +267,11 @@ class ControlPort(ControlSocket): """ ControlPort constructor. - Arguments: - control_addr (str) - ip address of the controller - control_port (int) - port number of the controller - connect (bool) - connects to the socket if True, leaves it - unconnected otherwise + :param str control_addr: ip address of the controller + :param int control_port: port number of the controller + :param bool connect: connects to the socket if True, leaves it unconnected otherwise - Raises: - stem.socket.SocketError if connect is True and we're unable to establish - a connection + :raises: :class:`stem.socket.SocketError` if connect is True and we're unable to establish a connection """ ControlSocket.__init__(self) @@ -305,8 +284,7 @@ class ControlPort(ControlSocket): """ Provides the ip address our socket connects to. - Returns: - str with the ip address of our socket + :returns: str with the ip address of our socket """ return self._control_addr @@ -315,8 +293,7 @@ class ControlPort(ControlSocket): """ Provides the port our socket connects to. - Returns: - int with the port of our socket + :returns: int with the port of our socket """ return self._control_port @@ -339,14 +316,10 @@ class ControlSocketFile(ControlSocket): """ ControlSocketFile constructor. - Arguments: - socket_path (str) - path where the control socket is located - connect (bool) - connects to the socket if True, leaves it - unconnected otherwise + :param str socket_path: path where the control socket is located + :param bool connect: connects to the socket if True, leaves it unconnected otherwise - Raises: - stem.socket.SocketError if connect is True and we're unable to establish - a connection + :raises: :class:`stem.socket.SocketError` if connect is True and we're unable to establish a connection """ ControlSocket.__init__(self) @@ -358,8 +331,7 @@ class ControlSocketFile(ControlSocket): """ Provides the path our socket connects to. - Returns: - str with the path for our control socket + :returns: str with the path for our control socket """ return self._socket_path @@ -380,25 +352,26 @@ def send_message(control_file, message, raw = False): line at the end). If the message doesn't contain a newline then it's sent as... - <message>\r\n + :: + + <message>\\r\\n + + and if it does contain newlines then it's split on ``\\n`` and sent as... - and if it does contain newlines then it's split on \n and sent as... + :: - +<line 1>\r\n - <line 2>\r\n - <line 3>\r\n - .\r\n + +<line 1>\\r\\n + <line 2>\\r\\n + <line 3>\\r\\n + .\\r\\n - Arguments: - control_file (file) - file derived from the control socket (see the - socket's makefile() method for more information) - message (str) - message to be sent on the control socket - raw (bool) - leaves the message formatting untouched, passing it - to the socket as-is + :param file control_file: file derived from the control socket (see the socket's makefile() method for more information) + :param str message: message to be sent on the control socket + :param bool raw: leaves the message formatting untouched, passing it to the socket as-is - Raises: - stem.socket.SocketError if a problem arises in using the socket - stem.socket.SocketClosed if the socket is known to be shut down + :raises: + * :class:`stem.socket.SocketError` if a problem arises in using the socket + * :class:`stem.socket.SocketClosed` if the socket is known to be shut down """ if not raw: message = send_formatting(message) @@ -432,17 +405,13 @@ def recv_message(control_file): Pulls from a control socket until we either have a complete message or encounter a problem. - Arguments: - control_file (file) - file derived from the control socket (see the - socket's makefile() method for more information) + :param file control_file: file derived from the control socket (see the socket's makefile() method for more information) - Returns: - stem.response.ControlMessage read from the socket + :returns: :class:`stem.response.ControlMessage` read from the socket - Raises: - stem.socket.ProtocolError the content from the socket is malformed - stem.socket.SocketClosed if the socket closes before we receive a complete - message + :raises: + * :class:`stem.socket.ProtocolError` the content from the socket is malformed + * :class:`stem.socket.SocketClosed` if the socket closes before we receive a complete message """ parsed_content, raw_content = [], "" @@ -547,13 +516,11 @@ def recv_message(control_file): def send_formatting(message): """ Performs the formatting expected from sent control messages. For more - information see the stem.socket.send_message function. + information see the :func:`stem.socket.send_message` function. - Arguments: - message (str) - message to be formatted + :param str message: message to be formatted - Returns: - str of the message wrapped by the formatting expected from controllers + :returns: str of the message wrapped by the formatting expected from controllers """ # From control-spec section 2.2... @@ -573,3 +540,15 @@ def send_formatting(message): else: return message + "\r\n" +class ControllerError(Exception): + "Base error for controller communication issues." + +class ProtocolError(ControllerError): + "Malformed content from the control socket." + +class SocketError(ControllerError): + "Error arose while communicating with the control socket." + +class SocketClosed(SocketError): + "Control socket was closed before completing the message." +