



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    	=  logging.get_logger(__name__)

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


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


class 						lowerCamelCase__			(		_a ):
						_lowerCAmelCase             =			['''feature_extractor''', '''tokenizer''']
						# Names need to be attr_class for attr in attributes
						_lowerCAmelCase             =			None
						_lowerCAmelCase             =			None
						_lowerCAmelCase             =			None


						def __init__(			self    :	List[Any]   ,							*_a    :	Optional[Any]   ,							**_a    :	str      ):
													# 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:
																											a__:							List[str]									=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():
																				a__:							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.
																				a__:							str									=AUTO_TO_BASE_CLASS_MAPPING.get(_a   ,							_a      )
																				if isinstance(_a   ,							_a      ):
																											a__:							str									=tuple(getattr(_a   ,							_a      ) for n in class_name if n is not None      )
																				else:
																											a__:							Optional[Any]									=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    :	int      ):
													a__:							Optional[int]									=[F"- {name}: {repr(getattr(self   ,							_a      )      )}" for name in self.attributes]
													a__:							List[Any]									="\n".join(_a      )
													return F"{self.__class__.__name__}:\n{attributes_repr}"


						def 	_lowerCamelCase      (			self    :	List[str]   ,							_a    :	Optional[int]   ,							_a    :	bool = False   ,							**_a    :	str      ):
													os.makedirs(_a   ,							exist_ok=_a      )

													if push_to_hub:
																				a__:							Union[str, Any]									=kwargs.pop("commit_message"   ,							_a      )
																				a__:							Any									=kwargs.pop("repo_id"   ,							save_directory.split(os.path.sep      )[-1]      )
																				a__:							Optional[int]									=self._create_repo(_a   ,							**_a      )
																				a__:							Dict									=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:
																				a__:							Tuple									=[getattr(self   ,							_a      ) for attribute_name in self.attributes]
																				a__:							Optional[Any]									=[(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:
																				a__:							Dict									=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:
																											a__:							int									=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 	_lowerCamelCase      (			cls    :	Tuple   ,							_a    :	Union[str, os.PathLike]   ,							_a    :	Optional[Union[str, os.PathLike]] = None   ,							_a    :	bool = False   ,							_a    :	bool = False   ,							_a    :	Optional[Union[str, bool]] = None   ,							_a    :	str = "main"   ,							**_a    :	Optional[Any]   ,							):
													a__:							Union[str, Any]									=cache_dir
													a__:							Dict									=force_download
													a__:							int									=local_files_only
													a__:							str									=revision

													a__:							Any									=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`."      )
																				a__:							List[Any]									=use_auth_token

													if token is not None:
																				# change to `token` in a follow-up PR
																				a__:							List[str]									=token

													a__:							Tuple									=cls._get_arguments_from_pretrained(_a   ,							**_a      )
													return cls(*_a      )


						@classmethod
						def 	_lowerCamelCase      (			cls    :	Union[str, Any]   ,							_a    :	Optional[int]="AutoProcessor"      ):
													if not isinstance(_a   ,							_a      ):
																				a__:							Dict									=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."      )

													a__:							Dict									=auto_class


						@classmethod
						def 	_lowerCamelCase      (			cls    :	int   ,							_a    :	Optional[int]   ,							**_a    :	Optional[Any]      ):
													a__:							Optional[Any]									=[]
													for attribute_name in cls.attributes:
																				a__:							Optional[Any]									=getattr(cls   ,							F"{attribute_name}_class"      )
																				if isinstance(_a   ,							_a      ):
																											a__:							Optional[Any]									=tuple(getattr(_a   ,							_a      ) if n is not None else None for n in class_name      )
																											a__:							List[str]									=kwargs.get("use_fast"   ,							_a      )
																											if use_fast and classes[1] is not None:
																																		a__:							Optional[int]									=classes[1]
																											else:
																																		a__:							Optional[Any]									=classes[0]
																				else:
																											a__:							Any									=getattr(_a   ,							_a      )

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







						@property
						def 	_lowerCamelCase      (			self    :	Tuple      ):
													a__:							Optional[Any]									=getattr(self   ,							self.attributes[0]      )
													return getattr(_a   ,							"model_input_names"   ,							_a      )


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










from typing import Callable





def     __lowerCamelCase							(   __magic_name__						:	Callable    ):

							def wrapper(__magic_name__						:	Optional[Any]    ):
														a__:							List[Any]									=function_with_docstring.__doc__
														return target_function

							return wrapper





