diff --git a/package/PartSeg/_roi_analysis/batch_window.py b/package/PartSeg/_roi_analysis/batch_window.py index 54f1bcad0..260aa9b96 100644 --- a/package/PartSeg/_roi_analysis/batch_window.py +++ b/package/PartSeg/_roi_analysis/batch_window.py @@ -65,7 +65,7 @@ def save( range_changed=None, step_changed=None, ): - pass + """empty function to satisfy interface""" @classmethod def get_name(cls) -> str: diff --git a/package/PartSeg/_roi_analysis/prepare_plan_widget.py b/package/PartSeg/_roi_analysis/prepare_plan_widget.py index 69a5897bf..c7514706b 100644 --- a/package/PartSeg/_roi_analysis/prepare_plan_widget.py +++ b/package/PartSeg/_roi_analysis/prepare_plan_widget.py @@ -1047,7 +1047,7 @@ def update_view(self, reset=False): QTreeWidgetItem(child, [line]) else: - logging.error(f"Unknown operation {op_type}") + logging.error("Unknown operation %s", op_type) # pragma: no cover self.blockSignals(False) self.set_path() self.changed_node.emit() diff --git a/package/PartSeg/common_gui/algorithms_description.py b/package/PartSeg/common_gui/algorithms_description.py index 3c02adfbf..05b994b6a 100644 --- a/package/PartSeg/common_gui/algorithms_description.py +++ b/package/PartSeg/common_gui/algorithms_description.py @@ -122,7 +122,7 @@ def set_value(self, val): try: return self._setter(self._widget, val) except (TypeError, ValueError) as e: - logging.error(f"Error {e} setting value {val} to {self.name}") + logging.error("Error %s setting value %s to %s", e, val, self.name) def get_field(self) -> QWidget: """ diff --git a/package/PartSeg/common_gui/flow_layout.py b/package/PartSeg/common_gui/flow_layout.py index 754aafefa..84c2a4646 100644 --- a/package/PartSeg/common_gui/flow_layout.py +++ b/package/PartSeg/common_gui/flow_layout.py @@ -73,7 +73,7 @@ def addLayout(self, layout): self.itemList.append(layout) def addStretch(self): - pass + """To satisfy the QLayout API""" def count(self): return len(self.itemList) diff --git a/package/PartSeg/common_gui/napari_image_view.py b/package/PartSeg/common_gui/napari_image_view.py index 234e44c31..59a348051 100644 --- a/package/PartSeg/common_gui/napari_image_view.py +++ b/package/PartSeg/common_gui/napari_image_view.py @@ -1031,8 +1031,8 @@ def _calc_layer_filter(layer: NapariImage, filter_type: NoiseFilterType, radius: def _print_dict(dkt: MutableMapping, indent="") -> str: - if not isinstance(dkt, MutableMapping): - logging.error(f"{type(dkt)} instead of dict passed to _print_dict") + if not isinstance(dkt, MutableMapping): # pragma: no cover + logging.error("%s instead of dict passed to _print_dict", type(dkt)) return indent + str(dkt) res = [] for k, v in dkt.items(): diff --git a/package/PartSeg/plugins/old_partseg/old_partseg.py b/package/PartSeg/plugins/old_partseg/old_partseg.py index fd842a61a..93ca99046 100644 --- a/package/PartSeg/plugins/old_partseg/old_partseg.py +++ b/package/PartSeg/plugins/old_partseg/old_partseg.py @@ -38,8 +38,7 @@ def _load(cls, tar_file: tarfile.TarFile, file_path: str) -> ProjectTuple: seg_array = np.load(res_buffer) except KeyError: seg_array = None - algorithm_str = tar_file.extractfile("data.json").read() - algorithm_dict = json.loads(algorithm_str) + algorithm_dict = json.load(tar_file.extractfile("data.json")) spacing = np.array(algorithm_dict["spacing"][::-1]) / UNIT_SCALE[Units.nm.value] image = Image(image_arr.reshape((1,) + image_arr.shape + (1,)), spacing, file_path, axes_order="TZYXC") values = { diff --git a/package/PartSegCore/analysis/batch_processing/batch_backend.py b/package/PartSegCore/analysis/batch_processing/batch_backend.py index b34b5d5f0..0fec0c613 100644 --- a/package/PartSegCore/analysis/batch_processing/batch_backend.py +++ b/package/PartSegCore/analysis/batch_processing/batch_backend.py @@ -476,7 +476,7 @@ def set_number_of_workers(self, val: int): :param int val: number of workers. """ - logging.debug(f"Number off process {val}") + logging.debug("Number off process %s", val) self.batch_manager.set_number_of_process(val) def get_results(self) -> BatchResultDescription: @@ -764,7 +764,7 @@ def wrote_data_to_file(self): if i == 100: # pragma: no cover raise PermissionError(f"Fail to write result excel {self.file_path}") except Exception as e: # pragma: no cover # pylint: disable=W0703 - logging.error(f"[batch_backend] {e}") + logging.error("[batch_backend] %s", e) self.error_queue.put(prepare_error_data(e)) finally: self.writing = False diff --git a/package/PartSegCore/analysis/batch_processing/parallel_backend.py b/package/PartSegCore/analysis/batch_processing/parallel_backend.py index d11e7aee3..b919c94e4 100644 --- a/package/PartSegCore/analysis/batch_processing/parallel_backend.py +++ b/package/PartSegCore/analysis/batch_processing/parallel_backend.py @@ -159,11 +159,11 @@ def cancel_work(self, global_parameters): del self.calculation_dict[global_parameters.uuid] def join_all(self): - logging.debug(f"Join begin {len(self.process_list)} {self.number_off_process}") + logging.debug("Join begin %s %s", len(self.process_list), self.number_off_process) with self.locker: if len(self.process_list) > self.number_off_process: to_remove = [] - logging.debug(f"Process list start {self.process_list}") + logging.debug("Process list start %s", self.process_list) for p in self.process_list: if not p.is_alive(): p.join() @@ -172,12 +172,15 @@ def join_all(self): for p in to_remove: self.process_list.remove(p) self.number_off_alive_process -= len(to_remove) - logging.debug(f"Process list end {self.process_list}") + logging.debug("Process list end %s", self.process_list) # FIXME self.number_off_alive_process, self.number_off_process negative values if len(self.process_list) > self.number_off_process and len(self.process_list) > 0: logging.info( - f"Wait on process, time {time.time()}, {self.number_off_alive_process}," - f" {len(self.process_list)}, {self.number_off_process}" + "Wait on process, time %s, %s, %s, %s", + time.time(), + self.number_off_alive_process, + len(self.process_list), + self.number_off_process, ) Timer(1, self.join_all).start() @@ -235,12 +238,12 @@ def calculate_task(self, val: Tuple[Any, uuid.UUID]): def run(self): """Worker main loop""" - logging.debug(f"Process started {os.getpid()}") + logging.debug("Process started %s", os.getpid()) while True: if not self.order_queue.empty(): with suppress(Empty): order = self.order_queue.get_nowait() - logging.debug(f"Order message: {order}") + logging.debug("Order message: %s", order) if order == SubprocessOrder.kill: break if not self.task_queue.empty(): @@ -253,10 +256,10 @@ def run(self): except (MemoryError, OSError): # pragma: no cover pass except Exception as ex: # pragma: no cover # pylint: disable=W0703 - logging.warning(f"Unsupported exception {ex}") + logging.warning("Unsupported exception %s", ex) else: time.sleep(0.1) - logging.info(f"Process {os.getpid()} ended") + logging.info("Process %s ended", os.getpid()) def spawn_worker(task_queue: Queue, order_queue: Queue, result_queue: Queue, calculation_dict: Dict[uuid.UUID, Any]): diff --git a/package/PartSegCore/analysis/calculate_pipeline.py b/package/PartSegCore/analysis/calculate_pipeline.py index d595a7d8b..e82bcef4f 100644 --- a/package/PartSegCore/analysis/calculate_pipeline.py +++ b/package/PartSegCore/analysis/calculate_pipeline.py @@ -15,7 +15,7 @@ def _empty_fun(_a1, _a2): - pass + """Empty function for calculation run callback""" @dataclass(frozen=True) diff --git a/package/PartSegCore/analysis/calculation_plan.py b/package/PartSegCore/analysis/calculation_plan.py index 3b349d1c3..1e13cd79f 100644 --- a/package/PartSegCore/analysis/calculation_plan.py +++ b/package/PartSegCore/analysis/calculation_plan.py @@ -255,16 +255,16 @@ def set_map_path(self, value): self.path_to_file = value def parse_map(self, sep=";"): - if not os.path.exists(self.path_to_file): - logging.error(f"File does not exists: {self.path_to_file}") + if not os.path.exists(self.path_to_file): # pragma: no cover + logging.error("File does not exists: %s", self.path_to_file) raise ValueError(f"File for mapping mask does not exists: {self.path_to_file}") with open(self.path_to_file, encoding="utf-8") as map_file: dir_name = os.path.dirname(self.path_to_file) for i, line in enumerate(map_file): try: file_name, mask_name = line.split(sep) - except ValueError: - logging.error(f"Error in parsing map file\nline {i}\n{line}\nfrom file{self.path_to_file}") + except ValueError: # pragma: no cover + logging.error("Error in parsing map file\nline %s\n%s\nfrom file %s", i, line, self.path_to_file) continue file_name = file_name.strip() mask_name = mask_name.strip() @@ -710,7 +710,7 @@ def get_el_name(el): # noqa C901 :param el: Plan element :return: str """ - if el.__class__.__name__ not in CalculationPlan.correct_name.keys(): + if el.__class__.__name__ not in CalculationPlan.correct_name: print(el, el.__class__.__name__, file=sys.stderr) raise ValueError(f"Unknown type {el.__class__.__name__}") if isinstance(el, RootType): diff --git a/package/PartSegCore/class_generator.py b/package/PartSegCore/class_generator.py index 946f9bfeb..c40289aed 100644 --- a/package/PartSegCore/class_generator.py +++ b/package/PartSegCore/class_generator.py @@ -187,8 +187,7 @@ def add_classes(types_list, translate_dict, global_state): continue if hasattr(type_, "__module__") and type_.__module__ == "typing": if hasattr(type_, "__args__") and isinstance(type_.__args__, collections.abc.Iterable): - sub_types = [x for x in type_.__args__ if not isinstance(x, omit_list)] - if sub_types: + if sub_types := [x for x in type_.__args__ if not isinstance(x, omit_list)]: add_classes(sub_types, translate_dict, global_state) if type_._name is None: # pylint: disable=W0212 type_str = str(type_.__origin__) @@ -251,8 +250,7 @@ def _make_class(typename, types, defaults_dict, base_classes, readonly): field_definitions = "" init_sig = [f"self.{f_name} = {v_name}" for f_name, v_name in zip(slots, type_dict.keys())] tuple_list = [f"self.{name_}" for name_ in slots] - init_content = "\n ".join(init_sig) - init_content += "\n self.__post_init__()" + init_content = "\n ".join(init_sig) + "\n self.__post_init__()" class_definition = _class_template.format( imports="\n".join(import_set), typename=typename, @@ -268,7 +266,7 @@ def _make_class(typename, types, defaults_dict, base_classes, readonly): base_classes=", ".join(translate_dict[x] for x in base_classes), ) - global_state["__name__"] = "serialize_%s" % typename + global_state["__name__"] = f"serialize_{typename}" try: # pylint: disable=W0122 exec(class_definition, global_state) # nosec @@ -291,9 +289,9 @@ def _make_class(typename, types, defaults_dict, base_classes, readonly): class BaseMeta(type): - def __new__(mcs, name, bases, attrs): + def __new__(cls, name, bases, attrs): if attrs.get("_root", False): - return super().__new__(mcs, name, bases, attrs) + return super().__new__(cls, name, bases, attrs) warnings.warn( "BaseSerializableClass is deprecated, use pydantic.BaseModel instead", FutureWarning, stacklevel=2 ) @@ -352,23 +350,23 @@ class BaseSerializableClass(metaclass=BaseMeta): __old_names__ = () def __init__(self, *args, **kwargs): - pass + """declare interface""" def __post_init__(self): - pass + """declare interface""" def asdict(self) -> collections.OrderedDict: - pass + """declare interface""" def replace_(self, **_kwargs): return self def as_tuple(self) -> typing.Tuple: - pass + """declare interface""" @classmethod def make_(cls, iterable): - pass + """declare interface""" class SerializeClassEncoder(json.JSONEncoder): diff --git a/package/PartSegImage/image_reader.py b/package/PartSegImage/image_reader.py index eea113f6c..18be52b53 100644 --- a/package/PartSegImage/image_reader.py +++ b/package/PartSegImage/image_reader.py @@ -7,11 +7,10 @@ from threading import Lock import numpy as np -import tifffile.tifffile +import tifffile from czifile.czifile import CziFile from defusedxml import ElementTree from oiffile import OifFile -from tifffile import TiffFile, natural_sorted from PartSegImage.image import Image @@ -71,7 +70,7 @@ def read(self, image_path: typing.Union[str, Path], mask_path=None, ext=None) -> :param image_path: path to image or buffer :param mask_path: path to mask or buffer - :param ext: extension if need to decide algorithm, if absent and image_path is path then + :param ext: extension to decide algorithm, if absent and image_path is path then should be deduced from path :return: image structure """ @@ -107,7 +106,7 @@ def update_array_shape(cls, array: np.ndarray, axes: str): Rearrange order of array axes to get proper internal axes order :param array: array to reorder - :param axes_li: current order of array axes as string like "TZYXC" + :param axes: current order of array axes as string like "TZYXC" """ try: final_mapping_dict = {letter: i for i, letter in enumerate(cls.return_order())} @@ -206,33 +205,36 @@ def read(self, image_path: typing.Union[str, BytesIO, Path], mask_path=None, ext class OifImagReader(BaseImageReader): def read(self, image_path: typing.Union[str, Path], mask_path=None, ext=None) -> Image: with OifFile(image_path) as image_file: - tiffs = natural_sorted(image_file.glob("*.tif")) - with TiffFile(image_file.open_file(tiffs[0]), name=tiffs[0]) as tif_file: + tiffs = tifffile.natural_sorted(image_file.glob("*.tif")) + with tifffile.TiffFile(image_file.open_file(tiffs[0]), name=tiffs[0]) as tif_file: axes = image_file.series[0].axes + tif_file.series[0].axes image_data = image_file.asarray() image_data = self.update_array_shape(image_data, axes) with suppress(KeyError): - flat_parm = image_file.mainfile["Reference Image Parameter"] - x_scale = flat_parm["HeightConvertValue"] * name_to_scalar[flat_parm["HeightUnit"]] - y_scale = flat_parm["WidthConvertValue"] * name_to_scalar[flat_parm["WidthUnit"]] - i = 0 - while True: - name = f"Axis {i} Parameters Common" - if name not in image_file.mainfile: - z_scale = 1 - break - axis_info = image_file.mainfile[name] - if axis_info["AxisCode"] == "Z": - z_scale = axis_info["Interval"] * name_to_scalar[axis_info["UnitName"]] - break - i += 1 - - self.spacing = z_scale, x_scale, y_scale - # TODO add mask reading + self._read_scale_parameter(image_file) + # TODO add mask reading return self.image_class( image_data, self.spacing, file_path=os.path.abspath(image_path), axes_order=self.return_order() ) + def _read_scale_parameter(self, image_file): + flat_parm = image_file.mainfile["Reference Image Parameter"] + x_scale = flat_parm["HeightConvertValue"] * name_to_scalar[flat_parm["HeightUnit"]] + y_scale = flat_parm["WidthConvertValue"] * name_to_scalar[flat_parm["WidthUnit"]] + i = 0 + while True: + name = f"Axis {i} Parameters Common" + if name not in image_file.mainfile: # pragma: no cover + z_scale = 1 + break + axis_info = image_file.mainfile[name] + if axis_info["AxisCode"] == "Z": + z_scale = axis_info["Interval"] * name_to_scalar[axis_info["UnitName"]] + break + i += 1 + + self.spacing = z_scale, x_scale, y_scale + class CziImageReader(BaseImageReaderBuffer): """ @@ -286,8 +288,8 @@ def read(self, image_path: typing.Union[str, Path], mask_path=None, ext=None) -> for channel in channels: try: name = next(iter(channel)).attrib["val"] - except StopIteration: # pragma: no cover - raise ValueError("Missed information about channel name in obsep file") + except StopIteration as e: # pragma: no cover + raise ValueError("Missed information about channel name in obsep file") from e for ex in possible_extensions: if (directory / (name + ex)).exists(): name += ex @@ -298,8 +300,8 @@ def read(self, image_path: typing.Union[str, Path], mask_path=None, ext=None) -> for channel in channels: try: name = next(iter(channel)).attrib["val"] + "_deconv" - except StopIteration: # pragma: no cover - raise ValueError("Missed information about channel name in obsep file") + except StopIteration as e: # pragma: no cover + raise ValueError("Missed information about channel name in obsep file") from e for ex in possible_extensions: if (directory / (name + ex)).exists(): name += ex @@ -324,8 +326,8 @@ class TiffImageReader(BaseImageReaderBuffer): """ TIFF/LSM files reader. Base reading with :py:meth:`BaseImageReader.read_image` - image_file: TiffFile - mask_file: TiffFile + image_file: tifffile.TiffFile + mask_file: tifffile.TiffFile """ def __init__(self, callback_function=None): @@ -341,7 +343,7 @@ def read(self, image_path: typing.Union[str, BytesIO, Path], mask_path=None, ext Read tiff image from tiff_file """ self.spacing, self.colors, self.channel_names, self.ranges = self.default_spacing, None, None, None - with TiffFile(image_path) as image_file: + with tifffile.TiffFile(image_path) as image_file: total_pages_num = len(image_file.series[0]) axes = image_file.series[0].axes @@ -353,8 +355,8 @@ def read(self, image_path: typing.Union[str, BytesIO, Path], mask_path=None, ext elif image_file.is_ome: self.read_ome_metadata(image_file) else: - x_spac, y_spac = self.read_resolution_from_tags(image_file) - self.spacing = self.default_spacing[0], y_spac, x_spac + x_spacing, y_spacing = self.read_resolution_from_tags(image_file) + self.spacing = self.default_spacing[0], x_spacing, y_spacing mutex = Lock() count_pages = [0] @@ -365,7 +367,7 @@ def report_func(): mutex.release() if mask_path is not None: - with TiffFile(mask_path) as mask_file: + with tifffile.TiffFile(mask_path) as mask_file: self.callback_function("max", total_pages_num + len(mask_file.series[0])) self.verify_mask(mask_file, image_file) mask_file.report_func = report_func @@ -417,8 +419,8 @@ def verify_mask(mask_file, image_file): continue try: j = image_series.axes.index(pos) - except ValueError: # pragma: no cover - raise ValueError(f"{INCOMPATIBLE_IMAGE_MASK} (axes)") + except ValueError as e: # pragma: no cover + raise ValueError(f"{INCOMPATIBLE_IMAGE_MASK} (axes)") from e # TODO add verification if problem with T/Z/I if image_series.shape[j] != mask_series.shape[i]: # pragma: no cover raise ValueError(INCOMPATIBLE_IMAGE_MASK) @@ -521,4 +523,4 @@ def read_lsm_metadata(self, image_file): "centimeter": 10**-2, "cm": 10**-2, "cal": 2.54 * 10**-2, -} #: dict with known names of scalar to scalar value. May be some missed +} #: dict with known names of scalar to scalar value. Some may be missed diff --git a/package/tests/test_PartSeg/roi_analysis/test_advanced_window.py b/package/tests/test_PartSeg/roi_analysis/test_advanced_window.py index 2388373bb..d9bb31445 100644 --- a/package/tests/test_PartSeg/roi_analysis/test_advanced_window.py +++ b/package/tests/test_PartSeg/roi_analysis/test_advanced_window.py @@ -169,4 +169,7 @@ def _check(*_, text=None, **_kwargs): def _empty(): - pass + """ + Empty function for monkeypatching to prevent recursive call + in `test_rename_profile` test + """ diff --git a/package/tests/test_PartSeg/test_analysis.py b/package/tests/test_PartSeg/test_analysis.py index 2fc3c9887..241468352 100644 --- a/package/tests/test_PartSeg/test_analysis.py +++ b/package/tests/test_PartSeg/test_analysis.py @@ -1,22 +1,20 @@ # pylint: disable=R0201 +from unittest.mock import patch import numpy as np import pytest from qtpy.QtCore import QEvent from qtpy.QtWidgets import QApplication, QCheckBox -from PartSeg._roi_analysis.measurement_widget import MeasurementsStorage, MeasurementWidget, QMessageBox +from PartSeg._roi_analysis.measurement_widget import MeasurementsStorage, MeasurementWidget from PartSeg._roi_mask.simple_measurements import SimpleMeasurements from PartSegCore.analysis.measurement_base import AreaType, PerComponent from PartSegCore.analysis.measurement_calculation import ComponentsInfo, MeasurementResult class TestMeasurementWidget: - def test_missed_mask(self, qtbot, analysis_segmentation, part_settings, monkeypatch): - def simple(*args, **kwargs): - pass - - monkeypatch.setattr(QMessageBox, "information", simple) + @patch("PartSeg._roi_analysis.measurement_widget.QMessageBox") + def test_missed_mask(self, qmessagebox_path, qtbot, analysis_segmentation, part_settings, monkeypatch): widget = MeasurementWidget(part_settings) qtbot.addWidget(widget) @@ -27,6 +25,8 @@ def simple(*args, **kwargs): widget.measurement_type.setCurrentIndex(2) assert widget.measurement_type.currentIndex() == 0 assert not widget.recalculate_button.isEnabled() + qmessagebox_path.information.assert_called_once() + assert qmessagebox_path.information.call_args[0][1] == "Need mask" @pytest.mark.enablethread @pytest.mark.enabledialog diff --git a/package/tests/test_PartSeg/test_roi_analysis_batch.py b/package/tests/test_PartSeg/test_roi_analysis_batch.py index 1844d1221..53ccd0139 100644 --- a/package/tests/test_PartSeg/test_roi_analysis_batch.py +++ b/package/tests/test_PartSeg/test_roi_analysis_batch.py @@ -343,9 +343,8 @@ def _check_profile(profile: ROIExtractionProfile): with qtbot.waitSignal(widget.roi_extraction_profile_selected, check_params_cb=check_profile("test2")): widget.roi_profile.setCurrentRow(1) - with widget.enable_protect(): - with qtbot.assert_not_emitted(widget.roi_extraction_profile_selected): - widget.roi_profile.setCurrentRow(0) + with widget.enable_protect(), qtbot.assert_not_emitted(widget.roi_extraction_profile_selected): + widget.roi_profile.setCurrentRow(0) part_settings.roi_profiles["test3"] = ROIExtractionProfile( name="test3", @@ -414,9 +413,8 @@ def _check_pipeline(pipeline: SegmentationPipeline): with qtbot.waitSignal(widget.roi_extraction_pipeline_selected, check_params_cb=check_pipeline("test2")): widget.roi_pipeline.setCurrentRow(1) - with widget.enable_protect(): - with qtbot.assert_not_emitted(widget.roi_extraction_pipeline_selected): - widget.roi_pipeline.setCurrentRow(0) + with widget.enable_protect(), qtbot.assert_not_emitted(widget.roi_extraction_pipeline_selected): + widget.roi_pipeline.setCurrentRow(0) with qtbot.waitSignal(widget.roi_extraction_pipeline_add, check_params_cb=check_pipeline("test")): widget._add_profile() @@ -486,9 +484,8 @@ def _check_measurement(measurement): widget.measurements_list.setCurrentRow(0) with qtbot.waitSignal(widget.set_of_measurement_selected, check_params_cb=check_measurement("statistic2")): widget.measurements_list.setCurrentRow(1) - with widget.enable_protect(): - with qtbot.assert_not_emitted(widget.set_of_measurement_selected): - widget.measurements_list.setCurrentRow(0) + with widget.enable_protect(), qtbot.assert_not_emitted(widget.set_of_measurement_selected): + widget.measurements_list.setCurrentRow(0) def test_set_current_node(self, qtbot, part_settings): widget = prepare_plan_widget.SelectMeasurementOp(part_settings) diff --git a/package/tests/test_PartSeg/test_sentry.py b/package/tests/test_PartSeg/test_sentry.py index 719c0eb8f..f31cee70b 100644 --- a/package/tests/test_PartSeg/test_sentry.py +++ b/package/tests/test_PartSeg/test_sentry.py @@ -27,7 +27,7 @@ def test_sentry_serialize_clip(monkeypatch): try: raise ValueError("eeee") except ValueError as e: - event, hint = sentry_sdk.utils.event_from_exception(e) + event, _hint = sentry_sdk.utils.event_from_exception(e) event["message"] = message cliped = serialize(event) diff --git a/package/tests/test_PartSegCore/segmentation/test_segmentation_algorithm.py b/package/tests/test_PartSegCore/segmentation/test_segmentation_algorithm.py index 98d843fec..37a9439bd 100644 --- a/package/tests/test_PartSegCore/segmentation/test_segmentation_algorithm.py +++ b/package/tests/test_PartSegCore/segmentation/test_segmentation_algorithm.py @@ -15,8 +15,8 @@ from PartSegCore.segmentation.segmentation_algorithm import final_algorithm_list as algorithm_list -def empty(*args): - pass +def empty(*_): + """Empty function to pass as a callback""" @pytest.fixture(autouse=True) diff --git a/package/tests/test_PartSegCore/test_class_generator.py b/package/tests/test_PartSegCore/test_class_generator.py index 66e8404f5..16afb9ac6 100644 --- a/package/tests/test_PartSegCore/test_class_generator.py +++ b/package/tests/test_PartSegCore/test_class_generator.py @@ -37,7 +37,7 @@ def teardown_module(): def empty(*_): - pass + """Empty function to avoid unused variable warning.""" def test_readonly(): @@ -167,7 +167,7 @@ class Test2(BaseSerializableClass): def test_forward_ref(): - class Test(BaseSerializableClass): # pylint: disable=W0612 + class Test(BaseSerializableClass): # pylint: disable=W0612 # skipcq: PTC-W0065 val: int child: typing.Optional["Test"] = None # noqa F821