


import enum
import warnings

from .. import MODEL_FOR_CAUSAL_LM_MAPPING, TF_MODEL_FOR_CAUSAL_LM_MAPPING
from ..utils import add_end_docstrings, is_tf_available
from .base import PIPELINE_INIT_ARGS, Pipeline


if is_tf_available():
    import tensorflow as tf







class 			_lowercase (							enum.Enum):


       """simple docstring"""




       A__											=			0
       A__											=			1
       A__											=			2







@add_end_docstrings(lowercase__)
class 			_lowercase (							lowercase__):


       """simple docstring"""




       A__											=			"\n    In 1991, the remains of Russian Tsar Nicholas II and his family (except for Alexei and Maria) are discovered. The\n    voice of Nicholas's young son, Tsarevich Alexei Nikolaevich, narrates the remainder of the story. 1883 Western\n    Siberia, a young Grigori Rasputin is asked by his father and a group of men to perform magic. Rasputin has a vision\n    and denounces one of the men as a horse thief. Although his father initially slaps him for making such an\n    accusation, Rasputin watches as the man is chased outside and beaten. Twenty years later, Rasputin sees a vision of\n    the Virgin Mary, prompting him to become a priest. Rasputin quickly becomes famous, with people, even a bishop,\n    begging for his blessing. <eod> </s> <eos>\n    "





       def __init__(   self							:			List[str]					,      *__lowerCamelCase							:			Optional[Any]					,      **__lowerCamelCase							:			Optional[Any]       ):


             '''simple docstring'''



             super().__init__(*__lowerCamelCase					,      **__lowerCamelCase       )
             self.check_model_type(
                 TF_MODEL_FOR_CAUSAL_LM_MAPPING if self.framework == "tf" else MODEL_FOR_CAUSAL_LM_MAPPING       )
             if "prefix" not in self._preprocess_params:
                   # This is very specific. The logic is quite complex and needs to be done
                   # as a "default".
                   # It also defines both some preprocess_kwargs and generate_kwargs
                   # which is why we cannot put them in their respective methods.
                   lowerCamelCase__		:				List[Any]    =  None
                   if self.model.config.prefix is not None:
                         lowerCamelCase__		:				str    =  self.model.config.prefix
                   if prefix is None and self.model.__class__.__name__ in [
                       "XLNetLMHeadModel",
                       "TransfoXLLMHeadModel",
                       "TFXLNetLMHeadModel",
                       "TFTransfoXLLMHeadModel",
                   ]:
                         # For XLNet and TransformerXL we add an article to the prompt to give more state to the model.
                         lowerCamelCase__		:				List[Any]    =  self.XL_PREFIX
                   if prefix is not None:
                         # Recalculate some generate_kwargs linked to prefix.
                         lowerCamelCase__    ,   lowerCamelCase__    ,   lowerCamelCase__		:				List[Any]    =  self._sanitize_parameters(prefix=__lowerCamelCase					,      **self._forward_params       )
                         lowerCamelCase__		:				Optional[Any]    =  {**self._preprocess_params, **preprocess_params}
                         lowerCamelCase__		:				str    =  {**self._forward_params, **forward_params}





       def 						lowerCAmelCase     (   self							:			Optional[int]					,      __lowerCamelCase							:			Any=None					,      __lowerCamelCase							:			Optional[int]=None					,      __lowerCamelCase							:			str=None					,      __lowerCamelCase							:			Union[str, Any]=None					,      __lowerCamelCase							:			Any=None					,      __lowerCamelCase							:			int=None					,      __lowerCamelCase							:			int=None					,      __lowerCamelCase							:			Optional[Any]=None					,      **__lowerCamelCase							:			Optional[Any]					,      ):


             '''simple docstring'''



             lowerCamelCase__		:				str    =  {}
             if prefix is not None:
                   lowerCamelCase__		:				List[str]    =  prefix
             if prefix:
                   lowerCamelCase__		:				Tuple    =  self.tokenizer(
                       __lowerCamelCase					,      padding=__lowerCamelCase					,      add_special_tokens=__lowerCamelCase					,      return_tensors=self.framework       )
                   lowerCamelCase__		:				Optional[Any]    =  prefix_inputs["input_ids"].shape[-1]

             if handle_long_generation is not None:
                   if handle_long_generation not in {"hole"}:
                         raise ValueError(
                             f"{handle_long_generation} is not a valid value for `handle_long_generation` parameter expected"
                             " [None, 'hole']"       )
                   lowerCamelCase__		:				Tuple    =  handle_long_generation

             preprocess_params.update(__lowerCamelCase       )
             lowerCamelCase__		:				Tuple    =  generate_kwargs

             lowerCamelCase__		:				Optional[Any]    =  {}
             if return_full_text is not None and return_type is None:
                   if return_text is not None:
                         raise ValueError("`return_text` is mutually exclusive with `return_full_text`"       )
                   if return_tensors is not None:
                         raise ValueError("`return_full_text` is mutually exclusive with `return_tensors`"       )
                   lowerCamelCase__		:				Optional[Any]    =  ReturnType.FULL_TEXT if return_full_text else ReturnType.NEW_TEXT
             if return_tensors is not None and return_type is None:
                   if return_text is not None:
                         raise ValueError("`return_text` is mutually exclusive with `return_tensors`"       )
                   lowerCamelCase__		:				Optional[Any]    =  ReturnType.TENSORS
             if return_type is not None:
                   lowerCamelCase__		:				Any    =  return_type
             if clean_up_tokenization_spaces is not None:
                   lowerCamelCase__		:				Any    =  clean_up_tokenization_spaces

             if stop_sequence is not None:
                   lowerCamelCase__		:				Optional[Any]    =  self.tokenizer.encode(__lowerCamelCase					,      add_special_tokens=__lowerCamelCase       )
                   if len(__lowerCamelCase       ) > 1:
                         warnings.warn(
                             "Stopping on a multiple token sequence is not yet supported on transformers. The first token of"
                             " the stop sequence will be used as the stop sequence string in the interim."       )
                   lowerCamelCase__		:				Optional[int]    =  stop_sequence_ids[0]

             return preprocess_params, forward_params, postprocess_params





       def 						lowerCAmelCase     (   self							:			List[Any]					,      *__lowerCamelCase							:			Union[str, Any]					,      **__lowerCamelCase							:			str       ):


             '''simple docstring'''



             if self.model.__class__.__name__ in ["TransfoXLLMHeadModel"]:
                   kwargs.update({"add_space_before_punct_symbol": True}       )

             return super()._parse_and_tokenize(*__lowerCamelCase					,      **__lowerCamelCase       )





       def __call__(   self							:			Any					,      __lowerCamelCase							:			Union[str, Any]					,      **__lowerCamelCase							:			Dict       ):


             '''simple docstring'''



             return super().__call__(__lowerCamelCase					,      **__lowerCamelCase       )





       def 						lowerCAmelCase     (   self							:			Dict					,      __lowerCamelCase							:			List[Any]					,      __lowerCamelCase							:			Union[str, Any]=""					,      __lowerCamelCase							:			Any=None					,      **__lowerCamelCase							:			Tuple       ):


             '''simple docstring'''



             lowerCamelCase__		:				Optional[Any]    =  self.tokenizer(
                 prefix + prompt_text					,      padding=__lowerCamelCase					,      add_special_tokens=__lowerCamelCase					,      return_tensors=self.framework       )
             lowerCamelCase__		:				Optional[int]    =  prompt_text

             if handle_long_generation == "hole":
                   lowerCamelCase__		:				Optional[int]    =  inputs["input_ids"].shape[-1]
                   if "max_new_tokens" in generate_kwargs:
                         lowerCamelCase__		:				Any    =  generate_kwargs["max_new_tokens"]
                   else:
                         lowerCamelCase__		:				Optional[Any]    =  generate_kwargs.get("max_length"					,      self.model.config.max_length       ) - cur_len
                         if new_tokens < 0:
                               raise ValueError("We cannot infer how many new tokens are expected"       )
                   if cur_len + new_tokens > self.tokenizer.model_max_length:
                         lowerCamelCase__		:				Optional[Any]    =  self.tokenizer.model_max_length - new_tokens
                         if keep_length <= 0:
                               raise ValueError(
                                   "We cannot use `hole` to handle this generation the number of desired tokens exceeds the"
                                   " models max length"       )

                         lowerCamelCase__		:				List[str]    =  inputs["input_ids"][:, -keep_length:]
                         if "attention_mask" in inputs:
                               lowerCamelCase__		:				str    =  inputs["attention_mask"][:, -keep_length:]

             return inputs





       def 						lowerCAmelCase     (   self							:			Optional[int]					,      __lowerCamelCase							:			int					,      **__lowerCamelCase							:			int       ):


             '''simple docstring'''



             lowerCamelCase__		:				int    =  model_inputs["input_ids"]
             lowerCamelCase__		:				List[Any]    =  model_inputs.get("attention_mask"					,      __lowerCamelCase       )
             # Allow empty prompts
             if input_ids.shape[1] == 0:
                   lowerCamelCase__		:				Dict    =  None
                   lowerCamelCase__		:				List[str]    =  None
                   lowerCamelCase__		:				Tuple    =  1
             else:
                   lowerCamelCase__		:				List[str]    =  input_ids.shape[0]
             lowerCamelCase__		:				str    =  model_inputs.pop("prompt_text"       )

             # If there is a prefix, we may need to adjust the generation length. Do so without permanently modifying
             # generate_kwargs, as some of the parameterization may come from the initialization of the pipeline.
             lowerCamelCase__		:				Union[str, Any]    =  generate_kwargs.pop("prefix_length"					,      0       )
             if prefix_length > 0:
                   lowerCamelCase__		:				Union[str, Any]    =  "max_new_tokens" in generate_kwargs or (
                       "generation_config" in generate_kwargs
                       and generate_kwargs["generation_config"].max_new_tokens is not None
                   )
                   if not has_max_new_tokens:
                         lowerCamelCase__		:				Tuple    =  generate_kwargs.get("max_length"       ) or self.model.config.max_length
                         generate_kwargs["max_length"] += prefix_length
                   lowerCamelCase__		:				Tuple    =  "min_new_tokens" in generate_kwargs or (
                       "generation_config" in generate_kwargs
                       and generate_kwargs["generation_config"].min_new_tokens is not None
                   )
                   if not has_min_new_tokens and "min_length" in generate_kwargs:
                         generate_kwargs["min_length"] += prefix_length

        # BS x SL
             lowerCamelCase__		:				List[str]    =  self.model.generate(input_ids=__lowerCamelCase					,      attention_mask=__lowerCamelCase					,      **__lowerCamelCase       )
             lowerCamelCase__		:				Union[str, Any]    =  generated_sequence.shape[0]
             if self.framework == "pt":
                   lowerCamelCase__		:				Optional[Any]    =  generated_sequence.reshape(__lowerCamelCase					,      out_b // in_b					,      *generated_sequence.shape[1:]       )
             elif self.framework == "tf":
                   lowerCamelCase__		:				int    =  tf.reshape(__lowerCamelCase					,      (in_b, out_b // in_b, *generated_sequence.shape[1:])       )
             return {"generated_sequence": generated_sequence, "input_ids": input_ids, "prompt_text": prompt_text}





       def 						lowerCAmelCase     (   self							:			Optional[int]					,      __lowerCamelCase							:			Dict					,      __lowerCamelCase							:			List[str]=ReturnType.FULL_TEXT					,      __lowerCamelCase							:			Optional[Any]=True       ):


             '''simple docstring'''



             lowerCamelCase__		:				Optional[Any]    =  model_outputs["generated_sequence"][0]
             lowerCamelCase__		:				Tuple    =  model_outputs["input_ids"]
             lowerCamelCase__		:				int    =  model_outputs["prompt_text"]
             lowerCamelCase__		:				Union[str, Any]    =  generated_sequence.numpy().tolist()
             lowerCamelCase__		:				Dict    =  []
             for sequence in generated_sequence:
                   if return_type == ReturnType.TENSORS:
                         lowerCamelCase__		:				Optional[Any]    =  {"generated_token_ids": sequence}
                   elif return_type in {ReturnType.NEW_TEXT, ReturnType.FULL_TEXT}:
                         # Decode text
                         lowerCamelCase__		:				Union[str, Any]    =  self.tokenizer.decode(
                             __lowerCamelCase					,      skip_special_tokens=__lowerCamelCase					,      clean_up_tokenization_spaces=__lowerCamelCase					,      )

                         # Remove PADDING prompt of the sequence if XLNet or Transfo-XL model is used
                         if input_ids is None:
                               lowerCamelCase__		:				Tuple    =  0
                         else:
                               lowerCamelCase__		:				Optional[int]    =  len(
                                   self.tokenizer.decode(
                                       input_ids[0]					,      skip_special_tokens=__lowerCamelCase					,      clean_up_tokenization_spaces=__lowerCamelCase					,      )       )

                         if return_type == ReturnType.FULL_TEXT:
                               lowerCamelCase__		:				Optional[int]    =  prompt_text + text[prompt_length:]
                         else:
                               lowerCamelCase__		:				int    =  text[prompt_length:]

                         lowerCamelCase__		:				List[Any]    =  {"generated_text": all_text}
                   records.append(__lowerCamelCase       )

             return records






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      :    str		=					"<" 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      :    str		=					[
    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 			_lowercase :


       """simple docstring"""




       A__											=			True
       A__											=			None
       # Automatically constructed
       A__											=			"PIL.Image.Image"
       A__											=			pa.struct({"bytes": pa.binary(), "path": pa.string()})
       A__											=			field(default="Image"							,  init=lowercase__							,  repr=lowercase__)





       def __call__(   self							:			Any       ):


             '''simple docstring'''



             return self.pa_type





       def 						lowerCAmelCase     (   self							:			Optional[Any]					,      __lowerCamelCase							:			Union[str, bytes, dict, np.ndarray, "PIL.Image.Image"]       ):


             '''simple docstring'''



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

             if isinstance(__lowerCamelCase					,      __lowerCamelCase       ):
                   lowerCamelCase__		:				str    =  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 						lowerCAmelCase     (   self							:			Any					,      __lowerCamelCase							:			dict					,      __lowerCamelCase							:			List[Any]=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:
                   lowerCamelCase__		:				Union[str, Any]    =  {}

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





       def 						lowerCAmelCase     (   self							:			Dict       ):


             '''simple docstring'''



             from .features import Value

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





       def 						lowerCAmelCase     (   self							:			Optional[Any]					,      __lowerCamelCase							:			Union[pa.StringArray, pa.StructArray, pa.ListArray]       ):


             '''simple docstring'''



             if pa.types.is_string(storage.type       ):
                   lowerCamelCase__		:				Dict    =  pa.array([None] * len(__lowerCamelCase       )					,      type=pa.binary()       )
                   lowerCamelCase__		:				List[str]    =  pa.StructArray.from_arrays([bytes_array, storage]					,      ["bytes", "path"]					,      mask=storage.is_null()       )
             elif pa.types.is_binary(storage.type       ):
                   lowerCamelCase__		:				List[Any]    =  pa.array([None] * len(__lowerCamelCase       )					,      type=pa.string()       )
                   lowerCamelCase__		:				Any    =  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:
                         lowerCamelCase__		:				Dict    =  storage.field("bytes"       )
                   else:
                         lowerCamelCase__		:				Optional[int]    =  pa.array([None] * len(__lowerCamelCase       )					,      type=pa.binary()       )
                   if storage.type.get_field_index("path"       ) >= 0:
                         lowerCamelCase__		:				Dict    =  storage.field("path"       )
                   else:
                         lowerCamelCase__		:				Dict    =  pa.array([None] * len(__lowerCamelCase       )					,      type=pa.string()       )
                   lowerCamelCase__		:				int    =  pa.StructArray.from_arrays([bytes_array, path_array]					,      ["bytes", "path"]					,      mask=storage.is_null()       )
             elif pa.types.is_list(storage.type       ):
                   lowerCamelCase__		:				Union[str, Any]    =  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()					,      )
                   lowerCamelCase__		:				Dict    =  pa.array([None] * len(__lowerCamelCase       )					,      type=pa.string()       )
                   lowerCamelCase__		:				Dict    =  pa.StructArray.from_arrays(
                       [bytes_array, path_array]					,      ["bytes", "path"]					,      mask=bytes_array.is_null()       )
             return array_cast(__lowerCamelCase					,      self.pa_type       )





       def 						lowerCAmelCase     (   self							:			int					,      __lowerCamelCase							:			pa.StructArray       ):


             '''simple docstring'''



             @no_op_if_value_is_null
             def path_to_bytes(__lowerCamelCase							:			Union[str, Any]       ):
                   with xopen(__lowerCamelCase					,      "rb"       ) as f:
                         lowerCamelCase__		:				str    =  f.read()
                   return bytes_

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



def       lowercase_		(		):

      """simple docstring"""




      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()
            lowerCamelCase__		:				List[str]    =  list(set(PIL.Image.OPEN.keys()						) & set(PIL.Image.SAVE.keys()						)						)
      return _IMAGE_COMPRESSION_FORMATS

def       lowercase_		(		_A			:    "PIL.Image.Image"						):

      """simple docstring"""




      lowerCamelCase__		:				Optional[Any]    =  BytesIO()
      if image.format in list_image_compression_formats():
            lowerCamelCase__		:				int    =  image.format
      else:
            lowerCamelCase__		:				int    =  "PNG" if image.mode in ["1", "L", "LA", "RGB", "RGBA"] else "TIFF"
      image.save(_A    ,					format=_A						)
      return buffer.getvalue()

def       lowercase_		(		_A			:    "PIL.Image.Image"						):

      """simple docstring"""




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

def       lowercase_		(		_A			:    np.ndarray						):

      """simple docstring"""




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

      lowerCamelCase__		:				int    =  array.dtype
      lowerCamelCase__		:				List[str]    =  dtype.byteorder if dtype.byteorder != "=" else _NATIVE_BYTEORDER
      lowerCamelCase__		:				List[str]    =  dtype.kind
      lowerCamelCase__		:				Optional[Any]    =  dtype.itemsize

      lowerCamelCase__		:				Dict    =  None

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


def       lowercase_		(		_A			:    Union[List[str], List[dict], List[np.ndarray], List["PIL.Image.Image"]]						):

      """simple docstring"""




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

      if objs:
            lowerCamelCase__    ,   lowerCamelCase__		:				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						):
                  lowerCamelCase__		:				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						):
                  lowerCamelCase__		:				int    =  no_op_if_value_is_null(_A						)
                  return [obj_to_image_dict_func(_A						) for obj in objs]
            else:
                  return objs
      else:
            return objs


