Skip to content

Commit 6170264

Browse files
fix: ensure the virtual environment is .venv for uv
1 parent b1bceba commit 6170264

File tree

1 file changed

+47
-26
lines changed
  • lua/mason-core/installer/managers

1 file changed

+47
-26
lines changed

lua/mason-core/installer/managers/pypi.lua

Lines changed: 47 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -15,28 +15,40 @@ local spawn = require "mason-core.spawn"
1515
local M = {}
1616

1717
local use_uv = settings.current.pip.use_uv
18-
local VENV_DIR = "venv"
18+
local VENV_DIR
19+
if use_uv then
20+
VENV_DIR = ".venv"
21+
else
22+
VENV_DIR = "venv"
23+
end
1924

2025
---@async
2126
---@param candidates string[]
2227
local function resolve_python3(candidates)
2328
local is_executable = _.compose(_.equals(1), vim.fn.executable)
2429
a.scheduler()
25-
if use_uv then
26-
candidates = { "uv" }
27-
end
2830
local available_candidates = _.filter(is_executable, candidates)
31+
vim.print("starting resolve_python3")
2932
for __, candidate in ipairs(available_candidates) do
30-
---@type string
31-
local version_output = spawn[candidate]({ "--version" }):map(_.prop "stdout"):get_or_else ""
32-
local ok, version
33-
if use_uv then
34-
ok, version = pcall(semver.new, version_output:match "uv (%d+.%d+.%d+)")
35-
else
36-
ok, version = pcall(semver.new, version_output:match "Python (3%.%d+.%d+)")
37-
end
38-
if ok then
39-
return { executable = candidate, version = version }
33+
if use_uv and candidate == "uv" then
34+
---@type string
35+
vim.print("Calling uv")
36+
local version_output = spawn[candidate]({ "--version" }):map(_.prop "stdout"):get_or_else ""
37+
vim.print("Got version output" .. version_output)
38+
local ok, version = pcall(semver.new, version_output:match "uv (%d+.%d+.%d+).*")
39+
vim.print("Ok is " .. tostring(ok))
40+
vim.print("Version is " .. tostring(version))
41+
if ok then
42+
vim.print("Returning")
43+
return { executable = candidate, version = version }
44+
end
45+
elseif not use_uv then
46+
---@type string
47+
local version_output = spawn[candidate]({ "--version" }):map(_.prop "stdout"):get_or_else ""
48+
local ok, version = pcall(semver.new, version_output:match "Python (3%.%d+.%d+)")
49+
if ok then
50+
return { executable = candidate, version = version }
51+
end
4052
end
4153
end
4254
return nil
@@ -46,6 +58,7 @@ end
4658
---@param specifiers string
4759
local function pep440_check_version(version, specifiers)
4860
-- The version check only implements a subset of the PEP440 specification and may error with certain inputs.
61+
vim.print("starting pep440")
4962
local ok, result = pcall(pep440.check_version, version, specifiers)
5063
if not ok then
5164
log.fmt_warn(
@@ -61,6 +74,7 @@ end
6174

6275
---@param supported_python_versions string
6376
local function get_versioned_candidates(supported_python_versions)
77+
vim.print("starting get_versioned_candidates")
6478
return _.filter_map(function(pair)
6579
local version, executable = unpack(pair)
6680
if not pep440_check_version(tostring(version), supported_python_versions) then
@@ -71,29 +85,30 @@ local function get_versioned_candidates(supported_python_versions)
7185
{ semver.new "3.12.0", "python3.12" },
7286
{ semver.new "3.11.0", "python3.11" },
7387
{ semver.new "3.10.0", "python3.10" },
74-
{ semver.new "3.9.0", "python3.9" },
75-
{ semver.new "3.8.0", "python3.8" },
76-
{ semver.new "3.7.0", "python3.7" },
77-
{ semver.new "3.6.0", "python3.6" },
88+
{ semver.new "3.9.0", "python3.9" },
89+
{ semver.new "3.8.0", "python3.8" },
90+
{ semver.new "3.7.0", "python3.7" },
91+
{ semver.new "3.6.0", "python3.6" },
7892
})
7993
end
8094

8195
---@async
8296
---@param pkg { name: string, version: string }
8397
local function create_venv(pkg)
98+
vim.print("starting create_venv")
8499
local ctx = installer.context()
85100
---@type string?
86101
local supported_python_versions = providers.pypi.get_supported_python_versions(pkg.name, pkg.version):get_or_nil()
87102

88103
-- 1. Resolve stock python3 installation.
89-
local stock_candidates = platform.is.win and { "python", "python3" } or { "python3", "python" }
104+
local stock_candidates = platform.is.win and { "python", "python3", "uv" } or { "python3", "python", "uv" }
90105
local stock_target = resolve_python3(stock_candidates)
91106
if stock_target then
92107
log.fmt_debug("Resolved stock python3 installation version %s", stock_target.version)
93108
end
94109

95110
-- 2. Resolve suitable versioned python3 installation (python3.12, python3.11, etc.).
96-
local versioned_candidates = {}
111+
local versioned_candidates = { "uv" }
97112
if supported_python_versions ~= nil then
98113
if stock_target and not pep440_check_version(tostring(stock_target.version), supported_python_versions) then
99114
log.fmt_debug("Finding versioned candidates for %s", supported_python_versions)
@@ -113,32 +128,35 @@ local function create_venv(pkg)
113128
-- 3. If a versioned python3 installation was not found, warn the user if the stock python3 installation is outside
114129
-- the supported version range.
115130
if
116-
target == stock_target
131+
use_uv == false
132+
and target == stock_target
117133
and supported_python_versions ~= nil
118134
and not pep440_check_version(tostring(target.version), supported_python_versions)
119135
then
120136
if ctx.opts.force then
121137
ctx.stdio_sink.stderr(
122-
("Warning: The resolved python3 version %s is not compatible with the required Python versions: %s.\n"):format(
138+
("Warning: The resolved python3 version %s is not compatible with the required Python versions: %s.\n")
139+
:format(
123140
target.version,
124141
supported_python_versions
125142
)
126143
)
127144
else
128145
ctx.stdio_sink.stderr "Run with :MasonInstall --force to bypass this version validation.\n"
129146
return Result.failure(
130-
("Failed to find a python3 installation in PATH that meets the required versions (%s). Found version: %s."):format(
147+
("Failed to find a python3 installation in PATH that meets the required versions (%s). Found version: %s.")
148+
:format(
131149
supported_python_versions,
132150
target.version
133151
)
134152
)
135153
end
136154
end
137155

138-
log.fmt_debug("Found python3 installation version=%s, executable=%s", target.version, target.executable)
139156
ctx.stdio_sink.stdout "Creating virtual environment…\n"
140-
157+
print(vim.inspect("Creating virtualenv"))
141158
if use_uv then
159+
print(vim.inspect("with uv"))
142160
log.fmt_debug("Found uv installation version=%s, executable=%s", target.version, target.executable)
143161
return ctx.spawn[target.executable] { "venv", VENV_DIR }
144162
else
@@ -170,6 +188,9 @@ end
170188
---@param args SpawnArgs
171189
local function venv_python(args)
172190
local ctx = installer.context()
191+
if use_uv then
192+
return ctx.spawn[{ "uv", "venv" }](args)
193+
end
173194
return find_venv_executable(ctx, "python"):and_then(function(python_path)
174195
return ctx.spawn[path.concat { ctx.cwd:get(), python_path }](args)
175196
end)
@@ -181,14 +202,14 @@ end
181202
local function pip_install(pkgs, extra_args)
182203
if use_uv then
183204
local ctx = installer.context()
205+
184206
local task = ctx.spawn["uv"] {
185207
"pip",
186208
"install",
187209
"-U",
188210
extra_args or vim.NIL,
189211
pkgs,
190212
}
191-
-- vim.api.nvim_set_current_dir(curdir)
192213
return task
193214
else
194215
return venv_python {

0 commit comments

Comments
 (0)