fix(lab): avoid runtime typing on Python 3.9

This commit is contained in:
DCCONSTRUCTIONS
2026-08-31 20:01:49 +03:00
parent 2989fba99c
commit a3299dcfc3
4 changed files with 20 additions and 5 deletions
@@ -11,7 +11,7 @@ $ProgressPreference = "SilentlyContinue"
$RuntimeRoot = [IO.Path]::GetFullPath("D:\NDC_MISSIONCORE\runtime").TrimEnd("\") $RuntimeRoot = [IO.Path]::GetFullPath("D:\NDC_MISSIONCORE\runtime").TrimEnd("\")
$BuildRoot = Join-Path $RuntimeRoot "staging\observatory-lab-v1-build-$SourceRevision" $BuildRoot = Join-Path $RuntimeRoot "staging\observatory-lab-v1-build-$SourceRevision"
$SharedAdapterSha256 = "91c1878a58acf3ac35ce894f4de9b63cba3b7f29a65548e28df176063a2953c9" $SharedAdapterSha256 = "b7dcb3532a65ddc2d6988391056dd2f58f5f631a4db978ebfb5e170bde9c3916"
$BuildMethod = "docker-commit-exact-layer-v1" $BuildMethod = "docker-commit-exact-layer-v1"
$MaximumLayerBytes = [int64](16MB) $MaximumLayerBytes = [int64](16MB)
@@ -23,7 +23,7 @@ import zlib
from collections.abc import Callable, Mapping, Sequence from collections.abc import Callable, Mapping, Sequence
from dataclasses import dataclass from dataclasses import dataclass
from pathlib import Path, PurePosixPath from pathlib import Path, PurePosixPath
from typing import Final, Literal, cast from typing import Final, Literal, Optional, cast
REQUEST_SCHEMA: Final = "missioncore.observatory-portable-lab-v1-component-request/v1" REQUEST_SCHEMA: Final = "missioncore.observatory-portable-lab-v1-component-request/v1"
SOURCE_SCHEMA: Final = "missioncore.observatory-portable-lab-v1-source/v1" SOURCE_SCHEMA: Final = "missioncore.observatory-portable-lab-v1-source/v1"
@@ -73,7 +73,7 @@ _CAMERA_JOB_ID = re.compile(r"^recorded-camera-[a-f0-9]{24}$")
Component = Literal["eomt", "ddrnet"] Component = Literal["eomt", "ddrnet"]
AssetKind = Literal["file", "tree"] AssetKind = Literal["file", "tree"]
AssetVerification = Literal["sha256", "identity-sha256"] AssetVerification = Literal["sha256", "identity-sha256"]
CommandRunner = Callable[[Sequence[str], Mapping[str, str] | None], None] CommandRunner = Callable[[Sequence[str], Optional[Mapping[str, str]]], None] # noqa: UP045
class ComponentAdapterError(RuntimeError): class ComponentAdapterError(RuntimeError):
@@ -792,7 +792,7 @@ def _paths(value: object, component: Component) -> dict[str, str | None]:
_exact_keys(document, set(expected), "component paths") _exact_keys(document, set(expected), "component paths")
if document != expected: if document != expected:
raise ComponentAdapterError("component path contract changed") raise ComponentAdapterError("component path contract changed")
return cast(dict[str, str | None], document) return cast(dict[str, Optional[str]], document) # noqa: UP045
def _asset_bindings( def _asset_bindings(
@@ -41,7 +41,7 @@ def test_component_image_installer_binds_bases_and_adapter_sources() -> None:
for digest in ( for digest in (
"58df7489c3f2276f9591d500a012dee03e23d35543ce3c390b4c001e6bf90794", "58df7489c3f2276f9591d500a012dee03e23d35543ce3c390b4c001e6bf90794",
"591cb382c099eeb05e7ec16e2371e0b2da54d2bb5c49ec0f4ac88dbf72b0f0cd", "591cb382c099eeb05e7ec16e2371e0b2da54d2bb5c49ec0f4ac88dbf72b0f0cd",
"91c1878a58acf3ac35ce894f4de9b63cba3b7f29a65548e28df176063a2953c9", "b7dcb3532a65ddc2d6988391056dd2f58f5f631a4db978ebfb5e170bde9c3916",
"b48ef255403abcfd177a6550688410a52b0fbd29d2a54c8417cb5a0daa330ad5", "b48ef255403abcfd177a6550688410a52b0fbd29d2a54c8417cb5a0daa330ad5",
"a398a43fe4069bf1b1fc2ec61b44df53dad6072cccb6d10a2627e76a96a94056", "a398a43fe4069bf1b1fc2ec61b44df53dad6072cccb6d10a2627e76a96a94056",
): ):
@@ -1,5 +1,6 @@
from __future__ import annotations from __future__ import annotations
import ast
import hashlib import hashlib
import json import json
import shutil import shutil
@@ -35,6 +36,20 @@ def test_component_entrypoints_keep_the_legacy_python39_syntax_floor() -> None:
for path in paths: for path in paths:
source = path.read_text(encoding="utf-8") source = path.read_text(encoding="utf-8")
assert "\ntype " not in source assert "\ntype " not in source
module = ast.parse(source, filename=str(path), feature_version=(3, 9))
for statement in module.body:
if isinstance(statement, ast.Assign):
assert not any(
isinstance(node, ast.BinOp) and isinstance(node.op, ast.BitOr)
for node in ast.walk(statement.value)
), f"runtime-evaluated PEP 604 alias in {path.name}"
for call in (node for node in ast.walk(module) if isinstance(node, ast.Call)):
if isinstance(call.func, ast.Name) and call.func.id == "cast":
assert call.args
assert not any(
isinstance(node, ast.BinOp) and isinstance(node.op, ast.BitOr)
for node in ast.walk(call.args[0])
), f"runtime-evaluated PEP 604 cast in {path.name}"
assert "slots=True" not in paths[0].read_text(encoding="utf-8") assert "slots=True" not in paths[0].read_text(encoding="utf-8")
assert "slots=True" not in paths[2].read_text(encoding="utf-8") assert "slots=True" not in paths[2].read_text(encoding="utf-8")