]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-36346: Emit DeprecationWarning for PyArg_Parse() with 'u' or 'Z'. (GH-20927)
authorInada Naoki <songofacandy@gmail.com>
Mon, 22 Feb 2021 13:11:48 +0000 (22:11 +0900)
committerGitHub <noreply@github.com>
Mon, 22 Feb 2021 13:11:48 +0000 (22:11 +0900)
Emit DeprecationWarning when PyArg_Parse*() is called with 'u', 'Z' format.

See PEP 623.

Lib/test/test_getargs2.py
Lib/test/test_unicode.py
Misc/NEWS.d/next/Core and Builtins/2021-02-22-19-00-00.bpo-36346.uAoni0.rst [new file with mode: 0644]
Python/getargs.c

index 09560197913059290fa69775258a333ff10b1453..c67e6f51a2346439babe05e61f70eb689267aa59 100644 (file)
@@ -4,6 +4,7 @@ import string
 import sys
 from test import support
 from test.support import import_helper
+from test.support import warnings_helper
 # Skip this test if the _testcapi module isn't available.
 _testcapi = import_helper.import_module('_testcapi')
 from _testcapi import getargs_keywords, getargs_keyword_only
@@ -979,42 +980,66 @@ class String_TestCase(unittest.TestCase):
     @support.requires_legacy_unicode_capi
     def test_u(self):
         from _testcapi import getargs_u
-        self.assertEqual(getargs_u('abc\xe9'), 'abc\xe9')
-        self.assertRaises(ValueError, getargs_u, 'nul:\0')
-        self.assertRaises(TypeError, getargs_u, b'bytes')
-        self.assertRaises(TypeError, getargs_u, bytearray(b'bytearray'))
-        self.assertRaises(TypeError, getargs_u, memoryview(b'memoryview'))
-        self.assertRaises(TypeError, getargs_u, None)
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(getargs_u('abc\xe9'), 'abc\xe9')
+        with self.assertWarns(DeprecationWarning):
+            self.assertRaises(ValueError, getargs_u, 'nul:\0')
+        with self.assertWarns(DeprecationWarning):
+            self.assertRaises(TypeError, getargs_u, b'bytes')
+        with self.assertWarns(DeprecationWarning):
+            self.assertRaises(TypeError, getargs_u, bytearray(b'bytearray'))
+        with self.assertWarns(DeprecationWarning):
+            self.assertRaises(TypeError, getargs_u, memoryview(b'memoryview'))
+        with self.assertWarns(DeprecationWarning):
+            self.assertRaises(TypeError, getargs_u, None)
 
     @support.requires_legacy_unicode_capi
     def test_u_hash(self):
         from _testcapi import getargs_u_hash
-        self.assertEqual(getargs_u_hash('abc\xe9'), 'abc\xe9')
-        self.assertEqual(getargs_u_hash('nul:\0'), 'nul:\0')
-        self.assertRaises(TypeError, getargs_u_hash, b'bytes')
-        self.assertRaises(TypeError, getargs_u_hash, bytearray(b'bytearray'))
-        self.assertRaises(TypeError, getargs_u_hash, memoryview(b'memoryview'))
-        self.assertRaises(TypeError, getargs_u_hash, None)
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(getargs_u_hash('abc\xe9'), 'abc\xe9')
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(getargs_u_hash('nul:\0'), 'nul:\0')
+        with self.assertWarns(DeprecationWarning):
+            self.assertRaises(TypeError, getargs_u_hash, b'bytes')
+        with self.assertWarns(DeprecationWarning):
+            self.assertRaises(TypeError, getargs_u_hash, bytearray(b'bytearray'))
+        with self.assertWarns(DeprecationWarning):
+            self.assertRaises(TypeError, getargs_u_hash, memoryview(b'memoryview'))
+        with self.assertWarns(DeprecationWarning):
+            self.assertRaises(TypeError, getargs_u_hash, None)
 
     @support.requires_legacy_unicode_capi
     def test_Z(self):
         from _testcapi import getargs_Z
-        self.assertEqual(getargs_Z('abc\xe9'), 'abc\xe9')
-        self.assertRaises(ValueError, getargs_Z, 'nul:\0')
-        self.assertRaises(TypeError, getargs_Z, b'bytes')
-        self.assertRaises(TypeError, getargs_Z, bytearray(b'bytearray'))
-        self.assertRaises(TypeError, getargs_Z, memoryview(b'memoryview'))
-        self.assertIsNone(getargs_Z(None))
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(getargs_Z('abc\xe9'), 'abc\xe9')
+        with self.assertWarns(DeprecationWarning):
+            self.assertRaises(ValueError, getargs_Z, 'nul:\0')
+        with self.assertWarns(DeprecationWarning):
+            self.assertRaises(TypeError, getargs_Z, b'bytes')
+        with self.assertWarns(DeprecationWarning):
+            self.assertRaises(TypeError, getargs_Z, bytearray(b'bytearray'))
+        with self.assertWarns(DeprecationWarning):
+            self.assertRaises(TypeError, getargs_Z, memoryview(b'memoryview'))
+        with self.assertWarns(DeprecationWarning):
+            self.assertIsNone(getargs_Z(None))
 
     @support.requires_legacy_unicode_capi
     def test_Z_hash(self):
         from _testcapi import getargs_Z_hash
-        self.assertEqual(getargs_Z_hash('abc\xe9'), 'abc\xe9')
-        self.assertEqual(getargs_Z_hash('nul:\0'), 'nul:\0')
-        self.assertRaises(TypeError, getargs_Z_hash, b'bytes')
-        self.assertRaises(TypeError, getargs_Z_hash, bytearray(b'bytearray'))
-        self.assertRaises(TypeError, getargs_Z_hash, memoryview(b'memoryview'))
-        self.assertIsNone(getargs_Z_hash(None))
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(getargs_Z_hash('abc\xe9'), 'abc\xe9')
+        with self.assertWarns(DeprecationWarning):
+            self.assertEqual(getargs_Z_hash('nul:\0'), 'nul:\0')
+        with self.assertWarns(DeprecationWarning):
+            self.assertRaises(TypeError, getargs_Z_hash, b'bytes')
+        with self.assertWarns(DeprecationWarning):
+            self.assertRaises(TypeError, getargs_Z_hash, bytearray(b'bytearray'))
+        with self.assertWarns(DeprecationWarning):
+            self.assertRaises(TypeError, getargs_Z_hash, memoryview(b'memoryview'))
+        with self.assertWarns(DeprecationWarning):
+            self.assertIsNone(getargs_Z_hash(None))
 
 
 class Object_TestCase(unittest.TestCase):
@@ -1053,6 +1078,8 @@ class Test6012(unittest.TestCase):
 
 class SkipitemTest(unittest.TestCase):
 
+    # u, and Z raises DeprecationWarning
+    @warnings_helper.ignore_warnings(category=DeprecationWarning)
     def test_skipitem(self):
         """
         If this test failed, you probably added a new "format unit"
@@ -1221,6 +1248,14 @@ class Test_testcapi(unittest.TestCase):
                     for name in dir(_testcapi)
                     if name.startswith('test_') and name.endswith('_code'))
 
+    @warnings_helper.ignore_warnings(category=DeprecationWarning)
+    def test_u_code(self):
+        _testcapi.test_u_code()
+
+    @warnings_helper.ignore_warnings(category=DeprecationWarning)
+    def test_Z_code(self):
+        _testcapi.test_Z_code()
+
 
 if __name__ == "__main__":
     unittest.main()
index df8f2c92b38f887e77a556ba36c2195fa5a562a7..2626be6281c946e72cfa5b8d5c46c71d0ec0a95c 100644 (file)
@@ -2368,12 +2368,14 @@ class UnicodeTest(string_tests.CommonTest,
             text = 'a' * length + 'b'
 
             # fill wstr internal field
-            abc = getargs_u(text)
+            with self.assertWarns(DeprecationWarning):
+                abc = getargs_u(text)
             self.assertEqual(abc, text)
 
             # resize text: wstr field must be cleared and then recomputed
             text += 'c'
-            abcdef = getargs_u(text)
+            with self.assertWarns(DeprecationWarning):
+                abcdef = getargs_u(text)
             self.assertNotEqual(abc, abcdef)
             self.assertEqual(abcdef, text)
 
diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-02-22-19-00-00.bpo-36346.uAoni0.rst b/Misc/NEWS.d/next/Core and Builtins/2021-02-22-19-00-00.bpo-36346.uAoni0.rst
new file mode 100644 (file)
index 0000000..3b3e727
--- /dev/null
@@ -0,0 +1,2 @@
+``PyArg_Parse*()`` functions now emits ``DeprecationWarning`` when ``u`` or
+``Z`` format is used. See :pep:`623` for detail.
index 8839492e5ef41a5e77c96b8f7e758a247e0d7a5a..936eb6a89a392870a05874964fa37174e8d4b7f3 100644 (file)
@@ -1014,7 +1014,10 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
     case 'u': /* raw unicode buffer (Py_UNICODE *) */
     case 'Z': /* raw unicode buffer or None */
     {
-        // TODO: Raise DeprecationWarning
+        if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
+                "getargs: The '%c' format is deprecated. Use 'U' instead.", c)) {
+            return NULL;
+        }
 _Py_COMP_DIAG_PUSH
 _Py_COMP_DIAG_IGNORE_DEPR_DECLS
         Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **);