Skip to content

Commit a08c4be

Browse files
committed
Basic abstraction and one migration
1 parent 3af9093 commit a08c4be

File tree

5 files changed

+104
-8
lines changed

5 files changed

+104
-8
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
2+
3+
if MYPY_CHECK_RUNNING:
4+
from typing import List, Optional
5+
6+
from .base import BaseEnvironment
7+
8+
9+
def get_environment(paths=None):
10+
# type: (Optional[List[str]]) -> BaseEnvironment
11+
from .pkg_resources import Environment
12+
13+
if paths is None:
14+
return Environment.default()
15+
return Environment.from_paths(paths)

src/pip/_internal/metadata/base.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
2+
3+
if MYPY_CHECK_RUNNING:
4+
from typing import List, Optional
5+
6+
7+
class BaseDistribution:
8+
@property
9+
def installer(self):
10+
# type: () -> str
11+
raise NotImplementedError()
12+
13+
14+
class BaseEnvironment:
15+
"""An environment containing distributions to introspect."""
16+
17+
@classmethod
18+
def default(cls):
19+
# type: () -> BaseEnvironment
20+
raise NotImplementedError()
21+
22+
@classmethod
23+
def from_paths(cls, paths):
24+
# type: (List[str]) -> BaseEnvironment
25+
raise NotImplementedError()
26+
27+
def get_distribution(self, name):
28+
# type: (str) -> Optional[BaseDistribution]
29+
raise NotImplementedError()
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
from pip._vendor import pkg_resources
2+
3+
from pip._internal.utils.packaging import get_installer
4+
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
5+
6+
from .base import BaseDistribution, BaseEnvironment
7+
8+
if MYPY_CHECK_RUNNING:
9+
from typing import List, Optional
10+
11+
12+
class Distribution(BaseDistribution):
13+
def __init__(self, dist):
14+
# type: (pkg_resources.Distribution) -> None
15+
self._dist = dist
16+
17+
@property
18+
def installer(self):
19+
# type: () -> str
20+
# TODO: Move get_installer() implementation here.
21+
return get_installer(self._dist)
22+
23+
24+
class Environment(BaseEnvironment):
25+
def __init__(self, ws):
26+
# type: (pkg_resources.WorkingSet) -> None
27+
self._ws = ws
28+
29+
@classmethod
30+
def default(cls):
31+
# type: () -> BaseEnvironment
32+
return cls(pkg_resources.working_set)
33+
34+
@classmethod
35+
def from_paths(cls, paths):
36+
# type: (List[str]) -> BaseEnvironment
37+
return cls(pkg_resources.WorkingSet(paths))
38+
39+
def get_distribution(self, name):
40+
# type: (str) -> Optional[BaseDistribution]
41+
req = pkg_resources.Requirement(name)
42+
try:
43+
dist = self._ws.find(req)
44+
except pkg_resources.DistributionNotFound:
45+
return None
46+
return Distribution(dist)

src/pip/_internal/self_outdated_check.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010

1111
from pip._internal.index.collector import LinkCollector
1212
from pip._internal.index.package_finder import PackageFinder
13+
from pip._internal.metadata import get_environment
1314
from pip._internal.models.selection_prefs import SelectionPreferences
1415
from pip._internal.utils.filesystem import adjacent_tmp_file, check_path_owner, replace
15-
from pip._internal.utils.misc import ensure_dir, get_distribution, get_installed_version
16-
from pip._internal.utils.packaging import get_installer
16+
from pip._internal.utils.misc import ensure_dir, get_installed_version
1717
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
1818

1919
if MYPY_CHECK_RUNNING:
@@ -103,10 +103,8 @@ def was_installed_by_pip(pkg):
103103
This is used not to display the upgrade message when pip is in fact
104104
installed by system package manager, such as dnf on Fedora.
105105
"""
106-
dist = get_distribution(pkg)
107-
if not dist:
108-
return False
109-
return "pip" == get_installer(dist)
106+
dist = get_environment().get_distribution(pkg)
107+
return dist is not None and "pip" == dist.installer
110108

111109

112110
def pip_self_version_check(session, options):

tests/unit/test_self_check_outdated.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,14 @@ def get_metadata_lines(self, name):
5757
raise NotImplementedError('nope')
5858

5959

60+
class MockEnvironment(object):
61+
def __init__(self, installer):
62+
self.installer = installer
63+
64+
def get_distribution(self, name):
65+
return MockDistribution(self.installer)
66+
67+
6068
def _options():
6169
''' Some default options that we pass to
6270
self_outdated_check.pip_self_version_check '''
@@ -97,8 +105,8 @@ def test_pip_self_version_check(monkeypatch, stored_time, installed_ver,
97105
pretend.call_recorder(lambda *a, **kw: None))
98106
monkeypatch.setattr(logger, 'debug',
99107
pretend.call_recorder(lambda s, exc_info=None: None))
100-
monkeypatch.setattr(self_outdated_check, 'get_distribution',
101-
lambda name: MockDistribution(installer))
108+
monkeypatch.setattr(self_outdated_check, 'get_environment',
109+
lambda: MockEnvironment(installer))
102110

103111
fake_state = pretend.stub(
104112
state={"last_check": stored_time, 'pypi_version': installed_ver},

0 commit comments

Comments
 (0)