

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

     lowerCamelCase :      Any					 =     True
except ImportError:
     lowerCamelCase :      Union[str, Any]					 =     False

lowerCamelCase :      Any					 =     logging.get_logger(__name__)  # pylint: disable=invalid-name


def        _lowerCAmelCase					(						_UpperCamelCase						:     Namespace				)      ->			Any:
     """simple docstring"""




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







class 							A__    (       A__  ):





  @staticmethod
  def 						A  (		_a      :	ArgumentParser )	->    Dict:





       '''simple docstring'''






       _SCREAMING_SNAKE_CASE							    =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=_a							,					help='Configuration file on which to run.' )
       add_new_model_parser.add_argument(
           '--path'							,					type=_a							,					help='Path to cookiecutter. Should only be used for testing purposes.' )
       add_new_model_parser.set_defaults(func=_a )





  def __init__(		self      :	Optional[Any]							,					_a      :	bool							,					_a      :	str							,					_a      :	Optional[Any]=None							,					*_a      :	List[Any] )	->    Union[str, Any]:





       '''simple docstring'''






       _SCREAMING_SNAKE_CASE							    =testing
       _SCREAMING_SNAKE_CASE							    =testing_file
       _SCREAMING_SNAKE_CASE							    =path





  def 						A  (		self      :	str )	->    int:





       '''simple docstring'''






       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
       _SCREAMING_SNAKE_CASE							    =[directory for directory in os.listdir() if 'cookiecutter-template-' == directory[:22]]
       if len(_a ) > 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.' )

       _SCREAMING_SNAKE_CASE							    =(
           Path(_a ).parent.parent.parent.parent if self._path is None else Path(self._path ).parent.parent
       )
       _SCREAMING_SNAKE_CASE							    =path_to_transformer_root / 'templates' / 'adding_a_new_model'

       # Execute cookiecutter
       if not self._testing:
            cookiecutter(str(_a ) )
       else:
            with open(self._testing_file							,					'r' ) as configuration_file:
                 _SCREAMING_SNAKE_CASE							    =json.load(_a )

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

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

       # Retrieve configuration
       with open(directory + '/configuration.json'							,					'r' ) as configuration_file:
            _SCREAMING_SNAKE_CASE							    =json.load(_a )

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

       _SCREAMING_SNAKE_CASE							    ='PyTorch' in generate_tensorflow_pytorch_and_flax
       _SCREAMING_SNAKE_CASE							    ='TensorFlow' in generate_tensorflow_pytorch_and_flax
       _SCREAMING_SNAKE_CASE							    ='Flax' in generate_tensorflow_pytorch_and_flax

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

       # 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(_a      :	Any ):
            with open(_a							,					'r' ) as f:
                 _SCREAMING_SNAKE_CASE							    =f.readlines()
            with open(_a							,					'w' ) as f:
                 for line in lines:
                      if "# Copied from transformers." not in line:
                           f.write(_a )

       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(_a      :	str							,					_a      :	str							,					_a      :	List[str] ):
            # Create temp file
            _SCREAMING_SNAKE_CASE    ,						_SCREAMING_SNAKE_CASE							    =mkstemp()
            _SCREAMING_SNAKE_CASE							    =False
            with fdopen(_a							,					'w' ) as new_file:
                 with open(_a ) as old_file:
                      for line in old_file:
                           new_file.write(_a )
                           if line_to_copy_below in line:
                                _SCREAMING_SNAKE_CASE							    =True
                                for line_to_copy in lines_to_copy:
                                     new_file.write(_a )

            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(_a							,					_a )
            # Remove original file
            remove(_a )
            # Move new file
            move(_a							,					_a )

       def skip_units(_a      :	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(_a      :	str ):
            with open(_a ) as datafile:
                 _SCREAMING_SNAKE_CASE							    =[]
                 _SCREAMING_SNAKE_CASE							    =False
                 _SCREAMING_SNAKE_CASE							    =False
                 for line in datafile:
                      if "# To replace in: " in line and "##" not in line:
                           _SCREAMING_SNAKE_CASE							    =line.split('"' )[1]
                           _SCREAMING_SNAKE_CASE							    =skip_units(_a )
                      elif "# Below: " in line and "##" not in line:
                           _SCREAMING_SNAKE_CASE							    =line.split('"' )[1]
                           _SCREAMING_SNAKE_CASE							    =skip_units(_a )
                      elif "# End." in line and "##" not in line:
                           if not skip_file and not skip_snippet:
                                replace(_a							,					_a							,					_a )

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

            remove(_a )

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



'''simple docstring'''
from typing import Optional, Union

import torch
from torch import nn

from ...configuration_utils import ConfigMixin, register_to_config
from ...models.modeling_utils import ModelMixin







class 							A__    (       A__     ,   A__  ):





  @register_to_config
  def __init__(		self      :	Dict							,					_a      :	int = 768							,					)	->    Union[str, Any]:





       '''simple docstring'''






       super().__init__()

       _SCREAMING_SNAKE_CASE							    =nn.Parameter(torch.zeros(1							,					_a ) )
       _SCREAMING_SNAKE_CASE							    =nn.Parameter(torch.ones(1							,					_a ) )





  def 						A  (		self      :	Tuple							,					_a      :	Optional[Union[str, torch.device]] = None							,					_a      :	Optional[torch.dtype] = None							,					)	->    List[Any]:





       '''simple docstring'''






       _SCREAMING_SNAKE_CASE							    =nn.Parameter(self.mean.to(_a ).to(_a ) )
       _SCREAMING_SNAKE_CASE							    =nn.Parameter(self.std.to(_a ).to(_a ) )
       return self





  def 						A  (		self      :	Tuple							,					_a      :	str )	->    str:





       '''simple docstring'''






       _SCREAMING_SNAKE_CASE							    =(embeds - self.mean) * 1.0 / self.std
       return embeds





  def 						A  (		self      :	List[str]							,					_a      :	Optional[Any] )	->    Tuple:





       '''simple docstring'''






       _SCREAMING_SNAKE_CASE							    =(embeds * self.std) + self.mean
       return embeds
