ó
    Ð.>g”9  ã                  ó¬   • S r SSKJr  SSKrSSKrSSKrSSKJr  SSKJ	r	  \	(       a  SSK
Jr  SSKJrJr   " S S	5      r " S
 S5      r " S S\5      rg)u•  :module: watchdog.utils.dirsnapshot
:synopsis: Directory snapshots and comparison.
:author: yesudeep@google.com (Yesudeep Mangalapilly)
:author: contact@tiger-222.fr (MickaÃ«l Schoentgen)

.. ADMONITION:: Where are the moved events? They 'disappeared'

        This implementation does not take partition boundaries
        into consideration. It will only work when the directory
        tree is entirely on the same file system. More specifically,
        any part of the code that depends on inode numbers can
        break if partition boundaries are crossed. In these cases,
        the snapshot diff will represent file/directory movement as
        created and deleted events.

Classes
-------
.. autoclass:: DirectorySnapshot
   :members:
   :show-inheritance:

.. autoclass:: DirectorySnapshotDiff
   :members:
   :show-inheritance:

.. autoclass:: EmptyDirectorySnapshot
   :members:
   :show-inheritance:

é    )ÚannotationsN)ÚS_ISDIR)ÚTYPE_CHECKING)ÚIterator)ÚAnyÚCallablec                  ó   • \ rS rSrSrSS.       SS jjrSS jrSS jr\SS j5       r	\SS	 j5       r
\SS
 j5       r\SS j5       r\SS j5       r\SS j5       r\SS j5       r\SS j5       r " S S5      rSrg)ÚDirectorySnapshotDiffé-   a}  Compares two directory snapshots and creates an object that represents
the difference between the two snapshots.

:param ref:
    The reference directory snapshot.
:type ref:
    :class:`DirectorySnapshot`
:param snapshot:
    The directory snapshot which will be compared
    with the reference snapshot.
:type snapshot:
    :class:`DirectorySnapshot`
:param ignore_device:
    A boolean indicating whether to ignore the device id or not.
    By default, a file may be uniquely identified by a combination of its first
    inode and its device id. The problem is that the device id may (or may not)
    change between system boots. This problem would cause the DirectorySnapshotDiff
    to think a file has been deleted and created again but it would be the
    exact same file.
    Set to True only if you are sure you will always use the same device.
:type ignore_device:
    :class:`bool`
F©Úignore_devicec               ó¨  • UR                   UR                   -
  nUR                   UR                   -
  nU(       a  SS jnOSS jnUR                   UR                   -   H9  nU" X5      U" X'5      :w  d  M  UR                  U5        UR                  U5        M;     [        5       n[        U5       HQ  nUR                  U5      n	UR	                  U	5      n
U
(       d  M.  UR                  U5        UR                  Xz45        MS     [        U5       HQ  nUR                  U5      n	UR	                  U	5      nU(       d  M.  UR                  U5        UR                  X·45        MS     [        5       nUR                   UR                   -   Hr  nU" X5      U" X'5      :X  d  M  UR                  U5      UR                  U5      :w  d&  UR                  U5      UR                  U5      :w  d  Ma  UR                  U5        Mt     U H`  u  pºUR                  U5      UR                  U
5      :w  d&  UR                  U5      UR                  U
5      :w  d  MO  UR                  U5        Mb     U Vs/ s H  orR                  U5      (       d  M  UPM     snU l	        U Vs/ s H  oqR                  U5      (       d  M  UPM     snU l
        U Vs/ s H  oqR                  U5      (       d  M  UPM     snU l        U VVs/ s H   u  pÞUR                  U5      (       d  M  XÞ4PM"     snnU l        [        U[        U R                  5      -
  5      U l        [        U[        U R                  5      -
  5      U l        [        U[        U R                  5      -
  5      U l        [        U[        U R                  5      -
  5      U l        g s  snf s  snf s  snf s  snnf )Nc                ó*   • U R                  U5      S   $ )Nr   ©Úinode©Ú	directoryÚ	full_paths     Ú</usr/lib/python3/dist-packages/watchdog/utils/dirsnapshot.pyÚ	get_inodeÚ1DirectorySnapshotDiff.__init__.<locals>.get_inodeR   s   € Ø —‘ yÓ1°!Ñ4Ð4ó    c                ó$   • U R                  U5      $ ©Nr   r   s     r   r   r   W   s   € Ø —‘ yÓ1Ð1r   )r   ÚDirectorySnapshotr   úbytes | strÚreturnzint | tuple[int, int])ÚpathsÚaddÚsetr   ÚpathÚremoveÚmtimeÚsizeÚisdirÚ_dirs_createdÚ_dirs_deletedÚ_dirs_modifiedÚ_dirs_movedÚlistÚ_files_createdÚ_files_deletedÚ_files_modifiedÚ_files_moved)ÚselfÚrefÚsnapshotr   ÚcreatedÚdeletedr   r!   Úmovedr   Únew_pathÚold_pathÚmodifiedÚfrmÚtos                  r   Ú__init__ÚDirectorySnapshotDiff.__init__F   sá  € ð —.‘. 3§9¡9Ñ,ˆØ—)‘)˜hŸn™nÑ,ˆæõ5ô
2ð —I‘I §¡Ô.ˆDÙ˜Ó#¡y°Ó'@Õ@Ø—‘˜DÔ!Ø—‘˜DÖ!ñ /ô 7:³eˆÜ˜–LˆDØ—I‘I˜d“OˆEØ—}‘} UÓ+ˆHßˆxà—‘˜tÔ$Ø—	‘	˜4Ð*Ö+ñ !ô ˜–LˆDØ—N‘N 4Ó(ˆEØ—x‘x “ˆHßˆxØ—‘˜tÔ$Ø—	‘	˜8Ð*Ö+ñ !ô &)£UˆØ—I‘I §¡Ô.ˆDÙ˜Ó#¡y°Ó'@Õ@Ø—	‘	˜$“ 8§>¡>°$Ó#7Ó7¸3¿8¹8ÀD»>ÈXÏ]É]Ð[_ÓM`Õ;`à—‘˜TÖ"ñ	 /ó #(ÑˆHØ�y‰y˜Ó" h§n¡n°XÓ&>Ó>À#Ç(Á(È8ÓBTÐX`×XeÑXeÐfnÓXoÕBoØ—‘˜XÖ&ñ #(ñ 07ÓOªw t¿.¹.È×:NŸd©wÑOˆÔÙ/6ÓJªw t¿)¹)ÀD¿/Ÿd©wÑJˆÔÙ08ÓL²¨¿I¹IÀd¿OŸt±ÑLˆÔÙ7<ÔO²u©)¨3ÀÇ	Á	È#Ç›I˜S›I±uÒOˆÔä" 7¬S°×1CÑ1CÓ-DÑ#DÓEˆÔÜ" 7¬S°×1CÑ1CÓ-DÑ#DÓEˆÔÜ# H¬s°4×3FÑ3FÓ/GÑ$GÓHˆÔÜ  ¬¨T×-=Ñ-=Ó)>Ñ!>Ó?ˆÕùò PùÚJùÚLùÛOs0   É(N?ÊN?ÊOÊ4OËO	Ë#O	Ë6OÌOc                ó"   • U R                  5       $ r   ©Ú__repr__©r/   s    r   Ú__str__ÚDirectorySnapshotDiff.__str__ˆ   ó   € Ø�}‰}‹Ðr   c                óŽ  • SnUR                  [        U 5      R                  [        U R                  5      [        U R
                  5      [        U R                  5      [        U R                  5      [        U R                  5      [        U R                  5      [        U R                  5      [        U R                  5      5	      $ )Nzz<{0} files(created={1}, deleted={2}, modified={3}, moved={4}), folders(created={5}, deleted={6}, modified={7}, moved={8})>)ÚformatÚtypeÚ__name__Úlenr+   r,   r-   r.   r&   r'   r(   r)   )r/   Úfmts     r   r>   ÚDirectorySnapshotDiff.__repr__‹   s�   € ðKð 	ð �z‰zÜ�‹J×ÑÜ�×#Ñ#Ó$Ü�×#Ñ#Ó$Ü�×$Ñ$Ó%Ü�×!Ñ!Ó"Ü�×"Ñ"Ó#Ü�×"Ñ"Ó#Ü�×#Ñ#Ó$Ü�× Ñ Ó!ó

ð 
	
r   c                ó   • U R                   $ )z List of files that were created.)r+   r?   s    r   Úfiles_createdÚ#DirectorySnapshotDiff.files_createdœ   ó   € ð ×"Ñ"Ð"r   c                ó   • U R                   $ )z List of files that were deleted.)r,   r?   s    r   Úfiles_deletedÚ#DirectorySnapshotDiff.files_deleted¡   rM   r   c                ó   • U R                   $ )z!List of files that were modified.)r-   r?   s    r   Úfiles_modifiedÚ$DirectorySnapshotDiff.files_modified¦   s   € ð ×#Ñ#Ð#r   c                ó   • U R                   $ )z•List of files that were moved.

Each event is a two-tuple the first item of which is the path
that has been renamed to the second item in the tuple.
)r.   r?   s    r   Úfiles_movedÚ!DirectorySnapshotDiff.files_moved«   s   € ð × Ñ Ð r   c                ó   • U R                   $ )z'List of directories that were modified.)r(   r?   s    r   Údirs_modifiedÚ#DirectorySnapshotDiff.dirs_modified´   rM   r   c                ó   • U R                   $ )z›List of directories that were moved.

Each event is a two-tuple the first item of which is the path
that has been renamed to the second item in the tuple.
)r)   r?   s    r   Ú
dirs_movedÚ DirectorySnapshotDiff.dirs_moved¹   s   € ð ×ÑÐr   c                ó   • U R                   $ )z&List of directories that were deleted.)r'   r?   s    r   Údirs_deletedÚ"DirectorySnapshotDiff.dirs_deletedÂ   ó   € ð ×!Ñ!Ð!r   c                ó   • U R                   $ )z&List of directories that were created.)r&   r?   s    r   Údirs_createdÚ"DirectorySnapshotDiff.dirs_createdÇ   r`   r   c                  óŒ   • \ rS rSrSrS\R                  \R                  SS.           SS jjrSS jr	SS jr
SS	 jrS
rg)Ú$DirectorySnapshotDiff.ContextManageréÌ   aì  Context manager that creates two directory snapshots and a
diff object that represents the difference between the two snapshots.

:param path:
    The directory path for which a snapshot should be taken.
:type path:
    ``str``
:param recursive:
    ``True`` if the entire directory tree should be included in the
    snapshot; ``False`` otherwise.
:type recursive:
    ``bool``
:param stat:
    Use custom stat function that returns a stat structure for path.
    Currently only st_dev, st_ino, st_mode and st_mtime are needed.

    A function taking a ``path`` as argument which will be called
    for every entry in the directory tree.
:param listdir:
    Use custom listdir function. For details see ``os.scandir``.
:param ignore_device:
    A boolean indicating whether to ignore the device id or not.
    By default, a file may be uniquely identified by a combination of its first
    inode and its device id. The problem is that the device id may (or may not)
    change between system boots. This problem would cause the DirectorySnapshotDiff
    to think a file has been deleted and created again but it would be the
    exact same file.
    Set to True only if you are sure you will always use the same device.
:type ignore_device:
    :class:`bool`
TF)Ú	recursiveÚstatÚlistdirr   c               ó@   • Xl         X l        X0l        X@l        XPl        g r   )r!   rg   rh   ri   r   )r/   r!   rg   rh   ri   r   s         r   r:   Ú-DirectorySnapshotDiff.ContextManager.__init__í   s   € ð ŒIØ&ŒNØŒIØ"ŒLØ!.Õr   c                ó.   • U R                  5       U l        g r   )Úget_snapshotÚpre_snapshotr?   s    r   Ú	__enter__Ú.DirectorySnapshotDiff.ContextManager.__enter__ü   s   € Ø $× 1Ñ 1Ó 3ˆDÕr   c                óŠ   • U R                  5       U l        [        U R                  U R                  U R                  S9U l        g )Nr   )rm   Úpost_snapshotr
   rn   r   Údiff)r/   Úargss     r   Ú__exit__Ú-DirectorySnapshotDiff.ContextManager.__exit__ÿ   s:   € Ø!%×!2Ñ!2Ó!4ˆDÔÜ-Ø×!Ñ!Ø×"Ñ"Ø"×0Ñ0ñˆD�Ir   c                ój   • [        U R                  U R                  U R                  U R                  S9$ )N)r!   rg   rh   ri   )r   r!   rg   rh   ri   r?   s    r   rm   Ú1DirectorySnapshotDiff.ContextManager.get_snapshot  s+   € Ü$Ø—Y‘YØŸ.™.Ø—Y‘YØŸ™ñ	ð r   )rs   r   ri   r!   rr   rn   rg   rh   N)r!   Ústrrg   Úboolrh   úCallable[[str], os.stat_result]ri   ú-Callable[[str | None], Iterator[os.DirEntry]]r   rz   r   ÚNone©r   r}   )rt   Úobjectr   r}   )r   r   )rF   Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Úosrh   Úscandirr:   ro   ru   rm   Ú__static_attributes__© r   r   ÚContextManagerre   Ì   sm   † ñ	ðH #Ø46·G±GØEGÇZÁZØ"'ñ	/àð	/ð ð		/ð
 2ð	/ð Cð	/ð  ð	/ð õ	/ô	4ô	÷	r   rˆ   )r&   r'   r(   r)   r+   r,   r-   r.   N)r0   r   r1   r   r   rz   r   r}   ©r   ry   )r   zlist[bytes | str])r   z%list[tuple[bytes | str, bytes | str]])rF   r€   r�   r‚   rƒ   r:   r@   r>   ÚpropertyrK   rO   rR   rU   rX   r[   r^   rb   rˆ   r†   r‡   r   r   r
   r
   -   sø   † ñð: $ñ@@àð@@ð $ð@@ð
 ð@@ð 
õ@@ôDô
ð" ó#ó ð#ð ó#ó ð#ð ó$ó ð$ð ó!ó ð!ð ó#ó ð#ð ó ó ð ð ó"ó ð"ð ó"ó ð"÷Aô Ar   r
   c                  óà   • \ rS rSrSrS\R                  \R                  S.         SS jjrSS jr	\
SS j5       rSS jrSS	 jrSS
 jrSS jrSS jrSS jrSS jrSS jrSS jrSrg)r   i  a‡  A snapshot of stat information of files in a directory.

:param path:
    The directory path for which a snapshot should be taken.
:type path:
    ``str``
:param recursive:
    ``True`` if the entire directory tree should be included in the
    snapshot; ``False`` otherwise.
:type recursive:
    ``bool``
:param stat:
    Use custom stat function that returns a stat structure for path.
    Currently only st_dev, st_ino, st_mode and st_mtime are needed.

    A function taking a ``path`` as argument which will be called
    for every entry in the directory tree.
:param listdir:
    Use custom listdir function. For details see ``os.scandir``.
T)rg   rh   ri   c               óf  • X l         X0l        X@l        0 U l        0 U l        U R                  U5      nXPR                  U'   XR                  UR
                  UR                  4'   U R                  U5       H9  u  peUR
                  UR                  4nX`R                  U'   XPR                  U'   M;     g r   )rg   rh   ri   Ú
_stat_infoÚ_inode_to_pathÚst_inoÚst_devÚwalk)r/   r!   rg   rh   ri   ÚstÚpÚis           r   r:   ÚDirectorySnapshot.__init__&  s–   € ð #ŒØŒ	ØŒà=?ˆŒØBDˆÔà�Y‰Y�t‹_ˆØ "�‰˜ÑØ6:×Ñ˜RŸY™Y¨¯	©	Ð2Ñ3à—Y‘Y˜t–_‰EˆAØ—‘˜BŸI™IÐ&ˆAØ%&×Ñ Ñ"Ø!#�O‰O˜AÓò %r   c              #  ó0  #   •  U R                  U5       Vs/ s H,  n[        R                  R                  XR                  5      PM.     nn/ nU HM  n[        R                  " [
        5         X`R                  U5      4nUR                  U5        Uv •  S S S 5        MO     U R                  (       ab  U H[  u  px[        R                  " [        5         [!        UR"                  5      (       a  U R%                  U5       S h  v•N   S S S 5        M]     g g s  snf ! [
         aH  nUR                  [        R                  [        R                  [        R                  4;   a   S nAg e S nAff = f! , (       d  f       GM/  = f N! , (       d  f       Mß  = f7fr   )ri   r„   r!   ÚjoinÚnameÚOSErrorÚerrnoÚENOENTÚENOTDIRÚEINVALÚ
contextlibÚsuppressrh   Úappendrg   ÚPermissionErrorr   Úst_moder‘   )	r/   ÚrootÚentryr   ÚeÚentriesr“   r!   r’   s	            r   r‘   ÚDirectorySnapshot.walk>  s%  é € ð
	ØAEÇÁÈdÔASÓTÒAS¸”R—W‘W—\‘\ $¯
©
Ö3ÑASˆEÐTð ˆÛˆAÜ×$Ò$¤WÕ-ØŸI™I a›LÐ)�Ø—‘˜uÔ%Ø’÷ .Ñ-ñ ð �>�>Û#‘�Ü×(Ò(¬Õ9Ü˜rŸz™z×*Ñ*Ø#'§9¡9¨T£?×2Ð2÷ :Ñ9ò $ð ùò% UøÜó 	ð
 �w‰wœ5Ÿ<™<¬¯©¼¿¹ÐEÓEÜàûð	ú÷ .×-úñ 3÷ :Ö9üs‡   ‚F„D —3DÁ
D Á!FÁ-(E/Â>FÃ/FÄFÄFÄFÄD Ä
E,Ä$=E'Å!FÅ&E'Å'E,Å,FÅ/
E?	Å9	FÆFÆ
F	ÆFc                óH   • [        U R                  R                  5       5      $ )z,Set of file/directory paths in the snapshot.)r    r�   Úkeysr?   s    r   r   ÚDirectorySnapshot.pathsX  s   € ô �4—?‘?×'Ñ'Ó)Ó*Ð*r   c                ó8   • U R                   R                  U5      $ )z<Returns path for id. None if id is unknown to this snapshot.)rŽ   Úget)r/   Úuids     r   r!   ÚDirectorySnapshot.path]  s   € à×"Ñ"×&Ñ& sÓ+Ð+r   c                óP   • U R                   U   nUR                  UR                  4$ )zReturns an id for path.)r�   r�   r�   )r/   r!   r’   s      r   r   ÚDirectorySnapshot.inodea  s#   € à�_‰_˜TÑ"ˆØ—	‘	˜2Ÿ9™9Ð%Ð%r   c                óF   • [        U R                  U   R                  5      $ r   )r   r�   r¢   ©r/   r!   s     r   r%   ÚDirectorySnapshot.isdirf  s   € Ü�t—‘ tÑ,×4Ñ4Ó5Ð5r   c                ó4   • U R                   U   R                  $ r   )r�   Úst_mtimer²   s     r   r#   ÚDirectorySnapshot.mtimei  s   € Ø�‰˜tÑ$×-Ñ-Ð-r   c                ó4   • U R                   U   R                  $ r   )r�   Úst_sizer²   s     r   r$   ÚDirectorySnapshot.sizel  s   € Ø�‰˜tÑ$×,Ñ,Ð,r   c                ó    • U R                   U   $ )aD  Returns a stat information object for the specified path from
the snapshot.

Attached information is subject to change. Do not use unless
you specify `stat` in constructor. Use :func:`inode`, :func:`mtime`,
:func:`isdir` instead.

:param path:
    The path for which stat information should be obtained
    from a snapshot.
)r�   r²   s     r   Ú	stat_infoÚDirectorySnapshot.stat_infoo  s   € ð �‰˜tÑ$Ð$r   c                ó   • [        X5      $ )z|Allow subtracting a DirectorySnapshot object instance from
another.

:returns:
    A :class:`DirectorySnapshotDiff` object.
)r
   )r/   Úprevious_dirsnaps     r   Ú__sub__ÚDirectorySnapshot.__sub__}  s   € ô %Ð%5Ó<Ð<r   c                ó"   • U R                  5       $ r   r=   r?   s    r   r@   ÚDirectorySnapshot.__str__†  rB   r   c                ó,   • [        U R                  5      $ r   )ry   r�   r?   s    r   r>   ÚDirectorySnapshot.__repr__‰  s   € Ü�4—?‘?Ó#Ð#r   )rŽ   r�   ri   rg   rh   N)
r!   ry   rg   rz   rh   r{   ri   r|   r   r}   )r£   ry   r   z$Iterator[tuple[str, os.stat_result]])r   zset[bytes | str])r­   útuple[int, int]r   zbytes | str | None)r!   r   r   rÅ   )r!   r   r   rz   )r!   r   r   Úfloat)r!   r   r   Úint)r!   r   r   zos.stat_result)r¾   r   r   r
   r‰   )rF   r€   r�   r‚   rƒ   r„   rh   r…   r:   r‘   rŠ   r   r!   r   r%   r#   r$   r»   r¿   r@   r>   r†   r‡   r   r   r   r     s•   † ñð2 Ø02·±ØACÇÁñ$àð$ð ð	$ð
 .ð$ð ?ð$ð 
õ$ô03ð4 ó+ó ð+ô,ô&ô
6ô.ô-ô%ô=ô÷$r   r   c                  óJ   • \ rS rSrSrSS jr\S	S j5       r\S
S j5       r	Sr
g)ÚEmptyDirectorySnapshoti�  z°Class to implement an empty snapshot. This is used together with
DirectorySnapshot and DirectorySnapshotDiff in order to get all the files/folders
in the directory as created.
c                ó   • g r   r‡   r?   s    r   r:   ÚEmptyDirectorySnapshot.__init__“  s   € Ør   c                ó   • g)z�Mock up method to return the path of the received inode. As the snapshot
is intended to be empty, it always returns None.

:returns:
    None.
Nr‡   )Ú_s    r   r!   ÚEmptyDirectorySnapshot.path–  s   € ð 	r   c                ó   • [        5       $ )z®Mock up method to return a set of file/directory paths in the snapshot. As
the snapshot is intended to be empty, it always returns an empty set.

:returns:
    An empty set.
)r    r?   s    r   r   ÚEmptyDirectorySnapshot.paths   s   € ô ‹uˆr   r‡   Nr~   )rÍ   r   r   r}   )r   r    )rF   r€   r�   r‚   rƒ   r:   Ústaticmethodr!   rŠ   r   r†   r‡   r   r   rÉ   rÉ   �  s4   † ñô
ð óó ðð óó ór   rÉ   )rƒ   Ú
__future__r   rž   rš   r„   rh   r   Útypingr   Úcollections.abcr   r   r   r
   r   rÉ   r‡   r   r   Ú<module>rÕ      sN   ðñõ> #ã Û Û 	Ý Ý  æÝ(ß$÷`ñ `÷Fz$ñ z$ôzÐ.õ r   