






import logging
import os
import threading
import time


try:
			import warnings
except ImportError:
			UpperCAmelCase__      			=						None

try:
			import msvcrt
except ImportError:
			UpperCAmelCase__      			=						None

try:
			import fcntl
except ImportError:
			UpperCAmelCase__      			=						None


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


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

UpperCAmelCase__      			=						'''3.0.12'''


UpperCAmelCase__      			=						None







def     a_   ()				->						Dict:



					"""simple docstring"""
					global _logger
					__a					:						List[Any]      =					_logger or logging.getLogger(__name__      )
					return _logger




class 							snake_case_       (    __UpperCamelCase      ):

						"""simple docstring"""



						def __init__(self:					List[str] ,					__UpperCAmelCase:					Union[str, Any]   )    ->     Union[str, Any]:




											'''simple docstring'''



											__a					:						Dict      =					lock_file
											return None



						def __str__(self:					Optional[Any]   )    ->     List[Any]:




											'''simple docstring'''



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




class 							snake_case_       :

						"""simple docstring"""



						def __init__(self:					Union[str, Any] ,					__UpperCAmelCase:					Optional[int]   )    ->     Union[str, Any]:




											'''simple docstring'''



											__a					:						int      =					lock
											return None



						def __enter__(self:					Tuple   )    ->     List[str]:




											'''simple docstring'''



											return self.lock



						def __exit__(self:					Dict ,					__UpperCAmelCase:					List[str] ,					__UpperCAmelCase:					Tuple ,					__UpperCAmelCase:					Tuple   )    ->     List[str]:




											'''simple docstring'''



											self.lock.release()
											return None




class 							snake_case_       :

						"""simple docstring"""



						def __init__(self:					Optional[Any] ,					__UpperCAmelCase:					Optional[int] ,					__UpperCAmelCase:					List[Any]=-1 ,					__UpperCAmelCase:					Tuple=None   )    ->     Union[str, Any]:




											'''simple docstring'''



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

											# The default timeout value.
											__a					:						Dict      =					timeout

											# We use this lock primarily for the lock counter.
											__a					:						Optional[int]      =					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					:						Any      =					0
											return None



						@property
						def        UpperCAmelCase__					(self:					List[str]   )    ->     Any:




											'''simple docstring'''



											return self._lock_file



						@property
						def        UpperCAmelCase__					(self:					Union[str, Any]   )    ->     Union[str, Any]:




											'''simple docstring'''



											return self._timeout



						@timeout.setter
						def        UpperCAmelCase__					(self:					Optional[int] ,					__UpperCAmelCase:					Union[str, Any]   )    ->     int:




											'''simple docstring'''



											__a					:						Optional[Any]      =					float(__UpperCAmelCase   )
											return None



						def        UpperCAmelCase__					(self:					Optional[Any]   )    ->     int:




											'''simple docstring'''



											raise NotImplementedError()



						def        UpperCAmelCase__					(self:					Tuple   )    ->     List[Any]:




											'''simple docstring'''



											raise NotImplementedError()



						@property
						def        UpperCAmelCase__					(self:					Optional[int]   )    ->     Dict:




											'''simple docstring'''



											return self._lock_file_fd is not None



						def        UpperCAmelCase__					(self:					Optional[Any] ,					__UpperCAmelCase:					str=None ,					__UpperCAmelCase:					Optional[int]=0.05   )    ->     Any:




											'''simple docstring'''



											if timeout is None:
																__a					:						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

											__a					:						List[str]      =					id(self   )
											__a					:						List[str]      =					self._lock_file
											__a					:						List[str]      =					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					:						int      =					max(0 ,					self._lock_counter - 1   )

																raise
											return _Acquire_ReturnProxy(lock=self   )



						def        UpperCAmelCase__					(self:					Optional[Any] ,					__UpperCAmelCase:					List[Any]=False   )    ->     List[Any]:




											'''simple docstring'''



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

																					if self._lock_counter == 0 or force:
																										__a					:						Any      =					id(self   )
																										__a					:						Optional[int]      =					self._lock_file

																										logger().debug(f'Attempting to release lock {lock_id} on {lock_filename}'   )
																										self._release()
																										__a					:						Any      =					0
																										logger().debug(f'Lock {lock_id} released on {lock_filename}'   )

											return None



						def __enter__(self:					Optional[int]   )    ->     Any:




											'''simple docstring'''



											self.acquire()
											return self



						def __exit__(self:					Optional[Any] ,					__UpperCAmelCase:					Union[str, Any] ,					__UpperCAmelCase:					Tuple ,					__UpperCAmelCase:					List[str]   )    ->     List[str]:




											'''simple docstring'''



											self.release()
											return None



						def __del__(self:					List[Any]   )    ->     Optional[Any]:




											'''simple docstring'''



											self.release(force=__UpperCAmelCase   )
											return None



						def        UpperCAmelCase__					(self:					str ,					__UpperCAmelCase:					str ,					__UpperCAmelCase:					int   )    ->     str:




											'''simple docstring'''



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




class 							snake_case_       (    __UpperCamelCase      ):

						"""simple docstring"""



						def __init__(self:					List[Any] ,					__UpperCAmelCase:					Optional[int] ,					__UpperCAmelCase:					int=-1 ,					__UpperCAmelCase:					List[Any]=None   )    ->     Optional[Any]:




											'''simple docstring'''



											from .file_utils import relative_to_absolute_path

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



						def        UpperCAmelCase__					(self:					str   )    ->     int:




											'''simple docstring'''



											__a					:						Any      =					os.O_RDWR | os.O_CREAT | os.O_TRUNC

											try:
																__a					:						Optional[int]      =					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					:						Tuple      =					fd
											return None



						def        UpperCAmelCase__					(self:					Union[str, Any]   )    ->     Dict:




											'''simple docstring'''



											__a					:						Tuple      =					self._lock_file_fd
											__a					:						Any      =					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 							snake_case_       (    __UpperCamelCase      ):

						"""simple docstring"""



						def __init__(self:					List[str] ,					__UpperCAmelCase:					Dict ,					__UpperCAmelCase:					int=-1 ,					__UpperCAmelCase:					Union[str, Any]=None   )    ->     int:




											'''simple docstring'''



											__a					:						Dict      =					os.statvfs(os.path.dirname(__UpperCAmelCase   )   ).f_namemax
											super().__init__(__UpperCAmelCase ,					timeout=__UpperCAmelCase ,					max_filename_length=__UpperCAmelCase   )



						def        UpperCAmelCase__					(self:					int   )    ->     str:




											'''simple docstring'''



											__a					:						Any      =					os.O_RDWR | os.O_CREAT | os.O_TRUNC
											__a					:						Union[str, Any]      =					os.open(self._lock_file ,					__UpperCAmelCase   )

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



						def        UpperCAmelCase__					(self:					List[str]   )    ->     List[Any]:




											'''simple docstring'''



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




class 							snake_case_       (    __UpperCamelCase      ):

						"""simple docstring"""



						def        UpperCAmelCase__					(self:					Tuple   )    ->     int:




											'''simple docstring'''



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



						def        UpperCAmelCase__					(self:					Optional[Any]   )    ->     Dict:




											'''simple docstring'''



											os.close(self._lock_file_fd   )
											__a					:						Dict      =					None

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


UpperCAmelCase__      			=						None

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

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













UpperCAmelCase__      			=						'''Input must be a string of 8 numbers plus letter'''
UpperCAmelCase__      			=						'''TRWAGMYFPDXBNJZSQVHLCKE'''







def     a_   (__A      )				->						bool:



					"""simple docstring"""

					if not isinstance(__A				,       __A      ):
										__a					:						Any      =					f'Expected string as input, found {type(__A      ).__name__}'
										raise TypeError(__A      )

					__a					:						int      =					spanish_id.replace("-"				,       ""      ).upper()
					if len(__A      ) != 9:
										raise ValueError(__A      )

					try:
										__a					:						Tuple      =					int(spanish_id_clean[0:8]      )
										__a					:						Optional[int]      =					spanish_id_clean[8]
					except ValueError as ex:
										raise ValueError(__A      ) from ex

					if letter.isdigit():
										raise ValueError(__A      )

					return letter == LOOKUP_LETTERS[number % 23]


if __name__ == "__main__":
			import doctest

			doctest.testmod()





