diff --git a/catkin_virtualenv/cmake/catkin_generate_virtualenv.cmake b/catkin_virtualenv/cmake/catkin_generate_virtualenv.cmake index 09c3015..3eb9595 100644 --- a/catkin_virtualenv/cmake/catkin_generate_virtualenv.cmake +++ b/catkin_virtualenv/cmake/catkin_generate_virtualenv.cmake @@ -114,6 +114,7 @@ function(catkin_generate_virtualenv) add_custom_command(COMMENT "Install requirements to ${CMAKE_BINARY_DIR}/${venv_dir}" OUTPUT ${CMAKE_BINARY_DIR}/${venv_dir}/bin/activate COMMAND ${CATKIN_ENV} rosrun catkin_virtualenv venv_install ${venv_dir} + --python ${ARG_PYTHON_INTERPRETER} --requirements ${requirements_list} --extra-pip-args ${processed_pip_args} DEPENDS ${CMAKE_BINARY_DIR}/${venv_dir}/bin/python diff --git a/catkin_virtualenv/scripts/venv_init b/catkin_virtualenv/scripts/venv_init index 65420c0..6d1aef8 100755 --- a/catkin_virtualenv/scripts/venv_init +++ b/catkin_virtualenv/scripts/venv_init @@ -42,9 +42,8 @@ if __name__ == '__main__': extra_pip_args = args.extra_pip_args[1:-1] print(args.use_system_packages) - venv = Virtualenv(args.venv) + venv = Virtualenv(args.venv, python=args.python) venv.initialize( - python=args.python, use_system_packages=args.use_system_packages, extra_pip_args=[arg for arg in extra_pip_args.split(" ") if arg != ""], ) diff --git a/catkin_virtualenv/scripts/venv_install b/catkin_virtualenv/scripts/venv_install index 2b73ab3..bd38e66 100755 --- a/catkin_virtualenv/scripts/venv_install +++ b/catkin_virtualenv/scripts/venv_install @@ -23,7 +23,6 @@ import argparse from catkin_virtualenv import configure_logging from catkin_virtualenv.venv import Virtualenv - if __name__ == '__main__': configure_logging() @@ -34,12 +33,14 @@ if __name__ == '__main__': '--requirements', required=True, nargs='+', help="Requirements to sync to virtualenv.") parser.add_argument( '--extra-pip-args', default='""', type=str, help="Extra pip args for install.") + parser.add_argument( + '--python', default="python3", help="Build the virtualenv with which python version.") args = parser.parse_args() extra_pip_args = args.extra_pip_args[1:-1] - venv = Virtualenv(args.venv) + venv = Virtualenv(args.venv, args.python) venv.install( requirements=args.requirements, extra_pip_args=[arg for arg in extra_pip_args.split(" ") if arg != ""], diff --git a/catkin_virtualenv/src/catkin_virtualenv/venv.py b/catkin_virtualenv/src/catkin_virtualenv/venv.py index b08a4ce..823347c 100644 --- a/catkin_virtualenv/src/catkin_virtualenv/venv.py +++ b/catkin_virtualenv/src/catkin_virtualenv/venv.py @@ -25,7 +25,6 @@ import re import shutil import subprocess -import tempfile try: from urllib.request import urlretrieve @@ -35,7 +34,7 @@ from distutils.spawn import find_executable -from . import run_command, relocate +from . import relocate, run_command from .collect_requirements import collect_requirements _BYTECODE_REGEX = re.compile(r".*\.py[co]") @@ -45,11 +44,12 @@ class Virtualenv: - def __init__(self, path): + def __init__(self, path, python="python3"): """Manage a virtualenv at the specified path.""" self.path = path + self.python = python # eg. python3.12 - def initialize(self, python, use_system_packages, extra_pip_args, clean=True): + def initialize(self, use_system_packages, extra_pip_args, clean=True): """Initialize a new virtualenv using the specified python version and extra arguments.""" if clean: try: @@ -57,6 +57,7 @@ def initialize(self, python, use_system_packages, extra_pip_args, clean=True): except Exception: pass + python = self.python system_python = find_executable(python) if not system_python: @@ -66,8 +67,9 @@ def initialize(self, python, use_system_packages, extra_pip_args, clean=True): raise RuntimeError(error_msg) preinstall = [ - "pip==24.0", - "pip-tools==7.4.1", + "pip==25.3", + "pip-tools==7.5.1", + "setuptools", # No-longer preinstalled with python3.14 venvs. ] builtin_venv = self._check_module(system_python, "venv") @@ -75,9 +77,10 @@ def initialize(self, python, use_system_packages, extra_pip_args, clean=True): virtualenv = [system_python, "-m", "venv"] else: virtualenv = ["virtualenv", "--no-setuptools", "--verbose", "--python", python] + # TODO: This fix for setuptools breaks python2 support. Do we still care about Python2? # py2's virtualenv command will try install latest setuptools. setuptools>=45 not compatible with py2, # but we do require a reasonably up-to-date version (because of pip==20.1), so v44 at least. - preinstall += ["setuptools>=44,<45"] + preinstall += ["setuptools"] if use_system_packages: virtualenv.append("--system-site-packages") @@ -92,7 +95,7 @@ def initialize(self, python, use_system_packages, extra_pip_args, clean=True): if without_pip: # install pip via get-pip.py version_proc = run_command( - ["python", "-cimport sys; print('{}.{}'.format(*sys.version_info))"], capture_output=True + [python, "-cimport sys; print('{}.{}'.format(*sys.version_info))"], capture_output=True ) version = version_proc.stdout if isinstance(version, bytes): @@ -100,19 +103,19 @@ def initialize(self, python, use_system_packages, extra_pip_args, clean=True): version = version.strip() # download pip from https://bootstrap.pypa.io/pip/ get_pip_path, _ = urlretrieve("https://bootstrap.pypa.io/pip/get-pip.py") - run_command([self._venv_bin("python"), get_pip_path], check=True) + run_command([self._venv_bin(python), get_pip_path], check=True) # (gservin): test --no-cache-dir run_command( - [self._venv_bin("python"), "-m", "pip", "install", "--no-cache-dir", "-vvv"] + extra_pip_args + preinstall, + [self._venv_bin(python), "-m", "pip", "install", "--no-cache-dir", "-vvv"] + extra_pip_args + preinstall, check=True, ) def install(self, requirements, extra_pip_args): """Purge the cache first before installing.""" # (KLAD) testing to debug an issue on build farm - command = [self._venv_bin("python"), "-m", "pip", "cache", "purge"] + command = [self._venv_bin(self.python), "-m", "pip", "cache", "purge"] """ Sync a virtualenv with the specified requirements.""" # (KLAD) testing no-cache-dir - command = [self._venv_bin("python"), "-m", "pip", "install", "-vvv", "--no-cache-dir"] + extra_pip_args + command = [self._venv_bin(self.python), "-m", "pip", "install", "-vvv", "--no-cache-dir"] + extra_pip_args for req in requirements: run_command(command + ["-r", req], check=True)