# 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,
        )
        """
        with self._lock:
            self._send(buf)
            return self._receive(required=True)

    def batch_start(self):
        """
        Starts a new batch transmission.

        When called, this method starts a new batch transmission. All
        subsequent calls to :meth:`send` will append data to the batch buffer
        instead of actually sending the data.

        To terminate the batch transmission, call :meth:`batch_send` or
        :meth:`batch_forget`. If a batch has already been started, a
        :exc:`~picraft.exc.BatchStarted` exception is raised.

        .. note::

            This method can be used as a context manager (:keyword:`with`)
            which will cause a batch to be started, and implicitly terminated
            with :meth:`batch_send` or :meth:`batch_forget` depending on
            whether an exception is raised within the enclosed block.
        """
        try:
            self._local.batch
        except AttributeError:
            self._local.batch = []
            return self
        else:

# 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,
        )

        """
        with self._lock:
            self._send(buf)
            return self._receive(required=True)

    def batch_start(self):
        """
        Starts a new batch transmission.

        When called, this method starts a new batch transmission. All
        subsequent calls to :meth:`send` will append data to the batch buffer
        instead of actually sending the data.

        To terminate the batch transmission, call :meth:`batch_send` or
        :meth:`batch_forget`. If a batch has already been started, a
        :exc:`~picraft.exc.BatchStarted` exception is raised.

        .. note::

            This method can be used as a context manager (:keyword:`with`)
            which will cause a batch to be started, and implicitly terminated
            with :meth:`batch_send` or :meth:`batch_forget` depending on
            whether an exception is raised within the enclosed block.
        """
        try:
            self._local.batch
        except AttributeError:
            self._local.batch = []
            return self
        else:

            raise BatchStarted('batch already started')