]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-132099: Accept an integer as the address for BTPROTO_HCI on Linux (GH-132525)
authorSerhiy Storchaka <storchaka@gmail.com>
Wed, 16 Apr 2025 10:02:51 +0000 (13:02 +0300)
committerGitHub <noreply@github.com>
Wed, 16 Apr 2025 10:02:51 +0000 (13:02 +0300)
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
Lib/test/test_socket.py
Misc/NEWS.d/next/Library/2025-04-14-20-38-43.gh-issue-132099.0l0LlK.rst [new file with mode: 0644]
Modules/socketmodule.c

index 79b14a72258d4be539d2dcd932f38234c9b0890e..6b666753ceb9355f0afcc9ef70d46034ff5a9038 100644 (file)
@@ -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``
+      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.
index 23642217a51b270e9d9e0d021a530ab79361621a..8a3793b9072b781790cbc1ccdd21bbba744188a4 100644 (file)
@@ -2745,6 +2745,12 @@ class BasicBluetoothTest(unittest.TestCase):
                 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 @@ class BasicBluetoothTest(unittest.TestCase):
                     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 (file)
index 0000000..de69873
--- /dev/null
@@ -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,)``.
index 1ee9d52b7968c6a6952444af3a2577011fc8a5ac..2326620dcff84fd2b22c423c89982141564e9566 100644 (file)
@@ -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;