diff --git a/openpilot/starpilot/galaxy/tests/test_layout_snap.mjs b/openpilot/starpilot/galaxy/tests/test_layout_snap.mjs index 48c4fe72fd..95920d08fb 100644 --- a/openpilot/starpilot/galaxy/tests/test_layout_snap.mjs +++ b/openpilot/starpilot/galaxy/tests/test_layout_snap.mjs @@ -32,7 +32,7 @@ assert.deepEqual(pure(snapMove, { ...box, x: 253 }, targets, 6), { x: 253, y: 11 assert.deepEqual(pure(snapMove, box, bounds, 0), { x: 34, y: 113, guides: [] }) const target = (value, line = "start", kind = "widget", axis = "x", label = "Home") => ({ axis, value, line, kind, label }) result = pure(snapMove, { ...box, x: 100 }, [target(104), target(146, "center", "center")], 6) -assert.equal(result.x, 96) // Equal distance prefers bounds centre. +assert.equal(result.x, 96) // Equal distance prefers bounds center. assert.equal(result.guides[0].kind, "center") for (const kinds of [["zone", "widget"], ["widget", "bounds"], ["bounds", "center"]]) { const first = target(104, "start", kinds[0]), second = target(96, "start", kinds[1]) diff --git a/openpilot/starpilot/galaxy/tests/test_onroad_layout.mjs b/openpilot/starpilot/galaxy/tests/test_onroad_layout.mjs index 8b139bbf3c..059d90611b 100644 --- a/openpilot/starpilot/galaxy/tests/test_onroad_layout.mjs +++ b/openpilot/starpilot/galaxy/tests/test_onroad_layout.mjs @@ -236,7 +236,7 @@ invalidSnap.cancelDrag() const traySnap = editor().vm traySnap.layout.current_speed.enabled = false traySnap.startDrag("current_speed", largePoint(2400, 0), true) -traySnap.moveDrag(largePoint(324, 550)) // Widget centre follows the tray pointer. +traySnap.moveDrag(largePoint(324, 550)) // Widget center follows the tray pointer. assert.equal(traySnap.layout.current_speed.x, 30) assert.equal(traySnap.layout.current_speed.enabled, true) assert.ok(traySnap.state.snapGuides.length) @@ -309,14 +309,14 @@ try { else delete globalThis.localStorage } for (const [guides, expected] of [ - [[{ axis: "x", kind: "center" }, { axis: "y", kind: "center" }], "Centred on the screen"], - [[{ axis: "x", kind: "center" }], "Centred across"], - [[{ axis: "y", kind: "center" }], "Centred top to bottom"], + [[{ axis: "x", kind: "center" }, { axis: "y", kind: "center" }], "Centered on the screen"], + [[{ axis: "x", kind: "center" }], "Centered across"], + [[{ axis: "y", kind: "center" }], "Centered top to bottom"], [[{ label: "Home" }, { label: "Home" }, { label: "Work" }], "Lined up with Home and Work"], [[{ label: "the edge" }, { label: "Home" }], "At the edge, lined up with Home"], - [[{ axis: "x", kind: "center", label: "the centre" }, { axis: "y", kind: "bounds", label: "the edge" }], "Centred across, at the edge"], - [[{ axis: "y", kind: "center", label: "the centre" }, { axis: "x", kind: "widget", label: "Home" }, { axis: "y", kind: "widget", label: "Work" }], - "Centred top to bottom, lined up with Home"], + [[{ axis: "x", kind: "center", label: "the center" }, { axis: "y", kind: "bounds", label: "the edge" }], "Centered across, at the edge"], + [[{ axis: "y", kind: "center", label: "the center" }, { axis: "x", kind: "widget", label: "Home" }, { axis: "y", kind: "widget", label: "Work" }], + "Centered top to bottom, lined up with Home"], ]) { snapVm.state.snapGuides = guides assert.equal(snapVm.snapSummary, expected) @@ -545,7 +545,7 @@ assert.equal(backdropCalls.at(-1)[3], "braking") vm.selectProfile("large") vm.state.scene = "engaged" vm.color("text", "#ABCDEF81") -assert.equal(backdropCalls.length, backdropCount + 5) // Colour edits change the real screen too. +assert.equal(backdropCalls.length, backdropCount + 5) // Color edits change the real screen too. vm.color("text", "#ABCDEF80") const draggingCount = backdropCalls.length vm.startDrag("current_speed", event(500, 200)) diff --git a/openpilot/starpilot/galaxy/web/js/layout-snap.js b/openpilot/starpilot/galaxy/web/js/layout-snap.js index 1cb8a83a50..545b245a8d 100644 --- a/openpilot/starpilot/galaxy/web/js/layout-snap.js +++ b/openpilot/starpilot/galaxy/web/js/layout-snap.js @@ -16,13 +16,13 @@ export function snapTargets(profile, layout, id, visible) { const add = (box, kind, label, names) => { for (const axis of ["x", "y"]) { const values = lines(box, axis) - // Keep the line role so widget centres cannot attract moving edges. + // Keep the line role so widget centers cannot attract moving edges. for (const line of names) targets.push({ axis, value: values[line], kind, label, line }) } } const bounds = profile.widgets[id].bounds || profile.bounds add(bounds, "bounds", "the edge", ["start", "end"]) - add(bounds, "center", "the centre", ["center"]) + add(bounds, "center", "the center", ["center"]) for (const [key, widget] of Object.entries(profile.widgets)) { const at = layout[key] if (key === id || !at?.enabled || !Number.isFinite(at.x) || !Number.isFinite(at.y) || diff --git a/openpilot/starpilot/galaxy/web/js/onroad-layout.js b/openpilot/starpilot/galaxy/web/js/onroad-layout.js index 134e7ba960..d80f6b12d5 100644 --- a/openpilot/starpilot/galaxy/web/js/onroad-layout.js +++ b/openpilot/starpilot/galaxy/web/js/onroad-layout.js @@ -437,12 +437,12 @@ export const OnroadLayoutPage = { // A finger covers the preview chip, so touch drags show the alignment in the sticky save bar. snapInBar() { return !!(this.state.drag?.touch && this.state.snapGuides.length) }, snapSummary() { - const guides = this.state.snapGuides, centred = new Set(guides.filter(guide => guide.kind === "center").map(guide => guide.axis)) - if (centred.size === 2) return "Centred on the screen" - // A centred axis is described once; the other axis still says what it lines up with. - const labels = [...new Set(guides.filter(guide => !centred.has(guide.axis)).map(guide => guide.label))] + const guides = this.state.snapGuides, centered = new Set(guides.filter(guide => guide.kind === "center").map(guide => guide.axis)) + if (centered.size === 2) return "Centered on the screen" + // A centered axis is described once; the other axis still says what it lines up with. + const labels = [...new Set(guides.filter(guide => !centered.has(guide.axis)).map(guide => guide.label))] const others = labels.filter(label => label !== "the edge").slice(0, 2) - const text = [centred.has("x") ? "centred across" : centred.has("y") ? "centred top to bottom" : "", + const text = [centered.has("x") ? "centered across" : centered.has("y") ? "centered top to bottom" : "", labels.includes("the edge") ? "at the edge" : "", others.length ? "lined up with " + others.join(" and ") : ""].filter(Boolean).join(", ") return text && text[0].toUpperCase() + text.slice(1) }, @@ -1273,7 +1273,7 @@ export const OnroadLayoutPage = { - + @@ -1362,7 +1362,7 @@ export const OnroadLayoutPage = {
Drag widgets to place them. Behind them is the comma's own screen for the chosen scene, including its border, road and alerts. Readings are samples.
-Widgets snap to the screen edges, the centre and other widgets. Turn snapping off with the magnet button, or hold Option (Alt) while dragging.
+Widgets snap to the screen edges, the center and other widgets. Turn snapping off with the magnet button, or hold Option (Alt) while dragging.
General edit shows samples of all enabled widgets together. Driving scenes hide widgets that would be absent, and the eyes follow the scene. Eye changes stay with that scene; your General edit eyes are remembered.
The stopped timer appears in General edit and Stopped timer. Turn off editing aids to see the screen without outlines and guides.
The steering wheel and driver monitoring icon can be resized in each layout{{ projection ? ', and the map overlay takes any size and opacity' : '' }}. Existing display preferences and driving state still control when widgets appear.
diff --git a/openpilot/starpilot/system/android_auto/projection_layout.py b/openpilot/starpilot/system/android_auto/projection_layout.py index b3997f032b..76fff314ab 100644 --- a/openpilot/starpilot/system/android_auto/projection_layout.py +++ b/openpilot/starpilot/system/android_auto/projection_layout.py @@ -352,7 +352,7 @@ def projection_customization(document, base_customization): dx, dy = shifts.get(key, (0, 0)) result['layouts']['large'][key] = {**placement, 'x': placement['x'] - dx, 'y': placement['y'] - dy} from openpilot.starpilot.ui.onroad_customization import rgba - # Card opacity is a colour, not a placement: fold it into the fill and keep the native placement shape. + # Card opacity is a color, not a placement: fold it into the fill and keep the native placement shape. opacity = result['layouts']['large'].get('cruise_limits', {}).pop('opacity', 100) if opacity != 100: red, green, blue, alpha = rgba(result, 'cardFill', 'large', 'cruise_limits') diff --git a/openpilot/starpilot/system/android_auto/tests/test_apk_identity.py b/openpilot/starpilot/system/android_auto/tests/test_apk_identity.py index 97d7c37850..a58afe4144 100644 --- a/openpilot/starpilot/system/android_auto/tests/test_apk_identity.py +++ b/openpilot/starpilot/system/android_auto/tests/test_apk_identity.py @@ -251,7 +251,8 @@ def test_import_job_labels_metadata_free_package_with_offered_version(tmp_path, def test_status_reports_expiry(tmp_path): cert, root, key_pem, _ = build_identity(days=5) directory = tmp_path / "identity" - apk_identity.install_identity({"phone-cert.pem": cert, "phone-key.pem": key_pem, "root-cert.pem": root}, {"subject": "O=CarService", "app_version": "16.2.1-release"}, directory) + apk_identity.install_identity({"phone-cert.pem": cert, "phone-key.pem": key_pem, "root-cert.pem": root}, + {"subject": "O=CarService", "app_version": "16.2.1-release"}, directory) status = apk_identity.identity_status(directory) assert status["installed"] and status["days_left"] in (4, 5) and "renew" in status["warning"] assert status["app_version"] == "16.2.1-release" diff --git a/openpilot/starpilot/system/android_auto/tests/test_apkpure.py b/openpilot/starpilot/system/android_auto/tests/test_apkpure.py index f55eb4dd80..428e10585b 100644 --- a/openpilot/starpilot/system/android_auto/tests/test_apkpure.py +++ b/openpilot/starpilot/system/android_auto/tests/test_apkpure.py @@ -168,7 +168,9 @@ def test_refresh_retries_before_giving_up_and_reports_pending(monkeypatch, cache assert waits == [apkpure.RETRY_DELAYS[0]] assert pending == [True, True] # the page waits while tries remain assert not apkpure.lookup_pending() - assert apkpure.download_status()["url"] == LINK + status = apkpure.download_status() + assert status is not None + assert status["url"] == LINK def test_refresh_is_single_flight(monkeypatch, cache): diff --git a/openpilot/starpilot/system/android_auto/tests/test_projection_bookmark.py b/openpilot/starpilot/system/android_auto/tests/test_projection_bookmark.py index 560dd78151..a9b9e6b999 100644 --- a/openpilot/starpilot/system/android_auto/tests/test_projection_bookmark.py +++ b/openpilot/starpilot/system/android_auto/tests/test_projection_bookmark.py @@ -3,6 +3,7 @@ import ast from pathlib import Path import tempfile from types import SimpleNamespace as NS +from typing import Any, cast from unittest.mock import Mock, patch import pytest @@ -29,8 +30,8 @@ def native_poll(): source = Path(__file__).parents[3] / 'ui/runtime_app.py' tree = ast.parse(source.read_text()) method = next(node for node in ast.walk(tree) if isinstance(node, ast.FunctionDef) and node.name == '_poll_projection_bookmark') - namespace = {'ui_state': NS(started=True, started_frame=1, sm=NS(logMonoTime={'carState': 50})), - 'display_message': Mock(return_value=object())} + namespace: dict[str, Any] = {'ui_state': NS(started=True, started_frame=1, sm=NS(logMonoTime={'carState': 50})), + 'display_message': Mock(return_value=object()), 'cast': cast} exec(compile(ast.Module(body=[method], type_ignores=[]), str(source), 'exec'), namespace) return namespace diff --git a/openpilot/starpilot/ui/onroad_customization.py b/openpilot/starpilot/ui/onroad_customization.py index dac278de24..fd6f045040 100644 --- a/openpilot/starpilot/ui/onroad_customization.py +++ b/openpilot/starpilot/ui/onroad_customization.py @@ -50,6 +50,7 @@ class Widget(TypedDict): defaultAnchor: NotRequired[str] colors: NotRequired[dict[str, str | None]] resizable: NotRequired[dict[str, int]] + sourcesExtent: NotRequired[dict[str, float]] class LayoutProfile(TypedDict): @@ -151,7 +152,7 @@ PROFILES["compact"]["widgets"][STOPPED_TIMER_WIDGET] = _timer_widget # Restore the Dom road graphic in the gap between the speed card and main speed. # It has no background and appears only with a current selected source. CEM_GAUGE_WIDGET = 'cem_gauge' -# The gauge draws centred in a 344 x 300 frame; its box is the part it can actually fill, at this offset inside +# The gauge draws centered in a 344 x 300 frame; its box is the part it can actually fill, at this offset inside # that frame. Version 6 and older layouts saved the frame's corner and move by this offset when they load. CEM_GAUGE_FRAME = (344, 300) CEM_GAUGE_INSET = (44, 24) diff --git a/openpilot/starpilot/ui/onroad_large_widgets.py b/openpilot/starpilot/ui/onroad_large_widgets.py index d5d52a990b..5e21e3faf2 100644 --- a/openpilot/starpilot/ui/onroad_large_widgets.py +++ b/openpilot/starpilot/ui/onroad_large_widgets.py @@ -5,6 +5,7 @@ HudRenderer and ExpButton. See the adjacent UI LICENSE for retained source. """ from pathlib import Path +from typing import cast import hashlib import json @@ -132,12 +133,12 @@ class UnifiedSpeedWidget: status_size = fit_size(status, FontRole.NORMAL, 30) if status else 30 status_ink = self.fonts.horizontal_ink(status, FontRole.NORMAL, status_size) if status else None status_v = self.fonts.vertical_ink(status, FontRole.NORMAL, status_size) if status else None - status_h = (status_v[1] - status_v[0]) if status else 0 + status_h = (cast(tuple[float, float], status_v)[1] - cast(tuple[float, float], status_v)[0]) if status else 0 footer_size = fit_size(footer, FontRole.NORMAL, 30) if footer else 30 footer_ink = self.fonts.horizontal_ink(footer, FontRole.NORMAL, footer_size) if footer else None footer_v = self.fonts.vertical_ink(footer, FontRole.NORMAL, footer_size) if footer else None - footer_h = (footer_v[1] - footer_v[0]) if footer else 0 + footer_h = (cast(tuple[float, float], footer_v)[1] - cast(tuple[float, float], footer_v)[0]) if footer else 0 if align == 'center': # Every line shares the card's horizontal center, and the entire stack is visually vertically centered. @@ -151,16 +152,21 @@ class UnifiedSpeedWidget: lambda y: self.fonts.draw(value, FontRole.SPEED, size, start(*number_ink), y - number_v[0] + dash_offset, text) )) if has_value: + unit_v = cast(tuple[float, float], unit_v) segments.append(( unit_v[0], unit_h, lambda y: self.fonts.draw(shown.unit, FontRole.NORMAL, unit_size, start(*unit_ink), y - unit_v[0], muted) )) if status: + status_ink = cast(tuple[float, float], status_ink) + status_v = cast(tuple[float, float], status_v) segments.append(( status_v[0], status_h, lambda y: self.fonts.draw(status, FontRole.NORMAL, status_size, start(*status_ink), y - status_v[0], accent if active else muted) )) if footer: + footer_ink = cast(tuple[float, float], footer_ink) + footer_v = cast(tuple[float, float], footer_v) segments.append(( footer_v[0], footer_h, lambda y: self.fonts.draw(footer, FontRole.NORMAL, footer_size, start(*footer_ink), y - footer_v[0], footer_color) @@ -183,6 +189,7 @@ class UnifiedSpeedWidget: left = start(*number_ink) self.fonts.draw(value, FontRole.SPEED, size, left, number_y, text) if has_value: + unit_v = cast(tuple[float, float], unit_v) unit_x = left + number_ink[0] - 14 - unit_ink[1] if align == 'right' else left + number_ink[1] + 14 - unit_ink[0] unit_y = number_y + number_v[1] - unit_v[1] self.fonts.draw(shown.unit, FontRole.NORMAL, unit_size, unit_x, unit_y, muted) diff --git a/openpilot/starpilot/ui/runtime_app.py b/openpilot/starpilot/ui/runtime_app.py index 24d8d56218..f7cc8324db 100644 --- a/openpilot/starpilot/ui/runtime_app.py +++ b/openpilot/starpilot/ui/runtime_app.py @@ -13,7 +13,7 @@ import math from pathlib import Path import time import threading -from typing import Any +from typing import Any, cast from collections.abc import Callable import pyray as rl @@ -472,7 +472,7 @@ class StarShellSession: display_message(ui_state.sm, 'carState', now_ns, after_frame=ui_state.started_frame) is not None) stamp = int(ui_state.sm.logMonoTime['carState']) if authorized else 0 for _ in range(receiver.drain(now_ns, stamp, authorized=authorized)): - publish() + cast('Callable[[], None]', publish)() def _poll_wheel(self, now_ns): if getattr(ui_state, "replay_clock", None) is not None: diff --git a/openpilot/starpilot/ui/tests/test_dinish_speed.py b/openpilot/starpilot/ui/tests/test_dinish_speed.py index 0167849251..e282ddb2a3 100644 --- a/openpilot/starpilot/ui/tests/test_dinish_speed.py +++ b/openpilot/starpilot/ui/tests/test_dinish_speed.py @@ -169,9 +169,10 @@ def test_galaxy_card_pixels_align_without_reading_font_textures(): widget = UnifiedSpeedWidget(fonts) canvas = _Canvas.__new__(_Canvas) canvas.profile, canvas.viewport, canvas.fonts, canvas.target = Profile.LARGE, viewport, fonts, target - canvas.view = SimpleNamespace(_ordered_widgets=lambda content, state, widget=widget, **kw: widget.render(content, state)) - canvas._settle = lambda state: None - with patch.dict('openpilot.starpilot.ui.layout_preview_renderer.RUNTIME_PREVIEW_WIDGETS', large=('cruise_limits',)), \ + with patch.object(canvas, 'view', + SimpleNamespace(_ordered_widgets=lambda content, state, widget=widget, **kw: widget.render(content, state)), create=True), \ + patch.object(canvas, '_settle', lambda state: None), \ + patch.dict('openpilot.starpilot.ui.layout_preview_renderer.RUNTIME_PREVIEW_WIDGETS', large=('cruise_limits',)), \ patch.object(rl, 'load_image_from_texture', side_effect=mobile_readback) as readback: png = canvas.render_widget_art(state, document['layouts']['large']) # A saved 50% background must show on the first frame, without a slider diff --git a/openpilot/starpilot/ui/tests/test_layout_preview_renderer.py b/openpilot/starpilot/ui/tests/test_layout_preview_renderer.py index 9462693d58..6c38f03831 100644 --- a/openpilot/starpilot/ui/tests/test_layout_preview_renderer.py +++ b/openpilot/starpilot/ui/tests/test_layout_preview_renderer.py @@ -83,7 +83,9 @@ class LayoutPreviewRendererTests(unittest.TestCase): self.assertTrue(sample.visual_preview.layout_sample) # Drawn as the car would, without replay labels. from openpilot.starpilot.ui.onroad_conditional import status # The gauge still reads the real reason, but the mode caption itself is not drawn in the editor. - family, detail, _ = status(sample) + observed = status(sample) + assert observed is not None + family, detail, _ = observed self.assertEqual(family, "CEM") self.assertFalse(detail.startswith("PREVIEW")) self.assertEqual(sample_state("cem_lead", document).speed_mps, 0.0) diff --git a/openpilot/starpilot/ui/tests/test_layout_scenes.py b/openpilot/starpilot/ui/tests/test_layout_scenes.py index a1eccdd242..f59cb94eaf 100644 --- a/openpilot/starpilot/ui/tests/test_layout_scenes.py +++ b/openpilot/starpilot/ui/tests/test_layout_scenes.py @@ -1,9 +1,11 @@ """Scene sketches and eye controls must agree with the native driving presentation.""" import json +from collections.abc import Callable from pathlib import Path import shutil import subprocess +from typing import NoReturn, cast import pytest @@ -23,7 +25,7 @@ from openpilot.starpilot.ui.unified_speed_presentation import resolve_unified_sp def test_every_scene_matches_native_border_mode_and_widget_visibility(target): node = shutil.which('node') if node is None: - pytest.skip('Node is required for the browser/native scene contract') + cast('Callable[[str], NoReturn]', pytest.skip)('Node is required for the browser/native scene contract') profile = Profile.COMPACT if target == 'compact' else Profile.LARGE document = default_document() if target == 'projection': diff --git a/openpilot/starpilot/ui/tests/test_layout_widget_art.py b/openpilot/starpilot/ui/tests/test_layout_widget_art.py index 8c97ed5d6d..3fa7303a31 100644 --- a/openpilot/starpilot/ui/tests/test_layout_widget_art.py +++ b/openpilot/starpilot/ui/tests/test_layout_widget_art.py @@ -119,10 +119,11 @@ def test_large_wheel_art_is_drawn_inside_its_crop_with_or_without_sidebar(monkey document = projection_customization(projection, document) canvas = renderer._Canvas.__new__(renderer._Canvas) canvas.profile, canvas.viewport = Profile.LARGE, viewport - canvas.fonts = NS(profile=Profile.LARGE) + monkeypatch.setattr(canvas, 'fonts', NS(profile=Profile.LARGE), raising=False) canvas.target = NS(texture=object()) view = OnroadView.__new__(OnroadView) - view.fonts, view.projection_viewport = canvas.fonts, viewport + monkeypatch.setattr(view, 'fonts', canvas.fonts, raising=False) + view.projection_viewport = viewport view.steering_wheel = SteeringWheelWidget(Path('/unused')) view.steering_wheel._texture = object() # Real widget geometry, without loading a GL texture. canvas.view = view diff --git a/openpilot/starpilot/ui/tests/test_onroad_cem_gauge.py b/openpilot/starpilot/ui/tests/test_onroad_cem_gauge.py index f0165b46cc..8119066486 100644 --- a/openpilot/starpilot/ui/tests/test_onroad_cem_gauge.py +++ b/openpilot/starpilot/ui/tests/test_onroad_cem_gauge.py @@ -116,7 +116,7 @@ def test_custom_placement_disable_layer_migration_preserve_existing_widgets(): sample = state(customization=migrated) with patch.object(gauge, '_render_unified_road') as draw: gauge.render(sample) - # The saved box is inset 44 x 24 inside the gauge's drawing frame, which is centred at (172, 145 - 60). + # The saved box is inset 44 x 24 inside the gauge's drawing frame, which is centered at (172, 145 - 60). assert draw.call_args.args[1:3] == (960. - 44 + 172, 600. - 24 + 85) migrated['layouts']['large'][CEM_GAUGE_WIDGET]['enabled'] = False draw.reset_mock() diff --git a/openpilot/starpilot/ui/tests/test_speed_source_drawer_native.py b/openpilot/starpilot/ui/tests/test_speed_source_drawer_native.py index 3a0ddbe402..df37d92452 100644 --- a/openpilot/starpilot/ui/tests/test_speed_source_drawer_native.py +++ b/openpilot/starpilot/ui/tests/test_speed_source_drawer_native.py @@ -155,5 +155,5 @@ class DrawerNativeTest(unittest.TestCase): widget = UnifiedSpeedWidget(Mock(spec=BitmapFonts, **vars(fonts))) widget._draw_sources(rl.Rectangle(88, 545, 320, 76), state) self.assertEqual([text for text, _ in drawn], ['Dash', '56', 'Vision', '56']) - self.assertIn(('56', FontRole.MEDIUM), drawn) # The accepted source's reading is emphasised. + self.assertIn(('56', FontRole.MEDIUM), drawn) # The accepted source's reading is emphasized. self.assertIn(('56', FontRole.NORMAL), drawn) diff --git a/openpilot/starpilot/ui/tests/test_speed_stack.py b/openpilot/starpilot/ui/tests/test_speed_stack.py index 1d73401eb6..d9c5e5b94f 100644 --- a/openpilot/starpilot/ui/tests/test_speed_stack.py +++ b/openpilot/starpilot/ui/tests/test_speed_stack.py @@ -1,6 +1,5 @@ """Regression checks for qualified values, saved geometry and request feedback.""" from dataclasses import replace -from types import SimpleNamespace as N from unittest.mock import Mock from openpilot.starpilot.ui.onroad_state import ObservationKind, OnroadInput, OnroadState, SlcActionKind, SlcUiRequest, SpeedLimitObservation diff --git a/openpilot/system/ui/tests/test_frame_timing.py b/openpilot/system/ui/tests/test_frame_timing.py index 2574818c66..51912cb289 100644 --- a/openpilot/system/ui/tests/test_frame_timing.py +++ b/openpilot/system/ui/tests/test_frame_timing.py @@ -1,4 +1,5 @@ from types import SimpleNamespace +from typing import Any, cast from unittest.mock import Mock import pytest @@ -197,7 +198,7 @@ def test_projection_bookmark_is_saved_once_without_rendering_starpilot(frame, mo source = Path(__file__).parents[3] / 'starpilot/ui/runtime_app.py' method = next(node for node in ast.walk(ast.parse(source.read_text())) if isinstance(node, ast.FunctionDef) and node.name == '_poll_projection_bookmark') - namespace = {'ui_state': state, 'display_message': Mock(return_value=object())} + namespace: dict[str, Any] = {'ui_state': state, 'display_message': Mock(return_value=object()), 'cast': cast} exec(compile(ast.Module(body=[method], type_ignores=[]), str(source), 'exec'), namespace) # Short Unix socket path for macOS. The real transport and native dispatch run # while the top widget is unrelated to StarPilot, or no widget is drawn at all. diff --git a/prebuilt.json b/prebuilt.json index 29264a2208..a42301f8d5 100644 --- a/prebuilt.json +++ b/prebuilt.json @@ -1 +1 @@ -{"protected_inventory_sha256": "ab34357011d34391030f316138a394c2390c042aabf3cae579a0ac5bd0472920", "schema_version": 1} +{"protected_inventory_sha256": "e10d74d6606301a472810871c5349040d6db434e66388e860ac574d5d1f8d043", "schema_version": 1}