Index: Python/getargs.c =================================================================== --- Python/getargs.c (révision 81783) +++ Python/getargs.c (copie de travail) @@ -1311,13 +1311,16 @@ int temp=-1; Py_buffer view; - if (pb && pb->bf_releasebuffer && *format != '*') - /* Buffer must be released, yet caller does not use - the Py_buffer protocol. */ - return converterr("pinned buffer", arg, msgbuf, bufsize); + if (*format++ != '*' && *format++ != '#') + return converterr( + "invalid use of 'w' format character", + arg, msgbuf, bufsize); + if (pb == NULL || pb->bf_getbuffer == NULL) + return converterr("single-segment read-write buffer", + arg, msgbuf, bufsize); - if (pb && pb->bf_getbuffer && *format == '*') { + if (*format == '*') { /* Caller is interested in Py_buffer, and the object supports it directly. */ format++; @@ -1332,29 +1335,28 @@ } if (!PyBuffer_IsContiguous((Py_buffer*)p, 'C')) return converterr("contiguous buffer", arg, msgbuf, bufsize); - break; - } + } else /* if (*format == '#') */ { + if (pb->bf_releasebuffer) + /* Buffer must be released, yet caller does not use + the Py_buffer protocol. */ + return converterr("pinned buffer", arg, msgbuf, bufsize); - /* Here we have processed w*, only w and w# remain. */ - if (pb == NULL || - pb->bf_getbuffer == NULL || - ((temp = PyObject_GetBuffer(arg, &view, - PyBUF_SIMPLE)) != 0) || - view.readonly == 1) { - if (temp==0) { - PyBuffer_Release(&view); + format++; + temp = PyObject_GetBuffer(arg, &view, PyBUF_SIMPLE); + if (temp != 0 || view.readonly == 1) { + if (temp==0) + PyBuffer_Release(&view); + return converterr("single-segment read-write buffer", + arg, msgbuf, bufsize); } - return converterr("single-segment read-write buffer", - arg, msgbuf, bufsize); - } - if ((count = view.len) < 0) - return converterr("(unspecified)", arg, msgbuf, bufsize); - *p = view.buf; - if (*format == '#') { + count = view.len; + if (count < 0) + return converterr("(unspecified)", arg, msgbuf, bufsize); + *p = view.buf; + FETCH_SIZE; STORE_SIZE(count); - format++; } break; } Index: Doc/c-api/arg.rst =================================================================== --- Doc/c-api/arg.rst (révision 81783) +++ Doc/c-api/arg.rst (copie de travail) @@ -156,21 +156,17 @@ single-segment buffer objects are accepted; :exc:`TypeError` is raised for all others. -``w`` (read-write character buffer) [char \*] - Similar to ``s``, but accepts any object which implements the read-write buffer - interface. The caller must determine the length of the buffer by other means, - or use ``w#`` instead. Only single-segment buffer objects are accepted; - :exc:`TypeError` is raised for all others. - ``w*`` (read-write byte-oriented buffer) [Py_buffer] - This is to ``w`` what ``s*`` is to ``s``. + This format accepts any object which implements the read-write buffer + interface. It fills a :ctype:`Py_buffer` structure provided by the caller. + The buffer may contain embedded null bytes. ``w#`` (read-write character buffer) [char \*, int] - Like ``s#``, but accepts any object which implements the read-write buffer - interface. The :ctype:`char \*` variable is set to point to the first byte - of the buffer, and the :ctype:`int` is set to the length of the buffer. - Only single-segment buffer objects are accepted; :exc:`TypeError` is raised - for all others. + Like ``w*``, except that it doesn't accept mutable buffer-like objects such + as :class:`bytearray`. The :ctype:`char \*` variable is set to point to the + first byte of the buffer, and the :ctype:`int` is set to the length of the + buffer. Only single-segment buffer objects are accepted; :exc:`TypeError` + is raised for all others. The buffer may contain embedded null bytes. ``es`` (string, Unicode object or character buffer compatible object) [const char \*encoding, char \*\*buffer] This variant on ``s`` is used for encoding Unicode and objects convertible to Index: Doc/whatsnew/3.2.rst =================================================================== --- Doc/whatsnew/3.2.rst (révision 81783) +++ Doc/whatsnew/3.2.rst (copie de travail) @@ -173,4 +173,7 @@ * bytearray objects cannot be used anymore as filenames: convert them to bytes +* PyArg_ParseTuple(): remove "w" format because the caller doesn't know the + buffer size. Use "w*" or "w#" format instead. + * Stub