Skip to content

Commit aea6d13

Browse files
committed
make things work on windows
1 parent 91a57ed commit aea6d13

File tree

6 files changed

+79
-2
lines changed

6 files changed

+79
-2
lines changed

libs/python/detect_test.go renamed to libs/python/detect_unix_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//go:build unix
2+
13
package python
24

35
import (

libs/python/detect_win_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//go:build windows
2+
3+
package python
4+
5+
import (
6+
"context"
7+
"testing"
8+
9+
"github.com/stretchr/testify/assert"
10+
)
11+
12+
func TestDetectsViaWhich(t *testing.T) {
13+
ctx := context.Background()
14+
py, err := DetectExecutable(ctx)
15+
assert.NoError(t, err)
16+
assert.NotEmpty(t, py)
17+
}
18+
19+
func TestDetectFailsNoInterpreters(t *testing.T) {
20+
t.Setenv("PATH", "testdata")
21+
ctx := context.Background()
22+
_, err := DetectExecutable(ctx)
23+
assert.ErrorIs(t, err, ErrNoPythonInterpreters)
24+
}

libs/python/interpreters.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"io/fs"
88
"os"
99
"path/filepath"
10+
"runtime"
1011
"sort"
1112
"strings"
1213

@@ -47,6 +48,9 @@ func (a allInterpreters) AtLeast(minimalVersion string) (*Interpreter, error) {
4748

4849
var ErrNoPythonInterpreters = errors.New("no python3 interpreters found")
4950

51+
const officialMswinPython = "(Python Official) https://www.python.org/downloads/windows"
52+
const microsoftStorePython = "(Microsoft Store) https://apps.microsoft.com/store/search?publisher=Python%20Software%20Foundation"
53+
5054
const worldWriteable = 0o002
5155

5256
func DetectInterpreters(ctx context.Context) (allInterpreters, error) {
@@ -70,7 +74,8 @@ func DetectInterpreters(ctx context.Context) (allInterpreters, error) {
7074
continue
7175
}
7276
perm := info.Mode().Perm()
73-
if perm&worldWriteable != 0 {
77+
xx := runtime.GOOS
78+
if xx != "windows" && perm&worldWriteable != 0 {
7479
// we try not to run any python binary that sits in a writable folder by all users.
7580
// this is mainly to avoid breaking the security model on a multi-user system.
7681
// If the PATH is pointing somewhere untrusted it is the user fault, but we can
@@ -119,7 +124,15 @@ func DetectInterpreters(ctx context.Context) (allInterpreters, error) {
119124

120125
// probe the binary version by executing it, like `python --version`
121126
// and parsing the output.
127+
//
128+
// Keep in mind, that mswin installations get python.exe and pythonw.exe,
129+
// which are slightly different: see https://stackoverflow.com/a/30313091
122130
out, err := process.Background(ctx, []string{resolved, "--version"})
131+
var processErr *process.ProcessError
132+
if errors.As(err, &processErr) {
133+
log.Debugf(ctx, "failed to check version for %s: %s", resolved, processErr.Err)
134+
continue
135+
}
123136
if err != nil {
124137
log.Debugf(ctx, "failed to check version for %s: %s", resolved, err)
125138
continue
@@ -158,6 +171,10 @@ func DetectInterpreters(ctx context.Context) (allInterpreters, error) {
158171
})
159172
}
160173
}
174+
if runtime.GOOS == "windows" && len(found) == 0 {
175+
return nil, fmt.Errorf("%w. Install them from %s or %s and restart the shell",
176+
ErrNoPythonInterpreters, officialMswinPython, microsoftStorePython)
177+
}
161178
if len(found) == 0 {
162179
return nil, ErrNoPythonInterpreters
163180
}

libs/python/interpreters_test.go renamed to libs/python/interpreters_unix_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//go:build unix
2+
13
package python
24

35
import (
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//go:build windows
2+
3+
package python
4+
5+
import (
6+
"context"
7+
"testing"
8+
9+
"github.com/stretchr/testify/assert"
10+
)
11+
12+
func TestAtLeastOnePythonInstalled(t *testing.T) {
13+
ctx := context.Background()
14+
all, err := DetectInterpreters(ctx)
15+
assert.NoError(t, err)
16+
a := all.Latest()
17+
t.Logf("latest is: %s", a)
18+
assert.True(t, len(all) > 0)
19+
}
20+
21+
func TestNoInterpretersFound(t *testing.T) {
22+
t.Setenv("PATH", t.TempDir())
23+
24+
ctx := context.Background()
25+
_, err := DetectInterpreters(ctx)
26+
assert.ErrorIs(t, err, ErrNoPythonInterpreters)
27+
}

libs/python/venv_test.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package python
22

33
import (
4+
"runtime"
45
"testing"
56

67
"github.com/stretchr/testify/assert"
@@ -24,5 +25,9 @@ func TestDetectVirtualEnvPath_wrongDir(t *testing.T) {
2425
func TestDetectVirtualEnvPath_happy(t *testing.T) {
2526
venv, err := DetectVirtualEnvPath("testdata/some-dir-with-venv")
2627
assert.NoError(t, err)
27-
assert.Equal(t, "testdata/some-dir-with-venv/.venv", venv)
28+
found := "testdata/some-dir-with-venv/.venv"
29+
if runtime.GOOS == "windows" {
30+
found = "testdata\\some-dir-with-venv\\.venv"
31+
}
32+
assert.Equal(t, found, venv)
2833
}

0 commit comments

Comments
 (0)