From bdef6c93835351a003310a0bb366f582451cef4f Mon Sep 17 00:00:00 2001 From: Alex Huttunen Date: Wed, 5 Mar 2025 14:17:12 -0800 Subject: [PATCH 1/3] Allow overrides in the vendor specific data type DSDL ID range --- dronecan/dsdl/parser.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dronecan/dsdl/parser.py b/dronecan/dsdl/parser.py index 509660f..3c7abf1 100644 --- a/dronecan/dsdl/parser.py +++ b/dronecan/dsdl/parser.py @@ -866,6 +866,12 @@ def ensure_unique_dtid(t, filename): value = all_default_dtid[key] first = pretty_filename(value[0]) second = pretty_filename(filename) + + # Allow overrides for vendor specific data types in the range [20000, 21000) + if 20000 <= t.default_dtid < 21000: + logger.warning('Overriding previously defined data type: [%s] [%s]', first, second) + return + if t.get_dsdl_signature() != value[1].get_dsdl_signature(): error('Redefinition of data type ID: [%s] [%s]', first, second) else: From fec3e66eeed393b7df6d63f445ca366ebea71e51 Mon Sep 17 00:00:00 2001 From: Alex Huttunen Date: Wed, 25 Feb 2026 14:25:26 -0800 Subject: [PATCH 2/3] dsdl files are still used as part of test_parser.py, so they should be tracked --- .gitignore | 3 --- 1 file changed, 3 deletions(-) diff --git a/.gitignore b/.gitignore index 7f4ffe1..297d42a 100644 --- a/.gitignore +++ b/.gitignore @@ -77,6 +77,3 @@ target/ # history .history - -# we don't have dsdl in this repo any more -dsdl/ From 33ec6afa4d7a4e7c4afc4bd68780aea1e2b7f977 Mon Sep 17 00:00:00 2001 From: Alex Huttunen Date: Wed, 25 Feb 2026 14:38:50 -0800 Subject: [PATCH 3/3] adjust tests to differentate between vendor and non-vendor DSDL overrides --- .../ns0_nonvendor_base/ns0/21000.Type0.uavcan | 1 + .../ns0/21000.Type0.uavcan | 1 + test/dsdl/test_parser.py | 20 ++++++++++++++----- 3 files changed, 17 insertions(+), 5 deletions(-) create mode 100644 test/dsdl/fake_dsdl/ns0_nonvendor_base/ns0/21000.Type0.uavcan create mode 100644 test/dsdl/fake_dsdl/ns0_nonvendor_redefined/ns0/21000.Type0.uavcan diff --git a/test/dsdl/fake_dsdl/ns0_nonvendor_base/ns0/21000.Type0.uavcan b/test/dsdl/fake_dsdl/ns0_nonvendor_base/ns0/21000.Type0.uavcan new file mode 100644 index 0000000..c5497ee --- /dev/null +++ b/test/dsdl/fake_dsdl/ns0_nonvendor_base/ns0/21000.Type0.uavcan @@ -0,0 +1 @@ +uint8 field0 diff --git a/test/dsdl/fake_dsdl/ns0_nonvendor_redefined/ns0/21000.Type0.uavcan b/test/dsdl/fake_dsdl/ns0_nonvendor_redefined/ns0/21000.Type0.uavcan new file mode 100644 index 0000000..2472b20 --- /dev/null +++ b/test/dsdl/fake_dsdl/ns0_nonvendor_redefined/ns0/21000.Type0.uavcan @@ -0,0 +1 @@ +uint16 field0 diff --git a/test/dsdl/test_parser.py b/test/dsdl/test_parser.py index 5d65089..0d09c09 100644 --- a/test/dsdl/test_parser.py +++ b/test/dsdl/test_parser.py @@ -37,15 +37,25 @@ def test_duplicate_in_search_dir(self): def test_redefinition_in_search_dir(self): ''' - Validate the parser does not allow redefinitions in the search dir + Validate that vendor-specific type IDs in [20000, 21000) are allowed to be + overridden in the search dir. ''' ns0_dir = '{}/fake_dsdl/ns0_base/ns0'.format(os.path.dirname(__file__)) ns0_dir_with_redefinition = '{}/fake_dsdl/ns0_redefined/ns0'.format(os.path.dirname(__file__)) - try: + + parse_namespaces([ns0_dir], [ns0_dir_with_redefinition]) + + def test_non_vendor_redefinition_in_search_dir(self): + ''' + Validate the parser does not allow redefinitions with differing signatures for + non-vendor type IDs (outside the [20000, 21000) vendor-override range). + ''' + ns0_dir = '{}/fake_dsdl/ns0_nonvendor_base/ns0'.format(os.path.dirname(__file__)) + ns0_dir_with_redefinition = '{}/fake_dsdl/ns0_nonvendor_redefined/ns0'.format(os.path.dirname(__file__)) + + with self.assertRaises(DsdlException) as context: parse_namespaces([ns0_dir], [ns0_dir_with_redefinition]) - self.assertTrue(False) # parse_namespaces should raise an exception, shouldn't get here - except DsdlException as e: - self.assertTrue(e.args[0].startswith("Redefinition of data type ID")) + self.assertTrue(context.exception.args[0].startswith("Redefinition of data type ID")) if __name__ == '__main__':