Merge pull request #128 from gaborbernat/master

Allow querying non-host python intepreters
This commit is contained in:
Vineet Naik 2020-09-22 15:38:18 +05:30 committed by GitHub
commit e01462c25d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 112 additions and 26 deletions

View File

@ -25,16 +25,27 @@ jobs:
- pypy3
- pypy2
steps:
- name: Setup graphviz
uses: ts-graphviz/setup-graphviz@v1
- name: Setup python for tox
uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Install tox
run: python -m pip install tox
- name: Setup python for test ${{ matrix.py }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.py }}
- uses: actions/checkout@v2
- name: Setup graphviz
uses: ts-graphviz/setup-graphviz@v1
- name: Install dev requirements
run: pip install -r dev-requirements.txt
- name: Install project
run: pip install .[graphviz]
- name: Pick tox environment to run
run: |
import platform
import sys
major, minor, impl = sys.version_info[0], sys.version_info[1], platform.python_implementation()
print('::set-env name=TOXENV::' + ("py" if impl == "CPython" else "pypy") + ("{}{}".format(major, minor) if impl == "CPython" else ("3" if major == 3 else "")))
shell: python
- name: Setup test suite
run: tox -vv --notest
- name: Run test suite
run: pytest -v tests
run: tox --skip-pkg-install

View File

@ -1,6 +0,0 @@
pytest
pytest-cov
jinja2
ipython
flake8
mock;python_version<"3"

View File

@ -1,12 +1,15 @@
from __future__ import print_function
import os
import inspect
import sys
import subprocess
from itertools import chain
from collections import defaultdict, deque
import argparse
from operator import attrgetter
import json
from importlib import import_module
import tempfile
try:
from collections import OrderedDict
@ -711,6 +714,9 @@ def get_parser():
version='{0}'.format(__version__))
parser.add_argument('-f', '--freeze', action='store_true',
help='Print names so as to write freeze files')
parser.add_argument('--python', default=sys.executable,
help='Python to use to look for packages in it (default: where'
' installed)')
parser.add_argument('-a', '--all', action='store_true',
help='list all deps at top level')
parser.add_argument('-l', '--local-only',
@ -775,9 +781,43 @@ def _get_args():
return parser.parse_args()
def handle_non_host_target(args):
of_python = os.path.abspath(args.python)
# if target is not current python re-invoke it under the actual host
if of_python != os.path.abspath(sys.executable):
# there's no way to guarantee that graphviz is available, so refuse
if args.output_format:
print("graphviz functionality is not supported when querying"
" non-host python", file=sys.stderr)
raise SystemExit(1)
argv = sys.argv[1:] # remove current python executable
for py_at, value in enumerate(argv):
if value == "--python":
del argv[py_at]
del argv[py_at]
elif value.startswith("--python"):
del argv[py_at]
# feed the file as argument, instead of file
# to avoid adding the file path to sys.path, that can affect result
file_path = inspect.getsourcefile(sys.modules[__name__])
with open(file_path, 'rt') as file_handler:
content = file_handler.read()
cmd = [of_python, "-c", content]
cmd.extend(argv)
# invoke from an empty folder to avoid cwd altering sys.path
cwd = tempfile.mkdtemp()
try:
return subprocess.call(cmd, cwd=cwd)
finally:
os.removedirs(cwd)
return None
def main():
args = _get_args()
result = handle_non_host_target(args)
if result is not None:
return result
pkgs = get_installed_distributions(local_only=args.local_only,
user_only=args.user_only)

View File

@ -1,4 +1,5 @@
from contextlib import contextmanager
import platform
import sys
from tempfile import NamedTemporaryFile
try:
@ -7,6 +8,7 @@ except ImportError:
import mock
import pytest
import virtualenv
import pipdeptree as p
@ -520,3 +522,33 @@ def test_parser_svg():
args = parser.parse_args(['--graph-output', 'svg'])
assert args.output_format == 'svg'
assert not args.json
@pytest.mark.parametrize("args_joined", [True, False])
def test_custom_interpreter(tmp_path, monkeypatch, capfd, args_joined):
result = virtualenv.cli_run([str(tmp_path), "--activators", ""])
cmd = [sys.executable]
cmd += ["--python={}".format(result.creator.exe)] if args_joined else ["--python", str(result.creator.exe)]
monkeypatch.setattr(sys, "argv", cmd)
p.main()
out, _ = capfd.readouterr()
found = {i.split("==")[0] for i in out.splitlines()}
implementation = platform.python_implementation()
if implementation == "CPython":
expected = {"pip", "setuptools", "wheel"}
elif implementation == "PyPy":
expected = {"cffi", "greenlet", "pip", "readline", "setuptools", "wheel"}
else:
raise ValueError(implementation)
assert found == expected, out
monkeypatch.setattr(sys, "argv", cmd + ["--graph-output", "something"])
with pytest.raises(SystemExit) as context:
p.main()
out, err = capfd.readouterr()
assert context.value.code == 1
assert not out
assert err == "graphviz functionality is not supported when querying" " non-host python\n"

23
tox.ini
View File

@ -1,17 +1,26 @@
# Tox (http://tox.testrun.org/) is a tool for running tests
# in multiple virtualenvs. This configuration file will run the
# test suite on all supported python versions. To use it, "pip install tox"
# and then run "tox" from this directory.
# http://tox.readthedocs.org/ - sets up and runs the test suite based on a declarative configuration
[tox]
envlist = py27, py34, py35, py36, py37, py38
envlist =
py39
py38
py37
py36
py35
py34
py27
pypy3
pypy2
[testenv]
description = run test suite under {basepython}
commands =
pytest {posargs:-vv}
deps =
tox>=3.0.0
graphviz
pip>=8.0.2
pytest
pytest-cov
virtualenv>=20,<21
mock;python_version<"3"
extras =
graphviz