기술 · 실용 가이드
dircmp.diff_files가 계속 비어 있나요? 두 결과 저장 위치를 갱신하고 공통 파일 전체를 비교하세요
로컬 검사 28개로 clear_cache(), 새 기본 dircmp, diff_files만 깊게 비교하는 방법이 각각 놓치는 경우를 확인했습니다.

dircmp.diff_files가 비어 있어도 두 디렉터리의 바이트가 같다는 증거는 아닙니다. CPython 3.12.14 실험에서 4바이트 파일을 AAAA에서 BBBB로 바꾸고 크기와 수정 시각을 의도적으로 유지하자 얕은 비교와 이전에 캐시된 깊은 비교가 모두 True를 반환했습니다.
filecmp 모듈 캐시를 지우면 새로운 깊은 비교는 False가 됐습니다. 하지만 기존 dircmp 객체가 이미 계산한 빈 목록은 바뀌지 않았습니다. 빈 diff_files를 깊게 비교해도 실제 검사 파일 이름은 0개입니다. 두 상태를 구분하고 명확한 정책으로 현재 공통 파일 전체를 비교해야 합니다.
1. 보관된 결과 두 종류를 구분하기
filecmp.cmp의 비교 서명에는 파일 유형, 크기, 수정 시각이 들어갑니다. shallow=True면 같은 서명을 바이트를 읽지 않고 같다고 처리할 수 있습니다. shallow=False는 이 단축 경로를 피하지만 경로와 서명이 그대로면 문서에 명시된 비교 캐시가 이전 결과를 제공할 수 있습니다.
dircmp 속성은 필요할 때 지연 계산된 뒤 객체에 남습니다. 실험에서는 덮어쓰기 전에 d0.diff_files를 평가했습니다. clear_cache() 뒤 새 깊은 비교가 False여도 d0.diff_files는 원래 빈 목록이었습니다. 모듈 캐시 삭제가 d0를 재구성한 것은 아닙니다.
2. 통제한 덮어쓰기로 재현하기
소유한 새 임시 디렉터리를 사용합니다. 양쪽 report.bin에 b"AAAA"를 쓰고 같은 고정 수정 시각을 설정합니다. clear_cache(), cmp(a,b,shallow=False)를 실행하고 d0=filecmp.dircmp(left,right)의 d0.diff_files를 읽었습니다. 처음 깊은 결과는 True, 목록은 비어 있었습니다.
오른쪽만 b"BBBB"로 바꾸고 os.utime으로 원래 mtime을 복원합니다. 유형·크기·mtime 서명이 같고 실제 바이트는 다른지 단언으로 확인했습니다. 기본 얕은 호출과 캐시된 깊은 호출 모두 True였습니다. 이는 의도적인 서명 보존이며 파일시스템 타임스탬프 해상도 측정이 아닙니다.
3. 객체를 새로 만들고 common_files 비교하기
먼저 쓰기 작업을 멈추거나 격리해 입력을 안정시킵니다. 실측 3.12에서는 filecmp.clear_cache(); fresh=filecmp.dircmp(left,right,ignore=[],hide=[]); match,mismatch,errors=filecmp.cmpfiles(left,right,fresh.common_files,shallow=False)를 사용할 수 있습니다. 빈 필터 목록은 작은 테스트 데이터의 정책이며 모든 운영 환경에 대한 권고는 아닙니다.
변경 후 match와 errors는 비고 mismatch에는 report.bin이 있었습니다. 반대로 fresh.diff_files를 cmpfiles에 넘기면 세 목록 모두 비었습니다. 새 기본 객체도 얕은 비교를 하므로 같다고 오판한 파일을 이미 제외했습니다. common_files를 후보로 삼고 left_only, right_only, common_funny, errors도 남겨 단일 성공 표시로 축약하지 마세요.
4. 새 인수를 쓰기 전에 실행 버전 확인하기
실제 3.12.14는 filecmp.dircmp(left,right,shallow=False)에 TypeError를 발생시켰습니다. Python 3.13 문서는 이 인수가 3.13에서 추가됐다고 설명합니다. 3.13을 실행하지는 않았습니다. 지원 버전의 공개 깊은 비교 옵션도 바뀌는 입력을 원자적 스냅샷으로 만들거나 이미 평가한 예전 객체를 갱신한다는 보장은 아닙니다.
기본 dircmp도 메타데이터 단축 경로를 적용할 수 없으면 내용을 읽습니다. 마지막 대조에서 바이트는 같고 수정 시각은 달랐지만 얕은 비교가 True였습니다. 따라서 얕은 비교가 언제나 메타데이터만 보는 것은 아니며 시각 차이만으로 내용 차이를 증명할 수도 없습니다.
5. 오류와 이름 필터를 결과에 포함하기
missing.bin 대조는 mismatch 대신 cmpfiles의 errors에 들어갔습니다. extra.bin 추가 후 예전 객체의 계산된 right_only에는 없고 새 객체에는 있었습니다. 추가 전에 만들었지만 목록을 읽지 않았던 dircmp는 첫 접근에서 새 이름을 봤습니다. 객체 생성 시점은 스냅샷 경계가 아닙니다.
임시 테스트의 .git이라는 일반 파일은 기본 ignore 정책에서 숨겨지고 ignore=[],hide=[]에서는 나타났습니다. 애플리케이션이 비교할 이름을 먼저 정하세요. 내용 차이가 비어 있어도 이름, 유형, 전체 탐색 범위, 권한이 같다는 뜻은 아닙니다. 이번 평면 일반 파일 실험은 재귀, 링크 탐색, 특수 파일, 동시 변경을 시험하지 않았습니다.
6. 독립적인 바이트 검사로 확인 마치기
실제로 설치된 GNU cmp 3.10으로 변경된 두 report.bin에 cmp -s를 실행하자 종료값 1이 나와 바이트 차이를 독립 확인했습니다. GNU 상위 프로젝트 매뉴얼은 0을 같음, 1을 다름, 2를 실행 문제로 정의합니다. 새로 계산한 SHA-256도 달랐습니다. 오류 종료를 같음이나 일반 내용 차이로 처리하면 안 됩니다.
28개 단언이 모두 CPython 3.12.14/Linux에서 통과했습니다. 보고서는 실행 버전, 플랫폼, GNU 버전, 스크립트 SHA와 결과를 보존합니다. 실제 감사에서는 안정된 입력에서 선택한 이름 범위, 모든 공통 파일 결과, 미해결 오류를 보고하세요. 바이트 일치는 내용 관찰이며 진위, 메타데이터 일치, 쓰기 중 일관성에는 별도 보장이 필요합니다.
