


'''simple docstring'''
import logging
import os
import threading
import time


try:
		import warnings
except ImportError:
		__snake_case							      =     None

try:
		import msvcrt
except ImportError:
		__snake_case							      =     None

try:
		import fcntl
except ImportError:
		__snake_case							      =     None


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


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

__snake_case							      =     '''3.0.12'''


__snake_case							      =     None


def 			a      (			)  ->	List[str]:



					'''simple docstring'''






					global _logger
					UpperCamelCase__   :Any												= _logger or logging.getLogger(__name__   )
					return _logger
class    lowercase	(							A__					):

		"""simple docstring"""

		def __init__(		self    ,   UpperCamelCase_							):

							'''simple docstring'''


							UpperCamelCase__   :List[Any]												= lock_file
							return None




		def __str__(		self							):

							'''simple docstring'''


							UpperCamelCase__   :Optional[Any]												= F'''The file lock \'{self.lock_file}\' could not be acquired.'''
							return temp



class    lowercase	:

		"""simple docstring"""

		def __init__(		self    ,   UpperCamelCase_							):

							'''simple docstring'''


							UpperCamelCase__   :Tuple												= lock
							return None




		def __enter__(		self							):

							'''simple docstring'''


							return self.lock




		def __exit__(		self    ,   UpperCamelCase_    ,   UpperCamelCase_    ,   UpperCamelCase_							):

							'''simple docstring'''


							self.lock.release()
							return None



class    lowercase	:

		"""simple docstring"""

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

							'''simple docstring'''


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

							# The default timeout value.
							UpperCamelCase__   :Tuple												= timeout

							# We use this lock primarily for the lock counter.
							UpperCamelCase__   :List[Any]												= 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__   :Union[str, Any]												= 0
							return None




		@property
		def     lowerCAmelCase__				(		self							):

							'''simple docstring'''


							return self._lock_file




		@property
		def     lowerCAmelCase__				(		self							):

							'''simple docstring'''


							return self._timeout




		@timeout.setter
		def     lowerCAmelCase__				(		self    ,   UpperCamelCase_							):

							'''simple docstring'''


							UpperCamelCase__   :List[Any]												= float(UpperCamelCase_							)
							return None




		def     lowerCAmelCase__				(		self							):

							'''simple docstring'''


							raise NotImplementedError()




		def     lowerCAmelCase__				(		self							):

							'''simple docstring'''


							raise NotImplementedError()




		@property
		def     lowerCAmelCase__				(		self							):

							'''simple docstring'''


							return self._lock_file_fd is not None




		def     lowerCAmelCase__				(		self    ,   UpperCamelCase_=None    ,   UpperCamelCase_=0.05							):

							'''simple docstring'''


							if timeout is None:
												UpperCamelCase__   :Optional[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__   :Optional[Any]												= id(self							)
							UpperCamelCase__   :Any												= self._lock_file
							UpperCamelCase__   :Optional[Any]												= 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:
																	UpperCamelCase__   :Tuple												= max(0    ,   self._lock_counter - 1							)

												raise
							return _Acquire_ReturnProxy(lock=self							)




		def     lowerCAmelCase__				(		self    ,   UpperCamelCase_=False							):

							'''simple docstring'''


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

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

																						logger().debug(F'''Attempting to release lock {lock_id} on {lock_filename}'''							)
																						self._release()
																						UpperCamelCase__   :Any												= 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    ,   UpperCamelCase_    ,   UpperCamelCase_    ,   UpperCamelCase_							):

							'''simple docstring'''


							self.release()
							return None




		def __del__(		self							):

							'''simple docstring'''


							self.release(force=UpperCamelCase_							)
							return None




		def     lowerCAmelCase__				(		self    ,   UpperCamelCase_    ,   UpperCamelCase_							):

							'''simple docstring'''


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



class    lowercase	(							A__					):

		"""simple docstring"""

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

							'''simple docstring'''


							from .file_utils import relative_to_absolute_path

							super().__init__(UpperCamelCase_    ,   timeout=UpperCamelCase_    ,   max_filename_length=UpperCamelCase_							)
							UpperCamelCase__   :Any												= '''\\\\?\\''' + relative_to_absolute_path(self.lock_file							)




		def     lowerCAmelCase__				(		self							):

							'''simple docstring'''


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

							try:
												UpperCamelCase__   :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:
																	UpperCamelCase__   :int												= fd
							return None




		def     lowerCAmelCase__				(		self							):

							'''simple docstring'''


							UpperCamelCase__   :Any												= self._lock_file_fd
							UpperCamelCase__   :Tuple												= 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    lowercase	(							A__					):

		"""simple docstring"""

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

							'''simple docstring'''


							UpperCamelCase__   :List[Any]												= os.statvfs(os.path.dirname(UpperCamelCase_							)							).f_namemax
							super().__init__(UpperCamelCase_    ,   timeout=UpperCamelCase_    ,   max_filename_length=UpperCamelCase_							)




		def     lowerCAmelCase__				(		self							):

							'''simple docstring'''


							UpperCamelCase__   :List[str]												= os.O_RDWR | os.O_CREAT | os.O_TRUNC
							UpperCamelCase__   :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:
												UpperCamelCase__   :Optional[int]												= fd
							return None




		def     lowerCAmelCase__				(		self							):

							'''simple docstring'''


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



class    lowercase	(							A__					):

		"""simple docstring"""

		def     lowerCAmelCase__				(		self							):

							'''simple docstring'''


							UpperCamelCase__   :str												= os.O_WRONLY | os.O_CREAT | os.O_EXCL | os.O_TRUNC
							try:
												UpperCamelCase__   :Tuple												= os.open(self._lock_file    ,   UpperCamelCase_							)
							except OSError:
												pass
							else:
												UpperCamelCase__   :int												= fd
							return None




		def     lowerCAmelCase__				(		self							):

							'''simple docstring'''


							os.close(self._lock_file_fd							)
							UpperCamelCase__   :List[Any]												= None

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



__snake_case							      =     None

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

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






from datasets.utils.patching import _PatchedModuleObj, patch_submodule

from . import _test_patching






def lowerCamelCase__    (							)      ->				Any:
   import os as original_os
   from os import path as original_path
   from os import rename as original_rename
   from os.path import dirname as original_dirname
   from os.path import join as original_join

   assert _test_patching.os is original_os
   assert _test_patching.path is original_path
   assert _test_patching.join is original_join

   assert _test_patching.renamed_os is original_os
   assert _test_patching.renamed_path is original_path
   assert _test_patching.renamed_join is original_join

   __snake_case							       =   '''__test_patch_submodule_mock__'''
   with patch_submodule(_test_patching       ,      '''os.path.join'''       ,      snake_case_       ):
      # Every way to access os.path.join must be patched, and the rest must stay untouched

      # check os.path.join
      assert isinstance(_test_patching.os       ,      _PatchedModuleObj       )
      assert isinstance(_test_patching.os.path       ,      _PatchedModuleObj       )
      assert _test_patching.os.path.join is mock

      # check path.join
      assert isinstance(_test_patching.path       ,      _PatchedModuleObj       )
      assert _test_patching.path.join is mock

      # check join
      assert _test_patching.join is mock

      # check that the other attributes are untouched
      assert _test_patching.os.rename is original_rename
      assert _test_patching.path.dirname is original_dirname
      assert _test_patching.os.path.dirname is original_dirname

      # Even renamed modules or objects must be patched

      # check renamed_os.path.join
      assert isinstance(_test_patching.renamed_os       ,      _PatchedModuleObj       )
      assert isinstance(_test_patching.renamed_os.path       ,      _PatchedModuleObj       )
      assert _test_patching.renamed_os.path.join is mock

      # check renamed_path.join
      assert isinstance(_test_patching.renamed_path       ,      _PatchedModuleObj       )
      assert _test_patching.renamed_path.join is mock

      # check renamed_join
      assert _test_patching.renamed_join is mock

      # check that the other attributes are untouched
      assert _test_patching.renamed_os.rename is original_rename
      assert _test_patching.renamed_path.dirname is original_dirname
      assert _test_patching.renamed_os.path.dirname is original_dirname

   # check that everthing is back to normal when the patch is over

   assert _test_patching.os is original_os
   assert _test_patching.path is original_path
   assert _test_patching.join is original_join

   assert _test_patching.renamed_os is original_os
   assert _test_patching.renamed_path is original_path
   assert _test_patching.renamed_join is original_join






def lowerCamelCase__    (							)      ->				Any:
   assert _test_patching.open is open

   __snake_case							       =   '''__test_patch_submodule_builtin_mock__'''
   # _test_patching has "open" in its globals
   assert _test_patching.open is open
   with patch_submodule(_test_patching       ,      '''open'''       ,      snake_case_       ):
      assert _test_patching.open is mock

   # check that everthing is back to normal when the patch is over

   assert _test_patching.open is open






def lowerCamelCase__    (							)      ->				List[str]:
   # pandas.read_csv is not present in _test_patching
   __snake_case							       =   '''__test_patch_submodule_missing_mock__'''
   with patch_submodule(_test_patching       ,      '''pandas.read_csv'''       ,      snake_case_       ):
      pass






def lowerCamelCase__    (							)      ->				Union[str, Any]:
   # builtin should always be mocked even if they're not in the globals
   # in case they're loaded at one point
   __snake_case							       =   '''__test_patch_submodule_missing_builtin_mock__'''
   # _test_patching doesn't have "len" in its globals
   assert getattr(_test_patching       ,      '''len'''       ,      snake_case_       ) is None
   with patch_submodule(_test_patching       ,      '''len'''       ,      snake_case_       ):
      assert _test_patching.len is mock
   assert _test_patching.len is len






def lowerCamelCase__    (							)      ->				Union[str, Any]:
   __snake_case							       =   '''__test_patch_submodule_start_and_stop_mock__'''
   __snake_case							       =   patch_submodule(_test_patching       ,      '''open'''       ,      snake_case_       )
   assert _test_patching.open is open
   patch.start()
   assert _test_patching.open is mock
   patch.stop()
   assert _test_patching.open is open






def lowerCamelCase__    (							)      ->				Optional[int]:
   from os import rename as original_rename
   from os.path import dirname as original_dirname
   from os.path import join as original_join

   __snake_case							       =   '''__test_patch_submodule_successive_join__'''
   __snake_case							       =   '''__test_patch_submodule_successive_dirname__'''
   __snake_case							       =   '''__test_patch_submodule_successive_rename__'''
   assert _test_patching.os.path.join is original_join
   assert _test_patching.os.path.dirname is original_dirname
   assert _test_patching.os.rename is original_rename

   with patch_submodule(_test_patching       ,      '''os.path.join'''       ,      snake_case_       ):
      with patch_submodule(_test_patching       ,      '''os.rename'''       ,      snake_case_       ):
         with patch_submodule(_test_patching       ,      '''os.path.dirname'''       ,      snake_case_       ):
            assert _test_patching.os.path.join is mock_join
            assert _test_patching.os.path.dirname is mock_dirname
            assert _test_patching.os.rename is mock_rename

    # try another order
   with patch_submodule(_test_patching       ,      '''os.rename'''       ,      snake_case_       ):
      with patch_submodule(_test_patching       ,      '''os.path.join'''       ,      snake_case_       ):
         with patch_submodule(_test_patching       ,      '''os.path.dirname'''       ,      snake_case_       ):
            assert _test_patching.os.path.join is mock_join
            assert _test_patching.os.path.dirname is mock_dirname
            assert _test_patching.os.rename is mock_rename

   assert _test_patching.os.path.join is original_join
   assert _test_patching.os.path.dirname is original_dirname
   assert _test_patching.os.rename is original_rename







def lowerCamelCase__    (							)      ->				Tuple:
   __snake_case							       =   '''__test_patch_submodule_doesnt_exist_mock__'''
   with patch_submodule(_test_patching       ,      '''__module_that_doesn_exist__.__attribute_that_doesn_exist__'''       ,      snake_case_       ):
      pass
   with patch_submodule(_test_patching       ,      '''os.__attribute_that_doesn_exist__'''       ,      snake_case_       ):
      pass

