tan-cli 0.7.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tan/__init__.py +0 -0
- tan/__main__.py +120 -0
- tan/cli.py +939 -0
- tan/command_table.py +265 -0
- tan/commands/__init__.py +8 -0
- tan/commands/bootstrap_cmd.py +4856 -0
- tan/commands/bootstrap_patches.py +164 -0
- tan/commands/bootstrap_toolchain_fetch.py +155 -0
- tan/commands/bootstrap_toolchain_pin.py +36 -0
- tan/commands/build/__init__.py +1 -0
- tan/commands/build/configure_inputs.py +277 -0
- tan/commands/build/execute.py +1852 -0
- tan/commands/build/host_python.py +59 -0
- tan/commands/build/link_stale.py +78 -0
- tan/commands/build/manifest.py +428 -0
- tan/commands/build/materialise.py +81 -0
- tan/commands/build/token_substitution.py +381 -0
- tan/commands/build/toolchain.py +482 -0
- tan/commands/build/user_defines_wipe.py +115 -0
- tan/commands/build/workspace_patches.py +65 -0
- tan/commands/build_cmd.py +2236 -0
- tan/commands/build_output.py +331 -0
- tan/commands/clean_cmd.py +1183 -0
- tan/commands/completion_cmd.py +786 -0
- tan/commands/debug_config_cmd.py +2425 -0
- tan/commands/diff_cmd.py +940 -0
- tan/commands/doctor_cmd.py +4767 -0
- tan/commands/examples_cmd.py +644 -0
- tan/commands/explain_cmd.py +1319 -0
- tan/commands/faultdecode_cmd.py +931 -0
- tan/commands/flash_atoc_guard.py +240 -0
- tan/commands/flash_cmd.py +5731 -0
- tan/commands/flash_mram_guard.py +150 -0
- tan/commands/flash_ram.py +578 -0
- tan/commands/flash_raw.py +583 -0
- tan/commands/generate_cmd.py +1456 -0
- tan/commands/image_cmd.py +753 -0
- tan/commands/init_cmd.py +1740 -0
- tan/commands/inspect_cmd.py +377 -0
- tan/commands/kconfig_cmd.py +734 -0
- tan/commands/model_cmd.py +1514 -0
- tan/commands/model_device_cmd.py +351 -0
- tan/commands/model_device_live.py +234 -0
- tan/commands/model_host_cmd.py +430 -0
- tan/commands/model_zoo_cmd.py +363 -0
- tan/commands/monitor_actions.py +125 -0
- tan/commands/monitor_cmd.py +626 -0
- tan/commands/monitor_session.py +505 -0
- tan/commands/new_som_cmd.py +1522 -0
- tan/commands/pinmux_cmd.py +568 -0
- tan/commands/presets_cmd.py +1123 -0
- tan/commands/probe_cmd.py +421 -0
- tan/commands/reset_cmd.py +354 -0
- tan/commands/reset_confirm.py +168 -0
- tan/commands/run_cmd.py +637 -0
- tan/commands/scaffold_cmd.py +490 -0
- tan/commands/sdk_cmd.py +1723 -0
- tan/commands/size_cmd.py +1020 -0
- tan/commands/support_bundle_cmd.py +1073 -0
- tan/commands/trace_cmd.py +341 -0
- tan/commands/validate_cmd.py +2009 -0
- tan/commands/west_forward_cmd.py +736 -0
- tan/commands/workspace_patch_check.py +296 -0
- tan/core/__init__.py +1 -0
- tan/core/alp_conf_pregen.py +100 -0
- tan/core/artifact_provenance.py +240 -0
- tan/core/atoc_guard.py +276 -0
- tan/core/atoc_guard_messages.py +232 -0
- tan/core/atoc_replacement.py +118 -0
- tan/core/atomic_write.py +178 -0
- tan/core/board_context.py +351 -0
- tan/core/board_diagnostic.py +111 -0
- tan/core/board_files.py +221 -0
- tan/core/board_validator.py +542 -0
- tan/core/board_validator_compat.py +196 -0
- tan/core/board_validator_run.py +129 -0
- tan/core/board_validator_schema.py +186 -0
- tan/core/board_validator_skew.py +46 -0
- tan/core/board_yaml_edit.py +295 -0
- tan/core/board_yaml_pos.py +118 -0
- tan/core/bootstrap.py +2572 -0
- tan/core/build_plan.py +625 -0
- tan/core/consent.py +104 -0
- tan/core/console_filter.py +245 -0
- tan/core/debug_launch.py +1803 -0
- tan/core/devicetree_lint.py +168 -0
- tan/core/dir_removal.py +229 -0
- tan/core/doctor_git.py +172 -0
- tan/core/doctor_libraries.py +253 -0
- tan/core/doctor_render.py +185 -0
- tan/core/doctor_scope.py +66 -0
- tan/core/doctor_setools.py +237 -0
- tan/core/doctor_stale.py +180 -0
- tan/core/document_guards.py +723 -0
- tan/core/dp_id.py +97 -0
- tan/core/elf_load.py +63 -0
- tan/core/error_catalog.py +171 -0
- tan/core/example_catalog.py +499 -0
- tan/core/example_facets.py +151 -0
- tan/core/faultdecode.py +521 -0
- tan/core/flash_plan.py +2501 -0
- tan/core/flow_d_report.py +381 -0
- tan/core/flow_d_uptime.py +164 -0
- tan/core/fs_confine.py +130 -0
- tan/core/global_flags.py +230 -0
- tan/core/host_python.py +210 -0
- tan/core/image_bundle.py +247 -0
- tan/core/inert.py +147 -0
- tan/core/jlink_binary.py +128 -0
- tan/core/jlink_probe.py +481 -0
- tan/core/jsonc_splice.py +404 -0
- tan/core/launch_provenance.py +257 -0
- tan/core/link_refusal.py +76 -0
- tan/core/metadata_schema.py +376 -0
- tan/core/model_check.py +227 -0
- tan/core/model_device.py +449 -0
- tan/core/model_doctor.py +198 -0
- tan/core/model_host.py +48 -0
- tan/core/model_list.py +112 -0
- tan/core/model_zoo.py +353 -0
- tan/core/module_template.py +340 -0
- tan/core/mram_link.py +87 -0
- tan/core/new_som_ospi.py +94 -0
- tan/core/os_class.py +159 -0
- tan/core/patch_paths.py +87 -0
- tan/core/pending.py +40 -0
- tan/core/plain_zephyr_plan.py +138 -0
- tan/core/plan_exec.py +373 -0
- tan/core/plan_tokens.py +600 -0
- tan/core/probe.py +155 -0
- tan/core/probe_plan.py +237 -0
- tan/core/proxy.py +168 -0
- tan/core/publish.py +31 -0
- tan/core/python_floor.py +178 -0
- tan/core/ram_run.py +694 -0
- tan/core/ram_watch.py +231 -0
- tan/core/raw_write.py +160 -0
- tan/core/reset_plan.py +56 -0
- tan/core/run.py +161 -0
- tan/core/scaffold.py +2203 -0
- tan/core/scaffold_selftest_identity.py +225 -0
- tan/core/sdk_default_registry.py +565 -0
- tan/core/sdk_discovery.py +996 -0
- tan/core/sdk_removal.py +465 -0
- tan/core/serial_actions.py +175 -0
- tan/core/serial_capture.py +185 -0
- tan/core/serial_url.py +45 -0
- tan/core/setools.py +608 -0
- tan/core/setools_scratch.py +243 -0
- tan/core/shapes.py +194 -0
- tan/core/size.py +610 -0
- tan/core/som_buildability.py +204 -0
- tan/core/som_schema_version.py +62 -0
- tan/core/subprocess_env.py +201 -0
- tan/core/sysbuild_image.py +94 -0
- tan/core/system_manifest.py +827 -0
- tan/core/text_layout.py +73 -0
- tan/core/timestamp.py +182 -0
- tan/core/tool_lookup.py +383 -0
- tan/core/toolchain_pin.py +117 -0
- tan/core/toolchain_provision.py +1224 -0
- tan/core/trusted_path.py +134 -0
- tan/core/uboot_breakin.py +154 -0
- tan/core/uri_reference.py +415 -0
- tan/core/user_defines.py +152 -0
- tan/core/venv.py +332 -0
- tan/core/west_patches.py +143 -0
- tan/core/west_workspace_refusal.py +159 -0
- tan/core/zephyr_env.py +124 -0
- tan/env.py +185 -0
- tan/envelope.py +647 -0
- tan/exit_codes.py +12 -0
- tan/lazy_typer.py +185 -0
- tan/model/__init__.py +2 -0
- tan/model/_gen_fixture.py +132 -0
- tan/model/adapters/__init__.py +116 -0
- tan/model/adapters/cpu.py +26 -0
- tan/model/adapters/deepx.py +94 -0
- tan/model/adapters/drpai.py +242 -0
- tan/model/adapters/ethos_u.py +951 -0
- tan/model/adapters/executorch.py +55 -0
- tan/model/analyze.py +694 -0
- tan/model/build.py +304 -0
- tan/model/check.py +682 -0
- tan/model/manifest.py +625 -0
- tan/model/measure.py +216 -0
- tan/model/npu_ops_validate.py +130 -0
- tan/model/package.py +125 -0
- tan/model/perf.py +635 -0
- tan/model/perf_apply.py +721 -0
- tan/model/prep.py +193 -0
- tan/model/sram_fit.py +502 -0
- tan/model/targets.py +374 -0
- tan/model/tensorio.py +287 -0
- tan/net.py +73 -0
- tan/output_format.py +213 -0
- tan/planner/__init__.py +219 -0
- tan/planner/aperture.py +202 -0
- tan/planner/buildplan.py +1092 -0
- tan/planner/camera_owner.py +192 -0
- tan/planner/cameras.py +132 -0
- tan/planner/carveout.py +755 -0
- tan/planner/cli.py +274 -0
- tan/planner/headers.py +315 -0
- tan/planner/kconfig.py +2435 -0
- tan/planner/kconfig_symbols.py +473 -0
- tan/planner/libraries.py +677 -0
- tan/planner/link_target.py +237 -0
- tan/planner/linux_ownership.py +216 -0
- tan/planner/loader.py +1525 -0
- tan/planner/manifest.py +116 -0
- tan/planner/memory.py +161 -0
- tan/planner/memregion.py +56 -0
- tan/planner/models.py +533 -0
- tan/planner/orchestrator.py +874 -0
- tan/planner/ownership.py +203 -0
- tan/planner/partition.py +1160 -0
- tan/planner/paths.py +32 -0
- tan/planner/plain_slice.py +139 -0
- tan/planner/project_emit/__init__.py +60 -0
- tan/planner/project_emit/bom_netlist.py +375 -0
- tan/planner/project_emit/dts.py +580 -0
- tan/planner/project_emit/hw_info.py +221 -0
- tan/planner/project_emit/native_sim.py +136 -0
- tan/planner/project_emit/west_libs.py +213 -0
- tan/planner/project_loader.py +264 -0
- tan/planner/sdk_capability.py +203 -0
- tan/planner/sdk_compat.py +395 -0
- tan/planner/secure.py +350 -0
- tan/planner/slugs.py +394 -0
- tan/planner/som_metadata.py +325 -0
- tan/planner/strict_loaders.py +131 -0
- tan/planner/template.py +1037 -0
- tan/planner/template_pins.py +535 -0
- tan/planner/template_rewrite.py +714 -0
- tan/planner/topology.py +208 -0
- tan/planner/validate.py +365 -0
- tan/planner/whole_device_alias.py +67 -0
- tan/planner/zephyr_board.py +3510 -0
- tan/planner_cli.py +97 -0
- tan/planner_emit.py +617 -0
- tan/planner_root.py +119 -0
- tan/soc_ref.py +58 -0
- tan/templates/__init__.py +34 -0
- tan/templates/vendored/MANIFEST.md +1862 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/CMakeLists.txt +8 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/README.md +112 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/board.yaml +38 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/boards/native_sim_native_64.conf +11 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/boards/native_sim_native_64.overlay +29 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/prj.conf +5 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/src/main.c +266 -0
- tan/templates/vendored/diagnostics/E1M-AEN801/testcase.yaml +53 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/CMakeLists.txt +8 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/README.md +112 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/board.yaml +38 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/boards/native_sim_native_64.conf +11 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/boards/native_sim_native_64.overlay +29 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/prj.conf +5 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/src/main.c +266 -0
- tan/templates/vendored/diagnostics/E1M-V2N101/testcase.yaml +53 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/CMakeLists.txt +10 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/README.md +75 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/board.yaml +38 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/prj.conf +8 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/src/cold_chain.c +371 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/src/cold_chain.h +178 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/src/main.c +373 -0
- tan/templates/vendored/edge-ai/E1M-AEN801/testcase.yaml +62 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/CMakeLists.txt +10 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/README.md +75 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/board.yaml +37 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/prj.conf +8 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/src/cold_chain.c +371 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/src/cold_chain.h +178 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/src/main.c +373 -0
- tan/templates/vendored/edge-ai/E1M-V2N101/testcase.yaml +62 -0
- tan/templates/vendored/iot/E1M-AEN801/CMakeLists.txt +14 -0
- tan/templates/vendored/iot/E1M-AEN801/README.md +103 -0
- tan/templates/vendored/iot/E1M-AEN801/board.yaml +69 -0
- tan/templates/vendored/iot/E1M-AEN801/prj.conf +15 -0
- tan/templates/vendored/iot/E1M-AEN801/src/cc3501e_bridge.c +196 -0
- tan/templates/vendored/iot/E1M-AEN801/src/cc3501e_bridge.h +173 -0
- tan/templates/vendored/iot/E1M-AEN801/src/main.c +262 -0
- tan/templates/vendored/iot/E1M-AEN801/testcase.yaml +68 -0
- tan/templates/vendored/minimal/E1M-AEN801/CMakeLists.txt +8 -0
- tan/templates/vendored/minimal/E1M-AEN801/README.md +108 -0
- tan/templates/vendored/minimal/E1M-AEN801/board.yaml +32 -0
- tan/templates/vendored/minimal/E1M-AEN801/prj.conf +8 -0
- tan/templates/vendored/minimal/E1M-AEN801/src/main.c +111 -0
- tan/templates/vendored/minimal/E1M-AEN801/testcase.yaml +49 -0
- tan/templates/vendored/minimal/E1M-V2N101/CMakeLists.txt +8 -0
- tan/templates/vendored/minimal/E1M-V2N101/README.md +108 -0
- tan/templates/vendored/minimal/E1M-V2N101/board.yaml +32 -0
- tan/templates/vendored/minimal/E1M-V2N101/prj.conf +8 -0
- tan/templates/vendored/minimal/E1M-V2N101/src/main.c +111 -0
- tan/templates/vendored/minimal/E1M-V2N101/testcase.yaml +49 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/CMakeLists.txt +8 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/README.md +120 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/board.yaml +57 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/boards/native_sim_native_64.overlay +40 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/peer/CMakeLists.txt +13 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/peer/main.c +171 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/peer/prj.conf +17 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/peer/testcase.yaml +23 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/prj.conf +22 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/src/main.c +185 -0
- tan/templates/vendored/multicore-mailbox/E1M-AEN801/testcase.yaml +26 -0
- tan/templates/vendored/sensor/E1M-AEN801/CMakeLists.txt +8 -0
- tan/templates/vendored/sensor/E1M-AEN801/README.md +112 -0
- tan/templates/vendored/sensor/E1M-AEN801/board.yaml +57 -0
- tan/templates/vendored/sensor/E1M-AEN801/boards/native_sim_native_64.conf +10 -0
- tan/templates/vendored/sensor/E1M-AEN801/boards/native_sim_native_64.overlay +28 -0
- tan/templates/vendored/sensor/E1M-AEN801/prj.conf +5 -0
- tan/templates/vendored/sensor/E1M-AEN801/src/main.c +186 -0
- tan/templates/vendored/sensor/E1M-AEN801/testcase.yaml +52 -0
- tan/templates/vendored/sensor/E1M-V2N101/CMakeLists.txt +8 -0
- tan/templates/vendored/sensor/E1M-V2N101/README.md +112 -0
- tan/templates/vendored/sensor/E1M-V2N101/board.yaml +57 -0
- tan/templates/vendored/sensor/E1M-V2N101/boards/native_sim_native_64.conf +10 -0
- tan/templates/vendored/sensor/E1M-V2N101/boards/native_sim_native_64.overlay +28 -0
- tan/templates/vendored/sensor/E1M-V2N101/prj.conf +5 -0
- tan/templates/vendored/sensor/E1M-V2N101/src/main.c +186 -0
- tan/templates/vendored/sensor/E1M-V2N101/testcase.yaml +52 -0
- tan/version.py +102 -0
- tan_cli-0.7.0.dist-info/METADATA +125 -0
- tan_cli-0.7.0.dist-info/RECORD +330 -0
- tan_cli-0.7.0.dist-info/WHEEL +5 -0
- tan_cli-0.7.0.dist-info/entry_points.txt +2 -0
- tan_cli-0.7.0.dist-info/top_level.txt +1 -0
tan/core/python_floor.py
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
"""The Python floor `tan build` and `tan doctor` both enforce -- ONE
|
|
3
|
+
composition (tan-cli#1317), pure `tan/core` so neither command imports the other.
|
|
4
|
+
|
|
5
|
+
`effective_python_floor` is the higher of the alp-sdk manifest's
|
|
6
|
+
`prerequisites.pythonMinVersion` and the floor Zephyr's CMake itself enforces
|
|
7
|
+
(`zephyr_python_floor`).
|
|
8
|
+
"""
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import json
|
|
12
|
+
import re
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
|
|
15
|
+
from tan.core.bootstrap import BOOTSTRAP_MANIFEST_SCHEMA_VERSION
|
|
16
|
+
|
|
17
|
+
#: Zephyr's own floor, from `<zephyr>/cmake/modules/python.cmake`'s
|
|
18
|
+
#: `set(PYTHON_MINIMUM_REQUIRED 3.12)`. The LAST-resort fallback --
|
|
19
|
+
#: `zephyr_python_floor` reads the real file when a workspace resolves, and
|
|
20
|
+
#: (tan-cli#606) prefers alp-sdk's own manifest-declared
|
|
21
|
+
#: `zephyr.pythonMinVersion` over this constant when no workspace resolves but
|
|
22
|
+
#: a manifest does; this is what is left once BOTH are unavailable, so a
|
|
23
|
+
#: Zephyr bump raises the floor on the customer's machine without waiting for
|
|
24
|
+
#: a tan release only via one of those two live reads, never this one.
|
|
25
|
+
ZEPHYR_PYTHON_FLOOR = (3, 12)
|
|
26
|
+
|
|
27
|
+
#: The floor `metadata/bootstrap.json` is assumed to declare when no manifest
|
|
28
|
+
#: resolves at all -- used ONLY as the `manifest_floor` input to `max()` below,
|
|
29
|
+
#: never as a verdict by itself. It mirrors `crate::util::MIN_PYTHON`
|
|
30
|
+
#: (`crates/tan-cli/src/util.rs`), which is frozen at 3.10 and does NOT track
|
|
31
|
+
#: `metadata/bootstrap.json` -- that Rust constant and the manifest's declared
|
|
32
|
+
#: `pythonMinVersion` are two independently-edited numbers, not one fact, and
|
|
33
|
+
#: they can and do drift apart (the manifest is mid-raise to 3.12 as of this
|
|
34
|
+
#: writing; the oracle constant is not). The manifest is the authority: when it
|
|
35
|
+
#: resolves AND declares `pythonMinVersion`, that number is read live and this
|
|
36
|
+
#: constant is not consulted for the verdict -- but a manifest that resolves
|
|
37
|
+
#: while omitting the key still falls back to this same constant (see
|
|
38
|
+
#: `resolve_manifest_python_floor`/`_collect` below), so this is not a
|
|
39
|
+
#: no-manifest-only fallback. `ZEPHYR_PYTHON_FLOOR` above still composes with
|
|
40
|
+
#: it via `max()` either way, so a resolvable SDK checkout with the key present
|
|
41
|
+
#: never depends on this value being current.
|
|
42
|
+
FALLBACK_PYTHON_FLOOR = (3, 10)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _read_text(path: Path) -> str | None:
|
|
46
|
+
try:
|
|
47
|
+
return path.read_text(encoding="utf-8", errors="replace")
|
|
48
|
+
except (OSError, ValueError):
|
|
49
|
+
return None
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def parse_two(raw: str) -> tuple[int, int] | None:
|
|
53
|
+
match = re.search(r"(\d+)\.(\d+)", raw)
|
|
54
|
+
return (int(match.group(1)), int(match.group(2))) if match else None
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def zephyr_python_floor(
|
|
58
|
+
zephyr_base: str | None, *, manifest_zephyr_floor: tuple[int, int] | None = None
|
|
59
|
+
) -> tuple[tuple[int, int], str]:
|
|
60
|
+
"""The floor Zephyr's CMake will actually enforce, and where it came from.
|
|
61
|
+
|
|
62
|
+
Read from `<zephyr_base>/cmake/modules/python.cmake` when that resolves,
|
|
63
|
+
because THAT is the file whose `PYTHON_MINIMUM_REQUIRED` aborts the build --
|
|
64
|
+
a constant compiled into tan goes stale the moment Zephyr bumps it, and a
|
|
65
|
+
stale floor here reintroduces exactly the silent gap this command exists to
|
|
66
|
+
close.
|
|
67
|
+
|
|
68
|
+
When it does NOT resolve, `manifest_zephyr_floor` -- alp-sdk's OWN declared
|
|
69
|
+
`zephyr.pythonMinVersion` (tan-cli#606), when the caller's manifest read
|
|
70
|
+
found one -- is now preferred over `ZEPHYR_PYTHON_FLOOR`: a fact alp-sdk
|
|
71
|
+
already publishes beats a constant compiled into tan, the same reasoning
|
|
72
|
+
that prefers `python.cmake` itself one level up. `ZEPHYR_PYTHON_FLOOR`
|
|
73
|
+
remains the LAST resort, for an SDK whose manifest predates that key (or
|
|
74
|
+
when no manifest resolves at all) -- every host at `tan bootstrap` time
|
|
75
|
+
used to land here unconditionally; now only a manifest-less one does.
|
|
76
|
+
|
|
77
|
+
`zephyr_base` is a plain path in, not necessarily `$ZEPHYR_BASE` itself --
|
|
78
|
+
THIS function has no opinion on where it came from, only `_collect` (this
|
|
79
|
+
module's `hostPython`/`pythonFloor` caller) does. As of tan-cli#301,
|
|
80
|
+
`_collect` passes the resolved workspace's `zephyr/` subtree -- the SAME
|
|
81
|
+
`tan.core.venv.west_workspace_dir` result `zephyrWorkspace` reports -- when
|
|
82
|
+
one resolved, a literal `$ZEPHYR_BASE` read only when no workspace resolved
|
|
83
|
+
at all, and `None` (landing on `ZEPHYR_PYTHON_FLOOR` below) when neither
|
|
84
|
+
does; that is the three-way split the resulting `source` string names. The
|
|
85
|
+
OTHER caller, `tan.commands.bootstrap_cmd.resolve_python_floor`, still
|
|
86
|
+
passes a literal `$ZEPHYR_BASE` read directly -- `tan bootstrap` runs before
|
|
87
|
+
any workspace can have resolved, so there is nothing else for it to prefer.
|
|
88
|
+
|
|
89
|
+
**The fallback names WHICH of three causes fired (tan-cli#488 defect 7).**
|
|
90
|
+
It used to be one hardcoded string -- "no $ZEPHYR_BASE workspace on this
|
|
91
|
+
host to read `cmake/modules/python.cmake` from" -- for every way the read
|
|
92
|
+
could fail, but only ONE of the three causes below makes that true. A
|
|
93
|
+
`.west` workspace mid-`west update` (`zephyr_workspace_check`'s own
|
|
94
|
+
"legitimate, working-in-progress host state") resolves a real
|
|
95
|
+
`zephyr_base` whose `cmake/modules/python.cmake` simply is not there yet
|
|
96
|
+
-- reported by `_collect` as `workspace`/`zephyrWorkspace` BOTH passing,
|
|
97
|
+
in the same envelope that then blamed a `$ZEPHYR_BASE` env var never
|
|
98
|
+
consulted for this call (`_collect` feeds this function the RESOLVED
|
|
99
|
+
workspace's own `zephyr/` subtree, never `$ZEPHYR_BASE` itself, once a
|
|
100
|
+
workspace resolves -- see above). `jlink_flash_device` fixed the identical
|
|
101
|
+
shape for its own three-cause fallback in tan-cli#310; this mirrors it.
|
|
102
|
+
"""
|
|
103
|
+
if manifest_zephyr_floor is not None:
|
|
104
|
+
fallback_floor = manifest_zephyr_floor
|
|
105
|
+
fallback_label = (
|
|
106
|
+
f"alp-sdk metadata/bootstrap.json zephyr.pythonMinVersion "
|
|
107
|
+
f"{fallback_floor[0]}.{fallback_floor[1]}"
|
|
108
|
+
)
|
|
109
|
+
else:
|
|
110
|
+
fallback_floor = ZEPHYR_PYTHON_FLOOR
|
|
111
|
+
fallback_label = f"tan's built-in pin {fallback_floor[0]}.{fallback_floor[1]}"
|
|
112
|
+
|
|
113
|
+
if zephyr_base:
|
|
114
|
+
path = Path(zephyr_base) / "cmake" / "modules" / "python.cmake"
|
|
115
|
+
text = _read_text(path)
|
|
116
|
+
if text is not None:
|
|
117
|
+
match = re.search(r"PYTHON_MINIMUM_REQUIRED\s+(\d+)\.(\d+)", text)
|
|
118
|
+
if match is not None:
|
|
119
|
+
return (int(match.group(1)), int(match.group(2))), str(path)
|
|
120
|
+
return fallback_floor, (
|
|
121
|
+
f"Zephyr's PYTHON_MINIMUM_REQUIRED, from {fallback_label} -- {path} was "
|
|
122
|
+
f"read but did not declare a parseable PYTHON_MINIMUM_REQUIRED"
|
|
123
|
+
)
|
|
124
|
+
return fallback_floor, (
|
|
125
|
+
f"Zephyr's PYTHON_MINIMUM_REQUIRED, from {fallback_label} -- {path} could not "
|
|
126
|
+
f"be read (a `.west` workspace mid-`west update` is a legitimate, "
|
|
127
|
+
f"working-in-progress host state, not a broken one)"
|
|
128
|
+
)
|
|
129
|
+
return fallback_floor, (
|
|
130
|
+
f"Zephyr's PYTHON_MINIMUM_REQUIRED, from {fallback_label} -- no $ZEPHYR_BASE "
|
|
131
|
+
f"workspace on this host to read `cmake/modules/python.cmake` from"
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def read_manifest_floors(sdk_root: str | None) -> tuple[tuple[int, int], tuple[int, int] | None]:
|
|
136
|
+
"""`(manifest_floor, zephyr_manifest_floor)` from `<sdk>/metadata/bootstrap.json`
|
|
137
|
+
with the SAME fallbacks `tan doctor`'s `_load_manifest` applies: an absent,
|
|
138
|
+
unparseable, wrong-schema or `prerequisites`-less manifest yields
|
|
139
|
+
`(FALLBACK_PYTHON_FLOOR, None)`."""
|
|
140
|
+
if sdk_root is None:
|
|
141
|
+
return FALLBACK_PYTHON_FLOOR, None
|
|
142
|
+
text = _read_text(Path(sdk_root) / "metadata" / "bootstrap.json")
|
|
143
|
+
if text is None:
|
|
144
|
+
return FALLBACK_PYTHON_FLOOR, None
|
|
145
|
+
try:
|
|
146
|
+
doc = json.loads(text)
|
|
147
|
+
except ValueError:
|
|
148
|
+
return FALLBACK_PYTHON_FLOOR, None
|
|
149
|
+
if not isinstance(doc, dict):
|
|
150
|
+
return FALLBACK_PYTHON_FLOOR, None
|
|
151
|
+
version = doc.get("schemaVersion")
|
|
152
|
+
if (
|
|
153
|
+
not isinstance(version, int)
|
|
154
|
+
or isinstance(version, bool)
|
|
155
|
+
or version != BOOTSTRAP_MANIFEST_SCHEMA_VERSION
|
|
156
|
+
):
|
|
157
|
+
return FALLBACK_PYTHON_FLOOR, None
|
|
158
|
+
prerequisites = doc.get("prerequisites")
|
|
159
|
+
if not isinstance(prerequisites, dict):
|
|
160
|
+
return FALLBACK_PYTHON_FLOOR, None
|
|
161
|
+
manifest = parse_two(str(prerequisites.get("pythonMinVersion") or "")) or FALLBACK_PYTHON_FLOOR
|
|
162
|
+
zephyr = doc.get("zephyr")
|
|
163
|
+
raw = zephyr.get("pythonMinVersion") if isinstance(zephyr, dict) else None
|
|
164
|
+
return manifest, parse_two(raw) if isinstance(raw, str) else None
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def effective_python_floor(
|
|
168
|
+
manifest_floor: tuple[int, int],
|
|
169
|
+
zephyr_base: str | None,
|
|
170
|
+
manifest_zephyr_floor: tuple[int, int] | None = None,
|
|
171
|
+
) -> tuple[tuple[int, int], str]:
|
|
172
|
+
"""`(floor, source)`: the highest anything in the build chain enforces."""
|
|
173
|
+
zephyr_floor, zephyr_source = zephyr_python_floor(
|
|
174
|
+
zephyr_base, manifest_zephyr_floor=manifest_zephyr_floor
|
|
175
|
+
)
|
|
176
|
+
if zephyr_floor >= manifest_floor:
|
|
177
|
+
return zephyr_floor, zephyr_source
|
|
178
|
+
return manifest_floor, "alp-sdk metadata/bootstrap.json pythonMinVersion"
|