Skip to content

Commit 72e94ec

Browse files
committed
Simplify Windows read-only file deletion using shutil.rmtree
1 parent 4fe4819 commit 72e94ec

1 file changed

Lines changed: 18 additions & 35 deletions

File tree

file_utils.py

Lines changed: 18 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -99,46 +99,29 @@ def list_folders_in_directory(directory):
9999
return folders
100100

101101

102-
# delete a folder and all its subfolders and files
103-
def delete_folder(folder_name):
104-
if os.path.exists(folder_name):
105-
# Use writable-aware deletion so read-only files (e.g. .git objects on Windows) don't cause PermissionError
106-
delete_files_and_subfolders(folder_name)
107-
_make_writable(folder_name)
108-
os.rmdir(folder_name)
102+
def _on_rm_error(func, path, _exc_info):
103+
"""On Windows, clear read-only flag and retry the removal."""
104+
os.chmod(path, stat.S_IWRITE)
105+
func(path)
109106

110107

111-
def _make_writable(path: str) -> None:
112-
"""On Windows, clear read-only so deletion can succeed."""
113-
# TODO - Check if this can be done in a cleaner way.
114-
is_windows = os.name == "nt"
115-
if is_windows:
116-
try:
117-
mode = os.stat(path).st_mode
118-
os.chmod(path, mode | stat.S_IWRITE)
119-
except OSError:
120-
pass
108+
def delete_folder(folder_name):
109+
"""Delete a folder and all its subfolders and files."""
110+
if os.path.exists(folder_name):
111+
shutil.rmtree(folder_name, onerror=_on_rm_error)
121112

122113

123114
def delete_files_and_subfolders(directory):
124-
total_files_deleted = 0
125-
total_folders_deleted = 0
126-
127-
# Walk the directory in reverse order (bottom-up)
128-
for root, dirs, files in os.walk(directory, topdown=False):
129-
# Delete files
130-
for file in files:
131-
file_path = os.path.join(root, file)
132-
_make_writable(file_path)
133-
os.remove(file_path)
134-
total_files_deleted += 1
135-
136-
# Delete directories
137-
for dir_ in dirs:
138-
dir_path = os.path.join(root, dir_)
139-
_make_writable(dir_path)
140-
os.rmdir(dir_path)
141-
total_folders_deleted += 1
115+
"""Delete all contents of a directory but keep the directory itself."""
116+
for entry in os.scandir(directory):
117+
if entry.is_dir(follow_symlinks=False):
118+
shutil.rmtree(entry.path, onerror=_on_rm_error)
119+
else:
120+
try:
121+
os.remove(entry.path)
122+
except PermissionError:
123+
os.chmod(entry.path, stat.S_IWRITE)
124+
os.remove(entry.path)
142125

143126

144127
def copy_file(source_path, destination_path):

0 commit comments

Comments
 (0)