





from typing import List, Union

import numpy as np

from ..tokenization_utils import TruncationStrategy
from ..utils import add_end_docstrings, logging
from .base import PIPELINE_INIT_ARGS, ArgumentHandler, ChunkPipeline


a__: Any							   =						logging.get_logger(__name__)




class        SCREAMING_SNAKE_CASE__					(		UpperCamelCase__ ):



 def 							UpperCamelCase     (				self,__lowerCamelCase					):
        if isinstance(__lowerCamelCase,__lowerCamelCase					):
               A__		   =		[label.strip() for label in labels.split(''','''					) if label.strip()]
        return labels




 def __call__(				self,__lowerCamelCase,__lowerCamelCase,__lowerCamelCase					):
        if len(__lowerCamelCase					) == 0 or len(__lowerCamelCase					) == 0:
               raise ValueError('''You must include at least one label and at least one sequence.'''					)
        if hypothesis_template.format(labels[0]					) == hypothesis_template:
               raise ValueError(
                   (
                       '''The provided hypothesis_template "{}" was not able to be formatted with the target labels. '''
                       '''Make sure the passed template includes formatting syntax such as {{}} where the label should go.'''
                   ).format(__lowerCamelCase					)					)

        if isinstance(__lowerCamelCase,__lowerCamelCase					):
               A__		   =		[sequences]

        A__		   =		[]
        for sequence in sequences:
               sequence_pairs.extend([[sequence, hypothesis_template.format(__lowerCamelCase					)] for label in labels]					)

        return sequence_pairs, sequences




@add_end_docstrings(UpperCamelCase__ )
class        SCREAMING_SNAKE_CASE__					(		UpperCamelCase__ ):



 def __init__(				self,__lowerCamelCase=ZeroShotClassificationArgumentHandler(),*__lowerCamelCase,**__lowerCamelCase					):
        A__		   =		args_parser
        super().__init__(*__lowerCamelCase,**__lowerCamelCase					)
        if self.entailment_id == -1:
               logger.warning(
                   '''Failed to determine \'entailment\' label id from the label2id mapping in the model config. Setting to '''
                   '''-1. Define a descriptive label2id mapping in the model config to ensure correct outputs.'''					)



 @property
 def 							UpperCamelCase     (				self					):
        for label, ind in self.model.config.labelaid.items():
               if label.lower().startswith('''entail'''					):
                      return ind
        return -1



 def 							UpperCamelCase     (				self,__lowerCamelCase,__lowerCamelCase=True,__lowerCamelCase=True,__lowerCamelCase=TruncationStrategy.ONLY_FIRST,**__lowerCamelCase					):
        A__		   =		self.framework
        if self.tokenizer.pad_token is None:
               # Override for tokenizers not supporting padding
               logger.error(
                   '''Tokenizer was not supporting padding necessary for zero-shot, attempting to use '''
                   ''' `pad_token=eos_token`'''					)
               A__		   =		self.tokenizer.eos_token
        try:
               A__		   =		self.tokenizer(
                   __lowerCamelCase,add_special_tokens=__lowerCamelCase,return_tensors=__lowerCamelCase,padding=__lowerCamelCase,truncation=__lowerCamelCase,)
        except Exception as e:
               if "too short" in str(__lowerCamelCase					):
                      # tokenizers might yell that we want to truncate
                      # to a value that is not even reached by the input.
                      # In that case we don't want to truncate.
                      # It seems there's not a really better way to catch that
                      # exception.

                      A__		   =		self.tokenizer(
                          __lowerCamelCase,add_special_tokens=__lowerCamelCase,return_tensors=__lowerCamelCase,padding=__lowerCamelCase,truncation=TruncationStrategy.DO_NOT_TRUNCATE,)
               else:
                      raise e

        return inputs



 def 							UpperCamelCase     (				self,**__lowerCamelCase					):
        if kwargs.get('''multi_class''',__lowerCamelCase					) is not None:
               A__		   =		kwargs['''multi_class''']
               logger.warning(
                   '''The `multi_class` argument has been deprecated and renamed to `multi_label`. '''
                   '''`multi_class` will be removed in a future version of Transformers.'''					)
        A__		   =		{}
        if "candidate_labels" in kwargs:
               A__		   =		self._args_parser._parse_labels(kwargs['''candidate_labels''']					)
        if "hypothesis_template" in kwargs:
               A__		   =		kwargs['''hypothesis_template''']

        A__		   =		{}
        if "multi_label" in kwargs:
               A__		   =		kwargs['''multi_label''']
        return preprocess_params, {}, postprocess_params



 def __call__(				self,__lowerCamelCase,*__lowerCamelCase,**__lowerCamelCase,):
        if len(__lowerCamelCase					) == 0:
               pass
        elif len(__lowerCamelCase					) == 1 and "candidate_labels" not in kwargs:
               A__		   =		args[0]
        else:
               raise ValueError(f"Unable to understand extra arguments {args}"					)

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



 def 							UpperCamelCase     (				self,__lowerCamelCase,__lowerCamelCase=None,__lowerCamelCase="This example is {}."					):
        A__   ,      A__		   =		self._args_parser(__lowerCamelCase,__lowerCamelCase,__lowerCamelCase					)

        for i, (candidate_label, sequence_pair) in enumerate(zip(__lowerCamelCase,__lowerCamelCase					)					):
               A__		   =		self._parse_and_tokenize([sequence_pair]					)

               yield {
                   "candidate_label": candidate_label,
                   "sequence": sequences[0],
                   "is_last": i == len(__lowerCamelCase					) - 1,
                   **model_input,
               }



 def 							UpperCamelCase     (				self,__lowerCamelCase					):
        A__		   =		inputs['''candidate_label''']
        A__		   =		inputs['''sequence''']
        A__		   =		{k: inputs[k] for k in self.tokenizer.model_input_names}
        A__		   =		self.model(**__lowerCamelCase					)

        A__		   =		{
            '''candidate_label''': candidate_label,
            '''sequence''': sequence,
            '''is_last''': inputs['''is_last'''],
            **outputs,
        }
        return model_outputs




 def 							UpperCamelCase     (				self,__lowerCamelCase,__lowerCamelCase=False					):
        A__		   =		[outputs['''candidate_label'''] for outputs in model_outputs]
        A__		   =		[outputs['''sequence'''] for outputs in model_outputs]
        A__		   =		np.concatenate([output['''logits'''].numpy() for output in model_outputs]					)
        A__		   =		logits.shape[0]
        A__		   =		len(__lowerCamelCase					)
        A__		   =		N // n
        A__		   =		logits.reshape((num_sequences, n, -1)					)

        if multi_label or len(__lowerCamelCase					) == 1:
               # softmax over the entailment vs. contradiction dim for each label independently
               A__		   =		self.entailment_id
               A__		   =		-1 if entailment_id == 0 else 0
               A__		   =		reshaped_outputs[..., [contradiction_id, entailment_id]]
               A__		   =		np.exp(__lowerCamelCase					) / np.exp(__lowerCamelCase					).sum(-1,keepdims=__lowerCamelCase					)
               A__		   =		scores[..., 1]
        else:
               # softmax the "entailment" logits over all candidate labels
               A__		   =		reshaped_outputs[..., self.entailment_id]
               A__		   =		np.exp(__lowerCamelCase					) / np.exp(__lowerCamelCase					).sum(-1,keepdims=__lowerCamelCase					)

        A__		   =		list(reversed(scores[0].argsort()					)					)
        return {
            "sequence": sequences[0],
            "labels": [candidate_labels[i] for i in top_inds],
            "scores": scores[0, top_inds].tolist(),
        }












import json
import os
import tempfile
import unittest
import unittest.mock as mock
from pathlib import Path

from requests.exceptions import HTTPError

from transformers.utils import (
    CONFIG_NAME,
    FLAX_WEIGHTS_NAME,
    TF2_WEIGHTS_NAME,
    TRANSFORMERS_CACHE,
    WEIGHTS_NAME,
    cached_file,
    get_file_from_repo,
    has_file,
)


a__: Union[str, Any]							   =						'hf-internal-testing/tiny-random-bert'
a__: Optional[int]							   =						os.path.join(TRANSFORMERS_CACHE, 'models--hf-internal-testing--tiny-random-bert')
a__: List[str]							   =						'9b8c223d42b2188cb49d29af482996f9d0f3e5a6'




class        SCREAMING_SNAKE_CASE__					(		unittest.TestCase ):



 def 							UpperCamelCase     (				self					):
        A__		   =		cached_file(__lowerCamelCase,__lowerCamelCase					)
        # Should have downloaded the file in here
        self.assertTrue(os.path.isdir(__lowerCamelCase					)					)
        # Cache should contain at least those three subfolders:
        for subfolder in ["blobs", "refs", "snapshots"]:
               self.assertTrue(os.path.isdir(os.path.join(__lowerCamelCase,__lowerCamelCase					)					)					)
        with open(os.path.join(__lowerCamelCase,'''refs''','''main'''					)					) as f:
               A__		   =		f.read()
        self.assertEqual(__lowerCamelCase,os.path.join(__lowerCamelCase,'''snapshots''',__lowerCamelCase,__lowerCamelCase					)					)
        self.assertTrue(os.path.isfile(__lowerCamelCase					)					)

        # File is cached at the same place the second time.
        A__		   =		cached_file(__lowerCamelCase,__lowerCamelCase					)
        self.assertEqual(__lowerCamelCase,__lowerCamelCase					)

        # Using a specific revision to test the full commit hash.
        A__		   =		cached_file(__lowerCamelCase,__lowerCamelCase,revision='''9b8c223'''					)
        self.assertEqual(__lowerCamelCase,os.path.join(__lowerCamelCase,'''snapshots''',__lowerCamelCase,__lowerCamelCase					)					)



 def 							UpperCamelCase     (				self					):
        with self.assertRaisesRegex(__lowerCamelCase,'''is not a valid model identifier'''					):
               A__		   =		cached_file('''tiny-random-bert''',__lowerCamelCase					)

        with self.assertRaisesRegex(__lowerCamelCase,'''is not a valid git identifier'''					):
               A__		   =		cached_file(__lowerCamelCase,__lowerCamelCase,revision='''aaaa'''					)

        with self.assertRaisesRegex(__lowerCamelCase,'''does not appear to have a file named'''					):
               A__		   =		cached_file(__lowerCamelCase,'''conf'''					)



 def 							UpperCamelCase     (				self					):
        with self.assertRaisesRegex(__lowerCamelCase,'''does not appear to have a file named'''					):
               A__		   =		cached_file(__lowerCamelCase,'''conf'''					)

        with open(os.path.join(__lowerCamelCase,'''refs''','''main'''					)					) as f:
               A__		   =		f.read()
        self.assertTrue(os.path.isfile(os.path.join(__lowerCamelCase,'''.no_exist''',__lowerCamelCase,'''conf'''					)					)					)

        A__		   =		cached_file(__lowerCamelCase,'''conf''',_raise_exceptions_for_missing_entries=__lowerCamelCase					)
        self.assertIsNone(__lowerCamelCase					)

        A__		   =		cached_file(__lowerCamelCase,'''conf''',local_files_only=__lowerCamelCase,_raise_exceptions_for_missing_entries=__lowerCamelCase					)
        self.assertIsNone(__lowerCamelCase					)

        A__		   =		mock.Mock()
        A__		   =		500
        A__		   =		{}
        A__		   =		HTTPError
        A__		   =		{}

        # Under the mock environment we get a 500 error when trying to reach the tokenizer.
        with mock.patch('''requests.Session.request''',return_value=__lowerCamelCase					) as mock_head:
               A__		   =		cached_file(__lowerCamelCase,'''conf''',_raise_exceptions_for_connection_errors=__lowerCamelCase					)
               self.assertIsNone(__lowerCamelCase					)
               # This check we did call the fake head request
               mock_head.assert_called()



 def 							UpperCamelCase     (				self					):
        self.assertTrue(has_file('''hf-internal-testing/tiny-bert-pt-only''',__lowerCamelCase					)					)
        self.assertFalse(has_file('''hf-internal-testing/tiny-bert-pt-only''',__lowerCamelCase					)					)
        self.assertFalse(has_file('''hf-internal-testing/tiny-bert-pt-only''',__lowerCamelCase					)					)



 def 							UpperCamelCase     (				self					):
        # `get_file_from_repo` returns None if the file does not exist
        self.assertIsNone(get_file_from_repo('''bert-base-cased''','''ahah.txt'''					)					)

        # The function raises if the repository does not exist.
        with self.assertRaisesRegex(__lowerCamelCase,'''is not a valid model identifier'''					):
               get_file_from_repo('''bert-base-case''',__lowerCamelCase					)

        # The function raises if the revision does not exist.
        with self.assertRaisesRegex(__lowerCamelCase,'''is not a valid git identifier'''					):
               get_file_from_repo('''bert-base-cased''',__lowerCamelCase,revision='''ahaha'''					)

        A__		   =		get_file_from_repo('''bert-base-cased''',__lowerCamelCase					)
        # The name is the cached name which is not very easy to test, so instead we load the content.
        A__		   =		json.loads(open(__lowerCamelCase,'''r'''					).read()					)
        self.assertEqual(config['''hidden_size'''],768					)




 def 							UpperCamelCase     (				self					):
        with tempfile.TemporaryDirectory() as tmp_dir:
               A__		   =		Path(__lowerCamelCase					) / '''a.txt'''
               filename.touch()
               self.assertEqual(get_file_from_repo(__lowerCamelCase,'''a.txt'''					),str(__lowerCamelCase					)					)

               self.assertIsNone(get_file_from_repo(__lowerCamelCase,'''b.txt'''					)					)





