Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Doc/howto/clinic.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
8 changes: 8 additions & 0 deletions Include/longobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions Lib/test/test_hashlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -560,12 +560,12 @@ def check_blake2(self, constructor, salt_size, person_size, key_size,

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(
Expand Down
4 changes: 2 additions & 2 deletions Lib/test/test_poll.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,9 @@ def test_poll3(self):
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
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Argument Clinic now has non-bitwise unsigned int converters.
31 changes: 8 additions & 23 deletions Modules/_blake2/blake2b_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
Expand Down Expand Up @@ -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 */
Expand Down
31 changes: 8 additions & 23 deletions Modules/_blake2/blake2s_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
Expand Down Expand Up @@ -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 */
Expand Down
18 changes: 9 additions & 9 deletions Modules/_blake2/clinic/blake2b_impl.c.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -14,34 +14,34 @@ 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 *
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};
Py_buffer salt = {NULL, NULL};
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 */
Expand Down Expand Up @@ -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]*/
18 changes: 9 additions & 9 deletions Modules/_blake2/clinic/blake2s_impl.c.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -14,34 +14,34 @@ 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 *
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};
Py_buffer salt = {NULL, NULL};
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 */
Expand Down Expand Up @@ -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]*/
10 changes: 5 additions & 5 deletions Modules/clinic/selectmodule.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading