


'''simple docstring'''

import logging
import os
import threading
import time


try:
   import warnings
except ImportError:
   lowercase__				     =		None

try:
   import msvcrt
except ImportError:
   lowercase__				     =		None

try:
   import fcntl
except ImportError:
   lowercase__				     =		None


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


# Data
# ------------------------------------------------
lowercase__				     =		[
    "Timeout",
    "BaseFileLock",
    "WindowsFileLock",
    "UnixFileLock",
    "SoftFileLock",
    "FileLock",
]

lowercase__				     =		"3.0.12"


lowercase__				     =		None






def __UpperCamelCase   (			)      ->     List[Any]:







     '''simple docstring'''






     global _logger
     _a						=		_logger or logging.getLogger(__name__				)
     return _logger





class 						__SCREAMING_SNAKE_CASE					(      lowerCamelCase__ ):






     def __init__(			self     ,							__UpperCamelCase		)       ->    Tuple:
          _a						=		lock_file
          return None






     def __str__(			self		)       ->    List[Any]:
          _a						=		f"The file lock '{self.lock_file}' could not be acquired."
          return temp







class 						__SCREAMING_SNAKE_CASE					:






     def __init__(			self     ,							__UpperCamelCase		)       ->    Tuple:
          _a						=		lock
          return None






     def __enter__(			self		)       ->    Union[str, Any]:
          return self.lock






     def __exit__(			self     ,							__UpperCamelCase     ,							__UpperCamelCase     ,							__UpperCamelCase		)       ->    List[str]:
          self.lock.release()
          return None







class 						__SCREAMING_SNAKE_CASE					:






     def __init__(			self     ,							__UpperCamelCase     ,							__UpperCamelCase=-1     ,							__UpperCamelCase=None		)       ->    Union[str, Any]:
          _a						=		max_filename_length if max_filename_length is not None else 255
          # Hash the filename if it's too long
          _a						=		self.hash_filename_if_too_long(__UpperCamelCase     ,							__UpperCamelCase		)
          # The path to the lock file.
          _a						=		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.
          _a						=		None

          # The default timeout value.
          _a						=		timeout

          # We use this lock primarily for the lock counter.
          _a						=		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.
          _a						=		0
          return None






     @property
     def  a_					(			self		)       ->    Union[str, Any]:
          return self._lock_file






     @property
     def  a_					(			self		)       ->    Tuple:
          return self._timeout






     @timeout.setter
     def  a_					(			self     ,							__UpperCamelCase		)       ->    Tuple:
          _a						=		float(__UpperCamelCase		)
          return None






     def  a_					(			self		)       ->    str:
          raise NotImplementedError()






     def  a_					(			self		)       ->    Union[str, Any]:
          raise NotImplementedError()






     @property
     def  a_					(			self		)       ->    Dict:
          return self._lock_file_fd is not None






     def  a_					(			self     ,							__UpperCamelCase=None     ,							__UpperCamelCase=0.05		)       ->    int:
          # Use the default timeout, if no timeout is provided.
          if timeout is None:
               _a						=		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

          _a						=		id(self		)
          _a						=		self._lock_file
          _a						=		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(__UpperCamelCase		)
          except:  # noqa
               # Something did go wrong, so decrement the counter.
               with self._thread_lock:
                    _a						=		max(0     ,							self._lock_counter - 1		)

               raise
          return _Acquire_ReturnProxy(lock=self		)






     def  a_					(			self     ,							__UpperCamelCase=False		)       ->    List[Any]:
          with self._thread_lock:
               if self.is_locked:
                    self._lock_counter -= 1

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

                         logger().debug(f"Attempting to release lock {lock_id} on {lock_filename}"		)
                         self._release()
                         _a						=		0
                         logger().debug(f"Lock {lock_id} released on {lock_filename}"		)

          return None






     def __enter__(			self		)       ->    Tuple:
          self.acquire()
          return self






     def __exit__(			self     ,							__UpperCamelCase     ,							__UpperCamelCase     ,							__UpperCamelCase		)       ->    Union[str, Any]:
          self.release()
          return None






     def __del__(			self		)       ->    Dict:
          self.release(force=__UpperCamelCase		)
          return None






     def  a_					(			self     ,							__UpperCamelCase     ,							__UpperCamelCase		)       ->    str:
          _a						=		os.path.basename(__UpperCamelCase		)
          if len(__UpperCamelCase		) > max_length and max_length > 0:
               _a						=		os.path.dirname(__UpperCamelCase		)
               _a						=		str(hash(__UpperCamelCase		)		)
               _a						=		filename[: max_length - len(__UpperCamelCase		) - 8] + "..." + hashed_filename + ".lock"
               return os.path.join(__UpperCamelCase     ,							__UpperCamelCase		)
          else:
               return path







class 						__SCREAMING_SNAKE_CASE					(      lowerCamelCase__ ):






     def __init__(			self     ,							__UpperCamelCase     ,							__UpperCamelCase=-1     ,							__UpperCamelCase=None		)       ->    Dict:
          from .file_utils import relative_to_absolute_path

          super().__init__(__UpperCamelCase     ,							timeout=__UpperCamelCase     ,							max_filename_length=__UpperCamelCase		)
          _a						=		"\\\\?\\" + relative_to_absolute_path(self.lock_file		)






     def  a_					(			self		)       ->    int:
          _a						=		os.O_RDWR | os.O_CREAT | os.O_TRUNC

          try:
               _a						=		os.open(self._lock_file     ,							__UpperCamelCase		)
          except OSError:
               pass
          else:
               try:
                    msvcrt.locking(__UpperCamelCase     ,							msvcrt.LK_NBLCK     ,							1		)
               except OSError:
                    os.close(__UpperCamelCase		)
               else:
                    _a						=		fd
          return None






     def  a_					(			self		)       ->    Tuple:
          _a						=		self._lock_file_fd
          _a						=		None
          msvcrt.locking(__UpperCamelCase     ,							msvcrt.LK_UNLCK     ,							1		)
          os.close(__UpperCamelCase		)

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







class 						__SCREAMING_SNAKE_CASE					(      lowerCamelCase__ ):






     def __init__(			self     ,							__UpperCamelCase     ,							__UpperCamelCase=-1     ,							__UpperCamelCase=None		)       ->    Dict:
          _a						=		os.statvfs(os.path.dirname(__UpperCamelCase		)		).f_namemax
          super().__init__(__UpperCamelCase     ,							timeout=__UpperCamelCase     ,							max_filename_length=__UpperCamelCase		)






     def  a_					(			self		)       ->    Union[str, Any]:
          _a						=		os.O_RDWR | os.O_CREAT | os.O_TRUNC
          _a						=		os.open(self._lock_file     ,							__UpperCamelCase		)

          try:
               fcntl.flock(__UpperCamelCase     ,							fcntl.LOCK_EX | fcntl.LOCK_NB		)
          except OSError:
               os.close(__UpperCamelCase		)
          else:
               _a						=		fd
          return None






     def  a_					(			self		)       ->    List[str]:
          # Do not remove the lockfile:
          #
          #   https://github.com/benediktschmitt/py-filelock/issues/31
          #   https://stackoverflow.com/questions/17708885/flock-removing-locked-file-without-race-condition
          _a						=		self._lock_file_fd
          _a						=		None
          fcntl.flock(__UpperCamelCase     ,							fcntl.LOCK_UN		)
          os.close(__UpperCamelCase		)
          return None







class 						__SCREAMING_SNAKE_CASE					(      lowerCamelCase__ ):






     def  a_					(			self		)       ->    Any:
          _a						=		os.O_WRONLY | os.O_CREAT | os.O_EXCL | os.O_TRUNC
          try:
               _a						=		os.open(self._lock_file     ,							__UpperCamelCase		)
          except OSError:
               pass
          else:
               _a						=		fd
          return None






     def  a_					(			self		)       ->    Optional[Any]:
          os.close(self._lock_file_fd		)
          _a						=		None

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







lowercase__				     =		None

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

   if warnings is not None:
      warnings.warn("only soft file lock is available")





'''simple docstring'''

lowercase__				     =		256
# Modulus to hash a string
lowercase__				     =		1_000_003






def __UpperCamelCase   (			__lowerCamelCase		: str      ,  __lowerCamelCase		: str				)      ->     bool:







     '''simple docstring'''






     _a						=		len(__lowerCamelCase				)
     _a						=		len(__lowerCamelCase				)
     if p_len > t_len:
          return False

     _a						=		0
     _a						=		0
     _a						=		1

     # Calculating the hash of pattern and substring of text
     for i in range(__lowerCamelCase				):
          _a						=		(ord(pattern[i]				) + p_hash * alphabet_size) % modulus
          _a						=		(ord(text[i]				) + text_hash * alphabet_size) % modulus
          if i == p_len - 1:
               continue
          _a						=		(modulus_power * alphabet_size) % modulus

     for i in range(0      ,  t_len - p_len + 1				):
          if text_hash == p_hash and text[i : i + p_len] == pattern:
               return True
          if i == t_len - p_len:
               continue
          # Calculate the https://en.wikipedia.org/wiki/Rolling_hash
          _a						=		(
              (text_hash - ord(text[i]				) * modulus_power) * alphabet_size
              + ord(text[i + p_len]				)
          ) % modulus
     return False






def __UpperCamelCase   (			)      ->     None:







     '''simple docstring'''






     _a						=		"abc1abc12"
     _a						=		"alskfjaldsabc1abc1abc12k23adsfabcabc"
     _a						=		"alskfjaldsk23adsfabcabc"
     assert rabin_karp(__lowerCamelCase      ,  __lowerCamelCase				) and not rabin_karp(__lowerCamelCase      ,  __lowerCamelCase				)

     # Test 2)
     _a						=		"ABABX"
     _a						=		"ABABZABABYABABX"
     assert rabin_karp(__lowerCamelCase      ,  __lowerCamelCase				)

     # Test 3)
     _a						=		"AAAB"
     _a						=		"ABAAAAAB"
     assert rabin_karp(__lowerCamelCase      ,  __lowerCamelCase				)

     # Test 4)
     _a						=		"abcdabcy"
     _a						=		"abcxabcdabxabcdabcdabcy"
     assert rabin_karp(__lowerCamelCase      ,  __lowerCamelCase				)

     # Test 5)
     _a						=		"Lü"
     _a						=		"Lüsai"
     assert rabin_karp(__lowerCamelCase      ,  __lowerCamelCase				)
     _a						=		"Lue"
     assert not rabin_karp(__lowerCamelCase      ,  __lowerCamelCase				)
     print("Success."				)


if __name__ == "__main__":
   test_rabin_karp()

