Skip to content

Commit 7751436

Browse files
committed
Extract venv management from test_installation
- Create and use a test.lib.helper.VirtualEnvironment class. - Import and use venv module instead of running "python -m venv". These changes make no significant difference in speed or clarity for the existing test in test_installation. The reason for this change is instead to support the use of new per-test virtual environments in at least one other test.
1 parent 66ff4c1 commit 7751436

File tree

2 files changed

+61
-22
lines changed

2 files changed

+61
-22
lines changed

test/lib/helper.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import textwrap
1515
import time
1616
import unittest
17+
import venv
1718

1819
import gitdb
1920

@@ -36,6 +37,7 @@
3637
"with_rw_repo",
3738
"with_rw_and_rw_remote_repo",
3839
"TestBase",
40+
"VirtualEnvironment",
3941
"TestCase",
4042
"SkipTest",
4143
"skipIf",
@@ -390,3 +392,42 @@ def _make_file(self, rela_path, data, repo=None):
390392
with open(abs_path, "w") as fp:
391393
fp.write(data)
392394
return abs_path
395+
396+
397+
class VirtualEnvironment:
398+
"""A newly created Python virtual environment for use in a test."""
399+
400+
__slots__ = ("_env_dir",)
401+
402+
def __init__(self, env_dir, *, with_pip):
403+
self._env_dir = env_dir
404+
venv.create(env_dir, symlinks=(os.name != "nt"), with_pip=with_pip)
405+
406+
@property
407+
def env_dir(self):
408+
"""The top-level directory of the environment."""
409+
return self._env_dir
410+
411+
@property
412+
def python(self):
413+
"""Path to the Python executable in the environment."""
414+
return self._executable("python")
415+
416+
@property
417+
def pip(self):
418+
"""Path to the pip executable in the environment, or RuntimeError if absent."""
419+
return self._executable("pip")
420+
421+
@property
422+
def sources(self):
423+
"""Path to a src directory in the environment, which may not exist yet."""
424+
return os.path.join(self.env_dir, "src")
425+
426+
def _executable(self, basename):
427+
if os.name == "nt":
428+
path = osp.join(self.env_dir, "Scripts", basename + ".exe")
429+
else:
430+
path = osp.join(self.env_dir, "bin", basename)
431+
if osp.isfile(path) or osp.islink(path):
432+
return path
433+
raise RuntimeError(f"no regular file or symlink {path!r}")

test/test_installation.py

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,19 @@
44
import ast
55
import os
66
import subprocess
7-
import sys
87

9-
from test.lib import TestBase
10-
from test.lib.helper import with_rw_directory
8+
from test.lib import TestBase, VirtualEnvironment, with_rw_directory
119

1210

1311
class TestInstallation(TestBase):
14-
def setUp_venv(self, rw_dir):
15-
self.venv = rw_dir
16-
subprocess.run([sys.executable, "-m", "venv", self.venv], stdout=subprocess.PIPE)
17-
bin_name = "Scripts" if os.name == "nt" else "bin"
18-
self.python = os.path.join(self.venv, bin_name, "python")
19-
self.pip = os.path.join(self.venv, bin_name, "pip")
20-
self.sources = os.path.join(self.venv, "src")
21-
self.cwd = os.path.dirname(os.path.dirname(__file__))
22-
os.symlink(self.cwd, self.sources, target_is_directory=True)
23-
2412
@with_rw_directory
2513
def test_installation(self, rw_dir):
26-
self.setUp_venv(rw_dir)
14+
venv = self._set_up_venv(rw_dir)
2715

2816
result = subprocess.run(
29-
[self.pip, "install", "."],
17+
[venv.pip, "install", "."],
3018
stdout=subprocess.PIPE,
31-
cwd=self.sources,
19+
cwd=venv.sources,
3220
)
3321
self.assertEqual(
3422
0,
@@ -37,9 +25,9 @@ def test_installation(self, rw_dir):
3725
)
3826

3927
result = subprocess.run(
40-
[self.python, "-c", "import git"],
28+
[venv.python, "-c", "import git"],
4129
stdout=subprocess.PIPE,
42-
cwd=self.sources,
30+
cwd=venv.sources,
4331
)
4432
self.assertEqual(
4533
0,
@@ -48,9 +36,9 @@ def test_installation(self, rw_dir):
4836
)
4937

5038
result = subprocess.run(
51-
[self.python, "-c", "import gitdb; import smmap"],
39+
[venv.python, "-c", "import gitdb; import smmap"],
5240
stdout=subprocess.PIPE,
53-
cwd=self.sources,
41+
cwd=venv.sources,
5442
)
5543
self.assertEqual(
5644
0,
@@ -62,9 +50,9 @@ def test_installation(self, rw_dir):
6250
# by inserting its location into PYTHONPATH or otherwise patched into
6351
# sys.path, make sure it is not wrongly inserted as the *first* entry.
6452
result = subprocess.run(
65-
[self.python, "-c", "import sys; import git; print(sys.path)"],
53+
[venv.python, "-c", "import sys; import git; print(sys.path)"],
6654
stdout=subprocess.PIPE,
67-
cwd=self.sources,
55+
cwd=venv.sources,
6856
)
6957
syspath = result.stdout.decode("utf-8").splitlines()[0]
7058
syspath = ast.literal_eval(syspath)
@@ -73,3 +61,13 @@ def test_installation(self, rw_dir):
7361
syspath[0],
7462
msg="Failed to follow the conventions for https://docs.python.org/3/library/sys.html#sys.path",
7563
)
64+
65+
@staticmethod
66+
def _set_up_venv(rw_dir):
67+
venv = VirtualEnvironment(rw_dir, with_pip=True)
68+
os.symlink(
69+
os.path.dirname(os.path.dirname(__file__)),
70+
venv.sources,
71+
target_is_directory=True,
72+
)
73+
return venv

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy