"""The Windows error codes a peer's open handle produces, declared once.Windows refuses to remove or replace a file while another process holds ahandle to it. Two codes carry that refusal, and CPython surfaces both as:class:`PermissionError`: ``ERROR_SHARING_VIOLATION`` (32) while a peer holdsthe file open, and ``ERROR_ACCESS_DENIED`` (5) once a delete against it isalready pending. Both clear when the last handle closes.Windows does not distinguish either from a denying ACL or a read-only attributeat the operation boundary, so the code alone never proves contention -- a retrybudget is what separates them: a transient block clears inside the window, and apermanent one outlasts it. Each caller owns that budget, because the rightanswer depends on what losing the race costs it.Declared here rather than in either consumer because the two that need itcannot share a module: :mod:`core.lockfile_unlink` imports:mod:`core.logging`, and :mod:`core.bucket_pointer` is read during``Settings()`` bootstrap and must not (its own comments record the circularbootstrap that import recreates). This module imports nothing, so it is safefrom both.Nothing is absorbed off Windows: ``winerror`` is absent there, so:func:`is_windows_contention` is ``False`` for every POSIX ``EACCES``, which isgenuine and must propagate."""from__future__importannotationsWINDOWS_CONTENDED_ACCESS_ERRORS=frozenset({5,32})"""``ERROR_ACCESS_DENIED`` and ``ERROR_SHARING_VIOLATION``."""
[docs]defis_windows_contention(exc:OSError)->bool:"""Report whether ``exc`` is Windows refusing an operation a handle blocks. Args: exc: The raised OS error to classify. Returns: ``True`` when the error carries a Windows contention code. ``False`` everywhere else, including every POSIX error, where no sharing-violation class exists to confuse with a genuine refusal. """returngetattr(exc,"winerror",None)inWINDOWS_CONTENDED_ACCESS_ERRORS