
"""simple docstring"""






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


_lowercase							=				logging.get_logger(__name__)

class 					__a     ( __a       ):



							'''simple docstring'''







							def   SCREAMING_SNAKE_CASE						(     self  ,    _lowerCamelCase       )			->							int:




										'''simple docstring'''
										if isinstance(_lowerCamelCase  ,    _lowerCamelCase       ):
													__lowercase       =       [label.strip() for label in labels.split(","       ) if label.strip()]
										return labels





							def __call__(     self  ,    _lowerCamelCase  ,    _lowerCamelCase  ,    _lowerCamelCase       )			->							Any:




										'''simple docstring'''
										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       ):
													__lowercase       =       [sequences]

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

										return sequence_pairs, sequences





@add_end_docstrings(__a       )
class 					__a     ( __a       ):



							'''simple docstring'''







							def __init__(     self  ,    _lowerCamelCase=ZeroShotClassificationArgumentHandler()  ,    *_lowerCamelCase  ,    **_lowerCamelCase       )			->							Optional[int]:




										'''simple docstring'''
										__lowercase       =       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   SCREAMING_SNAKE_CASE						(     self       )			->							Dict:




										'''simple docstring'''
										for label, ind in self.model.config.labelaid.items():
													if label.lower().startswith("entail"       ):
																return ind
										return -1
							def   SCREAMING_SNAKE_CASE						(     self  ,    _lowerCamelCase  ,    _lowerCamelCase=True  ,    _lowerCamelCase=True  ,    _lowerCamelCase=TruncationStrategy.ONLY_FIRST  ,    **_lowerCamelCase       )			->							Union[str, Any]:




										'''simple docstring'''
										__lowercase       =       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`"       )
													__lowercase       =       self.tokenizer.eos_token
										try:
													__lowercase       =       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.

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

										return inputs
							def   SCREAMING_SNAKE_CASE						(     self  ,    **_lowerCamelCase       )			->							Dict:




										'''simple docstring'''
										if kwargs.get("multi_class"  ,    _lowerCamelCase       ) is not None:
													__lowercase       =       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."       )
										__lowercase       =       {}
										if "candidate_labels" in kwargs:
													__lowercase       =       self._args_parser._parse_labels(kwargs["candidate_labels"]       )
										if "hypothesis_template" in kwargs:
													__lowercase       =       kwargs["hypothesis_template"]

										__lowercase       =       {}
										if "multi_label" in kwargs:
													__lowercase       =       kwargs["multi_label"]
										return preprocess_params, {}, postprocess_params
							def __call__(     self  ,    _lowerCamelCase  ,    *_lowerCamelCase  ,    **_lowerCamelCase  ,    )			->							Optional[Any]:




										'''simple docstring'''
										if len(_lowerCamelCase       ) == 0:
													pass
										elif len(_lowerCamelCase       ) == 1 and "candidate_labels" not in kwargs:
													__lowercase       =       args[0]
										else:
													raise ValueError(f'''Unable to understand extra arguments {args}'''       )

										return super().__call__(_lowerCamelCase  ,    **_lowerCamelCase       )
							def   SCREAMING_SNAKE_CASE						(     self  ,    _lowerCamelCase  ,    _lowerCamelCase=None  ,    _lowerCamelCase="This example is {}."       )			->							Dict:




										'''simple docstring'''
										__lowercase   ,					__lowercase       =       self._args_parser(_lowerCamelCase  ,    _lowerCamelCase  ,    _lowerCamelCase       )

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

													yield {
													    "candidate_label": candidate_label,
													    "sequence": sequences[0],
													    "is_last": i == len(_lowerCamelCase       ) - 1,
													    **model_input,
													}
							def   SCREAMING_SNAKE_CASE						(     self  ,    _lowerCamelCase       )			->							Optional[int]:




										'''simple docstring'''
										__lowercase       =       inputs["candidate_label"]
										__lowercase       =       inputs["sequence"]
										__lowercase       =       {k: inputs[k] for k in self.tokenizer.model_input_names}
										__lowercase       =       self.model(**_lowerCamelCase       )

										__lowercase       =       {
										    "candidate_label": candidate_label,
										    "sequence": sequence,
										    "is_last": inputs["is_last"],
										    **outputs,
										}
										return model_outputs





							def   SCREAMING_SNAKE_CASE						(     self  ,    _lowerCamelCase  ,    _lowerCamelCase=False       )			->							Optional[Any]:




										'''simple docstring'''
										__lowercase       =       [outputs["candidate_label"] for outputs in model_outputs]
										__lowercase       =       [outputs["sequence"] for outputs in model_outputs]
										__lowercase       =       np.concatenate([output["logits"].numpy() for output in model_outputs]       )
										__lowercase       =       logits.shape[0]
										__lowercase       =       len(_lowerCamelCase       )
										__lowercase       =       N // n
										__lowercase       =       logits.reshape((num_sequences, n, -1)       )

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

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







"""simple docstring"""






import html

from ...feature_extraction_utils import BatchFeature, FeatureExtractionMixin
from ...utils import is_bsa_available, logging, requires_backends


if is_bsa_available():
					import bsa
					from bsa import BeautifulSoup


_lowercase							=				logging.get_logger(__name__)

class 					__a     ( __a       ):



							'''simple docstring'''







							def __init__(     self  ,    **_lowerCamelCase       )			->							List[Any]:




										'''simple docstring'''
										requires_backends(self  ,    ["bs4"]       )
										super().__init__(**_lowerCamelCase       )
							def   SCREAMING_SNAKE_CASE						(     self  ,    _lowerCamelCase       )			->							Tuple:




										'''simple docstring'''
										__lowercase       =       []
										__lowercase       =       []
										__lowercase       =       element if element.name else element.parent
										for parent in child.parents:  # type: bs4.element.Tag
													__lowercase       =       parent.find_all(child.name  ,    recursive=_lowerCamelCase       )
													xpath_tags.append(child.name       )
													xpath_subscripts.append(
													    0 if 1 == len(_lowerCamelCase       ) else next(i for i, s in enumerate(_lowerCamelCase  ,    1       ) if s is child       )       )
													__lowercase       =       parent
										xpath_tags.reverse()
										xpath_subscripts.reverse()
										return xpath_tags, xpath_subscripts
							def   SCREAMING_SNAKE_CASE						(     self  ,    _lowerCamelCase       )			->							Union[str, Any]:




										'''simple docstring'''
										__lowercase       =       BeautifulSoup(_lowerCamelCase  ,    "html.parser"       )

										__lowercase       =       []
										__lowercase       =       []
										__lowercase       =       []

										for element in html_code.descendants:
													if type(_lowerCamelCase       ) == bsa.element.NavigableString:
																if type(element.parent       ) != bsa.element.Tag:
																			continue

																__lowercase       =       html.unescape(_lowerCamelCase       ).strip()
																if not text_in_this_tag:
																			continue

																all_doc_strings.append(_lowerCamelCase       )

																__lowercase   ,					__lowercase       =       self.xpath_soup(_lowerCamelCase       )
																stringaxtag_seq.append(_lowerCamelCase       )
																stringaxsubs_seq.append(_lowerCamelCase       )

										if len(_lowerCamelCase       ) != len(_lowerCamelCase       ):
													raise ValueError("Number of doc strings and xtags does not correspond"       )
										if len(_lowerCamelCase       ) != len(_lowerCamelCase       ):
													raise ValueError("Number of doc strings and xsubs does not correspond"       )

										return all_doc_strings, stringaxtag_seq, stringaxsubs_seq
							def   SCREAMING_SNAKE_CASE						(     self  ,    _lowerCamelCase  ,    _lowerCamelCase       )			->							Tuple:




										'''simple docstring'''
										__lowercase       =       ""
										for tagname, subs in zip(_lowerCamelCase  ,    _lowerCamelCase       ):
													xpath += f'''/{tagname}'''
													if subs != 0:
																xpath += f'''[{subs}]'''
										return xpath





							def __call__(     self  ,    _lowerCamelCase       )			->							BatchFeature:




										'''simple docstring'''
										__lowercase       =       False

										# Check that strings has a valid type
										if isinstance(_lowerCamelCase  ,    _lowerCamelCase       ):
													__lowercase       =       True
										elif isinstance(_lowerCamelCase  ,    (list, tuple)       ):
													if len(_lowerCamelCase       ) == 0 or isinstance(html_strings[0]  ,    _lowerCamelCase       ):
																__lowercase       =       True

										if not valid_strings:
													raise ValueError(
													    "HTML strings must of type `str`, `List[str]` (batch of examples), "
													    f'''but is of type {type(_lowerCamelCase       )}.'''       )

										__lowercase       =       bool(isinstance(_lowerCamelCase  ,    (list, tuple)       ) and (isinstance(html_strings[0]  ,    _lowerCamelCase       ))       )

										if not is_batched:
													__lowercase       =       [html_strings]

										# Get nodes + xpaths
										__lowercase       =       []
										__lowercase       =       []
										for html_string in html_strings:
													__lowercase   ,					__lowercase   ,					__lowercase       =       self.get_three_from_single(_lowerCamelCase       )
													nodes.append(_lowerCamelCase       )
													__lowercase       =       []
													for node, tag_list, sub_list in zip(_lowerCamelCase  ,    _lowerCamelCase  ,    _lowerCamelCase       ):
																__lowercase       =       self.construct_xpath(_lowerCamelCase  ,    _lowerCamelCase       )
																xpath_strings.append(_lowerCamelCase       )
													xpaths.append(_lowerCamelCase       )

										# return as Dict
										__lowercase       =       {"nodes": nodes, "xpaths": xpaths}
										__lowercase       =       BatchFeature(data=_lowerCamelCase  ,    tensor_type=_lowerCamelCase       )

										return encoded_inputs





