

import unittest

from transformers import MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING, AutoTokenizer, is_vision_available
from transformers.pipelines import pipeline
from transformers.pipelines.document_question_answering import apply_tesseract
from transformers.testing_utils import (
    is_pipeline_test,
    nested_simplify,
    require_detectrona,
    require_pytesseract,
    require_tf,
    require_torch,
    require_vision,
    slow,
)

from .test_pipelines_common import ANY


if is_vision_available():
				from PIL import Image

				from transformers.image_utils import load_image
else:

				class 						__UpperCamelCase    :




					@staticmethod
					def       __A					(		*lowerCAmelCase	:						List[str]		,	**lowerCAmelCase	:						str							):


						'''simple docstring'''







						pass



				def       __lowerCAmelCase      (						A    ):
					return None


# This is a pinned image from a specific revision of a document question answering space, hosted by HuggingFace,
# so we can expect it to be available.
_a:    Optional[Any] 							=			(
    """https://huggingface.co/spaces/impira/docquery/resolve/2f6c96314dc84dfda62d40de9da55f2f5165d403/invoice.png"""
)

@is_pipeline_test
@require_torch
@require_vision
class 						__UpperCamelCase    (					unittest.TestCase						):
	SCREAMING_SNAKE_CASE__    				=     MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING




	@require_pytesseract
	@require_vision
	def       __A					(		self	:						int		,	lowerCAmelCase	:						List[str]		,	lowerCAmelCase	:						int		,	lowerCAmelCase	:						List[str]							):


		'''simple docstring'''







		UpperCAmelCase_       				=			pipeline(
		    "document-question-answering"		,	model=lowerCAmelCase		,	tokenizer=lowerCAmelCase		,	image_processor=lowerCAmelCase							)

		UpperCAmelCase_       				=			INVOICE_URL
		UpperCAmelCase_       				=			list(zip(*apply_tesseract(load_image(lowerCAmelCase							)		,	lowerCAmelCase		,	""							)							)							)
		UpperCAmelCase_       				=			"What is the placebo?"
		UpperCAmelCase_       				=			[
		    {
		        "image": load_image(lowerCAmelCase							),
		        "question": question,
		    },
		    {
		        "image": image,
		        "question": question,
		    },
		    {
		        "image": image,
		        "question": question,
		        "word_boxes": word_boxes,
		    },
		]
		return dqa_pipeline, examples




	def       __A					(		self	:						List[str]		,	lowerCAmelCase	:						Any		,	lowerCAmelCase	:						int							):


		'''simple docstring'''







		UpperCAmelCase_       				=			dqa_pipeline(lowerCAmelCase		,	top_k=2							)
		self.assertEqual(
		    lowerCAmelCase		,	[
		        [
		            {"score": ANY(lowerCAmelCase							), "answer": ANY(lowerCAmelCase							), "start": ANY(lowerCAmelCase							), "end": ANY(lowerCAmelCase							)},
		            {"score": ANY(lowerCAmelCase							), "answer": ANY(lowerCAmelCase							), "start": ANY(lowerCAmelCase							), "end": ANY(lowerCAmelCase							)},
		        ]
		    ]
		    * 3		,	)




	@require_torch
	@require_detectrona
	@require_pytesseract
	def       __A					(		self	:						List[str]							):


		'''simple docstring'''







		UpperCAmelCase_       				=			pipeline("document-question-answering"		,	model="hf-internal-testing/tiny-random-layoutlmv2"							)
		UpperCAmelCase_       				=			INVOICE_URL
		UpperCAmelCase_       				=			"How many cats are there?"

		UpperCAmelCase_       				=			[
		    {"score": 0.0_001, "answer": "oy 2312/2019", "start": 38, "end": 39},
		    {"score": 0.0_001, "answer": "oy 2312/2019 DUE", "start": 38, "end": 40},
		]
		UpperCAmelCase_       				=			dqa_pipeline(image=lowerCAmelCase		,	question=lowerCAmelCase		,	top_k=2							)
		self.assertEqual(nested_simplify(lowerCAmelCase		,	decimals=4							)		,	lowerCAmelCase							)

		UpperCAmelCase_       				=			dqa_pipeline({"image": image, "question": question}		,	top_k=2							)
		self.assertEqual(nested_simplify(lowerCAmelCase		,	decimals=4							)		,	lowerCAmelCase							)

		# This image does not detect ANY text in it, meaning layoutlmv2 should fail.
		# Empty answer probably
		UpperCAmelCase_       				=			"./tests/fixtures/tests_samples/COCO/000000039769.png"
		UpperCAmelCase_       				=			dqa_pipeline(image=lowerCAmelCase		,	question=lowerCAmelCase		,	top_k=2							)
		self.assertEqual(lowerCAmelCase		,	[]							)

		# We can optionnally pass directly the words and bounding boxes
		UpperCAmelCase_       				=			"./tests/fixtures/tests_samples/COCO/000000039769.png"
		UpperCAmelCase_       				=			[]
		UpperCAmelCase_       				=			[]
		UpperCAmelCase_       				=			dqa_pipeline(image=lowerCAmelCase		,	question=lowerCAmelCase		,	words=lowerCAmelCase		,	boxes=lowerCAmelCase		,	top_k=2							)
		self.assertEqual(lowerCAmelCase		,	[]							)




	@slow
	@require_torch
	@require_detectrona
	@require_pytesseract
	def       __A					(		self	:						Optional[int]							):


		'''simple docstring'''







		UpperCAmelCase_       				=			pipeline(
		    "document-question-answering"		,	model="tiennvcs/layoutlmv2-base-uncased-finetuned-docvqa"		,	revision="9977165"		,	)
		UpperCAmelCase_       				=			INVOICE_URL
		UpperCAmelCase_       				=			"What is the invoice number?"

		UpperCAmelCase_       				=			dqa_pipeline(image=lowerCAmelCase		,	question=lowerCAmelCase		,	top_k=2							)
		self.assertEqual(
		    nested_simplify(lowerCAmelCase		,	decimals=4							)		,	[
		        {"score": 0.9_944, "answer": "us-001", "start": 16, "end": 16},
		        {"score": 0.0_009, "answer": "us-001", "start": 16, "end": 16},
		    ]		,	)

		UpperCAmelCase_       				=			dqa_pipeline({"image": image, "question": question}		,	top_k=2							)
		self.assertEqual(
		    nested_simplify(lowerCAmelCase		,	decimals=4							)		,	[
		        {"score": 0.9_944, "answer": "us-001", "start": 16, "end": 16},
		        {"score": 0.0_009, "answer": "us-001", "start": 16, "end": 16},
		    ]		,	)

		UpperCAmelCase_       				=			dqa_pipeline(
		    [{"image": image, "question": question}, {"image": image, "question": question}]		,	top_k=2							)
		self.assertEqual(
		    nested_simplify(lowerCAmelCase		,	decimals=4							)		,	[
		        [
		            {"score": 0.9_944, "answer": "us-001", "start": 16, "end": 16},
		            {"score": 0.0_009, "answer": "us-001", "start": 16, "end": 16},
		        ],
		    ]
		    * 2		,	)




	@slow
	@require_torch
	@require_detectrona
	@require_pytesseract
	def       __A					(		self	:						Any							):


		'''simple docstring'''







		UpperCAmelCase_       				=			pipeline(
		    "document-question-answering"		,	model="tiennvcs/layoutlmv2-base-uncased-finetuned-docvqa"		,	revision="9977165"		,	max_seq_len=50		,	)
		UpperCAmelCase_       				=			INVOICE_URL
		UpperCAmelCase_       				=			"What is the invoice number?"

		UpperCAmelCase_       				=			dqa_pipeline(image=lowerCAmelCase		,	question=lowerCAmelCase		,	top_k=2							)
		self.assertEqual(
		    nested_simplify(lowerCAmelCase		,	decimals=4							)		,	[
		        {"score": 0.9_974, "answer": "1110212019", "start": 23, "end": 23},
		        {"score": 0.9_948, "answer": "us-001", "start": 16, "end": 16},
		    ]		,	)

		UpperCAmelCase_       				=			dqa_pipeline({"image": image, "question": question}		,	top_k=2							)
		self.assertEqual(
		    nested_simplify(lowerCAmelCase		,	decimals=4							)		,	[
		        {"score": 0.9_974, "answer": "1110212019", "start": 23, "end": 23},
		        {"score": 0.9_948, "answer": "us-001", "start": 16, "end": 16},
		    ]		,	)

		UpperCAmelCase_       				=			dqa_pipeline(
		    [{"image": image, "question": question}, {"image": image, "question": question}]		,	top_k=2							)
		self.assertEqual(
		    nested_simplify(lowerCAmelCase		,	decimals=4							)		,	[
		        [
		            {"score": 0.9_974, "answer": "1110212019", "start": 23, "end": 23},
		            {"score": 0.9_948, "answer": "us-001", "start": 16, "end": 16},
		        ]
		    ]
		    * 2		,	)




	@slow
	@require_torch
	@require_pytesseract
	@require_vision
	def       __A					(		self	:						List[str]							):


		'''simple docstring'''







		UpperCAmelCase_       				=			AutoTokenizer.from_pretrained(
		    "impira/layoutlm-document-qa"		,	revision="3dc6de3"		,	add_prefix_space=lowerCAmelCase							)
		UpperCAmelCase_       				=			pipeline(
		    "document-question-answering"		,	model="impira/layoutlm-document-qa"		,	tokenizer=lowerCAmelCase		,	revision="3dc6de3"		,	)
		UpperCAmelCase_       				=			INVOICE_URL
		UpperCAmelCase_       				=			"What is the invoice number?"

		UpperCAmelCase_       				=			dqa_pipeline(image=lowerCAmelCase		,	question=lowerCAmelCase		,	top_k=2							)
		self.assertEqual(
		    nested_simplify(lowerCAmelCase		,	decimals=4							)		,	[
		        {"score": 0.4_251, "answer": "us-001", "start": 16, "end": 16},
		        {"score": 0.0_819, "answer": "1110212019", "start": 23, "end": 23},
		    ]		,	)

		UpperCAmelCase_       				=			dqa_pipeline({"image": image, "question": question}		,	top_k=2							)
		self.assertEqual(
		    nested_simplify(lowerCAmelCase		,	decimals=4							)		,	[
		        {"score": 0.4_251, "answer": "us-001", "start": 16, "end": 16},
		        {"score": 0.0_819, "answer": "1110212019", "start": 23, "end": 23},
		    ]		,	)

		UpperCAmelCase_       				=			dqa_pipeline(
		    [{"image": image, "question": question}, {"image": image, "question": question}]		,	top_k=2							)
		self.assertEqual(
		    nested_simplify(lowerCAmelCase		,	decimals=4							)		,	[
		        [
		            {"score": 0.4_251, "answer": "us-001", "start": 16, "end": 16},
		            {"score": 0.0_819, "answer": "1110212019", "start": 23, "end": 23},
		        ]
		    ]
		    * 2		,	)

		UpperCAmelCase_       				=			list(zip(*apply_tesseract(load_image(lowerCAmelCase							)		,	lowerCAmelCase		,	""							)							)							)

		# This model should also work if `image` is set to None
		UpperCAmelCase_       				=			dqa_pipeline({"image": None, "word_boxes": word_boxes, "question": question}		,	top_k=2							)
		self.assertEqual(
		    nested_simplify(lowerCAmelCase		,	decimals=4							)		,	[
		        {"score": 0.4_251, "answer": "us-001", "start": 16, "end": 16},
		        {"score": 0.0_819, "answer": "1110212019", "start": 23, "end": 23},
		    ]		,	)




	@slow
	@require_torch
	@require_pytesseract
	@require_vision
	def       __A					(		self	:						Union[str, Any]							):


		'''simple docstring'''







		UpperCAmelCase_       				=			AutoTokenizer.from_pretrained(
		    "impira/layoutlm-document-qa"		,	revision="3dc6de3"		,	add_prefix_space=lowerCAmelCase							)
		UpperCAmelCase_       				=			pipeline(
		    "document-question-answering"		,	model="impira/layoutlm-document-qa"		,	tokenizer=lowerCAmelCase		,	revision="3dc6de3"		,	max_seq_len=50		,	)
		UpperCAmelCase_       				=			INVOICE_URL
		UpperCAmelCase_       				=			"What is the invoice number?"

		UpperCAmelCase_       				=			dqa_pipeline(image=lowerCAmelCase		,	question=lowerCAmelCase		,	top_k=2							)
		self.assertEqual(
		    nested_simplify(lowerCAmelCase		,	decimals=4							)		,	[
		        {"score": 0.9_999, "answer": "us-001", "start": 16, "end": 16},
		        {"score": 0.9_998, "answer": "us-001", "start": 16, "end": 16},
		    ]		,	)

		UpperCAmelCase_       				=			dqa_pipeline(
		    [{"image": image, "question": question}, {"image": image, "question": question}]		,	top_k=2							)
		self.assertEqual(
		    nested_simplify(lowerCAmelCase		,	decimals=4							)		,	[
		        [
		            {"score": 0.9_999, "answer": "us-001", "start": 16, "end": 16},
		            {"score": 0.9_998, "answer": "us-001", "start": 16, "end": 16},
		        ]
		    ]
		    * 2		,	)

		UpperCAmelCase_       				=			list(zip(*apply_tesseract(load_image(lowerCAmelCase							)		,	lowerCAmelCase		,	""							)							)							)

		# This model should also work if `image` is set to None
		UpperCAmelCase_       				=			dqa_pipeline({"image": None, "word_boxes": word_boxes, "question": question}		,	top_k=2							)
		self.assertEqual(
		    nested_simplify(lowerCAmelCase		,	decimals=4							)		,	[
		        {"score": 0.9_999, "answer": "us-001", "start": 16, "end": 16},
		        {"score": 0.9_998, "answer": "us-001", "start": 16, "end": 16},
		    ]		,	)




	@slow
	@require_torch
	def       __A					(		self	:						List[Any]							):


		'''simple docstring'''







		UpperCAmelCase_       				=			pipeline(
		    "document-question-answering"		,	model="naver-clova-ix/donut-base-finetuned-docvqa"		,	tokenizer=AutoTokenizer.from_pretrained("naver-clova-ix/donut-base-finetuned-docvqa"							)		,	feature_extractor="naver-clova-ix/donut-base-finetuned-docvqa"		,	)

		UpperCAmelCase_       				=			INVOICE_URL
		UpperCAmelCase_       				=			"What is the invoice number?"
		UpperCAmelCase_       				=			dqa_pipeline(image=lowerCAmelCase		,	question=lowerCAmelCase		,	top_k=2							)
		self.assertEqual(nested_simplify(lowerCAmelCase		,	decimals=4							)		,	[{"answer": "us-001"}]							)




	@require_tf
	@unittest.skip("Document question answering not implemented in TF"							)
	def       __A					(		self	:						Union[str, Any]							):


		'''simple docstring'''







		pass


import warnings
from typing import Dict, List, Optional, Tuple

from ...tokenization_utils import AddedToken, PreTrainedTokenizer
from ...utils import logging


_a:    Dict 							=			logging.get_logger(__name__)

class 						__UpperCamelCase    (					lowercase						):
	SCREAMING_SNAKE_CASE__    				=     ['input_ids', 'attention_mask']




	def __init__(		self	:						Tuple		,	lowerCAmelCase	:						Union[str, Any]="</s>"		,	lowerCAmelCase	:						str="<unk>"		,	lowerCAmelCase	:						Optional[int]="<pad>"		,	lowerCAmelCase	:						List[str]=125		,	lowerCAmelCase	:						List[Any]=None		,	**lowerCAmelCase	:						Optional[Any]		,	):


		'''simple docstring'''







		if extra_ids > 0 and additional_special_tokens is None:
			UpperCAmelCase_       				=			[F"<extra_id_{i}>" for i in range(lowerCAmelCase							)]
		elif extra_ids > 0 and additional_special_tokens is not None:
			# Check that we have the right number of extra_id special tokens
			UpperCAmelCase_       				=			len(set(filter(lambda lowerCAmelCase							: bool("extra_id" in str(lowerCAmelCase							)							)		,	lowerCAmelCase							)							)							)
			if extra_tokens != extra_ids:
				raise ValueError(
				    F"Both extra_ids ({extra_ids}) and additional_special_tokens ({additional_special_tokens}) are"
				    " provided to ByT5Tokenizer. In this case the additional_special_tokens must include the"
				    " extra_ids tokens"							)

		UpperCAmelCase_       				=			AddedToken(lowerCAmelCase		,	lstrip=lowerCAmelCase		,	rstrip=lowerCAmelCase							) if isinstance(lowerCAmelCase		,	lowerCAmelCase							) else pad_token
		UpperCAmelCase_       				=			AddedToken(lowerCAmelCase		,	lstrip=lowerCAmelCase		,	rstrip=lowerCAmelCase							) if isinstance(lowerCAmelCase		,	lowerCAmelCase							) else eos_token
		UpperCAmelCase_       				=			AddedToken(lowerCAmelCase		,	lstrip=lowerCAmelCase		,	rstrip=lowerCAmelCase							) if isinstance(lowerCAmelCase		,	lowerCAmelCase							) else unk_token

		super().__init__(
		    eos_token=lowerCAmelCase		,	unk_token=lowerCAmelCase		,	pad_token=lowerCAmelCase		,	extra_ids=lowerCAmelCase		,	additional_special_tokens=lowerCAmelCase		,	**lowerCAmelCase		,	)

		UpperCAmelCase_       				=			extra_ids

		UpperCAmelCase_       				=			2**8  # utf is 8 bits

		# define special tokens dict
		UpperCAmelCase_       				=			{
		    self.pad_token: 0,
		    self.eos_token: 1,
		    self.unk_token: 2,
		}
		UpperCAmelCase_       				=			len(self.special_tokens_encoder							)
		UpperCAmelCase_       				=			len(lowerCAmelCase							)
		for i, token in enumerate(lowerCAmelCase							):
			UpperCAmelCase_       				=			self.vocab_size + i - n
		UpperCAmelCase_       				=			{v: k for k, v in self.special_tokens_encoder.items()}




	@property
	def       __A					(		self	:						Optional[Any]							):


		'''simple docstring'''







		return self._utf_vocab_size + self._num_special_tokens + self._extra_ids




	def       __A					(		self	:						List[Any]		,	lowerCAmelCase	:						List[int]		,	lowerCAmelCase	:						Optional[List[int]] = None		,	lowerCAmelCase	:						bool = False							):


		'''simple docstring'''







		if already_has_special_tokens:
			return super().get_special_tokens_mask(
			    token_ids_a=lowerCAmelCase		,	token_ids_a=lowerCAmelCase		,	already_has_special_tokens=lowerCAmelCase							)

		# normal case: some special tokens
		if token_ids_a is None:
			return ([0] * len(lowerCAmelCase							)) + [1]
		return ([0] * len(lowerCAmelCase							)) + [1] + ([0] * len(lowerCAmelCase							)) + [1]




	def       __A					(		self	:						Any		,	lowerCAmelCase	:						List[int]							):


		'''simple docstring'''







		if len(lowerCAmelCase							) > 0 and token_ids[-1] == self.eos_token_id:
			warnings.warn(
			    F"This sequence already has {self.eos_token}. In future versions this behavior may lead to duplicated"
			    " eos tokens being added."							)
			return token_ids
		else:
			return token_ids + [self.eos_token_id]




	def       __A					(		self	:						Optional[Any]		,	lowerCAmelCase	:						List[int]		,	lowerCAmelCase	:						Optional[List[int]] = None							):


		'''simple docstring'''







		UpperCAmelCase_       				=			[self.eos_token_id]

		if token_ids_a is None:
			return len(token_ids_a + eos							) * [0]
		return len(token_ids_a + eos + token_ids_a + eos							) * [0]




	def       __A					(		self	:						Tuple		,	lowerCAmelCase	:						List[int]		,	lowerCAmelCase	:						Optional[List[int]] = None							):


		'''simple docstring'''







		UpperCAmelCase_       				=			self._add_eos_if_not_present(lowerCAmelCase							)
		if token_ids_a is None:
			return token_ids_a
		else:
			UpperCAmelCase_       				=			self._add_eos_if_not_present(lowerCAmelCase							)
			return token_ids_a + token_ids_a




	def       __A					(		self	:						List[str]		,	lowerCAmelCase	:						str							):


		'''simple docstring'''







		UpperCAmelCase_       				=			[chr(lowerCAmelCase							) for i in text.encode("utf-8"							)]
		return tokens




	def       __A					(		self	:						Optional[Any]		,	lowerCAmelCase	:						List[Any]							):


		'''simple docstring'''







		if token in self.special_tokens_encoder:
			UpperCAmelCase_       				=			self.special_tokens_encoder[token]
		elif token in self.added_tokens_encoder:
			UpperCAmelCase_       				=			self.added_tokens_encoder[token]
		elif len(lowerCAmelCase							) != 1:
			UpperCAmelCase_       				=			self.unk_token_id
		else:
			UpperCAmelCase_       				=			ord(lowerCAmelCase							) + self._num_special_tokens
		return token_id




	def       __A					(		self	:						str		,	lowerCAmelCase	:						Any							):


		'''simple docstring'''







		if index in self.special_tokens_decoder:
			UpperCAmelCase_       				=			self.special_tokens_decoder[index]
		else:
			UpperCAmelCase_       				=			chr(index - self._num_special_tokens							)
		return token




	def       __A					(		self	:						Union[str, Any]		,	lowerCAmelCase	:						Union[str, Any]							):


		'''simple docstring'''







		UpperCAmelCase_       				=			b""
		for token in tokens:
			if token in self.special_tokens_decoder:
				UpperCAmelCase_       				=			self.special_tokens_decoder[token].encode("utf-8"							)
			elif token in self.added_tokens_decoder:
				UpperCAmelCase_       				=			self.special_tokens_decoder[token].encode("utf-8"							)
			elif token in self.special_tokens_encoder:
				UpperCAmelCase_       				=			token.encode("utf-8"							)
			elif token in self.added_tokens_encoder:
				UpperCAmelCase_       				=			token.encode("utf-8"							)
			else:
				UpperCAmelCase_       				=			bytes([ord(lowerCAmelCase							)]							)
			bstring += tok_string
		UpperCAmelCase_       				=			bstring.decode("utf-8"		,	errors="ignore"							)
		return string




	def       __A					(		self	:						List[Any]		,	lowerCAmelCase	:						str		,	lowerCAmelCase	:						Optional[str] = None							):


		'''simple docstring'''







		return ()