]> granicus.if.org Git - python/commitdiff
bpo-20260: Implement non-bitwise unsigned int converters for Argument Clinic. (GH...
authorSerhiy Storchaka <storchaka@gmail.com>
Thu, 26 Jul 2018 10:22:16 +0000 (13:22 +0300)
committerGitHub <noreply@github.com>
Thu, 26 Jul 2018 10:22:16 +0000 (13:22 +0300)
13 files changed:
Doc/howto/clinic.rst
Include/longobject.h
Lib/test/test_hashlib.py
Lib/test/test_poll.py
Misc/NEWS.d/next/Tools-Demos/2018-07-24-00-11-44.bpo-20260.klmmqI.rst [new file with mode: 0644]
Modules/_blake2/blake2b_impl.c
Modules/_blake2/blake2s_impl.c
Modules/_blake2/clinic/blake2b_impl.c.h
Modules/_blake2/clinic/blake2s_impl.c.h
Modules/clinic/selectmodule.c.h
Modules/selectmodule.c
Objects/longobject.c
Tools/clinic/clinic.py

index 695fbb1be192b2e1408ec2a0ebd3cd3a951033e3..c75c31c98319032fb1e6bb3cb44a1318dc69a56b 100644 (file)
@@ -878,6 +878,12 @@ converter::
     Write a pickled representation of obj to the open file.
     [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
 available.  For each converter it'll show you all the parameters
 it accepts, along with the default value for each parameter.
index 7bdd0472baaab4624847b662b93fd1faf6f4b44d..82c06c92a6389946c4a924d6f960fd78a689f72d 100644 (file)
@@ -65,6 +65,14 @@ PyAPI_FUNC(PyObject *) PyLong_GetInfo(void);
 #  error "void* different in size from int, long and long long"
 #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(),
    _PyBytes_DecodeEscapeRecode(), etc. */
 #ifndef Py_LIMITED_API
index 5b0218b08567d84d16aa473d4ed660db9bbf88a6..0f76b24cbb0f9c3b0032a148b2882c9cc7adb739 100644 (file)
@@ -560,12 +560,12 @@ class HashLibTestCase(unittest.TestCase):
 
         constructor(leaf_size=0)
         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)
 
         constructor(node_offset=0)
         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)
 
         constructor(
index d593495a999f20c350f67bc41aadd87e4bc6f535..445032dfb841f8951aaa4591af88a46c2ef9ab74 100644 (file)
@@ -159,9 +159,9 @@ class PollTests(unittest.TestCase):
             self.fail('Overflow must have occurred')
 
         # 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.modify, 1, -1)
+        self.assertRaises(ValueError, pollster.modify, 1, -1)
         self.assertRaises(OverflowError, pollster.modify, 1, 1 << 64)
 
     @cpython_only
diff --git a/Misc/NEWS.d/next/Tools-Demos/2018-07-24-00-11-44.bpo-20260.klmmqI.rst b/Misc/NEWS.d/next/Tools-Demos/2018-07-24-00-11-44.bpo-20260.klmmqI.rst
new file mode 100644 (file)
index 0000000..f8d0df0
--- /dev/null
@@ -0,0 +1 @@
+Argument Clinic now has non-bitwise unsigned int converters.
index 822b9f285cafd93b654284b3aa7383be4d0c9f97..92d7c5c3a2da076c339389f51c01f31424fce0cd 100644 (file)
@@ -75,8 +75,8 @@ _blake2b.blake2b.__new__ as py_blake2b_new
     person: Py_buffer = None
     fanout: int = 1
     depth: int = 1
-    leaf_size as leaf_size_obj: object = NULL
-    node_offset as node_offset_obj: object = NULL
+    leaf_size: unsigned_long = 0
+    node_offset: unsigned_long_long = 0
     node_depth: int = 0
     inner_size: int = 0
     last_node: bool = False
@@ -87,17 +87,14 @@ Return a new BLAKE2b hash object.
 static PyObject *
 py_blake2b_new_impl(PyTypeObject *type, PyObject *data, int digest_size,
                     Py_buffer *key, Py_buffer *salt, Py_buffer *person,
-                    int fanout, int depth, PyObject *leaf_size_obj,
-                    PyObject *node_offset_obj, int node_depth,
+                    int fanout, int depth, unsigned long leaf_size,
+                    unsigned long long node_offset, int node_depth,
                     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;
     Py_buffer buf;
 
-    unsigned long leaf_size = 0;
-    unsigned long long node_offset = 0;
-
     self = new_BLAKE2bObject(type);
     if (self == NULL) {
         goto error;
@@ -152,25 +149,13 @@ py_blake2b_new_impl(PyTypeObject *type, PyObject *data, int digest_size,
     }
     self->param.depth = (uint8_t)depth;
 
-    if (leaf_size_obj != NULL) {
-        leaf_size = PyLong_AsUnsignedLong(leaf_size_obj);
-        if (leaf_size == (unsigned long) -1 && PyErr_Occurred()) {
-            goto error;
-        }
-        if (leaf_size > 0xFFFFFFFFU) {
-            PyErr_SetString(PyExc_OverflowError, "leaf_size is too large");
-            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.
     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
     if (node_offset > 0xFFFFFFFFFFFFULL) {
         /* maximum 2**48 - 1 */
index 3b76c9cd89d73056e7c55435de1ce2255a7baf19..8c49082377f4a24ea2bf522a940e6f98f4439402 100644 (file)
@@ -75,8 +75,8 @@ _blake2s.blake2s.__new__ as py_blake2s_new
     person: Py_buffer = None
     fanout: int = 1
     depth: int = 1
-    leaf_size as leaf_size_obj: object = NULL
-    node_offset as node_offset_obj: object = NULL
+    leaf_size: unsigned_long = 0
+    node_offset: unsigned_long_long = 0
     node_depth: int = 0
     inner_size: int = 0
     last_node: bool = False
@@ -87,17 +87,14 @@ Return a new BLAKE2s hash object.
 static PyObject *
 py_blake2s_new_impl(PyTypeObject *type, PyObject *data, int digest_size,
                     Py_buffer *key, Py_buffer *salt, Py_buffer *person,
-                    int fanout, int depth, PyObject *leaf_size_obj,
-                    PyObject *node_offset_obj, int node_depth,
+                    int fanout, int depth, unsigned long leaf_size,
+                    unsigned long long node_offset, int node_depth,
                     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;
     Py_buffer buf;
 
-    unsigned long leaf_size = 0;
-    unsigned long long node_offset = 0;
-
     self = new_BLAKE2sObject(type);
     if (self == NULL) {
         goto error;
@@ -152,25 +149,13 @@ py_blake2s_new_impl(PyTypeObject *type, PyObject *data, int digest_size,
     }
     self->param.depth = (uint8_t)depth;
 
-    if (leaf_size_obj != NULL) {
-        leaf_size = PyLong_AsUnsignedLong(leaf_size_obj);
-        if (leaf_size == (unsigned long) -1 && PyErr_Occurred()) {
-            goto error;
-        }
-        if (leaf_size > 0xFFFFFFFFU) {
-            PyErr_SetString(PyExc_OverflowError, "leaf_size is too large");
-            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.
     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
     if (node_offset > 0xFFFFFFFFFFFFULL) {
         /* maximum 2**48 - 1 */
index 71c073aa36c6b1f27c446f622b8ef8a434dfa5d4..3cb70fb18f5f94a30d7b8752e5b06181d2db212f 100644 (file)
@@ -5,7 +5,7 @@ preserve
 PyDoc_STRVAR(py_blake2b_new__doc__,
 "blake2b(string=None, *, digest_size=_blake2b.blake2b.MAX_DIGEST_SIZE,\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"
 "--\n"
 "\n"
@@ -14,8 +14,8 @@ PyDoc_STRVAR(py_blake2b_new__doc__,
 static PyObject *
 py_blake2b_new_impl(PyTypeObject *type, PyObject *data, int digest_size,
                     Py_buffer *key, Py_buffer *salt, Py_buffer *person,
-                    int fanout, int depth, PyObject *leaf_size_obj,
-                    PyObject *node_offset_obj, int node_depth,
+                    int fanout, int depth, unsigned long leaf_size,
+                    unsigned long long node_offset, int node_depth,
                     int inner_size, int last_node);
 
 static PyObject *
@@ -23,7 +23,7 @@ py_blake2b_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
 {
     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 _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;
     int digest_size = BLAKE2B_OUTBYTES;
     Py_buffer key = {NULL, NULL};
@@ -31,17 +31,17 @@ py_blake2b_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
     Py_buffer person = {NULL, NULL};
     int fanout = 1;
     int depth = 1;
-    PyObject *leaf_size_obj = NULL;
-    PyObject *node_offset_obj = NULL;
+    unsigned long leaf_size = 0;
+    unsigned long long node_offset = 0;
     int node_depth = 0;
     int inner_size = 0;
     int last_node = 0;
 
     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;
     }
-    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:
     /* Cleanup for key */
@@ -122,4 +122,4 @@ _blake2b_blake2b_hexdigest(BLAKE2bObject *self, PyObject *Py_UNUSED(ignored))
 {
     return _blake2b_blake2b_hexdigest_impl(self);
 }
-/*[clinic end generated code: output=535a54852c98e51c input=a9049054013a1b77]*/
+/*[clinic end generated code: output=afc5c45dff0a24f9 input=a9049054013a1b77]*/
index ca908d393b5bb7b02f7bf4878382844c70ce8503..b444f7bb0d926a96f0aa449a238809bcd880d41b 100644 (file)
@@ -5,7 +5,7 @@ preserve
 PyDoc_STRVAR(py_blake2s_new__doc__,
 "blake2s(string=None, *, digest_size=_blake2s.blake2s.MAX_DIGEST_SIZE,\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"
 "--\n"
 "\n"
@@ -14,8 +14,8 @@ PyDoc_STRVAR(py_blake2s_new__doc__,
 static PyObject *
 py_blake2s_new_impl(PyTypeObject *type, PyObject *data, int digest_size,
                     Py_buffer *key, Py_buffer *salt, Py_buffer *person,
-                    int fanout, int depth, PyObject *leaf_size_obj,
-                    PyObject *node_offset_obj, int node_depth,
+                    int fanout, int depth, unsigned long leaf_size,
+                    unsigned long long node_offset, int node_depth,
                     int inner_size, int last_node);
 
 static PyObject *
@@ -23,7 +23,7 @@ py_blake2s_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
 {
     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 _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;
     int digest_size = BLAKE2S_OUTBYTES;
     Py_buffer key = {NULL, NULL};
@@ -31,17 +31,17 @@ py_blake2s_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
     Py_buffer person = {NULL, NULL};
     int fanout = 1;
     int depth = 1;
-    PyObject *leaf_size_obj = NULL;
-    PyObject *node_offset_obj = NULL;
+    unsigned long leaf_size = 0;
+    unsigned long long node_offset = 0;
     int node_depth = 0;
     int inner_size = 0;
     int last_node = 0;
 
     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;
     }
-    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:
     /* Cleanup for key */
@@ -122,4 +122,4 @@ _blake2s_blake2s_hexdigest(BLAKE2sObject *self, PyObject *Py_UNUSED(ignored))
 {
     return _blake2s_blake2s_hexdigest_impl(self);
 }
-/*[clinic end generated code: output=535ea7903f9ccf76 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=b705723d16f21f57 input=a9049054013a1b77]*/
index f66ceaab3ccb1815671634b0633d58f113832872..b87b3906f116d5e76fe2737e6ebee70cec269a63 100644 (file)
@@ -83,7 +83,7 @@ select_poll_register(pollObject *self, PyObject *const *args, Py_ssize_t nargs)
     unsigned short eventmask = POLLIN | POLLPRI | POLLOUT;
 
     if (!_PyArg_ParseStack(args, nargs, "O&|O&:register",
-        fildes_converter, &fd, ushort_converter, &eventmask)) {
+        fildes_converter, &fd, _PyLong_UnsignedShort_Converter, &eventmask)) {
         goto exit;
     }
     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;
 
     if (!_PyArg_ParseStack(args, nargs, "O&O&:modify",
-        fildes_converter, &fd, ushort_converter, &eventmask)) {
+        fildes_converter, &fd, _PyLong_UnsignedShort_Converter, &eventmask)) {
         goto exit;
     }
     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;
 
     if (!_PyArg_ParseStack(args, nargs, "O&|O&:register",
-        fildes_converter, &fd, ushort_converter, &eventmask)) {
+        fildes_converter, &fd, _PyLong_UnsignedShort_Converter, &eventmask)) {
         goto exit;
     }
     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;
 
     if (!_PyArg_ParseStack(args, nargs, "O&|O&:modify",
-        fildes_converter, &fd, ushort_converter, &eventmask)) {
+        fildes_converter, &fd, _PyLong_UnsignedShort_Converter, &eventmask)) {
         goto exit;
     }
     return_value = select_devpoll_modify_impl(self, fd, eventmask);
@@ -1047,4 +1047,4 @@ exit:
 #ifndef SELECT_KQUEUE_CONTROL_METHODDEF
     #define 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]*/
index 9ad6f8bdb7aee42b2c353a9faaf92614073a64c6..15aca2724a2ca01fb51ed5fff13346da8076caeb 100644 (file)
@@ -430,30 +430,12 @@ update_ufd_array(pollObject *self)
     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]
 select.poll.register
 
     fd: fildes
       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
     /
 
@@ -462,7 +444,7 @@ Register a file descriptor with the polling object.
 
 static PyObject *
 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;
     int err;
@@ -495,7 +477,7 @@ select.poll.modify
     fd: fildes
       either an integer, or an object with a fileno() method returning
       an int
-    eventmask: object(converter="ushort_converter", type="unsigned short")
+    eventmask: unsigned_short
       a bitmask describing the type of events to check for
     /
 
@@ -504,7 +486,7 @@ Modify an already registered file descriptor.
 
 static PyObject *
 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;
     int err;
@@ -832,7 +814,7 @@ select.devpoll.register
     fd: fildes
         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
     /
 
@@ -842,7 +824,7 @@ Register a file descriptor with the polling object.
 static PyObject *
 select_devpoll_register_impl(devpollObject *self, int fd,
                              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);
 }
@@ -853,7 +835,7 @@ select.devpoll.modify
     fd: fildes
         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
     /
 
@@ -863,7 +845,7 @@ Modify a possible already registered file descriptor.
 static PyObject *
 select_devpoll_modify_impl(devpollObject *self, int fd,
                            unsigned short eventmask)
-/*[clinic end generated code: output=bc2e6d23aaff98b4 input=f0d7de3889cc55fb]*/
+/*[clinic end generated code: output=bc2e6d23aaff98b4 input=48a820fc5967165d]*/
 static PyObject *
 devpoll_modify(devpollObject *self, PyObject *args)
 {
index ebf87a55b54bcd2f0923d2c7b09d80ad1a2f0b23..399d35427099017d25bb2bcc4d9836b10b3e4ac6 100644 (file)
@@ -1439,6 +1439,102 @@ PyLong_AsLongLongAndOverflow(PyObject *vv, int *overflow)
     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)                                \
     do {                                                \
         if (!PyLong_Check(v) || !PyLong_Check(w))       \
index e7c7eb47e818eeffee6a0f3bd29e0915bfc9d196..653afbea5fc94f8862f1f41d0f03c9675e32b3e6 100755 (executable)
@@ -2603,12 +2603,13 @@ class short_converter(CConverter):
 class unsigned_short_converter(CConverter):
     type = 'unsigned short'
     default_type = int
-    format_unit = 'H'
     c_ignored_default = "0"
 
     def converter_init(self, *, bitwise=False):
-        if not bitwise:
-            fail("Unsigned shorts must be bitwise (for now).")
+        if bitwise:
+            self.format_unit = 'H'
+        else:
+            self.converter = '_PyLong_UnsignedShort_Converter'
 
 @add_legacy_c_converter('C', accept={str})
 class int_converter(CConverter):
@@ -2628,12 +2629,13 @@ class int_converter(CConverter):
 class unsigned_int_converter(CConverter):
     type = 'unsigned int'
     default_type = int
-    format_unit = 'I'
     c_ignored_default = "0"
 
     def converter_init(self, *, bitwise=False):
-        if not bitwise:
-            fail("Unsigned ints must be bitwise (for now).")
+        if bitwise:
+            self.format_unit = 'I'
+        else:
+            self.converter = '_PyLong_UnsignedInt_Converter'
 
 class long_converter(CConverter):
     type = 'long'
@@ -2644,12 +2646,13 @@ class long_converter(CConverter):
 class unsigned_long_converter(CConverter):
     type = 'unsigned long'
     default_type = int
-    format_unit = 'k'
     c_ignored_default = "0"
 
     def converter_init(self, *, bitwise=False):
-        if not bitwise:
-            fail("Unsigned longs must be bitwise (for now).")
+        if bitwise:
+            self.format_unit = 'k'
+        else:
+            self.converter = '_PyLong_UnsignedLong_Converter'
 
 class long_long_converter(CConverter):
     type = 'long long'
@@ -2660,13 +2663,13 @@ class long_long_converter(CConverter):
 class unsigned_long_long_converter(CConverter):
     type = 'unsigned long long'
     default_type = int
-    format_unit = 'K'
     c_ignored_default = "0"
 
     def converter_init(self, *, bitwise=False):
-        if not bitwise:
-            fail("Unsigned long long must be bitwise (for now).")
-
+        if bitwise:
+            self.format_unit = 'K'
+        else:
+            self.converter = '_PyLong_UnsignedLongLong_Converter'
 
 class Py_ssize_t_converter(CConverter):
     type = 'Py_ssize_t'
@@ -2693,6 +2696,11 @@ class slice_index_converter(CConverter):
         else:
             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):
     type = 'float'