-
-
Notifications
You must be signed in to change notification settings - Fork 181
Kernel-dependent features like os.pidfd_open()
#193
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
Comments
The way things currently work is that we build the CPython distributions against very old kernel headers and glibc to ensure maximum binary portability by targeting a very old, ~universally supported syscall + glibc API surface. CPython currently uses compile time checks for features like On macOS, CPython is using Mach-O weak symbols and run-time checks allow us to reference macOS SDK APIs that aren't available in all machines. If they are present at run-time, CPython can use them. If they aren't, the features depending on them aren't available. This is ideal from an end-user perspective because it doesn't penalize the common user running on modern macOS by depriving them of newer features. On Linux, ELF has support for weak symbols/linking. This is conceptually similar to Mach-O's similar feature. Usually you add a compiler #pragma or similar preprocessor directive to indicate a symbol is weakly linked. If the symbol resolves at run-time, the symbol/function address is non-0 and you can call it. Unfortunately, I don't believe CPython has any support for weak symbols on Linux/ELF. So getting run-time conditional features isn't trivially achievable. (I'd have to page this in my brain but I want to say there are some practical limitations of weak symbols on ELF that may make their use non-viable. Even if there are, there are similar features like IFUNC that could potentially be employed for dynamic run-time dispatch support.) That's a long way of saying that features like pidfd_open() currently require separate build variants to work. That leads to an explosion of build variants targeting various Linux + glibc feature levels. That becomes unwieldy very fast. It might be worth engaging upstream CPython about supporting weak symbols, IFUNC, or similar run-time dynamic feature detection on Linux/ELF like they do on macOS. This would allow pre-built CPython binaries to have better performance and features versus what is achievable today. @gpshead is this worth a discussion in a CPython forum? If so, which one? |
Thanks for the detailed explanation! |
Just a note for others: The motivation of my question/request is that when distributing Python-based apps to non-controllable "enterprise" environments (e.g., air-gapped customer-owned clusters), we need to be able to enable/disable such kernel-specific features based on the runtime availability without rebuilding everything for each customer site. |
I have the same problem but with |
Would a short term solution for some users, not be to simply update the docker container for one with a newer
|
Yes, if you want the builds to pick up newer features from newer glibc and Linux the way to do that is to modernize those versions via the container base image. It has been a few years and it may be worth making that change universally. It depends what CPython upstream is doing with ABI compatibility in wheels. (We want our distros to be compatible with oldest ABI seen in binary wheels in the wild.) I almost filed a standalone issue to track this a few hours ago... |
I looked into this and it doesn't seem overly complicated to move the compatibility checks to runtime, though I am not really convinced it's worth the trouble over just publishing a couple of different builds targetting the already defined manylinux and manymusl platform tags. The main issue with supporting this upstream is the complexity and maintenance burden, though it's definitely worth a discussion. |
Upstream already uses weak linking on macOS so they can target an older SDK but leverage features from a newer one. The Apple SDKs do make this easier than on Linux. (I recall there being caveats with weak linking and runtime availability checking in Linux but I can't recall specifics.) You should engage upstream about doing this on Linux! |
We chatted on Discord and it sounds like the upstream is willing to accept patches for this on Linux. I intend to do so when I have the chance! We'll also probably add a build variant targeting one (or more) of the latest manylinux libc targets, since the added weak linking would only be available on 3.14+. |
Great to hear some progress here! 👍🏼 |
Commenting to help search engines: This is also the reason for
For |
Recent Python versions add optional features such as
os.pidfd_open()
when it is available during the build time.This is going to be the default implementation of asyncio's child process watcher as of Python 3.12, with a fallback to the thread-based legacy implementation.
It seems that the current Python 3.11 distribution in this repo does not have
os.pidfd_open()
.While this is not a critical regression because most libraries depending on it has a good fallback, but I'd like to be able to adopt such new kernel features.
I'm not sure how the current release process could handle this. Maybe we need to have multiple different builds like the x86_64 v2/v3/... CPU generations, by several Linux kernel versions. I'm afraid that this would incur too much burden for the build infra.
I'm just reporting this issue as a future reference, though.
The text was updated successfully, but these errors were encountered: