Repository: pypa/pip
File: src/pip/_internal/utils/temp_dir.py (Python)

Code before:
            path: str,
            exc_info: Tuple[Type[BaseException], BaseException, Any],
        ) -> None:
            """Log a warning for a `rmtree` error and continue"""
            exc_val = "\n".join(traceback.format_exception_only(*exc_info[:2]))
            exc_val = exc_val.rstrip()  # remove trailing new line
            if func in (os.unlink, os.remove, os.rmdir):
                logger.debug(
                    "Failed to remove a temporary file '%s' due to %s.\n",
                    path,
                    exc_val,
                )
            else:
                logger.debug("%s failed with %s.", func.__qualname__, exc_val)
            errors.append(exc_info[1])

        if self.ignore_cleanup_errors:
            try:
                # first try with tenacity; retrying to handle ephemeral errors
                rmtree(self._path, ignore_errors=False)
            except OSError:
                # last pass ignore/log all errors
                rmtree(self._path, onerror=onerror)
            if errors:
                logger.warning(
                    "Failed to remove contents of a temporary directory '%s'.\n"
                    "You can safely remove it manually.",
                    self._path,
                )
        else:
            rmtree(self._path)


class AdjacentTempDirectory(TempDirectory):
    """Helper class that creates a temporary directory adjacent to a real one.

    Attributes:
        original
            The original directory to create a temp directory for.
        path
            After calling create() or entering, contains the full
            path to the temporary directory.
        delete
            Whether the directory should be deleted when exiting
            (when used as a contextmanager)

    """

    # The characters that may be used to name the temp directory
    # We always prepend a ~ and then rotate through these until
    # a usable name is found.

Review comment (bug):
```suggestion
                    "Failed to remove contents in a temporary directory '%s'.\n"
```

Code after:
            path: str,
            exc_info: Tuple[Type[BaseException], BaseException, Any],
        ) -> None:
            """Log a warning for a `rmtree` error and continue"""
            exc_val = "\n".join(traceback.format_exception_only(*exc_info[:2]))
            exc_val = exc_val.rstrip()  # remove trailing new line
            if func in (os.unlink, os.remove, os.rmdir):
                logger.debug(
                    "Failed to remove a temporary file '%s' due to %s.\n",
                    path,
                    exc_val,
                )
            else:
                logger.debug("%s failed with %s.", func.__qualname__, exc_val)
            errors.append(exc_info[1])

        if self.ignore_cleanup_errors:
            try:
                # first try with tenacity; retrying to handle ephemeral errors
                rmtree(self._path, ignore_errors=False)
            except OSError:
                # last pass ignore/log all errors
                rmtree(self._path, onexc=onerror)
            if errors:
                logger.warning(
                    "Failed to remove contents in a temporary directory '%s'.\n"
                    "You can safely remove it manually.",
                    self._path,
                )
        else:
            rmtree(self._path)


class AdjacentTempDirectory(TempDirectory):
    """Helper class that creates a temporary directory adjacent to a real one.

    Attributes:
        original
            The original directory to create a temp directory for.
        path
            After calling create() or entering, contains the full
            path to the temporary directory.
        delete
            Whether the directory should be deleted when exiting
            (when used as a contextmanager)

    """

    # The characters that may be used to name the temp directory
    # We always prepend a ~ and then rotate through these until
    # a usable name is found.