





"""simple docstring"""





import copy
import json
import os
import tempfile

from transformers import is_torch_available

from .test_configuration_utils import config_common_kwargs






class 					_lowerCAmelCase   (     a       ):
       """simple docstring"""




       def __init__(    self    , __UpperCAmelCase    , __UpperCAmelCase=None    , __UpperCAmelCase=True    , __UpperCAmelCase=None    , **__UpperCAmelCase      ):



         '''simple docstring'''

         lowerCAmelCase__			:Dict											=							parent
         lowerCAmelCase__			:List[Any]											=							config_class
         lowerCAmelCase__			:List[Any]											=							has_text_modality
         lowerCAmelCase__			:str											=							kwargs
         lowerCAmelCase__			:Union[str, Any]											=							common_properties






       def      snake_case						(    self      ):



         '''simple docstring'''

         lowerCAmelCase__			:int											=							self.config_class(**self.inputs_dict      )
         lowerCAmelCase__			:Union[str, Any]											=							(
             ['hidden_size', 'num_attention_heads', 'num_hidden_layers']
             if self.common_properties is None
             else self.common_properties
         )

         # Add common fields for text models
         if self.has_text_modality:
           common_properties.extend(['vocab_size']      )

         # Test that config has the common properties as getters
         for prop in common_properties:
           self.parent.assertTrue(hasattr(__UpperCAmelCase    , __UpperCAmelCase      )    , msg=F"`{prop}` does not exist"      )

         # Test that config has the common properties as setter
         for idx, name in enumerate(__UpperCAmelCase      ):
           try:
             setattr(__UpperCAmelCase    , __UpperCAmelCase    , __UpperCAmelCase      )
             self.parent.assertEqual(
                 getattr(__UpperCAmelCase    , __UpperCAmelCase      )    , __UpperCAmelCase    , msg=F"`{name} value {idx} expected, but was {getattr(__UpperCAmelCase    , __UpperCAmelCase      )}"      )
           except NotImplementedError:
             # Some models might not be able to implement setters for common_properties
             # In that case, a NotImplementedError is raised
             pass

        # Test if config class can be called with Config(prop_name=..)
         for idx, name in enumerate(__UpperCAmelCase      ):
           try:
             lowerCAmelCase__			:Any											=							self.config_class(**{name: idx}      )
             self.parent.assertEqual(
                 getattr(__UpperCAmelCase    , __UpperCAmelCase      )    , __UpperCAmelCase    , msg=F"`{name} value {idx} expected, but was {getattr(__UpperCAmelCase    , __UpperCAmelCase      )}"      )
           except NotImplementedError:
             # Some models might not be able to implement setters for common_properties
             # In that case, a NotImplementedError is raised
             pass






       def      snake_case						(    self      ):



         '''simple docstring'''

         lowerCAmelCase__			:Optional[int]											=							self.config_class(**self.inputs_dict      )
         lowerCAmelCase__			:Tuple											=							json.loads(config.to_json_string()      )
         for key, value in self.inputs_dict.items():
           self.parent.assertEqual(obj[key]    , __UpperCAmelCase      )






       def      snake_case						(    self      ):



         '''simple docstring'''

         lowerCAmelCase__			:Any											=							self.config_class(**self.inputs_dict      )

         with tempfile.TemporaryDirectory() as tmpdirname:
           lowerCAmelCase__			:Optional[Any]											=							os.path.join(__UpperCAmelCase    , 'config.json'      )
           config_first.to_json_file(__UpperCAmelCase      )
           lowerCAmelCase__			:int											=							self.config_class.from_json_file(__UpperCAmelCase      )

         self.parent.assertEqual(config_second.to_dict()    , config_first.to_dict()      )






       def      snake_case						(    self      ):



         '''simple docstring'''

         lowerCAmelCase__			:Optional[Any]											=							self.config_class(**self.inputs_dict      )

         with tempfile.TemporaryDirectory() as tmpdirname:
           config_first.save_pretrained(__UpperCAmelCase      )
           lowerCAmelCase__			:str											=							self.config_class.from_pretrained(__UpperCAmelCase      )

         self.parent.assertEqual(config_second.to_dict()    , config_first.to_dict()      )






       def      snake_case						(    self      ):



         '''simple docstring'''

         lowerCAmelCase__			:int											=							self.config_class(**self.inputs_dict      )

         lowerCAmelCase__			:List[Any]											=							'test'
         with tempfile.TemporaryDirectory() as tmpdirname:
           lowerCAmelCase__			:Tuple											=							os.path.join(__UpperCAmelCase    , __UpperCAmelCase      )
           config_first.save_pretrained(__UpperCAmelCase      )
           lowerCAmelCase__			:Optional[int]											=							self.config_class.from_pretrained(__UpperCAmelCase    , subfolder=__UpperCAmelCase      )

         self.parent.assertEqual(config_second.to_dict()    , config_first.to_dict()      )






       def      snake_case						(    self      ):



         '''simple docstring'''

         lowerCAmelCase__			:str											=							self.config_class(**self.inputs_dict    , num_labels=5      )
         self.parent.assertEqual(len(config.idalabel      )    , 5      )
         self.parent.assertEqual(len(config.labelaid      )    , 5      )

         lowerCAmelCase__			:Any											=							3
         self.parent.assertEqual(len(config.idalabel      )    , 3      )
         self.parent.assertEqual(len(config.labelaid      )    , 3      )






       def      snake_case						(    self      ):



         '''simple docstring'''

         if self.config_class.is_composition:
           return
         lowerCAmelCase__			:List[Any]											=							self.config_class()
         self.parent.assertIsNotNone(__UpperCAmelCase      )






       def      snake_case						(    self      ):



         '''simple docstring'''

         lowerCAmelCase__			:Optional[Any]											=							copy.deepcopy(__UpperCAmelCase      )
         lowerCAmelCase__			:Tuple											=							self.config_class(**__UpperCAmelCase      )
         lowerCAmelCase__			:int											=							[]
         for key, value in config_common_kwargs.items():
           if key == "torch_dtype":
             if not is_torch_available():
               continue
             else:
               import torch

               if config.torch_dtype != torch.floataa:
                 wrong_values.append(('torch_dtype', config.torch_dtype, torch.floataa)      )
           elif getattr(__UpperCAmelCase    , __UpperCAmelCase      ) != value:
             wrong_values.append((key, getattr(__UpperCAmelCase    , __UpperCAmelCase      ), value)      )

         if len(__UpperCAmelCase      ) > 0:
           lowerCAmelCase__			:List[str]											=							'\n'.join([F"- {v[0]}: got {v[1]} instead of {v[2]}" for v in wrong_values]      )
           raise ValueError(F"The following keys were not properly set in the config:\n{errors}"      )






       def      snake_case						(    self      ):



         '''simple docstring'''

         self.create_and_test_config_common_properties()
         self.create_and_test_config_to_json_string()
         self.create_and_test_config_to_json_file()
         self.create_and_test_config_from_and_save_pretrained()
         self.create_and_test_config_from_and_save_pretrained_subfolder()
         self.create_and_test_config_with_num_labels()
         self.check_config_can_be_init_without_params()
         self.check_config_arguments_init()







"""simple docstring"""





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 					_lowerCAmelCase   :
         """simple docstring"""




         @staticmethod
         def      snake_case						(    *__UpperCAmelCase    , **__UpperCAmelCase      ):



           '''simple docstring'''

           pass






  def  __A   (_SCREAMING_SNAKE_CASE			)					->int:





    """simple docstring"""


    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											=		(
    """https://huggingface.co/spaces/impira/docquery/resolve/2f6c96314dc84dfda62d40de9da55f2f5165d403/invoice.png"""
)






@is_pipeline_test
@require_torch
@require_vision
class 					_lowerCAmelCase   (     unittest.TestCase       ):
       """simple docstring"""




       __magic_name__     :str		  =					MODEL_FOR_DOCUMENT_QUESTION_ANSWERING_MAPPING






       @require_pytesseract
       @require_vision
       def      snake_case						(    self    , __UpperCAmelCase    , __UpperCAmelCase    , __UpperCAmelCase      ):



         '''simple docstring'''

         lowerCAmelCase__			:Dict											=							pipeline(
             'document-question-answering'    , model=__UpperCAmelCase    , tokenizer=__UpperCAmelCase    , image_processor=__UpperCAmelCase      )

         lowerCAmelCase__			:Dict											=							INVOICE_URL
         lowerCAmelCase__			:Dict											=							list(zip(*apply_tesseract(load_image(__UpperCAmelCase      )    , __UpperCAmelCase    , ''      )      )      )
         lowerCAmelCase__			:List[Any]											=							'What is the placebo?'
         lowerCAmelCase__			:Dict											=							[
             {
                 'image': load_image(__UpperCAmelCase      ),
                 'question': question,
             },
             {
                 'image': image,
                 'question': question,
             },
             {
                 'image': image,
                 'question': question,
                 'word_boxes': word_boxes,
             },
         ]
         return dqa_pipeline, examples






       def      snake_case						(    self    , __UpperCAmelCase    , __UpperCAmelCase      ):



         '''simple docstring'''

         lowerCAmelCase__			:int											=							dqa_pipeline(__UpperCAmelCase    , top_k=2      )
         self.assertEqual(
             __UpperCAmelCase    , [
                 [
                     {'score': ANY(__UpperCAmelCase      ), 'answer': ANY(__UpperCAmelCase      ), 'start': ANY(__UpperCAmelCase      ), 'end': ANY(__UpperCAmelCase      )},
                     {'score': ANY(__UpperCAmelCase      ), 'answer': ANY(__UpperCAmelCase      ), 'start': ANY(__UpperCAmelCase      ), 'end': ANY(__UpperCAmelCase      )},
                 ]
             ]
             * 3    , )






       @require_torch
       @require_detectrona
       @require_pytesseract
       def      snake_case						(    self      ):



         '''simple docstring'''

         lowerCAmelCase__			:int											=							pipeline('document-question-answering'    , model='hf-internal-testing/tiny-random-layoutlmv2'      )
         lowerCAmelCase__			:Union[str, Any]											=							INVOICE_URL
         lowerCAmelCase__			:Tuple											=							'How many cats are there?'

         lowerCAmelCase__			:List[str]											=							[
             {'score': 0.00_01, 'answer': 'oy 2312/2019', 'start': 3_8, 'end': 3_9},
             {'score': 0.00_01, 'answer': 'oy 2312/2019 DUE', 'start': 3_8, 'end': 4_0},
         ]
         lowerCAmelCase__			:Any											=							dqa_pipeline(image=__UpperCAmelCase    , question=__UpperCAmelCase    , top_k=2      )
         self.assertEqual(nested_simplify(__UpperCAmelCase    , decimals=4      )    , __UpperCAmelCase      )

         lowerCAmelCase__			:Any											=							dqa_pipeline({'image': image, 'question': question}    , top_k=2      )
         self.assertEqual(nested_simplify(__UpperCAmelCase    , decimals=4      )    , __UpperCAmelCase      )

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

         # We can optionnally pass directly the words and bounding boxes
         lowerCAmelCase__			:Dict											=							'./tests/fixtures/tests_samples/COCO/000000039769.png'
         lowerCAmelCase__			:List[str]											=							[]
         lowerCAmelCase__			:int											=							[]
         lowerCAmelCase__			:List[str]											=							dqa_pipeline(image=__UpperCAmelCase    , question=__UpperCAmelCase    , words=__UpperCAmelCase    , boxes=__UpperCAmelCase    , top_k=2      )
         self.assertEqual(__UpperCAmelCase    , []      )






       @slow
       @require_torch
       @require_detectrona
       @require_pytesseract
       def      snake_case						(    self      ):



         '''simple docstring'''

         lowerCAmelCase__			:Union[str, Any]											=							pipeline(
             'document-question-answering'    , model='tiennvcs/layoutlmv2-base-uncased-finetuned-docvqa'    , revision='9977165'    , )
         lowerCAmelCase__			:str											=							INVOICE_URL
         lowerCAmelCase__			:List[Any]											=							'What is the invoice number?'

         lowerCAmelCase__			:Tuple											=							dqa_pipeline(image=__UpperCAmelCase    , question=__UpperCAmelCase    , top_k=2      )
         self.assertEqual(
             nested_simplify(__UpperCAmelCase    , decimals=4      )    , [
                 {'score': 0.99_44, 'answer': 'us-001', 'start': 1_6, 'end': 1_6},
                 {'score': 0.00_09, 'answer': 'us-001', 'start': 1_6, 'end': 1_6},
             ]    , )

         lowerCAmelCase__			:Union[str, Any]											=							dqa_pipeline({'image': image, 'question': question}    , top_k=2      )
         self.assertEqual(
             nested_simplify(__UpperCAmelCase    , decimals=4      )    , [
                 {'score': 0.99_44, 'answer': 'us-001', 'start': 1_6, 'end': 1_6},
                 {'score': 0.00_09, 'answer': 'us-001', 'start': 1_6, 'end': 1_6},
             ]    , )

         lowerCAmelCase__			:Dict											=							dqa_pipeline(
             [{'image': image, 'question': question}, {'image': image, 'question': question}]    , top_k=2      )
         self.assertEqual(
             nested_simplify(__UpperCAmelCase    , decimals=4      )    , [
                 [
                     {'score': 0.99_44, 'answer': 'us-001', 'start': 1_6, 'end': 1_6},
                     {'score': 0.00_09, 'answer': 'us-001', 'start': 1_6, 'end': 1_6},
                 ],
             ]
             * 2    , )






       @slow
       @require_torch
       @require_detectrona
       @require_pytesseract
       def      snake_case						(    self      ):



         '''simple docstring'''

         lowerCAmelCase__			:Tuple											=							pipeline(
             'document-question-answering'    , model='tiennvcs/layoutlmv2-base-uncased-finetuned-docvqa'    , revision='9977165'    , max_seq_len=5_0    , )
         lowerCAmelCase__			:List[Any]											=							INVOICE_URL
         lowerCAmelCase__			:List[Any]											=							'What is the invoice number?'

         lowerCAmelCase__			:Optional[Any]											=							dqa_pipeline(image=__UpperCAmelCase    , question=__UpperCAmelCase    , top_k=2      )
         self.assertEqual(
             nested_simplify(__UpperCAmelCase    , decimals=4      )    , [
                 {'score': 0.99_74, 'answer': '1110212019', 'start': 2_3, 'end': 2_3},
                 {'score': 0.99_48, 'answer': 'us-001', 'start': 1_6, 'end': 1_6},
             ]    , )

         lowerCAmelCase__			:List[str]											=							dqa_pipeline({'image': image, 'question': question}    , top_k=2      )
         self.assertEqual(
             nested_simplify(__UpperCAmelCase    , decimals=4      )    , [
                 {'score': 0.99_74, 'answer': '1110212019', 'start': 2_3, 'end': 2_3},
                 {'score': 0.99_48, 'answer': 'us-001', 'start': 1_6, 'end': 1_6},
             ]    , )

         lowerCAmelCase__			:int											=							dqa_pipeline(
             [{'image': image, 'question': question}, {'image': image, 'question': question}]    , top_k=2      )
         self.assertEqual(
             nested_simplify(__UpperCAmelCase    , decimals=4      )    , [
                 [
                     {'score': 0.99_74, 'answer': '1110212019', 'start': 2_3, 'end': 2_3},
                     {'score': 0.99_48, 'answer': 'us-001', 'start': 1_6, 'end': 1_6},
                 ]
             ]
             * 2    , )






       @slow
       @require_torch
       @require_pytesseract
       @require_vision
       def      snake_case						(    self      ):



         '''simple docstring'''

         lowerCAmelCase__			:List[Any]											=							AutoTokenizer.from_pretrained(
             'impira/layoutlm-document-qa'    , revision='3dc6de3'    , add_prefix_space=__UpperCAmelCase      )
         lowerCAmelCase__			:Optional[Any]											=							pipeline(
             'document-question-answering'    , model='impira/layoutlm-document-qa'    , tokenizer=__UpperCAmelCase    , revision='3dc6de3'    , )
         lowerCAmelCase__			:List[str]											=							INVOICE_URL
         lowerCAmelCase__			:Any											=							'What is the invoice number?'

         lowerCAmelCase__			:List[Any]											=							dqa_pipeline(image=__UpperCAmelCase    , question=__UpperCAmelCase    , top_k=2      )
         self.assertEqual(
             nested_simplify(__UpperCAmelCase    , decimals=4      )    , [
                 {'score': 0.42_51, 'answer': 'us-001', 'start': 1_6, 'end': 1_6},
                 {'score': 0.08_19, 'answer': '1110212019', 'start': 2_3, 'end': 2_3},
             ]    , )

         lowerCAmelCase__			:Optional[int]											=							dqa_pipeline({'image': image, 'question': question}    , top_k=2      )
         self.assertEqual(
             nested_simplify(__UpperCAmelCase    , decimals=4      )    , [
                 {'score': 0.42_51, 'answer': 'us-001', 'start': 1_6, 'end': 1_6},
                 {'score': 0.08_19, 'answer': '1110212019', 'start': 2_3, 'end': 2_3},
             ]    , )

         lowerCAmelCase__			:List[str]											=							dqa_pipeline(
             [{'image': image, 'question': question}, {'image': image, 'question': question}]    , top_k=2      )
         self.assertEqual(
             nested_simplify(__UpperCAmelCase    , decimals=4      )    , [
                 [
                     {'score': 0.42_51, 'answer': 'us-001', 'start': 1_6, 'end': 1_6},
                     {'score': 0.08_19, 'answer': '1110212019', 'start': 2_3, 'end': 2_3},
                 ]
             ]
             * 2    , )

         lowerCAmelCase__			:Dict											=							list(zip(*apply_tesseract(load_image(__UpperCAmelCase      )    , __UpperCAmelCase    , ''      )      )      )

         # This model should also work if `image` is set to None
         lowerCAmelCase__			:Tuple											=							dqa_pipeline({'image': None, 'word_boxes': word_boxes, 'question': question}    , top_k=2      )
         self.assertEqual(
             nested_simplify(__UpperCAmelCase    , decimals=4      )    , [
                 {'score': 0.42_51, 'answer': 'us-001', 'start': 1_6, 'end': 1_6},
                 {'score': 0.08_19, 'answer': '1110212019', 'start': 2_3, 'end': 2_3},
             ]    , )






       @slow
       @require_torch
       @require_pytesseract
       @require_vision
       def      snake_case						(    self      ):



         '''simple docstring'''

         lowerCAmelCase__			:Optional[Any]											=							AutoTokenizer.from_pretrained(
             'impira/layoutlm-document-qa'    , revision='3dc6de3'    , add_prefix_space=__UpperCAmelCase      )
         lowerCAmelCase__			:Tuple											=							pipeline(
             'document-question-answering'    , model='impira/layoutlm-document-qa'    , tokenizer=__UpperCAmelCase    , revision='3dc6de3'    , max_seq_len=5_0    , )
         lowerCAmelCase__			:Dict											=							INVOICE_URL
         lowerCAmelCase__			:List[Any]											=							'What is the invoice number?'

         lowerCAmelCase__			:List[str]											=							dqa_pipeline(image=__UpperCAmelCase    , question=__UpperCAmelCase    , top_k=2      )
         self.assertEqual(
             nested_simplify(__UpperCAmelCase    , decimals=4      )    , [
                 {'score': 0.99_99, 'answer': 'us-001', 'start': 1_6, 'end': 1_6},
                 {'score': 0.99_98, 'answer': 'us-001', 'start': 1_6, 'end': 1_6},
             ]    , )

         lowerCAmelCase__			:List[str]											=							dqa_pipeline(
             [{'image': image, 'question': question}, {'image': image, 'question': question}]    , top_k=2      )
         self.assertEqual(
             nested_simplify(__UpperCAmelCase    , decimals=4      )    , [
                 [
                     {'score': 0.99_99, 'answer': 'us-001', 'start': 1_6, 'end': 1_6},
                     {'score': 0.99_98, 'answer': 'us-001', 'start': 1_6, 'end': 1_6},
                 ]
             ]
             * 2    , )

         lowerCAmelCase__			:Optional[Any]											=							list(zip(*apply_tesseract(load_image(__UpperCAmelCase      )    , __UpperCAmelCase    , ''      )      )      )

         # This model should also work if `image` is set to None
         lowerCAmelCase__			:List[str]											=							dqa_pipeline({'image': None, 'word_boxes': word_boxes, 'question': question}    , top_k=2      )
         self.assertEqual(
             nested_simplify(__UpperCAmelCase    , decimals=4      )    , [
                 {'score': 0.99_99, 'answer': 'us-001', 'start': 1_6, 'end': 1_6},
                 {'score': 0.99_98, 'answer': 'us-001', 'start': 1_6, 'end': 1_6},
             ]    , )






       @slow
       @require_torch
       def      snake_case						(    self      ):



         '''simple docstring'''

         lowerCAmelCase__			:List[str]											=							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'    , )

         lowerCAmelCase__			:Dict											=							INVOICE_URL
         lowerCAmelCase__			:str											=							'What is the invoice number?'
         lowerCAmelCase__			:Tuple											=							dqa_pipeline(image=__UpperCAmelCase    , question=__UpperCAmelCase    , top_k=2      )
         self.assertEqual(nested_simplify(__UpperCAmelCase    , decimals=4      )    , [{'answer': 'us-001'}]      )






       @require_tf
       @unittest.skip('Document question answering not implemented in TF'      )
       def      snake_case						(    self      ):



         '''simple docstring'''

         pass
