Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Address deprecation warning in shutil.rmtree(onerror=...) #1401

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions copier/template.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Tools related to template management."""
import re
import sys
from collections import ChainMap, defaultdict
from contextlib import suppress
from dataclasses import field
Expand Down Expand Up @@ -198,11 +199,18 @@
def _cleanup(self) -> None:
temp_clone = self._temp_clone()
if temp_clone:
rmtree(
temp_clone,
ignore_errors=False,
onerror=handle_remove_readonly,
)
if sys.version_info >= (3, 12):
rmtree(

Check warning on line 203 in copier/template.py

View check run for this annotation

Codecov / codecov/patch

copier/template.py#L203

Added line #L203 was not covered by tests
temp_clone,
ignore_errors=False,
onexc=handle_remove_readonly,
)
else:
rmtree(
temp_clone,
ignore_errors=False,
onerror=handle_remove_readonly,
)

def _temp_clone(self) -> Optional[Path]:
"""Get the path to the temporary clone of the template.
Expand Down
13 changes: 9 additions & 4 deletions copier/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from importlib.metadata import version
from pathlib import Path
from types import TracebackType
from typing import Any, Callable, Literal, Optional, TextIO, Tuple, Union, cast
from typing import Any, Callable, Literal, Optional, TextIO, Tuple, Type, Union, cast

import colorama
from packaging.version import Version
Expand Down Expand Up @@ -148,7 +148,10 @@


def handle_remove_readonly(
func: Callable, path: str, exc: Tuple[BaseException, OSError, TracebackType]
func: Callable,
path: str,
# TODO: Change this union to simply `BaseException` when Python 3.11 support is dropped
exc: Union[BaseException, Tuple[Type[BaseException], BaseException, TracebackType]],
) -> None:
"""Handle errors when trying to remove read-only files through `shutil.rmtree`.

Expand All @@ -158,9 +161,11 @@
Arguments:
func: An OS-dependant function used to remove a file.
path: The path to the file to remove.
exc: A `sys.exc_info()` object.
exc: An exception (Python >= 3.12) or `sys.exc_info()` object.
"""
excvalue = exc[1]
# TODO: Change to `excvalue = exc` when Python 3.11 support is dropped
excvalue = cast(OSError, exc if isinstance(exc, BaseException) else exc[1])

Check warning on line 167 in copier/tools.py

View check run for this annotation

Codecov / codecov/patch

copier/tools.py#L167

Added line #L167 was not covered by tests

if func in (os.rmdir, os.remove, os.unlink) and excvalue.errno == errno.EACCES:
os.chmod(path, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO) # 0777
func(path)
Expand Down