From e475d10adcc7aafc845f81cfb724e31cf5c3fb2b Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sun, 19 Jul 2026 08:51:16 -0700 Subject: [PATCH] more ruff (#38377) * lil more ruff * no exclusions! * rm nb exception * and generated * not used * c408 * random * all * unittest is fine --- openpilot/cereal/messaging/__init__.py | 79 +++++++++++++------ .../messaging/tests/test_pub_sub_master.py | 3 +- openpilot/cereal/services.py | 6 +- openpilot/common/swaglog.py | 2 +- openpilot/selfdrive/car/tests/test_models.py | 2 +- .../tests/test_torqued_lat_accel_offset.py | 2 - openpilot/selfdrive/locationd/helpers.py | 3 +- .../selfdrive/locationd/test/test_lagd.py | 11 +-- openpilot/selfdrive/modeld/compile_modeld.py | 4 +- .../selfdrive/pandad/tests/test_pandad_spi.py | 4 +- openpilot/selfdrive/test/mem_usage.py | 2 +- .../selfdrive/ui/layouts/settings/settings.py | 4 +- .../selfdrive/ui/tests/profile_onroad.py | 2 +- openpilot/system/athena/tests/test_athenad.py | 2 +- .../system/loggerd/tests/test_uploader.py | 4 +- openpilot/system/ui/lib/shader_polygon.py | 4 +- openpilot/system/webrtc/webrtcd.py | 5 +- openpilot/tools/lib/url_file.py | 2 +- openpilot/tools/lib/vidindex.py | 2 +- openpilot/tools/replay/lib/ui_helpers.py | 4 +- .../sim/bridge/metadrive/metadrive_bridge.py | 60 +++++++------- pyproject.toml | 19 ++--- .../examples/find_segments_with_message.ipynb | 5 +- .../examples/ford_vin_fingerprint.ipynb | 9 ++- .../examples/hkg_canfd_gear_message.ipynb | 10 +-- tools/car_porting/test_car_model.py | 2 +- 26 files changed, 136 insertions(+), 116 deletions(-) diff --git a/openpilot/cereal/messaging/__init__.py b/openpilot/cereal/messaging/__init__.py index cb5f090095..dcc54baeb0 100644 --- a/openpilot/cereal/messaging/__init__.py +++ b/openpilot/cereal/messaging/__init__.py @@ -7,12 +7,43 @@ import os import capnp import time -from typing import Optional, List, Union, Dict +from typing import Union from openpilot.cereal import log from openpilot.cereal.services import SERVICE_LIST from openpilot.common.utils import MovingAverage +__all__ = ( + "NO_TRAVERSAL_LIMIT", + "Context", + "FrequencyTracker", + "IpcError", + "MultiplePublishersError", + "Poller", + "PubMaster", + "PubSocket", + "SocketEventHandle", + "SubMaster", + "SubSocket", + "delete_fake_prefix", + "drain_sock", + "drain_sock_raw", + "fake_event_handle", + "get_fake_prefix", + "log_from_bytes", + "new_message", + "pub_sock", + "recv_one", + "recv_one_or_none", + "recv_one_retry", + "recv_sock", + "reset_context", + "set_fake_prefix", + "sub_sock", + "toggle_fake_events", + "wait_for_one_event", +) + NO_TRAVERSAL_LIMIT = 2**64-1 @@ -22,8 +53,8 @@ def pub_sock(endpoint: str) -> PubSocket: return msgq.pub_sock(endpoint, segment_size) -def sub_sock(endpoint: str, poller: Optional[Poller] = None, addr: str = "127.0.0.1", - conflate: bool = False, timeout: Optional[int] = None) -> SubSocket: +def sub_sock(endpoint: str, poller: Poller | None = None, addr: str = "127.0.0.1", + conflate: bool = False, timeout: int | None = None) -> SubSocket: service = SERVICE_LIST.get(endpoint) segment_size = service.queue_size if service else 0 return msgq.sub_sock(endpoint, poller=poller, addr=addr, conflate=conflate, @@ -39,7 +70,7 @@ def log_from_bytes(dat: bytes, struct: capnp.lib.capnp._StructModule = log.Event return msg -def new_message(service: Optional[str], size: Optional[int] = None, **kwargs) -> capnp.lib.capnp._DynamicStructBuilder: +def new_message(service: str | None, size: int | None = None, **kwargs) -> capnp.lib.capnp._DynamicStructBuilder: args = { 'valid': False, 'logMonoTime': int(time.monotonic() * 1e9), @@ -54,14 +85,14 @@ def new_message(service: Optional[str], size: Optional[int] = None, **kwargs) -> return dat -def drain_sock(sock: SubSocket, wait_for_one: bool = False) -> List[capnp.lib.capnp._DynamicStructReader]: +def drain_sock(sock: SubSocket, wait_for_one: bool = False) -> list[capnp.lib.capnp._DynamicStructReader]: """Receive all message currently available on the queue""" msgs = drain_sock_raw(sock, wait_for_one=wait_for_one) return [log_from_bytes(m) for m in msgs] # TODO: print when we drop packets? -def recv_sock(sock: SubSocket, wait: bool = False) -> Optional[capnp.lib.capnp._DynamicStructReader]: +def recv_sock(sock: SubSocket, wait: bool = False) -> capnp.lib.capnp._DynamicStructReader | None: """Same as drain sock, but only returns latest message. Consider using conflate instead.""" dat = None @@ -82,14 +113,14 @@ def recv_sock(sock: SubSocket, wait: bool = False) -> Optional[capnp.lib.capnp._ return dat -def recv_one(sock: SubSocket) -> Optional[capnp.lib.capnp._DynamicStructReader]: +def recv_one(sock: SubSocket) -> capnp.lib.capnp._DynamicStructReader | None: dat = sock.receive() if dat is not None: dat = log_from_bytes(dat) return dat -def recv_one_or_none(sock: SubSocket) -> Optional[capnp.lib.capnp._DynamicStructReader]: +def recv_one_or_none(sock: SubSocket) -> capnp.lib.capnp._DynamicStructReader | None: dat = sock.receive(non_blocking=True) if dat is not None: dat = log_from_bytes(dat) @@ -148,27 +179,27 @@ class FrequencyTracker: class SubMaster: - def __init__(self, services: List[str], poll: Optional[str] = None, - ignore_alive: Optional[List[str]] = None, ignore_avg_freq: Optional[List[str]] = None, - ignore_valid: Optional[List[str]] = None, addr: str = "127.0.0.1", frequency: Optional[float] = None): + def __init__(self, services: list[str], poll: str | None = None, + ignore_alive: list[str] | None = None, ignore_avg_freq: list[str] | None = None, + ignore_valid: list[str] | None = None, addr: str = "127.0.0.1", frequency: float | None = None): self.frame = -1 self.services = services - self.seen = {s: False for s in services} - self.updated = {s: False for s in services} - self.recv_time = {s: 0. for s in services} - self.recv_frame = {s: 0 for s in services} + self.seen = dict.fromkeys(services, False) + self.updated = dict.fromkeys(services, False) + self.recv_time = dict.fromkeys(services, 0.0) + self.recv_frame = dict.fromkeys(services, 0) self.sock = {} self.data = {} - self.logMonoTime = {s: 0 for s in services} + self.logMonoTime = dict.fromkeys(services, 0) # zero-frequency / on-demand services are always alive and presumed valid; all others must pass checks on_demand = {s: SERVICE_LIST[s].frequency <= 1e-5 for s in services} - self.static_freq_services = set(s for s in services if not on_demand[s]) + self.static_freq_services = {s for s in services if not on_demand[s]} self.alive = {s: on_demand[s] for s in services} self.freq_ok = {s: on_demand[s] for s in services} self.valid = {s: on_demand[s] for s in services} - self.freq_tracker: Dict[str, FrequencyTracker] = {} + self.freq_tracker: dict[str, FrequencyTracker] = {} self.poller = Poller() polled_services = set([poll, ] if poll is not None else services) self.non_polled_services = set(services) - polled_services @@ -211,7 +242,7 @@ class SubMaster: msgs.append(recv_one_or_none(self.sock[s])) self.update_msgs(time.monotonic(), msgs) - def update_msgs(self, cur_time: float, msgs: List[capnp.lib.capnp._DynamicStructReader]) -> None: + def update_msgs(self, cur_time: float, msgs: list[capnp.lib.capnp._DynamicStructReader]) -> None: self.frame += 1 self.updated = dict.fromkeys(self.services, False) for msg in msgs: @@ -234,21 +265,21 @@ class SubMaster: self.alive[s] = (cur_time - self.recv_time[s]) < (10. / SERVICE_LIST[s].frequency) or (self.seen[s] and self.simulation) self.freq_ok[s] = self.freq_tracker[s].valid or self.simulation - def all_alive(self, service_list: Optional[List[str]] = None) -> bool: + def all_alive(self, service_list: list[str] | None = None) -> bool: return all(self.alive[s] for s in (service_list or self.services) if s not in self.ignore_alive) - def all_freq_ok(self, service_list: Optional[List[str]] = None) -> bool: + def all_freq_ok(self, service_list: list[str] | None = None) -> bool: return all(self.freq_ok[s] for s in (service_list or self.services) if self._check_avg_freq(s)) - def all_valid(self, service_list: Optional[List[str]] = None) -> bool: + def all_valid(self, service_list: list[str] | None = None) -> bool: return all(self.valid[s] for s in (service_list or self.services) if s not in self.ignore_valid) - def all_checks(self, service_list: Optional[List[str]] = None) -> bool: + def all_checks(self, service_list: list[str] | None = None) -> bool: return self.all_alive(service_list) and self.all_freq_ok(service_list) and self.all_valid(service_list) class PubMaster: - def __init__(self, services: List[str]): + def __init__(self, services: list[str]): self.sock = {} for s in services: self.sock[s] = pub_sock(s) diff --git a/openpilot/cereal/messaging/tests/test_pub_sub_master.py b/openpilot/cereal/messaging/tests/test_pub_sub_master.py index eb8f62140b..02f944b69f 100644 --- a/openpilot/cereal/messaging/tests/test_pub_sub_master.py +++ b/openpilot/cereal/messaging/tests/test_pub_sub_master.py @@ -1,6 +1,7 @@ import random import time -from typing import Sized, cast +from typing import cast +from collections.abc import Sized import openpilot.cereal.messaging as messaging from openpilot.cereal.messaging.tests.test_messaging import events, random_sock, random_socks, \ diff --git a/openpilot/cereal/services.py b/openpilot/cereal/services.py index 0f5e50f31f..db1731a986 100755 --- a/openpilot/cereal/services.py +++ b/openpilot/cereal/services.py @@ -1,6 +1,5 @@ #!/usr/bin/env python3 from enum import IntEnum -from typing import Optional # TODO: this should be automatically determined using the capnp schema @@ -11,7 +10,7 @@ class QueueSize(IntEnum): class Service: - def __init__(self, should_log: bool, frequency: float, decimation: Optional[int] = None, + def __init__(self, should_log: bool, frequency: float, decimation: int | None = None, queue_size: QueueSize = QueueSize.SMALL): self.should_log = should_log self.frequency = frequency @@ -112,8 +111,7 @@ def build_header(): for k, v in SERVICE_LIST.items(): should_log = "true" if v.should_log else "false" decimation = -1 if v.decimation is None else v.decimation - h += ' { "%s", {"%s", %s, %f, %d, %d}},\n' % \ - (k, k, should_log, v.frequency, decimation, v.queue_size) + h += f' {{ "{k}", {{"{k}", {should_log}, {v.frequency:f}, {decimation:d}, {v.queue_size:d}}}}},\n' h += "};\n" h += "#endif\n" diff --git a/openpilot/common/swaglog.py b/openpilot/common/swaglog.py index ea72766fcb..ac64230eed 100644 --- a/openpilot/common/swaglog.py +++ b/openpilot/common/swaglog.py @@ -39,7 +39,7 @@ class SwaglogRotatingFileHandler(BaseRotatingHandler): return stream def get_existing_logfiles(self): - log_files = list() + log_files = [] base_dir = os.path.dirname(self.base_filename) for fn in os.listdir(base_dir): fp = os.path.join(base_dir, fn) diff --git a/openpilot/selfdrive/car/tests/test_models.py b/openpilot/selfdrive/car/tests/test_models.py index ac2cd3ec7e..436de261e6 100644 --- a/openpilot/selfdrive/car/tests/test_models.py +++ b/openpilot/selfdrive/car/tests/test_models.py @@ -2,7 +2,7 @@ import time import os import pytest import random -import unittest # noqa: TID251 +import unittest from collections import defaultdict, Counter import hypothesis.strategies as st from hypothesis import Phase, given, settings diff --git a/openpilot/selfdrive/controls/tests/test_torqued_lat_accel_offset.py b/openpilot/selfdrive/controls/tests/test_torqued_lat_accel_offset.py index 93a57d7f60..7a63da23a5 100644 --- a/openpilot/selfdrive/controls/tests/test_torqued_lat_accel_offset.py +++ b/openpilot/selfdrive/controls/tests/test_torqued_lat_accel_offset.py @@ -7,8 +7,6 @@ from opendbc.car.lateral import get_friction, FRICTION_THRESHOLD from openpilot.common.realtime import DT_MDL from openpilot.selfdrive.locationd.torqued import TorqueEstimator, MIN_BUCKET_POINTS, POINTS_PER_BUCKET, STEER_BUCKET_BOUNDS -np.random.seed(0) - LA_ERR_STD = 1.0 INPUT_NOISE_STD = 0.08 V_EGO = 30.0 diff --git a/openpilot/selfdrive/locationd/helpers.py b/openpilot/selfdrive/locationd/helpers.py index fe7930c509..849b950de2 100644 --- a/openpilot/selfdrive/locationd/helpers.py +++ b/openpilot/selfdrive/locationd/helpers.py @@ -69,6 +69,7 @@ class NPQueue: class PointBuckets: def __init__(self, x_bounds: list[tuple[float, float]], min_points: list[float], min_points_total: int, points_per_bucket: int, rowsize: int) -> None: + self._rng = np.random.default_rng() self.x_bounds = x_bounds self.buckets = {bounds: NPQueue(maxlen=points_per_bucket, rowsize=rowsize) for bounds in x_bounds} self.buckets_min_points = dict(zip(x_bounds, min_points, strict=True)) @@ -98,7 +99,7 @@ class PointBuckets: points = np.vstack([x.arr for x in self.buckets.values()]) if num_points is None: return points - return points[np.random.choice(np.arange(len(points)), min(len(points), num_points), replace=False)] + return points[self._rng.choice(np.arange(len(points)), min(len(points), num_points), replace=False)] def load_points(self, points: list[list[float]]) -> None: for point in points: diff --git a/openpilot/selfdrive/locationd/test/test_lagd.py b/openpilot/selfdrive/locationd/test/test_lagd.py index 128c19332f..efaba6ead9 100644 --- a/openpilot/selfdrive/locationd/test/test_lagd.py +++ b/openpilot/selfdrive/locationd/test/test_lagd.py @@ -81,6 +81,7 @@ class TestLagd: assert retrieve_initial_lag(params, CP) is None def test_ncc(self): + rng = np.random.default_rng() lag_frames = random.randint(1, 19) desired_sig = np.sin(np.arange(0.0, 10.0, 0.1)) @@ -91,15 +92,15 @@ class TestLagd: assert np.argmax(corr) == lag_frames # add some noise - desired_sig += np.random.normal(0, 0.05, len(desired_sig)) - actual_sig += np.random.normal(0, 0.05, len(actual_sig)) + desired_sig += rng.normal(0, 0.05, len(desired_sig)) + actual_sig += rng.normal(0, 0.05, len(actual_sig)) corr = masked_normalized_cross_correlation(desired_sig, actual_sig, mask, 200)[len(desired_sig) - 1:len(desired_sig) + 20] assert np.argmax(corr) in range(lag_frames - MAX_ERR_FRAMES, lag_frames + MAX_ERR_FRAMES + 1) # mask out 40% of the values, and make them noise - mask = np.random.choice([True, False], size=len(desired_sig), p=[0.6, 0.4]) - desired_sig[~mask] = np.random.normal(0, 1, size=np.sum(~mask)) - actual_sig[~mask] = np.random.normal(0, 1, size=np.sum(~mask)) + mask = rng.choice([True, False], size=len(desired_sig), p=[0.6, 0.4]) + desired_sig[~mask] = rng.normal(0, 1, size=np.sum(~mask)) + actual_sig[~mask] = rng.normal(0, 1, size=np.sum(~mask)) corr = masked_normalized_cross_correlation(desired_sig, actual_sig, mask, 200)[len(desired_sig) - 1:len(desired_sig) + 20] assert np.argmax(corr) in range(lag_frames - MAX_ERR_FRAMES, lag_frames + MAX_ERR_FRAMES + 1) diff --git a/openpilot/selfdrive/modeld/compile_modeld.py b/openpilot/selfdrive/modeld/compile_modeld.py index 769fb69eb3..f74ab27b8c 100755 --- a/openpilot/selfdrive/modeld/compile_modeld.py +++ b/openpilot/selfdrive/modeld/compile_modeld.py @@ -242,7 +242,7 @@ def compile_jit(jit, make_random_inputs, input_keys, make_queues): SEED = 42 def random_inputs_run(fn, seed, test_val=None, test_buffers=None, expect_match=True): input_queues, npy = make_queues(Device.DEFAULT) - np.random.seed(seed) + rng = np.random.default_rng(seed) Tensor.manual_seed(seed) testing = test_val is not None or test_buffers is not None @@ -250,7 +250,7 @@ def compile_jit(jit, make_random_inputs, input_keys, make_queues): for i in range(n_runs): for v in npy.values(): - v[:] = np.random.randn(*v.shape).astype(v.dtype) + v[:] = rng.standard_normal(v.shape).astype(v.dtype) Device.default.synchronize() random_inputs = make_random_inputs() st = time.perf_counter() diff --git a/openpilot/selfdrive/pandad/tests/test_pandad_spi.py b/openpilot/selfdrive/pandad/tests/test_pandad_spi.py index 02f5accfd6..2bc302b47c 100644 --- a/openpilot/selfdrive/pandad/tests/test_pandad_spi.py +++ b/openpilot/selfdrive/pandad/tests/test_pandad_spi.py @@ -38,10 +38,10 @@ class TestBoarddSpi: total_recv_count = 0 total_sent_count = 0 - sent_msgs = {bus: list() for bus in range(3)} + sent_msgs = {bus: [] for bus in range(3)} st = time.monotonic() - ts = {s: list() for s in socks.keys()} + ts = {s: [] for s in socks.keys()} for _ in range(int(os.getenv("TEST_TIME", "20"))): # send some CAN messages if not JUNGLE_SPAM: diff --git a/openpilot/selfdrive/test/mem_usage.py b/openpilot/selfdrive/test/mem_usage.py index 1446d0b4dc..02b7934466 100644 --- a/openpilot/selfdrive/test/mem_usage.py +++ b/openpilot/selfdrive/test/mem_usage.py @@ -7,7 +7,7 @@ from openpilot.common.utils import tabulate DEMO_ROUTE = "5beb9b58bd12b691/0000010a--a51155e496" MB = 1024 * 1024 -TABULATE_OPTS = dict(tablefmt="simple_grid", stralign="center", numalign="center") +TABULATE_OPTS = {"tablefmt": "simple_grid", "stralign": "center", "numalign": "center"} def _get_procs(): diff --git a/openpilot/selfdrive/ui/layouts/settings/settings.py b/openpilot/selfdrive/ui/layouts/settings/settings.py index 68f45df77d..48b75e5dbd 100644 --- a/openpilot/selfdrive/ui/layouts/settings/settings.py +++ b/openpilot/selfdrive/ui/layouts/settings/settings.py @@ -1,5 +1,5 @@ import pyray as rl -from dataclasses import dataclass +from dataclasses import dataclass, field from enum import IntEnum from collections.abc import Callable from openpilot.selfdrive.ui.layouts.settings.developer import DeveloperLayout @@ -43,7 +43,7 @@ class PanelType(IntEnum): class PanelInfo: name: str instance: Widget - button_rect: rl.Rectangle = rl.Rectangle(0, 0, 0, 0) + button_rect: rl.Rectangle = field(default_factory=lambda: rl.Rectangle(0, 0, 0, 0)) class SettingsLayout(Widget): diff --git a/openpilot/selfdrive/ui/tests/profile_onroad.py b/openpilot/selfdrive/ui/tests/profile_onroad.py index 18194d7363..29e44d6260 100755 --- a/openpilot/selfdrive/ui/tests/profile_onroad.py +++ b/openpilot/selfdrive/ui/tests/profile_onroad.py @@ -92,7 +92,7 @@ if __name__ == "__main__": vipc.create_buffers(VisionStreamType.VISION_STREAM_ROAD, 5, W, H) vipc.start_listener() yuv_buffer_size = W * H + (W // 2) * (H // 2) * 2 - yuv_data = np.random.randint(0, 256, yuv_buffer_size, dtype=np.uint8).tobytes() + yuv_data = np.random.default_rng().integers(0, 256, yuv_buffer_size, dtype=np.uint8).tobytes() with cProfile.Profile() as pr: for _ in gui_app.render(): if ui_state.sm.frame >= len(message_chunks): diff --git a/openpilot/system/athena/tests/test_athenad.py b/openpilot/system/athena/tests/test_athenad.py index 253a057b91..accf0784ab 100644 --- a/openpilot/system/athena/tests/test_athenad.py +++ b/openpilot/system/athena/tests/test_athenad.py @@ -437,7 +437,7 @@ class TestAthenadMethods: thread.join() def test_get_logs_to_send_sorted(self): - fl = list() + fl = [] for i in range(10): file = f'swaglog.{i:010}' self._create_file(file, Paths.swaglog_root()) diff --git a/openpilot/system/loggerd/tests/test_uploader.py b/openpilot/system/loggerd/tests/test_uploader.py index eec85eda2e..3af78e2c37 100644 --- a/openpilot/system/loggerd/tests/test_uploader.py +++ b/openpilot/system/loggerd/tests/test_uploader.py @@ -18,8 +18,8 @@ class FakeLogHandler(logging.Handler): self.reset() def reset(self): - self.upload_order = list() - self.upload_ignored = list() + self.upload_order = [] + self.upload_ignored = [] def emit(self, record): try: diff --git a/openpilot/system/ui/lib/shader_polygon.py b/openpilot/system/ui/lib/shader_polygon.py index 94af35e157..de729d6aae 100644 --- a/openpilot/system/ui/lib/shader_polygon.py +++ b/openpilot/system/ui/lib/shader_polygon.py @@ -152,7 +152,7 @@ class ShaderState: self.initialized = False -def _configure_shader_color(state: ShaderState, color: Optional[rl.Color], +def _configure_shader_color(state: ShaderState, color: Optional[rl.Color], # noqa: UP045 # rl.Color is a function, so `rl.Color | None` fails gradient: Gradient | None, origin_rect: rl.Rectangle): assert (color is not None) != (gradient is not None), "Either color or gradient must be provided" @@ -204,7 +204,7 @@ def triangulate(pts: np.ndarray) -> list[tuple[float, float]]: def draw_polygon(origin_rect: rl.Rectangle, points: np.ndarray, - color: Optional[rl.Color] = None, gradient: Gradient | None = None): + color: Optional[rl.Color] = None, gradient: Gradient | None = None): # noqa: UP045 # rl.Color is a function, so `rl.Color | None` fails """ Draw a ribbon polygon (two chains) with a triangle strip and gradient. diff --git a/openpilot/system/webrtc/webrtcd.py b/openpilot/system/webrtc/webrtcd.py index 8276df98f2..82ebb7b018 100755 --- a/openpilot/system/webrtc/webrtcd.py +++ b/openpilot/system/webrtc/webrtcd.py @@ -566,13 +566,14 @@ def webrtcd_thread(host: str, port: int, debug: bool): http_thread.start() shutting_down = False + shutdown_task = None def request_shutdown() -> None: - nonlocal shutting_down + nonlocal shutting_down, shutdown_task if shutting_down: return shutting_down = True - loop.create_task(_shutdown(server, state, loop)) + shutdown_task = loop.create_task(_shutdown(server, state, loop)) for sig in (signal.SIGINT, signal.SIGTERM): loop.add_signal_handler(sig, request_shutdown) diff --git a/openpilot/tools/lib/url_file.py b/openpilot/tools/lib/url_file.py index 3f72429b94..ec0a3d5815 100644 --- a/openpilot/tools/lib/url_file.py +++ b/openpilot/tools/lib/url_file.py @@ -21,7 +21,7 @@ logging.getLogger("urllib3").setLevel(logging.WARNING) def hash_url(link: str) -> str: - return md5((link.split("?")[0]).encode('utf-8')).hexdigest() + return md5(link.split("?", maxsplit=1)[0].encode('utf-8')).hexdigest() def prune_cache(new_entry: str | None = None) -> None: diff --git a/openpilot/tools/lib/vidindex.py b/openpilot/tools/lib/vidindex.py index 4aef6fb4d5..b200700887 100755 --- a/openpilot/tools/lib/vidindex.py +++ b/openpilot/tools/lib/vidindex.py @@ -269,7 +269,7 @@ def hevc_index(hevc_file_name: str, allow_corrupt: bool=False) -> tuple[list, in raise VideoFileInvalid("first byte must be 0x00") prefix_dat = b"" - frame_types = list() + frame_types = [] i = 1 # skip past first byte 0x00 try: diff --git a/openpilot/tools/replay/lib/ui_helpers.py b/openpilot/tools/replay/lib/ui_helpers.py index 6a3e8c20ed..8f0c14983f 100644 --- a/openpilot/tools/replay/lib/ui_helpers.py +++ b/openpilot/tools/replay/lib/ui_helpers.py @@ -122,8 +122,8 @@ def init_plots(arr, name_to_arr_idx, plot_xlims, plot_ylims, plot_names, plot_co title_texts = [] for j2, (nm, cl) in enumerate(zip(pl_list, plot_colors[i], strict=False)): if j2 > 0: - title_texts.append(TextArea(", ", textprops=dict(color="white", fontsize=10))) - title_texts.append(TextArea(nm, textprops=dict(color=label_palette[cl], fontsize=10))) + title_texts.append(TextArea(", ", textprops={"color": "white", "fontsize": 10})) + title_texts.append(TextArea(nm, textprops={"color": label_palette[cl], "fontsize": 10})) packed = HPacker(children=title_texts, pad=0, sep=0) ab = AnchoredOffsetbox(loc='lower center', child=packed, bbox_to_anchor=(0.5, 1.0), bbox_transform=axs[i].transAxes, frameon=False, pad=0) diff --git a/openpilot/tools/sim/bridge/metadrive/metadrive_bridge.py b/openpilot/tools/sim/bridge/metadrive/metadrive_bridge.py index b8dc94cf86..4222ba45a7 100644 --- a/openpilot/tools/sim/bridge/metadrive/metadrive_bridge.py +++ b/openpilot/tools/sim/bridge/metadrive/metadrive_bridge.py @@ -29,11 +29,11 @@ def curve_block(length, angle=45, direction=0): def create_map(track_size=60): curve_len = track_size * 2 - return dict( - type=MapGenerateMethod.PG_MAP_FILE, - lane_num=2, - lane_width=4.5, - config=[ + return { + "type": MapGenerateMethod.PG_MAP_FILE, + "lane_num": 2, + "lane_width": 4.5, + "config": [ None, straight_block(track_size), curve_block(curve_len, 90), @@ -44,7 +44,7 @@ def create_map(track_size=60): straight_block(track_size), curve_block(curve_len, 90), ] - ) + } class MetaDriveBridge(SimulatorBridge): @@ -65,29 +65,29 @@ class MetaDriveBridge(SimulatorBridge): if self.dual_camera: sensors["rgb_wide"] = (RGBCameraWide, W, H) - config = dict( - use_render=self.should_render, - vehicle_config=dict( - enable_reverse=False, - render_vehicle=False, - image_source="rgb_road", - ), - sensors=sensors, - image_on_cuda=_cuda_enable, - image_observation=True, - interface_panel=[], - out_of_route_done=False, - on_continuous_line_done=False, - crash_vehicle_done=False, - crash_object_done=False, - arrive_dest_done=False, - traffic_density=0.0, # traffic is incredibly expensive - map_config=create_map(), - decision_repeat=1, - physics_world_step_size=self.TICKS_PER_FRAME/100, - preload_models=False, - show_logo=False, - anisotropic_filtering=False - ) + config = { + "use_render": self.should_render, + "vehicle_config": { + "enable_reverse": False, + "render_vehicle": False, + "image_source": "rgb_road", + }, + "sensors": sensors, + "image_on_cuda": _cuda_enable, + "image_observation": True, + "interface_panel": [], + "out_of_route_done": False, + "on_continuous_line_done": False, + "crash_vehicle_done": False, + "crash_object_done": False, + "arrive_dest_done": False, + "traffic_density": 0.0, # traffic is incredibly expensive + "map_config": create_map(), + "decision_repeat": 1, + "physics_world_step_size": self.TICKS_PER_FRAME/100, + "preload_models": False, + "show_logo": False, + "anisotropic_filtering": False + } return MetaDriveWorld(queue, config, self.test_duration, self.test_run, self.dual_camera) diff --git a/pyproject.toml b/pyproject.toml index 7ff0482b2f..597f7a4489 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -152,33 +152,26 @@ lint.select = [ "E", "F", "W", "PIE", "C4", "ISC", "A", "B", "NPY", # numpy "UP", # pyupgrade + "ASYNC", + "B904", "B905", + "PLC0207", "TRY203", "TRY400", "TRY401", # try/excepts - "RUF008", "RUF100", + "RUF006", "RUF008", "RUF009", "RUF061", "RUF064", "RUF100", "RUF102", "RUF103", "RUF104", "TID251", "PLE", "PLR1704", ] lint.ignore = [ "E741", "E402", - "C408", - "ISC003", "B027", - "B024", - "NPY002", # new numpy random syntax is worse - "UP045", "UP007", # these don't play nice with raylib atm + "UP007", # this doesn't play nice with raylib atm ] line-length = 160 -exclude = [ - "openpilot/cereal", - "*.ipynb", - "generated", -] lint.flake8-implicit-str-concat.allow-multiline = false [tool.ruff.lint.flake8-tidy-imports.banned-api] "pytest.main".msg = "pytest.main requires special handling that is easy to mess up!" -"unittest".msg = "Use pytest" -"time.time".msg = "Use time.monotonic" +"time.time".msg = "Use time.monotonic" # time.time can skip due to its reference clock, you probably want a monotonic clock # raylib banned APIs "pyray.measure_text_ex".msg = "Use openpilot.system.ui.lib.text_measure" diff --git a/tools/car_porting/examples/find_segments_with_message.ipynb b/tools/car_porting/examples/find_segments_with_message.ipynb index af17bde52b..f91827f7e5 100644 --- a/tools/car_porting/examples/find_segments_with_message.ipynb +++ b/tools/car_porting/examples/find_segments_with_message.ipynb @@ -9,7 +9,6 @@ "source": [ "# Import all cars from opendbc\n", "\n", - "from opendbc.car import structs\n", "from opendbc.car.values import PLATFORMS as TEST_PLATFORMS\n", "\n", "# Example: add additional platforms/segments to test outside of commaCarSegments\n", @@ -147,8 +146,8 @@ } ], "source": [ - "from openpilot.tools.lib.logreader import LogReader, comma_car_segments_source\n", - "from tqdm.notebook import tqdm, tnrange\n", + "from openpilot.tools.lib.logreader import comma_car_segments_source\n", + "from tqdm.notebook import tnrange\n", "\n", "# Example search for CAN ignition messages\n", "# Be careful when filtering by bus, account for odd harness arrangements on Honda/HKG\n", diff --git a/tools/car_porting/examples/ford_vin_fingerprint.ipynb b/tools/car_porting/examples/ford_vin_fingerprint.ipynb index 6b806d22d2..cb5fd8f820 100644 --- a/tools/car_porting/examples/ford_vin_fingerprint.ipynb +++ b/tools/car_porting/examples/ford_vin_fingerprint.ipynb @@ -53,12 +53,12 @@ " if vin.startswith('1FT'):\n", " if vin_positions_567 in F150_CODES:\n", " if vin[7] in LIGHTNING_CODES:\n", - " return f\"FORD F-150 LIGHTNING 1ST GEN\"\n", + " return \"FORD F-150 LIGHTNING 1ST GEN\"\n", " else:\n", - " return f\"FORD F-150 14TH GEN\"\n", + " return \"FORD F-150 14TH GEN\"\n", " elif vin.startswith('3FM'):\n", " if vin_positions_567 in MACHE_CODES:\n", - " return f\"FORD MUSTANG MACH-E 1ST GEN\"\n", + " return \"FORD MUSTANG MACH-E 1ST GEN\"\n", " elif vin.startswith('5LM'):\n", " pass\n", "\n", @@ -147,7 +147,8 @@ "source": [ "for vin, real_fingerprint in VINS_TO_CHECK:\n", " determined_fingerprint = ford_vin_fingerprint(vin)\n", - " print(f\"vin: {vin} real platform: {real_fingerprint: <30} determined platform: {determined_fingerprint: <30} correct: {real_fingerprint == determined_fingerprint}\")" + " print(f\"vin: {vin} real platform: {real_fingerprint: <30} \" +\n", + " f\"determined platform: {determined_fingerprint: <30} correct: {real_fingerprint == determined_fingerprint}\")" ] } ], diff --git a/tools/car_porting/examples/hkg_canfd_gear_message.ipynb b/tools/car_porting/examples/hkg_canfd_gear_message.ipynb index f0bca8decc..ec902b7d10 100644 --- a/tools/car_porting/examples/hkg_canfd_gear_message.ipynb +++ b/tools/car_porting/examples/hkg_canfd_gear_message.ipynb @@ -21,9 +21,7 @@ } ], "source": [ - "from opendbc.car import structs\n", "from opendbc.car.hyundai.values import CAR, HyundaiFlags\n", - "from opendbc.car.hyundai.fingerprints import FW_VERSIONS\n", "\n", "TEST_PLATFORMS = set(CAR.with_flags(HyundaiFlags.CANFD)) & set(CAR.with_flags(HyundaiFlags.EV)) # CAN-FD electric vehicles only\n", "#TEST_PLATFORMS = set(CAR.with_flags(HyundaiFlags.CANFD)) - set(CAR.with_flags(HyundaiFlags.EV)) # CAN-FD hybrid and ICE vehicles only\n", @@ -190,15 +188,13 @@ ], "source": [ "import copy\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", "\n", "from opendbc.can.parser import CANParser\n", "from opendbc.car.hyundai.values import DBC\n", "from opendbc.car.hyundai.hyundaicanfd import CanBus\n", "\n", "from openpilot.selfdrive.pandad import can_capnp_to_list\n", - "from openpilot.tools.lib.logreader import LogReader, comma_car_segments_source\n", + "from openpilot.tools.lib.logreader import comma_car_segments_source\n", "\n", "message_names = [\"GEAR_SHIFTER\", \"ACCELERATOR\", \"GEAR\", \"GEAR_ALT\", \"GEAR_ALT_2\"]\n", "\n", @@ -229,11 +225,11 @@ " for i, parsed_messages in enumerate(parsed_message_history):\n", " gear = parsed_messages[name][\"GEAR\"]\n", " if gear != gear_prev:\n", - " print(f\" *** Signal transition found! ***\")\n", + " print(\" *** Signal transition found! ***\")\n", " examples.append(i)\n", " gear_prev = gear\n", "\n", - "print(f\"Analysis finished\")\n" + "print(\"Analysis finished\")\n" ] }, { diff --git a/tools/car_porting/test_car_model.py b/tools/car_porting/test_car_model.py index 20e7d136ea..61ec2e15ed 100755 --- a/tools/car_porting/test_car_model.py +++ b/tools/car_porting/test_car_model.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 import argparse import sys -import unittest # noqa: TID251 +import unittest from opendbc.car.tests.routes import CarTestRoute from openpilot.selfdrive.car.tests.test_models import TestCarModel from openpilot.tools.lib.route import SegmentRange