refactor(core): replace all Union usage by | syntax in core except `core/vendor` [no changelog]
What changed, and why it matters
This commit is a routine code cleanup that replaces older Python type-hint syntax (Union[...]) with the newer pipe syntax (|). It also updates one helper function to return None instead of the string 'dynamic' for consistency. There is no change to program logic, no security fix, and no vulnerability introduced.
No security action required. Treat as normal maintenance/refactoring commit.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The diff is a pure refactoring across seven files in the Trezor core firmware repository. It converts typing.Union annotations to PEP 604 union type syntax (e.g., Union[int, str] -> int | str). In core/src/trezor/loop.py it also adjusts an import to avoid a forward-reference string. In core/tests/test_apps.ethereum.sign_typed_data.py it changes parse_array_n to return None instead of ‘dynamic’, with the caller updated accordingly. These are syntactic/semantic-equivalent changes within the type system; runtime behavior is unchanged.
Changed components
core/embed/upymod/modtrezorio/modtrezorio.ccore/mocks/generated/trezorio/__init__.pyicore/mocks/uio.pyicore/src/apps/cardano/helpers/chunks.pycore/src/apps/monero/xmr/serialize/base_types.pycore/src/trezor/loop.pycore/tests/test_apps.ethereum.sign_typed_data.pyInspect captured patch +15 / −20
diff --git a/core/embed/upymod/modtrezorio/modtrezorio.c b/core/embed/upymod/modtrezorio/modtrezorio.c
index 9f605f14..08533ed5 100644
--- a/core/embed/upymod/modtrezorio/modtrezorio.c
+++ b/core/embed/upymod/modtrezorio/modtrezorio.c
@@ -88,7 +88,7 @@ uint32_t last_touch_sample_time = 0;
/// USB_EVENT: int # interface id for USB events
-/// WireInterface = Union[USBIF, BLEIF]
+/// WireInterface = USBIF | BLEIF
/// USBIF_WIRE: int # interface id of the USB wire interface
/// USBIF_DEBUG: int # interface id of the USB debug interface
/// USBIF_WEBAUTHN: int # interface id of the USB WebAuthn
diff --git a/core/mocks/generated/trezorio/__init__.pyi b/core/mocks/generated/trezorio/__init__.pyi
index b14c2ee7..d26e1478 100644
--- a/core/mocks/generated/trezorio/__init__.pyi
+++ b/core/mocks/generated/trezorio/__init__.pyi
@@ -97,7 +97,7 @@ BUTTON_RELEASED: int # button up event
BUTTON_LEFT: int # button number of left button
BUTTON_RIGHT: int # button number of right button
USB_EVENT: int # interface id for USB events
-WireInterface = Union[USBIF, BLEIF]
+WireInterface = USBIF | BLEIF
USBIF_WIRE: int # interface id of the USB wire interface
USBIF_DEBUG: int # interface id of the USB debug interface
USBIF_WEBAUTHN: int # interface id of the USB WebAuthn
diff --git a/core/mocks/uio.pyi b/core/mocks/uio.pyi
index 808dc629..6cf1e651 100644
--- a/core/mocks/uio.pyi
+++ b/core/mocks/uio.pyi
@@ -6,10 +6,10 @@ class FileIO:
def write(self, data: bytes | str) -> int: ...
class StringIO:
- def __init__(self, _: Union[int, str]) -> None: ...
+ def __init__(self, _: int | str) -> None: ...
class BytesIO:
- def __init__(self, _: Union[int, bytes]) -> None: ...
+ def __init__(self, _: int | bytes) -> None: ...
def getvalue(self) -> bytes: ...
def open(name: str, mode: str = ...) -> FileIO:
diff --git a/core/src/apps/cardano/helpers/chunks.py b/core/src/apps/cardano/helpers/chunks.py
index c63376b5..1ee81b09 100644
--- a/core/src/apps/cardano/helpers/chunks.py
+++ b/core/src/apps/cardano/helpers/chunks.py
@@ -6,12 +6,9 @@ from trezor.wire import ProcessError
from trezor.wire.context import call as ctx_call
if TYPE_CHECKING:
- from typing import Generic, TypeVar, Union
+ from typing import Generic, TypeVar
- Chunk = Union[
- messages.CardanoTxInlineDatumChunk,
- messages.CardanoTxReferenceScriptChunk,
- ]
+ Chunk = messages.CardanoTxInlineDatumChunk | messages.CardanoTxReferenceScriptChunk
C = TypeVar("C", bound=Chunk)
else:
diff --git a/core/src/apps/monero/xmr/serialize/base_types.py b/core/src/apps/monero/xmr/serialize/base_types.py
index 8c9d8dc4..7ba850e4 100644
--- a/core/src/apps/monero/xmr/serialize/base_types.py
+++ b/core/src/apps/monero/xmr/serialize/base_types.py
@@ -1,17 +1,14 @@
from typing import TYPE_CHECKING
if TYPE_CHECKING:
- from typing import Protocol, TypeVar, Union
+ from typing import Protocol, TypeVar
T = TypeVar("T")
XT = TypeVar("XT", bound="XmrType")
ST = TypeVar("ST", bound="XmrStructuredType")
- XmrFieldType = Union[
- tuple[str, XT],
- tuple[str, ST, XT],
- ]
+ XmrFieldType = tuple[str, XT] | tuple[str, ST, XT]
XmrFspec = tuple[XmrFieldType, ...]
diff --git a/core/src/trezor/loop.py b/core/src/trezor/loop.py
index 860c0207..fa680753 100644
--- a/core/src/trezor/loop.py
+++ b/core/src/trezor/loop.py
@@ -14,9 +14,11 @@ from typing import TYPE_CHECKING
from trezor import io, log
if TYPE_CHECKING:
- from typing import Any, Awaitable, Callable, Coroutine, Generator, Union
+ from typing import Any, Awaitable, Callable, Coroutine, Generator
- Task = Union[Coroutine, Generator, "wait"]
+ from .loop import wait
+
+ Task = Coroutine | Generator | wait
AwaitableTask = Task | Awaitable
Finalizer = Callable[[Task, Any], None]
diff --git a/core/tests/test_apps.ethereum.sign_typed_data.py b/core/tests/test_apps.ethereum.sign_typed_data.py
index 136170ad..3516f276 100644
--- a/core/tests/test_apps.ethereum.sign_typed_data.py
+++ b/core/tests/test_apps.ethereum.sign_typed_data.py
@@ -81,8 +81,7 @@ def get_field_type(type_name: str, types: dict) -> EFT:
if is_array(type_name):
data_type = EDT.ARRAY
- array_size = parse_array_n(type_name)
- size = None if array_size == "dynamic" else array_size
+ size = parse_array_n(type_name)
member_typename = typeof_array(type_name)
entry_type = get_field_type(member_typename, types)
elif type_name.startswith("uint"):
@@ -138,10 +137,10 @@ def parse_type_n(type_name: str) -> int:
raise ValueError(f"Invalid type name: {type_name}")
-def parse_array_n(type_name: str) -> Union[int, str]:
+def parse_array_n(type_name: str) -> int | None:
"""Parse N in type[<N>] where "type" can itself be an array type."""
if type_name.endswith("[]"):
- return "dynamic"
+ return None
start_idx = type_name.rindex("[") + 1
return int(type_name[start_idx:-1])
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.