2 from optparse
import Values
3 from typing
import Any
, Dict
, List
5 from pip
._vendor
.packaging
.markers
import default_environment
6 from pip
._vendor
.rich
import print_json
8 from pip
import __version__
9 from pip
._internal
.cli
import cmdoptions
10 from pip
._internal
.cli
.req_command
import Command
11 from pip
._internal
.cli
.status_codes
import SUCCESS
12 from pip
._internal
.metadata
import BaseDistribution
, get_environment
13 from pip
._internal
.utils
.compat
import stdlib_pkgs
14 from pip
._internal
.utils
.urls
import path_to_url
16 logger
= logging
.getLogger(__name__
)
19 class InspectCommand(Command
):
21 Inspect the content of a Python environment and produce a report in JSON format.
24 ignore_require_venv
= True
28 def add_options(self
) -> None:
29 self
.cmd_opts
.add_option(
34 "If in a virtualenv that has global access, do not list "
35 "globally-installed packages."
38 self
.cmd_opts
.add_option(
43 help="Only output packages installed in user-site.",
45 self
.cmd_opts
.add_option(cmdoptions
.list_path())
46 self
.parser
.insert_option_group(0, self
.cmd_opts
)
48 def run(self
, options
: Values
, args
: List
[str]) -> int:
49 cmdoptions
.check_list_path_option(options
)
50 dists
= get_environment(options
.path
).iter_installed_distributions(
51 local_only
=options
.local
,
52 user_only
=options
.user
,
53 skip
=set(stdlib_pkgs
),
57 "pip_version": __version__
,
58 "installed": [self
._dist
_to
_dict
(dist
) for dist
in dists
],
59 "environment": default_environment(),
62 print_json(data
=output
)
65 def _dist_to_dict(self
, dist
: BaseDistribution
) -> Dict
[str, Any
]:
66 res
: Dict
[str, Any
] = {
67 "metadata": dist
.metadata_dict
,
68 "metadata_location": dist
.info_location
,
70 # direct_url. Note that we don't have download_info (as in the installation
71 # report) since it is not recorded in installed metadata.
72 direct_url
= dist
.direct_url
73 if direct_url
is not None:
74 res
["direct_url"] = direct_url
.to_dict()
76 # Emulate direct_url for legacy editable installs.
77 editable_project_location
= dist
.editable_project_location
78 if editable_project_location
is not None:
80 "url": path_to_url(editable_project_location
),
86 installer
= dist
.installer
88 res
["installer"] = installer
90 if dist
.installed_with_dist_info
:
91 res
["requested"] = dist
.requested