Skip to content

Commit 87c92ad

Browse files
committed
Implement multi-backend metadata
1 parent 07d9181 commit 87c92ad

File tree

4 files changed

+108
-45
lines changed

4 files changed

+108
-45
lines changed
+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
"""
2+
This package wraps the vendored importlib_metadata and pkg_resources to
3+
provide a (mostly) compatible shim.
4+
5+
The pkg_resources implementation is used on Python 2, otherwise we use
6+
importlib_metadata.
7+
"""
8+
9+
__all__ = [
10+
"Distribution",
11+
"get_file_lines",
12+
"get_metadata",
13+
]
14+
15+
import sys
16+
17+
if sys.version_info < (3, 5):
18+
from pip._internal.metadata._pkg_resources import (
19+
Distribution,
20+
get_file_lines,
21+
get_metadata,
22+
)
23+
else:
24+
from pip._internal.metadata._importlib_metadata import (
25+
Distribution,
26+
get_file_lines,
27+
get_metadata,
28+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
2+
3+
if MYPY_CHECK_RUNNING:
4+
from email.message import Message
5+
from typing import Iterator, Optional
6+
from pip._vendor.importlib_metadata import Distribution
7+
8+
9+
def get_metadata(dist):
10+
# type: (Distribution) -> Message
11+
return dist.metadata
12+
13+
14+
def get_file_lines(dist, name):
15+
# type: (Distribution, str) -> Optional[Iterator[str]]
16+
content = dist.read_text("INSTALLER")
17+
if not content:
18+
return None
19+
return content.splitlines()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
from __future__ import absolute_import
2+
3+
import logging
4+
from email.parser import FeedParser
5+
6+
from pip._vendor import pkg_resources
7+
8+
from pip._internal.exceptions import NoneMetadataError
9+
from pip._internal.utils.misc import display_path
10+
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
11+
12+
if MYPY_CHECK_RUNNING:
13+
from typing import Iterator, Optional
14+
from email.message import Message
15+
from pip._vendor.pkg_resources import Distribution
16+
17+
18+
logger = logging.getLogger(__name__)
19+
20+
21+
def get_metadata(dist):
22+
# type: (Distribution) -> Message
23+
"""
24+
:raises NoneMetadataError: if the distribution reports `has_metadata()`
25+
True but `get_metadata()` returns None.
26+
"""
27+
metadata_name = 'METADATA'
28+
if (isinstance(dist, pkg_resources.DistInfoDistribution) and
29+
dist.has_metadata(metadata_name)):
30+
metadata = dist.get_metadata(metadata_name)
31+
elif dist.has_metadata('PKG-INFO'):
32+
metadata_name = 'PKG-INFO'
33+
metadata = dist.get_metadata(metadata_name)
34+
else:
35+
logger.warning("No metadata found in %s", display_path(dist.location))
36+
metadata = ''
37+
38+
if metadata is None:
39+
raise NoneMetadataError(dist, metadata_name)
40+
41+
feed_parser = FeedParser()
42+
# The following line errors out if with a "NoneType" TypeError if
43+
# passed metadata=None.
44+
feed_parser.feed(metadata)
45+
return feed_parser.close()
46+
47+
48+
def get_file_lines(dist, name):
49+
# type: (Distribution, str) -> Optional[Iterator[str]]
50+
if not dist.has_metadata(name):
51+
return None
52+
return dist.get_metadata_lines(name)

src/pip/_internal/utils/packaging.py

+9-45
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,11 @@
1-
from __future__ import absolute_import
2-
3-
import logging
4-
from email.parser import FeedParser
5-
6-
from pip._vendor import pkg_resources
71
from pip._vendor.packaging import specifiers, version
82

9-
from pip._internal.exceptions import NoneMetadataError
10-
from pip._internal.utils.misc import display_path
3+
from pip._internal.metadata import get_file_lines, get_metadata
114
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
125

136
if MYPY_CHECK_RUNNING:
147
from typing import Optional, Tuple
15-
from email.message import Message
16-
from pip._vendor.pkg_resources import Distribution
17-
18-
19-
logger = logging.getLogger(__name__)
8+
from pip._internal.metadata import Distribution
209

2110

2211
def check_requires_python(requires_python, version_info):
@@ -41,35 +30,8 @@ def check_requires_python(requires_python, version_info):
4130
return python_version in requires_python_specifier
4231

4332

44-
def get_metadata(dist):
45-
# type: (Distribution) -> Message
46-
"""
47-
:raises NoneMetadataError: if the distribution reports `has_metadata()`
48-
True but `get_metadata()` returns None.
49-
"""
50-
metadata_name = 'METADATA'
51-
if (isinstance(dist, pkg_resources.DistInfoDistribution) and
52-
dist.has_metadata(metadata_name)):
53-
metadata = dist.get_metadata(metadata_name)
54-
elif dist.has_metadata('PKG-INFO'):
55-
metadata_name = 'PKG-INFO'
56-
metadata = dist.get_metadata(metadata_name)
57-
else:
58-
logger.warning("No metadata found in %s", display_path(dist.location))
59-
metadata = ''
60-
61-
if metadata is None:
62-
raise NoneMetadataError(dist, metadata_name)
63-
64-
feed_parser = FeedParser()
65-
# The following line errors out if with a "NoneType" TypeError if
66-
# passed metadata=None.
67-
feed_parser.feed(metadata)
68-
return feed_parser.close()
69-
70-
7133
def get_requires_python(dist):
72-
# type: (pkg_resources.Distribution) -> Optional[str]
34+
# type: (Distribution) -> Optional[str]
7335
"""
7436
Return the "Requires-Python" metadata for a distribution, or None
7537
if not present.
@@ -87,8 +49,10 @@ def get_requires_python(dist):
8749

8850
def get_installer(dist):
8951
# type: (Distribution) -> str
90-
if dist.has_metadata('INSTALLER'):
91-
for line in dist.get_metadata_lines('INSTALLER'):
92-
if line.strip():
93-
return line.strip()
52+
lines = get_file_lines(dist, 'INSTALLER')
53+
if lines is None:
54+
return ''
55+
for line in lines:
56+
if line.strip():
57+
return line.strip()
9458
return ''

0 commit comments

Comments
 (0)