Skip to content

feat(uv): add uv as a pip alternative for dealing with pypi#1640

Open
KingMichaelPark wants to merge 4 commits into
mason-org:mainfrom
KingMichaelPark:feat/add-uv-as-pypi-source
Open

feat(uv): add uv as a pip alternative for dealing with pypi#1640
KingMichaelPark wants to merge 4 commits into
mason-org:mainfrom
KingMichaelPark:feat/add-uv-as-pypi-source

Conversation

@KingMichaelPark
Copy link
Copy Markdown
Contributor

UV is a very fast installer for python packages
that can be 10-100x faster to resolve packages. This adds
an option for Mason to use it instead of pip to resolve
python packages that are installed via Mason.

More info about the replacement: https://github.com/astral-sh/uv
I have no affiliations with uv/astral, it is just very fast and
it would be nice to have updates for packages like sqlfluff take
a lot less time than they currently do to resolve during updates.

@KingMichaelPark KingMichaelPark force-pushed the feat/add-uv-as-pypi-source branch 5 times, most recently from 6843a02 to 0514854 Compare February 28, 2024 21:56
@iguanacucumber
Copy link
Copy Markdown

I think we should do this for bun too, since now it's compatible with alot more things now

@KingMichaelPark KingMichaelPark force-pushed the feat/add-uv-as-pypi-source branch 4 times, most recently from 4fbe794 to b1bceba Compare September 13, 2024 14:13
@PyDataBlog
Copy link
Copy Markdown

Can we get some traction for this? it would boost pkg installation speeds astronomically.

@iguanacucumber
Copy link
Copy Markdown

i tried installing about 10 python based tools with this PR:

  • with pip -> 2 minutes
  • with uv -> 15 seconds

@iguanacucumber
Copy link
Copy Markdown

i'm having some issues on another computer:
20241019_15h26m19s_grim

@KingMichaelPark KingMichaelPark force-pushed the feat/add-uv-as-pypi-source branch from 6170264 to 6c3a15e Compare October 20, 2024 17:27
@KingMichaelPark
Copy link
Copy Markdown
Contributor Author

@iguanacucumber if you could retry it seems to be resolved on my side now

@iguanacucumber
Copy link
Copy Markdown

20241021_00h40m04s_grim
every other package installs file excepts debugpy

@KingMichaelPark
Copy link
Copy Markdown
Contributor Author

I won't have time to work on this for a few days so you're more than welcome to open a PR on my branch if you desperately need it. (You should be able to just add debugpy to your dev dependencies in your project as a workaround in the short term)

@KingMichaelPark
Copy link
Copy Markdown
Contributor Author

KingMichaelPark commented Oct 23, 2024

Alright, debugpy installs now, to have this work with mason-lspconfig I had to fork that for now:

return {
    "neovim/nvim-lspconfig",
    dependencies = {
        { "KingMichaelPark/mason.nvim", opts = { pip = { use_uv = true } } },
        "KingMichaelPark/mason-lspconfig.nvim",
        "hrsh7th/cmp-nvim-lsp",
        "nvim-telescope/telescope.nvim"
    },

@KingMichaelPark KingMichaelPark force-pushed the feat/add-uv-as-pypi-source branch 4 times, most recently from f7fb948 to f724f1a Compare October 26, 2024 07:08
@lljbash
Copy link
Copy Markdown

lljbash commented Jan 15, 2025

This PR is really helpful! I was wondering if the maintainer has any plans to merge it? @williamboman

@dusktreader
Copy link
Copy Markdown

Not only would this boost install speeds dramatically for lsps that are installed via pip, it would also eliminate the need for pip itself and consequently for python3-venv.

Further, the packages could require different versions of python since uv can install python binaries as well. I believe this happens automatically.

@user520881
Copy link
Copy Markdown

is there plans to merge this?

@Xylot
Copy link
Copy Markdown

Xylot commented May 6, 2025

@williamboman Are there plans to merge this?

For anyone that needs a quick workaround, I noticed that Mason appends itself to the top of the path at nvim startup:

:echo $PATH
>>> ~/.local/share/nvim/mason/bin:...

So I just symlinked my system python to that directory in order to force Mason to recognize it first.

ln -s /usr/bin/python3 ~/.local/share/nvim/mason/bin/python3

@KingMichaelPark KingMichaelPark force-pushed the feat/add-uv-as-pypi-source branch 2 times, most recently from 0bdf8da to 91ed1a0 Compare May 7, 2025 16:29
@KingMichaelPark
Copy link
Copy Markdown
Contributor Author

Quick question: Does this also appear in checkhealth? Cuz imo it should but marked as optional

Now it does.

@Conarius Conarius requested a review from a team July 22, 2025 11:07
@Conarius Conarius requested a review from a team July 22, 2025 11:07
@KingMichaelPark KingMichaelPark force-pushed the feat/add-uv-as-pypi-source branch 2 times, most recently from 09b940d to 32c755a Compare September 18, 2025 08:50
@KingMichaelPark
Copy link
Copy Markdown
Contributor Author

@williamboman @seblyng @mirekdlugosz This also fixes the 404 in your CI for shellharden.

@gaardhus
Copy link
Copy Markdown

What is holding this PR back? Looking forward to being able to use uv with mason.

@benatouba
Copy link
Copy Markdown

It would be amazing to see this merged.

@iguanacucumber
Copy link
Copy Markdown

iguanacucumber commented Nov 14, 2025

Been rocking this branch for a year now (previous message) and i've encountered no issues for months, its pretty stable.

@KingMichaelPark KingMichaelPark force-pushed the feat/add-uv-as-pypi-source branch from 32c755a to b0827eb Compare November 14, 2025 15:55
@KingMichaelPark
Copy link
Copy Markdown
Contributor Author

(Rebased to latest)

@Mintass
Copy link
Copy Markdown

Mintass commented Dec 5, 2025

Anything left before being merged? I'm currently using uv as a replacement for pip, really excited for this PR.

@Conarius
Copy link
Copy Markdown

Conarius commented Dec 6, 2025

It now only needs approval from @williamboman

@acsezen
Copy link
Copy Markdown

acsezen commented Dec 11, 2025

Any reason to not approve it? @williamboman
Thanks!

@KingMichaelPark KingMichaelPark force-pushed the feat/add-uv-as-pypi-source branch from b0827eb to c80c52c Compare January 17, 2026 14:54
UV is a very fast installer for python packages
that can be 10-100x faster to resolve packages. This adds
an option for Mason to use it instead of pip to resolve
python packages that are installed via Mason.

More info about the replacement: https://github.com/astral-sh/uv
I have no relationship with uv, it is just very fast and
it would be nice to have updates for packages like sqlfluff take
a lot less time than they currently do to resolve during updates.

fix: ensure the virtual environment is .venv for uv

fix: venv dir can stay venv

feat: update stdio ctx reference

feat: add uv as installer for python

UV is a very fast installer for python packages
that can be 10-100x faster to resolve packages. This adds
an option for Mason to use it instead of pip to resolve
python packages that are installed via Mason.

More info about the replacement: https://github.com/astral-sh/uv
I have no relationship with uv, it is just very fast and
it would be nice to have updates for packages like sqlfluff take
a lot less time than they currently do to resolve during updates.

fix: ensure the virtual environment is .venv for uv

fix: venv dir can stay venv

feat: update stdio ctx reference
@KingMichaelPark KingMichaelPark force-pushed the feat/add-uv-as-pypi-source branch from c80c52c to aa279cb Compare January 17, 2026 15:32
@lljbash
Copy link
Copy Markdown

lljbash commented Mar 16, 2026

Found a bug: commit aa279cb lost most of the use_uv logic. When use_uv = true, the code still uses python3 -m venv instead of uv venv, causing installation to fail on systems without python3-venv.

Fix: KingMichaelPark#2

I used vibe coding (AI-assisted) to debug and fix this. Please review carefully before merging.

@KingMichaelPark KingMichaelPark force-pushed the feat/add-uv-as-pypi-source branch from 5a62206 to 6ca3f5f Compare March 16, 2026 10:10
crrsh added a commit to crrsh/dotfiles that referenced this pull request Apr 11, 2026
- updated numhl to use `Diagnostic...` because it will be more consistent
accross colorschemes.
- added more `cmd`s to lazy load Mason
- add config to use uv for when merged mason-org/mason.nvim#1640
- remove underline for diagnostic hints
- testing out enabling `virtual_text` for current line
@mrijken
Copy link
Copy Markdown

mrijken commented Apr 13, 2026

What is need to get this merged?

@williamboman
Copy link
Copy Markdown
Member

Hey guys apologies for not attending to this for over 2 years (I was going for a world record). I saw this when it was first opened but I haven't been too interested in adding this for the following reasons:

  1. uv was fairly new at the creation of this PR, this is definitely not the case anymore as it's managed to become quite dominant within the python community
  2. mason uses a lot of different tools, which people have many opinions of. when bun was released people instantly requested bun support (without actually realizing what it would entail). supporting a variety of different toolchains for a package source is a non goal
  3. the only compelling argument I can think of to add uv support would be to alleviate the requirement on python3-venv which for some reason is not included in certain distributions, specifically Debian. faster installs are certainly a big bonus but in my mind not enough to justify the added complexity (different virtualenv implementations and saturating mason settings with more options)

As for the implementation itself, I'd want to avoid the branching that's happening and instead implement uv as a standalone "compiler". I wouldn't be opposed to a different solution where mason doesn't necessarily lock itself into permanently supporting both python3-venv and uv through the concept of simple feature flags, i.e. to enable uv:

require("mason").setup {
  features = {
    "python-uv"
  }
}

Does this sound like an acceptable solution to you guys? Also, do you agree with my 3rd point above or am I missing something in terms of what supporting uv would offer?

@KingMichaelPark
Copy link
Copy Markdown
Contributor Author

Hi @williamboman that makes perfect sense to me. You're under no obligation to support things you don't want to maintain (or in this case the way it has been implemented). If you wanted to close this in favour of implementing something more generic I think that makes sense. (I've just been mainting the fork for this PR for a while and there's been no issue with me rebasing from time to time).

The only way I could see your maintanance burden becoming easier would be allowing users to override the install, update, uninstall command at their own risk. (just having your current maintainable behaviour the default). Something along the lines of (warning just pseudo code):

local settings = {
    overrides = {
        pypi = {
            uninstall = function(pkg) return { "uv", "pip", "uninstall", "--color", "never", "--directory", "venv", pkg } end,
            install = function(pkg) return { "uv", "pip", "install", "--color", "never", "--directory", "venv", pkg } end,
            upgrade = function(pkg) return { "uv", "pip", "install", "-U", "--color", "never", "--directory", "venv", pkg } end,
        },
    }
}

function M.uninstall(pkg)
    log.fmt_debug("pypi: uninstall %s", pkg)
    -- The ability for others to override (maybe you need to tell them what the directory needs to be though)
    local override = settings.overrides.pypi
    if type(override) == "table" and type(override.uninstall) == "function" then
        return override.uninstall(pkg)
        -- Your existing code
    else
        return venv_python {
            "-m",
            "pip",
            "uninstall",
            "-y",
            pkg,
        }
    end
end

I am not sure if this is any better for you, but it might solve the bun/pnpm issues as well if you just let users use alternative tools with a little guidance on where to specify packages to be installed. But I did not spend a tremendous amount of time looking through the code so I don't know if just knowing that is sufficient to making the tools executable or not, so this might be a bad idea.

Regardless, whatever you want to do is fine, it won't really affect me much!

@williamboman
Copy link
Copy Markdown
Member

williamboman commented Apr 22, 2026

Something like that is already possible, although technically not a public API yet (haven't fully tested this yet but it should work).

local Result = require "mason-core.result"
local path = require "mason-core.path"
local compiler = require "mason-core.installer.compiler"
local pypi = require "mason-core.installer.compiler.compilers.pypi"

local extend = { __index = pypi }

local uv = {
    ---@async
    ---@param ctx InstallContext
    ---@param source ParsedPypiSource
    install = function(ctx, source)
        -- Note that this implementation will always try to use uv and not fall back to default.
        -- Uncomment the following for a default fallback.
        -- if vim.fn.executable "uv" ~= 1 then
        --   return pypi.install(ctx, source)
        -- end
        return Result.try(function(try)
            ctx:promote_cwd()
            try(ctx.spawn.uv({ "venv", "venv" }))
            try(ctx.spawn.uv({
                "pip",
                "install",
                source.extra and ("%s[%s]==%s"):format(source.package, source.extra, source.version)
                or ("%s==%s"):format(source.package, source.version),
                source.extra_packages or vim.NIL,
                env = {
                    VIRTUAL_ENV = path.concat { ctx.cwd:get(), "venv" },
                },
            }))
        end)
    end,
}

setmetatable(uv, extend)

compiler.register_compiler("pypi", uv)

@KingMichaelPark
Copy link
Copy Markdown
Contributor Author

Do you have a preference one way or another on whether you want this to be added to mason and if so, do you want the community to do it or is it something you'd prefer to implement in the future? (I couldn't tell by your response, but I certainly appreciate you sending the snippet above!)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.