Pythonで、読み取り専用属性を外してフォルダを削除する方法

Pythonで、フォルダを削除する際、読み取り専用属性を外しつつ削除するコードを作りました。
試行錯誤して作ったのが以下の通り。

import os
import shutil
import stat

def handle_remove_readonly(func, path, exc_info):
    """
    読み取り専用属性を削除してから再試行するエラーハンドラ。
    読み取り専用属性が原因で削除に失敗した場合、この関数が呼び出される。
    """
    if not os.access(path, os.W_OK):
        os.chmod(path, stat.S_IWRITE)  # 読み取り専用属性を解除して書き込み可能にする
        func(path)  # 属性変更後に再度削除を試みる

def remove_directory_with_readonly_files(directory):
    """
    指定されたディレクトリを削除する。
    このディレクトリに読み取り専用ファイルが含まれている場合でも、属性を解除して削除を行う。
    """
    if os.path.isdir(directory):
        shutil.rmtree(directory, onerror=handle_remove_readonly)
        print(f"Deleted directory: {directory}")
    else:
        print(f"Directory does not exist: {directory}")

# 使用例
if __name__ == "__main__":
    test_directory = './TestOut_Dir/temp_extract'  # 削除したいディレクトリのパス
    remove_directory_with_readonly_files(test_directory)

shutil.rmtreeが失敗した際、エラーハンドリングとして handle_remove_readonlyをcallbackして実行させる。

この中で、書き換え可能でなければ書き換え可能に変えて、エラーを起こした関数を再度呼ぶ。

ちなみに、ここでいう「エラーを起こした関数」は shutil.rmtree自身ではなく、rmtree関数内部で使用されるos.rmdir / os.remove 

こんなやり方あるんだなと少し感動した次第。

コメント

タイトルとURLをコピーしました