Skip to content

Commit 7fbd9fe

Browse files
committed
Fix finding Python within virtualenv on Windows; new pythontest package
1 parent 6b4b908 commit 7fbd9fe

File tree

5 files changed

+84
-0
lines changed

5 files changed

+84
-0
lines changed

.github/workflows/push.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ jobs:
4040
with:
4141
python-version: '3.9'
4242

43+
- name: Install uv
44+
uses: astral-sh/setup-uv@v4
45+
4346
- name: Set go env
4447
run: |
4548
echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV

internal/testutil/cmd.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package testutil
2+
3+
import (
4+
"bytes"
5+
"os"
6+
"os/exec"
7+
8+
"github.com/stretchr/testify/require"
9+
)
10+
11+
func RunCommand(t TestingT, name string, args ...string) {
12+
cmd := exec.Command(name, args...)
13+
cmd.Stdout = os.Stdout
14+
cmd.Stderr = os.Stderr
15+
require.NoError(t, cmd.Run())
16+
}
17+
18+
func CaptureCommandOutput(t TestingT, name string, args ...string) string {
19+
cmd := exec.Command(name, args...)
20+
var stdout bytes.Buffer
21+
cmd.Stdout = &stdout
22+
cmd.Stderr = os.Stderr
23+
err := cmd.Run()
24+
require.NoError(t, err)
25+
return stdout.String()
26+
}

internal/testutil/env.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,25 @@ func Chdir(t TestingT, dir string) string {
6161

6262
return wd
6363
}
64+
65+
func InsertPathEntry(t TestingT, path string) {
66+
var separator string
67+
if runtime.GOOS == "windows" {
68+
separator = ";"
69+
} else {
70+
separator = ":"
71+
}
72+
73+
t.Setenv("PATH", path+separator+os.Getenv("PATH"))
74+
}
75+
76+
func InsertVirtualenvInPath(t TestingT, venvPath string) {
77+
if runtime.GOOS == "windows" {
78+
// https://github.com/pypa/virtualenv/commit/993ba1316a83b760370f5a3872b3f5ef4dd904c1
79+
venvPath = filepath.Join(venvPath, "Scripts")
80+
} else {
81+
venvPath = filepath.Join(venvPath, "bin")
82+
}
83+
84+
InsertPathEntry(t, venvPath)
85+
}

libs/python/detect.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,32 @@ func DetectExecutable(ctx context.Context) (string, error) {
2525
// the parent directory tree.
2626
//
2727
// See https://github.com/pyenv/pyenv#understanding-python-version-selection
28+
29+
// On Windows when virtualenv is created, the <env>/Scripts directory
30+
// contains python.exe but no python3.exe. However, system python does have python3 entry
31+
// and it is also added to PATH, so it is found first.
32+
if runtime.GOOS == "windows" {
33+
out, err := exec.LookPath("python.exe")
34+
if err == nil && out != "" {
35+
return out, nil
36+
}
37+
if err != nil && !errors.Is(err, exec.ErrNotFound) {
38+
return "", err
39+
}
40+
}
41+
2842
out, err := exec.LookPath("python3")
43+
2944
// most of the OS'es have python3 in $PATH, but for those which don't,
3045
// we perform the latest version lookup
3146
if err != nil && !errors.Is(err, exec.ErrNotFound) {
3247
return "", err
3348
}
49+
3450
if out != "" {
3551
return out, nil
3652
}
53+
3754
// otherwise, detect all interpreters and pick the least that satisfies
3855
// minimal version requirements
3956
all, err := DetectInterpreters(ctx)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package pythontest
2+
3+
import (
4+
"context"
5+
"testing"
6+
)
7+
8+
func TestVenv(t *testing.T) {
9+
// Test at least two version to ensure we capture a case where venv version does not match system one
10+
for _, pythonVersion := range []string{"3.11", "3.12"} {
11+
t.Run(pythonVersion, func(t *testing.T) {
12+
ctx := context.Background()
13+
RequirePythonVENV(t, ctx, pythonVersion, true)
14+
})
15+
}
16+
}

0 commit comments

Comments
 (0)