
'''simple docstring'''






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


A			      =      'src/transformers'


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





def    UpperCAmelCase							(  UpperCAmelCase__							:							Optional[int]):
				if _re_test_backend.search(UpperCAmelCase__) is None:
								return None
				lowerCamelCase					:			Optional[Any]									= [b[0] for b in _re_backend.findall(UpperCAmelCase__)]
				backends.sort()
				return "_and_".join(UpperCAmelCase__)





def    UpperCAmelCase							(  UpperCAmelCase__							:							Any):
				with open(UpperCAmelCase__       ,							'r'       ,							encoding='utf-8'       ,							newline='\n') as f:
								lowerCamelCase					:			int									= f.readlines()

				lowerCamelCase					:			str									= 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
				lowerCamelCase					:			Any									= []
				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(UpperCAmelCase__):
												lowerCamelCase					:			List[Any]									= _re_one_line_import_struct.search(UpperCAmelCase__).groups()[0]
												lowerCamelCase					:			List[str]									= re.findall('\[([^\]]+)\]'       ,							UpperCAmelCase__)
												for imp in imports:
																objects.extend([obj[1:-1] for obj in imp.split(', ')])
												line_index += 1
												continue
								lowerCamelCase					:			Optional[int]									= _re_import_struct_key_value.search(UpperCAmelCase__)
								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(UpperCAmelCase__) > 0]
												objects.extend(UpperCAmelCase__)
								elif line.startswith(' ' * 8 + '"'):
												objects.append(line[9:-3])
								line_index += 1

				lowerCamelCase					:			Tuple									= {'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					:			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					:			Union[str, 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					:			int									= []
												# Until we unindent, add backend objects to the list
												while len(lines[line_index]) <= 1 or lines[line_index].startswith(' ' * 4):
																lowerCamelCase					:			int									= 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:
																				lowerCamelCase					:			Optional[Any]									= _re_import_struct_add_many.search(UpperCAmelCase__).groups()[0].split(', ')
																				lowerCamelCase					:			Optional[int]									= [obj[1:-1] for obj in imports if len(UpperCAmelCase__) > 0]
																				objects.extend(UpperCAmelCase__)
																elif _re_between_brackets.search(UpperCAmelCase__) is not None:
																				lowerCamelCase					:			Any									= _re_between_brackets.search(UpperCAmelCase__).groups()[0].split(', ')
																				lowerCamelCase					:			str									= [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

												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					:			Any									= []
				while (
				    line_index < len(UpperCAmelCase__)
				    and find_backend(lines[line_index]) is None
				    and not lines[line_index].startswith('else')
				):
								lowerCamelCase					:			int									= lines[line_index]
								lowerCamelCase					:			List[str]									= _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

				lowerCamelCase					:			Dict									= {'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.
								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					:			Union[str, 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					:			Union[str, Any]									= []
												# Until we unindent, add backend objects to the list
												while len(lines[line_index]) <= 1 or lines[line_index].startswith(' ' * 8):
																lowerCamelCase					:			Optional[int]									= lines[line_index]
																lowerCamelCase					:			Tuple									= _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

												lowerCamelCase					:			Optional[Any]									= objects
								else:
												line_index += 1

				return import_dict_objects, type_hint_objects





def    UpperCAmelCase							(  UpperCAmelCase__							:							Optional[Any]       ,							UpperCAmelCase__							:							Optional[int]):

				def find_duplicates(UpperCAmelCase__							:							List[str]):
								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!"]

				lowerCamelCase					:			int									= []
				for key in import_dict_objects.keys():
								lowerCamelCase					:			int									= find_duplicates(import_dict_objects[key])
								if duplicate_imports:
												errors.append(F'''Duplicate _import_structure definitions for: {duplicate_imports}''')
								lowerCamelCase					:			Dict									= 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[str]									= '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    UpperCAmelCase							(  ):
				lowerCamelCase					:			Dict									= []
				for root, _, files in os.walk(UpperCAmelCase__):
								if "__init__.py" in files:
												lowerCamelCase					:			Dict									= os.path.join(UpperCAmelCase__       ,							'__init__.py')
												lowerCamelCase					:			List[Any]									= parse_init(UpperCAmelCase__)
												if objects is not None:
																lowerCamelCase					:			Dict									= analyze_results(*UpperCAmelCase__)
																if len(UpperCAmelCase__) > 0:
																				lowerCamelCase					:			List[Any]									= 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    UpperCAmelCase							(  ):
				lowerCamelCase					:			Optional[int]									= []
				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
												lowerCamelCase					:			Any									= str((Path(UpperCAmelCase__) / folder).relative_to(UpperCAmelCase__))
												lowerCamelCase					:			Optional[int]									= short_path.replace(os.path.sep       ,							'.')
												submodules.append(UpperCAmelCase__)
								for fname in files:
												if fname == "__init__.py":
																continue
												lowerCamelCase					:			Dict									= str((Path(UpperCAmelCase__) / fname).relative_to(UpperCAmelCase__))
												lowerCamelCase					:			Dict									= short_path.replace('.py'       ,							'').replace(os.path.sep       ,							'.')
												if len(submodule.split('.')) == 1:
																submodules.append(UpperCAmelCase__)
				return submodules


A			      =      [
    'convert_pytorch_checkpoint_to_tf2',
    'modeling_flax_pytorch_utils',
]





def    UpperCAmelCase							(  ):
				# This is to make sure the transformers module imported is the one in the repo.
				lowerCamelCase					:			Tuple									= importlib.util.spec_from_file_location(
				    'transformers'       ,							os.path.join(UpperCAmelCase__       ,							'__init__.py')       ,							submodule_search_locations=[PATH_TO_TRANSFORMERS]       ,							)
				lowerCamelCase					:			int									= spec.loader.load_module()

				lowerCamelCase					:			List[str]									= [
				    module
				    for module in get_transformers_submodules()
				    if module not in IGNORE_SUBMODULES and module not in transformers._import_structure.keys()
				]
				if len(UpperCAmelCase__) > 0:
								lowerCamelCase					:			Tuple									= '\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()





'''simple docstring'''






import importlib.metadata
import operator
import re
import sys
from typing import Optional

from packaging import version


A			      =      {
    '<': operator.lt,
    '<=': operator.le,
    '==': operator.eq,
    '!=': operator.ne,
    '>=': operator.ge,
    '>': operator.gt,
}





def    UpperCAmelCase							(  UpperCAmelCase__							:							Optional[Any]       ,							UpperCAmelCase__							:							Optional[Any]       ,							UpperCAmelCase__							:							Union[str, Any]       ,							UpperCAmelCase__							:							List[Any]       ,							UpperCAmelCase__							:							Dict       ,							UpperCAmelCase__							:							Optional[int]):
				if got_ver is None or want_ver is None:
								raise ValueError(
								    F'''Unable to compare versions for {requirement}: need={want_ver} found={got_ver}. This is unusual. Consider'''
								    F''' reinstalling {pkg}.''')
				if not ops[op](version.parse(UpperCAmelCase__)       ,							version.parse(UpperCAmelCase__)):
								raise ImportError(
								    F'''{requirement} is required for a normal functioning of this module, but found {pkg}=={got_ver}.{hint}''')





def    UpperCAmelCase							(  UpperCAmelCase__							:							str       ,							UpperCAmelCase__							:							Optional[str] = None):
				lowerCamelCase					:			List[Any]									= F'''\n{hint}''' if hint is not None else ''

				# non-versioned check
				if re.match(R'^[\w_\-\d]+$'       ,							UpperCAmelCase__):
								lowerCamelCase			, lowerCamelCase			, lowerCamelCase					:			Optional[Any]									= requirement, None, None
				else:
								lowerCamelCase					:			Optional[Any]									= re.findall(R'^([^!=<>\s]+)([\s!=<>]{1,2}.+)'       ,							UpperCAmelCase__)
								if not match:
												raise ValueError(
												    'requirement needs to be in the pip package format, .e.g., package_a==1.23, or package_b>=1.23, but'
												    F''' got {requirement}''')
								lowerCamelCase			, lowerCamelCase					:			Dict									= match[0]
								lowerCamelCase					:			Dict									= want_full.split(',')  # there could be multiple requirements
								lowerCamelCase					:			Union[str, Any]									= {}
								for w in want_range:
												lowerCamelCase					:			int									= re.findall(R'^([\s!=<>]{1,2})(.+)'       ,							UpperCAmelCase__)
												if not match:
																raise ValueError(
																    'requirement needs to be in the pip package format, .e.g., package_a==1.23, or package_b>=1.23,'
																    F''' but got {requirement}''')
												lowerCamelCase			, lowerCamelCase					:			List[Any]									= match[0]
												lowerCamelCase					:			Optional[int]									= want_ver
												if op not in ops:
																raise ValueError(F'''{requirement}: need one of {list(ops.keys())}, but got {op}''')

    # special case
				if pkg == "python":
								lowerCamelCase					:			Optional[int]									= '.'.join([str(UpperCAmelCase__) for x in sys.version_info[:3]])
								for op, want_ver in wanted.items():
												_compare_versions(UpperCAmelCase__       ,							UpperCAmelCase__       ,							UpperCAmelCase__       ,							UpperCAmelCase__       ,							UpperCAmelCase__       ,							UpperCAmelCase__)
								return

				# check if any version is installed
				try:
								lowerCamelCase					:			Any									= importlib.metadata.version(UpperCAmelCase__)
				except importlib.metadata.PackageNotFoundError:
								raise importlib.metadata.PackageNotFoundError(
								    F'''The \'{requirement}\' distribution was not found and is required by this application. {hint}''')

				# check that the right version is installed if version number or a range was provided
				if want_ver is not None:
								for op, want_ver in wanted.items():
												_compare_versions(UpperCAmelCase__       ,							UpperCAmelCase__       ,							UpperCAmelCase__       ,							UpperCAmelCase__       ,							UpperCAmelCase__       ,							UpperCAmelCase__)





def    UpperCAmelCase							(  UpperCAmelCase__							:							str):
				lowerCamelCase					:			List[str]									= 'Try: pip install transformers -U or pip install -e \'.[dev]\' if you\'re working with git main'
				return require_version(UpperCAmelCase__       ,							UpperCAmelCase__)
