summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_capi.py
diff options
context:
space:
mode:
authorLarry Hastings <larry@hastings.org>2012-06-22 10:56:29 (GMT)
committerLarry Hastings <larry@hastings.org>2012-06-22 10:56:29 (GMT)
commit8f904daee9dcb6b36b925f184144921e8bf6aaa6 (patch)
tree00a5b0a927251e8f4b9b449095f96e2fa6d43bdb /Lib/test/test_capi.py
parent466bfff9fb59961245848587d9f7aa62684e2e12 (diff)
downloadcpython-8f904daee9dcb6b36b925f184144921e8bf6aaa6.zip
cpython-8f904daee9dcb6b36b925f184144921e8bf6aaa6.tar.gz
cpython-8f904daee9dcb6b36b925f184144921e8bf6aaa6.tar.bz2
Issue #14769: test_capi now has SkipitemTest, which cleverly checks
for "parity" between PyArg_ParseTuple() and the Python/getargs.c static function skipitem() for all possible "format units".
Diffstat (limited to 'Lib/test/test_capi.py')
-rw-r--r--Lib/test/test_capi.py71
1 files changed, 70 insertions, 1 deletions
diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py
index a58c577..e24bd6f 100644
--- a/Lib/test/test_capi.py
+++ b/Lib/test/test_capi.py
@@ -214,9 +214,78 @@ class EmbeddingTest(unittest.TestCase):
finally:
os.chdir(oldcwd)
+class SkipitemTest(unittest.TestCase):
+
+ def test_skipitem(self):
+ """
+ If this test failed, you probably added a new "format unit"
+ in Python/getargs.c, but neglected to update our poor friend
+ skipitem() in the same file. (If so, shame on you!)
+
+ This function brute-force tests all** ASCII characters (1 to 127
+ inclusive) as format units, checking to see that
+ PyArg_ParseTupleAndKeywords() return consistent errors both when
+ the unit is attempted to be used and when it is skipped. If the
+ format unit doesn't exist, we'll get one of two specific error
+ messages (one for used, one for skipped); if it does exist we
+ *won't* get that error--we'll get either no error or some other
+ error. If we get the "does not exist" error for one test and
+ not for the other, there's a mismatch, and the test fails.
+
+ ** Okay, it actually skips some ASCII characters. Some characters
+ have special funny semantics, and it would be difficult to
+ accomodate them here.
+ """
+ empty_tuple = ()
+ tuple_1 = (0,)
+ dict_b = {'b':1}
+ keywords = ["a", "b"]
+
+ # Python C source files must be ASCII,
+ # therefore we'll never have a format unit > 127
+ for i in range(1, 128):
+ c = chr(i)
+
+ # skip non-printable characters, no one is insane enough to define
+ # one as a format unit
+ # skip parentheses, the error reporting is inconsistent about them
+ # skip 'e', it's always a two-character code
+ # skip '|' and '$', they don't represent arguments anyway
+ if (not c.isprintable()) or (c in '()e|$'):
+ continue
+
+ # test the format unit when not skipped
+ format = c + "i"
+ try:
+ # (note: the format string must be bytes!)
+ _testcapi.parse_tuple_and_keywords(tuple_1, dict_b,
+ format.encode("ascii"), keywords)
+ when_not_skipped = False
+ except TypeError as e:
+ s = "argument 1 must be impossible<bad format char>, not int"
+ when_not_skipped = (str(e) == s)
+ except RuntimeError as e:
+ when_not_skipped = False
+
+ # test the format unit when skipped
+ optional_format = "|" + format
+ try:
+ _testcapi.parse_tuple_and_keywords(empty_tuple, dict_b,
+ optional_format.encode("ascii"), keywords)
+ when_skipped = False
+ except RuntimeError as e:
+ s = "impossible<bad format char>: '{}'".format(format)
+ when_skipped = (str(e) == s)
+
+ message = ("test_skipitem_parity: "
+ "detected mismatch between convertsimple and skipitem "
+ "for format unit '{}' ({}), not skipped {}, skipped {}".format(
+ c, i, when_skipped, when_not_skipped))
+ self.assertIs(when_skipped, when_not_skipped, message)
def test_main():
- support.run_unittest(CAPITest, TestPendingCalls, Test6012, EmbeddingTest)
+ support.run_unittest(CAPITest, TestPendingCalls,
+ Test6012, EmbeddingTest, SkipitemTest)
for name in dir(_testcapi):
if name.startswith('test_'):