o
    NiB                     @   s  d Z ddlmZ ddlmZ ddlmZ ddlZddlZddlZddlZddl	Z	ddl
Z
ddlmZ ddlmZ ddlZddlZddlm  mZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlm Z  ej!d6ddZ"d6ddZ#dd Z$dd Z%dd Z&G dd de'Z(G dd de'Z)G dd  d e j*Z+			!d7d"d#Z,G d$d% d%e'Z-G d&d' d'e+Z.d(d) Z/G d*d+ d+ej0Z1G d,d- d-ej0Z2d.d/ Z3ej!d6d0d1Z4G d2d3 d3e'Z5G d4d5 d5e'Z6dS )8zTest utilities.    )absolute_import)division)print_functionN)Iterator)absltest)dataset_builder)dataset_info)dataset_utils)example_parser)example_serializer)features)splits)utils)	test_casec                 c   s    t | }|V  t| dS )z*Context manager for a temporary directory.N)make_tmp_dir
rm_tmp_dir)dirnametmp r   Z/home/ubuntu/.local/lib/python3.10/site-packages/tensorflow_datasets/testing/test_utils.pytmp_dir0   s   r   c                 C   s,   | rt jj| st jj|  tj| dS )zMake a temporary directory.)dir)tfiogfileexistsmakedirstempfilemkdtempr   r   r   r   r   8   s   r   c                 C   s   t jj|  dS )zRm temporary directory.N)r   r   r   rmtreer   r   r   r   r   ?   s   r   c                 C   s.   t jj| rt jj|  t jj|  dS )z)Possibly deletes and recreates directory.N)r   r   r   r   r    r   )dr   r   r   
remake_dirD   s   r"   c                   C   s   t jt jtddS )N	test_datafake_examples)ospathjoinr   __file__r   r   r   r   fake_examples_dirK   s   r)   c                   @   sv   e Zd ZdZdd Zdd Zdd Zejde	d  fd	d
ZddddZ
dd ZejdddZdddZdd ZdS )MockFsaE  This util wraps mock for the `tf.io.gfile` API.

  Usage:

  ```
  fs = MockFs()
  with fs.mock():

    fs.add_file('/path/to/file1', 'Content of file 1')

    assert tf.io.gfile.exists('/path/to/file1')
    with tf.io.gfile.GFile('/path/to/file2', 'w') as f:
      f.write('Content of file 2')
    tf.io.gfile.rename('/path/to/file1', '/path/to/file1_moved')

    assert fs.files == {
        '/path/to/file2': 'Content of file 2',
        '/path/to/file1_moved': 'Content of file 1',
    }
  ```

  Attributes:
    files: Dict[str, str], mapping existing files -> file content
  c                 C   s   i | _ d | _d S N)files_cmselfr   r   r   __init__i   s   
zMockFs.__init__c                 C   s   |   | _| j S r+   )contextmanagerr-   	__enter__r.   r   r   r   r2   m   s   

zMockFs.__enter__c                 C   s   | j |||S r+   )r-   __exit__)r/   exc_type	exc_value	tracebackr   r   r   r3   q   s   zMockFs.__exit__returnc                 c   s6    |    | V  W d   dS 1 sw   Y  dS )zOpen the file.N)mockr.   r   r   r   r1   t   s   
"zMockFs.contextmanagerNc                 C   s$   |d u r	d |n|}|| j|< d S )NzContent of {})formatr,   )r/   r&   contentr   r   r   add_filez   s   zMockFs.add_filec                    s.     tjjtjj  t fdd| jD S )Nc                    s2   h | ]}|  rtj| tjjd  qS )r   )
startswithr%   r&   relpathsplitsep).0pr&   r   r   	<setcomp>   s
    
z)MockFs._list_directory.<locals>.<setcomp>)rstripr%   r&   r?   listr,   )r/   r&   r   rB   r   _list_directory~   s   zMockFs._list_directoryrc                 c   s    | dr| |d d|v }| j| }|r t|d}nt|}|}|V  | }W d   n1 s9w   Y  |rE|dn|| j|< dS )zPatch `tf.io.gfile.GFile`.w bzutf-8N)	r<   r;   r,   r   BytesIOencodeStringIOgetvaluedecode)r/   r&   mode	is_binaryr:   fobjfnew_contentr   r   r   _open   s   



zMockFs._openFc                 C   sL   |s|| j v rtd|||| j vrtd|| j || j |< d S )NzCannot overwrite: {} -> {}zCannot rename unknown file: {})r,   FileExistsErrorr9   FileNotFoundErrorpop)r/   from_to	overwriter   r   r   _rename   s
   
zMockFs._renamec              	      s0   t jjjtjd fdddd  j j jdS )Nr   c                    s
   |  j v S r+   )r,   rB   r.   r   r   <lambda>   s   
 zMockFs.mock.<locals>.<lambda>c                 S   s   d S r+   r   )_r   r   r   r]      s    )r   r   listdirGFilerename)	r   r8   patchobjectr   r   rF   rU   r\   r.   r   r.   r   r8      s   
zMockFs.mockr+   )r7   N)rG   )F)__name__
__module____qualname____doc__r0   r2   r3   
contextlibr1   r   r;   rF   rU   r\   r8   r   r   r   r   r*   O   s    
r*   c                   @   s(   e Zd ZdZ							dddZdS )FeatureExpectationItemz"Test item of a FeatureExpectation.Nc	           	      C   sP   || _ || _|| _|| _|| _|| _|s |d us|d ur td|| _|| _d S )Nz1dtype and shape should only be set with transform)	valueexpectedexpected_serializeddecodersdtypeshape
ValueError	raise_cls	raise_msg)	r/   rj   rk   rl   rm   rn   ro   rq   rr   r   r   r   r0      s   

zFeatureExpectationItem.__init__)NNNNNNN)rd   re   rf   rg   r0   r   r   r   r   ri      s    ri   c                       s:   e Zd ZdZe fddZejdd Zdd Z	  Z
S )SubTestCasezAdds subTest() context manager to the TestCase if supported.

  Note: To use this feature, make sure you call super() in setUpClass to
  initialize the sub stack.
  c                    s   t t|   g | _d S r+   )superrs   
setUpClass_sub_test_stack)cls	__class__r   r   ru      s   
zSubTestCase.setUpClassc                 c   sX    | j | d| j }| | d V  W d    n1 s w   Y  | j   d S )N/)rv   appendr'   subTestrX   )r/   test_strsub_test_strr   r   r   _subTest   s   zSubTestCase._subTestc                    sF   t |trtj||dd}tj fdd|dd dS  || dS )z7Same as assertAllEqual but compatible with nested dict.T)	dict_onlyc                    s     | d | d S Nr      )assertAllEqualxr.   r   r   r]          z2SubTestCase.assertAllEqualNested.<locals>.<lambda>N)
isinstancedictr   
zip_nested
map_nestedr   )r/   d1d2zipped_examplesr   r.   r   assertAllEqualNested   s   


z SubTestCase.assertAllEqualNested)rd   re   rf   rg   classmethodru   rh   r1   r   r   __classcell__r   r   rx   r   rs      s    
rs   Tc                    s"    fdd}| dur|| S |S )ai  Execute the decorated test in both graph mode and eager mode.

  This function returns a decorator intended to be applied to test methods in
  a `test_case.TestCase` class. Doing so will cause the contents of the test
  method to be executed twice - once in graph mode, and once with eager
  execution enabled. This allows unittests to confirm the equivalence between
  eager and graph execution.

  NOTE: This decorator can only be used when executing eagerly in the
  outer scope.

  For example, consider the following unittest:

  ```python
  class SomeTest(tfds.testing.TestCase):

    @tfds.testing.run_in_graph_and_eager_modes
    def test_foo(self):
      x = tf.constant([1, 2])
      y = tf.constant([3, 4])
      z = tf.add(x, y)
      self.assertAllEqual([4, 6], self.evaluate(z))

  if __name__ == '__main__':
    tfds.testing.test_main()
  ```

  This test validates that `tf.add()` has the same behavior when computed with
  eager execution enabled as it does when constructing a TensorFlow graph and
  executing the `z` tensor with a session.

  Args:
    func: function to be annotated. If `func` is None, this method returns a
      decorator the can be applied to a function. If `func` is not None this
      returns the decorator applied to `func`.
    config: An optional config_pb2.ConfigProto to use to configure the session
      when executing graphs.
    use_gpu: If True, attempt to run as many operations as possible on GPU.

  Returns:
    Returns a decorator that will run the decorated test method twice:
    once by constructing and executing a graph in a session and once with
    eager execution enabled.
  c                    s    fdd}|S )zDecorator for a method.c              	      s   t  std| g|R i | |   t   7 |   | j d | g|R i | W d   n1 s?w   Y  W d   dS W d   dS 1 sWw   Y  dS )zRun the decorated test method.zPMust be executing eagerly when using the run_in_graph_and_eager_modes decorator.)use_gpuconfigN)r   executing_eagerlyrp   tearDownGraph
as_defaultsetUptest_sessionr/   argskwargs)r   rS   r   r   r   	decorated  s   "zBrun_in_graph_and_eager_modes.<locals>.decorator.<locals>.decoratedr   )rS   r   r   r   )rS   r   	decorator  s   z/run_in_graph_and_eager_modes.<locals>.decoratorNr   )funcr   r   r   r   r   r   run_in_graph_and_eager_modes   s   0r   c                   @       e Zd ZdZdd Zdd ZdS )RaggedConstantzContainer of tf.ragged.constant values.

  This simple wrapper forward the arguments to delay the RaggedTensor
  construction after `@run_in_graph_and_eager_modes` has been called.
  This is required to avoid incompabilities between Graph/eager.
  c                 O   s   || _ t|| _d S r+   )_argsr   _kwargsr   r   r   r   r0   ;  s   zRaggedConstant.__init__c                 C   s   t jj| ji | jS r+   )r   raggedconstantr   r   r.   r   r   r   build?  s   zRaggedConstant.buildN)rd   re   rf   rg   r0   r   r   r   r   r   r   3  s    r   c                   @   s(   e Zd ZdZe dddZdd ZdS )FeatureExpectationsTestCasez2Tests FeatureExpectations with full encode-decode.Nc           	   	   C   s   |  d | |j| W d   n1 sw   Y  |  d | |j| W d   n1 s3w   Y  |durY|  d | ||  W d   n1 sTw   Y  td|i}|  t|D ]%\}}|  t	| | j
|||||d W d   n1 sw   Y  qhdS )z.Test the given feature against the predicates.ro   Nrn   serialized_infoinner)fdicttestfeaturero   rn   )r   assertEqualro   rn   get_serialized_infor   FeaturesDict_set_top_level	enumeratestrassertFeatureTest)	r/   r   ro   rn   testsr   r   ir   r   r   r   assertFeatureF  s6   z)FeatureExpectationsTestCase.assertFeaturec              	   C   sn  t t |j d|ji}|jdura| d? |js'td	|jt
|| |j|j t|||jd W d   n1 sBw   Y  W d   dS W d   dS 1 sZw   Y  dS |jdur| d | |j||j W d   n1 sw   Y  | d t||d|jid\}}|d }|d }| d tjd	d
 |}	| |	|jp|j W d   n1 sw   Y  | d! |jdu r|jn|j}
t||
}tdd
 | W d   n1 sw   Y  | d tjdd
 |j}| || W d   n1 sw   Y  W d   dS W d   dS 1 s0w   Y  dS )z6Test that encode=>decoding of a value works correctly.r   Nraisez0test.raise_msg should be set with {} for test {}rm   out_serializeoutrn   c                 S   s   | j S r+   rn   )sr   r   r   r]     s    z?FeatureExpectationsTestCase.assertFeatureTest.<locals>.<lambda>ro   c                 S   s   | d j | d S r   )ro   assert_is_compatible_withr   r   r   r   r]     r   	out_valuec                 S   s   t | tr	|  S | S r+   )r   r   r   )tr   r   r   r]     s    )dillloadsdumpsencode_examplerj   rq   r   rr   rp   r9   typeassertRaisesWithPredicateMatchfeatures_encode_decoderm   rl   r   r   nestmap_structurern   ro   r   r   r   rk   r   )r/   r   r   r   ro   rn   input_value
out_tensor	out_numpy
out_dtypesexpected_shape
out_shapesrk   r   r   r   r   f  sn   


"



 $z-FeatureExpectationsTestCase.assertFeatureTestr+   )rd   re   rf   rg   r   r   r   r   r   r   r   r   C  s
    r   c                 C   s   |  |}|  }t|}t|}||}tjj	
|}||j}tj| j|d}	||	}t r=tt|}
n
tjjj| }
t|
}|
|fS )zCRuns the full pipeline: encode > write > tmp files > read > decode.r   )r   r   r   ExampleSerializerr
   ExampleParserserialize_exampler   dataDatasetfrom_tensorsmapparse_example	functoolspartialdecode_exampler   nextitercompatv1make_one_shot_iteratorget_nextr	   as_numpy)features_dictexamplerm   encoded_examplespecs
serializerparserserialized_exampleds	decode_fnr   r   r   r   r   r     s"   





r   c                   @   sH   e Zd ZdZedZdddejdddgZd	d
 Zdd Z	dd Z
dS )DummyDatasetSharedGeneratorTest DatasetBuilder.1.0.0z2.0.0z0.0.9z0.0.8z0.0.7zv1.0.0)tfds_version_to_preparec                 C   s   t j| tdtjiddS )Nr   )r   r   )builderr   supervised_keys)r   DatasetInfor   r   r   int64r.   r   r   r   _info  s
   z!DummyDatasetSharedGenerator._infoc                 C   s8   ~t jt jjdtdidt jt jjdtddidgS )Nrange_   name
gen_kwargs   )r   SplitGeneratorSplitTRAINrangeTESTr/   
dl_managerr   r   r   _split_generators  s   
z-DummyDatasetSharedGenerator._split_generatorsc                 c   s    |D ]	}|d|ifV  qd S )Nr   r   )r/   r   r   r   r   r   _generate_examples  s   z.DummyDatasetSharedGenerator._generate_examplesN)rd   re   rf   rg   r   VersionVERSIONSUPPORTED_VERSIONSr   r  r  r   r   r   r   r     s    
r   c                   @   s2   e Zd ZdZedZdd Zdd Zdd Z	d	S )

DummyMnistr   r   c                 C   s,   t j| ttjddtjdddddS )N   r  r   )ro   
   )num_classesimagelabelzMnist description.)r   r   description)r   r   r   r   Image
ClassLabelr.   r   r   r   r     s   

zDummyMnist._infoc                 C   s(   t jt jjt dt jt jjt dgS )Nr   )r   r   r   r   r   r   r   r   r   r   r    s   zDummyMnist._split_generatorsc                 c   s4    t dD ]}|tjdtjd|d dfV  qd S )Nr   r  r   r	  r  )r   nponesuint8)r/   r   r   r   r   r    s   zDummyMnist._generate_examplesN)
rd   re   rf   rg   r   r  r  r   r  r  r   r   r   r   r    s    


r  c                   C   s   t   t j  dS )zEntrypoint for tests.N)r   enable_v2_behaviorr   mainr   r   r   r   	test_main  s   r  c                 #   sJ    d fdd	}t jd| dV  W d   dS 1 sw   Y  dS )zMock out the kaggle CLI.

  Args:
    err_msg: `str`, if provided, the kaggle CLI will raise a CalledProcessError
      and this will be the command output.

  Yields:
    None, context will have kaggle CLI mocked out.
  Nc                    s   |sJ | d dksJ | d } rt d|  | | dd  }tj|d}tjj	|d}|
| W d   n1 sAw   Y  d	||S )
z/Mock subprocess.check_output for download call.   downloadr   z--pathz
output.txtrH   NzDownloading {} to {})
subprocessCalledProcessErrorindexr%   r&   r'   r   r   r   r`   writer9   )command_argsencodingcompetition_or_datasetout_dirfpathrS   err_msgr   r   check_output  s   z%mock_kaggle_api.<locals>.check_outputzsubprocess.check_outputr+   )r   r8   rb   )r$  r%  r   r#  r   mock_kaggle_api  s
   "r&  c                   @   r   )DummySerializerz-To mock example_serializer.ExampleSerializer.c                 C      ~d S r+   r   r/   r   r   r   r   r0   (     zDummySerializer.__init__c                 C   s   t |S r+   )bytes)r/   r   r   r   r   r   +  s   z!DummySerializer.serialize_exampleN)rd   re   rf   rg   r0   r   r   r   r   r   r'  %      r'  c                   @   r   )DummyParserz%To mock example_parser.ExampleParser.c                 C   r(  r+   r   r)  r   r   r   r0   2  r*  zDummyParser.__init__c                 C   s   |S r+   r   )r/   exr   r   r   r   5  s   zDummyParser.parse_exampleN)rd   re   rf   rg   r0   r   r   r   r   r   r-  /  r,  r-  r+   )NNT)7rg   
__future__r   r   r   rh   r   r   r%   r  r   typingr   absl.testingr   r   numpyr  tensorflow.compat.v2r   v2r   tensorflow_datasets.corer   r   r	   r
   r   r   r   r   tensorflow_datasets.testingr   r1   r   r   r   r"   r)   rc   r*   ri   TestCasers   r   r   r   r   GeneratorBasedBuilderr   r  r  r&  r'  r-  r   r   r   r   <module>   s^   
^#
J]$!
