1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-05-01 06:29:20 +00:00

refactor(core): remove trezorui2 module

- also remove "check" scripts which seem outdated

[no changelog]
This commit is contained in:
obrusvit 2024-12-05 22:48:28 +01:00 committed by Vít Obrusník
parent ad9618c282
commit 9caf540e16
19 changed files with 3 additions and 391 deletions

View File

@ -164,7 +164,6 @@
#define MICROPY_PY_TREZORUTILS (1) #define MICROPY_PY_TREZORUTILS (1)
#define MICROPY_PY_TREZORPROTO (1) #define MICROPY_PY_TREZORPROTO (1)
#define MICROPY_PY_TREZORTRANSLATE (1) #define MICROPY_PY_TREZORTRANSLATE (1)
#define MICROPY_PY_TREZORUI2 (1)
#define MICROPY_PY_TREZORUI_API (1) #define MICROPY_PY_TREZORUI_API (1)
#ifdef SYSTEM_VIEW #ifdef SYSTEM_VIEW

View File

@ -213,7 +213,6 @@ extern const struct _mp_print_t mp_stderr_print;
#define MICROPY_PY_TREZORUTILS (1) #define MICROPY_PY_TREZORUTILS (1)
#define MICROPY_PY_TREZORPROTO (1) #define MICROPY_PY_TREZORPROTO (1)
#define MICROPY_PY_TREZORTRANSLATE (1) #define MICROPY_PY_TREZORTRANSLATE (1)
#define MICROPY_PY_TREZORUI2 (1)
#define MICROPY_PY_TREZORUI_API (1) #define MICROPY_PY_TREZORUI_API (1)
#define MP_STATE_PORT MP_STATE_VM #define MP_STATE_PORT MP_STATE_VM

View File

@ -8,7 +8,6 @@ mp_obj_t protobuf_debug_msg_def_type();
#endif #endif
extern mp_obj_module_t mp_module_trezorproto; extern mp_obj_module_t mp_module_trezorproto;
extern mp_obj_module_t mp_module_trezorui2;
extern mp_obj_module_t mp_module_trezorui_api; extern mp_obj_module_t mp_module_trezorui_api;
extern mp_obj_module_t mp_module_trezortranslate; extern mp_obj_module_t mp_module_trezortranslate;

View File

@ -683,7 +683,6 @@ static void _librust_qstrs(void) {
MP_QSTR_touch_event; MP_QSTR_touch_event;
MP_QSTR_trace; MP_QSTR_trace;
MP_QSTR_trezorproto; MP_QSTR_trezorproto;
MP_QSTR_trezorui2;
MP_QSTR_trezorui_api; MP_QSTR_trezorui_api;
MP_QSTR_tutorial; MP_QSTR_tutorial;
MP_QSTR_tutorial__continue; MP_QSTR_tutorial__continue;

View File

@ -8,7 +8,7 @@ use super::component::{
}; };
use crate::{ use crate::{
error::Error, error::Error,
micropython::{macros::obj_module, module::Module, obj::Obj, qstr::Qstr}, micropython::obj::Obj,
ui::{ ui::{
component::{ component::{
text::paragraphs::{ParagraphSource, Paragraphs}, text::paragraphs::{ParagraphSource, Paragraphs},
@ -184,12 +184,3 @@ where
unreachable!(); unreachable!();
} }
} }
#[no_mangle]
pub static mp_module_trezorui2: Module = obj_module! {
/// from trezor import utils
/// from trezorui_api import *
///
Qstr::MP_QSTR___name__ => Qstr::MP_QSTR_trezorui2.to_obj(),
};

View File

@ -7,7 +7,7 @@ use super::component::{
}; };
use crate::{ use crate::{
error::Error, error::Error,
micropython::{macros::obj_module, map::Map, module::Module, obj::Obj, qstr::Qstr}, micropython::obj::Obj,
ui::{ ui::{
component::{ component::{
base::Component, base::Component,
@ -200,12 +200,3 @@ impl ComponentMsgObj for super::component::bl_confirm::Confirm<'_> {
} }
} }
} }
#[no_mangle]
pub static mp_module_trezorui2: Module = obj_module! {
/// from trezor import utils
/// from trezorui_api import *
///
Qstr::MP_QSTR___name__ => Qstr::MP_QSTR_trezorui2.to_obj(),
};

View File

@ -9,7 +9,7 @@ use super::component::{
}; };
use crate::{ use crate::{
error::Error, error::Error,
micropython::{macros::obj_module, map::Map, module::Module, obj::Obj, qstr::Qstr, util}, micropython::obj::Obj,
strutil::TString, strutil::TString,
ui::{ ui::{
component::{ component::{
@ -284,11 +284,3 @@ impl ComponentMsgObj for super::component::bl_confirm::Confirm<'_> {
} }
} }
} }
#[no_mangle]
pub static mp_module_trezorui2: Module = obj_module! {
/// from trezor import utils
/// from trezorui_api import *
///
Qstr::MP_QSTR___name__ => Qstr::MP_QSTR_trezorui2.to_obj(),
};

View File

@ -20,10 +20,6 @@
#include "librust.h" #include "librust.h"
#include "py/runtime.h" #include "py/runtime.h"
#if MICROPY_PY_TREZORUI2
MP_REGISTER_MODULE(MP_QSTR_trezorui2, mp_module_trezorui2);
#endif
#if MICROPY_PY_TREZORUI_API #if MICROPY_PY_TREZORUI_API
MP_REGISTER_MODULE(MP_QSTR_trezorui_api, mp_module_trezorui_api); MP_REGISTER_MODULE(MP_QSTR_trezorui_api, mp_module_trezorui_api);
#endif #endif

View File

@ -1,7 +0,0 @@
from typing import *
from trezor import utils
from trezorui_api import *
from trezor import utils
from trezorui_api import *
from trezor import utils
from trezorui_api import *

View File

@ -4,7 +4,6 @@ from micropython import const
from trezorui import Display from trezorui import Display
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
import trezorui2
from trezor import io, log, loop, utils, wire, workflow from trezor import io, log, loop, utils, wire, workflow
from trezor.messages import ButtonAck, ButtonRequest from trezor.messages import ButtonAck, ButtonRequest
from trezor.wire import context from trezor.wire import context

View File

@ -1,6 +1,5 @@
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
import trezorui2
import trezorui_api import trezorui_api
from trezor import TR, ui, utils from trezor import TR, ui, utils
from trezor.enums import ButtonRequestType from trezor.enums import ButtonRequestType

View File

@ -1,6 +1,5 @@
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
import trezorui2
import trezorui_api import trezorui_api
from trezor import TR from trezor import TR
from trezor.enums import ButtonRequestType, RecoveryType from trezor.enums import ButtonRequestType, RecoveryType

View File

@ -1,6 +1,5 @@
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
import trezorui2
import trezorui_api import trezorui_api
from trezor import TR, ui, utils from trezor import TR, ui, utils
from trezor.enums import ButtonRequestType from trezor.enums import ButtonRequestType

View File

@ -1,6 +1,5 @@
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
import trezorui2
import trezorui_api import trezorui_api
from trezor import TR, ui from trezor import TR, ui
from trezor.enums import ButtonRequestType, RecoveryType from trezor.enums import ButtonRequestType, RecoveryType

View File

@ -1,6 +1,5 @@
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
import trezorui2
import trezorui_api import trezorui_api
from trezor import TR, ui, utils from trezor import TR, ui, utils
from trezor.enums import ButtonRequestType from trezor.enums import ButtonRequestType

View File

@ -1,6 +1,5 @@
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
import trezorui2
import trezorui_api import trezorui_api
from trezor import TR, ui from trezor import TR, ui
from trezor.enums import ButtonRequestType from trezor.enums import ButtonRequestType

View File

@ -119,12 +119,3 @@ Generate a CMakeLists.txt file for the core.
### `provision_device.py` ### `provision_device.py`
Run the provisioning flow on a prodtest firmware, against a staging provisioning server. Run the provisioning flow on a prodtest firmware, against a staging provisioning server.
### `rust_api_checks.py`
Check that the Rust UI API is consistent with the Python UI API.
### `rust_api_models_unification.py`
Checks the consistency of the Rust API between models.

View File

@ -1,246 +0,0 @@
#!/usr/bin/env python3
"""
Compare the mock python API with the real Rust one.
"""
from __future__ import annotations
import re
from pathlib import Path
HERE = Path(__file__).parent
CORE_DIR = HERE.parent
TT_FILE = CORE_DIR / "embed/rust/src/ui/model_tt/layout.rs"
TR_FILE = CORE_DIR / "embed/rust/src/ui/model_tr/layout.rs"
ALL_FILES = [
TT_FILE,
TR_FILE,
]
# These are functions not defined directly in layout.rs
RUST_EXTERNAL_FUNCTIONS = [
"disable_animation",
"jpeg_info",
"jpeg_test",
]
# These functions do not directly proccess upy arguments
RUST_DELEGATING_FUNCTIONS = [
"new_show_success",
"new_show_warning",
"new_show_error",
"new_show_info",
]
def _get_all_functions_with_definitions(file: Path) -> dict[str, str]:
all_functions: dict[str, str] = {}
with open(file, "r") as f:
lines = f.readlines()
func_name: str | None = None
definition_lines: list[str] = []
for line in lines:
# Function name
func_match = re.search(r'^extern "C" fn (\w+)', line)
if func_match:
func_name = func_match.group(1)
continue
if not func_name:
continue
# Saving the line
definition_lines.append(line.rstrip())
# End of definition - save and reset
if line.startswith("}"):
if func_name:
all_functions[func_name] = "\n".join(definition_lines)
func_name = None
definition_lines = []
continue
return all_functions
def _get_all_qstr_code_types(file: Path) -> dict[str, dict[str, str]]:
all_function_defs = _get_all_functions_with_definitions(file)
all_qstr_defs: dict[str, dict[str, str]] = {}
for func_name, func_def in all_function_defs.items():
qstr_defs: dict[str, str] = {}
one_separated_line: list[str] = []
for line in func_def.splitlines():
one_separated_line.append(line.strip())
if not line.endswith(";"):
continue
one_line = "".join(one_separated_line)
one_separated_line = []
qstr_match = re.search(r"MP_QSTR_(\w+)", one_line)
if not qstr_match:
continue
qstr_name = qstr_match.group(1)
rust_match = re.search(r"let (\w+): (.*?) =", one_line)
if not rust_match:
raise ValueError("No Rust type found")
rust_type = rust_match.group(2)
if rust_type == "Obj":
# Cannot get the exact type
upy_type = "Any"
else:
upy_type = rust_type
# There could be a default value
default = None
if "unwrap_or_else" in one_line:
default_match = re.search(r"unwrap_or_else\(\|_?\|\s+(.*?)\)", one_line)
if default_match:
default = default_match.group(1)
else:
raise ValueError("No default value found")
elif "kwargs.get_or(" in one_line:
default_match = re.search(
r"kwargs.get_or\(Qstr::MP_QSTR_\w+, (.*?)\)", one_line
)
if default_match:
default = default_match.group(1)
else:
raise ValueError("No default value found")
option_match = re.match(r"Option<(.*)>", upy_type)
if option_match:
upy_type = option_match.group(1)
upy_type = f"{upy_type} | None"
gc_match = re.match(r"Gc<(.*)>", upy_type)
if gc_match:
upy_type = gc_match.group(1)
upy_type = upy_type.replace("StrBuffer", "str")
upy_type = upy_type.replace("List", "list")
if re.match(r"^[ui]\d+$", upy_type) or upy_type == "usize":
upy_type = "int"
if default:
if "const_none" in default:
default = "None"
elif default in ("true", "false"):
default = default.capitalize()
elif ".into(" in default:
default = default.split(".into(")[0]
elif "StrBuffer::empty" in default:
default = '""'
upy_type += f" = {default}"
qstr_defs[qstr_name] = upy_type
all_qstr_defs[func_name] = qstr_defs
return all_qstr_defs
def _get_all_upy_types(file: Path) -> dict[str, dict[str, str]]:
all_functions: dict[str, dict[str, str]] = {}
with open(file, "r") as f:
lines = f.readlines()
func_name: str | None = None
definition_lines: list[str] = []
for line in lines:
line = line.strip()
# Function name
func_match = re.search(r"^/// def (\w+)\(", line)
if func_match:
func_name = func_match.group(1)
continue
if not func_name:
continue
# Saving the line
definition_lines.append(line)
# End of definition - save and reset
if line.startswith("Qstr::MP_QSTR_"):
if func_name:
if f"new_{func_name}" in line:
func_name = f"new_{func_name}"
def_text = "\n".join(definition_lines)
var_names_and_types = re.findall(r"(\w+): ([^#]*?)[,\n]", def_text)
all_functions[func_name] = {
name: type for name, type in var_names_and_types
}
unused_args: list[str] = []
for def_l in definition_lines:
if "# unused" in def_l:
unused_match = re.search(r"(\w+):", def_l)
if unused_match:
unused_args.append(unused_match.group(1))
all_functions[func_name]["_unused_args"] = unused_args # type: ignore
func_name = None
definition_lines = []
continue
return all_functions
def check_file(file: Path) -> None:
all_rust_types = _get_all_qstr_code_types(file)
all_upy_types = _get_all_upy_types(file)
# Find discrepancies between these types
for func_name, rust_types in all_rust_types.items():
upy_types = all_upy_types.get(func_name)
if upy_types is None:
print(f"Missing upy function {func_name}")
continue
unused_args = upy_types.get("_unused_args", [])
for qstr_name, rust_type in rust_types.items():
upy_type = upy_types.get(qstr_name)
if not upy_type:
print(f"Missing upy argument {qstr_name} in {func_name} ({rust_type})")
continue
if upy_type and qstr_name in unused_args:
print(f"Argument {qstr_name} marked as unused but used in {func_name}")
if rust_type != upy_type:
if rust_type == "Any":
continue
if rust_type == "list" and upy_type.startswith("list"):
continue
print(f"Discrepancy in {func_name} {qstr_name}:")
print(f" Rust: {rust_type}")
print(f" Upy: {upy_type}")
# Find things missing in Rust
for func_name, upy_types in all_upy_types.items():
rust_types = all_rust_types.get(func_name)
if rust_types is None:
if func_name in RUST_EXTERNAL_FUNCTIONS:
continue
print(f"Missing Rust function {func_name}")
continue
unused_args = upy_types.get("_unused_args", [])
for qstr_name, upy_type in upy_types.items():
if qstr_name == "_unused_args":
continue
rust_type = rust_types.get(qstr_name)
if not rust_type and qstr_name not in unused_args:
if func_name in RUST_DELEGATING_FUNCTIONS:
continue
print(f"Not parsing argument {qstr_name} in {func_name}")
continue
def main() -> None:
for file in ALL_FILES:
print(f"Checking {file}")
check_file(file)
if __name__ == "__main__":
main()

View File

@ -1,85 +0,0 @@
#!/usr/bin/env python3
"""
Check the consistency of the Rust API between models.
"""
from __future__ import annotations
import re
from collections import defaultdict
from pathlib import Path
HERE = Path(__file__).parent
CORE_DIR = HERE.parent
MOCK_FILE = CORE_DIR / "mocks/generated/trezorui2.pyi"
def _get_all_functions_with_definitions() -> dict[str, dict[str, str]]:
all_functions: dict[str, dict[str, str]] = defaultdict(dict)
with open(MOCK_FILE, "r") as f:
lines = f.readlines()
model: str | None = None
func_name: str | None = None
definition_lines: list[str] = []
for line in lines:
# Model line, e.g. "# rust/src/ui/model_tt/layout.rs"
model_match = re.search(r"^# rust/src/ui/model_(\w+)/", line)
if model_match:
model = model_match.group(1).upper()
continue
if model is None:
continue
# Function name
func_match = re.search(r"^def\s+(\w+)", line)
if func_match:
func_name = func_match.group(1)
# Getting rid of comments before saving the definition
line = line.split("#")[0].rstrip()
definition_lines.append(line)
# End of definition - save and reset
if line.endswith(":"):
if func_name and model:
all_functions[func_name][model] = "\n".join(definition_lines)
func_name = None
model = None
definition_lines = []
continue
return all_functions
def main() -> None:
all_functions = _get_all_functions_with_definitions()
# Show only those in one model
print(f"{40 * '/'}\nONLY ONE MODEL FUNCTIONS\n{40 * '/'}\n")
only_one_model_amount = 0
for func_name, func_defs in all_functions.items():
if len(func_defs) == 1:
print(f"{list(func_defs.keys())[0]} - {func_name}")
only_one_model_amount += 1
# Show those in both models, with comparing the definitions
print(f"\n{40 * '/'}\nDIFFERENT IMPLEMENTATIONS\n{40 * '/'}\n")
diff_impl_amount = 0
for func_name, func_defs in all_functions.items():
if len(func_defs) == 2:
models = list(func_defs.keys())
if func_defs[models[0]] != func_defs[models[1]]:
print(func_name)
for model in func_defs.keys():
print(model + " - " + func_defs[model])
print("\n" + "-" * 40 + "\n")
diff_impl_amount += 1
print(f"Total only one model functions: {only_one_model_amount}")
print(f"Total different implementations: {diff_impl_amount}")
if __name__ == "__main__":
main()