| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| Expand Up | @@ -3161,6 +3161,72 @@ fields, or any other data types containing pointer type fields. | |
| that should be merged into a containing structure or union. | ||
|
|
||
|
|
||
| .. decorator:: struct(*, align=None, layout, endian='native', pack=None) | ||
| :module: ctypes.util | ||
|
|
||
| A :term:`decorator` that allows generating structure types using an | ||
| annotation-based syntax, similar to the :mod:`dataclasses` module. | ||
|
|
||
| For example: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| from ctypes.util import struct | ||
| from ctypes import c_int | ||
|
|
||
| @struct | ||
| class Point: | ||
| x: c_int | ||
| y: c_int | ||
|
|
||
| point = Point(1, 2) | ||
|
|
||
| *align*, *layout*, and *pack* supply the value for the :attr:`~ctypes.Structure._align_`, | ||
| :attr:`~ctypes.Structure._layout_`, and :attr:`~ctypes.Structure._pack_` | ||
| attributes, respectively. | ||
|
|
||
| *endian* controls which structure class will be used as the base. | ||
|
|
||
| - If *endian* is ``'native'``, :class:`~ctypes.Structure` will be used. | ||
| - If *endian* is ``'big'``, :class:`~ctypes.BigEndianStructure` will be used. | ||
| - If *endian* is ``'little'``, :class:`~ctypes.LittleEndianStructure` will be used. | ||
|
|
||
| Any other value will raise a :class:`ValueError`. | ||
|
|
||
| For controlling field-specific data, wrap the annotation in :class:`typing.Annotated` | ||
| with :class:`CFieldInfo` as the second argument, like so: | ||
|
Comment thread
Comment on lines
+3196
to
+3197
Copy link
Copy Markdown
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityMaybe 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?
Sorry, something went wrong.
All reactions
Copy link
Copy Markdown
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityAnnotated is more correct, isn't it? field() from dataclasses predates typing.Annotated, so that's why it's used there.
Sorry, something went wrong.
johnslavik reacted with thumbs up emoji
All reactions
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityYes, it is more correct.
Sorry, something went wrong.
All reactions
|
||
|
|
||
| .. code-block:: python | ||
|
|
||
| @struct | ||
| class PyObject: | ||
| ob_refcnt: c_ssize_t | ||
| ob_type: c_void_p | ||
|
|
||
| @struct | ||
| class PyHovercraftObject: | ||
| ob_base: Annotated[PyObject, CFieldInfo(anonymous=True)] | ||
|
|
||
| .. versionadded:: next | ||
|
|
||
|
|
||
| .. class:: CFieldInfo(anonymous=False, bit_width=None) | ||
| :module: ctypes.util | ||
|
|
||
| Information regarding a structure field defined by the :func:`struct` | ||
| decorator. This should be used in the second argument of a | ||
| :class:`typing.Annotated` wrapping a ctypes type. | ||
|
|
||
| *anonymous* specifies whether the field will be present in the | ||
| :attr:`~ctypes.Structure._anonymous_` attribute of the generated class. | ||
|
|
||
| If *bit_width* is non-``None``, the annotated field will be *bit_width* | ||
| number of bits in the generated structure. This is equivalent to passing | ||
| a third item in :attr:`~ctypes.Structure._fields_`. | ||
|
|
||
| .. versionadded:: next | ||
|
|
||
|
|
||
| .. _ctypes-arrays-pointers: | ||
|
|
||
| Arrays and pointers | ||
| Expand Down | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,9 +1,16 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import os | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import sys | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from dataclasses import dataclass | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| lazy import functools | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| lazy import shutil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| lazy import subprocess | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| lazy import annotationlib | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| lazy from typing import Annotated, get_args, ClassVar, get_origin | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| lazy from ctypes import Structure, BigEndianStructure, LittleEndianStructure | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # find_library(name) returns the pathname of a library, or None. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if os.name == "nt": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Expand Down Expand Up | @@ -491,6 +498,82 @@ def dllist(): | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ctypes.byref(ctypes.py_object(libraries))) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return libraries | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @dataclass(slots=True, frozen=True) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| class CFieldInfo: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| anonymous: bool = False | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bit_width: int | None = None | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def _process_struct(decorated_class, /, *, align, layout, endian, pack): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fields = [] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| anonymous = [] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if issubclass(decorated_class, Structure): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fields.extend(decorated_class._fields_) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| anonymous.extend(decorated_class._anonymous_) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for name, hint in annotationlib.get_annotations(decorated_class).items(): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if get_origin(hint) is ClassVar: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| continue | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| field = [name] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if get_origin(hint) is Annotated: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cls, field_info = get_args(hint) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| field.append(cls) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if not isinstance(field_info, CFieldInfo): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| raise TypeError(f"expected CFieldInfo in Annotated, got {field_info!r}") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if field_info.bit_width is not None: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| field.append(field_info.bit_width) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if field_info.anonymous is True: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| anonymous.append(name) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| field.append(hint) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fields.append(field) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if endian == 'big': | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| endian_class = BigEndianStructure | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| elif endian == 'little': | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| endian_class = LittleEndianStructure | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| elif endian == 'native': | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| endian_class = Structure | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| raise ValueError(f"expected 'big', 'little', or 'native', but got {endian!r}") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @functools.wraps(decorated_class, updated=()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| class _Struct(endian_class): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| vars().update(vars(decorated_class)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if align is not None: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| _align_ = align | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if layout is not None: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| _layout_ = layout | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if pack is not None: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| _pack_ = pack | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| _fields_ = fields | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| _anonymous_ = anonymous | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return _Struct | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 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(decorated_class): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return process_the_struct(decorated_class) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return inner | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return process_the_struct(class_or_none) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment thread
Comment on lines
+560
to
+575
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityI meant it like this:
Suggested change
That's how decorators of this fashion are usually made.
Sorry, something went wrong.
All reactions
Copy link
Copy Markdown
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Qualityprocess_the_struct isn't defined here; what are you trying to show?
Sorry, something went wrong.
All reactions
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityEdited the suggestion
Sorry, something went wrong.
All reactions
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ################################################################ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # test code | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Expand Down | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Back | FazBrowse Home | New Git URL |
Uh oh!
There was an error while loading. Please reload this page.
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.
Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityConsider adding a collation: old syntax vs. new syntax.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
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.
Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityI don't think that's necessary -- the examples for Structure are right above.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.