bpo-20260: Implement non-bitwise unsigned int converters for Argument Clinic. (GH-8434)

This commit is contained in:
Serhiy Storchaka 2018-07-26 13:22:16 +03:00 committed by GitHub
parent 323748ad74
commit 7cb7bcff20
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 183 additions and 112 deletions

View File

@ -878,6 +878,12 @@ converter::
Write a pickled representation of obj to the open file. Write a pickled representation of obj to the open file.
[clinic start generated code]*/ [clinic start generated code]*/
One advantage of real converters is that they're more flexible than legacy
converters. For example, the ``unsigned_int`` converter (and all the
``unsigned_`` converters) can be specified without ``bitwise=True``. Their
default behavior performs range checking on the value, and they won't accept
negative numbers. You just can't do that with a legacy converter!
Argument Clinic will show you all the converters it has Argument Clinic will show you all the converters it has
available. For each converter it'll show you all the parameters available. For each converter it'll show you all the parameters
it accepts, along with the default value for each parameter. it accepts, along with the default value for each parameter.

View File

@ -65,6 +65,14 @@ PyAPI_FUNC(PyObject *) PyLong_GetInfo(void);
# error "void* different in size from int, long and long long" # error "void* different in size from int, long and long long"
#endif /* SIZEOF_VOID_P */ #endif /* SIZEOF_VOID_P */
#ifndef Py_LIMITED_API
PyAPI_FUNC(int) _PyLong_UnsignedShort_Converter(PyObject *, void *);
PyAPI_FUNC(int) _PyLong_UnsignedInt_Converter(PyObject *, void *);
PyAPI_FUNC(int) _PyLong_UnsignedLong_Converter(PyObject *, void *);
PyAPI_FUNC(int) _PyLong_UnsignedLongLong_Converter(PyObject *, void *);
PyAPI_FUNC(int) _PyLong_Size_t_Converter(PyObject *, void *);
#endif
/* Used by Python/mystrtoul.c, _PyBytes_FromHex(), /* Used by Python/mystrtoul.c, _PyBytes_FromHex(),
_PyBytes_DecodeEscapeRecode(), etc. */ _PyBytes_DecodeEscapeRecode(), etc. */
#ifndef Py_LIMITED_API #ifndef Py_LIMITED_API

View File

@ -560,12 +560,12 @@ class HashLibTestCase(unittest.TestCase):
constructor(leaf_size=0) constructor(leaf_size=0)
constructor(leaf_size=(1<<32)-1) constructor(leaf_size=(1<<32)-1)
self.assertRaises(OverflowError, constructor, leaf_size=-1) self.assertRaises(ValueError, constructor, leaf_size=-1)
self.assertRaises(OverflowError, constructor, leaf_size=1<<32) self.assertRaises(OverflowError, constructor, leaf_size=1<<32)
constructor(node_offset=0) constructor(node_offset=0)
constructor(node_offset=max_offset) constructor(node_offset=max_offset)
self.assertRaises(OverflowError, constructor, node_offset=-1) self.assertRaises(ValueError, constructor, node_offset=-1)
self.assertRaises(OverflowError, constructor, node_offset=max_offset+1) self.assertRaises(OverflowError, constructor, node_offset=max_offset+1)
constructor( constructor(

View File

@ -159,9 +159,9 @@ class PollTests(unittest.TestCase):
self.fail('Overflow must have occurred') self.fail('Overflow must have occurred')
# Issues #15989, #17919 # Issues #15989, #17919
self.assertRaises(OverflowError, pollster.register, 0, -1) self.assertRaises(ValueError, pollster.register, 0, -1)
self.assertRaises(OverflowError, pollster.register, 0, 1 << 64) self.assertRaises(OverflowError, pollster.register, 0, 1 << 64)
self.assertRaises(OverflowError, pollster.modify, 1, -1) self.assertRaises(ValueError, pollster.modify, 1, -1)
self.assertRaises(OverflowError, pollster.modify, 1, 1 << 64) self.assertRaises(OverflowError, pollster.modify, 1, 1 << 64)
@cpython_only @cpython_only

View File

@ -0,0 +1 @@
Argument Clinic now has non-bitwise unsigned int converters.

View File

@ -75,8 +75,8 @@ _blake2b.blake2b.__new__ as py_blake2b_new
person: Py_buffer = None person: Py_buffer = None
fanout: int = 1 fanout: int = 1
depth: int = 1 depth: int = 1
leaf_size as leaf_size_obj: object = NULL leaf_size: unsigned_long = 0
node_offset as node_offset_obj: object = NULL node_offset: unsigned_long_long = 0
node_depth: int = 0 node_depth: int = 0
inner_size: int = 0 inner_size: int = 0
last_node: bool = False last_node: bool = False
@ -87,17 +87,14 @@ Return a new BLAKE2b hash object.
static PyObject * static PyObject *
py_blake2b_new_impl(PyTypeObject *type, PyObject *data, int digest_size, py_blake2b_new_impl(PyTypeObject *type, PyObject *data, int digest_size,
Py_buffer *key, Py_buffer *salt, Py_buffer *person, Py_buffer *key, Py_buffer *salt, Py_buffer *person,
int fanout, int depth, PyObject *leaf_size_obj, int fanout, int depth, unsigned long leaf_size,
PyObject *node_offset_obj, int node_depth, unsigned long long node_offset, int node_depth,
int inner_size, int last_node) int inner_size, int last_node)
/*[clinic end generated code: output=7506d8d890e5f13b input=e41548dfa0866031]*/ /*[clinic end generated code: output=65e732c66c2297a0 input=75ab5196b695adee]*/
{ {
BLAKE2bObject *self = NULL; BLAKE2bObject *self = NULL;
Py_buffer buf; Py_buffer buf;
unsigned long leaf_size = 0;
unsigned long long node_offset = 0;
self = new_BLAKE2bObject(type); self = new_BLAKE2bObject(type);
if (self == NULL) { if (self == NULL) {
goto error; goto error;
@ -152,25 +149,13 @@ py_blake2b_new_impl(PyTypeObject *type, PyObject *data, int digest_size,
} }
self->param.depth = (uint8_t)depth; self->param.depth = (uint8_t)depth;
if (leaf_size_obj != NULL) { if (leaf_size > 0xFFFFFFFFU) {
leaf_size = PyLong_AsUnsignedLong(leaf_size_obj); PyErr_SetString(PyExc_OverflowError, "leaf_size is too large");
if (leaf_size == (unsigned long) -1 && PyErr_Occurred()) { goto error;
goto error;
}
if (leaf_size > 0xFFFFFFFFU) {
PyErr_SetString(PyExc_OverflowError, "leaf_size is too large");
goto error;
}
} }
// NB: Simple assignment here would be incorrect on big endian platforms. // NB: Simple assignment here would be incorrect on big endian platforms.
store32(&(self->param.leaf_length), leaf_size); store32(&(self->param.leaf_length), leaf_size);
if (node_offset_obj != NULL) {
node_offset = PyLong_AsUnsignedLongLong(node_offset_obj);
if (node_offset == (unsigned long long) -1 && PyErr_Occurred()) {
goto error;
}
}
#ifdef HAVE_BLAKE2S #ifdef HAVE_BLAKE2S
if (node_offset > 0xFFFFFFFFFFFFULL) { if (node_offset > 0xFFFFFFFFFFFFULL) {
/* maximum 2**48 - 1 */ /* maximum 2**48 - 1 */

View File

@ -75,8 +75,8 @@ _blake2s.blake2s.__new__ as py_blake2s_new
person: Py_buffer = None person: Py_buffer = None
fanout: int = 1 fanout: int = 1
depth: int = 1 depth: int = 1
leaf_size as leaf_size_obj: object = NULL leaf_size: unsigned_long = 0
node_offset as node_offset_obj: object = NULL node_offset: unsigned_long_long = 0
node_depth: int = 0 node_depth: int = 0
inner_size: int = 0 inner_size: int = 0
last_node: bool = False last_node: bool = False
@ -87,17 +87,14 @@ Return a new BLAKE2s hash object.
static PyObject * static PyObject *
py_blake2s_new_impl(PyTypeObject *type, PyObject *data, int digest_size, py_blake2s_new_impl(PyTypeObject *type, PyObject *data, int digest_size,
Py_buffer *key, Py_buffer *salt, Py_buffer *person, Py_buffer *key, Py_buffer *salt, Py_buffer *person,
int fanout, int depth, PyObject *leaf_size_obj, int fanout, int depth, unsigned long leaf_size,
PyObject *node_offset_obj, int node_depth, unsigned long long node_offset, int node_depth,
int inner_size, int last_node) int inner_size, int last_node)
/*[clinic end generated code: output=fe060b258a8cbfc6 input=458cfdcb3d0d47ff]*/ /*[clinic end generated code: output=b95806be0514dcf7 input=f18d6efd9b9a1271]*/
{ {
BLAKE2sObject *self = NULL; BLAKE2sObject *self = NULL;
Py_buffer buf; Py_buffer buf;
unsigned long leaf_size = 0;
unsigned long long node_offset = 0;
self = new_BLAKE2sObject(type); self = new_BLAKE2sObject(type);
if (self == NULL) { if (self == NULL) {
goto error; goto error;
@ -152,25 +149,13 @@ py_blake2s_new_impl(PyTypeObject *type, PyObject *data, int digest_size,
} }
self->param.depth = (uint8_t)depth; self->param.depth = (uint8_t)depth;
if (leaf_size_obj != NULL) { if (leaf_size > 0xFFFFFFFFU) {
leaf_size = PyLong_AsUnsignedLong(leaf_size_obj); PyErr_SetString(PyExc_OverflowError, "leaf_size is too large");
if (leaf_size == (unsigned long) -1 && PyErr_Occurred()) { goto error;
goto error;
}
if (leaf_size > 0xFFFFFFFFU) {
PyErr_SetString(PyExc_OverflowError, "leaf_size is too large");
goto error;
}
} }
// NB: Simple assignment here would be incorrect on big endian platforms. // NB: Simple assignment here would be incorrect on big endian platforms.
store32(&(self->param.leaf_length), leaf_size); store32(&(self->param.leaf_length), leaf_size);
if (node_offset_obj != NULL) {
node_offset = PyLong_AsUnsignedLongLong(node_offset_obj);
if (node_offset == (unsigned long long) -1 && PyErr_Occurred()) {
goto error;
}
}
#ifdef HAVE_BLAKE2S #ifdef HAVE_BLAKE2S
if (node_offset > 0xFFFFFFFFFFFFULL) { if (node_offset > 0xFFFFFFFFFFFFULL) {
/* maximum 2**48 - 1 */ /* maximum 2**48 - 1 */

View File

@ -5,7 +5,7 @@ preserve
PyDoc_STRVAR(py_blake2b_new__doc__, PyDoc_STRVAR(py_blake2b_new__doc__,
"blake2b(string=None, *, digest_size=_blake2b.blake2b.MAX_DIGEST_SIZE,\n" "blake2b(string=None, *, digest_size=_blake2b.blake2b.MAX_DIGEST_SIZE,\n"
" key=None, salt=None, person=None, fanout=1, depth=1,\n" " key=None, salt=None, person=None, fanout=1, depth=1,\n"
" leaf_size=None, node_offset=None, node_depth=0, inner_size=0,\n" " leaf_size=0, node_offset=0, node_depth=0, inner_size=0,\n"
" last_node=False)\n" " last_node=False)\n"
"--\n" "--\n"
"\n" "\n"
@ -14,8 +14,8 @@ PyDoc_STRVAR(py_blake2b_new__doc__,
static PyObject * static PyObject *
py_blake2b_new_impl(PyTypeObject *type, PyObject *data, int digest_size, py_blake2b_new_impl(PyTypeObject *type, PyObject *data, int digest_size,
Py_buffer *key, Py_buffer *salt, Py_buffer *person, Py_buffer *key, Py_buffer *salt, Py_buffer *person,
int fanout, int depth, PyObject *leaf_size_obj, int fanout, int depth, unsigned long leaf_size,
PyObject *node_offset_obj, int node_depth, unsigned long long node_offset, int node_depth,
int inner_size, int last_node); int inner_size, int last_node);
static PyObject * static PyObject *
@ -23,7 +23,7 @@ py_blake2b_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
{ {
PyObject *return_value = NULL; PyObject *return_value = NULL;
static const char * const _keywords[] = {"string", "digest_size", "key", "salt", "person", "fanout", "depth", "leaf_size", "node_offset", "node_depth", "inner_size", "last_node", NULL}; static const char * const _keywords[] = {"string", "digest_size", "key", "salt", "person", "fanout", "depth", "leaf_size", "node_offset", "node_depth", "inner_size", "last_node", NULL};
static _PyArg_Parser _parser = {"|O$iy*y*y*iiOOiip:blake2b", _keywords, 0}; static _PyArg_Parser _parser = {"|O$iy*y*y*iiO&O&iip:blake2b", _keywords, 0};
PyObject *data = NULL; PyObject *data = NULL;
int digest_size = BLAKE2B_OUTBYTES; int digest_size = BLAKE2B_OUTBYTES;
Py_buffer key = {NULL, NULL}; Py_buffer key = {NULL, NULL};
@ -31,17 +31,17 @@ py_blake2b_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
Py_buffer person = {NULL, NULL}; Py_buffer person = {NULL, NULL};
int fanout = 1; int fanout = 1;
int depth = 1; int depth = 1;
PyObject *leaf_size_obj = NULL; unsigned long leaf_size = 0;
PyObject *node_offset_obj = NULL; unsigned long long node_offset = 0;
int node_depth = 0; int node_depth = 0;
int inner_size = 0; int inner_size = 0;
int last_node = 0; int last_node = 0;
if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser,
&data, &digest_size, &key, &salt, &person, &fanout, &depth, &leaf_size_obj, &node_offset_obj, &node_depth, &inner_size, &last_node)) { &data, &digest_size, &key, &salt, &person, &fanout, &depth, _PyLong_UnsignedLong_Converter, &leaf_size, _PyLong_UnsignedLongLong_Converter, &node_offset, &node_depth, &inner_size, &last_node)) {
goto exit; goto exit;
} }
return_value = py_blake2b_new_impl(type, data, digest_size, &key, &salt, &person, fanout, depth, leaf_size_obj, node_offset_obj, node_depth, inner_size, last_node); return_value = py_blake2b_new_impl(type, data, digest_size, &key, &salt, &person, fanout, depth, leaf_size, node_offset, node_depth, inner_size, last_node);
exit: exit:
/* Cleanup for key */ /* Cleanup for key */
@ -122,4 +122,4 @@ _blake2b_blake2b_hexdigest(BLAKE2bObject *self, PyObject *Py_UNUSED(ignored))
{ {
return _blake2b_blake2b_hexdigest_impl(self); return _blake2b_blake2b_hexdigest_impl(self);
} }
/*[clinic end generated code: output=535a54852c98e51c input=a9049054013a1b77]*/ /*[clinic end generated code: output=afc5c45dff0a24f9 input=a9049054013a1b77]*/

View File

@ -5,7 +5,7 @@ preserve
PyDoc_STRVAR(py_blake2s_new__doc__, PyDoc_STRVAR(py_blake2s_new__doc__,
"blake2s(string=None, *, digest_size=_blake2s.blake2s.MAX_DIGEST_SIZE,\n" "blake2s(string=None, *, digest_size=_blake2s.blake2s.MAX_DIGEST_SIZE,\n"
" key=None, salt=None, person=None, fanout=1, depth=1,\n" " key=None, salt=None, person=None, fanout=1, depth=1,\n"
" leaf_size=None, node_offset=None, node_depth=0, inner_size=0,\n" " leaf_size=0, node_offset=0, node_depth=0, inner_size=0,\n"
" last_node=False)\n" " last_node=False)\n"
"--\n" "--\n"
"\n" "\n"
@ -14,8 +14,8 @@ PyDoc_STRVAR(py_blake2s_new__doc__,
static PyObject * static PyObject *
py_blake2s_new_impl(PyTypeObject *type, PyObject *data, int digest_size, py_blake2s_new_impl(PyTypeObject *type, PyObject *data, int digest_size,
Py_buffer *key, Py_buffer *salt, Py_buffer *person, Py_buffer *key, Py_buffer *salt, Py_buffer *person,
int fanout, int depth, PyObject *leaf_size_obj, int fanout, int depth, unsigned long leaf_size,
PyObject *node_offset_obj, int node_depth, unsigned long long node_offset, int node_depth,
int inner_size, int last_node); int inner_size, int last_node);
static PyObject * static PyObject *
@ -23,7 +23,7 @@ py_blake2s_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
{ {
PyObject *return_value = NULL; PyObject *return_value = NULL;
static const char * const _keywords[] = {"string", "digest_size", "key", "salt", "person", "fanout", "depth", "leaf_size", "node_offset", "node_depth", "inner_size", "last_node", NULL}; static const char * const _keywords[] = {"string", "digest_size", "key", "salt", "person", "fanout", "depth", "leaf_size", "node_offset", "node_depth", "inner_size", "last_node", NULL};
static _PyArg_Parser _parser = {"|O$iy*y*y*iiOOiip:blake2s", _keywords, 0}; static _PyArg_Parser _parser = {"|O$iy*y*y*iiO&O&iip:blake2s", _keywords, 0};
PyObject *data = NULL; PyObject *data = NULL;
int digest_size = BLAKE2S_OUTBYTES; int digest_size = BLAKE2S_OUTBYTES;
Py_buffer key = {NULL, NULL}; Py_buffer key = {NULL, NULL};
@ -31,17 +31,17 @@ py_blake2s_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
Py_buffer person = {NULL, NULL}; Py_buffer person = {NULL, NULL};
int fanout = 1; int fanout = 1;
int depth = 1; int depth = 1;
PyObject *leaf_size_obj = NULL; unsigned long leaf_size = 0;
PyObject *node_offset_obj = NULL; unsigned long long node_offset = 0;
int node_depth = 0; int node_depth = 0;
int inner_size = 0; int inner_size = 0;
int last_node = 0; int last_node = 0;
if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser,
&data, &digest_size, &key, &salt, &person, &fanout, &depth, &leaf_size_obj, &node_offset_obj, &node_depth, &inner_size, &last_node)) { &data, &digest_size, &key, &salt, &person, &fanout, &depth, _PyLong_UnsignedLong_Converter, &leaf_size, _PyLong_UnsignedLongLong_Converter, &node_offset, &node_depth, &inner_size, &last_node)) {
goto exit; goto exit;
} }
return_value = py_blake2s_new_impl(type, data, digest_size, &key, &salt, &person, fanout, depth, leaf_size_obj, node_offset_obj, node_depth, inner_size, last_node); return_value = py_blake2s_new_impl(type, data, digest_size, &key, &salt, &person, fanout, depth, leaf_size, node_offset, node_depth, inner_size, last_node);
exit: exit:
/* Cleanup for key */ /* Cleanup for key */
@ -122,4 +122,4 @@ _blake2s_blake2s_hexdigest(BLAKE2sObject *self, PyObject *Py_UNUSED(ignored))
{ {
return _blake2s_blake2s_hexdigest_impl(self); return _blake2s_blake2s_hexdigest_impl(self);
} }
/*[clinic end generated code: output=535ea7903f9ccf76 input=a9049054013a1b77]*/ /*[clinic end generated code: output=b705723d16f21f57 input=a9049054013a1b77]*/

View File

@ -83,7 +83,7 @@ select_poll_register(pollObject *self, PyObject *const *args, Py_ssize_t nargs)
unsigned short eventmask = POLLIN | POLLPRI | POLLOUT; unsigned short eventmask = POLLIN | POLLPRI | POLLOUT;
if (!_PyArg_ParseStack(args, nargs, "O&|O&:register", if (!_PyArg_ParseStack(args, nargs, "O&|O&:register",
fildes_converter, &fd, ushort_converter, &eventmask)) { fildes_converter, &fd, _PyLong_UnsignedShort_Converter, &eventmask)) {
goto exit; goto exit;
} }
return_value = select_poll_register_impl(self, fd, eventmask); return_value = select_poll_register_impl(self, fd, eventmask);
@ -122,7 +122,7 @@ select_poll_modify(pollObject *self, PyObject *const *args, Py_ssize_t nargs)
unsigned short eventmask; unsigned short eventmask;
if (!_PyArg_ParseStack(args, nargs, "O&O&:modify", if (!_PyArg_ParseStack(args, nargs, "O&O&:modify",
fildes_converter, &fd, ushort_converter, &eventmask)) { fildes_converter, &fd, _PyLong_UnsignedShort_Converter, &eventmask)) {
goto exit; goto exit;
} }
return_value = select_poll_modify_impl(self, fd, eventmask); return_value = select_poll_modify_impl(self, fd, eventmask);
@ -229,7 +229,7 @@ select_devpoll_register(devpollObject *self, PyObject *const *args, Py_ssize_t n
unsigned short eventmask = POLLIN | POLLPRI | POLLOUT; unsigned short eventmask = POLLIN | POLLPRI | POLLOUT;
if (!_PyArg_ParseStack(args, nargs, "O&|O&:register", if (!_PyArg_ParseStack(args, nargs, "O&|O&:register",
fildes_converter, &fd, ushort_converter, &eventmask)) { fildes_converter, &fd, _PyLong_UnsignedShort_Converter, &eventmask)) {
goto exit; goto exit;
} }
return_value = select_devpoll_register_impl(self, fd, eventmask); return_value = select_devpoll_register_impl(self, fd, eventmask);
@ -269,7 +269,7 @@ select_devpoll_modify(devpollObject *self, PyObject *const *args, Py_ssize_t nar
unsigned short eventmask = POLLIN | POLLPRI | POLLOUT; unsigned short eventmask = POLLIN | POLLPRI | POLLOUT;
if (!_PyArg_ParseStack(args, nargs, "O&|O&:modify", if (!_PyArg_ParseStack(args, nargs, "O&|O&:modify",
fildes_converter, &fd, ushort_converter, &eventmask)) { fildes_converter, &fd, _PyLong_UnsignedShort_Converter, &eventmask)) {
goto exit; goto exit;
} }
return_value = select_devpoll_modify_impl(self, fd, eventmask); return_value = select_devpoll_modify_impl(self, fd, eventmask);
@ -1047,4 +1047,4 @@ exit:
#ifndef SELECT_KQUEUE_CONTROL_METHODDEF #ifndef SELECT_KQUEUE_CONTROL_METHODDEF
#define SELECT_KQUEUE_CONTROL_METHODDEF #define SELECT_KQUEUE_CONTROL_METHODDEF
#endif /* !defined(SELECT_KQUEUE_CONTROL_METHODDEF) */ #endif /* !defined(SELECT_KQUEUE_CONTROL_METHODDEF) */
/*[clinic end generated code: output=3e425445d49c49e2 input=a9049054013a1b77]*/ /*[clinic end generated code: output=561bec8bcb0e00c5 input=a9049054013a1b77]*/

View File

@ -430,30 +430,12 @@ update_ufd_array(pollObject *self)
return 1; return 1;
} }
static int
ushort_converter(PyObject *obj, void *ptr)
{
unsigned long uval;
uval = PyLong_AsUnsignedLong(obj);
if (uval == (unsigned long)-1 && PyErr_Occurred())
return 0;
if (uval > USHRT_MAX) {
PyErr_SetString(PyExc_OverflowError,
"Python int too large for C unsigned short");
return 0;
}
*(unsigned short *)ptr = Py_SAFE_DOWNCAST(uval, unsigned long, unsigned short);
return 1;
}
/*[clinic input] /*[clinic input]
select.poll.register select.poll.register
fd: fildes fd: fildes
either an integer, or an object with a fileno() method returning an int either an integer, or an object with a fileno() method returning an int
eventmask: object(converter="ushort_converter", type="unsigned short", c_default="POLLIN | POLLPRI | POLLOUT") = POLLIN | POLLPRI | POLLOUT eventmask: unsigned_short(c_default="POLLIN | POLLPRI | POLLOUT") = POLLIN | POLLPRI | POLLOUT
an optional bitmask describing the type of events to check for an optional bitmask describing the type of events to check for
/ /
@ -462,7 +444,7 @@ Register a file descriptor with the polling object.
static PyObject * static PyObject *
select_poll_register_impl(pollObject *self, int fd, unsigned short eventmask) select_poll_register_impl(pollObject *self, int fd, unsigned short eventmask)
/*[clinic end generated code: output=0dc7173c800a4a65 input=499d96a2836217f5]*/ /*[clinic end generated code: output=0dc7173c800a4a65 input=f18711d9bb021e25]*/
{ {
PyObject *key, *value; PyObject *key, *value;
int err; int err;
@ -495,7 +477,7 @@ select.poll.modify
fd: fildes fd: fildes
either an integer, or an object with a fileno() method returning either an integer, or an object with a fileno() method returning
an int an int
eventmask: object(converter="ushort_converter", type="unsigned short") eventmask: unsigned_short
a bitmask describing the type of events to check for a bitmask describing the type of events to check for
/ /
@ -504,7 +486,7 @@ Modify an already registered file descriptor.
static PyObject * static PyObject *
select_poll_modify_impl(pollObject *self, int fd, unsigned short eventmask) select_poll_modify_impl(pollObject *self, int fd, unsigned short eventmask)
/*[clinic end generated code: output=1a7b88bf079eff17 input=b8e0e04a1264b78f]*/ /*[clinic end generated code: output=1a7b88bf079eff17 input=a8e383df075c32cf]*/
{ {
PyObject *key, *value; PyObject *key, *value;
int err; int err;
@ -832,7 +814,7 @@ select.devpoll.register
fd: fildes fd: fildes
either an integer, or an object with a fileno() method returning either an integer, or an object with a fileno() method returning
an int an int
eventmask: object(converter="ushort_converter", type="unsigned short", c_default="POLLIN | POLLPRI | POLLOUT") = POLLIN | POLLPRI | POLLOUT eventmask: unsigned_short(c_default="POLLIN | POLLPRI | POLLOUT") = POLLIN | POLLPRI | POLLOUT
an optional bitmask describing the type of events to check for an optional bitmask describing the type of events to check for
/ /
@ -842,7 +824,7 @@ Register a file descriptor with the polling object.
static PyObject * static PyObject *
select_devpoll_register_impl(devpollObject *self, int fd, select_devpoll_register_impl(devpollObject *self, int fd,
unsigned short eventmask) unsigned short eventmask)
/*[clinic end generated code: output=6e07fe8b74abba0c input=389a0785bb8feb57]*/ /*[clinic end generated code: output=6e07fe8b74abba0c input=5bd7cacc47a8ee46]*/
{ {
return internal_devpoll_register(self, fd, eventmask, 0); return internal_devpoll_register(self, fd, eventmask, 0);
} }
@ -853,7 +835,7 @@ select.devpoll.modify
fd: fildes fd: fildes
either an integer, or an object with a fileno() method returning either an integer, or an object with a fileno() method returning
an int an int
eventmask: object(converter="ushort_converter", type="unsigned short", c_default="POLLIN | POLLPRI | POLLOUT") = POLLIN | POLLPRI | POLLOUT eventmask: unsigned_short(c_default="POLLIN | POLLPRI | POLLOUT") = POLLIN | POLLPRI | POLLOUT
an optional bitmask describing the type of events to check for an optional bitmask describing the type of events to check for
/ /
@ -863,7 +845,7 @@ Modify a possible already registered file descriptor.
static PyObject * static PyObject *
select_devpoll_modify_impl(devpollObject *self, int fd, select_devpoll_modify_impl(devpollObject *self, int fd,
unsigned short eventmask) unsigned short eventmask)
/*[clinic end generated code: output=bc2e6d23aaff98b4 input=f0d7de3889cc55fb]*/ /*[clinic end generated code: output=bc2e6d23aaff98b4 input=48a820fc5967165d]*/
static PyObject * static PyObject *
devpoll_modify(devpollObject *self, PyObject *args) devpoll_modify(devpollObject *self, PyObject *args)
{ {

View File

@ -1439,6 +1439,102 @@ PyLong_AsLongLongAndOverflow(PyObject *vv, int *overflow)
return res; return res;
} }
int
_PyLong_UnsignedShort_Converter(PyObject *obj, void *ptr)
{
unsigned long uval;
if (PyLong_Check(obj) && _PyLong_Sign(obj) < 0) {
PyErr_SetString(PyExc_ValueError, "value must be positive");
return 0;
}
uval = PyLong_AsUnsignedLong(obj);
if (uval == (unsigned long)-1 && PyErr_Occurred())
return 0;
if (uval > USHRT_MAX) {
PyErr_SetString(PyExc_OverflowError,
"Python int too large for C unsigned short");
return 0;
}
*(unsigned short *)ptr = Py_SAFE_DOWNCAST(uval, unsigned long, unsigned short);
return 1;
}
int
_PyLong_UnsignedInt_Converter(PyObject *obj, void *ptr)
{
unsigned long uval;
if (PyLong_Check(obj) && _PyLong_Sign(obj) < 0) {
PyErr_SetString(PyExc_ValueError, "value must be positive");
return 0;
}
uval = PyLong_AsUnsignedLong(obj);
if (uval == (unsigned long)-1 && PyErr_Occurred())
return 0;
if (uval > UINT_MAX) {
PyErr_SetString(PyExc_OverflowError,
"Python int too large for C unsigned int");
return 0;
}
*(unsigned int *)ptr = Py_SAFE_DOWNCAST(uval, unsigned long, unsigned int);
return 1;
}
int
_PyLong_UnsignedLong_Converter(PyObject *obj, void *ptr)
{
unsigned long uval;
if (PyLong_Check(obj) && _PyLong_Sign(obj) < 0) {
PyErr_SetString(PyExc_ValueError, "value must be positive");
return 0;
}
uval = PyLong_AsUnsignedLong(obj);
if (uval == (unsigned long)-1 && PyErr_Occurred())
return 0;
*(unsigned long *)ptr = uval;
return 1;
}
int
_PyLong_UnsignedLongLong_Converter(PyObject *obj, void *ptr)
{
unsigned long long uval;
if (PyLong_Check(obj) && _PyLong_Sign(obj) < 0) {
PyErr_SetString(PyExc_ValueError, "value must be positive");
return 0;
}
uval = PyLong_AsUnsignedLongLong(obj);
if (uval == (unsigned long long)-1 && PyErr_Occurred())
return 0;
*(unsigned long long *)ptr = uval;
return 1;
}
int
_PyLong_Size_t_Converter(PyObject *obj, void *ptr)
{
size_t uval;
if (PyLong_Check(obj) && _PyLong_Sign(obj) < 0) {
PyErr_SetString(PyExc_ValueError, "value must be positive");
return 0;
}
uval = PyLong_AsSize_t(obj);
if (uval == (size_t)-1 && PyErr_Occurred())
return 0;
*(size_t *)ptr = uval;
return 1;
}
#define CHECK_BINOP(v,w) \ #define CHECK_BINOP(v,w) \
do { \ do { \
if (!PyLong_Check(v) || !PyLong_Check(w)) \ if (!PyLong_Check(v) || !PyLong_Check(w)) \

View File

@ -2603,12 +2603,13 @@ class short_converter(CConverter):
class unsigned_short_converter(CConverter): class unsigned_short_converter(CConverter):
type = 'unsigned short' type = 'unsigned short'
default_type = int default_type = int
format_unit = 'H'
c_ignored_default = "0" c_ignored_default = "0"
def converter_init(self, *, bitwise=False): def converter_init(self, *, bitwise=False):
if not bitwise: if bitwise:
fail("Unsigned shorts must be bitwise (for now).") self.format_unit = 'H'
else:
self.converter = '_PyLong_UnsignedShort_Converter'
@add_legacy_c_converter('C', accept={str}) @add_legacy_c_converter('C', accept={str})
class int_converter(CConverter): class int_converter(CConverter):
@ -2628,12 +2629,13 @@ class int_converter(CConverter):
class unsigned_int_converter(CConverter): class unsigned_int_converter(CConverter):
type = 'unsigned int' type = 'unsigned int'
default_type = int default_type = int
format_unit = 'I'
c_ignored_default = "0" c_ignored_default = "0"
def converter_init(self, *, bitwise=False): def converter_init(self, *, bitwise=False):
if not bitwise: if bitwise:
fail("Unsigned ints must be bitwise (for now).") self.format_unit = 'I'
else:
self.converter = '_PyLong_UnsignedInt_Converter'
class long_converter(CConverter): class long_converter(CConverter):
type = 'long' type = 'long'
@ -2644,12 +2646,13 @@ class long_converter(CConverter):
class unsigned_long_converter(CConverter): class unsigned_long_converter(CConverter):
type = 'unsigned long' type = 'unsigned long'
default_type = int default_type = int
format_unit = 'k'
c_ignored_default = "0" c_ignored_default = "0"
def converter_init(self, *, bitwise=False): def converter_init(self, *, bitwise=False):
if not bitwise: if bitwise:
fail("Unsigned longs must be bitwise (for now).") self.format_unit = 'k'
else:
self.converter = '_PyLong_UnsignedLong_Converter'
class long_long_converter(CConverter): class long_long_converter(CConverter):
type = 'long long' type = 'long long'
@ -2660,13 +2663,13 @@ class long_long_converter(CConverter):
class unsigned_long_long_converter(CConverter): class unsigned_long_long_converter(CConverter):
type = 'unsigned long long' type = 'unsigned long long'
default_type = int default_type = int
format_unit = 'K'
c_ignored_default = "0" c_ignored_default = "0"
def converter_init(self, *, bitwise=False): def converter_init(self, *, bitwise=False):
if not bitwise: if bitwise:
fail("Unsigned long long must be bitwise (for now).") self.format_unit = 'K'
else:
self.converter = '_PyLong_UnsignedLongLong_Converter'
class Py_ssize_t_converter(CConverter): class Py_ssize_t_converter(CConverter):
type = 'Py_ssize_t' type = 'Py_ssize_t'
@ -2693,6 +2696,11 @@ class slice_index_converter(CConverter):
else: else:
fail("slice_index_converter: illegal 'accept' argument " + repr(accept)) fail("slice_index_converter: illegal 'accept' argument " + repr(accept))
class size_t_converter(CConverter):
type = 'size_t'
converter = '_PyLong_Size_t_Converter'
c_ignored_default = "0"
class float_converter(CConverter): class float_converter(CConverter):
type = 'float' type = 'float'