ó
    pyüiÿ€  ã                   óÖ  • S r SSKrSSKrSSKJr  SSKJr  SSKJr  SSK	J
r
  SSKJrJr  SS	KJr  S
SKJr  S
SKJr  S
SKJr  \R,                  " \5      r\
S   rS/r\" SS9 " S S5      5       r\" SS9 " S S5      5       r\" SS9 " S S5      5       r\" SS9 " S S5      5       r\" SS9 " S S5      5       rS&S\ \-  S-  S\4S jjr!S\S\4S  jr"S!\#S\ 4S" jr$S#\S$\ SS4S% jr%g)'z4Contains utilities to manage the HF cache directory.é    N)Údefaultdict)Ú	dataclass)ÚPath)ÚLiteral)ÚCacheNotFoundÚCorruptedCacheExceptioné   )ÚHF_HUB_CACHEé   )Úlogging)Úformat_timesince)Útabulate)ÚmodelÚdatasetÚspacez	.DS_StoreT)Úfrozenc                   óž   • \ rS rSr% Sr\\S'   \\S'   \\S'   \\S'   \	\S'   \	\S'   \
S	\4S
 j5       r\
S	\4S j5       r\
S	\4S j5       rSrg)ÚCachedFileInfoé'   a¢  Frozen data structure holding information about a single cached file.

Args:
    file_name (`str`):
        Name of the file. Example: `config.json`.
    file_path (`Path`):
        Path of the file in the `snapshots` directory. The file path is a symlink
        referring to a blob in the `blobs` folder.
    blob_path (`Path`):
        Path of the blob file. This is equivalent to `file_path.resolve()`.
    size_on_disk (`int`):
        Size of the blob file in bytes.
    blob_last_accessed (`float`):
        Timestamp of the last time the blob file has been accessed (from any
        revision).
    blob_last_modified (`float`):
        Timestamp of the last time the blob file has been modified/created.

> [!WARNING]
> `blob_last_accessed` and `blob_last_modified` reliability can depend on the OS you
> are using. See [python documentation](https://docs.python.org/3/library/os.html#os.stat_result)
> for more details.
Ú	file_nameÚ	file_pathÚ	blob_pathÚsize_on_diskÚblob_last_accessedÚblob_last_modifiedÚreturnc                 ó,   • [        U R                  5      $ )zš
(property) Timestamp of the last time the blob file has been accessed (from any
revision), returned as a human-readable string.

Example: "2 weeks ago".
)r   r   ©Úselfs    Úa/home/mande/repo/quber/.venv/lib/python3.13/site-packages/huggingface_hub/utils/_cache_manager.pyÚblob_last_accessed_strÚ%CachedFileInfo.blob_last_accessed_strI   ó   € ô   × 7Ñ 7Ó8Ð8ó    c                 ó,   • [        U R                  5      $ )z†
(property) Timestamp of the last time the blob file has been modified, returned
as a human-readable string.

Example: "2 weeks ago".
)r   r   r   s    r    Úblob_last_modified_strÚ%CachedFileInfo.blob_last_modified_strS   r#   r$   c                 ó,   • [        U R                  5      $ )zQ
(property) Size of the blob file as a human-readable string.

Example: "42.2K".
©Ú_format_sizer   r   s    r    Úsize_on_disk_strÚCachedFileInfo.size_on_disk_str]   ó   € ô ˜D×-Ñ-Ó.Ð.r$   © N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__ÚstrÚ__annotations__r   ÚintÚfloatÚpropertyr!   r&   r+   Ú__static_attributes__r.   r$   r    r   r   '   sy   ‡ ñð0 ƒNØƒOØƒOØÓàÓØÓàð9¨ó 9ó ð9ð ð9¨ó 9ó ð9ð ð/ #ó /ó ó/r$   r   c                   óª   • \ rS rSr% Sr\\S'   \\S'   \\S'   \	\
   \S'   \	\   \S'   \\S'   \S	\4S
 j5       r\S	\4S j5       r\S	\4S j5       rSrg)ÚCachedRevisionInfoég   a¾  Frozen data structure holding information about a revision.

A revision correspond to a folder in the `snapshots` folder and is populated with
the exact tree structure as the repo on the Hub but contains only symlinks. A
revision can be either referenced by 1 or more `refs` or be "detached" (no refs).

Args:
    commit_hash (`str`):
        Hash of the revision (unique).
        Example: `"9338f7b671827df886678df2bdd7cc7b4f36dffd"`.
    snapshot_path (`Path`):
        Path to the revision directory in the `snapshots` folder. It contains the
        exact tree structure as the repo on the Hub.
    files: (`frozenset[CachedFileInfo]`):
        Set of [`~CachedFileInfo`] describing all files contained in the snapshot.
    refs (`frozenset[str]`):
        Set of `refs` pointing to this revision. If the revision has no `refs`, it
        is considered detached.
        Example: `{"main", "2.4.0"}` or `{"refs/pr/1"}`.
    size_on_disk (`int`):
        Sum of the blob file sizes that are symlink-ed by the revision.
    last_modified (`float`):
        Timestamp of the last time the revision has been created/modified.

> [!WARNING]
> `last_accessed` cannot be determined correctly on a single revision as blob files
> are shared across revisions.

> [!WARNING]
> `size_on_disk` is not necessarily the sum of all file sizes because of possible
> duplicated files. Besides, only blobs are taken into account, not the (negligible)
> size of folders and symlinks.
Úcommit_hashÚsnapshot_pathr   ÚfilesÚrefsÚlast_modifiedr   c                 ó,   • [        U R                  5      $ )z…
(property) Timestamp of the last time the revision has been modified, returned
as a human-readable string.

Example: "2 weeks ago".
©r   rA   r   s    r    Úlast_modified_strÚ$CachedRevisionInfo.last_modified_str“   ó   € ô   × 2Ñ 2Ó3Ð3r$   c                 ó,   • [        U R                  5      $ ©zV
(property) Sum of the blob file sizes as a human-readable string.

Example: "42.2K".
r)   r   s    r    r+   Ú#CachedRevisionInfo.size_on_disk_str�   r-   r$   c                 ó,   • [        U R                  5      $ )z3
(property) Total number of files in the revision.
)Úlenr?   r   s    r    Únb_filesÚCachedRevisionInfo.nb_files¦   s   € ô
 �4—:‘:‹Ðr$   r.   N)r/   r0   r1   r2   r3   r4   r5   r   r6   Ú	frozensetr   r7   r8   rD   r+   rL   r9   r.   r$   r    r;   r;   g   s†   ‡ ñ ðD ÓØÓØÓØ�^Ñ$Ó$Ø
�C‰.ÓàÓàð4 3ó 4ó ð4ð ð/ #ó /ó ð/ð ð˜#ó ó ór$   r;   c                   óò   • \ rS rSr% Sr\\S'   \\S'   \\S'   \	\S'   \	\S'   \
\   \S'   \\S	'   \\S
'   \S\4S j5       r\S\4S j5       r\S\4S j5       r\S\4S j5       r\S\\\4   4S j5       rSrg)ÚCachedRepoInfoé®   aÞ  Frozen data structure holding information about a cached repository.

Args:
    repo_id (`str`):
        Repo id of the repo on the Hub. Example: `"google/fleurs"`.
    repo_type (`Literal["dataset", "model", "space"]`):
        Type of the cached repo.
    repo_path (`Path`):
        Local path to the cached repo.
    size_on_disk (`int`):
        Sum of the blob file sizes in the cached repo.
    nb_files (`int`):
        Total number of blob files in the cached repo.
    revisions (`frozenset[CachedRevisionInfo]`):
        Set of [`~CachedRevisionInfo`] describing all revisions cached in the repo.
    last_accessed (`float`):
        Timestamp of the last time a blob file of the repo has been accessed.
    last_modified (`float`):
        Timestamp of the last time a blob file of the repo has been modified/created.

> [!WARNING]
> `size_on_disk` is not necessarily the sum of all revisions sizes because of
> duplicated files. Besides, only blobs are taken into account, not the (negligible)
> size of folders and symlinks.

> [!WARNING]
> `last_accessed` and `last_modified` reliability can depend on the OS you are using.
> See [python documentation](https://docs.python.org/3/library/os.html#os.stat_result)
> for more details.
Úrepo_idÚ	repo_typeÚ	repo_pathr   rL   Ú	revisionsÚlast_accessedrA   r   c                 ó,   • [        U R                  5      $ )z
(property) Last time a blob file of the repo has been accessed, returned as a
human-readable string.

Example: "2 weeks ago".
)r   rV   r   s    r    Úlast_accessed_strÚ CachedRepoInfo.last_accessed_strÙ   rF   r$   c                 ó,   • [        U R                  5      $ )z
(property) Last time a blob file of the repo has been modified, returned as a
human-readable string.

Example: "2 weeks ago".
rC   r   s    r    rD   Ú CachedRepoInfo.last_modified_strã   rF   r$   c                 ó,   • [        U R                  5      $ rH   r)   r   s    r    r+   ÚCachedRepoInfo.size_on_disk_strí   r-   r$   c                 ó8   • U R                    SU R                   3$ )z9Canonical `type/id` identifier used across cache tooling.Ú/)rS   rR   r   s    r    Úcache_idÚCachedRepoInfo.cache_idö   s   € ð —.‘.Ð!  4§<¡< .Ð1Ð1r$   c                 ór   • U R                    VVs0 s H  oR                    H  o"U_M     M     snn$ s  snnf )zA
(property) Mapping between `refs` and revision data structures.
)rU   r@   )r   ÚrevisionÚrefs      r    r@   ÚCachedRepoInfo.refsû   s,   € ð
 /3¯nªnÔVªn (ÏÍÀ�X’É‘©nÒVÐVùÓVs   �3r.   N)r/   r0   r1   r2   r3   r4   r5   ÚREPO_TYPE_Tr   r6   rN   r;   r7   r8   rX   rD   r+   r`   Údictr@   r9   r.   r$   r    rP   rP   ®   sÏ   ‡ ñð> ƒLØÓØƒOØÓØƒMØÐ+Ñ,Ó,àÓØÓàð4 3ó 4ó ð4ð ð4 3ó 4ó ð4ð ð/ #ó /ó ð/ð ð2˜#ó 2ó ð2ð ðW�d˜3Ð 2Ð2Ñ3ó Wó óWr$   rP   c                   ó†   • \ rS rSr% Sr\\S'   \\   \S'   \\   \S'   \\   \S'   \\   \S'   \	S\
4S	 j5       rSS jrSrg
)ÚDeleteCacheStrategyi  aš  Frozen data structure holding the strategy to delete cached revisions.

This object is not meant to be instantiated programmatically but to be returned by
[`~utils.HFCacheInfo.delete_revisions`]. See documentation for usage example.

Args:
    expected_freed_size (`float`):
        Expected freed size once strategy is executed.
    blobs (`frozenset[Path]`):
        Set of blob file paths to be deleted.
    refs (`frozenset[Path]`):
        Set of reference file paths to be deleted.
    repos (`frozenset[Path]`):
        Set of entire repo paths to be deleted.
    snapshots (`frozenset[Path]`):
        Set of snapshots to be deleted (directory of symlinks).
Úexpected_freed_sizeÚblobsr@   ÚreposÚ	snapshotsr   c                 ó,   • [        U R                  5      $ )z\
(property) Expected size that will be freed as a human-readable string.

Example: "42.2K".
)r*   rj   r   s    r    Úexpected_freed_size_strÚ+DeleteCacheStrategy.expected_freed_size_str  s   € ô ˜D×4Ñ4Ó5Ð5r$   Nc                 ó2  • U R                    H  n[        USS9  M     U R                   H  n[        USS9  M     U R                   H  n[        USS9  M     U R                   H  n[        USS9  M     [
        R                  SU R                   S35        g)	aJ  Execute the defined strategy.

> [!WARNING]
> If this method is interrupted, the cache might get corrupted. Deletion order is
> implemented so that references and symlinks are deleted before the actual blob
> files.

> [!WARNING]
> This method is irreversible. If executed, cached files are erased and must be
> downloaded again.
Úrepo)Ú	path_typeÚsnapshotrd   ÚblobzCache deletion done. Saved Ú.N)rl   Ú_try_delete_pathrm   r@   rk   ÚloggerÚinforo   )r   Úpaths     r    ÚexecuteÚDeleteCacheStrategy.execute&  s‰   € ð" —J”JˆDÜ˜T¨VÔ4ñ ð —N”NˆDÜ˜T¨ZÔ8ñ #ð —I”IˆDÜ˜T¨UÔ3ñ ð —J”JˆDÜ˜T¨VÔ4ñ ô 	�‰Ð1°$×2NÑ2NÐ1OÈqÐQÕRr$   r.   )r   N)r/   r0   r1   r2   r3   r6   r5   rN   r   r8   r4   ro   r{   r9   r.   r$   r    ri   ri     sV   ‡ ñð$ ÓØ�T‰?ÓØ
�D‰/ÓØ�T‰?ÓØ˜‰Óàð6¨ó 6ó ð6÷ Sr$   ri   c                   óˆ   • \ rS rSr% Sr\\S'   \\   \S'   \	\
   \S'   \S\4S j5       rS\S\4S	 jrS
S.S\S\4S jjrSrg)ÚHFCacheInfoiI  a7  Frozen data structure holding information about the entire cache-system.

This data structure is returned by [`scan_cache_dir`] and is immutable.

Args:
    size_on_disk (`int`):
        Sum of all valid repo sizes in the cache-system.
    repos (`frozenset[CachedRepoInfo]`):
        Set of [`~CachedRepoInfo`] describing all valid cached repos found on the
        cache-system while scanning.
    warnings (`list[CorruptedCacheException]`):
        List of [`~CorruptedCacheException`] that occurred while scanning the cache.
        Those exceptions are captured so that the scan can continue. Corrupted repos
        are skipped from the scan.

> [!WARNING]
> Here `size_on_disk` is equal to the sum of all repo sizes (only blobs). However if
> some cached repos are corrupted, their sizes are not taken into account.
r   rl   Úwarningsr   c                 ó,   • [        U R                  5      $ )zk
(property) Sum of all valid repo sizes in the cache-system as a human-readable
string.

Example: "42.2K".
r)   r   s    r    r+   ÚHFCacheInfo.size_on_disk_strc  s   € ô ˜D×-Ñ-Ó.Ð.r$   rU   c                 óÖ  • [        U5      n[        [         5      nU R                   HV  nUR                   HC  nUR                  U;   d  M  X4   R                  U5        UR                  UR                  5        ME     MX     [        U5      S:”  a'  [        R                  SSR                  U5       35        [        5       n[        5       n[        5       n[        5       n	Sn
UR                  5        GHD  u  p¼UR                  U-
  n[        U5      S:X  a+  UR                  UR                  5        X«R                  -  n
MO  U Hï  nU	R                  UR                  5        UR                   H$  nUR                  UR                  S-  U-  5        M&     UR                    H�  nUR"                  U;  d  M  SnU H=  nUR                    H!  nUR"                  UR"                  :X  d  M  Sn  O   U(       a  M=    O   U(       d  Mc  UR                  UR"                  5        U
UR                  -  n
M�     Mñ     GMG     [%        ['        U5      ['        U5      ['        U5      ['        U	5      U
S9$ )aª  Prepare the strategy to delete one or more revisions cached locally.

Input revisions can be any revision hash. If a revision hash is not found in the
local cache, a warning is thrown but no error is raised. Revisions can be from
different cached repos since hashes are unique across repos,

Examples:
```py
>>> from huggingface_hub import scan_cache_dir
>>> cache_info = scan_cache_dir()
>>> delete_strategy = cache_info.delete_revisions(
...     "81fd1d6e7847c99f5862c9fb81387956d99ec7aa"
... )
>>> print(f"Will free {delete_strategy.expected_freed_size_str}.")
Will free 7.9K.
>>> delete_strategy.execute()
Cache deletion done. Saved 7.9K.
```

```py
>>> from huggingface_hub import scan_cache_dir
>>> scan_cache_dir().delete_revisions(
...     "81fd1d6e7847c99f5862c9fb81387956d99ec7aa",
...     "e2983b237dccf3ab4937c97fa717319a9ca1a96d",
...     "6c0e6080953db56375760c0471a8c5f2929baf11",
... ).execute()
Cache deletion done. Saved 8.6G.
```

> [!WARNING]
> `delete_revisions` returns a [`~utils.DeleteCacheStrategy`] object that needs to
> be executed. The [`~utils.DeleteCacheStrategy`] is not meant to be modified but
> allows having a dry run before actually executing the deletion.
r   z,Revision(s) not found - cannot delete them: ú, r@   TF)rk   r@   rl   rm   rj   )Úsetr   rl   rU   r=   ÚaddÚremoverK   rx   ÚwarningÚjoinÚitemsrT   r   r>   r@   r?   r   ri   rN   )r   rU   Úhashes_to_deleteÚrepos_with_revisionsrr   rc   Údelete_strategy_blobsÚdelete_strategy_refsÚdelete_strategy_reposÚdelete_strategy_snapshotsÚ#delete_strategy_expected_freed_sizeÚaffected_repoÚrevisions_to_deleteÚother_revisionsÚrevision_to_deleterd   ÚfileÚis_file_aloneÚrev_files                      r    Údelete_revisionsÚHFCacheInfo.delete_revisionsm  s1  € ôF &)¨£^ÐäNYÔZ]ÓN^Ðà—J”JˆDØ ŸNœN�Ø×'Ñ'Ð+;Õ;Ø(Ñ.×2Ñ2°8Ô<Ø$×+Ñ+¨H×,@Ñ,@ÖAó +ñ ô ÐÓ  1Ó$Ü�N‰NÐIÈ$Ï)É)ÐTdÓJeÐIfÐgÔhä+.«5ÐÜ*-«%ÐÜ+.«5ÐÜ/2«uÐ!Ø./Ð+à2F×2LÑ2L×2NÑ.ˆMØ+×5Ñ5Ð8KÑKˆOô �?Ó# qÓ(Ø%×)Ñ)¨-×*AÑ*AÔBØ3×7QÑ7QÑQÐ3Ùó ':Ð"à)×-Ñ-Ð.@×.NÑ.NÔOð .×2Ô2�CØ(×,Ñ,¨]×-DÑ-DÀvÑ-MÐPSÑ-SÖTñ 3ð /×4Ô4�DØ—~‘~Ð-BÕBØ(,˜Û(7˜HØ,4¯N¬N Ø#'§>¡>°X×5GÑ5GÕ#GØ49 MÙ$)ñ -;÷ $1 =Ù %ñ )8÷ )˜=Ø1×5Ñ5°d·n±nÔEØ?À4×CTÑCTÑTÒ?ó 5ô ':ñ 3OôL #ÜÐ1Ó2ÜÐ/Ó0ÜÐ1Ó2ÜÐ 9Ó:Ø Cñ
ð 	
r$   r   )Ú	verbosityrš   c                ó  • US:X  a«  [        [        U R                  S S9 Vs/ s H€  nUR                  UR                  UR
                  S UR                  UR                  UR                  SR                  [        UR                  5      5      [        UR                  5      /PM‚     sn/ SQS9$ [        [        U R                  S S9 VVs/ s H�  n[        UR                  S	 S9  H€  nUR                  UR                  UR                  UR
                  S UR                  UR                  SR                  [        UR                  5      5      [        UR                  5      /PM‚     MŸ     snn/ S
QS9$ s  snf s  snnf )a�  Generate a table from the [`HFCacheInfo`] object.

Pass `verbosity=0` to get a table with a single row per repo, with columns
"repo_id", "repo_type", "size_on_disk", "nb_files", "last_accessed", "last_modified", "refs", "local_path".

Pass `verbosity=1` to get a table with a row per repo and revision (thus multiple rows can appear for a single repo), with columns
"repo_id", "repo_type", "revision", "size_on_disk", "nb_files", "last_modified", "refs", "local_path".

Example:
```py
>>> from huggingface_hub.utils import scan_cache_dir

>>> hf_cache_info = scan_cache_dir()
HFCacheInfo(...)

>>> print(hf_cache_info.export_as_table())
REPO ID                                             REPO TYPE SIZE ON DISK NB FILES LAST_ACCESSED LAST_MODIFIED REFS LOCAL PATH
--------------------------------------------------- --------- ------------ -------- ------------- ------------- ---- --------------------------------------------------------------------------------------------------
roberta-base                                        model             2.7M        5 1 day ago     1 week ago    main ~/.cache/huggingface/hub/models--roberta-base
suno/bark                                           model             8.8K        1 1 week ago    1 week ago    main ~/.cache/huggingface/hub/models--suno--bark
t5-base                                             model           893.8M        4 4 days ago    7 months ago  main ~/.cache/huggingface/hub/models--t5-base
t5-large                                            model             3.0G        4 5 weeks ago   5 months ago  main ~/.cache/huggingface/hub/models--t5-large

>>> print(hf_cache_info.export_as_table(verbosity=1))
REPO ID                                             REPO TYPE REVISION                                 SIZE ON DISK NB FILES LAST_MODIFIED REFS LOCAL PATH
--------------------------------------------------- --------- ---------------------------------------- ------------ -------- ------------- ---- -----------------------------------------------------------------------------------------------------------------------------------------------------
roberta-base                                        model     e2da8e2f811d1448a5b465c236feacd80ffbac7b         2.7M        5 1 week ago    main ~/.cache/huggingface/hub/models--roberta-base/snapshots/e2da8e2f811d1448a5b465c236feacd80ffbac7b
suno/bark                                           model     70a8a7d34168586dc5d028fa9666aceade177992         8.8K        1 1 week ago    main ~/.cache/huggingface/hub/models--suno--bark/snapshots/70a8a7d34168586dc5d028fa9666aceade177992
t5-base                                             model     a9723ea7f1b39c1eae772870f3b547bf6ef7e6c1       893.8M        4 7 months ago  main ~/.cache/huggingface/hub/models--t5-base/snapshots/a9723ea7f1b39c1eae772870f3b547bf6ef7e6c1
t5-large                                            model     150ebc2c4b72291e770f58e6057481c8d2ed331a         3.0G        4 5 months ago  main ~/.cache/huggingface/hub/models--t5-large/snapshots/150ebc2c4b72291e770f58e6057481c8d2ed331a
```

Args:
    verbosity (`int`, *optional*):
        The verbosity level. Defaults to 0.

Returns:
    `str`: The table as a string.
r   c                 ó   • U R                   $ ©N©rT   ©rr   s    r    Ú<lambda>Ú-HFCacheInfo.export_as_table.<locals>.<lambda>  ó   € ÀDÇNÂNr$   )Úkeyz>12rƒ   )úREPO IDú	REPO TYPEúSIZE ON DISKúNB FILESÚLAST_ACCESSEDÚLAST_MODIFIEDÚREFSú
LOCAL PATH)ÚrowsÚheadersc                 ó   • U R                   $ r�   rž   rŸ   s    r    r    r¡      r¢   r$   c                 ó   • U R                   $ r�   )r=   )rc   s    r    r    r¡   !  s   € ÐPX×PdÒPdr$   )r¤   r¥   ÚREVISIONr¦   r§   r©   rª   r«   )r   Úsortedrl   rR   rS   r+   rL   rX   rD   rˆ   r@   r4   rT   rU   r=   r>   )r   rš   rr   rc   s       r    Úexport_as_tableÚHFCacheInfo.export_as_tableÑ  sj  € ðP ˜‹>Üô !' t§z¡zÑ7RÒ Sóò !T˜ð Ÿ™ØŸ™Ø×0Ñ0°Ð5ØŸ™Ø×.Ñ.Ø×.Ñ.ØŸ	™	¤&¨¯©Ó"3Ó4Ü˜DŸN™NÓ+ó	ñ !Tñò	ñð ô4 ô !' t§z¡zÑ7RÒ Sôò !T˜Ü$*¨4¯>©>Ñ?dÕ$e˜ð Ÿ™ØŸ™Ø ×,Ñ,Ø#×4Ñ4°SÐ9Ø ×)Ñ)Ø ×2Ñ2ØŸ	™	¤&¨¯©Ó"7Ó8Ü˜H×2Ñ2Ó3ó	ñ %fñ	ñ !Tòò	ñð ùò3ùó4s   £BE<ÃB$F
r.   N)r/   r0   r1   r2   r3   r6   r5   rN   rP   Úlistr   r8   r4   r+   ri   r˜   r²   r9   r.   r$   r    r~   r~   I  sx   ‡ ñð( ÓØ�^Ñ$Ó$ØÐ*Ñ+Ó+àð/ #ó /ó ð/ðb
¨3ð b
Ð3Fô b
ðH 34ò \¨Cð \¸÷ \ð \r$   r~   Ú	cache_dirr   c                 óN  • U c  [         n [        U 5      R                  5       R                  5       n U R	                  5       (       d  [        SU  S3U S9eU R                  5       (       a  [        SU  S35      e[        5       n/ nU R                  5        HB  nUR                  S:X  a  M  UR                  S:X  a  M'   UR                  [        U5      5        MD     [        [!        U5      [#        S U 5       5      US	9$ ! [         a  nUR                  U5         SnAM‹  SnAff = f)
as
  Scan the entire HF cache-system and return a [`~HFCacheInfo`] structure.

Use `scan_cache_dir` in order to programmatically scan your cache-system. The cache
will be scanned repo by repo. If a repo is corrupted, a [`~CorruptedCacheException`]
will be thrown internally but captured and returned in the [`~HFCacheInfo`]
structure. Only valid repos get a proper report.

```py
>>> from huggingface_hub import scan_cache_dir

>>> hf_cache_info = scan_cache_dir()
HFCacheInfo(
    size_on_disk=3398085269,
    repos=frozenset({
        CachedRepoInfo(
            repo_id='t5-small',
            repo_type='model',
            repo_path=PosixPath(...),
            size_on_disk=970726914,
            nb_files=11,
            revisions=frozenset({
                CachedRevisionInfo(
                    commit_hash='d78aea13fa7ecd06c29e3e46195d6341255065d5',
                    size_on_disk=970726339,
                    snapshot_path=PosixPath(...),
                    files=frozenset({
                        CachedFileInfo(
                            file_name='config.json',
                            size_on_disk=1197
                            file_path=PosixPath(...),
                            blob_path=PosixPath(...),
                        ),
                        CachedFileInfo(...),
                        ...
                    }),
                ),
                CachedRevisionInfo(...),
                ...
            }),
        ),
        CachedRepoInfo(...),
        ...
    }),
    warnings=[
        CorruptedCacheException("Snapshots dir doesn't exist in cached repo: ..."),
        CorruptedCacheException(...),
        ...
    ],
)
```

You can also print a detailed report directly from the `hf` command line using:
```text
> hf cache ls
ID                          SIZE     LAST_ACCESSED LAST_MODIFIED REFS
--------------------------- -------- ------------- ------------- -----------
dataset/nyu-mll/glue          157.4M 2 days ago    2 days ago    main script
model/LiquidAI/LFM2-VL-1.6B     3.2G 4 days ago    4 days ago    main
model/microsoft/UserLM-8b      32.1G 4 days ago    4 days ago    main

Done in 0.0s. Scanned 6 repo(s) for a total of 3.4G.
Got 1 warning(s) while scanning. Use -vvv to print details.
```

Args:
    cache_dir (`str` or `Path`, `optional`):
        Cache directory to cache. Defaults to the default HF cache directory.

> [!WARNING]
> Raises:
>
>     `CacheNotFound`
>       If the cache directory does not exist.
>
>     [`ValueError`](https://docs.python.org/3/library/exceptions.html#ValueError)
>       If the cache directory is a file, instead of a directory.

Returns: a [`~HFCacheInfo`] object.
NzCache directory not found: zM. Please use `cache_dir` argument or set `HF_HUB_CACHE` environment variable.)rµ   z1Scan cache expects a directory but found a file: z.lockszCACHEDIR.TAGc              3   ó8   #   • U  H  oR                   v •  M     g 7fr�   )r   )Ú.0rr   s     r    Ú	<genexpr>Ú!scan_cache_dir.<locals>.<genexpr>�  s   é € Ð=²u¨t×*Ö*²uùó   ‚)rl   r   r   )r
   r   Ú
expanduserÚresolveÚexistsr   Úis_fileÚ
ValueErrorr„   ÚiterdirÚnamer…   Ú_scan_cached_repor   Úappendr~   rN   Úsum)rµ   rl   r   rT   Úes        r    Úscan_cache_dirrÇ   0  s.  € ð` ÑÜ ˆ	ä�Y“×*Ñ*Ó,×4Ñ4Ó6€IØ×Ñ×ÑÜØ)¨)¨ð  5Bð  CØñ
ð 	
ð
 ×Ñ×ÑÜØ?À	¸{ð  KXð  Yó
ð 	
ô "%£€EØ.0€HØ×&Ñ&Ö(ˆ	Ø�>‰>˜XÓ%ÙØ�>‰>˜^Ó+Ùð	Ø�I‰IÔ'¨	Ó2Ö3ñ )ô Ü˜ÓÜÑ=±uÓ=Ó=Øñð øô 'ó 	Ø�O‰O˜A×Òûð	ús   Â<C>Ã>
D$ÄDÄD$rT   c                 óX	  ^• U R                  5       (       d  [        SU  35      eSU R                  ;  a  [        SU  35      eU R                  R                  SSS9u  pUSS nUR	                  SS5      nUS	;  a  [        S
U SU  S35      e0 mU S-  nU S-  nUR                  5       (       a  UR                  5       (       d  [        SU 35      e[        [        5      nUR                  5       (       a½  UR                  5       (       a  [        SU 35      eUR                  S5       H…  nUR                  5       (       d  UR                  [        ;   a  M.  [        UR                  U5      5      nUR                  5        nUR                  5       n	SSS5        UW	   R                  U5        M‡     [        5       n
UR!                  5        GHá  nUR                  [        ;   a  M  UR                  5       (       a  [        SU 35      e[        5       nUR                  S5       H½  nUR                  5       (       a  M  [#        U5      R%                  5       nUR                  5       (       d  [        SU 35      eUT;  a  UR'                  5       TU'   UR                  [)        UR                  UTU   R*                  UTU   R,                  TU   R.                  S95        M¿     [1        U5      S:”  a  [3        U4S jU 5       5      nOUR'                  5       R.                  nU
R                  [5        UR                  [7        U5      [7        UR9                  UR                  [        5       5      5      [;        U4S jU Vs1 s H  nUR<                  iM     sn 5       5      UUS95        GMä     [1        U5      S:”  a  [        S[?        U5       SU  S35      e[1        T5      S:”  aA  [3        S TRA                  5        5       5      n[3        S TRA                  5        5       5      nO(U R'                  5       nUR,                  nUR.                  n[C        [1        T5      UU U[7        U
5      [;        S TRA                  5        5       5      UUS9$ ! , (       d  f       GN	= fs  snf )z~Scan a single cache repo and return information about it.

Any unexpected behavior will raise a [`~CorruptedCacheException`].
zRepo path is not a directory: z--z6Repo path is not a valid HuggingFace cache directory: r   )ÚmaxsplitNéÿÿÿÿr_   >   r   r   r   z8Repo type must be `dataset`, `model` or `space`, found `z` (z).rm   r@   z,Snapshots dir doesn't exist in cached repo: z!Refs directory cannot be a file: z**/*z*Snapshots folder corrupted. Found a file: zBlob missing (broken symlink): )r   r   r   r   r   r   r   c              3   óV   >#   • U  H  nTUR                      R                  v •  M      g 7fr�   )r   Úst_mtime)r¸   r•   Ú
blob_statss     €r    r¹   Ú$_scan_cached_repo.<locals>.<genexpr>û  s#   øé € Ð(fÒYeÐQU¨°D·N±NÑ)C×)LÖ)LÒYeùs   ƒ&)c              3   óB   >#   • U  H  nTU   R                   v •  M     g 7fr�   ©Úst_size)r¸   r   rÍ   s     €r    r¹   rÎ     s    øé € ð !ÚCl°i�J˜yÑ)×1Ö1ÒClùs   ƒ)r=   r?   r@   r   r>   rA   z-Reference(s) refer to missing commit hashes: z (c              3   ó8   #   • U  H  oR                   v •  M     g 7fr�   )Úst_atime©r¸   Ústats     r    r¹   rÎ     ó   é € Ð OÒ;N°4§¦Ò;Nùr»   c              3   ó8   #   • U  H  oR                   v •  M     g 7fr�   )rÌ   rÔ   s     r    r¹   rÎ     rÖ   r»   c              3   ó8   #   • U  H  oR                   v •  M     g 7fr�   rÐ   rÔ   s     r    r¹   rÎ   #  s   é € ÐFÒ2E¨$ŸžÒ2Eùr»   )rL   rR   rT   rS   rU   r   rV   rA   )"Úis_dirr   rÂ   ÚsplitÚreplacer¾   r   r„   r¿   ÚglobÚFILES_TO_IGNOREr4   Úrelative_toÚopenÚreadr…   rÁ   r   r½   rÕ   r   rÑ   rÓ   rÌ   rK   Úmaxr;   rN   ÚpoprÅ   r   rg   ÚvaluesrP   )rT   rS   rR   Úsnapshots_pathÚ	refs_pathÚrefs_by_hashÚref_pathÚref_nameÚfr=   Úcached_revisionsÚrevision_pathÚcached_filesr   r   Úrevision_last_modifiedr•   Úrepo_last_accessedÚrepo_last_modifiedÚ
repo_statsrÍ   s                       @r    rÃ   rÃ   ¢  sf  ø€ ð
 ×Ñ×ÑÜ%Ð(FÀyÀkÐ&RÓSÐSà�9—>‘>Ó!Ü%Ð(^Ð_hÐ^iÐ&jÓkÐkà"Ÿ™×-Ñ-¨d¸QÐ-Ð?Ñ€IØ˜#˜2�€IØ�o‰o˜d CÓ(€GàÐ5Ó5Ü%ØFÀyÀkÐQTÐU^ÐT_Ð_aÐbó
ð 	
ð .0€Jà Ñ,€NØ˜FÑ"€Ià× Ñ ×"Ñ"¨.×*?Ñ*?×*AÑ*AÜ%Ð(TÐUcÐTdÐ&eÓfÐfô
 )4´CÓ(8€LØ×Ñ×Ñð ×Ñ×ÑÜ)Ð,MÈiÈ[Ð*YÓZÐZà!Ÿ™ vÖ.ˆHà�‰× Ñ  H§M¡M´_Ó$DÙä˜8×/Ñ/°	Ó:Ó;ˆHØ—‘” AØŸf™f›h�÷ !ð ˜Ñ%×)Ñ)¨(Ö3ñ /ô 14³ÐØ'×/Ñ/×1ˆà×Ñ¤Ó0ÙØ× Ñ ×"Ñ"Ü)Ð,VÐWdÐVeÐ*fÓgÐgä“uˆØ&×+Ñ+¨FÖ3ˆIà×Ñ×!Ñ!Ùä˜Y›×/Ñ/Ó1ˆIØ×#Ñ#×%Ñ%Ü-Ð0OÐPYÈ{Ð.[Ó\Ð\à 
Ó*Ø(1¯©Ó(8�
˜9Ñ%à×ÑÜØ'Ÿn™nØ'Ø!+¨IÑ!6×!>Ñ!>Ø'Ø'1°)Ñ'<×'EÑ'EØ'1°)Ñ'<×'EÑ'Eñö	ñ 4ô2 ˆ|Ó˜qÓ Ü%(Ô(fÑYeÓ(fÓ%fÑ"à%2×%7Ñ%7Ó%9×%BÑ%BÐ"à×ÑÜØ)×.Ñ.Ü Ó-Ü˜|×/Ñ/°×0BÑ0BÄCÃEÓJÓKÜ ô !Ù_kÓClÒ_kÐW[ÀDÇNÄNÑ_kÒCló!ó ð ,Ø4ñ	÷	
ñM 2ôh ˆ<Ó˜1ÓÜ%Ø;¼DÀÓ<NÐ;OÈrÐR[ÐQ\Ð\^Ð_ó
ð 	
ô ˆ:ƒ˜ÓÜ Ñ O¸:×;LÑ;LÔ;NÓ OÓOÐÜ Ñ O¸:×;LÑ;LÔ;NÓ OÓOÑà—^‘^Ó%ˆ
Ø'×0Ñ0ÐØ'×0Ñ0Ðô Ü�Z“ØØØÜÐ,Ó-ÜÑF°*×2CÑ2CÔ2EÓFÓFØ(Ø(ñ	ð 	÷W !–üòf Dms   ÆRÎR'Ò
R$	Únumc                 óp   • [        U 5      nS H   n[        U5      S:  a	  US U 3s  $ US-  nM"     US S3$ )zcFormat size in bytes into a human-readable string.

Taken from https://stackoverflow.com/a/1094933
)Ú ÚKÚMÚGÚTÚPÚEÚZg     @�@z3.1fz.1fÚY)r7   Úabs)rñ   Únum_fÚunits      r    r*   r*   )  sM   € ô
 �#‹J€EÛ7ˆÜˆu‹:˜ÓØ˜D�\ $ Ð(Ò(Ø�‰Šñ 8ð �Cˆ[˜ˆ?Ðr$   rz   rs   c                 ób  • [         R                  SU SU  35         U R                  5       (       a  [        R                  " U 5        g	[
        R                  " U 5        g	! [         a    [         R                  SU SU  S3SS9   g	[         a    [         R                  SU SU  S3SS9   g	f = f)
a(  Try to delete a local file or folder.

If the path does not exist, error is logged as a warning and then ignored.

Args:
    path (`Path`)
        Path to delete. Can be a file or a folder.
    path_type (`str`)
        What path are we deleting ? Only for logging purposes. Example: "snapshot".
zDelete z: zCouldn't delete z: file not found (Ú)T)Úexc_infoz: permission denied (N)
rx   ry   r¿   Úosr†   ÚshutilÚrmtreeÚFileNotFoundErrorr‡   ÚPermissionError)rz   rs   s     r    rw   rw   6  s£   € ô ‡K�K�'˜)˜ B t fÐ-Ô.ðbØ�<‰<�>‰>Ü�IŠI�d�Oä�MŠM˜$ÕøÜó _Ü�‰Ð)¨)¨Ð4FÀtÀfÈAÐNÐY]ˆÓ^Üó bÜ�‰Ð)¨)¨Ð4IÈ$ÈÈqÐQÐ\`ˆÓaðbús   �+A  Á	A  Á %B.Â$B.Â-B.r�   )&r3   r  r  Úcollectionsr   Údataclassesr   Úpathlibr   Útypingr   Úhuggingface_hub.errorsr   r   Ú	constantsr
   ró   r   Ú_parsingr   Ú	_terminalr   Ú
get_loggerr/   rx   rf   rÝ   r   r;   rP   ri   r~   r4   rÇ   rÃ   r6   r*   rw   r.   r$   r    Ú<module>r     sf  ðñ ;ã 	Û Ý #Ý !Ý Ý ç Iå $Ý Ý &Ý ð 
×	Ò	˜HÓ	%€àÐ1Ñ2€ð �-€ñ �$Ñ÷</ð </ó ð</ñ~ �$Ñ÷Cð Có ðCñL �$Ñ÷QWð QWó ðQWñh �$Ñ÷BSð BSó ðBSñJ �$Ñ÷cð có ðcñLo˜c D™j¨4Ñ/ð o¸;õ oðdD ð D¨.ô DðN
�cð 
˜cô 
ðb˜4ð b¨Cð b°Dõ br$   