Skip to content

Commit 7abac6b

Browse files
Enforce ruff/bugbear rules (B) (#286)
* Enforce ruff/bugbear rule B018 B018 Found useless expression. Either assign it to a variable or remove it. * Enforce ruff/bugbear rule B009 B009 Do not call `getattr` with a constant attribute value. It is not any safer than normal property access. * Enforce ruff/bugbear rule B010 B010 Do not call `setattr` with a constant attribute value. It is not any safer than normal property access. * Enforce ruff/bugbear rule B032 B032 Possible unintentional type annotation (using `:`). Did you mean to assign (using `=`)? * Enforce ruff/bugbear rule B904 B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling * Enforce ruff/bugbear rule B007 B007 Loop control variable not used within loop body * Enforce ruff/bugbear rule B028 B028 No explicit `stacklevel` keyword argument found
1 parent 6652a16 commit 7abac6b

19 files changed

Lines changed: 153 additions & 152 deletions

bin/create_iods_modules.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,8 @@ def _create_modules(directory):
102102
# https://github.com/innolitics/dicom-standard/tree/master/standard
103103
try:
104104
directory = sys.argv[1]
105-
except IndexError:
106-
raise ValueError('Path to directory must be provided.')
105+
except IndexError as e:
106+
raise ValueError('Path to directory must be provided.') from e
107107
if not os.path.exists(directory):
108108
raise OSError(f'Path does not exist: "{directory}"')
109109
if not os.path.isdir(directory):

src/highdicom/_module_utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,8 @@ def check_required_attributes(
9292
for p in base_path:
9393
try:
9494
tree = tree['attributes'][p]
95-
except KeyError:
96-
raise AttributeError(f"Invalid base path: {base_path}.")
95+
except KeyError as e:
96+
raise AttributeError(f"Invalid base path: {base_path}.") from e
9797

9898
# Define recursive function
9999
def check(

src/highdicom/ann/content.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ def get_values(self, number_of_annotations: int) -> np.ndarray:
111111
f'annotation indices: {error}. This may either be due to '
112112
'incorrect encoding of the measurements or due to incorrectly '
113113
'specified "number_of_annotations".'
114-
)
114+
) from error
115115
return values
116116

117117
@classmethod
@@ -339,11 +339,11 @@ def __init__(
339339

340340
try:
341341
coordinates = np.concatenate(graphic_data, axis=0)
342-
except ValueError:
342+
except ValueError as e:
343343
raise ValueError(
344344
'Items of argument "graphic_data" must be arrays with the '
345345
'same dimensions.'
346-
)
346+
) from e
347347

348348
if coordinates.dtype.kind in ('u', 'i'):
349349
coordinates = coordinates.astype(np.float32)
@@ -420,8 +420,8 @@ def __init__(
420420
)
421421
try:
422422
measured_values = item.get_values(self.NumberOfAnnotations)
423-
except IndexError:
424-
raise ValueError(error_message)
423+
except IndexError as e:
424+
raise ValueError(error_message) from e
425425
if len(measured_values) != self.NumberOfAnnotations:
426426
# This should not occur, but safety first.
427427
raise ValueError(error_message)
@@ -541,10 +541,10 @@ def get_graphic_data(
541541
coordinate_dimensionality = 3
542542

543543
try:
544-
coordinates_data = getattr(self, 'DoublePointCoordinatesData')
544+
coordinates_data = self.DoublePointCoordinatesData
545545
coordinates_dtype = np.float64
546546
except AttributeError:
547-
coordinates_data = getattr(self, 'PointCoordinatesData')
547+
coordinates_data = self.PointCoordinatesData
548548
coordinates_dtype = np.float32
549549
decoded_coordinates_data = np.frombuffer(
550550
coordinates_data,

src/highdicom/color.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ def __init__(self, icc_profile: bytes):
8787
"""
8888
try:
8989
self._icc_transform = self._build_icc_transform(icc_profile)
90-
except OSError:
91-
raise ValueError('Could not read ICC Profile.')
90+
except OSError as e:
91+
raise ValueError('Could not read ICC Profile.') from e
9292

9393
def transform_frame(self, array: np.ndarray) -> np.ndarray:
9494
"""Transforms a frame by applying the ICC profile.
@@ -138,8 +138,10 @@ def _build_icc_transform(icc_profile: bytes) -> ImageCmsTransform:
138138
profile: bytes
139139
try:
140140
profile = ImageCmsProfile(BytesIO(icc_profile))
141-
except OSError:
142-
raise ValueError('Cannot read ICC Profile in image metadata.')
141+
except OSError as e:
142+
raise ValueError(
143+
'Cannot read ICC Profile in image metadata.'
144+
) from e
143145
name = getProfileName(profile).strip()
144146
description = getProfileDescription(profile).strip()
145147
logger.debug(f'found ICC Profile "{name}": "{description}"')

src/highdicom/content.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1352,7 +1352,7 @@ def from_dataset(
13521352
)
13531353
processing_type = processing_type_items[0].value
13541354

1355-
instance._processing_procedure: Union[
1355+
instance._processing_procedure: Union[ # noqa: B032
13561356
SpecimenCollection,
13571357
SpecimenSampling,
13581358
SpecimenStaining,

src/highdicom/io.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -312,12 +312,14 @@ def open(self) -> None:
312312
if self._fp is None:
313313
try:
314314
self._fp = DicomFile(str(self._filename), mode='rb')
315-
except FileNotFoundError:
316-
raise FileNotFoundError(f'File not found: "{self._filename}"')
317-
except Exception:
315+
except FileNotFoundError as e:
316+
raise FileNotFoundError(
317+
f'File not found: "{self._filename}"'
318+
) from e
319+
except Exception as e:
318320
raise OSError(
319321
f'Could not open file for reading: "{self._filename}"'
320-
)
322+
) from e
321323
is_little_endian, is_implicit_VR = self._check_file_format(self._fp)
322324
self._fp.is_little_endian = is_little_endian
323325
self._fp.is_implicit_VR = is_implicit_VR
@@ -377,7 +379,9 @@ def _read_metadata(self) -> None:
377379
try:
378380
metadata = dcmread(self._fp, stop_before_pixels=True)
379381
except Exception as err:
380-
raise OSError(f'DICOM metadata cannot be read from file: "{err}"')
382+
raise OSError(
383+
f'DICOM metadata cannot be read from file: "{err}"'
384+
) from err
381385

382386
# Cache Transfer Syntax UID, since we need it to decode frame items
383387
self._transfer_syntax_uid = UID(metadata.file_meta.TransferSyntaxUID)
@@ -391,10 +395,10 @@ def _read_metadata(self) -> None:
391395
# Determine whether dataset contains a Pixel Data element
392396
try:
393397
tag = TupleTag(self._fp.read_tag())
394-
except EOFError:
398+
except EOFError as e:
395399
raise ValueError(
396400
'Dataset does not represent an image information entity.'
397-
)
401+
) from e
398402
if int(tag) not in _PIXEL_DATA_TAGS:
399403
raise ValueError(
400404
'Dataset does not represent an image information entity.'
@@ -412,7 +416,9 @@ def _read_metadata(self) -> None:
412416
try:
413417
self._basic_offset_table = _get_bot(self._fp, number_of_frames)
414418
except Exception as err:
415-
raise OSError(f'Failed to build Basic Offset Table: "{err}"')
419+
raise OSError(
420+
f'Failed to build Basic Offset Table: "{err}"'
421+
) from err
416422
self._first_frame_offset = self._fp.tell()
417423
else:
418424
if self._fp.is_implicit_VR:

src/highdicom/ko/sop.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,11 +177,11 @@ def resolve_reference(self, sop_instance_uid: str) -> Tuple[str, str, str]:
177177
"""
178178
try:
179179
return self._reference_lut[sop_instance_uid]
180-
except KeyError:
180+
except KeyError as e:
181181
raise ValueError(
182182
'Could not find any evidence for SOP Instance UID '
183183
f'"{sop_instance_uid}" in KOS document.'
184-
)
184+
) from e
185185

186186
@classmethod
187187
def from_dataset(cls, dataset: Dataset) -> 'KeyObjectSelectionDocument':

src/highdicom/legacy/sop.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,10 @@ def _convert_legacy_to_enhanced(
6262
from highdicom._modules import MODULE_ATTRIBUTE_MAP
6363
try:
6464
ref_ds = sf_datasets[0]
65-
except IndexError:
66-
raise ValueError('No data sets of single-frame legacy images provided.')
65+
except IndexError as e:
66+
raise ValueError(
67+
'No data sets of single-frame legacy images provided.'
68+
) from e
6769

6870
if mf_dataset is None:
6971
mf_dataset = Dataset()
@@ -166,7 +168,7 @@ def _convert_legacy_to_enhanced(
166168

167169
# Per-Frame Functional Groups
168170
perframe_items = []
169-
for i, ds in enumerate(sf_datasets):
171+
for ds in sf_datasets:
170172
perframe_item = Dataset()
171173

172174
# Frame Content (M)
@@ -334,7 +336,7 @@ def _convert_legacy_to_enhanced(
334336
Dataset()
335337
for _ in range(len(sf_datasets))
336338
]
337-
for tag, dataelements in unassigned_dataelements.items():
339+
for _tag, dataelements in unassigned_dataelements.items():
338340
values = [str(da.value) for da in dataelements]
339341
unique_values = set(values)
340342
if len(unique_values) == 1:
@@ -455,8 +457,8 @@ def __init__(
455457

456458
try:
457459
ref_ds = legacy_datasets[0]
458-
except IndexError:
459-
raise ValueError('No DICOM data sets of provided.')
460+
except IndexError as e:
461+
raise ValueError('No DICOM data sets of provided.') from e
460462

461463
if ref_ds.Modality != 'MR':
462464
raise ValueError(
@@ -548,8 +550,8 @@ def __init__(
548550

549551
try:
550552
ref_ds = legacy_datasets[0]
551-
except IndexError:
552-
raise ValueError('No DICOM data sets of provided.')
553+
except IndexError as e:
554+
raise ValueError('No DICOM data sets of provided.') from e
553555

554556
if ref_ds.Modality != 'CT':
555557
raise ValueError(
@@ -627,8 +629,8 @@ def __init__(
627629

628630
try:
629631
ref_ds = legacy_datasets[0]
630-
except IndexError:
631-
raise ValueError('No DICOM data sets of provided.')
632+
except IndexError as e:
633+
raise ValueError('No DICOM data sets of provided.') from e
632634

633635
if ref_ds.Modality != 'PT':
634636
raise ValueError(

src/highdicom/pm/sop.py

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -456,8 +456,8 @@ def __init__(
456456
sffg_item.RealWorldValueMappingSequence = real_world_value_mappings
457457
try:
458458
real_world_value_mappings[0]
459-
except IndexError:
460-
raise TypeError(error_message)
459+
except IndexError as e:
460+
raise TypeError(error_message) from e
461461
if not isinstance(
462462
real_world_value_mappings[0],
463463
RealWorldValueMapping
@@ -479,8 +479,8 @@ def __init__(
479479
)
480480
try:
481481
real_world_value_mappings[0][0]
482-
except IndexError:
483-
raise TypeError(error_message)
482+
except IndexError as e:
483+
raise TypeError(error_message) from e
484484
if not isinstance(
485485
real_world_value_mappings[0][0],
486486
RealWorldValueMapping
@@ -700,13 +700,8 @@ def __init__(
700700
palette_color_lut_transformation,
701701
'PaletteColorLookupTableUID'
702702
):
703-
setattr(
704-
self,
705-
'PaletteColorLookupTableUID',
706-
getattr(
707-
palette_color_lut_transformation,
708-
'PaletteColorLookupTableUID'
709-
)
703+
self.PaletteColorLookupTableUID = (
704+
palette_color_lut_transformation.PaletteColorLookupTableUID
710705
)
711706
else:
712707
self.PixelPresentation = 'MONOCHROME'

src/highdicom/seg/sop.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1992,7 +1992,8 @@ def __init__(
19921992
"Setting workers != 0 or passing an instance of "
19931993
"concurrent.futures.Executor when using a non-encapsulated "
19941994
"transfer syntax has no effect.",
1995-
UserWarning
1995+
UserWarning,
1996+
stacklevel=2,
19961997
)
19971998
using_multiprocessing = False
19981999

@@ -2061,7 +2062,7 @@ def __init__(
20612062
'Could not determine position of plane '
20622063
f'#{plane_index} in three dimensional coordinate '
20632064
f'system based on dimension index values: {error}'
2064-
)
2065+
) from error
20652066
else:
20662067
dimension_index_values = []
20672068

0 commit comments

Comments
 (0)