Repository: apytypes/apytypes (language: python)

Issue:
Floating-point formats specified with very large numbers give different exception
If the number of exponent bits or mantissa bits doesn't fit inside an uint8, the constructor will raise a different exception:

```Python
APyFloat(0, 0, 0, 100, 5)
# ValueError: Exponent bits can at most be 30 but 100 was given

APyFloat(0, 0, 0, 1000, 5)
# TypeError: __init__(): incompatible function arguments. The following argument types are supported:
#    1. __init__(self, sign: int, exp: int, man: int, exp_bits: int, man_bits: int, bias: Optional[int] = None) -> None
```
It would be better if the constructor instead threw a ValueError like in the first case. The same goes for `from_float`, `from_bits`, and `cast`. This is (probably) solved by changing the parameter definitions from `std::uint8_t` to `int`. 


Discussion / hints:

Fix patch:
diff --git a/src/apyfloat.cc b/src/apyfloat.cc
index 4f5bb9a5f..ba2ff67f9 100644
--- a/src/apyfloat.cc
+++ b/src/apyfloat.cc
@@ -27,8 +27,8 @@ void APyFloat::create_in_place(
     int sign,
     exp_t exp,
     man_t man,
-    std::uint8_t exp_bits,
-    std::uint8_t man_bits,
+    int exp_bits,
+    int man_bits,
     std::optional<exp_t> bias
 )
 {
@@ -112,10 +112,7 @@ APyFloat::APyFloat(
  */
 
 APyFloat APyFloat::from_double(
-    double value,
-    std::uint8_t exp_bits,
-    std::uint8_t man_bits,
-    std::optional<exp_t> bias
+    double value, int exp_bits, int man_bits, std::optional<exp_t> bias
 )
 {
     check_exponent_format(exp_bits);
@@ -130,8 +127,8 @@ APyFloat APyFloat::from_double(
 }
 
 APyFloat APyFloat::cast(
-    std::optional<uint8_t> new_exp_bits,
-    std::optional<uint8_t> new_man_bits,
+    std::optional<int> new_exp_bits,
+    std::optional<int> new_man_bits,
     std::optional<exp_t> new_bias,
     std::optional<QuantizationMode> quantization
 ) const
@@ -545,8 +542,8 @@ APyFloat::operator double() const { return to_double(); }
 
 APyFloat APyFloat::from_bits(
     nb::int_ python_long_int_bit_pattern,
-    std::uint8_t exp_bits,
-    std::uint8_t man_bits,
+    int exp_bits,
+    int man_bits,
     std::optional<exp_t> bias
 )
 {
diff --git a/src/apyfloat.h b/src/apyfloat.h
index c05693137..c0ea72c76 100644
--- a/src/apyfloat.h
+++ b/src/apyfloat.h
@@ -59,16 +59,16 @@ class APyFloat {
         int sign,
         exp_t exp,
         man_t man,
-        std::uint8_t exp_bits,
-        std::uint8_t man_bits,
+        int exp_bits,
+        int man_bits,
         std::optional<exp_t> bias = std::nullopt
     );
 
     //! Create APyFloat from double
     static APyFloat from_double(
         double value,
-        std::uint8_t exp_bits,
-        std::uint8_t man_bits,
+        int exp_bits,
+        int man_bits,
         std::optional<exp_t> bias = std::nullopt
     );
     double to_double() const;
@@ -77,8 +77,8 @@ class APyFloat {
     //! Create APyFloat from bit-representation
     static APyFloat from_bits(
         nanobind::int_ python_long_int_bit_pattern,
-        std::uint8_t exp_bits,
-        std::uint8_t man_bits,
+        int exp_bits,
+        int man_bits,
         std::optional<exp_t> bias = std::nullopt
     );
 
@@ -86,8 +86,8 @@ class APyFloat {
     nanobind::int_ to_bits() const;
 
     APyFloat cast(
-        std::optional<uint8_t> exp_bits,
-        std::optional<uint8_t> man_bits,
+        std::optional<int> exp_bits,
+        std::optional<int> man_bits,
         std::optional<exp_t> bias = std::nullopt,
         std::optional<QuantizationMode> quantization = std::nullopt
     ) const;
diff --git a/src/apyfloat_util.cc b/src/apyfloat_util.cc
index 980eec630..e89298726 100644
--- a/src/apyfloat_util.cc
+++ b/src/apyfloat_util.cc
@@ -75,25 +75,27 @@ QuantizationMode translate_quantization_mode(QuantizationMode quantization, bool
     }
 }
 
-void check_exponent_format(std::uint8_t exp_bits)
+void check_exponent_format(int exp_bits)
 {
-    if (exp_bits > _EXP_LIMIT_BITS) {
+    if ((exp_bits > _EXP_LIMIT_BITS) || (exp_bits < 0)) {
         throw nb::value_error(fmt::format(
-                                  "Exponent bits can at most be {} but {} was given",
+                                  "Exponent bits must be a non-negative integer less "
+                                  "or equal to {} but {} was given",
                                   _EXP_LIMIT_BITS,
-                                  (unsigned int)exp_bits
+                                  exp_bits
         )
                                   .c_str());
     }
 }
 
-void check_mantissa_format(std::uint8_t man_bits)
+void check_mantissa_format(int man_bits)
 {
-    if (man_bits > _MAN_LIMIT_BITS) {
+    if ((man_bits > _MAN_LIMIT_BITS) || (man_bits < 0)) {
         throw nb::value_error(fmt::format(
-                                  "Mantissa bits can at most be {} but {} was given",
+                                  "Mantissa bits must be a non-negative integer less "
+                                  "or equal to {} but {} was given",
                                   _MAN_LIMIT_BITS,
-                                  (unsigned int)man_bits
+                                  man_bits
         )
                                   .c_str());
     }
diff --git a/src/apyfloat_util.h b/src/apyfloat_util.h
index 06729ee13..62214d7e7 100644
--- a/src/apyfloat_util.h
+++ b/src/apyfloat_util.h
@@ -214,8 +214,8 @@ void quantize_apymantissa(
 QuantizationMode translate_quantization_mode(QuantizationMode quantization, bool sign);
 
 //! Check that the number of exponent bits is allowed, throw otherwise
-void check_exponent_format(std::uint8_t exp_bits);
+void check_exponent_format(int exp_bits);
 
 //! Check that the number of mantissa bits is allowed, throw otherwise
-void check_mantissa_format(std::uint8_t man_bits);
+void check_mantissa_format(int man_bits);
 #endif // _APYFLOAT_UTIL_H
diff --git a/src/apyfloatarray.cc b/src/apyfloatarray.cc
index bd4636bc8..e6eb46fe7 100644
--- a/src/apyfloatarray.cc
+++ b/src/apyfloatarray.cc
@@ -19,8 +19,8 @@ void APyFloatArray::create_in_place(
     const nanobind::sequence& sign_seq,
     const nanobind::sequence& exp_seq,
     const nanobind::sequence& man_seq,
-    std::uint8_t exp_bits,
-    std::uint8_t man_bits,
+    int exp_bits,
+    int man_bits,
     std::optional<exp_t> bias
 )
 {
@@ -1079,8 +1079,8 @@ bool APyFloatArray::is_identical(const APyFloatArray& other) const
 
 APyFloatArray APyFloatArray::from_double(
     const nb::sequence& double_seq,
-    std::uint8_t exp_bits,
-    std::uint8_t man_bits,
+    int exp_bits,
+    int man_bits,
     std::optional<exp_t> bias
 )
 {
@@ -1121,11 +1121,14 @@ APyFloatArray APyFloatArray::from_double(
 
 APyFloatArray APyFloatArray::from_array(
     const nb::ndarray<nb::c_contig>& ndarray,
-    std::uint8_t exp_bits,
-    std::uint8_t man_bits,
+    int exp_bits,
+    int man_bits,
     std::optional<exp_t> bias
 )
 {
+    check_exponent_format(exp_bits);
+    check_mantissa_format(man_bits);
+
     std::size_t ndim = ndarray.ndim();
     assert(ndim > 0);
     std::vector<std::size_t> shape(ndim, 0);
@@ -1212,8 +1215,8 @@ APyFloatArray APyFloatArray::transpose() const
 }
 
 APyFloatArray APyFloatArray::cast(
-    std::optional<uint8_t> new_exp_bits,
-    std::optional<uint8_t> new_man_bits,
+    std::optional<int> new_exp_bits,
+    std::optional<int> new_man_bits,
     std::optional<exp_t> new_bias,
     std::optional<QuantizationMode> quantization
 ) const
diff --git a/src/apyfloatarray.h b/src/apyfloatarray.h
index 430cb3d5c..2d0bb5137 100644
--- a/src/apyfloatarray.h
+++ b/src/apyfloatarray.h
@@ -97,8 +97,8 @@ class APyFloatArray {
         const nanobind::sequence& sign_seq,
         const nanobind::sequence& exp_seq,
         const nanobind::sequence& man_seq,
-        std::uint8_t exp_bits,
-        std::uint8_t man_bits,
+        int exp_bits,
+        int man_bits,
         std::optional<exp_t> bias = std::nullopt
     );
 
@@ -106,16 +106,16 @@ class APyFloatArray {
     //! of `doubles`
     static APyFloatArray from_double(
         const nanobind::sequence& double_seq,
-        std::uint8_t exp_bits,
-        std::uint8_t man_bits,
+        int exp_bits,
+        int man_bits,
         std::optional<exp_t> bias = std::nullopt
     );
 
     //! Create an `APyFloatArray` tensor object initialized with values from an ndarray
     static APyFloatArray from_array(
         const nanobind::ndarray<nanobind::c_contig>& ndarray,
-        std::uint8_t exp_bits,
-        std::uint8_t man_bits,
+        int exp_bits,
+        int man_bits,
         std::optional<exp_t> bias = std::nullopt
     );
 
@@ -127,8 +127,8 @@ class APyFloatArray {
 
     //! Returns a copy of the tensor with the elements resized.
     APyFloatArray cast(
-        std::optional<uint8_t> exp_bits,
-        std::optional<uint8_t> man_bits,
+        std::optional<int> exp_bits,
+        std::optional<int> man_bits,
         std::optional<exp_t> bias = std::nullopt,
         std::optional<QuantizationMode> quantization = std::nullopt
     ) const;
diff --git a/src/apytypes_common.cc b/src/apytypes_common.cc
index 7cd8631b0..93b0d3dee 100644
--- a/src/apytypes_common.cc
+++ b/src/apytypes_common.cc
@@ -3,6 +3,7 @@
 namespace nb = nanobind;
 
 #include "apyfloat.h"
+#include "apyfloat_util.h"
 #include "apytypes_common.h"
 #include "apytypes_util.h"
 #include <random>
@@ -170,8 +171,8 @@ std::optional<APyFloatAccumulatorOption> get_accumulator_mode_float()
 }
 
 APyFloatAccumulatorContext::APyFloatAccumulatorContext(
-    std::optional<std::uint8_t> exp_bits,
-    std::optional<std::uint8_t> man_bits,
+    std::optional<int> exp_bits,
+    std::optional<int> man_bits,
     std::optional<exp_t> bias,
     std::optional<QuantizationMode> quantization
 )
@@ -189,6 +190,9 @@ APyFloatAccumulatorContext::APyFloatAccumulatorContext(
         );
     }
 
+    check_exponent_format(exp_bits.value());
+    check_mantissa_format(man_bits.value());
+
     new_mode.exp_bits = exp_bits.value();
     new_mode.man_bits = man_bits.value();
     new_mode.bias = bias;
diff --git a/src/apytypes_common.h b/src/apytypes_common.h
index 02f45b434..a09c7c573 100644
--- a/src/apytypes_common.h
+++ b/src/apytypes_common.h
@@ -185,8 +185,8 @@ struct APyFloatAccumulatorOption {
 class APyFloatAccumulatorContext : public ContextManager {
 public:
     APyFloatAccumulatorContext(
-        std::optional<std::uint8_t> = std::nullopt,
-        std::optional<std::uint8_t> = std::nullopt,
+        std::optional<int> = std::nullopt,
+        std::optional<int> = std::nullopt,
         std::optional<exp_t> = std::nullopt,
         std::optional<QuantizationMode> quantization = std::nullopt
     );
diff --git a/src/apytypes_context_wrapper.cc b/src/apytypes_context_wrapper.cc
index 8ad8901d3..5fdd8ec9e 100644
--- a/src/apytypes_context_wrapper.cc
+++ b/src/apytypes_context_wrapper.cc
@@ -99,8 +99,8 @@ void bind_accumulator_context(nb::module_& m)
     )
         .def(
             nb::init<
-                std::optional<std::uint8_t>,
-                std::optional<std::uint8_t>,
+                std::optional<int>,
+                std::optional<int>,
                 std::optional<exp_t>,
                 std::optional<QuantizationMode>>(),
             // nb::kw_only() is added in NanoBind v2.0.0


Test patch:
diff --git a/lib/test/apyfloat/test_methods.py b/lib/test/apyfloat/test_methods.py
index cc8f3f51f..75905735f 100644
--- a/lib/test/apyfloat/test_methods.py
+++ b/lib/test/apyfloat/test_methods.py
@@ -6,53 +6,101 @@
 def test_scalar_constructor_raises():
     # Too many exponent bits
     with pytest.raises(
-        ValueError, match="Exponent bits can at most be .. but 100 was given"
+        ValueError,
+        match="Exponent bits must be a non-negative integer less or equal to .. but 300 was given",
     ):
-        APyFloat(0, 0, 0, 100, 5)
+        APyFloat(0, 0, 0, 300, 5)
+    with pytest.raises(
+        ValueError,
+        match="Exponent bits must be a non-negative integer less or equal to .. but -300 was given",
+    ):
+        APyFloat(0, 0, 0, -300, 5)
     # Too many mantissa bits
     with pytest.raises(
-        ValueError, match="Mantissa bits can at most be .. but 100 was given"
+        ValueError,
+        match="Mantissa bits must be a non-negative integer less or equal to .. but 300 was given",
+    ):
+        APyFloat(0, 0, 0, 5, 300)
+    with pytest.raises(
+        ValueError,
+        match="Mantissa bits must be a non-negative integer less or equal to .. but -300 was given",
     ):
-        APyFloat(0, 0, 0, 5, 100)
+        APyFloat(0, 0, 0, 5, -300)
 
 
 def test_scalar_from_float_raises():
     # Too many exponent bits
     with pytest.raises(
-        ValueError, match="Exponent bits can at most be .. but 100 was given"
+        ValueError,
+        match="Exponent bits must be a non-negative integer less or equal to .. but 300 was given",
     ):
-        APyFloat.from_float(0, 100, 5)
+        APyFloat.from_float(0, 300, 5)
+    with pytest.raises(
+        ValueError,
+        match="Exponent bits must be a non-negative integer less or equal to .. but -300 was given",
+    ):
+        APyFloat.from_float(0, -300, 5)
     # Too many mantissa bits
     with pytest.raises(
-        ValueError, match="Mantissa bits can at most be .. but 100 was given"
+        ValueError,
+        match="Mantissa bits must be a non-negative integer less or equal to .. but 300 was given",
+    ):
+        APyFloat.from_float(0, 5, 300)
+    with pytest.raises(
+        ValueError,
+        match="Mantissa bits must be a non-negative integer less or equal to .. but -300 was given",
     ):
-        APyFloat.from_float(0, 5, 100)
+        APyFloat.from_float(0, 5, -300)
 
 
 def test_scalar_from_bits_raises():
     # Too many exponent bits
     with pytest.raises(
-        ValueError, match="Exponent bits can at most be .. but 100 was given"
+        ValueError,
+        match="Exponent bits must be a non-negative integer less or equal to .. but 300 was given",
     ):
-        APyFloat.from_bits(0, 100, 5)
+        APyFloat.from_bits(0, 300, 5)
+    with pytest.raises(
+        ValueError,
+        match="Exponent bits must be a non-negative integer less or equal to .. but -300 was given",
+    ):
+        APyFloat.from_bits(0, -300, 5)
     # Too many mantissa bits
     with pytest.raises(
-        ValueError, match="Mantissa bits can at most be .. but 100 was given"
+        ValueError,
+        match="Mantissa bits must be a non-negative integer less or equal to .. but 300 was given",
+    ):
+        APyFloat.from_bits(0, 5, 300)
+    with pytest.raises(
+        ValueError,
+        match="Mantissa bits must be a non-negative integer less or equal to .. but -300 was given",
     ):
-        APyFloat.from_bits(0, 5, 100)
+        APyFloat.from_bits(0, 5, -300)
 
 
 def test_scalar_cast_raises():
     # Too many exponent bits
     with pytest.raises(
-        ValueError, match="Exponent bits can at most be .. but 100 was given"
+        ValueError,
+        match="Exponent bits must be a non-negative integer less or equal to .. but 300 was given",
     ):
-        APyFloat(0, 0, 0, 5, 5).cast(100, 5)
+        APyFloat(0, 0, 0, 5, 5).cast(300, 5)
+    with pytest.raises(
+        ValueError,
+        match="Exponent bits must be a non-negative integer less or equal to .. but -300 was given",
+    ):
+        APyFloat(0, 0, 0, 5, 5).cast(-300, 5)
     # Too many mantissa bits
     with pytest.raises(
-        ValueError, match="Mantissa bits can at most be .. but 100 was given"
+        ValueError,
+        match="Mantissa bits must be a non-negative integer less or equal to .. but 300 was given",
+    ):
+        APyFloat(0, 0, 0, 5, 5).cast(5, 300)
+    with pytest.raises(
+        ValueError,
+        match="Mantissa bits must be a non-negative integer less or equal to .. but -300 was given",
     ):
-        APyFloat(0, 0, 0, 5, 5).cast(5, 100)
+        APyFloat(0, 0, 0, 5, 5).cast(5, -300)
 
 
 @pytest.mark.float_special
diff --git a/lib/test/apyfloatarray/test_constructors.py b/lib/test/apyfloatarray/test_constructors.py
index 3b9c6df34..5ddad92c1 100644
--- a/lib/test/apyfloatarray/test_constructors.py
+++ b/lib/test/apyfloatarray/test_constructors.py
@@ -28,14 +28,26 @@ def test_constructor_raises():
     ):
         APyFloatArray([True], [4], [APyFloatArray], 10, 10)
     with pytest.raises(
-        ValueError, match="Exponent bits can at most be .. but 100 was given"
+        ValueError,
+        match="Exponent bits must be a non-negative integer less or equal to .. but 300 was given",
+    ):
+        APyFloatArray([0], [0], [0], 300, 5)
+    with pytest.raises(
+        ValueError,
+        match="Exponent bits must be a non-negative integer less or equal to .. but -300 was given",
     ):
-        APyFloatArray([0], [0], [0], 100, 5)
+        APyFloatArray([0], [0], [0], -300, 5)
     # Too many mantissa bits
     with pytest.raises(
-        ValueError, match="Mantissa bits can at most be .. but 100 was given"
+        ValueError,
+        match="Mantissa bits must be a non-negative integer less or equal to .. but 300 was given",
+    ):
+        APyFloatArray([0], [0], [0], 5, 300)
+    with pytest.raises(
+        ValueError,
+        match="Mantissa bits must be a non-negative integer less or equal to .. but -300 was given",
     ):
-        APyFloatArray([0], [0], [0], 5, 100)
+        APyFloatArray([0], [0], [0], 5, -300)
 
 
 @pytest.mark.float_array
diff --git a/lib/test/apyfloatarray/test_methods.py b/lib/test/apyfloatarray/test_methods.py
index 51b91d30c..df11c4003 100644
--- a/lib/test/apyfloatarray/test_methods.py
+++ b/lib/test/apyfloatarray/test_methods.py
@@ -1,4 +1,5 @@
 import pytest
+import numpy as np
 from apytypes import APyFloatArray, APyFloat, QuantizationMode
 
 
@@ -19,27 +20,76 @@ def test_is_identical():
 def test_array_from_float_raises():
     # Too many exponent bits
     with pytest.raises(
-        ValueError, match="Exponent bits can at most be .. but 100 was given"
+        ValueError,
+        match="Exponent bits must be a non-negative integer less or equal to .. but 300 was given",
     ):
-        APyFloatArray.from_float([0], 100, 5)
+        APyFloatArray.from_float([0], 300, 5)
+    with pytest.raises(
+        ValueError,
+        match="Exponent bits must be a non-negative integer less or equal to .. but -300 was given",
+    ):
+        APyFloatArray.from_float([0], -300, 5)
     # Too many mantissa bits
     with pytest.raises(
-        ValueError, match="Mantissa bits can at most be .. but 100 was given"
+        ValueError,
+        match="Mantissa bits must be a non-negative integer less or equal to .. but 300 was given",
     ):
-        APyFloatArray.from_float([0], 5, 100)
+        APyFloatArray.from_float([0], 5, 300)
+    with pytest.raises(
+        ValueError,
+        match="Mantissa bits must be a non-negative integer less or equal to .. but -300 was given",
+    ):
+        APyFloatArray.from_float([0], 5, -300)
 
 
 def test_array_cast_raises():
     # Too many exponent bits
     with pytest.raises(
-        ValueError, match="Exponent bits can at most be .. but 100 was given"
+        ValueError,
+        match="Exponent bits must be a non-negative integer less or equal to .. but 300 was given",
+    ):
+        APyFloatArray([0], [0], [0], 5, 5).cast(300, 5)
+    with pytest.raises(
+        ValueError,
+        match="Exponent bits must be a non-negative integer less or equal to .. but -300 was given",
+    ):
+        APyFloatArray([0], [0], [0], 5, 5).cast(-300, 5)
+    # Too many mantissa bits
+    with pytest.raises(
+        ValueError,
+        match="Mantissa bits must be a non-negative integer less or equal to .. but 300 was given",
+    ):
+        APyFloatArray([0], [0], [0], 5, 5).cast(5, 300)
+    with pytest.raises(
+        ValueError,
+        match="Mantissa bits must be a non-negative integer less or equal to .. but -300 was given",
+    ):
+        APyFloatArray([0], [0], [0], 5, 5).cast(5, -300)
+
+
+def test_array_from_array_raises():
+    # Too many exponent bits
+    with pytest.raises(
+        ValueError,
+        match="Exponent bits must be a non-negative integer less or equal to .. but 300 was given",
+    ):
+        APyFloatArray.from_array(np.array([[1, 2, 3, 4]]), 5, 5).cast(300, 5)
+    with pytest.raises(
+        ValueError,
+        match="Exponent bits must be a non-negative integer less or equal to .. but -300 was given",
     ):
-        APyFloatArray([0], [0], [0], 5, 5).cast(100, 5)
+        APyFloatArray.from_array(np.array([[1, 2, 3, 4]]), 5, 5).cast(-300, 5)
     # Too many mantissa bits
     with pytest.raises(
-        ValueError, match="Mantissa bits can at most be .. but 100 was given"
+        ValueError,
+        match="Mantissa bits must be a non-negative integer less or equal to .. but 300 was given",
+    ):
+        APyFloatArray.from_array(np.array([[1, 2, 3, 4]]), 5, 5).cast(5, 300)
+    with pytest.raises(
+        ValueError,
+        match="Mantissa bits must be a non-negative integer less or equal to .. but -300 was given",
     ):
-        APyFloatArray([0], [0], [0], 5, 5).cast(5, 100)
+        APyFloatArray.from_array(np.array([[1, 2, 3, 4]]), 5, 5).cast(5, -300)
 
 
 @pytest.mark.float_array
diff --git a/lib/test/test_contextmanagers.py b/lib/test/test_contextmanagers.py
index cad0aa046..672f38208 100644
--- a/lib/test/test_contextmanagers.py
+++ b/lib/test/test_contextmanagers.py
@@ -228,6 +228,28 @@ def test_raises(self):
         with APyFloatAccumulatorContext(exp_bits=5, man_bits=2):  # should not raise
             pass
 
+        with pytest.raises(
+            ValueError,
+            match="Exponent bits must be a non-negative integer less or equal to .. but 300 was given",
+        ):
+            APyFloatAccumulatorContext(exp_bits=300, man_bits=5)
+        with pytest.raises(
+            ValueError,
+            match="Exponent bits must be a non-negative integer less or equal to .. but -300 was given",
+        ):
+            APyFloatAccumulatorContext(exp_bits=-300, man_bits=5)
+        # Too many mantissa bits
+        with pytest.raises(
+            ValueError,
+            match="Mantissa bits must be a non-negative integer less or equal to .. but 300 was given",
+        ):
+            APyFloatAccumulatorContext(exp_bits=5, man_bits=300)
+        with pytest.raises(
+            ValueError,
+            match="Mantissa bits must be a non-negative integer less or equal to .. but -300 was given",
+        ):
+            APyFloatAccumulatorContext(exp_bits=5, man_bits=-300)
+
     def test_with_quantization_context(self):
         """Test that the APyFloatAccumulatorContext interacts correctly with the APyFloatQuanizationContext."""
         with APyFloatQuantizationContext(QuantizationMode.TO_POS):