
    d0                         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	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
Zd Zd Z d Z!d Z"d Z#d Z$ddZ%ddZ&d Z'dS )z*Utility functions common to Dulwich tests.    N)SkipTestskipIf   )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                 D   |t          j                    }t          j                            t          j                            t                    dddd|           }t          j                            ||           }t          j        ||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_dirs       W/home/feoh/.local/pipx/venvs/poetry/lib/python3.11/site-packages/dulwich/tests/utils.py	open_repor&   -   s~     #%%w||BGOOH55tT:wX\]]HGLL400M
OHmd;;;;    c                     |                                   t          j                            | j                            t          j                            }t          j        |           dS )zTear down a test repository.N)closer   r   r   rstripsepr   rmtree)repor"   s     r%   tear_down_repor.   C   sJ    JJLLLwty//7788H
M(r'   c                      G d d|           }d| j         z   |_          |            }|                                D ]6\  }}|dk    rt          |          fd|_        %t	          |||           7|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                       e Zd ZdZdS )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%   
TestObjectr1   V   s        	 	 	r'   r7   TestObject_idc                       S Nr6   )shas   r%   <lambda>zmake_object.<locals>.<lambda>g   s    c r'   )r2   itemsr   r<   setattr)clsattrsr7   objr!   valuer<   s         @r%   make_objectrD   J   s        S    (#,6J
*,,C{{}} & &e4<<5//C!kkkCGGCu%%%%Jr'   c            
      l    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)updaterD   r   )rA   default_time	all_attrss      r%   make_commitrT   m   s\     L4#:##
 
I Uv+++++r'   c           	      *   | j         }t          | j                  }t          t	          j        t          j        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     rF   r   rG   s   Test Tag)taggertag_timetag_timezonerN   objectr!   )r9   r
   	type_nameinttimemktimedatetime	timetuplerQ   rD   r	   )targetrA   	target_idtarget_typerR   rS   s         r%   make_tagrd      s     	Iv/00Kt{8#4T1a#@#@#J#J#L#LMMNNL4 #	* I Us((i(((r'   c                       fd}|S )z5Generate a test method that tests the given function.c                       |            d S r;   r6   selffuncmethods    r%   do_testz!functest_builder.<locals>.do_test   s    tTr'   r6   rj   ri   rk   s   `` r%   functest_builderrm      s)          Nr'   c                       fd}|S )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.
    c                 x    t          t          j                  st          dz             |            d S )Nz%s extension not found)
isinstancetypesBuiltinFunctionTyper   rg   s    r%   rk   z%ext_functest_builder.<locals>.do_test   sD    $ 9:: 	<3d:;;;tTr'   r6   rl   s   `` r%   ext_functest_builderrs      s)    ,     
 Nr'   c           	         t          |           }t          |          }t          |j        |           i }i }i }t          |          |k     rt	          |          D ]\  }\  }	}
|	t
          vr|	|
t          |	|
g          f||<   )|
\  }}
t          |t                    r||vrH||         \  }}}n|	                    |          \  }}||
t          ||
g          f||<   t          |          |k     t	          |          D ]\  }\  }	}| 
                                }|	t          k    r<|\  }}
|||         z
  }||         \  }}}|t          t          ||
                    f}ny|	t          k    rn|\  }}
t          |t                    r||         \  }}}n(|	                    |          \  }}t          ||          }|t          t          ||
                    f}t          |j        |	|          }|||<   |||<   g }t!          |          D ]I}||         \  }	}
}t          |          dk    sJ |                    ||         |	|
|||         f           J|                                 |                     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   rp   r\   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_rB   offset
base_index	base_database_refcrc32expectedr<   s                         r%   
build_packr      s   & 
ABl##Kbh,,,LGF
l

k
)
)#,\#:#: 	 	A${**#+T78dV3L3L"MQJD$$$$ 7|++&24&8#q!!#(==#6#6 qv..LOO l

k
)
)$ (55  ?Hcy  "JGJ//D*:6OAy!l9d;;<<=CC"" NHd(C(( 9%1(%;"9dd+0==+B+B(y}i88l9d;;<<=C!"(Hc::
q		H; F F*1o$3xx2~~~~XtS&)DEEEELLNNNFF1IIIOr'   c                    |i }|i }d}i g }|D ]g}|d         }	 fd|dd         D             }n.# t           $ r!}	|	j        \  }
t          d|
z            |	d}	~	ww xY wg }|                    |g           D ]\}t	          |          dk    r|\  }}||t
          f}|\  }}}|                    ||j        |f           |                     |           ]t          | |          }d|z  
                    d          |||d	}|                    |                    |i                      t          di |}|d
         dz   }|j        |<   |                     |           |                    |           i|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                      g | ]
}|         S r6   r6   ).0pnnumss     r%   
<listcomp>z&build_commit_graph.<locals>.<listcomp>8  s    888r$r(888r'   rV   zUnknown parent %ir   z	Commit %iascii)rN   rO   rP   rL   rL   d   r6   )KeyErrorargs
ValueErrorgetrv   Fr}   r9   
add_objectr   encoderQ   rT   )object_storecommit_spectreesrA   rL   commitscommit
commit_num
parent_idsexcmissing_parentblobsentryr   blobmodetree_idcommit_attrs
commit_objr   s                      @r%   build_commit_graphr     s   > }}KDG  #  #AY
	L8888VABBZ888JJ 	L 	L 	L #^0>ABBK	L YYz2.. 	* 	*E5zzQ"
dtQ$D$LL$.///##D))))lE22 $j088AA!&	
 
 	EIIj"55666 00<00
 #=1C7%=Z
+++z""""Ns   5
A AA c                  V    g t           j        fd} | t           _        fd}|fS )z:Wrap warnings.showwarning with code that records warnings.c                  >                         | d                    d S )Nr   )r}   )r   kwargscaught_warningss     r%   custom_showwarningz1setup_warning_catcher.<locals>.custom_showwarning`  s!    tAw'''''r'   c                        t           _        d S r;   warningsshowwarning)original_showwarnings   r%   restore_showwarningz2setup_warning_catcher.<locals>.restore_showwarninge  s    3r'   r   )r   r   r   r   s     @@r%   setup_warning_catcherr   Z  s^     O#/( ( ( ( ( .H4 4 4 4 4 ///r'   r;   )NN)(r5   r_   r   r   r   r]   rq   r   dulwich.testsr   r   indexr   objectsr   r   r	   r
   packr   r   r   r   r   r   r   r   r-   r   r   r&   r.   rD   rT   rd   rm   rs   r   r   r   r6   r'   r%   <module>r      s  * 1 0  				      * * * * * * * *       9 9 9 9 9 9 9 9 9 9 9 9' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '          ,       F, , ,.) ) ).    <I I I IXI I I IX0 0 0 0 0r'   