Skip to content

Commit 7eed90b

Browse files
committed
Don't require virtualenv binary
With Python 3 we can use python3 -m venv to create a virtualenv. The main dififculty is that we're missing activate_this.py which we use to activate the environment. But we can do the relevant path / env manipulations ourselves and so cut down the number of dependencies.
1 parent 1b79903 commit 7eed90b

File tree

4 files changed

+42
-11
lines changed

4 files changed

+42
-11
lines changed

.taskcluster.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ tasks:
5757
owner: ${owner}
5858
source: ${event.repository.clone_url}
5959
payload:
60-
image: webplatformtests/wpt:0.53
60+
image: webplatformtests/wpt:0.54
6161
maxRunTime: 7200
6262
artifacts:
6363
public/results:

tools/ci/tc/tasks/test.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ components:
44
workerType: ci
55
schedulerId: taskcluster-github
66
deadline: "24 hours"
7-
image: webplatformtests/wpt:0.53
7+
image: webplatformtests/wpt:0.54
88
maxRunTime: 7200
99
artifacts:
1010
public/results:
@@ -116,6 +116,7 @@ components:
116116
- python3.7
117117
- python3.7-distutils
118118
- python3.7-dev
119+
- python3.7-venv
119120

120121
tox-python3_10:
121122
env:
@@ -125,6 +126,7 @@ components:
125126
- python3.10
126127
- python3.10-distutils
127128
- python3.10-dev
129+
- python3.10-venv
128130

129131
tests-affected:
130132
options:

tools/docker/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ RUN apt-get -qqy update \
3131
python3 \
3232
python3-dev \
3333
python3-pip \
34+
python3-venv \
3435
software-properties-common \
3536
qemu-kvm \
3637
tzdata \
@@ -64,7 +65,6 @@ RUN apt-get -qqy install \
6465
RUN apt-get -y autoremove
6566

6667
RUN pip install --upgrade pip
67-
RUN pip install virtualenv
6868

6969
ENV TZ "UTC"
7070
RUN echo "${TZ}" > /etc/timezone \

tools/wpt/virtualenv.py

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
# mypy: allow-untyped-defs
22

3+
import logging
34
import os
45
import shutil
6+
import site
57
import sys
6-
import logging
8+
import sysconfig
9+
from pathlib import Path
710
from shutil import which
811

912
# The `pkg_resources` module is provided by `setuptools`, which is itself a
@@ -27,9 +30,7 @@ def __init__(self, path, skip_virtualenv_setup):
2730
self.path = path
2831
self.skip_virtualenv_setup = skip_virtualenv_setup
2932
if not skip_virtualenv_setup:
30-
self.virtualenv = which("virtualenv")
31-
if not self.virtualenv:
32-
raise ValueError("virtualenv must be installed and on the PATH")
33+
self.virtualenv = [sys.executable, "-m", "venv"]
3334
self._working_set = None
3435

3536
@property
@@ -47,7 +48,7 @@ def create(self):
4748
if os.path.exists(self.path):
4849
shutil.rmtree(self.path)
4950
self._working_set = None
50-
call(self.virtualenv, self.path, "-p", sys.executable)
51+
call(*self.virtualenv, self.path)
5152

5253
@property
5354
def bin_path(self):
@@ -100,9 +101,37 @@ def activate(self):
100101
# https://github.com/web-platform-tests/wpt/issues/27377
101102
# https://github.com/python/cpython/pull/9516
102103
os.environ.pop('__PYVENV_LAUNCHER__', None)
103-
path = os.path.join(self.bin_path, "activate_this.py")
104-
with open(path) as f:
105-
exec(f.read(), {"__file__": path})
104+
105+
# Setup the path and site packages as if we'd launched with the virtualenv active
106+
bin_dir = os.path.join(self.path, "bin")
107+
os.environ["PATH"] = os.pathsep.join([bin_dir] + os.environ.get("PATH", "").split(os.pathsep))
108+
os.environ["VIRTUAL_ENV"] = self.path
109+
110+
prev_length = len(sys.path)
111+
112+
schemes = sysconfig.get_scheme_names()
113+
if "venv" in schemes:
114+
scheme = "venv"
115+
else:
116+
scheme = "nt_user" if os.name == "nt" else "posix_user"
117+
sys_paths = sysconfig.get_paths(scheme)
118+
data_path = sys_paths["data"]
119+
added = set()
120+
# Add the venv library paths as sitedirs.
121+
# This converts system paths like /usr/local/lib/python3.10/site-packages
122+
# to venv-relative paths like {self.path}/lib/python3.10/site-packages and adds
123+
# those paths as site dirs to be used for module import.
124+
for key in ["purelib", "platlib"]:
125+
host_path = Path(sys_paths[key])
126+
relative_path = host_path.relative_to(data_path)
127+
site_dir = os.path.normpath(os.path.normcase(Path(self.path) / relative_path))
128+
if site_dir not in added:
129+
site.addsitedir(site_dir)
130+
added.add(site_dir)
131+
sys.path[:] = sys.path[prev_length:] + sys.path[0:prev_length]
132+
133+
sys.real_prefix = sys.prefix
134+
sys.prefix = self.path
106135

107136
def start(self):
108137
if not self.exists or self.broken_link:

0 commit comments

Comments
 (0)