# Path: aredis/connection.py
# class ClusterConnection(Connection):
#     "Manages TCP communication to and from a Redis server"
#     description = "ClusterConnection<host={host},port={port}>"
# 
#     def __init__(self, *args, **kwargs):
#         self.readonly = kwargs.pop('readonly', False)
#         super(ClusterConnection, self).__init__(*args, **kwargs)
# 
#     async def on_connect(self):
#         """
#         Initialize the connection, authenticate and select a database and send READONLY if it is
#         set during object initialization.
#         """
#         if self.db:
#             warnings.warn('SELECT DB is not allowed in cluster mode')
#             self.db = ''
#         await super(ClusterConnection, self).on_connect()
#         if self.readonly:
#             await self.send_command('READONLY')
#             if nativestr(await self.read_response()) != 'OK':
#                 raise ConnectionError('READONLY command failed')
# 
# Path: aredis/exceptions.py
# class LockError(RedisError, ValueError):
#     """Errors acquiring or releasing a lock"""
#     # NOTE: For backwards compatability, this class derives from ValueError.
#     # This was originally chosen to behave like threading.Lock.
#     pass
# 
# class WatchError(RedisError):
#     pass
# 
# Path: aredis/utils.py
# def b(x):
#     return x.encode('latin-1') if not isinstance(x, bytes) else x
# 
# class dummy:
#     """
#     Instances of this class can be used as an attribute container.
#     """
# 
#     def __init__(self):
#         self.token = None
# 
#     def set(self, value):
#         self.token = value
# 
#     def get(self):
#         return self.token


import asyncio
import time as mod_time
import uuid
import warnings
import contextvars
from aredis.connection import ClusterConnection
from aredis.exceptions import LockError, WatchError
from aredis.utils import b, dummy
        self.timeout = timeout
        self.sleep = sleep
        self.blocking = blocking
        self.blocking_timeout = blocking_timeout
        self.thread_local = bool(thread_local)
        self.local = contextvars.ContextVar('token', default=None) if self.thread_local else dummy()
        if self.timeout and self.sleep > self.timeout:
            raise LockError("'sleep' must be less than 'timeout'")

    async def __aenter__(self):
        # force blocking, as otherwise the user would have to check whether
        # the lock was actually acquired or not.
        await self.acquire(blocking=True)
        return self

    async def __aexit__(self, exc_type, exc_value, traceback):
        await self.release()

    async def acquire(self, blocking=None, blocking_timeout=None):
        """
        Use Redis to hold a shared, distributed lock named ``name``.
        Returns True once the lock is acquired.

        If ``blocking`` is False, always return immediately. If the lock
        was acquired, return True, otherwise return False.

        ``blocking_timeout`` specifies the maximum number of seconds to
        wait trying to acquire the lock.
        """
        sleep = self.sleep

# Path: aredis/connection.py
# class ClusterConnection(Connection):
#     "Manages TCP communication to and from a Redis server"
#     description = "ClusterConnection<host={host},port={port}>"
# 
#     def __init__(self, *args, **kwargs):
#         self.readonly = kwargs.pop('readonly', False)
#         super(ClusterConnection, self).__init__(*args, **kwargs)
# 
#     async def on_connect(self):
#         """
#         Initialize the connection, authenticate and select a database and send READONLY if it is
#         set during object initialization.
#         """
#         if self.db:
#             warnings.warn('SELECT DB is not allowed in cluster mode')
#             self.db = ''
#         await super(ClusterConnection, self).on_connect()
#         if self.readonly:
#             await self.send_command('READONLY')
#             if nativestr(await self.read_response()) != 'OK':
#                 raise ConnectionError('READONLY command failed')
# 
# Path: aredis/exceptions.py
# class LockError(RedisError, ValueError):
#     """Errors acquiring or releasing a lock"""
#     # NOTE: For backwards compatability, this class derives from ValueError.
#     # This was originally chosen to behave like threading.Lock.
#     pass
# 
# class WatchError(RedisError):
#     pass
# 
# Path: aredis/utils.py
# def b(x):
#     return x.encode('latin-1') if not isinstance(x, bytes) else x
# 
# class dummy:
#     """
#     Instances of this class can be used as an attribute container.
#     """
# 
#     def __init__(self):
#         self.token = None
# 
#     def set(self, value):
#         self.token = value
# 
#     def get(self):
#         return self.token


# Path: aredis/lock.py
import asyncio
import time as mod_time
import uuid
import warnings
import contextvars
from aredis.connection import ClusterConnection
from aredis.exceptions import LockError, WatchError
from aredis.utils import b, dummy

        self.timeout = timeout
        self.sleep = sleep
        self.blocking = blocking
        self.blocking_timeout = blocking_timeout
        self.thread_local = bool(thread_local)
        self.local = contextvars.ContextVar('token', default=None) if self.thread_local else dummy()
        if self.timeout and self.sleep > self.timeout:
            raise LockError("'sleep' must be less than 'timeout'")

    async def __aenter__(self):
        # force blocking, as otherwise the user would have to check whether
        # the lock was actually acquired or not.
        await self.acquire(blocking=True)
        return self

    async def __aexit__(self, exc_type, exc_value, traceback):
        await self.release()

    async def acquire(self, blocking=None, blocking_timeout=None):
        """
        Use Redis to hold a shared, distributed lock named ``name``.
        Returns True once the lock is acquired.

        If ``blocking`` is False, always return immediately. If the lock
        was acquired, return True, otherwise return False.

        ``blocking_timeout`` specifies the maximum number of seconds to
        wait trying to acquire the lock.
        """
        sleep = self.sleep

        token = b(uuid.uuid1().hex)