X Tutup
Skip to content

Commit 7cb7bcf

Browse files
bpo-20260: Implement non-bitwise unsigned int converters for Argument Clinic. (pythonGH-8434)
1 parent 323748a commit 7cb7bcf

File tree

13 files changed

+183
-112
lines changed

13 files changed

+183
-112
lines changed

Doc/howto/clinic.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -878,6 +878,12 @@ converter::
878878
Write a pickled representation of obj to the open file.
879879
[clinic start generated code]*/
880880

881+
One advantage of real converters is that they're more flexible than legacy
882+
converters. For example, the ``unsigned_int`` converter (and all the
883+
``unsigned_`` converters) can be specified without ``bitwise=True``. Their
884+
default behavior performs range checking on the value, and they won't accept
885+
negative numbers. You just can't do that with a legacy converter!
886+
881887
Argument Clinic will show you all the converters it has
882888
available. For each converter it'll show you all the parameters
883889
it accepts, along with the default value for each parameter.

Include/longobject.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,14 @@ PyAPI_FUNC(PyObject *) PyLong_GetInfo(void);
6565
# error "void* different in size from int, long and long long"
6666
#endif /* SIZEOF_VOID_P */
6767

68+
#ifndef Py_LIMITED_API
69+
PyAPI_FUNC(int) _PyLong_UnsignedShort_Converter(PyObject *, void *);
70+
PyAPI_FUNC(int) _PyLong_UnsignedInt_Converter(PyObject *, void *);
71+
PyAPI_FUNC(int) _PyLong_UnsignedLong_Converter(PyObject *, void *);
72+
PyAPI_FUNC(int) _PyLong_UnsignedLongLong_Converter(PyObject *, void *);
73+
PyAPI_FUNC(int) _PyLong_Size_t_Converter(PyObject *, void *);
74+
#endif
75+
6876
/* Used by Python/mystrtoul.c, _PyBytes_FromHex(),
6977
_PyBytes_DecodeEscapeRecode(), etc. */
7078
#ifndef Py_LIMITED_API

Lib/test/test_hashlib.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -560,12 +560,12 @@ def check_blake2(self, constructor, salt_size, person_size, key_size,
560560

561561
constructor(leaf_size=0)
562562
constructor(leaf_size=(1<<32)-1)
563-
self.assertRaises(OverflowError, constructor, leaf_size=-1)
563+
self.assertRaises(ValueError, constructor, leaf_size=-1)
564564
self.assertRaises(OverflowError, constructor, leaf_size=1<<32)
565565

566566
constructor(node_offset=0)
567567
constructor(node_offset=max_offset)
568-
self.assertRaises(OverflowError, constructor, node_offset=-1)
568+
self.assertRaises(ValueError, constructor, node_offset=-1)
569569
self.assertRaises(OverflowError, constructor, node_offset=max_offset+1)
570570

571571
constructor(

Lib/test/test_poll.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,9 +159,9 @@ def test_poll3(self):
159159
self.fail('Overflow must have occurred')
160160

161161
# Issues #15989, #17919
162-
self.assertRaises(OverflowError, pollster.register, 0, -1)
162+
self.assertRaises(ValueError, pollster.register, 0, -1)
163163
self.assertRaises(OverflowError, pollster.register, 0, 1 << 64)
164-
self.assertRaises(OverflowError, pollster.modify, 1, -1)
164+
self.assertRaises(ValueError, pollster.modify, 1, -1)
165165
self.assertRaises(OverflowError, pollster.modify, 1, 1 << 64)
166166

167167
@cpython_only
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Argument Clinic now has non-bitwise unsigned int converters.

Modules/_blake2/blake2b_impl.c

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ _blake2b.blake2b.__new__ as py_blake2b_new
7575
person: Py_buffer = None
7676
fanout: int = 1
7777
depth: int = 1
78-
leaf_size as leaf_size_obj: object = NULL
79-
node_offset as node_offset_obj: object = NULL
78+
leaf_size: unsigned_long = 0
79+
node_offset: unsigned_long_long = 0
8080
node_depth: int = 0
8181
inner_size: int = 0
8282
last_node: bool = False
@@ -87,17 +87,14 @@ Return a new BLAKE2b hash object.
8787
static PyObject *
8888
py_blake2b_new_impl(PyTypeObject *type, PyObject *data, int digest_size,
8989
Py_buffer *key, Py_buffer *salt, Py_buffer *person,
90-
int fanout, int depth, PyObject *leaf_size_obj,
91-
PyObject *node_offset_obj, int node_depth,
90+
int fanout, int depth, unsigned long leaf_size,
91+
unsigned long long node_offset, int node_depth,
9292
int inner_size, int last_node)
93-
/*[clinic end generated code: output=7506d8d890e5f13b input=e41548dfa0866031]*/
93+
/*[clinic end generated code: output=65e732c66c2297a0 input=75ab5196b695adee]*/
9494
{
9595
BLAKE2bObject *self = NULL;
9696
Py_buffer buf;
9797

98-
unsigned long leaf_size = 0;
99-
unsigned long long node_offset = 0;
100-
10198
self = new_BLAKE2bObject(type);
10299
if (self == NULL) {
103100
goto error;
@@ -152,25 +149,13 @@ py_blake2b_new_impl(PyTypeObject *type, PyObject *data, int digest_size,
152149
}
153150
self->param.depth = (uint8_t)depth;
154151

155-
if (leaf_size_obj != NULL) {
156-
leaf_size = PyLong_AsUnsignedLong(leaf_size_obj);
157-
if (leaf_size == (unsigned long) -1 && PyErr_Occurred()) {
158-
goto error;
159-
}
160-
if (leaf_size > 0xFFFFFFFFU) {
161-
PyErr_SetString(PyExc_OverflowError, "leaf_size is too large");
162-
goto error;
163-
}
152+
if (leaf_size > 0xFFFFFFFFU) {
153+
PyErr_SetString(PyExc_OverflowError, "leaf_size is too large");
154+
goto error;
164155
}
165156
// NB: Simple assignment here would be incorrect on big endian platforms.
166157
store32(&(self->param.leaf_length), leaf_size);
167158

168-
if (node_offset_obj != NULL) {
169-
node_offset = PyLong_AsUnsignedLongLong(node_offset_obj);
170-
if (node_offset == (unsigned long long) -1 && PyErr_Occurred()) {
171-
goto error;
172-
}
173-
}
174159
#ifdef HAVE_BLAKE2S
175160
if (node_offset > 0xFFFFFFFFFFFFULL) {
176161
/* maximum 2**48 - 1 */

Modules/_blake2/blake2s_impl.c

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ _blake2s.blake2s.__new__ as py_blake2s_new
7575
person: Py_buffer = None
7676
fanout: int = 1
7777
depth: int = 1
78-
leaf_size as leaf_size_obj: object = NULL
79-
node_offset as node_offset_obj: object = NULL
78+
leaf_size: unsigned_long = 0
79+
node_offset: unsigned_long_long = 0
8080
node_depth: int = 0
8181
inner_size: int = 0
8282
last_node: bool = False
@@ -87,17 +87,14 @@ Return a new BLAKE2s hash object.
8787
static PyObject *
8888
py_blake2s_new_impl(PyTypeObject *type, PyObject *data, int digest_size,
8989
Py_buffer *key, Py_buffer *salt, Py_buffer *person,
90-
int fanout, int depth, PyObject *leaf_size_obj,
91-
PyObject *node_offset_obj, int node_depth,
90+
int fanout, int depth, unsigned long leaf_size,
91+
unsigned long long node_offset, int node_depth,
9292
int inner_size, int last_node)
93-
/*[clinic end generated code: output=fe060b258a8cbfc6 input=458cfdcb3d0d47ff]*/
93+
/*[clinic end generated code: output=b95806be0514dcf7 input=f18d6efd9b9a1271]*/
9494
{
9595
BLAKE2sObject *self = NULL;
9696
Py_buffer buf;
9797

98-
unsigned long leaf_size = 0;
99-
unsigned long long node_offset = 0;
100-
10198
self = new_BLAKE2sObject(type);
10299
if (self == NULL) {
103100
goto error;
@@ -152,25 +149,13 @@ py_blake2s_new_impl(PyTypeObject *type, PyObject *data, int digest_size,
152149
}
153150
self->param.depth = (uint8_t)depth;
154151

155-
if (leaf_size_obj != NULL) {
156-
leaf_size = PyLong_AsUnsignedLong(leaf_size_obj);
157-
if (leaf_size == (unsigned long) -1 && PyErr_Occurred()) {
158-
goto error;
159-
}
160-
if (leaf_size > 0xFFFFFFFFU) {
161-
PyErr_SetString(PyExc_OverflowError, "leaf_size is too large");
162-
goto error;
163-
}
152+
if (leaf_size > 0xFFFFFFFFU) {
153+
PyErr_SetString(PyExc_OverflowError, "leaf_size is too large");
154+
goto error;
164155
}
165156
// NB: Simple assignment here would be incorrect on big endian platforms.
166157
store32(&(self->param.leaf_length), leaf_size);
167158

168-
if (node_offset_obj != NULL) {
169-
node_offset = PyLong_AsUnsignedLongLong(node_offset_obj);
170-
if (node_offset == (unsigned long long) -1 && PyErr_Occurred()) {
171-
goto error;
172-
}
173-
}
174159
#ifdef HAVE_BLAKE2S
175160
if (node_offset > 0xFFFFFFFFFFFFULL) {
176161
/* maximum 2**48 - 1 */

Modules/_blake2/clinic/blake2b_impl.c.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ preserve
55
PyDoc_STRVAR(py_blake2b_new__doc__,
66
"blake2b(string=None, *, digest_size=_blake2b.blake2b.MAX_DIGEST_SIZE,\n"
77
" key=None, salt=None, person=None, fanout=1, depth=1,\n"
8-
" leaf_size=None, node_offset=None, node_depth=0, inner_size=0,\n"
8+
" leaf_size=0, node_offset=0, node_depth=0, inner_size=0,\n"
99
" last_node=False)\n"
1010
"--\n"
1111
"\n"
@@ -14,34 +14,34 @@ PyDoc_STRVAR(py_blake2b_new__doc__,
1414
static PyObject *
1515
py_blake2b_new_impl(PyTypeObject *type, PyObject *data, int digest_size,
1616
Py_buffer *key, Py_buffer *salt, Py_buffer *person,
17-
int fanout, int depth, PyObject *leaf_size_obj,
18-
PyObject *node_offset_obj, int node_depth,
17+
int fanout, int depth, unsigned long leaf_size,
18+
unsigned long long node_offset, int node_depth,
1919
int inner_size, int last_node);
2020

2121
static PyObject *
2222
py_blake2b_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2323
{
2424
PyObject *return_value = NULL;
2525
static const char * const _keywords[] = {"string", "digest_size", "key", "salt", "person", "fanout", "depth", "leaf_size", "node_offset", "node_depth", "inner_size", "last_node", NULL};
26-
static _PyArg_Parser _parser = {"|O$iy*y*y*iiOOiip:blake2b", _keywords, 0};
26+
static _PyArg_Parser _parser = {"|O$iy*y*y*iiO&O&iip:blake2b", _keywords, 0};
2727
PyObject *data = NULL;
2828
int digest_size = BLAKE2B_OUTBYTES;
2929
Py_buffer key = {NULL, NULL};
3030
Py_buffer salt = {NULL, NULL};
3131
Py_buffer person = {NULL, NULL};
3232
int fanout = 1;
3333
int depth = 1;
34-
PyObject *leaf_size_obj = NULL;
35-
PyObject *node_offset_obj = NULL;
34+
unsigned long leaf_size = 0;
35+
unsigned long long node_offset = 0;
3636
int node_depth = 0;
3737
int inner_size = 0;
3838
int last_node = 0;
3939

4040
if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser,
41-
&data, &digest_size, &key, &salt, &person, &fanout, &depth, &leaf_size_obj, &node_offset_obj, &node_depth, &inner_size, &last_node)) {
41+
&data, &digest_size, &key, &salt, &person, &fanout, &depth, _PyLong_UnsignedLong_Converter, &leaf_size, _PyLong_UnsignedLongLong_Converter, &node_offset, &node_depth, &inner_size, &last_node)) {
4242
goto exit;
4343
}
44-
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);
44+
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);
4545

4646
exit:
4747
/* Cleanup for key */
@@ -122,4 +122,4 @@ _blake2b_blake2b_hexdigest(BLAKE2bObject *self, PyObject *Py_UNUSED(ignored))
122122
{
123123
return _blake2b_blake2b_hexdigest_impl(self);
124124
}
125-
/*[clinic end generated code: output=535a54852c98e51c input=a9049054013a1b77]*/
125+
/*[clinic end generated code: output=afc5c45dff0a24f9 input=a9049054013a1b77]*/

Modules/_blake2/clinic/blake2s_impl.c.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ preserve
55
PyDoc_STRVAR(py_blake2s_new__doc__,
66
"blake2s(string=None, *, digest_size=_blake2s.blake2s.MAX_DIGEST_SIZE,\n"
77
" key=None, salt=None, person=None, fanout=1, depth=1,\n"
8-
" leaf_size=None, node_offset=None, node_depth=0, inner_size=0,\n"
8+
" leaf_size=0, node_offset=0, node_depth=0, inner_size=0,\n"
99
" last_node=False)\n"
1010
"--\n"
1111
"\n"
@@ -14,34 +14,34 @@ PyDoc_STRVAR(py_blake2s_new__doc__,
1414
static PyObject *
1515
py_blake2s_new_impl(PyTypeObject *type, PyObject *data, int digest_size,
1616
Py_buffer *key, Py_buffer *salt, Py_buffer *person,
17-
int fanout, int depth, PyObject *leaf_size_obj,
18-
PyObject *node_offset_obj, int node_depth,
17+
int fanout, int depth, unsigned long leaf_size,
18+
unsigned long long node_offset, int node_depth,
1919
int inner_size, int last_node);
2020

2121
static PyObject *
2222
py_blake2s_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2323
{
2424
PyObject *return_value = NULL;
2525
static const char * const _keywords[] = {"string", "digest_size", "key", "salt", "person", "fanout", "depth", "leaf_size", "node_offset", "node_depth", "inner_size", "last_node", NULL};
26-
static _PyArg_Parser _parser = {"|O$iy*y*y*iiOOiip:blake2s", _keywords, 0};
26+
static _PyArg_Parser _parser = {"|O$iy*y*y*iiO&O&iip:blake2s", _keywords, 0};
2727
PyObject *data = NULL;
2828
int digest_size = BLAKE2S_OUTBYTES;
2929
Py_buffer key = {NULL, NULL};
3030
Py_buffer salt = {NULL, NULL};
3131
Py_buffer person = {NULL, NULL};
3232
int fanout = 1;
3333
int depth = 1;
34-
PyObject *leaf_size_obj = NULL;
35-
PyObject *node_offset_obj = NULL;
34+
unsigned long leaf_size = 0;
35+
unsigned long long node_offset = 0;
3636
int node_depth = 0;
3737
int inner_size = 0;
3838
int last_node = 0;
3939

4040
if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser,
41-
&data, &digest_size, &key, &salt, &person, &fanout, &depth, &leaf_size_obj, &node_offset_obj, &node_depth, &inner_size, &last_node)) {
41+
&data, &digest_size, &key, &salt, &person, &fanout, &depth, _PyLong_UnsignedLong_Converter, &leaf_size, _PyLong_UnsignedLongLong_Converter, &node_offset, &node_depth, &inner_size, &last_node)) {
4242
goto exit;
4343
}
44-
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);
44+
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);
4545

4646
exit:
4747
/* Cleanup for key */
@@ -122,4 +122,4 @@ _blake2s_blake2s_hexdigest(BLAKE2sObject *self, PyObject *Py_UNUSED(ignored))
122122
{
123123
return _blake2s_blake2s_hexdigest_impl(self);
124124
}
125-
/*[clinic end generated code: output=535ea7903f9ccf76 input=a9049054013a1b77]*/
125+
/*[clinic end generated code: output=b705723d16f21f57 input=a9049054013a1b77]*/

Modules/clinic/selectmodule.c.h

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)
X Tutup