
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

  lowercase    :   Tuple		       =				True
except ImportError:
  lowercase    :   Dict		       =				False

lowercase    :   str		       =				logging.get_logger(__name__)  # pylint: disable=invalid-name







def 		_snake_case(    SCREAMING_SNAKE_CASE__							)					->       str:
       return AddNewModelCommand(args.testing   ,      args.testing_file   ,      path=args.path							)




class __snake_case						( _lowerCamelCase	):
    @staticmethod
    def  _SCREAMING_SNAKE_CASE			(    snake_case ):



           '''simple docstring'''







           lowercase				:	Optional[int]			      = 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=__UpperCamelCase						,help="""Configuration file on which to run.""" )
           add_new_model_parser.add_argument(
               """--path"""						,type=__UpperCamelCase						,help="""Path to cookiecutter. Should only be used for testing purposes.""" )
           add_new_model_parser.set_defaults(func=__UpperCamelCase )
    def __init__(    self						,snake_case						,snake_case						,snake_case=None						,*snake_case ):



           '''simple docstring'''







           lowercase				:	List[str]			      = testing
           lowercase				:	str			      = testing_file
           lowercase				:	Optional[Any]			      = path
    def  _SCREAMING_SNAKE_CASE			(    self ):



           '''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
           lowercase				:	List[Any]			      = [directory for directory in os.listdir() if """cookiecutter-template-""" == directory[:22]]
           if len(__UpperCamelCase ) > 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.""" )

           lowercase				:	Any			      = (
               Path(__UpperCamelCase ).parent.parent.parent.parent if self._path is None else Path(self._path ).parent.parent
           )
           lowercase				:	Union[str, Any]			      = path_to_transformer_root / """templates""" / """adding_a_new_model"""

           # Execute cookiecutter
           if not self._testing:
                  cookiecutter(str(__UpperCamelCase ) )
           else:
                  with open(self._testing_file						,"""r""" ) as configuration_file:
                         lowercase				:	Optional[Any]			      = json.load(__UpperCamelCase )

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

           lowercase				:	Union[str, Any]			      = [directory for directory in os.listdir() if """cookiecutter-template-""" in directory[:22]][0]

           # Retrieve configuration
           with open(directory + """/configuration.json"""						,"""r""" ) as configuration_file:
                  lowercase				:	Optional[int]			      = json.load(__UpperCamelCase )

           lowercase				:	List[str]			      = configuration["""lowercase_modelname"""]
           lowercase				:	int			      = configuration["""generate_tensorflow_pytorch_and_flax"""]
           os.remove(f"{directory}/configuration.json" )

           lowercase				:	str			      = """PyTorch""" in generate_tensorflow_pytorch_and_flax
           lowercase				:	Any			      = """TensorFlow""" in generate_tensorflow_pytorch_and_flax
           lowercase				:	Dict			      = """Flax""" in generate_tensorflow_pytorch_and_flax

           lowercase				:	Optional[Any]			      = f"{path_to_transformer_root}/src/transformers/models/{lowercase_model_name}"
           os.makedirs(__UpperCamelCase						,exist_ok=__UpperCamelCase )
           os.makedirs(f"{path_to_transformer_root}/tests/models/{lowercase_model_name}"						,exist_ok=__UpperCamelCase )

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

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

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

           def skip_units(snake_case ):
                  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 ):
                  with open(__UpperCamelCase ) as datafile:
                         lowercase				:	Optional[int]			      = []
                         lowercase				:	int			      = False
                         lowercase				:	str			      = False
                         for line in datafile:
                                if "# To replace in: " in line and "##" not in line:
                                       lowercase				:	Tuple			      = line.split("""\"""" )[1]
                                       lowercase				:	Any			      = skip_units(__UpperCamelCase )
                                elif "# Below: " in line and "##" not in line:
                                       lowercase				:	Dict			      = line.split("""\"""" )[1]
                                       lowercase				:	List[str]			      = skip_units(__UpperCamelCase )
                                elif "# End." in line and "##" not in line:
                                       if not skip_file and not skip_snippet:
                                              replace(__UpperCamelCase						,__UpperCamelCase						,__UpperCamelCase )

                                       lowercase				:	Tuple			      = []
                                elif "# Replace with" in line and "##" not in line:
                                       lowercase				:	int			      = []
                                elif "##" not in line:
                                       lines_to_copy.append(__UpperCamelCase )

                  remove(__UpperCamelCase )

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





from ...configuration_utils import PretrainedConfig
from ...utils import logging


__snake_case     :Optional[Any]			       =logging.get_logger(__name__)

__snake_case     :Tuple			       ={
    'transfo-xl-wt103': 'https://huggingface.co/transfo-xl-wt103/resolve/main/config.json',
}



class        lowerCAmelCase__					(  _lowerCamelCase       ):
				A_   :     Any								=     'transfo-xl'
				A_   :     Dict								=     ['mems']
				A_   :     int								=     {
				    'n_token': 'vocab_size',
				    'hidden_size': 'd_model',
				    'num_attention_heads': 'n_head',
				    'num_hidden_layers': 'n_layer',
				}


				def __init__(							self      :  Optional[Any]						, __UpperCamelCase      :  str=267_735						, __UpperCamelCase      :  int=[20_000, 40_000, 200_000]						, __UpperCamelCase      :  List[str]=1_024						, __UpperCamelCase      :  Union[str, Any]=1_024						, __UpperCamelCase      :  Optional[Any]=16						, __UpperCamelCase      :  Dict=64						, __UpperCamelCase      :  Optional[Any]=4_096						, __UpperCamelCase      :  int=4						, __UpperCamelCase      :  List[str]=False						, __UpperCamelCase      :  Optional[int]=18						, __UpperCamelCase      :  int=1_600						, __UpperCamelCase      :  Dict=1_000						, __UpperCamelCase      :  Optional[Any]=True						, __UpperCamelCase      :  Optional[Any]=True						, __UpperCamelCase      :  Optional[Any]=0						, __UpperCamelCase      :  Any=-1						, __UpperCamelCase      :  Any=True						, __UpperCamelCase      :  List[Any]=0.1						, __UpperCamelCase      :  str=0.0						, __UpperCamelCase      :  Dict=True						, __UpperCamelCase      :  int="normal"						, __UpperCamelCase      :  List[Any]=0.0_1						, __UpperCamelCase      :  str=0.0_1						, __UpperCamelCase      :  Any=0.0_2						, __UpperCamelCase      :  str=1e-5						, __UpperCamelCase      :  Optional[int]=0						, **__UpperCamelCase      :  Any						, )		->     int:
											A      						=    vocab_size
											A      						=    []
											self.cutoffs.extend(__UpperCamelCase       )
											if proj_share_all_but_first:
																		A      						=    [False] + [True] * len(self.cutoffs       )
											else:
																		A      						=    [False] + [False] * len(self.cutoffs       )
											A      						=    d_model
											A      						=    d_embed
											A      						=    d_head
											A      						=    d_inner
											A      						=    div_val
											A      						=    pre_lnorm
											A      						=    n_layer
											A      						=    n_head
											A      						=    mem_len
											A      						=    same_length
											A      						=    attn_type
											A      						=    clamp_len
											A      						=    sample_softmax
											A      						=    adaptive
											A      						=    dropout
											A      						=    dropatt
											A      						=    untie_r
											A      						=    init
											A      						=    init_range
											A      						=    proj_init_std
											A      						=    init_std
											A      						=    layer_norm_epsilon
											super().__init__(eos_token_id=__UpperCamelCase						, **__UpperCamelCase       )


				@property
				def __UpperCamelCase						(							self      :  Any       )		->     Optional[int]:
											# Message copied from Transformer-XL documentation
											logger.info(f'''The model {self.model_type} is one of the few models that has no sequence length limit.'''       )
											return -1


				@max_position_embeddings.setter
				def __UpperCamelCase						(							self      :  List[Any]						, __UpperCamelCase      :  List[Any]       )		->     List[Any]:
											# Message copied from Transformer-XL documentation
											raise NotImplementedError(
											    f'''The model {self.model_type} is one of the few models that has no sequence length limit.'''       )