From c58b304170bb25c8db3e085e32ec06ff5bb2cbb0 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Thu, 8 Oct 2026 14:49:28 +0200 Subject: [PATCH] tst: test that kernel functions keep mutability Cover places where the mutability of an object travels with its tnum or its type: converting compressed vectors and matrices back to plain lists, CLONE_OBJ, turning a plain list into a positional object, setting the IsMutable filter again after MakeImmutable, and the HPC-GAP serializer. These are the places that need care when mutability moves out of the tnum (see #6025). Assisted-by: Claude Code (Opus 5.5) --- tst/testinstall/hpc/serialize.tst | 13 +++++++++++++ tst/testinstall/kernel/objects.tst | 24 +++++++++++++++++++++++- tst/testinstall/kernel/vec8bit.tst | 11 +++++++++++ tst/testinstall/kernel/vecgf2.tst | 11 +++++++++++ 4 files changed, 58 insertions(+), 1 deletion(-) diff --git a/tst/testinstall/hpc/serialize.tst b/tst/testinstall/hpc/serialize.tst index decc1745b1..38cc0055d1 100644 --- a/tst/testinstall/hpc/serialize.tst +++ b/tst/testinstall/hpc/serialize.tst @@ -137,6 +137,19 @@ gap> CheckSerialization(["abc", MakeImmutable("abc")]); gap> CheckSerialization([1,2,,3,,,4,"x","y"]); gap> CheckSerializationGeneric([~], x->IsIdenticalObj(x, x[1])); +# +# mutability +# +gap> Mutability := x -> [IsMutable(x), List(x, IsMutable), IsMutable(x[2].a), +> IsIdenticalObj(x[5], x[6])];; +gap> x := MakeImmutable([1]);; +gap> x := [[2], rec(a := [3]), "abc", [1..5], x, x, [true,false]];; +gap> CheckSerializationBy(x, Mutability); +gap> CheckSerializationBy(MakeImmutable(x), Mutability); +gap> CheckSerializationBy(MakeImmutable(rec(a := 1)), IsMutable); +gap> CheckSerializationBy(MakeImmutable([1..5]), IsMutable); +gap> CheckSerializationBy(MakeImmutable([true,false]), IsMutable); + # # object set # diff --git a/tst/testinstall/kernel/objects.tst b/tst/testinstall/kernel/objects.tst index 88dc4df441..198c0ac1ee 100644 --- a/tst/testinstall/kernel/objects.tst +++ b/tst/testinstall/kernel/objects.tst @@ -1,7 +1,7 @@ # # Tests for functions defined in src/objects.c # -#@local x, t1c, t2c, t1p, t2p +#@local x, y, t1c, t2c, t1p, t2p, tm gap> START_TEST("kernel/objects.tst"); # @@ -69,6 +69,21 @@ Error, PosObj Element: ![2] must have an assigned value gap> x![4]; Error, PosObj Element: ![4] must have an assigned value +# the type decides whether the resulting object is mutable +gap> tm := NewType(NewFamily("MockFamily"), IsPositionalObjectRep and IsMutable);; +gap> x := MakeImmutable([ 1 ]);; +gap> SET_TYPE_POSOBJ(x, tm);; +gap> IsMutable(x); +true +gap> x := MakeImmutable([ 1 ]);; +gap> SET_TYPE_POSOBJ(x, t2p);; +gap> IsMutable(x); +false +gap> x := Objectify(tm, [ 1 ]);; MakeImmutable(x);; IsMutable(x); +false +gap> SetFilterObj(x, IsMutable);; IsMutable(x); +true + # # CLONE_OBJ # @@ -92,5 +107,12 @@ gap> # TODO: overwriting an immutable object via CLONE_OBJ should probably gap> # not be allowed, but InstallValue relies on it... #@fi +# the clone has the mutability of the source +gap> x := [ 1 ];; y := MakeImmutable([ 2 ]);; +gap> CLONE_OBJ(x, y); +gap> x; IsMutable(x); +[ 2 ] +false + # gap> STOP_TEST("kernel/objects.tst"); diff --git a/tst/testinstall/kernel/vec8bit.tst b/tst/testinstall/kernel/vec8bit.tst index b9fe3df7e4..2e2e7a2d50 100644 --- a/tst/testinstall/kernel/vec8bit.tst +++ b/tst/testinstall/kernel/vec8bit.tst @@ -99,6 +99,11 @@ Error, COPY_VEC8BIT: must be a positive small integer (not the value 'fail\ gap> v := V8([]);; PLAIN_VEC8BIT(v);; IsPlistRep(v); Length(v); true 0 +gap> v := MakeImmutable(V8([o, z]));; v := v + v;; IsMutable(v); +false +gap> PLAIN_VEC8BIT(v);; IsPlistRep(v); IsMutable(v); +true +false # bad arguments gap> PLAIN_VEC8BIT(fail); @@ -595,6 +600,12 @@ Error, CONV_MAT8BIT: must be a plain list (not a positional object) # gap> m := Mx08(2);; PLAIN_MAT8BIT(m);; IsPlistRep(m) and m = [[], []]; true +gap> m := MakeImmutable(M8([[o, z], [z, o]]));; m := m * m;; IsMutable(m); +false +gap> PLAIN_MAT8BIT(m);; IsPlistRep(m); IsMutable(m); IsMutable(m[1]); +true +false +false # bad arguments gap> PLAIN_MAT8BIT(fail); diff --git a/tst/testinstall/kernel/vecgf2.tst b/tst/testinstall/kernel/vecgf2.tst index c3021d52cb..e03466ab07 100644 --- a/tst/testinstall/kernel/vecgf2.tst +++ b/tst/testinstall/kernel/vecgf2.tst @@ -74,6 +74,11 @@ Error, COPY_GF2VEC: argument must be a list of GF2 elements # gap> v := V2([]);; PLAIN_GF2VEC(v);; IsPlistRep(v) and Length(v) = 0; true +gap> v := MakeImmutable(V2([o, z]));; v := v + v;; IsMutable(v); +false +gap> PLAIN_GF2VEC(v);; IsPlistRep(v); IsMutable(v); +true +false # bad arguments gap> PLAIN_GF2VEC(fail); @@ -84,6 +89,12 @@ Error, PLAIN_GF2VEC: must be a GF2 vector (not the value 'fail') # gap> m := Mx02(2);; PLAIN_GF2MAT(m);; IsPlistRep(m) and m = [[], []]; true +gap> m := MakeImmutable(M2([[o, z], [z, o]]));; m := m * m;; IsMutable(m); +false +gap> PLAIN_GF2MAT(m);; IsPlistRep(m); IsMutable(m); IsMutable(m[1]); +true +false +false # bad arguments gap> PLAIN_GF2MAT(fail);