
    ybjw                    D   % S SK Jr  S SKrS SKrS SKrS SKrS SKJrJrJ	r	  S SK
Jr  S SKJr  SS jrSS jrSS jrSS	 jrSS
.SS jjr\R&                  S:g  =(       a    \R(                  \R*                  ;   rS\S'   \R(                  \R0                  ;   rS\S'   / SQrg)    )annotationsN)EACCESEIOEISDIR)Path)Finalc                    [        U5      nU(       a:  [        R                  " X5      =nS:X  a  [        [        S5      eX#S nU(       a  M9  gg)aC  
Write the whole buffer to *fd*, looping over the short writes ``os.write`` is allowed to make.

A marker written with a bare ``os.write`` can land partially: a peer reading it mid-write parses a truncated record
as malformed or as a foreign holder. Looping until the buffer drains keeps the record atomic in the process and
kernel view. No ``fsync``: filelock needs a complete record, not crash-durable storage.

:param fd: file descriptor open for writing.
:param data: bytes to write in full.

:raises OSError: if a write reports zero progress before the record is complete.

r   z5os.write wrote 0 bytes before the record was completeN)
memoryviewoswriteOSErrorr   )fddata	remainingwrittens       ڊ/tmp/claude-0/-home-danvics-docker-quiz/c1e0577a-e42c-4a3d-b1ea-3edd61103a4e/scratchpad/stt/lib/python3.13/site-packages/filelock/_util.py	write_allr      sF     4 I
xx..G14#VWWh'	 )    c                L    [         R                  " U 5      nUR                  [        R
                  -  (       dp  [         R                  " U [         R                  [         R                  [         R                  ;   S9(       d(   [         R                  " U 5        [        [        SU 5      e[        R                  " UR                  5      (       a6  [        R                  S:X  a  [        [        SU 5      e[        [         SU 5      eg! [         a     gf = f! [         a     gf = f)a  
Raise an exception if attempting to open the file for writing would fail.

Separates files that can never be written from files that are writable but currently locked.

:param filename: file to check

:raises OSError: as if the file was opened for writing.

N)effective_idszPermission deniedwin32zIs a directory)r   lstatr   st_modestatS_IWUSRaccessW_OKsupports_effective_idsFileNotFoundErrorPermissionErrorr   S_ISDIRsysplatformIsADirectoryErrorr   )filename	file_stats     r   raise_on_not_writable_filer'   !   s    
 HHX&	 ,bii"''b6O6O)O7	HHX f&98DD||I%%&&<<7"!&*=xHH(8(CC '#   ! 		s#   D D 
DD
D#"D#c                J    [        U 5      R                  R                  SSS9  g)zd
Ensure the directory containing the file exists (create it if necessary).

:param filename: file.

T)parentsexist_okN)r   parentmkdir)r%   s    r   ensure_directory_existsr-   I   s!     	Nt<r   c                \   U  S[         R                  " 5        S[        R                  " S5       3n[	        U 5      R                  U5         [         R                  " U5      nUR                  U:  d  UR                  U:w  a  g[	        U5      R                  5         g! [         a     gf = f)a  
Atomically break a stale lock file judged stale at modification time *mtime_before*.

Rename the file to a process-private name before unlinking it, so two processes breaking the same lock cannot
delete each other's work: only one rename of a given inode wins, the loser gets ``OSError``. After the rename,
re-check the file. A newer modification time, or a different inode than *ino_before*, means a peer recreated the
lock between the stale decision and the rename, so we grabbed a live file and abort, leaving the renamed file in
place. A rollback rename is itself racy, the same trade-off as the soft read/write marker break. The inode check
matters because filesystems with coarse modification-time granularity (NFS, FAT) can give a same-second recreation
the old mtime, so mtime alone would miss it and unlink a live lock; the inode is the reliable identity, mirroring
the token re-check in the soft read/write marker break. ``lstat`` avoids following a hostile symlink swapped in
after the decision.

The break name carries a random token so it is unguessable and unique per attempt. Without it two breakers in the
same process share ``<lock>.break.<pid>``, and a second break can rename a recreated live lock onto that path in
the window between the re-verify ``lstat`` above and the ``unlink`` below, deleting a live lock the inode check
just approved. A private name keeps anyone else from targeting our break path, matching the soft read/write marker
break.

:param lock_file: path to the lock file to break.
:param mtime_before: modification time observed when the lock was judged stale.
:param ino_before: inode number observed when the lock was judged stale.

:raises OSError: if the rename fails (e.g. the file vanished or is not owned in a sticky directory).

z.break..   N)r   getpidsecrets	token_hexr   renamer   r   st_mtimest_inounlink)	lock_filemtime_before
ino_before
break_pathst_afters        r   break_lock_filer=   S   s    6 ;gbiik]!G4E4Eb4I3JKJO:&88J' <'8??j+H	  s   B 
B+*B+)r   c                   Ub#  [         (       a  [        R                  " US 5        g [        R                  " U S [        (       + S9  g )N)follow_symlinks)_SUPPORTS_UTIME_FDr   utime_SUPPORTS_UTIME_NOFOLLOW)namer   s     r   touchrD   y   s4    
 
~,,
THHT4-E)EFr   r   zFinal[bool]r@   rB   )r=   r-   r'   rD   r   )r   intr   bytesreturnNone)r%   strrG   rH   )r%   z
Path | strrG   rH   )r8   rI   r9   floatr:   rE   rG   rH   )rC   rI   r   z
int | NonerG   rH   )
__future__r   r   r2   r   r"   errnor   r   r   pathlibr   typingr   r   r'   r-   r=   rD   r#   rA   supports_fdr@   __annotations__supports_follow_symlinksrB   __all__ r   r   <module>rT      s    " 	   
 % %  (*%DP=#L *. G #&,,'"9"Xbhh"..>X K X(*B4O4O(O + Or   