o
    Uhw                  	   @   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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 dd	lmZ dd
lmZmZmZmZmZmZmZmZm Z m!Z!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.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9 ddl:m;Z; ddl<m=Z=m>Z> dZ?dZ@ejAdkrdndZBG dd deZCG dd dZDG dd deDZEG dd deEZFG dd deDZGG dd deZHdd  ZId!e(d"ed#eJe d$dfd%d&ZKd'd(d!e(d$eLeJeM eJeM eJeM f fd)d*ZNG d+d, d,ZOG d-d. d.ZPd/d0 ZQG d1d2 d2eDZRd3d4 ZSG d5d6 d6eEZTeU eU d7d8 fd9e(d:eUe d;eUe fd<d=ZVd'd>d9e(d?ee d@eWfdAdBZXd9e(dCeMd$eLeef fdDdEZYdS )Fz/Git object store interfaces and implementation.    N)IterableIteratorSequence)suppress)BytesIO)CallableOptionalProtocolcast   )NotTreeError)GitFile)S_ISGITLINKZERO_SHABlobCommitObjectIDShaFileTagTree	TreeEntryhex_to_filename
hex_to_shaobject_class
sha_to_hexvalid_hexsha)PACK_SPOOL_FILE_MAX_SIZEObjectContainerPackPackDataPackedObjectContainerPackFileDisappearedPackHintPackIndexerPackInflaterPackStreamCopierUnpackedObjectextend_packfull_unpacked_objectgenerate_unpacked_objects	iter_sha1load_pack_index_filepack_objects_to_datawrite_pack_datawrite_pack_index)DEPTH_INFINITE)PEELED_TAG_SUFFIXRefinfopackwin32i$  i  c                   @   s4   e Zd Zdeeeg df eg df f fddZdS )PackContainerreturnNc                 C      dS )zAdd a new pack.N selfr8   r8   h/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/dulwich/object_store.pyadd_pack]       zPackContainer.add_pack)__name__
__module____qualname__tupler   r   r<   r8   r8   r8   r;   r5   \   s    ,r5   c                   @   sb  e Zd ZdZ	d6deeef dee de	e fddZ
defdd	Zd
edefddZedd Zdeeef fddZd
edefddZdd Zd7ddZd6d7ddZ				d8ddZd9ddZdddee d edee fd!d"Zdddd#d$ fd%d&Zd'd( Z	)d:deeee f fd*d+Z d,d- Z!d.d$ dfd/d0Z"d7d1d2Z#d3edee fd4d5Z$dS );BaseObjectStorezObject store interface.Nrefsdepthr6   c                    s&   fdd  fdd|  D S )Nc                    s"    sdS  t kr
dS  | kS )NFT)r/   
_get_depthsharD   r:   r8   r;   _want_deepeng   s
   z9BaseObjectStore.determine_wants_all.<locals>._want_deepenc                    s6   g | ]\}}|vs |r| ts|tks|qS r8   )endswithr0   r   ).0refrG   )rI   r:   r8   r;   
<listcomp>n   s    z7BaseObjectStore.determine_wants_all.<locals>.<listcomp>)items)r:   rC   rD   r8   )rI   rD   r:   r;   determine_wants_alld   s   z#BaseObjectStore.determine_wants_allc                 C   
   t | jz=Check if a particular object is present by SHA1 and is loose.)NotImplementedErrorcontains_looser:   rG   r8   r8   r;   rS   v      
zBaseObjectStore.contains_loosesha1c                 C   s
   |  |S )Check if a particular object is present by SHA1.

        This method makes no distinction between loose and packed objects.
        )rS   )r:   rV   r8   r8   r;   __contains__z   s   
zBaseObjectStore.__contains__c                 C      t )zIterable of pack objects.rR   r9   r8   r8   r;   packs      zBaseObjectStore.packsc                 C   rP   zObtain the raw text for an object.

        Args:
          name: sha for the object.
        Returns: tuple with numeric type and object contents.
        )rR   get_rawr:   namer8   r8   r;   r^      s   
zBaseObjectStore.get_rawc                 C   s   |  |\}}tj|||dS )zObtain an object by SHA1.rF   )r^   r   from_raw_string)r:   rV   type_numuncompr8   r8   r;   __getitem__   s   zBaseObjectStore.__getitem__c                 C   rP   5Iterate over the SHAs that are present in this store.)rR   __iter__r9   r8   r8   r;   rg      rU   zBaseObjectStore.__iter__c                 C   rP   ))Add a single object to this object store.)rR   
add_objectr:   objr8   r8   r;   ri      rU   zBaseObjectStore.add_objectc                 C   rP   )Add a set of objects to this object store.

        Args:
          objects: Iterable over a list of (object, path) tuples
        )rR   add_objectsr:   objectsprogressr8   r8   r;   rm      s   
zBaseObjectStore.add_objectsFc           	   	   c   s^    ddl m} || ||||||dD ]}|jj|jjf|jj|jjf|jj|jjffV  qdS )a  Find the differences between the contents of two trees.

        Args:
          source: SHA1 of the source tree
          target: SHA1 of the target tree
          want_unchanged: Whether unchanged files should be reported
          include_trees: Whether to include trees
          change_type_same: Whether to report files changing
            type in the same entry.
        Returns: Iterator over tuples with
            (oldpath, newpath), (oldmode, newmode), (oldsha, newsha)
        r   )tree_changes)want_unchangedinclude_treeschange_type_samerename_detectorN)	diff_treerq   oldpathnewmoderG   )	r:   sourcetargetrr   rs   rt   ru   rq   changer8   r8   r;   rq      s    

zBaseObjectStore.tree_changesc                 C   s   t jdtdd t| ||dS )aW  Iterate the contents of a tree and all subtrees.

        Iteration is depth-first pre-order, as in e.g. os.walk.

        Args:
          tree_id: SHA1 of the tree.
          include_trees: If True, include tree objects in the iteration.
        Returns: Iterator over TreeEntry namedtuples for all the objects in a
            tree.
        z2Please use dulwich.object_store.iter_tree_contents   
stacklevelrs   )warningswarnDeprecationWarningiter_tree_contents)r:   tree_idrs   r8   r8   r;   r      s   z"BaseObjectStore.iter_tree_contentsallow_missingshasr   c             	   c   s6    |D ]}z| | V  W q t y   |s Y qw d S N)KeyError)r:   r   r   rG   r8   r8   r;   iterobjects_subset   s   z"BaseObjectStore.iterobjects_subsetc                 C      | j S r   parentscommitr8   r8   r;   <lambda>       zBaseObjectStore.<lambda>c              	   C   s*   t dt t| ||||||d}t|S )a`  Find the missing objects required for a set of revisions.

        Args:
          haves: Iterable over SHAs already in common.
          wants: Iterable over SHAs of objects to fetch.
          shallow: Set of shallow commit SHA1s to skip
          progress: Simple progress function that will be called with
            updated progress strings.
          get_tagged: Function that returns a dict of pointed-to sha ->
            tag sha for including tags.
          get_parents: Optional function for getting the parents of a
            commit.
        Returns: Iterator over (sha, path) pairs.
        z%Please use MissingObjectFinder(store))haveswantsshallowrp   
get_taggedget_parents)r   r   r   MissingObjectFinderiter)r:   r   r   r   rp   r   r   finderr8   r8   r;   find_missing_objects   s   	z$BaseObjectStore.find_missing_objectsc                 C   s<   g }t |}|r|| v r|| || t |}|s|S )zFind which revisions this store has in common using graphwalker.

        Args:
          graphwalker: A graphwalker object.
        Returns: List of SHAs that are in common
        )nextappendack)r:   graphwalkerr   rG   r8   r8   r;   find_common_revisions	  s   

z%BaseObjectStore.find_common_revisionsTc                    s6   t  ||||d}t|}t fdd|D ||dS )p  Generate pack data objects for a set of wants/haves.

        Args:
          have: List of SHA1s of objects that should not be sent
          want: List of SHA1s of objects that should be sent
          shallow: Set of shallow commit SHA1s to skip
          ofs_delta: Whether OFS deltas can be included
          progress: Optional progress reporting method
        r   r   r   rp   c                    s   g | ]
\}} | |fqS r8   r8   )rK   oidrx   r9   r8   r;   rM   ,  s    z6BaseObjectStore.generate_pack_data.<locals>.<listcomp>)	ofs_deltarp   )r   listr,   )r:   havewantr   rp   r   missing_objects
object_idsr8   r9   r;   generate_pack_data  s   
z"BaseObjectStore.generate_pack_datac                 C   s   t jdtdd t| |d S )a  Peel all tags from a SHA.

        Args:
          sha: The object SHA to peel.
        Returns: The fully-peeled SHA1 of a tag object, after peeling all
            intermediate tags; if the original ref does not point to a tag,
            this will equal the original SHA1.
        z*Please use dulwich.object_store.peel_sha()r~   r   r   )r   r   r   peel_sharT   r8   r8   r;   r   1  s   	zBaseObjectStore.peel_shac                 C   r   r   r   r   r8   r8   r;   r   D  r   c           
         s   |vrdS d}||fg}|rN|du s||k rN| d\} t| }| }t|tr5|j\}}	|	 }| fdd||D  |rN|du s||k s|S )aS  Return the current available depth for the given head.
        For commits with multiple parents, the largest possible depth will be
        returned.

        Args:
            head: commit to start from
            get_parents: optional function for getting the parents of a commit
            max_depth: maximum depth to search
        r   r   Nc                 3   s$    | ]}|v r| d  fV  qdS )r   Nr8   )rK   parentrH   r8   r;   	<genexpr>[  s    z-BaseObjectStore._get_depth.<locals>.<genexpr>)popmax
isinstancer   objectextend)
r:   headr   	max_depthcurrent_depthqueueecmt_clsrG   r8   rH   r;   rE   A  s    




zBaseObjectStore._get_depthc                 C   r7   )z,Close any files opened by this object store.Nr8   r9   r8   r8   r;   close`  r=   zBaseObjectStore.closeprefixc                 c   s     | D ]
}| |r|V  qdS )zIterate over all SHA1s that start with a given prefix.

        The default implementation is a naive iteration over all objects.
        However, subclasses may override this method with more efficient
        implementations.
        N)
startswith)r:   r   rG   r8   r8   r;   iter_prefixd  s   
zBaseObjectStore.iter_prefixr   r6   N)FFFN)FNNT)%r>   r?   r@   __doc__dictr1   r   r   intr   rO   boolrS   bytesrX   propertyr[   rA   r^   r   rd   rg   ri   rm   rq   r   r   r   r   r   r   r&   r   r   rE   r   r   r8   r8   r8   r;   rB   a   sb    


	


&

#


rB   c                   @   s  e Zd ZdHdIddZdeeeg df eg df f fddZ	dJded	e	e
 ddfd
dZedd ZdefddZdefddZdIddZ	dKdeee	e
 f fddZdIddZdd Zdee fddZdIddZedd  Zd!d" Zd#d$ Zdee fd%d&ZdId'd(ZdId)d*Z d+d, Z!d-d. Z"d/d0 Z#d1d2 Z$d3d4 Z%d5d5dd6d7ed8ede	e fd9d:Z&d5d;d<e'e( d7ede	e fd=d>Z)d5d?d@e(dAede
fdBdCZ*	dJdDe+eeee, f  dEeee,gdf  ddfdFdGZ-dS )LPackBasedObjectStorer6   Nc                 C   s   i | _ || _d S r   )_pack_cachepack_compression_level)r:   r   r8   r8   r;   __init__q     
zPackBasedObjectStore.__init__c                 C   rP   )z$Add a new pack to this object store.)rR   r<   r9   r8   r8   r;   r<   u  rU   zPackBasedObjectStore.add_packcountunpacked_objectsc                 C   sP   |dkrdS |   \}}}zt|j|||| jd W | S  ty'   |   w )Add pack data to this object store.

        Args:
          count: Number of items to add
          pack_data: Iterator over pack data tuples
        r   N)num_recordsrp   compression_level)r<   r-   writer   BaseException)r:   r   r   rp   fr   abortr8   r8   r;   add_pack_datay  s    	z"PackBasedObjectStore.add_pack_datac                 C      g S r   r8   r9   r8   r8   r;   
alternates     zPackBasedObjectStore.alternatesc              	   C   s6   | j D ]}z
||v rW  dS W q ty   Y qw dS )zpCheck if a particular object is present by SHA1 and is packed.

        This does not check alternates.
        TF)r[   r!   )r:   rG   r3   r8   r8   r;   contains_packed  s   
z$PackBasedObjectStore.contains_packedc                 C   s6   |  |s
| |rdS | jD ]	}||v r dS qdS )rW   TF)r   rS   r   )r:   rG   	alternater8   r8   r;   rX     s   
z!PackBasedObjectStore.__contains__c                 C   s6   | j |}||ur|| j |< |r|  dS dS dS )z/Add a newly appeared pack to the cache by path.N)r   getr   )r:   	base_namer3   	prev_packr8   r8   r;   _add_cached_pack  s   
z%PackBasedObjectStore._add_cached_packTc           	      C   sB   t | ||||d}| }t|}t|ttt| ||||dfS )r   r   )rp   r   other_haves)r   get_remote_hasr   lenr)   r
   r    )	r:   r   r   r   rp   r   r   
remote_hasr   r8   r8   r;   r     s   
z'PackBasedObjectStore.generate_pack_datac                 C   s0   | j }i | _ |r| \}}|  |sd S d S r   )r   popitemr   )r:   
pack_cacher`   r3   r8   r8   r;   _clear_cached_packs  s   z(PackBasedObjectStore._clear_cached_packsc                 C   s
   | j  S r   )r   valuesr9   r8   r8   r;   _iter_cached_packs     
z'PackBasedObjectStore._iter_cached_packsc                 C   rP   r   )rR   _update_pack_cacher9   r8   r8   r;   r     r   z'PackBasedObjectStore._update_pack_cachec                 C   s   |    d S r   )r   r9   r8   r8   r;   r        zPackBasedObjectStore.closec                 C   s   t |  t |   S zList with pack objects.)r   r   r   r9   r8   r8   r;   r[     s   zPackBasedObjectStore.packsc                 c   s    | j D ]}|E dH  qdS )z=Iterate over the SHAs of all the objects in alternate stores.N)r   )r:   r   r8   r8   r;   _iter_alternate_objects  s   
z,PackBasedObjectStore._iter_alternate_objectsc                 C   rP   z+Iterate over the SHAs of all loose objects.)rR   _iter_loose_objectsr9   r8   r8   r;   r     rU   z(PackBasedObjectStore._iter_loose_objectsc                 C   rP   r   )rR   _get_loose_objectrT   r8   r8   r;   r     r   z&PackBasedObjectStore._get_loose_objectc                 C   rP   r   )rR   _remove_loose_objectrT   r8   r8   r;   r     r   z)PackBasedObjectStore._remove_loose_objectc                 C   rP   r   rR   _remove_packr_   r8   r8   r;   r     r   z!PackBasedObjectStore._remove_packc                 C   sX   t  }|  D ]}|| |df q| t| |D ]
\}}| |j qt|S )zGPack loose objects.

        Returns: Number of objects packed
        N)	setr   addr   rm   r   r   idr   )r:   ro   rG   rk   rx   r8   r8   r;   pack_loose_objects  s   z'PackBasedObjectStore.pack_loose_objectsc           	      C   s   t  }|  D ]
}|| | qdd |D }dd | jD }| D ]\}}|dd | D  q%| |}|	|
 d |D ]}| |j qE| D ]	\}}| | qR|   t|S )zRepack the packs in this repository.

        Note that this implementation is fairly naive and currently keeps all
        objects in memory while it repacks.
        c                 S   s   h | ]}|d fqS r   r8   rK   rk   r8   r8   r;   	<setcomp>  s    z.PackBasedObjectStore.repack.<locals>.<setcomp>c                 S   s   i | ]}|  |qS r8   )r`   rK   pr8   r8   r;   
<dictcomp>  s    z/PackBasedObjectStore.repack.<locals>.<dictcomp>c                 s   s    | ]}|d fV  qd S r   r8   r   r8   r8   r;   r         z.PackBasedObjectStore.repack.<locals>.<genexpr>N)r   r   r   r   r[   rN   updateiterobjectsrm   r   r`   r   r   r   r   r   )	r:   loose_objectsrG   ro   	old_packsr`   r3   consolidatedrk   r8   r8   r;   repack  s   
zPackBasedObjectStore.repackc              	   c   sX    |    |  D ]}z|E dH  W q	 ty   Y q	w |  E dH  |  E dH  dS )rf   N)r   r   r!   r   r   r:   r3   r8   r8   r;   rg   "  s   zPackBasedObjectStore.__iter__c                 C   s   |  |duS )zoCheck if a particular object is present by SHA1 and is loose.

        This does not check alternates.
        N)r   rT   r8   r8   r;   rS   -  s   z#PackBasedObjectStore.contains_loosec              
   C   s  |t krt|t|dkrt|}|}nt|dkr |}d}ntd||  D ]}z||W   S  ttfy@   Y q+w |du rIt|}| 	|}|durY|j
| fS |  D ]}z||W   S  typ   Y q]w | jD ]}z||W   S  ty   Y qtw t|)zObtain the raw fulltext for an object.

        Args:
          name: sha for the object.
        Returns: tuple with numeric type and object contents.
        (      NzInvalid object name )r   r   r   r   AssertionErrorr   r^   r!   r   r   rb   as_raw_stringr   r   )r:   r`   rG   hexshar3   retr   r8   r8   r;   r^   4  sB   

zPackBasedObjectStore.get_rawFinclude_compr   convert_ofs_deltar   r  c          
      c   s    t |}|  D ]}|j||d|dD ]}|V  t| }|| qq	|  D ]}|j||d|dD ]}|V  t| }|| q5q*| jD ]}	|	j||d|dD ]}|V  t| }|| qUqJd S NTr  )r   r   iter_unpacked_subsetr   rG   remover   r   )
r:   r   r  r   r  todor   unpackedr	  r   r8   r8   r;   r  ]  sH   


	
z)PackBasedObjectStore.iter_unpacked_subsetr   r   c                c   s    t |}|  D ]}|j|ddD ]}|V  ||j qq	|  D ]}|j|ddD ]}|V  ||j q,q#| jD ]}|j|ddD ]}|V  ||j qEq<|D ]}| |}|d urc|V  qT|sit|qTd S NTr   )	r   r   r   r  r   r   r   r   r   )r:   r   r   r  r   or   r   r8   r8   r;   r     s2   

z'PackBasedObjectStore.iterobjects_subsetr  rV   r  c             
   C   s  |t krt|t|dkrt|}|}nt|dkr |}d}ntd||  D ]}z
|j||dW   S  ttfyB   Y q+w |du rKt|}| 	 D ]}z
|j||dW   S  tyd   Y qOw | j
D ]}z
|j||dW   S  ty}   Y qhw t|)zWObtain the unpacked object.

        Args:
          sha1: sha for the object.
        r  r  NzInvalid object sha1 r  )r   r   r   r   r  r   get_unpacked_objectr!   r   r   r   )r:   rV   r  rG   r	  r3   r   r8   r8   r;   r    s<   
z(PackBasedObjectStore.get_unpacked_objectro   rp   c                 C   s&   t |}dd |D }| j|||dS )zAdd a set of objects to this object store.

        Args:
          objects: Iterable over (object, path) tuples, should support
            __len__.
        Returns: Pack object of the objects written.
        c                 s   s    | ]	\}}t |V  qd S r   )r(   )rK   r  r   r8   r8   r;   r     s    z3PackBasedObjectStore.add_objects.<locals>.<genexpr>rp   )r   r   )r:   ro   rp   r   record_iterr8   r8   r;   rm     s   z PackBasedObjectStore.add_objects)r   r   r   r   ).r>   r?   r@   r   rA   r   r   r<   r   r   r&   r   r   r   r   r   rX   r   r   r   r   r   r   r   r   r[   r   r   r   r   r   r   r   r   r  rg   rS   r^   r  r   r   r   r  r   strrm   r8   r8   r8   r;   r   p  s    (


	





-
+

*r   c                       s   e Zd ZdZ	d+	d, fddZdefddZed	d
 Ze	dd Z
dd Zd,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-dd Zd-d!d"Zd#d$ Zd,d%d&Zed'd( Z fd)d*Z  ZS ).DiskObjectStorez+Git-style object store that exists on disk.r   r6   Nc                    s<   t  j|d || _tj| jt| _d| _|| _|| _	dS )zOpen an object store.

        Args:
          path: Path of the object store.
          loose_compression_level: zlib compression level for loose objects
          pack_compression_level: zlib compression level for pack objects
        )r   N)
superr   rx   osjoinPACKDIRpack_dir_alternatesloose_compression_levelr   )r:   rx   r!  r   	__class__r8   r;   r     s   

zDiskObjectStore.__init__c                 C   s   d| j j d| jdS )N<(z)>)r#  r>   rx   r9   r8   r8   r;   __repr__  s   zDiskObjectStore.__repr__c                 C   s   zt |dd }W n ty   d}Y nw zt |dd }W n ty/   |}Y nw zt |dd }W n tyG   |}Y nw | |||S )N)s   cores   compressionr   s   looseCompressionpackCompression)r   r   decoder   )clsrx   configdefault_compression_levelr!  r   r8   r8   r;   from_config  s,   zDiskObjectStore.from_configc                 C   s:   | j d ur| j S g | _ |  D ]
}| j t| q| j S r   )r   _read_alternate_pathsr   r  )r:   rx   r8   r8   r;   r     s   
zDiskObjectStore.alternatesc              	   c   s    zt tj| jtdd}W n
 ty   Y d S w |7 | D ])}|d}|dr.q!tj	|r;t
|V  q!t
tjt| j|V  q!W d    d S 1 sVw   Y  d S )Nr   rb   
   #)r   r  rx   r  INFODIRFileNotFoundError	readlinesrstripr   isabsfsdecodefsencode)r:   r   liner8   r8   r;   r-    s    

 "z%DiskObjectStore._read_alternate_pathsc              	   C   s  zt t j| jt W n	 ty   Y nw t j| jtd}t|d<}zt|d}W n	 ty6   Y nw | |	|
  W d   n1 sKw   Y  |	t |d  W d   n1 sdw   Y  t j|swt j| j|}| jt| dS )z+Add an alternate path to this object store.r   wbr.  Nr/  )r  mkdirrx   r  r1  FileExistsErrorr   openr2  r   readr7  r5  r   r   r  )r:   rx   alternates_pathr   orig_fr8   r8   r;   add_alternate_path  s(   
z"DiskObjectStore.add_alternate_pathc           	      C   s   zt | j}W n ty   |   g  Y S w t }|D ](}|drE|drEt j	|d d }||v rE|dt
d  }|| qg }|D ]}|| jvrett j| j|}|| || j|< qJt| j| D ]
}| j|  qm|S )z4Read and iterate over new pack files and cache them.pack-.packr   .idxN)r  listdirr  r2  r   r   r   rJ   rx   splitextr   r   r   r   r  r   r   )	r:   pack_dir_contents
pack_filesr`   idx_name	pack_name	new_packsr   r3   r8   r8   r;   r   2  s0   



z"DiskObjectStore._update_pack_cachec                 C   s   t | j|S r   )r   rx   rT   r8   r8   r;   _get_shafile_pathO  s   z!DiskObjectStore._get_shafile_pathc                 c   s`    t | jD ]&}t|dkrqt t j| j|D ]}t || }t|s)q|V  qqd S )Nr~   )r  rD  rx   r   r  r7  r   )r:   baserestrG   r8   r8   r;   r   S  s   z#DiskObjectStore._iter_loose_objectsc                 C   s,   |  |}zt|W S  ty   Y d S w r   )rK  r   	from_pathr2  )r:   rG   rx   r8   r8   r;   r   ]  s   
z!DiskObjectStore._get_loose_objectc                 C   s   t | | d S r   )r  r  rK  rT   r8   r8   r;   r   d     z$DiskObjectStore._remove_loose_objectc                 C   sR   z| j tj|j= W n	 ty   Y nw |  t|jj t|j	j d S r   )
r   r  rx   basename	_basenamer   r   r  dataindexr  r8   r8   r;   r   g  s   zDiskObjectStore._remove_packc                 C   s0   t dd |D }|d}tj| jd| S )Nc                 s       | ]}|d  V  qdS r   Nr8   rK   entryr8   r8   r;   r   q  r   z5DiskObjectStore._get_pack_basepath.<locals>.<genexpr>asciirA  )r*   r(  r  rx   r  r  )r:   entriessuffixr8   r8   r;   _get_pack_basepathp  s   
z"DiskObjectStore._get_pack_basepathc                 C   s  g }t |D ]\}}|dur|d| d| dd || qt|| | j| j|d\}	}
|  z| }W n	 t	yD   Y nw t
| |  ||
 |  | |}| jD ]}|j|krj|  S q_|d }|d }tjd	krtt t
| W d   n1 sw   Y  t
|| t|d
td}t|||	 W d   n1 sw   Y  t|}|  | || |S )a@  Move a specific file containing a pack into the pack directory.

        Note: The file should be on the same file system as the
            packs directory.

        Args:
          f: Open file object for the pack.
          path: Path to the pack file.
          indexer: A PackIndexer for indexing the pack.
        Nzgenerating index: /rX  )r^   r   rp   rB  rC  r4   r9  mask)	enumerateencoder   r'   ext_refsr^   r   flushfilenoAttributeErrorr  fsyncr   r   sortr[  r[   rQ  sysplatformr   r2  r  renamer   	PACK_MODEr.   r   check_length_and_checksumr   )r:   r   rx   num_objectsindexerrp   rY  irW  pack_shaextra_entriesrd  pack_base_namer3   target_pack_pathtarget_index_path
index_file
final_packr8   r8   r;   _complete_packv  sR   







zDiskObjectStore._complete_packc           
      C   s   ddl }|j| jdd\}}t|d/}t|t t|| jd}t	||||d}	|	j
|d | j||t|	||dW  d   S 1 sFw   Y  dS )	aw  Add a new thin pack to this object store.

        Thin packs are packs that contain deltas with parents that exist
        outside the pack. They should never be placed in the object store
        directly, and always indexed and completed as they are copied.

        Args:
          read_all: Read function that blocks until the number of
            requested bytes are read.
          read_some: Read function that returns at least one byte, but may
            not return the number of bytes requested.
        Returns: A Pack object pointing at the now-completed thin pack in the
            objects/pack directory.
        r   N	tmp_pack_)dirr   w+bresolve_ext_ref)
delta_iterr  )tempfilemkstemprx   r  fdopenchmodrk  r#   r^   r%   verifyrw  r   )
r:   read_all	read_somerp   r~  fdrx   r   rn  copierr8   r8   r;   add_thin_pack  s   $zDiskObjectStore.add_thin_packc                    s^   ddl }|jjdd\}t|d tt  fdd}d fd	d
} ||fS )Add a new pack to this object store.

        Returns: Fileobject to write to, a commit function to
            call when the pack is finished and an abort
            function.
        r   NrB  )ry  rZ  rz  c                     s~      dkr4 d t } tj| jd} t| |W  d    S 1 s-w   Y  d S    t	
 d S )Nr   r{  )tellseekr   r#   for_pack_datar^   rw  r   r   r  r  )pdrn  r   rx   r:   r8   r;   r     s   
$
z(DiskObjectStore.add_pack.<locals>.commitr6   c                      s       t d S r   )r   r  r  r8   )r   rx   r8   r;   r     s   z'DiskObjectStore.add_pack.<locals>.abortr   )r~  r  r  r  r  r  rk  )r:   r~  r  r   r   r8   r  r;   r<     s   
zDiskObjectStore.add_packc                 C   s   |  |j}tj|}zt| W n	 ty   Y nw tj|r%dS t|dt	d}|
|j| jd W d   dS 1 sBw   Y  dS )z^Add a single object to this object store.

        Args:
          obj: Object to add
        Nr9  r^  )r   )rK  r   r  rx   dirnamer:  r;  existsr   rk  r   as_legacy_objectr!  )r:   rk   rx   ry  r   r8   r8   r;   ri     s   "zDiskObjectStore.add_objectc                 C   sR   zt | W n	 ty   Y nw t t j|d t t j|t | |S )Nr2   )r  r:  r;  rx   r  r  )r)  rx   r8   r8   r;   init   s   zDiskObjectStore.initc           
      #   sZ   t |dk rt |E d H  d S t }|d d  }|dd   }z(ttj| j|D ]}|	|rKt
|| }||vrK|| |V  q1W n	 tyV   Y nw | jD ]6}t |d dkrit|nt|d d }|j|D ]}t|}|	|r||vr|| |V  qxqZ| jD ]}	|	|D ]}||vr|| |V  qqd S )Nr~   r   r   )r   r  r   r   r(  r  rD  rx   r  r   r7  r   r2  r[   binascii	unhexlifyrS  r   r   )
r:   r   seenry  rM  r`   rG   r   
bin_prefixr   r"  r8   r;   r   
  sN   






zDiskObjectStore.iter_prefix)r   r   r   r   )r>   r?   r@   r   r   r  r&  classmethodr,  r   r   r-  r@  r   rK  r   r   r   r   r[  rw  r  r<   ri   r  r   __classcell__r8   r8   r"  r;   r    s6    





	

>
 
	r  c                       s   e Zd ZdZd# fddZdd Zdd	 Zdefd
dZdd Z	e
dd ZdefddZdefddZdeddfddZd#ddZd$d#ddZdd Z	d$dedee ddfdd Zd$d#d!d"Z  ZS )%MemoryObjectStorez.Object store that keeps all objects in memory.r6   Nc                    s   t    i | _d| _d S )Nr   )r  r   _datar   r9   r"  r8   r;   r   0  s   

zMemoryObjectStore.__init__c                 C   s2   t |dkr|S t |dkrt|S td|)Nr  r  zInvalid sha )r   r   
ValueErrorrT   r8   r8   r;   
_to_hexsha5  s
   zMemoryObjectStore._to_hexshac                 C   s   |  || jv S rQ   )r  r  rT   r8   r8   r;   rS   =  s   z MemoryObjectStore.contains_loosec                 C   r7   )z>Check if a particular object is present by SHA1 and is packed.Fr8   rT   r8   r8   r;   r   A  r   z!MemoryObjectStore.contains_packedc                 C   s   t | j S re   )r   r  keysr9   r8   r8   r;   rg   E  s   zMemoryObjectStore.__iter__c                 C   r   r   r8   r9   r8   r8   r;   r[   I  r\   zMemoryObjectStore.packsr`   c                 C   s   | |  | }|j| fS r]   )r  rb   r  )r:   r`   rk   r8   r8   r;   r^   N  s   zMemoryObjectStore.get_rawc                 C   s   | j | |  S r   )r  r  copyr_   r8   r8   r;   rd   X  rO  zMemoryObjectStore.__getitem__c                 C   s   | j | |= dS )z3Delete an object from this store, for testing only.N)r  r  r_   r8   r8   r;   __delitem__[  s   zMemoryObjectStore.__delitem__c                 C   s   |  | j|j< dS )rh   N)r  r  r   rj   r8   r8   r;   ri   _  s   zMemoryObjectStore.add_objectc                 C   s   |D ]	\}}|  | qdS )rl   N)ri   )r:   ro   rp   rk   rx   r8   r8   r;   rm   c  s   zMemoryObjectStore.add_objectsc                    s@   ddl m} |tdd d fdd}d fd	d
} ||fS )a  Add a new pack to this object store.

        Because this object store doesn't support packs, we extract and add the
        individual objects.

        Returns: Fileobject to write to and a commit function to
            call when the pack is finished.
        r   )SpooledTemporaryFile	incoming-max_sizer   r6   Nc                     s\      } | dkr( d t | }t|jD ]}| q|  d S    d S )Nr   )	r  r  r   	from_filer$   r  r^   ri   r   )sizer   rk   r   r:   r8   r;   r   y  s   
z*MemoryObjectStore.add_pack.<locals>.commitc                      s       d S r   )r   r8   )r   r8   r;   r     r   z)MemoryObjectStore.add_pack.<locals>.abortr   )r~  r  r   )r:   r  r   r   r8   r  r;   r<   l  s
   	
zMemoryObjectStore.add_packr   r   c                 C   s   |D ]	}|  |  qdS )r   N)ri   sha_file)r:   r   r   rp   unpacked_objectr8   r8   r;   r     s   	zMemoryObjectStore.add_pack_datac                 C   sH   |   \}}}zt|||}|  W n ty   |   w |  dS )a  Add a new thin pack to this object store.

        Thin packs are packs that contain deltas with parents that exist
        outside the pack. Because this object store doesn't support packs, we
        extract and add the individual objects.

        Args:
          read_all: Read function that blocks until the number of
            requested bytes are read.
          read_some: Read function that returns at least one byte, but may
            not return the number of bytes requested.
        N)r<   r%   r  r   )r:   r  r  rp   r   r   r   r  r8   r8   r;   r    s   
zMemoryObjectStore.add_thin_packr   r   )r>   r?   r@   r   r   r  rS   r   r   rg   r   r[   r   r^   rd   r  ri   rm   r<   r   r   r&   r   r  r  r8   r8   r"  r;   r  -  s0    


	
r  c                   @   s"   e Zd ZdZdee fddZdS )ObjectIteratorz%Interface for iterating over objects.r6   c                 C   rP   r   )rR   r   r9   r8   r8   r;   r     r   zObjectIterator.iterobjectsN)r>   r?   r@   r   r   r   r   r8   r8   r8   r;   r    s    r  c                 C   s&   | |}t |tst||| |S )zLook up an object in a Git tree.

    Args:
      lookup_obj: Callback for retrieving object by SHA1
      root_sha: SHA1 of the root tree
      path: Path to lookup
    Returns: A tuple of (mode, SHA) of the resulting path.
    )r   r   r   lookup_path)
lookup_objroot_sharx   treer8   r8   r;   tree_lookup_path  s   	
r  	obj_storetree_shaksetr6   c                 C   s^   | | }t |tsJ | D ]\}}}t|s,||vr,|| t|r,t| || qdS )zCollect SHA1s of files and directories for specified tree.

    Args:
      obj_store: Object store to get objects by SHA from
      tree_sha: tree reference to walk
      kset: set to fill with references to files and directories
    N)r   r   	iteritemsr   r   statS_ISDIR_collect_filetree_revs)r  r  r  filetreer`   rz   rG   r8   r8   r;   r    s   


r  Fignore_unknownc             	   C   s   t  }t  }t  }|D ]L}z| | }W n ty   |s Y qw t|tr+|| qt|trR|| |jd }t| |g|d\}	}
}||	O }||
O }||O }q|| q|||fS )a4  Split object id list into three lists with commit, tag, and other SHAs.

    Commits referenced by tags are included into commits
    list as well. Only SHA1s known in this repository will get
    through, and unless ignore_unknown argument is True, KeyError
    is thrown for SHA1 missing in the repository

    Args:
      obj_store: Object store to get objects by SHA1 from
      lst: Collection of commit and tag SHAs
      ignore_unknown: True to skip SHA1 missing in the repository
        silently.
    Returns: A tuple of (commits, tags, others) SHA1s
    r   r  )r   r   r   r   r   r   r   _split_commits_and_tags)r  lstr  commitstagsothersr   r  taggedctr  r8   r8   r;   r    s0   





r  c                   @   s   e Zd ZdZddddd d	dddZd	d
 Zdeeee	e
 e	e ef  ddfddZdee
e	e f fddZdd ZdS )r   a1  Find the objects missing from another object store.

    Args:
      object_store: Object store containing at least all objects to be
        sent
      haves: SHA1s of commits not to send (already present in target)
      wants: SHA1s of commits to send
      progress: Optional function to report progress to.
      get_tagged: Function that returns a dict of pointed-to sha -> tag
        sha for including tags.
      get_parents: Optional function for getting the parents of a commit.
      tagged: dict of pointed-to sha -> tag sha for including tags
    Nc                 C   r   r   r   r   r8   r8   r;   r     r   zMissingObjectFinder.<lambda>)r   rp   r   r   r6   c                C   sF  || _ |d u r
t }|| _t||dd\}}	}
t||dd\}}}t|||| jdd }t||||| jd\}}t | _|D ]}| j| || }t||j| j q>|	D ]}| j| qUt| j| _	dd |D | _
||	}| j
dd |D  ||
}| j
d	d |D  |d u rd
d | _n|| _|r| pi | _d S )NTr  F)r   r   r   c                 S      h | ]	}|d t jdfqS NF)r   rb   rK   wr8   r8   r;   r   K      z/MissingObjectFinder.__init__.<locals>.<setcomp>c                 S   r  r  )r   rb   r  r8   r8   r;   r   N  r  c                 S   s   h | ]}|d d dfqS r  r8   r  r8   r8   r;   r   Q  s    c                 S      d S r   r8   )xr8   r8   r;   r   T  r=   z.MissingObjectFinder.__init__.<locals>.<lambda>)object_storer   _get_parentsr  _collect_ancestorsr   r   r  r  sha_doneobjects_to_send
differencer   rp   _tagged)r:   r  r   r   r   rp   r   r   have_commits	have_tagshave_otherswant_commits	want_tagswant_othersall_ancestorsmissing_commitscommon_commitshr   r  missing_tagsmissing_othersr8   r8   r;   r     sT   



zMissingObjectFinder.__init__c                 C   r   r   )r   r9   r8   r8   r;   r   Y  s   z"MissingObjectFinder.get_remote_hasrY  c                    s    j  fdd|D  d S )Nc                    s   g | ]}|d   j vr|qS )r   )r  )rK   r   r9   r8   r;   rM   _  s    z0MissingObjectFinder.add_todo.<locals>.<listcomp>)r  r   )r:   rY  r8   r9   r;   add_todo\  s   zMissingObjectFinder.add_todoc                 C   sP  	 | j s| dt| j dd t| j  \}}}}|| jvr$nq|sf| j| }t|t	r>| 
|jdtjdfg n(t|trP| 
dd | D  nt|trf| 
|jd	 d |jd
 jdfg || jv rx| 
| j| d d dfg | j| t| jd d
kr| dt| j dd |d u rd }||fS ||f}||fS )NTzcounting objects: z, done.
rX      Fc                 S   s@   g | ]\}}}t |s||t|rtjntjt| fqS r8   )r   r  S_ISREGr   rb   r   r  )rK   nmsr8   r8   r;   rM   q  s    
z0MissingObjectFinder.__next__.<locals>.<listcomp>r   r   i  r]  )r  rp   r   r  ra  StopIterationr   r  r   r   r  r  r   rb   r  r   r   r  r   )r:   rG   r`   rb   leafr  	pack_hintr8   r8   r;   __next__a  s@   
	



"
zMissingObjectFinder.__next__c                 C   s   | S r   r8   r9   r8   r8   r;   rg        zMissingObjectFinder.__iter__r   )r>   r?   r@   r   r   r   r   rA   r   r   r   r   r   r  r"   r  rg   r8   r8   r8   r;   r     s"    

I
(r   c                   @   s   e Zd ZU dZee ed< 	 eegef ed< 	 ee ed< 	ddee de	ee  ddfdd	Z
dd
dZdeddfddZdd ZeZdS )ObjectStoreGraphWalkerzFGraph walker that finds what commits are missing from an object store.headsr   r   Nlocal_headsr6   c                 C   s.   t || _|| _i | _|du rt  }|| _dS )zCreate a new instance.

        Args:
          local_heads: Heads to start search with
          get_parents: Function for finding the parents of a SHA1.
        N)r   r  r   r   r   )r:   r  r   r   r8   r8   r;   r     s   

zObjectStoreGraphWalker.__init__c                 C   r7   )zNothing in common was found.Nr8   r9   r8   r8   r;   nak  r=   zObjectStoreGraphWalker.nakrG   c                 C   s   t |dkrtd|d|h}| jrK|D ]}|| jv r#| j| qt }|D ]}| j|}|dur:|| d| j|< q)|sDdS |}| jsdS dS )z@Ack that a revision and its ancestors are present in the source.r  zunexpected sha z	 receivedN)r   r  r  r  r   r   r   r   )r:   rG   	ancestorsanew_ancestorspsr8   r8   r;   r     s$   

zObjectStoreGraphWalker.ackc                    s`    j r. j  }z |}W n
 ty   Y dS w | j|<  j  fdd|D  |S dS )z.Iterate over ancestors of heads in the target.Nc                    s   g | ]	}| j vr|qS r8   r   r   r9   r8   r;   rM     r  z/ObjectStoreGraphWalker.next.<locals>.<listcomp>)r  r   r   r   r   r   )r:   r
  r  r8   r9   r;   r     s   

zObjectStoreGraphWalker.nextr   r   )r>   r?   r@   r   r   r   __annotations__r   r   r   r   r  r   r   r  r8   r8   r8   r;   r    s&   
 


r  c              	   C   s   i }|D ]3\}}}z
| dd\}}W n ty*   |du r"||= n||f||< Y qw ||g |||f q| D ]3\}	}
z
| ||	 d  }W n tyV   t }Y nw t| ||
}t|dkrg||	= q<t	j
|jf||	< q<| | |S )a  Commit a specified set of changes to a tree structure.

    This will apply a set of changes on top of an existing tree, storing new
    objects in object_store.

    changes are a list of tuples with (path, mode, object_sha).
    Paths can be both blobs and trees. See the mode and
    object sha to None deletes the path.

    This method works especially well if there are only a small
    number of changes to a big tree. For a large number of changes
    to a large tree, use e.g. commit_tree.

    Args:
      object_store: Object store to store new objects in
        and retrieve old ones from.
      tree: Original tree root
      changes: changes to apply
    Returns: New tree root object
       /r   Nr   )splitr  
setdefaultr   rN   r   r   commit_tree_changesr   r  S_IFDIRr   ri   )r  r  changesnested_changesrx   new_modenew_shar  subpathr`   
subchangesorig_subtreesubtreer8   r8   r;   r    s.   

r  c                   @   s   e Zd ZdZddddZdd Zddd	Zed
d Zdd Z	ddde
e dedee fddZddddde
e dedee fddZdd ZdefddZdefddZdS ) OverlayObjectStorez5Object store that can overlay multiple object stores.Nr6   c                 C   s   || _ || _d S r   )bases	add_store)r:   r  r  r8   r8   r;   r     r   zOverlayObjectStore.__init__c                 C   s    | j d u r
t| j| j |S r   )r  rR   ri   )r:   r   r8   r8   r;   ri     s   

zOverlayObjectStore.add_objectc                 C   s"   | j d u r
t| j| j ||S r   )r  rR   ri   rm   rn   r8   r8   r;   rm     s   

zOverlayObjectStore.add_objectsc                 C   s    g }| j D ]}||j q|S r   )r  r   r[   )r:   r
  br8   r8   r;   r[     s   
zOverlayObjectStore.packsc                 c   s:    t  }| jD ]}|D ]}||vr|V  || qqd S r   )r   r  r   )r:   doner  o_idr8   r8   r;   rg      s   

zOverlayObjectStore.__iter__Fr   r   r   c                c   sV    t |}| jD ]}|j|ddD ]}|V  ||j qq|r'|s)t|jd S d S r  )r   r  r   r  r   r   )r:   r   r   r  r  r  r8   r8   r;   r   (  s   

z%OverlayObjectStore.iterobjects_subsetTr  c                c   sZ    t |}| jD ]}|j||d|dD ]}|V  ||j qq|r)|s+t|jd S d S r  )r   r  r  r  r   r   )r:   r   r  r   r  r  r  r  r8   r8   r;   r  3  s   


z'OverlayObjectStore.iter_unpacked_subsetc              	   C   s6   | j D ]}z||W   S  ty   Y qw t|r   )r  r^   r   )r:   sha_idr  r8   r8   r;   r^   H  s   
zOverlayObjectStore.get_rawc                 C       | j D ]
}||r dS qdS NTF)r  r   r:   rG   r  r8   r8   r;   r   P  
   

z"OverlayObjectStore.contains_packedc                 C   r  r  )r  rS   r  r8   r8   r;   rS   V  r  z!OverlayObjectStore.contains_looser   r   )r>   r?   r@   r   r   ri   rm   r   r[   rg   r   r   r   r   r   r   r  r^   r   rS   r8   r8   r8   r;   r    s:    

	

r  c                 c   sD    |    D ]}|sq|dd\}}|dkrqt|V  qdS )z'Yield the packs listed in a packs file.    r      PN)r=  
splitlinesr  r  r6  )r   r8  kindr`   r8   r8   r;   read_packs_file]  s   r
  c                   @   sp   e Zd ZdZdd ZdddZddd	Zdd
dZdee	 fddZ
defddZdd ZdddZdd ZdS )BucketBasedObjectStorezHObject store implementation that uses a bucket store like S3 as backend.c                 C   s   t g S r   )r   r9   r8   r8   r;   r   k  s   z*BucketBasedObjectStore._iter_loose_objectsr6   Nc                 C   r  r   r8   rT   r8   r8   r;   r   o  r  z(BucketBasedObjectStore._get_loose_objectc                 C   r  r   r8   rT   r8   r8   r;   r   r  r   z+BucketBasedObjectStore._remove_loose_objectc                 C   rP   r   r   r_   r8   r8   r;   r   v  r   z#BucketBasedObjectStore._remove_packc                 C   rP   r   )rR   _iter_pack_namesr9   r8   r8   r;   r  y  r   z'BucketBasedObjectStore._iter_pack_namesc                 C   rP   r   )rR   	_get_packr_   r8   r8   r;   r  |  r   z BucketBasedObjectStore._get_packc                 C   sj   t |  }g }|D ]}|| jvr | |}|| || j|< q
t | j| D ]
}| j|  q(|S r   )r   r  r   r  r   r   r   )r:   rG  rJ  r   r3   r8   r8   r;   r     s   



z)BucketBasedObjectStore._update_pack_cachec                 C   rY   r   rZ   )r:   rP  	pack_fileru  r8   r8   r;   _upload_pack  r  z#BucketBasedObjectStore._upload_packc                    s2   ddl jtdd  fdd} | jfS )r  r   Nr  r  c                     s      dkr   d S  d t j } |  }tdd |D d}jt	dd}| 
 }t||| |d t|d |}jD ]}|
 | 
 kr]|   |  |  S qG d |d | | t| |}|| |S )Nr   c                 s   rT  rU  r8   rV  r8   r8   r;   r     r   zBBucketBasedObjectStore.add_pack.<locals>.commit.<locals>.<genexpr>rX  r  r  rC  )r  r   r  r   r`   sorted_entriesr*   r(  r  r   get_stored_checksumr.   r+   r[   r  r   from_objectsr   )r   rY  rP  idxfchecksumidxr3   rv  pfr:   r~  r8   r;   r     s4   




z/BucketBasedObjectStore.add_pack.<locals>.commit)r~  r  r   r   )r:   r   r8   r  r;   r<     s   zBucketBasedObjectStore.add_packr   )r>   r?   r@   r   r   r   r   r   r   r  r  r   r  r   r  r<   r8   r8   r8   r;   r  h  s    



r  c                 C   r   r   r   r   r8   r8   r;   r     r   r   storecommonr   c           
      C   sz   t  }t  }g }|| |r9|d}||v r|| n||vr7|| ||v r,q| | }	|||	 |s||fS )a  Collect all ancestors of heads up to (excluding) those in common.

    Args:
      heads: commits to start from
      common: commits to end at, or empty set to walk repository
        completely
      get_parents: Optional function for getting the parents of a
        commit.
    Returns: a tuple (A, B) where A - all commits reachable
        from heads but not present in common, B - common (shared) elements
        that are directly reachable from heads
    r   )r   r   r   r   )
r  r  r  r   r   r  r  r   r   r   r8   r8   r;   r    s    



r  r   r   rs   c                c   s    |du rdS t dtj|g}|rQ| }t|jrBg }| |j }t|ts)J |j	ddD ]}|
||j q/|t| t|jrJ|rM|V  |sdS dS )a;  Iterate the contents of a tree and all subtrees.

    Iteration is depth-first pre-order, as in e.g. os.walk.

    Args:
      tree_id: SHA1 of the tree.
      include_trees: If True, include tree objects in the iteration.
    Returns: Iterator over TreeEntry namedtuples for all the objects in a
        tree.
    Nr  T)
name_order)r   r  r  r   r  rz   rG   r   r   r  r   in_pathrx   r   reversed)r  r   rs   r  rW  extrar  subentryr8   r8   r;   r     s    
r   rG   c                 C   sN   | |  }}t |j}|tu r#t|tsJ |j\}}| | }|tu s||fS )a  Peel all tags from a SHA.

    Args:
      sha: The object SHA to peel.
    Returns: The fully-peeled SHA1 of a tag object, after peeling all
        intermediate tags; if the original ref does not point to a tag,
        this will equal the original SHA1.
    )r   	type_namer   r   r   )r  rG   unpeeledrk   	obj_classr8   r8   r;   r      s   	

r   )Zr   r  r  r  rh  r   collections.abcr   r   r   
contextlibr   ior   typingr   r   r	   r
   errorsr   filer   ro   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r3   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   protocolr/   rC   r0   r1   r1  r  ri  rk  r5   rB   r   r  r  r  r  r   r  rA   r   r  r   r  r  r  r
  r  	frozensetr  r   r   r   r8   r8   r8   r;   <module>   s   @T    j  W 

+ K0UX
%
"