"""simple docstring"""




import unittest

from transformers import (
    MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING,
    TF_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING,
    TextClassificationPipeline,
    pipeline,
)
from transformers.testing_utils import is_pipeline_test, nested_simplify, require_tf, require_torch, slow

from .test_pipelines_common import ANY


# These 2 model types require different inputs than those of the usual text models.
_a      :		Union[str, Any]           =   {'LayoutLMv2Config', 'LayoutLMv3Config'}
@is_pipeline_test
class 						__A							( unittest.TestCase		):
     _UpperCamelCase							:			int							=		MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING
     _UpperCamelCase							:			List[str]							=		TF_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING

     if model_mapping is not None:
          _UpperCamelCase							:			Any							=		{config: model for config, model in model_mapping.items() if config.__name__ not in _TO_SKIP}
     if tf_model_mapping is not None:
          _UpperCamelCase							:			Optional[int]							=		{
              config: model for config, model in tf_model_mapping.items() if config.__name__ not in _TO_SKIP
          }






     @require_torch
     def     __A  (		self  ):
       _lowerCAmelCase						:       Tuple  			=     pipeline(
           task="""text-classification"""				,     model="""hf-internal-testing/tiny-random-distilbert"""				,     framework="""pt"""  )

       _lowerCAmelCase						:       Union[str, Any]  			=     text_classifier("""This is great !"""  )
       self.assertEqual(nested_simplify(a__  )				,     [{"""label""": """LABEL_0""", """score""": 0.5_0_4}]  )

       _lowerCAmelCase						:       List[Any]  			=     text_classifier("""This is great !"""				,     top_k=2  )
       self.assertEqual(
           nested_simplify(a__  )				,     [{"""label""": """LABEL_0""", """score""": 0.5_0_4}, {"""label""": """LABEL_1""", """score""": 0.4_9_6}]  )

       _lowerCAmelCase						:       Any  			=     text_classifier(["""This is great !""", """This is bad"""]				,     top_k=2  )
       self.assertEqual(
           nested_simplify(a__  )				,     [
               [{"""label""": """LABEL_0""", """score""": 0.5_0_4}, {"""label""": """LABEL_1""", """score""": 0.4_9_6}],
               [{"""label""": """LABEL_0""", """score""": 0.5_0_4}, {"""label""": """LABEL_1""", """score""": 0.4_9_6}],
           ]				,     )

       _lowerCAmelCase						:       Optional[int]  			=     text_classifier("""This is great !"""				,     top_k=1  )
       self.assertEqual(nested_simplify(a__  )				,     [{"""label""": """LABEL_0""", """score""": 0.5_0_4}]  )

       # Legacy behavior
       _lowerCAmelCase						:       Tuple  			=     text_classifier("""This is great !"""				,     return_all_scores=a__  )
       self.assertEqual(nested_simplify(a__  )				,     [{"""label""": """LABEL_0""", """score""": 0.5_0_4}]  )

       _lowerCAmelCase						:       int  			=     text_classifier("""This is great !"""				,     return_all_scores=a__  )
       self.assertEqual(
           nested_simplify(a__  )				,     [[{"""label""": """LABEL_0""", """score""": 0.5_0_4}, {"""label""": """LABEL_1""", """score""": 0.4_9_6}]]  )

       _lowerCAmelCase						:       str  			=     text_classifier(["""This is great !""", """Something else"""]				,     return_all_scores=a__  )
       self.assertEqual(
           nested_simplify(a__  )				,     [
               [{"""label""": """LABEL_0""", """score""": 0.5_0_4}, {"""label""": """LABEL_1""", """score""": 0.4_9_6}],
               [{"""label""": """LABEL_0""", """score""": 0.5_0_4}, {"""label""": """LABEL_1""", """score""": 0.4_9_6}],
           ]				,     )

       _lowerCAmelCase						:       str  			=     text_classifier(["""This is great !""", """Something else"""]				,     return_all_scores=a__  )
       self.assertEqual(
           nested_simplify(a__  )				,     [
               {"""label""": """LABEL_0""", """score""": 0.5_0_4},
               {"""label""": """LABEL_0""", """score""": 0.5_0_4},
           ]				,     )






     @require_torch
     def     __A  (		self  ):
       import torch

       _lowerCAmelCase						:       Any  			=     pipeline(
           task="""text-classification"""				,     model="""hf-internal-testing/tiny-random-distilbert"""				,     framework="""pt"""				,     device=torch.device("""cpu"""  )				,     )

       _lowerCAmelCase						:       Union[str, Any]  			=     text_classifier("""This is great !"""  )
       self.assertEqual(nested_simplify(a__  )				,     [{"""label""": """LABEL_0""", """score""": 0.5_0_4}]  )






     @require_tf
     def     __A  (		self  ):
       _lowerCAmelCase						:       Union[str, Any]  			=     pipeline(
           task="""text-classification"""				,     model="""hf-internal-testing/tiny-random-distilbert"""				,     framework="""tf"""  )

       _lowerCAmelCase						:       Tuple  			=     text_classifier("""This is great !"""  )
       self.assertEqual(nested_simplify(a__  )				,     [{"""label""": """LABEL_0""", """score""": 0.5_0_4}]  )






     @slow
     @require_torch
     def     __A  (		self  ):
       _lowerCAmelCase						:       Union[str, Any]  			=     pipeline("""text-classification"""  )

       _lowerCAmelCase						:       str  			=     text_classifier("""This is great !"""  )
       self.assertEqual(nested_simplify(a__  )				,     [{"""label""": """POSITIVE""", """score""": 1.0}]  )
       _lowerCAmelCase						:       Optional[int]  			=     text_classifier("""This is bad !"""  )
       self.assertEqual(nested_simplify(a__  )				,     [{"""label""": """NEGATIVE""", """score""": 1.0}]  )
       _lowerCAmelCase						:       int  			=     text_classifier("""Birds are a type of animal"""  )
       self.assertEqual(nested_simplify(a__  )				,     [{"""label""": """POSITIVE""", """score""": 0.9_8_8}]  )






     @slow
     @require_tf
     def     __A  (		self  ):
       _lowerCAmelCase						:       Tuple  			=     pipeline("""text-classification"""				,     framework="""tf"""  )

       _lowerCAmelCase						:       int  			=     text_classifier("""This is great !"""  )
       self.assertEqual(nested_simplify(a__  )				,     [{"""label""": """POSITIVE""", """score""": 1.0}]  )
       _lowerCAmelCase						:       int  			=     text_classifier("""This is bad !"""  )
       self.assertEqual(nested_simplify(a__  )				,     [{"""label""": """NEGATIVE""", """score""": 1.0}]  )
       _lowerCAmelCase						:       Optional[Any]  			=     text_classifier("""Birds are a type of animal"""  )
       self.assertEqual(nested_simplify(a__  )				,     [{"""label""": """POSITIVE""", """score""": 0.9_8_8}]  )






     def     __A  (		self				,     a__				,     a__				,     a__  ):
       _lowerCAmelCase						:       List[str]  			=     TextClassificationPipeline(model=a__				,     tokenizer=a__  )
       return text_classifier, ["HuggingFace is in", "This is another test"]






     def     __A  (		self				,     a__				,     a__  ):
       _lowerCAmelCase						:       Dict  			=     text_classifier.model
       # Small inputs because BartTokenizer tiny has maximum position embeddings = 22
       _lowerCAmelCase						:       Any  			=     """HuggingFace is in"""
       _lowerCAmelCase						:       int  			=     text_classifier(a__  )

       self.assertEqual(nested_simplify(a__  )				,     [{"""label""": ANY(a__  ), """score""": ANY(a__  )}]  )
       self.assertTrue(outputs[0]["""label"""] in model.config.idalabel.values()  )

       _lowerCAmelCase						:       Optional[Any]  			=     ["""HuggingFace is in """, """Paris is in France"""]
       _lowerCAmelCase						:       Optional[Any]  			=     text_classifier(a__  )
       self.assertEqual(
           nested_simplify(a__  )				,     [{"""label""": ANY(a__  ), """score""": ANY(a__  )}, {"""label""": ANY(a__  ), """score""": ANY(a__  )}]				,     )
       self.assertTrue(outputs[0]["""label"""] in model.config.idalabel.values()  )
       self.assertTrue(outputs[1]["""label"""] in model.config.idalabel.values()  )

       # Forcing to get all results with `top_k=None`
       # This is NOT the legacy format
       _lowerCAmelCase						:       Dict  			=     text_classifier(a__				,     top_k=a__  )
       _lowerCAmelCase						:       Optional[Any]  			=     len(model.config.idalabel.values()  )
       self.assertEqual(
           nested_simplify(a__  )				,     [[{"""label""": ANY(a__  ), """score""": ANY(a__  )}] * N, [{"""label""": ANY(a__  ), """score""": ANY(a__  )}] * N]				,     )

       _lowerCAmelCase						:       str  			=     {"""text""": """HuggingFace is in """, """text_pair""": """Paris is in France"""}
       _lowerCAmelCase						:       Dict  			=     text_classifier(a__  )
       self.assertEqual(
           nested_simplify(a__  )				,     {"""label""": ANY(a__  ), """score""": ANY(a__  )}				,     )
       self.assertTrue(outputs["""label"""] in model.config.idalabel.values()  )

       # This might be used a text pair, but tokenizer + pipe interaction
       # makes it hard to understand that it's not using the pair properly
       # https://github.com/huggingface/transformers/issues/17305
       # We disabled this usage instead as it was outputting wrong outputs.
       _lowerCAmelCase						:       Any  			=     [["""HuggingFace is in """, """Paris is in France"""]]
       with self.assertRaises(a__  ):
         text_classifier(a__  )

       # This used to be valid for doing text pairs
       # We're keeping it working because of backward compatibility
       _lowerCAmelCase						:       Optional[Any]  			=     text_classifier([[["""HuggingFace is in """, """Paris is in France"""]]]  )
       self.assertEqual(
           nested_simplify(a__  )				,     [{"""label""": ANY(a__  ), """score""": ANY(a__  )}]				,     )
       self.assertTrue(outputs[0]["""label"""] in model.config.idalabel.values()  )





"""simple docstring"""




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_tf_available():
     from ..models.auto.modeling_tf_auto import TF_MODEL_FOR_VISION_2_SEQ_MAPPING

if is_torch_available():
     import torch

     from ..models.auto.modeling_auto import MODEL_FOR_VISION_2_SEQ_MAPPING

_a      :		Dict           =   logging.get_logger(__name__)
@add_end_docstrings(SCREAMING_SNAKE_CASE_		)
class 						__A							( SCREAMING_SNAKE_CASE_		):






     def __init__(		self				,     *a__				,     **a__  ):
       super().__init__(*a__				,     **a__  )
       requires_backends(self				,     """vision"""  )
       self.check_model_type(
           TF_MODEL_FOR_VISION_2_SEQ_MAPPING if self.framework == """tf""" else MODEL_FOR_VISION_2_SEQ_MAPPING  )






     def     __A  (		self				,     a__=None				,     a__=None				,     a__=None  ):
       _lowerCAmelCase						:       List[str]  			=     {}
       _lowerCAmelCase						:       Union[str, Any]  			=     {}

       if prompt is not None:
         _lowerCAmelCase						:       List[Any]  			=     prompt

       if generate_kwargs is not None:
         _lowerCAmelCase						:       List[str]  			=     generate_kwargs
       if max_new_tokens is not None:
         if "generate_kwargs" not in forward_kwargs:
           _lowerCAmelCase						:       str  			=     {}
         if "max_new_tokens" in forward_kwargs["generate_kwargs"]:
           raise ValueError(
               """'max_new_tokens' is defined twice, once in 'generate_kwargs' and once as a direct parameter,"""
               """ please use only one"""  )
         _lowerCAmelCase						:       Optional[Any]  			=     max_new_tokens
       return preprocess_params, forward_kwargs, {}






     def __call__(		self				,     a__				,     **a__  ):
       return super().__call__(a__				,     **a__  )






     def     __A  (		self				,     a__				,     a__=None  ):
       _lowerCAmelCase						:       Tuple  			=     load_image(a__  )

       if prompt is not None:
         if not isinstance(a__				,     a__  ):
           raise ValueError(
               F"Received an invalid text input, got - {type(a__  )} - but expected a single string. "
               """Note also that one single text can be provided for conditional image to text generation."""  )

         _lowerCAmelCase						:       Optional[int]  			=     self.model.config.model_type

         if model_type == "git":
           _lowerCAmelCase						:       Optional[Any]  			=     self.image_processor(images=a__				,     return_tensors=self.framework  )
           _lowerCAmelCase						:       List[str]  			=     self.tokenizer(text=a__				,     add_special_tokens=a__  ).input_ids
           _lowerCAmelCase						:       Union[str, Any]  			=     [self.tokenizer.cls_token_id] + input_ids
           _lowerCAmelCase						:       Dict  			=     torch.tensor(a__  ).unsqueeze(0  )
           model_inputs.update({"""input_ids""": input_ids}  )

         elif model_type == "pix2struct":
           _lowerCAmelCase						:       Tuple  			=     self.image_processor(images=a__				,     header_text=a__				,     return_tensors=self.framework  )

         elif model_type != "vision-encoder-decoder":
           # vision-encoder-decoder does not support conditional generation
           _lowerCAmelCase						:       Optional[int]  			=     self.image_processor(images=a__				,     return_tensors=self.framework  )
           _lowerCAmelCase						:       Optional[int]  			=     self.tokenizer(a__				,     return_tensors=self.framework  )
           model_inputs.update(a__  )

         else:
           raise ValueError(F"Model type {model_type} does not support conditional text generation"  )

       else:
         _lowerCAmelCase						:       Any  			=     self.image_processor(images=a__				,     return_tensors=self.framework  )

       if self.model.config.model_type == "git" and prompt is None:
         _lowerCAmelCase						:       Union[str, Any]  			=     None

       return model_inputs






     def     __A  (		self				,     a__				,     a__=None  ):
       # Git model sets `model_inputs["input_ids"] = None` in `preprocess` (when `prompt=None`). In batch model, the
       # pipeline will group them into a list of `None`, which fail `_forward`. Avoid this by checking it first.
       if (
           "input_ids" in model_inputs
           and isinstance(model_inputs["""input_ids"""]				,     a__  )
           and all(x is None for x in model_inputs["""input_ids"""]  )
       ):
         _lowerCAmelCase						:       Optional[int]  			=     None

       if generate_kwargs is None:
         _lowerCAmelCase						:       List[str]  			=     {}
       # FIXME: We need to pop here due to a difference in how `generation.py` and `generation.tf_utils.py`
       #  parse inputs. In the Tensorflow version, `generate` raises an error if we don't use `input_ids` whereas
       #  the PyTorch version matches it with `self.model.main_input_name` or `self.model.encoder.main_input_name`
       #  in the `_prepare_model_inputs` method.
       _lowerCAmelCase						:       Tuple  			=     model_inputs.pop(self.model.main_input_name  )
       _lowerCAmelCase						:       Union[str, Any]  			=     self.model.generate(a__				,     **a__				,     **a__  )
       return model_outputs






     def     __A  (		self				,     a__  ):
       _lowerCAmelCase						:       Optional[int]  			=     []
       for output_ids in model_outputs:
         _lowerCAmelCase						:       Any  			=     {
             """generated_text""": self.tokenizer.decode(
                 a__				,     skip_special_tokens=a__				,     )
         }
         records.append(a__  )
       return records




