"argument 1 must be sequence of length 1, not 0"):
parse(([],), {}, '(' + f + ')', ['a'])
- def test_specific_type_errors(self):
- parse = _testcapi.parse_tuple_and_keywords
-
- def check(format, arg, expected, got='list'):
- errmsg = f'must be {expected}, not {got}'
- with self.assertRaisesRegex(TypeError, errmsg):
- parse((arg,), {}, format, ['a'])
-
- check('k', [], 'int')
- check('k?', [], 'int or None')
- check('K', [], 'int')
- check('K?', [], 'int or None')
- check('c', [], 'a byte string of length 1')
- check('c?', [], 'a byte string of length 1 or None')
- check('c', b'abc', 'a byte string of length 1',
- 'a bytes object of length 3')
- check('c?', b'abc', 'a byte string of length 1 or None',
- 'a bytes object of length 3')
- check('c', bytearray(b'abc'), 'a byte string of length 1',
- 'a bytearray object of length 3')
- check('c?', bytearray(b'abc'), 'a byte string of length 1 or None',
- 'a bytearray object of length 3')
- check('C', [], 'a unicode character')
- check('C?', [], 'a unicode character or None')
- check('C', 'abc', 'a unicode character',
- 'a string of length 3')
- check('C?', 'abc', 'a unicode character or None',
- 'a string of length 3')
- check('s', [], 'str')
- check('s?', [], 'str or None')
- check('z', [], 'str or None')
- check('z?', [], 'str or None')
- check('es', [], 'str')
- check('es?', [], 'str or None')
- check('es#', [], 'str')
- check('es#?', [], 'str or None')
- check('et', [], 'str, bytes or bytearray')
- check('et?', [], 'str, bytes, bytearray or None')
- check('et#', [], 'str, bytes or bytearray')
- check('et#?', [], 'str, bytes, bytearray or None')
- check('w*', [], 'read-write bytes-like object')
- check('w*?', [], 'read-write bytes-like object or None')
- check('S', [], 'bytes')
- check('S?', [], 'bytes or None')
- check('U', [], 'str')
- check('U?', [], 'str or None')
- check('Y', [], 'bytearray')
- check('Y?', [], 'bytearray or None')
- check('(OO)', 42, '2-item tuple', 'int')
- check('(OO)?', 42, '2-item tuple or None', 'int')
- check('(OO)', (1, 2, 3), 'tuple of length 2', '3')
-
- def test_nullable(self):
- parse = _testcapi.parse_tuple_and_keywords
-
- def check(format, arg, allows_none=False):
- # Because some format units (such as y*) require cleanup,
- # we force the parsing code to perform the cleanup by adding
- # an argument that always fails.
- # By checking for an exception, we ensure that the parsing
- # of the first argument was successful.
- self.assertRaises(OverflowError, parse,
- (arg, 256), {}, format + '?b', ['a', 'b'])
- self.assertRaises(OverflowError, parse,
- (None, 256), {}, format + '?b', ['a', 'b'])
- self.assertRaises(OverflowError, parse,
- (arg, 256), {}, format + 'b', ['a', 'b'])
- self.assertRaises(OverflowError if allows_none else TypeError, parse,
- (None, 256), {}, format + 'b', ['a', 'b'])
-
- check('b', 42)
- check('B', 42)
- check('h', 42)
- check('H', 42)
- check('i', 42)
- check('I', 42)
- check('n', 42)
- check('l', 42)
- check('k', 42)
- check('L', 42)
- check('K', 42)
- check('f', 2.5)
- check('d', 2.5)
- check('D', 2.5j)
- check('c', b'a')
- check('C', 'a')
- check('p', True, allows_none=True)
- check('y', b'buffer')
- check('y*', b'buffer')
- check('y#', b'buffer')
- check('s', 'string')
- check('s*', 'string')
- check('s#', 'string')
- check('z', 'string', allows_none=True)
- check('z*', 'string', allows_none=True)
- check('z#', 'string', allows_none=True)
- check('w*', bytearray(b'buffer'))
- check('U', 'string')
- check('S', b'bytes')
- check('Y', bytearray(b'bytearray'))
- check('O', object, allows_none=True)
-
- check('(OO)', (1, 2))
- self.assertEqual(parse((((1, 2), 3),), {}, '((OO)?O)', ['a']), (1, 2, 3))
- self.assertEqual(parse(((None, 3),), {}, '((OO)?O)', ['a']), (NULL, NULL, 3))
- self.assertEqual(parse((((1, 2), 3),), {}, '((OO)O)', ['a']), (1, 2, 3))
- self.assertRaises(TypeError, parse, ((None, 3),), {}, '((OO)O)', ['a'])
-
- parse((None,), {}, 'es?', ['a'])
- parse((None,), {}, 'es#?', ['a'])
- parse((None,), {}, 'et?', ['a'])
- parse((None,), {}, 'et#?', ['a'])
- parse((None,), {}, 'O!?', ['a'])
- parse((None,), {}, 'O&?', ['a'])
-
- # TODO: More tests for es?, es#?, et?, et#?, O!, O&
-
@unittest.skipIf(_testinternalcapi is None, 'needs _testinternalcapi')
def test_gh_119213(self):
rc, out, err = script_helper.assert_python_ok("-c", """if True:
/* New getargs implementation */
-#include <stdbool.h>
-
#define PY_CXX_CONST const
#include "Python.h"
#include "pycore_abstract.h" // _PyNumber_Index()
const char *format = *p_format;
int i;
Py_ssize_t len;
- bool nullable = false;
int istuple = PyTuple_Check(arg);
int mustbetuple = istuple;
- assert(*format == '(');
- format++;
for (;;) {
int c = *format++;
if (c == '(') {
level++;
}
else if (c == ')') {
- if (level == 0) {
- if (*format == '?') {
- nullable = true;
- }
+ if (level == 0)
break;
- }
level--;
}
else if (c == ':' || c == ';' || c == '\0')
}
}
- if (arg == Py_None && nullable) {
- const char *msg = skipitem(p_format, p_va, flags);
- if (msg != NULL) {
- levels[0] = 0;
- }
- return msg;
- }
if (istuple) {
/* fallthrough */
}
{
levels[0] = 0;
PyOS_snprintf(msgbuf, bufsize,
- "must be %d-item tuple%s, not %.50s",
- n,
- nullable ? " or None" : "",
- arg == Py_None ? "None" : Py_TYPE(arg)->tp_name);
+ "must be %d-item tuple, not %.50s",
+ n,
+ arg == Py_None ? "None" : Py_TYPE(arg)->tp_name);
return msgbuf;
}
else {
return msgbuf;
}
- format = *p_format + 1;
+ format = *p_format;
for (i = 0; i < n; i++) {
const char *msg;
PyObject *item = PyTuple_GET_ITEM(arg, i);
}
}
- format++;
- if (*format == '?') {
- format++;
- }
*p_format = format;
if (!istuple) {
Py_DECREF(arg);
const char *format = *p_format;
if (*format == '(' /* ')' */) {
+ format++;
msg = converttuple(arg, &format, p_va, flags, levels, msgbuf,
bufsize, freelist);
+ if (msg == NULL)
+ format++;
}
else {
msg = convertsimple(arg, &format, p_va, flags,
}
static const char *
-converterr(bool nullable, const char *expected, PyObject *arg, char *msgbuf, size_t bufsize)
+converterr(const char *expected, PyObject *arg, char *msgbuf, size_t bufsize)
{
assert(expected != NULL);
assert(arg != NULL);
}
else {
PyOS_snprintf(msgbuf, bufsize,
- "must be %.50s%s, not %.50s", expected,
- nullable ? " or None" : "",
+ "must be %.50s, not %.50s", expected,
arg == Py_None ? "None" : Py_TYPE(arg)->tp_name);
}
return msgbuf;
}
static const char *
-convertcharerr(bool nullable, const char *expected, const char *what, Py_ssize_t size,
+convertcharerr(const char *expected, const char *what, Py_ssize_t size,
char *msgbuf, size_t bufsize)
{
assert(expected != NULL);
PyOS_snprintf(msgbuf, bufsize,
- "must be %.50s%s, not %.50s of length %zd",
- expected,
- nullable ? " or None" : "",
- what, size);
+ "must be %.50s, not %.50s of length %zd",
+ expected, what, size);
return msgbuf;
}
char *msgbuf, size_t bufsize, freelist_t *freelist)
{
#define RETURN_ERR_OCCURRED return msgbuf
-#define HANDLE_NULLABLE \
- if (*format == '?') { \
- format++; \
- if (arg == Py_None) { \
- break; \
- } \
- nullable = true; \
- }
-
const char *format = *p_format;
char c = *format++;
const char *sarg;
- bool nullable = false;
switch (c) {
case 'b': { /* unsigned byte -- very short int */
unsigned char *p = va_arg(*p_va, unsigned char *);
- HANDLE_NULLABLE;
long ival = PyLong_AsLong(arg);
if (ival == -1 && PyErr_Occurred())
RETURN_ERR_OCCURRED;
"unsigned byte integer is greater than maximum");
RETURN_ERR_OCCURRED;
}
+ else
*p = (unsigned char) ival;
break;
}
case 'B': {/* byte sized bitfield - both signed and unsigned
values allowed */
unsigned char *p = va_arg(*p_va, unsigned char *);
- HANDLE_NULLABLE;
Py_ssize_t bytes = PyLong_AsNativeBytes(arg, p, sizeof(unsigned char),
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
Py_ASNATIVEBYTES_ALLOW_INDEX |
case 'h': {/* signed short int */
short *p = va_arg(*p_va, short *);
- HANDLE_NULLABLE;
long ival = PyLong_AsLong(arg);
if (ival == -1 && PyErr_Occurred())
RETURN_ERR_OCCURRED;
case 'H': { /* short int sized bitfield, both signed and
unsigned allowed */
unsigned short *p = va_arg(*p_va, unsigned short *);
- HANDLE_NULLABLE;
Py_ssize_t bytes = PyLong_AsNativeBytes(arg, p, sizeof(unsigned short),
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
Py_ASNATIVEBYTES_ALLOW_INDEX |
case 'i': {/* signed int */
int *p = va_arg(*p_va, int *);
- HANDLE_NULLABLE;
long ival = PyLong_AsLong(arg);
if (ival == -1 && PyErr_Occurred())
RETURN_ERR_OCCURRED;
case 'I': { /* int sized bitfield, both signed and
unsigned allowed */
unsigned int *p = va_arg(*p_va, unsigned int *);
- HANDLE_NULLABLE;
Py_ssize_t bytes = PyLong_AsNativeBytes(arg, p, sizeof(unsigned int),
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
Py_ASNATIVEBYTES_ALLOW_INDEX |
{
PyObject *iobj;
Py_ssize_t *p = va_arg(*p_va, Py_ssize_t *);
- HANDLE_NULLABLE;
Py_ssize_t ival = -1;
iobj = _PyNumber_Index(arg);
if (iobj != NULL) {
}
case 'l': {/* long int */
long *p = va_arg(*p_va, long *);
- HANDLE_NULLABLE;
long ival = PyLong_AsLong(arg);
if (ival == -1 && PyErr_Occurred())
RETURN_ERR_OCCURRED;
case 'k': { /* long sized bitfield */
unsigned long *p = va_arg(*p_va, unsigned long *);
- HANDLE_NULLABLE;
if (!PyIndex_Check(arg)) {
- return converterr(nullable, "int", arg, msgbuf, bufsize);
+ return converterr("int", arg, msgbuf, bufsize);
}
Py_ssize_t bytes = PyLong_AsNativeBytes(arg, p, sizeof(unsigned long),
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
case 'L': {/* long long */
long long *p = va_arg( *p_va, long long * );
- HANDLE_NULLABLE;
long long ival = PyLong_AsLongLong(arg);
if (ival == (long long)-1 && PyErr_Occurred())
RETURN_ERR_OCCURRED;
case 'K': { /* long long sized bitfield */
unsigned long long *p = va_arg(*p_va, unsigned long long *);
- HANDLE_NULLABLE;
if (!PyIndex_Check(arg)) {
- return converterr(nullable, "int", arg, msgbuf, bufsize);
+ return converterr("int", arg, msgbuf, bufsize);
}
Py_ssize_t bytes = PyLong_AsNativeBytes(arg, p, sizeof(unsigned long long),
Py_ASNATIVEBYTES_NATIVE_ENDIAN |
case 'f': {/* float */
float *p = va_arg(*p_va, float *);
- HANDLE_NULLABLE;
double dval = PyFloat_AsDouble(arg);
if (dval == -1.0 && PyErr_Occurred())
RETURN_ERR_OCCURRED;
case 'd': {/* double */
double *p = va_arg(*p_va, double *);
- HANDLE_NULLABLE;
double dval = PyFloat_AsDouble(arg);
if (dval == -1.0 && PyErr_Occurred())
RETURN_ERR_OCCURRED;
case 'D': {/* complex double */
Py_complex *p = va_arg(*p_va, Py_complex *);
- HANDLE_NULLABLE;
Py_complex cval;
cval = PyComplex_AsCComplex(arg);
if (PyErr_Occurred())
case 'c': {/* char */
char *p = va_arg(*p_va, char *);
- HANDLE_NULLABLE;
if (PyBytes_Check(arg)) {
if (PyBytes_GET_SIZE(arg) != 1) {
- return convertcharerr(nullable, "a byte string of length 1",
+ return convertcharerr("a byte string of length 1",
"a bytes object", PyBytes_GET_SIZE(arg),
msgbuf, bufsize);
}
}
else if (PyByteArray_Check(arg)) {
if (PyByteArray_GET_SIZE(arg) != 1) {
- return convertcharerr(nullable, "a byte string of length 1",
+ return convertcharerr("a byte string of length 1",
"a bytearray object", PyByteArray_GET_SIZE(arg),
msgbuf, bufsize);
}
*p = PyByteArray_AS_STRING(arg)[0];
}
else
- return converterr(nullable, "a byte string of length 1", arg, msgbuf, bufsize);
+ return converterr("a byte string of length 1", arg, msgbuf, bufsize);
break;
}
case 'C': {/* unicode char */
int *p = va_arg(*p_va, int *);
- HANDLE_NULLABLE;
int kind;
const void *data;
if (!PyUnicode_Check(arg))
- return converterr(nullable, "a unicode character", arg, msgbuf, bufsize);
+ return converterr("a unicode character", arg, msgbuf, bufsize);
if (PyUnicode_GET_LENGTH(arg) != 1) {
- return convertcharerr(nullable, "a unicode character",
+ return convertcharerr("a unicode character",
"a string", PyUnicode_GET_LENGTH(arg),
msgbuf, bufsize);
}
case 'p': {/* boolean *p*redicate */
int *p = va_arg(*p_va, int *);
- HANDLE_NULLABLE;
int val = PyObject_IsTrue(arg);
if (val > 0)
*p = 1;
const char *buf;
Py_ssize_t count;
if (*format == '*') {
- format++;
- HANDLE_NULLABLE;
if (getbuffer(arg, (Py_buffer*)p, &buf) < 0)
- return converterr(nullable, buf, arg, msgbuf, bufsize);
+ return converterr(buf, arg, msgbuf, bufsize);
+ format++;
if (addcleanup(p, freelist, cleanup_buffer)) {
return converterr(
- nullable, "(cleanup problem)",
+ "(cleanup problem)",
arg, msgbuf, bufsize);
}
break;
}
- else if (*format == '#') {
+ count = convertbuffer(arg, (const void **)p, &buf);
+ if (count < 0)
+ return converterr(buf, arg, msgbuf, bufsize);
+ if (*format == '#') {
Py_ssize_t *psize = va_arg(*p_va, Py_ssize_t*);
- format++;
- HANDLE_NULLABLE;
- count = convertbuffer(arg, (const void **)p, &buf);
- if (count < 0)
- return converterr(nullable, buf, arg, msgbuf, bufsize);
*psize = count;
- }
- else {
- HANDLE_NULLABLE;
- count = convertbuffer(arg, (const void **)p, &buf);
- if (count < 0)
- return converterr(nullable, buf, arg, msgbuf, bufsize);
+ format++;
+ } else {
if (strlen(*p) != (size_t)count) {
PyErr_SetString(PyExc_ValueError, "embedded null byte");
RETURN_ERR_OCCURRED;
/* "s*" or "z*" */
Py_buffer *p = (Py_buffer *)va_arg(*p_va, Py_buffer *);
- format++;
- HANDLE_NULLABLE;
if (c == 'z' && arg == Py_None)
PyBuffer_FillInfo(p, NULL, NULL, 0, 1, 0);
else if (PyUnicode_Check(arg)) {
Py_ssize_t len;
sarg = PyUnicode_AsUTF8AndSize(arg, &len);
if (sarg == NULL)
- return converterr(nullable, CONV_UNICODE,
+ return converterr(CONV_UNICODE,
arg, msgbuf, bufsize);
PyBuffer_FillInfo(p, arg, (void *)sarg, len, 1, 0);
}
else { /* any bytes-like object */
const char *buf;
if (getbuffer(arg, p, &buf) < 0)
- return converterr(nullable, buf, arg, msgbuf, bufsize);
+ return converterr(buf, arg, msgbuf, bufsize);
}
if (addcleanup(p, freelist, cleanup_buffer)) {
return converterr(
- nullable, "(cleanup problem)",
+ "(cleanup problem)",
arg, msgbuf, bufsize);
}
+ format++;
} else if (*format == '#') { /* a string or read-only bytes-like object */
/* "s#" or "z#" */
const void **p = (const void **)va_arg(*p_va, const char **);
Py_ssize_t *psize = va_arg(*p_va, Py_ssize_t*);
- format++;
- HANDLE_NULLABLE;
if (c == 'z' && arg == Py_None) {
*p = NULL;
*psize = 0;
Py_ssize_t len;
sarg = PyUnicode_AsUTF8AndSize(arg, &len);
if (sarg == NULL)
- return converterr(nullable, CONV_UNICODE,
+ return converterr(CONV_UNICODE,
arg, msgbuf, bufsize);
*p = sarg;
*psize = len;
const char *buf;
Py_ssize_t count = convertbuffer(arg, p, &buf);
if (count < 0)
- return converterr(nullable, buf, arg, msgbuf, bufsize);
+ return converterr(buf, arg, msgbuf, bufsize);
*psize = count;
}
+ format++;
} else {
/* "s" or "z" */
const char **p = va_arg(*p_va, const char **);
Py_ssize_t len;
sarg = NULL;
- HANDLE_NULLABLE;
if (c == 'z' && arg == Py_None)
*p = NULL;
else if (PyUnicode_Check(arg)) {
sarg = PyUnicode_AsUTF8AndSize(arg, &len);
if (sarg == NULL)
- return converterr(nullable, CONV_UNICODE,
+ return converterr(CONV_UNICODE,
arg, msgbuf, bufsize);
if (strlen(sarg) != (size_t)len) {
PyErr_SetString(PyExc_ValueError, "embedded null character");
*p = sarg;
}
else
- return converterr(c == 'z' || nullable, "str",
+ return converterr(c == 'z' ? "str or None" : "str",
arg, msgbuf, bufsize);
}
break;
recode_strings = 0;
else
return converterr(
- nullable, "(unknown parser marker combination)",
+ "(unknown parser marker combination)",
arg, msgbuf, bufsize);
buffer = (char **)va_arg(*p_va, char **);
format++;
if (buffer == NULL)
- return converterr(nullable, "(buffer is NULL)",
+ return converterr("(buffer is NULL)",
arg, msgbuf, bufsize);
- Py_ssize_t *psize = NULL;
- if (*format == '#') {
- /* Using buffer length parameter '#':
-
- - if *buffer is NULL, a new buffer of the
- needed size is allocated and the data
- copied into it; *buffer is updated to point
- to the new buffer; the caller is
- responsible for PyMem_Free()ing it after
- usage
-
- - if *buffer is not NULL, the data is
- copied to *buffer; *buffer_len has to be
- set to the size of the buffer on input;
- buffer overflow is signalled with an error;
- buffer has to provide enough room for the
- encoded string plus the trailing 0-byte
-
- - in both cases, *buffer_len is updated to
- the size of the buffer /excluding/ the
- trailing 0-byte
-
- */
- psize = va_arg(*p_va, Py_ssize_t*);
-
- format++;
- if (psize == NULL) {
- return converterr(
- nullable, "(buffer_len is NULL)",
- arg, msgbuf, bufsize);
- }
- }
- HANDLE_NULLABLE;
/* Encode object */
if (!recode_strings &&
encoding,
NULL);
if (s == NULL)
- return converterr(nullable, "(encoding failed)",
+ return converterr("(encoding failed)",
arg, msgbuf, bufsize);
assert(PyBytes_Check(s));
size = PyBytes_GET_SIZE(s);
}
else {
return converterr(
- nullable,
- recode_strings ? "str"
- : nullable ? "str, bytes, bytearray"
- : "str, bytes or bytearray",
+ recode_strings ? "str" : "str, bytes or bytearray",
arg, msgbuf, bufsize);
}
/* Write output; output is guaranteed to be 0-terminated */
- if (psize != NULL) {
+ if (*format == '#') {
+ /* Using buffer length parameter '#':
+
+ - if *buffer is NULL, a new buffer of the
+ needed size is allocated and the data
+ copied into it; *buffer is updated to point
+ to the new buffer; the caller is
+ responsible for PyMem_Free()ing it after
+ usage
+
+ - if *buffer is not NULL, the data is
+ copied to *buffer; *buffer_len has to be
+ set to the size of the buffer on input;
+ buffer overflow is signalled with an error;
+ buffer has to provide enough room for the
+ encoded string plus the trailing 0-byte
+
+ - in both cases, *buffer_len is updated to
+ the size of the buffer /excluding/ the
+ trailing 0-byte
+
+ */
+ Py_ssize_t *psize = va_arg(*p_va, Py_ssize_t*);
+
+ format++;
+ if (psize == NULL) {
+ Py_DECREF(s);
+ return converterr(
+ "(buffer_len is NULL)",
+ arg, msgbuf, bufsize);
+ }
if (*buffer == NULL) {
*buffer = PyMem_NEW(char, size + 1);
if (*buffer == NULL) {
if (addcleanup(buffer, freelist, cleanup_ptr)) {
Py_DECREF(s);
return converterr(
- nullable, "(cleanup problem)",
+ "(cleanup problem)",
arg, msgbuf, bufsize);
}
} else {
if ((Py_ssize_t)strlen(ptr) != size) {
Py_DECREF(s);
return converterr(
- nullable, "encoded string without null bytes",
+ "encoded string without null bytes",
arg, msgbuf, bufsize);
}
*buffer = PyMem_NEW(char, size + 1);
}
if (addcleanup(buffer, freelist, cleanup_ptr)) {
Py_DECREF(s);
- return converterr(nullable, "(cleanup problem)",
+ return converterr("(cleanup problem)",
arg, msgbuf, bufsize);
}
memcpy(*buffer, ptr, size+1);
case 'S': { /* PyBytes object */
PyObject **p = va_arg(*p_va, PyObject **);
- HANDLE_NULLABLE;
if (PyBytes_Check(arg))
*p = arg;
else
- return converterr(nullable, "bytes", arg, msgbuf, bufsize);
+ return converterr("bytes", arg, msgbuf, bufsize);
break;
}
case 'Y': { /* PyByteArray object */
PyObject **p = va_arg(*p_va, PyObject **);
- HANDLE_NULLABLE;
if (PyByteArray_Check(arg))
*p = arg;
else
- return converterr(nullable, "bytearray", arg, msgbuf, bufsize);
+ return converterr("bytearray", arg, msgbuf, bufsize);
break;
}
case 'U': { /* PyUnicode object */
PyObject **p = va_arg(*p_va, PyObject **);
- HANDLE_NULLABLE;
if (PyUnicode_Check(arg)) {
*p = arg;
}
else
- return converterr(nullable, "str", arg, msgbuf, bufsize);
+ return converterr("str", arg, msgbuf, bufsize);
break;
}
type = va_arg(*p_va, PyTypeObject*);
p = va_arg(*p_va, PyObject **);
format++;
- HANDLE_NULLABLE;
if (PyType_IsSubtype(Py_TYPE(arg), type))
*p = arg;
else
- return converterr(nullable, type->tp_name, arg, msgbuf, bufsize);
+ return converterr(type->tp_name, arg, msgbuf, bufsize);
}
else if (*format == '&') {
void *addr = va_arg(*p_va, void *);
int res;
format++;
- HANDLE_NULLABLE;
if (! (res = (*convert)(arg, addr)))
- return converterr(nullable, "(unspecified)",
+ return converterr("(unspecified)",
arg, msgbuf, bufsize);
if (res == Py_CLEANUP_SUPPORTED &&
addcleanup(addr, freelist, convert) == -1)
- return converterr(nullable, "(cleanup problem)",
+ return converterr("(cleanup problem)",
arg, msgbuf, bufsize);
}
else {
p = va_arg(*p_va, PyObject **);
- HANDLE_NULLABLE;
*p = arg;
}
break;
if (*format != '*')
return converterr(
- nullable, "(invalid use of 'w' format character)",
+ "(invalid use of 'w' format character)",
arg, msgbuf, bufsize);
format++;
- HANDLE_NULLABLE;
/* Caller is interested in Py_buffer, and the object supports it
directly. The request implicitly asks for PyBUF_SIMPLE, so the
result is C-contiguous with format 'B'. */
if (PyObject_GetBuffer(arg, (Py_buffer*)p, PyBUF_WRITABLE) < 0) {
PyErr_Clear();
- return converterr(nullable, "read-write bytes-like object",
+ return converterr("read-write bytes-like object",
arg, msgbuf, bufsize);
}
assert(PyBuffer_IsContiguous((Py_buffer *)p, 'C'));
if (addcleanup(p, freelist, cleanup_buffer)) {
return converterr(
- nullable, "(cleanup problem)",
+ "(cleanup problem)",
arg, msgbuf, bufsize);
}
break;
}
default:
- return converterr(nullable, "(impossible<bad format char>)", arg, msgbuf, bufsize);
+ return converterr("(impossible<bad format char>)", arg, msgbuf, bufsize);
}
return "impossible<bad format char>";
}
- if (*format == '?') {
- format++;
- }
*p_format = format;
return NULL;