Skip to content

Commit

Permalink
Fix non-devel installs. (#121)
Browse files Browse the repository at this point in the history
(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.
  • Loading branch information
ericsnowcurrently authored Jan 4, 2022
1 parent d2f37e5 commit f9327fe
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 22 deletions.
8 changes: 5 additions & 3 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ include TODO.rst
include requirements.in
include requirements.txt
include runtests.py
include pyperformance
include tox.ini

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

include pyperformance/*.py
include pyperformance/data-files/requirements.txt
include pyperformance/data-files/benchmarks/MANIFEST
include pyperformance/data-files/benchmarks/base.toml
recursive-include pyperformance/data-files/benchmarks/bm_*/* *
include pyperformance/data-files/benchmarks/bm_*/*.toml
include pyperformance/data-files/benchmarks/bm_*/*.py
recursive-include pyperformance/data-files/benchmarks/bm_*/data *
recursive-exclude pyperformance/tests *
30 changes: 29 additions & 1 deletion pyperformance/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os.path
import sys


VERSION = (1, 0, 3)
Expand All @@ -11,4 +12,31 @@

def is_installed():
parent = os.path.dirname(PKG_ROOT)
return os.path.exists(os.path.join(parent, 'setup.py'))
if not os.path.exists(os.path.join(parent, 'setup.py')):
return True
if _is_venv():
return True
return _is_devel_install()


def _is_venv():
if sys.base_prefix == sys.prefix:
return False
return True


def _is_devel_install():
# pip install <path-to-git-checkout> will do a "devel" install.
# This means it creates a link back to the checkout instead
# of copying the files.
try:
import toml
except ModuleNotFoundError:
return False
sitepackages = os.path.dirname(toml.__file__)
if os.path.isdir(os.path.join(sitepackages, 'pyperformance')):
return False
if not os.path.exists(os.path.join(sitepackages, 'pyperformance.egg-link')):
# XXX Check the contents?
return False
return True
16 changes: 9 additions & 7 deletions pyperformance/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,10 @@ def parse_args():
@contextlib.contextmanager
def _might_need_venv(options):
try:
if not is_installed():
# Always force a local checkout to be installed.
assert not options.inside_venv
raise ModuleNotFoundError
yield
except ModuleNotFoundError:
if not options.inside_venv:
Expand Down Expand Up @@ -251,14 +255,12 @@ def _select_benchmarks(raw, manifest):
def _main():
parser, options = parse_args()

if not is_installed():
assert not options.inside_venv
print('switching to a venv.', flush=True)
exec_in_virtualenv(options)

if options.action == 'venv':
with _might_need_venv(options):
benchmarks = _benchmarks_from_options(options)
if options.venv_action in ('create', 'recreate'):
with _might_need_venv(options):
benchmarks = _benchmarks_from_options(options)
else:
benchmarks = None
cmd_venv(options, benchmarks)
sys.exit()
elif options.action == 'compile':
Expand Down
3 changes: 3 additions & 0 deletions pyperformance/tests/test_compare.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ def compare(self, *args, **kw):
else:
file1 = 'py36.json'
file2 = kw.get('file2', 'py38.json')
marker = file1

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

def test_compare(self):
Expand Down
22 changes: 11 additions & 11 deletions pyperformance/venv.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
REQUIREMENTS_FILE = os.path.join(pyperformance.DATA_DIR, 'requirements.txt')


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

def safe_rmtree(path):
if not os.path.exists(path):
return
return False

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


def python_implementation():
Expand Down Expand Up @@ -548,10 +551,6 @@ def exec_in_virtualenv(options):


def cmd_venv(options, benchmarks=None):
action = options.venv_action

requirements = Requirements.from_benchmarks(benchmarks)

venv = VirtualEnvironment(
options.python,
options.venv,
Expand All @@ -560,7 +559,9 @@ def cmd_venv(options, benchmarks=None):
venv_path = venv.get_path()
exists = venv.exists()

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

elif action == 'recreate':
requirements = Requirements.from_benchmarks(benchmarks)
if exists:
if venv.get_python_program() == sys.executable:
print("The virtual environment %s already exists" % venv_path)
Expand All @@ -577,7 +579,7 @@ def cmd_venv(options, benchmarks=None):
venv.install_reqs(requirements, exitonerror=True)
else:
print("The virtual environment %s already exists" % venv_path)
shutil.rmtree(venv_path)
safe_rmtree(venv_path)
print("The old virtual environment %s has been removed" % venv_path)
print()
venv.ensure()
Expand All @@ -589,23 +591,21 @@ def cmd_venv(options, benchmarks=None):
print("The virtual environment %s has been created" % venv_path)

elif action == 'remove':
if os.path.exists(venv_path):
shutil.rmtree(venv_path)
if safe_rmtree(venv_path):
print("The virtual environment %s has been removed" % venv_path)
else:
print("The virtual environment %s does not exist" % venv_path)

else:
# show command
text = "Virtual environment path: %s" % venv_path
created = venv.exists()
if created:
if exists:
text += " (already created)"
else:
text += " (not created yet)"
print(text)

if not created:
if not exists:
print()
print("Command to create it:")
cmd = "%s -m pyperformance venv create" % options.python
Expand Down

0 comments on commit f9327fe

Please sign in to comment.