
"""simple docstring"""






import collections
import importlib.util
import os
import re
from pathlib import Path


__UpperCAmelCase       =  'src/transformers'


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






def 						_snake_case       (	lowercase__		:  Optional[Any]		)  ->				List[str]:


			'''simple docstring'''





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






def 						_snake_case       (	lowercase__		:  Union[str, Any]		)  ->				Union[str, Any]:


			'''simple docstring'''





			with open(lowercase__      ,     """r"""      ,     encoding="""utf-8"""      ,     newline="""\n"""		) as f:
						lowerCAmelCase_    :int			     =  f.readlines()

			lowerCAmelCase_    :Any			     =  0
			while line_index < len(lowercase__		) and not lines[line_index].startswith("""_import_structure = {"""		):
						line_index += 1

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

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

			lowerCAmelCase_    :Dict			     =  {"""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.
						lowerCAmelCase_    :Tuple			     =  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:
									lowerCAmelCase_    :List[Any]			     =  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

									lowerCAmelCase_    :List[str]			     =  []
									# Until we unindent, add backend objects to the list
									while len(lines[line_index]		) <= 1 or lines[line_index].startswith(""" """ * 4		):
												lowerCAmelCase_    :List[Any]			     =  lines[line_index]
												if _re_import_struct_add_one.search(lowercase__		) is not None:
															objects.append(_re_import_struct_add_one.search(lowercase__		).groups()[0]		)
												elif _re_import_struct_add_many.search(lowercase__		) is not None:
															lowerCAmelCase_    :Union[str, Any]			     =  _re_import_struct_add_many.search(lowercase__		).groups()[0].split(""", """		)
															lowerCAmelCase_    :Any			     =  [obj[1:-1] for obj in imports if len(lowercase__		) > 0]
															objects.extend(lowercase__		)
												elif _re_between_brackets.search(lowercase__		) is not None:
															lowerCAmelCase_    :Optional[int]			     =  _re_between_brackets.search(lowercase__		).groups()[0].split(""", """		)
															lowerCAmelCase_    :Optional[int]			     =  [obj[1:-1] for obj in imports if len(lowercase__		) > 0]
															objects.extend(lowercase__		)
												elif _re_quote_object.search(lowercase__		) is not None:
															objects.append(_re_quote_object.search(lowercase__		).groups()[0]		)
												elif line.startswith(""" """ * 8 + """\""""		):
															objects.append(line[9:-3]		)
												elif line.startswith(""" """ * 1_2 + """\""""		):
															objects.append(line[1_3:-3]		)
												line_index += 1

									lowerCAmelCase_    :List[Any]			     =  objects
						else:
									line_index += 1

    # At this stage we are in the TYPE_CHECKING part, first grab the objects without a specific backend
			lowerCAmelCase_    :Union[str, Any]			     =  []
			while (
			    line_index < len(lowercase__		)
			    and find_backend(lines[line_index]		) is None
			    and not lines[line_index].startswith("""else"""		)
			):
						lowerCAmelCase_    :str			     =  lines[line_index]
						lowerCAmelCase_    :Union[str, Any]			     =  _re_import.search(lowercase__		)
						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

			lowerCAmelCase_    :Any			     =  {"""none""": objects}
			# Let's continue with backend-specific objects
			while line_index < len(lowercase__		):
						# If the line is an if is_backend_available, we grab all objects associated.
						lowerCAmelCase_    :Union[str, Any]			     =  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:
									lowerCAmelCase_    :int			     =  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

									lowerCAmelCase_    :List[Any]			     =  []
									# Until we unindent, add backend objects to the list
									while len(lines[line_index]		) <= 1 or lines[line_index].startswith(""" """ * 8		):
												lowerCAmelCase_    :Union[str, Any]			     =  lines[line_index]
												lowerCAmelCase_    :Optional[int]			     =  _re_import.search(lowercase__		)
												if single_line_import_search is not None:
															objects.extend(single_line_import_search.groups()[0].split(""", """		)		)
												elif line.startswith(""" """ * 1_2		):
															objects.append(line[1_2:-2]		)
												line_index += 1

									lowerCAmelCase_    :Union[str, Any]			     =  objects
						else:
									line_index += 1

			return import_dict_objects, type_hint_objects






def 						_snake_case       (	lowercase__		:  int      ,     lowercase__		:  List[Any]		)  ->				Any:


			'''simple docstring'''





			def find_duplicates(lowercase__		:  Union[str, Any]		):
						return [k for k, v in collections.Counter(lowercase__		).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!"]

			lowerCAmelCase_    :Any			     =  []
			for key in import_dict_objects.keys():
						lowerCAmelCase_    :Any			     =  find_duplicates(import_dict_objects[key]		)
						if duplicate_imports:
									errors.append(f"""Duplicate _import_structure definitions for: {duplicate_imports}"""		)
						lowerCAmelCase_    :List[str]			     =  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]		)		):
									lowerCAmelCase_    :List[Any]			     =  """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'''





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






def 						_snake_case       (	)  ->				List[str]:


			'''simple docstring'''





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


__UpperCAmelCase       =  [
    'convert_pytorch_checkpoint_to_tf2',
    'modeling_flax_pytorch_utils',
]






def 						_snake_case       (	)  ->				Union[str, Any]:


			'''simple docstring'''





			lowerCAmelCase_    :int			     =  importlib.util.spec_from_file_location(
			    """transformers"""      ,     os.path.join(lowercase__      ,     """__init__.py"""		)      ,     submodule_search_locations=[PATH_TO_TRANSFORMERS]      ,     )
			lowerCAmelCase_    :List[Any]			     =  spec.loader.load_module()

			lowerCAmelCase_    :List[Any]			     =  [
			    module
			    for module in get_transformers_submodules()
			    if module not in IGNORE_SUBMODULES and module not in transformers._import_structure.keys()
			]
			if len(lowercase__		) > 0:
						lowerCAmelCase_    :Optional[int]			     =  """\n""".join(f"""- {module}""" for module in module_not_registered		)
						raise ValueError(
						    """The following submodules are not properly registered 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()












def    A						(__A   :    list   ,				__A   :    int   ,				__A   :    int = 0   ,				__A   :    int = 0       )   ->      int:







     """simple docstring"""


     UpperCAmelCase_          =							right or len(__A       ) - 1
     if left > right:
          return -1
     elif list_data[left] == key:
          return left
     elif list_data[right] == key:
          return right
     else:
          return search(__A   ,				__A   ,				left + 1   ,				right - 1       )


if __name__ == "__main__":
    import doctest

    doctest.testmod()






