'''simple docstring'''






import logging
import os
import threading
import time


try:
    import warnings
except ImportError:
    SCREAMING_SNAKE_CASE_	   =			None

try:
    import msvcrt
except ImportError:
    SCREAMING_SNAKE_CASE_	   =			None

try:
    import fcntl
except ImportError:
    SCREAMING_SNAKE_CASE_	   =			None


# Backward compatibility
# ------------------------------------------------
try:
    TimeoutError
except NameError:
    SCREAMING_SNAKE_CASE_	   =			OSError


# Data
# ------------------------------------------------
SCREAMING_SNAKE_CASE_	   =			[
    'Timeout',
    'BaseFileLock',
    'WindowsFileLock',
    'UnixFileLock',
    'SoftFileLock',
    'FileLock',
]

SCREAMING_SNAKE_CASE_	   =			'3.0.12'


SCREAMING_SNAKE_CASE_	   =			None






def  UpperCamelCase__					(					)							->	List[Any]:

  '''simple docstring'''





  global _logger
  __UpperCAmelCase:					Union[str, Any]		= _logger or logging.getLogger(__name__     )
  return _logger




class    a (       __lowerCAmelCase				):



  """simple docstring"""







  def __init__(							self   ,    snake_case_					):

    '''simple docstring'''







    __UpperCAmelCase:					str		= lock_file
    return None







  def __str__(							self					):

    '''simple docstring'''







    __UpperCAmelCase:					str		= F'''The file lock \'{self.lock_file}\' could not be acquired.'''
    return temp




class    a :



  """simple docstring"""







  def __init__(							self   ,    snake_case_					):

    '''simple docstring'''







    __UpperCAmelCase:					Tuple		= lock
    return None







  def __enter__(							self					):

    '''simple docstring'''







    return self.lock







  def __exit__(							self   ,    snake_case_   ,    snake_case_   ,    snake_case_					):

    '''simple docstring'''







    self.lock.release()
    return None




class    a :



  """simple docstring"""







  def __init__(							self   ,    snake_case_   ,    snake_case_=-1   ,    snake_case_=None					):

    '''simple docstring'''







    __UpperCAmelCase:					Any		= max_filename_length if max_filename_length is not None else 255
    # Hash the filename if it's too long
    __UpperCAmelCase:					List[str]		= self.hash_filename_if_too_long(snake_case_   ,    snake_case_					)
    # The path to the lock file.
    __UpperCAmelCase:					Optional[int]		= lock_file

    # The file descriptor for the *_lock_file* as it is returned by the
    # os.open() function.
    # This file lock is only NOT None, if the object currently holds the
    # lock.
    __UpperCAmelCase:					str		= None

    # The default timeout value.
    __UpperCAmelCase:					List[str]		= timeout

    # We use this lock primarily for the lock counter.
    __UpperCAmelCase:					str		= threading.Lock()

    # The lock counter is used for implementing the nested locking
    # mechanism. Whenever the lock is acquired, the counter is increased and
    # the lock is only released, when this value is 0 again.
    __UpperCAmelCase:					str		= 0
    return None







  @property
  def    lowercase_  (							self					):

    '''simple docstring'''







    return self._lock_file







  @property
  def    lowercase_  (							self					):

    '''simple docstring'''







    return self._timeout







  @timeout.setter
  def    lowercase_  (							self   ,    snake_case_					):

    '''simple docstring'''







    __UpperCAmelCase:					Any		= float(snake_case_					)
    return None







  def    lowercase_  (							self					):

    '''simple docstring'''







    raise NotImplementedError()







  def    lowercase_  (							self					):

    '''simple docstring'''







    raise NotImplementedError()







  @property
  def    lowercase_  (							self					):

    '''simple docstring'''







    return self._lock_file_fd is not None







  def    lowercase_  (							self   ,    snake_case_=None   ,    snake_case_=0.0_5					):

    '''simple docstring'''







    if timeout is None:
      __UpperCAmelCase:					Union[str, Any]		= self.timeout

    # Increment the number right at the beginning.
    # We can still undo it, if something fails.
    with self._thread_lock:
      self._lock_counter += 1

    __UpperCAmelCase:					Union[str, Any]		= id(self					)
    __UpperCAmelCase:					Any		= self._lock_file
    __UpperCAmelCase:					Tuple		= time.time()
    try:
      while True:
        with self._thread_lock:
          if not self.is_locked:
            logger().debug(F'''Attempting to acquire lock {lock_id} on {lock_filename}'''					)
            self._acquire()

        if self.is_locked:
          logger().debug(F'''Lock {lock_id} acquired on {lock_filename}'''					)
          break
        elif timeout >= 0 and time.time() - start_time > timeout:
          logger().debug(F'''Timeout on acquiring lock {lock_id} on {lock_filename}'''					)
          raise Timeout(self._lock_file					)
        else:
          logger().debug(
              F'''Lock {lock_id} not acquired on {lock_filename}, waiting {poll_intervall} seconds ...'''					)
          time.sleep(snake_case_					)
    except:  # noqa
      # Something did go wrong, so decrement the counter.
      with self._thread_lock:
        __UpperCAmelCase:					str		= max(0   ,    self._lock_counter - 1					)

      raise
    return _Acquire_ReturnProxy(lock=self					)







  def    lowercase_  (							self   ,    snake_case_=False					):

    '''simple docstring'''







    with self._thread_lock:
      if self.is_locked:
        self._lock_counter -= 1

        if self._lock_counter == 0 or force:
          __UpperCAmelCase:					Tuple		= id(self					)
          __UpperCAmelCase:					Tuple		= self._lock_file

          logger().debug(F'''Attempting to release lock {lock_id} on {lock_filename}'''					)
          self._release()
          __UpperCAmelCase:					List[str]		= 0
          logger().debug(F'''Lock {lock_id} released on {lock_filename}'''					)

    return None







  def __enter__(							self					):

    '''simple docstring'''







    self.acquire()
    return self







  def __exit__(							self   ,    snake_case_   ,    snake_case_   ,    snake_case_					):

    '''simple docstring'''







    self.release()
    return None







  def __del__(							self					):

    '''simple docstring'''







    self.release(force=snake_case_					)
    return None







  def    lowercase_  (							self   ,    snake_case_   ,    snake_case_					):

    '''simple docstring'''







    __UpperCAmelCase:					Optional[Any]		= os.path.basename(snake_case_					)
    if len(snake_case_					) > max_length and max_length > 0:
      __UpperCAmelCase:					List[Any]		= os.path.dirname(snake_case_					)
      __UpperCAmelCase:					Tuple		= str(hash(snake_case_					)					)
      __UpperCAmelCase:					int		= filename[: max_length - len(snake_case_					) - 8] + """...""" + hashed_filename + """.lock"""
      return os.path.join(snake_case_   ,    snake_case_					)
    else:
      return path




class    a (       __lowerCAmelCase				):



  """simple docstring"""







  def __init__(							self   ,    snake_case_   ,    snake_case_=-1   ,    snake_case_=None					):

    '''simple docstring'''







    from .file_utils import relative_to_absolute_path

    super().__init__(snake_case_   ,    timeout=snake_case_   ,    max_filename_length=snake_case_					)
    __UpperCAmelCase:					int		= """\\\\?\\""" + relative_to_absolute_path(self.lock_file					)







  def    lowercase_  (							self					):

    '''simple docstring'''







    __UpperCAmelCase:					Tuple		= os.O_RDWR | os.O_CREAT | os.O_TRUNC

    try:
      __UpperCAmelCase:					int		= os.open(self._lock_file   ,    snake_case_					)
    except OSError:
      pass
    else:
      try:
        msvcrt.locking(snake_case_   ,    msvcrt.LK_NBLCK   ,    1					)
      except OSError:
        os.close(snake_case_					)
      else:
        __UpperCAmelCase:					Optional[int]		= fd
    return None







  def    lowercase_  (							self					):

    '''simple docstring'''







    __UpperCAmelCase:					Optional[int]		= self._lock_file_fd
    __UpperCAmelCase:					Any		= None
    msvcrt.locking(snake_case_   ,    msvcrt.LK_UNLCK   ,    1					)
    os.close(snake_case_					)

    try:
      os.remove(self._lock_file					)
    # Probably another instance of the application
    # that acquired the file lock.
    except OSError:
      pass
    return None




class    a (       __lowerCAmelCase				):



  """simple docstring"""







  def __init__(							self   ,    snake_case_   ,    snake_case_=-1   ,    snake_case_=None					):

    '''simple docstring'''







    __UpperCAmelCase:					Optional[int]		= os.statvfs(os.path.dirname(snake_case_					)					).f_namemax
    super().__init__(snake_case_   ,    timeout=snake_case_   ,    max_filename_length=snake_case_					)







  def    lowercase_  (							self					):

    '''simple docstring'''







    __UpperCAmelCase:					Any		= os.O_RDWR | os.O_CREAT | os.O_TRUNC
    __UpperCAmelCase:					Any		= os.open(self._lock_file   ,    snake_case_					)

    try:
      fcntl.flock(snake_case_   ,    fcntl.LOCK_EX | fcntl.LOCK_NB					)
    except OSError:
      os.close(snake_case_					)
    else:
      __UpperCAmelCase:					Optional[int]		= fd
    return None







  def    lowercase_  (							self					):

    '''simple docstring'''







    __UpperCAmelCase:					str		= self._lock_file_fd
    __UpperCAmelCase:					List[Any]		= None
    fcntl.flock(snake_case_   ,    fcntl.LOCK_UN					)
    os.close(snake_case_					)
    return None




class    a (       __lowerCAmelCase				):



  """simple docstring"""







  def    lowercase_  (							self					):

    '''simple docstring'''







    __UpperCAmelCase:					Dict		= os.O_WRONLY | os.O_CREAT | os.O_EXCL | os.O_TRUNC
    try:
      __UpperCAmelCase:					Dict		= os.open(self._lock_file   ,    snake_case_					)
    except OSError:
      pass
    else:
      __UpperCAmelCase:					List[Any]		= fd
    return None







  def    lowercase_  (							self					):

    '''simple docstring'''







    os.close(self._lock_file_fd					)
    __UpperCAmelCase:					int		= None

    try:
      os.remove(self._lock_file					)
    # The file is already deleted and that's what we want.
    except OSError:
      pass
    return None



SCREAMING_SNAKE_CASE_	   =			None

if msvcrt:
    SCREAMING_SNAKE_CASE_	   =			WindowsFileLock
elif fcntl:
    SCREAMING_SNAKE_CASE_	   =			UnixFileLock
else:
    SCREAMING_SNAKE_CASE_	   =			SoftFileLock

    if warnings is not None:
        warnings.warn('only soft file lock is available')
'''simple docstring'''






def  UpperCamelCase__					(					_lowercase    :				int     )							->	int:

  if not isinstance(_lowercase   ,    _lowercase     ):
    __UpperCAmelCase:					List[str]		= F'''Input value of [number={number}] must be an integer'''
    raise TypeError(_lowercase     )

  if number < 1:
    __UpperCAmelCase:					Dict		= F'''Input value of [number={number}] must be > 0'''
    raise ValueError(_lowercase     )

  __UpperCAmelCase:					int		= 1

  for i in range(1   ,    _lowercase     ):
    current_number *= 4 * i - 2
    current_number //= i + 1

  return current_number


if __name__ == "__main__":
    import doctest

    doctest.testmod()