Skip to content

Commit f9327fe

Browse files
Fix non-devel installs. (#121)
(for #120) In some cases the wrong files were getting installed. Also, running from a development env (AKA, git checkout) causes pyperformance to get installed into a venv. However, pip treats this as a "develop" install and the venv basically has a link back to the original files (rather than making a copy). This lead to incorrect logic when detecting "is installed" Both issues are resolved here.
1 parent d2f37e5 commit f9327fe

File tree

5 files changed

+57
-22
lines changed

5 files changed

+57
-22
lines changed

MANIFEST.in

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@ include TODO.rst
66
include requirements.in
77
include requirements.txt
88
include runtests.py
9-
include pyperformance
109
include tox.ini
1110

1211
include doc/*.rst doc/images/*.png doc/images/*.jpg
1312
include doc/conf.py doc/Makefile doc/make.bat
1413

14+
include pyperformance/*.py
1515
include pyperformance/data-files/requirements.txt
1616
include pyperformance/data-files/benchmarks/MANIFEST
17-
include pyperformance/data-files/benchmarks/base.toml
18-
recursive-include pyperformance/data-files/benchmarks/bm_*/* *
17+
include pyperformance/data-files/benchmarks/bm_*/*.toml
18+
include pyperformance/data-files/benchmarks/bm_*/*.py
19+
recursive-include pyperformance/data-files/benchmarks/bm_*/data *
20+
recursive-exclude pyperformance/tests *

pyperformance/__init__.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import os.path
2+
import sys
23

34

45
VERSION = (1, 0, 3)
@@ -11,4 +12,31 @@
1112

1213
def is_installed():
1314
parent = os.path.dirname(PKG_ROOT)
14-
return os.path.exists(os.path.join(parent, 'setup.py'))
15+
if not os.path.exists(os.path.join(parent, 'setup.py')):
16+
return True
17+
if _is_venv():
18+
return True
19+
return _is_devel_install()
20+
21+
22+
def _is_venv():
23+
if sys.base_prefix == sys.prefix:
24+
return False
25+
return True
26+
27+
28+
def _is_devel_install():
29+
# pip install <path-to-git-checkout> will do a "devel" install.
30+
# This means it creates a link back to the checkout instead
31+
# of copying the files.
32+
try:
33+
import toml
34+
except ModuleNotFoundError:
35+
return False
36+
sitepackages = os.path.dirname(toml.__file__)
37+
if os.path.isdir(os.path.join(sitepackages, 'pyperformance')):
38+
return False
39+
if not os.path.exists(os.path.join(sitepackages, 'pyperformance.egg-link')):
40+
# XXX Check the contents?
41+
return False
42+
return True

pyperformance/cli.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,10 @@ def parse_args():
201201
@contextlib.contextmanager
202202
def _might_need_venv(options):
203203
try:
204+
if not is_installed():
205+
# Always force a local checkout to be installed.
206+
assert not options.inside_venv
207+
raise ModuleNotFoundError
204208
yield
205209
except ModuleNotFoundError:
206210
if not options.inside_venv:
@@ -251,14 +255,12 @@ def _select_benchmarks(raw, manifest):
251255
def _main():
252256
parser, options = parse_args()
253257

254-
if not is_installed():
255-
assert not options.inside_venv
256-
print('switching to a venv.', flush=True)
257-
exec_in_virtualenv(options)
258-
259258
if options.action == 'venv':
260-
with _might_need_venv(options):
261-
benchmarks = _benchmarks_from_options(options)
259+
if options.venv_action in ('create', 'recreate'):
260+
with _might_need_venv(options):
261+
benchmarks = _benchmarks_from_options(options)
262+
else:
263+
benchmarks = None
262264
cmd_venv(options, benchmarks)
263265
sys.exit()
264266
elif options.action == 'compile':

pyperformance/tests/test_compare.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ def compare(self, *args, **kw):
4545
else:
4646
file1 = 'py36.json'
4747
file2 = kw.get('file2', 'py38.json')
48+
marker = file1
4849

4950
cmd = [sys.executable, '-m', 'pyperformance', 'compare',
5051
os.path.join(DATA_DIR, file1),
@@ -55,6 +56,8 @@ def compare(self, *args, **kw):
5556
universal_newlines=True)
5657
stdout = proc.communicate()[0]
5758
self.assertEqual(proc.returncode, exitcode, repr(stdout))
59+
if marker in stdout:
60+
stdout = stdout[stdout.index(marker):]
5861
return stdout.rstrip() + "\n"
5962

6063
def test_compare(self):

pyperformance/venv.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
REQUIREMENTS_FILE = os.path.join(pyperformance.DATA_DIR, 'requirements.txt')
2121

2222

23+
# XXX Use pyperformance.is_installed() instead?
2324
def is_build_dir():
2425
root_dir = os.path.join(PERFORMANCE_ROOT, '..')
2526
if not os.path.exists(os.path.join(root_dir, 'pyperformance')):
@@ -113,10 +114,12 @@ def get(self, name):
113114

114115
def safe_rmtree(path):
115116
if not os.path.exists(path):
116-
return
117+
return False
117118

118119
print("Remove directory %s" % path)
120+
# XXX Pass onerror to report on any files that could not be deleted?
119121
shutil.rmtree(path)
122+
return True
120123

121124

122125
def python_implementation():
@@ -548,10 +551,6 @@ def exec_in_virtualenv(options):
548551

549552

550553
def cmd_venv(options, benchmarks=None):
551-
action = options.venv_action
552-
553-
requirements = Requirements.from_benchmarks(benchmarks)
554-
555554
venv = VirtualEnvironment(
556555
options.python,
557556
options.venv,
@@ -560,7 +559,9 @@ def cmd_venv(options, benchmarks=None):
560559
venv_path = venv.get_path()
561560
exists = venv.exists()
562561

562+
action = options.venv_action
563563
if action == 'create':
564+
requirements = Requirements.from_benchmarks(benchmarks)
564565
if exists:
565566
print("The virtual environment %s already exists" % venv_path)
566567
venv.ensure()
@@ -569,6 +570,7 @@ def cmd_venv(options, benchmarks=None):
569570
print("The virtual environment %s has been created" % venv_path)
570571

571572
elif action == 'recreate':
573+
requirements = Requirements.from_benchmarks(benchmarks)
572574
if exists:
573575
if venv.get_python_program() == sys.executable:
574576
print("The virtual environment %s already exists" % venv_path)
@@ -577,7 +579,7 @@ def cmd_venv(options, benchmarks=None):
577579
venv.install_reqs(requirements, exitonerror=True)
578580
else:
579581
print("The virtual environment %s already exists" % venv_path)
580-
shutil.rmtree(venv_path)
582+
safe_rmtree(venv_path)
581583
print("The old virtual environment %s has been removed" % venv_path)
582584
print()
583585
venv.ensure()
@@ -589,23 +591,21 @@ def cmd_venv(options, benchmarks=None):
589591
print("The virtual environment %s has been created" % venv_path)
590592

591593
elif action == 'remove':
592-
if os.path.exists(venv_path):
593-
shutil.rmtree(venv_path)
594+
if safe_rmtree(venv_path):
594595
print("The virtual environment %s has been removed" % venv_path)
595596
else:
596597
print("The virtual environment %s does not exist" % venv_path)
597598

598599
else:
599600
# show command
600601
text = "Virtual environment path: %s" % venv_path
601-
created = venv.exists()
602-
if created:
602+
if exists:
603603
text += " (already created)"
604604
else:
605605
text += " (not created yet)"
606606
print(text)
607607

608-
if not created:
608+
if not exists:
609609
print()
610610
print("Command to create it:")
611611
cmd = "%s -m pyperformance venv create" % options.python

0 commit comments

Comments
 (0)