From 0ca64f4e1a74b269de61a90efba36058596adbed Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 14 Apr 2025 20:38:51 +0300 Subject: [PATCH 1/2] gh-132099: Accept an integer as the address for BTPROTO_HCI on Linux Previously only an integer packed in a tuple was accepted, while getsockname() could return a raw integer. Now the result of getsockname() is always acceptable as an address. --- Doc/library/socket.rst | 6 ++++-- Lib/test/test_socket.py | 8 ++++++-- .../2025-04-14-20-38-43.gh-issue-132099.0l0LlK.rst | 3 +++ Modules/socketmodule.c | 7 ++++++- 4 files changed, 19 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2025-04-14-20-38-43.gh-issue-132099.0l0LlK.rst diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index 79b14a72258d4b..2316abd6813268 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -156,8 +156,9 @@ created. Socket addresses are represented as follows: - :const:`BTPROTO_HCI` accepts a format that depends on your OS. - - On Linux it accepts a tuple ``(device_id, [channel])`` where ``device_id`` - is an integer specifying the number of the Bluetooth device, + - On Linux it accepts an integer ``device_id`` or a tuple + ``(device_id, [channel])`` where ``device_id`` + is specifies the number of the Bluetooth device, and ``channel`` is an optional integer specifying the HCI channel (:const:`HCI_CHANNEL_RAW` by default). - On FreeBSD, NetBSD and DragonFly BSD it accepts ``bdaddr`` @@ -171,6 +172,7 @@ created. Socket addresses are represented as follows: .. versionchanged:: next Added ``channel`` field. + ``device_id`` not packed in a tuple is now accepted. - :const:`BTPROTO_SCO` accepts ``bdaddr`` where ``bdaddr`` is the Bluetooth address as a string or a :class:`bytes` object. diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 23642217a51b27..8a3793b9072b78 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -2745,6 +2745,12 @@ def testBindHciSocket(self): addr = s.getsockname() self.assertEqual(addr, dev) + with (self.subTest('integer'), + socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW, socket.BTPROTO_HCI) as s): + s.bind(dev) + addr = s.getsockname() + self.assertEqual(addr, dev) + with (self.subTest('channel=HCI_CHANNEL_RAW'), socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW, socket.BTPROTO_HCI) as s): channel = socket.HCI_CHANNEL_RAW @@ -2789,8 +2795,6 @@ def testBadHciAddr(self): s.bind(()) with self.assertRaises(OSError): s.bind((dev, socket.HCI_CHANNEL_RAW, 0, 0)) - with self.assertRaises(OSError): - s.bind(dev) with self.assertRaises(OSError): s.bind(socket.BDADDR_ANY) with self.assertRaises(OSError): diff --git a/Misc/NEWS.d/next/Library/2025-04-14-20-38-43.gh-issue-132099.0l0LlK.rst b/Misc/NEWS.d/next/Library/2025-04-14-20-38-43.gh-issue-132099.0l0LlK.rst new file mode 100644 index 00000000000000..de69873605f42e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-04-14-20-38-43.gh-issue-132099.0l0LlK.rst @@ -0,0 +1,3 @@ +The Bluetooth socket with the :data:`~socket.BTPROTO_HCI` protocol on Linux +now accepts an address in the format of an integer ``device_id``, not only a +tuple ``(device_id,)``. diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 1ee9d52b7968c6..2326620dcff84f 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -2147,7 +2147,12 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, #if defined(HAVE_BLUETOOTH_BLUETOOTH_H) unsigned short dev; unsigned short channel = HCI_CHANNEL_RAW; - if (!PyArg_ParseTuple(args, "H|H", &dev, &channel)) { + if (PyLong_Check(args)) { + if (!PyArg_Parse(args, "H", &dev)) { + return 0; + } + } + else if (!PyArg_ParseTuple(args, "H|H", &dev, &channel)) { PyErr_Format(PyExc_OSError, "%s(): wrong format", caller); return 0; From 4341b1830175c0517f40933998159ecbf555230e Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 14 Apr 2025 21:41:27 +0300 Subject: [PATCH 2/2] Update Doc/library/socket.rst Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> --- Doc/library/socket.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index 2316abd6813268..6b666753ceb935 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -158,7 +158,7 @@ created. Socket addresses are represented as follows: - On Linux it accepts an integer ``device_id`` or a tuple ``(device_id, [channel])`` where ``device_id`` - is specifies the number of the Bluetooth device, + specifies the number of the Bluetooth device, and ``channel`` is an optional integer specifying the HCI channel (:const:`HCI_CHANNEL_RAW` by default). - On FreeBSD, NetBSD and DragonFly BSD it accepts ``bdaddr``