diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index fd6422cc8c06c5..74096d8acbaf31 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -330,11 +330,11 @@ property:: 10 b'Hi\x00lo\x00\x00\x00\x00\x00' >>> -The :func:`create_string_buffer` function replaces the :func:`c_buffer` function -(which is still available as an alias), as well as the :func:`c_string` function -from earlier ctypes releases. To create a mutable memory block containing -unicode characters of the C type :c:type:`wchar_t` use the -:func:`create_unicode_buffer` function. +To create a mutable memory block containing unicode characters of the C type +:c:type:`wchar_t` use the :func:`create_unicode_buffer` function. + +The :func:`c_buffer` alias to the :func:`create_string_buffer` function is +deprecated in Python 3.11. .. _ctypes-calling-functions-continued: diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index d6a95a2e3175c7..b5a8dc2f050890 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -292,6 +292,10 @@ Deprecated Python 3.10 or newer. See the :pep:`617` (New PEG parser for CPython). (Contributed by Victor Stinner in :issue:`40360`.) +* The :func:`ctypes.c_buffer` alias to the :func:`ctypes.create_string_buffer` + is now deprecated: use directly :func:`ctypes.create_string_buffer` instead. + (Contributed by Victor Stinner in :issue:`45082`.) + Removed ======= diff --git a/Lib/ctypes/__init__.py b/Lib/ctypes/__init__.py index 4afa4ebd422493..e4c704cb47c135 100644 --- a/Lib/ctypes/__init__.py +++ b/Lib/ctypes/__init__.py @@ -66,10 +66,11 @@ def create_string_buffer(init, size=None): raise TypeError(init) def c_buffer(init, size=None): -## "deprecated, use create_string_buffer instead" -## import warnings -## warnings.warn("c_buffer is deprecated, use create_string_buffer instead", -## DeprecationWarning, stacklevel=2) + """Deprecated: use create_string_buffer instead.""" + import warnings + warnings.warn("c_buffer() is deprecated: " + "use create_string_buffer() instead", + DeprecationWarning, stacklevel=2) return create_string_buffer(init, size) _c_functype_cache = {} diff --git a/Lib/ctypes/test/test_prototypes.py b/Lib/ctypes/test/test_prototypes.py index cd0c649de3e31b..9c74dbc27fe3dd 100644 --- a/Lib/ctypes/test/test_prototypes.py +++ b/Lib/ctypes/test/test_prototypes.py @@ -100,7 +100,7 @@ def test_POINTER_c_char_arg(self): self.assertEqual(None, func(c_char_p(None))) self.assertEqual(b"123", func(c_char_p(b"123"))) - self.assertEqual(b"123", func(c_buffer(b"123"))) + self.assertEqual(b"123", func(create_string_buffer(b"123"))) ca = c_char(b"a") self.assertEqual(ord(b"a"), func(pointer(ca))[0]) self.assertEqual(ord(b"a"), func(byref(ca))[0]) @@ -115,7 +115,7 @@ def test_c_char_p_arg(self): self.assertEqual(None, func(c_char_p(None))) self.assertEqual(b"123", func(c_char_p(b"123"))) - self.assertEqual(b"123", func(c_buffer(b"123"))) + self.assertEqual(b"123", func(create_string_buffer(b"123"))) ca = c_char(b"a") self.assertEqual(ord(b"a"), func(pointer(ca))[0]) self.assertEqual(ord(b"a"), func(byref(ca))[0]) @@ -130,7 +130,7 @@ def test_c_void_p_arg(self): self.assertEqual(b"123", func(c_char_p(b"123"))) self.assertEqual(None, func(c_char_p(None))) - self.assertEqual(b"123", func(c_buffer(b"123"))) + self.assertEqual(b"123", func(create_string_buffer(b"123"))) ca = c_char(b"a") self.assertEqual(ord(b"a"), func(pointer(ca))[0]) self.assertEqual(ord(b"a"), func(byref(ca))[0]) diff --git a/Lib/ctypes/test/test_python_api.py b/Lib/ctypes/test/test_python_api.py index 9c137469c3b5a5..0968525f18d6a5 100644 --- a/Lib/ctypes/test/test_python_api.py +++ b/Lib/ctypes/test/test_python_api.py @@ -70,7 +70,7 @@ def test_PyOS_snprintf(self): PyOS_snprintf = pythonapi.PyOS_snprintf PyOS_snprintf.argtypes = POINTER(c_char), c_size_t, c_char_p - buf = c_buffer(256) + buf = create_string_buffer(256) PyOS_snprintf(buf, sizeof(buf), b"Hello from %s", b"ctypes") self.assertEqual(buf.value, b"Hello from ctypes") diff --git a/Lib/ctypes/test/test_stringptr.py b/Lib/ctypes/test/test_stringptr.py index c20951f4ce0016..98db848483b558 100644 --- a/Lib/ctypes/test/test_stringptr.py +++ b/Lib/ctypes/test/test_stringptr.py @@ -16,14 +16,14 @@ class X(Structure): # NULL pointer access self.assertRaises(ValueError, getattr, x.str, "contents") - b = c_buffer(b"Hello, World") + b = create_string_buffer(b"Hello, World") from sys import getrefcount as grc self.assertEqual(grc(b), 2) x.str = b self.assertEqual(grc(b), 3) # POINTER(c_char) and Python string is NOT compatible - # POINTER(c_char) and c_buffer() is compatible + # POINTER(c_char) and create_string_buffer() is compatible for i in range(len(b)): self.assertEqual(b[i], x.str[i]) @@ -35,11 +35,11 @@ class X(Structure): x = X() # c_char_p and Python string is compatible - # c_char_p and c_buffer is NOT compatible + # c_char_p and create_string_buffer is NOT compatible self.assertEqual(x.str, None) x.str = b"Hello, World" self.assertEqual(x.str, b"Hello, World") - b = c_buffer(b"Hello, World") + b = create_string_buffer(b"Hello, World") self.assertRaises(TypeError, setattr, x, b"str", b) @@ -48,15 +48,15 @@ def test_functions(self): strchr.restype = c_char_p # c_char_p and Python string is compatible - # c_char_p and c_buffer are now compatible + # c_char_p and create_string_buffer are now compatible strchr.argtypes = c_char_p, c_char self.assertEqual(strchr(b"abcdef", b"c"), b"cdef") - self.assertEqual(strchr(c_buffer(b"abcdef"), b"c"), b"cdef") + self.assertEqual(strchr(create_string_buffer(b"abcdef"), b"c"), b"cdef") # POINTER(c_char) and Python string is NOT compatible - # POINTER(c_char) and c_buffer() is compatible + # POINTER(c_char) and create_string_buffer() is compatible strchr.argtypes = POINTER(c_char), c_char - buf = c_buffer(b"abcdef") + buf = create_string_buffer(b"abcdef") self.assertEqual(strchr(buf, b"c"), b"cdef") self.assertEqual(strchr(b"abcdef", b"c"), b"cdef") @@ -65,7 +65,7 @@ def test_functions(self): # So we must keep a reference to buf separately strchr.restype = POINTER(c_char) - buf = c_buffer(b"abcdef") + buf = create_string_buffer(b"abcdef") r = strchr(buf, b"c") x = r[0], r[1], r[2], r[3], r[4] self.assertEqual(x, (b"c", b"d", b"e", b"f", b"\000")) diff --git a/Lib/ctypes/test/test_strings.py b/Lib/ctypes/test/test_strings.py index 5434efda10c057..902d6fc0d155b9 100644 --- a/Lib/ctypes/test/test_strings.py +++ b/Lib/ctypes/test/test_strings.py @@ -1,6 +1,8 @@ +import ctypes import unittest from ctypes import * from ctypes.test import need_symbol +from test.support import warnings_helper class StringArrayTestCase(unittest.TestCase): def test(self): @@ -25,8 +27,8 @@ def test(self): self.assertRaises(ValueError, setattr, buf, "value", b"aaaaaaaa") self.assertRaises(TypeError, setattr, buf, "value", 42) - def test_c_buffer_value(self): - buf = c_buffer(32) + def test_c_string_buffer_value(self): + buf = ctypes.create_string_buffer(32) buf.value = b"Hello, World" self.assertEqual(buf.value, b"Hello, World") @@ -35,8 +37,8 @@ def test_c_buffer_value(self): self.assertRaises(TypeError, setattr, buf, "value", memoryview(b"abc")) self.assertRaises(ValueError, setattr, buf, "raw", memoryview(b"x" * 100)) - def test_c_buffer_raw(self): - buf = c_buffer(32) + def test_c_string_buffer_raw(self): + buf = ctypes.create_string_buffer(32) buf.raw = memoryview(b"Hello, World") self.assertEqual(buf.value, b"Hello, World") @@ -60,6 +62,10 @@ def test_del_segfault(self): with self.assertRaises(AttributeError): del buf.raw + def test_c_buffer_deprecation(self): + with warnings_helper.check_warnings(('', DeprecationWarning)): + ctypes.c_buffer(32) + @need_symbol('c_wchar') class WStringArrayTestCase(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Library/2021-09-01-23-31-23.bpo-45082.mI9gsQ.rst b/Misc/NEWS.d/next/Library/2021-09-01-23-31-23.bpo-45082.mI9gsQ.rst new file mode 100644 index 00000000000000..1d91ccd29c59b0 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-09-01-23-31-23.bpo-45082.mI9gsQ.rst @@ -0,0 +1,4 @@ +Deprecate the :func:`ctypes.c_buffer` alias to the +:func:`ctypes.create_string_buffer`: use directly +:func:`ctypes.create_string_buffer` instead. +Patch by Victor Stinner. diff --git a/PC/validate_ucrtbase.py b/PC/validate_ucrtbase.py index 0ba54ab3bb42df..2a45dca927ed63 100644 --- a/PC/validate_ucrtbase.py +++ b/PC/validate_ucrtbase.py @@ -5,7 +5,7 @@ import sys -from ctypes import (c_buffer, POINTER, byref, create_unicode_buffer, +from ctypes import (create_string_buffer, POINTER, byref, create_unicode_buffer, Structure, WinDLL) from ctypes.wintypes import DWORD, HANDLE @@ -60,7 +60,7 @@ class VS_FIXEDFILEINFO(Structure): print('Failed to get size of version info.') sys.exit(2) -ver_block = c_buffer(size) +ver_block = create_string_buffer(size) if (not version.GetFileVersionInfoW(name, None, size, ver_block) or not ver_block): print('Failed to get version info.')