



'''simple docstring'''





import logging
import os
import threading
import time


try:
       import warnings
except ImportError:
       __a          =		None

try:
       import msvcrt
except ImportError:
       __a          =		None

try:
       import fcntl
except ImportError:
       __a          =		None


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


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

__a          =		"3.0.12"


__a          =		None





def 						__snake_case(				)		-> List[str]:
      global _logger
      snake_case__  :    Optional[Any]    						=      _logger or logging.getLogger(__name__		)
      return _logger







class     UpperCAmelCase_       (       _a	):
    """simple docstring"""







    def __init__(    self					:     Any ,     snake_case_					:     List[Any]						):
          snake_case__  :    List[str]    						=      lock_file
          return None




    def __str__(    self					:     Any						):
          snake_case__  :    Optional[int]    						=      f"The file lock '{self.lock_file}' could not be acquired."
          return temp







class     UpperCAmelCase_       :
    """simple docstring"""







    def __init__(    self					:     List[Any] ,     snake_case_					:     int						):
          snake_case__  :    str    						=      lock
          return None




    def __enter__(    self					:     Dict						):
          return self.lock




    def __exit__(    self					:     Any ,     snake_case_					:     Dict ,     snake_case_					:     Dict ,     snake_case_					:     Tuple						):
          self.lock.release()
          return None







class     UpperCAmelCase_       :
    """simple docstring"""







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

          # The default timeout value.
          snake_case__  :    str    						=      timeout

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




    @property
    def lowerCamelCase       (    self					:     Any						):
          return self._lock_file




    @property
    def lowerCamelCase       (    self					:     Optional[int]						):
          return self._timeout




    @timeout.setter
    def lowerCamelCase       (    self					:     List[Any] ,     snake_case_					:     List[str]						):
          snake_case__  :    int    						=      float(snake_case_						)
          return None




    def lowerCamelCase       (    self					:     Optional[int]						):
          raise NotImplementedError()




    def lowerCamelCase       (    self					:     Union[str, Any]						):
          raise NotImplementedError()




    @property
    def lowerCamelCase       (    self					:     int						):
          return self._lock_file_fd is not None




    def lowerCamelCase       (    self					:     Optional[int] ,     snake_case_					:     List[str]=None ,     snake_case_					:     str=0.05						):
          # Use the default timeout, if no timeout is provided.
          if timeout is None:
                snake_case__  :    int    						=      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

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

                raise
          return _Acquire_ReturnProxy(lock=self						)




    def lowerCamelCase       (    self					:     str ,     snake_case_					:     Tuple=False						):
          with self._thread_lock:
                if self.is_locked:
                      self._lock_counter -= 1

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

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

          return None




    def __enter__(    self					:     Dict						):
          self.acquire()
          return self




    def __exit__(    self					:     Union[str, Any] ,     snake_case_					:     List[str] ,     snake_case_					:     Optional[int] ,     snake_case_					:     Dict						):
          self.release()
          return None




    def __del__(    self					:     List[str]						):
          self.release(force=snake_case_						)
          return None




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







class     UpperCAmelCase_       (       _a	):
    """simple docstring"""







    def __init__(    self					:     Any ,     snake_case_					:     Optional[Any] ,     snake_case_					:     Dict=-1 ,     snake_case_					:     Optional[int]=None						):
          from .file_utils import relative_to_absolute_path

          super().__init__(snake_case_ ,     timeout=snake_case_ ,     max_filename_length=snake_case_						)
          snake_case__  :    List[Any]    						=      """\\\\?\\""" + relative_to_absolute_path(self.lock_file						)




    def lowerCamelCase       (    self					:     Any						):
          snake_case__  :    Dict    						=      os.O_RDWR | os.O_CREAT | os.O_TRUNC

          try:
                snake_case__  :    str    						=      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:
                      snake_case__  :    List[Any]    						=      fd
          return None




    def lowerCamelCase       (    self					:     Union[str, Any]						):
          snake_case__  :    Union[str, Any]    						=      self._lock_file_fd
          snake_case__  :    Tuple    						=      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     UpperCAmelCase_       (       _a	):
    """simple docstring"""







    def __init__(    self					:     int ,     snake_case_					:     List[str] ,     snake_case_					:     Optional[Any]=-1 ,     snake_case_					:     Optional[Any]=None						):
          snake_case__  :    Union[str, Any]    						=      os.statvfs(os.path.dirname(snake_case_						)						).f_namemax
          super().__init__(snake_case_ ,     timeout=snake_case_ ,     max_filename_length=snake_case_						)




    def lowerCamelCase       (    self					:     int						):
          snake_case__  :    Tuple    						=      os.O_RDWR | os.O_CREAT | os.O_TRUNC
          snake_case__  :    Dict    						=      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:
                snake_case__  :    List[Any]    						=      fd
          return None




    def lowerCamelCase       (    self					:     int						):
          # 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
          snake_case__  :    Union[str, Any]    						=      self._lock_file_fd
          snake_case__  :    Optional[Any]    						=      None
          fcntl.flock(snake_case_ ,     fcntl.LOCK_UN						)
          os.close(snake_case_						)
          return None







class     UpperCAmelCase_       (       _a	):
    """simple docstring"""







    def lowerCamelCase       (    self					:     Dict						):
          snake_case__  :    Tuple    						=      os.O_WRONLY | os.O_CREAT | os.O_EXCL | os.O_TRUNC
          try:
                snake_case__  :    Any    						=      os.open(self._lock_file ,     snake_case_						)
          except OSError:
                pass
          else:
                snake_case__  :    str    						=      fd
          return None




    def lowerCamelCase       (    self					:     Optional[Any]						):
          os.close(self._lock_file_fd						)
          snake_case__  :    str    						=      None

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

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

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





'''simple docstring'''





import importlib
import os
import sys


# This is required to make the module import works (when the python process is running from the root of the repo)
sys.path.append(".")





def 						__snake_case(				_lowerCAmelCase		)		-> int:
      snake_case__  :    Optional[int]    						=      test_file.split(os.path.sep		)
      if components[0:2] != ["tests", "models"]:
            raise ValueError(
                """`test_file` should start with `tests/models/` (with `/` being the OS specific path separator). Got """
                f"{test_file} instead."		)
      snake_case__  :    Dict    						=      components[-1]
      if not test_fn.endswith("""py"""		):
            raise ValueError(f"`test_file` should be a python file. Got {test_fn} instead."		)
      if not test_fn.startswith("""test_modeling_"""		):
            raise ValueError(
                f"`test_file` should point to a file name of the form `test_modeling_*.py`. Got {test_fn} instead."		)

      snake_case__  :    int    						=      components[:-1] + [test_fn.replace(""".py"""     ,   """"""		)]
      snake_case__  :    int    						=      """.""".join(_lowerCAmelCase		)

      return test_module_path





def 						__snake_case(				_lowerCAmelCase		)		-> List[str]:
      snake_case__  :    str    						=      get_module_path(_lowerCAmelCase		)
      snake_case__  :    Union[str, Any]    						=      importlib.import_module(_lowerCAmelCase		)

      return test_module





def 						__snake_case(				_lowerCAmelCase		)		-> int:
      snake_case__  :    List[Any]    						=      []
      snake_case__  :    Optional[int]    						=      get_test_module(_lowerCAmelCase		)
      for attr in dir(_lowerCAmelCase		):
            if attr.endswith("""ModelTester"""		):
                  tester_classes.append(getattr(_lowerCAmelCase     ,   _lowerCAmelCase		)		)

    # sort with class names
      return sorted(_lowerCAmelCase     ,   key=lambda _lowerCAmelCase		: x.__name__		)





def 						__snake_case(				_lowerCAmelCase		)		-> Dict:
      snake_case__  :    List[str]    						=      []
      snake_case__  :    Any    						=      get_test_module(_lowerCAmelCase		)
      for attr in dir(_lowerCAmelCase		):
            snake_case__  :    Dict    						=      getattr(_lowerCAmelCase     ,   _lowerCAmelCase		)
            # (TF/Flax)ModelTesterMixin is also an attribute in specific model test module. Let's exclude them by checking
            # `all_model_classes` is not empty (which also excludes other special classes).
            snake_case__  :    List[str]    						=      getattr(_lowerCAmelCase     ,   """all_model_classes"""     ,   []		)
            if len(_lowerCAmelCase		) > 0:
                  test_classes.append(_lowerCAmelCase		)

    # sort with class names
      return sorted(_lowerCAmelCase     ,   key=lambda _lowerCAmelCase		: x.__name__		)





def 						__snake_case(				_lowerCAmelCase		)		-> Dict:
      snake_case__  :    Any    						=      get_test_classes(_lowerCAmelCase		)
      snake_case__  :    Optional[Any]    						=      set()
      for test_class in test_classes:
            model_classes.update(test_class.all_model_classes		)

      # sort with class names
      return sorted(_lowerCAmelCase     ,   key=lambda _lowerCAmelCase		: x.__name__		)





def 						__snake_case(				_lowerCAmelCase		)		-> Optional[Any]:
      snake_case__  :    Optional[int]    						=      test_class()
      if hasattr(_lowerCAmelCase     ,   """setUp"""		):
            test.setUp()

      snake_case__  :    Any    						=      None
      if hasattr(_lowerCAmelCase     ,   """model_tester"""		):
            # `(TF/Flax)ModelTesterMixin` has this attribute default to `None`. Let's skip this case.
            if test.model_tester is not None:
                  snake_case__  :    Tuple    						=      test.model_tester.__class__

      return model_tester





def 						__snake_case(				_lowerCAmelCase     ,   _lowerCAmelCase		)		-> Dict:
      snake_case__  :    Union[str, Any]    						=      get_test_classes(_lowerCAmelCase		)

      snake_case__  :    str    						=      []
      for test_class in test_classes:
            if model_class in test_class.all_model_classes:
                  target_test_classes.append(_lowerCAmelCase		)

    # sort with class names
      return sorted(_lowerCAmelCase     ,   key=lambda _lowerCAmelCase		: x.__name__		)





def 						__snake_case(				_lowerCAmelCase     ,   _lowerCAmelCase		)		-> Tuple:
      snake_case__  :    Optional[Any]    						=      get_test_classes_for_model(_lowerCAmelCase     ,   _lowerCAmelCase		)

      snake_case__  :    Union[str, Any]    						=      []
      for test_class in test_classes:
            snake_case__  :    Tuple    						=      get_model_tester_from_test_class(_lowerCAmelCase		)
            if tester_class is not None:
                  tester_classes.append(_lowerCAmelCase		)

    # sort with class names
      return sorted(_lowerCAmelCase     ,   key=lambda _lowerCAmelCase		: x.__name__		)





def 						__snake_case(				_lowerCAmelCase		)		-> Union[str, Any]:
      snake_case__  :    Optional[Any]    						=      get_test_classes(_lowerCAmelCase		)
      snake_case__  :    Union[str, Any]    						=      {test_class: get_model_tester_from_test_class(_lowerCAmelCase		) for test_class in test_classes}
      return test_tester_mapping





def 						__snake_case(				_lowerCAmelCase		)		-> int:
      snake_case__  :    Any    						=      get_model_classes(_lowerCAmelCase		)
      snake_case__  :    Any    						=      {
          model_class: get_test_classes_for_model(_lowerCAmelCase     ,   _lowerCAmelCase		) for model_class in model_classes
      }
      return model_test_mapping





def 						__snake_case(				_lowerCAmelCase		)		-> Optional[int]:
      snake_case__  :    Union[str, Any]    						=      get_model_classes(_lowerCAmelCase		)
      snake_case__  :    str    						=      {
          model_class: get_tester_classes_for_model(_lowerCAmelCase     ,   _lowerCAmelCase		) for model_class in model_classes
      }
      return model_to_tester_mapping





def 						__snake_case(				_lowerCAmelCase		)		-> int:
      if isinstance(_lowerCAmelCase     ,   _lowerCAmelCase		):
            return o
      elif isinstance(_lowerCAmelCase     ,   _lowerCAmelCase		):
            return o.__name__
      elif isinstance(_lowerCAmelCase     ,   (list, tuple)		):
            return [to_json(_lowerCAmelCase		) for x in o]
      elif isinstance(_lowerCAmelCase     ,   _lowerCAmelCase		):
            return {to_json(_lowerCAmelCase		): to_json(_lowerCAmelCase		) for k, v in o.items()}
      else:
            return o
