cpython: db3e15017172 (original) (raw)

Mercurial > cpython

changeset 72749:db3e15017172

Issue #3163: The struct module gets new format characters 'n' and 'N' supporting C integer types `ssize_t` and `size_t`, respectively. [#3163]

Antoine Pitrou solipsis@pitrou.net
date Thu, 06 Oct 2011 15:27:40 +0200
parents 542c8da10de9
children 1a0715386d27
files Doc/library/struct.rst Lib/test/test_struct.py Misc/NEWS Modules/_struct.c
diffstat 4 files changed, 150 insertions(+), 30 deletions(-)[+] [-] Doc/library/struct.rst 21 Lib/test/test_struct.py 66 Misc/NEWS 3 Modules/_struct.c 90

line wrap: on

line diff

--- a/Doc/library/struct.rst +++ b/Doc/library/struct.rst @@ -187,17 +187,24 @@ platform-dependent. | Q | :c:type:unsigned long | integer | 8 | \(2), \(3) |[](#l1.4) | | long | | | | +--------+--------------------------+--------------------+----------------+------------+ -| f | :c:type:float | float | 4 | (4) | +| n | :c:type:ssize_t | integer | | (4) | ++--------+--------------------------+--------------------+----------------+------------+ +| N | :c:type:size_t | integer | | (4) | +--------+--------------------------+--------------------+----------------+------------+ -| d | :c:type:double | float | 8 | (4) | +| f | :c:type:float | float | 4 | (5) | ++--------+--------------------------+--------------------+----------------+------------+ +| d | :c:type:double | float | 8 | (5) | +--------+--------------------------+--------------------+----------------+------------+ | s | :c:type:char[] | bytes | | | +--------+--------------------------+--------------------+----------------+------------+ | p | :c:type:char[] | bytes | | | +--------+--------------------------+--------------------+----------------+------------+ -| P | :c:type:void \* | integer | | (5) | +| P | :c:type:void \* | integer | | (6) | +--------+--------------------------+--------------------+----------------+------------+ +.. versionchanged:: 3.3

Notes: (1) @@ -219,11 +226,17 @@ Notes: Use of the :meth:__index__ method for non-integers is new in 3.2. (4)

+(5) For the 'f' and 'd' conversion codes, the packed representation uses the IEEE 754 binary32 (for 'f') or binary64 (for 'd') format, regardless of the floating-point format used by the platform. -(5) +(6) The 'P' format character is only available for the native byte ordering (selected as the default or with the '@' byte order character). The byte order character '=' chooses to use little- or big-endian ordering based

--- a/Lib/test/test_struct.py +++ b/Lib/test/test_struct.py @@ -8,9 +8,19 @@ from test.support import run_unittest ISBIGENDIAN = sys.byteorder == "big" IS32BIT = sys.maxsize == 0x7fffffff -integer_codes = 'b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q' +integer_codes = 'b', 'B', 'h', 'H', 'i', 'I', 'l', 'L', 'q', 'Q', 'n', 'N' byteorders = '', '@', '=', '<', '>', '!' +def iter_integer_formats(byteorders=byteorders):

+

Native 'q' packing isn't available on systems that don't have the C

long long type.

try: @@ -141,14 +151,13 @@ class StructTest(unittest.TestCase): } # standard integer sizes

# native integer sizes

@@ -166,9 +175,11 @@ class StructTest(unittest.TestCase): if HAVE_LONG_LONG: self.assertLessEqual(8, struct.calcsize('q')) self.assertLessEqual(struct.calcsize('l'), struct.calcsize('q'))

def test_integers(self):

class IntTester(unittest.TestCase): @@ -182,11 +193,11 @@ class StructTest(unittest.TestCase): self.byteorder) self.bytesize = struct.calcsize(format) self.bitsize = self.bytesize * 8

@@ -316,14 +327,23 @@ class StructTest(unittest.TestCase): struct.pack, self.format, obj)

+

def test_p_code(self): # Test p ("Pascal string") code. @@ -377,14 +397,10 @@ class StructTest(unittest.TestCase): self.assertRaises(OverflowError, struct.pack, ">f", big) def test_1530559(self):

--- a/Misc/NEWS +++ b/Misc/NEWS @@ -294,6 +294,9 @@ Core and Builtins Library ------- +- Issue #3163: The struct module gets new format characters 'n' and 'N'

--- a/Modules/_struct.c +++ b/Modules/_struct.c @@ -58,6 +58,7 @@ typedef struct { char c; long x; } st_lo typedef struct { char c; float x; } st_float; typedef struct { char c; double x; } st_double; typedef struct { char c; void *x; } st_void_p; +typedef struct { char c; size_t x; } st_size_t; #define SHORT_ALIGN (sizeof(st_short) - sizeof(short)) #define INT_ALIGN (sizeof(st_int) - sizeof(int)) @@ -65,6 +66,7 @@ typedef struct { char c; void *x; } st_v #define FLOAT_ALIGN (sizeof(st_float) - sizeof(float)) #define DOUBLE_ALIGN (sizeof(st_double) - sizeof(double)) #define VOID_P_ALIGN (sizeof(st_void_p) - sizeof(void )) +#define SIZE_T_ALIGN (sizeof(st_size_t) - sizeof(size_t)) / We can't support q and Q in native mode unless the compiler does; in std mode, they're 8 bytes on all platforms. */ @@ -213,6 +215,52 @@ get_ulonglong(PyObject v, unsigned PY_L #endif +/ Same, but handling Py_ssize_t */ + +static int +get_ssize_t(PyObject *v, Py_ssize_t *p) +{

+

+} + +/* Same, but handling size_t */ + +static int +get_size_t(PyObject *v, size_t *p) +{

+

+} + #define RANGE_ERROR(x, f, flag, mask) return _range_error(f, flag) @@ -369,6 +417,23 @@ nu_ulong(const char *p, const formatdef return PyLong_FromUnsignedLong(x); } +static PyObject * +nu_ssize_t(const char *p, const formatdef *f) +{

+} + +static PyObject * +nu_size_t(const char *p, const formatdef *f) +{

+} + + /* Native mode doesn't support q or Q unless the platform C supports long long (or, on Windows, __int64). */ @@ -558,6 +623,26 @@ np_ulong(char *p, PyObject *v, const for return 0; } +static int +np_ssize_t(char *p, PyObject *v, const formatdef *f) +{

+} + +static int +np_size_t(char *p, PyObject *v, const formatdef *f) +{

+} + #ifdef HAVE_LONG_LONG static int @@ -651,6 +736,8 @@ static formatdef native_table[] = { {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint}, {'l', sizeof(long), LONG_ALIGN, nu_long, np_long}, {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},

#ifdef HAVE_LONG_LONG {'q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_longlong, np_longlong}, {'Q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong}, @@ -1951,7 +2038,8 @@ these can be preceded by a decimal repea l:long; L:unsigned long; f:float; d:double.\n[](#l4.133) Special cases (preceding decimal count indicates length):\n[](#l4.134) s:string (array of char); p: pascal string (with count byte).\n[](#l4.135) -Special case (only available in native format):\n[](#l4.136) +Special cases (only available in native format):\n[](#l4.137)