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
gh-97588: Fix ctypes structs #97702
base: main
Are you sure you want to change the base?
gh-97588: Fix ctypes structs #97702
Conversation
@mdickinson You recently fixed a few things in ctypes, perhaps you could kindly help me find someone to review these changes here, please? Thanks! |
The git history of this PR is a bit dirty at the moment. I can clean it up, if there's interest. I can also polish the code more, if you give me some hints about what you want to see. I also have a repository with lots of extra tests via Python Hypothesis. (Alas, we can't use Python Hypothesis to test the standard library? Or can we?) |
This is the largest challenge I in getting this change out safely. Our API behavior is wrong, but it has been shipped in a couple of CPython releases already, so we probably need to assume that some users depend on it. That means documenting properly what the actual behavior was and adding an API flag to pick which behavior people want. If it appears this API has wide usage expecting it, defaulting to the existing behavior for a couple of releases before we can flip the default. If usage of the wrong behavior is rare, flipping the default while providing a flag for the old behavior could be done more rapidly than our usual deprecation period there. Searching a large corpus of code internally at work, usage of the three item tuple in ctypes Structure context (meaning bit field width) is not common. But it does come up.
|
@gpshead Thanks for having a look. I agree. Thanks for digging up those uses of ctypes. I'll try to run the test suites of those projects, perhaps. Some complications: the existing code often leads to undefined behaviour. Thus in a strict sense, we can not guarantee bug-for-bug compatibility, even if we don't change anything. Of course, in practice it's probably fine as long as we keep the old code in place (with a feature toggle as you suggest) and don't change compilers versions nor compiler flags too much. The undefined behaviour in the old version was what lead me to investigate ctypes in the first place. See #96823 for context. As an ambitious goal, in addition to the providing a proper fix behind a feature toggle, perhaps we can also fix (some of) the undefined behaviour in the old version, without breaking anything? I'm not sure. Do you have an opinion? |
ideally - if tests on those examples of use still happen to work as written, we can probably just go ahead and make the change without a breaking change cycle. Ultimately I want us to be rid of the existing bad/old behavior entirely. It's mostly a matter of seeing if it is feasible to give people depending on that (possibly undefined) behavior a heads up and time to fix things to work with the correct implementation. |
I am working my way through the list of users that you found.
I'm waiting for local |
@gpshead The problematic code is both gnarly and rarely executed: only once when we are reading in a struct / union definition. That shouldn't be on anyone's critical path: creation, reading or writing of those structs is done by other code. That should make it a prime candidate for implementing in Python instead of C? Do you have an opinion? That would make for a larger diff, maybe. But it's definitely easier to write readable and maintainable code in Python than in C. |
Hmm, it looks like if I want to test the changes here with client code, I might be better off back-porting to an older Python (like 3.11 or even older), so that eg numpy works. |
(I'm going to guess that ctypes changes so rarely the .diff of this branch applies pretty cleanly to 3.11 for testing purposes) |
regarding writing the critical path for this in Python instead of C... that sounds like a great idea. I agree that |
See #102774 The main change necessary was |
The existing code is quite a mess and doesn't correspond to what gcc nor clang nor msvc are doing.
This PR fixes all the issues below.