From b42e3a120d15eb5c9378b4ef89e2bbe1e26ce3b0 Mon Sep 17 00:00:00 2001 From: Daniel Han Date: Thu, 16 Apr 2026 07:36:59 -0700 Subject: [PATCH] Remove legacy venv Scripts entry from User PATH on upgrade (#5060) Older installers persisted the venv Scripts directory directly in the User PATH registry. The shim approach from #4961 no longer writes that entry, but on upgrade the old one survived and python.exe / pip.exe from the unsloth venv continued winning resolution in every new shell. Before creating the shim, read the current User PATH, filter out any entry matching $VenvDir\Scripts (using the same symmetric raw+expanded comparison as Add-ToUserPath), and write back if changed. No-op on fresh installs where the legacy entry was never written. Confirmed on a real Windows machine: `where.exe python` was returning the venv interpreter first even after the shim PR merged. --- install.ps1 | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/install.ps1 b/install.ps1 index dfb54b1e8..3fc9ac469 100644 --- a/install.ps1 +++ b/install.ps1 @@ -1042,6 +1042,38 @@ shell.Run cmd, 0, False # We do NOT add the venv Scripts dir to PATH (it also holds python.exe # and pip.exe, which would hijack the user's system interpreter). # Hardlink preferred; falls back to copy if cross-volume or non-NTFS. + # + # Remove the legacy venv Scripts PATH entry that older installers wrote. + $LegacyScriptsDir = Join-Path $VenvDir "Scripts" + try { + $legacyKey = [Microsoft.Win32.Registry]::CurrentUser.CreateSubKey('Environment') + try { + $rawPath = $legacyKey.GetValue('Path', '', [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames) + if ($rawPath) { + [string[]]$pathEntries = $rawPath -split ';' + $normalLegacy = $LegacyScriptsDir.Trim().Trim('"').TrimEnd('\').ToLowerInvariant() + $expNormalLegacy = [Environment]::ExpandEnvironmentVariables($LegacyScriptsDir).Trim().Trim('"').TrimEnd('\').ToLowerInvariant() + $filtered = @($pathEntries | Where-Object { + $stripped = $_.Trim().Trim('"') + $rawNorm = $stripped.TrimEnd('\').ToLowerInvariant() + $expNorm = [Environment]::ExpandEnvironmentVariables($stripped).TrimEnd('\').ToLowerInvariant() + ($rawNorm -ne $normalLegacy -and $rawNorm -ne $expNormalLegacy) -and + ($expNorm -ne $normalLegacy -and $expNorm -ne $expNormalLegacy) + }) + $cleanedPath = $filtered -join ';' + if ($cleanedPath -ne $rawPath) { + $legacyKey.SetValue('Path', $cleanedPath, [Microsoft.Win32.RegistryValueKind]::ExpandString) + try { + $d = "UnslothPathRefresh_$([guid]::NewGuid().ToString('N').Substring(0,8))" + [Environment]::SetEnvironmentVariable($d, '1', 'User') + [Environment]::SetEnvironmentVariable($d, [NullString]::Value, 'User') + } catch { } + } + } + } finally { + $legacyKey.Close() + } + } catch { } $ShimDir = Join-Path $StudioHome "bin" New-Item -ItemType Directory -Force -Path $ShimDir | Out-Null $ShimExe = Join-Path $ShimDir "unsloth.exe"