|
1 | 1 | from __future__ import annotations
|
2 | 2 |
|
| 3 | +import ast |
3 | 4 | import site
|
| 5 | +import subprocess # noqa: S404 |
4 | 6 | import sys
|
5 | 7 | from importlib.metadata import Distribution, distributions
|
| 8 | +from pathlib import Path |
6 | 9 | from typing import Iterable, Tuple
|
7 | 10 |
|
8 | 11 | from packaging.utils import canonicalize_name
|
9 | 12 |
|
10 | 13 |
|
11 | 14 | def get_installed_distributions(
|
| 15 | + interpreter: str = str(sys.executable), |
12 | 16 | local_only: bool = False, # noqa: FBT001, FBT002
|
13 | 17 | user_only: bool = False, # noqa: FBT001, FBT002
|
14 | 18 | ) -> list[Distribution]:
|
15 | 19 | # See https://docs.python.org/3/library/venv.html#how-venvs-work for more details.
|
16 | 20 | in_venv = sys.prefix != sys.base_prefix
|
17 | 21 | original_dists: Iterable[Distribution] = []
|
| 22 | + py_path = Path(interpreter).absolute() |
| 23 | + using_custom_interpreter = py_path != Path(sys.executable).absolute() |
18 | 24 |
|
19 |
| - if local_only and in_venv: |
| 25 | + if user_only: |
| 26 | + original_dists = distributions(path=[site.getusersitepackages()]) |
| 27 | + elif using_custom_interpreter: |
| 28 | + # We query the interpreter directly to get the `path` which is used by distributions(), |
| 29 | + # so we can search the customer dists with it. |
| 30 | + # If --python and --local-only are given at the same time, it means the dists only in |
| 31 | + # customer's env are needed. (.e.g --system-site-packages is given when creating venv) |
| 32 | + if local_only: |
| 33 | + args = "import sys, site; print(site.getsitepackages([sys.prefix]))" |
| 34 | + else: |
| 35 | + args = "import sys; print(sys.path)" |
| 36 | + |
| 37 | + cmd = [str(py_path), "-c", args] |
| 38 | + result = subprocess.run(cmd, stdout=subprocess.PIPE, check=False) # noqa: S603 |
| 39 | + original_dists = distributions(path=ast.literal_eval(result.stdout.decode("utf-8"))) |
| 40 | + elif local_only and in_venv: |
20 | 41 | venv_site_packages = site.getsitepackages([sys.prefix])
|
21 | 42 | original_dists = distributions(path=venv_site_packages)
|
22 |
| - elif user_only: |
23 |
| - original_dists = distributions(path=[site.getusersitepackages()]) |
24 | 43 | else:
|
25 | 44 | original_dists = distributions()
|
26 | 45 |
|
|
0 commit comments