Merge pull request #128 from gaborbernat/master
Allow querying non-host python intepreters
This commit is contained in:
commit
e01462c25d
|
@ -25,16 +25,27 @@ jobs:
|
||||||
- pypy3
|
- pypy3
|
||||||
- pypy2
|
- pypy2
|
||||||
steps:
|
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 }}
|
- name: Setup python for test ${{ matrix.py }}
|
||||||
uses: actions/setup-python@v2
|
uses: actions/setup-python@v2
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.py }}
|
python-version: ${{ matrix.py }}
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Setup graphviz
|
- name: Pick tox environment to run
|
||||||
uses: ts-graphviz/setup-graphviz@v1
|
run: |
|
||||||
- name: Install dev requirements
|
import platform
|
||||||
run: pip install -r dev-requirements.txt
|
import sys
|
||||||
- name: Install project
|
major, minor, impl = sys.version_info[0], sys.version_info[1], platform.python_implementation()
|
||||||
run: pip install .[graphviz]
|
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
|
- name: Run test suite
|
||||||
run: pytest -v tests
|
run: tox --skip-pkg-install
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
pytest
|
|
||||||
pytest-cov
|
|
||||||
jinja2
|
|
||||||
ipython
|
|
||||||
flake8
|
|
||||||
mock;python_version<"3"
|
|
|
@ -1,12 +1,15 @@
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
import os
|
import os
|
||||||
|
import inspect
|
||||||
import sys
|
import sys
|
||||||
|
import subprocess
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
from collections import defaultdict, deque
|
from collections import defaultdict, deque
|
||||||
import argparse
|
import argparse
|
||||||
from operator import attrgetter
|
from operator import attrgetter
|
||||||
import json
|
import json
|
||||||
from importlib import import_module
|
from importlib import import_module
|
||||||
|
import tempfile
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
@ -711,6 +714,9 @@ def get_parser():
|
||||||
version='{0}'.format(__version__))
|
version='{0}'.format(__version__))
|
||||||
parser.add_argument('-f', '--freeze', action='store_true',
|
parser.add_argument('-f', '--freeze', action='store_true',
|
||||||
help='Print names so as to write freeze files')
|
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',
|
parser.add_argument('-a', '--all', action='store_true',
|
||||||
help='list all deps at top level')
|
help='list all deps at top level')
|
||||||
parser.add_argument('-l', '--local-only',
|
parser.add_argument('-l', '--local-only',
|
||||||
|
@ -775,9 +781,43 @@ def _get_args():
|
||||||
return parser.parse_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():
|
def main():
|
||||||
args = _get_args()
|
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,
|
pkgs = get_installed_distributions(local_only=args.local_only,
|
||||||
user_only=args.user_only)
|
user_only=args.user_only)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
|
import platform
|
||||||
import sys
|
import sys
|
||||||
from tempfile import NamedTemporaryFile
|
from tempfile import NamedTemporaryFile
|
||||||
try:
|
try:
|
||||||
|
@ -7,6 +8,7 @@ except ImportError:
|
||||||
import mock
|
import mock
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
import virtualenv
|
||||||
|
|
||||||
import pipdeptree as p
|
import pipdeptree as p
|
||||||
|
|
||||||
|
@ -520,3 +522,33 @@ def test_parser_svg():
|
||||||
args = parser.parse_args(['--graph-output', 'svg'])
|
args = parser.parse_args(['--graph-output', 'svg'])
|
||||||
assert args.output_format == 'svg'
|
assert args.output_format == 'svg'
|
||||||
assert not args.json
|
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
23
tox.ini
|
@ -1,17 +1,26 @@
|
||||||
# Tox (http://tox.testrun.org/) is a tool for running tests
|
# http://tox.readthedocs.org/ - sets up and runs the test suite based on a declarative configuration
|
||||||
# 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.
|
|
||||||
|
|
||||||
[tox]
|
[tox]
|
||||||
envlist = py27, py34, py35, py36, py37, py38
|
envlist =
|
||||||
|
py39
|
||||||
|
py38
|
||||||
|
py37
|
||||||
|
py36
|
||||||
|
py35
|
||||||
|
py34
|
||||||
|
py27
|
||||||
|
pypy3
|
||||||
|
pypy2
|
||||||
|
|
||||||
[testenv]
|
[testenv]
|
||||||
|
description = run test suite under {basepython}
|
||||||
commands =
|
commands =
|
||||||
pytest {posargs:-vv}
|
pytest {posargs:-vv}
|
||||||
deps =
|
deps =
|
||||||
tox>=3.0.0
|
|
||||||
graphviz
|
graphviz
|
||||||
pip>=8.0.2
|
pip>=8.0.2
|
||||||
pytest
|
pytest
|
||||||
pytest-cov
|
pytest-cov
|
||||||
|
virtualenv>=20,<21
|
||||||
|
mock;python_version<"3"
|
||||||
|
extras =
|
||||||
|
graphviz
|
||||||
|
|
Loading…
Reference in New Issue