mirror of
https://github.com/python/cpython.git
synced 2025-10-30 05:01:30 +00:00
[3.14] Revert "gh-112068: C API: Add support of nullable arguments in PyArg_Parse (GH-121303)" (GH-136991) (#137006)
This commit is contained in:
parent
c328d140eb
commit
805daa2edb
12 changed files with 144 additions and 322 deletions
|
|
@ -113,18 +113,14 @@ There are three ways strings and buffers can be converted to C:
|
||||||
``z`` (:class:`str` or ``None``) [const char \*]
|
``z`` (:class:`str` or ``None``) [const char \*]
|
||||||
Like ``s``, but the Python object may also be ``None``, in which case the C
|
Like ``s``, but the Python object may also be ``None``, in which case the C
|
||||||
pointer is set to ``NULL``.
|
pointer is set to ``NULL``.
|
||||||
It is the same as ``s?`` with the C pointer was initialized to ``NULL``.
|
|
||||||
|
|
||||||
``z*`` (:class:`str`, :term:`bytes-like object` or ``None``) [Py_buffer]
|
``z*`` (:class:`str`, :term:`bytes-like object` or ``None``) [Py_buffer]
|
||||||
Like ``s*``, but the Python object may also be ``None``, in which case the
|
Like ``s*``, but the Python object may also be ``None``, in which case the
|
||||||
``buf`` member of the :c:type:`Py_buffer` structure is set to ``NULL``.
|
``buf`` member of the :c:type:`Py_buffer` structure is set to ``NULL``.
|
||||||
It is the same as ``s*?`` with the ``buf`` member of the :c:type:`Py_buffer`
|
|
||||||
structure was initialized to ``NULL``.
|
|
||||||
|
|
||||||
``z#`` (:class:`str`, read-only :term:`bytes-like object` or ``None``) [const char \*, :c:type:`Py_ssize_t`]
|
``z#`` (:class:`str`, read-only :term:`bytes-like object` or ``None``) [const char \*, :c:type:`Py_ssize_t`]
|
||||||
Like ``s#``, but the Python object may also be ``None``, in which case the C
|
Like ``s#``, but the Python object may also be ``None``, in which case the C
|
||||||
pointer is set to ``NULL``.
|
pointer is set to ``NULL``.
|
||||||
It is the same as ``s#?`` with the C pointer was initialized to ``NULL``.
|
|
||||||
|
|
||||||
``y`` (read-only :term:`bytes-like object`) [const char \*]
|
``y`` (read-only :term:`bytes-like object`) [const char \*]
|
||||||
This format converts a bytes-like object to a C pointer to a
|
This format converts a bytes-like object to a C pointer to a
|
||||||
|
|
@ -387,17 +383,6 @@ Other objects
|
||||||
Non-tuple sequences are deprecated if *items* contains format units
|
Non-tuple sequences are deprecated if *items* contains format units
|
||||||
which store a borrowed buffer or a borrowed reference.
|
which store a borrowed buffer or a borrowed reference.
|
||||||
|
|
||||||
``unit?`` (anything or ``None``) [*matching-variable(s)*]
|
|
||||||
``?`` modifies the behavior of the preceding format unit.
|
|
||||||
The C variable(s) corresponding to that parameter should be initialized
|
|
||||||
to their default value --- when the argument is ``None``,
|
|
||||||
:c:func:`PyArg_ParseTuple` does not touch the contents of the corresponding
|
|
||||||
C variable(s).
|
|
||||||
If the argument is not ``None``, it is parsed according to the specified
|
|
||||||
format unit.
|
|
||||||
|
|
||||||
.. versionadded:: 3.14
|
|
||||||
|
|
||||||
A few other characters have a meaning in a format string. These may not occur
|
A few other characters have a meaning in a format string. These may not occur
|
||||||
inside nested parentheses. They are:
|
inside nested parentheses. They are:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2940,11 +2940,6 @@ New features
|
||||||
file.
|
file.
|
||||||
(Contributed by Victor Stinner in :gh:`127350`.)
|
(Contributed by Victor Stinner in :gh:`127350`.)
|
||||||
|
|
||||||
* Add support of nullable arguments in :c:func:`PyArg_ParseTuple` and
|
|
||||||
similar functions.
|
|
||||||
Adding ``?`` after any format unit makes ``None`` be accepted as a value.
|
|
||||||
(Contributed by Serhiy Storchaka in :gh:`112068`.)
|
|
||||||
|
|
||||||
* The ``k`` and ``K`` formats in :c:func:`PyArg_ParseTuple` and
|
* The ``k`` and ``K`` formats in :c:func:`PyArg_ParseTuple` and
|
||||||
similar functions now use :meth:`~object.__index__` if available,
|
similar functions now use :meth:`~object.__index__` if available,
|
||||||
like all other integer formats.
|
like all other integer formats.
|
||||||
|
|
|
||||||
|
|
@ -1389,123 +1389,6 @@ def test_nested_sequence(self):
|
||||||
"argument 1 must be sequence of length 1, not 0"):
|
"argument 1 must be sequence of length 1, not 0"):
|
||||||
parse(([],), {}, '(' + f + ')', ['a'])
|
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')
|
@unittest.skipIf(_testinternalcapi is None, 'needs _testinternalcapi')
|
||||||
def test_gh_119213(self):
|
def test_gh_119213(self):
|
||||||
rc, out, err = script_helper.assert_python_ok("-c", """if True:
|
rc, out, err = script_helper.assert_python_ok("-c", """if True:
|
||||||
|
|
|
||||||
|
|
@ -732,7 +732,7 @@ def test_tagname(self):
|
||||||
m2.close()
|
m2.close()
|
||||||
m1.close()
|
m1.close()
|
||||||
|
|
||||||
with self.assertRaisesRegex(TypeError, 'must be str or None'):
|
with self.assertRaisesRegex(TypeError, 'tagname'):
|
||||||
mmap.mmap(-1, 8, tagname=1)
|
mmap.mmap(-1, 8, tagname=1)
|
||||||
|
|
||||||
@cpython_only
|
@cpython_only
|
||||||
|
|
|
||||||
|
|
@ -2012,7 +2012,7 @@ interpreter.
|
||||||
.. nonce: ofI5Fl
|
.. nonce: ofI5Fl
|
||||||
.. section: C API
|
.. section: C API
|
||||||
|
|
||||||
Add support of nullable arguments in :c:func:`PyArg_Parse` and similar
|
[Reverted in :gh:`136991`] Add support of nullable arguments in :c:func:`PyArg_Parse` and similar
|
||||||
functions. Adding ``?`` after any format unit makes ``None`` be accepted as
|
functions. Adding ``?`` after any format unit makes ``None`` be accepted as
|
||||||
a value.
|
a value.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Revert support of nullable arguments in :c:func:`PyArg_Parse`.
|
||||||
|
|
@ -3918,7 +3918,9 @@ _validate_paramflags(ctypes_state *st, PyTypeObject *type, PyObject *paramflags)
|
||||||
PyObject *name = Py_None;
|
PyObject *name = Py_None;
|
||||||
PyObject *defval;
|
PyObject *defval;
|
||||||
PyObject *typ;
|
PyObject *typ;
|
||||||
if (!PyArg_ParseTuple(item, "i|U?O", &flag, &name, &defval)) {
|
if (!PyArg_ParseTuple(item, "i|OO", &flag, &name, &defval) ||
|
||||||
|
!(name == Py_None || PyUnicode_Check(name)))
|
||||||
|
{
|
||||||
PyErr_SetString(PyExc_TypeError,
|
PyErr_SetString(PyExc_TypeError,
|
||||||
"paramflags must be a sequence of (int [,string [,value]]) tuples");
|
"paramflags must be a sequence of (int [,string [,value]]) tuples");
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -3983,8 +3985,10 @@ PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
void *handle;
|
void *handle;
|
||||||
PyObject *paramflags = NULL;
|
PyObject *paramflags = NULL;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "O|O?", &ftuple, ¶mflags))
|
if (!PyArg_ParseTuple(args, "O|O", &ftuple, ¶mflags))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
if (paramflags == Py_None)
|
||||||
|
paramflags = NULL;
|
||||||
|
|
||||||
ftuple = PySequence_Tuple(ftuple);
|
ftuple = PySequence_Tuple(ftuple);
|
||||||
if (!ftuple)
|
if (!ftuple)
|
||||||
|
|
@ -4116,8 +4120,10 @@ PyCFuncPtr_FromVtblIndex(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
GUID *iid = NULL;
|
GUID *iid = NULL;
|
||||||
Py_ssize_t iid_len = 0;
|
Py_ssize_t iid_len = 0;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "is|O?z#", &index, &name, ¶mflags, &iid, &iid_len))
|
if (!PyArg_ParseTuple(args, "is|Oz#", &index, &name, ¶mflags, &iid, &iid_len))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
if (paramflags == Py_None)
|
||||||
|
paramflags = NULL;
|
||||||
|
|
||||||
ctypes_state *st = get_module_state_by_def(Py_TYPE(type));
|
ctypes_state *st = get_module_state_by_def(Py_TYPE(type));
|
||||||
if (!_validate_paramflags(st, type, paramflags)) {
|
if (!_validate_paramflags(st, type, paramflags)) {
|
||||||
|
|
|
||||||
|
|
@ -1415,11 +1415,14 @@ interp_get_config(PyObject *self, PyObject *args, PyObject *kwds)
|
||||||
PyObject *idobj = NULL;
|
PyObject *idobj = NULL;
|
||||||
int restricted = 0;
|
int restricted = 0;
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwds,
|
if (!PyArg_ParseTupleAndKeywords(args, kwds,
|
||||||
"O?|$p:get_config", kwlist,
|
"O|$p:get_config", kwlist,
|
||||||
&idobj, &restricted))
|
&idobj, &restricted))
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
if (idobj == Py_None) {
|
||||||
|
idobj = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
int reqready = 0;
|
int reqready = 0;
|
||||||
PyInterpreterState *interp = \
|
PyInterpreterState *interp = \
|
||||||
|
|
@ -1536,14 +1539,14 @@ capture_exception(PyObject *self, PyObject *args, PyObject *kwds)
|
||||||
static char *kwlist[] = {"exc", NULL};
|
static char *kwlist[] = {"exc", NULL};
|
||||||
PyObject *exc_arg = NULL;
|
PyObject *exc_arg = NULL;
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwds,
|
if (!PyArg_ParseTupleAndKeywords(args, kwds,
|
||||||
"|O?:capture_exception", kwlist,
|
"|O:capture_exception", kwlist,
|
||||||
&exc_arg))
|
&exc_arg))
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *exc = exc_arg;
|
PyObject *exc = exc_arg;
|
||||||
if (exc == NULL) {
|
if (exc == NULL || exc == Py_None) {
|
||||||
exc = PyErr_GetRaisedException();
|
exc = PyErr_GetRaisedException();
|
||||||
if (exc == NULL) {
|
if (exc == NULL) {
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
|
|
|
||||||
|
|
@ -1228,16 +1228,23 @@ encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
static char *kwlist[] = {"markers", "default", "encoder", "indent", "key_separator", "item_separator", "sort_keys", "skipkeys", "allow_nan", NULL};
|
static char *kwlist[] = {"markers", "default", "encoder", "indent", "key_separator", "item_separator", "sort_keys", "skipkeys", "allow_nan", NULL};
|
||||||
|
|
||||||
PyEncoderObject *s;
|
PyEncoderObject *s;
|
||||||
PyObject *markers = Py_None, *defaultfn, *encoder, *indent, *key_separator;
|
PyObject *markers, *defaultfn, *encoder, *indent, *key_separator;
|
||||||
PyObject *item_separator;
|
PyObject *item_separator;
|
||||||
int sort_keys, skipkeys, allow_nan;
|
int sort_keys, skipkeys, allow_nan;
|
||||||
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!?OOOUUppp:make_encoder", kwlist,
|
if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOOOUUppp:make_encoder", kwlist,
|
||||||
&PyDict_Type, &markers, &defaultfn, &encoder, &indent,
|
&markers, &defaultfn, &encoder, &indent,
|
||||||
&key_separator, &item_separator,
|
&key_separator, &item_separator,
|
||||||
&sort_keys, &skipkeys, &allow_nan))
|
&sort_keys, &skipkeys, &allow_nan))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
if (markers != Py_None && !PyDict_Check(markers)) {
|
||||||
|
PyErr_Format(PyExc_TypeError,
|
||||||
|
"make_encoder() argument 1 must be dict or None, "
|
||||||
|
"not %.200s", Py_TYPE(markers)->tp_name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
s = (PyEncoderObject *)type->tp_alloc(type, 0);
|
s = (PyEncoderObject *)type->tp_alloc(type, 0);
|
||||||
if (s == NULL)
|
if (s == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
||||||
|
|
@ -667,12 +667,12 @@ PyThreadHandleObject_join(PyObject *op, PyObject *args)
|
||||||
PyThreadHandleObject *self = PyThreadHandleObject_CAST(op);
|
PyThreadHandleObject *self = PyThreadHandleObject_CAST(op);
|
||||||
|
|
||||||
PyObject *timeout_obj = NULL;
|
PyObject *timeout_obj = NULL;
|
||||||
if (!PyArg_ParseTuple(args, "|O?:join", &timeout_obj)) {
|
if (!PyArg_ParseTuple(args, "|O:join", &timeout_obj)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyTime_t timeout_ns = -1;
|
PyTime_t timeout_ns = -1;
|
||||||
if (timeout_obj != NULL) {
|
if (timeout_obj != NULL && timeout_obj != Py_None) {
|
||||||
if (_PyTime_FromSecondsObject(&timeout_ns, timeout_obj,
|
if (_PyTime_FromSecondsObject(&timeout_ns, timeout_obj,
|
||||||
_PyTime_ROUND_TIMEOUT) < 0) {
|
_PyTime_ROUND_TIMEOUT) < 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -1945,10 +1945,10 @@ thread_PyThread_start_joinable_thread(PyObject *module, PyObject *fargs,
|
||||||
PyObject *func = NULL;
|
PyObject *func = NULL;
|
||||||
int daemon = 1;
|
int daemon = 1;
|
||||||
thread_module_state *state = get_thread_state(module);
|
thread_module_state *state = get_thread_state(module);
|
||||||
PyObject *hobj = Py_None;
|
PyObject *hobj = NULL;
|
||||||
if (!PyArg_ParseTupleAndKeywords(fargs, fkwargs,
|
if (!PyArg_ParseTupleAndKeywords(fargs, fkwargs,
|
||||||
"O|O!?p:start_joinable_thread", keywords,
|
"O|Op:start_joinable_thread", keywords,
|
||||||
&func, state->thread_handle_type, &hobj, &daemon)) {
|
&func, &hobj, &daemon)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1958,6 +1958,14 @@ thread_PyThread_start_joinable_thread(PyObject *module, PyObject *fargs,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hobj == NULL) {
|
||||||
|
hobj = Py_None;
|
||||||
|
}
|
||||||
|
else if (hobj != Py_None && !Py_IS_TYPE(hobj, state->thread_handle_type)) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "'handle' must be a _ThreadHandle");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (PySys_Audit("_thread.start_joinable_thread", "OiO", func, daemon,
|
if (PySys_Audit("_thread.start_joinable_thread", "OiO", func, daemon,
|
||||||
hobj) < 0) {
|
hobj) < 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
|
#include "pycore_abstract.h" // _Py_convert_optional_to_ssize_t()
|
||||||
#include "pycore_bytesobject.h" // _PyBytes_Find()
|
#include "pycore_bytesobject.h" // _PyBytes_Find()
|
||||||
#include "pycore_fileutils.h" // _Py_stat_struct
|
#include "pycore_fileutils.h" // _Py_stat_struct
|
||||||
#include "pycore_weakref.h" // FT_CLEAR_WEAKREFS()
|
#include "pycore_weakref.h" // FT_CLEAR_WEAKREFS()
|
||||||
|
|
@ -515,7 +516,7 @@ mmap_read_method(PyObject *op, PyObject *args)
|
||||||
mmap_object *self = mmap_object_CAST(op);
|
mmap_object *self = mmap_object_CAST(op);
|
||||||
|
|
||||||
CHECK_VALID(NULL);
|
CHECK_VALID(NULL);
|
||||||
if (!PyArg_ParseTuple(args, "|n?:read", &num_bytes))
|
if (!PyArg_ParseTuple(args, "|O&:read", _Py_convert_optional_to_ssize_t, &num_bytes))
|
||||||
return NULL;
|
return NULL;
|
||||||
CHECK_VALID(NULL);
|
CHECK_VALID(NULL);
|
||||||
|
|
||||||
|
|
@ -1709,7 +1710,7 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict)
|
||||||
DWORD off_lo; /* lower 32 bits of offset */
|
DWORD off_lo; /* lower 32 bits of offset */
|
||||||
DWORD size_hi; /* upper 32 bits of size */
|
DWORD size_hi; /* upper 32 bits of size */
|
||||||
DWORD size_lo; /* lower 32 bits of size */
|
DWORD size_lo; /* lower 32 bits of size */
|
||||||
PyObject *tagname = NULL;
|
PyObject *tagname = Py_None;
|
||||||
DWORD dwErr = 0;
|
DWORD dwErr = 0;
|
||||||
int fileno;
|
int fileno;
|
||||||
HANDLE fh = 0;
|
HANDLE fh = 0;
|
||||||
|
|
@ -1719,7 +1720,7 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict)
|
||||||
"tagname",
|
"tagname",
|
||||||
"access", "offset", NULL };
|
"access", "offset", NULL };
|
||||||
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwdict, "in|U?iL", keywords,
|
if (!PyArg_ParseTupleAndKeywords(args, kwdict, "in|OiL", keywords,
|
||||||
&fileno, &map_size,
|
&fileno, &map_size,
|
||||||
&tagname, &access, &offset)) {
|
&tagname, &access, &offset)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -1852,7 +1853,13 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict)
|
||||||
m_obj->weakreflist = NULL;
|
m_obj->weakreflist = NULL;
|
||||||
m_obj->exports = 0;
|
m_obj->exports = 0;
|
||||||
/* set the tag name */
|
/* set the tag name */
|
||||||
if (tagname != NULL) {
|
if (!Py_IsNone(tagname)) {
|
||||||
|
if (!PyUnicode_Check(tagname)) {
|
||||||
|
Py_DECREF(m_obj);
|
||||||
|
return PyErr_Format(PyExc_TypeError, "expected str or None for "
|
||||||
|
"'tagname', not %.200s",
|
||||||
|
Py_TYPE(tagname)->tp_name);
|
||||||
|
}
|
||||||
m_obj->tagname = PyUnicode_AsWideCharString(tagname, NULL);
|
m_obj->tagname = PyUnicode_AsWideCharString(tagname, NULL);
|
||||||
if (m_obj->tagname == NULL) {
|
if (m_obj->tagname == NULL) {
|
||||||
Py_DECREF(m_obj);
|
Py_DECREF(m_obj);
|
||||||
|
|
|
||||||
257
Python/getargs.c
257
Python/getargs.c
|
|
@ -1,8 +1,6 @@
|
||||||
|
|
||||||
/* New getargs implementation */
|
/* New getargs implementation */
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#define PY_CXX_CONST const
|
#define PY_CXX_CONST const
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#include "pycore_abstract.h" // _PyNumber_Index()
|
#include "pycore_abstract.h" // _PyNumber_Index()
|
||||||
|
|
@ -468,12 +466,9 @@ converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
const char *format = *p_format;
|
const char *format = *p_format;
|
||||||
int i;
|
int i;
|
||||||
Py_ssize_t len;
|
Py_ssize_t len;
|
||||||
bool nullable = false;
|
|
||||||
int istuple = PyTuple_Check(arg);
|
int istuple = PyTuple_Check(arg);
|
||||||
int mustbetuple = istuple;
|
int mustbetuple = istuple;
|
||||||
|
|
||||||
assert(*format == '(');
|
|
||||||
format++;
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int c = *format++;
|
int c = *format++;
|
||||||
if (c == '(') {
|
if (c == '(') {
|
||||||
|
|
@ -482,12 +477,8 @@ converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
level++;
|
level++;
|
||||||
}
|
}
|
||||||
else if (c == ')') {
|
else if (c == ')') {
|
||||||
if (level == 0) {
|
if (level == 0)
|
||||||
if (*format == '?') {
|
|
||||||
nullable = true;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
level--;
|
level--;
|
||||||
}
|
}
|
||||||
else if (c == ':' || c == ';' || c == '\0')
|
else if (c == ':' || c == ';' || c == '\0')
|
||||||
|
|
@ -524,13 +515,6 @@ converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arg == Py_None && nullable) {
|
|
||||||
const char *msg = skipitem(p_format, p_va, flags);
|
|
||||||
if (msg != NULL) {
|
|
||||||
levels[0] = 0;
|
|
||||||
}
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
if (istuple) {
|
if (istuple) {
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
}
|
}
|
||||||
|
|
@ -539,10 +523,9 @@ converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
{
|
{
|
||||||
levels[0] = 0;
|
levels[0] = 0;
|
||||||
PyOS_snprintf(msgbuf, bufsize,
|
PyOS_snprintf(msgbuf, bufsize,
|
||||||
"must be %d-item tuple%s, not %.50s",
|
"must be %d-item tuple, not %.50s",
|
||||||
n,
|
n,
|
||||||
nullable ? " or None" : "",
|
arg == Py_None ? "None" : Py_TYPE(arg)->tp_name);
|
||||||
arg == Py_None ? "None" : Py_TYPE(arg)->tp_name);
|
|
||||||
return msgbuf;
|
return msgbuf;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
@ -579,7 +562,7 @@ converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
return msgbuf;
|
return msgbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
format = *p_format + 1;
|
format = *p_format;
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
const char *msg;
|
const char *msg;
|
||||||
PyObject *item = PyTuple_GET_ITEM(arg, i);
|
PyObject *item = PyTuple_GET_ITEM(arg, i);
|
||||||
|
|
@ -594,10 +577,6 @@ converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
format++;
|
|
||||||
if (*format == '?') {
|
|
||||||
format++;
|
|
||||||
}
|
|
||||||
*p_format = format;
|
*p_format = format;
|
||||||
if (!istuple) {
|
if (!istuple) {
|
||||||
Py_DECREF(arg);
|
Py_DECREF(arg);
|
||||||
|
|
@ -616,8 +595,11 @@ convertitem(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
const char *format = *p_format;
|
const char *format = *p_format;
|
||||||
|
|
||||||
if (*format == '(' /* ')' */) {
|
if (*format == '(' /* ')' */) {
|
||||||
|
format++;
|
||||||
msg = converttuple(arg, &format, p_va, flags, levels, msgbuf,
|
msg = converttuple(arg, &format, p_va, flags, levels, msgbuf,
|
||||||
bufsize, freelist);
|
bufsize, freelist);
|
||||||
|
if (msg == NULL)
|
||||||
|
format++;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
msg = convertsimple(arg, &format, p_va, flags,
|
msg = convertsimple(arg, &format, p_va, flags,
|
||||||
|
|
@ -647,7 +629,7 @@ _PyArg_BadArgument(const char *fname, const char *displayname,
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *
|
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(expected != NULL);
|
||||||
assert(arg != NULL);
|
assert(arg != NULL);
|
||||||
|
|
@ -657,23 +639,20 @@ converterr(bool nullable, const char *expected, PyObject *arg, char *msgbuf, siz
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
PyOS_snprintf(msgbuf, bufsize,
|
PyOS_snprintf(msgbuf, bufsize,
|
||||||
"must be %.50s%s, not %.50s", expected,
|
"must be %.50s, not %.50s", expected,
|
||||||
nullable ? " or None" : "",
|
|
||||||
arg == Py_None ? "None" : Py_TYPE(arg)->tp_name);
|
arg == Py_None ? "None" : Py_TYPE(arg)->tp_name);
|
||||||
}
|
}
|
||||||
return msgbuf;
|
return msgbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *
|
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)
|
char *msgbuf, size_t bufsize)
|
||||||
{
|
{
|
||||||
assert(expected != NULL);
|
assert(expected != NULL);
|
||||||
PyOS_snprintf(msgbuf, bufsize,
|
PyOS_snprintf(msgbuf, bufsize,
|
||||||
"must be %.50s%s, not %.50s of length %zd",
|
"must be %.50s, not %.50s of length %zd",
|
||||||
expected,
|
expected, what, size);
|
||||||
nullable ? " or None" : "",
|
|
||||||
what, size);
|
|
||||||
return msgbuf;
|
return msgbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -693,26 +672,15 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
char *msgbuf, size_t bufsize, freelist_t *freelist)
|
char *msgbuf, size_t bufsize, freelist_t *freelist)
|
||||||
{
|
{
|
||||||
#define RETURN_ERR_OCCURRED return msgbuf
|
#define RETURN_ERR_OCCURRED return msgbuf
|
||||||
#define HANDLE_NULLABLE \
|
|
||||||
if (*format == '?') { \
|
|
||||||
format++; \
|
|
||||||
if (arg == Py_None) { \
|
|
||||||
break; \
|
|
||||||
} \
|
|
||||||
nullable = true; \
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const char *format = *p_format;
|
const char *format = *p_format;
|
||||||
char c = *format++;
|
char c = *format++;
|
||||||
const char *sarg;
|
const char *sarg;
|
||||||
bool nullable = false;
|
|
||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
|
||||||
case 'b': { /* unsigned byte -- very short int */
|
case 'b': { /* unsigned byte -- very short int */
|
||||||
unsigned char *p = va_arg(*p_va, unsigned char *);
|
unsigned char *p = va_arg(*p_va, unsigned char *);
|
||||||
HANDLE_NULLABLE;
|
|
||||||
long ival = PyLong_AsLong(arg);
|
long ival = PyLong_AsLong(arg);
|
||||||
if (ival == -1 && PyErr_Occurred())
|
if (ival == -1 && PyErr_Occurred())
|
||||||
RETURN_ERR_OCCURRED;
|
RETURN_ERR_OCCURRED;
|
||||||
|
|
@ -726,6 +694,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
"unsigned byte integer is greater than maximum");
|
"unsigned byte integer is greater than maximum");
|
||||||
RETURN_ERR_OCCURRED;
|
RETURN_ERR_OCCURRED;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
*p = (unsigned char) ival;
|
*p = (unsigned char) ival;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -733,7 +702,6 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
case 'B': {/* byte sized bitfield - both signed and unsigned
|
case 'B': {/* byte sized bitfield - both signed and unsigned
|
||||||
values allowed */
|
values allowed */
|
||||||
unsigned char *p = va_arg(*p_va, unsigned char *);
|
unsigned char *p = va_arg(*p_va, unsigned char *);
|
||||||
HANDLE_NULLABLE;
|
|
||||||
unsigned long ival = PyLong_AsUnsignedLongMask(arg);
|
unsigned long ival = PyLong_AsUnsignedLongMask(arg);
|
||||||
if (ival == (unsigned long)-1 && PyErr_Occurred())
|
if (ival == (unsigned long)-1 && PyErr_Occurred())
|
||||||
RETURN_ERR_OCCURRED;
|
RETURN_ERR_OCCURRED;
|
||||||
|
|
@ -744,7 +712,6 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
|
|
||||||
case 'h': {/* signed short int */
|
case 'h': {/* signed short int */
|
||||||
short *p = va_arg(*p_va, short *);
|
short *p = va_arg(*p_va, short *);
|
||||||
HANDLE_NULLABLE;
|
|
||||||
long ival = PyLong_AsLong(arg);
|
long ival = PyLong_AsLong(arg);
|
||||||
if (ival == -1 && PyErr_Occurred())
|
if (ival == -1 && PyErr_Occurred())
|
||||||
RETURN_ERR_OCCURRED;
|
RETURN_ERR_OCCURRED;
|
||||||
|
|
@ -766,7 +733,6 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
case 'H': { /* short int sized bitfield, both signed and
|
case 'H': { /* short int sized bitfield, both signed and
|
||||||
unsigned allowed */
|
unsigned allowed */
|
||||||
unsigned short *p = va_arg(*p_va, unsigned short *);
|
unsigned short *p = va_arg(*p_va, unsigned short *);
|
||||||
HANDLE_NULLABLE;
|
|
||||||
unsigned long ival = PyLong_AsUnsignedLongMask(arg);
|
unsigned long ival = PyLong_AsUnsignedLongMask(arg);
|
||||||
if (ival == (unsigned long)-1 && PyErr_Occurred())
|
if (ival == (unsigned long)-1 && PyErr_Occurred())
|
||||||
RETURN_ERR_OCCURRED;
|
RETURN_ERR_OCCURRED;
|
||||||
|
|
@ -777,7 +743,6 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
|
|
||||||
case 'i': {/* signed int */
|
case 'i': {/* signed int */
|
||||||
int *p = va_arg(*p_va, int *);
|
int *p = va_arg(*p_va, int *);
|
||||||
HANDLE_NULLABLE;
|
|
||||||
long ival = PyLong_AsLong(arg);
|
long ival = PyLong_AsLong(arg);
|
||||||
if (ival == -1 && PyErr_Occurred())
|
if (ival == -1 && PyErr_Occurred())
|
||||||
RETURN_ERR_OCCURRED;
|
RETURN_ERR_OCCURRED;
|
||||||
|
|
@ -799,7 +764,6 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
case 'I': { /* int sized bitfield, both signed and
|
case 'I': { /* int sized bitfield, both signed and
|
||||||
unsigned allowed */
|
unsigned allowed */
|
||||||
unsigned int *p = va_arg(*p_va, unsigned int *);
|
unsigned int *p = va_arg(*p_va, unsigned int *);
|
||||||
HANDLE_NULLABLE;
|
|
||||||
unsigned long ival = PyLong_AsUnsignedLongMask(arg);
|
unsigned long ival = PyLong_AsUnsignedLongMask(arg);
|
||||||
if (ival == (unsigned long)-1 && PyErr_Occurred())
|
if (ival == (unsigned long)-1 && PyErr_Occurred())
|
||||||
RETURN_ERR_OCCURRED;
|
RETURN_ERR_OCCURRED;
|
||||||
|
|
@ -812,7 +776,6 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
{
|
{
|
||||||
PyObject *iobj;
|
PyObject *iobj;
|
||||||
Py_ssize_t *p = va_arg(*p_va, Py_ssize_t *);
|
Py_ssize_t *p = va_arg(*p_va, Py_ssize_t *);
|
||||||
HANDLE_NULLABLE;
|
|
||||||
Py_ssize_t ival = -1;
|
Py_ssize_t ival = -1;
|
||||||
iobj = _PyNumber_Index(arg);
|
iobj = _PyNumber_Index(arg);
|
||||||
if (iobj != NULL) {
|
if (iobj != NULL) {
|
||||||
|
|
@ -826,7 +789,6 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
}
|
}
|
||||||
case 'l': {/* long int */
|
case 'l': {/* long int */
|
||||||
long *p = va_arg(*p_va, long *);
|
long *p = va_arg(*p_va, long *);
|
||||||
HANDLE_NULLABLE;
|
|
||||||
long ival = PyLong_AsLong(arg);
|
long ival = PyLong_AsLong(arg);
|
||||||
if (ival == -1 && PyErr_Occurred())
|
if (ival == -1 && PyErr_Occurred())
|
||||||
RETURN_ERR_OCCURRED;
|
RETURN_ERR_OCCURRED;
|
||||||
|
|
@ -837,10 +799,9 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
|
|
||||||
case 'k': { /* long sized bitfield */
|
case 'k': { /* long sized bitfield */
|
||||||
unsigned long *p = va_arg(*p_va, unsigned long *);
|
unsigned long *p = va_arg(*p_va, unsigned long *);
|
||||||
HANDLE_NULLABLE;
|
|
||||||
unsigned long ival;
|
unsigned long ival;
|
||||||
if (!PyIndex_Check(arg)) {
|
if (!PyIndex_Check(arg)) {
|
||||||
return converterr(nullable, "int", arg, msgbuf, bufsize);
|
return converterr("int", arg, msgbuf, bufsize);
|
||||||
}
|
}
|
||||||
ival = PyLong_AsUnsignedLongMask(arg);
|
ival = PyLong_AsUnsignedLongMask(arg);
|
||||||
if (ival == (unsigned long)(long)-1 && PyErr_Occurred()) {
|
if (ival == (unsigned long)(long)-1 && PyErr_Occurred()) {
|
||||||
|
|
@ -852,7 +813,6 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
|
|
||||||
case 'L': {/* long long */
|
case 'L': {/* long long */
|
||||||
long long *p = va_arg( *p_va, long long * );
|
long long *p = va_arg( *p_va, long long * );
|
||||||
HANDLE_NULLABLE;
|
|
||||||
long long ival = PyLong_AsLongLong(arg);
|
long long ival = PyLong_AsLongLong(arg);
|
||||||
if (ival == (long long)-1 && PyErr_Occurred())
|
if (ival == (long long)-1 && PyErr_Occurred())
|
||||||
RETURN_ERR_OCCURRED;
|
RETURN_ERR_OCCURRED;
|
||||||
|
|
@ -863,10 +823,9 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
|
|
||||||
case 'K': { /* long long sized bitfield */
|
case 'K': { /* long long sized bitfield */
|
||||||
unsigned long long *p = va_arg(*p_va, unsigned long long *);
|
unsigned long long *p = va_arg(*p_va, unsigned long long *);
|
||||||
HANDLE_NULLABLE;
|
|
||||||
unsigned long long ival;
|
unsigned long long ival;
|
||||||
if (!PyIndex_Check(arg)) {
|
if (!PyIndex_Check(arg)) {
|
||||||
return converterr(nullable, "int", arg, msgbuf, bufsize);
|
return converterr("int", arg, msgbuf, bufsize);
|
||||||
}
|
}
|
||||||
ival = PyLong_AsUnsignedLongLongMask(arg);
|
ival = PyLong_AsUnsignedLongLongMask(arg);
|
||||||
if (ival == (unsigned long long)(long long)-1 && PyErr_Occurred()) {
|
if (ival == (unsigned long long)(long long)-1 && PyErr_Occurred()) {
|
||||||
|
|
@ -878,7 +837,6 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
|
|
||||||
case 'f': {/* float */
|
case 'f': {/* float */
|
||||||
float *p = va_arg(*p_va, float *);
|
float *p = va_arg(*p_va, float *);
|
||||||
HANDLE_NULLABLE;
|
|
||||||
double dval = PyFloat_AsDouble(arg);
|
double dval = PyFloat_AsDouble(arg);
|
||||||
if (dval == -1.0 && PyErr_Occurred())
|
if (dval == -1.0 && PyErr_Occurred())
|
||||||
RETURN_ERR_OCCURRED;
|
RETURN_ERR_OCCURRED;
|
||||||
|
|
@ -889,7 +847,6 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
|
|
||||||
case 'd': {/* double */
|
case 'd': {/* double */
|
||||||
double *p = va_arg(*p_va, double *);
|
double *p = va_arg(*p_va, double *);
|
||||||
HANDLE_NULLABLE;
|
|
||||||
double dval = PyFloat_AsDouble(arg);
|
double dval = PyFloat_AsDouble(arg);
|
||||||
if (dval == -1.0 && PyErr_Occurred())
|
if (dval == -1.0 && PyErr_Occurred())
|
||||||
RETURN_ERR_OCCURRED;
|
RETURN_ERR_OCCURRED;
|
||||||
|
|
@ -900,7 +857,6 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
|
|
||||||
case 'D': {/* complex double */
|
case 'D': {/* complex double */
|
||||||
Py_complex *p = va_arg(*p_va, Py_complex *);
|
Py_complex *p = va_arg(*p_va, Py_complex *);
|
||||||
HANDLE_NULLABLE;
|
|
||||||
Py_complex cval;
|
Py_complex cval;
|
||||||
cval = PyComplex_AsCComplex(arg);
|
cval = PyComplex_AsCComplex(arg);
|
||||||
if (PyErr_Occurred())
|
if (PyErr_Occurred())
|
||||||
|
|
@ -912,10 +868,9 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
|
|
||||||
case 'c': {/* char */
|
case 'c': {/* char */
|
||||||
char *p = va_arg(*p_va, char *);
|
char *p = va_arg(*p_va, char *);
|
||||||
HANDLE_NULLABLE;
|
|
||||||
if (PyBytes_Check(arg)) {
|
if (PyBytes_Check(arg)) {
|
||||||
if (PyBytes_GET_SIZE(arg) != 1) {
|
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),
|
"a bytes object", PyBytes_GET_SIZE(arg),
|
||||||
msgbuf, bufsize);
|
msgbuf, bufsize);
|
||||||
}
|
}
|
||||||
|
|
@ -923,28 +878,27 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
}
|
}
|
||||||
else if (PyByteArray_Check(arg)) {
|
else if (PyByteArray_Check(arg)) {
|
||||||
if (PyByteArray_GET_SIZE(arg) != 1) {
|
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),
|
"a bytearray object", PyByteArray_GET_SIZE(arg),
|
||||||
msgbuf, bufsize);
|
msgbuf, bufsize);
|
||||||
}
|
}
|
||||||
*p = PyByteArray_AS_STRING(arg)[0];
|
*p = PyByteArray_AS_STRING(arg)[0];
|
||||||
}
|
}
|
||||||
else
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'C': {/* unicode char */
|
case 'C': {/* unicode char */
|
||||||
int *p = va_arg(*p_va, int *);
|
int *p = va_arg(*p_va, int *);
|
||||||
HANDLE_NULLABLE;
|
|
||||||
int kind;
|
int kind;
|
||||||
const void *data;
|
const void *data;
|
||||||
|
|
||||||
if (!PyUnicode_Check(arg))
|
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) {
|
if (PyUnicode_GET_LENGTH(arg) != 1) {
|
||||||
return convertcharerr(nullable, "a unicode character",
|
return convertcharerr("a unicode character",
|
||||||
"a string", PyUnicode_GET_LENGTH(arg),
|
"a string", PyUnicode_GET_LENGTH(arg),
|
||||||
msgbuf, bufsize);
|
msgbuf, bufsize);
|
||||||
}
|
}
|
||||||
|
|
@ -957,7 +911,6 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
|
|
||||||
case 'p': {/* boolean *p*redicate */
|
case 'p': {/* boolean *p*redicate */
|
||||||
int *p = va_arg(*p_va, int *);
|
int *p = va_arg(*p_va, int *);
|
||||||
HANDLE_NULLABLE;
|
|
||||||
int val = PyObject_IsTrue(arg);
|
int val = PyObject_IsTrue(arg);
|
||||||
if (val > 0)
|
if (val > 0)
|
||||||
*p = 1;
|
*p = 1;
|
||||||
|
|
@ -976,31 +929,24 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
const char *buf;
|
const char *buf;
|
||||||
Py_ssize_t count;
|
Py_ssize_t count;
|
||||||
if (*format == '*') {
|
if (*format == '*') {
|
||||||
format++;
|
|
||||||
HANDLE_NULLABLE;
|
|
||||||
if (getbuffer(arg, (Py_buffer*)p, &buf) < 0)
|
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)) {
|
if (addcleanup(p, freelist, cleanup_buffer)) {
|
||||||
return converterr(
|
return converterr(
|
||||||
nullable, "(cleanup problem)",
|
"(cleanup problem)",
|
||||||
arg, msgbuf, bufsize);
|
arg, msgbuf, bufsize);
|
||||||
}
|
}
|
||||||
break;
|
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*);
|
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;
|
*psize = count;
|
||||||
}
|
format++;
|
||||||
else {
|
} else {
|
||||||
HANDLE_NULLABLE;
|
|
||||||
count = convertbuffer(arg, (const void **)p, &buf);
|
|
||||||
if (count < 0)
|
|
||||||
return converterr(nullable, buf, arg, msgbuf, bufsize);
|
|
||||||
if (strlen(*p) != (size_t)count) {
|
if (strlen(*p) != (size_t)count) {
|
||||||
PyErr_SetString(PyExc_ValueError, "embedded null byte");
|
PyErr_SetString(PyExc_ValueError, "embedded null byte");
|
||||||
RETURN_ERR_OCCURRED;
|
RETURN_ERR_OCCURRED;
|
||||||
|
|
@ -1016,35 +962,32 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
/* "s*" or "z*" */
|
/* "s*" or "z*" */
|
||||||
Py_buffer *p = (Py_buffer *)va_arg(*p_va, Py_buffer *);
|
Py_buffer *p = (Py_buffer *)va_arg(*p_va, Py_buffer *);
|
||||||
|
|
||||||
format++;
|
|
||||||
HANDLE_NULLABLE;
|
|
||||||
if (c == 'z' && arg == Py_None)
|
if (c == 'z' && arg == Py_None)
|
||||||
PyBuffer_FillInfo(p, NULL, NULL, 0, 1, 0);
|
PyBuffer_FillInfo(p, NULL, NULL, 0, 1, 0);
|
||||||
else if (PyUnicode_Check(arg)) {
|
else if (PyUnicode_Check(arg)) {
|
||||||
Py_ssize_t len;
|
Py_ssize_t len;
|
||||||
sarg = PyUnicode_AsUTF8AndSize(arg, &len);
|
sarg = PyUnicode_AsUTF8AndSize(arg, &len);
|
||||||
if (sarg == NULL)
|
if (sarg == NULL)
|
||||||
return converterr(nullable, CONV_UNICODE,
|
return converterr(CONV_UNICODE,
|
||||||
arg, msgbuf, bufsize);
|
arg, msgbuf, bufsize);
|
||||||
PyBuffer_FillInfo(p, arg, (void *)sarg, len, 1, 0);
|
PyBuffer_FillInfo(p, arg, (void *)sarg, len, 1, 0);
|
||||||
}
|
}
|
||||||
else { /* any bytes-like object */
|
else { /* any bytes-like object */
|
||||||
const char *buf;
|
const char *buf;
|
||||||
if (getbuffer(arg, p, &buf) < 0)
|
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)) {
|
if (addcleanup(p, freelist, cleanup_buffer)) {
|
||||||
return converterr(
|
return converterr(
|
||||||
nullable, "(cleanup problem)",
|
"(cleanup problem)",
|
||||||
arg, msgbuf, bufsize);
|
arg, msgbuf, bufsize);
|
||||||
}
|
}
|
||||||
|
format++;
|
||||||
} else if (*format == '#') { /* a string or read-only bytes-like object */
|
} else if (*format == '#') { /* a string or read-only bytes-like object */
|
||||||
/* "s#" or "z#" */
|
/* "s#" or "z#" */
|
||||||
const void **p = (const void **)va_arg(*p_va, const char **);
|
const void **p = (const void **)va_arg(*p_va, const char **);
|
||||||
Py_ssize_t *psize = va_arg(*p_va, Py_ssize_t*);
|
Py_ssize_t *psize = va_arg(*p_va, Py_ssize_t*);
|
||||||
|
|
||||||
format++;
|
|
||||||
HANDLE_NULLABLE;
|
|
||||||
if (c == 'z' && arg == Py_None) {
|
if (c == 'z' && arg == Py_None) {
|
||||||
*p = NULL;
|
*p = NULL;
|
||||||
*psize = 0;
|
*psize = 0;
|
||||||
|
|
@ -1053,7 +996,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
Py_ssize_t len;
|
Py_ssize_t len;
|
||||||
sarg = PyUnicode_AsUTF8AndSize(arg, &len);
|
sarg = PyUnicode_AsUTF8AndSize(arg, &len);
|
||||||
if (sarg == NULL)
|
if (sarg == NULL)
|
||||||
return converterr(nullable, CONV_UNICODE,
|
return converterr(CONV_UNICODE,
|
||||||
arg, msgbuf, bufsize);
|
arg, msgbuf, bufsize);
|
||||||
*p = sarg;
|
*p = sarg;
|
||||||
*psize = len;
|
*psize = len;
|
||||||
|
|
@ -1063,22 +1006,22 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
const char *buf;
|
const char *buf;
|
||||||
Py_ssize_t count = convertbuffer(arg, p, &buf);
|
Py_ssize_t count = convertbuffer(arg, p, &buf);
|
||||||
if (count < 0)
|
if (count < 0)
|
||||||
return converterr(nullable, buf, arg, msgbuf, bufsize);
|
return converterr(buf, arg, msgbuf, bufsize);
|
||||||
*psize = count;
|
*psize = count;
|
||||||
}
|
}
|
||||||
|
format++;
|
||||||
} else {
|
} else {
|
||||||
/* "s" or "z" */
|
/* "s" or "z" */
|
||||||
const char **p = va_arg(*p_va, const char **);
|
const char **p = va_arg(*p_va, const char **);
|
||||||
Py_ssize_t len;
|
Py_ssize_t len;
|
||||||
sarg = NULL;
|
sarg = NULL;
|
||||||
|
|
||||||
HANDLE_NULLABLE;
|
|
||||||
if (c == 'z' && arg == Py_None)
|
if (c == 'z' && arg == Py_None)
|
||||||
*p = NULL;
|
*p = NULL;
|
||||||
else if (PyUnicode_Check(arg)) {
|
else if (PyUnicode_Check(arg)) {
|
||||||
sarg = PyUnicode_AsUTF8AndSize(arg, &len);
|
sarg = PyUnicode_AsUTF8AndSize(arg, &len);
|
||||||
if (sarg == NULL)
|
if (sarg == NULL)
|
||||||
return converterr(nullable, CONV_UNICODE,
|
return converterr(CONV_UNICODE,
|
||||||
arg, msgbuf, bufsize);
|
arg, msgbuf, bufsize);
|
||||||
if (strlen(sarg) != (size_t)len) {
|
if (strlen(sarg) != (size_t)len) {
|
||||||
PyErr_SetString(PyExc_ValueError, "embedded null character");
|
PyErr_SetString(PyExc_ValueError, "embedded null character");
|
||||||
|
|
@ -1087,7 +1030,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
*p = sarg;
|
*p = sarg;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return converterr(c == 'z' || nullable, "str",
|
return converterr(c == 'z' ? "str or None" : "str",
|
||||||
arg, msgbuf, bufsize);
|
arg, msgbuf, bufsize);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -1116,14 +1059,48 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
recode_strings = 0;
|
recode_strings = 0;
|
||||||
else
|
else
|
||||||
return converterr(
|
return converterr(
|
||||||
nullable, "(unknown parser marker combination)",
|
"(unknown parser marker combination)",
|
||||||
arg, msgbuf, bufsize);
|
arg, msgbuf, bufsize);
|
||||||
buffer = (char **)va_arg(*p_va, char **);
|
buffer = (char **)va_arg(*p_va, char **);
|
||||||
format++;
|
format++;
|
||||||
if (buffer == NULL)
|
if (buffer == NULL)
|
||||||
return converterr(nullable, "(buffer is NULL)",
|
return converterr("(buffer is NULL)",
|
||||||
arg, msgbuf, bufsize);
|
arg, msgbuf, bufsize);
|
||||||
Py_ssize_t *psize = NULL;
|
|
||||||
|
/* Encode object */
|
||||||
|
if (!recode_strings &&
|
||||||
|
(PyBytes_Check(arg) || PyByteArray_Check(arg))) {
|
||||||
|
s = Py_NewRef(arg);
|
||||||
|
if (PyBytes_Check(arg)) {
|
||||||
|
size = PyBytes_GET_SIZE(s);
|
||||||
|
ptr = PyBytes_AS_STRING(s);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
size = PyByteArray_GET_SIZE(s);
|
||||||
|
ptr = PyByteArray_AS_STRING(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (PyUnicode_Check(arg)) {
|
||||||
|
/* Encode object; use default error handling */
|
||||||
|
s = PyUnicode_AsEncodedString(arg,
|
||||||
|
encoding,
|
||||||
|
NULL);
|
||||||
|
if (s == NULL)
|
||||||
|
return converterr("(encoding failed)",
|
||||||
|
arg, msgbuf, bufsize);
|
||||||
|
assert(PyBytes_Check(s));
|
||||||
|
size = PyBytes_GET_SIZE(s);
|
||||||
|
ptr = PyBytes_AS_STRING(s);
|
||||||
|
if (ptr == NULL)
|
||||||
|
ptr = "";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return converterr(
|
||||||
|
recode_strings ? "str" : "str, bytes or bytearray",
|
||||||
|
arg, msgbuf, bufsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write output; output is guaranteed to be 0-terminated */
|
||||||
if (*format == '#') {
|
if (*format == '#') {
|
||||||
/* Using buffer length parameter '#':
|
/* Using buffer length parameter '#':
|
||||||
|
|
||||||
|
|
@ -1146,55 +1123,15 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
trailing 0-byte
|
trailing 0-byte
|
||||||
|
|
||||||
*/
|
*/
|
||||||
psize = va_arg(*p_va, Py_ssize_t*);
|
Py_ssize_t *psize = va_arg(*p_va, Py_ssize_t*);
|
||||||
|
|
||||||
format++;
|
format++;
|
||||||
if (psize == NULL) {
|
if (psize == NULL) {
|
||||||
|
Py_DECREF(s);
|
||||||
return converterr(
|
return converterr(
|
||||||
nullable, "(buffer_len is NULL)",
|
"(buffer_len is NULL)",
|
||||||
arg, msgbuf, bufsize);
|
arg, msgbuf, bufsize);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
HANDLE_NULLABLE;
|
|
||||||
|
|
||||||
/* Encode object */
|
|
||||||
if (!recode_strings &&
|
|
||||||
(PyBytes_Check(arg) || PyByteArray_Check(arg))) {
|
|
||||||
s = Py_NewRef(arg);
|
|
||||||
if (PyBytes_Check(arg)) {
|
|
||||||
size = PyBytes_GET_SIZE(s);
|
|
||||||
ptr = PyBytes_AS_STRING(s);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
size = PyByteArray_GET_SIZE(s);
|
|
||||||
ptr = PyByteArray_AS_STRING(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (PyUnicode_Check(arg)) {
|
|
||||||
/* Encode object; use default error handling */
|
|
||||||
s = PyUnicode_AsEncodedString(arg,
|
|
||||||
encoding,
|
|
||||||
NULL);
|
|
||||||
if (s == NULL)
|
|
||||||
return converterr(nullable, "(encoding failed)",
|
|
||||||
arg, msgbuf, bufsize);
|
|
||||||
assert(PyBytes_Check(s));
|
|
||||||
size = PyBytes_GET_SIZE(s);
|
|
||||||
ptr = PyBytes_AS_STRING(s);
|
|
||||||
if (ptr == NULL)
|
|
||||||
ptr = "";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return converterr(
|
|
||||||
nullable,
|
|
||||||
recode_strings ? "str"
|
|
||||||
: nullable ? "str, bytes, bytearray"
|
|
||||||
: "str, bytes or bytearray",
|
|
||||||
arg, msgbuf, bufsize);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write output; output is guaranteed to be 0-terminated */
|
|
||||||
if (psize != NULL) {
|
|
||||||
if (*buffer == NULL) {
|
if (*buffer == NULL) {
|
||||||
*buffer = PyMem_NEW(char, size + 1);
|
*buffer = PyMem_NEW(char, size + 1);
|
||||||
if (*buffer == NULL) {
|
if (*buffer == NULL) {
|
||||||
|
|
@ -1205,7 +1142,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
if (addcleanup(buffer, freelist, cleanup_ptr)) {
|
if (addcleanup(buffer, freelist, cleanup_ptr)) {
|
||||||
Py_DECREF(s);
|
Py_DECREF(s);
|
||||||
return converterr(
|
return converterr(
|
||||||
nullable, "(cleanup problem)",
|
"(cleanup problem)",
|
||||||
arg, msgbuf, bufsize);
|
arg, msgbuf, bufsize);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1239,7 +1176,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
if ((Py_ssize_t)strlen(ptr) != size) {
|
if ((Py_ssize_t)strlen(ptr) != size) {
|
||||||
Py_DECREF(s);
|
Py_DECREF(s);
|
||||||
return converterr(
|
return converterr(
|
||||||
nullable, "encoded string without null bytes",
|
"encoded string without null bytes",
|
||||||
arg, msgbuf, bufsize);
|
arg, msgbuf, bufsize);
|
||||||
}
|
}
|
||||||
*buffer = PyMem_NEW(char, size + 1);
|
*buffer = PyMem_NEW(char, size + 1);
|
||||||
|
|
@ -1250,7 +1187,7 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
}
|
}
|
||||||
if (addcleanup(buffer, freelist, cleanup_ptr)) {
|
if (addcleanup(buffer, freelist, cleanup_ptr)) {
|
||||||
Py_DECREF(s);
|
Py_DECREF(s);
|
||||||
return converterr(nullable, "(cleanup problem)",
|
return converterr("(cleanup problem)",
|
||||||
arg, msgbuf, bufsize);
|
arg, msgbuf, bufsize);
|
||||||
}
|
}
|
||||||
memcpy(*buffer, ptr, size+1);
|
memcpy(*buffer, ptr, size+1);
|
||||||
|
|
@ -1261,32 +1198,29 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
|
|
||||||
case 'S': { /* PyBytes object */
|
case 'S': { /* PyBytes object */
|
||||||
PyObject **p = va_arg(*p_va, PyObject **);
|
PyObject **p = va_arg(*p_va, PyObject **);
|
||||||
HANDLE_NULLABLE;
|
|
||||||
if (PyBytes_Check(arg))
|
if (PyBytes_Check(arg))
|
||||||
*p = arg;
|
*p = arg;
|
||||||
else
|
else
|
||||||
return converterr(nullable, "bytes", arg, msgbuf, bufsize);
|
return converterr("bytes", arg, msgbuf, bufsize);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'Y': { /* PyByteArray object */
|
case 'Y': { /* PyByteArray object */
|
||||||
PyObject **p = va_arg(*p_va, PyObject **);
|
PyObject **p = va_arg(*p_va, PyObject **);
|
||||||
HANDLE_NULLABLE;
|
|
||||||
if (PyByteArray_Check(arg))
|
if (PyByteArray_Check(arg))
|
||||||
*p = arg;
|
*p = arg;
|
||||||
else
|
else
|
||||||
return converterr(nullable, "bytearray", arg, msgbuf, bufsize);
|
return converterr("bytearray", arg, msgbuf, bufsize);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'U': { /* PyUnicode object */
|
case 'U': { /* PyUnicode object */
|
||||||
PyObject **p = va_arg(*p_va, PyObject **);
|
PyObject **p = va_arg(*p_va, PyObject **);
|
||||||
HANDLE_NULLABLE;
|
|
||||||
if (PyUnicode_Check(arg)) {
|
if (PyUnicode_Check(arg)) {
|
||||||
*p = arg;
|
*p = arg;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return converterr(nullable, "str", arg, msgbuf, bufsize);
|
return converterr("str", arg, msgbuf, bufsize);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1297,11 +1231,10 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
type = va_arg(*p_va, PyTypeObject*);
|
type = va_arg(*p_va, PyTypeObject*);
|
||||||
p = va_arg(*p_va, PyObject **);
|
p = va_arg(*p_va, PyObject **);
|
||||||
format++;
|
format++;
|
||||||
HANDLE_NULLABLE;
|
|
||||||
if (PyType_IsSubtype(Py_TYPE(arg), type))
|
if (PyType_IsSubtype(Py_TYPE(arg), type))
|
||||||
*p = arg;
|
*p = arg;
|
||||||
else
|
else
|
||||||
return converterr(nullable, type->tp_name, arg, msgbuf, bufsize);
|
return converterr(type->tp_name, arg, msgbuf, bufsize);
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (*format == '&') {
|
else if (*format == '&') {
|
||||||
|
|
@ -1310,18 +1243,16 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
void *addr = va_arg(*p_va, void *);
|
void *addr = va_arg(*p_va, void *);
|
||||||
int res;
|
int res;
|
||||||
format++;
|
format++;
|
||||||
HANDLE_NULLABLE;
|
|
||||||
if (! (res = (*convert)(arg, addr)))
|
if (! (res = (*convert)(arg, addr)))
|
||||||
return converterr(nullable, "(unspecified)",
|
return converterr("(unspecified)",
|
||||||
arg, msgbuf, bufsize);
|
arg, msgbuf, bufsize);
|
||||||
if (res == Py_CLEANUP_SUPPORTED &&
|
if (res == Py_CLEANUP_SUPPORTED &&
|
||||||
addcleanup(addr, freelist, convert) == -1)
|
addcleanup(addr, freelist, convert) == -1)
|
||||||
return converterr(nullable, "(cleanup problem)",
|
return converterr("(cleanup problem)",
|
||||||
arg, msgbuf, bufsize);
|
arg, msgbuf, bufsize);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
p = va_arg(*p_va, PyObject **);
|
p = va_arg(*p_va, PyObject **);
|
||||||
HANDLE_NULLABLE;
|
|
||||||
*p = arg;
|
*p = arg;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -1333,30 +1264,29 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
||||||
|
|
||||||
if (*format != '*')
|
if (*format != '*')
|
||||||
return converterr(
|
return converterr(
|
||||||
nullable, "(invalid use of 'w' format character)",
|
"(invalid use of 'w' format character)",
|
||||||
arg, msgbuf, bufsize);
|
arg, msgbuf, bufsize);
|
||||||
format++;
|
format++;
|
||||||
HANDLE_NULLABLE;
|
|
||||||
|
|
||||||
/* Caller is interested in Py_buffer, and the object supports it
|
/* Caller is interested in Py_buffer, and the object supports it
|
||||||
directly. The request implicitly asks for PyBUF_SIMPLE, so the
|
directly. The request implicitly asks for PyBUF_SIMPLE, so the
|
||||||
result is C-contiguous with format 'B'. */
|
result is C-contiguous with format 'B'. */
|
||||||
if (PyObject_GetBuffer(arg, (Py_buffer*)p, PyBUF_WRITABLE) < 0) {
|
if (PyObject_GetBuffer(arg, (Py_buffer*)p, PyBUF_WRITABLE) < 0) {
|
||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
return converterr(nullable, "read-write bytes-like object",
|
return converterr("read-write bytes-like object",
|
||||||
arg, msgbuf, bufsize);
|
arg, msgbuf, bufsize);
|
||||||
}
|
}
|
||||||
assert(PyBuffer_IsContiguous((Py_buffer *)p, 'C'));
|
assert(PyBuffer_IsContiguous((Py_buffer *)p, 'C'));
|
||||||
if (addcleanup(p, freelist, cleanup_buffer)) {
|
if (addcleanup(p, freelist, cleanup_buffer)) {
|
||||||
return converterr(
|
return converterr(
|
||||||
nullable, "(cleanup problem)",
|
"(cleanup problem)",
|
||||||
arg, msgbuf, bufsize);
|
arg, msgbuf, bufsize);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return converterr(nullable, "(impossible<bad format char>)", arg, msgbuf, bufsize);
|
return converterr("(impossible<bad format char>)", arg, msgbuf, bufsize);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2751,9 +2681,6 @@ skipitem(const char **p_format, va_list *p_va, int flags)
|
||||||
return "impossible<bad format char>";
|
return "impossible<bad format char>";
|
||||||
|
|
||||||
}
|
}
|
||||||
if (*format == '?') {
|
|
||||||
format++;
|
|
||||||
}
|
|
||||||
|
|
||||||
*p_format = format;
|
*p_format = format;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue