


import os
import warnings
from pathlib import Path
from typing import Optional, Union

from .dynamic_module_utils import custom_object_save
from .tokenization_utils_base import PreTrainedTokenizerBase
from .utils import PushToHubMixin, copy_func, direct_transformers_import, logging


__UpperCAmelCase			:			int			      =					logging.get_logger(__name__)

# Dynamically import the Transformers module to grab the attribute classes of the processor form their names.
__UpperCAmelCase			:			str			      =					direct_transformers_import(Path(__file__).parent)


__UpperCAmelCase			:			Union[str, Any]			      =					{
    "AutoTokenizer": "PreTrainedTokenizerBase",
    "AutoFeatureExtractor": "FeatureExtractionMixin",
    "AutoImageProcessor": "ImageProcessingMixin",
}



class  UpperCAmelCase_						(				__lowerCAmelCase):
       '''simple docstring'''
       __UpperCamelCase   :  str				=       ["feature_extractor", "tokenizer"]
       # Names need to be attr_class for attr in attributes
       __UpperCamelCase   :  int				=       None
       __UpperCamelCase   :  Tuple				=       None
       __UpperCamelCase   :  List[str]				=       None






       def __init__(  self			,       *__SCREAMING_SNAKE_CASE			,       **__SCREAMING_SNAKE_CASE    ):




              """simple docstring"""




              for key in kwargs:
                     if key not in self.attributes:
                            raise TypeError(f"""Unexpected keyword argument {key}."""    )
              for arg, attribute_name in zip(_UpperCamelCase			,       self.attributes    ):
                     if attribute_name in kwargs:
                            raise TypeError(f"""Got multiple values for argument {attribute_name}."""    )
                     else:
                            UpperCamelCase     :						List[Any] 						=		arg

              if len(_UpperCamelCase    ) != len(self.attributes    ):
                     raise ValueError(
                         f"""This processor requires {len(self.attributes    )} arguments: {", ".join(self.attributes    )}. Got """
                         f"""{len(_UpperCamelCase    )} arguments instead."""    )

              # Check each arg is of the proper class (this will also catch a user initializing in the wrong order)
              for attribute_name, arg in kwargs.items():
                     UpperCamelCase     :						Tuple 						=		getattr(self			,       f"""{attribute_name}_class"""    )
                     # Nothing is ever going to be an instance of "AutoXxx", in that case we check the base class.
                     UpperCamelCase     :						Tuple 						=		AUTO_TO_BASE_CLASS_MAPPING.get(_UpperCamelCase			,       _UpperCamelCase    )
                     if isinstance(_UpperCamelCase			,       _UpperCamelCase    ):
                            UpperCamelCase     :						Optional[int] 						=		tuple(getattr(_UpperCamelCase			,       _UpperCamelCase    ) for n in class_name if n is not None    )
                     else:
                            UpperCamelCase     :						Optional[int] 						=		getattr(_UpperCamelCase			,       _UpperCamelCase    )

                     if not isinstance(_UpperCamelCase			,       _UpperCamelCase    ):
                            raise ValueError(
                                f"""Received a {type(_UpperCamelCase    ).__name__} for argument {attribute_name}, but a {class_name} was expected."""    )

                     setattr(self			,       _UpperCamelCase			,       _UpperCamelCase    )






       def __repr__(  self    ):




              """simple docstring"""




              UpperCamelCase     :						Optional[Any] 						=		[f"""- {name}: {repr(getattr(self			,       _UpperCamelCase    )    )}""" for name in self.attributes]
              UpperCamelCase     :						Union[str, Any] 						=		"""\n""".join(_UpperCamelCase    )
              return f"""{self.__class__.__name__}:\n{attributes_repr}"""






       def 			_lowercase (  self			,       __SCREAMING_SNAKE_CASE			,       __SCREAMING_SNAKE_CASE = False			,       **__SCREAMING_SNAKE_CASE    ):




              """simple docstring"""




              os.makedirs(_UpperCamelCase			,       exist_ok=_UpperCamelCase    )

              if push_to_hub:
                     UpperCamelCase     :						List[str] 						=		kwargs.pop('''commit_message'''			,       _UpperCamelCase    )
                     UpperCamelCase     :						Optional[Any] 						=		kwargs.pop('''repo_id'''			,       save_directory.split(os.path.sep    )[-1]    )
                     UpperCamelCase     :						Tuple 						=		self._create_repo(_UpperCamelCase			,       **_UpperCamelCase    )
                     UpperCamelCase     :						Any 						=		self._get_files_timestamps(_UpperCamelCase    )
              # If we have a custom config, we copy the file defining it in the folder and set the attributes so it can be
              # loaded from the Hub.
              if self._auto_class is not None:
                     UpperCamelCase     :						Any 						=		[getattr(self			,       _UpperCamelCase    ) for attribute_name in self.attributes]
                     UpperCamelCase     :						str 						=		[(a.init_kwargs if isinstance(_UpperCamelCase			,       _UpperCamelCase    ) else a) for a in attrs]
                     custom_object_save(self			,       _UpperCamelCase			,       config=_UpperCamelCase    )

              for attribute_name in self.attributes:
                     UpperCamelCase     :						Any 						=		getattr(self			,       _UpperCamelCase    )
                     # Include the processor class in the attribute config so this processor can then be reloaded with the
                     # `AutoProcessor` API.
                     if hasattr(_UpperCamelCase			,       '''_set_processor_class'''    ):
                            attribute._set_processor_class(self.__class__.__name__    )
                     attribute.save_pretrained(_UpperCamelCase    )

              if self._auto_class is not None:
                     # We added an attribute to the init_kwargs of the tokenizers, which needs to be cleaned up.
                     for attribute_name in self.attributes:
                            UpperCamelCase     :						Any 						=		getattr(self			,       _UpperCamelCase    )
                            if isinstance(_UpperCamelCase			,       _UpperCamelCase    ):
                                   del attribute.init_kwargs["auto_map"]

              if push_to_hub:
                     self._upload_modified_files(
                         _UpperCamelCase			,       _UpperCamelCase			,       _UpperCamelCase			,       commit_message=_UpperCamelCase			,       token=kwargs.get('''use_auth_token'''    )			,       )






       @classmethod
       def 			_lowercase (  cls			,       __SCREAMING_SNAKE_CASE			,       __SCREAMING_SNAKE_CASE = None			,       __SCREAMING_SNAKE_CASE = False			,       __SCREAMING_SNAKE_CASE = False			,       __SCREAMING_SNAKE_CASE = None			,       __SCREAMING_SNAKE_CASE = "main"			,       **__SCREAMING_SNAKE_CASE			,       ):




              """simple docstring"""




              UpperCamelCase     :						Tuple 						=		cache_dir
              UpperCamelCase     :						List[Any] 						=		force_download
              UpperCamelCase     :						Tuple 						=		local_files_only
              UpperCamelCase     :						Dict 						=		revision

              UpperCamelCase     :						List[Any] 						=		kwargs.pop('''use_auth_token'''			,       _UpperCamelCase    )
              if use_auth_token is not None:
                     warnings.warn(
                         '''The `use_auth_token` argument is deprecated and will be removed in v5 of Transformers.'''			,       _UpperCamelCase    )
                     if token is not None:
                            raise ValueError(
                                '''`token` and `use_auth_token` are both specified. Please set only the argument `token`.'''    )
                     UpperCamelCase     :						List[str] 						=		use_auth_token

              if token is not None:
                     # change to `token` in a follow-up PR
                     UpperCamelCase     :						Any 						=		token

              UpperCamelCase     :						Dict 						=		cls._get_arguments_from_pretrained(_UpperCamelCase			,       **_UpperCamelCase    )
              return cls(*_UpperCamelCase    )






       @classmethod
       def 			_lowercase (  cls			,       __SCREAMING_SNAKE_CASE="AutoProcessor"    ):




              """simple docstring"""




              if not isinstance(_UpperCamelCase			,       _UpperCamelCase    ):
                     UpperCamelCase     :						List[str] 						=		auto_class.__name__

              import transformers.models.auto as auto_module

              if not hasattr(_UpperCamelCase			,       _UpperCamelCase    ):
                     raise ValueError(f"""{auto_class} is not a valid auto class."""    )

              UpperCamelCase     :						List[Any] 						=		auto_class






       @classmethod
       def 			_lowercase (  cls			,       __SCREAMING_SNAKE_CASE			,       **__SCREAMING_SNAKE_CASE    ):




              """simple docstring"""




              UpperCamelCase     :						List[str] 						=		[]
              for attribute_name in cls.attributes:
                     UpperCamelCase     :						int 						=		getattr(cls			,       f"""{attribute_name}_class"""    )
                     if isinstance(_UpperCamelCase			,       _UpperCamelCase    ):
                            UpperCamelCase     :						str 						=		tuple(getattr(_UpperCamelCase			,       _UpperCamelCase    ) if n is not None else None for n in class_name    )
                            UpperCamelCase     :						str 						=		kwargs.get('''use_fast'''			,       _UpperCamelCase    )
                            if use_fast and classes[1] is not None:
                                   UpperCamelCase     :						Optional[int] 						=		classes[1]
                            else:
                                   UpperCamelCase     :						Tuple 						=		classes[0]
                     else:
                            UpperCamelCase     :						Tuple 						=		getattr(_UpperCamelCase			,       _UpperCamelCase    )

                     args.append(attribute_class.from_pretrained(_UpperCamelCase			,       **_UpperCamelCase    )    )
              return args






       @property
       def 			_lowercase (  self    ):




              """simple docstring"""




              UpperCamelCase     :						int 						=		getattr(self			,       self.attributes[0]    )
              return getattr(_UpperCamelCase			,       '''model_input_names'''			,       _UpperCamelCase    )




__UpperCAmelCase			:			Any			      =					copy_func(ProcessorMixin.push_to_hub)
if ProcessorMixin.push_to_hub.__doc__ is not None:
  __UpperCAmelCase			:			Any			      =					ProcessorMixin.push_to_hub.__doc__.format(
      object="processor", object_class="AutoProcessor", object_files="processor files"
  )


from __future__ import annotations







def     A__	(       __A ,			__A						):







    '''simple docstring'''
    _lowerCamelCase  :		List[str]			    =    [None] * (len(__A						) + len(__A						))

    _lowerCamelCase  :		Optional[int]			    =    0  # pointer to current index for left Half
    _lowerCamelCase  :		List[str]			    =    0  # pointer to current index for the right Half
    _lowerCamelCase  :		List[str]			    =    0  # pointer to current index for the sorted array Half

    while pointera < len(__A						) and pointera < len(__A						):
        if left_half[pointera] < right_half[pointera]:
            _lowerCamelCase  :		Optional[Any]			    =    left_half[pointera]
            pointera += 1
            index += 1
        else:
            _lowerCamelCase  :		List[Any]			    =    right_half[pointera]
            pointera += 1
            index += 1
    while pointera < len(__A						):
        _lowerCamelCase  :		int			    =    left_half[pointera]
        pointera += 1
        index += 1

    while pointera < len(__A						):
        _lowerCamelCase  :		Optional[Any]			    =    right_half[pointera]
        pointera += 1
        index += 1

    return sorted_array







def     A__	(       __A						):







    '''simple docstring'''
    if len(__A						) <= 1:
        return array
    # the actual formula to calculate the middle element = left + (right - left) // 2
    # this avoids integer overflow in case of large N
    _lowerCamelCase  :		int			    =    0 + (len(__A						) - 0) // 2

    # Split the array into halves till the array length becomes equal to One
    # merge the arrays of single length returned by mergeSort function and
    # pass them into the merge arrays function which merges the array
    _lowerCamelCase  :		List[str]			    =    array[:middle]
    _lowerCamelCase  :		Optional[int]			    =    array[middle:]

    return merge(merge_sort(__A						) ,			merge_sort(__A						)						)


if __name__ == "__main__":
    import doctest

    doctest.testmod()




