o
    Uh0                     @   s   d 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Zddlm	Z	 ddl
mZ ddlmZmZmZmZ ddlmZmZmZmZmZmZmZmZ ddlmZ dZdd	d
ZdddZdd Zdd Z dd Z!dd Z"dd Z#dddZ$d ddZ%dd Z&dS )!z*Utility functions common to Dulwich tests.    N)SkipTest)commit_tree)CommitFixedShaTagobject_class)DELTA_TYPES	OFS_DELTA	REF_DELTA
SHA1Writercreate_deltaobj_shawrite_pack_headerwrite_pack_object)Repoi  c                 C   sT   |du rt  }tjtjtdddd| }tj|| }tj||dd t	|S )a"  Open a copy of a repo in a temporary directory.

    Use this function for accessing repos in dulwich/tests/data/repos to avoid
    accidentally or intentionally modifying those repos in place. Use
    tear_down_repo to delete any temp files created.

    Args:
      name: The name of the repository, relative to
        dulwich/tests/data/repos
      temp_dir: temporary directory to initialize to. If not provided, a
        temporary directory will be created.
    Returns: An initialized Repo object that lives in a temporary directory.
    Nz..testdatareposT)symlinks)
tempfilemkdtempospathjoindirname__file__shutilcopytreer   )nametemp_dirrepo_dirtemp_repo_dir r!   g/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/dulwich/tests/utils.py	open_repo3   s   r#   returnc                 C   s,   |    tj| jtj}t| dS )zTear down a test repository.N)closer   r   r   rstripsepr   rmtree)repor   r!   r!   r"   tear_down_repoK   s   r*   c                    sd   G dd d| }d| j  |_ | }| D ]\}}|dkr)t|  fdd|_qt||| q|S )aL  Make an object for testing and assign some members.

    This method creates a new subclass to allow arbitrary attribute
    reassignment, which is not otherwise possible with objects having
    __slots__.

    Args:
      attrs: dict of attributes to set on the new object.
    Returns: A newly initialized object of type cls.
    c                   @   s   e Zd ZdZdS )zmake_object.<locals>.TestObjecta  Class that inherits from the given class, but without __slots__.

        Note that classes with __slots__ can't have arbitrary attributes
        monkey-patched in, so this is a class that is exactly the same only
        with a __dict__ instead of __slots__.
        N)__name__
__module____qualname____doc__r!   r!   r!   r"   
TestObject^   s    r/   TestObject_idc                      s    S Nr!   r!   shar!   r"   <lambda>m   s    zmake_object.<locals>.<lambda>)r+   itemsr   r4   setattr)clsattrsr/   objr   valuer!   r3   r"   make_objectR   s   r<   c               
   K   s6   d}d|dd|ddg dd	}| |  ttfi |S )zMake a Commit object with a default set of members.

    Args:
      attrs: dict of attributes to overwrite from the default values.
    Returns: A newly initialized Commit object.
    i ;=K   Test Author <test@nodomain.com>r   s"   Test Committer <test@nodomain.com>   Test message.s(   0000000000000000000000000000000000000000)	authorauthor_timeauthor_timezone	committercommit_timecommit_timezonemessageparentstree)updater<   r   )r9   default_time	all_attrsr!   r!   r"   make_commits   s   
rK   c                 K   s\   | j }t| j}tttddd }d|dd||fdd}|| t	t
fi |S )zMake a Tag object with a default set of values.

    Args:
      target: object to be tagged (Commit, Blob, Tree, etc)
      attrs: dict of attributes to overwrite from the default values.
    Returns: A newly initialized Tag object.
    i     r=   r   r>   s   Test Tag)taggertag_timetag_timezonerE   objectr   )r1   r   	type_nameinttimemktimedatetime	timetuplerH   r<   r   )targetr9   	target_idtarget_typerI   rJ   r!   r!   r"   make_tag   s   

rZ   c                       d fdd}|S )z5Generate a test method that tests the given function.r$   Nc                    s   |   d S r2   r!   selffuncmethodr!   r"   do_test   s   z!functest_builder.<locals>.do_testr$   Nr!   r`   r_   ra   r!   r^   r"   functest_builder   s   rd   c                    r[   )a  Generate a test method that tests the given extension function.

    This is intended to generate test methods that test both a pure-Python
    version and an extension version using common test code. The extension test
    will raise SkipTest if the extension is not found.

    Sample usage:

    class MyTest(TestCase);
        def _do_some_test(self, func_impl):
            self.assertEqual('foo', func_impl())

        test_foo = functest_builder(_do_some_test, foo_py)
        test_foo_extension = ext_functest_builder(_do_some_test, _foo_c)

    Args:
      method: The method to run. It must must two parameters, self and the
        function implementation to test.
      func: The function implementation to pass to method.
    r$   Nc                    s(   t  tjst  d|   d S )Nz extension not found)
isinstancetypesBuiltinFunctionTyper   r\   r^   r!   r"   ra      s   z%ext_functest_builder.<locals>.do_testrb   r!   rc   r!   r^   r"   ext_functest_builder   s   rh   c              	   C   s  t | }t|}t|j| i }i }i }t||k rct|D ]>\}\}	}
|	tvr4|	|
t|	|
gf||< q|
\}}
t|trJ||vrBq|| \}}}n|	|\}}||
t||
gf||< qt||k st|D ]b\}\}	}| 
 }|	tkr|\}}
|||  }|| \}}}|tt||
f}n*|	tkr|\}}
t|tr|| \}}}n|	|\}}t||}|tt||
f}t|j|	|}|||< |||< qgg }t|D ]}|| \}	}
}t|dksJ ||| |	|
||| f q|  | d |S )aF  Write test pack data from a concise spec.

    Args:
      f: A file-like object to write the pack to.
      objects_spec: A list of (type_num, obj). For non-delta types, obj
        is the string of that object's data.
        For delta types, obj is a tuple of (base, data), where:

        * base can be either an index in objects_spec of the base for that
        * delta; or for a ref delta, a SHA, in which case the resulting pack
        * will be thin and the base will be an external ref.
        * data is a string of the full, non-deltified data for that object.

        Note that offsets/refs and deltas are computed within this function.
      store: An optional ObjectStore for looking up external refs.
    Returns: A list of tuples in the order specified by objects_spec:
        (offset, type num, data, sha, CRC32)
       r   )r   lenr   write	enumerater   r   re   rR   get_rawtellr	   listr   r
   r   rangeappend	write_shaseek)fobjects_specstoresfnum_objectsfull_objectsoffsetscrc32sitype_numdatabasebase_type_num_r:   offset
base_index	base_database_refcrc32expectedr4   r!   r!   r"   
build_pack   s^   






r   c                    sR  |du ri }|du ri }d}i  g }|D ]}|d }z fdd|dd D }W n t yA }	 z|	j\}
td|
 |	d}	~	ww g }||g D ]$}t|dkr[|\}}||tf}|\}}}|||j|f | | qJt	| |}d| 
d	|||d
}|||i  tdi |}|d d }|j |< | | || q|S )a  Build a commit graph from a concise specification.

    Sample usage:
    >>> c1, c2, c3 = build_commit_graph(store, [[1], [2, 1], [3, 1, 2]])
    >>> store[store[c3].parents[0]] == c1
    True
    >>> store[store[c3].parents[1]] == c2
    True

    If not otherwise specified, commits will refer to the empty tree and have
    commit times increasing in the same order as the commit spec.

    Args:
      object_store: An ObjectStore to commit objects to.
      commit_spec: An iterable of iterables of ints defining the commit
        graph. Each entry defines one commit, and entries must be in
        topological order. The first element of each entry is a commit number,
        and the remaining elements are its parents. The commit numbers are only
        meaningful for the call to make_commits; since real commit objects are
        created, they will get created with real, opaque SHAs.
      trees: An optional dict of commit number -> tree spec for building
        trees for commits. The tree spec is an iterable of (path, blob, mode)
        or (path, blob) entries; if mode is omitted, it defaults to the normal
        file mode (0100644).
      attrs: A dict of commit number -> (dict of attribute -> value) for
        assigning additional values to the commits.
    Returns: The list of commit objects created.

    Raises:
      ValueError: If an undefined commit identifier is listed as a parent.
    Nr   c                    s   g | ]} | qS r!   r!   ).0pnnumsr!   r"   
<listcomp>?  s    z&build_commit_graph.<locals>.<listcomp>rL   zUnknown parent    zCommit ascii)rE   rF   rG   rC   rC   d   r!   )KeyErrorargs
ValueErrorgetrj   Frq   r1   
add_objectr   encoderH   rK   )object_storecommit_spectreesr9   rC   commitscommit
commit_num
parent_idsexcmissing_parentblobsentryr   blobmodetree_idcommit_attrs
commit_objr!   r   r"   build_commit_graph  sJ    




r   c                     s4   g  t jd fdd} | t _dfdd} |fS )z:Wrap warnings.showwarning with code that records warnings.r$   Nc                     s     | d  d S )Nr   )rq   )r   kwargs)caught_warningsr!   r"   custom_showwarningf  s   z1setup_warning_catcher.<locals>.custom_showwarningc                      s
    t _d S r2   warningsshowwarningr!   )original_showwarningr!   r"   restore_showwarningk  s   
z2setup_warning_catcher.<locals>.restore_showwarningrb   r   )r   r   r!   )r   r   r"   setup_warning_catchera  s   r   r2   rb   )NN)'r.   rU   r   r   r   rS   rf   r   unittestr   dulwich.indexr   dulwich.objectsr   r   r   r   dulwich.packr   r	   r
   r   r   r   r   r   dulwich.repor   r   r#   r*   r<   rK   rZ   rd   rh   r   r   r   r!   r!   r!   r"   <module>   s0   (


!	

LM