






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


lowerCamelCase										=  '''https://github.com/huggingface/datasets/tree/main/src/datasets/utils'''
lowerCamelCase										=  f"{BASE_REF_URL}/{__file__}"
lowerCamelCase										=  logging.getLogger(__name__)
def        UpperCAmelCase      (   _lowercase      ):


    '''simple docstring'''



    _lowercase     =	pkg_resources.read_text(_lowercase,      _lowercase      )
    return yaml.safe_load(_lowercase      ), f'''{BASE_REF_URL}/resources/{resource}'''


lowerCamelCase						,		lowerCamelCase										=  load_yaml_resource('''readme_structure.yaml''')

lowerCamelCase										=  [
    '''[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
lowerCamelCase										=  Tuple[dict, List[str], List[str]]

class 					snake_case_							:







   """simple docstring"""



   def __init__(    self:	Optional[Any]   ,       snake_case__:	str   ,       snake_case__:	str   ,       snake_case__:	List[str] = None   ,       snake_case__:	bool = False	)  ->		Optional[Any]:


       """simple docstring"""



       _lowercase     =	name
       _lowercase     =	level
       _lowercase     =	lines
       _lowercase     =	''
       _lowercase     =	True
       _lowercase     =	{}
       _lowercase     =	[]
       _lowercase     =	[]
       if self.lines is not None:
           self.parse(suppress_parsing_errors=snake_case__	)

   def 			SCREAMING_SNAKE_CASE__				(    self:	Optional[int]   ,       snake_case__:	bool = False	)  ->		Tuple:


       """simple docstring"""



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

               _lowercase     =	' '.join(line.split()[1:]	).strip(' \n'	)
           else:
               current_lines.append(snake_case__	)
       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.'''	)
               _lowercase     =	Section(snake_case__   ,       self.level + '#'   ,       snake_case__	)
           else:
               if current_lines != []:
                   self.text += "".join(snake_case__	).strip()
                   if self.text != "" and self.text not in FILLER_TEXT:
                       _lowercase     =	False

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

   def 			SCREAMING_SNAKE_CASE__				(    self:	List[Any]   ,       snake_case__:	dict	)  ->		ReadmeValidatorOutput:


       """simple docstring"""



       _lowercase     =	[]
       _lowercase     =	[]
       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
               _lowercase     =	[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
               _lowercase     =	[subsection['name'] for subsection in structure['subsections']]
               _lowercase     =	False
               for idx, name in enumerate(snake_case__	):
                   if name not in self.content:
                       # If the expected subsection is not present
                       error_list.append(f'''Section `{self.name}` is missing subsection: `{name}`.'''	)
                       _lowercase     =	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:
                           _lowercase ,    _lowercase ,    _lowercase     =	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 			SCREAMING_SNAKE_CASE__				(    self:	int	)  ->		dict:


       """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 					snake_case_							(       lowercase_      ):  # Level 0







   """simple docstring"""



   def __init__(    self:	Tuple   ,       snake_case__:	str   ,       snake_case__:	List[str]   ,       snake_case__:	dict = None   ,       snake_case__:	bool = False	)  ->		Optional[Any]:


       """simple docstring"""



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

   def 			SCREAMING_SNAKE_CASE__				(    self:	Optional[Any]	)  ->		Union[str, Any]:


       """simple docstring"""



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

   @classmethod
   def 			SCREAMING_SNAKE_CASE__				(    cls:	int   ,       snake_case__:	Path   ,       snake_case__:	dict = None   ,       snake_case__:	bool = False	)  ->		Any:


       """simple docstring"""



       with open(snake_case__   ,       encoding='utf-8'	) as f:
           _lowercase     =	f.readlines()
       return cls(snake_case__   ,       snake_case__   ,       snake_case__   ,       suppress_parsing_errors=snake_case__	)

   @classmethod
   def 			SCREAMING_SNAKE_CASE__				(    cls:	Union[str, Any]   ,       snake_case__:	str   ,       snake_case__:	dict = None   ,       snake_case__:	str = "root"   ,       snake_case__:	bool = False	)  ->		Union[str, Any]:


       """simple docstring"""



       _lowercase     =	string.split('\n'	)
       return cls(snake_case__   ,       snake_case__   ,       snake_case__   ,       suppress_parsing_errors=snake_case__	)

   def 			SCREAMING_SNAKE_CASE__				(    self:	str   ,       snake_case__:	bool = False	)  ->		List[str]:


       """simple docstring"""



       _lowercase     =	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:
           _lowercase     =	self.lines[line_count + 1 :]  # Get the last + 1 th item.
       else:
           _lowercase     =	self.lines[self.tag_count :]
       super().parse(suppress_parsing_errors=snake_case__	)

   def __str__(    self:	Union[str, Any]	)  ->		Optional[Any]:


       """simple docstring"""



       return str(self.to_dict()	)

   def 			SCREAMING_SNAKE_CASE__				(    self:	str   ,       snake_case__:	Tuple	)  ->		Union[str, Any]:


       """simple docstring"""



       _lowercase     =	[]
       _lowercase     =	[]
       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.
       _lowercase     =	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
           _lowercase     =	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
               _lowercase ,    _lowercase ,    _lowercase     =	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

   lowerCamelCase										=  ArgumentParser(usage='''Validate the content (excluding YAML tags) of a README.md file.''')
   ap.add_argument('''readme_filepath''')
   lowerCamelCase										=  ap.parse_args()
   lowerCamelCase										=  Path(args.readme_filepath)
   lowerCamelCase										=  ReadMe.from_readme(readme_filepath)








from typing import Dict, List, Optional, Union

import numpy as np

from ...image_processing_utils import BaseImageProcessor, BatchFeature, get_size_dict
from ...image_transforms import center_crop, normalize, rescale, resize, to_channel_dimension_format
from ...image_utils import (
    IMAGENET_STANDARD_MEAN,
    IMAGENET_STANDARD_STD,
    ChannelDimension,
    ImageInput,
    PILImageResampling,
    make_list_of_images,
    to_numpy_array,
    valid_images,
)
from ...utils import TensorType, is_vision_available, logging


if is_vision_available():
   import PIL


lowerCamelCase										=  logging.get_logger(__name__)

class 					snake_case_							(       lowercase_      ):







   """simple docstring"""



   __lowerCAmelCase      =						["""pixel_values"""]

   def __init__(    self:	int   ,       snake_case__:	bool = True   ,       snake_case__:	Dict[str, int] = None   ,       snake_case__:	PILImageResampling = PIL.Image.NEAREST   ,       snake_case__:	bool = False   ,       snake_case__:	Dict[str, int] = None   ,       snake_case__:	Union[int, float] = 1 / 255   ,       snake_case__:	bool = False   ,       snake_case__:	bool = True   ,       snake_case__:	bool = True   ,       snake_case__:	Optional[Union[float, List[float]]] = None   ,       snake_case__:	Optional[Union[float, List[float]]] = None   ,       snake_case__:	bool = True   ,       **snake_case__:	Optional[Any]   ,       )  ->		None:


       """simple docstring"""



       super().__init__(**snake_case__	)
       _lowercase     =	size if size is not None else {'height': 346, 'width': 346}
       _lowercase     =	get_size_dict(snake_case__	)
       _lowercase     =	crop_size if crop_size is not None else {'height': 289, 'width': 289}
       _lowercase     =	get_size_dict(snake_case__   ,       param_name='crop_size'	)

       _lowercase     =	do_resize
       _lowercase     =	size
       _lowercase     =	resample
       _lowercase     =	do_center_crop
       _lowercase     =	crop_size
       _lowercase     =	do_rescale
       _lowercase     =	rescale_factor
       _lowercase     =	rescale_offset
       _lowercase     =	do_normalize
       _lowercase     =	image_mean if image_mean is not None else IMAGENET_STANDARD_MEAN
       _lowercase     =	image_std if image_std is not None else IMAGENET_STANDARD_STD
       _lowercase     =	include_top

   def 			SCREAMING_SNAKE_CASE__				(    self:	str   ,       snake_case__:	np.ndarray   ,       snake_case__:	Dict[str, int]   ,       snake_case__:	PILImageResampling = PIL.Image.NEAREST   ,       snake_case__:	Optional[Union[str, ChannelDimension]] = None   ,       **snake_case__:	Optional[int]   ,       )  ->		np.ndarray:


       """simple docstring"""



       _lowercase     =	get_size_dict(snake_case__	)
       if "height" not in size or "width" not in size:
           raise ValueError(f'''The size dictionary must have keys \'height\' and \'width\'. Got {size.keys()}'''	)
       return resize(
           snake_case__   ,       size=(size['height'], size['width'])   ,       resample=snake_case__   ,       data_format=snake_case__   ,       **snake_case__	)

   def 			SCREAMING_SNAKE_CASE__				(    self:	Optional[Any]   ,       snake_case__:	np.ndarray   ,       snake_case__:	Dict[str, int]   ,       snake_case__:	Optional[Union[str, ChannelDimension]] = None   ,       **snake_case__:	str   ,       )  ->		np.ndarray:


       """simple docstring"""



       _lowercase     =	get_size_dict(snake_case__	)
       if "height" not in size or "width" not in size:
           raise ValueError(f'''The size dictionary must have keys \'height\' and \'width\'. Got {size.keys()}'''	)
       return center_crop(snake_case__   ,       size=(size['height'], size['width'])   ,       data_format=snake_case__   ,       **snake_case__	)

   def 			SCREAMING_SNAKE_CASE__				(    self:	Optional[Any]   ,       snake_case__:	np.ndarray   ,       snake_case__:	Union[int, float]   ,       snake_case__:	bool = True   ,       snake_case__:	Optional[Union[str, ChannelDimension]] = None   ,       **snake_case__:	List[str]   ,       )  ->		Optional[int]:


       """simple docstring"""



       if offset:
           _lowercase     =	(image - 1_27.5) * scale
           if data_format is not None:
               _lowercase     =	to_channel_dimension_format(snake_case__   ,       snake_case__	)
           _lowercase     =	rescaled_image.astype(np.floataa	)
       else:
           _lowercase     =	rescale(snake_case__   ,       scale=snake_case__   ,       data_format=snake_case__   ,       **snake_case__	)
       return rescaled_image

   def 			SCREAMING_SNAKE_CASE__				(    self:	Dict   ,       snake_case__:	np.ndarray   ,       snake_case__:	Union[float, List[float]]   ,       snake_case__:	Union[float, List[float]]   ,       snake_case__:	Optional[Union[str, ChannelDimension]] = None   ,       **snake_case__:	Any   ,       )  ->		np.ndarray:


       """simple docstring"""



       return normalize(snake_case__   ,       mean=snake_case__   ,       std=snake_case__   ,       data_format=snake_case__   ,       **snake_case__	)

   def 			SCREAMING_SNAKE_CASE__				(    self:	Optional[int]   ,       snake_case__:	ImageInput   ,       snake_case__:	bool = None   ,       snake_case__:	Dict[str, int] = None   ,       snake_case__:	Union[str, Any]=None   ,       snake_case__:	bool = None   ,       snake_case__:	Dict[str, int] = None   ,       snake_case__:	bool = None   ,       snake_case__:	float = None   ,       snake_case__:	bool = None   ,       snake_case__:	bool = None   ,       snake_case__:	Optional[Union[float, List[float]]] = None   ,       snake_case__:	Optional[Union[float, List[float]]] = None   ,       snake_case__:	bool = None   ,       snake_case__:	Optional[Union[str, TensorType]] = None   ,       snake_case__:	ChannelDimension = ChannelDimension.FIRST   ,       **snake_case__:	int   ,       )  ->		PIL.Image.Image:


       """simple docstring"""



       _lowercase     =	do_resize if do_resize is not None else self.do_resize
       _lowercase     =	resample if resample is not None else self.resample
       _lowercase     =	do_center_crop if do_center_crop is not None else self.do_center_crop
       _lowercase     =	do_rescale if do_rescale is not None else self.do_rescale
       _lowercase     =	rescale_factor if rescale_factor is not None else self.rescale_factor
       _lowercase     =	rescale_offset if rescale_offset is not None else self.rescale_offset
       _lowercase     =	do_normalize if do_normalize is not None else self.do_normalize
       _lowercase     =	image_mean if image_mean is not None else self.image_mean
       _lowercase     =	image_std if image_std is not None else self.image_std
       _lowercase     =	include_top if include_top is not None else self.include_top

       _lowercase     =	size if size is not None else self.size
       _lowercase     =	get_size_dict(snake_case__	)
       _lowercase     =	crop_size if crop_size is not None else self.crop_size
       _lowercase     =	get_size_dict(snake_case__   ,       param_name='crop_size'	)

       _lowercase     =	make_list_of_images(snake_case__	)

       if not valid_images(snake_case__	):
           raise ValueError(
               'Invalid image type. Must be of type PIL.Image.Image, numpy.ndarray, '
               'torch.Tensor, tf.Tensor or jax.ndarray.'	)

       if do_resize and size is None or resample is None:
           raise ValueError('Size and resample must be specified if do_resize is True.'	)

       if do_center_crop and crop_size is None:
           raise ValueError('Crop size must be specified if do_center_crop is True.'	)

       if do_rescale and rescale_factor is None:
           raise ValueError('Rescale factor must be specified if do_rescale is True.'	)

       if do_normalize and (image_mean is None or image_std is None):
           raise ValueError('Image mean and std must be specified if do_normalize is True.'	)

       # All transformations expect numpy arrays.
       _lowercase     =	[to_numpy_array(snake_case__	) for image in images]

       if do_resize:
           _lowercase     =	[self.resize(image=snake_case__   ,       size=snake_case__   ,       resample=snake_case__	) for image in images]

       if do_center_crop:
           _lowercase     =	[self.center_crop(image=snake_case__   ,       size=snake_case__	) for image in images]

       if do_rescale:
           _lowercase     =	[self.rescale(image=snake_case__   ,       scale=snake_case__   ,       offset=snake_case__	) for image in images]

       if do_normalize:
           _lowercase     =	[self.normalize(image=snake_case__   ,       mean=snake_case__   ,       std=snake_case__	) for image in images]

       if include_top:
           _lowercase     =	[self.normalize(image=snake_case__   ,       mean=[0, 0, 0]   ,       std=snake_case__	) for image in images]

       _lowercase     =	[to_channel_dimension_format(snake_case__   ,       snake_case__	) for image in images]

       _lowercase     =	{'pixel_values': images}
       return BatchFeature(data=snake_case__   ,       tensor_type=snake_case__	)
