# Path: picraft/exc.py
# class CommandError(ConnectionError):
#     "Exception raised when a network command fails"
# 
# class NoResponse(ConnectionError):
#     "Exception raised when a network command expects a response but gets none"
# 
# class BatchStarted(ConnectionError):
#     "Exception raised when a batch is started before a prior one is complete"
# 
# class BatchNotStarted(ConnectionError):
#     "Exception raised when a batch is terminated when none has been started"
# 
# class ConnectionClosed(ConnectionError):
#     "Exception raised when an operation is attempted against a closed connection"


import socket
import logging
import select
import threading
from .exc import (
        CommandError,
        NoResponse,
        BatchStarted,
        BatchNotStarted,
        ConnectionClosed,
        )
            if self._wfile:
                self._wfile.close()
                self._wfile = None
            if self._socket:
                self._socket.shutdown(socket.SHUT_RDWR)
                self._socket.close()
                self._socket = None

    def _readable(self, timeout):
        """
        Determines whether the socket is readable within the given timeout.
        """
        return bool(select.select([self._socket], [], [], timeout)[0])

    def _drain(self):
        """
        Drain all data from the readable end of the socket. This is typically
        used to ensure that any "Fail" messages are removed prior to executing
        something for which we expect a result.
        """
        while True:
            if not self._readable(0):
                break
            self._socket.recv(1500)

    def _send(self, buf):
        """
        Write *buf* (suitably encoded) to the socket.
        """
        if not self._socket:

# Path: picraft/exc.py
# class CommandError(ConnectionError):
#     "Exception raised when a network command fails"
# 
# class NoResponse(ConnectionError):
#     "Exception raised when a network command expects a response but gets none"
# 
# class BatchStarted(ConnectionError):
#     "Exception raised when a batch is started before a prior one is complete"
# 
# class BatchNotStarted(ConnectionError):
#     "Exception raised when a batch is terminated when none has been started"
# 
# class ConnectionClosed(ConnectionError):
#     "Exception raised when an operation is attempted against a closed connection"


# Path: picraft/connection.py
import socket
import logging
import select
import threading
from .exc import (
        CommandError,
        NoResponse,
        BatchStarted,
        BatchNotStarted,
        ConnectionClosed,
        )

            if self._wfile:
                self._wfile.close()
                self._wfile = None
            if self._socket:
                self._socket.shutdown(socket.SHUT_RDWR)
                self._socket.close()
                self._socket = None

    def _readable(self, timeout):
        """
        Determines whether the socket is readable within the given timeout.
        """
        return bool(select.select([self._socket], [], [], timeout)[0])

    def _drain(self):
        """
        Drain all data from the readable end of the socket. This is typically
        used to ensure that any "Fail" messages are removed prior to executing
        something for which we expect a result.
        """
        while True:
            if not self._readable(0):
                break
            self._socket.recv(1500)

    def _send(self, buf):
        """
        Write *buf* (suitably encoded) to the socket.
        """
        if not self._socket:

            raise ConnectionClosed('connection closed')