From 26bdd8b05b9a75c4b6cc5f7e0b1adb3ce0f92e6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Mon, 22 Jan 2024 00:34:32 -0300 Subject: [PATCH] sagemath: patch for scipy 1.12. See: https://github.com/sagemath/sage/pull/37123 Also apply a few minor fixes. Closes: #48317 [via git-merge-pr] --- srcpkgs/sagemath/files/sage_conf.py | 1 + .../patches/36862-giac_1.9.0-73.patch | 15 ++ ...fix_save_session_when_cython_changes.patch | 182 ++++++++++++++++++ .../sagemath/patches/37123-scipy_1.12.patch | 26 +++ srcpkgs/sagemath/patches/get_patches | 7 +- srcpkgs/sagemath/template | 8 +- 6 files changed, 234 insertions(+), 5 deletions(-) create mode 100644 srcpkgs/sagemath/patches/36862-giac_1.9.0-73.patch create mode 100644 srcpkgs/sagemath/patches/37004-fix_save_session_when_cython_changes.patch create mode 100644 srcpkgs/sagemath/patches/37123-scipy_1.12.patch diff --git a/srcpkgs/sagemath/files/sage_conf.py b/srcpkgs/sagemath/files/sage_conf.py index bc5388de895..b5b23603118 100644 --- a/srcpkgs/sagemath/files/sage_conf.py +++ b/srcpkgs/sagemath/files/sage_conf.py @@ -1,3 +1,4 @@ # configuration for sage on void linux SAGE_SHARE = "/usr/share/sagemath" GAP_SHARE_DIR = "/usr/share/gap" +JMOL_DIR = "/usr/share/jmol" diff --git a/srcpkgs/sagemath/patches/36862-giac_1.9.0-73.patch b/srcpkgs/sagemath/patches/36862-giac_1.9.0-73.patch new file mode 100644 index 00000000000..8eb2c20a34c --- /dev/null +++ b/srcpkgs/sagemath/patches/36862-giac_1.9.0-73.patch @@ -0,0 +1,15 @@ +diff --git a/src/sage/calculus/calculus.py b/src/sage/calculus/calculus.py +index dfaafb4353f..8d62ade24c8 100644 +--- a/src/sage/calculus/calculus.py ++++ b/src/sage/calculus/calculus.py +@@ -568,8 +568,8 @@ def symbolic_sum(expression, v, a, b, algorithm='maxima', hold=False): + + An example of this summation with Giac:: + +- sage: symbolic_sum(1/(1+k^2), k, -oo, oo, algorithm='giac') +- (pi*e^(2*pi) - pi*e^(-2*pi))/(e^(2*pi) + e^(-2*pi) - 2) ++ sage: symbolic_sum(1/(1+k^2), k, -oo, oo, algorithm='giac').factor() ++ pi*(e^(2*pi) + 1)/((e^pi + 1)*(e^pi - 1)) + + The same summation is solved by SymPy:: + diff --git a/srcpkgs/sagemath/patches/37004-fix_save_session_when_cython_changes.patch b/srcpkgs/sagemath/patches/37004-fix_save_session_when_cython_changes.patch new file mode 100644 index 00000000000..c3e6c055026 --- /dev/null +++ b/srcpkgs/sagemath/patches/37004-fix_save_session_when_cython_changes.patch @@ -0,0 +1,182 @@ +diff --git a/src/sage/doctest/forker.py b/src/sage/doctest/forker.py +index efd28d10abe..56a9fe5e8f6 100644 +--- a/src/sage/doctest/forker.py ++++ b/src/sage/doctest/forker.py +@@ -2477,19 +2477,6 @@ class DocTestTask(): + ['cputime', 'err', 'failures', 'optionals', 'tests', 'walltime', 'walltime_skips'] + """ + +- extra_globals = {} +- """ +- Extra objects to place in the global namespace in which tests are run. +- Normally this should be empty but there are special cases where it may +- be useful. +- +- For example, in Sage versions 9.1 and earlier, on Python 3 add +- ``long`` as an alias for ``int`` so that tests that use the +- ``long`` built-in (of which there are many) still pass. We did +- this so that the test suite could run on Python 3 while Python 2 +- was still the default. +- """ +- + def __init__(self, source): + """ + Initialization. +@@ -2614,10 +2601,6 @@ def _run(self, runner, options, results): + # Remove '__package__' item from the globals since it is not + # always in the globals in an actual Sage session. + dict_all.pop('__package__', None) +- +- # Add any other special globals for testing purposes only +- dict_all.update(self.extra_globals) +- + sage_namespace = RecordingDict(dict_all) + sage_namespace['__name__'] = '__main__' + doctests, extras = self.source.create_doctests(sage_namespace) +diff --git a/src/sage/misc/session.pyx b/src/sage/misc/session.pyx +index 31454dac993..53b732309da 100644 +--- a/src/sage/misc/session.pyx ++++ b/src/sage/misc/session.pyx +@@ -27,7 +27,7 @@ This saves a dictionary with ``w`` as one of the keys:: + + sage: z = load(os.path.join(d.name, 'session')) + sage: list(z) +- ['d', 'w'] ++ ['w', 'd'] + sage: z['w'] + 2/3 + +@@ -68,11 +68,12 @@ AUTHOR: + import builtins + import types + +-# We want the caller's locals, but locals() is emulated in Cython +-cdef caller_locals = builtins.locals +- + # Sage imports + from sage.misc.persist import load, save, loads, dumps ++from sage.misc.lazy_import import LazyImport ++ ++# We want the caller's locals, but locals() is emulated in Cython ++cdef caller_locals = builtins.locals + + # This module-scope variables is used to save the + # global state of the sage environment at the moment +@@ -80,7 +81,6 @@ from sage.misc.persist import load, save, loads, dumps + + state_at_init = None + +-CythonFunctionType = type(lambda: None) + + def init(state=None): + """ +@@ -163,9 +163,13 @@ def _is_new_var(x, v, hidden): + # definitely new. + if x not in state_at_init: + return True ++ # A lazy import that was there at init time is not new ++ if isinstance(v, LazyImport): ++ return False + # A variable could also be new even if it was there at init, say if + # its value changed. +- return x not in state_at_init or state_at_init[x] is not v ++ return state_at_init[x] is not v ++ + + def show_identifiers(hidden=False): + r""" +@@ -196,7 +200,7 @@ def show_identifiers(hidden=False): + sage: a = 10 + sage: factor = 20 + sage: show_identifiers() +- ['a', 'factor'] ++ ['factor', 'a'] + + To get the actual value of a variable from the list, use the + :func:`globals()` function.:: +@@ -210,7 +214,7 @@ def show_identifiers(hidden=False): + + sage: _hello = 10 + sage: show_identifiers() +- ['a', 'factor'] ++ ['factor', 'a'] + sage: '_hello' in show_identifiers(hidden=True) + True + +@@ -218,19 +222,13 @@ def show_identifiers(hidden=False): + least in command line mode.:: + + sage: show_identifiers(hidden=True) # random output +- ['__', '_i', '_6', '_4', '_3', '_1', '_ii', '__doc__', '__builtins__', '___', '_9', '__name__', '_', 'a', '_i12', '_i14', 'factor', '__file__', '_hello', '_i13', '_i11', '_i10', '_i15', '_i5', '_13', '_10', '_iii', '_i9', '_i8', '_i7', '_i6', '_i4', '_i3', '_i2', '_i1', '_init_cmdline', '_14'] ++ ['__builtin__', '_ih', '_oh', '_dh', 'exit', 'quit', '_', '__', '___', ++ '_i', '_ii', '_iii', '_i1', 'factor', '_i2', '_2', '_i3', 'a', '_i4', ++ '_i5', '_5', '_i6', '_6', '_i7', '_hello', '_i8', '_8', '_i9', '_9', ++ '_i10'] + """ +- from sage.doctest.forker import DocTestTask + state = caller_locals() +- # Ignore extra variables injected into the global namespace by the doctest +- # runner +- _none = object() +- +- def _in_extra_globals(name, val): +- return val == DocTestTask.extra_globals.get(name, _none) +- +- return sorted([x for x, v in state.items() if _is_new_var(x, v, hidden) +- and not _in_extra_globals(x, v)]) ++ return [x for x, v in state.items() if _is_new_var(x, v, hidden)] + + + def save_session(name='sage_session', verbose=False): +@@ -293,28 +291,44 @@ def save_session(name='sage_session', verbose=False): + sage: f = lambda x : x^2 + sage: save_session(tmp_f) + sage: save_session(tmp_f, verbose=True) +- Saving... +- Not saving f: f is a function, method, class or type + ... ++ Not saving f: f is a function or method + + Something similar happens for cython-defined functions:: + + sage: g = cython_lambda('double x', 'x*x + 1.5') + sage: save_session(tmp_f, verbose=True) +- Saving... +- Not saving g: g is a function, method, class or type + ... ++ Not saving g: g is a cython function or method ++ ++ And the same for a lazy import:: ++ ++ sage: from sage.misc.lazy_import import LazyImport ++ sage: lazy_ZZ = LazyImport('sage.rings.integer_ring', 'ZZ') ++ sage: save_session(tmp_f, verbose=True) ++ ... ++ Not saving lazy_ZZ: lazy_ZZ is a lazy import + """ + state = caller_locals() + # This dict D will contain the session -- as a dict -- that we will save to disk. + D = {} + # We iterate only over the new variables that were defined in this + # session, since those are the only ones we will save. +- for k in show_identifiers(hidden = True): ++ for k in show_identifiers(hidden=True): + try: + x = state[k] +- if isinstance(x, (types.FunctionType, types.BuiltinFunctionType, types.BuiltinMethodType, CythonFunctionType, type)): +- raise TypeError('{} is a function, method, class or type'.format(k)) ++ ++ if isinstance(x, type): ++ raise TypeError('{} is a class or type'.format(k)) ++ ++ if isinstance(x, (types.FunctionType, types.BuiltinFunctionType, types.BuiltinMethodType)): ++ raise TypeError('{} is a function or method'.format(k)) ++ ++ if getattr(type(x), '__name__', None) == 'cython_function_or_method': ++ raise TypeError('{} is a cython function or method'.format(k)) ++ ++ if isinstance(x, LazyImport): ++ raise TypeError('{} is a lazy import'.format(k)) + + # We attempt to pickle *and* unpickle every variable to + # make *certain* that we can pickled D at the end below. diff --git a/srcpkgs/sagemath/patches/37123-scipy_1.12.patch b/srcpkgs/sagemath/patches/37123-scipy_1.12.patch new file mode 100644 index 00000000000..3973b55cdbd --- /dev/null +++ b/srcpkgs/sagemath/patches/37123-scipy_1.12.patch @@ -0,0 +1,26 @@ +diff --git a/src/sage/matrix/matrix_double_dense.pyx b/src/sage/matrix/matrix_double_dense.pyx +index 5d19067f2ed..97e50fb2616 100644 +--- a/src/sage/matrix/matrix_double_dense.pyx ++++ b/src/sage/matrix/matrix_double_dense.pyx +@@ -867,7 +867,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): + # set cutoff as RDF element + if eps == 'auto': + if scipy is None: import scipy +- eps = 2*max(self._nrows, self._ncols)*scipy.finfo(float).eps*sv[0] ++ eps = 2*max(self._nrows, self._ncols)*numpy.finfo(float).eps*sv[0] + eps = RDF(eps) + # locate non-zero entries + rank = 0 +diff --git a/src/sage/numerical/optimize.py b/src/sage/numerical/optimize.py +index 708d440a205..9f973c6bd69 100644 +--- a/src/sage/numerical/optimize.py ++++ b/src/sage/numerical/optimize.py +@@ -426,7 +426,7 @@ def minimize(func, x0, gradient=None, hessian=None, algorithm="default", + hess = func.hessian() + hess_fast = [ [fast_callable(a, vars=var_names, domain=float) for a in row] for row in hess] + hessian = lambda p: [[a(*p) for a in row] for row in hess_fast] +- from scipy import dot ++ from numpy import dot + hessian_p = lambda p,v: dot(numpy.array(hessian(p)),v) + min = optimize.fmin_ncg(f, [float(_) for _ in x0], fprime=gradient, + fhess=hessian, fhess_p=hessian_p, disp=verbose, **args) diff --git a/srcpkgs/sagemath/patches/get_patches b/srcpkgs/sagemath/patches/get_patches index a552b402727..b7836e27910 100755 --- a/srcpkgs/sagemath/patches/get_patches +++ b/srcpkgs/sagemath/patches/get_patches @@ -20,6 +20,11 @@ get_pr() { # run from patches dir cd $(dirname "$0") -# needs review +# all merged in 10.3.beta6 or before get_pr 35848 "flintlib 3.0" get_pr 36769 "fix jmol detect" +get_pr 36862 "giac 1.9.0-73" +get_pr 37004 "fix save_session when cython changes" + +# positive review +get_pr 37123 "scipy 1.12" diff --git a/srcpkgs/sagemath/template b/srcpkgs/sagemath/template index 5d5bdccd70a..7bc92e7c107 100644 --- a/srcpkgs/sagemath/template +++ b/srcpkgs/sagemath/template @@ -1,7 +1,7 @@ # Template file for 'sagemath' pkgname=sagemath version=10.2 -revision=1 +revision=2 build_wrksrc=pkgs/sagemath-standard build_style=python3-module _bindir=/usr/lib/sagemath/$version/bin @@ -15,7 +15,7 @@ makedepends="boost-devel brial-devel cliquer-devel ecl eclib-devel mpfr-devel ntl-devel openblas-devel pari-devel planarity-devel python3-cypari2 python3-cysignals python3-devel python3-gmpy2 python3-memory_allocator python3-numpy rankwidth-devel singular symmetrica-devel" -depends="eclib-devel fflas-ffpack flintlib-devel gcc-fortran gd-devel +depends="eclib-devel fflas-ffpack flintlib-devel gcc-fortran meson gd-devel gfan giac gsl-devel gzip libpng-devel linbox-devel m4ri-devel maxima-ecl mpfr-devel nauty ntl-devel palp pari-devel pari-elldata-small pari-galdata pari-galpol-small pari-seadata-small pkg-config python3-Cython python3-cypari2 @@ -26,7 +26,7 @@ depends="eclib-devel fflas-ffpack flintlib-devel gcc-fortran gd-devel python3-sympy python3-traitlets sage-data-combinatorial_designs sage-data-conway_polynomials sage-data-elliptic_curves sage-data-graphs sage-data-polytopes_db sympow tachyon threejs-sage" -checkdepends="$depends pythran python3-Sphinx meson" +checkdepends="$depends pythran python3-Sphinx" short_desc="Open source mathematics software" maintainer="Gonzalo TornarĂ­a " license="GPL-2.0-or-later" @@ -34,7 +34,7 @@ homepage="https://www.sagemath.org/" changelog="https://github.com/sagemath/sage/releases" distfiles="https://github.com/sagemath/sage/archive/refs/tags/$version.tar.gz" checksum=e7125f13495e1068edab73735aca7f9b2c655688096e9d109e628c023e76411f -nocross="due to ntl (eclib), fflas-ffpack, givaro, linbox, sympow, maxima" +nocross="due to ntl (eclib, singular), fflas-ffpack, givaro, linbox, sympow, maxima" post_patch() { # git tree needs bootstrapping