
"""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


_A				=					logging.get_logger(__name__)

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


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






class 			_lowercase  (							__UpperCAmelCase						):
	lowercase_								=      ['feature_extractor', 'tokenizer']
	# Names need to be attr_class for attr in attributes
	lowercase_								=      None
	lowercase_								=      None
	lowercase_								=      None




	def __init__(					self						,					*UpperCAmelCase_						,					**UpperCAmelCase_   )						->				Tuple:






			for key in kwargs:
					if key not in self.attributes:
							raise TypeError(F"""Unexpected keyword argument {key}."""   )
			for arg, attribute_name in zip(_snake_case						,					self.attributes   ):
					if attribute_name in kwargs:
							raise TypeError(F"""Got multiple values for argument {attribute_name}."""   )
					else:
							lowerCamelCase	:     Union[str, Any]            =       arg

			if len(_snake_case   ) != len(self.attributes   ):
					raise ValueError(
					    F"""This processor requires {len(self.attributes   )} arguments: {', '.join(self.attributes   )}. Got """
					    F"""{len(_snake_case   )} 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():
					lowerCamelCase	:     Optional[Any]            =       getattr(self						,					F"""{attribute_name}_class"""   )
					# Nothing is ever going to be an instance of "AutoXxx", in that case we check the base class.
					lowerCamelCase	:     str            =       AUTO_TO_BASE_CLASS_MAPPING.get(_snake_case						,					_snake_case   )
					if isinstance(_snake_case						,					_snake_case   ):
							lowerCamelCase	:     str            =       tuple(getattr(_snake_case						,					_snake_case   ) for n in class_name if n is not None   )
					else:
							lowerCamelCase	:     List[Any]            =       getattr(_snake_case						,					_snake_case   )

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

					setattr(self						,					_snake_case						,					_snake_case   )




	def __repr__(					self   )						->				Any:
			lowerCamelCase	:     Optional[Any]            =       [F"""- {name}: {repr(getattr(self						,					_snake_case   )   )}""" for name in self.attributes]
			lowerCamelCase	:     Any            =       '\n'.join(_snake_case   )
			return F"""{self.__class__.__name__}:\n{attributes_repr}"""




	def      _UpperCamelCase       (					self						,					UpperCAmelCase_						,					UpperCAmelCase_ = False						,					**UpperCAmelCase_   )						->				Union[str, Any]:
			os.makedirs(_snake_case						,					exist_ok=_snake_case   )

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

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

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

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




	@classmethod
	def      _UpperCamelCase       (					cls						,					UpperCAmelCase_						,					UpperCAmelCase_ = None						,					UpperCAmelCase_ = False						,					UpperCAmelCase_ = False						,					UpperCAmelCase_ = None						,					UpperCAmelCase_ = "main"						,					**UpperCAmelCase_						,					)						->				Dict:
			lowerCamelCase	:     List[Any]            =       cache_dir
			lowerCamelCase	:     Optional[int]            =       force_download
			lowerCamelCase	:     Optional[Any]            =       local_files_only
			lowerCamelCase	:     Dict            =       revision

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

			if token is not None:
					# change to `token` in a follow-up PR
					lowerCamelCase	:     Union[str, Any]            =       token

			lowerCamelCase	:     Optional[int]            =       cls._get_arguments_from_pretrained(_snake_case						,					**_snake_case   )
			return cls(*_snake_case   )




	@classmethod
	def      _UpperCamelCase       (					cls						,					UpperCAmelCase_="AutoProcessor"   )						->				List[str]:






			if not isinstance(_snake_case						,					_snake_case   ):
					lowerCamelCase	:     Any            =       auto_class.__name__

			import transformers.models.auto as auto_module

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

			lowerCamelCase	:     Tuple            =       auto_class




	@classmethod
	def      _UpperCamelCase       (					cls						,					UpperCAmelCase_						,					**UpperCAmelCase_   )						->				Tuple:
			lowerCamelCase	:     List[str]            =       []
			for attribute_name in cls.attributes:
					lowerCamelCase	:     str            =       getattr(cls						,					F"""{attribute_name}_class"""   )
					if isinstance(_snake_case						,					_snake_case   ):
							lowerCamelCase	:     Tuple            =       tuple(getattr(_snake_case						,					_snake_case   ) if n is not None else None for n in class_name   )
							lowerCamelCase	:     Union[str, Any]            =       kwargs.get('use_fast'						,					_snake_case   )
							if use_fast and classes[1] is not None:
									lowerCamelCase	:     Any            =       classes[1]
							else:
									lowerCamelCase	:     Optional[int]            =       classes[0]
					else:
							lowerCamelCase	:     Optional[Any]            =       getattr(_snake_case						,					_snake_case   )

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




	@property
	def      _UpperCamelCase       (					self   )						->				Optional[int]:
			lowerCamelCase	:     Any            =       getattr(self						,					self.attributes[0]   )
			return getattr(_snake_case						,					'model_input_names'						,					_snake_case   )


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














def       _a   (							lowerCamelCase__				)  ->      list[int]:
 if len(lowerCamelCase__				) > 1:
  lowerCamelCase_							:    Optional[Any]							=     len(lowerCamelCase__				) // 2  # Finds the middle of the array
  lowerCamelCase_							:    int							=     arr[
      :middle_length
  ]  # Creates an array of the elements in the first half.
  lowerCamelCase_							:    List[Any]							=     arr[
      middle_length:
  ]  # Creates an array of the elements in the second half.
  lowerCamelCase_							:    Optional[Any]							=     len(lowerCamelCase__				)
  lowerCamelCase_							:    Optional[Any]							=     len(lowerCamelCase__				)
  merge(lowerCamelCase__				)  # Starts sorting the left.
  merge(lowerCamelCase__				)  # Starts sorting the right
  lowerCamelCase_							:    Dict							=     0  # Left Counter
  lowerCamelCase_							:    str							=     0  # Right Counter
  lowerCamelCase_							:    Tuple							=     0  # Position Counter
  while (
      left_index < left_size and right_index < right_size
  ):  # Runs until the lowers size of the left and right are sorted.
   if left_array[left_index] < right_array[right_index]:
    lowerCamelCase_							:    Optional[int]							=     left_array[left_index]
    left_index += 1
   else:
    lowerCamelCase_							:    Union[str, Any]							=     right_array[right_index]
    right_index += 1
   index += 1
  while (
      left_index < left_size
  ):  # Adds the left over elements in the left half of the array
   lowerCamelCase_							:    Tuple							=     left_array[left_index]
   left_index += 1
   index += 1
  while (
      right_index < right_size
  ):  # Adds the left over elements in the right half of the array
   lowerCamelCase_							:    Optional[int]							=     right_array[right_index]
   right_index += 1
   index += 1
 return arr


if __name__ == "__main__":
       import doctest

       doctest.testmod()
