# Path: aredis/exceptions.py
# class ConnectionError(RedisError):
#     pass
# 
# class TimeoutError(RedisError):
#     pass
# 
# class RedisError(Exception):
#     pass
# 
# class ExecAbortError(ResponseError):
#     pass
# 
# class BusyLoadingError(ConnectionError):
#     pass
# 
# class NoScriptError(ResponseError):
#     pass
# 
# class ReadOnlyError(ResponseError):
#     pass
# 
# class ResponseError(RedisError):
#     pass
# 
# class InvalidResponse(RedisError):
#     pass
# 
# class AskError(ResponseError):
#     """
#     src node: MIGRATING to dst node
#         get > ASK error
#         ask dst node > ASKING command
#     dst node: IMPORTING from src node
#         asking command only affects next command
#         any op will be allowed after asking command
#     """
# 
#     def __init__(self, resp):
#         """should only redirect to master node"""
#         self.args = (resp,)
#         self.message = resp
#         slot_id, new_node = resp.split(' ')
#         host, port = new_node.rsplit(':', 1)
#         self.slot_id = int(slot_id)
#         self.node_addr = self.host, self.port = host, int(port)
# 
# class MovedError(AskError):
#     pass
# 
# class TryAgainError(ResponseError):
# 
#     def __init__(self, *args, **kwargs):
#         pass
# 
# class ClusterDownError(ClusterError, ResponseError):
# 
#     def __init__(self, resp):
#         self.args = (resp,)
#         self.message = resp
# 
# class ClusterCrossSlotError(ResponseError):
#     message = "Keys in request don't hash to the same slot"
# 
# Path: aredis/utils.py
# def b(x):
#     return x.encode('latin-1') if not isinstance(x, bytes) else x
# 
# def nativestr(x):
#     return x if isinstance(x, str) else x.decode('utf-8', 'replace')
# 
# LOOP_DEPRECATED = sys.version_info >= (3, 8)


import asyncio
import inspect
import os
import socket
import ssl
import sys
import time
import warnings
import aredis.compat
    import hiredis
from io import BytesIO
from aredis.exceptions import (ConnectionError, TimeoutError,
                               RedisError, ExecAbortError,
                               BusyLoadingError, NoScriptError,
                               ReadOnlyError, ResponseError,
                               InvalidResponse, AskError,
                               MovedError, TryAgainError,
                               ClusterDownError, ClusterCrossSlotError)
from aredis.utils import b, nativestr, LOOP_DEPRECATED
        if self._stream is not None:
            self._stream = None
        self._reader = None
        self._next_response = False

    async def read_response(self):
        if not self._stream:
            raise ConnectionError("Socket closed on remote end")

        # _next_response might be cached from a can_read() call
        if self._next_response is not False:
            response = self._next_response
            self._next_response = False
            return response

        response = self._reader.gets()
        while response is False:
            try:
                buffer = await self._stream.read(self._read_size)
            # CancelledError will be caught by client so that command won't be retried again
            # For more detailed discussion please see https://github.com/NoneGG/aredis/issues/56
            except aredis.compat.CancelledError:
                raise
            except Exception:
                e = sys.exc_info()[1]
                raise ConnectionError("Error {} while reading from stream: {}".format(type(e), e.args))
            if not buffer:
                raise ConnectionError("Socket closed on remote end")
            self._reader.feed(buffer)
            response = self._reader.gets()

# Path: aredis/exceptions.py
# class ConnectionError(RedisError):
#     pass
# 
# class TimeoutError(RedisError):
#     pass
# 
# class RedisError(Exception):
#     pass
# 
# class ExecAbortError(ResponseError):
#     pass
# 
# class BusyLoadingError(ConnectionError):
#     pass
# 
# class NoScriptError(ResponseError):
#     pass
# 
# class ReadOnlyError(ResponseError):
#     pass
# 
# class ResponseError(RedisError):
#     pass
# 
# class InvalidResponse(RedisError):
#     pass
# 
# class AskError(ResponseError):
#     """
#     src node: MIGRATING to dst node
#         get > ASK error
#         ask dst node > ASKING command
#     dst node: IMPORTING from src node
#         asking command only affects next command
#         any op will be allowed after asking command
#     """
# 
#     def __init__(self, resp):
#         """should only redirect to master node"""
#         self.args = (resp,)
#         self.message = resp
#         slot_id, new_node = resp.split(' ')
#         host, port = new_node.rsplit(':', 1)
#         self.slot_id = int(slot_id)
#         self.node_addr = self.host, self.port = host, int(port)
# 
# class MovedError(AskError):
#     pass
# 
# class TryAgainError(ResponseError):
# 
#     def __init__(self, *args, **kwargs):
#         pass
# 
# class ClusterDownError(ClusterError, ResponseError):
# 
#     def __init__(self, resp):
#         self.args = (resp,)
#         self.message = resp
# 
# class ClusterCrossSlotError(ResponseError):
#     message = "Keys in request don't hash to the same slot"
# 
# Path: aredis/utils.py
# def b(x):
#     return x.encode('latin-1') if not isinstance(x, bytes) else x
# 
# def nativestr(x):
#     return x if isinstance(x, str) else x.decode('utf-8', 'replace')
# 
# LOOP_DEPRECATED = sys.version_info >= (3, 8)


# Path: aredis/connection.py
import asyncio
import inspect
import os
import socket
import ssl
import sys
import time
import warnings
import aredis.compat
    import hiredis
from io import BytesIO
from aredis.exceptions import (ConnectionError, TimeoutError,
                               RedisError, ExecAbortError,
                               BusyLoadingError, NoScriptError,
                               ReadOnlyError, ResponseError,
                               InvalidResponse, AskError,
                               MovedError, TryAgainError,
                               ClusterDownError, ClusterCrossSlotError)
from aredis.utils import b, nativestr, LOOP_DEPRECATED

        if self._stream is not None:
            self._stream = None
        self._reader = None
        self._next_response = False

    async def read_response(self):
        if not self._stream:
            raise ConnectionError("Socket closed on remote end")

        # _next_response might be cached from a can_read() call
        if self._next_response is not False:
            response = self._next_response
            self._next_response = False
            return response

        response = self._reader.gets()
        while response is False:
            try:
                buffer = await self._stream.read(self._read_size)
            # CancelledError will be caught by client so that command won't be retried again
            # For more detailed discussion please see https://github.com/NoneGG/aredis/issues/56
            except aredis.compat.CancelledError:
                raise
            except Exception:
                e = sys.exc_info()[1]
                raise ConnectionError("Error {} while reading from stream: {}".format(type(e), e.args))
            if not buffer:
                raise ConnectionError("Socket closed on remote end")
            self._reader.feed(buffer)
            response = self._reader.gets()

        if isinstance(response, ResponseError):