





'''simple docstring'''






import json
import os
import shutil
import warnings
from argparse import ArgumentParser, Namespace
from pathlib import Path
from typing import List

from ..utils import logging
from . import BaseTransformersCLICommand


try:
      from cookiecutter.main import cookiecutter

      A__				:   List[Any]      =True
except ImportError:
      A__				:   Any      =False

A__				:   Optional[int]      =logging.get_logger(__name__)  # pylint: disable=invalid-name
def    UpperCamelCase__      (		lowerCAmelCase  ):





      """simple docstring"""


      return AddNewModelCommand(args.testing							,	args.testing_file							,	path=args.path  )





class  UpperCAmelCase     (			snake_case_   ):




      @staticmethod
      def 				lowercase__    (			__snake_case			: Any  )				->      Tuple:
            _lowerCAmelCase							     =							parser.add_parser("""add-new-model"""  )
            add_new_model_parser.add_argument("""--testing"""			,			action="""store_true"""			,			help="""If in testing mode."""  )
            add_new_model_parser.add_argument("""--testing_file"""			,			type=__snake_case			,			help="""Configuration file on which to run."""  )
            add_new_model_parser.add_argument(
                """--path"""			,			type=__snake_case			,			help="""Path to cookiecutter. Should only be used for testing purposes."""  )
            add_new_model_parser.set_defaults(func=__snake_case  )




      def __init__(			self			: str			,			__snake_case			: Dict			,			__snake_case			: Optional[Any]			,			__snake_case			: List[str]=None			,			*__snake_case			: List[str]  )				->      Union[str, Any]:
            _lowerCAmelCase							     =							testing
            _lowerCAmelCase							     =							testing_file
            _lowerCAmelCase							     =							path




      def 				lowercase__    (			self			: List[str]  )				->      List[str]:
            warnings.warn(
                """The command `transformers-cli add-new-model` is deprecated and will be removed in v5 of Transformers. """
                """It is not actively maintained anymore, so might give a result that won't pass all tests and quality """
                """checks, you should use `transformers-cli add-new-model-like` instead."""  )
            if not _has_cookiecutter:
                  raise ImportError(
                      """Model creation dependencies are required to use the `add_new_model` command. Install them by running """
                      """the following at the root of your `transformers` clone:\n\n\t$ pip install -e .[modelcreation]\n"""  )
            # Ensure that there is no other `cookiecutter-template-xxx` directory in the current working directory
            _lowerCAmelCase							     =							[directory for directory in os.listdir() if """cookiecutter-template-""" == directory[:22]]
            if len(__snake_case  ) > 0:
                  raise ValueError(
                      """Several directories starting with `cookiecutter-template-` in current working directory. """
                      """Please clean your directory by removing all folders starting with `cookiecutter-template-` or """
                      """change your working directory."""  )

            _lowerCAmelCase							     =							(
                Path(__snake_case  ).parent.parent.parent.parent if self._path is None else Path(self._path  ).parent.parent
            )
            _lowerCAmelCase							     =							path_to_transformer_root / """templates""" / """adding_a_new_model"""

            # Execute cookiecutter
            if not self._testing:
                  cookiecutter(str(__snake_case  )  )
            else:
                  with open(self._testing_file			,			"""r"""  ) as configuration_file:
                        _lowerCAmelCase							     =							json.load(__snake_case  )

                  cookiecutter(
                      str(path_to_cookiecutter if self._path is None else self._path  )			,			no_input=__snake_case			,			extra_context=__snake_case			,			)

            _lowerCAmelCase							     =							[directory for directory in os.listdir() if """cookiecutter-template-""" in directory[:22]][0]

            # Retrieve configuration
            with open(directory + """/configuration.json"""			,			"""r"""  ) as configuration_file:
                  _lowerCAmelCase							     =							json.load(__snake_case  )

            _lowerCAmelCase							     =							configuration["""lowercase_modelname"""]
            _lowerCAmelCase							     =							configuration["""generate_tensorflow_pytorch_and_flax"""]
            os.remove(f"{directory}/configuration.json"  )

            _lowerCAmelCase							     =							"""PyTorch""" in generate_tensorflow_pytorch_and_flax
            _lowerCAmelCase							     =							"""TensorFlow""" in generate_tensorflow_pytorch_and_flax
            _lowerCAmelCase							     =							"""Flax""" in generate_tensorflow_pytorch_and_flax

            _lowerCAmelCase							     =							f"{path_to_transformer_root}/src/transformers/models/{lowercase_model_name}"
            os.makedirs(__snake_case			,			exist_ok=__snake_case  )
            os.makedirs(f"{path_to_transformer_root}/tests/models/{lowercase_model_name}"			,			exist_ok=__snake_case  )

            # Tests require submodules as they have parent imports
            with open(f"{path_to_transformer_root}/tests/models/{lowercase_model_name}/__init__.py"			,			"""w"""  ):
                  pass

            shutil.move(
                f"{directory}/__init__.py"			,			f"{model_dir}/__init__.py"			,			)
            shutil.move(
                f"{directory}/configuration_{lowercase_model_name}.py"			,			f"{model_dir}/configuration_{lowercase_model_name}.py"			,			)

            def remove_copy_lines(__snake_case			: str  ):
                  with open(__snake_case			,			"""r"""  ) as f:
                        _lowerCAmelCase							     =							f.readlines()
                  with open(__snake_case			,			"""w"""  ) as f:
                        for line in lines:
                              if "# Copied from transformers." not in line:
                                    f.write(__snake_case  )

            if output_pytorch:
                  if not self._testing:
                        remove_copy_lines(f"{directory}/modeling_{lowercase_model_name}.py"  )

                  shutil.move(
                      f"{directory}/modeling_{lowercase_model_name}.py"			,			f"{model_dir}/modeling_{lowercase_model_name}.py"			,			)

                  shutil.move(
                      f"{directory}/test_modeling_{lowercase_model_name}.py"			,			f"{path_to_transformer_root}/tests/models/{lowercase_model_name}/test_modeling_{lowercase_model_name}.py"			,			)
            else:
                  os.remove(f"{directory}/modeling_{lowercase_model_name}.py"  )
                  os.remove(f"{directory}/test_modeling_{lowercase_model_name}.py"  )

            if output_tensorflow:
                  if not self._testing:
                        remove_copy_lines(f"{directory}/modeling_tf_{lowercase_model_name}.py"  )

                  shutil.move(
                      f"{directory}/modeling_tf_{lowercase_model_name}.py"			,			f"{model_dir}/modeling_tf_{lowercase_model_name}.py"			,			)

                  shutil.move(
                      f"{directory}/test_modeling_tf_{lowercase_model_name}.py"			,			f"{path_to_transformer_root}/tests/models/{lowercase_model_name}/test_modeling_tf_{lowercase_model_name}.py"			,			)
            else:
                  os.remove(f"{directory}/modeling_tf_{lowercase_model_name}.py"  )
                  os.remove(f"{directory}/test_modeling_tf_{lowercase_model_name}.py"  )

            if output_flax:
                  if not self._testing:
                        remove_copy_lines(f"{directory}/modeling_flax_{lowercase_model_name}.py"  )

                  shutil.move(
                      f"{directory}/modeling_flax_{lowercase_model_name}.py"			,			f"{model_dir}/modeling_flax_{lowercase_model_name}.py"			,			)

                  shutil.move(
                      f"{directory}/test_modeling_flax_{lowercase_model_name}.py"			,			f"{path_to_transformer_root}/tests/models/{lowercase_model_name}/test_modeling_flax_{lowercase_model_name}.py"			,			)
            else:
                  os.remove(f"{directory}/modeling_flax_{lowercase_model_name}.py"  )
                  os.remove(f"{directory}/test_modeling_flax_{lowercase_model_name}.py"  )

            shutil.move(
                f"{directory}/{lowercase_model_name}.md"			,			f"{path_to_transformer_root}/docs/source/en/model_doc/{lowercase_model_name}.md"			,			)

            shutil.move(
                f"{directory}/tokenization_{lowercase_model_name}.py"			,			f"{model_dir}/tokenization_{lowercase_model_name}.py"			,			)

            shutil.move(
                f"{directory}/tokenization_fast_{lowercase_model_name}.py"			,			f"{model_dir}/tokenization_{lowercase_model_name}_fast.py"			,			)

            from os import fdopen, remove
            from shutil import copymode, move
            from tempfile import mkstemp

            def replace(__snake_case			: Dict			,			__snake_case			: Optional[Any]			,			__snake_case			: str  ):
                  # Create temp file
                  _lowerCAmelCase     ,							_lowerCAmelCase							     =							mkstemp()
                  _lowerCAmelCase							     =							False
                  with fdopen(__snake_case			,			"""w"""  ) as new_file:
                        with open(__snake_case  ) as old_file:
                              for line in old_file:
                                    new_file.write(__snake_case  )
                                    if line_to_copy_below in line:
                                          _lowerCAmelCase							     =							True
                                          for line_to_copy in lines_to_copy:
                                                new_file.write(__snake_case  )

                  if not line_found:
                        raise ValueError(f"Line {line_to_copy_below} was not found in file."  )

                  # Copy the file permissions from the old file to the new file
                  copymode(__snake_case			,			__snake_case  )
                  # Remove original file
                  remove(__snake_case  )
                  # Move new file
                  move(__snake_case			,			__snake_case  )

            def skip_units(__snake_case			: str  ):
                  return (
                      ("generating PyTorch" in line and not output_pytorch)
                      or ("generating TensorFlow" in line and not output_tensorflow)
                      or ("generating Flax" in line and not output_flax)
                  )

            def replace_in_files(__snake_case			: Optional[int]  ):
                  with open(__snake_case  ) as datafile:
                        _lowerCAmelCase							     =							[]
                        _lowerCAmelCase							     =							False
                        _lowerCAmelCase							     =							False
                        for line in datafile:
                              if "# To replace in: " in line and "##" not in line:
                                    _lowerCAmelCase							     =							line.split("""\""""  )[1]
                                    _lowerCAmelCase							     =							skip_units(__snake_case  )
                              elif "# Below: " in line and "##" not in line:
                                    _lowerCAmelCase							     =							line.split("""\""""  )[1]
                                    _lowerCAmelCase							     =							skip_units(__snake_case  )
                              elif "# End." in line and "##" not in line:
                                    if not skip_file and not skip_snippet:
                                          replace(__snake_case			,			__snake_case			,			__snake_case  )

                                    _lowerCAmelCase							     =							[]
                              elif "# Replace with" in line and "##" not in line:
                                    _lowerCAmelCase							     =							[]
                              elif "##" not in line:
                                    lines_to_copy.append(__snake_case  )

                  remove(__snake_case  )

            replace_in_files(f"{directory}/to_replace_{lowercase_model_name}.py"  )
            os.rmdir(__snake_case  )













'''simple docstring'''

from typing import List

from .keymap import KEYMAP, get_character





def lowerCamelCase						(     __lowerCamelCase :    str    )						->Optional[int]:

    def decorator(__lowerCamelCase :    int    ):
        _SCREAMING_SNAKE_CASE									=			getattr(__lowerCamelCase					,       """handle_key"""					,       []    )
        handle += [key]
        setattr(__lowerCamelCase					,       """handle_key"""					,       __lowerCamelCase    )
        return func

    return decorator





def lowerCamelCase						(     *__lowerCamelCase :    List[str]    )						->Dict:

    def decorator(__lowerCamelCase :    int    ):
        _SCREAMING_SNAKE_CASE									=			getattr(__lowerCamelCase					,       """handle_key"""					,       []    )
        handle += keys
        setattr(__lowerCamelCase					,       """handle_key"""					,       __lowerCamelCase    )
        return func

    return decorator


class 					a_     (				snake_case_       ):

    '''simple docstring'''


    def __new__(		cls ,		A ,		A ,		A       )		->   int:
        _SCREAMING_SNAKE_CASE									=			super().__new__(cls ,		A ,		A ,		A       )
        if not hasattr(A ,		"""key_handler"""       ):
            setattr(A ,		"""key_handler""" ,		{}       )
        setattr(A ,		"""handle_input""" ,		KeyHandler.handle_input       )

        for value in attrs.values():
            _SCREAMING_SNAKE_CASE									=			getattr(A ,		"""handle_key""" ,		[]       )
            for key in handled_keys:
                _SCREAMING_SNAKE_CASE									=			value
        return new_cls





    @staticmethod
    def 			snake_case_(		cls       )		->   str:
        _SCREAMING_SNAKE_CASE									=			get_character()
        if char != KEYMAP["undefined"]:
            _SCREAMING_SNAKE_CASE									=			ord(A       )
        _SCREAMING_SNAKE_CASE									=			cls.key_handler.get(A       )
        if handler:
            _SCREAMING_SNAKE_CASE									=			char
            return handler(cls       )
        else:
            return None





def lowerCamelCase						(     cls :    Any    )						->Dict:
    return KeyHandler(cls.__name__					,       cls.__bases__					,       cls.__dict__.copy()    )



