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


__snake_case         =     logging.get_logger(__name__)

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


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







class       __snake_case (  snake_case__ ):
 __lowerCamelCase     : str 	=   ['feature_extractor', 'tokenizer']
 # Names need to be attr_class for attr in attributes
 __lowerCamelCase     : int 	=   None
 __lowerCamelCase     : Optional[int] 	=   None
 __lowerCamelCase     : Any 	=   None
 def __init__(	self		, *snake_case__		, **snake_case__    )						->				Any:
       '''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(__snake_case		, self.attributes    ):
             if attribute_name in kwargs:
                   raise TypeError(f'''Got multiple values for argument {attribute_name}.'''    )
             else:
                   UpperCAmelCase     :			str     	=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():
             UpperCAmelCase     :			int     	=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(__snake_case		, __snake_case    )
             if isinstance(__snake_case		, __snake_case    ):
                   UpperCAmelCase     :			List[str]     	=tuple(getattr(__snake_case		, __snake_case    ) for n in class_name if n is not None    )
             else:
                   UpperCAmelCase     :			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    )						->				str:
       '''simple docstring'''





       UpperCAmelCase     :			Tuple     	=[f'''- {name}: {repr(getattr(self		, __snake_case    )    )}''' for name in self.attributes]
       UpperCAmelCase     :			Dict     	='''\n'''.join(__snake_case    )
       return f'''{self.__class__.__name__}:\n{attributes_repr}'''
 def 						UpperCAmelCase__							(	self		, snake_case__		, snake_case__ = False		, **snake_case__    )						->				Dict:
       '''simple docstring'''





       os.makedirs(__snake_case		, exist_ok=__snake_case    )

       if push_to_hub:
             UpperCAmelCase     :			Tuple     	=kwargs.pop('''commit_message'''		, __snake_case    )
             UpperCAmelCase     :			Union[str, Any]     	=kwargs.pop('''repo_id'''		, save_directory.split(os.path.sep    )[-1]    )
             UpperCAmelCase     :			str     	=self._create_repo(__snake_case		, **__snake_case    )
             UpperCAmelCase     :			Union[str, Any]     	=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:
             UpperCAmelCase     :			Tuple     	=[getattr(self		, __snake_case    ) for attribute_name in self.attributes]
             UpperCAmelCase     :			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:
             UpperCAmelCase     :			str     	=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:
                   UpperCAmelCase     :			Optional[int]     	=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		, snake_case__		, snake_case__ = None		, snake_case__ = False		, snake_case__ = False		, snake_case__ = None		, snake_case__ = "main"		, **snake_case__		, )						->				Tuple:
       '''simple docstring'''





       UpperCAmelCase     :			Optional[Any]     	=cache_dir
       UpperCAmelCase     :			Optional[int]     	=force_download
       UpperCAmelCase     :			Any     	=local_files_only
       UpperCAmelCase     :			Any     	=revision

       UpperCAmelCase     :			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`.'''    )
             UpperCAmelCase     :			Optional[int]     	=use_auth_token

       if token is not None:
             # change to `token` in a follow-up PR
             UpperCAmelCase     :			Optional[int]     	=token

       UpperCAmelCase     :			Any     	=cls._get_arguments_from_pretrained(__snake_case		, **__snake_case    )
       return cls(*__snake_case    )
 @classmethod
 def 						UpperCAmelCase__							(	cls		, snake_case__="AutoProcessor"    )						->				Optional[int]:
       '''simple docstring'''





       if not isinstance(__snake_case		, __snake_case    ):
             UpperCAmelCase     :			Optional[int]     	=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.'''    )

       UpperCAmelCase     :			str     	=auto_class
 @classmethod
 def 						UpperCAmelCase__							(	cls		, snake_case__		, **snake_case__    )						->				Optional[Any]:
       '''simple docstring'''





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

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






 @property
 def 						UpperCAmelCase__							(	self    )						->				Dict:
       '''simple docstring'''





       UpperCAmelCase     :			Optional[int]     	=getattr(self		, self.attributes[0]    )
       return getattr(__snake_case		, '''model_input_names'''		, __snake_case    )



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




def   snake_case_    (			__lowercase      ,							__lowercase      ,							__lowercase      ,							__lowercase							):
   UpperCAmelCase_				:   Optional[int]							= int((lower_bound + upper_bound) // 2							)
   if array[r] == value:
      return r
   if lower_bound >= upper_bound:
      return -1
   if array[r] < value:
      return binary_search(__lowercase      ,							r + 1      ,							__lowercase      ,							__lowercase							)
   else:
      return binary_search(__lowercase      ,							__lowercase      ,							r - 1      ,							__lowercase							)
def   snake_case_    (			__lowercase      ,							__lowercase							):
   UpperCAmelCase_				:   Union[str, Any]							= 0
   if matrix[index][0] == value:
      return [index, 0]
   while index < len(__lowercase							) and matrix[index][0] < value:
      UpperCAmelCase_				:   str							= binary_search(matrix[index]      ,							0      ,							len(matrix[index]							) - 1      ,							__lowercase							)
      if r != -1:
         return [index, r]
      index += 1
   return [-1, -1]


if __name__ == "__main__":
       import doctest

       doctest.testmod()