




import os
from argparse import ArgumentParser
from pathlib import Path
from shutil import copyfile, rmtree
from typing import Generator

import datasets.config
from datasets.builder import DatasetBuilder
from datasets.commands import BaseDatasetsCLICommand
from datasets.download.download_manager import DownloadMode
from datasets.load import dataset_module_factory, import_main_class
from datasets.utils.filelock import logger as fl_logger
from datasets.utils.info_utils import VerificationMode
from datasets.utils.logging import ERROR, get_logger


__A						:		Any          =						get_logger(__name__)





def      UpperCAmelCase  (						UpperCamelCase__   )     ->     Tuple:







				'''simple docstring'''


				return TestCommand(
				    args.dataset						,			args.name						,			args.cache_dir						,			args.data_dir						,			args.all_configs						,			args.save_info or args.save_infos						,			args.ignore_verifications						,			args.force_redownload						,			args.clear_cache						,			)

class 		lowercase_       (	lowerCAmelCase__				):
					__UpperCamelCase     	= False  # to tell pytest it's not a test class




					@staticmethod
					def     _lowercase						(   _lowercase:		ArgumentParser):


									'''simple docstring'''


									__lowerCAmelCase					=  parser.add_parser("""test""",     help="""Test dataset implementation.""")
									test_parser.add_argument("""--name""",     type=_lowercase,     default=_lowercase,     help="""Dataset processing name""")
									test_parser.add_argument(
									    """--cache_dir""",     type=_lowercase,     default=_lowercase,     help="""Cache directory where the datasets are stored.""",     )
									test_parser.add_argument(
									    """--data_dir""",     type=_lowercase,     default=_lowercase,     help="""Can be used to specify a manual directory to get the files from.""",     )
									test_parser.add_argument("""--all_configs""",     action="""store_true""",     help="""Test all dataset configurations""")
									test_parser.add_argument(
									    """--save_info""",     action="""store_true""",     help="""Save the dataset infos in the dataset card (README.md)""")
									test_parser.add_argument(
									    """--ignore_verifications""",     action="""store_true""",     help="""Run the test without checksums and splits checks.""",     )
									test_parser.add_argument("""--force_redownload""",     action="""store_true""",     help="""Force dataset redownload""")
									test_parser.add_argument(
									    """--clear_cache""",     action="""store_true""",     help="""Remove downloaded files and cached datasets after each config test""",     )
									# aliases
									test_parser.add_argument("""--save_infos""",     action="""store_true""",     help="""alias to save_info""")
									test_parser.add_argument("""dataset""",     type=_lowercase,     help="""Name of the dataset to download""")
									test_parser.set_defaults(func=_test_command_factory)




					def __init__(   self:		Optional[Any],     _lowercase:		str,     _lowercase:		str,     _lowercase:		str,     _lowercase:		str,     _lowercase:		bool,     _lowercase:		bool,     _lowercase:		bool,     _lowercase:		bool,     _lowercase:		bool,     ):


									'''simple docstring'''


									__lowerCAmelCase					=  dataset
									__lowerCAmelCase					=  name
									__lowerCAmelCase					=  cache_dir
									__lowerCAmelCase					=  data_dir
									__lowerCAmelCase					=  all_configs
									__lowerCAmelCase					=  save_infos
									__lowerCAmelCase					=  ignore_verifications
									__lowerCAmelCase					=  force_redownload
									__lowerCAmelCase					=  clear_cache
									if clear_cache and not cache_dir:
													print(
													    """When --clear_cache is used, specifying a cache directory is mandatory.\n"""
													    """The 'download' folder of the cache directory and the dataset builder cache will be deleted after each configuration test.\n"""
													    """Please provide a --cache_dir that will be used to test the dataset script.""")
													exit(1)
									if save_infos:
													__lowerCAmelCase					=  True







					def     _lowercase						(   self:		Union[str, Any]):


									'''simple docstring'''


									fl_logger().setLevel(_lowercase)
									if self._name is not None and self._all_configs:
													print("""Both parameters `config` and `all_configs` can't be used at once.""")
													exit(1)
									__lowerCAmelCase	,				__lowerCAmelCase					=  self._dataset, self._name
									__lowerCAmelCase					=  dataset_module_factory(_lowercase)
									__lowerCAmelCase					=  import_main_class(module.module_path)
									__lowerCAmelCase					=  len(builder_cls.BUILDER_CONFIGS) if self._all_configs and builder_cls.BUILDER_CONFIGS else 1

									def get_builders() -> Generator[DatasetBuilder, None, None]:
													if self._all_configs and builder_cls.BUILDER_CONFIGS:
																	for i, config in enumerate(builder_cls.BUILDER_CONFIGS):
																					if "config_name" in module.builder_kwargs:
																									yield builder_cls(
																									    cache_dir=self._cache_dir,     data_dir=self._data_dir,     **module.builder_kwargs,     )
																					else:
																									yield builder_cls(
																									    config_name=config.name,     cache_dir=self._cache_dir,     data_dir=self._data_dir,     **module.builder_kwargs,     )
													else:
																	if "config_name" in module.builder_kwargs:
																					yield builder_cls(cache_dir=self._cache_dir,     data_dir=self._data_dir,     **module.builder_kwargs)
																	else:
																					yield builder_cls(
																					    config_name=_lowercase,     cache_dir=self._cache_dir,     data_dir=self._data_dir,     **module.builder_kwargs,     )

									for j, builder in enumerate(get_builders()):
													print(f'''Testing builder \'{builder.config.name}\' ({j + 1}/{n_builders})''')
													__lowerCAmelCase					=  os.path.exists(
													    os.path.join(builder.get_imported_module_dir(),     datasets.config.DATASETDICT_INFOS_FILENAME))  # record checksums only if we need to update a (deprecated) dataset_infos.json
													builder.download_and_prepare(
													    download_mode=DownloadMode.REUSE_CACHE_IF_EXISTS
													    if not self._force_redownload
													    else DownloadMode.FORCE_REDOWNLOAD,     verification_mode=VerificationMode.NO_CHECKS
													    if self._ignore_verifications
													    else VerificationMode.ALL_CHECKS,     try_from_hf_gcs=_lowercase,     )
													builder.as_dataset()
													if self._save_infos:
																	builder._save_infos()

													# If save_infos=True, the dataset card (README.md) is created next to the loaded module file.
													# The dataset_infos are saved in the YAML part of the README.md

													# Let's move it to the original directory of the dataset script, to allow the user to
													# upload them on S3 at the same time afterwards.
													if self._save_infos:
																	__lowerCAmelCase					=  os.path.join(builder_cls.get_imported_module_dir(),     """README.md""")
																	__lowerCAmelCase					=  Path(_lowercase).name + """.py"""
																	__lowerCAmelCase					=  os.path.join(_lowercase,     _lowercase)
																	if os.path.isfile(_lowercase):
																					__lowerCAmelCase					=  os.path.dirname(_lowercase)
																	elif os.path.isfile(_lowercase):
																					__lowerCAmelCase					=  path
																	elif os.path.isdir(_lowercase):  # for local directories containing only data files
																					__lowerCAmelCase					=  path
																	else:  # in case of a remote dataset
																					__lowerCAmelCase					=  None
																					print(f'''Dataset card saved at {dataset_readme_path}''')

																	# Move dataset_info back to the user
																	if dataset_dir is not None:
																					__lowerCAmelCase					=  os.path.join(_lowercase,     """README.md""")
																					copyfile(_lowercase,     _lowercase)
																					print(f'''Dataset card saved at {user_dataset_readme_path}''')

            # If clear_cache=True, the download folder and the dataset builder cache directory are deleted
													if self._clear_cache:
																	if os.path.isdir(builder._cache_dir):
																					logger.warning(f'''Clearing cache at {builder._cache_dir}''')
																					rmtree(builder._cache_dir)
																	__lowerCAmelCase					=  os.path.join(self._cache_dir,     datasets.config.DOWNLOADED_DATASETS_DIR)
																	if os.path.isdir(_lowercase):
																					logger.warning(f'''Clearing cache at {download_dir}''')
																					rmtree(_lowercase)

									print("""Test successful.""")









'''simple docstring'''






import json
import os
import re
import unicodedata
from typing import Optional, Tuple

from ...tokenization_utils import PreTrainedTokenizer, _is_control, _is_punctuation, _is_whitespace
from ...utils import logging


a_       :     Tuple 							=     logging.get_logger(__name__)

a_       :     Optional[Any] 							=     {
    "vocab_file": "vocab.json",
    "merges_file": "merges.txt",
}

a_       :     str 							=     {
    "vocab_file": {"openai-gpt": "https://huggingface.co/openai-gpt/resolve/main/vocab.json"},
    "merges_file": {"openai-gpt": "https://huggingface.co/openai-gpt/resolve/main/merges.txt"},
}

a_       :     Union[str, Any] 							=     {
    "openai-gpt": 5_1_2,
}






def 						_A					(lowerCAmelCase__	:Any		) ->	int:




     '''simple docstring'''



     _a         =				text.strip()
     if not text:
          return []
     _a         =				text.split()
     return tokens




class 			a  (  _SCREAMING_SNAKE_CASE							):
 def __init__(			self   ,					__magic_name__=True   ,					__magic_name__=None   ,					__magic_name__=True   ,					__magic_name__=None   ,					__magic_name__=True   ,					)       ->				Optional[Any]:
      if never_split is None:
           _a         =				[]
      _a         =				do_lower_case
      _a         =				set(__magic_name__    )
      _a         =				tokenize_chinese_chars
      _a         =				strip_accents
      _a         =				do_split_on_punc
 def 				__UpperCAmelCase		(			self   ,					__magic_name__   ,					__magic_name__=None    )       ->				List[str]:
      _a         =				self.never_split.union(set(__magic_name__    )    ) if never_split else self.never_split
      _a         =				self._clean_text(__magic_name__    )

      # This was added on November 1st, 2018 for the multilingual and Chinese
      # models. This is also applied to the English models now, but it doesn't
      # matter since the English models were not trained on any Chinese data
      # and generally don't have any Chinese data in them (there are Chinese
      # characters in the vocabulary because Wikipedia does have some Chinese
      # words in the English Wikipedia.).
      if self.tokenize_chinese_chars:
           _a         =				self._tokenize_chinese_chars(__magic_name__    )
      # prevents treating the same character with different unicode codepoints as different characters
      _a         =				unicodedata.normalize('NFC'   ,					__magic_name__    )
      _a         =				whitespace_tokenize(__magic_name__    )
      _a         =				[]
      for token in orig_tokens:
           if token not in never_split:
                if self.do_lower_case:
                     _a         =				token.lower()
                     if self.strip_accents is not False:
                          _a         =				self._run_strip_accents(__magic_name__    )
                elif self.strip_accents:
                     _a         =				self._run_strip_accents(__magic_name__    )
           split_tokens.extend(self._run_split_on_punc(__magic_name__   ,					__magic_name__    )    )

      _a         =				whitespace_tokenize(' '.join(__magic_name__    )    )
      return output_tokens
 def 				__UpperCAmelCase		(			self   ,					__magic_name__    )       ->				List[str]:
      _a         =				unicodedata.normalize('NFD'   ,					__magic_name__    )
      _a         =				[]
      for char in text:
           _a         =				unicodedata.category(__magic_name__    )
           if cat == "Mn":
                continue
           output.append(__magic_name__    )
      return "".join(__magic_name__    )
 def 				__UpperCAmelCase		(			self   ,					__magic_name__   ,					__magic_name__=None    )       ->				Dict:
      if not self.do_split_on_punc or (never_split is not None and text in never_split):
           return [text]
      _a         =				list(__magic_name__    )
      _a         =				0
      _a         =				True
      _a         =				[]
      while i < len(__magic_name__    ):
           _a         =				chars[i]
           if _is_punctuation(__magic_name__    ):
                output.append([char]    )
                _a         =				True
           else:
                if start_new_word:
                     output.append([]    )
                _a         =				False
                output[-1].append(__magic_name__    )
           i += 1

      return ["".join(__magic_name__    ) for x in output]
 def 				__UpperCAmelCase		(			self   ,					__magic_name__    )       ->				Tuple:
      _a         =				[]
      for char in text:
           _a         =				ord(__magic_name__    )
           if self._is_chinese_char(__magic_name__    ):
                output.append(' '    )
                output.append(__magic_name__    )
                output.append(' '    )
           else:
                output.append(__magic_name__    )
      return "".join(__magic_name__    )
 def 				__UpperCAmelCase		(			self   ,					__magic_name__    )       ->				Union[str, Any]:
      # This defines a "chinese character" as anything in the CJK Unicode block:
      #   https://en.wikipedia.org/wiki/CJK_Unified_Ideographs_(Unicode_block)
      #
      # Note that the CJK Unicode block is NOT all Japanese and Korean characters,
      # despite its name. The modern Korean Hangul alphabet is a different block,
      # as is Japanese Hiragana and Katakana. Those alphabets are used to write
      # space-separated words, so they are not treated specially and handled
      # like the all of the other languages.
      if (
          (cp >= 0x4E00 and cp <= 0x9FFF)
          or (cp >= 0x3400 and cp <= 0x4DBF)  #
          or (cp >= 0x2_0000 and cp <= 0x2_A6DF)  #
          or (cp >= 0x2_A700 and cp <= 0x2_B73F)  #
          or (cp >= 0x2_B740 and cp <= 0x2_B81F)  #
          or (cp >= 0x2_B820 and cp <= 0x2_CEAF)  #
          or (cp >= 0xF900 and cp <= 0xFAFF)
          or (cp >= 0x2_F800 and cp <= 0x2_FA1F)  #
      ):  #
           return True

      return False




 def 				__UpperCAmelCase		(			self   ,					__magic_name__    )       ->				Any:
      _a         =				[]
      for char in text:
           _a         =				ord(__magic_name__    )
           if cp == 0 or cp == 0xFFFD or _is_control(__magic_name__    ):
                continue
           if _is_whitespace(__magic_name__    ):
                output.append(' '    )
           else:
                output.append(__magic_name__    )
      return "".join(__magic_name__    )






def 						_A					(lowerCAmelCase__	:str		) ->	Tuple:




     '''simple docstring'''



     _a         =				set()
     _a         =				word[0]
     for char in word[1:]:
          pairs.add((prev_char, char)		)
          _a         =				char
     return pairs






def 						_A					(lowerCAmelCase__	:Tuple		) ->	Union[str, Any]:




     '''simple docstring'''



     _a         =				text.replace('—'					,    '-'		)
     _a         =				text.replace('–'					,    '-'		)
     _a         =				text.replace('―'					,    '-'		)
     _a         =				text.replace('…'					,    '...'		)
     _a         =				text.replace('´'					,    '\''		)
     _a         =				re.sub(r'(-+|~+|!+|"+|;+|\?+|\++|,+|\)+|\(+|\\+|\/+|\*+|\[+|\]+|}+|{+|\|+|_+)'					,    r' \1 '					,    lowerCAmelCase__		)
     _a         =				re.sub(r'\s*\n\s*'					,    ' \n '					,    lowerCAmelCase__		)
     _a         =				re.sub(r'[^\S\n]+'					,    ' '					,    lowerCAmelCase__		)
     return text.strip()






class 			a  (  _SCREAMING_SNAKE_CASE							):
 _lowerCAmelCase			       =						VOCAB_FILES_NAMES
 _lowerCAmelCase			       =						PRETRAINED_VOCAB_FILES_MAP
 _lowerCAmelCase			       =						PRETRAINED_POSITIONAL_EMBEDDINGS_SIZES
 _lowerCAmelCase			       =						["""input_ids""", """attention_mask"""]
 def __init__(			self   ,					__magic_name__   ,					__magic_name__   ,					__magic_name__="<unk>"   ,					**__magic_name__    )       ->				Any:
      super().__init__(unk_token=__magic_name__   ,					**__magic_name__    )

      try:
           import ftfy
           from spacy.lang.en import English

           _a         =				English()
           _a         =				_nlp.tokenizer
           _a         =				ftfy.fix_text
      except ImportError:
           logger.warning('ftfy or spacy is not installed using BERT BasicTokenizer instead of SpaCy & ftfy.'    )
           _a         =				BasicTokenizer(do_lower_case=__magic_name__    )
           _a         =				None

      with open(__magic_name__   ,					encoding='utf-8'    ) as vocab_handle:
           _a         =				json.load(__magic_name__    )
      _a         =				{v: k for k, v in self.encoder.items()}
      with open(__magic_name__   ,					encoding='utf-8'    ) as merges_handle:
           _a         =				merges_handle.read().split('\n'    )[1:-1]
      _a         =				[tuple(merge.split()    ) for merge in merges]
      _a         =				dict(zip(__magic_name__   ,					range(len(__magic_name__    )    )    )    )
      _a         =				{}
 @property
 def 				__UpperCAmelCase		(			self    )       ->				Optional[int]:
      return True
 @property
 def 				__UpperCAmelCase		(			self    )       ->				int:
      return len(self.encoder    )
 def 				__UpperCAmelCase		(			self    )       ->				List[str]:
      return dict(self.encoder   ,					**self.added_tokens_encoder    )
 def 				__UpperCAmelCase		(			self   ,					__magic_name__    )       ->				Any:
      _a         =				tuple(token[:-1]    ) + (token[-1] + '</w>',)
      if token in self.cache:
           return self.cache[token]
      _a         =				get_pairs(__magic_name__    )

      if not pairs:
           return token + "</w>"

      while True:
           _a         =				min(__magic_name__   ,					key=lambda __magic_name__    : self.bpe_ranks.get(__magic_name__   ,					float('inf'    )    )    )
           if bigram not in self.bpe_ranks:
                break
           _a   , _a         =				bigram
           _a         =				[]
           _a         =				0
           while i < len(__magic_name__    ):
                try:
                     _a         =				word.index(__magic_name__   ,					__magic_name__    )
                except ValueError:
                     new_word.extend(word[i:]    )
                     break
                else:
                     new_word.extend(word[i:j]    )
                     _a         =				j

                if word[i] == first and i < len(__magic_name__    ) - 1 and word[i + 1] == second:
                     new_word.append(first + second    )
                     i += 2
                else:
                     new_word.append(word[i]    )
                     i += 1
           _a         =				tuple(__magic_name__    )
           _a         =				new_word
           if len(__magic_name__    ) == 1:
                break
           else:
                _a         =				get_pairs(__magic_name__    )
      _a         =				' '.join(__magic_name__    )
      if word == "\n  </w>":
           _a         =				'\n</w>'
      _a         =				word
      return word
 def 				__UpperCAmelCase		(			self   ,					__magic_name__    )       ->				Union[str, Any]:
      _a         =				[]
      if self.fix_text is None:
           # Using BERT's BasicTokenizer
           _a         =				self.nlp.tokenize(__magic_name__    )
           for token in text:
                split_tokens.extend(list(self.bpe(__magic_name__    ).split(' '    )    )    )
      else:
           # Using SpaCy & ftfy (original tokenization process of OpenAI GPT)
           _a         =				self.nlp(text_standardize(self.fix_text(__magic_name__    )    )    )
           for token in text:
                split_tokens.extend(list(self.bpe(token.text.lower()    ).split(' '    )    )    )
      return split_tokens
 def 				__UpperCAmelCase		(			self   ,					__magic_name__    )       ->				Any:
      return self.encoder.get(__magic_name__   ,					self.encoder.get(self.unk_token    )    )
 def 				__UpperCAmelCase		(			self   ,					__magic_name__    )       ->				Any:
      return self.decoder.get(__magic_name__   ,					self.unk_token    )
 def 				__UpperCAmelCase		(			self   ,					__magic_name__    )       ->				Dict:
      _a         =				''.join(__magic_name__    ).replace('</w>'   ,					' '    ).strip()
      return out_string




 def 				__UpperCAmelCase		(			self   ,					__magic_name__   ,					__magic_name__ = None    )       ->				Tuple[str]:
      if not os.path.isdir(__magic_name__    ):
           logger.error(f'Vocabulary path ({save_directory}) should be a directory'    )
           return
      _a         =				os.path.join(
          __magic_name__   ,					(filename_prefix + '-' if filename_prefix else '') + VOCAB_FILES_NAMES['vocab_file']    )
      _a         =				os.path.join(
          __magic_name__   ,					(filename_prefix + '-' if filename_prefix else '') + VOCAB_FILES_NAMES['merges_file']    )

      with open(__magic_name__   ,					'w'   ,					encoding='utf-8'    ) as f:
           f.write(json.dumps(self.encoder   ,					indent=2   ,					sort_keys=__magic_name__   ,					ensure_ascii=__magic_name__    ) + '\n'    )

      _a         =				0
      with open(__magic_name__   ,					'w'   ,					encoding='utf-8'    ) as writer:
           writer.write('#version: 0.2\n'    )
           for bpe_tokens, token_index in sorted(self.bpe_ranks.items()   ,					key=lambda __magic_name__    : kv[1]    ):
                if index != token_index:
                     logger.warning(
                         f'Saving vocabulary to {merge_file}: BPE merge indices are not consecutive.'
                         ' Please check that the tokenizer is not corrupted!'    )
                     _a         =				token_index
                writer.write(' '.join(__magic_name__    ) + '\n'    )
                index += 1

      return vocab_file, merge_file

