
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

							UpperCAmelCase__					:	List[str]							       =					True
except ImportError:
							UpperCAmelCase__					:	Dict							       =					False

UpperCAmelCase__					:	Optional[int]							       =					logging.get_logger(__name__)  # pylint: disable=invalid-name



def    _lowercase       (   __SCREAMING_SNAKE_CASE			)						->  Any:
			return AddNewModelCommand(args.testing					,     args.testing_file					,     path=args.path			)



class       UpperCamelCase_      (    snake_case_ ):




							'''simple docstring'''

							@staticmethod
							def 							lowerCAmelCase__			(					UpperCamelCase)			->						Union[str, Any]:
										UpperCamelCase__     :		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  ,    UpperCamelCase  ,    UpperCamelCase  ,    UpperCamelCase=None  ,    *UpperCamelCase)			->						Dict:
										UpperCamelCase__     :		str	 =					testing
										UpperCamelCase__     :		List[str]	 =					testing_file
										UpperCamelCase__     :		Dict	 =					path






							def 							lowerCAmelCase__			(					self)			->						List[Any]:
										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
										UpperCamelCase__     :		Tuple	 =					[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.')

										UpperCamelCase__     :		Optional[Any]	 =					(
										    Path(UpperCamelCase).parent.parent.parent.parent if self._path is None else Path(self._path).parent.parent
										)
										UpperCamelCase__     :		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:
																UpperCamelCase__     :		Any	 =					json.load(UpperCamelCase)

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

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

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

										UpperCamelCase__     :		List[str]	 =					configuration['lowercase_modelname']
										UpperCamelCase__     :		Dict	 =					configuration['generate_tensorflow_pytorch_and_flax']
										os.remove(F"""{directory}/configuration.json""")

										UpperCamelCase__     :		Optional[int]	 =					'PyTorch' in generate_tensorflow_pytorch_and_flax
										UpperCamelCase__     :		Tuple	 =					'TensorFlow' in generate_tensorflow_pytorch_and_flax
										UpperCamelCase__     :		List[Any]	 =					'Flax' in generate_tensorflow_pytorch_and_flax

										UpperCamelCase__     :		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(UpperCamelCase):
													with open(UpperCamelCase  ,    'r') as f:
																UpperCamelCase__     :		List[str]	 =					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(UpperCamelCase  ,    UpperCamelCase  ,    UpperCamelCase):
													# Create temp file
													UpperCamelCase__ ,      UpperCamelCase__     :		List[str]	 =					mkstemp()
													UpperCamelCase__     :		List[str]	 =					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:
																									UpperCamelCase__     :		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(UpperCamelCase):
													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(UpperCamelCase):
													with open(UpperCamelCase) as datafile:
																UpperCamelCase__     :		Any	 =					[]
																UpperCamelCase__     :		str	 =					False
																UpperCamelCase__     :		Any	 =					False
																for line in datafile:
																			if "# To replace in: " in line and "##" not in line:
																						UpperCamelCase__     :		Tuple	 =					line.split('\"')[1]
																						UpperCamelCase__     :		Union[str, Any]	 =					skip_units(UpperCamelCase)
																			elif "# Below: " in line and "##" not in line:
																						UpperCamelCase__     :		Union[str, Any]	 =					line.split('\"')[1]
																						UpperCamelCase__     :		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)

																						UpperCamelCase__     :		int	 =					[]
																			elif "# Replace with" in line and "##" not in line:
																						UpperCamelCase__     :		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)





import inspect
import unittest

from transformers import ConvNextConfig
from transformers.testing_utils import require_torch, require_vision, slow, torch_device
from transformers.utils import cached_property, is_torch_available, is_vision_available

from ...test_backbone_common import BackboneTesterMixin
from ...test_configuration_common import ConfigTester
from ...test_modeling_common import ModelTesterMixin, floats_tensor, ids_tensor
from ...test_pipeline_mixin import PipelineTesterMixin


if is_torch_available():
			import torch

			from transformers import ConvNextBackbone, ConvNextForImageClassification, ConvNextModel
			from transformers.models.convnext.modeling_convnext import CONVNEXT_PRETRAINED_MODEL_ARCHIVE_LIST


if is_vision_available():
			from PIL import Image

			from transformers import AutoImageProcessor




class        _SCREAMING_SNAKE_CASE	:



	def __init__(       self		,    lowercase		,    lowercase=13		,    lowercase=32		,    lowercase=3		,    lowercase=4		,    lowercase=[10, 20, 30, 40]		,    lowercase=[2, 2, 3, 2]		,    lowercase=True		,    lowercase=True		,    lowercase=37		,    lowercase="gelu"		,    lowercase=10		,    lowercase=0.0_2		,    lowercase=["stage2", "stage3", "stage4"]		,    lowercase=[2, 3, 4]		,    lowercase=None		,    )							->			Any:
					lowerCamelCase_         =     parent
					lowerCamelCase_         =     batch_size
					lowerCamelCase_         =     image_size
					lowerCamelCase_         =     num_channels
					lowerCamelCase_         =     num_stages
					lowerCamelCase_         =     hidden_sizes
					lowerCamelCase_         =     depths
					lowerCamelCase_         =     is_training
					lowerCamelCase_         =     use_labels
					lowerCamelCase_         =     intermediate_size
					lowerCamelCase_         =     hidden_act
					lowerCamelCase_         =     num_labels
					lowerCamelCase_         =     initializer_range
					lowerCamelCase_         =     out_features
					lowerCamelCase_         =     out_indices
					lowerCamelCase_         =     scope



	def        SCREAMING_SNAKE_CASE_(       self					)							->			Tuple:
					lowerCamelCase_         =     floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]					)

					lowerCamelCase_         =     None
					if self.use_labels:
									lowerCamelCase_         =     ids_tensor([self.batch_size]		,    self.num_labels					)

					lowerCamelCase_         =     self.get_config()
					return config, pixel_values, labels



	def        SCREAMING_SNAKE_CASE_(       self					)							->			Dict:
					return ConvNextConfig(
					    num_channels=self.num_channels		,    hidden_sizes=self.hidden_sizes		,    depths=self.depths		,    num_stages=self.num_stages		,    hidden_act=self.hidden_act		,    is_decoder=lowercase		,    initializer_range=self.initializer_range		,    out_features=self.out_features		,    out_indices=self.out_indices		,    num_labels=self.num_labels		,    )



	def        SCREAMING_SNAKE_CASE_(       self		,    lowercase		,    lowercase		,    lowercase					)							->			Tuple:
					lowerCamelCase_         =     ConvNextModel(config=lowercase					)
					model.to(lowercase					)
					model.eval()
					lowerCamelCase_         =     model(lowercase					)
					# expected last hidden states: B, C, H // 32, W // 32
					self.parent.assertEqual(
					    result.last_hidden_state.shape		,    (self.batch_size, self.hidden_sizes[-1], self.image_size // 32, self.image_size // 32)		,    )



	def        SCREAMING_SNAKE_CASE_(       self		,    lowercase		,    lowercase		,    lowercase					)							->			str:
					lowerCamelCase_         =     ConvNextForImageClassification(lowercase					)
					model.to(lowercase					)
					model.eval()
					lowerCamelCase_         =     model(lowercase		,    labels=lowercase					)
					self.parent.assertEqual(result.logits.shape		,    (self.batch_size, self.num_labels)					)



	def        SCREAMING_SNAKE_CASE_(       self		,    lowercase		,    lowercase		,    lowercase					)							->			str:
					lowerCamelCase_         =     ConvNextBackbone(config=lowercase					)
					model.to(lowercase					)
					model.eval()
					lowerCamelCase_         =     model(lowercase					)

					# verify hidden states
					self.parent.assertEqual(len(result.feature_maps					)		,    len(config.out_features					)					)
					self.parent.assertListEqual(list(result.feature_maps[0].shape					)		,    [self.batch_size, self.hidden_sizes[1], 4, 4]					)

					# verify channels
					self.parent.assertEqual(len(model.channels					)		,    len(config.out_features					)					)
					self.parent.assertListEqual(model.channels		,    config.hidden_sizes[1:]					)

					# verify backbone works with out_features=None
					lowerCamelCase_         =     None
					lowerCamelCase_         =     ConvNextBackbone(config=lowercase					)
					model.to(lowercase					)
					model.eval()
					lowerCamelCase_         =     model(lowercase					)

					# verify feature maps
					self.parent.assertEqual(len(result.feature_maps					)		,    1					)
					self.parent.assertListEqual(list(result.feature_maps[0].shape					)		,    [self.batch_size, self.hidden_sizes[-1], 1, 1]					)

					# verify channels
					self.parent.assertEqual(len(model.channels					)		,    1					)
					self.parent.assertListEqual(model.channels		,    [config.hidden_sizes[-1]]					)



	def        SCREAMING_SNAKE_CASE_(       self					)							->			Optional[Any]:
					lowerCamelCase_         =     self.prepare_config_and_inputs()
					lowerCamelCase_      ,       lowerCamelCase_      ,       lowerCamelCase_         =     config_and_inputs
					lowerCamelCase_         =     {"pixel_values": pixel_values}
					return config, inputs_dict




@require_torch
class        _SCREAMING_SNAKE_CASE	( snake_case_     ,			snake_case_     ,			unittest.TestCase		):
	lowerCAmelCase__   =					(
	    (
	        ConvNextModel,
	        ConvNextForImageClassification,
	        ConvNextBackbone,
	    )
	    if is_torch_available()
	    else ()
	)
	lowerCAmelCase__   =					(
	    {'feature-extraction': ConvNextModel, 'image-classification': ConvNextForImageClassification}
	    if is_torch_available()
	    else {}
	)

	lowerCAmelCase__   =					True
	lowerCAmelCase__   =					False
	lowerCAmelCase__   =					False
	lowerCAmelCase__   =					False
	lowerCAmelCase__   =					False



	def        SCREAMING_SNAKE_CASE_(       self					)							->			Optional[int]:
					lowerCamelCase_         =     ConvNextModelTester(self					)
					lowerCamelCase_         =     ConfigTester(self		,    config_class=lowercase		,    has_text_modality=lowercase		,    hidden_size=37					)



	def        SCREAMING_SNAKE_CASE_(       self					)							->			Union[str, Any]:
					self.create_and_test_config_common_properties()
					self.config_tester.create_and_test_config_to_json_string()
					self.config_tester.create_and_test_config_to_json_file()
					self.config_tester.create_and_test_config_from_and_save_pretrained()
					self.config_tester.create_and_test_config_with_num_labels()
					self.config_tester.check_config_can_be_init_without_params()
					self.config_tester.check_config_arguments_init()



	def        SCREAMING_SNAKE_CASE_(       self					)							->			Optional[Any]:
					return



	@unittest.skip(reason="ConvNext does not use inputs_embeds"					)
	def        SCREAMING_SNAKE_CASE_(       self					)							->			List[str]:
					pass



	@unittest.skip(reason="ConvNext does not support input and output embeddings"					)
	def        SCREAMING_SNAKE_CASE_(       self					)							->			List[Any]:
					pass



	@unittest.skip(reason="ConvNext does not use feedforward chunking"					)
	def        SCREAMING_SNAKE_CASE_(       self					)							->			Tuple:
					pass



	def        SCREAMING_SNAKE_CASE_(       self					)							->			Union[str, Any]:
					lowerCamelCase_      ,       lowerCamelCase_         =     self.model_tester.prepare_config_and_inputs_for_common()

					for model_class in self.all_model_classes:
									lowerCamelCase_         =     model_class(lowercase					)
									lowerCamelCase_         =     inspect.signature(model.forward					)
									# signature.parameters is an OrderedDict => so arg_names order is deterministic
									lowerCamelCase_         =     [*signature.parameters.keys()]

									lowerCamelCase_         =     ["pixel_values"]
									self.assertListEqual(arg_names[:1]		,    lowercase					)



	def        SCREAMING_SNAKE_CASE_(       self					)							->			Dict:
					lowerCamelCase_         =     self.model_tester.prepare_config_and_inputs()
					self.model_tester.create_and_check_model(*lowercase					)



	def        SCREAMING_SNAKE_CASE_(       self					)							->			Dict:
					lowerCamelCase_         =     self.model_tester.prepare_config_and_inputs()
					self.model_tester.create_and_check_backbone(*lowercase					)



	def        SCREAMING_SNAKE_CASE_(       self					)							->			Optional[Any]:
					def check_hidden_states_output(lowercase		,    lowercase		,    lowercase					):
									lowerCamelCase_         =     model_class(lowercase					)
									model.to(lowercase					)
									model.eval()

									with torch.no_grad():
													lowerCamelCase_         =     model(**self._prepare_for_class(lowercase		,    lowercase					)					)

									lowerCamelCase_         =     outputs.encoder_hidden_states if config.is_encoder_decoder else outputs.hidden_states

									lowerCamelCase_         =     self.model_tester.num_stages
									self.assertEqual(len(lowercase					)		,    expected_num_stages + 1					)

									# ConvNext's feature maps are of shape (batch_size, num_channels, height, width)
									self.assertListEqual(
									    list(hidden_states[0].shape[-2:]					)		,    [self.model_tester.image_size // 4, self.model_tester.image_size // 4]		,    )

					lowerCamelCase_      ,       lowerCamelCase_         =     self.model_tester.prepare_config_and_inputs_for_common()

					for model_class in self.all_model_classes:
									lowerCamelCase_         =     True
									check_hidden_states_output(lowercase		,    lowercase		,    lowercase					)

									# check that output_hidden_states also work using config
									del inputs_dict["output_hidden_states"]
									lowerCamelCase_         =     True

									check_hidden_states_output(lowercase		,    lowercase		,    lowercase					)



	def        SCREAMING_SNAKE_CASE_(       self					)							->			str:
					lowerCamelCase_         =     self.model_tester.prepare_config_and_inputs()
					self.model_tester.create_and_check_for_image_classification(*lowercase					)



	@slow
	def        SCREAMING_SNAKE_CASE_(       self					)							->			Dict:
					for model_name in CONVNEXT_PRETRAINED_MODEL_ARCHIVE_LIST[:1]:
									lowerCamelCase_         =     ConvNextModel.from_pretrained(lowercase					)
									self.assertIsNotNone(lowercase					)





def      lowerCamelCase_					(							):
				lowerCamelCase_         =     Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png"       )
				return image




@require_torch
@require_vision
class        _SCREAMING_SNAKE_CASE	( unittest.TestCase		):



	@cached_property
	def        SCREAMING_SNAKE_CASE_(       self					)							->			List[str]:
					return AutoImageProcessor.from_pretrained("facebook/convnext-tiny-224"					) if is_vision_available() else None



	@slow
	def        SCREAMING_SNAKE_CASE_(       self					)							->			List[Any]:
					lowerCamelCase_         =     ConvNextForImageClassification.from_pretrained("facebook/convnext-tiny-224"					).to(lowercase					)

					lowerCamelCase_         =     self.default_image_processor
					lowerCamelCase_         =     prepare_img()
					lowerCamelCase_         =     image_processor(images=lowercase		,    return_tensors="pt"					).to(lowercase					)

					# forward pass
					with torch.no_grad():
									lowerCamelCase_         =     model(**lowercase					)

					# verify the logits
					lowerCamelCase_         =     torch.Size((1, 1000)					)
					self.assertEqual(outputs.logits.shape		,    lowercase					)

					lowerCamelCase_         =     torch.tensor([-0.0_2_6_0, -0.4_7_3_9, 0.1_9_1_1]					).to(lowercase					)

					self.assertTrue(torch.allclose(outputs.logits[0, :3]		,    lowercase		,    atol=1e-4					)					)




@require_torch
class        _SCREAMING_SNAKE_CASE	( unittest.TestCase     ,			snake_case_		):
	lowerCAmelCase__   =					(ConvNextBackbone,) if is_torch_available() else ()
	lowerCAmelCase__   =					ConvNextConfig

	lowerCAmelCase__   =					False



	def        SCREAMING_SNAKE_CASE_(       self					)							->			List[Any]:
					lowerCamelCase_         =     ConvNextModelTester(self					)


