FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

[DOC] [BLD] Building / developing matplotlib with uv & pixi · Issue #30877 · matplotlib/matplotlib · GitHub

Repository navigation

[DOC] [BLD] Building / developing matplotlib with uv & pixi #30877

Open

Description

I've been slowly converting all my personal repos to use uv for dependency management, and gave it a shot on matplotlib to see if it'd work. The below works right out of the box for me:

# Create a virtual environment with uv
uv venv .venv

# Activate the environment (optional, uv commands will automatically use the venv)
source .venv/bin/activate  # Linux/macOS
# or: .venv\Scripts\activate  # Windows

# Install dev dependencies
uv pip install -r requirements/dev/dev-requirements.txt

# Install matplotlib in editable mode
uv pip install --no-build-isolation --editable ".[dev]"

# Verify installation
uv run python -c "import matplotlib; print(matplotlib.__file__)"

Then I just point my VSCode python interpreter to the one in the .venv and everything works well. Note that a uv sync workflow does not work, given our somewhat custom build setup.

I'm ambivalent about adding this as an option to the development setup instructions, since the pip commands throughout would need a toggle. I'm also unclear what sort of CI we use to ensure build instructions work as-written. But figured it was worth sharing here in case people want to use this approach.

Activity

  1. changed the title [-][DOC] [BLD] Building matplotlib with uv[/-] [+][DOC] [BLD] Building / developing matplotlib with uv[/+] on Dec 18, 2025
  2. sanrishi commented on Dec 18, 2025

    Contributor

    Is there any issue in this approach
    Happy to contribute.

  3. scottshambaugh commented on Dec 18, 2025

    ContributorAuthor

    @sanchit122006 to clarify, this was meant more as a “sharing experience” / discussion post rather than a request to change docs or supported workflows.

    Something like a new development workflow would need maintainer consensus before working on it. If there’s interest in going that direction, this thread would be the place for people to weigh in.

  4. sanrishi commented on Dec 18, 2025

    Contributor

    @scottshambaugh I’ve tried a similar setup with uv on my side and it worked pretty smoothly for me as well.

    The steps you outlined match what I ended up with, including the editable install with --no-build-isolation, which I’ve found is often needed anyway when working on Matplotlib locally. Using uv run to sanity-check the install is also nice since it avoids depending on whether the environment is activated or not.

    I agree that the bigger questions are more around long-term support than whether this works in practice — documenting an alternative workflow and making sure CI covers it would be the heavier lift. As a personal dev setup though, this seems totally reasonable, and it’s useful to have the experience written down here for others who are already using uv.

  5. timhoffm commented on Dec 18, 2025

    Member

    https://matplotlib.org/devdocs/devel/development_setup.html currently has the high-level structure:

    When applicable, we distguish different tooling, e.g. in https://matplotlib.org/devdocs/devel/development_setup.html#create-a-dedicated-environment

    Would it work to just add uv there? AFAICS, the only difference is that you must use uv pip instead of pip in the following. One could either state this once and hope that the user remembers, or we would have to tabs to all such calls.

  6. sanrishi commented on Dec 18, 2025

    Contributor

    Yes i seen it too, In practice it mostly comes down to a pip to uv pip substitution once the environment is created.

    I agree that the main challenge is how to incorporate this into the docs cleanly without introducing duplication or extra maintenance.

  7. timhoffm commented on Dec 18, 2025

    Member

    Do you think a tab in "Create a dedictated environment with a warning admonition that in the following pip has to replaced by uv pip would do the trick?

  8. sanrishi commented on Dec 18, 2025

    Contributor

    @timhoffm Yes, that seems so good a separate tab with a clear upfront note about replacing pip with uv pip should make the distinction clear without adding too much duplication to the docs

  9. simranjeet-kaur-5 commented on Dec 29, 2025

    Hi, I’m new to Matplotlib and would like to work on this issue if it’s still available. Please let me know if that’s okay.

  10. scottshambaugh commented on Dec 29, 2025

    ContributorAuthor

    Do we currently test the pip and conda install methods through CI? I think it's fine to add the uv tab and add a note to change the later commands to uv pip, but we should test the methods we recommend.

  11. timhoffm commented on Dec 30, 2025

    Member

    We test conda here:

    - micromamba env create -f environment.yml python=%PYTHON_VERSION% pywin32

    I think everything else is pip.

  12. timhoffm commented on Dec 30, 2025

    Member

    @simranjeet-kaur-5 Thanks for your interest. We're still figuring out what exactly we want to do.

  13. scottshambaugh commented on Dec 30, 2025

    ContributorAuthor

    A dedicated github workflow for this could look like the below. I'm not clear on when we use that versus the other CI hosts.

    name: uv build
    
    on: [push, pull_request]
    
    jobs:
      build:
        runs-on: ${{ matrix.os }}-latest
        strategy:
          fail-fast: false
          matrix:
            os: [Ubuntu, MacOS, Windows]
            python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
    
        steps:
          - uses: actions/checkout@v5
    
          - uses: actions/setup-python@v6
            with:
              python-version: ${{ matrix.python-version }}
    
          - uses: astral-sh/setup-uv@v7
            with:
              enable-cache: true
    
          - name: Install deps + matplotlib (editable)
            run: |
              uv pip install -r requirements/dev/dev-requirements.txt
              uv pip install --no-build-isolation -e ".[dev]"
    
          - name: Verify + build
            run: |
              uv run python -c "import matplotlib; print(matplotlib.__version__)"
              uv build

    or I think it would be fine to skip the env matrix and treat it as a smoke test:

      build:
        runs-on: ubuntu-latest
    
        steps:
          - uses: actions/checkout@v5
    
          - uses: actions/setup-python@v6
            with:
              python-version: "3.12"
  14. 6 remaining items

  15. scottshambaugh commented on Mar 23, 2026

    ContributorAuthor

    uv and pixi installs are working now with the merge of #29281

    The documentation and CI to close out this issue is ready to be worked, see my comments here and here for installation commands.

  16. jklymak commented on Mar 23, 2026

    Member

    There are quite a few issues on a Mac install:

    I had to remove anything to do with test-extra or it tried to install win32 components.

    #30480 (comment) still applies

    I had to run add:

    pixi add meson-python ninja meson 
    

    After those steps the dev build worked.

  17. QuLogic commented on Mar 23, 2026

    Member

    What win32 components? The only one directly listed is pywin32 and it is platform specific.

  18. changed the title [-][DOC] [BLD] Building / developing matplotlib with uv[/-] [+][DOC] [BLD] Building / developing matplotlib with uv & pixi[/+] on Mar 23, 2026
  19. jklymak commented on Mar 23, 2026

    Member

    @QuLogic yes, it's rather frustrating.

    The crash was:

    pixi install
     WARN Using local manifest /Users/jklymak/matplotlib/pyproject.toml rather than /Users/jklymak/matplotlib/pixi.toml from environment variable `PIXI_PROJECT_MANIFEST`
    Error:   × failed to solve the pypi requirements of environment 'default' for platform 'osx-arm64'
      ├─▶ failed to resolve pypi dependencies
      ╰─▶ Because only the following versions of pywin32 are available:
              pywin32==222
              pywin32==223
              pywin32==224
              pywin32==225
              pywin32==226
              pywin32==227
              pywin32==228
              pywin32==300
              pywin32==301
              pywin32==302
              pywin32==303
              pywin32==304
              pywin32==305
              pywin32==306
              pywin32==307
              pywin32==308
              pywin32==309
              pywin32==310
              pywin32==311
          and pywin32<=302 has no wheels with a matching Python ABI tag (e.g., `cp311`), we can conclude that pywin32<=302 cannot be used.
          And because pywin32>=303 has no wheels with a matching platform tag (e.g., `macosx_13_0_arm64`) and you require pywin32, we can conclude
          that your requirements are unsatisfiable.
          
          hint: You require CPython 3.11 (`cp311`), but we only found wheels for `pywin32` (v302) with the following Python ABI tags: `cp36m`,
          `cp37m`, `cp38`, `cp39`, `cp310`
          
          hint: Wheels are available for `pywin32` (v311) on the following platforms: `win32`, `win_amd64`, `win_arm64`
    
    

    I don't understand the tooling very well. Here is what gemini thought the problem was:

    1. The Platform Mismatch
      pywin32 is a library that provides a bridge to the Windows API. It contains Windows-specific C code that cannot be compiled or installed on macOS.

    The Error: Pixi searched for a version of pywin32 compatible with osx-arm64.

    The Result: Since no such version exists, the solver concluded that your requirements were "unsatisfiable" and stopped the entire installation.

    1. Solve Group Strictness
      In your original config, you had solve-group = "default" for all environments.

    A Solve Group tells Pixi: "I want one single pixi.lock file where the versions of Numpy, Pytest, etc., are identical across my dev, test, and doc environments."

    Because test-extras was part of that group, Pixi felt obligated to resolve the Windows-only pywin32 as part of the "master plan" for your Mac environment.

    1. Solver "Eagerness"
      Modern Python solvers (like uv, which Pixi uses under the hood) are very thorough. Even if a dependency has a marker like ; sys_platform == 'win32', the solver often tries to fetch the metadata for that package to ensure that if you were on Windows, a valid version exists.

    Because pywin32 doesn't even have a "placeholder" for Mac, the search returned 0 results, triggering the crash.

  20. jklymak commented on Mar 23, 2026

    Member

    BTW< happy to try new edits to the pyproject.toml to get this working.

  21. QuLogic commented on Mar 24, 2026

    Member

    pywin32 doesn't have wheels or an sdist to download on macOS, but I don't understand this split:

          and pywin32<=302 has no wheels with a matching Python ABI tag (e.g., `cp311`), we can conclude that pywin32<=302 cannot be used.
          And because pywin32>=303 has no wheels with a matching platform tag (e.g., `macosx_13_0_arm64`) and you require pywin32, we can conclude
          that your requirements are unsatisfiable.
    

    because there were never any macosx_13_0_arm64 tagged wheels.

    Unfortunately, this is a bug in pixi; it doesn't affect uv on Linux, for example.

  22. QuLogic commented on Mar 24, 2026

    Member

    Assuming it works on Windows (I didn't test it locally), #31358 should remove the pywin32 dependency entirely.

  23. jklymak commented on Mar 24, 2026

    Member

    Can we add meson-python ninja meson to the pyproject.toml? I think it is ninja in particular that is missing, but I didn't test

  24. QuLogic commented on Mar 24, 2026

    Member

    Those are in build requirements already; you can also ask to install those with --group build if you are fine doing a separate pre-install step. But I don't think the problem is missing requirements directly; it's that uv/pixi copied the nonsensical idea from pip to keep build isolation enabled even for editable installs, so it doesn't install build dependencies in the main environment and when meson tries to rebuild, ninja from the isolated environment is gone.

    Anyway, I don't feel like fighting against tools that are trying to be too smart that I don't use, so someone that does use uv/pixi will have to continue this investigation on their own.

  25. jklymak commented on Mar 25, 2026

    Member

    OK< here is what I got to work on MacOS:

    1. make a pixi.toml:
    [workspace]
    channels = ["conda-forge"]
    platforms = ["osx-arm64", "osx-x64", "linux-x64"]
    
    [dependencies]
    python = "3.12.*"
    pip = "*"
    meson = "*"
    ninja = "*"
    pkg-config = "*"
    compilers = "*"
    meson-python = "*"
    pybind11 = "*"
    setuptools = ">=64"
    setuptools-scm = ">=7"
    
    [tasks.prepare-freetype]
    cmd = "true"
    description = "No-op on non-mac platforms"
    
    [target.osx-arm64.tasks.prepare-freetype]
    cmd = "cp subprojects/packagefiles/freetype-2.6.1-meson/src/gzip/zconf.h subprojects/freetype-2.6.1/src/gzip"
    description = "Copy zconf.h needed for vendored freetype build (macOS ARM)"
    
    [tasks.dev-install]
    depends-on = ["prepare-freetype"]
    cmd = "python -m pip install --no-build-isolation --no-deps -e ."
    description = "Editable install using meson-python (no build isolation)"
    
    [tasks.clean-build]
    cmd = "rm -rf build meson-logs meson-private .mesonpy-*"
    description = "Remove meson build artifacts"
    
    [tasks.rebuild]
    depends-on = ["clean-build", "dev-install"]
    description = "Clean and rebuild editable install"
    
    [tasks.install-test]
    cmd = "python -m pip install --group test --no-build-isolation"
    description = "Install test dependencies from pyproject.toml"
    
    [tasks.install-doc]
    cmd = "python -m pip install --group doc --no-build-isolation"
    description = "Install doc dependencies from pyproject.toml"
    1. do pixi run rebuild if you need to clear out old libraries, or just pixi run dev-install
    2. optionally, do pixi run install-test and pixi run install-doc

    Note this does the freetype zconf copy for osx-arm64 but not other OSes. clean-build only works for linux-like OSs so I haven't tried to make this useful for win64.

    It seems it would be nice to include this in some way for other devs, but not sure if it should be at the top-level.

  26. jklymak commented on Mar 26, 2026

    Member

    See #31384 where I suggest this toml be added to tools/pixi.toml and the documentation expanded...

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions


      Back | FazBrowse Home | New Git URL