struct.pack('h', ...) difference between 1.5.2 and 2.0

François Pinard pinard at
Fri Dec 21 16:15:55 EST 2001

Hello, my fellow python lovers.

One of my co-worker's script, written for 1.5.2, used the expression:

        struct.pack('h', socket.htons(VALUE))

which worked for any VALUE fitting in 16 bits.  One could argue that this
could be better written as:

        struct.pack('H', socket.htons(VALUE))

or even as:

        struct.pack('!h', VALUE)

but this is not the subject of this message.

The initial writing fails with Python 2.0 whenever (VALUE & 1 << 7) is
not zero.  Python 2.2c1 also fails with this diagnostic:

   struct.error: short format requires SHRT_MIN<=number<=SHRT_MAX

The error could find its justification by saying that `struct.pack' became
more strict about the signed versus unsigned quantities.  However, if we
replace `h' et `H' by `i' and `I' above, and `htons' by `htonl', one might
expect a similar failure in similar circumstances, but there is none.

The `Python Library' documentation I have here is silent on the signed
or unsigned qualities of the result of `socket.htons' and `socket.htonl'.
Quick experimentation shows that the former returns unsigned 16-bit integer
values, while the latter returns signed 32-bit integer values.

If `struct.pack' was and is lenient about checking ranges for `i' and `I',
may I humbly suggest that it could also stay lenient as it once was about
`h' and `H', as one may question that the stricter checking introduced by
Python 2.0 is fruitful.

Or else, I would be tempted to consider as a bug against 2.2c1 that
`struct.pack' is strict for the `h' case and lenient for the `I' case.
It should then be either lenient for both, as it was for 1.5.2, or become
strict for both.  Is it your feeling as well?

François Pinard

More information about the Python-list mailing list