



"""simple docstring"""


import collections
import os
import re
from pathlib import Path


UpperCamelCase						:				int             =      '''src/transformers'''


# Matches is_xxx_available()
UpperCamelCase						:				int             =      re.compile(R"is\_([a-z_]*)_available()")
# Catches a one-line _import_struct = {xxx}
UpperCamelCase						:				int             =      re.compile(R"^_import_structure\s+=\s+\{([^\}]+)\}")
# Catches a line with a key-values pattern: "bla": ["foo", "bar"]
UpperCamelCase						:				Optional[int]             =      re.compile(R"\s+\"\S*\":\s+\[([^\]]*)\]")
# Catches a line if not is_foo_available
UpperCamelCase						:				Dict             =      re.compile(R"^\s*if\s+not\s+is\_[a-z_]*\_available\(\)")
# Catches a line _import_struct["bla"].append("foo")
UpperCamelCase						:				Any             =      re.compile(R"^\s*_import_structure\[\"\S*\"\]\.append\(\"(\S*)\"\)")
# Catches a line _import_struct["bla"].extend(["foo", "bar"]) or _import_struct["bla"] = ["foo", "bar"]
UpperCamelCase						:				str             =      re.compile(R"^\s*_import_structure\[\S*\](?:\.extend\(|\s*=\s+)\[([^\]]*)\]")
# Catches a line with an object between quotes and a comma:     "MyModel",
UpperCamelCase						:				Tuple             =      re.compile(R"^\s+\"([^\"]+)\",")
# Catches a line with objects between brackets only:    ["foo", "bar"],
UpperCamelCase						:				Any             =      re.compile(R"^\s+\[([^\]]+)\]")
# Catches a line with from foo import bar, bla, boo
UpperCamelCase						:				str             =      re.compile(R"\s+from\s+\S*\s+import\s+([^\(\s].*)\n")
# Catches a line with try:
UpperCamelCase						:				Optional[int]             =      re.compile(R"^\s*try:")
# Catches a line with else:
UpperCamelCase						:				Dict             =      re.compile(R"^\s*else:")







def  __snake_case       (   UpperCamelCase__	)      ->		Dict:







		"""simple docstring"""





		if _re_test_backend.search(UpperCamelCase__	) is None:
				return None
		A					       = [b[0] for b in _re_backend.findall(UpperCamelCase__	)]
		backends.sort()
		return "_and_".join(UpperCamelCase__	)







def  __snake_case       (   UpperCamelCase__	)      ->		Any:







		"""simple docstring"""





		with open(UpperCamelCase__ ,			'r' ,			encoding='utf-8' ,			newline='\n'	) as f:
				A					       = f.readlines()

		A					       = 0
		while line_index < len(UpperCamelCase__	) and not lines[line_index].startswith('_import_structure = {'	):
				line_index += 1

		# If this is a traditional init, just return.
		if line_index >= len(UpperCamelCase__	):
				return None

		# First grab the objects without a specific backend in _import_structure
		A					       = []
		while not lines[line_index].startswith('if TYPE_CHECKING'	) and find_backend(lines[line_index]	) is None:
				A					       = lines[line_index]
				# If we have everything on a single line, let's deal with it.
				if _re_one_line_import_struct.search(UpperCamelCase__	):
						A					       = _re_one_line_import_struct.search(UpperCamelCase__	).groups()[0]
						A					       = re.findall(r'\[([^\]]+)\]' ,			UpperCamelCase__	)
						for imp in imports:
								objects.extend([obj[1:-1] for obj in imp.split(', '	)]	)
						line_index += 1
						continue
				A					       = _re_import_struct_key_value.search(UpperCamelCase__	)
				if single_line_import_search is not None:
						A					       = [obj[1:-1] for obj in single_line_import_search.groups()[0].split(', '	) if len(UpperCamelCase__	) > 0]
						objects.extend(UpperCamelCase__	)
				elif line.startswith(' ' * 8 + '\"'	):
						objects.append(line[9:-3]	)
				line_index += 1

		A					       = {'none': objects}
		# Let's continue with backend-specific objects in _import_structure
		while not lines[line_index].startswith('if TYPE_CHECKING'	):
				# If the line is an if not is_backend_available, we grab all objects associated.
				A					       = find_backend(lines[line_index]	)
				# Check if the backend declaration is inside a try block:
				if _re_try.search(lines[line_index - 1]	) is None:
						A					       = None

				if backend is not None:
						line_index += 1

						# Scroll until we hit the else block of try-except-else
						while _re_else.search(lines[line_index]	) is None:
								line_index += 1

						line_index += 1

						A					       = []
						# Until we unindent, add backend objects to the list
						while len(lines[line_index]	) <= 1 or lines[line_index].startswith(' ' * 4	):
								A					       = lines[line_index]
								if _re_import_struct_add_one.search(UpperCamelCase__	) is not None:
										objects.append(_re_import_struct_add_one.search(UpperCamelCase__	).groups()[0]	)
								elif _re_import_struct_add_many.search(UpperCamelCase__	) is not None:
										A					       = _re_import_struct_add_many.search(UpperCamelCase__	).groups()[0].split(', '	)
										A					       = [obj[1:-1] for obj in imports if len(UpperCamelCase__	) > 0]
										objects.extend(UpperCamelCase__	)
								elif _re_between_brackets.search(UpperCamelCase__	) is not None:
										A					       = _re_between_brackets.search(UpperCamelCase__	).groups()[0].split(', '	)
										A					       = [obj[1:-1] for obj in imports if len(UpperCamelCase__	) > 0]
										objects.extend(UpperCamelCase__	)
								elif _re_quote_object.search(UpperCamelCase__	) is not None:
										objects.append(_re_quote_object.search(UpperCamelCase__	).groups()[0]	)
								elif line.startswith(' ' * 8 + '\"'	):
										objects.append(line[9:-3]	)
								elif line.startswith(' ' * 12 + '\"'	):
										objects.append(line[13:-3]	)
								line_index += 1

						A					       = objects
				else:
						line_index += 1

    # At this stage we are in the TYPE_CHECKING part, first grab the objects without a specific backend
		A					       = []
		while (
		    line_index < len(UpperCamelCase__	)
		    and find_backend(lines[line_index]	) is None
		    and not lines[line_index].startswith('else'	)
		):
				A					       = lines[line_index]
				A					       = _re_import.search(UpperCamelCase__	)
				if single_line_import_search is not None:
						objects.extend(single_line_import_search.groups()[0].split(', '	)	)
				elif line.startswith(' ' * 8	):
						objects.append(line[8:-2]	)
				line_index += 1

		A					       = {'none': objects}
		# Let's continue with backend-specific objects
		while line_index < len(UpperCamelCase__	):
				# If the line is an if is_backend_available, we grab all objects associated.
				A					       = find_backend(lines[line_index]	)
				# Check if the backend declaration is inside a try block:
				if _re_try.search(lines[line_index - 1]	) is None:
						A					       = None

				if backend is not None:
						line_index += 1

						# Scroll until we hit the else block of try-except-else
						while _re_else.search(lines[line_index]	) is None:
								line_index += 1

						line_index += 1

						A					       = []
						# Until we unindent, add backend objects to the list
						while len(lines[line_index]	) <= 1 or lines[line_index].startswith(' ' * 8	):
								A					       = lines[line_index]
								A					       = _re_import.search(UpperCamelCase__	)
								if single_line_import_search is not None:
										objects.extend(single_line_import_search.groups()[0].split(', '	)	)
								elif line.startswith(' ' * 12	):
										objects.append(line[12:-2]	)
								line_index += 1

						A					       = objects
				else:
						line_index += 1

		return import_dict_objects, type_hint_objects







def  __snake_case       (   UpperCamelCase__ ,			UpperCamelCase__	)      ->		List[Any]:







		"""simple docstring"""





		def find_duplicates(UpperCamelCase__	):
				return [k for k, v in collections.Counter(UpperCamelCase__	).items() if v > 1]

		if list(import_dict_objects.keys()	) != list(type_hint_objects.keys()	):
				return ["Both sides of the init do not have the same backends!"]

		A					       = []
		for key in import_dict_objects.keys():
				A					       = find_duplicates(import_dict_objects[key]	)
				if duplicate_imports:
						errors.append(f'Duplicate _import_structure definitions for: {duplicate_imports}'	)
				A					       = find_duplicates(type_hint_objects[key]	)
				if duplicate_type_hints:
						errors.append(f'Duplicate TYPE_CHECKING objects for: {duplicate_type_hints}'	)

				if sorted(set(import_dict_objects[key]	)	) != sorted(set(type_hint_objects[key]	)	):
						A					       = 'base imports' if key == 'none' else f'{key} backend'
						errors.append(f'Differences for {name}:'	)
						for a in type_hint_objects[key]:
								if a not in import_dict_objects[key]:
										errors.append(f'  {a} in TYPE_HINT but not in _import_structure.'	)
						for a in import_dict_objects[key]:
								if a not in type_hint_objects[key]:
										errors.append(f'  {a} in _import_structure but not in TYPE_HINT.'	)
		return errors







def  __snake_case       (   )      ->		Tuple:







		"""simple docstring"""





		A					       = []
		for root, _, files in os.walk(UpperCamelCase__	):
				if "__init__.py" in files:
						A					       = os.path.join(UpperCamelCase__ ,			'__init__.py'	)
						A					       = parse_init(UpperCamelCase__	)
						if objects is not None:
								A					       = analyze_results(*UpperCamelCase__	)
								if len(UpperCamelCase__	) > 0:
										A					       = f'Problem in {fname}, both halves do not define the same objects.\n{errors[0]}'
										failures.append('\n'.join(UpperCamelCase__	)	)
		if len(UpperCamelCase__	) > 0:
				raise ValueError('\n\n'.join(UpperCamelCase__	)	)







def  __snake_case       (   )      ->		int:







		"""simple docstring"""





		A					       = []
		for path, directories, files in os.walk(UpperCamelCase__	):
				for folder in directories:
						# Ignore private modules
						if folder.startswith('_'	):
								directories.remove(UpperCamelCase__	)
								continue
						# Ignore leftovers from branches (empty folders apart from pycache)
						if len(list((Path(UpperCamelCase__	) / folder).glob('*.py'	)	)	) == 0:
								continue
						A					       = str((Path(UpperCamelCase__	) / folder).relative_to(UpperCamelCase__	)	)
						A					       = short_path.replace(os.path.sep ,			'.'	)
						submodules.append(UpperCamelCase__	)
				for fname in files:
						if fname == "__init__.py":
								continue
						A					       = str((Path(UpperCamelCase__	) / fname).relative_to(UpperCamelCase__	)	)
						A					       = short_path.replace('.py' ,			''	).replace(os.path.sep ,			'.'	)
						if len(submodule.split('.'	)	) == 1:
								submodules.append(UpperCamelCase__	)
		return submodules


UpperCamelCase						:				List[str]             =      [
    '''convert_pytorch_checkpoint_to_tf2''',
    '''modeling_flax_pytorch_utils''',
    '''models.esm.openfold_utils''',
]







def  __snake_case       (   )      ->		Any:







		"""simple docstring"""





		from transformers.utils import direct_transformers_import

		A					       = direct_transformers_import(UpperCamelCase__	)

		A					       = set(transformers._import_structure.keys()	)
		# This contains all the base keys of the _import_structure object defined in the init, but if the user is missing
		# some optional dependencies, they may not have all of them. Thus we read the init to read all additions and
		# (potentiall re-) add them.
		with open(os.path.join(UpperCamelCase__ ,			'__init__.py'	) ,			'r'	) as f:
				A					       = f.read()
		import_structure_keys.update(set(re.findall(r'import_structure\[\"([^\"]*)\"\]' ,			UpperCamelCase__	)	)	)

		A					       = [
		    module
		    for module in get_transformers_submodules()
		    if module not in IGNORE_SUBMODULES and module not in import_structure_keys
		]

		if len(UpperCamelCase__	) > 0:
				A					       = '\n'.join(f'- {module}' for module in module_not_registered	)
				raise ValueError(
				    'The following submodules are not properly registed in the main init of Transformers:\n'
				    f'{list_of_modules}\n'
				    'Make sure they appear somewhere in the keys of `_import_structure` with an empty list as value.'	)


if __name__ == "__main__":
	check_all_inits()
	check_submodules()









"""simple docstring"""


import json
import os
import subprocess
import unittest
from ast import literal_eval

import pytest
from parameterized import parameterized, parameterized_class

from . import is_sagemaker_available


if is_sagemaker_available():
	from sagemaker import Session, TrainingJobAnalytics
	from sagemaker.huggingface import HuggingFace



@pytest.mark.skipif(
    literal_eval(os.getenv("""TEST_SAGEMAKER"""							,    """False"""			)			) is not True							,    reason="""Skipping test because should only be run when releasing minor transformers version"""							,    )
@pytest.mark.usefixtures("""sm_env"""			)
@parameterized_class(
    [
        {
            """framework""": """pytorch""",
            """script""": """run_glue.py""",
            """model_name_or_path""": """distilbert-base-cased""",
            """instance_type""": """ml.p3.16xlarge""",
            """results""": {"""train_runtime""": 650, """eval_accuracy""": 0.7, """eval_loss""": 0.6},
        },
        {
            """framework""": """pytorch""",
            """script""": """run_ddp.py""",
            """model_name_or_path""": """distilbert-base-cased""",
            """instance_type""": """ml.p3.16xlarge""",
            """results""": {"""train_runtime""": 600, """eval_accuracy""": 0.7, """eval_loss""": 0.6},
        },
        {
            """framework""": """tensorflow""",
            """script""": """run_tf_dist.py""",
            """model_name_or_path""": """distilbert-base-cased""",
            """instance_type""": """ml.p3.16xlarge""",
            """results""": {"""train_runtime""": 600, """eval_accuracy""": 0.6, """eval_loss""": 0.7},
        },
    ]			)
class 			lowerCamelCase__						(   unittest.TestCase			):







						def __a						(							self   :    int		):
								if self.framework == "pytorch":
										subprocess.run(
										    f'cp ./examples/pytorch/text-classification/run_glue.py {self.env.test_path}/run_glue.py'.split()			,			encoding='utf-8'			,			check=_lowercase			,			)
								assert hasattr(self			,			'env'		)







						def __a						(							self   :    Optional[int]			,			_lowercase   :    int		):
								A					       = f'{self.env.base_job_name}-{instance_count}-{"ddp" if "ddp" in self.script else "smd"}'
								# distributed data settings
								A					       = {'smdistributed': {'dataparallel': {'enabled': True}}} if self.script != 'run_ddp.py' else None

								# creates estimator
								return HuggingFace(
								    entry_point=self.script			,			source_dir=self.env.test_path			,			role=self.env.role			,			image_uri=self.env.image_uri			,			base_job_name=_lowercase			,			instance_count=_lowercase			,			instance_type=self.instance_type			,			debugger_hook_config=_lowercase			,			hyperparameters={**self.env.distributed_hyperparameters, 'model_name_or_path': self.model_name_or_path}			,			metric_definitions=self.env.metric_definitions			,			distribution=_lowercase			,			py_version='py36'			,			)







						def __a						(							self   :    Tuple			,			_lowercase   :    List[str]		):
								TrainingJobAnalytics(_lowercase		).export_csv(f'{self.env.test_path}/{job_name}_metrics.csv'		)







						@parameterized.expand([(2,)]		)
						def __a						(							self   :    List[Any]			,			_lowercase   :    Union[str, Any]		):
								# create estimator
								A					       = self.create_estimator(_lowercase		)

								# run training
								estimator.fit()

								# result dataframe
								A					       = TrainingJobAnalytics(estimator.latest_training_job.name		).dataframe()

								# extract kpis
								A					       = list(result_metrics_df[result_metrics_df.metric_name == 'eval_accuracy']['value']		)
								A					       = list(result_metrics_df[result_metrics_df.metric_name == 'eval_loss']['value']		)
								# get train time from SageMaker job, this includes starting, preprocessing, stopping
								A					       = (
								    Session().describe_training_job(estimator.latest_training_job.name		).get('TrainingTimeInSeconds'			,			999_999		)
								)

								# assert kpis
								assert train_runtime <= self.results["train_runtime"]
								assert all(t >= self.results['eval_accuracy'] for t in eval_accuracy		)
								assert all(t <= self.results['eval_loss'] for t in eval_loss		)

								# dump tests result into json file to share in PR
								with open(f'{estimator.latest_training_job.name}.json'			,			'w'		) as outfile:
										json.dump({'train_time': train_runtime, 'eval_accuracy': eval_accuracy, 'eval_loss': eval_loss}			,			_lowercase		)





