2
2
3
3
import logging
4
4
import operator
5
+ from abc import ABC , abstractmethod
5
6
from collections import defaultdict
6
7
from pathlib import Path
7
8
from typing import TYPE_CHECKING , Any , Callable , Sequence
21
22
from tox .tox_env .package import PathPackage
22
23
23
24
24
- class Pip (Installer [Python ]):
25
- """Pip is a python installer that can install packages as defined by PEP-508 and PEP-517."""
26
-
25
+ class PythonInstallerListDependencies (Installer [Python ], ABC ):
27
26
def __init__ (self , tox_env : Python , with_list_deps : bool = True ) -> None : # noqa: FBT001, FBT002
28
27
self ._with_list_deps = with_list_deps
29
28
super ().__init__ (tox_env )
30
29
31
30
def _register_config (self ) -> None :
31
+ if self ._with_list_deps : # pragma: no branch
32
+ self ._env .conf .add_config (
33
+ keys = ["list_dependencies_command" ],
34
+ of_type = Command ,
35
+ default = Command (self .freeze_cmd ()),
36
+ desc = "command used to list installed packages" ,
37
+ )
38
+
39
+ @abstractmethod
40
+ def freeze_cmd (self ) -> list [str ]:
41
+ raise NotImplementedError
42
+
43
+ def installed (self ) -> list [str ]:
44
+ cmd : Command = self ._env .conf ["list_dependencies_command" ]
45
+ result = self ._env .execute (cmd = cmd .args , stdin = StdinSource .OFF , run_id = "freeze" , show = False )
46
+ result .assert_success ()
47
+ return result .out .splitlines ()
48
+
49
+
50
+ class Pip (PythonInstallerListDependencies ):
51
+ """Pip is a python installer that can install packages as defined by PEP-508 and PEP-517."""
52
+
53
+ def _register_config (self ) -> None :
54
+ super ()._register_config ()
32
55
self ._env .conf .add_config (
33
56
keys = ["pip_pre" ],
34
57
of_type = bool ,
@@ -54,13 +77,9 @@ def _register_config(self) -> None:
54
77
default = False ,
55
78
desc = "Use the exact versions of installed deps as constraints, otherwise use the listed deps." ,
56
79
)
57
- if self ._with_list_deps : # pragma: no branch
58
- self ._env .conf .add_config (
59
- keys = ["list_dependencies_command" ],
60
- of_type = Command ,
61
- default = Command (["python" , "-m" , "pip" , "freeze" , "--all" ]),
62
- desc = "command used to list installed packages" ,
63
- )
80
+
81
+ def freeze_cmd (self ) -> list [str ]: # noqa: PLR6301
82
+ return ["python" , "-m" , "pip" , "freeze" , "--all" ]
64
83
65
84
def default_install_command (self , conf : Config , env_name : str | None ) -> Command : # noqa: ARG002
66
85
isolated_flag = "-E" if self ._env .base_python .version_info .major == 2 else "-I" # noqa: PLR2004
@@ -82,12 +101,6 @@ def post_process_install_command(self, cmd: Command) -> Command:
82
101
install_command .pop (opts_at )
83
102
return cmd
84
103
85
- def installed (self ) -> list [str ]:
86
- cmd : Command = self ._env .conf ["list_dependencies_command" ]
87
- result = self ._env .execute (cmd = cmd .args , stdin = StdinSource .OFF , run_id = "freeze" , show = False )
88
- result .assert_success ()
89
- return result .out .splitlines ()
90
-
91
104
def install (self , arguments : Any , section : str , of_type : str ) -> None :
92
105
if isinstance (arguments , PythonDeps ):
93
106
self ._install_requirement_file (arguments , section , of_type )
@@ -239,4 +252,7 @@ def build_install_cmd(self, args: Sequence[str]) -> list[str]:
239
252
return install_command [:opts_at ] + list (args ) + install_command [opts_at + 1 :]
240
253
241
254
242
- __all__ = ("Pip" ,)
255
+ __all__ = [
256
+ "Pip" ,
257
+ "PythonInstallerListDependencies" ,
258
+ ]
0 commit comments