Skip to content

Commit f14ffa7

Browse files
committed
Merge branch 'jazzy' into backport/jazzy/events-executor
2 parents 7bb976f + 17a7449 commit f14ffa7

29 files changed

Lines changed: 622 additions & 80 deletions

pyproject.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ select = [
6161
"C90", # mccabe
6262
"NPY", # numpy
6363
"PD", # pandas-vet
64-
# "N", # pep8-naming, Can't fix without breaking API
64+
"N", # pep8-naming
6565
"PERF", # Perflint
6666
"E", # pycodestyle errors
6767
"W", # pycodestyle warnings
@@ -96,6 +96,8 @@ ignore = [
9696
"S110", # try-except-pass
9797
"S311", # suspicious-non-cryptographic-random-usage
9898

99+
"N818", # error-suffix-on-exception-name, Would break existing exception names
100+
99101
# Pylint "too-many" errors
100102
"PLR0911",
101103
"PLR0912",

rosapi/CHANGELOG.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
Changelog for package rosapi
33
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
44

5+
2.5.0 (2026-03-02)
6+
------------------
7+
58
2.4.2 (2025-11-20)
69
------------------
710
* fix: Invert success check for set_param function (backport `#1133 <https://github.com/RobotWebTools/rosbridge_suite/issues/1133>`_) (`#1134 <https://github.com/RobotWebTools/rosbridge_suite/issues/1134>`_)

rosapi/package.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0"?>
22
<package format="3">
33
<name>rosapi</name>
4-
<version>2.4.2</version>
4+
<version>2.5.0</version>
55
<description>
66
Provides services for getting various ROS meta-information, including ROS topic, services, interfaces or
77
action servers and managing ROS parameters.

rosapi_msgs/CHANGELOG.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
Changelog for package rosapi_msgs
33
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
44

5+
2.5.0 (2026-03-02)
6+
------------------
7+
58
2.4.2 (2025-11-20)
69
------------------
710

rosapi_msgs/package.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0"?>
22
<package format="3">
33
<name>rosapi_msgs</name>
4-
<version>2.4.2</version>
4+
<version>2.5.0</version>
55
<description>Interface definitions for rosapi package.</description>
66

77
<license>BSD</license>

rosbridge_library/CHANGELOG.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22
Changelog for package rosbridge_library
33
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
44

5+
2.5.0 (2026-03-02)
6+
------------------
7+
* fix: numpy.ndarray not handled in CBOR serialization (backport `#1161 <https://github.com/RobotWebTools/rosbridge_suite/issues/1161>`_) (`#1162 <https://github.com/RobotWebTools/rosbridge_suite/issues/1162>`_)
8+
* fix: Handle action rejection and server timeout (backport `#1139 <https://github.com/RobotWebTools/rosbridge_suite/issues/1139>`_) (`#1154 <https://github.com/RobotWebTools/rosbridge_suite/issues/1154>`_)
9+
* fix: Failing service and subscription tests (backport `#1147 <https://github.com/RobotWebTools/rosbridge_suite/issues/1147>`_) (`#1151 <https://github.com/RobotWebTools/rosbridge_suite/issues/1151>`_)
10+
* Contributors: Błażej Sowa, Spir0u, atofetti-botbot
11+
512
2.4.2 (2025-11-20)
613
------------------
714
* fix: Apply service timeout parameter correctly (backport `#1125 <https://github.com/RobotWebTools/rosbridge_suite/issues/1125>`_) (`#1129 <https://github.com/RobotWebTools/rosbridge_suite/issues/1129>`_)

rosbridge_library/package.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0"?>
22
<package format="3">
33
<name>rosbridge_library</name>
4-
<version>2.4.2</version>
4+
<version>2.5.0</version>
55
<description>
66
The core rosbridge package, responsible for interpreting JSON and performing the appropriate
77
ROS action, like subscribe, publish, call service, and interact with params.

rosbridge_library/src/rosbridge_library/internal/cbor_conversion.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ def extract_cbor_values(msg: ROSMessage) -> dict[str, Any]:
9898
packed = struct.pack(fmt_to_length, *val)
9999
out[slot] = CBORTag(tag=tag, value=packed)
100100

101+
# fixed-size primitive arrays
102+
elif hasattr(val, "tolist"):
103+
out[slot] = val.tolist()
104+
101105
# array of messages
102106
elif type(val) in LIST_TYPES:
103107
out[slot] = [extract_cbor_values(i) for i in val]

rosbridge_library/src/rosbridge_library/internal/ros_loader.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
_msgs_lock = Lock()
5858
_srvs_lock = Lock()
5959
_actions_lock = Lock()
60+
_import_lock = Lock()
6061

6162

6263
class InvalidTypeStringException(Exception):
@@ -203,12 +204,21 @@ def _get_class(
203204
if cls is not None:
204205
return cls
205206

206-
# Load the class
207-
cls = _load_class(modname, subname, classname)
208-
209-
# Cache the class for both the regular and normalised typestring
210-
_add_to_cache(cache, lock, typestring, cls)
211-
_add_to_cache(cache, lock, norm_typestring, cls)
207+
# Serialize imports to prevent deadlocks from concurrent first-time imports
208+
with _import_lock:
209+
# Check cache again in case it was loaded while waiting for the lock
210+
cls = _get_from_cache(cache, lock, typestring)
211+
if cls is not None:
212+
return cls
213+
cls = _get_from_cache(cache, lock, norm_typestring)
214+
if cls is not None:
215+
return cls
216+
217+
cls = _load_class(modname, subname, classname)
218+
219+
# Cache the class for both the regular and normalised typestring
220+
_add_to_cache(cache, lock, typestring, cls)
221+
_add_to_cache(cache, lock, norm_typestring, cls)
212222

213223
return cls
214224

rosbridge_library/test/internal/subscribers/test_multi_subscriber.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,14 @@ def tearDown(self) -> None:
3737
self.executor.shutdown()
3838
rclpy.shutdown()
3939

40-
def assertTopicSubscribed(self, topic: str, timeout: float = 1.0) -> None:
40+
def assert_topic_subscribed(self, topic: str, timeout: float = 1.0) -> None:
4141
start_time = time.monotonic()
4242
while not is_topic_subscribed(self.node, topic):
4343
time.sleep(0.05)
4444
if time.monotonic() - start_time > timeout:
4545
self.fail(f"Timed out waiting for topic '{topic}' to be subscribed.")
4646

47-
def assertTopicNotSubscribed(self, topic: str, timeout: float = 1.0) -> None:
47+
def assert_topic_not_subscribed(self, topic: str, timeout: float = 1.0) -> None:
4848
start_time = time.monotonic()
4949
while is_topic_subscribed(self.node, topic):
5050
time.sleep(0.05)
@@ -56,22 +56,22 @@ def test_register_multisubscriber(self) -> None:
5656
topic = "/test_register_multisubscriber"
5757
msg_type = "std_msgs/String"
5858

59-
self.assertTopicNotSubscribed(topic)
59+
self.assert_topic_not_subscribed(topic)
6060
MultiSubscriber(topic, self.client_id, lambda *_args: None, self.node, msg_type=msg_type)
61-
self.assertTopicSubscribed(topic)
61+
self.assert_topic_subscribed(topic)
6262

6363
def test_unregister_multisubscriber(self) -> None:
6464
"""Register and unregister a subscriber on a clean topic with a good msg type."""
6565
topic = "/test_unregister_multisubscriber"
6666
msg_type = "std_msgs/String"
6767

68-
self.assertTopicNotSubscribed(topic)
68+
self.assert_topic_not_subscribed(topic)
6969
multi: MultiSubscriber[String] = MultiSubscriber(
7070
topic, self.client_id, lambda *_args: None, self.node, msg_type=msg_type
7171
)
72-
self.assertTopicSubscribed(topic)
72+
self.assert_topic_subscribed(topic)
7373
multi.unregister()
74-
self.assertTopicNotSubscribed(topic)
74+
self.assert_topic_not_subscribed(topic)
7575

7676
def test_verify_type(self) -> None:
7777
topic = "/test_verify_type"
@@ -101,11 +101,11 @@ def test_subscribe_unsubscribe(self) -> None:
101101
topic = "/test_subscribe_unsubscribe"
102102
msg_type = "std_msgs/String"
103103

104-
self.assertTopicNotSubscribed(topic)
104+
self.assert_topic_not_subscribed(topic)
105105
multi: MultiSubscriber[String] = MultiSubscriber(
106106
topic, self.client_id, lambda *_args: None, self.node, msg_type=msg_type
107107
)
108-
self.assertTopicSubscribed(topic)
108+
self.assert_topic_subscribed(topic)
109109
self.assertEqual(len(multi.new_subscriptions), 0)
110110

111111
multi.subscribe(self.client_id, lambda _: None)
@@ -115,7 +115,7 @@ def test_subscribe_unsubscribe(self) -> None:
115115
self.assertEqual(len(multi.new_subscriptions), 0)
116116

117117
multi.unregister()
118-
self.assertTopicNotSubscribed(topic)
118+
self.assert_topic_not_subscribed(topic)
119119

120120
def test_subscribe_receive_json(self) -> None:
121121
topic = "/test_subscribe_receive_json"

0 commit comments

Comments
 (0)