






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


A_		:		Optional[List[str]]		     =			None
A_		:		Union[str, Any]		     =			'<' 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
A_		:		Any		     =			[
    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     _lowerCAmelCase:





       """simple docstring"""







       a    :		bool									=True
       a    :		Optional[str]									=None
       # Automatically constructed
       a    :		ClassVar[str]									="PIL.Image.Image"
       a    :		ClassVar[Any]									=pa.struct({'''bytes''': pa.binary(), '''path''': pa.string()} )
       a    :		str									=field(default='''Image'''							,     init=UpperCAmelCase_							,     repr=UpperCAmelCase_ )





       def __call__( self							):
         return self.pa_type





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

         if isinstance(_lowerCamelCase  ,      _lowerCamelCase							):
           UpperCamelCase_: Dict   				=    np.array(_lowerCamelCase							)

         if isinstance(_lowerCamelCase  ,      _lowerCamelCase							):
           return {"path": value, "bytes": None}
         elif isinstance(_lowerCamelCase  ,      _lowerCamelCase							):
           return {"path": None, "bytes": value}
         elif isinstance(_lowerCamelCase  ,      np.ndarray							):
           # convert the image array to PNG/TIFF bytes
           return encode_np_array(_lowerCamelCase							)
         elif isinstance(_lowerCamelCase  ,      PIL.Image.Image							):
           # convert the PIL image to bytes (default format is PNG/TIFF)
           return encode_pil_image(_lowerCamelCase							)
         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       _a   ( self  ,      _lowerCamelCase  ,      _lowerCamelCase=None							):
         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:
           UpperCamelCase_: List[Any]   				=    {}

         UpperCamelCase_				,UpperCamelCase_: 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(_lowerCamelCase							):
               UpperCamelCase_: List[Any]   				=    PIL.Image.open(_lowerCamelCase							)
             else:
               UpperCamelCase_: Optional[Any]   				=    path.split('::'							)[-1]
               try:
                 UpperCamelCase_: Any   				=    string_to_dict(_lowerCamelCase  ,      config.HUB_DATASETS_URL							)['repo_id']
                 UpperCamelCase_: Tuple   				=    token_per_repo_id.get(_lowerCamelCase							)
               except ValueError:
                 UpperCamelCase_: Tuple   				=    None
               with xopen(_lowerCamelCase  ,      'rb'  ,      use_auth_token=_lowerCamelCase							) as f:
                 UpperCamelCase_: Dict   				=    BytesIO(f.read()							)
               UpperCamelCase_: int   				=    PIL.Image.open(bytes_							)
         else:
           UpperCamelCase_: Optional[int]   				=    PIL.Image.open(BytesIO(bytes_							)							)
         image.load()  # to avoid "Too many open files" errors
         return image





       def       _a   ( self							):
         from .features import Value

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





       def       _a   ( self  ,      _lowerCamelCase							):
         if pa.types.is_string(storage.type							):
           UpperCamelCase_: int   				=    pa.array([None] * len(_lowerCamelCase							)  ,      type=pa.binary()							)
           UpperCamelCase_: int   				=    pa.StructArray.from_arrays([bytes_array, storage]  ,      ['bytes', 'path']  ,      mask=storage.is_null()							)
         elif pa.types.is_binary(storage.type							):
           UpperCamelCase_: str   				=    pa.array([None] * len(_lowerCamelCase							)  ,      type=pa.string()							)
           UpperCamelCase_: Optional[int]   				=    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:
             UpperCamelCase_: Union[str, Any]   				=    storage.field('bytes'							)
           else:
             UpperCamelCase_: Dict   				=    pa.array([None] * len(_lowerCamelCase							)  ,      type=pa.binary()							)
           if storage.type.get_field_index('path'							) >= 0:
             UpperCamelCase_: List[Any]   				=    storage.field('path'							)
           else:
             UpperCamelCase_: Dict   				=    pa.array([None] * len(_lowerCamelCase							)  ,      type=pa.string()							)
           UpperCamelCase_: List[Any]   				=    pa.StructArray.from_arrays([bytes_array, path_array]  ,      ['bytes', 'path']  ,      mask=storage.is_null()							)
         elif pa.types.is_list(storage.type							):
           UpperCamelCase_: int   				=    pa.array(
               [encode_np_array(np.array(_lowerCamelCase							)							)['bytes'] if arr is not None else None for arr in storage.to_pylist()]  ,      type=pa.binary()  ,      )
           UpperCamelCase_: Optional[Any]   				=    pa.array([None] * len(_lowerCamelCase							)  ,      type=pa.string()							)
           UpperCamelCase_: Optional[Any]   				=    pa.StructArray.from_arrays(
               [bytes_array, path_array]  ,      ['bytes', 'path']  ,      mask=bytes_array.is_null()							)
         return array_cast(_lowerCamelCase  ,      self.pa_type							)





       def       _a   ( self  ,      _lowerCamelCase							):

         @no_op_if_value_is_null
         def path_to_bytes(_lowerCamelCase							):
           with xopen(_lowerCamelCase  ,      'rb'							) as f:
             UpperCamelCase_: Dict   				=    f.read()
           return bytes_

         UpperCamelCase_: Any   				=    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()  ,      )
         UpperCamelCase_: Tuple   				=    pa.array(
             [os.path.basename(_lowerCamelCase							) if path is not None else None for path in storage.field('path'							).to_pylist()]  ,      type=pa.string()  ,      )
         UpperCamelCase_: List[str]   				=    pa.StructArray.from_arrays([bytes_array, path_array]  ,      ['bytes', 'path']  ,      mask=bytes_array.is_null()							)
         return array_cast(_lowerCamelCase  ,      self.pa_type							)







def   snake_case ()	->    List[str]:
  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()
    UpperCamelCase_: Union[str, Any]   				=    list(set(PIL.Image.OPEN.keys()  ) & set(PIL.Image.SAVE.keys()  )  )
  return _IMAGE_COMPRESSION_FORMATS

def   snake_case (UpperCAmelCase__  )	->    bytes:
  UpperCamelCase_: Optional[int]   				=    BytesIO()
  if image.format in list_image_compression_formats():
    UpperCamelCase_: Dict   				=    image.format
  else:
    UpperCamelCase_: List[Any]   				=    'PNG' if image.mode in ['1', 'L', 'LA', 'RGB', 'RGBA'] else 'TIFF'
  image.save(UpperCAmelCase__     ,   format=UpperCAmelCase__  )
  return buffer.getvalue()

def   snake_case (UpperCAmelCase__  )	->    dict:
  if hasattr(UpperCAmelCase__     ,   'filename'  ) and image.filename != "":
    return {"path": image.filename, "bytes": None}
  else:
    return {"path": None, "bytes": image_to_bytes(UpperCAmelCase__  )}

def   snake_case (UpperCAmelCase__  )	->    dict:
  if config.PIL_AVAILABLE:
    import PIL.Image
  else:
    raise ImportError('To support encoding images, please install \'Pillow\'.'  )

  UpperCamelCase_: Optional[Any]   				=    array.dtype
  UpperCamelCase_: Any   				=    dtype.byteorder if dtype.byteorder != '=' else _NATIVE_BYTEORDER
  UpperCamelCase_: Optional[Any]   				=    dtype.kind
  UpperCamelCase_: str   				=    dtype.itemsize

  UpperCamelCase_: int   				=    None

  # Multi-channel array case (only np.dtype("|u1") is allowed)
  if array.shape[2:]:
    UpperCamelCase_: Optional[Any]   				=    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:
    UpperCamelCase_: Optional[int]   				=    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:
      UpperCamelCase_: Optional[int]   				=    dtype_byteorder + dtype_kind + str(UpperCAmelCase__  )
      UpperCamelCase_: Union[str, Any]   				=    np.dtype(UpperCAmelCase__  )
      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}'''  )
  UpperCamelCase_: Any   				=    PIL.Image.fromarray(array.astype(UpperCAmelCase__  )  )
  return {"path": None, "bytes": image_to_bytes(UpperCAmelCase__  )}

def   snake_case (UpperCAmelCase__  )	->    List[dict]:
  if config.PIL_AVAILABLE:
    import PIL.Image
  else:
    raise ImportError('To support encoding images, please install \'Pillow\'.'  )

  if objs:
    UpperCamelCase_				,UpperCamelCase_: Dict   				=    first_non_null_value(UpperCAmelCase__  )
    if isinstance(UpperCAmelCase__     ,   UpperCAmelCase__  ):
      return [{"path": obj, "bytes": None} if obj is not None else None for obj in objs]
    if isinstance(UpperCAmelCase__     ,   np.ndarray  ):
      UpperCamelCase_: Tuple   				=    no_op_if_value_is_null(UpperCAmelCase__  )
      return [obj_to_image_dict_func(UpperCAmelCase__  ) for obj in objs]
    elif isinstance(UpperCAmelCase__     ,   PIL.Image.Image  ):
      UpperCamelCase_: List[Any]   				=    no_op_if_value_is_null(UpperCAmelCase__  )
      return [obj_to_image_dict_func(UpperCAmelCase__  ) for obj in objs]
    else:
      return objs
  else:
    return objs







from typing import TYPE_CHECKING

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


A_		:		Tuple		     =			{
    'configuration_funnel': ['FUNNEL_PRETRAINED_CONFIG_ARCHIVE_MAP', 'FunnelConfig'],
    'convert_funnel_original_tf_checkpoint_to_pytorch': [],
    'tokenization_funnel': ['FunnelTokenizer'],
}

try:
   if not is_tokenizers_available():
      raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
   pass
else:
   A_		:		List[str]		     =			['FunnelTokenizerFast']

try:
   if not is_torch_available():
      raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
   pass
else:
   A_		:		List[str]		     =			[
       'FUNNEL_PRETRAINED_MODEL_ARCHIVE_LIST',
       'FunnelBaseModel',
       'FunnelForMaskedLM',
       'FunnelForMultipleChoice',
       'FunnelForPreTraining',
       'FunnelForQuestionAnswering',
       'FunnelForSequenceClassification',
       'FunnelForTokenClassification',
       'FunnelModel',
       'FunnelPreTrainedModel',
       'load_tf_weights_in_funnel',
   ]

try:
   if not is_tf_available():
      raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
   pass
else:
   A_		:		str		     =			[
       'TF_FUNNEL_PRETRAINED_MODEL_ARCHIVE_LIST',
       'TFFunnelBaseModel',
       'TFFunnelForMaskedLM',
       'TFFunnelForMultipleChoice',
       'TFFunnelForPreTraining',
       'TFFunnelForQuestionAnswering',
       'TFFunnelForSequenceClassification',
       'TFFunnelForTokenClassification',
       'TFFunnelModel',
       'TFFunnelPreTrainedModel',
   ]


if TYPE_CHECKING:
   from .configuration_funnel import FUNNEL_PRETRAINED_CONFIG_ARCHIVE_MAP, FunnelConfig
   from .tokenization_funnel import FunnelTokenizer

   try:
      if not is_tokenizers_available():
         raise OptionalDependencyNotAvailable()
   except OptionalDependencyNotAvailable:
      pass
   else:
      from .tokenization_funnel_fast import FunnelTokenizerFast

   try:
      if not is_torch_available():
         raise OptionalDependencyNotAvailable()
   except OptionalDependencyNotAvailable:
      pass
   else:
      from .modeling_funnel import (
          FUNNEL_PRETRAINED_MODEL_ARCHIVE_LIST,
          FunnelBaseModel,
          FunnelForMaskedLM,
          FunnelForMultipleChoice,
          FunnelForPreTraining,
          FunnelForQuestionAnswering,
          FunnelForSequenceClassification,
          FunnelForTokenClassification,
          FunnelModel,
          FunnelPreTrainedModel,
          load_tf_weights_in_funnel,
      )

   try:
      if not is_tf_available():
         raise OptionalDependencyNotAvailable()
   except OptionalDependencyNotAvailable:
      pass
   else:
      from .modeling_tf_funnel import (
          TF_FUNNEL_PRETRAINED_MODEL_ARCHIVE_LIST,
          TFFunnelBaseModel,
          TFFunnelForMaskedLM,
          TFFunnelForMultipleChoice,
          TFFunnelForPreTraining,
          TFFunnelForQuestionAnswering,
          TFFunnelForSequenceClassification,
          TFFunnelForTokenClassification,
          TFFunnelModel,
          TFFunnelPreTrainedModel,
      )

else:
   import sys

   A_		:		Any		     =			_LazyModule(__name__, globals()['__file__'], _import_structure, module_spec=__spec__)