From 65ce60aef150776f884715b4315a10a0d6ae769e Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 25 Dec 2018 11:10:05 +0200 Subject: [PATCH] bpo-20180: Simplify char_converter in Argument Clinic. (GH-9828) Fix also handling non-ascii default values. --- Lib/test/clinic.test | 30 ++++++++++++++++-------------- Tools/clinic/clinic.py | 21 +++------------------ 2 files changed, 19 insertions(+), 32 deletions(-) diff --git a/Lib/test/clinic.test b/Lib/test/clinic.test index fdb9e2f335c..5f6fec8d4ed 100644 --- a/Lib/test/clinic.test +++ b/Lib/test/clinic.test @@ -349,6 +349,7 @@ test_char_converter k: char = b'?' l: char = b'\\' m: char = b'\000' + n: char = b'\377' / [clinic start generated code]*/ @@ -356,7 +357,7 @@ test_char_converter PyDoc_STRVAR(test_char_converter__doc__, "test_char_converter($module, a=b\'A\', b=b\'\\x07\', c=b\'\\x08\', d=b\'\\t\',\n" " e=b\'\\n\', f=b\'\\x0b\', g=b\'\\x0c\', h=b\'\\r\', i=b\'\"\',\n" -" j=b\"\'\", k=b\'?\', l=b\'\\\\\', m=b\'\\x00\', /)\n" +" j=b\"\'\", k=b\'?\', l=b\'\\\\\', m=b\'\\x00\', n=b\'\\xff\', /)\n" "--\n" "\n"); @@ -366,31 +367,32 @@ PyDoc_STRVAR(test_char_converter__doc__, static PyObject * test_char_converter_impl(PyObject *module, char a, char b, char c, char d, char e, char f, char g, char h, char i, char j, - char k, char l, char m); + char k, char l, char m, char n); static PyObject * test_char_converter(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; char a = 'A'; - char b = '\a'; - char c = '\b'; + char b = '\x07'; + char c = '\x08'; char d = '\t'; char e = '\n'; - char f = '\v'; - char g = '\f'; + char f = '\x0b'; + char g = '\x0c'; char h = '\r'; - char i = '\"'; + char i = '"'; char j = '\''; - char k = '\?'; + char k = '?'; char l = '\\'; - char m = '\0'; + char m = '\x00'; + char n = '\xff'; - if (!_PyArg_ParseStack(args, nargs, "|ccccccccccccc:test_char_converter", - &a, &b, &c, &d, &e, &f, &g, &h, &i, &j, &k, &l, &m)) { + if (!_PyArg_ParseStack(args, nargs, "|cccccccccccccc:test_char_converter", + &a, &b, &c, &d, &e, &f, &g, &h, &i, &j, &k, &l, &m, &n)) { goto exit; } - return_value = test_char_converter_impl(module, a, b, c, d, e, f, g, h, i, j, k, l, m); + return_value = test_char_converter_impl(module, a, b, c, d, e, f, g, h, i, j, k, l, m, n); exit: return return_value; @@ -399,8 +401,8 @@ exit: static PyObject * test_char_converter_impl(PyObject *module, char a, char b, char c, char d, char e, char f, char g, char h, char i, char j, - char k, char l, char m) -/*[clinic end generated code: output=d9b268767e933c77 input=40431047c768ec24]*/ + char k, char l, char m, char n) +/*[clinic end generated code: output=14c61e8ee78f3d47 input=e42330417a44feac]*/ /*[clinic input] test_unsigned_char_converter diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index cd492b47a24..b0acbcfde08 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -2562,29 +2562,14 @@ class char_converter(CConverter): format_unit = 'c' c_ignored_default = "'\0'" - # characters which need to be escaped in C code - _escapes = {x: r'\%d' % x for x in range(7)} - _escapes.update({ - 0x07: r'\a', - 0x08: r'\b', - 0x09: r'\t', - 0x0A: r'\n', - 0x0B: r'\v', - 0x0C: r'\f', - 0x0D: r'\r', - 0x22: r'\"', - 0x27: r'\'', - 0x3F: r'\?', - 0x5C: r'\\', - }) - def converter_init(self): if isinstance(self.default, self.default_type): if len(self.default) != 1: fail("char_converter: illegal default value " + repr(self.default)) - c_ord = self.default[0] - self.c_default = "'%s'" % self._escapes.get(c_ord, chr(c_ord)) + self.c_default = repr(bytes(self.default))[1:] + if self.c_default == '"\'"': + self.c_default = r"'\''" @add_legacy_c_converter('B', bitwise=True)