





"""simple docstring"""






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


lowerCAmelCase_      =				logging.get_logger(__name__)

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


lowerCAmelCase_      =				{
    '''AutoTokenizer''': '''PreTrainedTokenizerBase''',
    '''AutoFeatureExtractor''': '''FeatureExtractionMixin''',
    '''AutoImageProcessor''': '''ImageProcessingMixin''',
}



class 						lowerCAmelCase       (   snake_case				):
       lowerCAmelCase__    			=	["""feature_extractor""", """tokenizer"""]
       # Names need to be attr_class for attr in attributes
       lowerCAmelCase__    			=	None
       lowerCAmelCase__    			=	None
       lowerCAmelCase__    			=	None






       def __init__( self     ,	*a__     ,	**a__  ):
              # Sanitize args and kwargs
              for key in kwargs:
                     if key not in self.attributes:
                            raise TypeError(f"""Unexpected keyword argument {key}."""  )
              for arg, attribute_name in zip(a__     ,	self.attributes  ):
                     if attribute_name in kwargs:
                            raise TypeError(f"""Got multiple values for argument {attribute_name}."""  )
                     else:
                            _UpperCAmelCase			     =  arg

              if len(a__  ) != len(self.attributes  ):
                     raise ValueError(
                         f"""This processor requires {len(self.attributes  )} arguments: {", ".join(self.attributes  )}. Got """
                         f"""{len(a__  )} 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			     =  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			     =  AUTO_TO_BASE_CLASS_MAPPING.get(a__     ,	a__  )
                     if isinstance(a__     ,	a__  ):
                            _UpperCAmelCase			     =  tuple(getattr(a__     ,	a__  ) for n in class_name if n is not None  )
                     else:
                            _UpperCAmelCase			     =  getattr(a__     ,	a__  )

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

                     setattr(self     ,	a__     ,	a__  )






       def __repr__( self  ):
              _UpperCAmelCase			     =  [f"""- {name}: {repr(getattr(self     ,	a__  )  )}""" for name in self.attributes]
              _UpperCAmelCase			     =  '\n'.join(a__  )
              return f"""{self.__class__.__name__}:\n{attributes_repr}"""






       def 				__A			( self     ,	a__     ,	a__ = False     ,	**a__  ):
              os.makedirs(a__     ,	exist_ok=a__  )

              if push_to_hub:
                     _UpperCAmelCase			     =  kwargs.pop('commit_message'     ,	a__  )
                     _UpperCAmelCase			     =  kwargs.pop('repo_id'     ,	save_directory.split(os.path.sep  )[-1]  )
                     _UpperCAmelCase			     =  self._create_repo(a__     ,	**a__  )
                     _UpperCAmelCase			     =  self._get_files_timestamps(a__  )
              # 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			     =  [getattr(self     ,	a__  ) for attribute_name in self.attributes]
                     _UpperCAmelCase			     =  [(a.init_kwargs if isinstance(a__     ,	a__  ) else a) for a in attrs]
                     custom_object_save(self     ,	a__     ,	config=a__  )

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

              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			     =  getattr(self     ,	a__  )
                            if isinstance(a__     ,	a__  ):
                                   del attribute.init_kwargs["auto_map"]

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






       @classmethod
       def 				__A			( cls     ,	a__     ,	a__ = None     ,	a__ = False     ,	a__ = False     ,	a__ = None     ,	a__ = "main"     ,	**a__     ,	):
              _UpperCAmelCase			     =  cache_dir
              _UpperCAmelCase			     =  force_download
              _UpperCAmelCase			     =  local_files_only
              _UpperCAmelCase			     =  revision

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

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

              _UpperCAmelCase			     =  cls._get_arguments_from_pretrained(a__     ,	**a__  )
              return cls(*a__  )






       @classmethod
       def 				__A			( cls     ,	a__="AutoProcessor"  ):
              if not isinstance(a__     ,	a__  ):
                     _UpperCAmelCase			     =  auto_class.__name__

              import transformers.models.auto as auto_module

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

              _UpperCAmelCase			     =  auto_class






       @classmethod
       def 				__A			( cls     ,	a__     ,	**a__  ):
              _UpperCAmelCase			     =  []
              for attribute_name in cls.attributes:
                     _UpperCAmelCase			     =  getattr(cls     ,	f"""{attribute_name}_class"""  )
                     if isinstance(a__     ,	a__  ):
                            _UpperCAmelCase			     =  tuple(getattr(a__     ,	a__  ) if n is not None else None for n in class_name  )
                            _UpperCAmelCase			     =  kwargs.get('use_fast'     ,	a__  )
                            if use_fast and classes[1] is not None:
                                   _UpperCAmelCase			     =  classes[1]
                            else:
                                   _UpperCAmelCase			     =  classes[0]
                     else:
                            _UpperCAmelCase			     =  getattr(a__     ,	a__  )

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






       @property
       def 				__A			( self  ):
              _UpperCAmelCase			     =  getattr(self     ,	self.attributes[0]  )
              return getattr(a__     ,	'model_input_names'     ,	a__  )


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













"""simple docstring"""






from __future__ import annotations

def    __lowerCamelCase     (							SCREAMING_SNAKE_CASE,SCREAMING_SNAKE_CASE				)		->							list:






       """simple docstring"""




       _UpperCAmelCase			     =  [None] * (len(SCREAMING_SNAKE_CASE				) + len(SCREAMING_SNAKE_CASE				))

       _UpperCAmelCase			     =  0  # pointer to current index for left Half
       _UpperCAmelCase			     =  0  # pointer to current index for the right Half
       _UpperCAmelCase			     =  0  # pointer to current index for the sorted array Half

       while pointera < len(SCREAMING_SNAKE_CASE				) and pointera < len(SCREAMING_SNAKE_CASE				):
              if left_half[pointera] < right_half[pointera]:
                     _UpperCAmelCase			     =  left_half[pointera]
                     pointera += 1
                     index += 1
              else:
                     _UpperCAmelCase			     =  right_half[pointera]
                     pointera += 1
                     index += 1
       while pointera < len(SCREAMING_SNAKE_CASE				):
              _UpperCAmelCase			     =  left_half[pointera]
              pointera += 1
              index += 1

       while pointera < len(SCREAMING_SNAKE_CASE				):
              _UpperCAmelCase			     =  right_half[pointera]
              pointera += 1
              index += 1

       return sorted_array

def    __lowerCamelCase     (							SCREAMING_SNAKE_CASE				)		->							list:






       """simple docstring"""




       if len(SCREAMING_SNAKE_CASE				) <= 1:
              return array
       # the actual formula to calculate the middle element = left + (right - left) // 2
       # this avoids integer overflow in case of large N
       _UpperCAmelCase			     =  0 + (len(SCREAMING_SNAKE_CASE				) - 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
       _UpperCAmelCase			     =  array[:middle]
       _UpperCAmelCase			     =  array[middle:]

       return merge(merge_sort(SCREAMING_SNAKE_CASE				),merge_sort(SCREAMING_SNAKE_CASE				)				)


if __name__ == "__main__":
    import doctest

    doctest.testmod()






