@@ -9,10 +9,12 @@ local pep440 = require "mason-core.pep440"
99local  platform  =  require  " mason-core.platform" 
1010local  providers  =  require  " mason-core.providers" 
1111local  semver  =  require  " mason-core.semver" 
12+ local  settings  =  require  " mason.settings" 
1213local  spawn  =  require  " mason-core.spawn" 
1314
1415local  M  =  {}
1516
17+ local  use_uv  =  settings .current .pip .use_uv 
1618local  VENV_DIR  =  " venv" 
1719
1820function  M .venv_path (dir )
@@ -30,11 +32,20 @@ local function resolve_python3(candidates)
3032    a .scheduler ()
3133    local  available_candidates  =  _ .filter (is_executable , candidates )
3234    for  __ , candidate  in  ipairs (available_candidates ) do 
33-         --- @type  string 
34-         local  version_output  =  spawn [candidate ]({ " --version"  map (_ .prop  " stdout" get_or_else  " " 
35-         local  ok , version  =  pcall (semver .new , version_output :match  " Python (3%.%d+.%d+)" 
36-         if  ok  then 
37-             return  { executable  =  candidate , version  =  version  }
35+         if  use_uv  and  candidate  ==  " uv"  then 
36+             --- @type  string 
37+             local  version_output  =  spawn [candidate ]({ " --version"  map (_ .prop  " stdout" get_or_else  " " 
38+             local  ok , version  =  pcall (semver .new , version_output :match  " uv (%d+.%d+.%d+).*" 
39+             if  ok  then 
40+                 return  { executable  =  candidate , version  =  version  }
41+             end 
42+         elseif  not  use_uv  then 
43+             --- @type  string 
44+             local  version_output  =  spawn [candidate ]({ " --version"  map (_ .prop  " stdout" get_or_else  " " 
45+             local  ok , version  =  pcall (semver .new , version_output :match  " Python (3%.%d+.%d+)" 
46+             if  ok  then 
47+                 return  { executable  =  candidate , version  =  version  }
48+             end 
3849        end 
3950    end 
4051    return  nil 
@@ -84,14 +95,14 @@ local function create_venv(pkg)
8495    local  supported_python_versions  =  providers .pypi .get_supported_python_versions (pkg .name , pkg .version ):get_or_nil ()
8596
8697    --  1. Resolve stock python3 installation.
87-     local  stock_candidates  =  platform .is .win  and  { " python" " python3"   or  { " python3" " python"  
98+     local  stock_candidates  =  platform .is .win  and  { " python" " python3" ,  " uv "  or  { " python3" " python" ,  " uv "  
8899    local  stock_target  =  resolve_python3 (stock_candidates )
89100    if  stock_target  then 
90101        log .fmt_debug (" Resolved stock python3 installation version %s" stock_target .version )
91102    end 
92103
93104    --  2. Resolve suitable versioned python3 installation (python3.12, python3.11, etc.).
94-     local  versioned_candidates  =  {}
105+     local  versioned_candidates  =  {  " uv "  
95106    if  supported_python_versions  ~=  nil  then 
96107        if  stock_target  and  not  pep440_check_version (tostring (stock_target .version ), supported_python_versions ) then 
97108            log .fmt_debug (" Finding versioned candidates for %s" supported_python_versions )
@@ -111,7 +122,8 @@ local function create_venv(pkg)
111122    --  3. If a versioned python3 installation was not found, warn the user if the stock python3 installation is outside
112123    --  the supported version range.
113124    if 
114-         target  ==  stock_target 
125+         use_uv  ==  false 
126+         and  target  ==  stock_target 
115127        and  supported_python_versions  ~=  nil 
116128        and  not  pep440_check_version (tostring (target .version ), supported_python_versions )
117129    then 
@@ -133,9 +145,14 @@ local function create_venv(pkg)
133145        end 
134146    end 
135147
136-     log .fmt_debug (" Found python3 installation version=%s, executable=%s" target .version , target .executable )
137148    ctx .stdio_sink :stdout  " Creating virtual environment…\n " 
138-     return  ctx .spawn [target .executable ] { " -m" " venv" " --system-site-packages" VENV_DIR  }
149+     if  use_uv  then 
150+         log .fmt_debug (" Found uv installation version=%s, executable=%s" target .version , target .executable )
151+         return  ctx .spawn [target .executable ] { " venv" VENV_DIR  }
152+     else 
153+         log .fmt_debug (" Found python3 installation version=%s, executable=%s" target .version , target .executable )
154+         return  ctx .spawn [target .executable ] { " -m" " venv" " --system-site-packages" VENV_DIR  }
155+     end 
139156end 
140157
141158--- @param  ctx  InstallContext 
161178--- @param  args  SpawnArgs 
162179local  function  venv_python (args )
163180    local  ctx  =  installer .context ()
181+     if  use_uv  then 
182+         return  ctx .spawn [" uv" args )
183+     end 
164184    return  find_venv_executable (ctx , " python" and_then (function (python_path )
165185        return  ctx .spawn [path .concat  { ctx .cwd :get (), python_path  }](args )
166186    end )
@@ -170,15 +190,27 @@ end
170190--- @param  pkgs  string[] 
171191--- @param  extra_args ?  string[] 
172192local  function  pip_install (pkgs , extra_args )
173-     return  venv_python  {
174-         " -m" 
175-         " pip" 
176-         " --disable-pip-version-check" 
177-         " install" 
178-         " --ignore-installed" 
179-         extra_args  or  vim .NIL ,
180-         pkgs ,
181-     }
193+     if  use_uv  then 
194+         return  venv_python  {
195+             " pip" 
196+             " install" 
197+             " --directory" 
198+             " venv" 
199+             " -U" 
200+             extra_args  or  vim .NIL ,
201+             pkgs ,
202+         }
203+     else 
204+         return  venv_python  {
205+             " -m" 
206+             " pip" 
207+             " --disable-pip-version-check" 
208+             " install" 
209+             " --ignore-installed" 
210+             extra_args  or  vim .NIL ,
211+             pkgs ,
212+         }
213+     end 
182214end 
183215
184216--- @async 
@@ -192,7 +224,7 @@ function M.init(opts)
192224        ctx :promote_cwd ()
193225        try (create_venv (opts .package ))
194226
195-         if  opts .upgrade_pip  then 
227+         if  opts .upgrade_pip  and   not   use_uv   then 
196228            ctx .stdio_sink :stdout  " Upgrading pip inside the virtual environment…\n " 
197229            try (pip_install ({ " pip"  opts .install_extra_args ))
198230        end 
0 commit comments