Skip to content

CI: Add Mac and update Linux free-threaded CI #27581

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from

Conversation

ngoldbaum
Copy link
Member

This adds testing on MacOS for free-threaded Python and streamlines the linux tests.

In both cases I'm using setup-uv to get python. It turns out to be trivial to replace setup-python with it. The main advantage is it has native support for free-threaded Python.

Unfortunately I'm hitting some issues with spin on Windows (see scientific-python/spin#241 for an upstream fix) when I install python with the setup-uv action, so I'm holding off on adding Windows CI for now.

@ngoldbaum ngoldbaum added component: CI 39 - free-threading PRs and issues related to support for free-threading CPython (a.k.a. no-GIL, PEP 703) labels Oct 16, 2024
@ngoldbaum ngoldbaum requested a review from rgommers October 16, 2024 20:53
@andyfaff
Copy link
Member

this looks good to me. Could you please make the ultra minor nit requests, then we'll merge.

- uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0
with:
python-version: ${{ matrix.version }}
- uses: astral-sh/setup-uv@v3
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please use a hash for the version.

pip install -r requirements/build_requirements.txt
pip install pytest pytest-xdist hypothesis
- name: Build and test
run: spin test
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

new line at EOF

Copy link
Member

@rgommers rgommers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @ngoldbaum!

+1 for moving to setup-uv. I think moving from the python.org binaries to the python-build-standalone ones should not matter in principle, so no worries there.

I'd avoid using a venv by default unless there's a compelling reason to do so (see my inline comment for more details).

In the step where the build environment is set up, there's an issue visible:

Defaulting to user installation because normal site-packages is not writeable

Perhaps that will also go away when dropping the venv usage.

uv python install ${{ matrix.version }}
uv venv --python ${{ matrix.version }}
. .venv/bin/activate
echo PATH=$PATH >> $GITHUB_ENV
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like either a misunderstanding in how to use setup-uv, or a bug in setup-uv. Its docs claim that it's a drop-in replacement for setup-python, and we don't need this kind of path manipulation with setup-python.

It's possible that the cause is trying to use a venv. That is not what we do in CI jobs usually, and is not necessary / just extra overhead. Is there a reason for doing this?

Copy link
Member Author

@ngoldbaum ngoldbaum Oct 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uv doesn't yet support setting up a global python environment (see the "important" note below the spot I linked), so I either need to use a virtualenv or I need to replace direct python invocations with uv run. That means I need to update meson_actions/action.yml, which means I also need to update the linux SIMD tests, since those tests use meson_actions/action.yml. I'm poking around at doing that and hopefully that's not too bad, but I hope you see why I tried using a virtualenv first.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I poked at this, and it looks like uv really doesn't want me to directly use the global uv environment. If I try to force it to do that, I get errors like:

  error: The interpreter at /home/runner/.local/share/uv/python/cpython-3.12.7-linux-x86_64-gnu is externally managed, and indicates the following:
    This Python installation is managed by uv and should not be modified.
  Consider creating a virtual environment with `uv venv`.
  Error: Process completed with exit code 2.

See this CI run on my fork.

I opened an issue to ask about this on the setup-uv repo: astral-sh/setup-uv#124

But for now, I think if we want to use setup-uv, we're more-or-less forced to use a virtualenv. I'll try to figure out where the "Defaulting to user installation because normal site-packages is not writeable" message is coming from.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a virtualenv is needed, having the user mess with $GITHUB_ENV is pretty bad UX. setup-pixi does this in a nicer way, by simply adding activate-environment: true: https://github.com/prefix-dev/setup-pixi?tab=readme-ov-file#environment-activation. That shouldn't be too hard to implement, so I hope setup-uv will gain that as well.

@ngoldbaum
Copy link
Member Author

ngoldbaum commented Oct 17, 2024

Well, unfortunately, nothing is ever as easy as I'd like.

The issue Ralf pointed out was caused by me unintentionally using the system pip. After making sure there's a pip in the uv python environment I was able to get the tests to run, but there are some issues that look like they're caused by using the python-build-standalone python instead of a python.org python.

  • All the test_mem_policy.py tests fail.
    • This ends up coming down to an issue with the way numpy.testing populates the C include path when it tries to build an extension. I can fix it by using sysconfig.get_path('include') as the include path in addition to sysconfig.get_config_var('INCLUDEPY') which is the path that's there right now. The path in INCLUDEPY is not a real path on these binaries, it seems to be relative to wherever the build is happening when Python was built.
  • Failures due to floating point exceptions in the array coercion tests. I didn't fully debug this, but it seems to be coming from PyObject_Str on a float object setting a floating point exception. This only happens with the Python 3.11 from UV, not the Python 3.12 or 3.13 binaries. This feels like a python-build-standalone bug.
  • test_public_api fails because numpy.distutils.msvccompiler is broken. Again, only on Python 3.11, which I guess is because distutils doesn't exist on the newer versions.

See this CI run if you're curious for more details about these failures.

This is getting complicated enough I think I'm going to give up on completely replacing setup-python with setup-uv in the linux tests and instead just use uv to install a free-threaded python builds in the linux and mac tests.

@ngoldbaum
Copy link
Member Author

Also worth noting that I can reproduce all these failures locally on Python 3.11 on Linux using UV's python install.

@rgommers
Copy link
Member

Might be worth reporting the bugs to python-build-standalone and see if they get responses/fixes? If so, this PR will be unblocked without too much extra work. If not, then I'm not sure we should be switching to it just yet. Those builds used to be rarely used, and now with uv pushing them they're going to see lots of usage, so perhaps it's just early days here.

@ngoldbaum
Copy link
Member Author

Might be worth reporting the bugs to python-build-standalone and see if they get responses/fixes?

Yup, reporting these issues is on my backlog now.

If so, this PR will be unblocked without too much extra work. If not, then I'm not sure we should be switching to it just yet.

So I'd still like to get the free-threaded Mac CI, which does seem to be working. I'd also like to replace deadsnakes with uv for the linux free-threaded job since I have that figured out. The issues all seem to be in old versions of python.

Those builds used to be rarely used, and now with uv pushing them they're going to see lots of usage, so perhaps it's just early days here.

Agreed.

@ngoldbaum ngoldbaum force-pushed the free-threaded-ci-update branch from 19ad5ee to b20541b Compare October 17, 2024 18:50
@zanieb
Copy link

zanieb commented Oct 18, 2024

This is cool to see! I'm happy to help unblock ya'll with changes to setup-uv, python-build-standalone, and uv if necessary.

@ngoldbaum
Copy link
Member Author

Closing in favor of #27707

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
39 - free-threading PRs and issues related to support for free-threading CPython (a.k.a. no-GIL, PEP 703) component: CI
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants