Title: struct.Struct Addition
Type: enhancement Stage: resolved
Components: Extension Modules Versions: Python 3.7
Status: closed Resolution: rejected
Dependencies: Superseder:
Assigned To: Nosy List: mark.dickinson, martin.panter, meador.inge, palaviv, rhettinger, serhiy.storchaka, vstinner
Priority: normal Keywords:

Created on 2017-03-25 15:44 by palaviv, last changed 2017-04-21 23:37 by vstinner. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 817 closed palaviv, 2017-03-25 15:46
Messages (6)
msg290486 - (view) Author: Aviv Palivoda (palaviv) * Date: 2017-03-25 15:44
I would like to suggest that the struct.Struct class will support addition. For example you will be able to do:

>>> s1 = Struct(">L")
>>> s2 = Struct(">B")
>>> s3 = s1 + s2
>>> s3.format
msg290488 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2017-03-25 16:45
What is the purpose of this feature? Note that the layout of the structure consisting of two structures is not the same as the layout of the structure consisting of the same fields as separate structures.

struct {
    struct {
        char a;
        short b;
    } s1;
    struct {
        char c;
        int d;
    } s2;


struct {
    char a;
    short b;
    char c;
    int d;

can have different sizes and offsets of fields.

As for the concrete implementation, it looks to me that Struct('2L') + Struct('25B') results to Struct('2L5B').
msg290490 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2017-03-25 17:25
I concur with Serhiy that this proposal is likely to cause more problems than it solves.
msg290495 - (view) Author: Aviv Palivoda (palaviv) * Date: 2017-03-25 18:12
I have two use cases for this feature:

struct a {
    int a;
#ifdef VER2
    unsigned int b;

Now I may do:
>>> ver1 = Struct("i")
>>> ver2 = ver1 + Struct("I")


struct a {
    int a;
    union inner {
        int b;
        unsigned int c;
    } u;

As you can see with this feature I may do:
>>> start = Struct("i")
>>> union_b = Struct("i")
>>> union_c = Struct("I")
>>> version_a = start + union_b
>>> version_b = start + union_c

If you have a big struct with many options in the union this save's copying the initial format.

> As for the concrete implementation, it looks to me that Struct('2L') + Struct('25B') results to Struct('2L5B').

I will fix the case when there is no format provided.
msg290501 - (view) Author: Martin Panter (martin.panter) * (Python committer) Date: 2017-03-25 21:32
For the native alignment case (prefix code @), perhaps you can already use the “ctypes” module, which supports structures with more complicated embedded fields.

For the the unaligned modes (prefixes =, <, > and !), I am a little sympathetic. In the past, I wanted to make various structures that extended from a common base structure:

HSF_VOL_DESC = Struct("< B 5s B")

# Python 3's "Struct.format" is a byte string!
NSR_DESC = Struct(HSF_VOL_DESC.format.decode() + "B")

But I think if Issue 21071 was fixed (change Struct.format to text string, or perhaps add a new attribute), I would be happy enough writing

NSR_DESC = Struct(HSF_VOL_DESC.format_str + "B")

Transforming Aviv’s examples:

s3 = Struct(s1.format_str + s2.format_str[1:])
s3 = Struct(s1.format_str + "B")  # if s2 is not needed on its own
ver2 = Struct(ver1.format_str + "I")
version_a = Struct(start.format_str + union_b.format_str[1:])
msg292082 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2017-04-21 23:37
I dislike this feature. I reject it: Serhiy, Raymond and me dislike it.

I never needed this feature and a correct implementation can be very complex if you have to take care of endian, alignement, etc. It's trivial to implement you own add using the format attribute if you want the simple implementation format1+format2.
Date User Action Args
2017-04-21 23:37:22vstinnersetstatus: open -> closed

nosy: + vstinner
messages: + msg292082

resolution: rejected
stage: resolved
2017-03-25 21:32:25martin.pantersetnosy: + martin.panter
messages: + msg290501
2017-03-25 18:12:11palavivsetmessages: + msg290495
2017-03-25 17:25:28rhettingersetnosy: + rhettinger
messages: + msg290490
2017-03-25 16:45:26serhiy.storchakasetnosy: + serhiy.storchaka
messages: + msg290488
2017-03-25 15:46:20palavivsetpull_requests: + pull_request723
2017-03-25 15:44:48palavivcreate