From cae030422b3c7431e99aa2e98152e93316ec7e6d Mon Sep 17 00:00:00 2001 From: M Q Date: Mon, 20 Mar 2023 20:21:23 -0700 Subject: [PATCH 01/15] Set typeguard version to be about 2.12.1 to avoid incompatible v3 Signed-off-by: M Q --- requirements.txt | 2 +- setup.cfg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 92151b3f..ee919f55 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ numpy>=1.21.6 networkx>=2.4 colorama>=0.4.1 -typeguard>=2.12.1 +typeguard~=2.12.1 diff --git a/setup.cfg b/setup.cfg index 8fefc871..fd958a77 100644 --- a/setup.cfg +++ b/setup.cfg @@ -26,7 +26,7 @@ install_requires = numpy>=1.21.6 networkx>=2.4 colorama>=0.4.1 - typeguard>=2.12.1 + typeguard~=2.12.1 [options.extras_require] all = From 4608b2243003068a79a72c0a758c3fca7abbdeae Mon Sep 17 00:00:00 2001 From: M Q Date: Mon, 20 Mar 2023 20:35:08 -0700 Subject: [PATCH 02/15] Set typeguard ver close to 2.12.1 to avoid incompatible v3 Signed-off-by: M Q --- notebooks/tutorials/02_mednist_app-prebuilt.ipynb | 2 +- notebooks/tutorials/03_segmentation_app.ipynb | 2 +- notebooks/tutorials/03_segmentation_viz_app.ipynb | 2 +- notebooks/tutorials/06_monai_bundle_app.ipynb | 2 +- notebooks/tutorials/07_multi_model_app.ipynb | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/notebooks/tutorials/02_mednist_app-prebuilt.ipynb b/notebooks/tutorials/02_mednist_app-prebuilt.ipynb index 60d335f1..5c973452 100644 --- a/notebooks/tutorials/02_mednist_app-prebuilt.ipynb +++ b/notebooks/tutorials/02_mednist_app-prebuilt.ipynb @@ -84,7 +84,7 @@ "Collecting networkx>=2.4\n", " Downloading networkx-2.5.1-py3-none-any.whl (1.6 MB)\n", "\u001b[K |████████████████████████████████| 1.6 MB 12.8 MB/s eta 0:00:01\n", - "\u001b[?25hCollecting typeguard>=2.12.1\n", + "\u001b[?25hCollecting typeguard~=2.12.1\n", " Downloading typeguard-2.12.1-py3-none-any.whl (17 kB)\n", "Collecting numpy>=1.17\n", " Downloading numpy-1.19.5-cp36-cp36m-manylinux2010_x86_64.whl (14.8 MB)\n", diff --git a/notebooks/tutorials/03_segmentation_app.ipynb b/notebooks/tutorials/03_segmentation_app.ipynb index 29bc13e9..fc02e3a4 100644 --- a/notebooks/tutorials/03_segmentation_app.ipynb +++ b/notebooks/tutorials/03_segmentation_app.ipynb @@ -104,7 +104,7 @@ "!python -c \"import pydicom\" || pip install -q \"pydicom>=1.4.2\"\n", "!python -c \"import highdicom\" || pip install -q \"highdicom>=0.18.2\"\n", "!python -c \"import SimpleITK\" || pip install -q \"SimpleITK>=2.0.0\"\n", - "!python -c \"import typeguard\" || pip install -q \"typeguard>=2.12.1\"\n", + "!python -c \"import typeguard\" || pip install -q \"typeguard~=2.12.1\"\n", "\n", "# Install MONAI Deploy App SDK package\n", "!python -c \"import monai.deploy\" || pip install --upgrade -q \"monai-deploy-app-sdk\"" diff --git a/notebooks/tutorials/03_segmentation_viz_app.ipynb b/notebooks/tutorials/03_segmentation_viz_app.ipynb index d9ce34aa..5f7ce27b 100644 --- a/notebooks/tutorials/03_segmentation_viz_app.ipynb +++ b/notebooks/tutorials/03_segmentation_viz_app.ipynb @@ -113,7 +113,7 @@ "!python -c \"import pydicom\" || pip install -q \"pydicom>=1.4.2\"\n", "!python -c \"import highdicom\" || pip install -q \"highdicom>=0.18.2\"\n", "!python -c \"import SimpleITK\" || pip install -q \"SimpleITK>=2.0.0\"\n", - "!python -c \"import typeguard\" || pip install -q \"typeguard>=2.12.1\"\n", + "!python -c \"import typeguard\" || pip install -q \"typeguard~=2.12.1\"\n", "\n", "# Install MONAI Deploy App SDK package\n", "!python -c \"import monai.deploy\" || pip install --upgrade -q \"monai-deploy-app-sdk\"\n", diff --git a/notebooks/tutorials/06_monai_bundle_app.ipynb b/notebooks/tutorials/06_monai_bundle_app.ipynb index d1d8baf7..62090c80 100644 --- a/notebooks/tutorials/06_monai_bundle_app.ipynb +++ b/notebooks/tutorials/06_monai_bundle_app.ipynb @@ -106,7 +106,7 @@ "!python -c \"import pydicom\" || pip install -q \"pydicom>=1.4.2\"\n", "!python -c \"import highdicom\" || pip install -q \"highdicom>=0.18.2\"\n", "!python -c \"import SimpleITK\" || pip install -q \"SimpleITK>=2.0.0\"\n", - "!python -c \"import typeguard\" || pip install -q \"typeguard>=2.12.1\"\n", + "!python -c \"import typeguard\" || pip install -q \"typeguard~=2.12.1\"\n", "\n", "# Install MONAI Deploy App SDK package\n", "!python -c \"import monai.deploy\" || pip install --upgrade -q \"monai-deploy-app-sdk\"" diff --git a/notebooks/tutorials/07_multi_model_app.ipynb b/notebooks/tutorials/07_multi_model_app.ipynb index ac737859..a475863c 100644 --- a/notebooks/tutorials/07_multi_model_app.ipynb +++ b/notebooks/tutorials/07_multi_model_app.ipynb @@ -144,7 +144,7 @@ "!python -c \"import pydicom\" || pip install -q \"pydicom>=1.4.2\"\n", "!python -c \"import highdicom\" || pip install -q \"highdicom>=0.18.2\"\n", "!python -c \"import SimpleITK\" || pip install -q \"SimpleITK>=2.0.0\"\n", - "!python -c \"import typeguard\" || pip install -q \"typeguard>=2.12.1\"\n", + "!python -c \"import typeguard\" || pip install -q \"typeguard~=2.12.1\"\n", "\n", "# Install MONAI Deploy App SDK package\n", "!python -c \"import monai.deploy\" || pip install --upgrade -q \"monai-deploy-app-sdk\"" From cc513411193a1acfa6c4f4724dfa22c74d0c448c Mon Sep 17 00:00:00 2001 From: M Q Date: Mon, 20 Mar 2023 21:09:54 -0700 Subject: [PATCH 03/15] Fixed complaints by black (new version) Signed-off-by: M Q --- .../apps/ai_livertumor_seg_app/livertumor_seg_operator.py | 2 -- examples/apps/ai_unetr_seg_app/unetr_seg_operator.py | 2 -- monai/deploy/operators/dicom_data_loader_operator.py | 1 - .../operators/dicom_encapsulated_pdf_writer_operator.py | 1 - monai/deploy/operators/dicom_series_to_volume_operator.py | 1 - monai/deploy/operators/dicom_text_sr_writer_operator.py | 1 - monai/deploy/operators/dicom_utils.py | 2 -- monai/deploy/operators/monai_bundle_inference_operator.py | 2 +- platforms/nuance_pin/app/inference.py | 2 -- platforms/nuance_pin/app/post_inference_ops.py | 4 ---- platforms/nuance_pin/app_wrapper.py | 1 - 11 files changed, 1 insertion(+), 18 deletions(-) diff --git a/examples/apps/ai_livertumor_seg_app/livertumor_seg_operator.py b/examples/apps/ai_livertumor_seg_app/livertumor_seg_operator.py index d7b18727..1471ee5b 100644 --- a/examples/apps/ai_livertumor_seg_app/livertumor_seg_operator.py +++ b/examples/apps/ai_livertumor_seg_app/livertumor_seg_operator.py @@ -52,14 +52,12 @@ class LiverTumorSegOperator(Operator): """ def __init__(self): - self.logger = logging.getLogger("{}.{}".format(__name__, type(self).__name__)) super().__init__() self._input_dataset_key = "image" self._pred_dataset_key = "pred" def compute(self, op_input: InputContext, op_output: OutputContext, context: ExecutionContext): - input_image = op_input.get("image") if not input_image: raise ValueError("Input image is not found.") diff --git a/examples/apps/ai_unetr_seg_app/unetr_seg_operator.py b/examples/apps/ai_unetr_seg_app/unetr_seg_operator.py index 7b45d208..3f036503 100644 --- a/examples/apps/ai_unetr_seg_app/unetr_seg_operator.py +++ b/examples/apps/ai_unetr_seg_app/unetr_seg_operator.py @@ -46,14 +46,12 @@ class UnetrSegOperator(Operator): """ def __init__(self): - self.logger = logging.getLogger("{}.{}".format(__name__, type(self).__name__)) super().__init__() self._input_dataset_key = "image" self._pred_dataset_key = "pred" def compute(self, op_input: InputContext, op_output: OutputContext, context: ExecutionContext): - input_image = op_input.get("image") if not input_image: raise ValueError("Input image is not found.") diff --git a/monai/deploy/operators/dicom_data_loader_operator.py b/monai/deploy/operators/dicom_data_loader_operator.py index f1b57b1a..60937661 100644 --- a/monai/deploy/operators/dicom_data_loader_operator.py +++ b/monai/deploy/operators/dicom_data_loader_operator.py @@ -118,7 +118,6 @@ def _load_data(self, files: List[str]): logging.warning(f"Ignored {file}, reason being: {ex}") for sop_instance in sop_instances: - study_instance_uid = sop_instance[0x0020, 0x000D].value.name # name is the UID as str if study_instance_uid not in study_dict: diff --git a/monai/deploy/operators/dicom_encapsulated_pdf_writer_operator.py b/monai/deploy/operators/dicom_encapsulated_pdf_writer_operator.py index ddafac65..bd66915f 100644 --- a/monai/deploy/operators/dicom_encapsulated_pdf_writer_operator.py +++ b/monai/deploy/operators/dicom_encapsulated_pdf_writer_operator.py @@ -42,7 +42,6 @@ @md.output("dicom_instance", DataPath, IOType.DISK) @md.env(pip_packages=["pydicom >= 1.4.2", "PyPDF2 >= 2.11.1", "monai"]) class DICOMEncapsulatedPDFWriterOperator(Operator): - DCM_EXTENSION = ".dcm" def __init__( diff --git a/monai/deploy/operators/dicom_series_to_volume_operator.py b/monai/deploy/operators/dicom_series_to_volume_operator.py index e5837b8f..e89dd265 100644 --- a/monai/deploy/operators/dicom_series_to_volume_operator.py +++ b/monai/deploy/operators/dicom_series_to_volume_operator.py @@ -389,7 +389,6 @@ def _get_instance_properties(obj: object, not_none: bool = True) -> Dict: def test(): - from pathlib import Path from monai.deploy.operators.dicom_data_loader_operator import DICOMDataLoaderOperator diff --git a/monai/deploy/operators/dicom_text_sr_writer_operator.py b/monai/deploy/operators/dicom_text_sr_writer_operator.py index 422a2770..5b7937e3 100644 --- a/monai/deploy/operators/dicom_text_sr_writer_operator.py +++ b/monai/deploy/operators/dicom_text_sr_writer_operator.py @@ -39,7 +39,6 @@ @md.output("dicom_instance", DataPath, IOType.DISK) @md.env(pip_packages=["pydicom >= 1.4.2", "monai"]) class DICOMTextSRWriterOperator(Operator): - # File extension for the generated DICOM Part 10 file. DCM_EXTENSION = ".dcm" diff --git a/monai/deploy/operators/dicom_utils.py b/monai/deploy/operators/dicom_utils.py index 6d434953..6df12fe7 100644 --- a/monai/deploy/operators/dicom_utils.py +++ b/monai/deploy/operators/dicom_utils.py @@ -60,7 +60,6 @@ class ModelInfo(object): """ def __init__(self, creator: str = "", name: str = "", version: str = "", uid: str = ""): - self.creator = creator if isinstance(creator, str) else "" self.name = name if isinstance(name, str) else "" self.version = version if isinstance(version, str) else "" @@ -77,7 +76,6 @@ def __init__( series_number: str = "0000", software_version_number: str = "", ): - self.manufacturer = manufacturer if isinstance(manufacturer, str) else "" self.manufacturer_model = manufacturer_model if isinstance(manufacturer_model, str) else "" self.series_number = series_number if isinstance(series_number, str) else "" diff --git a/monai/deploy/operators/monai_bundle_inference_operator.py b/monai/deploy/operators/monai_bundle_inference_operator.py index 226e27af..e1327e8f 100644 --- a/monai/deploy/operators/monai_bundle_inference_operator.py +++ b/monai/deploy/operators/monai_bundle_inference_operator.py @@ -268,6 +268,7 @@ def _ensure_str_list(config_names): DEFAULT_BundleConfigNames = BundleConfigNames() + # The operator env decorator defines the required pip packages commonly used in the Bundles. # The MONAI Deploy App SDK packager currently relies on the App to consolidate all required packages in order to # install them in the MAP Docker image. @@ -768,7 +769,6 @@ def _convert_from_image(self, img: Image) -> Tuple[np.ndarray, Dict]: or ("spacing" in img_meta_dict and "original_affine" in img_meta_dict) or "row_pixel_spacing" not in img_meta_dict ): - return img.asnumpy(), img_meta_dict else: return self._convert_from_image_dicom_source(img) diff --git a/platforms/nuance_pin/app/inference.py b/platforms/nuance_pin/app/inference.py index b2d8e6e4..50c104cd 100644 --- a/platforms/nuance_pin/app/inference.py +++ b/platforms/nuance_pin/app/inference.py @@ -82,7 +82,6 @@ def detection_list(self): @md.env(pip_packages=["monai>=0.8.1", "torch>=1.5", "numpy>=1.21", "nibabel"]) class LungNoduleInferenceOperator(Operator): def __init__(self, model_path: str = "model/model.ts"): - self.logger = logging.getLogger("{}.{}".format(__name__, type(self).__name__)) super().__init__() self._input_dataset_key = "image" @@ -125,7 +124,6 @@ def __init__(self, model_path: str = "model/model.ts"): self.detector.eval() def compute(self, op_input: InputContext, op_output: OutputContext, context: ExecutionContext): - input_image = op_input.get("image") if not input_image: raise ValueError("Input image not found.") diff --git a/platforms/nuance_pin/app/post_inference_ops.py b/platforms/nuance_pin/app/post_inference_ops.py index 2a0d78a2..200335bd 100644 --- a/platforms/nuance_pin/app/post_inference_ops.py +++ b/platforms/nuance_pin/app/post_inference_ops.py @@ -36,7 +36,6 @@ def __init__(self, pin_processor: Optional[AiJobProcessor], *args, **kwargs): self.pin_processor = pin_processor def compute(self, op_input: InputContext, op_output: OutputContext, context: ExecutionContext): - selected_study = op_input.get("original_dicom")[0] # assuming a single study selected_series = selected_study.selected_series[0] # assuming a single series detection_result: DetectionResult = op_input.get("detection_predictions").detection_list[0] @@ -60,7 +59,6 @@ def compute(self, op_input: InputContext, op_output: OutputContext, context: Exe accession = all_ref_images[0].AccessionNumber for inst_num, (box_data, box_score) in enumerate(zip(detection_result.box_data, detection_result.score_data)): - tracking_id = f"{accession}_nodule_{inst_num}" # site-specific ID tracking_uid = hd.UID() @@ -160,7 +158,6 @@ def __init__(self, pin_processor: Optional[AiJobProcessor], *args, **kwargs): self.pin_processor = pin_processor def compute(self, op_input: InputContext, op_output: OutputContext, context: ExecutionContext): - selected_study = op_input.get("original_dicom")[0] # assuming a single study selected_series = selected_study.selected_series[0] # assuming a single series detection_result: DetectionResult = op_input.get("detection_predictions").detection_list[0] @@ -190,7 +187,6 @@ def compute(self, op_input: InputContext, op_output: OutputContext, context: Exe slice_coords = list(range(len(selected_series.series.get_sop_instances()))) for box_data, box_score in zip(detection_result.box_data, detection_result.score_data): - affected_slice_idx = [ idx for idx, slice_coord in enumerate(slice_coords) diff --git a/platforms/nuance_pin/app_wrapper.py b/platforms/nuance_pin/app_wrapper.py index c9601812..99e14583 100644 --- a/platforms/nuance_pin/app_wrapper.py +++ b/platforms/nuance_pin/app_wrapper.py @@ -50,7 +50,6 @@ class MONAIAppWrapper(AiJobProcessor): - partner_name = os.environ["AI_PARTNER_NAME"] service_name = os.environ["AI_SVC_NAME"] service_version = os.environ["AI_SVC_VERSION"] From 4755981638e2386a9c87f71b5cf953bbc8af29cf Mon Sep 17 00:00:00 2001 From: M Q Date: Mon, 20 Mar 2023 21:32:00 -0700 Subject: [PATCH 04/15] Excluded two files to avoid black complaint but it never stated what's wrong Signed-off-by: M Q --- setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index fd958a77..f8f734a6 100644 --- a/setup.cfg +++ b/setup.cfg @@ -54,7 +54,7 @@ per_file_ignores = # 30 warnings with N802 in dicom_study.py dicom_study.py: N802 dicom_series.py:N802 -exclude = *.pyi,.git,.eggs,monai/deploy/_version.py,dist,versioneer.py,venv,.venv,_version.py +exclude = *.pyi,.git,.eggs,monai/deploy/_version.py,dist,versioneer.py,venv,.venv,_version.py, nx_digraph.py, single_process_executor.py [isort] known_first_party = monai From 9d1a55b872ac2abb3738582dae6aea2685271cd0 Mon Sep 17 00:00:00 2001 From: M Q Date: Tue, 21 Mar 2023 00:08:10 -0700 Subject: [PATCH 05/15] Exclude files with relative path due to unknown black complaints Signed-off-by: M Q --- setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index f8f734a6..dbc7954f 100644 --- a/setup.cfg +++ b/setup.cfg @@ -54,7 +54,7 @@ per_file_ignores = # 30 warnings with N802 in dicom_study.py dicom_study.py: N802 dicom_series.py:N802 -exclude = *.pyi,.git,.eggs,monai/deploy/_version.py,dist,versioneer.py,venv,.venv,_version.py, nx_digraph.py, single_process_executor.py +exclude = *.pyi,.git,.eggs,monai/deploy/_version.py,dist,versioneer.py,venv,.venv,_version.py, monai/deploy/core/graphs/nx_digraph.py, monai/deploy/core/executors/single_process_executor.py [isort] known_first_party = monai From 6cedec4383f334f77fe066f3fd4bc227e588450d Mon Sep 17 00:00:00 2001 From: M Q Date: Tue, 21 Mar 2023 00:21:51 -0700 Subject: [PATCH 06/15] Another small fix to get the exclude list work Signed-off-by: M Q --- setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index dbc7954f..0fa15325 100644 --- a/setup.cfg +++ b/setup.cfg @@ -54,7 +54,7 @@ per_file_ignores = # 30 warnings with N802 in dicom_study.py dicom_study.py: N802 dicom_series.py:N802 -exclude = *.pyi,.git,.eggs,monai/deploy/_version.py,dist,versioneer.py,venv,.venv,_version.py, monai/deploy/core/graphs/nx_digraph.py, monai/deploy/core/executors/single_process_executor.py +exclude = *.pyi,.git,.eggs,monai/deploy/_version.py,dist,versioneer.py,venv,.venv,_version.py,monai/deploy/core/graphs/nx_digraph.py,monai/deploy/core/executors/single_process_executor.py [isort] known_first_party = monai From b4acee6accfe86424fddd997c8a67b5475c675b2 Mon Sep 17 00:00:00 2001 From: M Q Date: Tue, 21 Mar 2023 12:44:32 -0700 Subject: [PATCH 07/15] Fixed local file permission issue causing black to fail Signed-off-by: M Q --- monai/deploy/core/executors/single_process_executor.py | 2 +- monai/deploy/core/graphs/nx_digraph.py | 2 +- setup.cfg | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/monai/deploy/core/executors/single_process_executor.py b/monai/deploy/core/executors/single_process_executor.py index a1086fc7..85c01665 100644 --- a/monai/deploy/core/executors/single_process_executor.py +++ b/monai/deploy/core/executors/single_process_executor.py @@ -141,7 +141,7 @@ def run(self): ) next_op_exec_context = ExecutionContext(exec_context, next_op) - for (out_label, in_labels) in io_map.items(): + for out_label, in_labels in io_map.items(): output = op_exec_context.output_context.get(out_label) for in_label in in_labels: next_op_exec_context.input_context.set(output, in_label) diff --git a/monai/deploy/core/graphs/nx_digraph.py b/monai/deploy/core/graphs/nx_digraph.py index 34397b12..a02ae250 100644 --- a/monai/deploy/core/graphs/nx_digraph.py +++ b/monai/deploy/core/graphs/nx_digraph.py @@ -52,5 +52,5 @@ def gen_worklist(self) -> Generator[Optional[Operator], None, None]: return worklist def gen_next_operators(self, op: Operator) -> Generator[Optional[Operator], None, None]: - for (_, v) in self._graph.out_edges(op): + for _, v in self._graph.out_edges(op): yield v diff --git a/setup.cfg b/setup.cfg index 0fa15325..fd958a77 100644 --- a/setup.cfg +++ b/setup.cfg @@ -54,7 +54,7 @@ per_file_ignores = # 30 warnings with N802 in dicom_study.py dicom_study.py: N802 dicom_series.py:N802 -exclude = *.pyi,.git,.eggs,monai/deploy/_version.py,dist,versioneer.py,venv,.venv,_version.py,monai/deploy/core/graphs/nx_digraph.py,monai/deploy/core/executors/single_process_executor.py +exclude = *.pyi,.git,.eggs,monai/deploy/_version.py,dist,versioneer.py,venv,.venv,_version.py [isort] known_first_party = monai From 36f4c52f2561e0d81aaa2e44e269c7e290ad60d5 Mon Sep 17 00:00:00 2001 From: M Q Date: Tue, 21 Mar 2023 13:13:56 -0700 Subject: [PATCH 08/15] Changes to fix flake8 complaints Signed-off-by: M Q --- monai/deploy/operators/monai_bundle_inference_operator.py | 2 +- monai/deploy/utils/importutil.py | 2 +- platforms/nuance_pin/app/post_inference_ops.py | 6 ++++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/monai/deploy/operators/monai_bundle_inference_operator.py b/monai/deploy/operators/monai_bundle_inference_operator.py index e1327e8f..16d7759a 100644 --- a/monai/deploy/operators/monai_bundle_inference_operator.py +++ b/monai/deploy/operators/monai_bundle_inference_operator.py @@ -622,7 +622,7 @@ def post_process(self, data: Any, *args, **kwargs) -> Union[Image, Any, Tuple[An if is_map_compose(self._postproc): if isinstance(data, (list, tuple)): - outputs_dict = dict(zip(data, self._outputs.keys())) + outputs_dict = dict(zip(data, self._outputs.keys(), strict=True)) elif not isinstance(data, dict): oname = first(self._outputs.keys()) outputs_dict = {oname: data} diff --git a/monai/deploy/utils/importutil.py b/monai/deploy/utils/importutil.py index 1cba334f..0fefb0d8 100644 --- a/monai/deploy/utils/importutil.py +++ b/monai/deploy/utils/importutil.py @@ -155,7 +155,7 @@ def exact_version(the_module, version_str: str = "") -> bool: Returns True if the module's __version__ matches version_str """ if not hasattr(the_module, "__version__"): - warnings.warn(f"{the_module} has no attribute __version__ in exact_version check.") + warnings.warn(f"{the_module} has no attribute __version__ in exact_version check.", stacklevel=2) return False return bool(the_module.__version__ == version_str) diff --git a/platforms/nuance_pin/app/post_inference_ops.py b/platforms/nuance_pin/app/post_inference_ops.py index 200335bd..d3674214 100644 --- a/platforms/nuance_pin/app/post_inference_ops.py +++ b/platforms/nuance_pin/app/post_inference_ops.py @@ -58,7 +58,9 @@ def compute(self, op_input: InputContext, op_output: OutputContext, context: Exe all_ref_images = [ins.get_native_sop_instance() for ins in selected_series.series.get_sop_instances()] accession = all_ref_images[0].AccessionNumber - for inst_num, (box_data, box_score) in enumerate(zip(detection_result.box_data, detection_result.score_data)): + for inst_num, (box_data, box_score) in enumerate( + zip(detection_result.box_data, detection_result.score_data, strict=True) + ): tracking_id = f"{accession}_nodule_{inst_num}" # site-specific ID tracking_uid = hd.UID() @@ -186,7 +188,7 @@ def compute(self, op_input: InputContext, op_output: OutputContext, context: Exe slice_coords = list(range(len(selected_series.series.get_sop_instances()))) - for box_data, box_score in zip(detection_result.box_data, detection_result.score_data): + for box_data, box_score in zip(detection_result.box_data, detection_result.score_data, strict=True): affected_slice_idx = [ idx for idx, slice_coord in enumerate(slice_coords) From 84185ff8eb5b4fde2e6e08c6663f821638880eff Mon Sep 17 00:00:00 2001 From: M Q Date: Tue, 21 Mar 2023 13:22:37 -0700 Subject: [PATCH 09/15] More falke8 complaint fix Signed-off-by: M Q --- monai/deploy/operators/monai_bundle_inference_operator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monai/deploy/operators/monai_bundle_inference_operator.py b/monai/deploy/operators/monai_bundle_inference_operator.py index 16d7759a..22ce948b 100644 --- a/monai/deploy/operators/monai_bundle_inference_operator.py +++ b/monai/deploy/operators/monai_bundle_inference_operator.py @@ -587,7 +587,7 @@ def compute(self, op_input: InputContext, op_output: OutputContext, context: Exe outputs = self.post_process(ensure_tuple(outputs)[0], **kw_args) logging.debug(f"Post-processing elapsed time (seconds): {time.time() - start}") if isinstance(outputs, (tuple, list)): - output_dict = dict(zip(self._outputs.keys(), outputs)) + output_dict = dict(zip(self._outputs.keys(), outputs), strict=True) elif not isinstance(outputs, dict): output_dict = {first(self._outputs.keys()): outputs} else: From da88d9dbf03f64cca83a414002c458ebe069da7e Mon Sep 17 00:00:00 2001 From: M Q Date: Tue, 21 Mar 2023 13:36:12 -0700 Subject: [PATCH 10/15] Flake8 fix Signed-off-by: M Q --- monai/deploy/operators/monai_bundle_inference_operator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monai/deploy/operators/monai_bundle_inference_operator.py b/monai/deploy/operators/monai_bundle_inference_operator.py index 22ce948b..5907ca1f 100644 --- a/monai/deploy/operators/monai_bundle_inference_operator.py +++ b/monai/deploy/operators/monai_bundle_inference_operator.py @@ -587,7 +587,7 @@ def compute(self, op_input: InputContext, op_output: OutputContext, context: Exe outputs = self.post_process(ensure_tuple(outputs)[0], **kw_args) logging.debug(f"Post-processing elapsed time (seconds): {time.time() - start}") if isinstance(outputs, (tuple, list)): - output_dict = dict(zip(self._outputs.keys(), outputs), strict=True) + output_dict = dict(zip(self._outputs.keys(), outputs, strict=True)) elif not isinstance(outputs, dict): output_dict = {first(self._outputs.keys()): outputs} else: From b92d6feca0a840aacb2a1ff75129249771f06484 Mon Sep 17 00:00:00 2001 From: M Q Date: Tue, 21 Mar 2023 14:12:24 -0700 Subject: [PATCH 11/15] Input folder required by the new versio of pytype Signed-off-by: M Q --- run | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/run b/run index 86cb3355..70f4fac8 100755 --- a/run +++ b/run @@ -619,7 +619,7 @@ pytype_format() { local python_version="$(get_python_version)" pushd "${TOP}" > /dev/null - run_command ${MONAI_PY_EXE} -m pytype -j "${num_workers}" --python-version="${python_version}" + run_command ${MONAI_PY_EXE} -m pytype -j "${num_workers}" --python-version="${python_version}" "${TOP}" result=$? popd > /dev/null From bc1977e28c682512d3c1946de53ff4670d7d8022 Mon Sep 17 00:00:00 2001 From: M Q Date: Wed, 22 Mar 2023 20:56:44 -0700 Subject: [PATCH 12/15] Used pyproject.toml for pytype config as the existing config is out of date Also, need to update the code to quiet the complaints from pytype. A couple errors in the source code need to be investigated but for now ignored Signed-off-by: M Q --- .../operators/dicom_seg_writer_operator.py | 1 + .../monai_bundle_inference_operator.py | 6 +- pyproject.toml | 75 ++++++++++++++++++- run | 2 +- setup.cfg | 41 ++-------- 5 files changed, 86 insertions(+), 39 deletions(-) diff --git a/monai/deploy/operators/dicom_seg_writer_operator.py b/monai/deploy/operators/dicom_seg_writer_operator.py index efa33d9f..5a142f85 100644 --- a/monai/deploy/operators/dicom_seg_writer_operator.py +++ b/monai/deploy/operators/dicom_seg_writer_operator.py @@ -9,6 +9,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import os import datetime import logging from pathlib import Path diff --git a/monai/deploy/operators/monai_bundle_inference_operator.py b/monai/deploy/operators/monai_bundle_inference_operator.py index 5907ca1f..156abe22 100644 --- a/monai/deploy/operators/monai_bundle_inference_operator.py +++ b/monai/deploy/operators/monai_bundle_inference_operator.py @@ -78,8 +78,8 @@ def _read_from_archive(archive, root_name: str, config_name: str, do_search=True # Try directly read with constructed and expected path into the archive for suffix in bundle_suffixes: + path = Path(root_name, config_folder, config_name).with_suffix(suffix) try: - path = Path(root_name, config_folder, config_name).with_suffix(suffix) logging.debug(f"Trying to read config '{config_name}' content from {path}.") content_text = archive.read(str(path)) break @@ -587,7 +587,7 @@ def compute(self, op_input: InputContext, op_output: OutputContext, context: Exe outputs = self.post_process(ensure_tuple(outputs)[0], **kw_args) logging.debug(f"Post-processing elapsed time (seconds): {time.time() - start}") if isinstance(outputs, (tuple, list)): - output_dict = dict(zip(self._outputs.keys(), outputs, strict=True)) + output_dict = dict(zip(self._outputs.keys(), outputs)) elif not isinstance(outputs, dict): output_dict = {first(self._outputs.keys()): outputs} else: @@ -622,7 +622,7 @@ def post_process(self, data: Any, *args, **kwargs) -> Union[Image, Any, Tuple[An if is_map_compose(self._postproc): if isinstance(data, (list, tuple)): - outputs_dict = dict(zip(data, self._outputs.keys(), strict=True)) + outputs_dict = dict(zip(data, self._outputs.keys())) elif not isinstance(data, dict): oname = first(self._outputs.keys()) outputs_dict = {oname: data} diff --git a/pyproject.toml b/pyproject.toml index e820df8e..a7aefad4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,5 +36,78 @@ exclude = ''' ''' # https://github.com/microsoft/pyright/blob/main/docs/configuration.md +# NOTE: All relative paths are relative to the location of this file. [tool.pyright] -ignore = ["versioneer.py", "_version.py"] \ No newline at end of file +ignore = ["versioneer.py", "_version.py"] + +# https://google.github.io/pytype/ +[tool.pytype] +# Space-separated list of files or directories to exclude. +exclude = [ + 'versioneer.py', + '_version.py', + '**/_version.py', +] +# Space-separated list of files or directories to process. +inputs = [ + 'monai', +] +# Keep going past errors to analyze as many files as possible. +keep_going = true +# Run N jobs in parallel. When 'auto' is used, this will be equivalent to the +# number of CPUs on the host system. +jobs = 8 +# All pytype output goes here. +output = '.pytype' +# Platform (e.g., "linux", "win32") that the target code runs on. +platform = 'linux' +# Paths to source code directories, separated by ':'. +pythonpath = '.' + +# Always use function return type annotations. This flag is temporary and will +# be removed once this behavior is enabled by default. +always_use_return_annotations = false + +# Enable parameter count checks for overriding methods. This flag is temporary +# and will be removed once this behavior is enabled by default. +overriding_parameter_count_checks = false + +# Enable return type checks for overriding methods. This flag is temporary and +# will be removed once this behavior is enabled by default. +overriding_return_type_checks = true + +# Use the enum overlay for more precise enum checking. This flag is temporary +# and will be removed once this behavior is enabled by default. +use_enum_overlay = false + +# Opt-in: Do not allow Any as a return type. +no_return_any = false + +# Experimental: Support pyglib's @cached.property. +enable_cached_property = false + +# Experimental: Infer precise return types even for invalid function calls. +precise_return = false + +# Experimental: Solve unknown types to label with structural types. +protocols = false + +# Experimental: Only load submodules that are explicitly imported. +strict_import = false + +# Experimental: Enable exhaustive checking of function parameter types. +strict_parameter_checks = false + +# Experimental: Emit errors for comparisons between incompatible primitive +# types. +strict_primitive_comparisons = false + +# Space-separated list of error names to ignore. +disable = [ + 'pyi-error', + 'container-type-mismatch', + 'attribute-error', +] + +# Don't report errors. +report_errors = true diff --git a/run b/run index 70f4fac8..86cb3355 100755 --- a/run +++ b/run @@ -619,7 +619,7 @@ pytype_format() { local python_version="$(get_python_version)" pushd "${TOP}" > /dev/null - run_command ${MONAI_PY_EXE} -m pytype -j "${num_workers}" --python-version="${python_version}" "${TOP}" + run_command ${MONAI_PY_EXE} -m pytype -j "${num_workers}" --python-version="${python_version}" result=$? popd > /dev/null diff --git a/setup.cfg b/setup.cfg index fd958a77..fa60f6c1 100644 --- a/setup.cfg +++ b/setup.cfg @@ -43,8 +43,13 @@ ignore = E203,E305,E402,E501,E721,E741,F821,F841,F999,W503,W504,C408,E302,W291,E303, # N812 lowercase 'torch.nn.functional' imported as non lowercase 'F' N812, - B024, #abstract base class, but it has no abstract methods - B027 #method in base class with no implementation + #B024, abstract base class, but it has no abstract methods + B024, + # B027, #method in base class with no implementation + B027, + # B905 `zip()` without an explicit `strict=` parameter, but conflicting with pytype + B905 + per_file_ignores = __init__.py: F401 # Allow using camel case for variable/argument names for the sake of readability. @@ -105,38 +110,6 @@ ignore_errors = True # Ignores all non-fatal errors. ignore_errors = True -[pytype] -# Space-separated list of files or directories to exclude. -exclude = versioneer.py _version.py -# Space-separated list of files or directories to process. -inputs = monai -# Keep going past errors to analyze as many files as possible. -keep_going = True -# Run N jobs in parallel. -jobs = 8 -# All pytype output goes here. -output = .pytype -# Paths to source code directories, separated by ':'. -pythonpath = . -# Check attribute values against their annotations. -check_attribute_types = True -# Check container mutations against their annotations. -check_container_types = True -# Check parameter defaults and assignments against their annotations. -check_parameter_types = True -# Check variable values against their annotations. -check_variable_types = True -# Comma or space separated list of error names to ignore. -disable = pyi-error -# Report errors. -report_errors = True -# Experimental: Infer precise return types even for invalid function calls. -precise_return = True -# Experimental: solve unknown types to label with structural types. -protocols = True -# Experimental: Only load submodules that are explicitly imported. -strict_import = False - [tool:pytest] # If a pytest section is found in one of the possible config files # (pytest.ini, tox.ini or setup.cfg), then pytest will not look for any others, From 20536f594a05a7b8ab7a9d017b22e91e62902ff2 Mon Sep 17 00:00:00 2001 From: M Q Date: Wed, 22 Mar 2023 21:06:53 -0700 Subject: [PATCH 13/15] isort: Imports are incorrectly sorted and/or formatted. Signed-off-by: M Q --- monai/deploy/operators/dicom_seg_writer_operator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monai/deploy/operators/dicom_seg_writer_operator.py b/monai/deploy/operators/dicom_seg_writer_operator.py index 5a142f85..124415e5 100644 --- a/monai/deploy/operators/dicom_seg_writer_operator.py +++ b/monai/deploy/operators/dicom_seg_writer_operator.py @@ -9,9 +9,9 @@ # See the License for the specific language governing permissions and # limitations under the License. -import os import datetime import logging +import os from pathlib import Path from random import randint from typing import TYPE_CHECKING, Dict, List, Optional, Sequence, Union From aa066528c51f28ca1825a8d7c79eeab2fd2c762b Mon Sep 17 00:00:00 2001 From: M Q Date: Wed, 22 Mar 2023 21:45:38 -0700 Subject: [PATCH 14/15] Gtihub run of pytype complains about import-error though local run does not! Signed-off-by: M Q --- monai/deploy/core/application.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monai/deploy/core/application.py b/monai/deploy/core/application.py index 106ff8d5..c6261b4d 100644 --- a/monai/deploy/core/application.py +++ b/monai/deploy/core/application.py @@ -82,7 +82,7 @@ def __init__( self.description = get_docstring(self.__class__) if not self.version: try: - from _version import get_versions + from monai.deploy._version import get_versions self.version = get_versions()["version"] except ImportError: From 4b681d16ec5c682f34718a03e0ace6682820b76d Mon Sep 17 00:00:00 2001 From: M Q Date: Wed, 22 Mar 2023 22:48:15 -0700 Subject: [PATCH 15/15] mypy complains about the fix required by flake8; the latter is wrong and quieted Signed-off-by: M Q --- platforms/nuance_pin/app/post_inference_ops.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/platforms/nuance_pin/app/post_inference_ops.py b/platforms/nuance_pin/app/post_inference_ops.py index d3674214..200335bd 100644 --- a/platforms/nuance_pin/app/post_inference_ops.py +++ b/platforms/nuance_pin/app/post_inference_ops.py @@ -58,9 +58,7 @@ def compute(self, op_input: InputContext, op_output: OutputContext, context: Exe all_ref_images = [ins.get_native_sop_instance() for ins in selected_series.series.get_sop_instances()] accession = all_ref_images[0].AccessionNumber - for inst_num, (box_data, box_score) in enumerate( - zip(detection_result.box_data, detection_result.score_data, strict=True) - ): + for inst_num, (box_data, box_score) in enumerate(zip(detection_result.box_data, detection_result.score_data)): tracking_id = f"{accession}_nodule_{inst_num}" # site-specific ID tracking_uid = hd.UID() @@ -188,7 +186,7 @@ def compute(self, op_input: InputContext, op_output: OutputContext, context: Exe slice_coords = list(range(len(selected_series.series.get_sop_instances()))) - for box_data, box_score in zip(detection_result.box_data, detection_result.score_data, strict=True): + for box_data, box_score in zip(detection_result.box_data, detection_result.score_data): affected_slice_idx = [ idx for idx, slice_coord in enumerate(slice_coords)