From dfbeb160de829d16d3668dec5bc902a31ad25835 Mon Sep 17 00:00:00 2001 From: Larry Hastings Date: Mon, 13 Oct 2014 10:39:41 +0100 Subject: Issue #22615: Argument Clinic now supports the "type" argument for the int converter. This permits using the int converter with enums and typedefs. --- Misc/NEWS | 4 ++ Modules/arraymodule.c | 111 +++++++++++++++++++++-------------------- Modules/clinic/arraymodule.c.h | 6 +-- Objects/bytesobject.c | 2 +- Tools/clinic/clinic.py | 4 +- 5 files changed, 68 insertions(+), 59 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS index 806e029..1453637 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -1263,6 +1263,10 @@ Tests Tools/Demos ----------- +- Issue #22615: Argument Clinic now supports the "type" argument for the + int converter. This permits using the int converter with enums and + typedefs. + - Issue #20076: The makelocalealias.py script no longer ignores UTF-8 mapping. - Issue #20079: The makelocalealias.py script now can parse the SUPPORTED file diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index f15571d..b7ef702 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -59,7 +59,50 @@ static PyTypeObject PyArrayIter_Type; #define PyArrayIter_Check(op) PyObject_TypeCheck(op, &PyArrayIter_Type) -/* Must come after arrayobject and arrayiterobject definitions. */ +enum machine_format_code { + UNKNOWN_FORMAT = -1, + /* UNKNOWN_FORMAT is used to indicate that the machine format for an + * array type code cannot be interpreted. When this occurs, a list of + * Python objects is used to represent the content of the array + * instead of using the memory content of the array directly. In that + * case, the array_reconstructor mechanism is bypassed completely, and + * the standard array constructor is used instead. + * + * This is will most likely occur when the machine doesn't use IEEE + * floating-point numbers. + */ + + UNSIGNED_INT8 = 0, + SIGNED_INT8 = 1, + UNSIGNED_INT16_LE = 2, + UNSIGNED_INT16_BE = 3, + SIGNED_INT16_LE = 4, + SIGNED_INT16_BE = 5, + UNSIGNED_INT32_LE = 6, + UNSIGNED_INT32_BE = 7, + SIGNED_INT32_LE = 8, + SIGNED_INT32_BE = 9, + UNSIGNED_INT64_LE = 10, + UNSIGNED_INT64_BE = 11, + SIGNED_INT64_LE = 12, + SIGNED_INT64_BE = 13, + IEEE_754_FLOAT_LE = 14, + IEEE_754_FLOAT_BE = 15, + IEEE_754_DOUBLE_LE = 16, + IEEE_754_DOUBLE_BE = 17, + UTF16_LE = 18, + UTF16_BE = 19, + UTF32_LE = 20, + UTF32_BE = 21 +}; +#define MACHINE_FORMAT_CODE_MIN 0 +#define MACHINE_FORMAT_CODE_MAX 21 + + +/* + * Must come after arrayobject, arrayiterobject, + * and enum machine_code_type definitions. + */ #include "clinic/arraymodule.c.h" #define array_Check(op) PyObject_TypeCheck(op, &Arraytype) @@ -1712,45 +1755,6 @@ array_array___sizeof___impl(arrayobject *self) /*********************** Pickling support ************************/ -enum machine_format_code { - UNKNOWN_FORMAT = -1, - /* UNKNOWN_FORMAT is used to indicate that the machine format for an - * array type code cannot be interpreted. When this occurs, a list of - * Python objects is used to represent the content of the array - * instead of using the memory content of the array directly. In that - * case, the array_reconstructor mechanism is bypassed completely, and - * the standard array constructor is used instead. - * - * This is will most likely occur when the machine doesn't use IEEE - * floating-point numbers. - */ - - UNSIGNED_INT8 = 0, - SIGNED_INT8 = 1, - UNSIGNED_INT16_LE = 2, - UNSIGNED_INT16_BE = 3, - SIGNED_INT16_LE = 4, - SIGNED_INT16_BE = 5, - UNSIGNED_INT32_LE = 6, - UNSIGNED_INT32_BE = 7, - SIGNED_INT32_LE = 8, - SIGNED_INT32_BE = 9, - UNSIGNED_INT64_LE = 10, - UNSIGNED_INT64_BE = 11, - SIGNED_INT64_LE = 12, - SIGNED_INT64_BE = 13, - IEEE_754_FLOAT_LE = 14, - IEEE_754_FLOAT_BE = 15, - IEEE_754_DOUBLE_LE = 16, - IEEE_754_DOUBLE_BE = 17, - UTF16_LE = 18, - UTF16_BE = 19, - UTF32_LE = 20, - UTF32_BE = 21 -}; -#define MACHINE_FORMAT_CODE_MIN 0 -#define MACHINE_FORMAT_CODE_MAX 21 - static const struct mformatdescr { size_t size; int is_signed; @@ -1939,13 +1943,12 @@ Internal. Used for pickling support. [clinic start generated code]*/ static PyObject * -array__array_reconstructor_impl(PyModuleDef *module, PyTypeObject *arraytype, int typecode, int mformat_code, PyObject *items) -/*[clinic end generated code: output=a0a4ab61c2fbc17a input=450d59a5373c4eea]*/ +array__array_reconstructor_impl(PyModuleDef *module, PyTypeObject *arraytype, int typecode, enum machine_format_code mformat_code, PyObject *items) +/*[clinic end generated code: output=c51081ec91caf7e9 input=f72492708c0a1d50]*/ { PyObject *converted_items; PyObject *result; struct arraydescr *descr; - enum machine_format_code mformat_code_enum = mformat_code; if (!PyType_Check(arraytype)) { PyErr_Format(PyExc_TypeError, @@ -1968,8 +1971,8 @@ array__array_reconstructor_impl(PyModuleDef *module, PyTypeObject *arraytype, in "second argument must be a valid type code"); return NULL; } - if (mformat_code_enum < MACHINE_FORMAT_CODE_MIN || - mformat_code_enum > MACHINE_FORMAT_CODE_MAX) { + if (mformat_code < MACHINE_FORMAT_CODE_MIN || + mformat_code > MACHINE_FORMAT_CODE_MAX) { PyErr_SetString(PyExc_ValueError, "third argument must be a valid machine format code."); return NULL; @@ -1982,8 +1985,8 @@ array__array_reconstructor_impl(PyModuleDef *module, PyTypeObject *arraytype, in } /* Fast path: No decoding has to be done. */ - if (mformat_code_enum == typecode_to_mformat_code((char)typecode) || - mformat_code_enum == UNKNOWN_FORMAT) { + if (mformat_code == typecode_to_mformat_code((char)typecode) || + mformat_code == UNKNOWN_FORMAT) { return make_array(arraytype, (char)typecode, items); } @@ -1992,16 +1995,16 @@ array__array_reconstructor_impl(PyModuleDef *module, PyTypeObject *arraytype, in * object is architecturally different from the one that pickled the * array. */ - if (Py_SIZE(items) % mformat_descriptors[mformat_code_enum].size != 0) { + if (Py_SIZE(items) % mformat_descriptors[mformat_code].size != 0) { PyErr_SetString(PyExc_ValueError, "string length not a multiple of item size"); return NULL; } - switch (mformat_code_enum) { + switch (mformat_code) { case IEEE_754_FLOAT_LE: case IEEE_754_FLOAT_BE: { int i; - int le = (mformat_code_enum == IEEE_754_FLOAT_LE) ? 1 : 0; + int le = (mformat_code == IEEE_754_FLOAT_LE) ? 1 : 0; Py_ssize_t itemcount = Py_SIZE(items) / 4; const unsigned char *memstr = (unsigned char *)PyBytes_AS_STRING(items); @@ -2023,7 +2026,7 @@ array__array_reconstructor_impl(PyModuleDef *module, PyTypeObject *arraytype, in case IEEE_754_DOUBLE_LE: case IEEE_754_DOUBLE_BE: { int i; - int le = (mformat_code_enum == IEEE_754_DOUBLE_LE) ? 1 : 0; + int le = (mformat_code == IEEE_754_DOUBLE_LE) ? 1 : 0; Py_ssize_t itemcount = Py_SIZE(items) / 8; const unsigned char *memstr = (unsigned char *)PyBytes_AS_STRING(items); @@ -2044,7 +2047,7 @@ array__array_reconstructor_impl(PyModuleDef *module, PyTypeObject *arraytype, in } case UTF16_LE: case UTF16_BE: { - int byteorder = (mformat_code_enum == UTF16_LE) ? -1 : 1; + int byteorder = (mformat_code == UTF16_LE) ? -1 : 1; converted_items = PyUnicode_DecodeUTF16( PyBytes_AS_STRING(items), Py_SIZE(items), "strict", &byteorder); @@ -2054,7 +2057,7 @@ array__array_reconstructor_impl(PyModuleDef *module, PyTypeObject *arraytype, in } case UTF32_LE: case UTF32_BE: { - int byteorder = (mformat_code_enum == UTF32_LE) ? -1 : 1; + int byteorder = (mformat_code == UTF32_LE) ? -1 : 1; converted_items = PyUnicode_DecodeUTF32( PyBytes_AS_STRING(items), Py_SIZE(items), "strict", &byteorder); @@ -2079,7 +2082,7 @@ array__array_reconstructor_impl(PyModuleDef *module, PyTypeObject *arraytype, in case SIGNED_INT64_BE: { int i; const struct mformatdescr mf_descr = - mformat_descriptors[mformat_code_enum]; + mformat_descriptors[mformat_code]; Py_ssize_t itemcount = Py_SIZE(items) / mf_descr.size; const unsigned char *memstr = (unsigned char *)PyBytes_AS_STRING(items); diff --git a/Modules/clinic/arraymodule.c.h b/Modules/clinic/arraymodule.c.h index 51b9a54..57d7690 100644 --- a/Modules/clinic/arraymodule.c.h +++ b/Modules/clinic/arraymodule.c.h @@ -446,7 +446,7 @@ PyDoc_STRVAR(array__array_reconstructor__doc__, {"_array_reconstructor", (PyCFunction)array__array_reconstructor, METH_VARARGS, array__array_reconstructor__doc__}, static PyObject * -array__array_reconstructor_impl(PyModuleDef *module, PyTypeObject *arraytype, int typecode, int mformat_code, PyObject *items); +array__array_reconstructor_impl(PyModuleDef *module, PyTypeObject *arraytype, int typecode, enum machine_format_code mformat_code, PyObject *items); static PyObject * array__array_reconstructor(PyModuleDef *module, PyObject *args) @@ -454,7 +454,7 @@ array__array_reconstructor(PyModuleDef *module, PyObject *args) PyObject *return_value = NULL; PyTypeObject *arraytype; int typecode; - int mformat_code; + enum machine_format_code mformat_code; PyObject *items; if (!PyArg_ParseTuple(args, @@ -502,4 +502,4 @@ PyDoc_STRVAR(array_arrayiterator___setstate____doc__, #define ARRAY_ARRAYITERATOR___SETSTATE___METHODDEF \ {"__setstate__", (PyCFunction)array_arrayiterator___setstate__, METH_O, array_arrayiterator___setstate____doc__}, -/*[clinic end generated code: output=dff8eae01f0ab208 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=e1deb61c6a3bc8c8 input=a9049054013a1b77]*/ diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index ff99f93..6dc9f13 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -1819,7 +1819,7 @@ exit: static PyObject * bytes_translate_impl(PyBytesObject *self, PyObject *table, int group_right_1, PyObject *deletechars) -/*[clinic end generated code: output=f0f29a57f41df5d8 input=a90fad893c3c88d7]*/ +/*[clinic end generated code: output=f0f29a57f41df5d8 input=d8fa5519d7cc4be7]*/ { char *input, *output; const char *table_chars; diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index 962abdf..92edf6f 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -2426,11 +2426,13 @@ class int_converter(CConverter): format_unit = 'i' c_ignored_default = "0" - def converter_init(self, *, types='int'): + def converter_init(self, *, types='int', type=None): if types == 'str': self.format_unit = 'C' elif types != 'int': fail("int_converter: illegal 'types' argument") + if type != None: + self.type = type class unsigned_int_converter(CConverter): type = 'unsigned int' -- cgit v0.12