





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 		snake_case_   :







			'''simple docstring'''




			@staticmethod
			def    UpperCAmelCase			(						*__lowerCamelCase							:     List[Any]					,      **__lowerCamelCase							:     Tuple   )       -> Optional[Any]:

					'''simple docstring'''




					pass





		def  SCREAMING_SNAKE_CASE				(      snake_case							)		->    Optional[Any]:
				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.
SCREAMING_SNAKE_CASE_   :      str			=   (
    '''https://huggingface.co/spaces/impira/docquery/resolve/2f6c96314dc84dfda62d40de9da55f2f5165d403/invoice.png'''
)

@is_pipeline_test
@require_torch
@require_vision
class 		snake_case_   (							unittest.TestCase						):







	'''simple docstring'''
	__UpperCamelCase   =		MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING




	@require_pytesseract
	@require_vision
	def    UpperCAmelCase			(						self							:     Tuple					,      __lowerCamelCase							:     Optional[int]					,      __lowerCamelCase							:     List[Any]					,      __lowerCamelCase							:     str   )       -> Dict:

			'''simple docstring'''




			__lowercase											=     pipeline(
			    'document-question-answering'					,      model=__lowerCamelCase					,      tokenizer=__lowerCamelCase					,      image_processor=__lowerCamelCase   )

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




	def    UpperCAmelCase			(						self							:     Union[str, Any]					,      __lowerCamelCase							:     Tuple					,      __lowerCamelCase							:     Optional[int]   )       -> Union[str, Any]:

			'''simple docstring'''




			__lowercase											=     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    UpperCAmelCase			(						self							:     Tuple   )       -> Dict:

			'''simple docstring'''




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

			__lowercase											=     [
			    {'score': 0.0001, 'answer': 'oy 2312/2019', 'start': 38, 'end': 39},
			    {'score': 0.0001, 'answer': 'oy 2312/2019 DUE', 'start': 38, 'end': 40},
			]
			__lowercase											=     dqa_pipeline(image=__lowerCamelCase					,      question=__lowerCamelCase					,      top_k=2   )
			self.assertEqual(nested_simplify(__lowerCamelCase					,      decimals=4   )					,      __lowerCamelCase   )

			__lowercase											=     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
			__lowercase											=     './tests/fixtures/tests_samples/COCO/000000039769.png'
			__lowercase											=     dqa_pipeline(image=__lowerCamelCase					,      question=__lowerCamelCase					,      top_k=2   )
			self.assertEqual(__lowerCamelCase					,      []   )

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




	@slow
	@require_torch
	@require_detectrona
	@require_pytesseract
	def    UpperCAmelCase			(						self							:     Any   )       -> Any:

			'''simple docstring'''




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

			__lowercase											=     dqa_pipeline(image=__lowerCamelCase					,      question=__lowerCamelCase					,      top_k=2   )
			self.assertEqual(
			    nested_simplify(__lowerCamelCase					,      decimals=4   )					,      [
			        {'score': 0.9944, 'answer': 'us-001', 'start': 16, 'end': 16},
			        {'score': 0.0009, 'answer': 'us-001', 'start': 16, 'end': 16},
			    ]					,      )

			__lowercase											=     dqa_pipeline({'image': image, 'question': question}					,      top_k=2   )
			self.assertEqual(
			    nested_simplify(__lowerCamelCase					,      decimals=4   )					,      [
			        {'score': 0.9944, 'answer': 'us-001', 'start': 16, 'end': 16},
			        {'score': 0.0009, 'answer': 'us-001', 'start': 16, 'end': 16},
			    ]					,      )

			__lowercase											=     dqa_pipeline(
			    [{'image': image, 'question': question}, {'image': image, 'question': question}]					,      top_k=2   )
			self.assertEqual(
			    nested_simplify(__lowerCamelCase					,      decimals=4   )					,      [
			        [
			            {'score': 0.9944, 'answer': 'us-001', 'start': 16, 'end': 16},
			            {'score': 0.0009, 'answer': 'us-001', 'start': 16, 'end': 16},
			        ],
			    ]
			    * 2					,      )




	@slow
	@require_torch
	@require_detectrona
	@require_pytesseract
	def    UpperCAmelCase			(						self							:     Any   )       -> int:

			'''simple docstring'''




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

			__lowercase											=     dqa_pipeline(image=__lowerCamelCase					,      question=__lowerCamelCase					,      top_k=2   )
			self.assertEqual(
			    nested_simplify(__lowerCamelCase					,      decimals=4   )					,      [
			        {'score': 0.9974, 'answer': '1110212019', 'start': 23, 'end': 23},
			        {'score': 0.9948, 'answer': 'us-001', 'start': 16, 'end': 16},
			    ]					,      )

			__lowercase											=     dqa_pipeline({'image': image, 'question': question}					,      top_k=2   )
			self.assertEqual(
			    nested_simplify(__lowerCamelCase					,      decimals=4   )					,      [
			        {'score': 0.9974, 'answer': '1110212019', 'start': 23, 'end': 23},
			        {'score': 0.9948, 'answer': 'us-001', 'start': 16, 'end': 16},
			    ]					,      )

			__lowercase											=     dqa_pipeline(
			    [{'image': image, 'question': question}, {'image': image, 'question': question}]					,      top_k=2   )
			self.assertEqual(
			    nested_simplify(__lowerCamelCase					,      decimals=4   )					,      [
			        [
			            {'score': 0.9974, 'answer': '1110212019', 'start': 23, 'end': 23},
			            {'score': 0.9948, 'answer': 'us-001', 'start': 16, 'end': 16},
			        ]
			    ]
			    * 2					,      )




	@slow
	@require_torch
	@require_pytesseract
	@require_vision
	def    UpperCAmelCase			(						self							:     List[Any]   )       -> int:

			'''simple docstring'''




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

			__lowercase											=     dqa_pipeline(image=__lowerCamelCase					,      question=__lowerCamelCase					,      top_k=2   )
			self.assertEqual(
			    nested_simplify(__lowerCamelCase					,      decimals=4   )					,      [
			        {'score': 0.4251, 'answer': 'us-001', 'start': 16, 'end': 16},
			        {'score': 0.0819, 'answer': '1110212019', 'start': 23, 'end': 23},
			    ]					,      )

			__lowercase											=     dqa_pipeline({'image': image, 'question': question}					,      top_k=2   )
			self.assertEqual(
			    nested_simplify(__lowerCamelCase					,      decimals=4   )					,      [
			        {'score': 0.4251, 'answer': 'us-001', 'start': 16, 'end': 16},
			        {'score': 0.0819, 'answer': '1110212019', 'start': 23, 'end': 23},
			    ]					,      )

			__lowercase											=     dqa_pipeline(
			    [{'image': image, 'question': question}, {'image': image, 'question': question}]					,      top_k=2   )
			self.assertEqual(
			    nested_simplify(__lowerCamelCase					,      decimals=4   )					,      [
			        [
			            {'score': 0.4251, 'answer': 'us-001', 'start': 16, 'end': 16},
			            {'score': 0.0819, 'answer': '1110212019', 'start': 23, 'end': 23},
			        ]
			    ]
			    * 2					,      )

			__lowercase											=     list(zip(*apply_tesseract(load_image(__lowerCamelCase   )					,      __lowerCamelCase					,      ''   )   )   )

			# This model should also work if `image` is set to None
			__lowercase											=     dqa_pipeline({'image': None, 'word_boxes': word_boxes, 'question': question}					,      top_k=2   )
			self.assertEqual(
			    nested_simplify(__lowerCamelCase					,      decimals=4   )					,      [
			        {'score': 0.4251, 'answer': 'us-001', 'start': 16, 'end': 16},
			        {'score': 0.0819, 'answer': '1110212019', 'start': 23, 'end': 23},
			    ]					,      )




	@slow
	@require_torch
	@require_pytesseract
	@require_vision
	def    UpperCAmelCase			(						self							:     Optional[int]   )       -> Optional[Any]:

			'''simple docstring'''




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

			__lowercase											=     dqa_pipeline(image=__lowerCamelCase					,      question=__lowerCamelCase					,      top_k=2   )
			self.assertEqual(
			    nested_simplify(__lowerCamelCase					,      decimals=4   )					,      [
			        {'score': 0.9999, 'answer': 'us-001', 'start': 16, 'end': 16},
			        {'score': 0.9998, 'answer': 'us-001', 'start': 16, 'end': 16},
			    ]					,      )

			__lowercase											=     dqa_pipeline(
			    [{'image': image, 'question': question}, {'image': image, 'question': question}]					,      top_k=2   )
			self.assertEqual(
			    nested_simplify(__lowerCamelCase					,      decimals=4   )					,      [
			        [
			            {'score': 0.9999, 'answer': 'us-001', 'start': 16, 'end': 16},
			            {'score': 0.9998, 'answer': 'us-001', 'start': 16, 'end': 16},
			        ]
			    ]
			    * 2					,      )

			__lowercase											=     list(zip(*apply_tesseract(load_image(__lowerCamelCase   )					,      __lowerCamelCase					,      ''   )   )   )

			# This model should also work if `image` is set to None
			__lowercase											=     dqa_pipeline({'image': None, 'word_boxes': word_boxes, 'question': question}					,      top_k=2   )
			self.assertEqual(
			    nested_simplify(__lowerCamelCase					,      decimals=4   )					,      [
			        {'score': 0.9999, 'answer': 'us-001', 'start': 16, 'end': 16},
			        {'score': 0.9998, 'answer': 'us-001', 'start': 16, 'end': 16},
			    ]					,      )




	@slow
	@require_torch
	def    UpperCAmelCase			(						self							:     Dict   )       -> Tuple:

			'''simple docstring'''




			__lowercase											=     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'					,      )

			__lowercase											=     INVOICE_URL
			__lowercase											=     'What is the invoice number?'
			__lowercase											=     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    UpperCAmelCase			(						self							:     Tuple   )       -> List[Any]:

			'''simple docstring'''




			pass











class 		snake_case_   :







	'''simple docstring'''




	def __init__(						self							:     Dict					,      __lowerCamelCase							:     int					,      __lowerCamelCase							:     Optional[Any]=None					,      __lowerCamelCase							:     Optional[Any]=None   )       -> Dict:

			'''simple docstring'''




			__lowercase											=     data
			__lowercase											=     previous
			__lowercase											=     next_node




	def __str__(						self							:     int   )       -> str:

			'''simple docstring'''




			return F"{self.data}"




	def    UpperCAmelCase			(						self							:     int   )       -> int:

			'''simple docstring'''




			return self.data




	def    UpperCAmelCase			(						self							:     Tuple   )       -> Optional[int]:

			'''simple docstring'''




			return self.next






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

			'''simple docstring'''




			return self.previous





class 		snake_case_   :







	'''simple docstring'''




	def __init__(						self							:     Tuple					,      __lowerCamelCase							:     Optional[Any]   )       -> str:

			'''simple docstring'''




			__lowercase											=     head




	def __iter__(						self							:     Union[str, Any]   )       -> List[Any]:

			'''simple docstring'''




			return self






	def    UpperCAmelCase			(						self							:     str   )       -> str:

			'''simple docstring'''




			if not self.current:
					raise StopIteration
			else:
					__lowercase											=     self.current.get_data()
					__lowercase											=     self.current.get_next()
					return value





class 		snake_case_   :







	'''simple docstring'''




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

			'''simple docstring'''




			__lowercase											=     None  # First node in list
			__lowercase											=     None  # Last node in list




	def __str__(						self							:     int   )       -> Any:

			'''simple docstring'''




			__lowercase											=     self.head
			__lowercase											=     []
			while current is not None:
					nodes.append(current.get_data()   )
					__lowercase											=     current.get_next()
			return " ".join(str(__lowerCamelCase   ) for node in nodes   )




	def __contains__(						self							:     Tuple					,      __lowerCamelCase							:     int   )       -> List[Any]:

			'''simple docstring'''




			__lowercase											=     self.head
			while current:
					if current.get_data() == value:
							return True
					__lowercase											=     current.get_next()
			return False




	def __iter__(						self							:     Optional[int]   )       -> List[str]:

			'''simple docstring'''




			return LinkedListIterator(self.head   )




	def    UpperCAmelCase			(						self							:     Any   )       -> str:

			'''simple docstring'''




			if self.head:
					return self.head.get_data()
			return None




	def    UpperCAmelCase			(						self							:     str   )       -> Union[str, Any]:

			'''simple docstring'''




			if self.tail:
					return self.tail.get_data()
			return None




	def    UpperCAmelCase			(						self							:     str					,      __lowerCamelCase							:     Node   )       -> None:

			'''simple docstring'''




			if self.head is None:
					__lowercase											=     node
					__lowercase											=     node
			else:
					self.insert_before_node(self.head					,      __lowerCamelCase   )




	def    UpperCAmelCase			(						self							:     Dict					,      __lowerCamelCase							:     Node   )       -> None:

			'''simple docstring'''




			if self.head is None:
					self.set_head(__lowerCamelCase   )
			else:
					self.insert_after_node(self.tail					,      __lowerCamelCase   )




	def    UpperCAmelCase			(						self							:     Optional[Any]					,      __lowerCamelCase							:     int   )       -> None:

			'''simple docstring'''




			__lowercase											=     Node(__lowerCamelCase   )
			if self.head is None:
					self.set_head(__lowerCamelCase   )
			else:
					self.set_tail(__lowerCamelCase   )




	def    UpperCAmelCase			(						self							:     int					,      __lowerCamelCase							:     Node					,      __lowerCamelCase							:     Node   )       -> None:

			'''simple docstring'''




			__lowercase											=     node
			__lowercase											=     node.previous

			if node.get_previous() is None:
					__lowercase											=     node_to_insert
			else:
					__lowercase											=     node_to_insert

			__lowercase											=     node_to_insert




	def    UpperCAmelCase			(						self							:     Optional[Any]					,      __lowerCamelCase							:     Node					,      __lowerCamelCase							:     Node   )       -> None:

			'''simple docstring'''




			__lowercase											=     node
			__lowercase											=     node.next

			if node.get_next() is None:
					__lowercase											=     node_to_insert
			else:
					__lowercase											=     node_to_insert

			__lowercase											=     node_to_insert




	def    UpperCAmelCase			(						self							:     List[str]					,      __lowerCamelCase							:     int					,      __lowerCamelCase							:     int   )       -> None:

			'''simple docstring'''




			__lowercase											=     1
			__lowercase											=     Node(__lowerCamelCase   )
			__lowercase											=     self.head
			while node:
					if current_position == position:
							self.insert_before_node(__lowerCamelCase					,      __lowerCamelCase   )
							return
					current_position += 1
					__lowercase											=     node.next
			self.insert_after_node(self.tail					,      __lowerCamelCase   )




	def    UpperCAmelCase			(						self							:     Optional[Any]					,      __lowerCamelCase							:     int   )       -> Node:

			'''simple docstring'''




			__lowercase											=     self.head
			while node:
					if node.get_data() == item:
							return node
					__lowercase											=     node.get_next()
			raise Exception('Node not found'   )




	def    UpperCAmelCase			(						self							:     Optional[Any]					,      __lowerCamelCase							:     List[str]   )       -> Dict:

			'''simple docstring'''




			if (node := self.get_node(__lowerCamelCase   )) is not None:
					if node == self.head:
							__lowercase											=     self.head.get_next()

					if node == self.tail:
							__lowercase											=     self.tail.get_previous()

					self.remove_node_pointers(__lowerCamelCase   )




	@staticmethod
	def    UpperCAmelCase			(						__lowerCamelCase							:     Node   )       -> None:

			'''simple docstring'''




			if node.get_next():
					__lowercase											=     node.previous

			if node.get_previous():
					__lowercase											=     node.next

			__lowercase											=     None
			__lowercase											=     None






	def    UpperCAmelCase			(						self							:     str   )       -> List[str]:

			'''simple docstring'''




			return self.head is None





def  SCREAMING_SNAKE_CASE				(      )		->    None:
		pass


if __name__ == "__main__":
		import doctest

		doctest.testmod()




