]> granicus.if.org Git - python/commitdiff
bpo-23927: Make getargs.c skipitem() skipping 'w*'. (GH-8192)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Wed, 11 Jul 2018 17:10:40 +0000 (10:10 -0700)
committerGitHub <noreply@github.com>
Wed, 11 Jul 2018 17:10:40 +0000 (10:10 -0700)
(cherry picked from commit 504373c59b48f1ea12132d515459022730db6047)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
Lib/test/test_capi.py
Misc/NEWS.d/next/C API/2018-07-09-11-39-54.bpo-23927.pDFkxb.rst [new file with mode: 0644]
Python/getargs.c

index b36a2ce585ce3ea35a3ec20ab408299f8d1f36dc..2725333e7e96c2374bc33e807d4c4ab10176dd3d 100644 (file)
@@ -5,6 +5,7 @@ import os
 import pickle
 import random
 import re
+import string
 import subprocess
 import sys
 import sysconfig
@@ -565,6 +566,37 @@ class SkipitemTest(unittest.TestCase):
                     c, i, when_skipped, when_not_skipped))
             self.assertIs(when_skipped, when_not_skipped, message)
 
+    def test_skipitem_with_suffix(self):
+        parse = _testcapi.parse_tuple_and_keywords
+        empty_tuple = ()
+        tuple_1 = (0,)
+        dict_b = {'b':1}
+        keywords = ["a", "b"]
+
+        supported = ('s#', 's*', 'z#', 'z*', 'u#', 'Z#', 'y#', 'y*', 'w#', 'w*')
+        for c in string.ascii_letters:
+            for c2 in '#*':
+                f = c + c2
+                with self.subTest(format=f):
+                    optional_format = "|" + f + "i"
+                    if f in supported:
+                        parse(empty_tuple, dict_b, optional_format, keywords)
+                    else:
+                        with self.assertRaisesRegex(SystemError,
+                                    'impossible<bad format char>'):
+                            parse(empty_tuple, dict_b, optional_format, keywords)
+
+        for c in map(chr, range(32, 128)):
+            f = 'e' + c
+            optional_format = "|" + f + "i"
+            with self.subTest(format=f):
+                if c in 'st':
+                    parse(empty_tuple, dict_b, optional_format, keywords)
+                else:
+                    with self.assertRaisesRegex(SystemError,
+                                'impossible<bad format char>'):
+                        parse(empty_tuple, dict_b, optional_format, keywords)
+
     def test_parse_tuple_and_keywords(self):
         # Test handling errors in the parse_tuple_and_keywords helper itself
         self.assertRaises(TypeError, _testcapi.parse_tuple_and_keywords,
diff --git a/Misc/NEWS.d/next/C API/2018-07-09-11-39-54.bpo-23927.pDFkxb.rst b/Misc/NEWS.d/next/C API/2018-07-09-11-39-54.bpo-23927.pDFkxb.rst
new file mode 100644 (file)
index 0000000..3e2ac6c
--- /dev/null
@@ -0,0 +1,2 @@
+Fixed :exc:`SystemError` in :c:func:`PyArg_ParseTupleAndKeywords` when the
+``w*`` format unit is used for optional parameter.
index 4d27418a84ba0779efa7fb50bc591b7ee3505eda..594b150deeb1f0d0e637cbf63c8d8debd943ed02 100644 (file)
@@ -2281,7 +2281,9 @@ skipitem(const char **p_format, va_list *p_va, int flags)
                         (void) va_arg(*p_va, int *);
                 }
                 format++;
-            } else if ((c == 's' || c == 'z' || c == 'y') && *format == '*') {
+            } else if ((c == 's' || c == 'z' || c == 'y' || c == 'w')
+                       && *format == '*')
+            {
                 format++;
             }
             break;