aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2023-11-27 20:11:09 +0200
committerGitHub <noreply@github.com>2023-11-27 18:11:09 +0000
commit581b24415525f10ca178d5537e9cbd7558ce938a (patch)
tree0f6d6e02127f47c15ec280b8452761896b9cd49a
parent[3.11] gh-84443: SSLSocket.recv_into() now support buffer protocol with items... (diff)
downloadcpython-581b24415525f10ca178d5537e9cbd7558ce938a.tar.gz
cpython-581b24415525f10ca178d5537e9cbd7558ce938a.tar.bz2
cpython-581b24415525f10ca178d5537e9cbd7558ce938a.zip
[3.11] gh-112438: Fix support of format units with the "e" prefix in nested tuples in PyArg_Parse (gh-112439) (GH-112461)
(cherry picked from commit 4eea1e82369fbf7a795d1956e7a8212a1b58009f)
-rw-r--r--Lib/test/test_capi/test_getargs.py27
-rw-r--r--Misc/NEWS.d/next/C API/2023-11-27-09-44-16.gh-issue-112438.GdNZiI.rst2
-rw-r--r--Python/getargs.c2
3 files changed, 30 insertions, 1 deletions
diff --git a/Lib/test/test_capi/test_getargs.py b/Lib/test/test_capi/test_getargs.py
index 27675533d1b..1ce1ec3b41c 100644
--- a/Lib/test/test_capi/test_getargs.py
+++ b/Lib/test/test_capi/test_getargs.py
@@ -1322,6 +1322,33 @@ class ParseTupleAndKeywords_Test(unittest.TestCase):
with self.assertRaisesRegex(SystemError, 'Empty keyword'):
parse((1,), {}, 'O|OO', ['', 'a', ''])
+ def test_nested_tuple(self):
+ parse = _testcapi.parse_tuple_and_keywords
+
+ parse(((1, 2, 3),), {}, '(OOO)', ['a'])
+ parse((1, (2, 3), 4), {}, 'O(OO)O', ['a', 'b', 'c'])
+ parse(((1, 2, 3),), {}, '(iii)', ['a'])
+
+ with self.assertRaisesRegex(TypeError,
+ "argument 1 must be sequence of length 2, not 3"):
+ parse(((1, 2, 3),), {}, '(ii)', ['a'])
+ with self.assertRaisesRegex(TypeError,
+ "argument 1 must be sequence of length 2, not 1"):
+ parse(((1,),), {}, '(ii)', ['a'])
+ with self.assertRaisesRegex(TypeError,
+ "argument 1 must be 2-item sequence, not int"):
+ parse((1,), {}, '(ii)', ['a'])
+ with self.assertRaisesRegex(TypeError,
+ "argument 1 must be 2-item sequence, not bytes"):
+ parse((b'ab',), {}, '(ii)', ['a'])
+
+ for f in 'es', 'et', 'es#', 'et#':
+ with self.assertRaises(LookupError): # empty encoding ""
+ parse((('a',),), {}, '(' + f + ')', ['a'])
+ with self.assertRaisesRegex(TypeError,
+ "argument 1 must be sequence of length 1, not 0"):
+ parse(((),), {}, '(' + f + ')', ['a'])
+
class Test_testcapi(unittest.TestCase):
locals().update((name, getattr(_testcapi, name))
diff --git a/Misc/NEWS.d/next/C API/2023-11-27-09-44-16.gh-issue-112438.GdNZiI.rst b/Misc/NEWS.d/next/C API/2023-11-27-09-44-16.gh-issue-112438.GdNZiI.rst
new file mode 100644
index 00000000000..113119efd6a
--- /dev/null
+++ b/Misc/NEWS.d/next/C API/2023-11-27-09-44-16.gh-issue-112438.GdNZiI.rst
@@ -0,0 +1,2 @@
+Fix support of format units "es", "et", "es#", and "et#" in nested tuples in
+:c:func:`PyArg_ParseTuple`-like functions.
diff --git a/Python/getargs.c b/Python/getargs.c
index 3105bd556c1..e18d7719929 100644
--- a/Python/getargs.c
+++ b/Python/getargs.c
@@ -522,7 +522,7 @@ converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
}
else if (c == ':' || c == ';' || c == '\0')
break;
- else if (level == 0 && Py_ISALPHA(c))
+ else if (level == 0 && Py_ISALPHA(c) && c != 'e')
n++;
}