cibuildwheel icon indicating copy to clipboard operation
cibuildwheel copied to clipboard

Non-default identifiers?

Open henryiii opened this issue 1 year ago • 6 comments

Description

Currently, we have added a single opt-in identifier (per platform): the free threaded build requires a custom setting, free-threaded-support. But there is an incoming build that we might also want to make opt-in (#1538, GraalPy), and PyPy3.7-3.9 should also be opt-in. Mayne even past-EoL Pythons could be opt in if requires-python was not found. Pyodide (and iOS/Android in the future) are platforms, so not an issue. Maybe we should come up with a way to specify a non-default builds more generally?

As a quick thought to get design ideas going, we could have an opt-in list:

[tool.cibuildwheel]
opt-in = ["free-threaded", "graalpy", "old-pypy", "old-python"]
CIBW_OPT_IN: "free-threaded;graalpy;old-pypy;old-python"

Build log

No response

CI config

No response

henryiii avatar Oct 17 '24 05:10 henryiii

Yep. All good points. I'd like a system such as this too. On the design, here's whats top of mind for me:

  • Do we want to reuse the syntax of build identifiers? e.g. CIBW_BUILD_INCLUDE=graalpy* or CIBW_BUILD_INCLUDE=cp3??t-*

    Probably not... it gets pretty confusing when compared with the CIBW_BUILD option - this ends up being just a more powerful CIBW_BUILD

  • Do we want to change the default CIBW_BUILD to do this?

    Given the amount of wildcards in existing configurations, it's probably not a good idea, as they'd end up opting-in users unexpectedly (e.g. *-manylinux_x86_64 would select all pythons, whereas before it just meant CPython and PyPy)

  • Add more options to the --platform option?

    can't think of a way to do this while keeping the name 'platform', so doesn't feel worth it

I do think it's a shame that we keep adding more build selector options. We already have platform, arch, build/skip, requires-python, free-threaded-support, prerelease-pythons. But, actually, we could also roll prerelease-pythons into this too, which would help clean things up a bit.

So, yeah, I like the design above. On syntax/naming, I'd be inclined to be something like

[tool.cibuildwheel]
enable = ["cpython-free-threaded", "graalpy", "pypy-eol", "cpython-eol", "cpython-prerelease"]
CIBW_ENABLE: "cpython-free-threaded graalpy pypy-eol cpython-eol cpython-prerelease"

joerick avatar Oct 18 '24 09:10 joerick

I do think it's a shame that we keep adding more build selector options

This is supposed to help with that, instead of adding a new one for graalpy. :) The others have their own reasons for existing.

Naming seems fine to me.

henryiii avatar Oct 18 '24 12:10 henryiii

Should we make it an error to set enable and free-threaded-support or prerelease-pythons? We can make it a warning to use those old settings, maybe after one release, then we could remove them eventually. Also, should we make setting this from an environment variable additive? That logically seems better, as you don't want to disable an enable, you just want to add a new enable. Also, adding prerelease-pythons means you'd be able to set this from the pyproject.toml now, but I think that's fine for consistently. Though I'd recommend people use the CIBW_ENABLE: "cpython-prerelease" and make it additive with the TOML setting.

henryiii avatar Oct 18 '24 12:10 henryiii

And what about musl? Should that require an enable too?

henryiii avatar Oct 18 '24 18:10 henryiii

And what about musl? Should that require an enable too?

I don't think so, there was really some demand for those wheels (i.e. should be enable by default) and those not wishing to provide them already have the proper skip in place.

Maybe even past-EoL Pythons could be opt in if requires-python was not found.

Sounds reasonable. Should we warn when it's not found or is this a potential nightmare w.r.t. false positives (cibuildwheel can't resolve it but metadata gets correctly populated with python-requires) ?

Though I'd recommend people use the CIBW_ENABLE: "cpython-prerelease" and make it additive with the TOML setting.

Must have IMHO. We probably want to recommend not setting this one in pyproject.toml or only if abi3 (useful to set it with abi3 to get the tests to run as early as possible with new python versions) and no free-threading.

What about PyPy itself ? The same rational as musl could be used to say nothing more than managing eol could be done but if going this route with GraalPy, maybe we ought to do the same with PyPy ?

mayeut avatar Oct 20 '24 11:10 mayeut

musl

One other way to argue this would be to note that all the other groups we've proposed are rows on the identifier table, this would be the only column-based one. Okay, sounds good. I think this is very much just trying to get the 'default' build avoid things most projects won't need unless there's a special need.

nightmare w.r.t. false positives

The only case affected is projects trying to build EoL Python version with python requires set via setup.py will suddenly not get those old wheels, and will have to add this to opt back in. I think we could have a warning if python-requires is not set.

What about PyPy itself?

It would help to have a good idea of the long-term plans of PyPy. I've heard conflicting things about it's future. If PyPy is going away, we could put it behind a flag. If it's not, having just the supported PyPy on by default is an improvement, and people already have the skips / builds in place for avoiding it if they don't like it.

henryiii avatar Oct 20 '24 13:10 henryiii

The only case affected is projects trying to build EoL Python version with python requires set via setup.py will suddenly not get those old wheels, and will have to add this to opt back in. I think we could have a warning if python-requires is not set.

I've been thinking more about the *-eol flags in enable and it occurs to me that CIBW_PROJECT_REQUIRES_PYTHON is a much better place to set this default. We can change the policy to set this to match the CPython EOL schedule.

There might be an argument to also have pypy-eol since those go EOL sooner. But the cpython-eol flag seems redundant to me, if we're being driven by CIBW_PROJECT_REQUIRES_PYTHON (and project.requires-python).[^1]

[^1]: On the other hand, we could decide that cpython-eol AND CIBW_PROJECT_REQUIRES_PYTHON need to be set before cibuildwheel will build EOL CPythons. Which does have some logic to it, actually, because then we have the ability to by-default turn off EOL pythons for different interpreters at different thresholds. E.g. what if a user wants eol pypy but not eol cpython. Buuut, I suspect most packagers would rather just keep building the old versions since they get a lot of usage, so I'm slightly reticent to force a config change on them - let me know if you disagree.

What about PyPy itself?

It would help to have a good idea of the long-term plans of PyPy. I've heard conflicting things about it's future. If PyPy is going away, we could put it behind a flag. If it's not, having just the supported PyPy on by default is an improvement, and people already have the skips / builds in place for avoiding it if they don't like it.

Agreed. I'd also like to know a little about usage. How often are the PyPy wheels used, compared the the CPython ones? When we added it, I was quite keen on it being on by default because my assumption was that usage was fairly low because of lack of wheels on PyPI. But now we've run the experiment and we can check the results. Of course some maintainers choose to disable PyPy builds too, but that's not exactly an argument in favour of it being on by default ;)

joerick avatar Oct 27 '24 12:10 joerick

IMO we do want at least a pypy-eol, since we don't want people building PyPy wheels for non-supported PyPy versions. Though if PyPy is going away long term, then we should just put all of them behind an option. I think SPEC 0 (36 months, vs. the old 42 months of NEP 29) is basically killing PyPy, since there's now no window of supported PyPy's for NumPy and friends.

henryiii avatar Oct 28 '24 05:10 henryiii

And CIBW_PROJECT_REQUIRES_PYTHON is not supported in pyproject.toml for projects that don't use PEP 621. That was the main (only) reason to have cpython-eol, otherwise it would have no effect if this is set.

henryiii avatar Oct 28 '24 05:10 henryiii

@mattip, thoughts on making old versions or all versions opt-in?

henryiii avatar Oct 28 '24 06:10 henryiii

I think it is fine to make all versions of PyPy opt-in. Testing c-extension modules on PyPy is generally slow and annoys end users. We can revisit this decision in the future if needed.

mattip avatar Oct 28 '24 07:10 mattip

What about this list then::

free-threading
prerelease
pypy
graalpy

?

henryiii avatar Oct 29 '24 03:10 henryiii

Yeah, that seems right to me, but I'd be inclined to prefix on the cpython ones, just to be explicit.

cpython-free-threading
cpython-prerelease
pypy
graalpy

Just in case we need a -prerelease tag on a different interpreter in future.

joerick avatar Oct 29 '24 09:10 joerick

Couldn't we just require both if that happens? For example, if there was a pypy prerelease, it could be ["pypy", "prerelease"]? You are basically opting-in, saying you know these exist and are going to handle them in your CIBW_BUILD, and if you support pypy and prereleases, it seems sensible than you'd support pypy prereleases?

henryiii avatar Oct 29 '24 13:10 henryiii

Should we also support opting out? So "!cpython-free-threading" would mean never build free-threading, even if it becomes the default in 3.15/3.26? That would also make these potentially usable before 3.0, as you could set !pypy to explicitly never build pypy. Or is that too much?

henryiii avatar Nov 01 '24 03:11 henryiii

Should we also support opting out?

Obviously it makes sense as a concept as this allows changing defaults without disrupting users who opted-out explicitely as you explained.

That being said, at the moment, the only one I'm almost sure we'll want to change at some point is the free-threading one (and we might want to remove the option for the version just before it becomes the only way cpython is built, if I understood the end game correctly).

mayeut avatar Nov 02 '24 10:11 mayeut

Couldn't we just require both if that happens? For example, if there was a pypy prerelease, it could be ["pypy", "prerelease"]? You are basically opting-in, saying you know these exist and are going to handle them in your CIBW_BUILD, and if you support pypy and prereleases, it seems sensible than you'd support pypy prereleases?

Yeah, but I think it's conceptually more complicated. If we keep the categories separate, we have a direct mapping from each enable flag to a set of build identifiers that it turns on. If we have implied relationships, then we have boolean logic between each flag and the resulting builds. Unless there's an implementation reason why keeping the prereleases flag the same is a good idea?

Should we also support opting out? So "!cpython-free-threading" would mean never build free-threading, even if it becomes the default in 3.15/3.26? That would also make these potentially usable before 3.0, as you could set !pypy to explicitly never build pypy. Or is that too much?

I think we could leave this open as a possible future API surface, but I'm not sure that's what we'd promote when the time comes. when/if we get to turning on free-threaded by default, we could just document skip = "cp3??t-*" to disable those. It feels better to me to use the same option we already have for skipping rather than talking about a new one. That said, it certainly can't hurt to leave the possibility open.

joerick avatar Nov 05 '24 18:11 joerick

cpython-free-threading vs. cpython-free-threaded?

henryiii avatar Nov 06 '24 04:11 henryiii

I just checked the official decision on this and it looks likecpython-freethreading is the way to go.

joerick avatar Nov 06 '24 09:11 joerick

(That actually fits better with cpython-prerelease too, same number of dashes)

henryiii avatar Nov 06 '24 14:11 henryiii