From ad41d25ff4789fbf7188a0a1737e5b70d006e28f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Est=C3=A9vez?= Date: Wed, 9 Apr 2025 15:26:38 +0200 Subject: [PATCH 1/4] take filenames with dots into account in get_sigmf_filenames() The function get_sigmf_filenames() does not work correctly if a file contains dots in the filename. These are interpretted as suffixes by pathlib, and a part of the filename can be removed when forming the different SigMF filenames. This fixes the problem by only considering as file extensions the canonical SigMF file extensions. Any other suffixes are treated as part of the filename and not removed. This fixes #106. --- sigmf/sigmffile.py | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/sigmf/sigmffile.py b/sigmf/sigmffile.py index 940b775..2005ddf 100644 --- a/sigmf/sigmffile.py +++ b/sigmf/sigmffile.py @@ -1111,11 +1111,26 @@ def get_sigmf_filenames(filename): ------- dict with 'data_fn', 'meta_fn', and 'archive_fn' as keys. """ - stem_path = Path(filename).with_suffix("") + stem_path = Path(filename) + # If the path has a sigmf suffix, remove it. Otherwise do not remove the + # suffix, because the filename might contain '.' characters which are part + # of the filename rather than an extension. + sigmf_suffixes = [ + SIGMF_DATASET_EXT, SIGMF_METADATA_EXT, + SIGMF_ARCHIVE_EXT, SIGMF_COLLECTION_EXT, + ] + if stem_path.suffix in sigmf_suffixes: + with_suffix_path = stem_path + stem_path = stem_path.with_suffix("") + else: + # Add a dummy suffix to prevent the .with_suffix() calls below from + # overriding part of the filename which is interpreted as a suffix + with_suffix_path = stem_path.with_name(f"{stem_path.name}{SIGMF_DATASET_EXT}") + return { "base_fn": stem_path, - "data_fn": stem_path.with_suffix(SIGMF_DATASET_EXT), - "meta_fn": stem_path.with_suffix(SIGMF_METADATA_EXT), - "archive_fn": stem_path.with_suffix(SIGMF_ARCHIVE_EXT), - "collection_fn": stem_path.with_suffix(SIGMF_COLLECTION_EXT), + "data_fn": with_suffix_path.with_suffix(SIGMF_DATASET_EXT), + "meta_fn": with_suffix_path.with_suffix(SIGMF_METADATA_EXT), + "archive_fn": with_suffix_path.with_suffix(SIGMF_ARCHIVE_EXT), + "collection_fn": with_suffix_path.with_suffix(SIGMF_COLLECTION_EXT), } From 510e378340f15deb353d702ea3725b8bcdff8842 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Est=C3=A9vez?= Date: Thu, 10 Apr 2025 09:27:00 +0200 Subject: [PATCH 2/4] fix SigMFCollection.get_SigMFFile() The get_SigMFFile() method was broken because it used ".sigmf_meta" instead of ".sigmf-meta". This rewrites the method to use get_sigmf_filenames(). --- sigmf/sigmffile.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sigmf/sigmffile.py b/sigmf/sigmffile.py index 2005ddf..ad75c97 100644 --- a/sigmf/sigmffile.py +++ b/sigmf/sigmffile.py @@ -915,13 +915,13 @@ def get_SigMFFile(self, stream_name=None, stream_index=None): """ Returns the SigMFFile instance of the specified stream if it exists """ - metafile = None - if stream_name is not None: - if stream_name in self.get_stream_names(): - metafile = stream_name + ".sigmf_meta" + if stream_name is not None and stream_name not in self.get_stream_names(): + # invalid stream name + return if stream_index is not None and stream_index < len(self): - metafile = self.get_stream_names()[stream_index] + ".sigmf_meta" - if metafile is not None: + stream_name = self.get_stream_names()[stream_index] + if stream_name is not None: + metafile = get_sigmf_filenames(stream_name)["meta_fn"] metafile_path = self.base_path / metafile return fromfile(metafile_path, skip_checksum=self.skip_checksums) From 3880517f5b3bbdfe7a746ef57b9b42330a59e26f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Est=C3=A9vez?= Date: Thu, 10 Apr 2025 09:34:10 +0200 Subject: [PATCH 3/4] test that SigMF files with . in the filename are loaded correctly This adds a unit test that shows that SigMF files like a.sigmf-meta, b.c.sigmf-meta, and d.e.f.sigmf-meta are all loaded correctly. --- tests/test_sigmffile.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/test_sigmffile.py b/tests/test_sigmffile.py index 0b792e4..99dea9e 100644 --- a/tests/test_sigmffile.py +++ b/tests/test_sigmffile.py @@ -43,6 +43,21 @@ def test_pathlib_handle(self): obj_pth = sigmffile.fromfile(self.temp_path_data) obj_pth.validate() + def test_filenames_with_dots(self): + """test that filenames with . characters are handled correctly""" + filenames = ["a", "b.c", "d.e.f"] + for filename in filenames: + temp_path_data = self.temp_dir / f"{filename}.sigmf-data" + temp_path_meta = self.temp_dir / f"{filename}.sigmf-meta" + TEST_FLOAT32_DATA.tofile(temp_path_data) + self.sigmf_object = SigMFFile(TEST_METADATA, data_file=temp_path_data) + self.sigmf_object.tofile(temp_path_meta) + files = [str(temp_path_data), temp_path_data, + str(temp_path_meta), temp_path_meta] + for f in files: + obj = sigmffile.fromfile(f) + obj.validate() + def test_iterator_basic(self): """make sure default batch_size works""" count = 0 From ceae657e4a5f0e354ddecd9f4e19f2bc7067f756 Mon Sep 17 00:00:00 2001 From: Teque5 Date: Thu, 10 Apr 2025 13:38:49 -0700 Subject: [PATCH 4/4] increment patch version --- sigmf/__init__.py | 2 +- tests/test_sigmffile.py | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/sigmf/__init__.py b/sigmf/__init__.py index 243d5ed..6af0426 100644 --- a/sigmf/__init__.py +++ b/sigmf/__init__.py @@ -5,7 +5,7 @@ # SPDX-License-Identifier: LGPL-3.0-or-later # version of this python module -__version__ = "1.2.8" +__version__ = "1.2.9" # matching version of the SigMF specification __specification__ = "1.2.3" diff --git a/tests/test_sigmffile.py b/tests/test_sigmffile.py index 99dea9e..290ebc8 100644 --- a/tests/test_sigmffile.py +++ b/tests/test_sigmffile.py @@ -44,7 +44,7 @@ def test_pathlib_handle(self): obj_pth.validate() def test_filenames_with_dots(self): - """test that filenames with . characters are handled correctly""" + """test that filenames with non-extension . characters are handled correctly""" filenames = ["a", "b.c", "d.e.f"] for filename in filenames: temp_path_data = self.temp_dir / f"{filename}.sigmf-data" @@ -52,10 +52,9 @@ def test_filenames_with_dots(self): TEST_FLOAT32_DATA.tofile(temp_path_data) self.sigmf_object = SigMFFile(TEST_METADATA, data_file=temp_path_data) self.sigmf_object.tofile(temp_path_meta) - files = [str(temp_path_data), temp_path_data, - str(temp_path_meta), temp_path_meta] - for f in files: - obj = sigmffile.fromfile(f) + files = [str(temp_path_data), temp_path_data, str(temp_path_meta), temp_path_meta] + for filename in files: + obj = sigmffile.fromfile(filename) obj.validate() def test_iterator_basic(self):