



"""simple docstring"""







from __future__ import annotations

from collections.abc import Callable
from typing import Generic, TypeVar

lowerCAmelCase_   						=   TypeVar('T')
lowerCAmelCase_   						=   TypeVar('U')
class        __A       (	Generic[T, U]    ):







		'''simple docstring'''





		def __init__(	self						:  Any			,_snake_case						:  T | None			,_snake_case						:  U | None						)					->		int:






				"""simple docstring"""



				lowercase__   :    Union[str, Any]				=			key
				lowercase__   :    Dict				=			val
				lowercase__   :    DoubleLinkedListNode[T, U] | None				=			None
				lowercase__   :    DoubleLinkedListNode[T, U] | None				=			None







		def __repr__(	self						:  Any						)					->		str:






				"""simple docstring"""



				return (
				    f"""Node: key: {self.key}, val: {self.val}, """
				    f"""has next: {bool(self.next						)}, has prev: {bool(self.prev						)}"""
				)





class        __A       (	Generic[T, U]    ):







		'''simple docstring'''





		def __init__(	self						:  List[str]						)					->		None:






				"""simple docstring"""



				lowercase__   :    DoubleLinkedListNode[T, U]				=			DoubleLinkedListNode(_snake_case			,_snake_case						)
				lowercase__   :    DoubleLinkedListNode[T, U]				=			DoubleLinkedListNode(_snake_case			,_snake_case						)
				lowercase__		,			lowercase__   :    Any				=			self.rear, self.head







		def __repr__(	self						:  Optional[Any]						)					->		str:






				"""simple docstring"""



				lowercase__   :    Any				=			['''DoubleLinkedList''']
				lowercase__   :    Dict				=			self.head
				while node.next is not None:
						rep.append(str(_snake_case						)						)
						lowercase__   :    str				=			node.next
				rep.append(str(self.rear						)						)
				return ",\n    ".join(_snake_case						)







		def 					UpperCAmelCase    (	self						:  int			,_snake_case						:  DoubleLinkedListNode[T, U]						)					->		None:






				"""simple docstring"""



				lowercase__   :    Dict				=			self.rear.prev

				# All nodes other than self.head are guaranteed to have non-None previous
				assert previous is not None

				lowercase__   :    str				=			node
				lowercase__   :    str				=			previous
				lowercase__   :    List[Any]				=			node
				lowercase__   :    Tuple				=			self.rear







		def 					UpperCAmelCase    (	self						:  Optional[Any]			,_snake_case						:  DoubleLinkedListNode[T, U]						)					->		DoubleLinkedListNode[T, U] | None:






				"""simple docstring"""



				if node.prev is None or node.next is None:
						return None

				lowercase__   :    Dict				=			node.next
				lowercase__   :    Any				=			node.prev
				lowercase__   :    int				=			None
				lowercase__   :    int				=			None
				return node





class        __A       (	Generic[T, U]    ):







		'''simple docstring'''





		lowerCAmelCase			:					dict[Callable[[T], U], LRUCache[T, U]]   	=				{}







		def __init__(	self						:  Any			,_snake_case						:  int						)					->		Any:






				"""simple docstring"""



				lowercase__   :    DoubleLinkedList[T, U]				=			DoubleLinkedList()
				lowercase__   :    Optional[Any]				=			capacity
				lowercase__   :    Tuple				=			0
				lowercase__   :    List[str]				=			0
				lowercase__   :    Dict				=			0
				lowercase__   :    dict[T, DoubleLinkedListNode[T, U]]				=			{}







		def __repr__(	self						:  str						)					->		str:






				"""simple docstring"""



				return (
				    f"""CacheInfo(hits={self.hits}, misses={self.miss}, """
				    f"""capacity={self.capacity}, current size={self.num_keys})"""
				)







		def __contains__(	self						:  Optional[int]			,_snake_case						:  T						)					->		bool:






				"""simple docstring"""



				return key in self.cache







		def 					UpperCAmelCase    (	self						:  Any			,_snake_case						:  T						)					->		U | None:






				"""simple docstring"""



				if key in self.cache:
						self.hits += 1
						lowercase__   :    DoubleLinkedListNode[T, U]				=			self.cache[key]
						lowercase__   :    Dict				=			self.list.remove(self.cache[key]						)
						assert node == value_node

						# node is guaranteed not None because it is in self.cache
						assert node is not None
						self.list.add(_snake_case						)
						return node.val
				self.miss += 1
				return None







		def 					UpperCAmelCase    (	self						:  int			,_snake_case						:  T			,_snake_case						:  U						)					->		None:






				"""simple docstring"""



				if key not in self.cache:
						if self.num_keys >= self.capacity:
								# delete first node (oldest) when over capacity
								lowercase__   :    Dict				=			self.list.head.next

								# guaranteed to have a non-None first node when num_keys > 0
								# explain to type checker via assertions
								assert first_node is not None
								assert first_node.key is not None
								assert (
								    self.list.remove(_snake_case						) is not None
								)  # node guaranteed to be in list assert node.key is not None

								del self.cache[first_node.key]
								self.num_keys -= 1
						lowercase__   :    Union[str, Any]				=			DoubleLinkedListNode(_snake_case			,_snake_case						)
						self.list.add(self.cache[key]						)
						self.num_keys += 1

				else:
						# bump node to the end of the list, update value
						lowercase__   :    List[str]				=			self.list.remove(self.cache[key]						)
						assert node is not None  # node guaranteed to be in list
						lowercase__   :    str				=			value
						self.list.add(_snake_case						)







		@classmethod
		def 					UpperCAmelCase    (	cls						:  Union[str, Any]			,_snake_case						:  int = 128						)					->		Callable[[Callable[[T], U]], Callable[..., U]]:






				"""simple docstring"""



				def cache_decorator_inner(_snake_case						:  Callable[[T], U]						) -> Callable[..., U]:
						def cache_decorator_wrapper(*_snake_case						:  T						) -> U:
								if func not in cls.decorator_function_to_instance_map:
										lowercase__   :    Tuple				=			LRUCache(_snake_case						)

								lowercase__   :    Union[str, Any]				=			cls.decorator_function_to_instance_map[func].get(args[0]						)
								if result is None:
										lowercase__   :    List[str]				=			func(*_snake_case						)
										cls.decorator_function_to_instance_map[func].put(args[0]			,_snake_case						)
								return result

						def cache_info() -> LRUCache[T, U]:
								return cls.decorator_function_to_instance_map[func]

						setattr(_snake_case			,'''cache_info'''			,_snake_case						)  # noqa: B010

						return cache_decorator_wrapper

				return cache_decorator_inner


if __name__ == "__main__":
							import doctest

							doctest.testmod()





"""simple docstring"""







from collections import UserDict
from typing import List, Union

from ..utils import (
    add_end_docstrings,
    is_tf_available,
    is_torch_available,
    is_vision_available,
    logging,
    requires_backends,
)
from .base import PIPELINE_INIT_ARGS, Pipeline


if is_vision_available():
							from PIL import Image

							from ..image_utils import load_image

if is_torch_available():
							from ..models.auto.modeling_auto import MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING

if is_tf_available():
							from ..models.auto.modeling_tf_auto import TF_MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING
							from ..tf_utils import stable_softmax

lowerCAmelCase_   						=   logging.get_logger(__name__)
@add_end_docstrings(A_    )
class        __A       (	A_    ):







		'''simple docstring'''





		def __init__(	self						:  List[str]			,**_snake_case						:  Dict						)					->		List[Any]:






				"""simple docstring"""



				super().__init__(**_snake_case						)

				requires_backends(self			,'''vision'''						)
				self.check_model_type(
				    TF_MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING
				    if self.framework == '''tf'''
				    else MODEL_FOR_ZERO_SHOT_IMAGE_CLASSIFICATION_MAPPING						)







		def __call__(	self						:  Optional[int]			,_snake_case						:  Union[str, List[str], "Image", List["Image"]]			,**_snake_case						:  int						)					->		Optional[Any]:






				"""simple docstring"""



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







		def 					UpperCAmelCase    (	self						:  Dict			,**_snake_case						:  Optional[int]						)					->		List[Any]:






				"""simple docstring"""



				lowercase__   :    List[str]				=			{}
				if "candidate_labels" in kwargs:
						lowercase__   :    Any				=			kwargs['''candidate_labels''']
				if "hypothesis_template" in kwargs:
						lowercase__   :    Optional[Any]				=			kwargs['''hypothesis_template''']

				return preprocess_params, {}, {}







		def 					UpperCAmelCase    (	self						:  Optional[Any]			,_snake_case						:  Optional[int]			,_snake_case						:  Dict=None			,_snake_case						:  Union[str, Any]="This is a photo of {}."						)					->		List[str]:






				"""simple docstring"""



				lowercase__   :    List[Any]				=			load_image(_snake_case						)
				lowercase__   :    int				=			self.image_processor(images=[image]			,return_tensors=self.framework						)
				lowercase__   :    str				=			candidate_labels
				lowercase__   :    Dict				=			[hypothesis_template.format(_snake_case						) for x in candidate_labels]
				lowercase__   :    Any				=			self.tokenizer(_snake_case			,return_tensors=self.framework			,padding=_snake_case						)
				lowercase__   :    Optional[int]				=			[text_inputs]
				return inputs







		def 					UpperCAmelCase    (	self						:  Optional[Any]			,_snake_case						:  Optional[int]						)					->		List[Any]:






				"""simple docstring"""



				lowercase__   :    Optional[int]				=			model_inputs.pop('''candidate_labels'''						)
				lowercase__   :    Union[str, Any]				=			model_inputs.pop('''text_inputs'''						)
				if isinstance(text_inputs[0]			,_snake_case						):
						lowercase__   :    List[str]				=			text_inputs[0]
				else:
						# Batching case.
						lowercase__   :    int				=			text_inputs[0][0]

				lowercase__   :    Tuple				=			self.model(**_snake_case			,**_snake_case						)

				lowercase__   :    Union[str, Any]				=			{
				    '''candidate_labels''': candidate_labels,
				    '''logits''': outputs.logits_per_image,
				}
				return model_outputs







		def 					UpperCAmelCase    (	self						:  Any			,_snake_case						:  Tuple						)					->		Any:






				"""simple docstring"""



				lowercase__   :    Dict				=			model_outputs.pop('''candidate_labels'''						)
				lowercase__   :    Optional[Any]				=			model_outputs['''logits'''][0]
				if self.framework == "pt":
						lowercase__   :    Optional[int]				=			logits.softmax(dim=-1						).squeeze(-1						)
						lowercase__   :    Tuple				=			probs.tolist()
						if not isinstance(_snake_case			,_snake_case						):
								lowercase__   :    Any				=			[scores]
				elif self.framework == "tf":
						lowercase__   :    List[str]				=			stable_softmax(_snake_case			,axis=-1						)
						lowercase__   :    Optional[Any]				=			probs.numpy().tolist()
				else:
						raise ValueError(f"""Unsupported framework: {self.framework}"""						)

				lowercase__   :    Union[str, Any]				=			[
				    {'''score''': score, '''label''': candidate_label}
				    for score, candidate_label in sorted(zip(_snake_case			,_snake_case						)			,key=lambda _snake_case						: -x[0]						)
				]
				return result
