diff --git a/pycyphal/application/register/_value.py b/pycyphal/application/register/_value.py index 36dbf4dc..b1ab453e 100644 --- a/pycyphal/application/register/_value.py +++ b/pycyphal/application/register/_value.py @@ -350,9 +350,21 @@ def _strictify(s: RelaxedValue) -> Value: if all(isinstance(x, bool) for x in s): return _strictify(Bit(s)) if all(isinstance(x, (int, bool)) for x in s): - return _strictify(Natural64(s)) if all(x >= 0 for x in s) else _strictify(Integer64(s)) - if all(isinstance(x, (float, int, bool)) for x in s): - return _strictify(Real64(s)) + if len(s) <= 32: + return _strictify(Natural64(s)) if all(x >= 0 for x in s) else _strictify(Integer64(s)) + if len(s) <= 64: + return _strictify(Natural32(s)) if all(x >= 0 for x in s) else _strictify(Integer32(s)) + if len(s) <= 128: + return _strictify(Natural16(s)) if all(x >= 0 for x in s) else _strictify(Integer16(s)) + if len(s) <= 256: + return _strictify(Natural8(s)) if all(x >= 0 for x in s) else _strictify(Integer8(s)) + elif all(isinstance(x, (float, int, bool)) for x in s): + if len(s) <= 32: + return _strictify(Real64(s)) + if len(s) <= 64: + return _strictify(Real32(s)) + if len(s) <= 128: + return _strictify(Real16(s)) raise ValueConversionError(f"Don't know how to convert {s!r} into {Value}") # pragma: no cover diff --git a/tests/application/long_numerical_arrays.py b/tests/application/long_numerical_arrays.py new file mode 100644 index 00000000..21b1c3ee --- /dev/null +++ b/tests/application/long_numerical_arrays.py @@ -0,0 +1,81 @@ +# Copyright (c) 2025 OpenCyphal +# This software is distributed under the terms of the MIT License. +# Author: Huong Pham +from typing import List + + +def _unittest_strictify_bool() -> None: + # noinspection PyProtectedMember + from pycyphal.application.register._value import _strictify + + s = [True, False] + n = _strictify(s).bit + assert n is not None + v = n.value + assert (s == v).all() # type: ignore[attr-defined] + + +def _unittest_strictify_u64() -> None: + # noinspection PyProtectedMember + from pycyphal.application.register._value import _strictify + + s = [x * 1000000 for x in range(30)] + n = _strictify(s).natural64 + assert n is not None + v = n.value + assert (s == v).all() # type: ignore[attr-defined] + + +def _unittest_strictify_u32() -> None: + # noinspection PyProtectedMember + from pycyphal.application.register._value import _strictify + + s = [x * 1000000 for x in range(60)] + n = _strictify(s).natural32 + assert n is not None + v = n.value + assert (s == v).all() # type: ignore[attr-defined] + + +def _unittest_strictify_u16() -> None: + # noinspection PyProtectedMember + from pycyphal.application.register._value import _strictify + + s = [x * 100 for x in range(80)] + n = _strictify(s).natural16 + assert n is not None + v = n.value + assert (s == v).all() # type: ignore[attr-defined] + + +def _unittest_strictify_i64() -> None: + # noinspection PyProtectedMember + from pycyphal.application.register._value import _strictify + + s = [-x * 1000000 for x in range(30)] + n = _strictify(s).integer64 + assert n is not None + v = n.value + assert (s == v).all() # type: ignore[attr-defined] + + +def _unittest_strictify_i32() -> None: + # noinspection PyProtectedMember + from pycyphal.application.register._value import _strictify + + s = [-x * 1000000 for x in range(60)] + n = _strictify(s).integer32 + assert n is not None + v = n.value + assert (s == v).all() # type: ignore[attr-defined] + + +def _unittest_strictify_i16() -> None: + # noinspection PyProtectedMember + from pycyphal.application.register._value import _strictify + + s = [-x * 100 for x in range(80)] + n = _strictify(s).integer16 + assert n is not None + v = n.value + assert (s == v).all() # type: ignore[attr-defined]