


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      UpperCAmelCase_ ( UpperCamelCase   ):

   '''simple docstring'''




   __A			:				Union[str, Any]							=		["feature_extractor", "tokenizer"]
   # Names need to be attr_class for attr in attributes
   __A			:				int							=		None
   __A			:				Any							=		None
   __A			:				Dict							=		None






   def __init__(		self						,    *__A						,    **__A			):






     """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(__A						,    self.attributes			):
       if attribute_name in kwargs:
         raise TypeError(F"""Got multiple values for argument {attribute_name}."""			)
       else:
         lowerCamelCase			: Tuple   =    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():
       lowerCamelCase			: Union[str, 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			: Optional[Any]   =    AUTO_TO_BASE_CLASS_MAPPING.get(__A						,    __A			)
       if isinstance(__A						,    __A			):
         lowerCamelCase			: int   =    tuple(getattr(__A						,    __A			) for n in class_name if n is not None			)
       else:
         lowerCamelCase			: int   =    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			):






     """simple docstring"""





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






   def _snake_case   (		self						,    __A						,    __A = False						,    **__A			):






     """simple docstring"""





     os.makedirs(__A						,    exist_ok=__A			)

     if push_to_hub:
       lowerCamelCase			: List[Any]   =    kwargs.pop("commit_message"						,    __A			)
       lowerCamelCase			: List[Any]   =    kwargs.pop("repo_id"						,    save_directory.split(os.path.sep			)[-1]			)
       lowerCamelCase			: int   =    self._create_repo(__A						,    **__A			)
       lowerCamelCase			: List[str]   =    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:
       lowerCamelCase			: List[str]   =    [getattr(self						,    __A			) for attribute_name in self.attributes]
       lowerCamelCase			: Optional[int]   =    [(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:
       lowerCamelCase			: Union[str, Any]   =    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:
         lowerCamelCase			: Optional[Any]   =    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 _snake_case   (		cls						,    __A						,    __A = None						,    __A = False						,    __A = False						,    __A = None						,    __A = "main"						,    **__A						,    ):






     """simple docstring"""





     lowerCamelCase			: List[str]   =    cache_dir
     lowerCamelCase			: Any   =    force_download
     lowerCamelCase			: Dict   =    local_files_only
     lowerCamelCase			: Optional[int]   =    revision

     lowerCamelCase			: Union[str, 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`."			)
       lowerCamelCase			: Any   =    use_auth_token

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

     lowerCamelCase			: List[Any]   =    cls._get_arguments_from_pretrained(__A						,    **__A			)
     return cls(*__A			)






   @classmethod
   def _snake_case   (		cls						,    __A="AutoProcessor"			):






     """simple docstring"""





     if not isinstance(__A						,    __A			):
       lowerCamelCase			: List[Any]   =    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."""			)

     lowerCamelCase			: Optional[Any]   =    auto_class






   @classmethod
   def _snake_case   (		cls						,    __A						,    **__A			):






     """simple docstring"""





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

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






   @property
   def _snake_case   (		self			):






     """simple docstring"""





     lowerCamelCase			: str   =    getattr(self						,    self.attributes[0]			)
     return getattr(__A						,    "model_input_names"						,    __A			)



_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 		lowercase_(  SCREAMING_SNAKE_CASE_     ):


  '''simple docstring'''

  if number != int(SCREAMING_SNAKE_CASE_     ):
    raise ValueError("factorial() only accepts integral values"     )
  if number < 0:
    raise ValueError("factorial() not defined for negative values"     )
  lowerCamelCase			: Optional[Any]   =    1
  for i in range(1				,						number + 1     ):
    value *= i
  return value






def 		lowercase_(  SCREAMING_SNAKE_CASE_     ):


  '''simple docstring'''

  if not isinstance(SCREAMING_SNAKE_CASE_				,						SCREAMING_SNAKE_CASE_     ):
    raise ValueError("factorial() only accepts integral values"     )
  if n < 0:
    raise ValueError("factorial() not defined for negative values"     )
  return 1 if n == 0 or n == 1 else n * factorial(n - 1     )


if __name__ == "__main__":
   import doctest

   doctest.testmod()

   _snake_case					=					int(input('''Enter a positive integer: ''').strip() or 0)
   print(f'''factorial{n} is {factorial(n)}''')



