From a38c6e1284620de2864cb1f9cc7d45228bab1e93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leonard=20N=C3=BCrnberg?= Date: Tue, 23 Jul 2024 14:05:17 +0200 Subject: [PATCH] update linter config and resolve lint and pylint errors --- pyproject.toml | 5 +++- src/pydcmqi/segimage.py | 51 +++++++++++++++++++++++++++++++---------- tests/test_segimage.py | 5 +++- 3 files changed, 47 insertions(+), 14 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 5b91df9..cab7973 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -139,7 +139,9 @@ extend-select = [ ignore = [ "PLR09", # Too many <...> "PLR2004", # Magic value used in comparison - "ISC001", # Conflicts with formatter + "ISC001", # Conflicts with formatter, + "EM101", # Exception must not use a string literal, assign to variable first + "EM102", # Exception must not use an f-string literal, assign to variable first ] isort.required-imports = ["from __future__ import annotations"] # Uncomment if using a _compat.typing backport @@ -162,4 +164,5 @@ messages_control.disable = [ "missing-module-docstring", "missing-function-docstring", "wrong-import-position", + "C0103", # Attribute name doesn't conform to snake_case naming style ] diff --git a/src/pydcmqi/segimage.py b/src/pydcmqi/segimage.py index 4e81f2b..fd5ef24 100644 --- a/src/pydcmqi/segimage.py +++ b/src/pydcmqi/segimage.py @@ -17,9 +17,9 @@ def get_min_max_values(image: sitk.Image) -> tuple[float, float]: - filter = sitk.MinimumMaximumImageFilter() - filter.Execute(image) - return filter.GetMinimum(), filter.GetMaximum() + sitk_filter = sitk.MinimumMaximumImageFilter() + sitk_filter.Execute(image) + return sitk_filter.GetMinimum(), sitk_filter.GetMaximum() def _path(path: str | Path) -> Path: @@ -42,7 +42,6 @@ class Triplet: - `code value`, a unique identifier - `coding scheme designator`, the issuer of the code value """ - @staticmethod def fromDict(d: TripletDict) -> Triplet: """ @@ -120,9 +119,25 @@ class SegmentData: """ A class to store and manipulate the data for a segmentation or region of interest. """ - def __init__(self) -> None: - self._data: SegmentDict = {} + self._data: SegmentDict = { + "labelID": 0, + "SegmentLabel": "", + "SegmentDescription": "", + "SegmentAlgorithmName": "", + "SegmentAlgorithmType": "", + "recommendedDisplayRGBValue": [0, 0, 0], + "SegmentedPropertyCategoryCodeSequence": { + "CodeMeaning": "", + "CodeValue": "", + "CodingSchemeDesignator": "", + }, + "SegmentedPropertyTypeCodeSequence": { + "CodeMeaning": "", + "CodeValue": "", + "CodingSchemeDesignator": "", + }, + } def setConfigData(self, config: dict) -> None: self._data = config.copy() @@ -319,6 +334,9 @@ def hasAnatomicRegionModifier(self) -> bool: class Segment: + """ + A class to store and manipulate the data for a segmentation or region of interest. + """ def __init__(self) -> None: self.path: Path | None = None self.data = SegmentData() @@ -426,6 +444,9 @@ def saveAsBinary(self, path: str | Path) -> None: class SegImageData: + """ + A class to store and manipulate the data for a segmentation or region of interest. + """ def __init__(self) -> None: self._data: SegImageDict = {} @@ -511,6 +532,9 @@ def asdict(self) -> SegImageDict: class SegImageFiles: + """ + A class to store and manipulate the file paths for a segmentation or region of interest. + """ def __init__(self) -> None: self._dicomseg: Path | None = None self._config: Path | None = None @@ -525,6 +549,9 @@ def config(self) -> Path | None: class SegImage: + """ + A class to store and manipulate the data for a segmentation or region of interest. + """ verbose: bool = False @classmethod @@ -563,7 +590,7 @@ def load( dicomseg_file: Path | str, output_dir: Path | str | None = None, ) -> bool: - print(f"Converting file: {dicomseg_file} into {output_dir}.") + # print(f"Converting file: {dicomseg_file} into {output_dir}.") # TODO: use logging # we create a temporary output directory if none is provided in the specified tmp dir if output_dir is None: @@ -594,7 +621,7 @@ def load( self._import(output_dir) # update file paths - self.files._dicomseg = dicomseg_file + self.files._dicomseg = dicomseg_file # pylint: disable=W0212 def _import( self, output_dir: Path, disable_file_sanity_checks: bool = False @@ -610,7 +637,7 @@ def _import( config_file = output_dir / "pydcmqi-meta.json" # load the config file - with Path.open(config_file) as f: + with Path.open(config_file, encoding="utf-8") as f: self._config = json.load(f) # load data @@ -635,7 +662,7 @@ def _import( self.loaded = True # store file paths - self.files._config = config_file + self.files._config = config_file # pylint: disable=W0212 def write( self, @@ -678,11 +705,11 @@ def write( # store in the output directory # but for now just print - print(json.dumps(config, indent=2)) + # print(json.dumps(config, indent=2)) # TODO: use logging # store in _debug_test_meta.json meta_tmp_file = Path(self.tmp_dir) / "_debug_test_meta.json" - with Path.open(meta_tmp_file, "w") as f: + with Path.open(meta_tmp_file, "w", encoding="utf-8") as f: json.dump(config, f, indent=2) # export config file if requested diff --git a/tests/test_segimage.py b/tests/test_segimage.py index 301e7ae..6694b57 100644 --- a/tests/test_segimage.py +++ b/tests/test_segimage.py @@ -168,7 +168,10 @@ def test_tmp_dir(self): assert isinstance(segimg4.tmp_dir, Path) # specifying a tmp_dir with e.g. a numeric type will raise an ValueError - with pytest.raises(ValueError): + with pytest.raises( + ValueError, + match="Invalid tmp_dir, must be either None for default, a Path or a string.", + ): _ = SegImage(tmp_dir=1)