Skip to content
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

Add __slots__ to structs #130

Open
corby opened this issue Dec 21, 2023 · 4 comments
Open

Add __slots__ to structs #130

corby opened this issue Dec 21, 2023 · 4 comments

Comments

@corby
Copy link

corby commented Dec 21, 2023

This is an excellent tool and just what I was looking for. Thank you.

In order for the IDEs to recognize the fields as valid inputs we add __slots__ to all of our ctype.Structs.
Would it be possible to add a step to each struct def to add the slots?

e.g.:

class struct_c__SA_my_struct_t(Structure):
    pass

class struct_c__SA_my_struct_t._pack_ = 1  # source:True
class struct_c__SA_my_struct_t._fields_ = [
    ('my_var1', ctypes.c_ubyte),
    ('my_var2', ctypes.c_uint16),
]
class struct_c__SA_my_struct_t.__slots__ = ('my_var1','my_var2')
@mara004
Copy link

mara004 commented Mar 4, 2024

Note that __slots__ must be defined in the actual class body in order to be effective, that's very important.
The above post-definition assignment does nothing except set a casual attribute, i.e. won't enable the special slots feature.

Minimal repro:

>>> from ctypes import *
>>>
>>> class TestStruct (Structure): pass
... 
>>> TestStruct.__slots__ = ["a", "b"]
>>> s = TestStruct()
>>> s.c = 1
>>> 
>>> class TestStruct (Structure):
...     __slots__ = ["a", "b"]
... 
>>> s = TestStruct()
>>> s.c = 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'TestStruct' object has no attribute 'c'

@corby corby closed this as completed Jul 31, 2024
@mara004
Copy link

mara004 commented Jul 31, 2024

@corby Shouldn't this be kept open? I don't think ctypeslib provides slots yet?
The latest commit on master dates a year back, and searching for __slots__ yields nothing.

@corby corby reopened this Jul 31, 2024
@corby
Copy link
Author

corby commented Jul 31, 2024

Apologies. I thought the point of the note was adding slots to the system would be pointless since it won't enforce frozen attributes.

@mara004
Copy link

mara004 commented Jul 31, 2024

I thought the point of the note was adding slots to the system would be pointless since it won't enforce frozen attributes.

No: Slots are fine, you just have to get the declaration right.
What the above example was supposed to express is that assigning slots to a class after definition (as in your initial post) takes no effect beyond setting a casual attribute, whereas declaring them during class creation1 does.

It's quite easy to shoot yourself in the foot with a typo in a struct field name, so it is a good idea to (correctly) set up slots on bindings generation to prevent assignment of non-existent fields.

(Defining slots in the class body is not an issue with forward declarations, because they contain just the field names, no actual references.)

Footnotes

  1. e.g. in the class body itself, or in a metaclass

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants