






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






           '''simple docstring'''




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




            """simple docstring"""


            pass
     def 		_a       ( a					:List[str]					)				->     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.
UpperCAmelCase__							  =						(
    '''https://huggingface.co/spaces/impira/docquery/resolve/2f6c96314dc84dfda62d40de9da55f2f5165d403/invoice.png'''
)






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






      '''simple docstring'''




      __snake_case	    =    MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING







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




       """simple docstring"""


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

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







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




       """simple docstring"""


       a						    = 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  __lowerCAmelCase   ( self :		Tuple    )       ->Dict:




       """simple docstring"""


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

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

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

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







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




       """simple docstring"""


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

       a						    = 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},
           ]					,   )

       a						    = 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},
           ]					,   )

       a						    = 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  __lowerCAmelCase   ( self :		Any    )       ->int:




       """simple docstring"""


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

       a						    = 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},
           ]					,   )

       a						    = 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},
           ]					,   )

       a						    = 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  __lowerCAmelCase   ( self :		List[Any]    )       ->int:




       """simple docstring"""


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

       a						    = 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},
           ]					,   )

       a						    = 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},
           ]					,   )

       a						    = 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					,   )

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

       # This model should also work if `image` is set to None
       a						    = 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  __lowerCAmelCase   ( self :		Optional[int]    )       ->Optional[Any]:




       """simple docstring"""


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

       a						    = 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},
           ]					,   )

       a						    = 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					,   )

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

       # This model should also work if `image` is set to None
       a						    = 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  __lowerCAmelCase   ( self :		Dict    )       ->Tuple:




       """simple docstring"""


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

       a						    = INVOICE_URL
       a						    = '''What is the invoice number?'''
       a						    = 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  __lowerCAmelCase   ( 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()




