
'''simple docstring'''






import itertools
from dataclasses import dataclass
from typing import Optional

import pyarrow as pa

import datasets
from datasets.table import table_cast


__lowercase	=    datasets.utils.logging.get_logger(__name__)

@dataclass
class 							_snake_case     (  datasets.BuilderConfig ):
	"""simple docstring"""





	_UpperCamelCase							:  Optional[Any]								=		None







class 							_snake_case     (  datasets.ArrowBasedBuilder ):
	"""simple docstring"""





	_UpperCamelCase							:  List[Any]								=		ArrowConfig




	def 	__A      (						self				: int      ):
			return datasets.DatasetInfo(features=self.config.features      )




	def 	__A      (						self				: str					,						UpperCamelCase_				: List[str]      ):
			if not self.config.data_files:
					raise ValueError(F'At least one data file must be specified, but got data_files={self.config.data_files}'      )
			lowerCAmelCase_   :       Tuple    							=dl_manager.download_and_extract(self.config.data_files      )
			if isinstance(UpperCamelCase__					,						(str, list, tuple)      ):
					lowerCAmelCase_   :       List[Any]    							=data_files
					if isinstance(UpperCamelCase__					,						UpperCamelCase__      ):
							lowerCAmelCase_   :       Dict    							=[files]
					# Use `dl_manager.iter_files` to skip hidden files in an extracted archive
					lowerCAmelCase_   :       Dict    							=[dl_manager.iter_files(UpperCamelCase__      ) for file in files]
					return [datasets.SplitGenerator(name=datasets.Split.TRAIN					,						gen_kwargs={'''files''': files}      )]
			lowerCAmelCase_   :       Any    							=[]
			for split_name, files in data_files.items():
					if isinstance(UpperCamelCase__					,						UpperCamelCase__      ):
							lowerCAmelCase_   :       Optional[Any]    							=[files]
					# Use `dl_manager.iter_files` to skip hidden files in an extracted archive
					lowerCAmelCase_   :       List[Any]    							=[dl_manager.iter_files(UpperCamelCase__      ) for file in files]
					# Infer features is they are stoed in the arrow schema
					if self.info.features is None:
							for file in itertools.chain.from_iterable(UpperCamelCase__      ):
									with open(UpperCamelCase__					,						'''rb'''      ) as f:
											lowerCAmelCase_   :       List[Any]    							=datasets.Features.from_arrow_schema(pa.ipc.open_stream(UpperCamelCase__      ).schema      )
									break
					splits.append(datasets.SplitGenerator(name=UpperCamelCase__					,						gen_kwargs={'''files''': files}      )      )
			return splits




	def 	__A      (						self				: Tuple					,						UpperCamelCase_				: pa.Table      ):
			if self.info.features is not None:
					# more expensive cast to support nested features with keys in a different order
					# allows str <-> int/float or str to Audio for example
					lowerCAmelCase_   :       Union[str, Any]    							=table_cast(UpperCamelCase__					,						self.info.features.arrow_schema      )
			return pa_table





	def 	__A      (						self				: Union[str, Any]					,						UpperCamelCase_				: int      ):
			for file_idx, file in enumerate(itertools.chain.from_iterable(UpperCamelCase__      )      ):
					with open(UpperCamelCase__					,						'''rb'''      ) as f:
							try:
									for batch_idx, record_batch in enumerate(pa.ipc.open_stream(UpperCamelCase__      )      ):
											lowerCAmelCase_   :       str    							=pa.Table.from_batches([record_batch]      )
											# Uncomment for debugging (will print the Arrow table size and elements)
											# logger.warning(f"pa_table: {pa_table} num rows: {pa_table.num_rows}")
											# logger.warning('\n'.join(str(pa_table.slice(i, 1).to_pydict()) for i in range(pa_table.num_rows)))
											yield F'{file_idx}_{batch_idx}', self._cast_table(UpperCamelCase__      )
							except ValueError as e:
									logger.error(F'Failed to read file \'{file}\' with error {type(UpperCamelCase__      )}: {e}'      )
									raise














'''simple docstring'''







import csv
import os

import pytest

from datasets import Dataset, DatasetDict, Features, NamedSplit, Value
from datasets.io.csv import CsvDatasetReader, CsvDatasetWriter

from ..utils import assert_arrow_memory_doesnt_increase, assert_arrow_memory_increases





def 					SCREAMING_SNAKE_CASE_			(UpperCamelCase							,     UpperCamelCase ) ->			Dict:
							assert isinstance(UpperCamelCase							,     UpperCamelCase )
							assert dataset.num_rows == 4
							assert dataset.num_columns == 3
							assert dataset.column_names == ["col_1", "col_2", "col_3"]
							for feature, expected_dtype in expected_features.items():
														assert dataset.features[feature].dtype == expected_dtype





@pytest.mark.parametrize("""keep_in_memory"""							,     [False, True] )
def 					SCREAMING_SNAKE_CASE_			(UpperCamelCase							,     UpperCamelCase							,     UpperCamelCase ) ->			Any:
							lowerCamelCase__   :      Any			    =			tmp_path / """cache"""
							lowerCamelCase__   :      int			    =			{"""col_1""": """int64""", """col_2""": """int64""", """col_3""": """float64"""}
							with assert_arrow_memory_increases() if keep_in_memory else assert_arrow_memory_doesnt_increase():
														lowerCamelCase__   :      Any			    =			CsvDatasetReader(UpperCamelCase							,     cache_dir=UpperCamelCase							,     keep_in_memory=UpperCamelCase ).read()
							_check_csv_dataset(UpperCamelCase							,     UpperCamelCase )





@pytest.mark.parametrize(
    """features"""							,     [
        None,
        {"""col_1""": """string""", """col_2""": """int64""", """col_3""": """float64"""},
        {"""col_1""": """string""", """col_2""": """string""", """col_3""": """string"""},
        {"""col_1""": """int32""", """col_2""": """int32""", """col_3""": """int32"""},
        {"""col_1""": """float32""", """col_2""": """float32""", """col_3""": """float32"""},
    ]							,     )
def 					SCREAMING_SNAKE_CASE_			(UpperCamelCase							,     UpperCamelCase							,     UpperCamelCase ) ->			Any:
							lowerCamelCase__   :      Optional[int]			    =			tmp_path / """cache"""
							# CSV file loses col_1 string dtype information: default now is "int64" instead of "string"
							lowerCamelCase__   :      int			    =			{"""col_1""": """int64""", """col_2""": """int64""", """col_3""": """float64"""}
							lowerCamelCase__   :      int			    =			features.copy() if features else default_expected_features
							lowerCamelCase__   :      List[Any]			    =			(
							    Features({feature: Value(UpperCamelCase ) for feature, dtype in features.items()} ) if features is not None else None
							)
							lowerCamelCase__   :      Union[str, Any]			    =			CsvDatasetReader(UpperCamelCase							,     features=UpperCamelCase							,     cache_dir=UpperCamelCase ).read()
							_check_csv_dataset(UpperCamelCase							,     UpperCamelCase )





@pytest.mark.parametrize("""split"""							,     [None, NamedSplit("""train""" ), """train""", """test"""] )
def 					SCREAMING_SNAKE_CASE_			(UpperCamelCase							,     UpperCamelCase							,     UpperCamelCase ) ->			Union[str, Any]:
							lowerCamelCase__   :      Any			    =			tmp_path / """cache"""
							lowerCamelCase__   :      Union[str, Any]			    =			{"""col_1""": """int64""", """col_2""": """int64""", """col_3""": """float64"""}
							lowerCamelCase__   :      List[Any]			    =			CsvDatasetReader(UpperCamelCase							,     cache_dir=UpperCamelCase							,     split=UpperCamelCase ).read()
							_check_csv_dataset(UpperCamelCase							,     UpperCamelCase )
							assert dataset.split == split if split else "train"





@pytest.mark.parametrize("""path_type"""							,     [str, list] )
def 					SCREAMING_SNAKE_CASE_			(UpperCamelCase							,     UpperCamelCase							,     UpperCamelCase ) ->			Union[str, Any]:
							if issubclass(UpperCamelCase							,     UpperCamelCase ):
														lowerCamelCase__   :      int			    =			csv_path
							elif issubclass(UpperCamelCase							,     UpperCamelCase ):
														lowerCamelCase__   :      Tuple			    =			[csv_path]
							lowerCamelCase__   :      Optional[int]			    =			tmp_path / """cache"""
							lowerCamelCase__   :      str			    =			{"""col_1""": """int64""", """col_2""": """int64""", """col_3""": """float64"""}
							lowerCamelCase__   :      Dict			    =			CsvDatasetReader(UpperCamelCase							,     cache_dir=UpperCamelCase ).read()
							_check_csv_dataset(UpperCamelCase							,     UpperCamelCase )





def 					SCREAMING_SNAKE_CASE_			(UpperCamelCase							,     UpperCamelCase							,     UpperCamelCase=("train",) ) ->			int:
							assert isinstance(UpperCamelCase							,     UpperCamelCase )
							for split in splits:
														lowerCamelCase__   :      Optional[Any]			    =			dataset_dict[split]
														assert dataset.num_rows == 4
														assert dataset.num_columns == 3
														assert dataset.column_names == ["col_1", "col_2", "col_3"]
														for feature, expected_dtype in expected_features.items():
																					assert dataset.features[feature].dtype == expected_dtype





@pytest.mark.parametrize("""keep_in_memory"""							,     [False, True] )
def 					SCREAMING_SNAKE_CASE_			(UpperCamelCase							,     UpperCamelCase							,     UpperCamelCase ) ->			Optional[Any]:
							lowerCamelCase__   :      List[Any]			    =			tmp_path / """cache"""
							lowerCamelCase__   :      Dict			    =			{"""col_1""": """int64""", """col_2""": """int64""", """col_3""": """float64"""}
							with assert_arrow_memory_increases() if keep_in_memory else assert_arrow_memory_doesnt_increase():
														lowerCamelCase__   :      Any			    =			CsvDatasetReader({"""train""": csv_path}							,     cache_dir=UpperCamelCase							,     keep_in_memory=UpperCamelCase ).read()
							_check_csv_datasetdict(UpperCamelCase							,     UpperCamelCase )





@pytest.mark.parametrize(
    """features"""							,     [
        None,
        {"""col_1""": """string""", """col_2""": """int64""", """col_3""": """float64"""},
        {"""col_1""": """string""", """col_2""": """string""", """col_3""": """string"""},
        {"""col_1""": """int32""", """col_2""": """int32""", """col_3""": """int32"""},
        {"""col_1""": """float32""", """col_2""": """float32""", """col_3""": """float32"""},
    ]							,     )
def 					SCREAMING_SNAKE_CASE_			(UpperCamelCase							,     UpperCamelCase							,     UpperCamelCase ) ->			int:
							lowerCamelCase__   :      int			    =			tmp_path / """cache"""
							# CSV file loses col_1 string dtype information: default now is "int64" instead of "string"
							lowerCamelCase__   :      Optional[Any]			    =			{"""col_1""": """int64""", """col_2""": """int64""", """col_3""": """float64"""}
							lowerCamelCase__   :      List[str]			    =			features.copy() if features else default_expected_features
							lowerCamelCase__   :      Tuple			    =			(
							    Features({feature: Value(UpperCamelCase ) for feature, dtype in features.items()} ) if features is not None else None
							)
							lowerCamelCase__   :      str			    =			CsvDatasetReader({"""train""": csv_path}							,     features=UpperCamelCase							,     cache_dir=UpperCamelCase ).read()
							_check_csv_datasetdict(UpperCamelCase							,     UpperCamelCase )





@pytest.mark.parametrize("""split"""							,     [None, NamedSplit("""train""" ), """train""", """test"""] )
def 					SCREAMING_SNAKE_CASE_			(UpperCamelCase							,     UpperCamelCase							,     UpperCamelCase ) ->			Any:
							if split:
														lowerCamelCase__   :      Tuple			    =			{split: csv_path}
							else:
														lowerCamelCase__   :      Union[str, Any]			    =			{"""train""": csv_path, """test""": csv_path}
							lowerCamelCase__   :      Dict			    =			tmp_path / """cache"""
							lowerCamelCase__   :      Union[str, Any]			    =			{"""col_1""": """int64""", """col_2""": """int64""", """col_3""": """float64"""}
							lowerCamelCase__   :      Tuple			    =			CsvDatasetReader(UpperCamelCase							,     cache_dir=UpperCamelCase ).read()
							_check_csv_datasetdict(UpperCamelCase							,     UpperCamelCase							,     splits=list(path.keys() ) )
							assert all(dataset[split].split == split for split in path.keys() )





def 					SCREAMING_SNAKE_CASE_			(UpperCamelCase ) ->			Tuple:
							with open(UpperCamelCase							,     encoding="""utf-8""" ) as csvfile:
														yield from csv.reader(UpperCamelCase )





def 					SCREAMING_SNAKE_CASE_			(UpperCamelCase							,     UpperCamelCase ) ->			Optional[int]:
							lowerCamelCase__   :      Union[str, Any]			    =			tmp_path / """cache"""
							lowerCamelCase__   :      List[str]			    =			os.path.join(UpperCamelCase							,     """tmp.csv""" )
							lowerCamelCase__   :      Optional[Any]			    =			CsvDatasetReader({"""train""": csv_path}							,     cache_dir=UpperCamelCase ).read()
							CsvDatasetWriter(dataset["""train"""]							,     UpperCamelCase							,     num_proc=1 ).write()

							lowerCamelCase__   :      Optional[Any]			    =			iter_csv_file(UpperCamelCase )
							lowerCamelCase__   :      str			    =			iter_csv_file(UpperCamelCase )

							for rowa, rowa in zip(UpperCamelCase							,     UpperCamelCase ):
														assert rowa == rowa





def 					SCREAMING_SNAKE_CASE_			(UpperCamelCase							,     UpperCamelCase ) ->			List[str]:
							lowerCamelCase__   :      Any			    =			tmp_path / """cache"""
							lowerCamelCase__   :      List[str]			    =			os.path.join(UpperCamelCase							,     """tmp.csv""" )
							lowerCamelCase__   :      Optional[int]			    =			CsvDatasetReader({"""train""": csv_path}							,     cache_dir=UpperCamelCase ).read()
							CsvDatasetWriter(dataset["""train"""]							,     UpperCamelCase							,     num_proc=2 ).write()

							lowerCamelCase__   :      Tuple			    =			iter_csv_file(UpperCamelCase )
							lowerCamelCase__   :      Union[str, Any]			    =			iter_csv_file(UpperCamelCase )

							for rowa, rowa in zip(UpperCamelCase							,     UpperCamelCase ):
														assert rowa == rowa





def 					SCREAMING_SNAKE_CASE_			(UpperCamelCase							,     UpperCamelCase ) ->			Optional[int]:
							lowerCamelCase__   :      List[Any]			    =			tmp_path / """cache"""
							lowerCamelCase__   :      List[Any]			    =			os.path.join(UpperCamelCase							,     """tmp.csv""" )
							lowerCamelCase__   :      Dict			    =			CsvDatasetReader({"""train""": csv_path}							,     cache_dir=UpperCamelCase ).read()
							with pytest.raises(UpperCamelCase ):
														CsvDatasetWriter(dataset["""train"""]							,     UpperCamelCase							,     num_proc=0 )

