summarylogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.SRCINFO6
-rw-r--r--PKGBUILD17
-rw-r--r--sagemath-gap-4.12.patch345
-rw-r--r--sagemath-ipywidgets-8.patch489
4 files changed, 852 insertions, 5 deletions
diff --git a/.SRCINFO b/.SRCINFO
index 3a1d38a799ef..633a5099907d 100644
--- a/.SRCINFO
+++ b/.SRCINFO
@@ -1,6 +1,6 @@
pkgbase = sagemath-git
pkgdesc = Open Source Mathematics Software, free alternative to Magma, Maple, Mathematica, and Matlab
- pkgver = 9.7.beta6.r0.g7f7149489cd
+ pkgver = 9.7.beta8.r0.g12be2d94c86
pkgrel = 1
url = http://www.sagemath.org
arch = x86_64
@@ -104,6 +104,8 @@ pkgbase = sagemath-git
source = sagemath-linbox-1.7.patch
source = sagemath-bliss-0.77.patch
source = sagemath-tachyon-0.99.patch
+ source = sagemath-gap-4.12.patch
+ source = sagemath-ipywidgets-8.patch
sha256sums = SKIP
sha256sums = eee5fa15d8c7be7e009166dbde3ea24bb10d7793dc12880516f278f86b1a6694
sha256sums = bd188af45ce31579b82407adee8e9bf6033a996f7ea6e328fabca526f31c08ba
@@ -111,5 +113,7 @@ pkgbase = sagemath-git
sha256sums = eacea27b214d32cb886a75695153dfc36b5bad2fd2517e8e4eee18e74220e9e3
sha256sums = 3e1f866944235b999d2d727ed1ced431bd67405b053701c21068607ec76f23c3
sha256sums = 9760db6c6ec40cc16ab8a0cbf3d019df7f6a69ff292e35622f282b7c888aac77
+ sha256sums = 84c1700e285ab1d94d16d0a602417a414447d8a23ac2e55a093285cc4bd2916d
+ sha256sums = bdf56f85b608da12074780271ae134b02a03278f7b53a183f6dd97d8d72073e0
pkgname = sagemath-git
diff --git a/PKGBUILD b/PKGBUILD
index 2ccc0bafb9ee..7101d423988f 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -6,7 +6,7 @@
# Contributor: Stefan Husmann <stefan-husmann at t-online dot de>
pkgname=sagemath-git
-pkgver=9.7.beta6.r0.g7f7149489cd
+pkgver=9.7.beta8.r0.g12be2d94c86
pkgrel=1
pkgdesc='Open Source Mathematics Software, free alternative to Magma, Maple, Mathematica, and Matlab'
arch=(x86_64)
@@ -58,14 +58,18 @@ source=(git://git.sagemath.org/sage.git#branch=develop
test-optional.patch
sagemath-linbox-1.7.patch
sagemath-bliss-0.77.patch
- sagemath-tachyon-0.99.patch)
+ sagemath-tachyon-0.99.patch
+ sagemath-gap-4.12.patch
+ sagemath-ipywidgets-8.patch)
sha256sums=('SKIP'
'eee5fa15d8c7be7e009166dbde3ea24bb10d7793dc12880516f278f86b1a6694'
'bd188af45ce31579b82407adee8e9bf6033a996f7ea6e328fabca526f31c08ba'
'9d042070df3dfd53a1248659677798da888f733548eda91a6d5169c7aa1907e1'
'eacea27b214d32cb886a75695153dfc36b5bad2fd2517e8e4eee18e74220e9e3'
'3e1f866944235b999d2d727ed1ced431bd67405b053701c21068607ec76f23c3'
- '9760db6c6ec40cc16ab8a0cbf3d019df7f6a69ff292e35622f282b7c888aac77')
+ '9760db6c6ec40cc16ab8a0cbf3d019df7f6a69ff292e35622f282b7c888aac77'
+ '84c1700e285ab1d94d16d0a602417a414447d8a23ac2e55a093285cc4bd2916d'
+ 'bdf56f85b608da12074780271ae134b02a03278f7b53a183f6dd97d8d72073e0')
pkgver() {
cd sage
@@ -82,7 +86,11 @@ prepare(){
patch -p1 -i ../sagemath-bliss-0.77.patch
# Fix tests with tachyon 0.99 https://trac.sagemath.org/ticket/23712
patch -p1 -i ../sagemath-tachyon-0.99.patch
-
+# Port to GAP 4.12 https://trac.sagemath.org/ticket/34391
+ patch -p1 -i ../sagemath-gap-4.12.patch
+# Fixes for ipywidgets 8 https://trac.sagemath.org/ticket/34460
+ patch -p1 -i ../sagemath-ipywidgets-8.patch
+
# Arch-specific patches
# assume all optional packages are installed
patch -p1 -i ../sagemath-optional-packages.patch
@@ -100,6 +108,7 @@ build() {
export SAGE_NUM_THREADS=10
export PYTHONPATH="$PWD"/../sage-setup
+ export CPPFLAGS+=" -DUSE_GASMAN=1"
python setup.py build
}
diff --git a/sagemath-gap-4.12.patch b/sagemath-gap-4.12.patch
new file mode 100644
index 000000000000..b199fef1d996
--- /dev/null
+++ b/sagemath-gap-4.12.patch
@@ -0,0 +1,345 @@
+diff --git a/src/doc/en/thematic_tutorials/lie/weyl_groups.rst b/src/doc/en/thematic_tutorials/lie/weyl_groups.rst
+index c917338e44..182e74aad2 100644
+--- a/src/doc/en/thematic_tutorials/lie/weyl_groups.rst
++++ b/src/doc/en/thematic_tutorials/lie/weyl_groups.rst
+@@ -139,12 +139,12 @@ string, which you can print::
+ X.1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ X.2 1 -1 1 1 -1 1 1 -1 -1 -1 1 1 1
+ X.3 2 . 2 -1 . 2 2 . . . -1 2 2
+- X.4 3 -1 -1 . 1 -1 3 -1 1 -1 . -1 3
+- X.5 3 -1 -1 . 1 3 -1 -1 -1 1 . -1 3
+- X.6 3 1 -1 . -1 -1 3 1 -1 1 . -1 3
+- X.7 3 1 -1 . -1 3 -1 1 1 -1 . -1 3
+- X.8 3 -1 3 . -1 -1 -1 -1 1 1 . -1 3
+- X.9 3 1 3 . 1 -1 -1 1 -1 -1 . -1 3
++ X.4 3 -1 -1 . 1 3 -1 -1 -1 1 . -1 3
++ X.5 3 1 -1 . -1 3 -1 1 1 -1 . -1 3
++ X.6 3 -1 3 . -1 -1 -1 -1 1 1 . -1 3
++ X.7 3 -1 -1 . 1 -1 3 -1 1 -1 . -1 3
++ X.8 3 1 3 . 1 -1 -1 1 -1 -1 . -1 3
++ X.9 3 1 -1 . -1 -1 3 1 -1 1 . -1 3
+ X.10 4 -2 . -1 . . . 2 . . 1 . -4
+ X.11 4 2 . -1 . . . -2 . . 1 . -4
+ X.12 6 . -2 . . -2 -2 . . . . 2 6
+diff --git a/src/sage/coding/codecan/autgroup_can_label.pyx b/src/sage/coding/codecan/autgroup_can_label.pyx
+index de5db985e0..c83b9264e4 100644
+--- a/src/sage/coding/codecan/autgroup_can_label.pyx
++++ b/src/sage/coding/codecan/autgroup_can_label.pyx
+@@ -76,7 +76,7 @@ columns do share the same coloring::
+ ((1,),
+ (2,),
+ (3, 5, 4),
+- (6, 19, 16, 9, 21, 10, 8, 15, 14, 11, 20, 13, 12, 7, 17, 18))
++ (6, 19, 16, 21, 9, 10, 15, 8, 20, 11, 14, 13, 7, 12, 18, 17))
+
+ We can also restrict the group action to linear isometries::
+
+diff --git a/src/sage/coding/linear_code.py b/src/sage/coding/linear_code.py
+index e8e32f82c9..9d45160f44 100644
+--- a/src/sage/coding/linear_code.py
++++ b/src/sage/coding/linear_code.py
+@@ -466,27 +466,27 @@ class AbstractLinearCode(AbstractLinearCodeNoMetric):
+ 0
+ sage: C = codes.HammingCode(GF(4, 'z'), 3)
+ sage: C.automorphism_group_gens()
+- ([((1, 1, 1, 1, 1, z + 1, z, z + 1, z, z, z, 1, 1, z + 1, z + 1, z, z + 1, z, z + 1, z + 1, z + 1); (1,14,6,7,4,10,11,19)(2,8,16,13,3,17,21,15)(9,12,18,20), Ring endomorphism of Finite Field in z of size 2^2
++ ([((1, 1, 1, z, z + 1, 1, 1, 1, 1, z + 1, z, z, z + 1, z + 1, z + 1, 1, z + 1, z, z, 1, z); (1,13,14,20)(2,21,8,18,7,16,19,15)(3,10,5,12,17,9,6,4), Ring endomorphism of Finite Field in z of size 2^2
++ Defn: z |--> z + 1),
++ ((z, 1, z, z, z, z + 1, z, z, z, z, z, z, z + 1, z, z, z, z, z + 1, z, z, z); (1,11,5,12,3,19)(2,8)(6,18,13)(7,17,15)(9,10,14,16,20,21), Ring endomorphism of Finite Field in z of size 2^2
+ Defn: z |--> z + 1),
+- ((z + 1, 1, 1, z, z + 1, z, z, z + 1, z + 1, z + 1, 1, z + 1, z, z, 1, z + 1, 1, z, z + 1, z + 1, z); (1,18,6,19,2,9,17,10,13,14,21,11,4,5,12)(3,20,7,16,8), Ring endomorphism of Finite Field in z of size 2^2
+- Defn: z |--> z),
+ ((z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z); (), Ring endomorphism of Finite Field in z of size 2^2
+ Defn: z |--> z)],
+ 362880)
+ sage: C.automorphism_group_gens(equivalence="linear")
+- ([((z + 1, 1, z + 1, z + 1, z + 1, z, 1, z, 1, 1, 1, 1, z + 1, z + 1, z + 1, z, z, 1, z, z, z); (1,15,2,8,16,18,3)(4,9,12,13,20,10,11)(5,21,14,6,7,19,17), Ring endomorphism of Finite Field in z of size 2^2
++ ([((z, 1, z + 1, z + 1, 1, z + 1, z, 1, z + 1, z + 1, 1, z, 1, z + 1, z, 1, z, 1, z + 1, 1, 1); (1,12,11,10,6,8,9,20,13,21,5,14,3,16,17,19,7,4,2,15,18), Ring endomorphism of Finite Field in z of size 2^2
+ Defn: z |--> z),
+- ((z + 1, z + 1, z + 1, z + 1, z + 1, 1, z, 1, z, z, z, 1, z, 1, 1, 1, z + 1, z + 1, z + 1, 1, z); (1,15,21,8,9)(2,18,5,3,11,16,7,10,19,13,12,4,17,6,20), Ring endomorphism of Finite Field in z of size 2^2
++ ((z + 1, z + 1, z + 1, z, 1, 1, z, z, 1, z + 1, z, 1, 1, z, 1, z + 1, z, z + 1, z + 1, 1, z); (1,3,18,2,17,6,19)(4,15,13,20,7,14,16)(5,11,8,21,12,9,10), Ring endomorphism of Finite Field in z of size 2^2
+ Defn: z |--> z),
+ ((z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1); (), Ring endomorphism of Finite Field in z of size 2^2
+ Defn: z |--> z)],
+ 181440)
+ sage: C.automorphism_group_gens(equivalence="permutational")
+- ([((1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); (1,19)(3,17)(4,21)(5,20)(7,14)(9,12)(10,16)(11,15), Ring endomorphism of Finite Field in z of size 2^2
++ ([((1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); (1,11)(3,10)(4,9)(5,7)(12,21)(14,20)(15,19)(16,17), Ring endomorphism of Finite Field in z of size 2^2
+ Defn: z |--> z),
+- ((1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); (1,11)(3,10)(4,9)(5,7)(12,21)(14,20)(15,19)(16,17), Ring endomorphism of Finite Field in z of size 2^2
++ ((1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); (2,18)(3,19)(4,10)(5,16)(8,13)(9,14)(11,21)(15,20), Ring endomorphism of Finite Field in z of size 2^2
+ Defn: z |--> z),
+- ((1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); (1,17)(2,8)(3,14)(4,10)(7,12)(9,19)(13,18)(15,20), Ring endomorphism of Finite Field in z of size 2^2
++ ((1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); (1,19)(3,17)(4,21)(5,20)(7,14)(9,12)(10,16)(11,15), Ring endomorphism of Finite Field in z of size 2^2
+ Defn: z |--> z),
+ ((1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); (2,13)(3,14)(4,20)(5,11)(8,18)(9,19)(10,15)(16,21), Ring endomorphism of Finite Field in z of size 2^2
+ Defn: z |--> z)],
+@@ -692,10 +692,10 @@ class AbstractLinearCode(AbstractLinearCodeNoMetric):
+ sage: C_iso == aut_group_can_label.get_canonical_form()
+ True
+ sage: aut_group_can_label.get_autom_gens()
+- [((1, 1, 1, 1, 1, z + 1, z, z + 1, z, z, z, 1, 1, z + 1, z + 1, z, z + 1, z, z + 1, z + 1, z + 1); (1,14,6,7,4,10,11,19)(2,8,16,13,3,17,21,15)(9,12,18,20), Ring endomorphism of Finite Field in z of size 2^2
++ [((1, 1, 1, z, z + 1, 1, 1, 1, 1, z + 1, z, z, z + 1, z + 1, z + 1, 1, z + 1, z, z, 1, z); (1,13,14,20)(2,21,8,18,7,16,19,15)(3,10,5,12,17,9,6,4), Ring endomorphism of Finite Field in z of size 2^2
++ Defn: z |--> z + 1),
++ ((z, 1, z, z, z, z + 1, z, z, z, z, z, z, z + 1, z, z, z, z, z + 1, z, z, z); (1,11,5,12,3,19)(2,8)(6,18,13)(7,17,15)(9,10,14,16,20,21), Ring endomorphism of Finite Field in z of size 2^2
+ Defn: z |--> z + 1),
+- ((z + 1, 1, 1, z, z + 1, z, z, z + 1, z + 1, z + 1, 1, z + 1, z, z, 1, z + 1, 1, z, z + 1, z + 1, z); (1,18,6,19,2,9,17,10,13,14,21,11,4,5,12)(3,20,7,16,8), Ring endomorphism of Finite Field in z of size 2^2
+- Defn: z |--> z),
+ ((z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z, z); (), Ring endomorphism of Finite Field in z of size 2^2
+ Defn: z |--> z)]
+ """
+diff --git a/src/sage/combinat/root_system/hecke_algebra_representation.py b/src/sage/combinat/root_system/hecke_algebra_representation.py
+index bde2823421..bffcc85f6e 100644
+--- a/src/sage/combinat/root_system/hecke_algebra_representation.py
++++ b/src/sage/combinat/root_system/hecke_algebra_representation.py
+@@ -355,7 +355,7 @@ class HeckeAlgebraRepresentation(WithEqualityById, SageObject):
+ sage: q1, q2 = K.gens()
+ sage: KW = W.algebra(K)
+ sage: x = KW.an_element(); x
+- 123 + 3*32 + 2*3 + e
++ 123 + 3*2312 + 2*31 + e
+
+ sage: T = KW.demazure_lusztig_operators(q1,q2)
+ sage: T12 = T.Tw( (1,2) )
+diff --git a/src/sage/combinat/symmetric_group_algebra.py b/src/sage/combinat/symmetric_group_algebra.py
+index c3d67555a6..da953d2b01 100644
+--- a/src/sage/combinat/symmetric_group_algebra.py
++++ b/src/sage/combinat/symmetric_group_algebra.py
+@@ -101,7 +101,7 @@ def SymmetricGroupAlgebra(R, W, category=None):
+ sage: SGA.group()
+ Weyl Group of type ['A', 3] (as a matrix group acting on the ambient space)
+ sage: SGA.an_element()
+- s1*s2*s3 + 3*s3*s2 + 2*s3 + 1
++ s1*s2*s3 + 3*s2*s3*s1*s2 + 2*s3*s1 + 1
+
+ The preferred way to construct the symmetric group algebra is to
+ go through the usual ``algebra`` method::
+diff --git a/src/sage/groups/abelian_gps/abelian_group_gap.py b/src/sage/groups/abelian_gps/abelian_group_gap.py
+index a4b047113c..86090b4353 100644
+--- a/src/sage/groups/abelian_gps/abelian_group_gap.py
++++ b/src/sage/groups/abelian_gps/abelian_group_gap.py
+@@ -338,7 +338,7 @@ class AbelianGroup_gap(UniqueRepresentation, GroupMixinLibGAP, ParentLibGAP, Abe
+ if isinstance(x, AbelianGroupElement_gap):
+ try:
+ if x in self._cover:
+- x = self.gap().NaturalHomomorphism().Image(x.gap())
++ x = self._cover.gap().NaturalHomomorphismByNormalSubgroup(self._relations).Image(x.gap())
+ else:
+ x = x.gap()
+ except AttributeError:
+@@ -1043,7 +1043,7 @@ class AbelianGroupQuotient_gap(AbelianGroup_gap):
+ From: Abelian group with gap, generator orders (4,)
+ To: Quotient abelian group with generator orders (2,)
+ """
+- phi = self.gap().NaturalHomomorphism()
++ phi = self._cover.gap().NaturalHomomorphismByNormalSubgroup(self._relations)
+ Hom = self._cover.Hom(self)
+ return Hom(phi)
+
+diff --git a/src/sage/groups/finitely_presented.py b/src/sage/groups/finitely_presented.py
+index 2a61bbf91d..d26891a05f 100644
+--- a/src/sage/groups/finitely_presented.py
++++ b/src/sage/groups/finitely_presented.py
+@@ -596,9 +596,9 @@ class RewritingSystem():
+ sage: k = G.rewriting_system()
+ sage: k.gap()
+ Knuth Bendix Rewriting System for Monoid( [ a, A, b, B ] ) with rules
+- [ [ a^2, <identity ...> ], [ a*A, <identity ...> ],
+- [ A*a, <identity ...> ], [ b^2, <identity ...> ],
+- [ b*B, <identity ...> ], [ B*b, <identity ...> ] ]
++ [ [ a*A, <identity ...> ], [ A*a, <identity ...> ],
++ [ b*B, <identity ...> ], [ B*b, <identity ...> ],
++ [ a^2, <identity ...> ], [ b^2, <identity ...> ] ]
+ """
+ return self._gap
+
+diff --git a/src/sage/groups/fqf_orthogonal.py b/src/sage/groups/fqf_orthogonal.py
+index 75de408912..dd7d84d960 100644
+--- a/src/sage/groups/fqf_orthogonal.py
++++ b/src/sage/groups/fqf_orthogonal.py
+@@ -143,7 +143,7 @@ class FqfOrthogonalGroup(AbelianGroupAutomorphismGroup_subgroup):
+ [2/3 0 0]
+ [ 0 2/3 0]
+ [ 0 0 4/3]
+- generated by 2 elements
++ generated by 3 elements
+ sage: q = matrix.diagonal(QQ, [3/2, 1/4, 1/4])
+ sage: T = TorsionQuadraticForm(q)
+ sage: T.orthogonal_group().order()
+diff --git a/src/sage/groups/libgap_wrapper.pyx b/src/sage/groups/libgap_wrapper.pyx
+index a76afc2ac9..9340c0d6c6 100644
+--- a/src/sage/groups/libgap_wrapper.pyx
++++ b/src/sage/groups/libgap_wrapper.pyx
+@@ -25,7 +25,7 @@ Note how we call the constructor of both superclasses to initialize
+ its output via LibGAP::
+
+ sage: FooGroup()
+- <pc group of size 3 with 1 generators>
++ <pc group of size 3 with 1 generator>
+ sage: type(FooGroup().gap())
+ <class 'sage.libs.gap.element.GapElement'>
+
+@@ -106,7 +106,7 @@ class ParentLibGAP(SageObject):
+ ....: ParentLibGAP.__init__(self, lg)
+ ....: Group.__init__(self)
+ sage: FooGroup()
+- <pc group of size 3 with 1 generators>
++ <pc group of size 3 with 1 generator>
+ """
+
+ def __init__(self, libgap_parent, ambient=None):
+@@ -461,7 +461,7 @@ cdef class ElementLibGAP(MultiplicativeGroupElement):
+ ....: ParentLibGAP.__init__(self, lg)
+ ....: Group.__init__(self)
+ sage: FooGroup()
+- <pc group of size 3 with 1 generators>
++ <pc group of size 3 with 1 generator>
+ sage: FooGroup().gens()
+ (f1,)
+ """
+diff --git a/src/sage/groups/perm_gps/partn_ref2/refinement_generic.pyx b/src/sage/groups/perm_gps/partn_ref2/refinement_generic.pyx
+index 2fcb0363a8..ca73c6b1ab 100644
+--- a/src/sage/groups/perm_gps/partn_ref2/refinement_generic.pyx
++++ b/src/sage/groups/perm_gps/partn_ref2/refinement_generic.pyx
+@@ -427,7 +427,7 @@ cdef class LabelledBranching:
+ sage: from sage.groups.perm_gps.partn_ref2.refinement_generic import LabelledBranching
+ sage: L = LabelledBranching(3)
+ sage: L.small_generating_set()
+- []
++ [()]
+ sage: L.add_gen(libgap.eval('(1,2,3)'))
+ sage: L.small_generating_set()
+ [(1,2,3)]
+diff --git a/src/sage/groups/perm_gps/permgroup.py b/src/sage/groups/perm_gps/permgroup.py
+index 4908934699..34ba0ccfd4 100644
+--- a/src/sage/groups/perm_gps/permgroup.py
++++ b/src/sage/groups/perm_gps/permgroup.py
+@@ -913,7 +913,7 @@ class PermutationGroup_generic(FiniteGroup):
+ sage: f = PG._coerce_map_from_(MG)
+ sage: mg = MG.an_element()
+ sage: p = f(mg); p
+- (2,33,32,23,31,55)(3,49,38,44,40,28)(4,17,59,62,58,46)(5,21,47,20,43,8)(6,53,50)(7,37,12,57,14,29)(9,41,56,34,64,10)(11,25,19)(13,61,26,51,22,15)(16,45,36)(18,27,35,48,52,54)(24,63,42)(30,39,60)
++ (1,2,6,19,35,33)(3,9,26,14,31,23)(4,13,5)(7,22,17)(8,24,12)(10,16,32,27,20,28)(11,30,18)(15,25,36,34,29,21)
+ sage: PG(p._gap_()) == p
+ True
+
+@@ -959,12 +959,12 @@ class PermutationGroup_generic(FiniteGroup):
+ sage: P = G.as_permutation_group(algorithm='smaller', seed=5)
+ sage: P1 = G.as_permutation_group()
+ sage: P == P1
+- False
++ True
+ sage: g1, g2, g3 = G.gens()
+ sage: P(g1*g2)
+- (1,3,7,12)(2,4,8,10)(5,11)(6,9)
++ (1,4,13,11)(2,5,14,18)(3,15,8,16)(6,7)(9,20,19,12)(10,17)
+ sage: P1(g1*g2)
+- (2,29,25,68)(3,57,13,54)(4,11,72,37)(5,39,60,23)(6,64,75,63)(7,21,50,73)(8,46,38,32)(9,74,35,18)(10,44,49,48)(12,16,34,71)(14,79,27,40)(15,26)(17,62,59,76)(19,78,70,65)(20,22,58,51)(24,33,36,43)(28,81,80,52)(30,53,56,69)(31,61)(41,42,67,55)(45,77)(47,66)
++ (1,4,13,11)(2,5,14,18)(3,15,8,16)(6,7)(9,20,19,12)(10,17)
+
+ Another check for :trac:`5583`::
+
+diff --git a/src/sage/interfaces/gap.py b/src/sage/interfaces/gap.py
+index c34fe530c3..569caa27bf 100644
+--- a/src/sage/interfaces/gap.py
++++ b/src/sage/interfaces/gap.py
+@@ -1512,6 +1512,8 @@ def gap_reset_workspace(max_workspace_size=None, verbose=False):
+ """
+ # Create new workspace with filename WORKSPACE
+ g = Gap(use_workspace_cache=False, max_workspace_size=None)
++ g.eval('ColorPrompt(false)')
++ g.eval('SetUserPreference("UseColorPrompt", false)')
+ g.eval('SetUserPreference("HistoryMaxLines", 30)')
+ from sage.tests.gap_packages import all_installed_packages
+ for pkg in all_installed_packages(gap=g):
+diff --git a/src/sage/libs/gap/element.pyx b/src/sage/libs/gap/element.pyx
+index be43c4c3ee..e2681165a2 100644
+--- a/src/sage/libs/gap/element.pyx
++++ b/src/sage/libs/gap/element.pyx
+@@ -130,6 +130,7 @@ cdef char *capture_stdout(Obj func, Obj obj):
+ """
+ cdef Obj s, stream, output_text_string
+ cdef UInt res
++ cdef TypOutputFile output
+ # The only way to get a string representation of an object that is truly
+ # consistent with how it would be represented at the GAP REPL is to call
+ # ViewObj on it. Unfortunately, ViewObj *prints* to the output stream,
+@@ -145,12 +146,12 @@ cdef char *capture_stdout(Obj func, Obj obj):
+ output_text_string = GAP_ValueGlobalVariable("OutputTextString")
+ stream = CALL_2ARGS(output_text_string, s, GAP_True)
+
+- if not OpenOutputStream(stream):
++ if not OpenOutputStream(&output, stream):
+ raise GAPError("failed to open output capture stream for "
+ "representing GAP object")
+
+ CALL_1ARGS(func, obj)
+- CloseOutput()
++ CloseOutput(&output)
+ return CSTR_STRING(s)
+ finally:
+ GAP_Leave()
+diff --git a/src/sage/libs/gap/gap_includes.pxd b/src/sage/libs/gap/gap_includes.pxd
+index 5a9ab486f7..34035fe4e6 100644
+--- a/src/sage/libs/gap/gap_includes.pxd
++++ b/src/sage/libs/gap/gap_includes.pxd
+@@ -76,8 +76,10 @@ cdef extern from "gap/intobj.h" nogil:
+
+
+ cdef extern from "gap/io.h" nogil:
+- UInt OpenOutputStream(Obj stream)
+- UInt CloseOutput()
++ ctypedef struct TypOutputFile:
++ pass
++ UInt OpenOutputStream(TypOutputFile* output, Obj stream)
++ UInt CloseOutput(TypOutputFile* output)
+
+
+ cdef extern from "gap/libgap-api.h" nogil:
+diff --git a/src/sage/libs/gap/libgap.pyx b/src/sage/libs/gap/libgap.pyx
+index b1a64e5793..6a36613aa8 100644
+--- a/src/sage/libs/gap/libgap.pyx
++++ b/src/sage/libs/gap/libgap.pyx
+@@ -695,7 +695,7 @@ class Gap(Parent):
+ sage: libgap.List
+ <Gap function "List">
+ sage: libgap.GlobalRandomSource
+- <RandomSource in IsGlobalRandomSource>
++ <RandomSource in IsGAPRandomSource>
+ """
+ if name in dir(self.__class__):
+ return getattr(self.__class__, name)
+diff --git a/src/sage/libs/gap/util.pyx b/src/sage/libs/gap/util.pyx
+index 344ab88c42..635098767d 100644
+--- a/src/sage/libs/gap/util.pyx
++++ b/src/sage/libs/gap/util.pyx
+@@ -362,15 +362,9 @@ cdef Obj gap_eval(str gap_string) except? NULL:
+ GAPError: Error, Variable: 'Complex' must have a value
+ Syntax error: ; expected in stream:1
+ Complex Field with 53 bits of precision;;
+- ^^^^^^^^^^^^
++ ^^^^^
+ Error, Variable: 'with' must have a value
+- Syntax error: ; expected in stream:1
+- Complex Field with 53 bits of precision;;
+- ^^^^^^^^^^^^^^^^^^^^
+ Error, Variable: 'bits' must have a value
+- Syntax error: ; expected in stream:1
+- Complex Field with 53 bits of precision;;
+- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ Error, Variable: 'precision' must have a value
+
+ Test that on a subsequent attempt we get the same message (no garbage was
+diff --git a/src/sage/tests/gap_packages.py b/src/sage/tests/gap_packages.py
+index 2e4518ca22..c302b169b8 100644
+--- a/src/sage/tests/gap_packages.py
++++ b/src/sage/tests/gap_packages.py
+@@ -103,7 +103,7 @@ def all_installed_packages(ignore_dot_gap=False, gap=None):
+
+ sage: from sage.tests.gap_packages import all_installed_packages
+ sage: all_installed_packages()
+- (...'GAPDoc'...)
++ (...'gapdoc'...)
+ sage: all_installed_packages(ignore_dot_gap=True) == all_installed_packages(gap=gap, ignore_dot_gap=True)
+ True
+ """
diff --git a/sagemath-ipywidgets-8.patch b/sagemath-ipywidgets-8.patch
new file mode 100644
index 000000000000..95357aff89dd
--- /dev/null
+++ b/sagemath-ipywidgets-8.patch
@@ -0,0 +1,489 @@
+diff --git a/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py b/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py
+index e65d605..d7c4d84 100644
+--- a/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py
++++ b/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py
+@@ -1062,7 +1062,7 @@ class ClusterSeed(SageObject):
+
+ sage: S = ClusterSeed(['A',4])
+ sage: S.interact()
+- VBox(children=...
++ ...VBox(children=...
+ """
+ return cluster_interact(self, fig_size, circular, kind='seed')
+
+diff --git a/src/sage/combinat/cluster_algebra_quiver/interact.py b/src/sage/combinat/cluster_algebra_quiver/interact.py
+index 4e54c64..1c88e61 100644
+--- a/src/sage/combinat/cluster_algebra_quiver/interact.py
++++ b/src/sage/combinat/cluster_algebra_quiver/interact.py
+@@ -27,7 +27,7 @@ def cluster_interact(self, fig_size=1, circular=True, kind='seed'):
+
+ sage: S = ClusterSeed(['A',4])
+ sage: S.interact() # indirect doctest
+- VBox(children=...
++ ...VBox(children=...
+ """
+ if kind not in ['seed', 'quiver']:
+ raise ValueError('kind must be "seed" or "quiver"')
+@@ -107,7 +107,7 @@ def cluster_interact(self, fig_size=1, circular=True, kind='seed'):
+ show_lastmutation.observe(refresh, 'value')
+ which_plot.observe(refresh, 'value')
+
+- mut_buttons.on_displayed(refresh)
++ mut_buttons.on_widget_constructed(refresh)
+
+ if kind == 'seed':
+ top = widgets.HBox([show_seq, show_vars])
+diff --git a/src/sage/combinat/cluster_algebra_quiver/quiver.py b/src/sage/combinat/cluster_algebra_quiver/quiver.py
+index 4f6e16b..14a176c 100644
+--- a/src/sage/combinat/cluster_algebra_quiver/quiver.py
++++ b/src/sage/combinat/cluster_algebra_quiver/quiver.py
+@@ -699,7 +699,7 @@ class ClusterQuiver(SageObject):
+
+ sage: S = ClusterQuiver(['A',4])
+ sage: S.interact()
+- VBox(children=...
++ ...VBox(children=...
+ """
+ return cluster_interact(self, fig_size, circular, kind="quiver")
+
+diff --git a/src/sage/dynamics/complex_dynamics/mandel_julia.py b/src/sage/dynamics/complex_dynamics/mandel_julia.py
+index 224a484..ce67274 100644
+--- a/src/sage/dynamics/complex_dynamics/mandel_julia.py
++++ b/src/sage/dynamics/complex_dynamics/mandel_julia.py
+@@ -130,7 +130,7 @@ def mandelbrot_plot(f=None, **kwds):
+ ``interact`` to ``True``. (This is only implemented for ``z^2 + c``)::
+
+ sage: mandelbrot_plot(interact=True)
+- interactive(children=(FloatSlider(value=0.0, description='Real center', max=1.0, min=-1.0, step=1e-05),
++ ...interactive(children=(FloatSlider(value=0.0, description='Real center', max=1.0, min=-1.0, step=1e-05),
+ FloatSlider(value=0.0, description='Imag center', max=1.0, min=-1.0, step=1e-05),
+ FloatSlider(value=4.0, description='Width', max=4.0, min=1e-05, step=1e-05),
+ IntSlider(value=500, description='Iterations', max=1000),
+@@ -144,7 +144,7 @@ def mandelbrot_plot(f=None, **kwds):
+
+ sage: mandelbrot_plot(interact=True, x_center=-0.75, y_center=0.25,
+ ....: image_width=1/2, number_of_colors=75)
+- interactive(children=(FloatSlider(value=-0.75, description='Real center', max=1.0, min=-1.0, step=1e-05),
++ ...interactive(children=(FloatSlider(value=-0.75, description='Real center', max=1.0, min=-1.0, step=1e-05),
+ FloatSlider(value=0.25, description='Imag center', max=1.0, min=-1.0, step=1e-05),
+ FloatSlider(value=0.5, description='Width', max=4.0, min=1e-05, step=1e-05),
+ IntSlider(value=500, description='Iterations', max=1000),
+@@ -600,14 +600,14 @@ def julia_plot(f=None, **kwds):
+ the form ``f = z^2 + c``)::
+
+ sage: julia_plot(interact=True)
+- interactive(children=(FloatSlider(value=-1.0, description='Real c'...
++ ...interactive(children=(FloatSlider(value=-1.0, description='Real c'...
+
+ ::
+
+ sage: R.<z> = CC[]
+ sage: f = z^2 + 1/2
+ sage: julia_plot(f,interact=True)
+- interactive(children=(FloatSlider(value=0.5, description='Real c'...
++ ...interactive(children=(FloatSlider(value=0.5, description='Real c'...
+
+ To return the Julia set of a random `c` value with (formal) cycle structure
+ `(2,3)`, set ``period = [2,3]``::
+diff --git a/src/sage/interacts/library.py b/src/sage/interacts/library.py
+index 8166014..6a982db 100644
+--- a/src/sage/interacts/library.py
++++ b/src/sage/interacts/library.py
+@@ -12,7 +12,7 @@ interactive mathlet. In the command line, it will simply return the underlying
+ HTML and Sage code which creates the mathlet::
+
+ sage: interacts.calculus.taylor_polynomial()
+- Interactive function <function taylor_polynomial at ...> with 3 widgets
++ ...Interactive function <function taylor_polynomial at ...> with 3 widgets
+ title: HTMLText(value='<h2>Taylor polynomial</h2>')
+ f: EvalText(value='e^(-x)*sin(x)', description='$f(x)=$', layout=Layout(max_width='81em'))
+ order: SelectionSlider(description='order', options=(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12), value=1)
+@@ -101,7 +101,7 @@ def library_interact(
+ ....: def f(n):
+ ....: print(n)
+ sage: f() # an interact appears if using the notebook, else code
+- Interactive function <function f at ...> with 1 widget
++ ...Interactive function <function f at ...> with 1 widget
+ n: TransformIntSlider(value=5, description='n', max=15, min=-5)
+
+ TESTS:
+@@ -117,7 +117,7 @@ def library_interact(
+ DeprecationWarning: Use decorator factory @library_interact(widgets) instead of @library_interact without any arguments.
+ See https://trac.sagemath.org/33382 for details.
+ sage: f() # an interact appears if using the notebook, else code
+- Interactive function <function f at ...> with 1 widget
++ ...Interactive function <function f at ...> with 1 widget
+ n: TransformIntSlider(value=5, description='n', max=15, min=-5)
+
+ .. NOTE::
+@@ -183,7 +183,7 @@ def demo(n: int, m: int):
+ creates the mathlet::
+
+ sage: interacts.demo()
+- Interactive function <function demo at ...> with 2 widgets
++ ...Interactive function <function demo at ...> with 2 widgets
+ n: SelectionSlider(description='n', options=(0, 1, 2, 3, 4, 5, 6, 7, 8, 9), value=0)
+ m: SelectionSlider(description='m', options=(0, 1, 2, 3, 4, 5, 6, 7, 8, 9), value=0)
+ """
+@@ -213,7 +213,7 @@ def taylor_polynomial(title, f, order: int):
+ creates the mathlet::
+
+ sage: interacts.calculus.taylor_polynomial()
+- Interactive function <function taylor_polynomial at ...> with 3 widgets
++ ...Interactive function <function taylor_polynomial at ...> with 3 widgets
+ title: HTMLText(value='<h2>Taylor polynomial</h2>')
+ f: EvalText(value='e^(-x)*sin(x)', description='$f(x)=$', layout=Layout(max_width='81em'))
+ order: SelectionSlider(description='order', options=(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12), value=1)
+@@ -259,7 +259,7 @@ def definite_integral(title, f, g, interval, x_range, selection):
+ creates the mathlet::
+
+ sage: interacts.calculus.definite_integral()
+- Interactive function <function definite_integral at ...> with 6 widgets
++ ...Interactive function <function definite_integral at ...> with 6 widgets
+ title: HTMLText(value='<h2>Definite integral</h2>')
+ f: EvalText(value='3*x', description='$f(x)=$', layout=Layout(max_width='81em'))
+ g: EvalText(value='x^2', description='$g(x)=$', layout=Layout(max_width='81em'))
+@@ -345,7 +345,7 @@ def function_derivative(title, function, x_range, y_range):
+ creates the mathlet::
+
+ sage: interacts.calculus.function_derivative()
+- Interactive function <function function_derivative at ...> with 4 widgets
++ ...Interactive function <function function_derivative at ...> with 4 widgets
+ title: HTMLText(value='<h2>Derivative grapher</h2>')
+ function: EvalText(value='x^5-3*x^3+1', description='Function:', layout=Layout(max_width='81em'))
+ x_range: FloatRangeSlider(value=(-2.0, 2.0), description='Range (x)', max=15.0, min=-15.0)
+@@ -393,7 +393,7 @@ def difference_quotient(title, f, interval, a, x0):
+ creates the mathlet::
+
+ sage: interacts.calculus.difference_quotient()
+- Interactive function <function difference_quotient at ...> with 5 widgets
++ ...Interactive function <function difference_quotient at ...> with 5 widgets
+ title: HTMLText(value='<h2>Difference quotient</h2>')
+ f: EvalText(value='sin(x)', description='f(x)', layout=Layout(max_width='81em'))
+ interval: FloatRangeSlider(value=(0.0, 10.0), description='Range', max=10.0)
+@@ -458,7 +458,7 @@ def quadratic_equation(A, B, C):
+ creates the mathlet::
+
+ sage: interacts.calculus.quadratic_equation()
+- Interactive function <function quadratic_equation at ...> with 3 widgets
++ ...Interactive function <function quadratic_equation at ...> with 3 widgets
+ A: IntSlider(value=1, description='A', max=7, min=-7)
+ B: IntSlider(value=1, description='B', max=7, min=-7)
+ C: IntSlider(value=-2, description='C', max=7, min=-7)
+@@ -520,7 +520,7 @@ def trigonometric_properties_triangle(a0, a1, a2):
+ creates the mathlet::
+
+ sage: interacts.geometry.trigonometric_properties_triangle()
+- Interactive function <function trigonometric_properties_triangle at ...> with 3 widgets
++ ...Interactive function <function trigonometric_properties_triangle at ...> with 3 widgets
+ a0: IntSlider(value=30, description='A', max=360)
+ a1: IntSlider(value=180, description='B', max=360)
+ a2: IntSlider(value=300, description='C', max=360)
+@@ -601,7 +601,7 @@ def unit_circle(function, x):
+ creates the mathlet::
+
+ sage: interacts.geometry.unit_circle()
+- Interactive function <function unit_circle at ...> with 2 widgets
++ ...Interactive function <function unit_circle at ...> with 2 widgets
+ function: Dropdown(description='function', options=(('sin(x)', 0), ('cos(x)', 1), ('tan(x)', 2)), value=0)
+ x: TransformFloatSlider(value=0.0, description='x', max=6.283185307179586, step=0.015707963267948967)
+ """
+@@ -702,7 +702,7 @@ def special_points(
+ creates the mathlet::
+
+ sage: interacts.geometry.special_points()
+- Interactive function <function special_points at ...> with 10 widgets
++ ...Interactive function <function special_points at ...> with 10 widgets
+ title: HTMLText(value='<h2>Special points in triangle</h2>')
+ a0: IntSlider(value=30, description='A', max=360)
+ a1: IntSlider(value=180, description='B', max=360)
+@@ -875,7 +875,7 @@ def coin(n, interval):
+ creates the mathlet::
+
+ sage: interacts.statistics.coin()
+- Interactive function <function coin at ...> with 2 widgets
++ ...Interactive function <function coin at ...> with 2 widgets
+ n: IntSlider(value=1000, description='Number of Tosses', max=10000, min=2, step=100)
+ interval: IntRangeSlider(value=(0, 0), description='Plotting range (y)', max=1)
+ """
+@@ -915,7 +915,7 @@ def bisection_method(title, f, interval, d, maxn):
+ creates the mathlet::
+
+ sage: interacts.calculus.secant_method()
+- Interactive function <function secant_method at ...> with 5 widgets
++ ...Interactive function <function secant_method at ...> with 5 widgets
+ title: HTMLText(value='<h2>Secant method for numerical root finding</h2>')
+ f: EvalText(value='x^2-2', description='f(x)', layout=Layout(max_width='81em'))
+ interval: IntRangeSlider(value=(0, 4), description='range', max=5, min=-5)
+@@ -995,7 +995,7 @@ def secant_method(title, f, interval, d, maxn):
+ creates the mathlet::
+
+ sage: interacts.calculus.secant_method()
+- Interactive function <function secant_method at ...> with 5 widgets
++ ...Interactive function <function secant_method at ...> with 5 widgets
+ title: HTMLText(value='<h2>Secant method for numerical root finding</h2>')
+ f: EvalText(value='x^2-2', description='f(x)', layout=Layout(max_width='81em'))
+ interval: IntRangeSlider(value=(0, 4), description='range', max=5, min=-5)
+@@ -1068,7 +1068,7 @@ def newton_method(title, f, c, d, maxn, interval, list_steps):
+ creates the mathlet::
+
+ sage: interacts.calculus.newton_method()
+- Interactive function <function newton_method at ...> with 7 widgets
++ ...Interactive function <function newton_method at ...> with 7 widgets
+ title: HTMLText(value='<h2>Newton method</h2>')
+ f: EvalText(value='x^2 - 2', description='f', layout=Layout(max_width='81em'))
+ c: IntSlider(value=6, description='Start ($x$)', max=10, min=-10)
+@@ -1152,7 +1152,7 @@ def trapezoid_integration(
+ creates the mathlet::
+
+ sage: interacts.calculus.trapezoid_integration()
+- Interactive function <function trapezoid_integration at ...> with 7 widgets
++ ...Interactive function <function trapezoid_integration at ...> with 7 widgets
+ title: HTMLText(value='<h2>Trapezoid integration</h2>')
+ f: EvalText(value='x^2-5*x + 10', description='$f(x)=$', layout=Layout(max_width='81em'))
+ n: IntSlider(value=5, description='# divisions', min=1)
+@@ -1284,7 +1284,7 @@ def simpson_integration(
+ creates the mathlet::
+
+ sage: interacts.calculus.simpson_integration()
+- Interactive function <function simpson_integration at ...> with 7 widgets
++ ...Interactive function <function simpson_integration at ...> with 7 widgets
+ title: HTMLText(value='<h2>Simpson integration</h2>')
+ f: EvalText(value='x*sin(x)+x+1', description='$f(x)=$', layout=Layout(max_width='81em'))
+ n: IntSlider(value=6, description='# divisions', min=2, step=2)
+@@ -1547,7 +1547,7 @@ def function_tool(f, g, xrange, yrange, a, action, do_plot):
+ creates the mathlet::
+
+ sage: interacts.calculus.function_tool()
+- Interactive function <function function_tool at ...> with 7 widgets
++ ...Interactive function <function function_tool at ...> with 7 widgets
+ f: EvalText(value='sin(x)', description='f')
+ g: EvalText(value='cos(x)', description='g')
+ xrange: IntRangeSlider(value=(0, 1), description='x-range', max=3, min=-3)
+@@ -1677,7 +1677,7 @@ def julia(expo, c_real, c_imag, iterations, zoom_x, zoom_y, plot_points, dpi):
+ creates the mathlet::
+
+ sage: interacts.fractals.julia()
+- Interactive function <function julia at ...> with 8 widgets
++ ...Interactive function <function julia at ...> with 8 widgets
+ expo: FloatSlider(value=2.0, description='expo', max=10.0, min=-10.0)
+ c_real: FloatSlider(value=0.5, description='real part const.', max=2.0, min=-2.0, step=0.01)
+ c_imag: FloatSlider(value=0.5, description='imag part const.', max=2.0, min=-2.0, step=0.01)
+@@ -1729,7 +1729,7 @@ def mandelbrot(expo, iterations, zoom_x, zoom_y, plot_points, dpi):
+ creates the mathlet::
+
+ sage: interacts.fractals.mandelbrot()
+- Interactive function <function mandelbrot at ...> with 6 widgets
++ ...Interactive function <function mandelbrot at ...> with 6 widgets
+ expo: FloatSlider(value=2.0, description='expo', max=10.0, min=-10.0)
+ iterations: IntSlider(value=20, description='# iterations', min=1)
+ zoom_x: FloatRangeSlider(value=(-2.0, 1.0), description='Zoom X', max=2.0, min=-2.0, step=0.01)
+@@ -1774,7 +1774,7 @@ def cellular_automaton(N, rule_number, size):
+ creates the mathlet::
+
+ sage: interacts.fractals.cellular_automaton()
+- Interactive function <function cellular_automaton at ...> with 3 widgets
++ ...Interactive function <function cellular_automaton at ...> with 3 widgets
+ N: IntSlider(value=100, description='Number of iterations', max=500, min=1)
+ rule_number: IntSlider(value=110, description='Rule number', max=255)
+ size: IntSlider(value=6, description='size of graphic', max=11, min=1)
+@@ -1833,7 +1833,7 @@ def polar_prime_spiral(interval, show_factors, highlight_primes, show_curves, n,
+ creates the mathlet::
+
+ sage: sage.interacts.algebra.polar_prime_spiral()
+- Interactive function <function polar_prime_spiral at ...> with 6 widgets
++ ...Interactive function <function polar_prime_spiral at ...> with 6 widgets
+ interval: IntRangeSlider(value=(1, 1000), description='range', max=4000, min=1, step=10)
+ show_factors: Checkbox(value=True, description='show_factors')
+ highlight_primes: Checkbox(value=True, description='highlight_primes')
+diff --git a/src/sage/plot/plot3d/plot3d.py b/src/sage/plot/plot3d/plot3d.py
+index 44620a0..43e1ce9 100644
+--- a/src/sage/plot/plot3d/plot3d.py
++++ b/src/sage/plot/plot3d/plot3d.py
+@@ -1300,7 +1300,7 @@ def plot3d(f, urange, vrange, adaptive=False, transformation=None, **kwds):
+ sage: @interact
+ ....: def _(which_plot=[A,B,C,D,E]):
+ ....: show(which_plot)
+- Interactive function <function _ at ...> with 1 widget
++ ...Interactive function <function _ at ...> with 1 widget
+ which_plot: Dropdown(description='which_plot', options=(Graphics3d Object, Graphics3d Object, Graphics3d Object, Graphics3d Object, Graphics3d Object), value=Graphics3d Object)
+
+ Now plot a function::
+@@ -1314,7 +1314,7 @@ def plot3d(f, urange, vrange, adaptive=False, transformation=None, **kwds):
+ sage: @interact
+ ....: def _(which_plot=[F, G, H, I, J]):
+ ....: show(which_plot)
+- Interactive function <function _ at ...> with 1 widget
++ ...Interactive function <function _ at ...> with 1 widget
+ which_plot: Dropdown(description='which_plot', options=(Graphics3d Object, Graphics3d Object, Graphics3d Object, Graphics3d Object, Graphics3d Object), value=Graphics3d Object)
+
+ TESTS:
+diff --git a/src/sage/repl/display/formatter.py b/src/sage/repl/display/formatter.py
+index adde08d..62bde3b 100644
+--- a/src/sage/repl/display/formatter.py
++++ b/src/sage/repl/display/formatter.py
+@@ -169,8 +169,7 @@ class SageDisplayFormatter(DisplayFormatter):
+ sage: shell.run_cell('import ipywidgets')
+ sage: shell.run_cell('slider = ipywidgets.IntSlider()')
+ sage: shell.run_cell('get_ipython().display_formatter.format(slider)')
+- IntSlider(value=0)
+- ({}, {})
++ ...IntSlider(value=0)..., {})
+
+ sage: shell.run_cell('%display default')
+ sage: shell.quit()
+diff --git a/src/sage/repl/ipython_kernel/interact.py b/src/sage/repl/ipython_kernel/interact.py
+index 9b94bc4..a2665a4 100644
+--- a/src/sage/repl/ipython_kernel/interact.py
++++ b/src/sage/repl/ipython_kernel/interact.py
+@@ -18,7 +18,7 @@ EXAMPLES::
+ sage: @interact
+ ....: def f(x=(0, 10)):
+ ....: pass
+- Interactive function <function f at ...> with 1 widget
++ ...Interactive function <function f at ...> with 1 widget
+ x: IntSlider(value=5, description='x', max=10)
+ sage: f.widget.children
+ (IntSlider(value=5, description='x', max=10), Output())
+@@ -69,7 +69,7 @@ class sage_interactive(interactive):
+ sage: from sage.repl.ipython_kernel.interact import sage_interactive
+ sage: def myfunc(x=10, y="hello", z=None): pass
+ sage: sage_interactive(myfunc, x=(0,100), z=["one", "two", "three"])
+- Interactive function <function myfunc at ...> with 3 widgets
++ ...Interactive function <function myfunc at ...> with 3 widgets
+ x: IntSlider(value=10, description='x')
+ y: Text(value='hello', description='y')
+ z: Dropdown(description='z', options=('one', 'two', 'three'), value=None)
+@@ -99,10 +99,10 @@ class sage_interactive(interactive):
+
+ sage: def myfunc(auto_update=False): pass
+ sage: sage_interactive(myfunc)
+- Manual interactive function <function myfunc ...> with 0 widgets
++ ...Manual interactive function <function myfunc ...> with 0 widgets
+ sage: def myfunc(auto_update=None): pass
+ sage: sage_interactive(myfunc)
+- Interactive function <function myfunc ...> with 0 widgets
++ ...Interactive function <function myfunc ...> with 0 widgets
+ """
+ # Use *args to avoid name clash with keyword arguments
+ if len(args) < 2:
+@@ -126,7 +126,7 @@ class sage_interactive(interactive):
+ super(sage_interactive, self).__init__(f, options, **kwds)
+ if self.manual:
+ # In Sage, manual interacts are always run once
+- self.on_displayed(self.update)
++ self.on_widget_constructed(self.update)
+ else:
+ # In automatic mode, clicking on a ToggleButtons button
+ # should also run the interact
+@@ -143,7 +143,7 @@ class sage_interactive(interactive):
+ sage: from sage.repl.ipython_kernel.interact import sage_interactive
+ sage: def myfunc(): pass
+ sage: sage_interactive(myfunc)
+- Interactive function <function myfunc ...> with 0 widgets
++ ...Interactive function <function myfunc ...> with 0 widgets
+ """
+ s = "Manual interactive" if self.manual else "Interactive"
+ widgets = [w for w in self.children if isinstance(w, ValueWidget)]
+@@ -164,7 +164,7 @@ class sage_interactive(interactive):
+ sage: from sage.repl.ipython_kernel.interact import sage_interactive
+ sage: def myfunc(x=[1,2,3], auto_update=False): pass
+ sage: sage_interactive(myfunc).signature().parameters
+- mappingproxy({'x': <Parameter "x=[1, 2, 3]">})
++ ...mappingproxy({'x': <Parameter "x=[1, 2, 3]">})
+ """
+ return self.__signature
+
+@@ -181,14 +181,14 @@ class sage_interactive(interactive):
+
+ sage: from sage.repl.ipython_kernel.interact import sage_interactive
+ sage: sage_interactive.widget_from_single_value("sin(x)")
+- Text(value='sin(x)')
++ ...Text(value='sin(x)')
+ sage: sage_interactive.widget_from_single_value(sin(x))
+- EvalText(value='sin(x)')
++ ...EvalText(value='sin(x)')
+ sage: from sage.plot.colors import Color
+ sage: sage_interactive.widget_from_single_value(matrix([[1, 2], [3, 4]]))
+- Grid(value=[[1, 2], [3, 4]], children=(Label(value=''), VBox(children=(EvalText(value='1', layout=Layout(max_width='5em')), EvalText(value='3', layout=Layout(max_width='5em')))), VBox(children=(EvalText(value='2', layout=Layout(max_width='5em')), EvalText(value='4', layout=Layout(max_width='5em'))))))
++ ...Grid(value=[[1, 2], [3, 4]], children=(Label(value=''), VBox(children=(EvalText(value='1', layout=Layout(max_width='5em')), EvalText(value='3', layout=Layout(max_width='5em')))), VBox(children=(EvalText(value='2', layout=Layout(max_width='5em')), EvalText(value='4', layout=Layout(max_width='5em'))))))
+ sage: sage_interactive.widget_from_single_value(Color('cornflowerblue'))
+- SageColorPicker(value='#6495ed')
++ ...SageColorPicker(value='#6495ed')
+ """
+ # Support Sage matrices and colors
+ if isinstance(abbrev, Matrix):
+@@ -219,15 +219,15 @@ class sage_interactive(interactive):
+
+ sage: from sage.repl.ipython_kernel.interact import sage_interactive
+ sage: sage_interactive.widget_from_tuple( (0, 10) )
+- IntSlider(value=5, max=10)
++ ...IntSlider(value=5, max=10)
+ sage: sage_interactive.widget_from_tuple( ("number", (0, 10)) )
+- IntSlider(value=5, description='number', max=10)
++ ...IntSlider(value=5, description='number', max=10)
+ sage: sage_interactive.widget_from_tuple( (3, (0, 10)) )
+- IntSlider(value=3, max=10)
+- sage: sage_interactive.widget_from_tuple((2, dict(one=1, two=2, three=3)))
+- Dropdown(index=1, options={'one': 1, 'two': 2, 'three': 3}, value=2)
++ ...IntSlider(value=3, max=10)
++ sage: sage_interactive.widget_from_tuple((2, [('one', 1), ('two', 2), ('three', 3)]))
++ ...Dropdown(index=1, options=(('one', 1), ('two', 2), ('three', 3)), value=2)
+ sage: sage_interactive.widget_from_tuple( (sqrt(2), pi) )
+- FloatSlider(value=2.277903107981444, max=3.141592653589793, min=1.4142135623730951)
++ ...FloatSlider(value=2.277903107981444, max=3.141592653589793, min=1.4142135623730951)
+
+ TESTS:
+
+@@ -235,7 +235,7 @@ class sage_interactive(interactive):
+
+ sage: SCR = SR.subring(no_variables=True)
+ sage: sage_interactive.widget_from_tuple( (SCR(sqrt(2)), SCR(pi)) )
+- FloatSlider(value=2.277903107981444, max=3.141592653589793, min=1.4142135623730951)
++ ...FloatSlider(value=2.277903107981444, max=3.141592653589793, min=1.4142135623730951)
+ """
+ # Support (description, abbrev)
+ if len(abbrev) == 2 and isinstance(abbrev[0], str):
+@@ -269,17 +269,17 @@ class sage_interactive(interactive):
+
+ sage: from sage.repl.ipython_kernel.interact import sage_interactive
+ sage: sage_interactive.widget_from_iterable([1..5])
+- Dropdown(options=(1, 2, 3, 4, 5), value=1)
++ ...Dropdown(options=(1, 2, 3, 4, 5), value=1)
+ sage: sage_interactive.widget_from_iterable(iter([1..5]))
+- SelectionSlider(options=(1, 2, 3, 4, 5), value=1)
++ ...SelectionSlider(options=(1, 2, 3, 4, 5), value=1)
+ sage: sage_interactive.widget_from_iterable((1..5))
+- SelectionSlider(options=(1, 2, 3, 4, 5), value=1)
++ ...SelectionSlider(options=(1, 2, 3, 4, 5), value=1)
+ sage: sage_interactive.widget_from_iterable(x for x in [1..5])
+- SelectionSlider(options=(1, 2, 3, 4, 5), value=1)
++ ...SelectionSlider(options=(1, 2, 3, 4, 5), value=1)
+ sage: def gen():
+ ....: yield 1; yield 2; yield 3; yield 4; yield 5
+ sage: sage_interactive.widget_from_iterable(gen())
+- SelectionSlider(options=(1, 2, 3, 4, 5), value=1)
++ ...SelectionSlider(options=(1, 2, 3, 4, 5), value=1)
+ """
+ if isinstance(abbrev, Iterator):
+ return SelectionSlider(options=list(abbrev))
+diff --git a/src/sage/repl/ipython_kernel/widgets_sagenb.py b/src/sage/repl/ipython_kernel/widgets_sagenb.py
+index 2ce59d7..76f4f52 100644
+--- a/src/sage/repl/ipython_kernel/widgets_sagenb.py
++++ b/src/sage/repl/ipython_kernel/widgets_sagenb.py
+@@ -470,15 +470,6 @@ def selector(values, label=None, default=None, nrows=None, ncols=None, width=Non
+ sage: selector([(1,"one"), (2,"two"), (3,"three")], buttons=True)
+ ToggleButtons(options=(('one', 1), ('two', 2), ('three', 3)), value=1)
+
+- A dict of ``label:value`` pairs is also allowed. Since a ``dict``
+- is not ordered, it is better to use an :class:`OrderedDict`::
+-
+- sage: from collections import OrderedDict
+- sage: selector(OrderedDict(one=1, two=2, three=3))
+- Dropdown(options=OrderedDict([('one', 1), ('two', 2), ('three', 3)]), value=1)
+- sage: selector(OrderedDict(one=1, two=2, three=3), buttons=True)
+- ToggleButtons(options=OrderedDict([('one', 1), ('two', 2), ('three', 3)]), value=1)
+-
+ The values can be any kind of object:
+
+ sage: selector([sin(x^2), GF(29), EllipticCurve('37a1')])