MCPcopy Create free account
hub / github.com/tox-dev/filelock / _close_after_commit

Function _close_after_commit

tests/test_soft_stale.py:645–672  ·  view source on GitHub ↗
(mocker: MockerFixture, lock: SoftFileLock)

Source from the content-addressed store, hash-verified

643
644@contextmanager
645def _close_after_commit(mocker: MockerFixture, lock: SoftFileLock) -> Iterator[tuple[OSError, list[int]]]:
646 real_close = os.close
647 close_error = OSError(EINTR, "close failed")
648 attempts: list[int] = []
649 # close is an attribute of the shared os module, so this patch binds for every close in the process while the
650 # window is open, including one a GC-run finalizer (a multiprocessing pipe from an earlier test, say) makes on this
651 # very thread. Fail only the descriptor this lock lets go of: it clears its bookkeeping right before the one close
652 # attempt, so record the descriptor as it does.
653 released: list[int | None] = []
654 real_mark_released = lock._mark_descriptor_released
655
656 def mark_released() -> None:
657 released.append(lock._context.lock_file_fd)
658 real_mark_released()
659
660 def close(fd: int) -> None:
661 real_close(fd)
662 if fd not in released:
663 return
664 attempts.append(fd)
665 raise close_error
666
667 mocker.patch.object(lock, "_mark_descriptor_released", side_effect=mark_released)
668 close_mock = mocker.patch("filelock._soft.os.close", side_effect=close)
669 try:
670 yield close_error, attempts
671 finally:
672 mocker.stop(close_mock)
673
674
675def test_soft_windows_unlink_gives_up_after_every_attempt_is_denied(tmp_path: Path, mocker: MockerFixture) -> None:

Calls

no outgoing calls

Tested by

no test coverage detected