summary refs log tree commit diff
path: root/pkgs/applications/science/math/sage
diff options
context:
space:
mode:
authorMauricio Collares <mauricio@collares.org>2023-02-16 14:26:09 +0100
committerMauricio Collares <mauricio@collares.org>2023-05-21 16:28:24 +0200
commit0edaaae3ffd117b88879bf655260654947ee2dc4 (patch)
treeb5d9bcda109bb46ec677f4576d22749578285934 /pkgs/applications/science/math/sage
parent19bf4ba0e0c0789f57f03e4de6c908e00fe17f2a (diff)
downloadnixpkgs-0edaaae3ffd117b88879bf655260654947ee2dc4.tar
nixpkgs-0edaaae3ffd117b88879bf655260654947ee2dc4.tar.gz
nixpkgs-0edaaae3ffd117b88879bf655260654947ee2dc4.tar.bz2
nixpkgs-0edaaae3ffd117b88879bf655260654947ee2dc4.tar.lz
nixpkgs-0edaaae3ffd117b88879bf655260654947ee2dc4.tar.xz
nixpkgs-0edaaae3ffd117b88879bf655260654947ee2dc4.tar.zst
nixpkgs-0edaaae3ffd117b88879bf655260654947ee2dc4.zip
sage: 9.8 -> 10.0
Diffstat (limited to 'pkgs/applications/science/math/sage')
-rw-r--r--pkgs/applications/science/math/sage/default.nix2
-rw-r--r--pkgs/applications/science/math/sage/patches/configurationpy-error-verbose.patch19
-rw-r--r--pkgs/applications/science/math/sage/patches/do-not-test-find-library.patch87
-rw-r--r--pkgs/applications/science/math/sage/patches/fix-ecl-race.patch19
-rw-r--r--pkgs/applications/science/math/sage/patches/numpy-1.24-upgrade.patch58
-rw-r--r--pkgs/applications/science/math/sage/patches/tachyon-renamed-focallength.patch82
-rw-r--r--pkgs/applications/science/math/sage/python-modules/sage-docbuild.nix6
-rw-r--r--pkgs/applications/science/math/sage/sage-src.nix156
-rw-r--r--pkgs/applications/science/math/sage/sagelib.nix165
9 files changed, 130 insertions, 464 deletions
diff --git a/pkgs/applications/science/math/sage/default.nix b/pkgs/applications/science/math/sage/default.nix
index fa65ce0f364..d4b678d36f9 100644
--- a/pkgs/applications/science/math/sage/default.nix
+++ b/pkgs/applications/science/math/sage/default.nix
@@ -128,7 +128,7 @@ let
 
   singular = pkgs.singular.override { inherit flint; };
 
-  maxima = pkgs.maxima-ecl-5_45.override {
+  maxima = pkgs.maxima-ecl.override {
     lisp-compiler = pkgs.ecl.override {
       # "echo syntax error | ecl > /dev/full 2>&1" segfaults in
       # ECL. We apply a patch to fix it (write_error.patch), but it
diff --git a/pkgs/applications/science/math/sage/patches/configurationpy-error-verbose.patch b/pkgs/applications/science/math/sage/patches/configurationpy-error-verbose.patch
deleted file mode 100644
index ca01eba29a2..00000000000
--- a/pkgs/applications/science/math/sage/patches/configurationpy-error-verbose.patch
+++ /dev/null
@@ -1,19 +0,0 @@
-diff --git a/src/sage/repl/configuration.py b/src/sage/repl/configuration.py
-index 67d7d2accf..18279581e2 100644
---- a/src/sage/repl/configuration.py
-+++ b/src/sage/repl/configuration.py
-@@ -9,10 +9,11 @@ the IPython simple prompt is being used::
-     sage: cmd = 'print([sys.stdin.isatty(), sys.stdout.isatty()])'
-     sage: import pexpect
-     sage: output = pexpect.run(
--    ....:     'bash -c \'echo "{0}" | sage\''.format(cmd),
-+    ....:     'bash -c \'export SAGE_BANNER=no; echo "{0}" | sage\''.format(cmd),
-     ....: ).decode('utf-8', 'surrogateescape')
--    sage: 'sage: [False, True]' in output
--    True
-+    sage: print(output)
-+    sage...[False, True]
-+    ...
- """
- 
- #*****************************************************************************
diff --git a/pkgs/applications/science/math/sage/patches/do-not-test-find-library.patch b/pkgs/applications/science/math/sage/patches/do-not-test-find-library.patch
deleted file mode 100644
index 90a23f94cb5..00000000000
--- a/pkgs/applications/science/math/sage/patches/do-not-test-find-library.patch
+++ /dev/null
@@ -1,87 +0,0 @@
-diff --git a/src/sage/env.py b/src/sage/env.py
-index c4953cfa65..47b880f9ad 100644
---- a/src/sage/env.py
-+++ b/src/sage/env.py
-@@ -244,81 +244,8 @@ os.environ['MPMATH_SAGE'] = '1'
- SAGE_BANNER = var("SAGE_BANNER", "")
- SAGE_IMPORTALL = var("SAGE_IMPORTALL", "yes")
- 
--
--def _get_shared_lib_path(*libnames: str) -> Optional[str]:
--    """
--    Return the full path to a shared library file installed in
--    ``$SAGE_LOCAL/lib`` or the directories associated with the
--    Python sysconfig.
--
--    This can also be passed more than one library name (e.g. for cases where
--    some library may have multiple names depending on the platform) in which
--    case the first one found is returned.
--
--    This supports most *NIX variants (in which ``lib<libname>.so`` is found
--    under ``$SAGE_LOCAL/lib``), macOS (same, but with the ``.dylib``
--    extension), and Cygwin (under ``$SAGE_LOCAL/bin/cyg<libname>.dll``,
--    or ``$SAGE_LOCAL/bin/cyg<libname>-*.dll`` for versioned DLLs).
--
--    For distributions like Debian that use a multiarch layout, we also try the
--    multiarch lib paths (i.e. ``/usr/lib/<arch>/``).
--
--    This returns ``None`` if no matching library file could be found.
--
--    EXAMPLES::
--
--        sage: from sage.env import _get_shared_lib_path
--        sage: "gap" in _get_shared_lib_path("gap")
--        True
--        sage: _get_shared_lib_path("an_absurd_lib") is None
--        True
--
--    """
--
--    for libname in libnames:
--        search_directories: List[Path] = []
--        patterns: List[str] = []
--        if sys.platform == 'cygwin':
--            # Later down we take the first matching DLL found, so search
--            # SAGE_LOCAL first so that it takes precedence
--            if SAGE_LOCAL:
--                search_directories.append(Path(SAGE_LOCAL) / 'bin')
--            search_directories.append(Path(sysconfig.get_config_var('BINDIR')))
--            # Note: The following is not very robust, since if there are multible
--            # versions for the same library this just selects one more or less
--            # at arbitrary. However, practically speaking, on Cygwin, there
--            # will only ever be one version
--            patterns = [f'cyg{libname}.dll', f'cyg{libname}-*.dll']
--        else:
--            if sys.platform == 'darwin':
--                ext = 'dylib'
--            else:
--                ext = 'so'
--
--            if SAGE_LOCAL:
--                search_directories.append(Path(SAGE_LOCAL) / 'lib')
--            libdir = sysconfig.get_config_var('LIBDIR')
--            if libdir is not None:
--                libdir = Path(libdir)
--                search_directories.append(libdir)
--
--                multiarchlib = sysconfig.get_config_var('MULTIARCH')
--                if multiarchlib is not None:
--                    search_directories.append(libdir / multiarchlib),
--
--            patterns = [f'lib{libname}.{ext}']
--
--        for directory in search_directories:
--            for pattern in patterns:
--                path = next(directory.glob(pattern), None)
--                if path is not None:
--                    return str(path.resolve())
--
--    # Just return None if no files were found
--    return None
--
- # locate libgap shared object
--GAP_SO = var("GAP_SO", _get_shared_lib_path("gap", ""))
-+GAP_SO = var("GAP_SO", '/default')
- 
- # post process
- if DOT_SAGE is not None and ' ' in DOT_SAGE:
diff --git a/pkgs/applications/science/math/sage/patches/fix-ecl-race.patch b/pkgs/applications/science/math/sage/patches/fix-ecl-race.patch
deleted file mode 100644
index 6056416c3a2..00000000000
--- a/pkgs/applications/science/math/sage/patches/fix-ecl-race.patch
+++ /dev/null
@@ -1,19 +0,0 @@
-diff --git a/src/sage/doctest/forker.py b/src/sage/doctest/forker.py
-index 02e18e67e7..2ebf6eb35f 100644
---- a/src/sage/doctest/forker.py
-+++ b/src/sage/doctest/forker.py
-@@ -1075,6 +1075,14 @@ class SageDocTestRunner(doctest.DocTestRunner, object):
-             sage: set(ex2.predecessors) == set([ex0,ex1])
-             True
-         """
-+
-+        # Fix ECL dir race conditions by using a separate dir for each process
-+        # (https://trac.sagemath.org/ticket/26968)
-+        os.environ['MAXIMA_USERDIR'] = "{}/sage-maxima-{}".format(
-+            tempfile.gettempdir(),
-+            os.getpid()
-+        )
-+
-         if isinstance(globs, RecordingDict):
-             globs.start()
-         example.sequence_number = len(self.history)
diff --git a/pkgs/applications/science/math/sage/patches/numpy-1.24-upgrade.patch b/pkgs/applications/science/math/sage/patches/numpy-1.24-upgrade.patch
deleted file mode 100644
index 93b18ce028f..00000000000
--- a/pkgs/applications/science/math/sage/patches/numpy-1.24-upgrade.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-diff --git a/src/sage/misc/persist.pyx b/src/sage/misc/persist.pyx
-index 3ac5f1cc2b..cb1f327c19 100644
---- a/src/sage/misc/persist.pyx
-+++ b/src/sage/misc/persist.pyx
-@@ -157,7 +157,7 @@ def load(*filename, compress=True, verbose=True, **kwargs):
-         ....:     _ = f.write(code)
-         sage: load(t)
-         sage: hello
--        <fortran object>
-+        <fortran ...>
-     """
-     import sage.repl.load
-     if len(filename) != 1:
-diff --git a/src/sage/plot/complex_plot.pyx b/src/sage/plot/complex_plot.pyx
-index 6f0aeab87a..b77c69b2f7 100644
---- a/src/sage/plot/complex_plot.pyx
-+++ b/src/sage/plot/complex_plot.pyx
-@@ -461,6 +461,8 @@ def complex_to_rgb(z_values, contoured=False, tiled=False,
-             rgb[i, j, 2] = b
- 
-     sig_off()
-+    nan_indices = np.isnan(rgb).any(-1)     # Mask for undefined points
-+    rgb[nan_indices] = 1                    # Make nan_indices white
-     return rgb
- 
- 
-diff --git a/src/sage/plot/histogram.py b/src/sage/plot/histogram.py
-index 3bc2b76b58..388c2d1391 100644
---- a/src/sage/plot/histogram.py
-+++ b/src/sage/plot/histogram.py
-@@ -87,13 +87,8 @@ class Histogram(GraphicPrimitive):
- 
-         TESTS::
- 
--            sage: h = histogram([10,3,5], normed=True)[0]
--            doctest:warning...:
--            DeprecationWarning: the 'normed' option is deprecated. Use 'density' instead.
--            See https://trac.sagemath.org/25260 for details.
-+            sage: h = histogram([10,3,5], density=True)[0]
-             sage: h.get_minmax_data()
--            doctest:warning ...
--            ...VisibleDeprecationWarning: Passing `normed=True` on non-uniform bins has always been broken, and computes neither the probability density function nor the probability mass function. The result is only correct if the bins are uniform, when density=True will produce the same result anyway. The argument will be removed in a future version of numpy.
-             {'xmax': 10.0, 'xmin': 3.0, 'ymax': 0.476190476190..., 'ymin': 0}
-         """
-         import numpy
-diff --git a/src/sage/repl/ipython_extension.py b/src/sage/repl/ipython_extension.py
-index 798671aab4..cad6a47ca8 100644
---- a/src/sage/repl/ipython_extension.py
-+++ b/src/sage/repl/ipython_extension.py
-@@ -405,7 +405,7 @@ class SageMagics(Magics):
-             ....: C END FILE FIB1.F
-             ....: ''')
-             sage: fib
--            <fortran object>
-+            <fortran ...>
-             sage: from numpy import array
-             sage: a = array(range(10), dtype=float)
-             sage: fib(a, 10)
diff --git a/pkgs/applications/science/math/sage/patches/tachyon-renamed-focallength.patch b/pkgs/applications/science/math/sage/patches/tachyon-renamed-focallength.patch
deleted file mode 100644
index 2f2638bc806..00000000000
--- a/pkgs/applications/science/math/sage/patches/tachyon-renamed-focallength.patch
+++ /dev/null
@@ -1,82 +0,0 @@
-diff --git a/src/sage/interfaces/tachyon.py b/src/sage/interfaces/tachyon.py
-index 23671e5089..a5604a643c 100644
---- a/src/sage/interfaces/tachyon.py
-+++ b/src/sage/interfaces/tachyon.py
-@@ -74,14 +74,14 @@ Camera projection modes
- The ``PROJECTION`` keyword must be followed by one of the supported
- camera projection mode identifiers ``PERSPECTIVE``, ``PERSPECTIVE_DOF``,
- ``ORTHOGRAPHIC``, or ``FISHEYE``. The ``FISHEYE`` projection mode
--requires two extra parameters ``FOCALLENGTH`` and ``APERTURE`` which
-+requires two extra parameters ``FOCALDIST`` and ``APERTURE`` which
- precede the regular camera options.
- 
- ::
- 
-    Camera
-      projection perspective_dof
--     focallength 0.75
-+     focaldist 0.75
-      aperture 0.02
-      Zoom 0.666667
-      Aspectratio 1.000000
-diff --git a/src/sage/plot/plot3d/tachyon.py b/src/sage/plot/plot3d/tachyon.py
-index 88c8eba2d5..c4427dd484 100644
---- a/src/sage/plot/plot3d/tachyon.py
-+++ b/src/sage/plot/plot3d/tachyon.py
-@@ -92,7 +92,7 @@ angle, right angle)::
- Finally there is the ``projection='perspective_dof'`` option. ::
- 
-     sage: T = Tachyon(xres=800, antialiasing=4, raydepth=10,
--    ....: projection='perspective_dof', focallength='1.0', aperture='.0025')
-+    ....: projection='perspective_dof', focaldist='1.0', aperture='.0025')
-     sage: T.light((0,5,7), 1.0, (1,1,1))
-     sage: T.texture('t1', opacity=1, specular=.3)
-     sage: T.texture('t2', opacity=1, specular=.3, color=(0,0,1))
-@@ -186,7 +186,7 @@ class Tachyon(WithEqualityById, SageObject):
-       or ``'fisheye'``.
-     - ``frustum`` - (default ''), otherwise list of four numbers. Only
-       used with projection='fisheye'.
--    - ``focallength`` - (default ''), otherwise a number. Only used
-+    - ``focaldist`` - (default ''), otherwise a number. Only used
-       with projection='perspective_dof'.
-     - ``aperture`` - (default ''), otherwise a number.  Only used
-       with projection='perspective_dof'.
-@@ -331,7 +331,7 @@ class Tachyon(WithEqualityById, SageObject):
-     Use of the ``projection='perspective_dof'`` option.  This may not be
-     implemented correctly. ::
- 
--        sage: T = Tachyon(xres=800,antialiasing=4, raydepth=10, projection='perspective_dof', focallength='1.0', aperture='.0025')
-+        sage: T = Tachyon(xres=800,antialiasing=4, raydepth=10, projection='perspective_dof', focaldist='1.0', aperture='.0025')
-         sage: T.light((0,5,7), 1.0, (1,1,1))
-         sage: T.texture('t1', opacity=1, specular=.3)
-         sage: T.texture('t2', opacity=1, specular=.3, color=(0,0,1))
-@@ -365,7 +365,7 @@ class Tachyon(WithEqualityById, SageObject):
-                  look_at=[0, 0, 0],
-                  viewdir=None,
-                  projection='PERSPECTIVE',
--                 focallength='',
-+                 focaldist='',
-                  aperture='',
-                  frustum=''):
-         r"""
-@@ -391,7 +391,7 @@ class Tachyon(WithEqualityById, SageObject):
-             self._camera_position = (-3, 0, 0) # default value
-         self._updir = updir
-         self._projection = projection
--        self._focallength = focallength
-+        self._focaldist = focaldist
-         self._aperture = aperture
-         self._frustum = frustum
-         self._objects = []
-@@ -624,9 +624,9 @@ class Tachyon(WithEqualityById, SageObject):
-         camera_out = r"""
-            camera
-               projection %s""" % (tostr(self._projection))
--        if self._focallength != '':
-+        if self._focaldist != '':
-             camera_out = camera_out + r"""
--              focallength %s""" % (float(self._focallength))
-+              focaldist %s""" % (float(self._focaldist))
-         if self._aperture != '':
-             camera_out = camera_out + r"""
-               aperture %s""" % (float(self._aperture))
diff --git a/pkgs/applications/science/math/sage/python-modules/sage-docbuild.nix b/pkgs/applications/science/math/sage/python-modules/sage-docbuild.nix
index b0f40bf0658..fb8c3ec8a20 100644
--- a/pkgs/applications/science/math/sage/python-modules/sage-docbuild.nix
+++ b/pkgs/applications/science/math/sage/python-modules/sage-docbuild.nix
@@ -1,8 +1,9 @@
 { lib
 , buildPythonPackage
 , sage-src
-, sphinx
 , jupyter-sphinx
+, sphinx
+, sphinx-copybutton
 }:
 
 buildPythonPackage rec {
@@ -11,8 +12,9 @@ buildPythonPackage rec {
   src = sage-src;
 
   propagatedBuildInputs = [
-    sphinx
     jupyter-sphinx
+    sphinx
+    sphinx-copybutton
   ];
 
   preBuild = ''
diff --git a/pkgs/applications/science/math/sage/sage-src.nix b/pkgs/applications/science/math/sage/sage-src.nix
index f2e02685416..7f168aa5ff9 100644
--- a/pkgs/applications/science/math/sage/sage-src.nix
+++ b/pkgs/applications/science/math/sage/sage-src.nix
@@ -8,87 +8,41 @@
 # This is done because multiple derivations rely on these sources and they should
 # all get the same sources with the same patches applied.
 
-let
-  # Fetch a diff between `base` and `rev` on sage's git server.
-  # Used to fetch trac tickets by setting the `base` to the last release and the
-  # `rev` to the last commit of the ticket.
-  #
-  # We don't use sage's own build system (which builds all its
-  # dependencies), so we exclude changes to "build/" from patches by
-  # default to avoid conflicts.
-  fetchSageDiff = { base, name, rev, sha256, squashed ? false, excludes ? [ "build/*" ]
-                  , ...}@args: (
-    fetchpatch ({
-      inherit name sha256 excludes;
-
-      # There are three places to get changes from:
-      #
-      # 1) From Sage's Trac. Contains all release tags (like "9.4") and all developer
-      # branches (wip patches from tickets), but exports each commit as a separate
-      # patch, so merge commits can lead to conflicts. Used if squashed == false.
-      #
-      # The above is the preferred option. To use it, find a Trac ticket and pass the
-      # "Commit" field from the ticket as "rev", choosing "base" as an appropriate
-      # release tag, i.e. a tag that doesn't cause the patch to include a lot of
-      # unrelated changes. If there is no such tag (due to nonlinear history, for
-      # example), there are two other options, listed below.
-      #
-      # 2) From GitHub's sagemath/sage repo. This lets us use a GH feature that allows
-      # us to choose between a .patch file, with one patch per commit, or a .diff file,
-      # which squashes all commits into a single diff. This is used if squashed ==
-      # true. This repo has all release tags. However, it has no developer branches, so
-      # this option can't be used if a change wasn't yet shipped in a (possibly beta)
-      # release.
-      #
-      # 3) From GitHub's sagemath/sagetrac-mirror repo. Mirrors all developer branches,
-      # but has no release tags. The only use case not covered by 1 or 2 is when we need
-      # to apply a patch from an open ticket that contains merge commits.
-      #
-      # Item 3 could cover all use cases if the sagemath/sagetrack-mirror repo had
-      # release tags, but it requires a sha instead of a release number in "base", which
-      # is inconvenient.
-      urls = if squashed
-             then [
-               "https://github.com/sagemath/sage/compare/${base}...${rev}.diff"
-               "https://github.com/sagemath/sagetrac-mirror/compare/${base}...${rev}.diff"
-             ]
-             else [ "https://git.sagemath.org/sage.git/patch?id2=${base}&id=${rev}" ];
-    } // builtins.removeAttrs args [ "rev" "base" "sha256" "squashed" "excludes" ])
-  );
-in
 stdenv.mkDerivation rec {
-  version = "9.8";
+  version = "10.0";
   pname = "sage-src";
 
   src = fetchFromGitHub {
     owner = "sagemath";
     repo = "sage";
     rev = version;
-    sha256 = "sha256-dDbrzJXsOBARYfJz0r7n3LbaoXHnx7Acz6HBa95NV9o=";
+    sha256 = "sha256-zN/Lo/GBCjYGemuaYpgG3laufN8te3wPjXMQ+Me9zgY=";
   };
 
   # Patches needed because of particularities of nix or the way this is packaged.
   # The goal is to upstream all of them and get rid of this list.
   nixPatches = [
-    # Fixes a potential race condition which can lead to transient doctest failures.
-    ./patches/fix-ecl-race.patch
-
-    # Not necessary since library location is set explicitly
-    # https://trac.sagemath.org/ticket/27660#ticket
-    ./patches/do-not-test-find-library.patch
-
     # Parallelize docubuild using subprocesses, fixing an isolation issue. See
     # https://groups.google.com/forum/#!topic/sage-packaging/YGOm8tkADrE
     ./patches/sphinx-docbuild-subprocesses.patch
+
+    # After updating smypow to (https://github.com/sagemath/sage/issues/3360)
+    # we can now set the cache dir to be within the .sage directory. This is
+    # not strictly necessary, but keeps us from littering in the user's HOME.
+    ./patches/sympow-cache.patch
   ];
 
   # Since sage unfortunately does not release bugfix releases, packagers must
   # fix those bugs themselves. This is for critical bugfixes, where "critical"
   # == "causes (transient) doctest failures / somebody complained".
   bugfixPatches = [
-    # To help debug the transient error in
-    # https://trac.sagemath.org/ticket/23087 when it next occurs.
-    ./patches/configurationpy-error-verbose.patch
+    # Sage uses mixed integer programs (MIPs) to find edge disjoint
+    # spanning trees. For some reason, aarch64 glpk takes much longer
+    # than x86_64 glpk to solve such MIPs. Since the MIP formulation
+    # has "numerous problems" and will be replaced by a polynomial
+    # algorithm soon, disable this test for now.
+    # https://github.com/sagemath/sage/issues/34575
+    ./patches/disable-slow-glpk-test.patch
   ];
 
   # Patches needed because of package updates. We could just pin the versions of
@@ -98,73 +52,33 @@ stdenv.mkDerivation rec {
   # should come from or be proposed to upstream. This list will probably never
   # be empty since dependencies update all the time.
   packageUpgradePatches = [
-    # After updating smypow to (https://trac.sagemath.org/ticket/3360) we can
-    # now set the cache dir to be within the .sage directory. This is not
-    # strictly necessary, but keeps us from littering in the user's HOME.
-    ./patches/sympow-cache.patch
-
-    # Upstream will wait until Sage 9.7 to upgrade to linbox 1.7 because it
-    # does not support gcc 6. We can upgrade earlier.
-    # https://trac.sagemath.org/ticket/32959
-    ./patches/linbox-1.7-upgrade.patch
-
-    # adapted from https://trac.sagemath.org/ticket/23712#comment:22
-    ./patches/tachyon-renamed-focallength.patch
-
-    # https://trac.sagemath.org/ticket/34391
-    (fetchSageDiff {
-      name = "gap-4.12-upgrade.patch";
-      base = "9.8.beta7";
-      rev = "dd4a17281adcda74e11f998ef519b6bd0dafb043";
-      sha256 = "sha256-UQT9DO9xd5hh5RucvUkIm+rggPKu8bc1YaSI6LVYH98=";
-    })
-
-    # https://trac.sagemath.org/ticket/34701
-    (fetchSageDiff {
-      name = "libgap-fix-gc-crashes-on-aarch64.patch";
-      base = "eb8cd42feb58963adba67599bf6e311e03424328"; # TODO: update when #34391 lands
-      rev = "90acc7f1c13a80b8aa673469a2668feb9cd4207f";
-      sha256 = "sha256-9BhQLFB3wUhiXRQsK9L+I62lSjvTfrqMNi7QUIQvH4U=";
-    })
-
-    # https://github.com/sagemath/sage/pull/35235
+    # https://github.com/sagemath/sage/pull/35584, positively reviewed
     (fetchpatch {
-      name = "ipython-8.11-upgrade.patch";
-      url = "https://github.com/sagemath/sage/commit/23471e2d242c4de8789d7b1fc8b07a4b1d1e595a.diff";
-      sha256 = "sha256-wvH4BvDiaBv7jbOP8LvOE5Vs16Kcwz/C9jLpEMohzLQ=";
+      name = "networkx-3.1-upgrade.patch";
+      url = "https://github.com/sagemath/sage/compare/10.0.rc2..e599562cf5fdfb9799a5412fac40c2f8e9f97341.diff";
+      sha256 = "sha256-3A90kXqNR0c7+k8xrZXAt5wqWg/VFAPNhQujwTdOyhI=";
     })
 
-    # positively reviewed
+    # https://github.com/sagemath/sage/pull/35612, positively reviewed
     (fetchpatch {
-      name = "matplotlib-3.7.0-upgrade.patch";
-      url = "https://github.com/sagemath/sage/pull/35177.diff";
-      sha256 = "sha256-YdPnMsjXBm9ZRm6a8hH8rSynkrABjLoIzqwp3F/rKAw=";
+      name = "linbox-1.7-upgrade.patch";
+      url = "https://github.com/sagemath/sage/compare/10.0.rc2..9c8796c7b677e3a056348e3510331ea8b8c3c42e.diff";
+      sha256 = "sha256-/TpvIQZUqmbUuz6wvp3ni9oRir5LBA2FKDJcmnHI1r4=";
     })
 
-    # https://github.com/sagemath/sage/pull/35336, merged in 10.0.beta8
+    # https://github.com/sagemath/sage/pull/35619
     (fetchpatch {
-      name = "ipywidgets-8.0.5-upgrade.patch";
-      url = "https://github.com/sagemath/sage/commit/7ab3e3aa81d47a35d09161b965bba8ab16fd5c9e.diff";
-      sha256 = "sha256-WjdsPTui6uv92RerlV0mqltmLaxADvz+3aqSvxBFmfU=";
+      name = "maxima-5.46.0-upgrade.patch";
+      url = "https://github.com/sagemath/sage/compare/10.0.rc3..7e86af5dae8f89868b25a6f57189bb5ca618da89.diff";
+      sha256 = "sha256-pxSxdJ2lyHoMUIxhlIn1nTHaddRxGvvTj9IbwFCTBFU=";
     })
 
-    # https://github.com/sagemath/sage/pull/35499
+    # https://github.com/sagemath/sage/pull/35635, positively reviewed
     (fetchpatch {
-      name = "ipywidgets-8.0.5-upgrade-part-deux.patch";
-      url = "https://github.com/sagemath/sage/pull/35499.diff";
-      sha256 = "sha256-uNCjLs9qrARTQNsq1+kTdvuV2A1M4xx5b1gWh5c55X0=";
+      name = "sympy-1.12-upgrade.patch";
+      url = "https://github.com/sagemath/sage/compare/10.0.rc2..aa4193cdc8ec9fb7bd7c49696b7f914668f7913a.diff";
+      sha256 = "sha256-UAmYCxHvnE5p+H2DySNZTPFVm915jHtOEoG+tZz5n7I=";
     })
-
-    # rebased from https://github.com/sagemath/sage/pull/34994, merged in sage 10.0.beta2
-    ./patches/numpy-1.24-upgrade.patch
-
-    # Sage uses mixed integer programs (MIPs) to find edge disjoint
-    # spanning trees. For some reason, aarch64 glpk takes much longer
-    # than x86_64 glpk to solve such MIPs. Since the MIP formulation
-    # has "numerous problems" and will be replaced by a polynomial
-    # algorithm soon, disable this test for now.
-    # https://trac.sagemath.org/ticket/34575
-    ./patches/disable-slow-glpk-test.patch
   ];
 
   patches = nixPatches ++ bugfixPatches ++ packageUpgradePatches;
@@ -179,12 +93,10 @@ stdenv.mkDerivation rec {
       "s|var(\"SAGE_ROOT\".*|var(\"SAGE_ROOT\", \"$out\")|" \
       src/sage/env.py
 
-    # src/doc/en/reference/spkg/conf.py expects index.rst in its directory,
-    # a list of external packages in the sage distribution (build/pkgs)
-    # generated by the bootstrap script (which we don't run).  this is not
-    # relevant for other distributions, so remove it.
-    rm src/doc/en/reference/spkg/conf.py
-    sed -i "/spkg/d" src/doc/en/reference/index.rst
+    # docbuilding expects a spkg index generated by the doc/bootstrap script (which
+    # we don't run) to exist. the spkg list includes nix package names, but it's not
+    # worth the hassle of running the bootstrap script, so just create a dummy index.
+    touch src/doc/en/reference/spkg/index.rst
 
     # the bootstrap script also generates installation instructions for
     # arch, debian, fedora, cygwin and homebrew using data from build/pkgs.
diff --git a/pkgs/applications/science/math/sage/sagelib.nix b/pkgs/applications/science/math/sage/sagelib.nix
index 3d1c319a2f2..d8d5586e219 100644
--- a/pkgs/applications/science/math/sage/sagelib.nix
+++ b/pkgs/applications/science/math/sage/sagelib.nix
@@ -1,76 +1,83 @@
 { sage-src
 , env-locations
-, perl
+, python
 , buildPythonPackage
 , m4
+, perl
+, pkg-config
+, sage-setup
+, gd
+, iml
+, libpng
+, readline
 , arb
 , blas
-, lapack
+, boost
 , brial
 , cliquer
-, cypari2
-, cysignals
-, cython
-, lisp-compiler
 , eclib
 , ecm
+, fflas-ffpack
 , flint
-, gd
+, gap
 , giac
 , givaro
 , glpk
 , gsl
-, iml
-, jinja2
-, libpng
+, lapack
 , lcalc
-, lrcalc
-, gap
+, libbraiding
+, libhomfly
+, libmpc
 , linbox
+, lisp-compiler
+, lrcalc
 , m4ri
 , m4rie
-, memory-allocator
-, libmpc
 , mpfi
+, mpfr
 , ntl
-, numpy
 , pari
-, pkgconfig # the python module, not the pkg-config alias
-, pkg-config
 , planarity
 , ppl
-, primecountpy
-, python
-, ratpoints
-, readline
 , rankwidth
-, symmetrica
-, zn_poly
-, fflas-ffpack
-, boost
+, ratpoints
 , singular
-, pip
-, jupyter-core
-, sage-setup
-, libhomfly
-, libbraiding
-, gmpy2
-, pplpy
 , sqlite
-, jupyter-client
+, symmetrica
+, cvxopt
+, cypari2
+, cysignals
+, cython
+, fpylll
+, gmpy2
+, importlib-metadata
+, importlib-resources
+, ipykernel
+, ipython
 , ipywidgets
+, jinja2
+, jupyter-client
+, jupyter-core
+, lrcalc-python
+, matplotlib
+, memory-allocator
 , mpmath
+, networkx
+, numpy
+, pexpect
+, pillow
+, pip
+, pkgconfig
+, pplpy
+, primecountpy
+, ptyprocess
+, requests
 , rpy2
-, fpylll
 , scipy
+, sphinx
 , sympy
-, matplotlib
-, pillow
-, ipykernel
-, networkx
-, ptyprocess
-, lrcalc-python
-, sphinx # TODO: this is in setup.cfg, should we override it?
+, typing-extensions
 }:
 
 assert (!blas.isILP64) && (!lapack.isILP64);
@@ -87,83 +94,93 @@ buildPythonPackage rec {
 
   nativeBuildInputs = [
     iml
+    lisp-compiler
+    m4
     perl
-    jupyter-core
+    pip # needed to query installed packages
     pkg-config
     sage-setup
-    pip # needed to query installed packages
-    lisp-compiler
-    m4
   ];
 
   buildInputs = [
     gd
-    readline
     iml
     libpng
+    readline
   ];
 
   propagatedBuildInputs = [
-    cypari2
-    jinja2
-    numpy
-    pkgconfig
-    boost
+    # native dependencies (TODO: determine which ones need to be propagated)
     arb
+    blas
+    boost
     brial
     cliquer
-    lisp-compiler
     eclib
     ecm
     fflas-ffpack
     flint
+    gap
     giac
     givaro
     glpk
     gsl
+    lapack
     lcalc
-    gap
+    libbraiding
+    libhomfly
     libmpc
     linbox
+    lisp-compiler
     lrcalc
     m4ri
     m4rie
-    memory-allocator
     mpfi
+    mpfr
     ntl
-    blas
-    lapack
     pari
     planarity
     ppl
-    primecountpy
     rankwidth
     ratpoints
     singular
+    sqlite
     symmetrica
-    zn_poly
-    pip
-    cython
+
+    # from src/sage/setup.cfg and requirements.txt
+    cvxopt
+    cypari2
     cysignals
-    libhomfly
-    libbraiding
+    cython
+    fpylll
     gmpy2
-    pplpy
-    sqlite
-    mpmath
-    rpy2
-    scipy
-    sympy
-    matplotlib
-    pillow
+    importlib-metadata
+    importlib-resources
     ipykernel
-    fpylll
-    networkx
-    jupyter-client
+    ipython
     ipywidgets
-    ptyprocess
+    jinja2
+    jupyter-client
+    jupyter-core
     lrcalc-python
+    matplotlib
+    memory-allocator
+    mpmath
+    networkx
+    numpy
+    pexpect
+    pillow
+    pip
+    pkgconfig
+    pplpy
+    primecountpy
+    ptyprocess
+    requests
+    rpy2
+    scipy
     sphinx
+    sympy
+    typing-extensions
   ];
 
   preBuild = ''