"""simple docstring"""



import os
import sys
import warnings
from dataclasses import dataclass, field
from io import BytesIO
from typing import TYPE_CHECKING, Any, ClassVar, Dict, List, Optional, Union

import numpy as np
import pyarrow as pa

from .. import config
from ..download.streaming_download_manager import xopen
from ..table import array_cast
from ..utils.file_utils import is_local_path
from ..utils.py_utils import first_non_null_value, no_op_if_value_is_null, string_to_dict


if TYPE_CHECKING:
				import PIL.Image

				from .features import FeatureType


_UpperCamelCase								=		None
_UpperCamelCase								=		"""<""" if sys.byteorder == """little""" else """>"""
# Origin: https://github.com/python-pillow/Pillow/blob/698951e19e19972aeed56df686868f1329981c12/src/PIL/Image.py#L3126 minus "|i1" which values are not preserved correctly when saving and loading an image
_UpperCamelCase								=		[
    np.dtype("|b1"),
    np.dtype("|u1"),
    np.dtype("<u2"),
    np.dtype(">u2"),
    np.dtype("<i2"),
    np.dtype(">i2"),
    np.dtype("<u4"),
    np.dtype(">u4"),
    np.dtype("<i4"),
    np.dtype(">i4"),
    np.dtype("<f4"),
    np.dtype(">f4"),
    np.dtype("<f8"),
    np.dtype(">f8"),
]
@dataclass
class 						__UpperCAmelCase    :







			'''simple docstring'''
			_UpperCamelCase  :						Optional[Any]					     =				True
			_UpperCamelCase  :						Union[str, Any]					     =				None
			# Automatically constructed
			_UpperCamelCase  :						Tuple					     =				'PIL.Image.Image'
			_UpperCamelCase  :						List[str]					     =				pa.struct({'bytes': pa.binary(), 'path': pa.string()}     )
			_UpperCamelCase  :						int					     =				field(default='Image'							,   init=SCREAMING_SNAKE_CASE_							,   repr=SCREAMING_SNAKE_CASE_     )





			def __call__(			self							):







										'''simple docstring'''


										return self.pa_type





			def 		lowerCamelCase					(			self   ,      snake_case_							):







										'''simple docstring'''


										if config.PIL_AVAILABLE:
																	import PIL.Image
										else:
																	raise ImportError("""To support encoding images, please install \'Pillow\'."""							)

										if isinstance(snake_case__   ,      snake_case__							):
																	A__       :     List[Any]								=			np.array(snake_case__							)

										if isinstance(snake_case__   ,      snake_case__							):
																	return {"path": value, "bytes": None}
										elif isinstance(snake_case__   ,      snake_case__							):
																	return {"path": None, "bytes": value}
										elif isinstance(snake_case__   ,      np.ndarray							):
																	# convert the image array to PNG/TIFF bytes
																	return encode_np_array(snake_case__							)
										elif isinstance(snake_case__   ,      PIL.Image.Image							):
																	# convert the PIL image to bytes (default format is PNG/TIFF)
																	return encode_pil_image(snake_case__							)
										elif value.get("""path"""							) is not None and os.path.isfile(value["""path"""]							):
																	# we set "bytes": None to not duplicate the data if they're already available locally
																	return {"bytes": None, "path": value.get("""path"""							)}
										elif value.get("""bytes"""							) is not None or value.get("""path"""							) is not None:
																	# store the image bytes, and path is used to infer the image format using the file extension
																	return {"bytes": value.get("""bytes"""							), "path": value.get("""path"""							)}
										else:
																	raise ValueError(
																	    F'''An image sample should have one of \'path\' or \'bytes\' but they are missing or None in {value}.'''							)





			def 		lowerCamelCase					(			self   ,      snake_case_   ,      snake_case_=None							):







										'''simple docstring'''


										if not self.decode:
																	raise RuntimeError("""Decoding is disabled for this feature. Please use Image(decode=True) instead."""							)

										if config.PIL_AVAILABLE:
																	import PIL.Image
										else:
																	raise ImportError("""To support decoding images, please install \'Pillow\'."""							)

										if token_per_repo_id is None:
																	A__       :     Union[str, Any]								=			{}

										A__       :     Union[str, Any]								=			value['path'], value['bytes']
										if bytes_ is None:
																	if path is None:
																								raise ValueError(F'''An image should have one of \'path\' or \'bytes\' but both are None in {value}.'''							)
																	else:
																								if is_local_path(snake_case__							):
																															A__       :     str								=			PIL.Image.open(snake_case__							)
																								else:
																															A__       :     Tuple								=			path.split("""::"""							)[-1]
																															try:
																																						A__       :     List[Any]								=			string_to_dict(snake_case__   ,      config.HUB_DATASETS_URL							)['repo_id']
																																						A__       :     List[str]								=			token_per_repo_id.get(snake_case__							)
																															except ValueError:
																																						A__       :     Tuple								=			None
																															with xopen(snake_case__   ,      """rb"""   ,      use_auth_token=snake_case__							) as f:
																																						A__       :     int								=			BytesIO(f.read()							)
																															A__       :     Union[str, Any]								=			PIL.Image.open(bytes_							)
										else:
																	A__       :     List[str]								=			PIL.Image.open(BytesIO(bytes_							)							)
										image.load()  # to avoid "Too many open files" errors
										return image





			def 		lowerCamelCase					(			self							):







										'''simple docstring'''


										from .features import Value

										return (
										    self
										    if self.decode
										    else {
										        "bytes": Value("""binary"""							),
										        "path": Value("""string"""							),
										    }
										)





			def 		lowerCamelCase					(			self   ,      snake_case_							):







										'''simple docstring'''


										if pa.types.is_string(storage.type							):
																	A__       :     int								=			pa.array([None] * len(snake_case__							)   ,      type=pa.binary()							)
																	A__       :     Union[str, Any]								=			pa.StructArray.from_arrays([bytes_array, storage]   ,      ["""bytes""", """path"""]   ,      mask=storage.is_null()							)
										elif pa.types.is_binary(storage.type							):
																	A__       :     str								=			pa.array([None] * len(snake_case__							)   ,      type=pa.string()							)
																	A__       :     Dict								=			pa.StructArray.from_arrays([storage, path_array]   ,      ["""bytes""", """path"""]   ,      mask=storage.is_null()							)
										elif pa.types.is_struct(storage.type							):
																	if storage.type.get_field_index("""bytes"""							) >= 0:
																								A__       :     List[Any]								=			storage.field("""bytes"""							)
																	else:
																								A__       :     Optional[int]								=			pa.array([None] * len(snake_case__							)   ,      type=pa.binary()							)
																	if storage.type.get_field_index("""path"""							) >= 0:
																								A__       :     Dict								=			storage.field("""path"""							)
																	else:
																								A__       :     List[str]								=			pa.array([None] * len(snake_case__							)   ,      type=pa.string()							)
																	A__       :     Union[str, Any]								=			pa.StructArray.from_arrays([bytes_array, path_array]   ,      ["""bytes""", """path"""]   ,      mask=storage.is_null()							)
										elif pa.types.is_list(storage.type							):
																	A__       :     Optional[Any]								=			pa.array(
																	    [encode_np_array(np.array(snake_case__							)							)["""bytes"""] if arr is not None else None for arr in storage.to_pylist()]   ,      type=pa.binary()   ,      )
																	A__       :     List[str]								=			pa.array([None] * len(snake_case__							)   ,      type=pa.string()							)
																	A__       :     Optional[Any]								=			pa.StructArray.from_arrays(
																	    [bytes_array, path_array]   ,      ["""bytes""", """path"""]   ,      mask=bytes_array.is_null()							)
										return array_cast(snake_case__   ,      self.pa_type							)





			def 		lowerCamelCase					(			self   ,      snake_case_							):







										'''simple docstring'''


										@no_op_if_value_is_null
										def path_to_bytes(snake_case_							):
																	with xopen(snake_case__   ,      """rb"""							) as f:
																								A__       :     List[str]								=			f.read()
																	return bytes_

										A__       :     Dict								=			pa.array(
										    [
										        (path_to_bytes(x["""path"""]							) if x["""bytes"""] is None else x["""bytes"""]) if x is not None else None
										        for x in storage.to_pylist()
										    ]   ,      type=pa.binary()   ,      )
										A__       :     Optional[int]								=			pa.array(
										    [os.path.basename(snake_case__							) if path is not None else None for path in storage.field("""path"""							).to_pylist()]   ,      type=pa.string()   ,      )
										A__       :     int								=			pa.StructArray.from_arrays([bytes_array, path_array]   ,      ["""bytes""", """path"""]   ,      mask=bytes_array.is_null()							)
										return array_cast(snake_case__   ,      self.pa_type							)





def  _A(		):







							if config.PIL_AVAILABLE:
														import PIL.Image
							else:
														raise ImportError("""To support encoding images, please install \'Pillow\'."""							)

							global _IMAGE_COMPRESSION_FORMATS
							if _IMAGE_COMPRESSION_FORMATS is None:
														PIL.Image.init()
														A__       :     List[str]								=			list(set(PIL.Image.OPEN.keys()							) & set(PIL.Image.SAVE.keys()							)							)
							return _IMAGE_COMPRESSION_FORMATS

def  _A(		lowerCAmelCase							):
							A__       :     Union[str, Any]								=			BytesIO()
							if image.format in list_image_compression_formats():
														A__       :     Dict								=			image.format
							else:
														A__       :     Optional[Any]								=			'PNG' if image.mode in ['1', 'L', 'LA', 'RGB', 'RGBA'] else 'TIFF'
							image.save(_A			,  format=_A							)
							return buffer.getvalue()

def  _A(		lowerCAmelCase							):







							if hasattr(_A			,  """filename"""							) and image.filename != "":
														return {"path": image.filename, "bytes": None}
							else:
														return {"path": None, "bytes": image_to_bytes(_A							)}

def  _A(		lowerCAmelCase							):







							if config.PIL_AVAILABLE:
														import PIL.Image
							else:
														raise ImportError("""To support encoding images, please install \'Pillow\'."""							)

							A__       :     List[Any]								=			array.dtype
							A__       :     Tuple								=			dtype.byteorder if dtype.byteorder != '=' else _NATIVE_BYTEORDER
							A__       :     Tuple								=			dtype.kind
							A__       :     List[str]								=			dtype.itemsize

							A__       :     Any								=			None

							# Multi-channel array case (only np.dtype("|u1") is allowed)
							if array.shape[2:]:
														A__       :     Optional[int]								=			np.dtype("""|u1"""							)
														if dtype_kind not in ["u", "i"]:
																					raise TypeError(
																					    F'''Unsupported array dtype {dtype} for image encoding. Only {dest_dtype} is supported for multi-channel arrays.'''							)
														if dtype is not dest_dtype:
																					warnings.warn(F'''Downcasting array dtype {dtype} to {dest_dtype} to be compatible with \'Pillow\''''							)
    # Exact match
							elif dtype in _VALID_IMAGE_ARRAY_DTPYES:
														A__       :     List[Any]								=			dtype
							else:  # Downcast the type within the kind (np.can_cast(from_type, to_type, casting="same_kind") doesn't behave as expected, so do it manually)
														while dtype_itemsize >= 1:
																					A__       :     str								=			dtype_byteorder + dtype_kind + str(_A							)
																					A__       :     Optional[Any]								=			np.dtype(_A							)
																					if dest_dtype in _VALID_IMAGE_ARRAY_DTPYES:
																												warnings.warn(F'''Downcasting array dtype {dtype} to {dest_dtype} to be compatible with \'Pillow\''''							)
																												break
																					else:
																												dtype_itemsize //= 2

							if dest_dtype is None:
														raise TypeError(
														    F'''Cannot convert dtype {dtype} to a valid image dtype. Valid image dtypes: {_VALID_IMAGE_ARRAY_DTPYES}'''							)
							A__       :     List[str]								=			PIL.Image.fromarray(array.astype(_A							)							)
							return {"path": None, "bytes": image_to_bytes(_A							)}



def  _A(		lowerCAmelCase							):







							if config.PIL_AVAILABLE:
														import PIL.Image
							else:
														raise ImportError("""To support encoding images, please install \'Pillow\'."""							)

							if objs:
														A__       :     int								=			first_non_null_value(_A							)
														if isinstance(_A			,  _A							):
																					return [{"path": obj, "bytes": None} if obj is not None else None for obj in objs]
														if isinstance(_A			,  np.ndarray							):
																					A__       :     Optional[Any]								=			no_op_if_value_is_null(_A							)
																					return [obj_to_image_dict_func(_A							) for obj in objs]
														elif isinstance(_A			,  PIL.Image.Image							):
																					A__       :     str								=			no_op_if_value_is_null(_A							)
																					return [obj_to_image_dict_func(_A							) for obj in objs]
														else:
																					return objs
							else:
														return objs









'''simple docstring'''







from typing import TYPE_CHECKING

from ...utils import (
    OptionalDependencyNotAvailable,
    _LazyModule,
    is_flax_available,
    is_tf_available,
    is_tokenizers_available,
    is_torch_available,
)


lowerCAmelCase     :  List[str]											=    {
    """configuration_electra""": ["""ELECTRA_PRETRAINED_CONFIG_ARCHIVE_MAP""", """ElectraConfig""", """ElectraOnnxConfig"""],
    """tokenization_electra""": ["""ElectraTokenizer"""],
}

try:
       if not is_tokenizers_available():
              raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
       pass
else:
       lowerCAmelCase     :  Optional[Any]											=    ["""ElectraTokenizerFast"""]

try:
       if not is_torch_available():
              raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
       pass
else:
       lowerCAmelCase     :  str											=    [
           """ELECTRA_PRETRAINED_MODEL_ARCHIVE_LIST""",
           """ElectraForCausalLM""",
           """ElectraForMaskedLM""",
           """ElectraForMultipleChoice""",
           """ElectraForPreTraining""",
           """ElectraForQuestionAnswering""",
           """ElectraForSequenceClassification""",
           """ElectraForTokenClassification""",
           """ElectraModel""",
           """ElectraPreTrainedModel""",
           """load_tf_weights_in_electra""",
       ]

try:
       if not is_tf_available():
              raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
       pass
else:
       lowerCAmelCase     :  Tuple											=    [
           """TF_ELECTRA_PRETRAINED_MODEL_ARCHIVE_LIST""",
           """TFElectraForMaskedLM""",
           """TFElectraForMultipleChoice""",
           """TFElectraForPreTraining""",
           """TFElectraForQuestionAnswering""",
           """TFElectraForSequenceClassification""",
           """TFElectraForTokenClassification""",
           """TFElectraModel""",
           """TFElectraPreTrainedModel""",
       ]

try:
       if not is_flax_available():
              raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
       pass
else:
       lowerCAmelCase     :  Union[str, Any]											=    [
           """FlaxElectraForCausalLM""",
           """FlaxElectraForMaskedLM""",
           """FlaxElectraForMultipleChoice""",
           """FlaxElectraForPreTraining""",
           """FlaxElectraForQuestionAnswering""",
           """FlaxElectraForSequenceClassification""",
           """FlaxElectraForTokenClassification""",
           """FlaxElectraModel""",
           """FlaxElectraPreTrainedModel""",
       ]


if TYPE_CHECKING:
       from .configuration_electra import ELECTRA_PRETRAINED_CONFIG_ARCHIVE_MAP, ElectraConfig, ElectraOnnxConfig
       from .tokenization_electra import ElectraTokenizer

       try:
              if not is_tokenizers_available():
                     raise OptionalDependencyNotAvailable()
       except OptionalDependencyNotAvailable:
              pass
       else:
              from .tokenization_electra_fast import ElectraTokenizerFast

       try:
              if not is_torch_available():
                     raise OptionalDependencyNotAvailable()
       except OptionalDependencyNotAvailable:
              pass
       else:
              from .modeling_electra import (
                  ELECTRA_PRETRAINED_MODEL_ARCHIVE_LIST,
                  ElectraForCausalLM,
                  ElectraForMaskedLM,
                  ElectraForMultipleChoice,
                  ElectraForPreTraining,
                  ElectraForQuestionAnswering,
                  ElectraForSequenceClassification,
                  ElectraForTokenClassification,
                  ElectraModel,
                  ElectraPreTrainedModel,
                  load_tf_weights_in_electra,
              )

       try:
              if not is_tf_available():
                     raise OptionalDependencyNotAvailable()
       except OptionalDependencyNotAvailable:
              pass
       else:
              from .modeling_tf_electra import (
                  TF_ELECTRA_PRETRAINED_MODEL_ARCHIVE_LIST,
                  TFElectraForMaskedLM,
                  TFElectraForMultipleChoice,
                  TFElectraForPreTraining,
                  TFElectraForQuestionAnswering,
                  TFElectraForSequenceClassification,
                  TFElectraForTokenClassification,
                  TFElectraModel,
                  TFElectraPreTrainedModel,
              )

       try:
              if not is_flax_available():
                     raise OptionalDependencyNotAvailable()
       except OptionalDependencyNotAvailable:
              pass
       else:
              from .modeling_flax_electra import (
                  FlaxElectraForCausalLM,
                  FlaxElectraForMaskedLM,
                  FlaxElectraForMultipleChoice,
                  FlaxElectraForPreTraining,
                  FlaxElectraForQuestionAnswering,
                  FlaxElectraForSequenceClassification,
                  FlaxElectraForTokenClassification,
                  FlaxElectraModel,
                  FlaxElectraPreTrainedModel,
              )

else:
       import sys

       lowerCAmelCase     :  int											=    _LazyModule(__name__, globals()["""__file__"""], _import_structure, module_spec=__spec__)

