-
Notifications
You must be signed in to change notification settings - Fork 3.1k
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
Fix OS X platform detection for pep425tags #3232
Conversation
For the purpose of detecting the user's platform to determine which wheels are compatible, this switches pep425tags.get_platform() to avoid distutils.util.get_platform() on OS X, because that method returns the release on which the current interpreter was built (often 10.5 or 10.6) as opposed to the platform on which the interpreter is running.
Just to be clear, currently we'll accept any wheel compiled against an SDK starting from 10.0 and up to and including the SDK version that Python was built against (10.6 for Python.org). This change will change that so it's up to the version of OSX that is currently running instead. I'm not super familiar with the OSX binary ABI rules, so questions:
|
IIRC the answers are yes/yes/no, but if someone knows of a nice write-up of these rules that would be very useful. |
Ok. So this is probably safe to merge then. Sent from my iPhone
|
Fix OS X platform detection for pep425tags
@dstufft: Doesn't this change mercilessly break shit? Previously, I could just compile a python interpreter on the newest version of OSX and then all wheels would work, regardless of the platform that my interpreter was running on. Now, I have to make sure that all of my wheels are built with an interpreter that was compiled on a version of OSX not newer than the version my interpreter is going to run on. |
Are you really doing that? Building against an older SDK isn't that reliable, Apple's backwards compat is a lot better than its forward compat. IIRC the python.org installers are always built on the lowest supported OS X version. |
If your python interpreter is built on an ancient OS X version then you're fucked if someone is distributing wheels built on an interpreter that was built on a newer OS X version (previously this was so). |
And can you elaborate on the issue you're having, preferably with a concrete example? |
I built a python interpreter on OSX 10.11
This was nice because I didn't need to worry about what interpreter wheel distributors were building stuff with because newer interpreter build system versions are considered compatible with older wheel build system versions. For example, this was useful with cffi==1.3.0, https://pypi.python.org/pypi/cffi/1.3.0 because it only had wheels for 10.10. Those wheels weren't going to install with python.org or Apple distributions because those interpreters were built on 10.6/10.8. At this point, the cat was out of the bag and I had a custom python build, so I started building other wheels against my 10.11 system. The interpreter and wheels then worked no problem on 10.10 and 10.11 systems. But with the newer version of pip, these wheels won't work on 10.10 systems. Seems like a breaking change. |
This is unsupported usage and is not guaranteed to work. I'm surprised that the interpreter even runs, that's just luck I think. You need to set |
So those wheels are named |
Unsupported by Apple you mean?
Right
I'm not saying that the old way was correct. Just that the new way is incompatible with the assumptions the old way allowed you to make. I'm going to rebuild all of my wheels/interpreter, but just want to point out that this definitely broke shit. tl;dr You broke my hack that seemed inline with pip's policy but involved unsupported Apple behavior. |
indeed.
Fair enough, can be annoying if it used to make your life easier. Don't think it was "pip policy" though, more like a plain bug that was fixed by this PR. |
By policy, I mean this document.
Anyways, it's Friday, have a good weekend. |
Thanks @burrows-labs. That's not a |
I'm a bit confused I'm afraid - @burrows-labs - you are building wheels with an interpreter reporting itself as:
These wheels presumably have names like Then you are trying to install these wheels, via pip, on an interpreter reporting itself as something like:
? |
@matthew-brett no, his interpreter is built on 10.11 so gives I pinged you because (a) you're one of the experts here so would be nice if you could verify that this PR and my answers above are correct, and (b) your description isn't quite correct anymore after this PR so you may want to update it. |
OK - sorry - I've now read the thread the Robert pointed to at the beginning, and this thread with more attention. Explaining to myself: Interpreter SDK = SDK with which the interpreter was built; Initial pip rule: A) wheel SDK <= interpreter SDK. The change broke stuff for @burrows-labs because they are building with the 10.11 SDK (interpreter SDK) but running on an earlier platform version, so that wheels that appear compatible when running on 10.11 appear incompatible when running on 10.10. The assumption of the initial rule A) is that wheels should be using an SDK compatible with the interpreter. The assumption of the new rule B) is that that the only thing that matters is the platform on which the wheel will run (we can assume SDKs of versions <= platform version are available). We've got good reason to think that interpreter SDK can be > wheel SDK, as wheels built with the 10.6 SDK have been working well with homebrew / system Python, almost always built with higher SDKs. So, the key question is, whether the interpreter SDK can be < wheel SDK (Robert's initial example was Interpreter SDK == 10.5, wheel SDK == 10.6, platform version == 10.10). I don't know the answer to that. @minrk, @ned-deily - do you know whether there is a risk of using extension code compiled with a later SDK than that of the interpreter? |
I think it can be. IMO, the evidence to that effect comes from many people using interpreter SDK == 10.5/10.6 from Python.org or a re-distributor like Anaconda, and then either compiling or downloading wheels compiled with a more recent SDK, and things working fine. |
@matthew-brett That sums up my understanding of the issue. |
Robert - I don't think it's that common to download or compile wheels compiled for a higher SDK. By default the standard wheels are compiled against Python.org Python, and therefore SDK 10.6. If you build wheels against Python.org Python / Anaconda, you'll get 10.6 / 10.5 SDK. |
I think there's some confusion here between |
I've actually yet to find a combination that doesn't work in terms of platform, Python, and package deployment targets, probably because the libraries I test with don't call APIs that have changed. It would perhaps be best to find some APIs that are added/deprecated/removed and build extensions that call those to see what actually works. Checking the current platform version makes sense to me, but I don't know what happens when you load two libraries built against different targets calling changed versions of the same API. |
@ned-deily - thanks for the clarification. From the doc you pointed to, Apple makes a distinction between "Deployment target" (specified by |
Min - can you think of any ABI changes that we might run into, and could test against? |
Let me just say with my pip developer hat on, that we probably want to do what is considered the "correct" thing to do wrt what we accept as a viable wheel not just whatever works. Just to be clear though, there are two sides to this thing, one is what wheel sets (which I assume should be the deployment target, which I believe is what it is now) and the other is which wheels should pip itself support which I think is currently >= to the current platform we're running on, ignoring what platform the interpreter was built for. I think the assumption was that a wheel built for 10.11 may not run on 10.11 (missing symbols and the like) so we shouldn't attempt to use it. Perhaps this doesn't actually matter unless you're using one of the APIs provided by the SDK and we should offer a more generic version of the platform tag. |
Certainly. I only meant to convey that I haven't found examples that don't work, which we could use to double check that we are doing the right thing.
I think this is almost right. The wheel always stores the deployment target of Python itself, which will be the deployment target of the library unless MACOSX_DEPLOYMENT_TARGET is set explicitly. Changing the deployment target does not change the string stored in the wheel, which perhaps it should.
After this PR, yes. I think that's the correct behavior, but haven't found an authoritative answer or test case to back it up. I'm confident that it's the right interpretation for whole programs. Where I haven't found a test case or confirmation is what happens when you have load libraries with different targets in the same process. |
For the purpose of detecting the user's platform to determine which wheels are compatible, this switches
pep425tags.get_platform()
to avoiddistutils.util.get_platform()
on OS X, because that method returns the release on which the interpreter was built (often but not always 10.5 or 10.6) as opposed to the platform on which the interpreter is running.see also: https://mail.python.org/pipermail/distutils-sig/2015-November/027578.html