Skip to content

gh-104533: Add a dataclass-like decorator for ctypes structures - #153781

Merged
ZeroIntensity merged 10 commits into
python:mainfrom
ZeroIntensity:ctypes/struct-decorator
Jul 18, 2026
Merged

gh-104533: Add a dataclass-like decorator for ctypes structures#153781
ZeroIntensity merged 10 commits into
python:mainfrom
ZeroIntensity:ctypes/struct-decorator

Conversation

@ZeroIntensity

@ZeroIntensityZeroIntensity commented Jul 15, 2026

Copy link
Copy Markdown
Member

@read-the-docs-community

read-the-docs-communityBot commented Jul 15, 2026

Copy link
Copy Markdown

Documentation build overview

📚 cpython-previews | 🛠️ Build #33620062 | 📁 Comparing 2e469b6 against main (b4662e8)

🔍 Preview build

3 files changed
±library/ctypes.html
±whatsnew/3.16.html
±whatsnew/changelog.html

Comment threadLib/ctypes/util.py Outdated
Comment threadLib/ctypes/util.py Outdated
Comment threadLib/ctypes/util.py Outdated
Comment threadLib/ctypes/util.py Outdated
@ZeroIntensity
ZeroIntensity marked this pull request as ready for review July 16, 2026 09:39
Comment threadLib/ctypes/util.py Outdated
Comment threadLib/ctypes/util.py
Comment on lines +561 to +576
def struct(class_or_none=None, /, *, align=None, layout=None, endian='native', pack=None):
process_the_struct = functools.partial(
_process_struct,
align=align,
layout=layout,
endian=endian,
pack=pack
)

if class_or_none is None:
def inner(klass):
return process_the_struct(klass)

return inner

return process_the_struct(class_or_none)

@johnslavikjohnslavikJul 16, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant it like this:

Suggested change
defstruct(class_or_none=None, /, *, align=None, layout=None, endian='native', pack=None):
process_the_struct=functools.partial(
_process_struct,
align=align,
layout=layout,
endian=endian,
pack=pack
)
ifclass_or_noneisNone:
definner(klass):
returnprocess_the_struct(klass)
returninner
returnprocess_the_struct(class_or_none)
defstruct(class_or_none=None, /, *, align=None, layout=None, endian='native', pack=None):
ifclass_or_noneisNone:
returnfunctools.partial(
struct,
align=align,
layout=layout,
endian=endian,
pack=pack,
)
return_process_struct(
class_or_none,
align=align,
layout=layout,
endian=endian,
pack=pack,
)

That's how decorators of this fashion are usually made.
Feel free to ignore.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

process_the_struct isn't defined here; what are you trying to show?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Edited the suggestion

Comment on lines +3164 to +3165
.. decorator:: struct(*, align=None, layout, endian='native', pack=None)
:module: ctypes.util

@johnslavikjohnslavikJul 16, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding a collation: old syntax vs. new syntax.

@ZeroIntensityZeroIntensityJul 16, 2026

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that's necessary -- the examples for Structure are right above.

Comment threadLib/ctypes/util.py Outdated
ZeroIntensityand others added 2 commits July 16, 2026 12:01
Co-authored-by: Bartosz Sławecki <bartosz@ilikepython.com>
@ZeroIntensity
ZeroIntensity merged commit 5b85756 into python:mainJul 18, 2026
51 checks passed
@ZeroIntensity
ZeroIntensity deleted the ctypes/struct-decorator branch July 18, 2026 08:48
fedonman pushed a commit to fedonman/cpython that referenced this pull request Jul 18, 2026
…es (pythonGH-153781)
Co-authored-by: Bartosz Sławecki <bartosz@ilikepython.com>
Comment on lines +3196 to +3197
For controlling field-specific data, wrap the annotation in :class:`typing.Annotated`
with :class:`CFieldInfo` as the second argument, like so:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a silly question, but why does this use Annotated instead of dataclasses-style field: SomeType = field(anonymous=True) syntax? Did I miss a consensus on this?

@ZeroIntensityZeroIntensityJul 18, 2026

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Annotated is more correct, isn't it? field() from dataclasses predates typing.Annotated, so that's why it's used there.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it is more correct.

@vstinner

Copy link
Copy Markdown
Member

Oh, this new API looks easier to use than ctypes.Structure, I'm excited!

fromctypes.utilimportstructfromctypesimportc_int@structclassPoint:
x: c_inty: c_intpoint=Point(1, 2)
print(point)

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@ZeroIntensity@vstinner@merwok@GalaxySnail@johnslavik