-
-
Notifications
You must be signed in to change notification settings - Fork 31k
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-128715: Expose ctypes.CField, with info attributes #128950
base: main
Are you sure you want to change the base?
Conversation
|
||
# Do not use CField outside ctypes, yet. | ||
# The constructor is internal API and may change without warning. | ||
_internal_use=True, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is something that pytest does a lot but how about naming it _cpython=True
to stress that it's tied to CPython implementation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not really -- if there's another implementation of ctypes
I'd prefer that they use _internal_use
too :)
expected_size = (field.bit_size << 16) + offset_for_size | ||
self.assertEqual(field.size, expected_size) | ||
else: | ||
# size == byte_size |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know if you used ===
above to not uncomment by mistake, so maybe size === byte_size
as well? (or maybe the === was a typo)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow, good eye :)
Above it's not a guard against uncommenting; I meant something like ≡
-- they're always the same. Here, the else
case is where they're equal.
(The comments don't communicate that well, but, it doesn't really matter. The next person can make them consistent if they prefer that.)
"bit field %R size too large, got %zd", | ||
name, byte_size); | ||
} | ||
bitfield_size = PyLong_AsSsize_t(bit_size_obj); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note for myself: because bit_size_obj
should be small, we would use a fast path so this call would be efficient. However, if it's too large, then it will be slower, but we don't care as we will raise an exception.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is class creation. I'm leaving optimizations to PGO :)
Expose the type of struct/union field descriptors (
_ctypes._CField
) asctypes.CField
. (This is mainly to make it easier to refer to it -- for typing and documentation. CreatingCField
s manually is not supported.)Add attributes for easier introspection:
name
&type
, as defined in_fields_
byte_size
&byte_offset
, specify the chunk of memory to read/writebit_size
&bit_offset
, which specify the shift & mask for bitfieldsis_bitfield
&is_anonymous
booleansThe existing
offset
remains, as an alias forbyte_offset
.The existing
size
is unchanged. Usually it is the same asbyte_size
, but for bitfields, it contains a bit-packed combination ofbit_size
&bit_offset
.Update the
repr()
ofCField
.Use the same values internally as well. (Except
bit_size
, which might overflowPy_ssize_t
for very large types. Instead, in C usebitfield_size
, which is 0 for non-bitfields and thus serves asis_bitfield
flag. Different name used clarity.)Old names are removed from the C implementation to ensure a clean transition.
For simplicity, I keep
byte_size
inCFieldObject
for now, even though it's redundant: it's the size of the underlying type.Add a generic test that ensures the values are consistent, and that we don't have overlapping fields in structs. Use this check throughout
test_ctypes
, wherever a potentially interesting Structure or Union is created. (Tests for how simple structs behave after they're created don't need the checks, but I erred on the side of adding checks.)Lift the restriction on maximum field size that was temporarily added in GH-126938. The max size is now
Py_ssize_t
.This PR does not yet touch
cfield.c
getters & setters: the bit-packed “size” argument is computed and passed to those.📚 Documentation preview 📚: https://cpython-previews--128950.org.readthedocs.build/