o
    Uh                  	   @   s  U 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mZ ddl	m
Z
mZm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 dd
lmZ ercddl m!Z! dZ"dZ#dZ$dZ%dZ&dZ'dZ(dZ)dZ*dZ+dZ,dZ-dZ.dZ/dZ0e1Z2G dd deZ3dd Z4dd  Z5d!d" Z6d#d$ Z7d%e8fd&d'Z9d(d) Z:d*d+ Z;d,e<d-e<d%e1fd.d/Z=dud0e>d1ee> fd2d3Z?d4ee1e<f d%ee@d5  fd6d7ZAdvd8d9ZBd:ee1 d;e>d%dfd<d=ZCdvd>d?ZDd@dA ZEG dBdC dCZFG dDd5 d5ZGG dEdF dFeGZHdGee1 d%eeeIdH eIee1 e1f f  fdIdJZJdKdL ZKG dMdN dNeGZLG dOdP dPedPg dQZMdwdSdTZNdUdV ZOdWe8fdXdYZPdZeIe1eIe<e2f f d%e1fd[d\ZQdZeIe1eIe<e2f f d%e1fd]d^ZRdxd%e>fd`daZSG dbdc dceTZUG ddde deeGZVdfdg ZWdwdhdiZXdjdk ZYdldm ZZdndo Z[G dpdq dqeGZ\e\eVeHeLfZ]i Z^e_ee1e<f e@eG f e`dr< e]D ]Zaeae^eajb< eae^eajc< qeNZdePZezddslfmNZg ddtlfmPZh W n eiy   Y dS w egZNehZPdS )yzAccess to base git objects.    N)
namedtuple)CallableIterableIterator)sha1)BytesIO)TYPE_CHECKINGBinaryIOOptionalUnion   )ChecksumMismatchFileFormatExceptionNotBlobErrorNotCommitErrorNotTagErrorNotTreeErrorObjectFormatException)GitFile)HASHs(   0000000000000000000000000000000000000000   trees   parents   authors	   committers   encodings   mergetags   gpgsigs   objects   type   tags   taggeri   l    s   -----BEGIN PGP SIGNATURE-----c                   @   s   e Zd ZdZdS )EmptyFileExceptionz+An unexpectedly empty file was encountered.N)__name__
__module____qualname____doc__ r   r   c/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/dulwich/objects.pyr   U   s    r   c                 C   s   t | tkS )zhCheck if a mode indicates a submodule.

    Args:
      m: Mode to check
    Returns: a ``boolean``
    )statS_IFMTS_IFGITLINK)mr   r   r   S_ISGITLINKY   s   r#   c                 C   s"   t  }|| }|| 7 }|S N)zlibdecompressobj
decompressflush)stringdcompdcompedr   r   r   _decompressc   s   
r,   c                 C   s(   t | }t|dksJ d||S )z5Takes a string and returns the hex of the sha within.(   z!Incorrect length of sha1 string: )binasciihexlifylen)shahexshar   r   r   
sha_to_hexj   s   
r3   c              
   C   s\   t | dksJ d|  zt| W S  ty- } zt| ts! t|jd |d}~ww )z)Takes a hex sha and returns a binary sha.r-   zIncorrect length of hexsha: r   N)r0   r.   	unhexlify	TypeError
isinstancebytes
ValueErrorargs)hexexcr   r   r   
hex_to_shaq   s   
r<   returnc              	   C   s<   t | dkrdS zt|  W dS  ttjfy   Y dS w )Nr-   FT)r0   r.   r4   r5   Error)r:   r   r   r   valid_hexsha|   s   r?   c                 C   sR   t | t |urt| dddur|d}|dd }|dd }tj| ||S )zDTakes a hex sha and returns its filename relative to the given path.encodeNascii   )typegetattrdecodeospathjoin)rG   r:   dirfiler   r   r   hex_to_filename   s
    
rK   c                 C   sx   |  tjjddd }d|  }t|dksJ ||\}}t|dkr+t|dks/J ||| d}t| |S )z?Takes an object filename and returns its corresponding hex sha.rB   NzInvalid object filename: &   rA   )rsplitrF   rG   sepr0   r@   r<   )filenamenameserrmsgbaserestr:   r   r   r   filename_to_hex   s   
 rU   num_typelengthc                 C   s:   t | }|du rtd|  |jd t|d d S )zCReturn an object header for the given numeric type and text length.Nunsupported class type num:     rA       )object_classAssertionError	type_namestrr@   )rV   rW   clsr   r   r   object_header   s   r`   name	docstringc                    s(   d fdd} fdd}t |||dS )	zBA property that helps tracking whether serialization is necessary.r=   Nc                    s   t | d  | d| _d S )N_T)setattr_needs_serialization)objvaluera   r   r   set   s   
z"serializable_property.<locals>.setc                    s   t | d  S )Nrc   )rD   )rf   rh   r   r   get      z"serializable_property.<locals>.getdocr=   N)property)ra   rb   ri   rj   r   rh   r   serializable_property   s   rp   rC   ShaFilec                 C   s   t | dS )zGet the object class corresponding to the given type.

    Args:
      type: Either a type name string or a numeric type.
    Returns: The ShaFile subclass corresponding to the given type, or None if
        type is not a valid type name/number.
    N)	_TYPE_MAPrj   )rC   r   r   r   r[         r[   c                 C   s   t | st| d|  dS )zCheck if a string is a valid hex sha string.

    Args:
      hex: Hex string to check
      error_msg: Error message to use in exception
    Raises:
      ObjectFormatException: Raised when the string is not valid
     N)r?   r   )r:   	error_msgr   r   r   check_hexsha   s   	rv   identityru   c                 C   sx   | du rt || d}| d}t|dk| |d  dk| d|d dk|t| d kd| vd| vgs:t |dS )	zCheck if the specified identity is valid.

    This will raise an exception if the identity is not valid.

    Args:
      identity: Identity string
      error_msg: Error message to use in exception
    N   <   >r       rZ      
)r   findallr0   )rw   ru   email_start	email_endr   r   r   check_identity   s   	


r   c                 C   s   | t krtdt  dS )zCheck if the specified time is not prone to overflow error.

    This will raise an exception if the time is not valid.

    Args:
      time_seconds: time in seconds

    zDate field should not exceed N)MAX_TIMEr   )time_secondsr   r   r   
check_time   s   
r   c                  G   s   d | d S )z*Formats items into a space separated line.rY   r|   )rH   )itemsr   r   r   git_line   s   r   c                   @   s:   e Zd ZdZdZdddZdefddZdefd	d
Z	dS )FixedShazBSHA object that behaves like hashlib's but is given a fixed value.)_hexsha_shar=   Nc                 C   sF   t |dd d ur|d}t|tstd||| _t|| _d S )Nr@   rA   zExpected bytes for hexsha, got )rD   r@   r6   r7   r5   r   r<   r   )selfr2   r   r   r   __init__   s   

zFixedSha.__init__c                 C      | j S )zReturn the raw SHA digest.)r   r   r   r   r   digest     zFixedSha.digestc                 C   s   | j dS )zReturn the hex SHA digest.rA   )r   rE   r   r   r   r   	hexdigest  s   zFixedSha.hexdigestrn   )
r   r   r   r   	__slots__r   r7   r   r^   r   r   r   r   r   r      s    
r   c                	   @   s  e Zd ZU dZdZeed< eed< eed< e	e
e  ed< eeddf ed	< ed
edd fddZdYddZdZdedee fddZdZdedefddZde
e fddZdefddZdefddZdefddZdefddZd[d ed!e	e ddfd"d#Z	d[d$e
e d!e	e ddfd%d&Zed'd( ZdYd)d*Zed+edefd,d-Z ed.d/ Z!dYd0d1Z"d$e
e ddfd2d3Z#de
e fd4d5Z$ed6d7 Z%ed8d9 Z&e	d[d:ed!e	e dd fd;d<Z'e	d[ded$e
e d!e	e fd=d>Z(ed?d@ Z)dYdAdBZ*dYdCdDZ+dEdF Z,defdGdHZ-deedf fdIdJZ.d\dKdLZ/e0dMdN Z1defdOdPZ2defdQdRZ3defdSdTZ4defdUdVZ5defdWdXZ6dS )]rq   zA git SHA file.)_chunked_textre   r   re   r]   type_numr   Nr   r   fr=   c              
   C   s   d}t  }|| }d}d}|dk r1||}|||7 }| |7 } |d|}t|}|dk s|d| }|dd\}}	zt|	 W n tyY }
 zt	d|
 |
d}
~
ww t
|}|sjt	d	|d
| S )z<Parse a legacy object, creating it but not reading the file.i   r   r{   rZ   NrY   r   zObject size not an integer: zNot a known type: {}rA   )r%   r&   r'   readr}   r0   splitintr8   r   r[   formatrE   )magicr   bufsizedecompheaderstartendextrar]   sizer;   	obj_classr   r   r   _parse_legacy_object_header  s4   

z#ShaFile._parse_legacy_object_headerc                 C   s<   t |}|d}|dk rtd| ||d d  dS )z.Parse a legacy object, setting the raw string.rZ   r   zInvalid object header, no \0r   N)r,   r}   r   set_raw_string)r   maptext
header_endr   r   r   _parse_legacy_object7  s
   
zShaFile._parse_legacy_objectr{   compression_levelc                 c   sD    t |}||  V  |  D ]}||V  q| V  dS )zlReturn chunks representing the object in the experimental format.

        Returns: List of strings
        N)r%   compressobjcompress_headeras_raw_chunksr(   )r   r   compobjchunkr   r   r   as_legacy_object_chunks?  s   
zShaFile.as_legacy_object_chunksc                 C   s   d | j|dS )zAReturn string representing the object in the experimental format.    )r   )rH   r   )r   r   r   r   r   as_legacy_objectJ  s   
zShaFile.as_legacy_objectc                 C   s"   | j rd| _|  | _d| _ | jS )zxReturn chunks with serialization of the object.

        Returns: List of strings, not necessarily one per line
        NF)re   r   
_serializer   r   r   r   r   r   P  s
   
zShaFile.as_raw_chunksc                 C   s   d |  S )z\Return raw string with serialization of the object.

        Returns: String object
        r   )rH   r   r   r   r   r   as_raw_string[  s   zShaFile.as_raw_stringc                 C      |   S )z/Return raw string serialization of this object.r   r   r   r   r   	__bytes__b     zShaFile.__bytes__c                 C   
   t | jS )z#Return unique hash for this object.)hashidr   r   r   r   __hash__f  s   
zShaFile.__hash__c                 C   s   |   ddS )z:Return a string representing this object, fit for display.utf-8replace)r   rE   r   r   r   r   as_pretty_stringj  s   zShaFile.as_pretty_stringr   r1   c                 C   s*   t |tstd|| |g| dS )z9Set the contents of this object from a serialized string.zExpected bytes for text, got N)r6   r7   r5   set_raw_chunks)r   r   r1   r   r   r   r   n  s   
zShaFile.set_raw_stringchunksc                 C   s4   || _ | | |du rd| _nt|| _d| _dS )z6Set the contents of this object from a list of chunks.NF)r   _deserializer   r   re   )r   r   r1   r   r   r   r   t  s   


zShaFile.set_raw_chunksc                 C   s8   t | dd d? d@ }t|}|std| | S )z?Parse a new style object, creating it but not reading the file.r   r         zNot a known type )ordr[   r   )r   r   rV   r   r   r   r   _parse_object_header  s
   zShaFile._parse_object_headerc                 C   sf   t |dd }d}|d@ dkr$t |||d  }|d7 }|d@ dks||d }| t| dS )z-Parse a new style object, setting self._text.r   r      N)r   r   r,   )r   r   byteusedrawr   r   r   _parse_object  s   zShaFile._parse_objectr   c                 C   sD   t |dd }t |dd }|d> | }|d@ dko!|d dkS )Nr   r   rB            )r   )r_   r   b0b1wordr   r   r   _is_legacy_object  s   zShaFile._is_legacy_objectc                 C   sR   |  }|s
td| |r| ||}|| |S | ||}|| |S )NzCorrupted empty file detected)r   r   r   r   r   r   r   )r_   r   r   rf   r   r   r   _parse_file  s   


zShaFile._parse_filec                 C   s   d| _ g | _d| _dS )zDon't call this directly.NT)r   r   re   r   r   r   r   r     s   
zShaFile.__init__c                 C   
   t | jr$   )NotImplementedErrorr   r   r   r   r   r   r        
zShaFile._deserializec                 C   r   r$   )r   r   r   r   r   r   r     r   zShaFile._serializec                 C   s8   t |d}| |W  d   S 1 sw   Y  dS )zOpen a SHA file from disk.rbN)r   	from_file)r_   rG   r   r   r   r   	from_path  s   $zShaFile.from_pathc              
   C   s>   z|  |}d|_|W S  ttfy } ztd|d}~ww )z'Get the contents of a SHA file on disk.Nzinvalid object header)r   r   
IndexErrorr8   r   )r_   r   rf   r;   r   r   r   r     s   

zShaFile.from_filer)   c                 C   4   t | }|du rtd|  | }||| |S )zCreates an object of the indicated type from the raw string given.

        Args:
          type_num: The numeric type of the object.
          string: The raw uncompressed contents.
          sha: Optional known sha for the object
        NrX   )r[   r\   r   )r   r)   r1   r_   rf   r   r   r   from_raw_string     zShaFile.from_raw_stringc                 C   r   )zCreates an object of the indicated type from the raw chunks given.

        Args:
          type_num: The numeric type of the object.
          chunks: An iterable of the raw uncompressed contents.
          sha: Optional known sha for the object
        NrX   )r[   r\   r   )r   r   r1   r_   rf   r   r   r   from_raw_chunks  r   zShaFile.from_raw_chunksc                 C   s   |  }| | |S )zCreate a ShaFile from a string.r   )r_   r)   rf   r   r   r   from_string  s   
zShaFile.from_stringc                 C   s   t | |ddu rt|dS )a:  Check that the object has a given member variable.

        Args:
          member: the member variable to check for
          error_msg: the message for an error if the member is missing
        Raises:
          ObjectFormatException: with the given error_msg if member is
            missing or is None
        N)rD   r   )r   memberru   r   r   r   _check_has_member  s   
zShaFile._check_has_memberc              
   C   s^   | j }z| |   d| _| j }W n ty# } zt||d}~ww ||kr-t||dS )zCheck this object for internal consistency.

        Raises:
          ObjectFormatException: if the object is malformed in some way
          ChecksumMismatch: if the object was created with a SHA that does
            not match its contents
        N)r   r   r   r   	Exceptionr   r   )r   old_shanew_shar;   r   r   r   check  s   


zShaFile.checkc                 C   s   t | j|  S r$   )r`   r   
raw_lengthr   r   r   r   r        zShaFile._headerc                 C   s   t tt|  S )z4Returns the length of the raw string of this object.)sumr   r0   r   r   r   r   r   r     s   zShaFile.raw_lengthc                 C   sH   | j du s| jr!t }||   |  D ]}|| q|| _ | j S )z0The SHA1 object that is the name of this object.N)r   re   r   updater   r   )r   r   r   r   r   r   r1     s   zShaFile.shac                 C   s8   t | j}|du rtd| j || j|  | jS )z:Create a new copy of this SHA1 object from its raw string.Nzinvalid type num )r[   r   r\   r   r   r   )r   r   r   r   r   copy&  s   
zShaFile.copyc                 C   s   |    dS )zThe hex SHA of this object.rA   )r1   r   r@   r   r   r   r   r   -  s   z
ShaFile.idc                 C   s   d| j j d| j dS )N<rt   >)	__class__r   r   r   r   r   r   __repr__2  s   zShaFile.__repr__c                 C   s   t |t p| j|jkS )z3Check whether this object does not match the other.r6   rq   r   r   otherr   r   r   __ne__5  s   zShaFile.__ne__c                 C   s   t |to
| j|jkS )z1Return True if the SHAs of the two objects match.r   r   r   r   r   __eq__9  s   zShaFile.__eq__c                 C   s   t |tst| j|jk S )z9Return whether SHA of this object is less than the other.r6   rq   r5   r   r   r   r   r   __lt__=     
zShaFile.__lt__c                 C   s   t |tst| j|jkS )zDCheck whether SHA of this object is less than or equal to the other.r   r   r   r   r   __le__C  r   zShaFile.__le__rn   )r{   r$   )r=   rq   )7r   r   r   r   r   bool__annotations__r7   r   r
   listr   r   staticmethodr	   r   r   r   r   r   r   r   r   r   r^   r   ObjectIDr   r   r   r   classmethodr   r   r   r   r   r   r   r   r   r   r   r   r   r   r1   r   ro   r   r   r   r   r   r   r   r   r   r   rq     s   
 







	




c                       s   e Zd ZU dZdZdZdZee e	d< d  fdd	Z
d
d Zd ddZeeeddZdd Zdee ddfddZdd Zd ddZeeeddZedd Zd  fddZdee fddZ  ZS )!BlobzA Git Blob object.r   s   blob   r   r=   Nc                    s   t    g | _d| _d S NF)superr   r   re   r   r   r   r   r   T  s   

zBlob.__init__c                 C   r   r$   r   r   r   r   r   	_get_dataY  s   zBlob._get_datac                 C   s   |  | d S r$   r   )r   datar   r   r   	_set_data\  rk   zBlob._set_dataz*The text contained within the blob object.rl   c                 C   r   r$   r   r   r   r   r   _get_chunkedc     zBlob._get_chunkedr   c                 C   
   || _ d S r$   r  r   r   r   r   _set_chunkedf  r   zBlob._set_chunkedc                 C   r   r$   r  r   r   r   r   r   i  r	  zBlob._serializec                 C   r
  r$   r  r   r   r   r   r   l  r   zBlob._deserializez>The text in the blob object, as chunks (not necessarily lines)c                 C       t |}t|| st||S r$   )rq   r   r6   r   )r_   rG   blobr   r   r   r   u     

zBlob.from_pathc                    s   t    dS )Check this object for internal consistency.

        Raises:
          ObjectFormatException: if the object is malformed in some way
        N)r  r   r   r  r   r   r   |  s   z
Blob.checkc                 C   s   | j }|sg S t|dkr|d dS d}g }|D ];}|d}t|dkr@||p,d|d   ||dd  |d }qt|dkrU|du rO| }q|| 7 }q|dur_|| |S )z^Return list of lines in this blob.

        This preserves the original line endings.
        r   r   TNr   r{   )chunkedr0   
splitlinesappendextendpop)r   r   	remainingretr   linesr   r   r   r    s*   



zBlob.splitlinesrn   )r   r   r   r   r   r]   r   r   r7   r   r   r  r  ro   r  r  r  r   r   r  r   r   r   r  __classcell__r   r   r  r   r   J  s2   
 


r   r   NNc                 c   s    t d| }d}d}d}dd }|D ])}|dr$||dd 7 }q|dur/|||fV  |dkr5 n|dd\}}qd	}|durK|||fV  d
V  |sWd| fV  |  dS )aQ  Parse a message with a list of fields and a body.

    Args:
      chunks: the raw chunks of the tag or commit object.
    Returns: iterator of tuples of (field, value), one per header line, in the
        order read from the text, possibly including duplicates. Includes a
        field named None for the freeform tag/commit text.
    r   NFc                 S   s   | r|  dr| dd S | S )z"Strip the last newline from value.r|   Nr{   )endswith)rg   r   r   r   _strip_last_newline  s   z+_parse_message.<locals>._strip_last_newlinerY   r   r|   Tr  )r   rH   
startswithr   r   close)r   r   kveofr  liner   r   r   _parse_message  s*   

r"  c                 c   sb    | D ]!\}}| d}t||d V  |dd  D ]	}d| d V  qqdV  |r/|V  d S d S )Nr|   r   r   rY   )r   r   )headersbodyfieldrg   r  r!  r   r   r   _format_message  s   

r&  c                       s  e Zd ZU dZdZdZdZee e	d< d* fdd	Z
ed
d Zd* fddZdd Zd*ddZdd Zd*ddZeeeZeddZeddZeddZeddZeddZed d!Zd+d"ee ddfd#d$Zdefd%d&Zd+d'eee  ddfd(d)Z  Z S ),TagzA Git Tag object.r   r   )	_message_name_object_class_object_sha
_signature	_tag_time_tag_timezone_tag_timezone_neg_utc_taggerr0  r=   Nc                    s,   t    d | _d | _d | _d| _d | _d S r  )r  r   r0  r-  r.  r/  r,  r   r  r   r   r     s   

zTag.__init__c                 C   r  r$   )rq   r   r6   r   )r_   rP   tagr   r   r   r     r  zTag.from_pathc                    s  t    | jdusJ | dd | dd | dd | js%tdt| jd	 | jdur6t	| jd
 | dd t
| j d}t| jD ]6\}}|tkrX|durXtd|tkrd|tkrdtd|tkrp|tkrptd|tkr||tkr|td|}qHdS )r  Nr+  zmissing object shar*  zmissing object typer)  zmissing tag namezempty tag namezinvalid object shazinvalid taggerr-  zmissing tag timezunexpected objectzunexpected typezunexpected tag namezunexpected tagger)r  r   r   r   r)  r   rv   r+  r0  r   r   r-  r"  _OBJECT_HEADER_TYPE_HEADER_TAG_HEADER_TAGGER_HEADER)r   lastr%  rc   r  r   r   r     s0   


z	Tag.checkc                 C   s   g }| t| jf | t| jjf | t| jf | jr=| j	d u r,| t
| jf n| t
t| j| j	| j| jff | jd u rJ| jd u rJd }n
| jpNd| jpRd }tt||S )Nr   )r  r2  r+  r3  r*  r]   r4  r)  r0  r-  r5  format_time_entryr.  r/  messager,  r   r&  )r   r#  r$  r   r   r   r   )  s(   

zTag._serializec              	   C   s(  d| _ d| _d| _d| _t|D ]\}}|tkr|| _q|tkr8t|t	s'J t
|}|s4td||| _q|tkr@|| _q|tkrRt|\| _ | _\| _| _q|du r|du rad| _d| _qz|t}W n tyw   || _d| _Y qw |d| | _||d | _qtd|dd dS )z&Grab the metadata attached to the tag.NFzNot a known type: zUnknown field rA   r   )r0  r-  r.  r/  r"  r2  r+  r3  r6   r7   r[   r   r*  r4  r)  r5  parse_time_entryr(  r,  indexBEGIN_PGP_SIGNATUREr8   rE   )r   r   r%  rg   r   sig_idxr   r   r   r   C  sJ   
zTag._deserializec                 C   s   | j | jfS )z_Get the object pointed to by this tag.

        Returns: tuple of (object class, sha).
        )r*  r+  r   r   r   r   _get_objectl     zTag._get_objectc                 C   s   |\| _ | _d| _d S NT)r*  r+  re   r   rg   r   r   r   _set_objects  s   
zTag._set_objectra   zThe name of this tagtaggerz3Returns the name of the person who created this tagtag_timezLThe creation timestamp of the tag.  As the number of seconds since the epochtag_timezonez!The timezone that tag_time is in.r8  z the message attached to this tag	signaturezOptional detached GPG signaturekeyidc              	   C      dd l }|jddS}|d ur=||}|jd|gd}|j|  |jjjjd\| _	}W d    n1 s7w   Y  n|j|  |jjjjd\| _	}W d    d S W d    d S 1 s`w   Y  d S Nr   T)armor)rI  signers)mode)
gpgContextget_keysignr   	constantssigrK  DETACHrE  r   rF  rL  ckeyctxunused_resultr   r   r   rO    "   

" zTag.signc                 C   s&   |   }| jr|dt| j  }|S )zReturn raw string serialization without the GPG/SSH signature.

        self.signature is a signature for the returned raw byte string serialization.
        N)r   r,  r0   )r   r  r   r   r   raw_without_sig  s   zTag.raw_without_sigkeyidsc           	            | j du rdS ddl}| O  j|  | j d\}}|rV fdd|D }|D ]!}|D ]}|jD ]}|jrH|j|jkrH   W d   dS q2q-q)|jj	||||fdW d   dS 1 saw   Y  dS )a  Verify GPG signature for this tag (if it is signed).

        Args:
          keyids: Optional iterable of trusted keyids for this tag.
            If this tag is not signed by any key in keyids verification will
            fail. If not specified, this function only verifies that the tag
            has a valid signature.

        Raises:
          gpg.errors.BadSignatures: if GPG signature verification fails
          gpg.errors.MissingSignatures: if tag was not signed by a key
            specified in keyids
        Nr   rE  c                       g | ]}  |qS r   rN  .0rU  rV  r   r   
<listcomp>      zTag.verify.<locals>.<listcomp>results)
r,  rL  rM  verifyrY  
signaturescan_signfprerrorsMissingSignatures	r   rZ  rL  r  resultkeysrU  subkeyrQ  r   ra  r   rf    ,   



	"z
Tag.verifyrn   r$   )!r   r   r   r   r]   r   r   r
   r7   r   r   r   r   r   r   r   r=  rA  ro   objectrp   ra   rB  rC  rD  r8  rE  r^   rO  rY  r   rf  r  r   r   r  r   r'    s>   
 
#
)




$
r'  c                   @   s   e Zd ZdZdefddZdS )	TreeEntryz.Named tuple encapsulating a single tree entry.rG   c                 C   s4   t | jtstd|tt|| j| j| jS )z:Return a copy of this entry with the given path prepended.zExpected bytes for path, got )	r6   rG   r7   r5   rr  	posixpathrH   rK  r1   )r   rG   r   r   r   in_path  s   zTreeEntry.in_pathN)r   r   r   r   r7   rt  r   r   r   r   rr    s    rr  )rG   rK  r1   Fc              
   c   s    d}t | }||k rw| d|}| || }|r&|dr&td| dzt|d}W n tyB } z	td| d|d}~ww | d|}| |d	 | }	|d
 }| |d	 | }
t |
dkrgtdt|
}|	||fV  ||k sdS dS )zParse a tree text.

    Args:
      text: Serialized text to parse
    Returns: iterator of tuples of (name, mode, sha)

    Raises:
      ObjectFormatException: if the object was malformed in some way
    r   rY      0zInvalid mode ''r   NrZ   r         zSha has invalid length)r0   r:  r  r   r   r8   r3   )r   strictcountrW   mode_end	mode_textrK  r;   name_endra   r1   r2   r   r   r   
parse_tree  s.   
r~  c                 c   s:    | D ]\}}}|d dd | d t| V  qdS )zSerialize the items in a tree to a text.

    Args:
      items: Sorted iterable over (name, mode, sha) tuples
    Returns: Serialized tree text as chunks
    04orA   rY   rZ   N)r@   r<   )r   ra   rK  r2   r   r   r   serialize_tree  s
    r  
name_orderc                 c   sd    |rt }nt}t|  |dD ]\}}|\}}t|}t|ts(td|t|||V  qdS )aX  Iterate over a tree entries dictionary.

    Args:
      name_order: If True, iterate entries in order of their name. If
        False, iterate entries in tree order, that is, treat subtree entries as
        having '/' appended.
      entries: Dictionary mapping names to (mode, sha) tuples
    Returns: Iterator over (name, mode, hexsha)
    )rU  zExpected bytes for SHA, got N)	key_entry_name_order	key_entrysortedr   r   r6   r7   r5   rr  )entriesr  key_funcra   entryrK  r2   r   r   r   sorted_tree_items  s   

r  r  c                 C   s"   | \}\}}t |r|d7 }|S )zISort key for tree entry.

    Args:
      entry: (name, value) tuple
       /)r   S_ISDIR)r  ra   rK  r   r   r   r   r    s   
r  c                 C   s   | d S )z&Sort key for tree entry in name order.r   r   )r  r   r   r   r    r   r  r   c              	   C   s2   |t j@ rd}nd}d|||d| |dS )zPretty format tree entry.

    Args:
      name: Name of the directory entry
      mode: Mode of entry
      hexsha: Hexsha of the referenced object
    Returns: string describing the tree entry
    treer  z{:04o} {} {}	{}
rA   r   )r   S_IFDIRr   rE   )ra   rK  r2   encodingkindr   r   r   pretty_format_tree_entry"  s   
	
r  c                   @   s   e Zd ZdZdddZdS )SubmoduleEncounteredz3A submodule was encountered while resolving a path.r=   Nc                 C   s   || _ || _d S r$   )rG   r1   )r   rG   r1   r   r   r   r   :  s   
zSubmoduleEncountered.__init__rn   )r   r   r   r   r   r   r   r   r   r  7  s    r  c                       s   e Zd ZdZdZdZdZd* fddZed	d
 Z	de
fddZdd Zd*ddZd*ddZdefddZdd Zd*ddZd+dee fddZdee fddZd*ddZd* fd d!Zd"d# Zdefd$d%Zd&eegef d'e fd(d)Z!  Z"S ),TreezA Git tree object.r   rB   _entriesr=   Nc                    s   t    i | _d S r$   )r  r   r  r   r  r   r   r   G  s   

zTree.__init__c                 C   r  r$   )rq   r   r6   r   )r_   rP   r  r   r   r   r   K  r  zTree.from_pathc                 C   s
   || j v S r$   r  r   ra   r   r   r   __contains__R  r   zTree.__contains__c                 C   s
   | j | S r$   r  r  r   r   r   __getitem__U  r   zTree.__getitem__c                 C   s    |\}}||f| j |< d| _dS )a  Set a tree entry by name.

        Args:
          name: The name of the entry, as a string.
          value: A tuple of (mode, hexsha), where mode is the mode of the
            entry as an integral type and hexsha is the hex SHA of the entry as
            a string.
        TNr  re   )r   ra   rg   rK  r2   r   r   r   __setitem__X  s   	
zTree.__setitem__c                 C   s   | j |= d| _d S r?  r  r  r   r   r   __delitem__e  s   
zTree.__delitem__c                 C   r   r$   )r0   r  r   r   r   r   __len__i  r   zTree.__len__c                 C   r   r$   )iterr  r   r   r   r   __iter__l  r   zTree.__iter__c                 C   s   ||f| j |< d| _dS )a*  Add an entry to the tree.

        Args:
          mode: The mode of the entry as an integral type. Not all
            possible modes are supported by git; see check() for details.
          name: The name of the entry, as a string.
          hexsha: The hex SHA of the entry as a string.
        TNr  )r   ra   rK  r2   r   r   r   addo  s   	
zTree.addFc                 C   s   t | j|S )zIterate over entries.

        Args:
          name_order: If True, iterate in name order instead of tree
            order.
        Returns: Iterator over (name, mode, sha) tuples
        )r  r  )r   r  r   r   r   	iteritems{  rs   zTree.iteritemsc                 C   s   t |  S )zeReturn the sorted entries in this tree.

        Returns: List with (name, mode, sha) tuples
        )r   r  r   r   r   r   r     r>  z
Tree.itemsc              
   C   sJ   z	t d|}W n ty } zt||d}~ww dd |D | _dS )zGrab the entries in the tree.r   Nc                 S   s   i | ]
\}}}|||fqS r   r   )r`  nr"   sr   r   r   
<dictcomp>  s    z%Tree._deserialize.<locals>.<dictcomp>)r~  rH   r8   r   r  )r   r   parsed_entriesr;   r   r   r   r     s   
zTree._deserializec                    s   t    | jdusJ d}tjdB tjdB tjtjttjdB f}td	| jdD ]O\}}}t
|d|  d|v s?|d	v rJtd
|dd||vrVtd|d|||ff}|rwt|t|krjtd||d krwtd| |}q*dS )r  Ni  i  i  r   Tzinvalid sha r  )r      .s   ..s   .gitzinvalid name {}r   r   zinvalid mode 06ozentries not sortedr   zduplicate entry )r  r   r   r   S_IFREGS_IFLNKr  r!   r~  rH   rv   r   r   rE   r  )r   r6  allowed_modesra   rK  r1   r  r  r   r   r     s4   
	z
Tree.checkc                 C   s   t t|  S r$   )r   r  r  r   r   r   r   r     r   zTree._serializec                 C   s4   g }|   D ]\}}}|t||| qd|S )N )r  r  r  rH   )r   r   ra   rK  r2   r   r   r   r     s   
zTree.as_pretty_string
lookup_objrG   c           	      C   s   | d}| j}d}t|D ].\}}|sq|dur)t|r)td|d| |||}t|ts6t||| \}}q||fS )zLook up an object in a Git tree.

        Args:
          lookup_obj: Callback for retrieving object by SHA1
          path: Path to lookup
        Returns: A tuple of (mode, SHA) of the resulting path.
        r  N)	r   r   	enumerater#   r  rH   r6   r  r   )	r   r  rG   partsr1   rK  iprf   r   r   r   lookup_path  s   

zTree.lookup_pathrn   F)#r   r   r   r   r]   r   r   r   r   r   r   r  r  r  r  r   r  r  r  r   rr  r  r   r   r   r   r   r^   r   r   r   rq   r7   r  r  r   r   r  r   r  ?  s,    





$$r  c                 C   s   | d dvrt djdi t | dd }t| dd }|dkr&| }|dko-|dk}|dk r4dp5d}t|}t|d }|d }||d	 |d
   |fS )a  Parse a timezone text fragment (e.g. '+0100').

    Args:
      text: Text to parse.
    Returns: Tuple with timezone as seconds difference to UTC
        and a boolean indicating whether this was a UTC timezone
        prefixed with a negative sign (-0000).
    r   s   +-z(Timezone must start with + or - ({text})Nr      -r{   d     <   r   )r8   r   varsr   abs)r   rO  offsetunnecessary_negative_timezonesignumhoursminutesr   r   r   parse_timezone  s   r  c                 C   sP   | d dkr
t d| dk s|rd}|  } nd}d|| d | d d f dS )	a  Format a timezone for Git serialization.

    Args:
      offset: Timezone offset as seconds difference to UTC
      unnecessary_negative_timezone: Whether to use a minus sign for
        UTC or positive timezones (-0000 and --700 rather than +0000 / +0700).
    r  r   z#Unable to handle non-minute offset.-+z
%c%02d%02dr  rA   )r8   r@   )r  r  rO  r   r   r   format_timezone  s    r  c           
   
   C   s   z|  d}W n ty   | ddf Y S w z$| d|d  }| |d d }|dd\}}t|}t|\}}W n tyK }	 zt|	|	d}	~	ww ||||ffS )zParse event.

    Args:
      value: Bytes representing a git commit/tag line
    Raises:
      ObjectFormatException in case of parsing error (malformed
      field date)
    Returns: Tuple of (author, time, (timezone, timezone_neg_utc))
    s   > Nr  r   r   rB   rY   )rindexr8   rN   r   r  r   )
rg   rO   personrT   timetexttimezonetexttimetimezonetimezone_neg_utcr;   r   r   r   r9  
  s    

r9  c                 C   s(   |\}}d | t|dt||gS )zFormat an event.rY   rA   )rH   r^   r@   r  )r  r  timezone_infor  r  r   r   r   r7  #  s   r7  c              	   C   s   t dt g }g }d}d}d}d}g }d}d}	t| D ]R\}
}|
tkr'|}q|
tkr1|| q|
tkr:t|}q|
t	krCt|}q|
t
krJ|}q|
tkrY|t|d  q|
tkr`|}	q|
du rg|}q||
|f q|||||||	||f	S )zParse a commit object from chunks.

    Args:
      chunks: Chunks to parse
    Returns: Tuple of (tree, parents, author_info, commit_info,
        encoding, mergetag, gpgsig, message, extra)
    z$parse_commit will be removed in 0.22NNNr  r|   )warningswarnDeprecationWarningr"  _TREE_HEADER_PARENT_HEADERr  _AUTHOR_HEADERr9  _COMMITTER_HEADER_ENCODING_HEADER_MERGETAG_HEADERr'  r   _GPGSIG_HEADER)r   parentsr   r  author_infocommit_infor  mergetagr8  gpgsigr%  rg   r   r   r   parse_commit+  sL   

r  c                       s>  e Zd ZdZdZdZdZd8 fddZed	d
 Z	d8ddZ
d8 fddZd9dee ddfddZdefddZd9deee  ddfddZdd ZeddZdd Zd8ddZeeedd Zd!d" Zeed#d Zed$d%Zed&d'Zed(d)Zed*d+Zed,d-Z ed.d/Z!ed0d1Z"ed2d3Z#ed4d5Z$ed6d7Z%  Z&S ):CommitzA git commit object.s   commitr   )_author_author_time_author_timezone_author_timezone_neg_utc_commit_time_commit_timezone_commit_timezone_neg_utc
_committer	_encoding_extra_gpgsig	_mergetagr(  _parents_treer=   Nc                    s8   t    g | _d | _g | _d | _g | _d| _d| _d S r  )	r  r   r  r  r  r  r  r  r  r   r  r   r   r   w  s   

zCommit.__init__c                 C   r  r$   )rq   r   r6   r   )r_   rG   commitr   r   r   r     r  zCommit.from_pathc                 C   s6  g | _ g | _d | _d}d}d | _g | _d | _d | _t|D ]e\}}|tkr)|| _q|t	kr:|d us3J | j 
| q|tkrCt|}q|tkrLt|}q|tkrT|| _q|tkrj|d us^J | j
t|d  q|tkrr|| _q|d u rz|| _q| j
||f q|\| _| _\| _| _|\| _| _\| _| _d S )Nr  r|   )r  r  r  r  r  r(  r  r"  r  r  r  r  r9  r  r  r  r'  r   r  r  r  r  r  r  r  r  r  )r   r   r  r  r%  rg   r   r   r   r     sN   


zCommit._deserializec                    sB  t    | jdusJ | dd | dd | dd | dd	 | d
d | jD ]}t|d q-t| jd t| jd t| j	d t
| j t
| j d}t| jD ]F\}}|tkrh|durhtd|tkrv|ttfvrvtd|tkr|ttfvrtd|tkr|tkrtd|tkr|tkrtd|}qXdS )r  Nr  zmissing treer  zmissing authorr  zmissing committerr  zmissing author timer  zmissing commit timezinvalid parent shazinvalid tree shazinvalid authorzinvalid committerzunexpected treezunexpected parentzunexpected authorzunexpected committerzunexpected encoding)r  r   r   r   r  rv   r  r   r  r  r   r  r  r"  r  r   r  r  r  r  )r   parentr6  r%  rc   r  r   r   r     sD   





zCommit.checkrF  c              	   C   rG  rH  )
rL  rM  rN  rO  r   rP  rQ  rK  rR  r  rS  r   r   r   rO    rX  zCommit.signc                 C   s*   |   }t|tsJ d|_d|_| S )zReturn raw string serialization without the GPG/SSH signature.

        self.gpgsig is a signature for the returned raw byte string serialization.
        N)r   r6   r  r  r  r   )r   tmpr   r   r   rY    s
   zCommit.raw_without_sigrZ  c           	         r[  )a  Verify GPG signature for this commit (if it is signed).

        Args:
          keyids: Optional iterable of trusted keyids for this commit.
            If this commit is not signed by any key in keyids verification will
            fail. If not specified, this function only verifies that the commit
            has a valid signature.

        Raises:
          gpg.errors.BadSignatures: if GPG signature verification fails
          gpg.errors.MissingSignatures: if commit was not signed by a key
            specified in keyids
        Nr   r\  c                    r]  r   r^  r_  ra  r   r   rb    rc  z!Commit.verify.<locals>.<listcomp>rd  )
r  rL  rM  rf  rY  rg  rh  ri  rj  rk  rl  r   ra  r   rf    rp  zCommit.verifyc                 C   s   g }t | jtr| jjn| j}|t|f | jD ]	}|t|f q|tt	| j
| j| j| jff |tt	| j| j| j| jff | jrP|t| jf | jD ]}|t| d d f qS|| j | jrt|t| jf tt|| jS )Nr{   )r6   r  r  r   r  r  r  r  r  r7  r  r  r  r  r  r  r  r  r  r  r  r  r  r   r  r  r  r  r   r&  r(  )r   r#  
tree_bytesr  r  r   r   r   r     s>   





zCommit._serializer  z%Tree that is the state of this commitc                 C   r   )z(Return a list of parents of this commit.)r  r   r   r   r   _get_parentsD  r   zCommit._get_parentsc                 C   s   d| _ || _dS )z%Set a list of parents of this commit.TN)re   r  r@  r   r   r   _set_parentsH  s   
zCommit._set_parentsz&Parents of this commit, by their SHA1.rl   c                 C   s   t jdtdd | jS )z%Return extra settings of this commit.z6Commit.extra is deprecated. Use Commit._extra instead.rB   )
stacklevel)r  r  r  r  r   r   r   r   
_get_extraS  s   zCommit._get_extrazExtra header fields not understood (presumably added in a newer version of git). Kept verbatim so the object can be correctly reserialized. For private commit metadata, use pseudo-headers in Commit.message, rather than this field.authorz$The name of the author of the commit	committerz'The name of the committer of the commitr8  zThe commit messagecommit_timezFThe timestamp of the commit. As the number of seconds since the epoch.commit_timezonezThe zone the commit time is inauthor_timezOThe timestamp the commit was written. As the number of seconds since the epoch.author_timezonez'Returns the zone the author time is in.r  zEncoding of the commit message.r  zAssociated signed tag.r  zGPG Signature.rn   r$   )'r   r   r   r   r]   r   r   r   r   r   r   r   r
   r^   rO  r7   rY  r   rf  r   rp   r  r  r  ro   r  r  r   r  r  r8  r  r  r  r  r  r  r  r  r   r   r  r   r  _  sb    


-.!
#
	



r  rr   )r~  )r  r$   rn   r  )r   )jr   r.   rF   rs  r   r  r%   collectionsr   collections.abcr   r   r   hashlibr   ior   typingr   r	   r
   r   rj  r   r   r   r   r   r   r   rJ   r   _hashlibr   ZERO_SHAr  r  r  r  r  r  r  r2  r3  r4  r5  r!   r   r;  r7   r   r   r#   r,   r3   r<   r   r?   rK   rU   r   r`   r^   rp   rC   r[   rv   r   r   r   r   rq   r   tupler"  r&  r'  rr  r~  r  r  r  r  r  r   r  r  r  r  r9  r7  r  r  OBJECT_CLASSESrr   dictr   r_   r]   r   _parse_tree_py_sorted_tree_items_pydulwich._objects_parse_tree_rs_sorted_tree_items_rsImportErrorr   r   r   r   <module>   s   $	
"

  ;V
8 b

"" 
4  * 
