U
    +-e0                  
   @   s~  d Z ddlZddlmZmZ ddlmZ ddlmZm	Z	m
Z
mZmZmZmZ ddlmZmZ ddlmZ dd	lmZ dd
lmZ erddlmZ G dd deZdZdZdZdZdZ ej!dej"dZ#ed(e	eeef  e$e$ee
e
e  e
e
e  f dddZ%eG dd dZ&eG dd dZ'de(e(ee( e'ee( ee( edd d!Z)e(ee( e'e(d"d#d$Z*e(ee( d%d&d'Z+dS ))zLContains utilities to multi-commits (i.e. push changes iteratively on a PR).    N)	dataclassfield)sha256)TYPE_CHECKINGIterableListOptionalSetTupleUnion   )CommitOperationAddCommitOperationDelete)DiscussionWithDetails)experimental)_format_size)HfApic                   @   s   e Zd ZdZdS )MultiCommitExceptionzFBase exception for any exception happening while doing a multi-commit.N)__name__
__module____qualname____doc__ r   r   _/var/www/html/Darija-Ai-Train/env/lib/python3.8/site-packages/huggingface_hub/_multi_commits.pyr      s   r   a  
## {commit_message}

{commit_description}

**Multi commit ID:** {multi_commit_id}

Scheduled commits:

{multi_commit_strategy}

_This is a PR opened using the `huggingface_hub` library in the context of a multi-commit. PR can be commented as a usual PR. However, please be aware that manually updating the PR description, changing the PR status, or pushing new commits, is not recommended as it might corrupt the commit process. Learn more about multi-commits [in this guide](https://huggingface.co/docs/huggingface_hub/main/guides/upload)._
am  
Multi-commit is now completed! You can ping the repo owner to review the changes. This PR can now be commented or modified without risking to corrupt it.

_This is a comment posted using the `huggingface_hub` library in the context of a multi-commit. Learn more about multi-commits [in this guide](https://huggingface.co/docs/huggingface_hub/main/guides/upload)._
a  
`create_pr=False` has been passed so PR is automatically merged.

_This is a comment posted using the `huggingface_hub` library in the context of a multi-commit. Learn more about multi-commits [in this guide](https://huggingface.co/docs/huggingface_hub/main/guides/upload)._
a2  
Cannot merge Pull Requests as no changes are associated. This PR will be closed automatically.

_This is a comment posted using the `huggingface_hub` library in the context of a multi-commit. Learn more about multi-commits [in this guide](https://huggingface.co/docs/huggingface_hub/main/guides/upload)._
a   
An error occurred while trying to merge the Pull Request: `{error_message}`.

_This is a comment posted using the `huggingface_hub` library in the context of a multi-commit. Learn more about multi-commits [in this guide](https://huggingface.co/docs/huggingface_hub/main/guides/upload)._
z8- \[(?P<completed>[ |x])\].*(?P<step_id>[a-fA-F0-9]{64}))flags2           )
operationsmax_operations_per_commitmax_upload_size_per_commitreturnc           	      C   s   g }g }g }d}g }| D ]}t |trL|| t||kr|| g }nZ|jj|krf||g n@||jj |k r|| ||jj7 }n|| |g}|jj}t||kr|| g }d}qt|dkr|| t|dkr|| ||fS )a(
  Split a list of operations in a list of commits to perform.

    Implementation follows a sub-optimal (yet simple) algorithm:
    1. Delete operations are grouped together by commits of maximum `max_operations_per_commits` operations.
    2. All additions exceeding `max_upload_size_per_commit` are committed 1 by 1.
    3. All remaining additions are grouped together and split each time the `max_operations_per_commit` or the
       `max_upload_size_per_commit` limit is reached.

    We do not try to optimize the splitting to get the lowest number of commits as this is a NP-hard problem (see
    [bin packing problem](https://en.wikipedia.org/wiki/Bin_packing_problem)). For our use case, it is not problematic
    to use a sub-optimal solution so we favored an easy-to-explain implementation.

    Args:
        operations (`List` of [`~hf_api.CommitOperation`]):
            The list of operations to split into commits.
        max_operations_per_commit (`int`):
            Maximum number of operations in a single commit. Defaults to 50.
        max_upload_size_per_commit (`int`):
            Maximum size to upload (in bytes) in a single commit. Defaults to 2GB. Files bigger than this limit are
            uploaded, 1 per commit.

    Returns:
        `Tuple[List[List[CommitOperationAdd]], List[List[CommitOperationDelete]]]`: a tuple. First item is a list of
        lists of [`CommitOperationAdd`] representing the addition commits to push. The second item is a list of lists
        of [`CommitOperationDelete`] representing the deletion commits.

    <Tip warning={true}>

    `plan_multi_commits` is experimental. Its API and behavior is subject to change in the future without prior notice.

    </Tip>

    Example:
    ```python
    >>> from huggingface_hub import HfApi, plan_multi_commits
    >>> addition_commits, deletion_commits = plan_multi_commits(
    ...     operations=[
    ...          CommitOperationAdd(...),
    ...          CommitOperationAdd(...),
    ...          CommitOperationDelete(...),
    ...          CommitOperationDelete(...),
    ...          CommitOperationAdd(...),
    ...     ],
    ... )
    >>> HfApi().create_commits_on_pr(
    ...     repo_id="my-cool-model",
    ...     addition_commits=addition_commits,
    ...     deletion_commits=deletion_commits,
    ...     (...)
    ...     verbose=True,
    ... )
    ```

    <Tip warning={true}>

    The initial order of the operations is not guaranteed! All deletions will be performed before additions. If you are
    not updating multiple times the same file, you are fine.

    </Tip>
    r   )
isinstancer   appendlenupload_infosize)	r   r   r   addition_commitsdeletion_commits	additionsZadditions_sizeZ	deletionsopr   r   r   plan_multi_commitsM   s8    B







r*   c                   @   s`   e Zd ZU dZeeeef  ed< e	ddZ
eed< dZeed< ddd	d
ZedddZdS )MultiCommitStepaU  Dataclass containing a list of CommitOperation to commit at once.

    A [`MultiCommitStep`] is one atomic part of a [`MultiCommitStrategy`]. Each step is identified by its own
    deterministic ID based on the list of commit operations (hexadecimal sha256). ID is persistent between re-runs if
    the list of commits is kept the same.
    r   Finitid	completedNr    c                 C   s   t | jdkrtdt }| jD ]x}t|trZ|d ||j  ||j	j q"t|t
r|d ||j  |t|j  q"t  q"| | _d S )Nr   z?A MultiCommitStep must have at least 1 commit operation, got 0.s   ADDs   DELETE)r#   r   
ValueErrorr   r!   r   updateZpath_in_repoencoder$   r   str	is_folderNotImplementedError	hexdigestr.   )selfshar)   r   r   r   __post_init__   s    




zMultiCommitStep.__post_init__c              	   C   s   dd | j D }dd | j D }dd | j D }t|dkr|d| jrHdnd d	t| d
ttdd |D  d| j d	S d| jrdnd dt| dt| d| j d	S dS )zFormat a step for PR description.

        Formatting can be changed in the future as long as it is single line, starts with `- [ ]`/`- [x]` and contains
        `self.id`. Must be able to match `STEP_ID_REGEX`.
        c                 S   s   g | ]}t |tr|qS r   )r!   r   .0r)   r   r   r   
<listcomp>   s     
 z+MultiCommitStep.__str__.<locals>.<listcomp>c                 S   s    g | ]}t |tr|js|qS r   r!   r   r5   r;   r   r   r   r=      s     
  c                 S   s    g | ]}t |tr|jr|qS r   r>   r;   r   r   r   r=      s     
  r   z- [x z	] Upload z file(s) totalling c                 s   s   | ]}|j jV  qd S N)r$   r%   )r<   addr   r   r   	<genexpr>   s     z*MultiCommitStep.__str__.<locals>.<genexpr>z ()z	] Delete z file(s) and z folder(s) (N)r   r#   r/   r   sumr.   )r8   r(   Zfile_deletionsZfolder_deletionsr   r   r   __str__   s    >0zMultiCommitStep.__str__)r   r   r   r   r   r   r   r   __annotations__r   r.   r4   r/   boolr:   rF   r   r   r   r   r+      s   
r+   c                   @   s`   e Zd ZU dZee ed< ee ed< eddZe	ed< eddZ
ee	 ed< dd	d
dZdS )MultiCommitStrategya  Dataclass containing a list of [`MultiCommitStep`] to commit iteratively.

    A strategy is identified by its own deterministic ID based on the list of its steps (hexadecimal sha256). ID is
    persistent between re-runs if the list of commits is kept the same.
    r&   r'   Fr,   r.   	all_stepsNr0   c                 C   s   dd | j | j D | _t| jt| j t| j k r>tdt| jdkrTtdt }| j | j D ]"}|d  ||j  qf|	 | _d S )Nc                 S   s   h | ]
}|j qS r   )r.   )r<   stepr   r   r   	<setcomp>   s     z4MultiCommitStrategy.__post_init__.<locals>.<setcomp>zIGot duplicate commits in MultiCommitStrategy. All commits must be unique.r   z9A MultiCommitStrategy must have at least 1 commit, got 0.znew step)
r&   r'   rJ   r#   r1   r   r2   r3   r.   r7   )r8   r9   rK   r   r   r   r:      s    z!MultiCommitStrategy.__post_init__)r   r   r   r   r   r+   rG   r   r.   r4   rJ   r	   r:   r   r   r   r   rI      s   
rI   r   )apirepo_idcommit_messagecommit_descriptionstrategytoken	repo_typer    c                 C   s.   | j |d| d|j dt|||d||dS )Nz[WIP] z (multi-commit rD   rO   rP   rQ   )rN   titledescriptionrR   rS   )Zcreate_pull_requestr.   multi_commit_generate_comment)rM   rN   rO   rP   rQ   rR   rS   r   r   r    multi_commit_create_pull_request  s    	  rX   )rO   rP   rQ   r    c              	   C   s0   t j| |pd|jddd |j|j D dS )N 
c                 s   s   | ]}t |V  qd S rA   )r4   )r<   commitr   r   r   rC   *  s    z0multi_commit_generate_comment.<locals>.<genexpr>)rO   rP   Zmulti_commit_idZmulti_commit_strategy)$MULTI_COMMIT_PR_DESCRIPTION_TEMPLATEformatr.   joinr'   r&   rT   r   r   r   rW   !  s    

rW   )rV   r    c                 C   s   dd t | D S )Nc                 S   s   h | ]}|d  qS )r   r   )r<   matchr   r   r   rL   1  s     z4multi_commit_parse_pr_description.<locals>.<setcomp>)STEP_ID_REGEXfindall)rV   r   r   r   !multi_commit_parse_pr_description0  s    rb   )r   r   ),r   redataclassesr   r   hashlibr   typingr   r   r   r   r	   r
   r   Z_commit_apir   r   Z	communityr   utilsr   Zutils._cache_managerr   Zhf_apir   	Exceptionr   r\   Z+MULTI_COMMIT_PR_COMPLETION_COMMENT_TEMPLATEZ(MULTI_COMMIT_PR_CLOSING_COMMENT_TEMPLATEZ9MULTI_COMMIT_PR_CLOSE_COMMENT_FAILURE_NO_CHANGES_TEMPLATEZ:MULTI_COMMIT_PR_CLOSE_COMMENT_FAILURE_BAD_REQUEST_TEMPLATEcompile	MULTILINEr`   intr*   r+   rI   r4   rX   rW   rb   r   r   r   r   <module>   sZ   $  j6