[arch-commits] Commit in sagemath-doc/repos (6 files)

Antonio Rojas arojas at archlinux.org
Sun Dec 23 15:28:22 UTC 2018


    Date: Sunday, December 23, 2018 @ 15:28:21
  Author: arojas
Revision: 417632

archrelease: copy trunk to community-testing-any

Added:
  sagemath-doc/repos/community-testing-any/
  sagemath-doc/repos/community-testing-any/PKGBUILD
    (from rev 417631, sagemath-doc/trunk/PKGBUILD)
  sagemath-doc/repos/community-testing-any/docbuild_main.patch
    (from rev 417631, sagemath-doc/trunk/docbuild_main.patch)
  sagemath-doc/repos/community-testing-any/sagemath-doc-segfault.patch
    (from rev 417631, sagemath-doc/trunk/sagemath-doc-segfault.patch)
  sagemath-doc/repos/community-testing-any/sagemath-doc-sphinx-1.8.patch
    (from rev 417631, sagemath-doc/trunk/sagemath-doc-sphinx-1.8.patch)
  sagemath-doc/repos/community-testing-any/sagemath-gap-4.10.patch
    (from rev 417631, sagemath-doc/trunk/sagemath-gap-4.10.patch)

-------------------------------+
 PKGBUILD                      |   65 
 docbuild_main.patch           |    6 
 sagemath-doc-segfault.patch   |   63 
 sagemath-doc-sphinx-1.8.patch |   57 
 sagemath-gap-4.10.patch       | 4342 ++++++++++++++++++++++++++++++++++++++++
 5 files changed, 4533 insertions(+)

Copied: sagemath-doc/repos/community-testing-any/PKGBUILD (from rev 417631, sagemath-doc/trunk/PKGBUILD)
===================================================================
--- community-testing-any/PKGBUILD	                        (rev 0)
+++ community-testing-any/PKGBUILD	2018-12-23 15:28:21 UTC (rev 417632)
@@ -0,0 +1,65 @@
+# Maintainer: Antonio Rojas <arojas at archlinux.org>
+
+pkgname=sagemath-doc
+pkgver=8.5
+pkgrel=1
+pkgdesc="HTML documentation and inline help for SageMath"
+arch=(any)
+url="http://www.sagemath.org"
+license=(GPL)
+depends=(python2-sphinx gap-doc thebe)
+makedepends=(sage-notebook python2-pyzmq python2-docutils python2-jupyter_client python2-pkgconfig cython2 python2-ipywidgets)
+source=("$pkgname-$pkgver.tar.gz::https://github.com/sagemath/sage/archive/$pkgver.tar.gz"
+        docbuild_main.patch sagemath-doc-sphinx-1.8.patch sagemath-doc-segfault.patch sagemath-gap-4.10.patch)
+sha256sums=('369810fac9ad7fb6cb1eb2a82d3e3679edee015778de34c56670d4ee80bde690'
+            'ea5e17bb7a7cb36a22e5e3872fcc2585852bc971c4b139b0b2cd69a36c1b009b'
+            '17aae8d9c76a4e14cf3a4f5c7c9470e5312b18976bdd60f970ee736ca03a8cb3'
+            '141ac064305526785fb6d9507896876cbf893cd41ec1e42d86fc836f766c200f'
+            '224f8d1db783d7ae25408912c4891687d6a8a1dacc8c5b3a00b725a28d951b6c')
+
+prepare() {
+  cd sage-$pkgver
+
+# fix relative imports
+  patch -p0 -i ../docbuild_main.patch
+# use sage_setup imports from sagemath source, but use system sage ones (which include compiled modules)
+  mkdir -p local-python
+  ln -sr src/sage_setup local-python
+# fix build with sphinx 1.8
+  patch -p1 -i ../sagemath-doc-sphinx-1.8.patch
+# Partially revert https://trac.sagemath.org/ticket/24655 to workaround a segfault
+  patch -Rp1 -i ../sagemath-doc-segfault.patch
+# Port to GAP 4.10
+  patch -p1 -i ../sagemath-gap-4.10.patch
+}
+
+build() {
+  cd sage-$pkgver/src
+
+  export SAGE_LOCAL="/usr"
+  export SAGE_ROOT="/usr"
+  export SAGE_SRC="$PWD"
+  export SAGE_DOC_SRC="$SAGE_SRC"/doc
+  export SAGE_DOC="$SAGE_DOC_SRC"
+  export SAGE_DOC_MATHJAX=yes
+  export PYTHONPATH="$srcdir"/sage-$pkgver/local-python
+  python2 sage_setup/docbuild --no-pdf-links all html
+}
+
+package() {
+  cd sage-$pkgver/src/doc
+ 
+  mkdir -p "$pkgdir"/usr/share/doc/sage/en
+  cp -r en/introspect "$pkgdir"/usr/share/doc/sage/en
+  cp -r common "$pkgdir"/usr/share/doc/sage
+  cp -r html "$pkgdir"/usr/share/doc/sage
+
+# Replace duplicated files by symlinks (Gentoo)
+  cd "$pkgdir"/usr/share/doc/sage
+  mv html/en/_static{,.tmp}
+  for _dir in `find -name _static` ; do
+        rm -r $_dir
+        ln -s /usr/share/doc/sage/html/en/_static $_dir
+  done
+  mv html/en/_static{.tmp,}
+}

Copied: sagemath-doc/repos/community-testing-any/docbuild_main.patch (from rev 417631, sagemath-doc/trunk/docbuild_main.patch)
===================================================================
--- community-testing-any/docbuild_main.patch	                        (rev 0)
+++ community-testing-any/docbuild_main.patch	2018-12-23 15:28:21 UTC (rev 417632)
@@ -0,0 +1,6 @@
+--- src/sage_setup/docbuild/__main__.py.orig
++++ src/sage_setup/docbuild/__main__.py
+@@ -1,2 +1,2 @@
+-from . import main
++from sage_setup.docbuild import main
+ main()

Copied: sagemath-doc/repos/community-testing-any/sagemath-doc-segfault.patch (from rev 417631, sagemath-doc/trunk/sagemath-doc-segfault.patch)
===================================================================
--- community-testing-any/sagemath-doc-segfault.patch	                        (rev 0)
+++ community-testing-any/sagemath-doc-segfault.patch	2018-12-23 15:28:21 UTC (rev 417632)
@@ -0,0 +1,63 @@
+diff --git a/src/sage_setup/docbuild/__init__.py b/src/sage_setup/docbuild/__init__.py
+index 5877b5b..7dc8ff7 100644
+--- a/src/sage_setup/docbuild/__init__.py
++++ b/src/sage_setup/docbuild/__init__.py
+@@ -265,35 +265,29 @@ class DocBuilder(object):
+     # import the customized builder for object.inv files
+     inventory = builder_helper('inventory')
+ 
+-if NUM_THREADS > 1:
+-    def build_many(target, args):
+-        from multiprocessing import Pool
+-        pool = Pool(NUM_THREADS, maxtasksperchild=1)
+-        # map_async handles KeyboardInterrupt correctly. Plain map and
+-        # apply_async does not, so don't use it.
+-        x = pool.map_async(target, args, 1)
+-        try:
+-            ret = x.get(99999)
+-            pool.close()
+-            pool.join()
+-        except Exception:
+-            pool.terminate()
+-            if ABORT_ON_ERROR:
+-                raise
+-        return ret
+-else:
+-    def build_many(target, args):
+-        results = []
+-
+-        for arg in args:
+-            try:
+-                results.append(target(arg))
+-            except Exception:
+-                if ABORT_ON_ERROR:
+-                    raise
+-
+-        return results
+-
++def build_many(target, args):
++    # Pool() uses an actual fork() to run each new instance. This is important
++    # for performance reasons, i.e., don't use a forkserver when it becomes
++    # available with Python 3: Here, sage is already initialized which is quite
++    # costly, with a forkserver we would have to reinitialize it for every
++    # document we build. At the same time, don't serialize this by taking the
++    # pool (and thus the call to fork()) out completely: The call to Sphinx
++    # leaks memory, so we need to build each document in its own process to
++    # control the RAM usage.
++    from multiprocessing import Pool
++    pool = Pool(NUM_THREADS, maxtasksperchild=1)
++    # map_async handles KeyboardInterrupt correctly. Plain map and
++    # apply_async does not, so don't use it.
++    x = pool.map_async(target, args, 1)
++    try:
++        ret = x.get(99999)
++        pool.close()
++        pool.join()
++    except Exception:
++        pool.terminate()
++        if ABORT_ON_ERROR:
++            raise
++    return ret
+ 
+ ##########################################
+ #      Parallel Building Ref Manual      #

Copied: sagemath-doc/repos/community-testing-any/sagemath-doc-sphinx-1.8.patch (from rev 417631, sagemath-doc/trunk/sagemath-doc-sphinx-1.8.patch)
===================================================================
--- community-testing-any/sagemath-doc-sphinx-1.8.patch	                        (rev 0)
+++ community-testing-any/sagemath-doc-sphinx-1.8.patch	2018-12-23 15:28:21 UTC (rev 417632)
@@ -0,0 +1,57 @@
+diff --git a/src/sage_setup/docbuild/__init__.py b/src/sage_setup/docbuild/__init__.py
+index ff67979..83b49e1 100644
+--- a/src/sage_setup/docbuild/__init__.py
++++ b/src/sage_setup/docbuild/__init__.py
+@@ -332,6 +331,18 @@ class AllBuilder(object):
+         for document in refs:
+             getattr(get_builder(document), 'inventory')(*args, **kwds)
+ 
++        # In the inventory build, the directory
++        # SAGE_DOC/inventory/en/reference/_static might be created,
++        # but it is unnecessary in the inventory build -- this
++        # directory should contain javascript and style files
++        # specifically for the html build -- and it can confuse
++        # intersphinx and the html builder when they look for
++        # inventory files. So delete this directory.
++        staticdir = os.path.join(SAGE_DOC, 'inventory', 'en', 'reference', '_static')
++        if os.path.isdir(staticdir):
++            logger.info("Deleting _static directory in the inventory build")
++            shutil.rmtree(staticdir)
++
+         logger.warning("Building reference manual, second pass.\n")
+         for document in refs:
+             getattr(get_builder(document), name)(*args, **kwds)
+@@ -526,6 +537,17 @@ class ReferenceBuilder(AllBuilder):
+             output_dir = self._output_dir(format, lang)
+             L = [(doc, lang, format, kwds) + args for doc in self.get_all_documents(refdir)]
+             build_many(build_ref_doc, L)
++            # In the html build, a file -- not a directory --
++            # SAGE_DOC/html/en/reference/_static might be created,
++            # with the contents of Sphinx's graphviz.css file.  This
++            # is supposed to be a directory, and the presence of this
++            # file prevents copying of any css files, etc., to
++            # reference/_static. So delete this file.
++            staticfile = os.path.join(SAGE_DOC, 'html', 'en', 'reference', '_static')
++            if os.path.isfile(staticfile):
++                logger.info("Deleting _static file in the html build")
++                os.unlink(staticfile)
++
+             # The html refman must be build at the end to ensure correct
+             # merging of indexes and inventories.
+             # Sphinx is run here in the current process (not in a
+diff --git a/src/sage_setup/docbuild/ext/sage_autodoc.py b/src/sage_setup/docbuild/ext/sage_autodoc.py
+index 2c399bad51..96abec3382 100644
+--- a/src/sage_setup/docbuild/ext/sage_autodoc.py
++++ b/src/sage_setup/docbuild/ext/sage_autodoc.py
+@@ -39,8 +39,9 @@ from docutils.statemachine import ViewList
+ import sphinx
+ from sphinx.util import rpartition, force_decode
+ from sphinx.locale import _
+-from sphinx.pycode import ModuleAnalyzer, PycodeError
+-from sphinx.application import ExtensionError
++from sphinx.pycode import ModuleAnalyzer
++from sphinx.errors import ExtensionError, PycodeError
++from sphinx.util.logging import getLogger
+ from sphinx.util.nodes import nested_parse_with_titles
+ from docutils.parsers.rst import Directive
+ from sphinx.util.inspect import getargspec, isdescriptor, safe_getmembers, \

Copied: sagemath-doc/repos/community-testing-any/sagemath-gap-4.10.patch (from rev 417631, sagemath-doc/trunk/sagemath-gap-4.10.patch)
===================================================================
--- community-testing-any/sagemath-gap-4.10.patch	                        (rev 0)
+++ community-testing-any/sagemath-gap-4.10.patch	2018-12-23 15:28:21 UTC (rev 417632)
@@ -0,0 +1,4342 @@
+diff --git a/src/doc/en/constructions/groups.rst b/src/doc/en/constructions/groups.rst
+index e769171..c771783 100644
+--- a/src/doc/en/constructions/groups.rst
++++ b/src/doc/en/constructions/groups.rst
+@@ -163,7 +163,7 @@ If you want to find all the normal subgroups of a permutation group
+ 
+     sage: G = AlternatingGroup( 5 )
+     sage: gap(G).NormalSubgroups()
+-    [ Group( () ), AlternatingGroup( [ 1 .. 5 ] ) ]
++    [ AlternatingGroup( [ 1 .. 5 ] ), Group( () ) ]
+ 
+ or
+ 
+@@ -171,22 +171,22 @@ or
+ 
+     sage: G = gap("AlternatingGroup( 5 )")
+     sage: G.NormalSubgroups()
+-    [ Group( () ), AlternatingGroup( [ 1 .. 5 ] ) ]
++    [ AlternatingGroup( [ 1 .. 5 ] ), Group( () ) ]
+ 
+ Here's another way, working more directly with GAP::
+ 
+     sage: print(gap.eval("G := AlternatingGroup( 5 )"))
+     Alt( [ 1 .. 5 ] )
+     sage: print(gap.eval("normal := NormalSubgroups( G )"))
+-    [ Group(()), Alt( [ 1 .. 5 ] ) ]
++    [ Alt( [ 1 .. 5 ] ), Group(()) ]
+     sage: G = gap.new("DihedralGroup( 10 )")
+     sage: G.NormalSubgroups()
+-    [ Group( <identity> of ... ), Group( [ f2 ] ), Group( [ f1, f2 ] ) ]
++    [ Group( [ f1, f2 ] ), Group( [ f2 ] ), Group( <identity> of ... ) ]
+     sage: print(gap.eval("G := SymmetricGroup( 4 )"))
+     Sym( [ 1 .. 4 ] )
+     sage: print(gap.eval("normal := NormalSubgroups( G );"))
+-    [ Group(()), Group([ (1,4)(2,3), (1,3)(2,4) ]), Group([ (2,4,3), (1,4)
+-      (2,3), (1,3)(2,4) ]), Sym( [ 1 .. 4 ] ) ]
++    [ Sym( [ 1 .. 4 ] ), Alt( [ 1 .. 4 ] ), Group([ (1,4)(2,3), (1,3)(2,4) ]),
++      Group(()) ]
+ 
+ .. index::
+    pair: groups; center
+diff --git a/src/doc/en/prep/Quickstarts/Abstract-Algebra.rst b/src/doc/en/prep/Quickstarts/Abstract-Algebra.rst
+index 042b786..041d6f9 100644
+--- a/src/doc/en/prep/Quickstarts/Abstract-Algebra.rst
++++ b/src/doc/en/prep/Quickstarts/Abstract-Algebra.rst
+@@ -85,13 +85,13 @@ rather than just a list of numbers.  This can be very powerful.
+ 
+     sage: for K in D.normal_subgroups():
+     ....:     print(K)
+-    Subgroup of (Dihedral group of order 16 as a permutation group) generated by [()]
+-    Subgroup of (Dihedral group of order 16 as a permutation group) generated by [(1,5)(2,6)(3,7)(4,8)]
+-    Subgroup of (Dihedral group of order 16 as a permutation group) generated by [(1,3,5,7)(2,4,6,8), (1,5)(2,6)(3,7)(4,8)]
+-    Subgroup of (Dihedral group of order 16 as a permutation group) generated by [(1,2)(3,8)(4,7)(5,6), (1,3,5,7)(2,4,6,8), (1,5)(2,6)(3,7)(4,8)]
+-    Subgroup of (Dihedral group of order 16 as a permutation group) generated by [(2,8)(3,7)(4,6), (1,3,5,7)(2,4,6,8), (1,5)(2,6)(3,7)(4,8)]
+-    Subgroup of (Dihedral group of order 16 as a permutation group) generated by [(1,2,3,4,5,6,7,8), (1,3,5,7)(2,4,6,8), (1,5)(2,6)(3,7)(4,8)]
+     Subgroup of (Dihedral group of order 16 as a permutation group) generated by [(1,2,3,4,5,6,7,8), (1,8)(2,7)(3,6)(4,5)]
++    Subgroup of (Dihedral group of order 16 as a permutation group) generated by [(1,2,3,4,5,6,7,8), (1,3,5,7)(2,4,6,8), (1,5)(2,6)(3,7)(4,8)]
++    Subgroup of (Dihedral group of order 16 as a permutation group) generated by [(1,3,5,7)(2,4,6,8), (1,5)(2,6)(3,7)(4,8), (1,8)(2,7)(3,6)(4,5)]
++    Subgroup of (Dihedral group of order 16 as a permutation group) generated by [(2,8)(3,7)(4,6), (1,3,5,7)(2,4,6,8), (1,5)(2,6)(3,7)(4,8)]
++    Subgroup of (Dihedral group of order 16 as a permutation group) generated by [(1,3,5,7)(2,4,6,8), (1,5)(2,6)(3,7)(4,8)]
++    Subgroup of (Dihedral group of order 16 as a permutation group) generated by [(1,5)(2,6)(3,7)(4,8)]
++    Subgroup of (Dihedral group of order 16 as a permutation group) generated by [()]
+ 
+ We can access specific subgroups if we know the generators as a
+ permutation group.
+diff --git a/src/doc/en/thematic_tutorials/group_theory.rst b/src/doc/en/thematic_tutorials/group_theory.rst
+index 5d2fba0..868aefa 100644
+--- a/src/doc/en/thematic_tutorials/group_theory.rst
++++ b/src/doc/en/thematic_tutorials/group_theory.rst
+@@ -586,7 +586,12 @@ subgroups. ::
+ 
+     sage: C20 = CyclicPermutationGroup(20)
+     sage: C20.conjugacy_classes_subgroups()
+-    [Subgroup of (Cyclic group of order 20 as a permutation group) generated by [()], Subgroup of (Cyclic group of order 20 as a permutation group) generated by [(1,11)(2,12)(3,13)(4,14)(5,15)(6,16)(7,17)(8,18)(9,19)(10,20)], Subgroup of (Cyclic group of order 20 as a permutation group) generated by [(1,6,11,16)(2,7,12,17)(3,8,13,18)(4,9,14,19)(5,10,15,20)], Subgroup of (Cyclic group of order 20 as a permutation group) generated by [(1,5,9,13,17)(2,6,10,14,18)(3,7,11,15,19)(4,8,12,16,20)], Subgroup of (Cyclic group of order 20 as a permutation group) generated by [(1,3,5,7,9,11,13,15,17,19)(2,4,6,8,10,12,14,16,18,20)], Subgroup of (Cyclic group of order 20 as a permutation group) generated by [(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20)]]
++    [Subgroup of (Cyclic group of order 20 as a permutation group) generated by [()],
++     Subgroup of (Cyclic group of order 20 as a permutation group) generated by [(1,11)(2,12)(3,13)(4,14)(5,15)(6,16)(7,17)(8,18)(9,19)(10,20)],
++     Subgroup of (Cyclic group of order 20 as a permutation group) generated by [(1,6,11,16)(2,7,12,17)(3,8,13,18)(4,9,14,19)(5,10,15,20), (1,11)(2,12)(3,13)(4,14)(5,15)(6,16)(7,17)(8,18)(9,19)(10,20)],
++     Subgroup of (Cyclic group of order 20 as a permutation group) generated by [(1,5,9,13,17)(2,6,10,14,18)(3,7,11,15,19)(4,8,12,16,20)],
++     Subgroup of (Cyclic group of order 20 as a permutation group) generated by [(1,3,5,7,9,11,13,15,17,19)(2,4,6,8,10,12,14,16,18,20), (1,5,9,13,17)(2,6,10,14,18)(3,7,11,15,19)(4,8,12,16,20)],
++     Subgroup of (Cyclic group of order 20 as a permutation group) generated by [(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20), (1,3,5,7,9,11,13,15,17,19)(2,4,6,8,10,12,14,16,18,20), (1,5,9,13,17)(2,6,10,14,18)(3,7,11,15,19)(4,8,12,16,20)]]
+ 
+ Be careful, this command uses some more advanced ideas and will not
+ usually list *all* of the subgroups of a group. Here we are relying on
+@@ -639,10 +644,26 @@ suitable `g`. As an illustration, the code below:
+     sage: K = DihedralGroup(12)
+     sage: sg = K.conjugacy_classes_subgroups()
+     sage: sg
+-    [Subgroup of (Dihedral group of order 24 as a permutation group) generated by [()], Subgroup of (Dihedral group of order 24 as a permutation group) generated by [(1,2)(3,12)(4,11)(5,10)(6,9)(7,8)], Subgroup of (Dihedral group of order 24 as a permutation group) generated by [(1,7)(2,8)(3,9)(4,10)(5,11)(6,12)], Subgroup of (Dihedral group of order 24 as a permutation group) generated by [(2,12)(3,11)(4,10)(5,9)(6,8)], Subgroup of (Dihedral group of order 24 as a permutation group) generated by [(1,5,9)(2,6,10)(3,7,11)(4,8,12)], Subgroup of (Dihedral group of order 24 as a permutation group) generated by [(2,12)(3,11)(4,10)(5,9)(6,8), (1,7)(2,8)(3,9)(4,10)(5,11)(6,12)], Subgroup of (Dihedral group of order 24 as a permutation group) generated by [(1,2)(3,12)(4,11)(5,10)(6,9)(7,8), (1,7)(2,8)(3,9)(4,10)(5,11)(6,12)], Subgroup of (Dihedral group of order 24 as a permutation group) generated by [(1,7)(2,8)(3,9)(4,10)(5,11)(6,12), (1,10,7,4)(2,11,8,5)(3,12,9,6)], Subgroup of (Dihedra
 l group of order 24 as a permutation group) generated by [(1,3,5,7,9,11)(2,4,6,8,10,12), (1,5,9)(2,6,10)(3,7,11)(4,8,12)], Subgroup of (Dihedral group of order 24 as a permutation group) generated by [(1,2)(3,12)(4,11)(5,10)(6,9)(7,8), (1,5,9)(2,6,10)(3,7,11)(4,8,12)], Subgroup of (Dihedral group of order 24 as a permutation group) generated by [(2,12)(3,11)(4,10)(5,9)(6,8), (1,5,9)(2,6,10)(3,7,11)(4,8,12)], Subgroup of (Dihedral group of order 24 as a permutation group) generated by [(2,12)(3,11)(4,10)(5,9)(6,8), (1,7)(2,8)(3,9)(4,10)(5,11)(6,12), (1,10,7,4)(2,11,8,5)(3,12,9,6)], Subgroup of (Dihedral group of order 24 as a permutation group) generated by [(2,12)(3,11)(4,10)(5,9)(6,8), (1,3,5,7,9,11)(2,4,6,8,10,12), (1,5,9)(2,6,10)(3,7,11)(4,8,12)], Subgroup of (Dihedral group of order 24 as a permutation group) generated by [(1,2)(3,12)(4,11)(5,10)(6,9)(7,8), (1,3,5,7,9,11)(2,4,6,8,10,12), (1,5,9)(2,6,10)(3,7,11)(4,8,12)], Subgroup of (Dihedral group of order 24 as a permutation g
 roup) generated by [(1,2,3,4,5,6,7,8,9,10,11,12), (1,3,5,7,9,11)(2,4,6,8,10,12), (1,5,9)(2,6,10)(3,7,11)(4,8,12)], Subgroup of (Dihedral group of order 24 as a permutation group) generated by [(2,12)(3,11)(4,10)(5,9)(6,8), (1,2,3,4,5,6,7,8,9,10,11,12), (1,3,5,7,9,11)(2,4,6,8,10,12), (1,5,9)(2,6,10)(3,7,11)(4,8,12)]]
++    [Subgroup of (Dihedral group of order 24 as a permutation group) generated by [()],
++     Subgroup of (Dihedral group of order 24 as a permutation group) generated by [(1,7)(2,8)(3,9)(4,10)(5,11)(6,12)],
++     Subgroup of (Dihedral group of order 24 as a permutation group) generated by [(2,12)(3,11)(4,10)(5,9)(6,8)],
++     Subgroup of (Dihedral group of order 24 as a permutation group) generated by [(1,2)(3,12)(4,11)(5,10)(6,9)(7,8)],
++     Subgroup of (Dihedral group of order 24 as a permutation group) generated by [(1,5,9)(2,6,10)(3,7,11)(4,8,12)],
++     Subgroup of (Dihedral group of order 24 as a permutation group) generated by [(2,12)(3,11)(4,10)(5,9)(6,8), (1,7)(2,8)(3,9)(4,10)(5,11)(6,12)],
++     Subgroup of (Dihedral group of order 24 as a permutation group) generated by [(1,7)(2,8)(3,9)(4,10)(5,11)(6,12), (1,10,7,4)(2,11,8,5)(3,12,9,6)],
++     Subgroup of (Dihedral group of order 24 as a permutation group) generated by [(1,2)(3,12)(4,11)(5,10)(6,9)(7,8), (1,7)(2,8)(3,9)(4,10)(5,11)(6,12)],
++     Subgroup of (Dihedral group of order 24 as a permutation group) generated by [(1,3,5,7,9,11)(2,4,6,8,10,12), (1,5,9)(2,6,10)(3,7,11)(4,8,12)],
++     Subgroup of (Dihedral group of order 24 as a permutation group) generated by [(2,12)(3,11)(4,10)(5,9)(6,8), (1,5,9)(2,6,10)(3,7,11)(4,8,12)],
++     Subgroup of (Dihedral group of order 24 as a permutation group) generated by [(1,2)(3,12)(4,11)(5,10)(6,9)(7,8), (1,5,9)(2,6,10)(3,7,11)(4,8,12)],
++     Subgroup of (Dihedral group of order 24 as a permutation group) generated by [(2,12)(3,11)(4,10)(5,9)(6,8), (1,7)(2,8)(3,9)(4,10)(5,11)(6,12), (1,10,7,4)(2,11,8,5)(3,12,9,6)],
++     Subgroup of (Dihedral group of order 24 as a permutation group) generated by [(2,12)(3,11)(4,10)(5,9)(6,8), (1,3,5,7,9,11)(2,4,6,8,10,12), (1,5,9)(2,6,10)(3,7,11)(4,8,12)],
++     Subgroup of (Dihedral group of order 24 as a permutation group) generated by [(1,2,3,4,5,6,7,8,9,10,11,12), (1,3,5,7,9,11)(2,4,6,8,10,12), (1,5,9)(2,6,10)(3,7,11)(4,8,12)],
++     Subgroup of (Dihedral group of order 24 as a permutation group) generated by [(1,2)(3,12)(4,11)(5,10)(6,9)(7,8), (1,3,5,7,9,11)(2,4,6,8,10,12), (1,5,9)(2,6,10)(3,7,11)(4,8,12)],
++     Subgroup of (Dihedral group of order 24 as a permutation group) generated by [(2,12)(3,11)(4,10)(5,9)(6,8), (1,2,3,4,5,6,7,8,9,10,11,12), (1,3,5,7,9,11)(2,4,6,8,10,12), (1,5,9)(2,6,10)(3,7,11)(4,8,12)]]
++
+     sage: print("An order two subgroup:\n{}".format(sg[1].list()))
+     An order two subgroup:
+-    [(), (1,2)(3,12)(4,11)(5,10)(6,9)(7,8)]
++    [(), (1,7)(2,8)(3,9)(4,10)(5,11)(6,12)]
+ 
+ It is important to note that this is a nice long list of subgroups,
+ but will rarely create *every* such subgroup.  For example, the
+diff --git a/src/doc/en/thematic_tutorials/lie/weyl_groups.rst b/src/doc/en/thematic_tutorials/lie/weyl_groups.rst
+index c32cd12..64f5436 100644
+--- a/src/doc/en/thematic_tutorials/lie/weyl_groups.rst
++++ b/src/doc/en/thematic_tutorials/lie/weyl_groups.rst
+@@ -219,7 +219,7 @@ this as follows::
+     sage: def bi(u,v) : return [t for t in W if u.bruhat_le(t) and t.bruhat_le(v)]
+     ...
+     sage: bi(s1,s1*s2*s1)
+-    [s1*s2*s1, s1*s2, s1, s2*s1]
++    [s1*s2, s2*s1, s1, s1*s2*s1]
+ 
+ This would not be a good definition since it would fail if `W` is
+ affine and be inefficient of `W` is large. Sage has a Bruhat interval
+diff --git a/src/doc/ja/tutorial/tour_groups.rst b/src/doc/ja/tutorial/tour_groups.rst
+index d62d8ed..059313a 100644
+--- a/src/doc/ja/tutorial/tour_groups.rst
++++ b/src/doc/ja/tutorial/tour_groups.rst
+@@ -21,7 +21,7 @@ Sageでは,置換群,有限古典群(例えば :math:`SU(n,q)`),有限行�
+     False
+     sage: G.derived_series()           # 結果は変化しがち
+     [Subgroup of (Permutation Group with generators [(3,4), (1,2,3)(4,5)]) generated by [(3,4), (1,2,3)(4,5)],
+-     Subgroup of (Permutation Group with generators [(3,4), (1,2,3)(4,5)]) generated by [(1,5,3), (1,5)(3,4), (1,5)(2,4)]]
++     Subgroup of (Permutation Group with generators [(3,4), (1,2,3)(4,5)]) generated by [(1,3,5), (1,5)(3,4), (1,5)(2,4)]]
+     sage: G.center()
+     Subgroup of (Permutation Group with generators [(3,4), (1,2,3)(4,5)]) generated by [()]
+     sage: G.random_element()           # random 出力は変化する
+diff --git a/src/ext/gap/sage.g b/src/ext/gap/sage.g
+index 54fa74f..12402a7 100644
+--- a/src/ext/gap/sage.g
++++ b/src/ext/gap/sage.g
+@@ -1,7 +1,22 @@
+-
+ #
+ # SAGE support utilities to read into the GAP session.
+ #
++
++# Prevent loading the xgap package; we use the -p flag to GAP in order to
++# communicate with it via the pexpect interface; this is normally used by
++# for an xgap window to communicate with GAP, so unfortunatelly setting this
++# flag also allows the xgap package to be loaded and for some packages to
++# attempt to communicate with a "window handler" that doesn't exist.
++# Therefore we must explicitly disable loading of the xgap package.
++#
++# Don't use SetUserPreference since that leads to reloading the workspace,
++# which is confusing to the pexpect interface
++if IsBound(GAPInfo.ExcludeFromAutoload) then
++    Append(GAPInfo.ExcludeFromAutoload, "xgap");
++else
++    GAPInfo.ExcludeFromAutoload := [ "xgap" ];
++fi;
++
+ \$SAGE := rec();
+ 
+ \$SAGE.OldPager := Pager;
+@@ -62,19 +77,15 @@ end;
+ SetAllInfoLevels(0);
+ 
+ \$SAGE.OperationsAdmittingFirstArgument := function(obj)
+-    local   hits,  myflags,  i,  flagss,  flags;
+-    hits := [];
+-    myflags := FlagsType(TypeObj(obj));
+-    for i in [1,3..Length(OPERATIONS)-1] do
+-        flagss := OPERATIONS[i+1];
+-        for flags in flagss do
+-            if Length(flags) >= 1 and IS_SUBSET_FLAGS(myflags, flags[1]) then
+-                Add(hits, OPERATIONS[i]);
+-                break;
+-            fi;
+-        od;
+-    od;
+-    return hits;
++    local   myflags, mfi;
++    myflags := FlagsObj(obj);
++    mfi := function(o)
++        local f;
++        f := GET_OPER_FLAGS(o);
++        return f<>[] and f[1]<>[] and
++          IS_SUBSET_FLAGS(myflags, f[1][1]);
++    end;
++    return Filtered(OPERATIONS, mfi);
+ end;
+ 
+ 
+diff --git a/src/sage/categories/modules_with_basis.py b/src/sage/categories/modules_with_basis.py
+index 3619868..0e56128 100644
+--- a/src/sage/categories/modules_with_basis.py
++++ b/src/sage/categories/modules_with_basis.py
+@@ -1201,8 +1201,8 @@ class ModulesWithBasis(CategoryWithAxiom_over_base_ring):
+                 sage: DihedralGroup(6).algebra(QQ).random_element()
+                 -1/95*() - 1/2*(1,4)(2,5)(3,6)
+                 sage: SU(2, 13).algebra(QQ).random_element(1)
+-                1/2*[       3        0]
+-                [11*a + 1        9]
++                1/2*[       5 2*a + 12]
++                [   a + 6        6]
+                 sage: CombinatorialFreeModule(ZZ, Partitions(4)).random_element() # random
+                 2*B[[2, 1, 1]] + B[[2, 2]]
+             """
+diff --git a/src/sage/coding/codecan/autgroup_can_label.pyx b/src/sage/coding/codecan/autgroup_can_label.pyx
+index 569ce32..fa0eb65 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, 16, 8, 21, 12, 9, 13, 18, 11, 19, 15, 7, 20, 14, 17, 10]]
++     [6, 19, 9, 21, 16, 14, 11, 20, 15, 8, 10, 12, 7, 13, 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 18f53b4..b31b869 100644
+--- a/src/sage/coding/linear_code.py
++++ b/src/sage/coding/linear_code.py
+@@ -801,27 +801,31 @@ class AbstractLinearCode(Module):
+ 
+             sage: C = codes.HammingCode(GF(4, 'z'), 3)
+             sage: C.automorphism_group_gens()
+-            ([((z, 1, z, z, z, z + 1, 1, z + 1, 1, 1, 1, z + 1, 1, z + 1, z + 1, z + 1, 1, z, 1, z + 1, z); (1,9,5,15,20,13,4)(2,8,12,7,10,14,16,3,21,18,19,6,11,17), Ring endomorphism of Finite Field in z of size 2^2
++            ([((z, 1, z + 1, z + 1, 1, 1, z + 1, z, z, 1, z + 1, z + 1, z + 1, 1, z, z + 1, 1, z, z + 1, z + 1, z); (1,5,4,2)(6,17,10,20,19,18,12,8)(7,14,15,21,16,9,11,13), Ring endomorphism of Finite Field in z of size 2^2
+                 Defn: z |--> z + 1),
+-            ((z, z, z, z, z, 1, z + 1, 1, z + 1, z + 1, z + 1, 1, z, z + 1, z, z, 1, z + 1, 1, 1, 1); (1,10,20,16,6,3,11,19,15,8,5,9,17,12,13)(4,7,21,14,18), Ring endomorphism of Finite Field in z of size 2^2
++              ((z + 1, 1, z + 1, z + 1, z + 1, z, 1, z, 1, 1, 1, z + 1, z + 1, z, 1, z, z, 1, z, z, z); (1,5,20,19,16,6,4,12,2,18,21,10,11,15,8,14,13,7,3,9,17), 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
++              ((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, z + 1, z + 1, z + 1, z + 1, z + 1, z + 1, 1, z + 1, z + 1, z + 1, z + 1, z, z + 1, z + 1, z + 1, z + 1, 1, z + 1, z + 1, z + 1); (1,3,17,20,12,16)(2,18)(4,11,21,9,14,10)(5,15,19)(6,8), Ring endomorphism of Finite Field in z of size 2^2
++            ([((1, 1, 1, z, z + 1, z, z + 1, 1, 1, z, z + 1, z, 1, 1, z, z + 1, z, 1, 1, z, z + 1); (1,8,3,4,12,13,17,6,18,15,20,5,19,21,16)(2,11,10,9,7), Ring endomorphism of Finite Field in z of size 2^2
+                 Defn: z |--> z),
+-            ((z + 1, z, 1, z + 1, z, z + 1, z + 1, z, 1, z + 1, z, z + 1, z, 1, z, z, z + 1, z, 1, 1, z); (1,15,18,20,13,7,21,17,9,11,5,14,19,4,2,16,10,6,8,3,12), Ring endomorphism of Finite Field in z of size 2^2
++              ((1, z + 1, z, z + 1, z + 1, 1, 1, z + 1, z, z, z + 1, 1, z + 1, z, 1, z + 1, 1, z + 1, z, 1, z + 1); (1,21,12,14,11,5,9,3,15,13,16,20,6,18,19,17,7,4,8,10,2), 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
++              ((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,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); (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,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)], 64)
++            ([((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); (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,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
++                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)],
++            64)
+         """
+         aut_group_can_label = self._canonize(equivalence)
+         return aut_group_can_label.get_autom_gens(), \
+@@ -1069,12 +1073,12 @@ class AbstractLinearCode(Module):
+             sage: C_iso == aut_group_can_label.get_canonical_form()
+             True
+             sage: aut_group_can_label.get_autom_gens()
+-            [((z, 1, z + 1, z, 1, 1, z, 1, z + 1, 1, 1, z, 1, z + 1, z, 1, z, 1, z + 1, z + 1, 1); (1,10,8,21,3,20,2,4,6,18,14,9,12,16,17)(5,15,13,7,19), Ring endomorphism of Finite Field in z of size 2^2
+-            Defn: z |--> z),
+-            ((z + 1, z, z, z + 1, 1, 1, 1, z + 1, z + 1, z, 1, z, z + 1, 1, 1, z + 1, z + 1, 1, 1, z, z); (1,18,17,5,16,3,10,11,8,21,7,12,9,4)(2,19,15,14,6,20,13), Ring endomorphism of Finite Field in z of size 2^2
+-            Defn: z |--> z + 1),
+-            ((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)]
++            [((z + 1, z + 1, z, z, 1, z, z, z, z, z, z, z + 1, z + 1, z + 1, z + 1, z + 1, 1, 1, 1, 1, 1); (1,2,13,11,7,19,4,18)(3,6,20,9,15,12,21,16)(5,8,14,10), Ring endomorphism of Finite Field in z of size 2^2
++               Defn: z |--> z + 1),
++             ((z, 1, z + 1, 1, 1, 1, z + 1, z + 1, z, 1, 1, 1, z + 1, 1, z, z + 1, 1, z, 1, z + 1, z); (1,17,5,21,12,8,6,10,11,13,4,2,20,9)(3,19,18,15,7,14,16), Ring endomorphism of Finite Field in z of size 2^2
++               Defn: z |--> z + 1),
++             ((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)]
+         """
+         from sage.coding.codecan.autgroup_can_label import LinearCodeAutGroupCanLabel
+         return LinearCodeAutGroupCanLabel(self, algorithm_type=equivalence)
+diff --git a/src/sage/combinat/root_system/hecke_algebra_representation.py b/src/sage/combinat/root_system/hecke_algebra_representation.py
+index 32112c3..6498afb 100644
+--- a/src/sage/combinat/root_system/hecke_algebra_representation.py
++++ b/src/sage/combinat/root_system/hecke_algebra_representation.py
+@@ -358,7 +358,7 @@ class HeckeAlgebraRepresentation(WithEqualityById, SageObject):
+             sage: q1, q2 = K.gens()
+             sage: KW = W.algebra(K)
+             sage: x = KW.an_element(); x
+-            2*12321 + 3*1231 + 123 + e
++            123 + 3*32 + 2*3 + e
+ 
+             sage: T = KW.demazure_lusztig_operators(q1,q2)
+             sage: T12 = T.Tw( (1,2) )
+diff --git a/src/sage/combinat/root_system/root_system.py b/src/sage/combinat/root_system/root_system.py
+index efddfa05..6fb83f1 100644
+--- a/src/sage/combinat/root_system/root_system.py
++++ b/src/sage/combinat/root_system/root_system.py
+@@ -207,13 +207,13 @@ class RootSystem(UniqueRepresentation, SageObject):
+         sage: W = L.weyl_group()
+         sage: S3 = [ w.action(id) for w in W.classical() ]
+         sage: [L.classical()(x) for x in S3]
+-        [(1, 2, 3), (3, 2, 1), (3, 1, 2), (2, 1, 3), (2, 3, 1), (1, 3, 2)]
++        [(1, 2, 3), (3, 1, 2), (2, 3, 1), (2, 1, 3), (1, 3, 2), (3, 2, 1)]
+ 
+     And the action of `s_0` on these yields::
+ 
+         sage: s = W.simple_reflections()
+         sage: [L.classical()(s[0].action(x)) for x in S3]
+-        [(0, 2, 4), (-2, 2, 6), (-1, 1, 6), (0, 1, 5), (-2, 3, 5), (-1, 3, 4)]
++        [(0, 2, 4), (-1, 1, 6), (-2, 3, 5), (0, 1, 5), (-1, 3, 4), (-2, 2, 6)]
+ 
+     We can also plot various components of the ambient spaces::
+ 
+diff --git a/src/sage/combinat/symmetric_group_algebra.py b/src/sage/combinat/symmetric_group_algebra.py
+index d5f8637..d89cfca 100644
+--- a/src/sage/combinat/symmetric_group_algebra.py
++++ b/src/sage/combinat/symmetric_group_algebra.py
+@@ -103,7 +103,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()
+-        2*s1*s2*s3*s2*s1 + 3*s1*s2*s3*s1 + s1*s2*s3 + 1
++        s1*s2*s3 + 3*s3*s2 + 2*s3 + 1
+ 
+     The preferred way to construct the symmetric group algebra is to
+     go through the usual ``algebra`` method::
+diff --git a/src/sage/combinat/tiling.py b/src/sage/combinat/tiling.py
+index 580e01a..2f8713a 100644
+--- a/src/sage/combinat/tiling.py
++++ b/src/sage/combinat/tiling.py
+@@ -325,21 +325,21 @@ def ncube_isometry_group(n, orientation_preserving=True):
+ 
+         sage: ncube_isometry_group(3)
+         [
+-        [1 0 0]  [ 1  0  0]  [-1  0  0]  [-1  0  0]  [0 0 1]  [ 0  0 -1]
+-        [0 1 0]  [ 0 -1  0]  [ 0  1  0]  [ 0 -1  0]  [1 0 0]  [ 1  0  0]
+-        [0 0 1], [ 0  0 -1], [ 0  0 -1], [ 0  0  1], [0 1 0], [ 0 -1  0],
++        [1 0 0]  [ 1  0  0]  [ 0  1  0]  [ 0  0 -1]  [ 1  0  0]  [ 0  1  0]
++        [0 1 0]  [ 0  0  1]  [ 0  0 -1]  [ 0 -1  0]  [ 0  0 -1]  [-1  0  0]
++        [0 0 1], [ 0 -1  0], [-1  0  0], [-1  0  0], [ 0  1  0], [ 0  0  1],
+         <BLANKLINE>
+-        [ 0  0 -1]  [ 0  0  1]  [0 1 0]  [ 0 -1  0]  [ 0  1  0]  [ 0 -1  0]
+-        [-1  0  0]  [-1  0  0]  [0 0 1]  [ 0  0 -1]  [ 0  0 -1]  [ 0  0  1]
+-        [ 0  1  0], [ 0 -1  0], [1 0 0], [ 1  0  0], [-1  0  0], [-1  0  0],
++        [ 1  0  0]  [ 0  0  1]  [0 1 0]  [ 0  0  1]  [ 0  0 -1]  [ 0 -1  0]
++        [ 0 -1  0]  [-1  0  0]  [0 0 1]  [ 0 -1  0]  [-1  0  0]  [-1  0  0]
++        [ 0  0 -1], [ 0 -1  0], [1 0 0], [ 1  0  0], [ 0  1  0], [ 0  0 -1],
+         <BLANKLINE>
+-        [ 0  1  0]  [ 0 -1  0]  [ 0  1  0]  [ 0 -1  0]  [ 1  0  0]  [ 1  0  0]
+-        [ 1  0  0]  [ 1  0  0]  [-1  0  0]  [-1  0  0]  [ 0  0 -1]  [ 0  0  1]
+-        [ 0  0 -1], [ 0  0  1], [ 0  0  1], [ 0  0 -1], [ 0  1  0], [ 0 -1  0],
++        [ 0  1  0]  [ 0  0  1]  [ 0  0 -1]  [ 0 -1  0]  [0 0 1]  [ 0 -1  0]
++        [ 1  0  0]  [ 0  1  0]  [ 1  0  0]  [ 0  0  1]  [1 0 0]  [ 1  0  0]
++        [ 0  0 -1], [-1  0  0], [ 0 -1  0], [-1  0  0], [0 1 0], [ 0  0  1],
+         <BLANKLINE>
+-        [-1  0  0]  [-1  0  0]  [ 0  0 -1]  [ 0  0  1]  [ 0  0  1]  [ 0  0 -1]
+-        [ 0  0  1]  [ 0  0 -1]  [ 0  1  0]  [ 0 -1  0]  [ 0  1  0]  [ 0 -1  0]
+-        [ 0  1  0], [ 0 -1  0], [ 1  0  0], [ 1  0  0], [-1  0  0], [-1  0  0]
++        [-1  0  0]  [-1  0  0]  [ 0  0 -1]  [-1  0  0]  [ 0 -1  0]  [-1  0  0]
++        [ 0  1  0]  [ 0  0 -1]  [ 0  1  0]  [ 0  0  1]  [ 0  0 -1]  [ 0 -1  0]
++        [ 0  0 -1], [ 0 -1  0], [ 1  0  0], [ 0  1  0], [ 1  0  0], [ 0  0  1]
+         ]
+ 
+     TESTS::
+diff --git a/src/sage/env.py b/src/sage/env.py
+index 77e0596..3a64c2d 100644
+--- a/src/sage/env.py
++++ b/src/sage/env.py
+@@ -164,7 +164,7 @@ _add_variable_or_fallback('CONWAY_POLYNOMIALS_DATA_DIR',  opj('$SAGE_SHARE','con
+ _add_variable_or_fallback('GRAPHS_DATA_DIR',  opj('$SAGE_SHARE','graphs'))
+ _add_variable_or_fallback('ELLCURVE_DATA_DIR',opj('$SAGE_SHARE','ellcurves'))
+ _add_variable_or_fallback('POLYTOPE_DATA_DIR',opj('$SAGE_SHARE','reflexive_polytopes'))
+-_add_variable_or_fallback('GAP_ROOT_DIR',     opj('$SAGE_LOCAL','gap','latest'))
++_add_variable_or_fallback('GAP_ROOT_DIR',     opj('$SAGE_SHARE','gap'))
+ _add_variable_or_fallback('THEBE_DIR',        opj('$SAGE_SHARE','thebe'))
+ _add_variable_or_fallback('COMBINATORIAL_DESIGN_DATA_DIR', opj('$SAGE_SHARE', 'combinatorial_designs'))
+ _add_variable_or_fallback('CREMONA_MINI_DATA_DIR', opj('$SAGE_SHARE', 'cremona'))
+diff --git a/src/sage/graphs/generators/families.py b/src/sage/graphs/generators/families.py
+index 8e24817..ac7ea93 100644
+--- a/src/sage/graphs/generators/families.py
++++ b/src/sage/graphs/generators/families.py
+@@ -3177,15 +3177,16 @@ def MathonPseudocyclicStronglyRegularGraph(t, G=None, L=None):
+         sage: ff = list(map(lambda y: (y[0]-1,y[1]-1),
+         ....:          Permutation(map(lambda x: 1+r.index(x^-1), r)).cycle_tuples()[1:]))
+         sage: L = sum(i*(r[a]-r[b]) for i,(a,b) in zip(range(1,len(ff)+1), ff)); L
+-        [ 0 -1  1 -2 -3 -4  2  4  3]
+-        [ 1  0 -1 -4 -2 -3  3  2  4]
+-        [-1  1  0 -3 -4 -2  4  3  2]
+-        [ 2  4  3  0 -1  1 -2 -3 -4]
+-        [ 3  2  4  1  0 -1 -4 -2 -3]
+-        [ 4  3  2 -1  1  0 -3 -4 -2]
+-        [-2 -3 -4  2  4  3  0 -1  1]
+-        [-4 -2 -3  3  2  4  1  0 -1]
+-        [-3 -4 -2  4  3  2 -1  1  0]
++        [ 0  1 -1 -3 -2 -4  3  4  2]
++        [-1  0  1 -4 -3 -2  2  3  4]
++        [ 1 -1  0 -2 -4 -3  4  2  3]
++        [ 3  4  2  0  1 -1 -3 -2 -4]
++        [ 2  3  4 -1  0  1 -4 -3 -2]
++        [ 4  2  3  1 -1  0 -2 -4 -3]
++        [-3 -2 -4  3  4  2  0  1 -1]
++        [-4 -3 -2  2  3  4 -1  0  1]
++        [-2 -4 -3  4  2  3  1 -1  0]
++
+         sage: G.relabel()
+         sage: G3x3=graphs.MathonPseudocyclicStronglyRegularGraph(2,G=G,L=L)
+         sage: G3x3.is_strongly_regular(parameters=True)
+diff --git a/src/sage/groups/abelian_gps/abelian_group_gap.py b/src/sage/groups/abelian_gps/abelian_group_gap.py
+index cebcd39..55a20ed 100644
+--- a/src/sage/groups/abelian_gps/abelian_group_gap.py
++++ b/src/sage/groups/abelian_gps/abelian_group_gap.py
+@@ -363,10 +363,10 @@ class AbelianGroup_gap(UniqueRepresentation, GroupMixinLibGAP, ParentLibGAP, Abe
+             sage: from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap
+             sage: G = AbelianGroupGap([2, 3])
+             sage: G.all_subgroups()
+-            [Subgroup of Abelian group with gap, generator orders (2, 3) generated by (1,),
++            [Subgroup of Abelian group with gap, generator orders (2, 3) generated by (),
+              Subgroup of Abelian group with gap, generator orders (2, 3) generated by (f1,),
+              Subgroup of Abelian group with gap, generator orders (2, 3) generated by (f2,),
+-             Subgroup of Abelian group with gap, generator orders (2, 3) generated by (f1, f2)]
++             Subgroup of Abelian group with gap, generator orders (2, 3) generated by (f2, f1)]
+         """
+         subgroups_gap = self.gap().AllSubgroups()
+         subgroups_sage = []
+diff --git a/src/sage/groups/braid.py b/src/sage/groups/braid.py
+index 4eda6e8..07a765c 100644
+--- a/src/sage/groups/braid.py
++++ b/src/sage/groups/braid.py
+@@ -2163,7 +2163,8 @@ class BraidGroup_class(FiniteTypeArtinGroup):
+ 
+             sage: B = BraidGroup(5)
+             sage: B._element_from_libbraiding([[-2], [2, 1], [1, 2], [2, 1]])
+-            (s0^-1*s1^-1*s2^-1*s3^-1*s0^-1*s1^-1*s2^-1*s0^-1*s1^-1*s0^-1)^2*s1*s0^2*s1^2*s0
++            (s0^-1*s1^-1*s2^-1*s3^-1*s0^-1*s1^-1*s2^-1*s0^-1*s1^-1*s0^-1)^2*s1*s0^2*s1^2*s\
++            0
+             sage: B._element_from_libbraiding([[0]])
+             1
+         """
+diff --git a/src/sage/groups/finitely_presented.py b/src/sage/groups/finitely_presented.py
+index 8f9c192..f27f334 100644
+--- a/src/sage/groups/finitely_presented.py
++++ b/src/sage/groups/finitely_presented.py
+@@ -231,7 +231,6 @@ class FinitelyPresentedGroupElement(FreeGroupElement):
+ 
+             sage: TestSuite(G).run()
+             sage: TestSuite(H).run()
+-
+             sage: G.<a,b> = FreeGroup()
+             sage: H = G / (G([1]), G([2, 2, 2]))
+             sage: x = H([1, 2, -1, -2])
+@@ -1096,6 +1095,7 @@ class FinitelyPresentedGroup(GroupMixinLibGAP, UniqueRepresentation,
+             sage: C7 = G / [G.0**7]; C6 =  G / [G.0**6]
+             sage: C14 = G / [G.0**14]; C3 =  G / [G.0**3]
+             sage: C7.direct_product(C6).is_isomorphic(C14.direct_product(C3))
++            #I  Forcing finiteness test
+             True
+             sage: F = FreeGroup(2); D = F / [F([1,1,1,1,1]),F([2,2]),F([1,2])**2]
+             sage: D.direct_product(D).as_permutation_group().is_isomorphic(
+@@ -1189,6 +1189,7 @@ class FinitelyPresentedGroup(GroupMixinLibGAP, UniqueRepresentation,
+             sage: alpha = (Q.gens(), [a,b])
+             sage: S2 = C2.semidirect_product(Q, ([C2.0],[alpha]))
+             sage: S1.is_isomorphic(S2)
++            #I  Forcing finiteness test
+             True
+ 
+         Dihedral groups can be constructed as semidirect products
+@@ -1247,6 +1248,8 @@ class FinitelyPresentedGroup(GroupMixinLibGAP, UniqueRepresentation,
+             sage: Se2 =  D.semidirect_product(C ,id2)
+             sage: Dp1 = C.direct_product(D)
+             sage: Dp1.is_isomorphic(Se1), Dp1.is_isomorphic(Se2)
++            #I  Forcing finiteness test
++            #I  Forcing finiteness test
+             (True, True)
+ 
+         Most checks for validity of input are left to GAP to handle::
+@@ -1445,27 +1448,27 @@ class FinitelyPresentedGroup(GroupMixinLibGAP, UniqueRepresentation,
+             sage: H = AlternatingGroup(3)
+             sage: G.epimorphisms(H)
+             [Generic morphism:
+-            From: Finitely presented group < x0, x1, x2 | (x0*x1*x2)^2, x0^3 >
+-            To:   Alternating group of order 3!/2 as a permutation group
+-            Defn: x0 |--> ()
+-                  x1 |--> (1,2,3)
+-                  x2 |--> (1,3,2), Generic morphism:
+-            From: Finitely presented group < x0, x1, x2 | (x0*x1*x2)^2, x0^3 >
+-            To:   Alternating group of order 3!/2 as a permutation group
+-            Defn: x0 |--> (1,2,3)
+-                  x1 |--> ()
+-                  x2 |--> (1,3,2), Generic morphism:
+-            From: Finitely presented group < x0, x1, x2 | (x0*x1*x2)^2, x0^3 >
+-            To:   Alternating group of order 3!/2 as a permutation group
+-            Defn: x0 |--> (1,2,3)
+-                  x1 |--> (1,2,3)
+-                  x2 |--> (1,2,3), Generic morphism:
+-            From: Finitely presented group < x0, x1, x2 | (x0*x1*x2)^2, x0^3 >
+-            To:   Alternating group of order 3!/2 as a permutation group
+-            Defn: x0 |--> (1,2,3)
+-                  x1 |--> (1,3,2)
+-                  x2 |--> ()]
+-        
++               From: Finitely presented group < x0, x1, x2 | (x0*x1*x2)^2, x0^3 >
++               To:   Alternating group of order 3!/2 as a permutation group
++               Defn: x0 |--> ()
++                     x1 |--> (1,3,2)
++                     x2 |--> (1,2,3), Generic morphism:
++               From: Finitely presented group < x0, x1, x2 | (x0*x1*x2)^2, x0^3 >
++               To:   Alternating group of order 3!/2 as a permutation group
++               Defn: x0 |--> (1,3,2)
++                     x1 |--> ()
++                     x2 |--> (1,2,3), Generic morphism:
++               From: Finitely presented group < x0, x1, x2 | (x0*x1*x2)^2, x0^3 >
++               To:   Alternating group of order 3!/2 as a permutation group
++               Defn: x0 |--> (1,3,2)
++                     x1 |--> (1,2,3)
++                     x2 |--> (), Generic morphism:
++               From: Finitely presented group < x0, x1, x2 | (x0*x1*x2)^2, x0^3 >
++               To:   Alternating group of order 3!/2 as a permutation group
++               Defn: x0 |--> (1,2,3)
++                     x1 |--> (1,2,3)
++                     x2 |--> (1,2,3)]
++
+         ALGORITHM:
+         
+         Uses libgap's GQuotients function.
+diff --git a/src/sage/groups/finitely_presented_named.py b/src/sage/groups/finitely_presented_named.py
+index cfd8953..c8075f9 100644
+--- a/src/sage/groups/finitely_presented_named.py
++++ b/src/sage/groups/finitely_presented_named.py
+@@ -447,6 +447,7 @@ def QuaternionPresentation():
+         sage: Q.order(), Q.is_abelian()
+         (8, False)
+         sage: Q.is_isomorphic(groups.presentation.DiCyclic(2))
++        #I  Forcing finiteness test
+         True
+     """
+     F = FreeGroup(['a','b'])
+@@ -546,6 +547,12 @@ def BinaryDihedralPresentation(n):
+         ....:     P = groups.presentation.BinaryDihedral(n)
+         ....:     M = groups.matrix.BinaryDihedral(n)
+         ....:     assert P.is_isomorphic(M)
++        #I  Forcing finiteness test
++        #I  Forcing finiteness test
++        #I  Forcing finiteness test
++        #I  Forcing finiteness test
++        #I  Forcing finiteness test
++        #I  Forcing finiteness test
+     """
+     F = FreeGroup('x,y,z')
+     x,y,z = F.gens()
+diff --git a/src/sage/groups/matrix_gps/finitely_generated.py b/src/sage/groups/matrix_gps/finitely_generated.py
+index 78391d5..1946000 100644
+--- a/src/sage/groups/matrix_gps/finitely_generated.py
++++ b/src/sage/groups/matrix_gps/finitely_generated.py
+@@ -543,7 +543,7 @@ class FinitelyGeneratedMatrixGroup_gap(MatrixGroup_gap):
+         smallest one.
+ 
+         EXAMPLES::
+-        
++
+             sage: MS = MatrixSpace(GF(2), 5, 5)
+             sage: A = MS([[0,0,0,0,1],[0,0,0,1,0],[0,0,1,0,0],[0,1,0,0,0],[1,0,0,0,0]])
+             sage: G = MatrixGroup([A])
+@@ -711,8 +711,8 @@ class FinitelyGeneratedMatrixGroup_gap(MatrixGroup_gap):
+             sage: gens = [MS([[0,1],[-1,0]]),MS([[1,1],[2,3]])]
+             sage: G = MatrixGroup(gens)
+             sage: G.invariant_generators()
+-            [x1^7*x2 - x1*x2^7, 
+-             x1^12 - 2*x1^9*x2^3 - x1^6*x2^6 + 2*x1^3*x2^9 + x2^12, 
++            [x1^7*x2 - x1*x2^7,
++             x1^12 - 2*x1^9*x2^3 - x1^6*x2^6 + 2*x1^3*x2^9 + x2^12,
+              x1^18 + 2*x1^15*x2^3 + 3*x1^12*x2^6 + 3*x1^6*x2^12 - 2*x1^3*x2^15 + x2^18]
+ 
+             sage: q = 4; a = 2
+@@ -1069,10 +1069,10 @@ class FinitelyGeneratedMatrixGroup_gap(MatrixGroup_gap):
+             sage: chi = G.character(G.character_table()[1])
+             sage: R.<x,y,z> = K[]
+             sage: G.reynolds_operator(x*y^5, chi)
+-            1/3*x*y^5 + (-2/3*izeta3^3 - izeta3^2 - 8/3*izeta3 - 4/3)*x^5*z + (2/3*izeta3^3 + izeta3^2 + 8/3*izeta3 + 1)*y*z^5
++            1/3*x*y^5 + (2/3*izeta3^3 + izeta3^2 + 8/3*izeta3 + 1)*x^5*z + (-2/3*izeta3^3 - izeta3^2 - 8/3*izeta3 - 4/3)*y*z^5
+             sage: R.<x,y,z> = QQbar[]
+             sage: G.reynolds_operator(x*y^5, chi)
+-            1/3*x*y^5 + (-0.1666666666666667? + 0.2886751345948129?*I)*x^5*z + (-0.1666666666666667? - 0.2886751345948129?*I)*y*z^5
++             1/3*x*y^5 + (-0.1666666666666667? - 0.2886751345948129?*I)*x^5*z + (-0.1666666666666667? + 0.2886751345948129?*I)*y*z^5
+ 
+         ::
+ 
+@@ -1288,8 +1288,8 @@ class FinitelyGeneratedMatrixGroup_gap(MatrixGroup_gap):
+             sage: chi = G.character(G.character_table()[1])
+             sage: R.<x,y,z> = K[]
+             sage: sorted(G.invariants_of_degree(2, R=R, chi=chi))
+-            [x*y + (-2*izeta3^3 - 3*izeta3^2 - 8*izeta3 - 4)*x*z + (2*izeta3^3 + 3*izeta3^2 + 8*izeta3 + 3)*y*z,
+-             x^2 + (2*izeta3^3 + 3*izeta3^2 + 8*izeta3 + 3)*y^2 + (-2*izeta3^3 - 3*izeta3^2 - 8*izeta3 - 4)*z^2]
++            [x*y + (2*izeta3^3 + 3*izeta3^2 + 8*izeta3 + 3)*x*z + (-2*izeta3^3 - 3*izeta3^2 - 8*izeta3 - 4)*y*z,
++             x^2 + (-2*izeta3^3 - 3*izeta3^2 - 8*izeta3 - 4)*y^2 + (2*izeta3^3 + 3*izeta3^2 + 8*izeta3 + 3)*z^2]
+ 
+         ::
+ 
+diff --git a/src/sage/groups/perm_gps/permgroup.py b/src/sage/groups/perm_gps/permgroup.py
+index 2ae3a51..8b24ee6 100644
+--- a/src/sage/groups/perm_gps/permgroup.py
++++ b/src/sage/groups/perm_gps/permgroup.py
+@@ -325,7 +325,7 @@ def PermutationGroup(gens=None, gap_group=None, domain=None, canonicalize=True,
+         sage: G = PermutationGroup([[(1,2,3),(4,5)],[(3,4)]])
+         sage: current_randstate().set_seed_gap()
+         sage: G._gap_().DerivedSeries()
+-        [ Group( [ (3,4), (1,2,3)(4,5) ] ), Group( [ (1,5)(3,4), (1,5)(2,4), (1,5,3) ] ) ]
++        [ Group( [ (3,4), (1,2,3)(4,5) ] ), Group( [ (1,5)(3,4), (1,5)(2,4), (1,3,5) ] ) ]
+ 
+     TESTS::
+ 
+@@ -3256,7 +3256,7 @@ class PermutationGroup_generic(FiniteGroup):
+             [Subgroup of (Cyclic group of order 14 as a permutation group) generated by [()],
+              Subgroup of (Cyclic group of order 14 as a permutation group) generated by [(1,8)(2,9)(3,10)(4,11)(5,12)(6,13)(7,14)],
+              Subgroup of (Cyclic group of order 14 as a permutation group) generated by [(1,3,5,7,9,11,13)(2,4,6,8,10,12,14)],
+-             Subgroup of (Cyclic group of order 14 as a permutation group) generated by [(1,2,3,4,5,6,7,8,9,10,11,12,13,14)]]
++             Subgroup of (Cyclic group of order 14 as a permutation group) generated by [(1,2,3,4,5,6,7,8,9,10,11,12,13,14), (1,3,5,7,9,11,13)(2,4,6,8,10,12,14)]]
+ 
+         AUTHOR:
+ 
+@@ -3658,7 +3658,8 @@ class PermutationGroup_generic(FiniteGroup):
+             rec(
+               name := "Z(5)",
+               parameter := 5,
+-              series := "Z" )
++              series := "Z",
++              shortname := "C5" )
+ 
+         TESTS:
+ 
+diff --git a/src/sage/groups/perm_gps/permgroup_element.pyx b/src/sage/groups/perm_gps/permgroup_element.pyx
+index 03944d9..d459c0e 100644
+--- a/src/sage/groups/perm_gps/permgroup_element.pyx
++++ b/src/sage/groups/perm_gps/permgroup_element.pyx
+@@ -116,7 +116,7 @@ import sage.structure.coerce as coerce
+ from sage.structure.richcmp cimport richcmp_not_equal, rich_to_bool
+ 
+ from sage.libs.gap.element cimport GapElement_List
+-from sage.libs.gap.gap_includes cimport libGAP_Obj, libGAP_INT_INTOBJ, libGAP_ELM_LIST
++from sage.libs.gap.gap_includes cimport Obj, INT_INTOBJ, ELM_LIST
+ 
+ import operator
+ 
+@@ -951,7 +951,7 @@ cdef class PermutationGroupElement(MultiplicativeGroupElement):
+             (1,4)(2,3)
+         """
+         cdef GapElement_List lst = <GapElement_List?> lst_in
+-        cdef libGAP_Obj obj = lst.value
++        cdef Obj obj = lst.value
+ 
+         cdef PermutationGroupElement new = self._new_c()
+         cdef Py_ssize_t i, j, vn = len(lst)
+@@ -959,7 +959,7 @@ cdef class PermutationGroupElement(MultiplicativeGroupElement):
+         assert vn <= self.n
+ 
+         for i in range(vn):
+-            j = libGAP_INT_INTOBJ(libGAP_ELM_LIST(obj, i+1))
++            j = INT_INTOBJ(ELM_LIST(obj, i+1))
+             new.perm[i] = j - 1
+         for i in range(vn, self.n):
+             new.perm[i] = i
+diff --git a/src/sage/interfaces/gap.py b/src/sage/interfaces/gap.py
+index 55d41aa..8db06a9 100644
+--- a/src/sage/interfaces/gap.py
++++ b/src/sage/interfaces/gap.py
+@@ -1,3 +1,4 @@
++# -*- coding: UTF-8 -*-
+ r"""
+ Interface to GAP
+ 
+@@ -187,6 +188,7 @@ from sage.misc.cachefunc import cached_method
+ from sage.docs.instancedoc import instancedoc
+ from sage.interfaces.tab_completion import ExtraTabCompletion
+ from sage.structure.element import ModuleElement
++
+ import re
+ import os
+ import io
+@@ -194,12 +196,10 @@ import pexpect
+ import time
+ import platform
+ import string
++import warnings
+ 
+ WORKSPACE = gap_workspace_file()
+ 
+-from sage.env import GAP_ROOT_DIR
+-GAP_BINARY = os.path.join(GAP_ROOT_DIR, 'bin', 'gap.sh')
+-
+ first_try = True
+ 
+ gap_cmd = "gap -r"
+@@ -514,7 +514,7 @@ class Gap_generic(ExtraTabCompletion, Expect):
+             RuntimeError: Error loading Gap package chevie. You may want to install the gap_packages and/or database_gap SPKGs.
+         """
+         if verbose:
+-            print("Loading GAP package %s" % pkg)
++            print("Loading GAP package {}" % pkg)
+         x = self.eval('LoadPackage("%s")'%pkg)
+         if x == 'fail':
+             raise RuntimeError("Error loading Gap package "+str(pkg)+". "+
+@@ -610,8 +610,9 @@ class Gap_generic(ExtraTabCompletion, Expect):
+                 current_outputs.append(E.before)
+                 if x == 0:   # @p
+                     if E.after != b'@p1.':
+-                        print("Warning: possibly wrong version of GAP package interface\n")
+-                        print("Crossing fingers and continuing\n")
++                        warnings.warn(
++                            "possibly wrong version of GAP package "
++                            "interface. Crossing fingers and continuing.")
+                 elif x == 1: #@@
+                     current_outputs.append(b'@')
+                 elif x == 2: #special char
+@@ -626,11 +627,11 @@ class Gap_generic(ExtraTabCompletion, Expect):
+                 elif x == 4: # @e -- break loop
+                     E.sendline("quit;")
+                 elif x == 5: # @c completion, doesn't seem to happen when -p is in use
+-                    print("I didn't think GAP could do this\n")
++                    warnings.warn("I didn't think GAP could do this")
+                 elif x == 6: # @f GAP error message
+                     current_outputs = error_outputs;
+                 elif x == 7: # @h help text, but this stopped happening with new help
+-                    print("I didn't think GAP could do this")
++                    warnings.warn("I didn't think GAP could do this")
+                 elif x == 8: # @i awaiting normal input
+                     break;
+                 elif x == 9: # @m finished running a child
+@@ -640,9 +641,9 @@ class Gap_generic(ExtraTabCompletion, Expect):
+                 elif x==11: #@r echoing input
+                     current_outputs = terminal_echo
+                 elif x==12: #@sN shouldn't happen
+-                    print("Warning: this should never happen")
++                    warnings.warn("this should never happen")
+                 elif x==13: #@w GAP is trying to send a Window command
+-                    print("Warning: this should never happen")
++                    warnings.warn("this should never happen")
+                 elif x ==14: #@x seems to be safely ignorable
+                     pass
+                 elif x == 15:#@z GAP starting a subprocess
+@@ -908,17 +909,16 @@ class Gap_generic(ExtraTabCompletion, Expect):
+ 
+             sage: g = Gap()
+             sage: g.function_call("ConjugacyClassesSubgroups", sage.interfaces.gap.GapElement(g, 'SymmetricGroup(2)', name = 'a_variable_with_a_very_very_very_long_name'))
+-            [ ConjugacyClassSubgroups(SymmetricGroup( [ 1 .. 2 ] ),Group( [ () ] )),
+-              ConjugacyClassSubgroups(SymmetricGroup( [ 1 .. 2 ] ),SymmetricGroup( [ 1 .. 2 ] )) ]
++            [ ConjugacyClassSubgroups(SymmetricGroup( [ 1 .. 2 ] ),Group( () )),
++              ConjugacyClassSubgroups(SymmetricGroup( [ 1 .. 2 ] ),Group( [ (1,2) ] )) ]
+ 
+         When the command itself is so long that it warrants use of a temporary
+         file to be communicated to GAP, this does not cause problems since
+         the file will contain a single command::
+ 
+             sage: g.function_call("ConjugacyClassesSubgroups", sage.interfaces.gap.GapElement(g, 'SymmetricGroup(2)', name = 'a_variable_with_a_name_so_very_very_very_long_that_even_by_itself_will_make_expect_use_a_file'))
+-            [ ConjugacyClassSubgroups(SymmetricGroup( [ 1 .. 2 ] ),Group( [ () ] )),
+-              ConjugacyClassSubgroups(SymmetricGroup( [ 1 .. 2 ] ),SymmetricGroup( [ 1 .. 2 ] )) ]
+-
++            [ ConjugacyClassSubgroups(SymmetricGroup( [ 1 .. 2 ] ),Group( () )),
++              ConjugacyClassSubgroups(SymmetricGroup( [ 1 .. 2 ] ),Group( [ (1,2) ] )) ]
+         """
+         args, kwds = self._convert_args_kwds(args, kwds)
+         self._check_valid_function_name(function)
+@@ -1129,13 +1129,20 @@ class Gap(Gap_generic):
+         """
+         self.__use_workspace_cache = use_workspace_cache
+         cmd, self.__make_workspace = gap_command(use_workspace_cache, server is None)
+-        cmd += " -b -p -T"
++        # -b: suppress banner
++        # -p: enable "package output mode"; this confusingly named option
++        #     causes GAP to output special control characters that are normally
++        #     intended for communication with a window manager (i.e. for xgap)
++        #     but that we also use to control GAP with pexepect
++        # -T: disable interactive break loop when encountering errors
++        # -E: disable readline support
++        cmd += " -b -p -T -E"
+         if max_workspace_size is None:
+             max_workspace_size = _get_gap_memory_pool_size_MB()
+         cmd += ' -o ' + str(max_workspace_size)
+         cmd += ' -s ' + str(max_workspace_size)
+         cmd += ' -m 64m '   # attempt at a workaround for http://tracker.gap-system.org/issues/224
+-        cmd += ' ' + os.path.join(SAGE_EXTCODE,'gap','sage.g')
++        cmd += ' ' + os.path.join(SAGE_EXTCODE, 'gap', 'sage.g')
+         Expect.__init__(self,
+                         name='gap',
+                         prompt='gap> ',
+@@ -1343,11 +1350,11 @@ class Gap(Gap_generic):
+ 
+             sage: print(gap.help('SymmetricGroup', pager=False))
+             <BLANKLINE>
+-            50 Group Libraries
++              50.1-... SymmetricGroup
+             <BLANKLINE>
+-            When you start GAP, it already knows several groups. Currently GAP initially
+-            knows the following groups:
++              ‣ SymmetricGroup( [filt, ]deg ) ─────────────────────────────────── function
+             ...
++            <BLANKLINE>
+         """
+         tmp_to_use = self._local_tmpfile()
+         if self.is_remote():
+@@ -1364,6 +1371,7 @@ class Gap(Gap_generic):
+             print(line)
+         else:
+             (sline,) = match.groups()
++            sline = int(sline) - 1
+             if self.is_remote():
+                 self._get_tmpfile()
+             with io.open(self._local_tmpfile(), "r",
+@@ -1371,9 +1379,20 @@ class Gap(Gap_generic):
+                 help = fobj.read()
+                 if pager:
+                     from IPython.core.page import page
+-                    page(help, start=int(sline) - 1)
++                    page(help, start=sline)
+                 else:
+-                    return help
++                    # Find the n-th line and return from there
++                    idx = -1
++                    while sline:
++                        try:
++                            idx = help.find('\n', idx + 1)
++                            sline -= 1
++                        except ValueError:
++                            # We ran out of lines early somehow; this shouldn't
++                            # happen though
++                            break
++
++                    return help[idx:]
+ 
+     def set(self, var, value):
+         """
+@@ -1552,8 +1571,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('SetUserPreference("HistoryMaxLines", 30)')
+-    for pkg in ['GAPDoc', 'ctbllib', 'sonata', 'guava', 'factint', \
+-                'gapdoc', 'grape', 'design', \
++    for pkg in ['GAPDoc', 'ctbllib', 'sonata', 'guava', 'factint',
++                'gapdoc', 'grape', 'design',
+                 'toric', 'laguna', 'braid', 'polycyclic', 'nq']:
+         # NOTE: Do *not* autoload hap - it screws up PolynomialRing(Rationals,2)
+         try:
+@@ -1647,10 +1666,9 @@ class GapFunctionElement(FunctionElement):
+ 
+             sage: print(gap(4).SymmetricGroup.__doc__)
+             <BLANKLINE>
+-            50 Group Libraries
++              50.1-... SymmetricGroup
+             <BLANKLINE>
+-            When you start GAP, it already knows several groups. Currently GAP initially
+-            knows the following groups:
++              ‣ SymmetricGroup( [filt, ]deg ) ─────────────────────────────────── function
+             ...
+         """
+         M = self._obj.parent()
+@@ -1660,16 +1678,15 @@ class GapFunctionElement(FunctionElement):
+ 
+ @instancedoc
+ class GapFunction(ExpectFunction):
+-    def _instancedoc(self):
++    def _instancedoc_(self):
+         """
+         EXAMPLES::
+ 
+             sage: print(gap.SymmetricGroup.__doc__)
+             <BLANKLINE>
+-            50 Group Libraries
++              50.1-... SymmetricGroup
+             <BLANKLINE>
+-            When you start GAP, it already knows several groups. Currently GAP initially
+-            knows the following groups:
++              ‣ SymmetricGroup( [filt, ]deg ) ─────────────────────────────────── function
+             ...
+         """
+         M = self._parent
+diff --git a/src/sage/knots/link.py b/src/sage/knots/link.py
+index fe11d9c..7e305c4 100644
+--- a/src/sage/knots/link.py
++++ b/src/sage/knots/link.py
+@@ -479,9 +479,8 @@ class Link(object):
+              x1*x3^-1*x2^-1*x3, x3*x1^-1*x0^-1*x1 >
+             sage: GB = K8.fundamental_group(presentation='braid')
+             sage: GB
+-            Finitely presented group < x0, x1, x2 |
+-             x1*x2^-1*x1^-1*x0*x1*x2*x1*x2^-1*x1^-1*x0^-1*x1*x2*x1^-1*x0^-1,
+-             x1*x2^-1*x1^-1*x0*x1*x2*x1^-1*x2^-1*x1^-1*x0^-1*x1*x2*x1^-1*x0*x1*x2*x1*x2^-1*x1^-1*x0^-1*x1*x2*x1^-2, x1*x2^-1*x1^-1*x0*x1*x2*x1^-1*x2^-1 >
++            Finitely presented group < x0, x1, x2 | x1*x2^-1*x1^-1*x0*x1*x2*x1*x2^-1*x1^-1*x0^-1*x1*x2*x1^-1*x0^-1, x1*x2^-1*x1^-1*x0*x1*x2*x1^-1*x2^-1*x1^-1*x0^-1*x1*x2*x1^-1*x0*x1*x2*x1*x2^-1*\
++            x1^-1*x0^-1*x1*x2*x1^-2, x1*x2^-1*x1^-1*x0*x1*x2*x1^-1*x2^-1 >
+             sage: GA.simplified()
+             Finitely presented group < x0, x1 |
+              x1^-1*x0*x1*x0^-1*x1*x0*x1^-1*x0^-1*x1*x0^-1 >
+diff --git a/src/sage/libs/gap/assigned_names.py b/src/sage/libs/gap/assigned_names.py
+index a3633a4..ab5d973 100644
+--- a/src/sage/libs/gap/assigned_names.py
++++ b/src/sage/libs/gap/assigned_names.py
+@@ -27,7 +27,7 @@ from sage.libs.gap.saved_workspace import workspace
+ 
+ 
+ NamesGVars = libgap.function_factory('NamesGVars')
+-Filtered =libgap.function_factory('Filtered')
++Filtered = libgap.function_factory('Filtered')
+ ValueGlobal = libgap.function_factory('ValueGlobal')
+ IsBoundGlobal = libgap.function_factory('IsBoundGlobal')
+ IsFunction = libgap.function_factory('IsFunction')
+diff --git a/src/sage/libs/gap/element.pxd b/src/sage/libs/gap/element.pxd
+index c803ade..74e7d6c 100644
+--- a/src/sage/libs/gap/element.pxd
++++ b/src/sage/libs/gap/element.pxd
+@@ -8,31 +8,31 @@
+ #                  http://www.gnu.org/licenses/
+ #*****************************************************************************
+ 
+-from .types cimport libGAP_Obj, libGAP_UInt
++from .gap_includes cimport Obj, UInt
+ from sage.structure.sage_object cimport SageObject
+ from sage.structure.element cimport Element, ModuleElement, RingElement
+ 
+-cdef libGAP_Obj make_gap_list(sage_list) except NULL
+-cdef libGAP_Obj make_gap_record(sage_dict) except NULL
+-cdef libGAP_Obj make_gap_integer(sage_dict) except NULL
+-cdef libGAP_Obj make_gap_string(sage_string) except NULL
+-
+-cdef GapElement make_any_gap_element(parent, libGAP_Obj obj)
+-cdef GapElement make_GapElement(parent, libGAP_Obj obj)
+-cdef GapElement_List make_GapElement_List(parent, libGAP_Obj obj)
+-cdef GapElement_Record make_GapElement_Record(parent, libGAP_Obj obj)
+-cdef GapElement_Integer make_GapElement_Integer(parent, libGAP_Obj obj)
+-cdef GapElement_Rational make_GapElement_Rational(parent, libGAP_Obj obj)
+-cdef GapElement_String make_GapElement_String(parent, libGAP_Obj obj)
+-cdef GapElement_Boolean make_GapElement_Boolean(parent, libGAP_Obj obj)
+-cdef GapElement_Function make_GapElement_Function(parent, libGAP_Obj obj)
++cdef Obj make_gap_list(sage_list) except NULL
++cdef Obj make_gap_record(sage_dict) except NULL
++cdef Obj make_gap_integer(sage_dict) except NULL
++cdef Obj make_gap_string(sage_string) except NULL
+ 
++cdef GapElement make_any_gap_element(parent, Obj obj)
++cdef GapElement make_GapElement(parent, Obj obj)
++cdef GapElement_List make_GapElement_List(parent, Obj obj)
++cdef GapElement_Record make_GapElement_Record(parent, Obj obj)
++cdef GapElement_Integer make_GapElement_Integer(parent, Obj obj)
++cdef GapElement_Rational make_GapElement_Rational(parent, Obj obj)
++cdef GapElement_String make_GapElement_String(parent, Obj obj)
++cdef GapElement_Boolean make_GapElement_Boolean(parent, Obj obj)
++cdef GapElement_Function make_GapElement_Function(parent, Obj obj)
++cdef char *crepr(Obj)
+ 
+ 
+ cdef class GapElement(RingElement):
+ 
+     # the pointer to the GAP object (memory managed by GASMAN)
+-    cdef libGAP_Obj value
++    cdef Obj value
+ 
+     # comparison
+     cdef bint _compare_by_id
+@@ -41,7 +41,7 @@ cdef class GapElement(RingElement):
+     cpdef _set_compare_by_id(self)
+     cpdef _assert_compare_by_id(self)
+ 
+-    cdef _initialize(self, parent, libGAP_Obj obj)
++    cdef _initialize(self, parent, Obj obj)
+     cpdef _type_number(self)
+     cpdef is_bool(self)
+     cpdef _add_(self, other)
+@@ -81,11 +81,11 @@ cdef class GapElement_MethodProxy(GapElement_Function):
+     cdef GapElement first_argument
+ 
+ cdef class GapElement_Record(GapElement):
+-    cpdef libGAP_UInt record_name_to_index(self, name)
++    cpdef UInt record_name_to_index(self, name)
+ 
+ cdef class GapElement_RecordIterator(object):
+     cdef GapElement_Record rec
+-    cdef libGAP_UInt i
++    cdef UInt i
+ 
+ cdef class GapElement_List(GapElement):
+     pass
+diff --git a/src/sage/libs/gap/element.pyx b/src/sage/libs/gap/element.pyx
+index 446c393..0aa9c32 100644
+--- a/src/sage/libs/gap/element.pyx
++++ b/src/sage/libs/gap/element.pyx
+@@ -23,7 +23,7 @@ from cysignals.signals cimport sig_on, sig_off
+ 
+ from .gap_includes cimport *
+ from .util cimport *
+-from sage.cpython.string cimport char_to_str, str_to_bytes
++from sage.cpython.string cimport str_to_bytes, char_to_str
+ from sage.misc.cachefunc import cached_method
+ from sage.structure.sage_object cimport SageObject
+ from sage.structure.parent import Parent
+@@ -33,33 +33,33 @@ from sage.groups.perm_gps.permgroup_element cimport PermutationGroupElement
+ from sage.combinat.permutation import Permutation
+ 
+ decode_type_number = {
+-    libGAP_T_INT: 'T_INT (integer)',
+-    libGAP_T_INTPOS: 'T_INTPOS (positive integer)',
+-    libGAP_T_INTNEG: 'T_INTNEG (negative integer)',
+-    libGAP_T_RAT: 'T_RAT (rational number)',
+-    libGAP_T_CYC: 'T_CYC (universal cylotomic)',
+-    libGAP_T_FFE: 'T_FFE (finite field element)',
+-    libGAP_T_PERM2: 'T_PERM2',
+-    libGAP_T_PERM4: 'T_PERM4',
+-    libGAP_T_BOOL: 'T_BOOL',
+-    libGAP_T_CHAR: 'T_CHAR',
+-    libGAP_T_FUNCTION: 'T_FUNCTION',
+-    libGAP_T_PLIST: 'T_PLIST',
+-    libGAP_T_PLIST_CYC: 'T_PLIST_CYC',
+-    libGAP_T_BLIST: 'T_BLIST',
+-    libGAP_T_STRING: 'T_STRING',
+-    libGAP_T_MACFLOAT: 'T_MACFLOAT (hardware floating point number)',
+-    libGAP_T_COMOBJ: 'T_COMOBJ (component object)',
+-    libGAP_T_POSOBJ: 'T_POSOBJ (positional object)',
+-    libGAP_T_DATOBJ: 'T_DATOBJ (data object)',
+-    libGAP_T_WPOBJ:  'T_WPOBJ (weak pointer object)',
++    0: 'T_INT (integer)',
++    T_INTPOS: 'T_INTPOS (positive integer)',
++    T_INTNEG: 'T_INTNEG (negative integer)',
++    T_RAT: 'T_RAT (rational number)',
++    T_CYC: 'T_CYC (universal cylotomic)',
++    T_FFE: 'T_FFE (finite field element)',
++    T_PERM2: 'T_PERM2',
++    T_PERM4: 'T_PERM4',
++    T_BOOL: 'T_BOOL',
++    T_CHAR: 'T_CHAR',
++    T_FUNCTION: 'T_FUNCTION',
++    T_PLIST: 'T_PLIST',
++    T_PLIST_CYC: 'T_PLIST_CYC',
++    T_BLIST: 'T_BLIST',
++    T_STRING: 'T_STRING',
++    T_MACFLOAT: 'T_MACFLOAT (hardware floating point number)',
++    T_COMOBJ: 'T_COMOBJ (component object)',
++    T_POSOBJ: 'T_POSOBJ (positional object)',
++    T_DATOBJ: 'T_DATOBJ (data object)',
++    T_WPOBJ:  'T_WPOBJ (weak pointer object)',
+     }
+ 
+ ############################################################################
+ ### helper functions to construct lists and records ########################
+ ############################################################################
+ 
+-cdef libGAP_Obj make_gap_list(sage_list) except NULL:
++cdef Obj make_gap_list(sage_list) except NULL:
+     """
+     Convert Sage lists into Gap lists
+ 
+@@ -71,15 +71,50 @@ cdef libGAP_Obj make_gap_list(sage_list) except NULL:
+ 
+     The list of the elements in ``a`` as a Gap ``Obj``.
+     """
+-    # FIXME slow -- to make fast directly use ADD_LIST in Gap's C code.
+     from sage.libs.gap.libgap import libgap
+     cdef GapElement l = libgap.eval('[]')
++    cdef GapElement elem
+     for x in sage_list:
+-        l.Add(x)
++        if not isinstance(x, GapElement):
++            elem = <GapElement>libgap(x)
++        else:
++            elem = <GapElement>x
++
++        AddList(l.value, elem.value)
+     return l.value
+ 
+ 
+-cdef libGAP_Obj make_gap_record(sage_dict) except NULL:
++cdef char *crepr(Obj obj):
++    cdef Obj s, stream, output_text_string, view_obj
++    cdef UInt res
++    # 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,
++    # and there is no equivalent that simply returns the string that would be
++    # printed.  The closest approximation would be DisplayString, but this
++    # bypasses any type-specific overrides for ViewObj so for many objects
++    # that does not give consistent results.
++    # TODO: This is probably needlessly slow, but we might need better
++    # support from GAP to improve this...
++    try:
++        GAP_Enter()
++        s = NEW_STRING(0)
++        output_text_string = GAP_ValueGlobalVariable("OutputTextString")
++        stream = CALL_2ARGS(output_text_string, s, GAP_True)
++
++        if not OpenOutputStream(stream):
++            raise RuntimeError("failed to open output capture stream for "
++                               "representing GAP object")
++
++        viewobj = GAP_ValueGlobalVariable("ViewObj")
++        CALL_1ARGS(viewobj, obj)
++        CloseOutput()
++        return CSTR_STRING(s)
++    finally:
++        GAP_Leave()
++
++
++cdef Obj make_gap_record(sage_dict) except NULL:
+     """
+     Convert Sage lists into Gap lists
+ 
+@@ -99,19 +134,23 @@ cdef libGAP_Obj make_gap_record(sage_dict) except NULL:
+     from sage.libs.gap.libgap import libgap
+     data = [ (str(key), libgap(value)) for key, value in sage_dict.iteritems() ]
+ 
+-    libgap_enter()
+-    cdef libGAP_Obj rec = libGAP_NEW_PREC(len(data))
++    cdef Obj rec
+     cdef GapElement val
+-    cdef libGAP_UInt rnam
+-    for d in data:
+-        key, val = d
+-        rnam = libGAP_RNamName(str_to_bytes(key))
+-        libGAP_AssPRec(rec, rnam, val.value)
+-    libgap_exit()
+-    return rec
++    cdef UInt rnam
+ 
++    try:
++        GAP_Enter()
++        rec = NEW_PREC(len(data))
++        for d in data:
++            key, val = d
++            rnam = RNamName(str_to_bytes(key))
++            AssPRec(rec, rnam, val.value)
++        return rec
++    finally:
++        GAP_Leave()
+ 
+-cdef libGAP_Obj make_gap_integer(sage_int) except NULL:
++
++cdef Obj make_gap_integer(sage_int) except NULL:
+     """
+     Convert Sage integer into Gap integer
+ 
+@@ -128,19 +167,22 @@ cdef libGAP_Obj make_gap_integer(sage_int) except NULL:
+         sage: libgap(1)   # indirect doctest
+         1
+     """
+-    libgap_enter()
+-    cdef libGAP_Obj result = libGAP_INTOBJ_INT(<int>sage_int)
+-    libgap_exit()
+-    return result
++    cdef Obj result
++    try:
++        GAP_Enter()
++        result = INTOBJ_INT(<int>sage_int)
++        return result
++    finally:
++        GAP_Leave()
+ 
+ 
+-cdef libGAP_Obj make_gap_string(sage_string) except NULL:
++cdef Obj make_gap_string(sage_string) except NULL:
+     """
+-    Convert a Sage string to a Gap string
++    Convert a Python string to a Gap string
+ 
+     INPUT:
+ 
+-    - ``sage_string`` -- a Sage integer.
++    - ``sage_string`` -- a Python str.
+ 
+     OUTPUT:
+ 
+@@ -151,19 +193,21 @@ cdef libGAP_Obj make_gap_string(sage_string) except NULL:
+         sage: libgap('string')   # indirect doctest
+         "string"
+     """
+-    libgap_enter()
+-    cdef libGAP_Obj result
+-    sage_string = str_to_bytes(sage_string)
+-    libGAP_C_NEW_STRING(result, len(sage_string), sage_string)
+-    libgap_exit()
+-    return result
++    cdef Obj result
++    try:
++        GAP_Enter()
++        b = str_to_bytes(sage_string)
++        C_NEW_STRING(result, len(b), b)
++        return result
++    finally:
++        GAP_Leave()
+ 
+ 
+ ############################################################################
+ ### generic construction of GapElements ####################################
+ ############################################################################
+ 
+-cdef GapElement make_any_gap_element(parent, libGAP_Obj obj):
++cdef GapElement make_any_gap_element(parent, Obj obj):
+     """
+     Return the libGAP element wrapper of ``obj``
+ 
+@@ -199,55 +243,59 @@ cdef GapElement make_any_gap_element(parent, libGAP_Obj obj):
+         sage: irr[1]
+         0
+     """
+-    if obj is NULL:
+-        return make_GapElement(parent, obj)
+-    cdef int num = libGAP_TNUM_OBJ(obj)
+-    if num == libGAP_T_INT or num == libGAP_T_INTPOS or num == libGAP_T_INTNEG:
+-        return make_GapElement_Integer(parent, obj)
+-    elif num == libGAP_T_MACFLOAT:
+-        return make_GapElement_Float(parent, obj)
+-    elif num == libGAP_T_CYC:
+-        return make_GapElement_Cyclotomic(parent, obj)
+-    elif num == libGAP_T_FFE:
+-        return make_GapElement_FiniteField(parent, obj)
+-    elif num == libGAP_T_RAT:
+-        return make_GapElement_Rational(parent, obj)
+-    elif num == libGAP_T_BOOL:
+-        return make_GapElement_Boolean(parent, obj)
+-    elif num == libGAP_T_FUNCTION:
+-        return make_GapElement_Function(parent, obj)
+-    elif num == libGAP_T_PERM2 or num == libGAP_T_PERM4:
+-        return make_GapElement_Permutation(parent, obj)
+-    elif libGAP_FIRST_RECORD_TNUM <= num <= libGAP_LAST_RECORD_TNUM:
+-        return make_GapElement_Record(parent, obj)
+-    elif libGAP_FIRST_LIST_TNUM <= num <= libGAP_LAST_LIST_TNUM and libGAP_LEN_PLIST(obj) == 0:
+-        # Empty lists are lists and not strings in Python
+-        return make_GapElement_List(parent, obj)
+-    elif libGAP_IsStringConv(obj):
+-        # GAP strings are lists, too. Make sure this comes before non-empty make_GapElement_List
+-        return make_GapElement_String(parent, obj)
+-    elif libGAP_IS_LIST(obj):
+-        return make_GapElement_List(parent, obj)
+-    elif num == libGAP_T_CHAR:
+-        ch = make_GapElement(parent, obj).IntChar().sage()
+-        return make_GapElement_String(parent, make_gap_string(chr(ch)))
+-    result = make_GapElement(parent, obj)
+-    if num == libGAP_T_POSOBJ:
+-        if result.IsZmodnZObj():
+-            return make_GapElement_IntegerMod(parent, obj)
+-    if num == libGAP_T_COMOBJ:
+-        if result.IsRing():
+-            return make_GapElement_Ring(parent, obj)
+-    return result
+-
++    cdef int num
+ 
++    try:
++        GAP_Enter()
++        if obj is NULL:
++            return make_GapElement(parent, obj)
++        num = TNUM_OBJ(obj)
++        if IS_INT(obj):
++            return make_GapElement_Integer(parent, obj)
++        elif num == T_MACFLOAT:
++            return make_GapElement_Float(parent, obj)
++        elif num == T_CYC:
++            return make_GapElement_Cyclotomic(parent, obj)
++        elif num == T_FFE:
++            return make_GapElement_FiniteField(parent, obj)
++        elif num == T_RAT:
++            return make_GapElement_Rational(parent, obj)
++        elif num == T_BOOL:
++            return make_GapElement_Boolean(parent, obj)
++        elif num == T_FUNCTION:
++            return make_GapElement_Function(parent, obj)
++        elif num == T_PERM2 or num == T_PERM4:
++            return make_GapElement_Permutation(parent, obj)
++        elif IS_REC(obj):
++            return make_GapElement_Record(parent, obj)
++        elif IS_LIST(obj) and LEN_LIST(obj) == 0:
++            # Empty lists are lists and not strings in Python
++            return make_GapElement_List(parent, obj)
++        elif IsStringConv(obj):
++            # GAP strings are lists, too. Make sure this comes before non-empty make_GapElement_List
++            return make_GapElement_String(parent, obj)
++        elif IS_LIST(obj):
++            return make_GapElement_List(parent, obj)
++        elif num == T_CHAR:
++            ch = make_GapElement(parent, obj).IntChar().sage()
++            return make_GapElement_String(parent, make_gap_string(chr(ch)))
++        result = make_GapElement(parent, obj)
++        if num == T_POSOBJ:
++            if result.IsZmodnZObj():
++                return make_GapElement_IntegerMod(parent, obj)
++        if num == T_COMOBJ:
++            if result.IsRing():
++                return make_GapElement_Ring(parent, obj)
++        return result
++    finally:
++        GAP_Leave()
+ 
+ 
+ ############################################################################
+ ### GapElement #############################################################
+ ############################################################################
+ 
+-cdef GapElement make_GapElement(parent, libGAP_Obj obj):
++cdef GapElement make_GapElement(parent, Obj obj):
+     r"""
+     Turn a Gap C object (of type ``Obj``) into a Cython ``GapElement``.
+ 
+@@ -270,8 +318,6 @@ cdef GapElement make_GapElement(parent, libGAP_Obj obj):
+         <type 'sage.libs.gap.element.GapElement_Integer'>
+ 
+         sage: libgap.eval('')
+-        NULL
+-
+         sage: libgap(None)
+         Traceback (most recent call last):
+         ...
+@@ -344,7 +390,7 @@ cdef class GapElement(RingElement):
+         """
+         raise TypeError('this class cannot be instantiated from Python')
+ 
+-    cdef _initialize(self, parent, libGAP_Obj obj):
++    cdef _initialize(self, parent, Obj obj):
+         r"""
+         Initialize the GapElement.
+ 
+@@ -424,8 +470,8 @@ cdef class GapElement(RingElement):
+             sage: a
+             [ [ 0, -2 ], [ 2, 3, 4 ] ]
+         """
+-        if libGAP_IS_MUTABLE_OBJ(self.value):
+-            return make_any_gap_element(self.parent(), libGAP_SHALLOW_COPY_OBJ(self.value))
++        if IS_MUTABLE_OBJ(self.value):
++            return make_any_gap_element(self.parent(), SHALLOW_COPY_OBJ(self.value))
+         else:
+             return self
+ 
+@@ -456,8 +502,8 @@ cdef class GapElement(RingElement):
+             sage: l.deepcopy(1).IsMutable()
+             true
+         """
+-        if libGAP_IS_MUTABLE_OBJ(self.value):
+-            return make_any_gap_element(self.parent(), libGAP_CopyObj(self.value, mut))
++        if IS_MUTABLE_OBJ(self.value):
++            return make_any_gap_element(self.parent(), CopyObj(self.value, mut))
+         else:
+             return self
+ 
+@@ -514,7 +560,7 @@ cdef class GapElement(RingElement):
+             sage: x._type_number()
+             (0L, 'T_INT (integer)')
+         """
+-        n = libGAP_TNUM_OBJ(self.value)
++        n = TNUM_OBJ(self.value)
+         global decode_type_number
+         name = decode_type_number.get(n, 'unknown')
+         return (n, name)
+@@ -592,7 +638,6 @@ cdef class GapElement(RingElement):
+             sage: libgap(0)
+             0
+             sage: libgap.eval('')
+-            NULL
+             sage: libgap(0)
+             0
+             sage: libgap(0)._repr_()
+@@ -600,15 +645,9 @@ cdef class GapElement(RingElement):
+         """
+         if  self.value == NULL:
+             return 'NULL'
+-        try:
+-            libgap_enter()
+-            libgap_start_interaction('')
+-            libGAP_ViewObjHandler(self.value)
+-            s = char_to_str(libgap_get_output())
+-            return s.strip()
+-        finally:
+-            libgap_finish_interaction()
+-            libgap_exit()
++
++        s = char_to_str(crepr(self.value))
++        return s.strip()
+ 
+     cpdef _set_compare_by_id(self):
+         """
+@@ -777,17 +816,15 @@ cdef class GapElement(RingElement):
+         if self._compare_by_id:
+             return id(self) == id(other)
+         cdef GapElement c_other = <GapElement>other
+-        cdef bint result
+-        libgap_enter()
++        sig_on()
+         try:
+-            sig_on()
+-            result = libGAP_EQ(self.value, c_other.value)
+-            sig_off()
++            GAP_Enter()
++            return EQ(self.value, c_other.value)
+         except RuntimeError as msg:
+             raise ValueError('libGAP: cannot compare equality: '+str(msg))
+         finally:
+-            libgap_exit()
+-        return result
++            GAP_Leave()
++            sig_off()
+ 
+     cdef bint _compare_less(self, Element other) except -2:
+         """
+@@ -802,18 +839,16 @@ cdef class GapElement(RingElement):
+         """
+         if self._compare_by_id:
+             return id(self) < id(other)
+-        cdef bint result
+         cdef GapElement c_other = <GapElement>other
+-        libgap_enter()
++        sig_on()
+         try:
+-            sig_on()
+-            result = libGAP_LT(self.value, c_other.value)
+-            sig_off()
++            GAP_Enter()
++            return LT(self.value, c_other.value)
+         except RuntimeError as msg:
+             raise ValueError('libGAP: cannot compare less than: '+str(msg))
+         finally:
+-            libgap_exit()
+-        return result
++            GAP_Leave()
++            sig_off()
+ 
+     cpdef _add_(self, right):
+         r"""
+@@ -834,18 +869,17 @@ cdef class GapElement(RingElement):
+             ValueError: libGAP: Error, no method found!
+             Error, no 1st choice method found for `+' on 2 arguments
+         """
+-        cdef libGAP_Obj result
++        cdef Obj result
++        sig_on()
+         try:
+-            libgap_enter()
+-            sig_on()
+-            result = libGAP_SUM(self.value, (<GapElement>right).value)
+-            sig_off()
++            GAP_Enter()
++            result = SUM(self.value, (<GapElement>right).value)
++            return make_any_gap_element(self.parent(), result)
+         except RuntimeError as msg:
+-            libGAP_ClearError()
+             raise ValueError('libGAP: '+str(msg))
+         finally:
+-            libgap_exit()
+-        return make_any_gap_element(self.parent(), result)
++            GAP_Leave()
++            sig_off()
+ 
+ 
+     cpdef _sub_(self, right):
+@@ -867,18 +901,17 @@ cdef class GapElement(RingElement):
+             ValueError: libGAP: Error, no method found!
+             Error, no 1st choice method found for `-' on 2 arguments
+         """
+-        cdef libGAP_Obj result
++        cdef Obj result
++        sig_on()
+         try:
+-            libgap_enter()
+-            sig_on()
+-            result = libGAP_DIFF(self.value, (<GapElement>right).value)
+-            sig_off()
++            GAP_Enter()
++            result = DIFF(self.value, (<GapElement>right).value)
++            return make_any_gap_element(self.parent(), result)
+         except RuntimeError as msg:
+-            libGAP_ClearError()
+             raise ValueError('libGAP: {}'.format(msg))
+         finally:
+-            libgap_exit()
+-        return make_any_gap_element(self.parent(), result)
++            GAP_Leave()
++            sig_off()
+ 
+ 
+     cpdef _mul_(self, right):
+@@ -900,18 +933,17 @@ cdef class GapElement(RingElement):
+             ValueError: libGAP: Error, no method found!
+             Error, no 1st choice method found for `*' on 2 arguments
+         """
+-        cdef libGAP_Obj result
++        cdef Obj result
++        sig_on()
+         try:
+-            libgap_enter()
+-            sig_on()
+-            result = libGAP_PROD(self.value, (<GapElement>right).value)
+-            sig_off()
++            GAP_Enter()
++            result = PROD(self.value, (<GapElement>right).value)
++            return make_any_gap_element(self.parent(), result)
+         except RuntimeError as msg:
+-            libGAP_ClearError()
+             raise ValueError('libGAP: {}'.format(msg))
+         finally:
+-            libgap_exit()
+-        return make_any_gap_element(self.parent(), result)
++            GAP_Leave()
++            sig_off()
+ 
+ 
+     cpdef _div_(self, right):
+@@ -938,18 +970,17 @@ cdef class GapElement(RingElement):
+             ...
+             ValueError: libGAP: Error, Rational operations: <divisor> must not be zero
+         """
+-        cdef libGAP_Obj result
++        cdef Obj result
++        sig_on()
+         try:
+-            libgap_enter()
+-            sig_on()
+-            result = libGAP_QUO(self.value, (<GapElement>right).value)
+-            sig_off()
++            GAP_Enter()
++            result = QUO(self.value, (<GapElement>right).value)
++            return make_any_gap_element(self.parent(), result)
+         except RuntimeError as msg:
+-            libGAP_ClearError()
+             raise ValueError('libGAP: '+str(msg))
+         finally:
+-            libgap_exit()
+-        return make_any_gap_element(self.parent(), result)
++            GAP_Leave()
++            sig_off()
+ 
+     cpdef _mod_(self, right):
+         r"""
+@@ -968,18 +999,17 @@ cdef class GapElement(RingElement):
+             ValueError: libGAP: Error, no method found!
+             Error, no 1st choice method found for `mod' on 2 arguments
+         """
+-        cdef libGAP_Obj result
++        cdef Obj result
++        sig_on()
+         try:
+-            libgap_enter()
+-            sig_on()
+-            result = libGAP_MOD(self.value, (<GapElement>right).value)
+-            sig_off()
++            GAP_Enter()
++            result = MOD(self.value, (<GapElement>right).value)
++            return make_any_gap_element(self.parent(), result)
+         except RuntimeError as msg:
+-            libGAP_ClearError()
+             raise ValueError('libGAP: '+str(msg))
+         finally:
+-            libgap_exit()
+-        return make_any_gap_element(self.parent(), result)
++            GAP_Leave()
++            sig_off()
+ 
+ 
+     def __pow__(GapElement self, right, dummy):
+@@ -1008,18 +1038,17 @@ cdef class GapElement(RingElement):
+         if not isinstance(right, GapElement):
+             libgap = self.parent()
+             right = libgap(right)
+-        cdef libGAP_Obj result
++        cdef Obj result
++        sig_on()
+         try:
+-            libgap_enter()
+-            sig_on()
+-            result = libGAP_POW(self.value, (<GapElement>right).value)
+-            sig_off()
++            GAP_Enter()
++            result = POW(self.value, (<GapElement>right).value)
++            return make_any_gap_element(self.parent(), result)
+         except RuntimeError as msg:
+-            libGAP_ClearError()
+             raise ValueError('libGAP: ' + str(msg))
+         finally:
+-            libgap_exit()
+-        return make_any_gap_element(self.parent(), result)
++            GAP_Leave()
++            sig_off()
+ 
+ 
+     def is_function(self):
+@@ -1039,7 +1068,7 @@ cdef class GapElement(RingElement):
+             sage: a.is_function()
+             False
+         """
+-        return libGAP_IS_FUNC(self.value)
++        return IS_FUNC(self.value)
+ 
+ 
+     def is_list(self):
+@@ -1057,7 +1086,7 @@ cdef class GapElement(RingElement):
+             sage: libgap.eval('3/2').is_list()
+             False
+         """
+-        return libGAP_IS_LIST(self.value)
++        return IS_LIST(self.value)
+ 
+ 
+     def is_record(self):
+@@ -1075,7 +1104,7 @@ cdef class GapElement(RingElement):
+             sage: libgap.eval('rec(a:=1, b:=3)').is_record()
+             True
+         """
+-        return libGAP_IS_REC(self.value)
++        return IS_REC(self.value)
+ 
+ 
+     cpdef is_bool(self):
+@@ -1093,9 +1122,8 @@ cdef class GapElement(RingElement):
+         """
+         libgap = self.parent()
+         cdef GapElement r_sage = libgap.IsBool(self)
+-        cdef libGAP_Obj r_gap = r_sage.value
+-        return r_gap == libGAP_True
+-
++        cdef Obj r_gap = r_sage.value
++        return r_gap == GAP_True
+ 
+     def is_string(self):
+         r"""
+@@ -1110,7 +1138,7 @@ cdef class GapElement(RingElement):
+             sage: libgap('this is a string').is_string()
+             True
+         """
+-        return libGAP_IS_STRING(self.value)
++        return IS_STRING(self.value)
+ 
+ 
+     def is_permutation(self):
+@@ -1130,8 +1158,8 @@ cdef class GapElement(RingElement):
+             sage: libgap('this is a string').is_permutation()
+             False
+         """
+-        return (libGAP_TNUM_OBJ(self.value) == libGAP_T_PERM2 or
+-                libGAP_TNUM_OBJ(self.value) == libGAP_T_PERM4)
++        return (TNUM_OBJ(self.value) == T_PERM2 or
++                TNUM_OBJ(self.value) == T_PERM4)
+ 
+ 
+     def sage(self):
+@@ -1191,7 +1219,7 @@ cdef class GapElement(RingElement):
+ ### GapElement_Integer #####################################################
+ ############################################################################
+ 
+-cdef GapElement_Integer make_GapElement_Integer(parent, libGAP_Obj obj):
++cdef GapElement_Integer make_GapElement_Integer(parent, Obj obj):
+     r"""
+     Turn a Gap integer object into a GapElement_Integer Sage object
+ 
+@@ -1250,7 +1278,7 @@ cdef class GapElement_Integer(GapElement):
+             sage: N.IsInt()
+             true
+         """
+-        return libGAP_IS_INTOBJ(self.value)
++        return IS_INTOBJ(self.value)
+ 
+     def _rational_(self):
+         r"""
+@@ -1301,7 +1329,7 @@ cdef class GapElement_Integer(GapElement):
+         if ring is None:
+             ring = ZZ
+         if self.is_C_int():
+-            return ring(libGAP_INT_INTOBJ(self.value))
++            return ring(INT_INTOBJ(self.value))
+         else:
+             # TODO: waste of time!
+             # gap integers are stored as a mp_limb_t and we have a much more direct
+@@ -1318,13 +1346,13 @@ cdef class GapElement_Integer(GapElement):
+ 
+             sage: int(libgap(3))
+             3
+-            sage: type(_) is int
+-            True
++            sage: type(_)
++            <... 'int'>
+ 
+             sage: int(libgap(2)**128)
+             340282366920938463463374607431768211456L
+-            sage: type(_) is long
+-            True
++            sage: type(_)
++            <type 'long'>
+         """
+         return self.sage(ring=int)
+ 
+@@ -1345,7 +1373,7 @@ cdef class GapElement_Integer(GapElement):
+ ### GapElement_Float #####################################################
+ ##########################################################################
+ 
+-cdef GapElement_Float make_GapElement_Float(parent, libGAP_Obj obj):
++cdef GapElement_Float make_GapElement_Float(parent, Obj obj):
+     r"""
+     Turn a Gap macfloat object into a GapElement_Float Sage object
+ 
+@@ -1401,7 +1429,7 @@ cdef class GapElement_Float(GapElement):
+         """
+         if ring is None:
+             ring = RDF
+-        return ring(libGAP_VAL_MACFLOAT(self.value))
++        return ring(VAL_MACFLOAT(self.value))
+ 
+     def __float__(self):
+         r"""
+@@ -1410,7 +1438,7 @@ cdef class GapElement_Float(GapElement):
+             sage: float(libgap.eval("Float(3.5)"))
+             3.5
+         """
+-        return libGAP_VAL_MACFLOAT(self.value)
++        return VAL_MACFLOAT(self.value)
+ 
+ 
+ 
+@@ -1418,7 +1446,7 @@ cdef class GapElement_Float(GapElement):
+ ### GapElement_IntegerMod #####################################################
+ ############################################################################
+ 
+-cdef GapElement_IntegerMod make_GapElement_IntegerMod(parent, libGAP_Obj obj):
++cdef GapElement_IntegerMod make_GapElement_IntegerMod(parent, Obj obj):
+     r"""
+     Turn a Gap integer object into a :class:`GapElement_IntegerMod` Sage object
+ 
+@@ -1499,7 +1527,7 @@ cdef class GapElement_IntegerMod(GapElement):
+ ### GapElement_FiniteField #####################################################
+ ############################################################################
+ 
+-cdef GapElement_FiniteField make_GapElement_FiniteField(parent, libGAP_Obj obj):
++cdef GapElement_FiniteField make_GapElement_FiniteField(parent, Obj obj):
+     r"""
+     Turn a GAP finite field object into a :class:`GapElement_FiniteField` Sage object
+ 
+@@ -1666,7 +1694,7 @@ cdef class GapElement_FiniteField(GapElement):
+ ### GapElement_Cyclotomic #####################################################
+ ############################################################################
+ 
+-cdef GapElement_Cyclotomic make_GapElement_Cyclotomic(parent, libGAP_Obj obj):
++cdef GapElement_Cyclotomic make_GapElement_Cyclotomic(parent, Obj obj):
+     r"""
+     Turn a Gap cyclotomic object into a :class:`GapElement_Cyclotomic` Sage
+     object.
+@@ -1754,7 +1782,7 @@ cdef class GapElement_Cyclotomic(GapElement):
+ ### GapElement_Rational ####################################################
+ ############################################################################
+ 
+-cdef GapElement_Rational make_GapElement_Rational(parent, libGAP_Obj obj):
++cdef GapElement_Rational make_GapElement_Rational(parent, Obj obj):
+     r"""
+     Turn a Gap Rational number (of type ``Obj``) into a Cython ``GapElement_Rational``.
+ 
+@@ -1826,7 +1854,7 @@ cdef class GapElement_Rational(GapElement):
+ ### GapElement_Ring #####################################################
+ ############################################################################
+ 
+-cdef GapElement_Ring make_GapElement_Ring(parent, libGAP_Obj obj):
++cdef GapElement_Ring make_GapElement_Ring(parent, Obj obj):
+     r"""
+     Turn a Gap integer object into a :class:`GapElement_Ring` Sage
+     object.
+@@ -1968,7 +1996,7 @@ cdef class GapElement_Ring(GapElement):
+ ### GapElement_Boolean #####################################################
+ ############################################################################
+ 
+-cdef GapElement_Boolean make_GapElement_Boolean(parent, libGAP_Obj obj):
++cdef GapElement_Boolean make_GapElement_Boolean(parent, Obj obj):
+     r"""
+     Turn a Gap Boolean number (of type ``Obj``) into a Cython ``GapElement_Boolean``.
+ 
+@@ -2023,11 +2051,12 @@ cdef class GapElement_Boolean(GapElement):
+             ...
+             ValueError: the GAP boolean value "fail" cannot be represented in Sage
+         """
+-        if self.value == libGAP_True:   return True
+-        if self.value == libGAP_False:  return False
++        if self.value == GAP_True:
++            return True
++        if self.value == GAP_False:
++            return False
+         raise ValueError('the GAP boolean value "fail" cannot be represented in Sage')
+ 
+-
+     def __nonzero__(self):
+         """
+         Check that the boolean is "true".
+@@ -2051,15 +2080,15 @@ cdef class GapElement_Boolean(GapElement):
+             ....:         print("{} {}".format( x, type(x)))
+             false <type 'sage.libs.gap.element.GapElement_Boolean'>
+             fail <type 'sage.libs.gap.element.GapElement_Boolean'>
+-       """
+-        return self.value == libGAP_True
++        """
++        return self.value == GAP_True
+ 
+ 
+ ############################################################################
+ ### GapElement_String ####################################################
+ ############################################################################
+ 
+-cdef GapElement_String make_GapElement_String(parent, libGAP_Obj obj):
++cdef GapElement_String make_GapElement_String(parent, Obj obj):
+     r"""
+     Turn a Gap String (of type ``Obj``) into a Cython ``GapElement_String``.
+ 
+@@ -2108,11 +2137,9 @@ cdef class GapElement_String(GapElement):
+             sage: s.sage()
+             'string'
+             sage: type(_)
+-            <... 'str'>
++            <type 'str'>
+         """
+-        libgap_enter()
+-        s = char_to_str(libGAP_CSTR_STRING(self.value))
+-        libgap_exit()
++        s = char_to_str(CSTR_STRING(self.value))
+         return s
+ 
+     sage = __str__
+@@ -2121,7 +2148,7 @@ cdef class GapElement_String(GapElement):
+ ### GapElement_Function ####################################################
+ ############################################################################
+ 
+-cdef GapElement_Function make_GapElement_Function(parent, libGAP_Obj obj):
++cdef GapElement_Function make_GapElement_Function(parent, Obj obj):
+     r"""
+     Turn a Gap C function object (of type ``Obj``) into a Cython ``GapElement_Function``.
+ 
+@@ -2201,30 +2228,31 @@ cdef class GapElement_Function(GapElement):
+             <Gap function "NormalSubgroups">
+             sage: b
+             Sym( [ 1 .. 4 ] )
+-            sage: a(b)
+-            [ Group(()),
+-              Group([ (1,4)(2,3), (1,3)(2,4) ]),
+-              Group([ (2,4,3), (1,4)(2,3), (1,3)(2,4) ]),
+-              Sym( [ 1 .. 4 ] ) ]
++            sage: sorted(a(b))
++            [Group(()),
++             Sym( [ 1 .. 4 ] ),
++             Alt( [ 1 .. 4 ] ),
++             Group([ (1,4)(2,3), (1,2)(3,4) ])]
+ 
+             sage: libgap.eval("a := NormalSubgroups")
+             <Gap function "NormalSubgroups">
+             sage: libgap.eval("b := SymmetricGroup(4)")
+             Sym( [ 1 .. 4 ] )
+             sage: libgap.collect()
+-            sage: libgap.eval('a') (libgap.eval('b'))
+-            [ Group(()),
+-              Group([ (1,4)(2,3), (1,3)(2,4) ]),
+-              Group([ (2,4,3), (1,4)(2,3), (1,3)(2,4) ]),
+-              Sym( [ 1 .. 4 ] ) ]
++            sage: sorted(libgap.eval('a') (libgap.eval('b')))
++            [Group(()),
++             Sym( [ 1 .. 4 ] ),
++             Alt( [ 1 .. 4 ] ),
++             Group([ (1,4)(2,3), (1,2)(3,4) ])]
++
+             sage: a = libgap.eval('a')
+             sage: b = libgap.eval('b')
+             sage: libgap.collect()
+-            sage: a(b)
+-            [ Group(()),
+-              Group([ (1,4)(2,3), (1,3)(2,4) ]),
+-              Group([ (2,4,3), (1,4)(2,3), (1,3)(2,4) ]),
+-              Sym( [ 1 .. 4 ] ) ]
++            sage: sorted(a(b))
++            [Group(()),
++             Sym( [ 1 .. 4 ] ),
++             Alt( [ 1 .. 4 ] ),
++             Group([ (1,4)(2,3), (1,2)(3,4) ])]
+ 
+         Not every ``GapElement`` is callable::
+ 
+@@ -2269,46 +2297,46 @@ cdef class GapElement_Function(GapElement):
+             sage: libgap_exec('echo hello from the shell')
+             hello from the shell
+         """
+-        cdef libGAP_Obj result = NULL
+-        cdef libGAP_Obj arg_list
++        cdef Obj result = NULL
++        cdef Obj arg_list
+         cdef int i, n = len(args)
+ 
+         if n > 0:
+             libgap = self.parent()
+-            a = [x if isinstance(x,GapElement) else libgap(x) for x in args]
++            a = [x if isinstance(x, GapElement) else libgap(x) for x in args]
+ 
++        sig_on()
+         try:
+-            libgap_enter()
+-            sig_on()
++            GAP_Enter()
+             if n == 0:
+-                result = libGAP_CALL_0ARGS(self.value)
++                result = CALL_0ARGS(self.value)
+             elif n == 1:
+-                result = libGAP_CALL_1ARGS(self.value,
++                result = CALL_1ARGS(self.value,
+                                            (<GapElement>a[0]).value)
+             elif n == 2:
+-                result = libGAP_CALL_2ARGS(self.value,
++                result = CALL_2ARGS(self.value,
+                                            (<GapElement>a[0]).value,
+                                            (<GapElement>a[1]).value)
+             elif n == 3:
+-                result = libGAP_CALL_3ARGS(self.value,
++                result = CALL_3ARGS(self.value,
+                                            (<GapElement>a[0]).value,
+                                            (<GapElement>a[1]).value,
+                                            (<GapElement>a[2]).value)
+             elif n == 4:
+-                result = libGAP_CALL_4ARGS(self.value,
++                result = CALL_4ARGS(self.value,
+                                            (<GapElement>a[0]).value,
+                                            (<GapElement>a[1]).value,
+                                            (<GapElement>a[2]).value,
+                                            (<GapElement>a[3]).value)
+             elif n == 5:
+-                result = libGAP_CALL_5ARGS(self.value,
++                result = CALL_5ARGS(self.value,
+                                            (<GapElement>a[0]).value,
+                                            (<GapElement>a[1]).value,
+                                            (<GapElement>a[2]).value,
+                                            (<GapElement>a[3]).value,
+                                            (<GapElement>a[4]).value)
+             elif n == 6:
+-                result = libGAP_CALL_6ARGS(self.value,
++                result = CALL_6ARGS(self.value,
+                                            (<GapElement>a[0]).value,
+                                            (<GapElement>a[1]).value,
+                                            (<GapElement>a[2]).value,
+@@ -2316,21 +2344,20 @@ cdef class GapElement_Function(GapElement):
+                                            (<GapElement>a[4]).value,
+                                            (<GapElement>a[5]).value)
+             elif n >= 7:
+-                libgap_exit()
+                 arg_list = make_gap_list(args)
+-                libgap_enter()
+-                result = libGAP_CALL_XARGS(self.value, arg_list)
+-            sig_off()
++                result = CALL_XARGS(self.value, arg_list)
++
++            if result == NULL:
++                # We called a procedure that does not return anything
++                return None
++
++            return make_any_gap_element(self.parent(), result)
+         except RuntimeError as msg:
+             raise ValueError('libGAP: ' + str(msg))
+         finally:
+-            libgap_exit()
+-
+-        if result == NULL:
+-            # We called a procedure that does not return anything
+-            return None
++            GAP_Leave()
++            sig_off()
+ 
+-        return make_any_gap_element(self.parent(), result)
+ 
+ 
+     def _instancedoc_(self):
+@@ -2356,7 +2383,7 @@ cdef class GapElement_Function(GapElement):
+ ### GapElement_MethodProxy #################################################
+ ############################################################################
+ 
+-cdef GapElement_MethodProxy make_GapElement_MethodProxy(parent, libGAP_Obj function, GapElement base_object):
++cdef GapElement_MethodProxy make_GapElement_MethodProxy(parent, Obj function, GapElement base_object):
+     r"""
+     Turn a Gap C rec object (of type ``Obj``) into a Cython ``GapElement_Record``.
+ 
+@@ -2435,7 +2462,7 @@ cdef class GapElement_MethodProxy(GapElement_Function):
+             sage: lst
+             [ 1,, 3, 4, 5 ]
+         """
+-        if args:
++        if len(args) > 0:
+             return GapElement_Function.__call__(self, * ([self.first_argument] + list(args)))
+         else:
+             return GapElement_Function.__call__(self, self.first_argument)
+@@ -2446,7 +2473,7 @@ cdef class GapElement_MethodProxy(GapElement_Function):
+ ### GapElement_List ########################################################
+ ############################################################################
+ 
+-cdef GapElement_List make_GapElement_List(parent, libGAP_Obj obj):
++cdef GapElement_List make_GapElement_List(parent, Obj obj):
+     r"""
+     Turn a Gap C List object (of type ``Obj``) into a Cython ``GapElement_List``.
+ 
+@@ -2498,6 +2525,21 @@ cdef class GapElement_List(GapElement):
+         IndexError: index out of range.
+     """
+ 
++    def __bool__(self):
++        r"""
++        Return True if the list is non-empty, as with Python ``list``s.
++
++        EXAMPLES::
++
++            sage: lst = libgap.eval('[1,,,4]')
++            sage: bool(lst)
++            True
++            sage: lst = libgap.eval('[]')
++            sage: bool(lst)
++            False
++        """
++        return bool(len(self))
++
+     def __len__(self):
+         r"""
+         Return the length of the list.
+@@ -2512,7 +2554,7 @@ cdef class GapElement_List(GapElement):
+             sage: len(lst)
+             4
+         """
+-        return libGAP_LEN_LIST(self.value)
++        return LEN_LIST(self.value)
+ 
+     def __getitem__(self, i):
+         r"""
+@@ -2556,21 +2598,21 @@ cdef class GapElement_List(GapElement):
+             ValueError: too many indices
+         """
+         cdef int j
+-        cdef libGAP_Obj obj = self.value
++        cdef Obj obj = self.value
+ 
+         if isinstance(i, tuple):
+             for j in i:
+-                if not libGAP_IS_LIST(obj):
++                if not IS_LIST(obj):
+                     raise ValueError('too many indices')
+-                if j < 0 or j >= libGAP_LEN_LIST(obj):
++                if j < 0 or j >= LEN_LIST(obj):
+                     raise IndexError('index out of range')
+-                obj = libGAP_ELM_LIST(obj, j+1)
++                obj = ELM_LIST(obj, j+1)
+ 
+         else:
+             j = i
+-            if j < 0 or j >= libGAP_LEN_LIST(obj):
++            if j < 0 or j >= LEN_LIST(obj):
+                 raise IndexError('index out of range.')
+-            obj = libGAP_ELM_LIST(obj, j+1)
++            obj = ELM_LIST(obj, j+1)
+ 
+         return make_any_gap_element(self.parent(), obj)
+ 
+@@ -2623,20 +2665,20 @@ cdef class GapElement_List(GapElement):
+             sage: m
+             [ [ 1, 2 ], [ 3, 4 ] ]
+         """
+-        if not libGAP_IS_MUTABLE_OBJ(self.value):
++        if not IS_MUTABLE_OBJ(self.value):
+             raise TypeError('immutable Gap object does not support item assignment')
+ 
+         cdef int j
+-        cdef libGAP_Obj obj = self.value
++        cdef Obj obj = self.value
+ 
+         if isinstance(i, tuple):
+             for j in i[:-1]:
+-                if not libGAP_IS_LIST(obj):
++                if not IS_LIST(obj):
+                     raise ValueError('too many indices')
+-                if j < 0 or j >= libGAP_LEN_LIST(obj):
++                if j < 0 or j >= LEN_LIST(obj):
+                     raise IndexError('index out of range')
+-                obj = libGAP_ELM_LIST(obj, j+1)
+-            if not libGAP_IS_LIST(obj):
++                obj = ELM_LIST(obj, j+1)
++            if not IS_LIST(obj):
+                 raise ValueError('too many indices')
+             j = i[-1]
+         else:
+@@ -2651,7 +2693,7 @@ cdef class GapElement_List(GapElement):
+         else:
+             celt= self.parent()(elt)
+ 
+-        libGAP_ASS_LIST(obj, j+1, celt.value)
++        ASS_LIST(obj, j+1, celt.value)
+ 
+     def sage(self, **kwds):
+         r"""
+@@ -2769,7 +2811,7 @@ cdef class GapElement_List(GapElement):
+ ############################################################################
+ 
+ 
+-cdef GapElement_Permutation make_GapElement_Permutation(parent, libGAP_Obj obj):
++cdef GapElement_Permutation make_GapElement_Permutation(parent, Obj obj):
+     r"""
+     Turn a Gap C permutation object (of type ``Obj``) into a Cython ``GapElement_Permutation``.
+ 
+@@ -2834,7 +2876,7 @@ cdef class GapElement_Permutation(GapElement):
+ ### GapElement_Record ######################################################
+ ############################################################################
+ 
+-cdef GapElement_Record make_GapElement_Record(parent, libGAP_Obj obj):
++cdef GapElement_Record make_GapElement_Record(parent, Obj obj):
+     r"""
+     Turn a Gap C rec object (of type ``Obj``) into a Cython ``GapElement_Record``.
+ 
+@@ -2876,7 +2918,8 @@ cdef class GapElement_Record(GapElement):
+         sage: rec['no_such_element']
+         Traceback (most recent call last):
+         ...
+-        IndexError: libGAP: Error, Record: '<rec>.no_such_element' must have an assigned value
++        IndexError: libGAP: Error, Record Element: '<rec>.no_such_element' must
++        have an assigned value
+     """
+ 
+     def __len__(self):
+@@ -2893,7 +2936,7 @@ cdef class GapElement_Record(GapElement):
+             sage: len(rec)
+             3
+         """
+-        return libGAP_LEN_PREC(self.value)
++        return LEN_PREC(self.value)
+ 
+ 
+     def __iter__(self):
+@@ -2910,19 +2953,19 @@ cdef class GapElement_Record(GapElement):
+             sage: iter = rec.__iter__()
+             sage: type(iter)
+             <type 'sage.libs.gap.element.GapElement_RecordIterator'>
+-            sage: list(rec)
++            sage: sorted(rec)
+             [('a', 123), ('b', 456)]
+         """
+         return GapElement_RecordIterator(self)
+ 
+ 
+-    cpdef libGAP_UInt record_name_to_index(self, name):
++    cpdef UInt record_name_to_index(self, name):
+         r"""
+         Convert string to GAP record index.
+ 
+         INPUT:
+ 
+-        - ``name`` -- a python string.
++        - ``py_name`` -- a python string.
+ 
+         OUTPUT:
+ 
+@@ -2939,12 +2982,7 @@ cdef class GapElement_Record(GapElement):
+             3776L
+         """
+         name = str_to_bytes(name)
+-
+-        try:
+-            libgap_enter()
+-            return libGAP_RNamName(name)
+-        finally:
+-            libgap_exit()
++        return RNamName(name)
+ 
+     def __getitem__(self, name):
+         r"""
+@@ -2964,15 +3002,18 @@ cdef class GapElement_Record(GapElement):
+             sage: rec['first']
+             123
+         """
+-        cdef libGAP_UInt i = self.record_name_to_index(name)
+-        cdef libGAP_Obj result
++        cdef UInt i = self.record_name_to_index(name)
++        cdef Obj result
++        sig_on()
+         try:
+-            sig_on()
+-            result = libGAP_ELM_REC(self.value, i)
+-            sig_off()
++            GAP_Enter()
++            result = ELM_REC(self.value, i)
++            return make_any_gap_element(self.parent(), result)
+         except RuntimeError as msg:
+             raise IndexError('libGAP: ' + str(msg))
+-        return make_any_gap_element(self.parent(), result)
++        finally:
++            GAP_Leave()
++            sig_off()
+ 
+ 
+     def sage(self):
+@@ -3016,7 +3057,7 @@ cdef class GapElement_RecordIterator(object):
+     EXAMPLES::
+ 
+         sage: rec = libgap.eval('rec(a:=123, b:=456)')
+-        sage: list(rec)
++        sage: sorted(rec)
+         [('a', 123), ('b', 456)]
+         sage: dict(rec)
+         {'a': 123, 'b': 456}
+@@ -3052,20 +3093,18 @@ cdef class GapElement_RecordIterator(object):
+ 
+             sage: rec = libgap.eval('rec(a:=123, b:=456)')
+             sage: iter = rec.__iter__()
+-            sage: iter.__next__()
+-            ('a', 123)
+-            sage: next(iter)
+-            ('b', 456)
++            sage: a = iter.__next__()
++            sage: b = next(iter)
++            sage: sorted([a, b])
++            [('a', 123), ('b', 456)]
+         """
+-        cdef libGAP_UInt i = self.i
++        cdef UInt i = self.i
+         if i>len(self.rec):
+             raise StopIteration
+         # note the abs: negative values mean the rec keys are not sorted
+-        libgap_enter()
+-        key_index = abs(libGAP_GET_RNAM_PREC(self.rec.value, i))
+-        key = char_to_str(libGAP_NAME_RNAM(key_index))
+-        cdef libGAP_Obj result = libGAP_GET_ELM_PREC(self.rec.value,i)
+-        libgap_exit()
++        key_index = abs(GET_RNAM_PREC(self.rec.value, i))
++        key = char_to_str(CSTR_STRING(NAME_RNAM(key_index)))
++        cdef Obj result = GET_ELM_PREC(self.rec.value,i)
+         val = make_any_gap_element(self.rec.parent(), result)
+         self.i += 1
+         return (key, val)
+diff --git a/src/sage/libs/gap/gap_functions.py b/src/sage/libs/gap/gap_functions.py
+index 271a8aa..f7dac14 100644
+--- a/src/sage/libs/gap/gap_functions.py
++++ b/src/sage/libs/gap/gap_functions.py
+@@ -1,4 +1,4 @@
+-"Gap functions"
++"""Common global functions defined by GAP."""
+ 
+ ###############################################################################
+ #       Copyright (C) 2009, William Stein <wstein at gmail.com>
+@@ -11,8 +11,9 @@
+ ###############################################################################
+ 
+ 
++
+ # selected gap functions to use in tab completion
+-common_gap_functions = [
++common_gap_functions = set([
+   'AbelianGroup',
+   'AbelianInvariants',
+   'AbelianInvariantsMultiplier',
+@@ -37,13 +38,11 @@ common_gap_functions = [
+   'AppendTo',
+   'Apply',
+   'AsGroup',
+-  'Assert',
+-  'AtlasGroup',
+   'AutomorphismGroup',
+   'BaseOfGroup',
+   'Basis',
+   'BasisVectors',
+-  'Bell', 
++  'Bell',
+   'Binomial',
+   'BlockMatrix',
+   'Blocks',
+@@ -125,7 +124,6 @@ common_gap_functions = [
+   'CyclicGroup',
+   'CyclotomicField',
+   'CyclotomicPolynomial',
+-  'Cyclotomics',
+   'DefiningPolynomial',
+   'Degree',
+   'DegreeFFE',
+@@ -210,8 +208,6 @@ common_gap_functions = [
+   'GaloisGroup',
+   'GaloisMat',
+   'GaloisStabilizer',
+-  'GaussianIntegers',
+-  'GaussianRationals',
+   'Gcd',
+   'GcdInt',
+   'GcdOp',
+@@ -225,7 +221,6 @@ common_gap_functions = [
+   'GeneratorsOfField',
+   'GeneratorsOfGroup',
+   'GeneratorsOfIdeal',
+-  'GlobalMersenneTwister',
+   'GroebnerBasis',
+   'Group',
+   'GroupHomomorphismByFunction',
+@@ -243,23 +238,7 @@ common_gap_functions = [
+   'Image',
+   'Images',
+   'Index',
+-  'InfoAlgebra',
+-  'InfoAttributes',
+-  'InfoBckt',
+-  'InfoCharacterTable',
+-  'InfoCoh',
+-  'InfoComplement',
+-  'InfoCoset',
+-  'InfoFpGroup',
+-  'InfoGroebner',
+-  'InfoGroup',
+-  'InfoLattice',
+   'InfoLevel',
+-  'InfoMatrix',
+-  'InfoMonomial',
+-  'InfoNumtheor',
+-  'InfoOptions',
+-  'InfoPcSubgroup',
+   'InfoText',
+   'InnerAutomorphism',
+   'InnerAutomorphismsAutomorphismGroup',
+@@ -269,7 +248,6 @@ common_gap_functions = [
+   'IntHexString',
+   'IntScalarProducts',
+   'IntVecFFE',
+-  'Integers',
+   'IntersectSet',
+   'Intersection',
+   'InvariantBilinearForm',
+@@ -319,7 +297,6 @@ common_gap_functions = [
+   'IsBinaryRelation',
+   'IsBlockMatrixRep',
+   'IsBool',
+-  'IsBound',
+   'IsBoundGlobal',
+   'IsBrauerTable',
+   'IsBravaisGroup',
+@@ -528,7 +505,6 @@ common_gap_functions = [
+   'IsTransitive',
+   'IsTransitiveBinaryRelation',
+   'IsTrivial',
+-  'IsTuple',
+   'IsUniqueFactorizationRing',
+   'IsUnit',
+   'IsUnivariatePolynomial',
+@@ -718,7 +694,6 @@ common_gap_functions = [
+   'MonomialGrevlexOrdering',
+   'MonomialGrlexOrdering',
+   'MonomialLexOrdering',
+-  'MonomialTotalDegreeLess',
+   'MostFrequentGeneratorFpGroup',
+   'MovedPoints',
+   'MultRowVector',
+@@ -742,7 +717,6 @@ common_gap_functions = [
+   'NextIterator',
+   'NextPrimeInt',
+   'NiceBasis',
+-  'NiceBasisFiltersInfo',
+   'NiceFreeLeftModule',
+   'NiceFreeLeftModuleInfo',
+   'NiceMonomorphism',
+@@ -933,7 +907,6 @@ common_gap_functions = [
+   'Position',
+   'PositionBound',
+   'PositionCanonical',
+-  'PositionFirstComponent',
+   'PositionNonZero',
+   'PositionNot',
+   'PositionNthOccurrence',
+@@ -976,7 +949,6 @@ common_gap_functions = [
+   'PrimePGroup',
+   'PrimePowersInt',
+   'PrimeResidues',
+-  'Primes',
+   'PrimitiveElement',
+   'PrimitiveGroup',
+   'PrimitiveIdentification',
+@@ -1047,7 +1019,6 @@ common_gap_functions = [
+   'RationalClass',
+   'RationalClasses',
+   'RationalizedMat',
+-  'Rationals',
+   'Read',
+   'ReadAll',
+   'ReadAllLine',
+@@ -1094,7 +1065,6 @@ common_gap_functions = [
+   'ReesMatrixSemigroupElement',
+   'ReesZeroMatrixSemigroup',
+   'ReesZeroMatrixSemigroupElement',
+-  'ReesZeroMatrixSemigroupElementIsZero',
+   'RefinedPcGroup',
+   'RegularActionHomomorphism',
+   'RegularModule',
+@@ -1124,7 +1094,6 @@ common_gap_functions = [
+   'Reread',
+   'RereadPackage',
+   'Reset',
+-  'RestoreStateRandom',
+   'RestrictOutputsOfSLP',
+   'Restricted',
+   'RestrictedClassFunction',
+@@ -1157,8 +1126,6 @@ common_gap_functions = [
+   'SSortedList',
+   'SU',
+   'SameBlock',
+-  'SandwichMatrixOfReesMatrixSemigroup',
+-  'SandwichMatrixOfReesZeroMatrixSemigroup',
+   'SaveWorkspace',
+   'ScalarProduct',
+   'SchurCover',
+@@ -1249,7 +1216,6 @@ common_gap_functions = [
+   'StabilizerOfExternalSet',
+   'StabilizerPcgs',
+   'StandardAssociate',
+-  'StandardGeneratorsInfo',
+   'StandardizeTable',
+   'StarCyc',
+   'Stirling1',
+@@ -1296,7 +1262,6 @@ common_gap_functions = [
+   'SumIntersectionMat',
+   'SumX',
+   'SupersolvableResiduum',
+-  'SupportedCharacterTableInfo',
+   'SurjectiveActionHomomorphismAttr',
+   'SuzukiGroup',
+   'SylowComplement',
+@@ -1314,7 +1279,6 @@ common_gap_functions = [
+   'TableAutomorphisms',
+   'TableOfMarks',
+   'TableOfMarksByLattice',
+-  'TableOfMarksComponents',
+   'TableOfMarksCyclic',
+   'TableOfMarksDihedral',
+   'TableOfMarksFrobenius',
+@@ -1332,9 +1296,6 @@ common_gap_functions = [
+   'TracedCosetFpGroup',
+   'TransferDiagram',
+   'Transformation',
+-  'TransformationData',
+-  'TransformationRelation',
+-  'TransformationType',
+   'TransformingPermutations',
+   'TransformingPermutationsCharacterTables',
+   'TransitiveClosureBinaryRelation',
+@@ -1365,7 +1326,6 @@ common_gap_functions = [
+   'TrivialSubspace',
+   'Tuple',
+   'Tuples',
+-  'Unbind',
+   'UnbindElmWPObj',
+   'UnbindGlobal',
+   'UnderlyingCharacterTable',
+@@ -1441,4 +1401,6 @@ common_gap_functions = [
+   'ZeroOp',
+   'ZeroSM',
+   'ZeroSameMutability',
+- ]
++  'GASMAN_STATS',
++  'GASMAN',
++ ])
+diff --git a/src/sage/libs/gap/gap_globals.py b/src/sage/libs/gap/gap_globals.py
+new file mode 100644
+index 00000000..99b3921
+--- /dev/null
++++ b/src/sage/libs/gap/gap_globals.py
+@@ -0,0 +1,46 @@
++"""Common globals defined by GAP."""
++
++###############################################################################
++#       Copyright (C) 2009, William Stein <wstein at gmail.com>
++#       Copyright (C) 2012, Volker Braun <vbraun.name at gmail.com>
++#
++#   Distributed under the terms of the GNU General Public License (GPL)
++#   as published by the Free Software Foundation; either version 2 of
++#   the License, or (at your option) any later version.
++#                   http://www.gnu.org/licenses/
++###############################################################################
++
++
++from .gap_functions import common_gap_functions
++
++
++# selected gap globals to use in tab completion
++common_gap_globals = set([
++  'Assert',
++  'Cyclotomics',
++  'GaussianIntegers',
++  'GaussianRationals',
++  'GlobalMersenneTwister',
++  'GlobalRandomSource',
++  'InfoAlgebra',
++  'InfoAttributes',
++  'InfoBckt',
++  'InfoCharacterTable',
++  'InfoCoh',
++  'InfoComplement',
++  'InfoCoset',
++  'InfoFpGroup',
++  'InfoGroebner',
++  'InfoGroup',
++  'InfoLattice',
++  'InfoMatrix',
++  'InfoMonomial',
++  'InfoNumtheor',
++  'InfoOptions',
++  'InfoPcSubgroup',
++  'Integers',
++  'NiceBasisFiltersInfo',
++  'Primes',
++  'Rationals',
++  'TableOfMarksComponents'
++]) | common_gap_functions
+diff --git a/src/sage/libs/gap/gap_includes.pxd b/src/sage/libs/gap/gap_includes.pxd
+index c3f4dcb..f62b24e 100644
+--- a/src/sage/libs/gap/gap_includes.pxd
++++ b/src/sage/libs/gap/gap_includes.pxd
+@@ -10,318 +10,152 @@
+ ###############################################################################
+ 
+ 
+-from .types cimport *
+-
+-cdef extern from "<gap/libgap.h>":
+-    void libgap_initialize(int argc, char** argv)
+-    ctypedef void(*libgap_gasman_callback_ptr)()
+-    void libgap_set_gasman_callback(libgap_gasman_callback_ptr callback)
+-    ctypedef void(*libgap_error_func_ptr)(char* msg)
+-    void libgap_set_error_handler(libgap_error_func_ptr error_handler)
+-    void libgap_call_error_handler()
+-    void libgap_finalize()
+-    void libgap_start_interaction(char* inputline)
+-    char* libgap_get_output()
+-    char* libgap_get_error()
+-    void libgap_finish_interaction()
+-    void libgap_mark_stack_bottom()
+-    void libgap_enter()
+-    void libgap_exit()
+-
+-cdef extern from "<gap/gap.h>":
+-    void libGAP_ViewObjHandler(void*)
+-    void libGAP_InitializeGap(int*, char** argv)
+-    void libGAP_set_system_variables(char**, char**)
+-    cdef libGAP_UInt libGAP_Last
+-    cdef libGAP_UInt libGAP_Last2
+-    cdef libGAP_UInt libGAP_Last3
+-    cdef libGAP_ExecStatus libGAP_STATUS_END
+-    cdef libGAP_ExecStatus libGAP_STATUS_RETURN_VAL
+-    cdef libGAP_ExecStatus libGAP_STATUS_RETURN_VOID
+-    cdef libGAP_ExecStatus libGAP_STATUS_TNM
+-    cdef libGAP_ExecStatus libGAP_STATUS_QUIT
+-    cdef libGAP_ExecStatus libGAP_STATUS_EOF
+-    cdef libGAP_ExecStatus libGAP_STATUS_ERROR
+-    cdef libGAP_ExecStatus libGAP_STATUS_QQUIT
++cdef extern from "<gap/system.h>":
++    ctypedef char Char
++    ctypedef int Int
++    ctypedef unsigned int UInt
++    ctypedef void* Obj
+ 
+-cdef extern from "<gap/objects.h>":
+-    bint libGAP_IS_MUTABLE_OBJ(libGAP_Obj obj)
+-    bint libGAP_IS_COPYABLE_OBJ(libGAP_Obj obj)
+-    libGAP_Obj libGAP_SHALLOW_COPY_OBJ(libGAP_Obj obj)
+-    libGAP_Obj libGAP_CopyObj(libGAP_Obj obj, int mut)
+-
+-    bint libGAP_IS_INTOBJ(libGAP_Obj obj)
+-    libGAP_Obj libGAP_INTOBJ_INT(libGAP_Int)
+-    libGAP_Int libGAP_INT_INTOBJ(libGAP_Obj)
+-    libGAP_UInt libGAP_TNUM_OBJ(libGAP_Obj obj)
+-    char* libGAP_TNAM_OBJ(libGAP_Obj obj)
+-    cdef int libGAP_FIRST_REAL_TNUM
+-    cdef int libGAP_FIRST_CONSTANT_TNUM
+-    cdef int libGAP_T_INT
+-    cdef int libGAP_T_INTPOS
+-    cdef int libGAP_T_INTNEG
+-    cdef int libGAP_T_RAT
+-    cdef int libGAP_T_CYC
+-    cdef int libGAP_T_FFE
+-    cdef int libGAP_T_PERM2
+-    cdef int libGAP_T_PERM4
+-    cdef int libGAP_T_BOOL
+-    cdef int libGAP_T_CHAR
+-    cdef int libGAP_T_FUNCTION
+-    cdef int libGAP_T_FLAGS
+-    cdef int libGAP_T_MACFLOAT
+-    cdef int libGAP_T_RESERVED_BY_GAP
+-    cdef int libGAP_LAST_CONSTANT_TNUM
+-    cdef int libGAP_IMMUTABLE
+-    cdef int libGAP_FIRST_IMM_MUT_TNUM
+-    cdef int libGAP_FIRST_RECORD_TNUM
+-    cdef int libGAP_T_PREC
+-    cdef int libGAP_LAST_RECORD_TNUM
+-    cdef int libGAP_FIRST_LIST_TNUM
+-    cdef int libGAP_FIRST_PLIST_TNUM
+-    cdef int libGAP_T_PLIST
+-    cdef int libGAP_T_PLIST_NDENSE
+-    cdef int libGAP_T_PLIST_DENSE
+-    cdef int libGAP_T_PLIST_DENSE_NHOM
+-    cdef int libGAP_T_PLIST_DENSE_NHOM_SSORT
+-    cdef int libGAP_T_PLIST_DENSE_NHOM_NSORT
+-    cdef int libGAP_T_PLIST_EMPTY
+-    cdef int libGAP_T_PLIST_HOM
+-    cdef int libGAP_T_PLIST_HOM_NSORT
+-    cdef int libGAP_T_PLIST_HOM_SSORT
+-    cdef int libGAP_T_PLIST_TAB
+-    cdef int libGAP_T_PLIST_TAB_NSORT
+-    cdef int libGAP_T_PLIST_TAB_SSORT
+-    cdef int libGAP_T_PLIST_TAB_RECT
+-    cdef int libGAP_T_PLIST_TAB_RECT_NSORT
+-    cdef int libGAP_T_PLIST_TAB_RECT_SSORT
+-    cdef int libGAP_T_PLIST_CYC
+-    cdef int libGAP_T_PLIST_CYC_NSORT
+-    cdef int libGAP_T_PLIST_CYC_SSORT
+-    cdef int libGAP_T_PLIST_FFE
+-    cdef int libGAP_LAST_PLIST_TNUM
+-    cdef int libGAP_T_RANGE_NSORT
+-    cdef int libGAP_T_RANGE_SSORT
+-    cdef int libGAP_T_BLIST
+-    cdef int libGAP_T_BLIST_NSORT
+-    cdef int libGAP_T_BLIST_SSORT
+-    cdef int libGAP_T_STRING
+-    cdef int libGAP_T_STRING_NSORT
+-    cdef int libGAP_T_STRING_SSORT
+-    cdef int libGAP_LAST_LIST_TNUM
+-    cdef int libGAP_LAST_IMM_MUT_TNUM
+-    cdef int libGAP_FIRST_EXTERNAL_TNUM
+-    cdef int libGAP_T_COMOBJ
+-    cdef int libGAP_T_POSOBJ
+-    cdef int libGAP_T_DATOBJ
+-    cdef int libGAP_T_WPOBJ
+-    cdef int libGAP_LAST_EXTERNAL_TNUM
+-    cdef int libGAP_LAST_REAL_TNUM
+-    cdef int libGAP_LAST_VIRTUAL_TNUM
+-    cdef int libGAP_FIRST_COPYING_TNUM
+-    cdef int libGAP_COPYING
+-    cdef int libGAP_LAST_COPYING_TNUM
+-    cdef int libGAP_FIRST_TESTING_TNUM
+-    cdef int libGAP_TESTING
+-    cdef int libGAP_LAST_TESTING_TNUM
+-
+-cdef extern from "<gap/read.h>":
+-    void* libGAP_ReadEvalCommand(libGAP_Obj context, libGAP_UInt *dualSemicolon)
+-    void* libGAP_ReadEvalFile()
+-    void* libGAP_ReadEvalResult
+-    bint libGAP_READ_ERROR()
+-
+-cdef extern from "<gap/scanner.h>":
+-    void libGAP_ClearError()
+-    libGAP_UInt libGAP_NrError
+-    libGAP_UInt libGAP_Symbol
+-    void libGAP_GetSymbol()
+-    void libGAP_Match (libGAP_UInt symbol, char* msg, libGAP_UInt skipto)
+-    int libGAP_S_ILLEGAL
+-    int libGAP_S_IDENT
+-    int libGAP_S_UNBIND
+-    int libGAP_S_ISBOUND
+-    int libGAP_S_TRYNEXT
+-    int libGAP_S_INFO
+-    int libGAP_S_ASSERT
+-    int libGAP_S_SAVEWS
+-    int libGAP_S_LOADWS
+-    int libGAP_S_LBRACK
+-    int libGAP_S_LBRACE
+-    int libGAP_S_BLBRACK
+-    int libGAP_S_BLBRACE
+-    int libGAP_S_RBRACK
+-    int libGAP_S_RBRACE
+-    int libGAP_S_DOT
+-    int libGAP_S_BDOT
+-    int libGAP_S_LPAREN
+-    int libGAP_S_RPAREN
+-    int libGAP_S_COMMA
+-    int libGAP_S_DOTDOT
+-    int libGAP_S_COLON
+-    int libGAP_S_PARTIALINT
+-    int libGAP_S_INT
+-    int libGAP_S_TRUE
+-    int libGAP_S_FALSE
+-    int libGAP_S_CHAR
+-    int libGAP_S_STRING
+-    int libGAP_S_PARTIALSTRING
+-    int libGAP_S_REC
+-    int libGAP_S_FUNCTION
+-    int libGAP_S_LOCAL
+-    int libGAP_S_END
+-    int libGAP_S_MAPTO
+-    int libGAP_S_MULT
+-    int libGAP_S_DIV
+-    int libGAP_S_MOD
+-    int libGAP_S_POW
+-    int libGAP_S_PLUS
+-    int libGAP_S_MINUS
+-    int libGAP_S_EQ
+-    int libGAP_S_LT
+-    int libGAP_S_GT
+-    int libGAP_S_NE
+-    int libGAP_S_LE
+-    int libGAP_S_GE
+-    int libGAP_S_IN
+-    int libGAP_S_NOT
+-    int libGAP_S_AND
+-    int libGAP_S_OR
+-    int libGAP_S_ASSIGN
+-    int libGAP_S_IF
+-    int libGAP_S_FOR
+-    int libGAP_S_WHILE
+-    int libGAP_S_REPEAT
+-    int libGAP_S_THEN
+-    int libGAP_S_ELIF
+-    int libGAP_S_ELSE
+-    int libGAP_S_FI
+-    int libGAP_S_DO
+-    int libGAP_S_OD
+-    int libGAP_S_UNTIL
+-    int libGAP_S_BREAK
+-    int libGAP_S_RETURN
+-    int libGAP_S_QUIT
+-    int libGAP_S_QQUIT
+-    int libGAP_S_CONTINUE
+-    int libGAP_S_SEMICOLON
+-    int libGAP_S_EOF
+ 
+-cdef extern from "<gap/gvars.h>":
+-    libGAP_UInt libGAP_GVarName(char* name)
+-    void libGAP_AssGVar(libGAP_UInt gvar, libGAP_Obj val)
+-    libGAP_Obj libGAP_VAL_GVAR(libGAP_UInt gvar)
+-
+-cdef extern from "<gap/string.h>":
+-    char* libGAP_CSTR_STRING(libGAP_Obj list)
+-    int libGAP_GET_LEN_STRING(libGAP_Obj list)
+-    bint libGAP_IS_STRING(libGAP_Obj obj)
+-    bint libGAP_IsStringConv(libGAP_Obj obj)
+-    bint libGAP_ConvString(libGAP_Obj obj)
+-    void libGAP_C_NEW_STRING(libGAP_Obj new_gap_string, int length, char* c_string)
++cdef extern from "<gap/ariths.h>":
++    Obj SUM(Obj, Obj)
++    Obj DIFF(Obj, Obj)
++    Obj PROD(Obj, Obj)
++    Obj QUO(Obj, Obj)
++    Obj POW(Obj, Obj)
++    Obj MOD(Obj, Obj)
++    bint EQ(Obj opL, Obj opR)
++    bint LT(Obj opL, Obj opR)
+ 
+-cdef extern from "<gap/gasman.h>":
+-    void libGAP_InitGlobalBag(libGAP_Obj* addr, char* cookie)
+-    libGAP_Obj libGAP_NewBag(libGAP_UInt type, libGAP_UInt size)
+-    void libGAP_CHANGED_BAG(libGAP_Obj bag)
+-    void libGAP_MARK_BAG(libGAP_Obj bag)
+-    bint libGAP_IS_MARKED_ALIVE(libGAP_Obj bag)
+-    bint libGAP_IS_MARKED_DEAD(libGAP_Obj bag)
+-    bint libGAP_IS_MARKED_HALFDEAD(libGAP_Obj bag)
+-    cdef libGAP_UInt libGAP_NrAllBags
+-    cdef libGAP_UInt libGAP_SizeAllBags
+-    cdef libGAP_UInt libGAP_NrLiveBags
+-    cdef libGAP_UInt libGAP_SizeLiveBags
+-    cdef libGAP_UInt libGAP_NrDeadBags
+-    cdef libGAP_UInt libGAP_SizeDeadBags
+-    cdef libGAP_UInt libGAP_NrHalfDeadBags
+-    libGAP_UInt libGAP_CollectBags(libGAP_UInt size, libGAP_UInt full)
+-    void libGAP_CallbackForAllBags(void (*func)(libGAP_Obj))
+-    char* libGAP_TNAM_BAG(libGAP_Obj obj)
+-    libGAP_UInt libGAP_TNUM_BAG(libGAP_Obj)
+-    libGAP_UInt libGAP_SIZE_BAG(libGAP_Obj)
+-    void libGAP_CheckMasterPointers()
+-    libGAP_Obj* libGAP_MptrBags
+-    libGAP_Obj* libGAP_YoungBags
+-    libGAP_Obj* libGAP_OldBags
+-    libGAP_Obj* libGAP_AllocBags
+-    libGAP_Obj* libGAP_MarkedBags
+-    libGAP_Obj* libGAP_ChangedBags
+-
+-# in gasman.c but not declared in gasman.h
+-cdef extern:
+-    libGAP_Obj* libGAP_StopBags
+-    libGAP_Obj* libGAP_EndBags
+ 
+-cdef extern from "<gap/ariths.h>":
+-    libGAP_Obj libGAP_SUM (libGAP_Obj, libGAP_Obj)
+-    libGAP_Obj libGAP_DIFF(libGAP_Obj, libGAP_Obj)
+-    libGAP_Obj libGAP_PROD(libGAP_Obj, libGAP_Obj)
+-    libGAP_Obj libGAP_QUO(libGAP_Obj, libGAP_Obj)
+-    libGAP_Obj libGAP_POW(libGAP_Obj, libGAP_Obj)
+-    libGAP_Obj libGAP_MOD(libGAP_Obj, libGAP_Obj)
+-    libGAP_Obj libGAP_CALL_0ARGS(libGAP_Obj f)              # 0 arguments
+-    libGAP_Obj libGAP_CALL_1ARGS(libGAP_Obj f, libGAP_Obj a1)      # 1 argument
+-    libGAP_Obj libGAP_CALL_2ARGS(libGAP_Obj f, libGAP_Obj a1, libGAP_Obj a2)
+-    libGAP_Obj libGAP_CALL_3ARGS(libGAP_Obj f, libGAP_Obj a1, libGAP_Obj a2, libGAP_Obj a3)
+-    libGAP_Obj libGAP_CALL_4ARGS(libGAP_Obj f, libGAP_Obj a1, libGAP_Obj a2, libGAP_Obj a3,
+-                                 libGAP_Obj a4)
+-    libGAP_Obj libGAP_CALL_5ARGS(libGAP_Obj f, libGAP_Obj a1, libGAP_Obj a2, libGAP_Obj a3,
+-                                 libGAP_Obj a4, libGAP_Obj a5)
+-    libGAP_Obj libGAP_CALL_6ARGS(libGAP_Obj f, libGAP_Obj a1, libGAP_Obj a2, libGAP_Obj a3,
+-                                 libGAP_Obj a4, libGAP_Obj a5, libGAP_Obj a6)
+-    libGAP_Obj libGAP_CALL_XARGS(libGAP_Obj f, libGAP_Obj args)   # more than 6 arguments
+-    bint libGAP_EQ(libGAP_Obj opL, libGAP_Obj opR)
+-    bint libGAP_LT(libGAP_Obj opL, libGAP_Obj opR)
++cdef extern from "<gap/bool.h>":
++    cdef Obj GAP_True "True"
++    cdef Obj GAP_False "False"
++
+ 
+ cdef extern from "<gap/calls.h>":
+-    bint libGAP_IS_FUNC(libGAP_Obj)
++    bint IS_FUNC(Obj)
++    Obj CALL_0ARGS(Obj f)              # 0 arguments
++    Obj CALL_1ARGS(Obj f, Obj a1)      # 1 argument
++    Obj CALL_2ARGS(Obj f, Obj a1, Obj a2)
++    Obj CALL_3ARGS(Obj f, Obj a1, Obj a2, Obj a3)
++    Obj CALL_4ARGS(Obj f, Obj a1, Obj a2, Obj a3, Obj a4)
++    Obj CALL_5ARGS(Obj f, Obj a1, Obj a2, Obj a3, Obj a4, Obj a5)
++    Obj CALL_6ARGS(Obj f, Obj a1, Obj a2, Obj a3, Obj a4, Obj a5, Obj a6)
++    Obj CALL_XARGS(Obj f, Obj args)   # more than 6 arguments
++
++
++cdef extern from "<gap/gasman.h>":
++    Obj NewBag "NewBag"(UInt type, UInt size)
++    void MarkBag(Obj bag)
++    UInt CollectBags(UInt size, UInt full)
++
++
++cdef extern from "<gap/gasman_intern.h>":
++    void CallbackForAllBags(void (*func)(Obj))
++
++
++cdef extern from "<gap/gvars.h>":
++    UInt GVarName "GVarName"(char* name)
++    void AssGVar "AssGVar"(UInt gvar, Obj val)
++
++
++cdef extern from "<gap/integer.h>":
++    Int IS_INT(Obj)
++
++
++cdef extern from "<gap/intobj.h>":
++    bint IS_INTOBJ(Obj obj)
++    Obj INTOBJ_INT(Int)
++    Int INT_INTOBJ(Obj)
++
++
++cdef extern from "<gap/io.h>":
++    UInt OpenOutputStream(Obj stream)
++    UInt CloseOutput()
++
++
++cdef extern from "<gap/libgap-api.h>":
++    ctypedef void (*CallbackFunc)()
++    void GAP_Initialize(int argc, char ** argv, char ** env,
++        CallbackFunc, CallbackFunc)
++    Obj GAP_EvalString(const char *) except *
++    Obj GAP_EvalStringNoExcept "GAP_EvalString"(const char *)
++    Obj GAP_ValueGlobalVariable(const char *)
++
++
++cdef extern from "<gap/libgap-api.h>" nogil:
++    cdef void GAP_EnterStack()
++    cdef void GAP_LeaveStack()
++    cdef int GAP_Enter() except 0
++    cdef void GAP_Leave()
++    cdef int GAP_Error_Setjmp() except 0
+ 
+-cdef extern from "<gap/plist.h>":
+-    libGAP_Obj libGAP_NEW_PLIST(int type, int len)
+-    bint libGAP_IS_PLIST(libGAP_Obj lst)
+-    int libGAP_LEN_PLIST(libGAP_Obj lst)
+-    libGAP_Obj libGAP_ELM_PLIST(libGAP_Obj lst, int pos)
+ 
+ cdef extern from "<gap/lists.h>":
+-    void libGAP_UNB_LIST(libGAP_Obj lst, int pos)
+-    bint libGAP_IS_LIST(libGAP_Obj lst)
+-    int libGAP_LEN_LIST(libGAP_Obj lst)
+-    libGAP_Obj libGAP_ELM_LIST(libGAP_Obj lst, int pos)
+-    void libGAP_ASS_LIST(libGAP_Obj lst, int pos, libGAP_Obj elt)
++    bint IS_LIST(Obj lst)
++    int LEN_LIST(Obj lst)
++    Obj ELM_LIST(Obj lst, int pos)
++    Obj ELM0_LIST(Obj lst, int pos)
++    void ASS_LIST(Obj lst, int pos, Obj elt)
++
+ 
+ cdef extern from "<gap/listfunc.h>":
+-    void libGAP_AddList(libGAP_Obj list, libGAP_Obj obj)
+-    void libGAP_AddPlist(libGAP_Obj list, libGAP_Obj obj)
++    void AddList(Obj list, Obj obj)
++
+ 
+ cdef extern from "<gap/macfloat.h>":
+-    bint libGAP_IS_MACFLOAT(libGAP_Obj obj)
+-    double libGAP_VAL_MACFLOAT(libGAP_Obj obj)
++    double VAL_MACFLOAT(Obj obj)
++
++
++cdef extern from "<gap/objects.h>":
++    bint IS_MUTABLE_OBJ(Obj obj)
++    Obj SHALLOW_COPY_OBJ(Obj obj)
++    Obj CopyObj(Obj obj, int mut)
++
++    UInt SIZE_OBJ(Obj obj)
++    UInt TNUM_OBJ(Obj obj)
++    char* TNAM_OBJ(Obj obj)
++
++    cdef int T_INTPOS
++    cdef int T_INTNEG
++    cdef int T_RAT
++    cdef int T_CYC
++    cdef int T_FFE
++    cdef int T_PERM2
++    cdef int T_PERM4
++    cdef int T_BOOL
++    cdef int T_CHAR
++    cdef int T_FUNCTION
++    cdef int T_MACFLOAT
++    cdef int T_PLIST
++    cdef int T_PLIST_CYC
++    cdef int T_BLIST
++    cdef int T_STRING
++    cdef int T_COMOBJ
++    cdef int T_POSOBJ
++    cdef int T_DATOBJ
++    cdef int T_WPOBJ
+ 
+-cdef extern from "<gap/records.h>":
+-    char* libGAP_NAME_RNAM(libGAP_UInt rnam)
+-    libGAP_UInt libGAP_RNamIntg(int i)
+-    bint libGAP_IS_REC(libGAP_Obj obj)
+-    libGAP_Obj libGAP_ELM_REC(libGAP_Obj rec, libGAP_UInt rnam)
+-    libGAP_UInt libGAP_RNamName(libGAP_Char* name)
+ 
+ cdef extern from "<gap/precord.h>":
+-    libGAP_Obj libGAP_NEW_PREC(int len)
+-    int libGAP_LEN_PREC(libGAP_Obj rec)
+-    int libGAP_GET_RNAM_PREC(libGAP_Obj rec, int i)
+-    libGAP_Obj libGAP_GET_ELM_PREC(libGAP_Obj rec, int i)
+-    void libGAP_AssPRec(libGAP_Obj rec, libGAP_UInt rnam, libGAP_Obj val)
+-    void libGAP_UnbPRec(libGAP_Obj rec, libGAP_UInt rnam)
+-    bint libGAP_IsbPRec(libGAP_Obj rec, libGAP_UInt rnam)
+-    libGAP_Obj libGAP_ElmPRec(libGAP_Obj rec, libGAP_UInt rnam)
+-
+-cdef extern from "<gap/cyclotom.h>":
+-    pass
++    Obj NEW_PREC(int len)
++    int LEN_PREC(Obj rec)
++    int GET_RNAM_PREC(Obj rec, int i)
++    Obj GET_ELM_PREC(Obj rec, int i)
++    void AssPRec(Obj rec, UInt rnam, Obj val)
+ 
+-cdef extern from "<gap/bool.h>":
+-    cdef libGAP_Obj libGAP_True
+-    cdef libGAP_Obj libGAP_False
+ 
+-cdef extern from "<gap/vars.h>":
+-     cdef int libGAP_T_LVARS
+-     libGAP_Obj libGAP_BottomLVars
++cdef extern from "<gap/records.h>":
++    char* NAME_RNAM(UInt rnam)
++    bint IS_REC(Obj obj)
++    Obj ELM_REC(Obj rec, UInt rnam)
++    UInt RNamName(Char* name)
++
++
++cdef extern from "<gap/stringobj.h>":
++    char* CSTR_STRING(Obj list)
++    bint IS_STRING(Obj obj)
++    bint IsStringConv(Obj obj)
++    Obj NEW_STRING(Int)
++    void C_NEW_STRING(Obj new_gap_string, int length, char* c_string)
+diff --git a/src/sage/libs/gap/libgap.pyx b/src/sage/libs/gap/libgap.pyx
+index 8d2fc46..cb7b2cb 100644
+--- a/src/sage/libs/gap/libgap.pyx
++++ b/src/sage/libs/gap/libgap.pyx
+@@ -160,53 +160,10 @@ using the recursive expansion of the
+ Using the libGAP C library from Cython
+ ======================================
+ 
+-The lower-case ``libgap_foobar`` functions are ones that we added to
+-make the libGAP C shared library. The ``libGAP_foobar`` methods are
+-the original GAP methods simply prefixed with the string
+-``libGAP_``. The latter were originally not designed to be in a
+-library, so some care needs to be taken to call them.
+-
+-In particular, you must call ``libgap_mark_stack_bottom()`` in every
+-function that calls into the libGAP C functions. The reason is that
+-the GAP memory manager will automatically keep objects alive that are
+-referenced in local (stack-allocated) variables. While convenient,
+-this requires to look through the stack to find anything that looks
+-like an address to a memory bag. But this requires vigilance against
+-the following pattern::
+-
+-    cdef f()
+-      libgap_mark_stack_bottom()
+-      libGAP_function()
+-
+-    cdef g()
+-      libgap_mark_stack_bottom();
+-      f()                #  f() changed the stack bottom marker
+-      libGAP_function()  #  boom
+-
+-The solution is to re-order ``g()`` to first call ``f()``. In order to
+-catch this error, it is recommended that you wrap calls into libGAP in
+-``libgap_enter`` / ``libgap_exit`` blocks and not call
+-``libgap_mark_stack_bottom`` manually. So instead, always write
+-
+-    cdef f()
+-      libgap_enter()
+-      libGAP_function()
+-      libgap_exit()
+-
+-    cdef g()
+-      f()
+-      libgap_enter()
+-      libGAP_function()
+-      libgap_exit()
+-
+-If you accidentally call ``libgap_enter()`` twice then an error
+-message is printed to help you debug this::
+-
+-    sage: from sage.libs.gap.util import error_enter_libgap_block_twice
+-    sage: error_enter_libgap_block_twice()
+-    Traceback (most recent call last):
+-    ...
+-    RuntimeError: Entered a critical block twice
++.. TODO:: Update the following text
++
++   We are using libgap API provided by the GAP project since
++   GAP 4.10.
+ 
+ AUTHORS:
+ 
+@@ -215,6 +172,8 @@ AUTHORS:
+     almost complete rewrite; first usable version.
+   - Volker Braun (2012-08-28, GAP/Singular workshop): update to
+     gap-4.5.5, make it ready for public consumption.
++  - Dima Pasechnik (2018-09-18, GAP Days): started the port to native
++    libgap API
+ """
+ 
+ ###############################################################################
+@@ -254,6 +213,8 @@ AUTHORS:
+ 
+ from __future__ import print_function, absolute_import
+ 
++from pprint import pprint
++
+ from .gap_includes cimport *
+ from .util cimport *
+ from .element cimport *
+@@ -263,23 +224,20 @@ from sage.structure.parent cimport Parent
+ from sage.structure.element cimport ModuleElement, RingElement, Vector
+ from sage.rings.all import ZZ
+ from sage.misc.cachefunc import cached_method
+-from sage.misc.superseded import deprecated_function_alias
++from sage.misc.superseded import deprecated_function_alias, deprecation
+ 
+ 
+ ############################################################################
+ ### Debugging ##############################################################
+ ############################################################################
+ 
+-cdef void report(libGAP_Obj bag):
+-    print(libGAP_TNAM_OBJ(bag), <int>libGAP_TNUM_BAG(bag), <int>libGAP_SIZE_BAG(bag))
+ 
+-
+-cdef void print_gasman_objects():
+-    libgap_enter()
+-    libGAP_CallbackForAllBags(report)
+-    libgap_exit()
++cdef void report(Obj bag):
++    print(TNAM_OBJ(bag),  <int>SIZE_OBJ(bag))
+ 
+ 
++cdef void print_gasman_objects():
++    CallbackForAllBags(report)
+ 
+ 
+ from sage.misc.lazy_import import is_during_startup
+@@ -370,7 +328,7 @@ class Gap(Parent):
+             return make_GapElement_Record(self, make_gap_record(x))
+         elif isinstance(x, bool):
+             # attention: must come before int
+-            return make_GapElement_Boolean(self, libGAP_True if x else libGAP_False)
++            return make_GapElement_Boolean(self, GAP_True if x else GAP_False)
+         elif isinstance(x, int):
+             return make_GapElement_Integer(self, make_gap_integer(x))
+         elif isinstance(x, basestring):
+@@ -443,9 +401,18 @@ class Gap(Parent):
+             sage: libgap.eval('"string"')
+             "string"
+         """
++        cdef GapElement elem
++
+         if not isinstance(gap_command, basestring):
+             gap_command = str(gap_command._gap_init_())
+-        return make_any_gap_element(self, gap_eval(gap_command))
++
++        elem = make_any_gap_element(self, gap_eval(gap_command))
++
++        # If the element is NULL just return None instead
++        if elem.value == NULL:
++            return None
++
++        return elem
+ 
+     @cached_method
+     def function_factory(self, function_name):
+@@ -520,9 +487,11 @@ class Gap(Parent):
+             ...
+             ValueError: libGAP: Error, VAL_GVAR: No value bound to FooBar
+         """
++        is_readonlyglobal = self.function_factory('IsReadOnlyGlobal')
+         make_readwrite = self.function_factory('MakeReadWriteGlobal')
+         unbind_global = self.function_factory('UnbindGlobal')
+-        make_readwrite(variable)
++        if is_readonlyglobal(variable):
++            make_readwrite(variable)
+         unbind_global(variable)
+ 
+     def get_global(self, variable):
+@@ -634,7 +603,6 @@ class Gap(Parent):
+             <class 'sage.libs.gap.libgap.Gap'>
+         """
+         initialize()
+-        libgap_set_gasman_callback(gasman_callback)
+         from sage.rings.integer_ring import ZZ
+         Parent.__init__(self, base=ZZ)
+ 
+@@ -663,12 +631,13 @@ class Gap(Parent):
+            sage: 'OctaveAlgebra' in dir(libgap)
+            True
+         """
+-        from sage.libs.gap.gap_functions import common_gap_functions
+-        return dir(self.__class__) + list(common_gap_functions)
++        from sage.libs.gap.gap_globals import common_gap_globals
++        return dir(self.__class__) + sorted(common_gap_globals)
+ 
+     def __getattr__(self, name):
+         r"""
+-        The attributes of the Gap object are the Gap functions.
++        The attributes of the Gap object are the Gap functions, and in some
++        cases other global variables from GAP.
+ 
+         INPUT:
+ 
+@@ -677,32 +646,52 @@ class Gap(Parent):
+ 
+         OUTPUT:
+ 
+-        A :class:`GapElement_Function`. A ``AttributeError`` is raised
+-        if there is no such function.
++        A :class:`GapElement`. A ``AttributeError`` is raised
++        if there is no such function or global variable.
+ 
+         EXAMPLES::
+ 
+             sage: libgap.List
+             <Gap function "List">
++            sage: libgap.GlobalRandomSource
++            <RandomSource in IsGlobalRandomSource>
+         """
+         if name in dir(self.__class__):
+             return getattr(self.__class__, name)
++
+         from sage.libs.gap.gap_functions import common_gap_functions
++        from sage.libs.gap.gap_globals import common_gap_globals
+         if name in common_gap_functions:
+-            f = make_GapElement_Function(self, gap_eval(str(name)))
+-            assert f.is_function()
+-            self.__dict__[name] = f
+-            return f
++            g = make_GapElement_Function(self, gap_eval(name))
++            assert g.is_function()
++        elif name in common_gap_globals:
++            g = make_any_gap_element(self, gap_eval(name))
+         else:
+-            raise AttributeError('No such attribute: '+name+'.')
++            raise AttributeError(f'No such attribute: {name}.')
++
++        self.__dict__[name] = g
++        return g
+ 
+     def show(self):
+         """
+-        Print statistics about the GAP owned object list
++        Return statistics about the GAP owned object list
++
++        This includes the total memory allocated by GAP as returned by
++        ``libgap.eval('TotalMemoryAllocated()'), as well as garbage collection
++        / object count statistitics as returned by
++        ``libgap.eval('GasmanStatistics')``, and finally the total number of
++        GAP objects held by Sage as :class:`~sage.libs.gap.element.GapElement`
++        instances.
+ 
+-        Slight complication is that we want to do it without accessing
+-        libgap objects, so we don't create new GapElements as a side
+-        effect.
++        The value ``livekb + deadkb`` will roughly equal the total memory
++        allocated for GAP objects (see
++        ``libgap.eval('TotalMemoryAllocated()')``).
++
++        .. note::
++
++            Slight complication is that we want to do it without accessing
++            libgap objects, so we don't create new GapElements as a side
++            effect.
+ 
+         EXAMPLES::
+ 
+@@ -710,15 +699,25 @@ class Gap(Parent):
+             sage: b = libgap(456)
+             sage: c = libgap(789)
+             sage: del b
+-            sage: libgap.show() # random output
+-            11 LibGAP elements currently alive
+-            rec( full := rec( cumulative := 122, deadbags := 9,
+-            deadkb := 0, freekb := 7785, livebags := 304915,
+-            livekb := 47367, time := 33, totalkb := 68608 ),
+-            nfull := 3, npartial := 14 )
+-        """
+-        print('{} LibGAP elements currently alive'.format(self.count_GAP_objects()))
+-        print(self.eval('GasmanStatistics()'))
++            sage: libgap.collect()
++            sage: libgap.show()  # random output
++            {'gasman_stats': {'full': {'cumulative': 110,
++               'deadbags': 321400,
++               'deadkb': 12967,
++               'freekb': 15492,
++               'livebags': 396645,
++               'livekb': 37730,
++               'time': 110,
++               'totalkb': 65536},
++              'nfull': 1,
++              'npartial': 1},
++             'nelements': 23123,
++             'total_alloc': 3234234}
++        """
++        d = {'nelements': self.count_GAP_objects()}
++        d['total_alloc'] = self.eval('TotalMemoryAllocated()').sage()
++        d['gasman_stats'] = self.eval('GasmanStatistics()').sage()
++        return d
+ 
+     def count_GAP_objects(self):
+         """
+@@ -734,57 +733,19 @@ class Gap(Parent):
+             sage: libgap.count_GAP_objects()   # random output
+             5
+         """
+-        return sum([1 for obj in get_owned_objects()])
++        return len(get_owned_objects())
+ 
+     def mem(self):
+         """
+-        Return information about libGAP memory usage
++        Return information about GAP memory usage
+ 
+-        The GAP workspace is partitioned into 5 pieces (see gasman.c
+-        in the GAP sources for more details):
+-
+-        * The **masterpointer area**  contains  all the masterpointers  of  the bags.
+-
+-        * The **old bags area** contains the bodies of all the  bags that survived at
+-          least one  garbage collection.  This area is  only  scanned for dead bags
+-          during a full garbage collection.
+-
+-        * The **young bags area** contains the bodies of all  the bags that have been
+-          allocated since the  last garbage collection.  This  area is scanned  for
+-          dead  bags during  each garbage  collection.
+-
+-        * The **allocation area** is the storage  that is available for allocation of
+-          new bags.  When a new bag is allocated the storage for  the body is taken
+-          from  the beginning of   this area,  and  this  area  is  correspondingly
+-          reduced.   If  the body does not   fit in the  allocation  area a garbage
+-          collection is  performed.
+-
+-        * The **unavailable  area** is  the free  storage that  is not  available for
+-          allocation.
+-
+-        OUTPUT:
+-
+-        This function returns a tuple containing 5 integers. Each is
+-        the size (in bytes) of the five partitions of the
+-        workspace. This will potentially change after each GAP garbage
+-        collection.
+-
+-        EXAMPLES::
+-
+-            sage: libgap.collect()
+-            sage: libgap.mem()   # random output
+-            (1048576, 6706782, 0, 960930, 0)
+-
+-            sage: libgap.FreeGroup(3)
+-            <free group on the generators [ f1, f2, f3 ]>
+-            sage: libgap.mem()   # random output
+-            (1048576, 6706782, 47571, 913359, 0)
+-
+-            sage: libgap.collect()
+-            sage: libgap.mem()   # random output
+-            (1048576, 6734785, 0, 998463, 0)
++        This method is deprecated and is a no-op.  Use :meth:`Gap.show` to
++        display memory-usage and bag count statistics from GASMAN.
+         """
+-        return memory_usage()
++
++        deprecation(22626, 'this functionality is not supported by GAP; use '
++                           'libgap.show() for GAP memory usage statistics')
++        return (0, 0, 0, 0, 0)
+ 
+     def collect(self):
+         """
+@@ -796,9 +757,7 @@ class Gap(Parent):
+             sage: del a
+             sage: libgap.collect()
+         """
+-        libgap_enter()
+-        rc = libGAP_CollectBags(0, 1)
+-        libgap_exit()
++        rc = CollectBags(0, 1)
+         if rc != 1:
+             raise RuntimeError('Garbage collection failed.')
+ 
+diff --git a/src/sage/libs/gap/operations.py b/src/sage/libs/gap/operations.py
+index 92ffc3d..f28b4ab 100644
+--- a/src/sage/libs/gap/operations.py
++++ b/src/sage/libs/gap/operations.py
+@@ -11,6 +11,7 @@ lists all GAP operations for which ``Operation(x, ...)`` is defined.
+ 
+ import re
+ import string
++
+ from sage.structure.sage_object import SageObject
+ from sage.libs.gap.libgap import libgap
+ 
+@@ -18,6 +19,7 @@ Length = libgap.function_factory('Length')
+ FlagsType = libgap.function_factory('FlagsType')
+ TypeObj = libgap.function_factory('TypeObj')
+ IS_SUBSET_FLAGS = libgap.function_factory('IS_SUBSET_FLAGS')
++GET_OPER_FLAGS = libgap.function_factory('GET_OPER_FLAGS')
+ OPERATIONS = libgap.get_global('OPERATIONS')
+ NameFunction = libgap.function_factory('NameFunction')
+ 
+@@ -74,7 +76,7 @@ class OperationInspector(SageObject):
+ 
+             sage: from sage.libs.gap.operations import OperationInspector
+             sage: x = OperationInspector(libgap(123))
+-            sage: x.obj
++            sage: print(x.obj)
+             123
+         """
+         return self._obj
+@@ -95,20 +97,12 @@ class OperationInspector(SageObject):
+             sage: Unknown in x.operations()
+             True
+         """
+-        result = []
+-        for i in range(len(OPERATIONS) // 2):
+-            match = False
+-            for flag_list in OPERATIONS[2*i + 1]:
+-                if Length(flag_list) == 0:
+-                    continue
+-                first_flag = flag_list[0]
+-                if IS_SUBSET_FLAGS(self.flags, first_flag):
+-                    match = True
+-                    break
+-            if match:
+-                op = OPERATIONS[2*i]
+-                result.append(op)
+-        return result
++        def mfi(o):
++            filts = GET_OPER_FLAGS(o)
++            return any(all(IS_SUBSET_FLAGS(self.flags, fl) for fl in fls)
++                       for fls in filts)
++
++        return filter(mfi, OPERATIONS)
+ 
+     def op_names(self):
+         """
+diff --git a/src/sage/libs/gap/sage.gaprc b/src/sage/libs/gap/sage.gaprc
+new file mode 100644
+index 00000000..17613fa
+--- /dev/null
++++ b/src/sage/libs/gap/sage.gaprc
+@@ -0,0 +1,12 @@
++# This file is run by Sage when initializing libgap via GAP_Initialize, and may
++# contain bug fixes/workarounds and/or any Sage-specific patches necessary for
++# Sage's libgap interface.
++
++if GAPInfo.CommandLineOptions.norepl then
++    # GAP 4.10.0 has a bug that an interactive session will be started
++    # even if --norepl was set; see https://github.com/gap-system/gap/pull/2840
++    # To work around this we redefine the SESSION function to a no-op
++    MAKE_READ_WRITE_GLOBAL("SESSION");
++    UNBIND_GLOBAL("SESSION");
++    BIND_GLOBAL("SESSION", function() end);
++fi;
+diff --git a/src/sage/libs/gap/saved_workspace.py b/src/sage/libs/gap/saved_workspace.py
+index 3cb8fd3..ad5adec 100644
+--- a/src/sage/libs/gap/saved_workspace.py
++++ b/src/sage/libs/gap/saved_workspace.py
+@@ -9,7 +9,6 @@ workspaces.
+ import os
+ import glob
+ from sage.env import GAP_ROOT_DIR
+-from sage.interfaces.gap import GAP_BINARY
+ from sage.interfaces.gap_workspace import gap_workspace_file
+ 
+ 
+@@ -33,7 +32,7 @@ def timestamp():
+     libgap_dir = os.path.dirname(__file__)
+     libgap_files = glob.glob(os.path.join(libgap_dir, '*'))
+     gap_packages = glob.glob(os.path.join(GAP_ROOT_DIR, 'pkg', '*'))
+-    files = libgap_files + [GAP_BINARY] + gap_packages
++    files = libgap_files + gap_packages
+     if len(files) == 0:
+         print('Unable to find LibGAP files.')
+         return float('inf')
+diff --git a/src/sage/libs/gap/types.pxd b/src/sage/libs/gap/types.pxd
+deleted file mode 100644
+index dcf5003..00000000
+--- a/src/sage/libs/gap/types.pxd
++++ /dev/null
+@@ -1,26 +0,0 @@
+-###############################################################################
+-#       Copyright (C) 2009, William Stein <wstein at gmail.com>
+-#       Copyright (C) 2012, Volker Braun <vbraun.name at gmail.com>
+-#
+-#   Distributed under the terms of the GNU General Public License (GPL)
+-#   as published by the Free Software Foundation; either version 2 of
+-#   the License, or (at your option) any later version.
+-#                   http://www.gnu.org/licenses/
+-###############################################################################
+-
+-
+-cdef extern from "<gap/system.h>":
+-    ctypedef char libGAP_Char
+-    ctypedef int libGAP_Int
+-    ctypedef unsigned char libGAP_UChar
+-
+-cdef extern from "<gap/code.h>":
+-    ctypedef unsigned int libGAP_Stat
+-    ctypedef libGAP_Stat* libGAP_PtrBody
+-
+-cdef extern from "<gap/gap.h>":
+-    ctypedef unsigned int libGAP_UInt
+-    ctypedef void* libGAP_ExecStatus
+-
+-cdef extern from "<gap/objects.h>":
+-    ctypedef void* libGAP_Obj
+diff --git a/src/sage/libs/gap/util.pxd b/src/sage/libs/gap/util.pxd
+index 2a82834..d2ce2d0 100644
+--- a/src/sage/libs/gap/util.pxd
++++ b/src/sage/libs/gap/util.pxd
+@@ -8,25 +8,24 @@
+ #                  http://www.gnu.org/licenses/
+ #*****************************************************************************
+ 
+-from .types cimport libGAP_Obj
+-
++from .gap_includes cimport Obj
+ 
+ ############################################################################
+ ### Hooking into the GAP memory management #################################
+ ############################################################################
+ 
+ cdef class ObjWrapper(object):
+-    cdef libGAP_Obj value
++    cdef Obj value
+ 
+-cdef ObjWrapper wrap_obj(libGAP_Obj obj)
++cdef ObjWrapper wrap_obj(Obj obj)
+ 
+ # returns the refcount dictionary for debugging purposes
+ cpdef get_owned_objects()
+ 
+ # Reference count GAP objects that you want to prevent from being
+ # garbage collected
+-cdef void reference_obj(libGAP_Obj obj)
+-cdef void dereference_obj(libGAP_Obj obj)
++cdef void reference_obj(Obj obj)
++cdef void dereference_obj(Obj obj)
+ 
+ # callback from the GAP memory manager so we can mark all_gap_elements.values()
+ cdef void gasman_callback()
+@@ -44,12 +43,4 @@ cdef initialize()
+ ############################################################################
+ 
+ # Evaluate a string
+-cdef libGAP_Obj gap_eval(str gap_string) except? NULL
+-
+-
+-############################################################################
+-### Debug functions ########################################################
+-############################################################################
+-
+-# Return details of the GAP memory pool
+-cpdef memory_usage()
++cdef Obj gap_eval(str gap_string) except? NULL
+diff --git a/src/sage/libs/gap/util.pyx b/src/sage/libs/gap/util.pyx
+index 5ff6710..5e2805d 100644
+--- a/src/sage/libs/gap/util.pyx
++++ b/src/sage/libs/gap/util.pyx
+@@ -14,24 +14,33 @@ Utility functions for libGAP
+ 
+ from __future__ import print_function, absolute_import
+ 
+-import os.path
++import os
++import signal
++import warnings
+ 
+-from cpython.exc cimport PyErr_SetObject
++from libc.string cimport strcpy, strlen
++
++from cpython.exc cimport PyErr_SetObject, PyErr_Occurred, PyErr_Fetch
+ from cpython.object cimport Py_LT, Py_LE, Py_EQ, Py_NE, Py_GT, Py_GE
++from cpython.ref cimport PyObject
++from cysignals.memory cimport sig_malloc
++from cysignals.pysignals import changesignal
+ from cysignals.signals cimport sig_on, sig_off, sig_error
+ 
++import sage.env
++
+ from .gap_includes cimport *
+ from .element cimport *
+ from sage.cpython.string import FS_ENCODING
+ from sage.cpython.string cimport str_to_bytes, char_to_str
+ from sage.interfaces.gap_workspace import prepare_workspace_dir
+-from sage.env import SAGE_LOCAL, GAP_ROOT_DIR
+ 
+ 
+ ############################################################################
+ ### Hooking into the GAP memory management #################################
+ ############################################################################
+ 
++
+ cdef class ObjWrapper(object):
+     """
+     Wrapper for GAP master pointers
+@@ -47,7 +56,7 @@ cdef class ObjWrapper(object):
+ 
+     def __richcmp__(ObjWrapper self, ObjWrapper other, int op):
+         r"""
+-        Comparison wrapped libGAP_Obj.
++        Comparison wrapped Obj.
+ 
+         INPUT:
+ 
+@@ -68,8 +77,8 @@ cdef class ObjWrapper(object):
+             True
+         """
+         cdef result
+-        cdef libGAP_Obj self_value = self.value
+-        cdef libGAP_Obj other_value = other.value
++        cdef Obj self_value = self.value
++        cdef Obj other_value = other.value
+         if op == Py_LT:
+             return self_value < other_value
+         elif op == Py_LE:
+@@ -99,7 +108,7 @@ cdef class ObjWrapper(object):
+         return <int>(self.value)
+ 
+ 
+-cdef ObjWrapper wrap_obj(libGAP_Obj obj):
++cdef ObjWrapper wrap_obj(Obj obj):
+     """
+     Constructor function for :class:`ObjWrapper`
+     """
+@@ -109,8 +118,13 @@ cdef ObjWrapper wrap_obj(libGAP_Obj obj):
+ 
+ 
+ # a dictionary to keep all GAP elements
++# needed for GASMAN callbacks
++#
+ cdef dict owned_objects_refcount = dict()
+ 
++#
++# used in Sage's libgap.Gap.count_GAP_objects
++#
+ cpdef get_owned_objects():
+     """
+     Helper to access the refcount dictionary from Python code
+@@ -118,19 +132,20 @@ cpdef get_owned_objects():
+     return owned_objects_refcount
+ 
+ 
+-cdef void reference_obj(libGAP_Obj obj):
++cdef void reference_obj(Obj obj):
+     """
+     Reference ``obj``
+     """
+     cdef ObjWrapper wrapped = wrap_obj(obj)
+     global owned_objects_refcount
++#    print("reference_obj called "+ crepr(obj) +"\n")
+     if wrapped in owned_objects_refcount:
+         owned_objects_refcount[wrapped] += 1
+     else:
+         owned_objects_refcount[wrapped] = 1
+ 
+ 
+-cdef void dereference_obj(libGAP_Obj obj):
++cdef void dereference_obj(Obj obj):
+     """
+     Reference ``obj``
+     """
+@@ -147,7 +162,7 @@ cdef void gasman_callback():
+     """
+     global owned_objects_refcount
+     for obj in owned_objects_refcount:
+-        libGAP_MARK_BAG((<ObjWrapper>obj).value)
++        MarkBag((<ObjWrapper>obj).value)
+ 
+ 
+ 
+@@ -157,25 +172,6 @@ cdef void gasman_callback():
+ ### Initialization of libGAP ###############################################
+ ############################################################################
+ 
+-def _guess_gap_root():
+-    """
+-    Used as a fallback to determine gapdir if if GAP_ROOT_DIR is undefined or
+-    pointing to the wrong location.
+-
+-    EXAMPLES::
+-
+-        sage: from sage.libs.gap.util import _guess_gap_root
+-        sage: _guess_gap_root()
+-        The gap-4.5.5.spkg (or later) seems to be not installed!
+-        ...
+-    """
+-    print('The gap-4.5.5.spkg (or later) seems to be not installed!')
+-    gap_sh = open(os.path.join(SAGE_LOCAL, 'bin', 'gap')).read().splitlines()
+-    gapdir = next(dir for dir in gap_sh if dir.strip().startswith('GAP_DIR'))
+-    gapdir = gapdir.split('"')[1]
+-    gapdir = gapdir.replace('$SAGE_LOCAL', SAGE_LOCAL)
+-    return gapdir
+-
+ def gap_root():
+     """
+     Find the location of the GAP root install which is stored in the gap
+@@ -187,17 +183,68 @@ def gap_root():
+         sage: gap_root()   # random output
+         '/home/vbraun/opt/sage-5.3.rc0/local/gap/latest'
+     """
+-    try:
+-        if os.path.exists(GAP_ROOT_DIR):
+-            return GAP_ROOT_DIR
+-    except TypeError:
+-        raise RuntimeError('The GAP_ROOT_DIR environment variable is set to an invalid path: "{}"'.format(GAP_ROOT_DIR))
++    if os.path.exists(sage.env.GAP_ROOT_DIR):
++        return sage.env.GAP_ROOT_DIR
+ 
+-    return _guess_gap_root()
++    # Attempt to figure out the appropriate GAP_ROOT by reading the
++    # local/bin/gap shell script; this is an ugly hack that exists for
++    # historical reasons; the best approach to setting where Sage looks for
++    # the appropriate GAP_ROOT is to set the GAP_ROOT_DIR variable
++    SAGE_LOCAL = sage.env.SAGE_LOCAL
++    gap_sh = open(os.path.join(SAGE_LOCAL, 'bin', 'gap')).read().splitlines()
++    gapdir = filter(lambda dir:dir.strip().startswith('GAP_ROOT'), gap_sh)[0]
++    gapdir = gapdir.split('"')[1]
++    gapdir = gapdir.replace('$SAGE_LOCAL', SAGE_LOCAL)
++    return gapdir
+ 
+ 
+ # To ensure that we call initialize_libgap only once.
+ cdef bint _gap_is_initialized = False
++cdef extern char **environ
++
++
++cdef char* _reset_error_output_cmd = """\
++libgap_errout := "";
++MakeReadWriteGlobal("ERROR_OUTPUT");
++ERROR_OUTPUT := OutputTextString(libgap_errout, false);
++MakeReadOnlyGlobal("ERROR_OUTPUT");
++"""
++
++cdef char* _close_error_output_cmd = """\
++CloseStream(ERROR_OUTPUT);
++MakeReadWriteGlobal("ERROR_OUTPUT");
++ERROR_OUTPUT := "*errout*";
++MakeReadOnlyGlobal("ERROR_OUTPUT");
++MakeImmutable(libgap_errout);
++"""
++
++
++cdef char** copy_environ(char** env):
++    """
++    Make a copy of the environment block given by ``env``.
++
++    Returns a pointer to the copy, which is the caller's responsibility to
++    free.
++    """
++
++    cdef char** env_copy
++    cdef int envc = 0;
++    cdef int idx
++    cdef size_t size
++
++    while env[envc]:
++        envc += 1
++
++    env_copy = <char**>sig_malloc((envc + 1) * sizeof(char*))
++
++    for idx in range(envc):
++        size = strlen(env[idx]) + 1
++        env_copy[idx] = <char*>sig_malloc(size)
++        strcpy(env_copy[idx], env[idx])
++
++    env_copy[envc] = NULL
++    return env_copy
++
+ 
+ cdef initialize():
+     """
+@@ -209,13 +256,14 @@ cdef initialize():
+         sage: libgap(123)   # indirect doctest
+         123
+     """
+-    global _gap_is_initialized
++    global _gap_is_initialized, environ
+     if _gap_is_initialized: return
+ 
+     # Define argv and environ variables, which we will pass in to
+     # initialize GAP. Note that we must pass define the memory pool
+     # size!
+-    cdef char* argv[14]
++    cdef char** env
++    cdef char* argv[16]
+     argv[0] = "sage"
+     argv[1] = "-l"
+     s = str_to_bytes(gap_root(), FS_ENCODING, "surrogateescape")
+@@ -232,36 +280,56 @@ cdef initialize():
+     argv[8] = "64m"
+ 
+     argv[9] = "-q"    # no prompt!
+-    argv[10] = "-T"    # no debug loop
+-    argv[11] = NULL
+-    cdef int argc = 11   # argv[argc] must be NULL
++    argv[10] = "-E"   # don't use readline as this will interfere with Python
++    argv[11] = "--nointeract"  # Implies -T
++
++    cdef int argc = 12   # argv[argc] must be NULL
+ 
+     from .saved_workspace import workspace
+     workspace, workspace_is_up_to_date = workspace()
+     ws = str_to_bytes(workspace, FS_ENCODING, "surrogateescape")
+     if workspace_is_up_to_date:
+-        argv[11] = "-L"
+-        argv[12] = ws
+-        argv[13] = NULL
+-        argc = 13
++        argv[argc] = "-L"
++        argv[argc + 1] = ws
++        argc += 2
++
++    # Get the path to the sage.gaprc file and check that it exists
++    sage_gaprc = os.path.join(os.path.dirname(__file__), 'sage.gaprc')
++    if not os.path.exists(sage_gaprc):
++        warnings.warn(f"Sage's GAP initialization file {sage_gaprc} is "
++                       "is missing; some functionality may be limited")
++    else:
++        sage_gaprc = str_to_bytes(sage_gaprc, FS_ENCODING, "surrogateescape")
++        argv[argc] = sage_gaprc
++        argc += 1
++
++    argv[argc] = NULL
++
++    env = copy_environ(environ)
+ 
+     # Initialize GAP and capture any error messages
+     # The initialization just prints error and does not use the error handler
+-    libgap_start_interaction('')
+-    libgap_initialize(argc, argv)
+-    gap_error_msg = char_to_str(libgap_get_output())
+-    libgap_finish_interaction()
+-    if gap_error_msg:
+-        raise RuntimeError('libGAP initialization failed\n' + gap_error_msg)
++    sig_on()
++    try:
++        with changesignal(signal.SIGCHLD, signal.SIG_DFL), \
++                changesignal(signal.SIGINT, signal.SIG_DFL):
++            # Need to save/restore current SIGINT handling since GAP_Initialize
++            # currently clobbers it; it doesn't matter what we set SIGINT to
++            # temporarily.
++            GAP_Initialize(argc, argv, env, &gasman_callback,
++                           &error_handler)
++    except RuntimeError as msg:
++        raise RuntimeError('libGAP initialization failed\n' + msg)
++    finally:
++        sig_off()
+ 
+-    # The error handler is called if a GAP evaluation fails, e.g. 1/0
+-    libgap_set_error_handler(&error_handler)
++    # Set the ERROR_OUTPUT global in GAP to an output stream in which to
++    # receive error output
++    GAP_EvalString(_reset_error_output_cmd)
+ 
+     # Prepare global GAP variable to hold temporary GAP objects
+     global reference_holder
+-    libgap_enter()
+-    reference_holder = libGAP_GVarName("$SAGE_libgap_reference_holder")
+-    libgap_exit()
++    reference_holder = GVarName("$SAGE_libgap_reference_holder")
+ 
+     # Finished!
+     _gap_is_initialized = True
+@@ -279,7 +347,7 @@ cdef initialize():
+ ### Evaluate string in GAP #################################################
+ ############################################################################
+ 
+-cdef libGAP_Obj gap_eval(str gap_string) except? NULL:
++cdef Obj gap_eval(str gap_string) except? NULL:
+     r"""
+     Evaluate a string in GAP.
+ 
+@@ -290,79 +358,109 @@ cdef libGAP_Obj gap_eval(str gap_string) except? NULL:
+     OUTPUT:
+ 
+     The resulting GAP object or NULL+Python Exception in case of error.
++    The result object may also be NULL without a Python exception set for
++    statements that do not return a value.
+ 
+     EXAMPLES::
+ 
+         sage: libgap.eval('if 4>3 then\nPrint("hi");\nfi')
+-        NULL
+         sage: libgap.eval('1+1')   # testing that we have successfully recovered
+         2
+ 
+         sage: libgap.eval('if 4>3 thenPrint("hi");\nfi')
+         Traceback (most recent call last):
+         ...
+-        ValueError: libGAP: Syntax error: then expected
++        ValueError: libGAP: Syntax error: then expected in stream:1
+         if 4>3 thenPrint("hi");
+-        fi;
+-                       ^
++               ^^^^^^^^^
+         sage: libgap.eval('1+1')   # testing that we have successfully recovered
+         2
+ 
+     TESTS:
+ 
+-    Check that we fail gracefully if this is called within
+-    ``libgap_enter()``::
++    A bad eval string that results in multiple statement evaluations by GAP
++    and hence multiple errors should still result in a single exception
++    with a message capturing all errors that occurrer::
+ 
+-        sage: cython('''
+-        ....: # distutils: libraries = gap
+-        ....: from sage.libs.gap.gap_includes cimport libgap_enter
+-        ....: libgap_enter()
+-        ....: ''')
+-        sage: libgap.eval('1+1')
++        sage: libgap.eval('Complex Field with 53 bits of precision;')
+         Traceback (most recent call last):
+         ...
+-        ValueError: libGAP: Entered a critical block twice
++        ValueError: libGAP: 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 attemt we get the same message (no garbage was
++    left in the error stream)::
++
++        sage: libgap.eval('Complex Field with 53 bits of precision;')
++        Traceback (most recent call last):
++        ...
++        ValueError: libGAP: Error, Variable: 'Complex' must have a value
++        ...
++        Error, Variable: 'precision' must have a value
++
++        sage: libgap.eval('1+1')  # test that we successfully recover
++        2
+     """
+     initialize()
+-    cdef libGAP_ExecStatus status
++    cdef Obj result
++    cdef int i, j, nresults
+ 
+     # Careful: We need to keep a reference to the bytes object here
+     # so that Cython doesn't dereference it before libGAP is done with
+     # its contents.
+     cmd = str_to_bytes(gap_string + ';\n')
++    sig_on()
+     try:
+-        try:
+-            sig_on()
+-            libgap_enter()
+-            libgap_start_interaction(cmd)
+-            status = libGAP_ReadEvalCommand(libGAP_BottomLVars, NULL)
+-            if status != libGAP_STATUS_END:
+-                libgap_call_error_handler()
+-            sig_off()
+-        except RuntimeError as msg:
+-            raise ValueError('libGAP: '+str(msg).strip())
+-
+-        if libGAP_Symbol != libGAP_S_SEMICOLON:
+-            raise ValueError('did not end with semicolon')
+-        libGAP_GetSymbol()
+-        if libGAP_Symbol != libGAP_S_EOF:
++        GAP_Enter()
++        result = GAP_EvalString(cmd)
++        # We can assume that the result object is a GAP PList (plain list)
++        # and we should use functions for PLists directly for now; see
++        # https://github.com/gap-system/gap/pull/2988/files#r233021437
++
++        # If an error occurred in GAP_EvalString we won't even get
++        # here if the error handler was set; but in case it wasn't
++        # let's still check the result...
++        nresults = LEN_LIST(result)
++        if nresults > 1:  # to mimick the old libGAP
++            # TODO: Get rid of this restriction eventually?
+             raise ValueError('can only evaluate a single statement')
+ 
+-    finally:
+-        libgap_finish_interaction()
+-        libgap_exit()
++        # Get the result of the first statement
++        result = ELM0_LIST(result, 1) # 1-indexed!
+ 
+-    if libGAP_ReadEvalResult != NULL:
+-        libgap_enter()
+-        libGAP_AssGVar(libGAP_Last3, libGAP_VAL_GVAR(libGAP_Last2))
+-        libGAP_AssGVar(libGAP_Last2, libGAP_VAL_GVAR(libGAP_Last))
+-        libGAP_AssGVar(libGAP_Last, libGAP_ReadEvalResult)
+-        libgap_exit()
++        if ELM0_LIST(result, 1) != GAP_True:
++            # An otherwise unhandled error occurred in GAP (such as a
++            # syntax error).  Try running the error handler manually
++            # to capture the error output, if any.
++            # This should result in a RuntimeError being set.
++            error_handler_check_exception()
+ 
+-    return libGAP_ReadEvalResult   # may be NULL, thats ok
++        # The actual resultant object, if any, is in the second entry
++        # (which may be unassigned--see previous github comment; in this case
++        # 0 is returned without setting a a Python exception, so we should treat
++        # this like returning None)
+ 
++        return ELM0_LIST(result, 2)
++    except RuntimeError as msg:
++        raise ValueError(f'libGAP: {msg}')
++    finally:
++        GAP_Leave()
++        sig_off()
+ 
+-############################################################################
++
++###########################################################################
+ ### Helper to protect temporary objects from deletion ######################
+ ############################################################################
+ 
+@@ -370,9 +468,9 @@ cdef libGAP_Obj gap_eval(str gap_string) except? NULL:
+ # get deleted this works by assigning it to a global variable. This is
+ # very simple, but you can't use it to keep two objects alive. Be
+ # careful.
+-cdef libGAP_UInt reference_holder
++cdef UInt reference_holder
+ 
+-cdef void hold_reference(libGAP_Obj obj):
++cdef void hold_reference(Obj obj):
+     """
+     Hold a reference (inside the GAP kernel) to obj
+ 
+@@ -381,177 +479,79 @@ cdef void hold_reference(libGAP_Obj obj):
+     very simple, but you can't use it to keep two objects alive. Be
+     careful.
+     """
+-    libgap_enter()
+     global reference_holder
+-    libGAP_AssGVar(reference_holder, obj)
+-    libgap_exit()
++    AssGVar(reference_holder, obj)
+ 
+ 
+ ############################################################################
+ ### Error handler ##########################################################
+ ############################################################################
+ 
+-cdef void error_handler(char* msg):
+-    """
+-    The libgap error handler
+-
+-    We call ``sig_error()`` which causes us to jump back to the Sage
+-    signal handler. Since we wrap libGAP C calls in ``sig_on`` /
+-    ``sig_off`` blocks, this then jumps back to the ``sig_on`` where
+-    the ``RuntimeError`` we raise here will be seen.
+-    """
+-    msg_py = char_to_str(msg)
+-    msg_py = msg_py.replace('For debugging hints type ?Recovery from NoMethodFound\n', '')
+-    PyErr_SetObject(RuntimeError, msg_py)
+-    sig_error()
+-
+-
+-############################################################################
+-### Debug functions ########################################################
+-############################################################################
+ 
+-cdef inline void DEBUG_CHECK(libGAP_Obj obj):
++cdef object extract_libgap_errout():
+     """
+-    Check that ``obj`` is valid.
+-
+-    This function is only useful for debugging.
++    Reads the global variable libgap_errout and returns a Python string
++    containing the error message (with some boilerplate removed).
+     """
+-    libgap_enter()
+-    libGAP_CheckMasterPointers()
+-    libgap_exit()
+-    if obj == NULL:
+-        print('DEBUG_CHECK: Null pointer!')
+-
+-
++    cdef Obj r
++    cdef char *msg
+ 
++    r = GAP_ValueGlobalVariable("libgap_errout")
+ 
+-cpdef memory_usage():
+-    """
+-    Return information about the memory usage.
+-
+-    See :meth:`~sage.libs.gap.libgap.Gap.mem` for details.
+-    """
+-    cdef size_t SizeMptrsArea = libGAP_OldBags - libGAP_MptrBags
+-    cdef size_t SizeOldBagsArea = libGAP_YoungBags - libGAP_OldBags
+-    cdef size_t SizeYoungBagsArea = libGAP_AllocBags - libGAP_YoungBags
+-    cdef size_t SizeAllocationArea = libGAP_StopBags - libGAP_AllocBags
+-    cdef size_t SizeUnavailableArea = libGAP_EndBags - libGAP_StopBags
+-    return (SizeMptrsArea, SizeOldBagsArea, SizeYoungBagsArea, SizeAllocationArea, SizeUnavailableArea)
+-
+-
+-cpdef error_enter_libgap_block_twice():
+-    """
+-    Demonstrate that we catch errors from entering a block twice.
+-
+-    EXAMPLES::
+-
+-        sage: from sage.libs.gap.util import error_enter_libgap_block_twice
+-        sage: error_enter_libgap_block_twice()
+-        Traceback (most recent call last):
+-        ...
+-        RuntimeError: Entered a critical block twice
+-    """
+-    from sage.libs.gap.libgap import libgap
+-    try:
+-        # The exception will be seen by this sig_on() after being
+-        # raised by the second libgap_enter().
+-        sig_on()
+-        libgap_enter()
+-        libgap_enter()
+-        sig_off()
+-    finally:
+-        libgap_exit()
+-
+-
+-cpdef error_exit_libgap_block_without_enter():
+-    """
+-    Demonstrate that we catch errors from omitting libgap_enter.
+-
+-    EXAMPLES::
+-
+-        sage: from sage.libs.gap.util import error_exit_libgap_block_without_enter
+-        sage: error_exit_libgap_block_without_enter()
+-        Traceback (most recent call last):
+-        ...
+-        RuntimeError: Called libgap_exit without previous libgap_enter
+-    """
+-    from sage.libs.gap.libgap import libgap
+-    sig_on()
+-    libgap_exit()
+-    sig_off()
++    # Grab a pointer to the C string underlying the GAP string libgap_errout
++    # then copy it to a Python str (char_to_str contains an implicit strcpy)
++    msg = CSTR_STRING(r)
++    if msg != NULL:
++        msg_py = char_to_str(msg)
++        msg_py = msg_py.replace('For debugging hints type ?Recovery from '
++                                'NoMethodFound\n', '').strip()
++    else:
++        # Shouldn't happen but just in case...
++        msg_py = ""
+ 
+-############################################################################
+-### Auxilliary functions ###################################################
+-############################################################################
++    return msg_py
+ 
+ 
+-def command(command_string):
++cdef void error_handler():
+     """
+-    Playground for accessing Gap via libGap.
++    The libgap error handler.
+ 
+-    You should not use this function in your own programs. This is
+-    just here for convenience if you want to play with the libgap
+-    libray code.
+-
+-    EXAMPLES::
++    If an error occurred we set a RuntimeError; when the original
++    GAP_EvalString returns this exception will be raised.
+ 
+-        sage: from sage.libs.gap.util import command
+-        sage: command('1')
+-        Output follows...
+-        1
+-
+-        sage: command('1/0')
+-        Traceback (most recent call last):
+-        ...
+-        ValueError: libGAP: Error, Rational operations: <divisor> must not be zero
+-
+-        sage: command('NormalSubgroups')
+-        Output follows...
+-        <Attribute "NormalSubgroups">
+-
+-        sage: command('rec(a:=1, b:=2)')
+-        Output follows...
+-        rec( a := 1, b := 2 )
++    TODO: We should probably prevent re-entering this function if we
++    are already handling an error; if there is an error in our stream
++    handling code below it could result in a stack overflow.
+     """
+-    initialize()
+-    cdef libGAP_ExecStatus status
++    cdef PyObject* exc_type
++    cdef PyObject* exc_val
++    cdef PyObject* exc_tb
+ 
+-    cmd = str_to_bytes(command_string + ';\n')
++    # Close the error stream: This flushes any remaining output and closes
++    # the stream for further writing; reset ERROR_OUTPUT to something sane
++    # just in case (trying to print to a closed stream segfaults GAP)
+     try:
+-        libgap_enter()
+-        libgap_start_interaction(cmd)
+-        try:
+-            sig_on()
+-            status = libGAP_ReadEvalCommand(libGAP_BottomLVars, NULL)
+-            if status != libGAP_STATUS_END:
+-                libgap_call_error_handler()
+-            sig_off()
+-        except RuntimeError as msg:
+-            raise ValueError('libGAP: '+str(msg).strip())
+-
+-        assert libGAP_Symbol == libGAP_S_SEMICOLON, 'Did not end with semicolon?'
+-        libGAP_GetSymbol()
+-        if libGAP_Symbol != libGAP_S_EOF:
+-            raise ValueError('command() expects a single statement.')
+-
+-        if libGAP_ReadEvalResult:
+-            libGAP_ViewObjHandler(libGAP_ReadEvalResult)
+-            s = char_to_str(libgap_get_output())
+-            print('Output follows...')
+-            print(s.strip())
+-        else:
+-            print('No output.')
+-
++        GAP_EnterStack()
++        GAP_EvalStringNoExcept(_close_error_output_cmd)
++        msg = extract_libgap_errout()
++
++        if PyErr_Occurred() != NULL and msg:
++            # Sometimes error_handler() can be called multiple times from a
++            # single GAP_EvalString call before it returns; in this case we
++            # just update the exception by appending to the existing exception
++            # message
++            PyErr_Fetch(&exc_type, &exc_val, &exc_tb)
++            if exc_val != NULL:
++                msg = str(<object>exc_val) + '\n' + msg
++        elif not msg:
++            msg = "An unknown error occurred in libGAP"
++
++        PyErr_SetObject(RuntimeError, msg)
+     finally:
+-        libgap_exit()
+-        libgap_finish_interaction()
+-
+-    DEBUG_CHECK(libGAP_ReadEvalResult)
++        # Reset ERROR_OUTPUT with a new text string stream
++        GAP_EvalStringNoExcept(_reset_error_output_cmd)
++        GAP_LeaveStack()
+ 
+-    if libGAP_ReadEvalResult != NULL:
+-        libgap_enter()
+-        libGAP_AssGVar(libGAP_Last3, libGAP_VAL_GVAR(libGAP_Last2))
+-        libGAP_AssGVar(libGAP_Last2, libGAP_VAL_GVAR(libGAP_Last))
+-        libGAP_AssGVar(libGAP_Last, libGAP_ReadEvalResult)
+-        libgap_exit()
+ 
++cdef void error_handler_check_exception() except *:
++    error_handler()
+diff --git a/src/sage/misc/randstate.pyx b/src/sage/misc/randstate.pyx
+index d2f173c..0e13d60 100644
+--- a/src/sage/misc/randstate.pyx
++++ b/src/sage/misc/randstate.pyx
+@@ -54,23 +54,23 @@ Here we see that setting the random number seed really does make the
+ results of these random number generators reproducible. ::
+ 
+     sage: set_random_seed(0)
+-    sage: rtest()
+-    (303, -0.266166246380421, 1/6, (1,2), [ 1, 1, 1, 1, 0 ], 265625921, 79302, 0.2450652680687958)
++    sage: print(rtest())
++    (303, -0.266166246380421, 1/6, (1,2), [ 0, 1, 1, 0, 0 ], 265625921, 79302, 0.2450652680687958)
+     sage: set_random_seed(1)
+-    sage: rtest()
++    sage: print(rtest())
+     (978, 0.0557699430711638, -1/8*x^2 - 1/2*x + 1/2, (1,2,3), [ 1, 0, 0, 0, 1 ], 807447831, 23865, 0.6170498912488264)
+     sage: set_random_seed(2)
+-    sage: rtest()
+-    (207, -0.0141049486533456, 0, (1,3)(4,5), [ 1, 1, 1, 1, 1 ], 1642898426, 16190, 0.9343331114872127)
++    sage: print(rtest())
++    (207, -0.0141049486533456, 0, (1,3)(4,5), [ 1, 0, 1, 1, 1 ], 1642898426, 16190, 0.9343331114872127)
+     sage: set_random_seed(0)
+-    sage: rtest()
+-    (303, -0.266166246380421, 1/6, (1,2), [ 1, 1, 1, 1, 0 ], 265625921, 79302, 0.2450652680687958)
++    sage: print(rtest())
++    (303, -0.266166246380421, 1/6, (1,2), [ 0, 1, 1, 0, 0 ], 265625921, 79302, 0.2450652680687958)
+     sage: set_random_seed(1)
+-    sage: rtest()
++    sage: print(rtest())
+     (978, 0.0557699430711638, -1/8*x^2 - 1/2*x + 1/2, (1,2,3), [ 1, 0, 0, 0, 1 ], 807447831, 23865, 0.6170498912488264)
+     sage: set_random_seed(2)
+-    sage: rtest()
+-    (207, -0.0141049486533456, 0, (1,3)(4,5), [ 1, 1, 1, 1, 1 ], 1642898426, 16190, 0.9343331114872127)
++    sage: print(rtest())
++    (207, -0.0141049486533456, 0, (1,3)(4,5), [ 1, 0, 1, 1, 1 ], 1642898426, 16190, 0.9343331114872127)
+ 
+ Once we've set the random number seed, we can check what seed was used.
+ (This is not the current random number state; it does not change when
+@@ -79,8 +79,8 @@ random numbers are generated.)  ::
+     sage: set_random_seed(12345)
+     sage: initial_seed()
+     12345L
+-    sage: rtest()
+-    (720, -0.612180244315804, 0, (1,3), [ 1, 0, 1, 1, 1 ], 1911581957, 65175, 0.8043027951758298)
++    sage: print(rtest())
++    (720, -0.612180244315804, 0, (1,3), [ 1, 0, 1, 1, 0 ], 1911581957, 65175, 0.8043027951758298)
+     sage: initial_seed()
+     12345L
+ 
+@@ -214,9 +214,9 @@ We'll demonstrate isolation.  First, we show the sequence of random numbers
+ that you get without intervening ``with seed``. ::
+ 
+     sage: set_random_seed(0)
+-    sage: r1 = rtest(); r1
+-    (303, -0.266166246380421, 1/6, (1,2), [ 1, 1, 1, 1, 0 ], 265625921, 79302, 0.2450652680687958)
+-    sage: r2 = rtest(); r2
++    sage: r1 = rtest(); print(r1)
++    (303, -0.266166246380421, 1/6, (1,2), [ 0, 1, 1, 0, 0 ], 265625921, 79302, 0.2450652680687958)
++    sage: r2 = rtest(); print(r2)
+     (443, 0.185001351421963, -2, (1,3), [ 0, 0, 1, 1, 0 ], 53231108, 8171, 0.28363811590618193)
+ 
+ We get slightly different results with an intervening ``with seed``. ::
+@@ -242,10 +242,10 @@ case, as we see in this example::
+     sage: r1 == rtest()
+     True
+     sage: with seed(1):
+-    ....:     rtest()
+-    ....:     rtest()
++    ....:     print(rtest())
++    ....:     print(rtest())
+     (978, 0.0557699430711638, -1/8*x^2 - 1/2*x + 1/2, (1,2,3), [ 1, 0, 0, 0, 1 ], 807447831, 23865, 0.6170498912488264)
+-    (181, 0.607995392046754, -x + 1/2, (2,3)(4,5), [ 0, 1, 1, 0, 0 ], 1010791326, 9693, 0.5691716786307407)
++    (181, 0.607995392046754, -x + 1/2, (2,3)(4,5), [ 1, 0, 0, 1, 1 ], 1010791326, 9693, 0.5691716786307407)
+     sage: r2m == rtest()
+     True
+ 
+@@ -702,8 +702,8 @@ cdef class randstate:
+             sage: gap.Random(1, 10^50)
+             1496738263332555434474532297768680634540939580077
+             sage: gap(35).SCRRandomString()
+-            [ 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0,
+-              0, 0, 1, 0, 0, 1, 1, 0, 0, 1 ]
++            [ 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1,
++              1, 0, 0, 1, 1, 1, 1, 1, 0, 1 ]
+         """
+         global _gap_seed_randstate
+         if _gap_seed_randstate is not self:
+diff --git a/src/sage/tests/books/judson-abstract-algebra/homomorph-sage-exercises.py b/src/sage/tests/books/judson-abstract-algebra/homomorph-sage-exercises.py
+index d5ebaa6..84ed100 100644
+--- a/src/sage/tests/books/judson-abstract-algebra/homomorph-sage-exercises.py
++++ b/src/sage/tests/books/judson-abstract-algebra/homomorph-sage-exercises.py
+@@ -60,7 +60,6 @@ r"""
+ ~~~~~~~~~~~~~~~~~~~~~~ ::
+ 
+     sage: G = DihedralGroup(20)
+-    sage: [H.order() for H in G.normal_subgroups()]
++    sage: l=[H.order() for H in G.normal_subgroups()]; l.sort(); l
+     [1, 2, 4, 5, 10, 20, 20, 20, 40]
+-
+ """
+diff --git a/src/sage/tests/books/judson-abstract-algebra/normal-sage.py b/src/sage/tests/books/judson-abstract-algebra/normal-sage.py
+index 16119fd..3db475d 100644
+--- a/src/sage/tests/books/judson-abstract-algebra/normal-sage.py
++++ b/src/sage/tests/books/judson-abstract-algebra/normal-sage.py
+@@ -128,7 +128,7 @@ r"""
+ 
+     sage: G = DihedralGroup(8)
+     sage: N = G.normal_subgroups()
+-    sage: [H.order() for H in N]
++    sage: l=[H.order() for H in N]; l.sort(); l
+     [1, 2, 4, 8, 8, 8, 16]
+ 
+ """
+diff --git a/src/sage/tests/books/judson-abstract-algebra/sylow-sage.py b/src/sage/tests/books/judson-abstract-algebra/sylow-sage.py
+index d6cf39c..8b32726 100644
+--- a/src/sage/tests/books/judson-abstract-algebra/sylow-sage.py
++++ b/src/sage/tests/books/judson-abstract-algebra/sylow-sage.py
+@@ -226,7 +226,7 @@ r"""
+ ~~~~~~~~~~~~~~~~~~~~~~ ::
+ 
+     sage: gap.version()
+-    '4.8.6'
++    '4.10.0'
+ 
+ ~~~~~~~~~~~~~~~~~~~~~~ ::
+ 
+diff --git a/src/sage/tests/gap_packages.py b/src/sage/tests/gap_packages.py
+index ca961ed..4a3479b 100644
+--- a/src/sage/tests/gap_packages.py
++++ b/src/sage/tests/gap_packages.py
+@@ -124,7 +124,7 @@ def all_installed_packages(ignore_dot_gap=False):
+         (...'GAPDoc'...)
+     """
+     packages = []
+-    for path in libgap.eval('GAP_ROOT_PATHS').sage():
++    for path in libgap.eval('GAPInfo.RootPaths').sage():
+         if ignore_dot_gap and path.endswith('/.gap/'):
+             continue
+         pkg_dir = os.path.join(path, 'pkg')
+diff --git a/src/setup.py b/src/setup.py
+index bc8fe12..9d31c9d 100755
+--- a/src/setup.py
++++ b/src/setup.py
+@@ -948,6 +948,9 @@ code = setup(name = 'sage',
+       author_email= 'http://groups.google.com/group/sage-support',
+       url         = 'http://www.sagemath.org',
+       packages    = python_packages,
++      package_data = {
++          'sage.libs.gap': ['sage.gaprc'],
++      },
+       cmdclass = dict(build=sage_build,
+                       build_cython=sage_build_cython,
+                       build_ext=sage_build_ext,



More information about the arch-commits mailing list