From 4d64251c166ecbe57f9bd97728c5a22b7351174c Mon Sep 17 00:00:00 2001 From: Phil Elson Date: Wed, 15 Oct 2025 05:00:40 +0200 Subject: [PATCH 1/3] Improve the typing of the with_cleanup decorator, as used by the download, install, lock, and wheel commands --- src/pip/_internal/cli/req_command.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/pip/_internal/cli/req_command.py b/src/pip/_internal/cli/req_command.py index dc1328ff019..ea333eb974b 100644 --- a/src/pip/_internal/cli/req_command.py +++ b/src/pip/_internal/cli/req_command.py @@ -10,7 +10,7 @@ import logging from functools import partial from optparse import Values -from typing import Any +from typing import Any, Callable, TypeVar from pip._internal.build_env import SubprocessBuildEnvironmentInstaller from pip._internal.cache import WheelCache @@ -51,7 +51,9 @@ ] -def with_cleanup(func: Any) -> Any: +def with_cleanup( + func: Callable[[_CommandT, Values, list[str]], int], +) -> Callable[[_CommandT, Values, list[str]], int]: """Decorator for common logic related to managing temporary directories. """ @@ -61,8 +63,10 @@ def configure_tempdir_registry(registry: TempDirectoryTypeRegistry) -> None: registry.set_delete(t, False) def wrapper( - self: RequirementCommand, options: Values, args: list[Any] - ) -> int | None: + self: _CommandT, + options: Values, + args: list[str], + ) -> int: assert self.tempdir_registry is not None if options.no_clean: configure_tempdir_registry(self.tempdir_registry) @@ -349,3 +353,6 @@ def _build_package_finder( selection_prefs=selection_prefs, target_python=target_python, ) + + +_CommandT = TypeVar("_CommandT", bound=RequirementCommand) From 3225bd71d9abd23b74426f42651638590b963a22 Mon Sep 17 00:00:00 2001 From: Phil Elson Date: Sat, 18 Oct 2025 06:05:12 +0200 Subject: [PATCH 2/3] Bring the TypeVar definition to the with_cleanup decorator by using late bound type (via string) --- src/pip/_internal/cli/req_command.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pip/_internal/cli/req_command.py b/src/pip/_internal/cli/req_command.py index ea333eb974b..5628b8d38c4 100644 --- a/src/pip/_internal/cli/req_command.py +++ b/src/pip/_internal/cli/req_command.py @@ -51,6 +51,9 @@ ] +_CommandT = TypeVar("_CommandT", bound="RequirementCommand") + + def with_cleanup( func: Callable[[_CommandT, Values, list[str]], int], ) -> Callable[[_CommandT, Values, list[str]], int]: @@ -353,6 +356,3 @@ def _build_package_finder( selection_prefs=selection_prefs, target_python=target_python, ) - - -_CommandT = TypeVar("_CommandT", bound=RequirementCommand) From ad53974e38be7548991275b151efb1cae7d16d91 Mon Sep 17 00:00:00 2001 From: Richard Si Date: Sat, 18 Oct 2025 13:09:33 -0400 Subject: [PATCH 3/3] Reformat to original formatting --- src/pip/_internal/cli/req_command.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/pip/_internal/cli/req_command.py b/src/pip/_internal/cli/req_command.py index 5628b8d38c4..cc3a5ef639e 100644 --- a/src/pip/_internal/cli/req_command.py +++ b/src/pip/_internal/cli/req_command.py @@ -65,11 +65,7 @@ def configure_tempdir_registry(registry: TempDirectoryTypeRegistry) -> None: for t in KEEPABLE_TEMPDIR_TYPES: registry.set_delete(t, False) - def wrapper( - self: _CommandT, - options: Values, - args: list[str], - ) -> int: + def wrapper(self: _CommandT, options: Values, args: list[str]) -> int: assert self.tempdir_registry is not None if options.no_clean: configure_tempdir_registry(self.tempdir_registry)