Skip to content

Python SDK spring cleaning: 3.9, no more monkey patching, more lints #9182

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Mar 5, 2025
4 changes: 2 additions & 2 deletions crates/build/re_types_builder/src/codegen/python/views.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ fn init_method(reporter: &Reporter, objects: &Objects, obj: &Object) -> String {
contents: ViewContentsLike = "$origin/**",
name: Utf8Like | None = None,
visible: datatypes.BoolLike | None = None,
defaults: list[Union[AsComponents, ComponentBatchLike]] = [],
overrides: dict[EntityPathLike, list[ComponentBatchLike]] = {},
defaults: list[Union[AsComponents, ComponentBatchLike]] | None = None,
overrides: dict[EntityPathLike, list[ComponentBatchLike]] | None = None,
"#
.to_owned();

Expand Down
2 changes: 1 addition & 1 deletion docs/snippets/compare_snippet_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ def run_example(example: Example, language: str, args: argparse.Namespace) -> No
rust_output_path = run_prebuilt_rust(example, args.release, args.target, args.target_dir)
check_non_empty_rrd(rust_output_path)
else:
assert False, f"Unknown language: {language}"
raise AssertionError(f"Unknown language: {language}")


def build_rust_snippets(build_env: dict[str, str], release: bool, target: str | None, target_dir: str | None):
Expand Down
2 changes: 1 addition & 1 deletion examples/python/air_traffic_data/air_traffic_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ def download_eu_map_data() -> None:
# cspell:disable-next-line
map_data = gpd.read_file(MAP_DATA_DIR / f"NUTS_RG_01M_2021_4326_LEVL_{level}.json").set_crs("epsg:4326").to_crs(crs)

for i, row in map_data[map_data.CNTR_CODE == country_code].iterrows():
for _i, row in map_data[map_data.CNTR_CODE == country_code].iterrows():
entity_path = f"region_boundaries/{country_code}/{level}/{row.NUTS_ID}"
lines = shapely_geom_to_numpy(row.geometry)
rr.log(entity_path + "/2D", rr.LineStrips2D(lines, colors=color), static=True)
Expand Down
3 changes: 2 additions & 1 deletion examples/python/all_examples/all_examples/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from __future__ import annotations

import platform
from collections.abc import Iterable
from dataclasses import dataclass, field
from pathlib import Path
from typing import Any, Iterable, cast
from typing import Any, cast

import tomli
from pyproject_metadata import StandardMetadata
Expand Down
2 changes: 1 addition & 1 deletion examples/python/all_examples/hatch_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from all_examples import active_examples


class MetadataHook(MetadataHookInterface): # type: ignore[misc]
class MetadataHook(MetadataHookInterface):
def update(self, metadata: dict[str, Any]) -> None:
"""
Use our very own package to list the examples we depend on.
Expand Down
4 changes: 2 additions & 2 deletions examples/python/arkit_scenes/arkit_scenes/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import json
import os
from pathlib import Path
from typing import Any, Tuple
from typing import Any

import cv2
import numpy as np
Expand All @@ -26,7 +26,7 @@
[on GitHub](https://github.com/rerun-io/rerun/blob/latest/examples/python/arkit_scenes).
""".strip()

Color = Tuple[float, float, float, float]
Color = tuple[float, float, float, float]

# hack for now since dataset does not provide orientation information, only known after initial visual inspection
ORIENTATION = {
Expand Down
4 changes: 2 additions & 2 deletions examples/python/controlnet/controlnet.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ def controlnet_callback(
rr.set_index("timestep", timedelta=timestep)
latents = callback_kwargs["latents"]

image = pipe.vae.decode(latents / pipe.vae.config.scaling_factor, return_dict=False)[0] # type: ignore[attr-defined]
image = pipe.image_processor.postprocess(image, output_type="np").squeeze() # type: ignore[attr-defined]
image = pipe.vae.decode(latents / pipe.vae.config.scaling_factor, return_dict=False)[0]
image = pipe.image_processor.postprocess(image, output_type="np").squeeze()
rr.log("output", rr.Image(image))
rr.log("latent", rr.Tensor(latents.squeeze(), dim_names=["channel", "height", "width"]))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
import json
import logging
import os
from collections.abc import Sequence
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are some of these moved from typing to collection.abc? Is there a lint to catch the wrong usage?

from dataclasses import dataclass
from pathlib import Path
from typing import Any, Final, Sequence
from typing import Any, Final

import cv2
import numpy as np
Expand Down Expand Up @@ -176,7 +177,7 @@ def __init__(self, tracking_id: int, detection: Detection, bgr: cv2.typing.MatLi
self.tracked = detection.scaled_to_fit_image(bgr)
self.num_recent_undetected_frames = 0

self.tracker = cv2.legacy.TrackerCSRT_create() # type: ignore[attr-defined]
self.tracker = cv2.legacy.TrackerCSRT_create()
bbox_xywh_rounded = [int(val) for val in self.tracked.bbox_xywh]
self.tracker.init(bgr, bbox_xywh_rounded)
self.log_tracked()
Expand Down Expand Up @@ -218,7 +219,7 @@ def log_tracked(self) -> None:
def update_with_detection(self, detection: Detection, bgr: cv2.typing.MatLike) -> None:
self.num_recent_undetected_frames = 0
self.tracked = detection.scaled_to_fit_image(bgr)
self.tracker = cv2.TrackerCSRT_create() # type: ignore[attr-defined]
self.tracker = cv2.TrackerCSRT_create()
bbox_xywh_rounded = [int(val) for val in self.tracked.bbox_xywh]
self.tracker.init(bgr, bbox_xywh_rounded)
self.log_tracked()
Expand Down
5 changes: 3 additions & 2 deletions examples/python/dicom_mri/dicom_mri.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
import io
import os
import zipfile
from collections.abc import Iterable
from pathlib import Path
from typing import Final, Iterable
from typing import Final

import dicom_numpy
import numpy as np
Expand Down Expand Up @@ -37,7 +38,7 @@
def extract_voxel_data(
dicom_files: Iterable[Path],
) -> tuple[npt.NDArray[np.int16], npt.NDArray[np.float32]]:
slices = [dicom.read_file(f) for f in dicom_files] # type: ignore[misc]
slices = [dicom.read_file(f) for f in dicom_files]
try:
voxel_ndarray, ijk_to_xyz = dicom_numpy.combine_slices(slices)
except dicom_numpy.DicomImportException:
Expand Down
3 changes: 2 additions & 1 deletion examples/python/face_tracking/face_tracking.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@
import logging
import math
import os
from collections.abc import Iterable
from pathlib import Path
from typing import Final, Iterable
from typing import Final

import cv2
import mediapipe as mp
Expand Down
5 changes: 3 additions & 2 deletions examples/python/gesture_detection/gesture_detection.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
import itertools
import logging
import os
from collections.abc import Iterable
from pathlib import Path
from typing import Final, Iterable
from typing import Final

import cv2
import mediapipe as mp
Expand Down Expand Up @@ -114,7 +115,7 @@ def detect_and_log(self, image: cv2.typing.MatLike, frame_time_nano: int) -> Non
for log_key in ["hand2d/points", "hand2d/connections", "hand3d/points"]:
rr.log(log_key, rr.Clear(recursive=True))

for i, gesture in enumerate(recognition_result.gestures):
for gesture in recognition_result.gestures:
# Get the top gesture from the recognition result
gesture_category = gesture[0].category_name if recognition_result.gestures else "None"
self.present_detected_gesture(gesture_category) # Log the detected gesture
Expand Down
3 changes: 2 additions & 1 deletion examples/python/human_pose_tracking/human_pose_tracking.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
import argparse
import logging
import os
from collections.abc import Iterator
from contextlib import closing
from dataclasses import dataclass
from pathlib import Path
from typing import Any, Final, Iterator
from typing import Any, Final

import cv2
import mediapipe as mp
Expand Down
2 changes: 1 addition & 1 deletion examples/python/live_depth_sensor/live_depth_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def run_realsense(num_frames: int | None) -> None:
frame_nr += 1

frames = pipe.wait_for_frames()
for f in frames:
for _f in frames:
# Log the depth frame
depth_frame = frames.get_depth_frame()
depth_units = depth_frame.get_units()
Expand Down
2 changes: 1 addition & 1 deletion examples/python/live_scrolling_plot/live_scrolling_plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import argparse
import time
from typing import Iterator
from collections.abc import Iterator

import numpy as np
import rerun as rr # pip install rerun-sdk
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from __future__ import annotations

import math
from typing import Sequence
from collections.abc import Sequence

EARTH_RADIUS_METERS = 6.378137e6
REFERENCE_COORDINATES = {
Expand Down
2 changes: 1 addition & 1 deletion examples/python/objectron/objectron/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
import os
import sys
import time
from collections.abc import Iterable, Iterator
from dataclasses import dataclass
from pathlib import Path
from typing import Iterable, Iterator

import numpy as np
import rerun as rr # pip install rerun-sdk
Expand Down
5 changes: 3 additions & 2 deletions examples/python/ocr/ocr.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
import argparse
import logging
import os
from collections.abc import Iterable
from enum import Enum
from pathlib import Path
from typing import Any, Final, Iterable, Optional
from typing import Any, Final, Optional

import cv2 as cv2
import numpy as np
Expand Down Expand Up @@ -373,7 +374,7 @@ def detect_and_log_layouts(file_path: str) -> None:
layouts: list[Layout] = []
page_numbers = [i + 1 for i in range(len(images))]
processed_layouts: list[LayoutStructure] = []
for i, (image, page_number) in enumerate(zip(images, page_numbers)):
for image, page_number in zip(images, page_numbers):
layouts.append(detect_and_log_layout(image, page_number))
page_path = f"page_{page_number}"

Expand Down
2 changes: 1 addition & 1 deletion examples/python/raw_mesh/raw_mesh/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def log_scene(scene: trimesh.Scene, node: str, path: str | None = None) -> None:
rr.Mesh3D(
vertex_positions=mesh.vertices,
vertex_colors=vertex_colors,
vertex_normals=mesh.vertex_normals, # type: ignore[arg-type]
vertex_normals=mesh.vertex_normals,
vertex_texcoords=vertex_texcoords,
albedo_texture=albedo_texture,
triangle_indices=mesh.faces,
Expand Down
17 changes: 10 additions & 7 deletions examples/python/rgbd/rgbd.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,13 +141,16 @@ def download_progress(url: str, dst: Path) -> None:
total = int(resp.headers.get("content-length", 0))
chunk_size = 1024 * 1024
# Can also replace 'file' with a io.BytesIO object
with open(dst, "wb") as file, tqdm(
desc=dst.name,
total=total,
unit="iB",
unit_scale=True,
unit_divisor=1024,
) as bar:
with (
open(dst, "wb") as file,
tqdm(
desc=dst.name,
total=total,
unit="iB",
unit_scale=True,
unit_divisor=1024,
) as bar,
):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what are the extra () good for ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure, ruff did that, probably following the 3.9 min version.

for data in resp.iter_content(chunk_size=chunk_size):
size = file.write(data)
bar.update(size)
Expand Down
3 changes: 2 additions & 1 deletion examples/python/rrt_star/rrt_star.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
from __future__ import annotations

import argparse
from typing import Annotated, Generator, Literal
from collections.abc import Generator
from typing import Annotated, Literal

import numpy as np
import numpy.typing as npt
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def run_segmentation(mask_generator: SamAutomaticMaskGenerator, image: cv2.typin
# TODO(jleibs): we could instead draw each mask as a separate image layer, but the current layer-stacking
# does not produce great results.
masks_with_ids = list(enumerate(masks, start=1))
masks_with_ids.sort(key=(lambda x: x[1]["area"]), reverse=True) # type: ignore[no-any-return]
masks_with_ids.sort(key=(lambda x: x[1]["area"]), reverse=True)

# Layer all of the masks together, using the id as class-id in the segmentation
segmentation_img = np.zeros((image.shape[0], image.shape[1]))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ def read_and_log_sparse_reconstruction(dataset_path: Path, filter_output: bool,
rr.log("plot/avg_reproj_err", rr.SeriesLine(color=[240, 45, 58]), static=True)

# Iterate through images (video frames) logging data related to each frame.
for image in sorted(images.values(), key=lambda im: im.name): # type: ignore[no-any-return]
for image in sorted(images.values(), key=lambda im: im.name):
image_file = dataset_path / "images" / image.name

if not os.path.exists(image_file):
Expand Down
Loading
Loading