From ddb047a1cf5464ec7cf6c5063bfe4ad6b5dc5339 Mon Sep 17 00:00:00 2001 From: Hirokazu Ishida <38597814+HiroIshida@users.noreply.github.com> Date: Wed, 9 Nov 2022 04:27:13 +0900 Subject: [PATCH] Use mypy for static type checking (#30) * Add mypy.ini * Fix type annotation misstake by recent update * Ignore type annotation miss * Add mypy test in ci --- .github/workflows/peripheral.yml | 26 ++++++++++++++++++++ mypy.ini | 41 ++++++++++++++++++++++++++++++++ node_script/batch_processor.py | 2 +- node_script/wrapper.py | 11 +++++++-- 4 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/peripheral.yml create mode 100644 mypy.ini diff --git a/.github/workflows/peripheral.yml b/.github/workflows/peripheral.yml new file mode 100644 index 0000000..6f05ebe --- /dev/null +++ b/.github/workflows/peripheral.yml @@ -0,0 +1,26 @@ +name: Peripheral test + +on: + push: + branches: + - master + pull_request: + branches: + - master + +jobs: + peripheral: + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@v2 + - name: pip install formatters and mypy + run: | + pip3 install mypy + + - name: check by mypy + run: | + pip3 install -r requirements.txt + pip3 install numpy==1.23 # to enable numpy's type checking + mypy --version + mypy . diff --git a/mypy.ini b/mypy.ini new file mode 100644 index 0000000..71dddd3 --- /dev/null +++ b/mypy.ini @@ -0,0 +1,41 @@ +[mypy] +python_version = 3.8 +exclude = Detic +show_error_codes = True +warn_unused_ignores = False +check_untyped_defs = True + +[mypy-cv_bridge] +ignore_missing_imports = True +[mypy-rospy] +ignore_missing_imports = True +[mypy-rostest] +ignore_missing_imports = True +[mypy-rospkg] +ignore_missing_imports = True +[mypy-rosbag] +ignore_missing_imports = True +[mypy-message_filters] +ignore_missing_imports = True +[mypy-detectron2.*] +ignore_missing_imports = True +[mypy-detic.*] +ignore_missing_imports = True +[mypy-centernet.config] +ignore_missing_imports = True +[mypy-detic_ros.*] +ignore_missing_imports = True +[mypy-sensor_msgs.*] +ignore_missing_imports = True +[mypy-std_msgs.*] +ignore_missing_imports = True +[mypy-jsk_recognition_msgs.*] +ignore_missing_imports = True +[mypy-cv2] +ignore_missing_imports = True +[mypy-matplotlib.*] +ignore_missing_imports = True +[mypy-tqdm] +ignore_missing_imports = True +[mypy-moviepy.*] +ignore_missing_imports = True diff --git a/node_script/batch_processor.py b/node_script/batch_processor.py index 75175f2..ab255ee 100755 --- a/node_script/batch_processor.py +++ b/node_script/batch_processor.py @@ -53,7 +53,7 @@ def deep_cast(msg): def dump_result_as_pickle(results, image_list, output_file_name): - result_dict = {'image': [], 'seginfo': [], 'debug_image': []} + result_dict = {'image': [], 'seginfo': [], 'debug_image': []} # type: ignore for ((seginfo, debug_image, _), image) in zip(results, image_list): seginfo, debug_image, _ = detic_wrapper.infer(image) result_dict['image'].append(image) diff --git a/node_script/wrapper.py b/node_script/wrapper.py index 1e1b269..ac0a8a1 100644 --- a/node_script/wrapper.py +++ b/node_script/wrapper.py @@ -5,9 +5,9 @@ import rospkg from cv_bridge import CvBridge from sensor_msgs.msg import Image +from std_msgs.msg import Header from detic_ros.msg import SegmentationInfo - import torch import numpy as np @@ -21,6 +21,10 @@ class DeticWrapper: predictor: VisualizationDemo node_config: NodeConfig + bridge: CvBridge + class_names: List[str] + header: Optional[Header] + data: Optional[np.ndarray] class DummyArgs: vocabulary: str @@ -93,14 +97,17 @@ def get_debug_img(self, visualized_output: VisImage) -> Image: # Call after inference_step debug_img = self.bridge.cv2_to_imgmsg(visualized_output.get_image(), encoding="rgb8") + assert self.header is not None debug_img.header = self.header return debug_img def get_debug_segimg(self) -> Image: # Call after inference_step + assert self.data is not None human_friendly_scaling = 255 // self.data.max() new_data = (self.data * human_friendly_scaling).astype(np.uint8) debug_seg_img = self.bridge.cv2_to_imgmsg(new_data, encoding="mono8") + assert self.header is not None debug_seg_img.header = self.header return debug_seg_img @@ -114,7 +121,7 @@ def get_segmentation_info(self, seg_img: Image, header=self.header) return seg_info - def get_label_array(self, detected_classes: List[str]) -> LabelArray: + def get_label_array(self, detected_classes: List[int]) -> LabelArray: # Label 0 is reserved for the background labels = [Label(id=i+1, name=self.class_names[i]) for i in detected_classes] lab_arr = LabelArray(header=self.header,