



"""simple docstring"""





import logging
from pathlib import Path
from typing import Any, List, Tuple

import yaml


# loading package files: https://stackoverflow.com/a/20885799
try:
  import importlib.resources as pkg_resources
except ImportError:
  # Try backported to PY<37 `importlib_resources`.
  import importlib_resources as pkg_resources

from . import resources


SCREAMING_SNAKE_CASE				:     Optional[Any]          =	'''https://github.com/huggingface/datasets/tree/main/src/datasets/utils'''
SCREAMING_SNAKE_CASE				:     List[str]          =	F'{BASE_REF_URL}/{__file__}'
SCREAMING_SNAKE_CASE				:     int          =	logging.getLogger(__name__)






def 	__UpperCAmelCase					(       snake_case_  :  str   )							->	Tuple[Any, str]:






   """simple docstring"""


   _lowerCAmelCase					     =		pkg_resources.read_text(snake_case_   ,	snake_case_   )
   return yaml.safe_load(snake_case_   ), F"""{BASE_REF_URL}/resources/{resource}"""


SCREAMING_SNAKE_CASE    ,					SCREAMING_SNAKE_CASE				:     str          =	load_yaml_resource('''readme_structure.yaml''')

SCREAMING_SNAKE_CASE				:     Optional[int]          =	[
    '''[Needs More Information]''',
    '''[More Information Needed]''',
    '''(https://github.com/huggingface/datasets/blob/main/CONTRIBUTING.md#how-to-contribute-to-the-dataset-cards)''',
]

# Dictionary representation of section/readme, error_list, warning_list
SCREAMING_SNAKE_CASE				:     Any          =	Tuple[dict, List[str], List[str]]


class       __lowerCamelCase	:







   def __init__(self       ,	lowerCamelCase       ,	lowerCamelCase       ,	lowerCamelCase = None       ,	lowerCamelCase = False				):




      '''simple docstring'''




      _lowerCAmelCase					     =		name
      _lowerCAmelCase					     =		level
      _lowerCAmelCase					     =		lines
      _lowerCAmelCase					     =		""""""
      _lowerCAmelCase					     =		True
      _lowerCAmelCase					     =		{}
      _lowerCAmelCase					     =		[]
      _lowerCAmelCase					     =		[]
      if self.lines is not None:
         self.parse(suppress_parsing_errors=lowerCamelCase				)







   def 							A__						(self       ,	lowerCamelCase = False				):




      '''simple docstring'''




      _lowerCAmelCase					     =		""""""
      _lowerCAmelCase					     =		[]
      _lowerCAmelCase					     =		False
      for line in self.lines:
         if line.strip(""" \n"""				) == "":
            continue
         elif line.strip(""" \n"""				)[:3] == "```":
            _lowerCAmelCase					     =		not code_start
         elif line.split()[0] == self.level + "#" and not code_start:
            if current_sub_level != "":
               _lowerCAmelCase					     =		Section(lowerCamelCase       ,	self.level + """#"""       ,	lowerCamelCase				)
               _lowerCAmelCase					     =		[]
            else:
               if current_lines != []:
                  self.text += "".join(lowerCamelCase				).strip()
                  if self.text != "" and self.text not in FILLER_TEXT:
                     _lowerCAmelCase					     =		False
                  _lowerCAmelCase					     =		[]

            _lowerCAmelCase					     =		""" """.join(line.split()[1:]				).strip(""" \n"""				)
         else:
            current_lines.append(lowerCamelCase				)
      else:
         if current_sub_level != "":
            if current_sub_level in self.content:
               self.parsing_error_list.append(
                   f"""Multiple sections with the same heading `{current_sub_level}` have been found. Please keep only one of these sections."""				)
            _lowerCAmelCase					     =		Section(lowerCamelCase       ,	self.level + """#"""       ,	lowerCamelCase				)
         else:
            if current_lines != []:
               self.text += "".join(lowerCamelCase				).strip()
               if self.text != "" and self.text not in FILLER_TEXT:
                  _lowerCAmelCase					     =		False

      if self.level == "" and not suppress_parsing_errors:
         if self.parsing_error_list != [] or self.parsing_warning_list != []:
            _lowerCAmelCase					     =		_lowerCAmelCase					     =		"""\n""".join("""-\t""" + x for x in self.parsing_error_list + self.parsing_warning_list				)
            _lowerCAmelCase					     =		f"""The following issues were found while parsing the README at `{self.name}`:\n""" + errors
            raise ValueError(lowerCamelCase				)







   def 							A__						(self       ,	lowerCamelCase				):




      '''simple docstring'''




      _lowerCAmelCase					     =		[]
      _lowerCAmelCase					     =		[]
      if structure["allow_empty"] is False:
         # If content is expected
         if self.is_empty_text and self.content == {}:
            # If no content is found, mention it in the error_list
            error_list.append(f"""Expected some content in section `{self.name}` but it is empty."""				)

      if structure["allow_empty_text"] is False:
         # If some text is expected
         if self.is_empty_text:
            # If no text is found, mention it in the error_list
            error_list.append(
                f"""Expected some text in section `{self.name}` but it is empty (text in subsections are ignored)."""				)
        # Subsections Validation
      if structure["subsections"] is not None:
         # If subsections are expected
         if self.content == {}:
            # If no subsections are present
            _lowerCAmelCase					     =		[subsection["""name"""] for subsection in structure["""subsections"""]]
            # Mention the expected values in the error_list
            error_list.append(
                f"""Section `{self.name}` expected the following subsections: {", ".join(["`"+x+"`" for x in values]				)}. Found 'None'."""				)
         else:
            # If some subsections are present
            _lowerCAmelCase					     =		[subsection["""name"""] for subsection in structure["""subsections"""]]
            _lowerCAmelCase					     =		False
            for idx, name in enumerate(lowerCamelCase				):
               if name not in self.content:
                  # If the expected subsection is not present
                  error_list.append(f"""Section `{self.name}` is missing subsection: `{name}`."""				)
                  _lowerCAmelCase					     =		True
               else:
                  # If the subsection is present, validate subsection, return the result
                  # and concat the errors from subsection to section error_list

                  # Skip sublevel validation if current level is `###`
                  if self.level == "###":
                     continue
                  else:
                     _lowerCAmelCase     ,						_lowerCAmelCase     ,						_lowerCAmelCase					     =		self.content[name].validate(
                         structure["""subsections"""][idx]				)
                  error_list += subsec_error_list
                  warning_list += subsec_warning_list

            if has_missing_subsections:  # we only allow to have extra subsections if all the other ones are here
               for name in self.content:
                  if name not in structure_names:
                     # If an extra subsection is present
                     warning_list.append(
                         f"""`{self.name}` has an extra subsection: `{name}`. Skipping further validation checks for this subsection as expected structure is unknown."""				)
      if error_list:
         # If there are errors, do not return the dictionary as it is invalid
         return {}, error_list, warning_list
      else:
         return self.to_dict(), error_list, warning_list







   def 							A__						(self				):




      '''simple docstring'''




      return {
          "name": self.name,
          "text": self.text,
          "is_empty_text": self.is_empty_text,
          "subsections": [value.to_dict() for value in self.content.values()],
      }





class       __lowerCamelCase	(   __lowercase    ):  # Level 0







   def __init__(self       ,	lowerCamelCase       ,	lowerCamelCase       ,	lowerCamelCase = None       ,	lowerCamelCase = False				):




      '''simple docstring'''




      super().__init__(name=lowerCamelCase       ,	level=""""""				)  # Not using lines here as we need to use a child class parse
      _lowerCAmelCase					     =		structure
      _lowerCAmelCase					     =		-2
      _lowerCAmelCase					     =		0
      _lowerCAmelCase					     =		lines
      if self.lines is not None:
         self.parse(suppress_parsing_errors=lowerCamelCase				)







   def 							A__						(self				):




      '''simple docstring'''




      if self.structure is None:
         _lowerCAmelCase     ,						_lowerCAmelCase     ,						_lowerCAmelCase					     =		self._validate(lowerCamelCase				)
      else:
         _lowerCAmelCase     ,						_lowerCAmelCase     ,						_lowerCAmelCase					     =		self._validate(self.structure				)
      if error_list != [] or warning_list != []:
         _lowerCAmelCase					     =		"""\n""".join(["""-\t""" + x for x in error_list + warning_list]				)
         _lowerCAmelCase					     =		f"""The following issues were found for the README at `{self.name}`:\n""" + errors
         raise ValueError(lowerCamelCase				)







   @classmethod
   def 							A__						(cls       ,	lowerCamelCase       ,	lowerCamelCase = None       ,	lowerCamelCase = False				):




      '''simple docstring'''




      with open(lowerCamelCase       ,	encoding="""utf-8"""				) as f:
         _lowerCAmelCase					     =		f.readlines()
      return cls(lowerCamelCase       ,	lowerCamelCase       ,	lowerCamelCase       ,	suppress_parsing_errors=lowerCamelCase				)







   @classmethod
   def 							A__						(cls       ,	lowerCamelCase       ,	lowerCamelCase = None       ,	lowerCamelCase = "root"       ,	lowerCamelCase = False				):




      '''simple docstring'''




      _lowerCAmelCase					     =		string.split("""\n"""				)
      return cls(lowerCamelCase       ,	lowerCamelCase       ,	lowerCamelCase       ,	suppress_parsing_errors=lowerCamelCase				)







   def 							A__						(self       ,	lowerCamelCase = False				):




      '''simple docstring'''




      _lowerCAmelCase					     =		0

      for line in self.lines:
         self.yaml_tags_line_count += 1
         if line.strip(""" \n"""				) == "---":
            self.tag_count += 1
            if self.tag_count == 2:
               break
         line_count += 1
      if self.tag_count == 2:
         _lowerCAmelCase					     =		self.lines[line_count + 1 :]  # Get the last + 1 th item.
      else:
         _lowerCAmelCase					     =		self.lines[self.tag_count :]
      super().parse(suppress_parsing_errors=lowerCamelCase				)







   def __str__(self				):




      '''simple docstring'''




      return str(self.to_dict()				)







   def 							A__						(self       ,	lowerCamelCase				):




      '''simple docstring'''




      _lowerCAmelCase					     =		[]
      _lowerCAmelCase					     =		[]
      if self.yaml_tags_line_count == 0:
         warning_list.append("""Empty YAML markers are present in the README."""				)
      elif self.tag_count == 0:
         warning_list.append("""No YAML markers are present in the README."""				)
      elif self.tag_count == 1:
         warning_list.append("""Only the start of YAML tags present in the README."""				)
      # Check how many first level sections are present.
      _lowerCAmelCase					     =		len(self.content.keys()				)
      if num_first_level_keys > 1:
         # If more than one, add to the error list, continue
         error_list.append(
             f"""The README has several first-level headings: {", ".join(["`"+x+"`" for x in list(self.content.keys()				)]				)}. Only one heading is expected. Skipping further validation for this README."""				)
      elif num_first_level_keys < 1:
         # If less than one, append error.
         error_list.append(
             """The README has no first-level headings. One heading is expected. Skipping further validation for this README."""				)

      else:
         # If one exactly
         _lowerCAmelCase					     =		list(self.content.keys()				)[0]  # Get the key
         if start_key.startswith("""Dataset Card for"""				):  # Check correct start
            # If the starting is correct, validate all the sections
            _lowerCAmelCase     ,						_lowerCAmelCase     ,						_lowerCAmelCase					     =		self.content[start_key].validate(
                readme_structure["""subsections"""][0]				)
            error_list += sec_error_list
            warning_list += sec_warning_list
         else:
            # If not found, append error
            error_list.append(
                """No first-level heading starting with `Dataset Card for` found in README. Skipping further validation for this README."""				)
      if error_list:
         # If there are errors, do not return the dictionary as it is invalid
         return {}, error_list, warning_list
      else:
         return self.to_dict(), error_list, warning_list


if __name__ == "__main__":
  from argparse import ArgumentParser

  SCREAMING_SNAKE_CASE				:     str          =	ArgumentParser(usage='''Validate the content (excluding YAML tags) of a README.md file.''')
  ap.add_argument('''readme_filepath''')
  SCREAMING_SNAKE_CASE				:     List[str]          =	ap.parse_args()
  SCREAMING_SNAKE_CASE				:     int          =	Path(args.readme_filepath)
  SCREAMING_SNAKE_CASE				:     Optional[Any]          =	ReadMe.from_readme(readme_filepath)




"""simple docstring"""





from typing import TYPE_CHECKING

from ...utils import (
    OptionalDependencyNotAvailable,
    _LazyModule,
    is_torch_available,
)


SCREAMING_SNAKE_CASE				:     Union[str, Any]          =	{
    '''configuration_align''': [
        '''ALIGN_PRETRAINED_CONFIG_ARCHIVE_MAP''',
        '''AlignConfig''',
        '''AlignTextConfig''',
        '''AlignVisionConfig''',
    ],
    '''processing_align''': ['''AlignProcessor'''],
}

try:
  if not is_torch_available():
    raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
  pass
else:
  SCREAMING_SNAKE_CASE				:     Any          =	[
      '''ALIGN_PRETRAINED_MODEL_ARCHIVE_LIST''',
      '''AlignModel''',
      '''AlignPreTrainedModel''',
      '''AlignTextModel''',
      '''AlignVisionModel''',
  ]

if TYPE_CHECKING:
  from .configuration_align import (
      ALIGN_PRETRAINED_CONFIG_ARCHIVE_MAP,
      AlignConfig,
      AlignTextConfig,
      AlignVisionConfig,
  )
  from .processing_align import AlignProcessor

  try:
    if not is_torch_available():
      raise OptionalDependencyNotAvailable()
  except OptionalDependencyNotAvailable:
    pass
  else:
    from .modeling_align import (
        ALIGN_PRETRAINED_MODEL_ARCHIVE_LIST,
        AlignModel,
        AlignPreTrainedModel,
        AlignTextModel,
        AlignVisionModel,
    )

else:
  import sys

  SCREAMING_SNAKE_CASE				:     Any          =	_LazyModule(__name__, globals()['''__file__'''], _import_structure, module_spec=__spec__)