Skip to content

Commit b693a4d

Browse files
Always Try to Install psutil (#170)
(see #148) pyperf treated psutil as an optional dependency. Most of the time it should be installable, but we weren't really even trying. This change fixes that.
1 parent 9ba3fb4 commit b693a4d

File tree

2 files changed

+34
-36
lines changed

2 files changed

+34
-36
lines changed

pyperformance/_pip.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,16 @@
1414
OLD_SETUPTOOLS = '18.5'
1515

1616

17+
def get_pkg_name(req):
18+
"""Return the name of the package in the given requirement text."""
19+
# strip env markers
20+
req = req.partition(';')[0]
21+
# strip version
22+
req = req.partition('==')[0]
23+
req = req.partition('>=')[0]
24+
return req
25+
26+
1727
def get_best_pip_version(python):
1828
"""Return the pip to install for the given Python executable."""
1929
if not python or isinstance(python, str):

pyperformance/venv.py

Lines changed: 24 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@
77

88

99
REQUIREMENTS_FILE = os.path.join(pyperformance.DATA_DIR, 'requirements.txt')
10+
PYPERF_OPTIONAL = ['psutil']
1011

1112

1213
class Requirements(object):
1314

1415
@classmethod
15-
def from_file(cls, filename, optional=None):
16+
def from_file(cls, filename):
1617
self = cls()
17-
self._add_from_file(filename, optional)
18+
self._add_from_file(filename)
1819
return self
1920

2021
@classmethod
@@ -32,44 +33,25 @@ def __init__(self):
3233
# requirements
3334
self.specs = []
3435

35-
# optional requirements
36-
self._optional = set()
37-
3836
def __len__(self):
3937
return len(self.specs)
4038

41-
def iter_non_optional(self):
42-
for spec in self.specs:
43-
if spec in self._optional:
44-
continue
45-
yield spec
46-
47-
def iter_optional(self):
39+
def __iter__(self):
4840
for spec in self.specs:
49-
if spec not in self._optional:
50-
continue
5141
yield spec
5242

53-
def _add_from_file(self, filename, optional=None):
43+
def _add_from_file(self, filename):
5444
if not os.path.exists(filename):
5545
return
5646
for line in _utils.iter_clean_lines(filename):
57-
self._add(line, optional)
47+
self._add(line)
5848

59-
def _add(self, line, optional=None):
49+
def _add(self, line):
6050
self.specs.append(line)
61-
if optional:
62-
# strip env markers
63-
req = line.partition(';')[0]
64-
# strip version
65-
req = req.partition('==')[0]
66-
req = req.partition('>=')[0]
67-
if req in optional:
68-
self._optional.add(line)
6951

7052
def get(self, name):
7153
for req in self.specs:
72-
if req.startswith(name):
54+
if _pip.get_pkg_name(req) == name:
7355
return req
7456
return None
7557

@@ -186,8 +168,10 @@ def install_pyperformance(self):
186168
print("installing pyperformance in the venv at %s" % self.root)
187169
# Install pyperformance inside the virtual environment.
188170
if pyperformance.is_dev():
189-
basereqs = Requirements.from_file(REQUIREMENTS_FILE, ['psutil'])
171+
basereqs = Requirements.from_file(REQUIREMENTS_FILE)
190172
self.ensure_reqs(basereqs)
173+
if basereqs.get('pyperf'):
174+
self._install_pyperf_optional_dependencies()
191175

192176
root_dir = os.path.dirname(pyperformance.PKG_ROOT)
193177
ec, _, _ = _pip.install_editable(
@@ -202,9 +186,18 @@ def install_pyperformance(self):
202186
python=self.info,
203187
env=self._env,
204188
)
189+
self._install_pyperf_optional_dependencies()
205190
if ec != 0:
206191
sys.exit(ec)
207192

193+
def _install_pyperf_optional_dependencies(self):
194+
for req in PYPERF_OPTIONAL:
195+
try:
196+
self.ensure_reqs([req])
197+
except _venv.RequirementsInstallationFailedError:
198+
print("WARNING: failed to install %s" % req)
199+
pass
200+
208201
def ensure_reqs(self, requirements=None, *, exitonerror=False):
209202
# parse requirements
210203
bench = None
@@ -216,7 +209,7 @@ def ensure_reqs(self, requirements=None, *, exitonerror=False):
216209

217210
# Every benchmark must depend on pyperf.
218211
if bench is not None and not requirements.get('pyperf'):
219-
basereqs = Requirements.from_file(REQUIREMENTS_FILE, ['psutil'])
212+
basereqs = Requirements.from_file(REQUIREMENTS_FILE)
220213
pyperf_req = basereqs.get('pyperf')
221214
if not pyperf_req:
222215
raise NotImplementedError
@@ -229,21 +222,16 @@ def ensure_reqs(self, requirements=None, *, exitonerror=False):
229222
# install requirements
230223
try:
231224
super().ensure_reqs(
232-
*requirements.iter_non_optional(),
225+
*requirements,
233226
upgrade=False,
234227
)
235228
except _venv.RequirementsInstallationFailedError:
236229
if exitonerror:
237230
sys.exit(1)
238231
raise # re-raise
239232

240-
# install optional requirements
241-
for req in requirements.iter_optional():
242-
try:
243-
super().ensure_reqs(req, upgrade=True)
244-
except _venv.RequirementsInstallationFailedError:
245-
print("WARNING: failed to install %s" % req)
246-
print()
233+
if bench is not None:
234+
self._install_pyperf_optional_dependencies()
247235

248236
# Dump the package list and their versions: pip freeze
249237
_pip.run_pip('freeze', python=self.python, env=self._env)

0 commit comments

Comments
 (0)