# Add constants to struct module

**URL:** <https://discuss.python.org/t/add-constants-to-struct-module/26792>\
**Category:** Ideas\
**Created:** [May 15, 2023, 3:05pm UTC](https://discuss.python.org/t/add-constants-to-struct-module/26792 "2023-05-15T15:05:08Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ping-Winner](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/ping-winner/32/12503_2.png) [@Ping-Winner](https://discuss.python.org/u/Ping-Winner)\
**Post date:** [May 15, 2023, 3:05pm UTC](https://discuss.python.org/t/add-constants-to-struct-module/26792/1 "2023-05-15T15:05:08Z")

</div>

The `struct` module has various formatting characters, such as `b` for `signed char`, `>` for `big-endian` etc.  
Developers need to use strings like `'>bhQII?'` to represent the packing/unpacking format.  
Such strings are hard to build, error prone, and unreadable:

- **Hard to build** : No one remembers all these values by heart. It is very frustrating to open and read the documentation every time one builds such a string.
- **Error prone** : It is so easy to confuse and use `B` instead of `b`, or `>` instead of `<`.
- **Unreadable** : Reading the format string is not intuitive at all.

It would be nice to define each character as a constant value, something like this:

```auto
...
BIG_ENDIAN = '>'
LITTLE_ENDIAN = '<'
...
SIGNED_CHAR = 'b'
UNSIGNED_CHAR = 'B'
...

```

This will let us build readable format strings easily:

```auto
format_str = f'{struct.BIG_ENDIAN}{struct.UNSIGNED_CHAR}{struct.SIGNED_LONG_LONG}' # == '>Bq'
# (Just to make sense - I checked and fixed myself 7 times against documentation page to verify I represented this correctly)

```

It is much less error prone, much more readable, and easy to build and maintain. Especially when we have the IDE auto-complete.

What’s your opinion?

---

<div class="post-metadata">

**Author:** ![ntessore](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/ntessore/32/10786_2.png) [@ntessore](https://discuss.python.org/u/ntessore)\
**Post date:** [May 15, 2023, 3:34pm UTC](https://discuss.python.org/t/add-constants-to-struct-module/26792/2 "2023-05-15T15:34:34Z")

</div>

If you have the constants, why not put them into a tuple instead of a string?

---

<div class="post-metadata">

**Author:** ![pf\_moore](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/pf_moore/32/35_2.png) [@pf\_moore](https://discuss.python.org/u/pf_moore)\
**Post date:** [May 15, 2023, 3:52pm UTC](https://discuss.python.org/t/add-constants-to-struct-module/26792/3 "2023-05-15T15:52:48Z")

</div>

While the existing method isn’t particularly readable, I don’t find the proposed alternative any better. Rather than being too short, it’s too long, and anything non-trivial will likely start needing to be split over multiple lines. I see the struct module as a low level tool, and as such, terseness is usually a benefit. Consider regular expressions as an example of something similar in a different context.

Personally, I’d use the existing string with an explanatory comment, or write a “format builder” function specific to my application if I needed to write more than one format string.

---

<div class="post-metadata">

**Author:** ![Ping-Winner](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/ping-winner/32/12503_2.png) [@Ping-Winner](https://discuss.python.org/u/Ping-Winner)\
**Post date:** [May 15, 2023, 3:55pm UTC](https://discuss.python.org/t/add-constants-to-struct-module/26792/4 "2023-05-15T15:55:15Z")

</div>

Are you sure about the internal implementaion of `pack()` / `unpack()`?  
If they just iterate over `format`, using `tuple` sounds good too.

---

<div class="post-metadata">

**Author:** ![Tinche](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/tinche/32/12507_2.png) [@Tinche](https://discuss.python.org/u/Tinche)\
**Post date:** [May 15, 2023, 4:02pm UTC](https://discuss.python.org/t/add-constants-to-struct-module/26792/5 "2023-05-15T16:02:32Z")

</div>

I had the opportunity to use the struct library last week so I feel the OP’s pain. Your comment is exactly what I was thinking though, this sounds like a job for a format builder library. PyPI is a great place for such libraries to prove themselves before the standard library is considered.

---

<div class="post-metadata">

**Author:** ![ntessore](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/ntessore/32/10786_2.png) [@ntessore](https://discuss.python.org/u/ntessore)\
**Post date:** [May 15, 2023, 4:03pm UTC](https://discuss.python.org/t/add-constants-to-struct-module/26792/6 "2023-05-15T16:03:09Z")

</div>

I don’t know, but you are already proposing a change. Converting a tuple of constants (should be Enum values, I suppose) to a string at some step would be trivial.

Personally I think the existing format is perfectly fine. The struct module isn’t exactly something where you can get away without carefully reading the documentation, anyway.

---

<div class="post-metadata">

**Author:** ![Dutcho](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/dutcho/32/7074_2.png) [@Dutcho](https://discuss.python.org/u/Dutcho)\
**Post date:** [May 15, 2023, 4:23pm UTC](https://discuss.python.org/t/add-constants-to-struct-module/26792/7 "2023-05-15T16:23:10Z")

</div>

For making `struct` more readable, should we think along [`ctypes` path](https://discuss.python.org/t/annotation-based-sugar-for-ctypes/26579)?

---

<div class="post-metadata">

**Author:** ![DamirHanov](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/damirhanov/32/12200_2.png) [@DamirHanov](https://discuss.python.org/u/DamirHanov)\
**Post date:** [May 15, 2023, 5:22pm UTC](https://discuss.python.org/t/add-constants-to-struct-module/26792/8 "2023-05-15T17:22:07Z")

</div>

I use struct module a lot at my job. From my experience the pain you feel when starting with struct goes away in couple of weeks.  
Also, as already mentioned by Paul Moore almost all of fromats I build with some sort of format builder.

If you need something more expressive you might consider using [Construct](https://construct.readthedocs.io/en/latest/) package.

---

<div class="post-metadata">

**Author:** ![orent](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/orent/32/10796_2.png) [@orent](https://discuss.python.org/u/orent)\
**Post date:** [May 15, 2023, 7:53pm UTC](https://discuss.python.org/t/add-constants-to-struct-module/26792/9 "2023-05-15T19:53:36Z")

</div>

Instead of making struct more like crypes you can just use ctypes.

The ctypes module is perfectly usable for applications that do not involve loading DLLs or calling C functions e.g. speaking some binary protocol over a socket.

And with my proposed annotation-based sugar (see adjacent thread) the syntax is much nicer.
