Skip to content

Commit 7f3978e

Browse files
committed
Issue #22615: Argument Clinic now supports the "type" argument for the
int converter. This permits using the int converter with enums and typedefs.
1 parent e7f56fd commit 7f3978e

5 files changed

Lines changed: 68 additions & 59 deletions

File tree

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1263,6 +1263,10 @@ Tests
12631263
Tools/Demos
12641264
-----------
12651265

1266+
- Issue #22615: Argument Clinic now supports the "type" argument for the
1267+
int converter. This permits using the int converter with enums and
1268+
typedefs.
1269+
12661270
- Issue #20076: The makelocalealias.py script no longer ignores UTF-8 mapping.
12671271

12681272
- Issue #20079: The makelocalealias.py script now can parse the SUPPORTED file

Modules/arraymodule.c

Lines changed: 57 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,50 @@ static PyTypeObject PyArrayIter_Type;
5959

6060
#define PyArrayIter_Check(op) PyObject_TypeCheck(op, &PyArrayIter_Type)
6161

62-
/* Must come after arrayobject and arrayiterobject definitions. */
62+
enum machine_format_code {
63+
UNKNOWN_FORMAT = -1,
64+
/* UNKNOWN_FORMAT is used to indicate that the machine format for an
65+
* array type code cannot be interpreted. When this occurs, a list of
66+
* Python objects is used to represent the content of the array
67+
* instead of using the memory content of the array directly. In that
68+
* case, the array_reconstructor mechanism is bypassed completely, and
69+
* the standard array constructor is used instead.
70+
*
71+
* This is will most likely occur when the machine doesn't use IEEE
72+
* floating-point numbers.
73+
*/
74+
75+
UNSIGNED_INT8 = 0,
76+
SIGNED_INT8 = 1,
77+
UNSIGNED_INT16_LE = 2,
78+
UNSIGNED_INT16_BE = 3,
79+
SIGNED_INT16_LE = 4,
80+
SIGNED_INT16_BE = 5,
81+
UNSIGNED_INT32_LE = 6,
82+
UNSIGNED_INT32_BE = 7,
83+
SIGNED_INT32_LE = 8,
84+
SIGNED_INT32_BE = 9,
85+
UNSIGNED_INT64_LE = 10,
86+
UNSIGNED_INT64_BE = 11,
87+
SIGNED_INT64_LE = 12,
88+
SIGNED_INT64_BE = 13,
89+
IEEE_754_FLOAT_LE = 14,
90+
IEEE_754_FLOAT_BE = 15,
91+
IEEE_754_DOUBLE_LE = 16,
92+
IEEE_754_DOUBLE_BE = 17,
93+
UTF16_LE = 18,
94+
UTF16_BE = 19,
95+
UTF32_LE = 20,
96+
UTF32_BE = 21
97+
};
98+
#define MACHINE_FORMAT_CODE_MIN 0
99+
#define MACHINE_FORMAT_CODE_MAX 21
100+
101+
102+
/*
103+
* Must come after arrayobject, arrayiterobject,
104+
* and enum machine_code_type definitions.
105+
*/
63106
#include "clinic/arraymodule.c.h"
64107

65108
#define array_Check(op) PyObject_TypeCheck(op, &Arraytype)
@@ -1712,45 +1755,6 @@ array_array___sizeof___impl(arrayobject *self)
17121755

17131756
/*********************** Pickling support ************************/
17141757

1715-
enum machine_format_code {
1716-
UNKNOWN_FORMAT = -1,
1717-
/* UNKNOWN_FORMAT is used to indicate that the machine format for an
1718-
* array type code cannot be interpreted. When this occurs, a list of
1719-
* Python objects is used to represent the content of the array
1720-
* instead of using the memory content of the array directly. In that
1721-
* case, the array_reconstructor mechanism is bypassed completely, and
1722-
* the standard array constructor is used instead.
1723-
*
1724-
* This is will most likely occur when the machine doesn't use IEEE
1725-
* floating-point numbers.
1726-
*/
1727-
1728-
UNSIGNED_INT8 = 0,
1729-
SIGNED_INT8 = 1,
1730-
UNSIGNED_INT16_LE = 2,
1731-
UNSIGNED_INT16_BE = 3,
1732-
SIGNED_INT16_LE = 4,
1733-
SIGNED_INT16_BE = 5,
1734-
UNSIGNED_INT32_LE = 6,
1735-
UNSIGNED_INT32_BE = 7,
1736-
SIGNED_INT32_LE = 8,
1737-
SIGNED_INT32_BE = 9,
1738-
UNSIGNED_INT64_LE = 10,
1739-
UNSIGNED_INT64_BE = 11,
1740-
SIGNED_INT64_LE = 12,
1741-
SIGNED_INT64_BE = 13,
1742-
IEEE_754_FLOAT_LE = 14,
1743-
IEEE_754_FLOAT_BE = 15,
1744-
IEEE_754_DOUBLE_LE = 16,
1745-
IEEE_754_DOUBLE_BE = 17,
1746-
UTF16_LE = 18,
1747-
UTF16_BE = 19,
1748-
UTF32_LE = 20,
1749-
UTF32_BE = 21
1750-
};
1751-
#define MACHINE_FORMAT_CODE_MIN 0
1752-
#define MACHINE_FORMAT_CODE_MAX 21
1753-
17541758
static const struct mformatdescr {
17551759
size_t size;
17561760
int is_signed;
@@ -1939,13 +1943,12 @@ Internal. Used for pickling support.
19391943
[clinic start generated code]*/
19401944

19411945
static PyObject *
1942-
array__array_reconstructor_impl(PyModuleDef *module, PyTypeObject *arraytype, int typecode, int mformat_code, PyObject *items)
1943-
/*[clinic end generated code: output=a0a4ab61c2fbc17a input=450d59a5373c4eea]*/
1946+
array__array_reconstructor_impl(PyModuleDef *module, PyTypeObject *arraytype, int typecode, enum machine_format_code mformat_code, PyObject *items)
1947+
/*[clinic end generated code: output=c51081ec91caf7e9 input=f72492708c0a1d50]*/
19441948
{
19451949
PyObject *converted_items;
19461950
PyObject *result;
19471951
struct arraydescr *descr;
1948-
enum machine_format_code mformat_code_enum = mformat_code;
19491952

19501953
if (!PyType_Check(arraytype)) {
19511954
PyErr_Format(PyExc_TypeError,
@@ -1968,8 +1971,8 @@ array__array_reconstructor_impl(PyModuleDef *module, PyTypeObject *arraytype, in
19681971
"second argument must be a valid type code");
19691972
return NULL;
19701973
}
1971-
if (mformat_code_enum < MACHINE_FORMAT_CODE_MIN ||
1972-
mformat_code_enum > MACHINE_FORMAT_CODE_MAX) {
1974+
if (mformat_code < MACHINE_FORMAT_CODE_MIN ||
1975+
mformat_code > MACHINE_FORMAT_CODE_MAX) {
19731976
PyErr_SetString(PyExc_ValueError,
19741977
"third argument must be a valid machine format code.");
19751978
return NULL;
@@ -1982,8 +1985,8 @@ array__array_reconstructor_impl(PyModuleDef *module, PyTypeObject *arraytype, in
19821985
}
19831986

19841987
/* Fast path: No decoding has to be done. */
1985-
if (mformat_code_enum == typecode_to_mformat_code((char)typecode) ||
1986-
mformat_code_enum == UNKNOWN_FORMAT) {
1988+
if (mformat_code == typecode_to_mformat_code((char)typecode) ||
1989+
mformat_code == UNKNOWN_FORMAT) {
19871990
return make_array(arraytype, (char)typecode, items);
19881991
}
19891992

@@ -1992,16 +1995,16 @@ array__array_reconstructor_impl(PyModuleDef *module, PyTypeObject *arraytype, in
19921995
* object is architecturally different from the one that pickled the
19931996
* array.
19941997
*/
1995-
if (Py_SIZE(items) % mformat_descriptors[mformat_code_enum].size != 0) {
1998+
if (Py_SIZE(items) % mformat_descriptors[mformat_code].size != 0) {
19961999
PyErr_SetString(PyExc_ValueError,
19972000
"string length not a multiple of item size");
19982001
return NULL;
19992002
}
2000-
switch (mformat_code_enum) {
2003+
switch (mformat_code) {
20012004
case IEEE_754_FLOAT_LE:
20022005
case IEEE_754_FLOAT_BE: {
20032006
int i;
2004-
int le = (mformat_code_enum == IEEE_754_FLOAT_LE) ? 1 : 0;
2007+
int le = (mformat_code == IEEE_754_FLOAT_LE) ? 1 : 0;
20052008
Py_ssize_t itemcount = Py_SIZE(items) / 4;
20062009
const unsigned char *memstr =
20072010
(unsigned char *)PyBytes_AS_STRING(items);
@@ -2023,7 +2026,7 @@ array__array_reconstructor_impl(PyModuleDef *module, PyTypeObject *arraytype, in
20232026
case IEEE_754_DOUBLE_LE:
20242027
case IEEE_754_DOUBLE_BE: {
20252028
int i;
2026-
int le = (mformat_code_enum == IEEE_754_DOUBLE_LE) ? 1 : 0;
2029+
int le = (mformat_code == IEEE_754_DOUBLE_LE) ? 1 : 0;
20272030
Py_ssize_t itemcount = Py_SIZE(items) / 8;
20282031
const unsigned char *memstr =
20292032
(unsigned char *)PyBytes_AS_STRING(items);
@@ -2044,7 +2047,7 @@ array__array_reconstructor_impl(PyModuleDef *module, PyTypeObject *arraytype, in
20442047
}
20452048
case UTF16_LE:
20462049
case UTF16_BE: {
2047-
int byteorder = (mformat_code_enum == UTF16_LE) ? -1 : 1;
2050+
int byteorder = (mformat_code == UTF16_LE) ? -1 : 1;
20482051
converted_items = PyUnicode_DecodeUTF16(
20492052
PyBytes_AS_STRING(items), Py_SIZE(items),
20502053
"strict", &byteorder);
@@ -2054,7 +2057,7 @@ array__array_reconstructor_impl(PyModuleDef *module, PyTypeObject *arraytype, in
20542057
}
20552058
case UTF32_LE:
20562059
case UTF32_BE: {
2057-
int byteorder = (mformat_code_enum == UTF32_LE) ? -1 : 1;
2060+
int byteorder = (mformat_code == UTF32_LE) ? -1 : 1;
20582061
converted_items = PyUnicode_DecodeUTF32(
20592062
PyBytes_AS_STRING(items), Py_SIZE(items),
20602063
"strict", &byteorder);
@@ -2079,7 +2082,7 @@ array__array_reconstructor_impl(PyModuleDef *module, PyTypeObject *arraytype, in
20792082
case SIGNED_INT64_BE: {
20802083
int i;
20812084
const struct mformatdescr mf_descr =
2082-
mformat_descriptors[mformat_code_enum];
2085+
mformat_descriptors[mformat_code];
20832086
Py_ssize_t itemcount = Py_SIZE(items) / mf_descr.size;
20842087
const unsigned char *memstr =
20852088
(unsigned char *)PyBytes_AS_STRING(items);

Modules/clinic/arraymodule.c.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -446,15 +446,15 @@ PyDoc_STRVAR(array__array_reconstructor__doc__,
446446
{"_array_reconstructor", (PyCFunction)array__array_reconstructor, METH_VARARGS, array__array_reconstructor__doc__},
447447

448448
static PyObject *
449-
array__array_reconstructor_impl(PyModuleDef *module, PyTypeObject *arraytype, int typecode, int mformat_code, PyObject *items);
449+
array__array_reconstructor_impl(PyModuleDef *module, PyTypeObject *arraytype, int typecode, enum machine_format_code mformat_code, PyObject *items);
450450

451451
static PyObject *
452452
array__array_reconstructor(PyModuleDef *module, PyObject *args)
453453
{
454454
PyObject *return_value = NULL;
455455
PyTypeObject *arraytype;
456456
int typecode;
457-
int mformat_code;
457+
enum machine_format_code mformat_code;
458458
PyObject *items;
459459

460460
if (!PyArg_ParseTuple(args,
@@ -502,4 +502,4 @@ PyDoc_STRVAR(array_arrayiterator___setstate____doc__,
502502

503503
#define ARRAY_ARRAYITERATOR___SETSTATE___METHODDEF \
504504
{"__setstate__", (PyCFunction)array_arrayiterator___setstate__, METH_O, array_arrayiterator___setstate____doc__},
505-
/*[clinic end generated code: output=dff8eae01f0ab208 input=a9049054013a1b77]*/
505+
/*[clinic end generated code: output=e1deb61c6a3bc8c8 input=a9049054013a1b77]*/

Objects/bytesobject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1819,7 +1819,7 @@ bytes_translate(PyBytesObject *self, PyObject *args)
18191819

18201820
static PyObject *
18211821
bytes_translate_impl(PyBytesObject *self, PyObject *table, int group_right_1, PyObject *deletechars)
1822-
/*[clinic end generated code: output=f0f29a57f41df5d8 input=a90fad893c3c88d7]*/
1822+
/*[clinic end generated code: output=f0f29a57f41df5d8 input=d8fa5519d7cc4be7]*/
18231823
{
18241824
char *input, *output;
18251825
const char *table_chars;

Tools/clinic/clinic.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2426,11 +2426,13 @@ class int_converter(CConverter):
24262426
format_unit = 'i'
24272427
c_ignored_default = "0"
24282428

2429-
def converter_init(self, *, types='int'):
2429+
def converter_init(self, *, types='int', type=None):
24302430
if types == 'str':
24312431
self.format_unit = 'C'
24322432
elif types != 'int':
24332433
fail("int_converter: illegal 'types' argument")
2434+
if type != None:
2435+
self.type = type
24342436

24352437
class unsigned_int_converter(CConverter):
24362438
type = 'unsigned int'

0 commit comments

Comments
 (0)