Skip to content

Commit 8df7dcf

Browse files
committed
Add metadata field to pip list json output
1 parent bf1add7 commit 8df7dcf

File tree

4 files changed

+31
-4
lines changed

4 files changed

+31
-4
lines changed

docs/html/cli/pip_list.rst

+14-2
Original file line numberDiff line numberDiff line change
@@ -104,19 +104,31 @@ Examples
104104
105105
#. Use json formatting
106106

107+
The ``metadata`` field is the distribution metadata, converted to JSON using the
108+
transformation described in `PEP 566
109+
<https://peps.python.org/pep-0566/#json-compatible-metadata>`_.
110+
107111
.. tab:: Unix/macOS
108112

109113
.. code-block:: console
110114
111115
$ python -m pip list --format=json
112-
[{'name': 'colorama', 'version': '0.3.7'}, {'name': 'docopt', 'version': '0.6.2'}, ...
116+
[
117+
{'name': 'colorama', 'version': '0.3.7', 'metadata': {...}},
118+
{'name': 'docopt', 'version': '0.6.2', 'metadata': {...}},
119+
...
120+
]
113121
114122
.. tab:: Windows
115123

116124
.. code-block:: console
117125
118126
C:\> py -m pip list --format=json
119-
[{'name': 'colorama', 'version': '0.3.7'}, {'name': 'docopt', 'version': '0.6.2'}, ...
127+
[
128+
{'name': 'colorama', 'version': '0.3.7', 'metadata': {...}},
129+
{'name': 'docopt', 'version': '0.6.2', 'metadata': {...}},
130+
...
131+
]
120132
121133
#. Use freeze formatting
122134

news/11097.feature.rst

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add a ``metadata`` field to the ``pip list`` JSON output.

src/pip/_internal/commands/list.py

+13-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,17 @@
11
import json
22
import logging
33
from optparse import Values
4-
from typing import TYPE_CHECKING, Generator, List, Optional, Sequence, Tuple, cast
4+
from typing import (
5+
TYPE_CHECKING,
6+
Any,
7+
Dict,
8+
Generator,
9+
List,
10+
Optional,
11+
Sequence,
12+
Tuple,
13+
cast,
14+
)
515

616
from pip._vendor.packaging.utils import canonicalize_name
717

@@ -344,7 +354,7 @@ def format_for_columns(
344354
def format_for_json(packages: "_ProcessedDists", options: Values) -> str:
345355
data = []
346356
for dist in packages:
347-
info = {
357+
info: Dict[str, Any] = {
348358
"name": dist.raw_name,
349359
"version": str(dist.version),
350360
}
@@ -357,5 +367,6 @@ def format_for_json(packages: "_ProcessedDists", options: Values) -> str:
357367
editable_project_location = dist.editable_project_location
358368
if editable_project_location:
359369
info["editable_project_location"] = editable_project_location
370+
info["metadata"] = dist.json_metadata
360371
data.append(info)
361372
return json.dumps(data)

tests/functional/test_list.py

+3
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,9 @@ def test_list_json(simple_script: PipTestEnvironment) -> None:
682682
data = json.loads(result.stdout)
683683
assert subdict_in_list({"name": "simple", "version": "1.0"}, data)
684684
assert subdict_in_list({"name": "simple2", "version": "3.0"}, data)
685+
for item in data:
686+
assert item["metadata"]["name"] == item["name"]
687+
assert item["metadata"]["version"] == item["version"]
685688

686689

687690
def test_list_path(tmpdir: Path, script: PipTestEnvironment, data: TestData) -> None:

0 commit comments

Comments
 (0)