Watch at Ease세상을 읽고, 일상의 답을 찾다.

기술 · 실용 가이드

NamedTemporaryFile은 POSIX에서 되는데 Windows에서 실패하나요? 재열기와 삭제 계약을 고르세요

임시 경로에는 생성자, 두 번째 열기, 정리라는 세 주체가 있습니다. 이름을 넘기기 전에 어떤 핸들을 열어 둘지 정합니다.

Original diagram showing creator, consumer, and cleanup as three owners of a named temporary file.
원본 일러스트: 생성자, 소비자, 정리 책임을 먼저 연결합니다. Watch at Ease

NamedTemporaryFile은 보이는 경로를 주지만 모든 두 번째 핸들이 재열기, 이름 변경, 삭제를 할 수 있다는 뜻은 아닙니다. Windows는 기존 핸들의 액세스와 공유 모드를 검사합니다.

생성 전에 수명 계약을 고르고 delete와 delete_on_close를 연결하며 context 종료 전에 호환되지 않는 핸들을 닫고 소비 성공과 최종 삭제를 검증합니다.

다음 소유자를 먼저 정하기

Write down whether the next user is the same Python handle, a second Python open, a library that accepts a path, or an external process. Also state whether that consumer needs only read/write access or may rename, replace, or keep the file mapped.

If the consumer accepts a file object, prefer passing the existing object and avoid a second pathname open. If it requires a path, the handle and cleanup contract must be explicit.

세 가지 수명 계약 중 선택

For same-context reopen on Python 3.12+, delete=True with delete_on_close=False keeps automatic context-exit cleanup while allowing an ordinary second open on Windows. Close that second handle before leaving the context.

For an external process or API that cannot share delete access, flush and close the producer, use delete=False, pass the path, wait for the consumer, then remove the file in finally. For a specialized second Python open that shares delete access, use the documented O_TEMPORARY route only when every participant follows the same contract.

flush, close, 프로세스 종료 분리

flush makes Python buffers visible but does not release the Windows handle or its share-mode record. close releases that handle. Waiting for the subprocess proves only that process exit occurred; it does not prove another library or mapped view released the file.

Keep the producer, consumer, and cleanup timestamps in a small ledger. A cleanup PermissionError is evidence of an outstanding handle or missing delete right, not a reason to silently leak the path.

이름 변경과 삭제를 별도 액세스로 처리

Microsoft documents that delete access includes rename. A file can be readable and writable yet still reject os.replace, fileinput in-place editing, or cleanup because a prior handle did not share delete access.

Do not diagnose every WinError 32 as another process. Record the exact operation, every handle you own, whether each is closed, and whether the consumer might retain a mapping.

두 플랫폼에서 검증

Create a fixture that writes bytes, reopens or hands off the path exactly as production does, confirms the consumer read the expected hash, closes every handle, exits the context, and asserts whether the path should exist. Run it on Windows and POSIX.

For delete=False, assert deletion in finally and fail loudly if removal fails. For delete_on_close=False, assert the second handle closes before context exit. Also test the exception path so cleanup is not dependent on a successful consumer.

Original diagram comparing incompatible and compatible Windows file sharing contracts.
원본 일러스트: Windows는 모든 열린 핸들의 공유 모드를 검사합니다. Watch at Ease