


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__	(    a):




     '''simple docstring'''
     __SCREAMING_SNAKE_CASE        =			["feature_extractor", "tokenizer"]
     # Names need to be attr_class for attr in attributes
     __SCREAMING_SNAKE_CASE        =			None
     __SCREAMING_SNAKE_CASE        =			None
     __SCREAMING_SNAKE_CASE        =			None


     def __init__(						self			,						*__lowerCamelCase			,						**__lowerCamelCase)      ->    List[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(__lowerCamelCase			,						self.attributes):
                   if attribute_name in kwargs:
                          raise TypeError(F"Got multiple values for argument {attribute_name}.")
                   else:
                          _A				:	Dict       =			arg

            if len(__lowerCamelCase) != len(self.attributes):
                   raise ValueError(
                       F"This processor requires {len(self.attributes)} arguments: {', '.join(self.attributes)}. Got "
                       F"{len(__lowerCamelCase)} 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				:	Dict       =			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				:	int       =			AUTO_TO_BASE_CLASS_MAPPING.get(__lowerCamelCase			,						__lowerCamelCase)
                   if isinstance(__lowerCamelCase			,						__lowerCamelCase):
                          _A				:	int       =			tuple(getattr(__lowerCamelCase			,						__lowerCamelCase) for n in class_name if n is not None)
                   else:
                          _A				:	Optional[int]       =			getattr(__lowerCamelCase			,						__lowerCamelCase)

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

                   setattr(self			,						__lowerCamelCase			,						__lowerCamelCase)


     def __repr__(						self)      ->    str:
            _A				:	int       =			[F"- {name}: {repr(getattr(self			,						__lowerCamelCase))}" for name in self.attributes]
            _A				:	List[Any]       =			"\n".join(__lowerCamelCase)
            return F"{self.__class__.__name__}:\n{attributes_repr}"


     def 			_lowerCamelCase			(						self			,						__lowerCamelCase			,						__lowerCamelCase = False			,						**__lowerCamelCase)      ->    Optional[Any]:
            os.makedirs(__lowerCamelCase			,						exist_ok=__lowerCamelCase)

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

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

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

            if push_to_hub:
                   self._upload_modified_files(
                       __lowerCamelCase			,						__lowerCamelCase			,						__lowerCamelCase			,						commit_message=__lowerCamelCase			,						token=kwargs.get("use_auth_token")			,						)


     @classmethod
     def 			_lowerCamelCase			(						cls			,						__lowerCamelCase			,						__lowerCamelCase = None			,						__lowerCamelCase = False			,						__lowerCamelCase = False			,						__lowerCamelCase = None			,						__lowerCamelCase = "main"			,						**__lowerCamelCase			,						)      ->    List[Any]:
            _A				:	Optional[int]       =			cache_dir
            _A				:	str       =			force_download
            _A				:	str       =			local_files_only
            _A				:	Optional[Any]       =			revision

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

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

            _A				:	Dict       =			cls._get_arguments_from_pretrained(__lowerCamelCase			,						**__lowerCamelCase)
            return cls(*__lowerCamelCase)


     @classmethod
     def 			_lowerCamelCase			(						cls			,						__lowerCamelCase="AutoProcessor")      ->    str:
            if not isinstance(__lowerCamelCase			,						__lowerCamelCase):
                   _A				:	Any       =			auto_class.__name__

            import transformers.models.auto as auto_module

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

            _A				:	str       =			auto_class


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

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


     @property
     def 			_lowerCamelCase			(						self)      ->    List[Any]:
            _A				:	Optional[int]       =			getattr(self			,						self.attributes[0])
            return getattr(__lowerCamelCase			,						"model_input_names"			,						__lowerCamelCase)




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'
    )




from __future__ import annotations

from typing import Any







class 					lowerCAmelCase__	:




     '''simple docstring'''


     def __init__(						self			,						__lowerCamelCase			,						__lowerCamelCase)      ->    None:  # noqa: A002
            _A				:	List[str]       =			item
            _A				:	List[Any]       =			next







class 					lowerCAmelCase__	:




     '''simple docstring'''


     def __init__(						self)      ->    None:
            _A				:	Node | None       =			None
            _A				:	List[Any]       =			0


     def 			_lowerCamelCase			(						self			,						__lowerCamelCase)      ->    None:
            _A				:	Union[str, Any]       =			Node(__lowerCamelCase			,						self.head)
            self.size += 1


     def 			_lowerCamelCase			(						self)      ->    Any:
            # Switched 'self.is_empty()' to 'self.head is None'
            # because mypy was considering the possibility that 'self.head'
            # can be None in below else part and giving error
            if self.head is None:
                   return None
            else:
                   _A				:	str       =			self.head.item
                   _A				:	List[Any]       =			self.head.next
                   self.size -= 1
                   return item


     def 			_lowerCamelCase			(						self)      ->    bool:
            return self.head is None


     def __str__(						self)      ->    str:
            if self.is_empty():
                   return ""
            else:
                   _A				:	List[str]       =			self.head
                   _A				:	Optional[int]       =			""
                   _A				:	list[str]       =			[]
                   while iterate:
                          item_list.append(str(iterate.item))
                          _A				:	Optional[Any]       =			iterate.next

                   _A				:	List[str]       =			" --> ".join(__lowerCamelCase)

                   return item_str


     def __len__(						self)      ->    int:
            return self.size
