
import multiprocessing
import os
from typing import BinaryIO, Optional, Union

from .. import Dataset, Features, NamedSplit, config
from ..formatting import query_table
from ..packaged_modules.csv.csv import Csv
from ..utils import logging
from ..utils.typing import NestedDataStructureLike, PathLike
from .abc import AbstractDatasetReader


class   __lowerCAmelCase		(		SCREAMING_SNAKE_CASE__ ):



      """simple docstring"""







      def __init__( self						:    List[str]			,    _snake_case						:    str			,    _snake_case						:    Optional[int] = None			,    _snake_case						:    Tuple = None			,    _snake_case						:    int = None			,    _snake_case						:    Union[str, Any] = False			,    _snake_case						:    Any = False			,    _snake_case						:    List[Any] = None			,    **_snake_case						:    Union[str, Any]			,    ):
          super().__init__(
              _UpperCAmelCase			,    split=_UpperCAmelCase			,    features=_UpperCAmelCase			,    cache_dir=_UpperCAmelCase			,    keep_in_memory=_UpperCAmelCase			,    streaming=_UpperCAmelCase			,    num_proc=_UpperCAmelCase			,    **_UpperCAmelCase			,    )
          __lowercase						:     Tuple		      =    path_or_paths if isinstance(_UpperCAmelCase			,    _UpperCAmelCase			) else {self.split: path_or_paths}
          __lowercase						:     Union[str, Any]		      =    Csv(
              cache_dir=_UpperCAmelCase			,    data_files=_UpperCAmelCase			,    features=_UpperCAmelCase			,    **_UpperCAmelCase			,    )




      def 						snake_case_     ( self						:    Tuple			):
          # Build iterable dataset
          if self.streaming:
              __lowercase						:     Union[str, Any]		      =    self.builder.as_streaming_dataset(split=self.split			)
          # Build regular (map-style) dataset
          else:
              __lowercase						:     Tuple		      =    None
              __lowercase						:     str		      =    None
              __lowercase						:     Union[str, Any]		      =    None
              __lowercase						:     List[str]		      =    None

              self.builder.download_and_prepare(
                  download_config=_UpperCAmelCase			,    download_mode=_UpperCAmelCase			,    verification_mode=_UpperCAmelCase			,    base_path=_UpperCAmelCase			,    num_proc=self.num_proc			,    )
              __lowercase						:     Optional[int]		      =    self.builder.as_dataset(
                  split=self.split			,    verification_mode=_UpperCAmelCase			,    in_memory=self.keep_in_memory			)
          return dataset






class   __lowerCAmelCase		:



      """simple docstring"""







      def __init__( self						:    List[Any]			,    _snake_case						:    int			,    _snake_case						:    List[str]			,    _snake_case						:    Optional[Any] = None			,    _snake_case						:    Optional[Any] = None			,    **_snake_case						:    Any			,    ):
          if num_proc is not None and num_proc <= 0:
              raise ValueError(F'num_proc {num_proc} must be an integer > 0.'			)

          __lowercase						:     List[Any]		      =    dataset
          __lowercase						:     int		      =    path_or_buf
          __lowercase						:     Optional[int]		      =    batch_size if batch_size else config.DEFAULT_MAX_BATCH_SIZE
          __lowercase						:     Union[str, Any]		      =    num_proc
          __lowercase						:     Optional[Any]		      =    "utf-8"
          __lowercase						:     Optional[Any]		      =    to_csv_kwargs




      def 						snake_case_     ( self						:    Dict			):
          __lowercase						:     Any		      =    self.to_csv_kwargs.pop('''path_or_buf'''			,    _UpperCAmelCase			)
          __lowercase						:     int		      =    self.to_csv_kwargs.pop('''header'''			,    _UpperCAmelCase			)
          __lowercase						:     int		      =    self.to_csv_kwargs.pop('''index'''			,    _UpperCAmelCase			)

          if isinstance(self.path_or_buf			,    (str, bytes, os.PathLike)			):
              with open(self.path_or_buf			,    '''wb+'''			) as buffer:
                  __lowercase						:     Optional[Any]		      =    self._write(file_obj=_UpperCAmelCase			,    header=_UpperCAmelCase			,    index=_UpperCAmelCase			,    **self.to_csv_kwargs			)
          else:
              __lowercase						:     Optional[Any]		      =    self._write(file_obj=self.path_or_buf			,    header=_UpperCAmelCase			,    index=_UpperCAmelCase			,    **self.to_csv_kwargs			)
          return written




      def 						snake_case_     ( self						:    int			,    _snake_case						:    int			):
          __lowercase						:     Dict		      =    args

          __lowercase						:     Any		      =    query_table(
              table=self.dataset.data			,    key=slice(_UpperCAmelCase			,    offset + self.batch_size			)			,    indices=self.dataset._indices			,    )
          __lowercase						:     int		      =    batch.to_pandas().to_csv(
              path_or_buf=_UpperCAmelCase			,    header=header if (offset == 0) else False			,    index=_UpperCAmelCase			,    **_UpperCAmelCase			)
          return csv_str.encode(self.encoding			)




      def 						snake_case_     ( self						:    Optional[Any]			,    _snake_case						:    Optional[int]			,    _snake_case						:    str			,    _snake_case						:    Dict			,    **_snake_case						:    Any			):
          __lowercase						:     Tuple		      =    0

          if self.num_proc is None or self.num_proc == 1:
              for offset in logging.tqdm(
                  range(0			,    len(self.dataset			)			,    self.batch_size			)			,    unit='''ba'''			,    disable=not logging.is_progress_bar_enabled()			,    desc='''Creating CSV from Arrow format'''			,    ):
                  __lowercase						:     Union[str, Any]		      =    self._batch_csv((offset, header, index, to_csv_kwargs)			)
                  written += file_obj.write(_UpperCAmelCase			)

          else:
              __lowercase						:     List[Any]		      =    len(self.dataset			), self.batch_size
              with multiprocessing.Pool(self.num_proc			) as pool:
                  for csv_str in logging.tqdm(
                      pool.imap(
                          self._batch_csv			,    [(offset, header, index, to_csv_kwargs) for offset in range(0			,    _UpperCAmelCase			,    _UpperCAmelCase			)]			,    )			,    total=(num_rows // batch_size) + 1 if num_rows % batch_size else num_rows // batch_size			,    unit='''ba'''			,    disable=not logging.is_progress_bar_enabled()			,    desc='''Creating CSV from Arrow format'''			,    ):
                      written += file_obj.write(_UpperCAmelCase			)

          return written




import importlib.metadata
import sys

from transformers.testing_utils import TestCasePlus
from transformers.utils.versions import require_version, require_version_core


__lowerCAmelCase   :     Optional[Any]      =						importlib.metadata.version("numpy")
__lowerCAmelCase   :     Any      =						".".join([str(x) for x in sys.version_info[:3]])


class   __lowerCAmelCase		(		lowerCAmelCase_ ):



      """simple docstring"""







      def 						snake_case_     ( self						:    List[Any]			):
          # lt + different version strings
          require_version_core('''numpy<1000.4.5'''			)
          require_version_core('''numpy<1000.4'''			)
          require_version_core('''numpy<1000'''			)

          # le
          require_version_core('''numpy<=1000.4.5'''			)
          require_version_core(F'numpy<={numpy_ver}'			)

          # eq
          require_version_core(F'numpy=={numpy_ver}'			)

          # ne
          require_version_core('''numpy!=1000.4.5'''			)

          # ge
          require_version_core('''numpy>=1.0'''			)
          require_version_core('''numpy>=1.0.0'''			)
          require_version_core(F'numpy>={numpy_ver}'			)

          # gt
          require_version_core('''numpy>1.0.0'''			)

          # mix
          require_version_core('''numpy>1.0.0,<1000'''			)

          # requirement w/o version
          require_version_core('''numpy'''			)

          # unmet requirements due to version conflict
          for req in ["numpy==1.0.0", "numpy>=1000.0.0", F'numpy<{numpy_ver}']:
              try:
                  require_version_core(_snake_case			)
              except ImportError as e:
                  self.assertIn(F'{req} is required'			,    str(_snake_case			)			)
                  self.assertIn('''but found'''			,    str(_snake_case			)			)

        # unmet requirements due to missing module
          for req in ["numpipypie>1", "numpipypie2"]:
              try:
                  require_version_core(_snake_case			)
              except importlib.metadata.PackageNotFoundError as e:
                  self.assertIn(F'The \'{req}\' distribution was not found and is required by this application'			,    str(_snake_case			)			)
                  self.assertIn('''Try: pip install transformers -U'''			,    str(_snake_case			)			)

        # bogus requirements formats:
        # 1. whole thing
          for req in ["numpy??1.0.0", "numpy1.0.0"]:
              try:
                  require_version_core(_snake_case			)
              except ValueError as e:
                  self.assertIn('''requirement needs to be in the pip package format'''			,    str(_snake_case			)			)
        # 2. only operators
          for req in ["numpy=1.0.0", "numpy == 1.00", "numpy<>1.0.0", "numpy><1.00", "numpy>>1.0.0"]:
              try:
                  require_version_core(_snake_case			)
              except ValueError as e:
                  self.assertIn('''need one of '''			,    str(_snake_case			)			)




      def 						snake_case_     ( self						:    List[str]			):
          # matching requirement
          require_version('''python>=3.6.0'''			)

          # not matching requirements
          for req in ["python>9.9.9", "python<3.0.0"]:
              try:
                  require_version_core(_snake_case			)
              except ImportError as e:
                  self.assertIn(F'{req} is required'			,    str(_snake_case			)			)
                  self.assertIn(F'but found python=={python_ver}'			,    str(_snake_case			)			)


