diff --git a/srcpkgs/sagemath/patches/36403-00pre.patch b/srcpkgs/sagemath/patches/36403-00pre.patch new file mode 100644 index 00000000000..060404d5430 --- /dev/null +++ b/srcpkgs/sagemath/patches/36403-00pre.patch @@ -0,0 +1,29 @@ +Minor patch so that #36403 applies cleanly over sagemath 10.1 + +diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx +index 2053bca80c3..86aca6e00d8 100644 +--- a/src/sage/matrix/matrix2.pyx ++++ b/src/sage/matrix/matrix2.pyx +@@ -15123,7 +15302,8 @@ cdef class Matrix(Matrix1): + sage: N.conjugate_transpose() + Traceback (most recent call last): + ... +- AttributeError: 'sage.rings.finite_rings.integer_mod.IntegerMod_int' object has no attribute 'conjugate' ++ AttributeError: 'sage.rings.finite_rings.integer_mod.IntegerMod_int' object ++ has no attribute 'conjugate' + """ + # limited testing on a 1000 x 1000 matrix over CC: + # transpose is fast, conjugate is slow +diff --git a/src/sage/cpython/getattr.pyx b/src/sage/cpython/getattr.pyx +index 525ea5aa934..52afed49d64 100644 +--- a/src/sage/cpython/getattr.pyx ++++ b/src/sage/cpython/getattr.pyx +@@ -55,7 +55,7 @@ cdef class AttributeErrorMessage: + ... + AttributeError: 'sage.rings.integer.Integer' object has no attribute 'bla' + sage: x = polygen(ZZ, 'x') +- sage: QQ[x].gen().bla # optional - sage.libs.flint ++ sage: QQ[x].gen().bla # needs sage.libs.flint + Traceback (most recent call last): + ... + AttributeError: 'sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint' object has no attribute 'bla' diff --git a/srcpkgs/sagemath/patches/36407-python_3.12.patch b/srcpkgs/sagemath/patches/36407-python_3.12.patch new file mode 100644 index 00000000000..c75c275c307 --- /dev/null +++ b/srcpkgs/sagemath/patches/36407-python_3.12.patch @@ -0,0 +1,1744 @@ +diff --git a/build/sage_bootstrap/package.py b/build/sage_bootstrap/package.py +index 15b342223c4..eb82f96e05f 100644 +--- a/build/sage_bootstrap/package.py ++++ b/build/sage_bootstrap/package.py +@@ -303,7 +303,7 @@ def _init_checksum(self): + # Name of the directory containing the checksums.ini file + self.__tarball_package_name = os.path.realpath(checksums_ini).split(os.sep)[-2] + +- VERSION_PATCHLEVEL = re.compile('(?P.*)\.p(?P[0-9]+)') ++ VERSION_PATCHLEVEL = re.compile(r'(?P.*)\.p(?P[0-9]+)') + + def _init_version(self): + try: +diff --git a/src/doc/en/thematic_tutorials/coercion_and_categories.rst b/src/doc/en/thematic_tutorials/coercion_and_categories.rst +index bb23331c151..7f5712caea7 100644 +--- a/src/doc/en/thematic_tutorials/coercion_and_categories.rst ++++ b/src/doc/en/thematic_tutorials/coercion_and_categories.rst +@@ -1223,7 +1223,7 @@ However, only "elementary" construction functors have a rank:: + sage: (Fract*Poly).rank + Traceback (most recent call last): + ... +- AttributeError: 'CompositeConstructionFunctor' object has no attribute 'rank' ++ AttributeError: 'CompositeConstructionFunctor' object has no attribute 'rank'... + + .. end of output + +diff --git a/src/doc/en/thematic_tutorials/tutorial-objects-and-classes.rst b/src/doc/en/thematic_tutorials/tutorial-objects-and-classes.rst +index 553a946c4d8..3cd71a9bad4 100644 +--- a/src/doc/en/thematic_tutorials/tutorial-objects-and-classes.rst ++++ b/src/doc/en/thematic_tutorials/tutorial-objects-and-classes.rst +@@ -318,7 +318,7 @@ http://docs.python.org/library/ for a complete list. :: + sage: e.__dict__ + Traceback (most recent call last): + ... +- AttributeError: 'sage.rings.integer.Integer' object has no attribute '__dict__' ++ AttributeError: 'sage.rings.integer.Integer' object has no attribute '__dict__'... + + sage: id4 = SymmetricGroup(4).one() + sage: type(id4) +@@ -326,7 +326,7 @@ http://docs.python.org/library/ for a complete list. :: + sage: id4.__dict__ + Traceback (most recent call last): + ... +- AttributeError: 'sage.groups.perm_gps.permgroup_element.SymmetricGroupElement' object has no attribute '__dict__' ++ AttributeError: 'sage.groups.perm_gps.permgroup_element.SymmetricGroupElement' object has no attribute '__dict__'... + + .. note:: + +diff --git a/src/sage/algebras/cluster_algebra.py b/src/sage/algebras/cluster_algebra.py +index b72d2a12976..14669dfed5c 100644 +--- a/src/sage/algebras/cluster_algebra.py ++++ b/src/sage/algebras/cluster_algebra.py +@@ -167,7 +167,7 @@ + sage: (t*s).g_vector() + Traceback (most recent call last): + ... +- AttributeError: 'ClusterAlgebra_with_category.element_class' object has no attribute 'g_vector' ++ AttributeError: 'ClusterAlgebra_with_category.element_class' object has no attribute 'g_vector'... + sage: A = ClusterAlgebra(['A', 2], principal_coefficients=True) + sage: A.explore_to_depth(infinity) + sage: s = A.cluster_variable((0, -1)); s +diff --git a/src/sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py +index e4a91723558..343ee8a66f9 100644 +--- a/src/sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py ++++ b/src/sage/algebras/lie_conformal_algebras/weyl_lie_conformal_algebra.py +@@ -109,7 +109,7 @@ class WeylLieConformalAlgebra(LieConformalAlgebraWithStructureCoefficients): + sage: alpha0.degree() + Traceback (most recent call last): + ... +- AttributeError: 'WeylLieConformalAlgebra_with_category.element_class' object has no attribute 'degree' ++ AttributeError: 'WeylLieConformalAlgebra_with_category.element_class' object has no attribute 'degree'... + + TESTS:: + +diff --git a/src/sage/algebras/steenrod/steenrod_algebra.py b/src/sage/algebras/steenrod/steenrod_algebra.py +index 978a3557a9d..7c4d444f81c 100644 +--- a/src/sage/algebras/steenrod/steenrod_algebra.py ++++ b/src/sage/algebras/steenrod/steenrod_algebra.py +@@ -1080,7 +1080,7 @@ def homogeneous_component(self, n): + sage: a.antipode() # not defined + Traceback (most recent call last): + ... +- AttributeError: 'CombinatorialFreeModule_with_category.element_class' object has no attribute 'antipode' ++ AttributeError: 'CombinatorialFreeModule_with_category.element_class' object has no attribute 'antipode'... + sage: A(a).antipode() # convert to elt of A, then compute antipode + Sq(2,1) + Sq(5) + +diff --git a/src/sage/all__sagemath_repl.py b/src/sage/all__sagemath_repl.py +index 8d0b43679ca..c31b206bcb8 100644 +--- a/src/sage/all__sagemath_repl.py ++++ b/src/sage/all__sagemath_repl.py +@@ -79,6 +79,23 @@ + message=r"Use setlocale\(\), getencoding\(\) and getlocale\(\) instead", + module='docutils.io') + ++# triggered by dateutil 2.8.2 and sphinx 7.0.1 on Python 3.12 ++# see: https://github.com/dateutil/dateutil/pull/1285 ++# see: https://github.com/sphinx-doc/sphinx/pull/11468 ++warnings.filterwarnings('ignore', category=DeprecationWarning, ++ message=r"datetime.datetime.utcfromtimestamp\(\) is deprecated", ++ module='dateutil.tz.tz|sphinx.(builders.gettext|util.i18n)') ++ ++# triggered on Python 3.12 ++warnings.filterwarnings('ignore', category=DeprecationWarning, ++ message=r"This process.* is multi-threaded, " ++ r"use of .*\(\) may lead to deadlocks in the child.") ++ ++# pickling of itertools is deprecated in Python 3.12 ++warnings.filterwarnings('ignore', category=DeprecationWarning, ++ message=r"Pickle, copy, and deepcopy support will be " ++ r"removed from itertools in Python 3.14.") ++ + + from .all__sagemath_objects import * + from .all__sagemath_environment import * +diff --git a/src/sage/arith/long.pxd b/src/sage/arith/long.pxd +index 0031a0ae337..3ea70cef571 100644 +--- a/src/sage/arith/long.pxd ++++ b/src/sage/arith/long.pxd +@@ -19,6 +19,8 @@ from libc.limits cimport LONG_MIN, LONG_MAX + from cpython.object cimport Py_SIZE + from cpython.number cimport PyNumber_Index, PyIndex_Check + from cpython.longintrepr cimport py_long, PyLong_SHIFT, digit ++from sage.cpython.pycore_long cimport ( ++ ob_digit, _PyLong_IsNegative, _PyLong_DigitCount) + + from sage.libs.gmp.mpz cimport mpz_fits_slong_p, mpz_get_si + from sage.rings.integer_fake cimport is_Integer, Integer_AS_MPZ +@@ -299,8 +301,11 @@ cdef inline bint integer_check_long_py(x, long* value, int* err): + return 0 + + # x is a Python "int" (aka PyLongObject or py_long in cython) +- cdef const digit* D = (x).ob_digit +- cdef Py_ssize_t size = Py_SIZE(x) ++ cdef const digit* D = ob_digit(x) ++ cdef Py_ssize_t size = _PyLong_DigitCount(x) ++ ++ if _PyLong_IsNegative(x): ++ size = -size + + # We assume PyLong_SHIFT <= BITS_IN_LONG <= 3 * PyLong_SHIFT. + # This is true in all the default configurations: +diff --git a/src/sage/categories/category.py b/src/sage/categories/category.py +index 57ef7f4184b..29bce8ee415 100644 +--- a/src/sage/categories/category.py ++++ b/src/sage/categories/category.py +@@ -2129,7 +2129,7 @@ def _with_axioms(self, axioms): + sage: Semigroups().Inverse() + Traceback (most recent call last): + ... +- AttributeError: 'Semigroups_with_category' object has no attribute 'Inverse' ++ AttributeError: 'Semigroups_with_category' object has no attribute 'Inverse'... + sage: Semigroups()._with_axioms(["Inverse"]) + Category of semigroups + +diff --git a/src/sage/categories/category_with_axiom.py b/src/sage/categories/category_with_axiom.py +index 5227792e725..4775d4e5bf1 100644 +--- a/src/sage/categories/category_with_axiom.py ++++ b/src/sage/categories/category_with_axiom.py +@@ -554,7 +554,7 @@ class from the base category class:: + sage: Magmas.Unital.Associative + Traceback (most recent call last): + ... +- AttributeError: type object 'Magmas.Unital' has no attribute 'Associative' ++ AttributeError: type object 'Magmas.Unital' has no attribute 'Associative'... + + The purpose of this section is to explain the design of the code + layout and the rationale for this mismatch. +@@ -769,7 +769,7 @@ def _(): return LazyImport('sage.categories.rngs', 'Rngs', at_startup=True) + sage: Semirings().NoZeroDivisors() + Traceback (most recent call last): + ... +- AttributeError: 'Semirings_with_category' object has no attribute 'NoZeroDivisors' ++ AttributeError: 'Semirings_with_category' object has no attribute 'NoZeroDivisors'... + + Concretely, this is to be implemented by defining the new axiom in the + (``SubcategoryMethods`` nested class of the) appropriate category with +diff --git a/src/sage/categories/enumerated_sets.py b/src/sage/categories/enumerated_sets.py +index a8bea53f907..b0ea05d0563 100644 +--- a/src/sage/categories/enumerated_sets.py ++++ b/src/sage/categories/enumerated_sets.py +@@ -610,7 +610,7 @@ def _list_from_iterator(self): + sage: (QQ^2).list() # indirect test # needs sage.modules + Traceback (most recent call last): + ... +- AttributeError: 'FreeModule_ambient_field_with_category' object has no attribute 'list' ++ AttributeError: 'FreeModule_ambient_field_with_category' object has no attribute 'list'... + + Here we test that for an object that does not know whether it + is finite or not. Calling ``x.list()`` simply tries to create +@@ -622,11 +622,11 @@ def _list_from_iterator(self): + sage: Q.is_finite() + Traceback (most recent call last): + ... +- AttributeError: 'QuotientRing_generic_with_category' object has no attribute 'is_finite' ++ AttributeError: 'QuotientRing_generic_with_category' object has no attribute 'is_finite'... + sage: Q.list() # indirect test + Traceback (most recent call last): + ... +- AttributeError: 'QuotientRing_generic_with_category' object has no attribute 'list' ++ AttributeError: 'QuotientRing_generic_with_category' object has no attribute 'list'... + + Here is another example. We artificially create a version of + the ring of integers that does not know whether it is finite +diff --git a/src/sage/categories/examples/sets_cat.py b/src/sage/categories/examples/sets_cat.py +index e0853d63f94..fbadb9ca405 100644 +--- a/src/sage/categories/examples/sets_cat.py ++++ b/src/sage/categories/examples/sets_cat.py +@@ -619,7 +619,7 @@ class PrimeNumbers_Facade(PrimeNumbers_Abstract): + sage: pf.next() + Traceback (most recent call last): + ... +- AttributeError: 'sage.rings.integer.Integer' object has no attribute 'next' ++ AttributeError: 'sage.rings.integer.Integer' object has no attribute 'next'... + + unlike in the other implementations:: + +diff --git a/src/sage/categories/homset.py b/src/sage/categories/homset.py +index 22ba9d047fc..2a8b8aeedeb 100644 +--- a/src/sage/categories/homset.py ++++ b/src/sage/categories/homset.py +@@ -632,7 +632,7 @@ def __init__(self, X, Y, category=None, base=None, check=True): + sage: H = MyHomset(X, Y, category=1, base = ZZ, check = False) + Traceback (most recent call last): + ... +- AttributeError: 'sage.rings.integer.Integer' object has no attribute 'Homsets' ++ AttributeError: 'sage.rings.integer.Integer' object has no attribute 'Homsets'... + sage: P. = ZZ[] + sage: f = P.hom([1/2*t]) + sage: f.parent().domain() +diff --git a/src/sage/categories/modules_with_basis.py b/src/sage/categories/modules_with_basis.py +index e97bf851388..c4933d0657f 100644 +--- a/src/sage/categories/modules_with_basis.py ++++ b/src/sage/categories/modules_with_basis.py +@@ -2456,7 +2456,7 @@ def apply_multilinear_morphism(self, f, codomain=None): + sage: tensor([a, b]).apply_multilinear_morphism(f) # needs sage.modules + Traceback (most recent call last): + ... +- AttributeError: 'int' object has no attribute 'parent' ++ AttributeError: 'int' object has no attribute 'parent'... + + Here we consider an example where the codomain is a + module with basis with a different base ring:: +diff --git a/src/sage/categories/monoids.py b/src/sage/categories/monoids.py +index 38dd7248c9d..28474bd17b6 100644 +--- a/src/sage/categories/monoids.py ++++ b/src/sage/categories/monoids.py +@@ -556,7 +556,7 @@ def algebra_generators(self): + Traceback (most recent call last): + ... + AttributeError: 'IntegerModMonoid_with_category' object +- has no attribute 'monoid_generators' ++ has no attribute 'monoid_generators'... + sage: Z12.semigroup_generators() + Family (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) + sage: Z12.algebra(QQ).algebra_generators() # needs sage.modules +diff --git a/src/sage/combinat/finite_state_machine.py b/src/sage/combinat/finite_state_machine.py +index 494e8154c80..ec5120e41e6 100644 +--- a/src/sage/combinat/finite_state_machine.py ++++ b/src/sage/combinat/finite_state_machine.py +@@ -1835,7 +1835,7 @@ def __getstate__(self): + sage: T1.transitions + Traceback (most recent call last): + ... +- AttributeError: 'FSMState' object has no attribute 'transitions' ++ AttributeError: 'FSMState' object has no attribute 'transitions'... + sage: A1 = loads(dumps(A)) + sage: all(A.state(j) == A1.state(j) for j in [0, 1]) + True +diff --git a/src/sage/combinat/growth.py b/src/sage/combinat/growth.py +index cf8d18c1764..766eea37917 100644 +--- a/src/sage/combinat/growth.py ++++ b/src/sage/combinat/growth.py +@@ -371,7 +371,7 @@ + sage: GrowthDiagram(RulePascal(), [3,1,2]) + Traceback (most recent call last): + ... +- AttributeError: 'RulePascal' object has no attribute 'forward_rule' ++ AttributeError: 'RulePascal' object has no attribute 'forward_rule'... + + We now re-implement the rule where we provide the dual graded graphs:: + +diff --git a/src/sage/combinat/integer_lists/lists.py b/src/sage/combinat/integer_lists/lists.py +index 5143e5cb5e8..9117a6076f7 100644 +--- a/src/sage/combinat/integer_lists/lists.py ++++ b/src/sage/combinat/integer_lists/lists.py +@@ -261,7 +261,7 @@ def __getattr__(self, name): + sage: L.foo + Traceback (most recent call last): + ... +- AttributeError: 'NoneType' object has no attribute 'foo' ++ AttributeError: 'NoneType' object has no attribute 'foo'... + """ + return getattr(self.backend, name) + +diff --git a/src/sage/combinat/posets/posets.py b/src/sage/combinat/posets/posets.py +index c31597c72e9..c74bfc67cee 100644 +--- a/src/sage/combinat/posets/posets.py ++++ b/src/sage/combinat/posets/posets.py +@@ -8825,7 +8825,7 @@ def is_induced_subposet(self, other): + sage: Poset().is_induced_subposet('junk') + Traceback (most recent call last): + ... +- AttributeError: 'str' object has no attribute 'subposet' ++ AttributeError: 'str' object has no attribute 'subposet'... + """ + if (not self._is_facade or (isinstance(other, FinitePoset) and + not other._is_facade)): +diff --git a/src/sage/cpython/atexit.pyx b/src/sage/cpython/atexit.pyx +index 961aa348d0a..e5a82735137 100644 +--- a/src/sage/cpython/atexit.pyx ++++ b/src/sage/cpython/atexit.pyx +@@ -154,6 +154,10 @@ cdef extern from *: + #undef _PyGC_FINALIZED + #include "internal/pycore_interp.h" + #include "internal/pycore_pystate.h" ++ #if PY_VERSION_HEX >= 0x030c0000 ++ // struct atexit_callback was renamed in 3.12 to atexit_py_callback ++ #define atexit_callback atexit_py_callback ++ #endif + static atexit_callback ** _atexit_callbacks(PyObject *self) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + struct atexit_state state = interp->atexit; +diff --git a/src/sage/cpython/debug.pyx b/src/sage/cpython/debug.pyx +index 986abff2a99..cdaca3a4854 100644 +--- a/src/sage/cpython/debug.pyx ++++ b/src/sage/cpython/debug.pyx +@@ -78,7 +78,7 @@ def getattr_debug(obj, name, default=_no_default): + + EXAMPLES:: + +- sage: _ = getattr_debug(list, "reverse") ++ sage: _ = getattr_debug(list, "reverse") # not tested - broken in python 3.12 + getattr_debug(obj=, name='reverse'): + type(obj) = + object has __dict__ slot () +@@ -123,7 +123,7 @@ def getattr_debug(obj, name, default=_no_default): + sage: _ = getattr_debug(1, "foo") + Traceback (most recent call last): + ... +- AttributeError: 'sage.rings.integer.Integer' object has no attribute 'foo' ++ AttributeError: 'sage.rings.integer.Integer' object has no attribute 'foo'... + sage: _ = getattr_debug(1, "foo", "xyz") + getattr_debug(obj=1, name='foo'): + type(obj) = +diff --git a/src/sage/cpython/dict_internal.h b/src/sage/cpython/dict_internal.h +index 42a57bcb468..a5ee35bc198 100644 +--- a/src/sage/cpython/dict_internal.h ++++ b/src/sage/cpython/dict_internal.h +@@ -169,6 +169,7 @@ dictkeys_set_index(PyDictKeysObject *keys, Py_ssize_t i, Py_ssize_t ix) + #else /* Python >= 3.11 */ + + #define Py_BUILD_CORE ++#undef _PyGC_FINALIZED + #include + + /************************************************************/ +diff --git a/src/sage/cpython/getattr.pyx b/src/sage/cpython/getattr.pyx +index 52afed49d64..1f49e5230c3 100644 +--- a/src/sage/cpython/getattr.pyx ++++ b/src/sage/cpython/getattr.pyx +@@ -53,12 +53,12 @@ cdef class AttributeErrorMessage: + sage: 1.bla #indirect doctest + Traceback (most recent call last): + ... +- AttributeError: 'sage.rings.integer.Integer' object has no attribute 'bla' ++ AttributeError: 'sage.rings.integer.Integer' object has no attribute 'bla'... + sage: x = polygen(ZZ, 'x') + sage: QQ[x].gen().bla # needs sage.libs.flint + Traceback (most recent call last): + ... +- AttributeError: 'sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint' object has no attribute 'bla' ++ AttributeError: 'sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint' object has no attribute 'bla'... + + :: + +@@ -144,7 +144,7 @@ cpdef raw_getattr(obj, name): + sage: raw_getattr(X, "attr") + Traceback (most recent call last): + ... +- AttributeError: '...' object has no attribute 'attr' ++ AttributeError: '...' object has no attribute 'attr'... + sage: x = X() + sage: raw_getattr(x, "prop") + +@@ -173,7 +173,7 @@ cpdef raw_getattr(obj, name): + sage: raw_getattr(Y, "attr") + Traceback (most recent call last): + ... +- AttributeError: '...' object has no attribute 'attr' ++ AttributeError: '...' object has no attribute 'attr'... + sage: y = Y() + sage: raw_getattr(y, "prop") + +@@ -278,7 +278,7 @@ cpdef getattr_from_other_class(self, cls, name): + sage: getattr_from_other_class(1, A, "lazy_attribute") + Traceback (most recent call last): + ... +- AttributeError: 'sage.rings.integer.Integer' object has no attribute 'lazy_attribute' ++ AttributeError: 'sage.rings.integer.Integer' object has no attribute 'lazy_attribute'... + + The integer ring is a parent, so, lazy attributes work:: + +@@ -289,7 +289,7 @@ cpdef getattr_from_other_class(self, cls, name): + sage: getattr_from_other_class(17, A, "lazy_attribute") + Traceback (most recent call last): + ... +- AttributeError: 'sage.rings.integer.Integer' object has no attribute 'lazy_attribute' ++ AttributeError: 'sage.rings.integer.Integer' object has no attribute 'lazy_attribute'... + + In general, descriptors are not yet well supported, because they + often do not accept to be cheated with the type of their instance:: +@@ -305,7 +305,7 @@ cpdef getattr_from_other_class(self, cls, name): + sage: getattr_from_other_class(1, A, "__weakref__") + Traceback (most recent call last): + ... +- AttributeError: 'sage.rings.integer.Integer' object has no attribute '__weakref__' ++ AttributeError: 'sage.rings.integer.Integer' object has no attribute '__weakref__'... + + This was caught by :trac:`8296` for which we do a couple more tests:: + +@@ -314,7 +314,7 @@ cpdef getattr_from_other_class(self, cls, name): + sage: 1.__weakref__ + Traceback (most recent call last): + ... +- AttributeError: 'sage.rings.integer.Integer' object has no attribute '__weakref__' ++ AttributeError: 'sage.rings.integer.Integer' object has no attribute '__weakref__'... + + sage: n = 1 + sage: ip = get_ipython() # not tested: only works in interactive shell +@@ -329,7 +329,7 @@ cpdef getattr_from_other_class(self, cls, name): + sage: getattr_from_other_class(1, A, "__call__") + Traceback (most recent call last): + ... +- AttributeError: 'sage.rings.integer.Integer' object has no attribute '__call__' ++ AttributeError: 'sage.rings.integer.Integer' object has no attribute '__call__'... + + TESTS: + +@@ -339,14 +339,14 @@ cpdef getattr_from_other_class(self, cls, name): + sage: getattr_from_other_class(1, type, "__name__") + Traceback (most recent call last): + ... +- AttributeError: 'sage.rings.integer.Integer' object has no attribute '__name__' ++ AttributeError: 'sage.rings.integer.Integer' object has no attribute '__name__'... + + Non-strings as "name" are handled gracefully:: + + sage: getattr_from_other_class(1, type, None) + Traceback (most recent call last): + ... +- AttributeError: 'sage.rings.integer.Integer' object has no attribute None ++ AttributeError: 'sage.rings.integer.Integer' object has no attribute None... + """ + if not isinstance(cls, type): + raise TypeError(f"{cls!r} is not a type") +diff --git a/src/sage/cpython/pycore_long.h b/src/sage/cpython/pycore_long.h +new file mode 100644 +index 00000000000..ff1a73d097a +--- /dev/null ++++ b/src/sage/cpython/pycore_long.h +@@ -0,0 +1,98 @@ ++#include "Python.h" ++#include ++ ++#if PY_VERSION_HEX >= 0x030C00A5 ++#define ob_digit(o) (((PyLongObject*)o)->long_value.ob_digit) ++#else ++#define ob_digit(o) (((PyLongObject*)o)->ob_digit) ++#endif ++ ++#if PY_VERSION_HEX >= 0x030C00A7 ++// taken from cpython:Include/internal/pycore_long.h @ 3.12 ++ ++/* Long value tag bits: ++ * 0-1: Sign bits value = (1-sign), ie. negative=2, positive=0, zero=1. ++ * 2: Reserved for immortality bit ++ * 3+ Unsigned digit count ++ */ ++#define SIGN_MASK 3 ++#define SIGN_ZERO 1 ++#define SIGN_NEGATIVE 2 ++#define NON_SIZE_BITS 3 ++ ++static inline bool ++_PyLong_IsZero(const PyLongObject *op) ++{ ++ return (op->long_value.lv_tag & SIGN_MASK) == SIGN_ZERO; ++} ++ ++static inline bool ++_PyLong_IsNegative(const PyLongObject *op) ++{ ++ return (op->long_value.lv_tag & SIGN_MASK) == SIGN_NEGATIVE; ++} ++ ++static inline bool ++_PyLong_IsPositive(const PyLongObject *op) ++{ ++ return (op->long_value.lv_tag & SIGN_MASK) == 0; ++} ++ ++static inline Py_ssize_t ++_PyLong_DigitCount(const PyLongObject *op) ++{ ++ assert(PyLong_Check(op)); ++ return op->long_value.lv_tag >> NON_SIZE_BITS; ++} ++ ++#define TAG_FROM_SIGN_AND_SIZE(sign, size) ((1 - (sign)) | ((size) << NON_SIZE_BITS)) ++ ++static inline void ++_PyLong_SetSignAndDigitCount(PyLongObject *op, int sign, Py_ssize_t size) ++{ ++ assert(size >= 0); ++ assert(-1 <= sign && sign <= 1); ++ assert(sign != 0 || size == 0); ++ op->long_value.lv_tag = TAG_FROM_SIGN_AND_SIZE(sign, (size_t)size); ++} ++ ++#else ++// fallback for < 3.12 ++ ++static inline bool ++_PyLong_IsZero(const PyLongObject *op) ++{ ++ return Py_SIZE(op) == 0; ++} ++ ++static inline bool ++_PyLong_IsNegative(const PyLongObject *op) ++{ ++ return Py_SIZE(op) < 0; ++} ++ ++static inline bool ++_PyLong_IsPositive(const PyLongObject *op) ++{ ++ return Py_SIZE(op) > 0; ++} ++ ++static inline Py_ssize_t ++_PyLong_DigitCount(const PyLongObject *op) ++{ ++ Py_ssize_t size = Py_SIZE(op); ++ return size < 0 ? -size : size; ++} ++ ++static inline void ++_PyLong_SetSignAndDigitCount(PyLongObject *op, int sign, Py_ssize_t size) ++{ ++#if (PY_MAJOR_VERSION == 3) && (PY_MINOR_VERSION < 9) ++// The function Py_SET_SIZE is defined starting with python 3.9. ++ Py_SIZE(o) = size; ++#else ++ Py_SET_SIZE(op, sign < 0 ? -size : size); ++#endif ++} ++ ++#endif +diff --git a/src/sage/cpython/pycore_long.pxd b/src/sage/cpython/pycore_long.pxd +new file mode 100644 +index 00000000000..41de637ff18 +--- /dev/null ++++ b/src/sage/cpython/pycore_long.pxd +@@ -0,0 +1,9 @@ ++from cpython.longintrepr cimport py_long, digit ++ ++cdef extern from "pycore_long.h": ++ digit* ob_digit(py_long o) ++ bint _PyLong_IsZero(py_long o) ++ bint _PyLong_IsNegative(py_long o) ++ bint _PyLong_IsPositive(py_long o) ++ Py_ssize_t _PyLong_DigitCount(py_long o) ++ void _PyLong_SetSignAndDigitCount(py_long o, int sign, Py_ssize_t size) +diff --git a/src/sage/crypto/classical.py b/src/sage/crypto/classical.py +index 616dc861652..be899c781e5 100644 +--- a/src/sage/crypto/classical.py ++++ b/src/sage/crypto/classical.py +@@ -494,7 +494,7 @@ def rank_by_chi_square(self, C, pdict): + sage: A.rank_by_chi_square("", Plist) + Traceback (most recent call last): + ... +- AttributeError: 'str' object has no attribute 'parent' ++ AttributeError: 'str' object has no attribute 'parent'... + sage: A.rank_by_chi_square(A.encoding(""), Plist) + Traceback (most recent call last): + ... +@@ -703,7 +703,7 @@ def rank_by_squared_differences(self, C, pdict): + sage: A.rank_by_squared_differences("", Plist) + Traceback (most recent call last): + ... +- AttributeError: 'str' object has no attribute 'parent' ++ AttributeError: 'str' object has no attribute 'parent'... + sage: A.rank_by_squared_differences(A.encoding(""), Plist) + Traceback (most recent call last): + ... +@@ -2114,7 +2114,7 @@ def rank_by_chi_square(self, C, pdict): + sage: S.rank_by_chi_square("", Pdict) + Traceback (most recent call last): + ... +- AttributeError: 'str' object has no attribute 'parent' ++ AttributeError: 'str' object has no attribute 'parent'... + sage: S.rank_by_chi_square(S.encoding(""), Pdict) + Traceback (most recent call last): + ... +@@ -2351,7 +2351,7 @@ def rank_by_squared_differences(self, C, pdict): + sage: S.rank_by_squared_differences("", Pdict) + Traceback (most recent call last): + ... +- AttributeError: 'str' object has no attribute 'parent' ++ AttributeError: 'str' object has no attribute 'parent'... + sage: S.rank_by_squared_differences(S.encoding(""), Pdict) + Traceback (most recent call last): + ... +diff --git a/src/sage/crypto/mq/mpolynomialsystemgenerator.py b/src/sage/crypto/mq/mpolynomialsystemgenerator.py +index 9028dab1d98..4416d9ef7f6 100644 +--- a/src/sage/crypto/mq/mpolynomialsystemgenerator.py ++++ b/src/sage/crypto/mq/mpolynomialsystemgenerator.py +@@ -156,7 +156,7 @@ def sbox(self): + sage: msg.sbox() + Traceback (most recent call last): + ... +- AttributeError: '' object has no attribute '_sbox' ++ AttributeError: '' object has no attribute '_sbox'... + """ + return self._sbox + +diff --git a/src/sage/data_structures/bitset.pyx b/src/sage/data_structures/bitset.pyx +index 446062554c1..d9906b5edd2 100644 +--- a/src/sage/data_structures/bitset.pyx ++++ b/src/sage/data_structures/bitset.pyx +@@ -967,7 +967,7 @@ cdef class FrozenBitset: + sage: None | FrozenBitset('10101') + Traceback (most recent call last): + ... +- AttributeError: 'NoneType' object has no attribute '_union' ++ AttributeError: 'NoneType' object has no attribute '_union'... + """ + return self._union(other) + +@@ -1037,7 +1037,7 @@ cdef class FrozenBitset: + sage: None & FrozenBitset("101011") + Traceback (most recent call last): + ... +- AttributeError: 'NoneType' object has no attribute 'intersection' ++ AttributeError: 'NoneType' object has no attribute 'intersection'... + """ + return self.intersection(other) + +@@ -1106,7 +1106,7 @@ cdef class FrozenBitset: + sage: None - FrozenBitset('10101') + Traceback (most recent call last): + ... +- AttributeError: 'NoneType' object has no attribute 'difference' ++ AttributeError: 'NoneType' object has no attribute 'difference'... + """ + return self.difference(other) + +@@ -1179,7 +1179,7 @@ cdef class FrozenBitset: + sage: None ^^ FrozenBitset('11111' * 10) + Traceback (most recent call last): + ... +- AttributeError: 'NoneType' object has no attribute 'symmetric_difference' ++ AttributeError: 'NoneType' object has no attribute 'symmetric_difference'... + """ + return self.symmetric_difference(other) + +diff --git a/src/sage/doctest/reporting.py b/src/sage/doctest/reporting.py +index 361fea344c2..a3947c07e01 100644 +--- a/src/sage/doctest/reporting.py ++++ b/src/sage/doctest/reporting.py +@@ -368,7 +368,7 @@ def report(self, source, timeout, return_code, results, output, pid=None): + sage: DTR.report(None, None, None, None, None) + Traceback (most recent call last): + ... +- AttributeError: 'NoneType' object has no attribute 'basename' ++ AttributeError: 'NoneType' object has no attribute 'basename'... + + The only-errors mode does not output anything on success:: + +diff --git a/src/sage/dynamics/finite_dynamical_system.py b/src/sage/dynamics/finite_dynamical_system.py +index e5fbf568b7e..4295070615a 100644 +--- a/src/sage/dynamics/finite_dynamical_system.py ++++ b/src/sage/dynamics/finite_dynamical_system.py +@@ -240,7 +240,7 @@ class DiscreteDynamicalSystem(SageObject, metaclass=ClasscallMetaclass): + sage: D.inverse_evolution()(4) + Traceback (most recent call last): + ... +- AttributeError: 'DiscreteDynamicalSystem' object has no attribute 'inverse_evolution' ++ AttributeError: 'DiscreteDynamicalSystem' object has no attribute 'inverse_evolution'... + sage: D.orbit(3) + [3, 5, 1] + +@@ -252,7 +252,7 @@ class DiscreteDynamicalSystem(SageObject, metaclass=ClasscallMetaclass): + sage: D.inverse_evolution()(4) + Traceback (most recent call last): + ... +- AttributeError: 'DiscreteDynamicalSystem' object has no attribute 'inverse_evolution' ++ AttributeError: 'DiscreteDynamicalSystem' object has no attribute 'inverse_evolution'... + sage: D.orbit(3) + [3, 5, 1] + +diff --git a/src/sage/geometry/cone.py b/src/sage/geometry/cone.py +index f0a8620011a..53f78a4b7b6 100644 +--- a/src/sage/geometry/cone.py ++++ b/src/sage/geometry/cone.py +@@ -340,7 +340,7 @@ def Cone(rays, lattice=None, check=True, normalize=True): + sage: Cone([(1,0), (0,1)], check=False, normalize=False) + Traceback (most recent call last): + ... +- AttributeError: 'tuple' object has no attribute 'parent' ++ AttributeError: 'tuple' object has no attribute 'parent'... + + You can construct different "not" cones: not full-dimensional, not + strictly convex, not containing any rays:: +diff --git a/src/sage/geometry/fan.py b/src/sage/geometry/fan.py +index 258544012fe..3aecc84a55b 100644 +--- a/src/sage/geometry/fan.py ++++ b/src/sage/geometry/fan.py +@@ -443,7 +443,7 @@ def Fan(cones, rays=None, lattice=None, check=True, normalize=True, + sage: P2c = Fan(cones, rays, check=False, normalize=False) + Traceback (most recent call last): + ... +- AttributeError: 'tuple' object has no attribute 'parent' ++ AttributeError: 'tuple' object has no attribute 'parent'... + + Yet another way is to use functions :func:`FaceFan` and :func:`NormalFan` + to construct fans from :class:`lattice polytopes +diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx +index f0ac1e774a7..f03f0f832ff 100644 +--- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx ++++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx +@@ -351,7 +351,7 @@ cdef class FaceIterator_base(SageObject): + sage: FaceIterator_base(2) # indirect doctest + Traceback (most recent call last): + ... +- AttributeError: 'sage.rings.integer.Integer' object has no attribute 'combinatorial_polyhedron' ++ AttributeError: 'sage.rings.integer.Integer' object has no attribute 'combinatorial_polyhedron'... + """ + cdef int i + sig_free(self.structure.atom_rep) +@@ -1945,7 +1945,8 @@ cdef inline int next_face_loop(iter_t structure) nogil except -1: + # The function is not supposed to be called, + # just prevent it from crashing. + # Actually raising an error here results in a bad branch prediction. +- return -1 ++ # But return -1 results in a crash with python 3.12 ++ raise StopIteration + + # Getting ``[faces, n_faces, n_visited_all]`` according to dimension. + cdef face_list_t* faces = &structure.new_faces[structure.current_dimension] +diff --git a/src/sage/geometry/toric_plotter.py b/src/sage/geometry/toric_plotter.py +index 50b4008eb0f..950e3ba7ff8 100644 +--- a/src/sage/geometry/toric_plotter.py ++++ b/src/sage/geometry/toric_plotter.py +@@ -706,7 +706,7 @@ def set_rays(self, generators): + sage: tp.plot_rays() # needs sage.plot + Traceback (most recent call last): + ... +- AttributeError: 'ToricPlotter' object has no attribute 'rays' ++ AttributeError: 'ToricPlotter' object has no attribute 'rays'... + sage: tp.set_rays([(0,1)]) + sage: tp.plot_rays() # needs sage.plot + Graphics object consisting of 2 graphics primitives +diff --git a/src/sage/groups/matrix_gps/finitely_generated.py b/src/sage/groups/matrix_gps/finitely_generated.py +index d0ec214bb3b..c8098ad578a 100644 +--- a/src/sage/groups/matrix_gps/finitely_generated.py ++++ b/src/sage/groups/matrix_gps/finitely_generated.py +@@ -268,7 +268,7 @@ def MatrixGroup(*gens, **kwds): + sage: SL2C.gens() + Traceback (most recent call last): + ... +- AttributeError: 'LinearMatrixGroup_generic_with_category' object has no attribute 'gens' ++ AttributeError: 'LinearMatrixGroup_generic_with_category' object has no attribute 'gens'... + """ + if isinstance(gens[-1], dict): # hack for unpickling + kwds.update(gens[-1]) +diff --git a/src/sage/homology/chains.py b/src/sage/homology/chains.py +index 87c0947c0b0..b9a54940943 100644 +--- a/src/sage/homology/chains.py ++++ b/src/sage/homology/chains.py +@@ -298,7 +298,7 @@ def is_cycle(self): + sage: chain.is_cocycle() + Traceback (most recent call last): + ... +- AttributeError: 'Chains_with_category.element_class' object has no attribute 'is_cocycle' ++ AttributeError: 'Chains_with_category.element_class' object has no attribute 'is_cocycle'... + """ + return self.to_complex().is_cycle() + +@@ -325,7 +325,7 @@ def is_boundary(self): + sage: chain.is_coboundary() + Traceback (most recent call last): + ... +- AttributeError: 'Chains_with_category.element_class' object has no attribute 'is_coboundary' ++ AttributeError: 'Chains_with_category.element_class' object has no attribute 'is_coboundary'... + """ + return self.to_complex().is_boundary() + +@@ -539,7 +539,7 @@ def is_cocycle(self): + sage: cochain.is_cycle() + Traceback (most recent call last): + ... +- AttributeError: 'Cochains_with_category.element_class' object has no attribute 'is_cycle' ++ AttributeError: 'Cochains_with_category.element_class' object has no attribute 'is_cycle'... + """ + return self.to_complex().is_cycle() + +@@ -566,7 +566,7 @@ def is_coboundary(self): + sage: cochain.is_boundary() + Traceback (most recent call last): + ... +- AttributeError: 'Cochains_with_category.element_class' object has no attribute 'is_boundary' ++ AttributeError: 'Cochains_with_category.element_class' object has no attribute 'is_boundary'... + """ + return self.to_complex().is_boundary() + +@@ -604,7 +604,7 @@ def eval(self, other): + sage: z.eval(c) # z is not a cochain + Traceback (most recent call last): + ... +- AttributeError: 'Chains_with_category.element_class' object has no attribute 'eval' ++ AttributeError: 'Chains_with_category.element_class' object has no attribute 'eval'... + sage: c.eval(c) # can't evaluate a cochain on a cochain + Traceback (most recent call last): + ... +diff --git a/src/sage/homology/free_resolution.py b/src/sage/homology/free_resolution.py +index e3d38de4240..280a479b438 100644 +--- a/src/sage/homology/free_resolution.py ++++ b/src/sage/homology/free_resolution.py +@@ -275,7 +275,7 @@ def differential(self, i): + sage: FreeResolution.differiental(r, 1) + Traceback (most recent call last): + ... +- AttributeError: type object 'FreeResolution' has no attribute 'differiental' ++ AttributeError: type object 'FreeResolution' has no attribute 'differiental'... + """ + + def target(self): +diff --git a/src/sage/interfaces/magma.py b/src/sage/interfaces/magma.py +index b7a0ac20d03..529bfbc349b 100644 +--- a/src/sage/interfaces/magma.py ++++ b/src/sage/interfaces/magma.py +@@ -824,7 +824,7 @@ def _coerce_from_special_method(self, x): + sage: magma._coerce_from_special_method('2 + 3') # optional - magma + Traceback (most recent call last): + ... +- AttributeError: 'str' object has no attribute '_magma_init_' ++ AttributeError: 'str' object has no attribute '_magma_init_'... + """ + s = x._magma_init_(self) + a = self(s) +diff --git a/src/sage/lfunctions/dokchitser.py b/src/sage/lfunctions/dokchitser.py +index 58499396d6c..16119d20815 100644 +--- a/src/sage/lfunctions/dokchitser.py ++++ b/src/sage/lfunctions/dokchitser.py +@@ -418,8 +418,8 @@ def init_coeffs(self, v, cutoff=1, + sage: L(14) + 0.998583063162746 + sage: a = delta_qexp(1000) +- sage: sum(a[n]/float(n)^14 for n in range(1,1000)) +- 0.9985830631627459 ++ sage: sum(a[n]/float(n)^14 for n in reversed(range(1,1000))) ++ 0.9985830631627461 + + Illustrate that one can give a list of complex numbers for v + (see :trac:`10937`):: +diff --git a/src/sage/lfunctions/pari.py b/src/sage/lfunctions/pari.py +index bbf289aa21c..e4968866303 100644 +--- a/src/sage/lfunctions/pari.py ++++ b/src/sage/lfunctions/pari.py +@@ -141,8 +141,8 @@ def init_coeffs(self, v, cutoff=None, w=1): + sage: L(14) + 0.998583063162746 + sage: a = delta_qexp(1000) +- sage: sum(a[n]/float(n)^14 for n in range(1,1000)) +- 0.9985830631627459 ++ sage: sum(a[n]/float(n)^14 for n in reversed(range(1,1000))) ++ 0.9985830631627461 + + Illustrate that one can give a list of complex numbers for v + (see :trac:`10937`):: +diff --git a/src/sage/libs/gap/element.pyx b/src/sage/libs/gap/element.pyx +index 478caf9f9d0..363024ae281 100644 +--- a/src/sage/libs/gap/element.pyx ++++ b/src/sage/libs/gap/element.pyx +@@ -380,7 +380,7 @@ cdef GapElement make_GapElement(parent, Obj obj): + sage: libgap(None) + Traceback (most recent call last): + ... +- AttributeError: 'NoneType' object has no attribute '_libgap_init_' ++ AttributeError: 'NoneType' object has no attribute '_libgap_init_'... + """ + cdef GapElement r = GapElement.__new__(GapElement) + r._initialize(parent, obj) +diff --git a/src/sage/libs/gmp/pylong.pxd b/src/sage/libs/gmp/pylong.pxd +index a73f1da6d6f..84e1bb8cd87 100644 +--- a/src/sage/libs/gmp/pylong.pxd ++++ b/src/sage/libs/gmp/pylong.pxd +@@ -2,9 +2,10 @@ + Various functions to deal with conversion mpz <-> Python int/long + """ + ++from cpython.longintrepr cimport py_long + from sage.libs.gmp.types cimport * + + cdef mpz_get_pylong(mpz_srcptr z) + cdef mpz_get_pyintlong(mpz_srcptr z) +-cdef int mpz_set_pylong(mpz_ptr z, L) except -1 ++cdef int mpz_set_pylong(mpz_ptr z, py_long L) except -1 + cdef Py_hash_t mpz_pythonhash(mpz_srcptr z) +diff --git a/src/sage/libs/gmp/pylong.pyx b/src/sage/libs/gmp/pylong.pyx +index d5993cca5a5..1a36c29d3fa 100644 +--- a/src/sage/libs/gmp/pylong.pyx ++++ b/src/sage/libs/gmp/pylong.pyx +@@ -28,6 +28,8 @@ AUTHORS: + from cpython.object cimport Py_SIZE + from cpython.long cimport PyLong_FromLong + from cpython.longintrepr cimport _PyLong_New, py_long, digit, PyLong_SHIFT ++from sage.cpython.pycore_long cimport (ob_digit, _PyLong_IsNegative, ++ _PyLong_DigitCount, _PyLong_SetSignAndDigitCount) + from .mpz cimport * + + cdef extern from *: +@@ -60,12 +62,9 @@ cdef mpz_get_pylong_large(mpz_srcptr z): + """ + cdef size_t nbits = mpz_sizeinbase(z, 2) + cdef size_t pylong_size = (nbits + PyLong_SHIFT - 1) // PyLong_SHIFT +- L = _PyLong_New(pylong_size) +- mpz_export(L.ob_digit, NULL, +- -1, sizeof(digit), 0, PyLong_nails, z) +- if mpz_sgn(z) < 0: +- # Set correct size +- Py_SET_SIZE(L, -pylong_size) ++ cdef py_long L = _PyLong_New(pylong_size) ++ mpz_export(ob_digit(L), NULL, -1, sizeof(digit), 0, PyLong_nails, z) ++ _PyLong_SetSignAndDigitCount(L, mpz_sgn(z), pylong_size) + return L + + +@@ -88,16 +87,13 @@ cdef mpz_get_pyintlong(mpz_srcptr z): + return mpz_get_pylong_large(z) + + +-cdef int mpz_set_pylong(mpz_ptr z, L) except -1: ++cdef int mpz_set_pylong(mpz_ptr z, py_long L) except -1: + """ + Convert a Python ``long`` `L` to an ``mpz``. + """ +- cdef Py_ssize_t pylong_size = Py_SIZE(L) +- if pylong_size < 0: +- pylong_size = -pylong_size +- mpz_import(z, pylong_size, -1, sizeof(digit), 0, PyLong_nails, +- (L).ob_digit) +- if Py_SIZE(L) < 0: ++ cdef Py_ssize_t pylong_size = _PyLong_DigitCount(L) ++ mpz_import(z, pylong_size, -1, sizeof(digit), 0, PyLong_nails, ob_digit(L)) ++ if _PyLong_IsNegative(L): + mpz_neg(z, z) + + +diff --git a/src/sage/manifolds/calculus_method.py b/src/sage/manifolds/calculus_method.py +index f5830c0bc45..303dde6cd13 100644 +--- a/src/sage/manifolds/calculus_method.py ++++ b/src/sage/manifolds/calculus_method.py +@@ -257,7 +257,7 @@ def simplify(self, expression, method=None): + sage: cm.simplify(f) + Traceback (most recent call last): + ... +- AttributeError: 'sage.symbolic.expression.Expression' object has no attribute 'combsimp' ++ AttributeError: 'sage.symbolic.expression.Expression' object has no attribute 'combsimp'... + + In the present case, one should either transform ``f`` to a SymPy + object:: +diff --git a/src/sage/manifolds/differentiable/vectorfield_module.py b/src/sage/manifolds/differentiable/vectorfield_module.py +index d954b5d4839..af4bfb0ceec 100644 +--- a/src/sage/manifolds/differentiable/vectorfield_module.py ++++ b/src/sage/manifolds/differentiable/vectorfield_module.py +@@ -885,7 +885,7 @@ def tensor(self, *args, **kwds): + sage: XM.tensor(XM).tensor(XM.dual().tensor(XM.dual())) + Traceback (most recent call last): + ... +- AttributeError: 'TensorFieldModule_with_category' object has no attribute '_basis_sym' ++ AttributeError: 'TensorFieldModule_with_category' object has no attribute '_basis_sym'... + + .. SEEALSO:: + +diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx +index 86aca6e00d8..a5f6716e731 100644 +--- a/src/sage/matrix/matrix2.pyx ++++ b/src/sage/matrix/matrix2.pyx +@@ -15303,7 +15303,7 @@ cdef class Matrix(Matrix1): + Traceback (most recent call last): + ... + AttributeError: 'sage.rings.finite_rings.integer_mod.IntegerMod_int' object +- has no attribute 'conjugate' ++ has no attribute 'conjugate'... + """ + # limited testing on a 1000 x 1000 matrix over CC: + # transpose is fast, conjugate is slow +diff --git a/src/sage/matrix/matrix_cyclo_dense.pyx b/src/sage/matrix/matrix_cyclo_dense.pyx +index f54f3423ded..a49bb6240e6 100644 +--- a/src/sage/matrix/matrix_cyclo_dense.pyx ++++ b/src/sage/matrix/matrix_cyclo_dense.pyx +@@ -847,7 +847,7 @@ cdef class Matrix_cyclo_dense(Matrix_dense): + sage: A.set_mutable() + Traceback (most recent call last): + ... +- AttributeError: 'sage.matrix.matrix_cyclo_dense.Matrix_cyclo_dense' object has no attribute 'set_mutable' ++ AttributeError: 'sage.matrix.matrix_cyclo_dense.Matrix_cyclo_dense' object has no attribute 'set_mutable'... + sage: B = A.__copy__() + sage: B[0,0] = 20 + sage: B[0,0] +diff --git a/src/sage/matrix/matrix_gfpn_dense.pyx b/src/sage/matrix/matrix_gfpn_dense.pyx +index 4cccf473de1..8e8e4d7336b 100644 +--- a/src/sage/matrix/matrix_gfpn_dense.pyx ++++ b/src/sage/matrix/matrix_gfpn_dense.pyx +@@ -159,7 +159,7 @@ cdef class FieldConverter_class: + sage: C.field_to_fel('foo') + Traceback (most recent call last): + ... +- AttributeError: 'str' object has no attribute 'to_integer' ++ AttributeError: 'str' object has no attribute 'to_integer'... + """ + return FfFromInt(x.to_integer()) + +diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py +index 6aab58352be..b5e6f52349b 100644 +--- a/src/sage/matrix/matrix_space.py ++++ b/src/sage/matrix/matrix_space.py +@@ -1619,7 +1619,7 @@ def __getitem__(self, x): + sage: MS[2] + Traceback (most recent call last): + ... +- AttributeError: 'MatrixSpace_with_category' object has no attribute 'list' ++ AttributeError: 'MatrixSpace_with_category' object has no attribute 'list'... + """ + if isinstance(x, (integer.Integer, int)): + return self.list()[x] +diff --git a/src/sage/matroids/lean_matrix.pyx b/src/sage/matroids/lean_matrix.pyx +index 54c68e637c0..a137cbf70e5 100644 +--- a/src/sage/matroids/lean_matrix.pyx ++++ b/src/sage/matroids/lean_matrix.pyx +@@ -1,5 +1,4 @@ + # sage.doctest: optional - sage.rings.finite_rings +-# cython: profile=True + """ + Lean matrices + +diff --git a/src/sage/matroids/linear_matroid.pyx b/src/sage/matroids/linear_matroid.pyx +index 36f563aa433..318c82f2b64 100644 +--- a/src/sage/matroids/linear_matroid.pyx ++++ b/src/sage/matroids/linear_matroid.pyx +@@ -1134,7 +1134,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): + Traceback (most recent call last): + ... + AttributeError: 'sage.matroids.basis_matroid.BasisMatroid' object +- has no attribute 'base_ring' ++ has no attribute 'base_ring'... + sage: from sage.matroids.advanced import * + sage: M4 = BinaryMatroid(Matrix(M1)) + sage: M5 = LinearMatroid(reduced_matrix=Matrix(GF(2), [[-1, 0, 1], +diff --git a/src/sage/misc/dev_tools.py b/src/sage/misc/dev_tools.py +index e7bf176592c..3ece7db2894 100644 +--- a/src/sage/misc/dev_tools.py ++++ b/src/sage/misc/dev_tools.py +@@ -171,6 +171,7 @@ def load_submodules(module=None, exclude_pattern=None): + load sage.geometry.polyhedron.ppl_lattice_polygon... succeeded + """ + from .package_dir import walk_packages ++ import importlib.util + + if module is None: + import sage +@@ -194,8 +195,12 @@ def load_submodules(module=None, exclude_pattern=None): + try: + sys.stdout.write("load %s..." % module_name) + sys.stdout.flush() +- loader = importer.find_module(module_name) +- loader.load_module(module_name) ++ # see ++ # https://docs.python.org/3/library/importlib.html#importing-a-source-file-directly ++ spec = importer.find_spec(module_name) ++ module = importlib.util.module_from_spec(spec) ++ sys.modules[module_name] = module ++ spec.loader.exec_module(module) + sys.stdout.write(" succeeded\n") + except (ValueError, AttributeError, TypeError, ImportError): + # we might get error because of cython code that has been +diff --git a/src/sage/misc/functional.py b/src/sage/misc/functional.py +index c922b8f6f12..03697f08b7c 100644 +--- a/src/sage/misc/functional.py ++++ b/src/sage/misc/functional.py +@@ -86,7 +86,7 @@ def base_field(x): + sage: R.base_field() + Traceback (most recent call last): + ... +- AttributeError: 'PolynomialRing_dense_mod_p_with_category' object has no attribute 'base_field' ++ AttributeError: 'PolynomialRing_dense_mod_p_with_category' object has no attribute 'base_field'... + """ + try: + return x.base_field() +diff --git a/src/sage/misc/instancedoc.pyx b/src/sage/misc/instancedoc.pyx +index d8e1e4ac536..44ee70f64ba 100644 +--- a/src/sage/misc/instancedoc.pyx ++++ b/src/sage/misc/instancedoc.pyx +@@ -256,7 +256,7 @@ cdef class InstanceDocDescriptor: + sage: descr.__delete__(obj) + Traceback (most recent call last): + ... +- AttributeError: 'X' object has no attribute '__doc__' ++ AttributeError: 'X' object has no attribute '__doc__'... + + sage: descr.__delete__([]) + Traceback (most recent call last): +diff --git a/src/sage/misc/lazy_attribute.pyx b/src/sage/misc/lazy_attribute.pyx +index bdbec3b3ba1..1f07870b8ec 100644 +--- a/src/sage/misc/lazy_attribute.pyx ++++ b/src/sage/misc/lazy_attribute.pyx +@@ -441,37 +441,37 @@ class lazy_attribute(_lazy_attribute): + sage: B().unimplemented_A # todo: not implemented + Traceback (most recent call last): + ... +- AttributeError: 'super' object has no attribute 'unimplemented_A' ++ AttributeError: 'super' object has no attribute 'unimplemented_A'... + + We now make some systematic checks:: + + sage: B().unimplemented_A + Traceback (most recent call last): + ... +- AttributeError: '...' object has no attribute 'unimplemented_A' ++ AttributeError: '...' object has no attribute 'unimplemented_A'... + sage: B().unimplemented_B + Traceback (most recent call last): + ... +- AttributeError: '...' object has no attribute 'unimplemented_B' ++ AttributeError: '...' object has no attribute 'unimplemented_B'... + sage: B().unimplemented_AB + Traceback (most recent call last): + ... +- AttributeError: '...' object has no attribute 'unimplemented_AB' ++ AttributeError: '...' object has no attribute 'unimplemented_AB'... + sage: B().unimplemented_B_implemented_A + 1 + + sage: C().unimplemented_A() + Traceback (most recent call last): + ... +- AttributeError: '...' object has no attribute 'unimplemented_A' ++ AttributeError: '...' object has no attribute 'unimplemented_A'... + sage: C().unimplemented_B() + Traceback (most recent call last): + ... +- AttributeError: '...' object has no attribute 'unimplemented_B' ++ AttributeError: '...' object has no attribute 'unimplemented_B'... + sage: C().unimplemented_AB() + Traceback (most recent call last): + ... +- AttributeError: '...' object has no attribute 'unimplemented_AB' ++ AttributeError: '...' object has no attribute 'unimplemented_AB'... + sage: C().unimplemented_B_implemented_A # todo: not implemented + 1 + """ +diff --git a/src/sage/misc/object_multiplexer.py b/src/sage/misc/object_multiplexer.py +index d4e811ef16e..00fd89d6652 100644 +--- a/src/sage/misc/object_multiplexer.py ++++ b/src/sage/misc/object_multiplexer.py +@@ -85,7 +85,7 @@ def __getattr__(self, name): + sage: m.__bork__ + Traceback (most recent call last): + ... +- AttributeError: 'Multiplex' has no attribute '__bork__' ++ AttributeError: 'Multiplex' has no attribute '__bork__'... + """ + if name.startswith("__"): + raise AttributeError("'Multiplex' has no attribute '%s'" % name) +diff --git a/src/sage/misc/sage_input.py b/src/sage/misc/sage_input.py +index 66e78ecccbc..00e8d96ee9e 100644 +--- a/src/sage/misc/sage_input.py ++++ b/src/sage/misc/sage_input.py +@@ -3461,7 +3461,7 @@ def verify_same(a, b): + sage: verify_same(1, 1r) + Traceback (most recent call last): + ... +- AttributeError: 'int' object has no attribute 'parent' ++ AttributeError: 'int' object has no attribute 'parent'... + sage: verify_same(1r, 1) + Traceback (most recent call last): + ... +@@ -3525,7 +3525,7 @@ def verify_si_answer(x, answer, preparse): + sage: verify_si_answer(1, '1', False) + Traceback (most recent call last): + ... +- AttributeError: 'int' object has no attribute 'parent' ++ AttributeError: 'int' object has no attribute 'parent'... + sage: verify_si_answer(1, 'ZZ(1)', None) + """ + from sage.misc.sage_eval import sage_eval +diff --git a/src/sage/misc/sageinspect.py b/src/sage/misc/sageinspect.py +index f0545be7d81..811afc48755 100644 +--- a/src/sage/misc/sageinspect.py ++++ b/src/sage/misc/sageinspect.py +@@ -602,7 +602,7 @@ def visit_Num(self, node): + On Python 3 negative numbers are parsed first, for some reason, as + a UnaryOp node. + """ +- return node.n ++ return node.value + + def visit_Str(self, node): + r""" +@@ -624,7 +624,7 @@ def visit_Str(self, node): + sage: [vis(s) for s in ['"abstract"', "'syntax'", r'''r"tr\ee"''']] + ['abstract', 'syntax', 'tr\\ee'] + """ +- return node.s ++ return node.value + + def visit_List(self, node): + """ +diff --git a/src/sage/modules/fp_graded/steenrod/module.py b/src/sage/modules/fp_graded/steenrod/module.py +index 18460b0e9a1..4acfa6b4002 100755 +--- a/src/sage/modules/fp_graded/steenrod/module.py ++++ b/src/sage/modules/fp_graded/steenrod/module.py +@@ -70,7 +70,7 @@ + sage: SteenrodFPModule(ZZ, [0]) + Traceback (most recent call last): + ... +- AttributeError: 'sage.rings.integer_ring.IntegerRing_class' object has no attribute 'free_graded_module' ++ AttributeError: 'sage.rings.integer_ring.IntegerRing_class' object has no attribute 'free_graded_module'... + + AUTHORS: + +diff --git a/src/sage/monoids/trace_monoid.py b/src/sage/monoids/trace_monoid.py +index 00baa4d14f8..f8176a1e1f2 100644 +--- a/src/sage/monoids/trace_monoid.py ++++ b/src/sage/monoids/trace_monoid.py +@@ -40,7 +40,6 @@ + # https://www.gnu.org/licenses/ + # **************************************************************************** + +-from collections import OrderedDict + from itertools import repeat, chain, product + + from sage.misc.cachefunc import cached_method +@@ -633,14 +632,14 @@ def _compute_dependence_stack(self, x): + sage: x = b*a*d*a*c*b + sage: M._compute_dependence_stack(x) + ({a, b, c, d}, +- OrderedDict([(a, [False, False, True, True, False]), +- (b, [True, False, False, False, True]), +- (c, [True, False, False, False]), +- (d, [False, False, True, False])])) ++ {a: [False, False, True, True, False], ++ b: [True, False, False, False, True], ++ c: [True, False, False, False], ++ d: [False, False, True, False]}) + """ + independence = self._independence + generators_set = set(e for e, _ in x) +- stacks = OrderedDict(sorted((g, []) for g in generators_set)) ++ stacks = dict(sorted((g, []) for g in generators_set)) + for generator, times in reversed(list(x)): + stacks[generator].extend(repeat(True, times)) + for other_gen in generators_set: +diff --git a/src/sage/parallel/map_reduce.py b/src/sage/parallel/map_reduce.py +index 11e0673ee91..5441943731d 100644 +--- a/src/sage/parallel/map_reduce.py ++++ b/src/sage/parallel/map_reduce.py +@@ -1234,7 +1234,7 @@ def finish(self): + sage: S.print_communication_statistics() + Traceback (most recent call last): + ... +- AttributeError: 'RESetMPExample' object has no attribute '_stats' ++ AttributeError: 'RESetMPExample' object has no attribute '_stats'... + + sage: S.finish() + +diff --git a/src/sage/plot/colors.py b/src/sage/plot/colors.py +index 8c0db2b3c34..3281199400b 100644 +--- a/src/sage/plot/colors.py ++++ b/src/sage/plot/colors.py +@@ -1099,7 +1099,7 @@ def __getattr__(self, name): + sage: cols.punk + Traceback (most recent call last): + ... +- AttributeError: 'ColorsDict' has no attribute or colormap punk ++ AttributeError: 'ColorsDict' has no attribute or colormap punk... + """ + try: + return self[name] +@@ -1599,7 +1599,7 @@ def __getattr__(self, name): + sage: maps.punk + Traceback (most recent call last): + ... +- AttributeError: 'Colormaps' has no attribute or colormap punk ++ AttributeError: 'Colormaps' has no attribute or colormap punk... + sage: maps['punk'] + Traceback (most recent call last): + ... +diff --git a/src/sage/rings/asymptotic/asymptotic_ring.py b/src/sage/rings/asymptotic/asymptotic_ring.py +index b07319382d3..994490e6616 100644 +--- a/src/sage/rings/asymptotic/asymptotic_ring.py ++++ b/src/sage/rings/asymptotic/asymptotic_ring.py +@@ -1091,7 +1091,7 @@ def monomial_coefficient(self, monomial): + sage: O(n).monomial_coefficient(n) + Traceback (most recent call last): + ... +- AttributeError: 'OTermMonoid_with_category.element_class' object has no attribute 'coefficient' ++ AttributeError: 'OTermMonoid_with_category.element_class' object has no attribute 'coefficient'... + + The ``monomial`` must be exact:: + +diff --git a/src/sage/rings/asymptotic/growth_group.py b/src/sage/rings/asymptotic/growth_group.py +index 27c14592bca..5be12537d62 100644 +--- a/src/sage/rings/asymptotic/growth_group.py ++++ b/src/sage/rings/asymptotic/growth_group.py +@@ -1572,7 +1572,7 @@ def variable_names(self): + Traceback (most recent call last): + ... + AttributeError: 'GenericGrowthGroup_with_category.element_class' object +- has no attribute 'is_one' ++ has no attribute 'is_one'... + """ + if self.is_one(): + return tuple() +diff --git a/src/sage/rings/ideal.py b/src/sage/rings/ideal.py +index d36d9406f32..01c9fa3bf2d 100644 +--- a/src/sage/rings/ideal.py ++++ b/src/sage/rings/ideal.py +@@ -1553,7 +1553,7 @@ def gcd(self, other): + sage: J.gcd(I) + Traceback (most recent call last): + ... +- AttributeError: 'Ideal_generic' object has no attribute 'gcd' ++ AttributeError: 'Ideal_generic' object has no attribute 'gcd'... + + Note:: + +diff --git a/src/sage/rings/number_field/number_field.py b/src/sage/rings/number_field/number_field.py +index 7fe89197011..8832d27e8ea 100644 +--- a/src/sage/rings/number_field/number_field.py ++++ b/src/sage/rings/number_field/number_field.py +@@ -3823,7 +3823,7 @@ def primes_above(self, x, degree=None): + sage: F.prime_above(0) + Traceback (most recent call last): + ... +- AttributeError: 'NumberFieldIdeal' object has no attribute 'prime_factors' ++ AttributeError: 'NumberFieldIdeal' object has no attribute 'prime_factors'... + """ + if degree is not None: + degree = ZZ(degree) +@@ -3917,7 +3917,7 @@ def prime_above(self, x, degree=None): + sage: F.prime_above(0) + Traceback (most recent call last): + ... +- AttributeError: 'NumberFieldIdeal' object has no attribute 'prime_factors' ++ AttributeError: 'NumberFieldIdeal' object has no attribute 'prime_factors'... + + """ + ids = self.primes_above(x, degree) +@@ -5926,7 +5926,7 @@ def factor(self, n): + sage: L.factor(0) + Traceback (most recent call last): + ... +- AttributeError: 'NumberFieldIdeal' object has no attribute 'factor' ++ AttributeError: 'NumberFieldIdeal' object has no attribute 'factor'... + + AUTHORS: + +@@ -12698,7 +12698,7 @@ def is_real_place(v): + sage: is_real_place(v_fin) + Traceback (most recent call last): + ... +- AttributeError: 'NumberFieldFractionalIdeal' object has no attribute 'im_gens' ++ AttributeError: 'NumberFieldFractionalIdeal' object has no attribute 'im_gens'... + + """ + RR = sage.rings.real_mpfr.RealField(53) +diff --git a/src/sage/rings/padics/generic_nodes.py b/src/sage/rings/padics/generic_nodes.py +index 7047020edec..b6b514d4005 100644 +--- a/src/sage/rings/padics/generic_nodes.py ++++ b/src/sage/rings/padics/generic_nodes.py +@@ -740,7 +740,7 @@ def _get_element_class(self, name=None): + sage: R._get_element_class("foobar") + Traceback (most recent call last): + ... +- AttributeError: module 'sage.rings.padics.padic_relaxed_element' has no attribute 'pAdicRelaxedElement_foobar' ++ AttributeError: module 'sage.rings.padics.padic_relaxed_element' has no attribute 'pAdicRelaxedElement_foobar'... + """ + if name is None: + return self.Element +diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx +index c5a1129aecf..a5b7f937cfe 100644 +--- a/src/sage/rings/polynomial/polynomial_element.pyx ++++ b/src/sage/rings/polynomial/polynomial_element.pyx +@@ -10793,7 +10793,7 @@ cdef class Polynomial(CommutativePolynomial): + sage: (y**2 + x).nth_root(2) + Traceback (most recent call last): + ... +- AttributeError: ... has no attribute 'nth_root' ++ AttributeError: ... has no attribute 'nth_root'... + + TESTS:: + +@@ -11831,7 +11831,7 @@ cdef class Polynomial_generic_dense(Polynomial): + sage: int(1) // x # check that this doesn't segfault + Traceback (most recent call last): + ... +- AttributeError: type object 'int' has no attribute 'base_ring' ++ AttributeError: type object 'int' has no attribute 'base_ring'... + """ + if have_same_parent(self, right): + return (self)._floordiv_(right) +diff --git a/src/sage/rings/polynomial/polynomial_quotient_ring.py b/src/sage/rings/polynomial/polynomial_quotient_ring.py +index e372be888ee..aca4f08420f 100644 +--- a/src/sage/rings/polynomial/polynomial_quotient_ring.py ++++ b/src/sage/rings/polynomial/polynomial_quotient_ring.py +@@ -2362,7 +2362,7 @@ def field_extension(self, names): + sage: F, g, h = S.field_extension('b') # needs sage.rings.finite_rings + Traceback (most recent call last): + ... +- AttributeError: 'PolynomialQuotientRing_generic_with_category' object has no attribute 'field_extension' ++ AttributeError: 'PolynomialQuotientRing_generic_with_category' object has no attribute 'field_extension'... + + Over a finite field, the corresponding field extension is not a + number field:: +diff --git a/src/sage/rings/ring.pyx b/src/sage/rings/ring.pyx +index 5273891a5b0..a6e999b8805 100644 +--- a/src/sage/rings/ring.pyx ++++ b/src/sage/rings/ring.pyx +@@ -1734,7 +1734,7 @@ cdef class IntegralDomain(CommutativeRing): + sage: Z5.is_integrally_closed() + Traceback (most recent call last): + ... +- AttributeError: 'IntegerModRing_generic_with_category' object has no attribute 'is_integrally_closed' ++ AttributeError: 'IntegerModRing_generic_with_category' object has no attribute 'is_integrally_closed'... + """ + raise NotImplementedError + +diff --git a/src/sage/sat/solvers/satsolver.pyx b/src/sage/sat/solvers/satsolver.pyx +index c2f41b18f55..1c4ac400cb6 100644 +--- a/src/sage/sat/solvers/satsolver.pyx ++++ b/src/sage/sat/solvers/satsolver.pyx +@@ -375,10 +375,10 @@ def SAT(solver=None, *args, **kwds): + DIMACS Solver: 'kissat -q {input}' + """ + if solver is None: +- import pkgutil +- if pkgutil.find_loader('pycryptosat') is not None: ++ from importlib.util import find_spec ++ if find_spec('pycryptosat') is not None: + solver = "cryptominisat" +- elif pkgutil.find_loader('pycosat') is not None: ++ elif find_spec('pycosat') is not None: + solver = "picosat" + else: + solver = "LP" +diff --git a/src/sage/schemes/toric/morphism.py b/src/sage/schemes/toric/morphism.py +index 1c8944b6dfc..5d64d632f97 100644 +--- a/src/sage/schemes/toric/morphism.py ++++ b/src/sage/schemes/toric/morphism.py +@@ -246,7 +246,7 @@ + Traceback (most recent call last): + ... + AttributeError: 'SchemeMorphism_fan_toric_variety' object +- has no attribute 'fiber_generic' ++ has no attribute 'fiber_generic'... + + Let's use factorization mentioned above:: + +diff --git a/src/sage/sets/disjoint_union_enumerated_sets.py b/src/sage/sets/disjoint_union_enumerated_sets.py +index 3dea567a779..5c5e08612f2 100644 +--- a/src/sage/sets/disjoint_union_enumerated_sets.py ++++ b/src/sage/sets/disjoint_union_enumerated_sets.py +@@ -597,7 +597,7 @@ def Element(self): + sage: U.Element + Traceback (most recent call last): + ... +- AttributeError: 'DisjointUnionEnumeratedSets_with_category' object has no attribute 'Element' ++ AttributeError: 'DisjointUnionEnumeratedSets_with_category' object has no attribute 'Element'... + """ + if not self._facade: + return ElementWrapper +diff --git a/src/sage/sets/set.py b/src/sage/sets/set.py +index a1789c61300..112d3d8dc3b 100644 +--- a/src/sage/sets/set.py ++++ b/src/sage/sets/set.py +@@ -163,7 +163,7 @@ def Set(X=None, category=None): + sage: sorted(B.list(), key=repr) + Traceback (most recent call last): + ... +- AttributeError: 'Set_object_with_category' object has no attribute 'list' ++ AttributeError: 'Set_object_with_category' object has no attribute 'list'... + sage: type(B) + + +diff --git a/src/sage/structure/category_object.pyx b/src/sage/structure/category_object.pyx +index b6a7eaecb5b..c06933494dc 100644 +--- a/src/sage/structure/category_object.pyx ++++ b/src/sage/structure/category_object.pyx +@@ -836,7 +836,7 @@ cdef class CategoryObject(SageObject): + sage: Sets().example().sadfasdf + Traceback (most recent call last): + ... +- AttributeError: 'PrimeNumbers_with_category' object has no attribute 'sadfasdf' ++ AttributeError: 'PrimeNumbers_with_category' object has no attribute 'sadfasdf'... + """ + return self.getattr_from_category(name) + +diff --git a/src/sage/structure/element.pyx b/src/sage/structure/element.pyx +index caae7e40ffc..543506e9a74 100644 +--- a/src/sage/structure/element.pyx ++++ b/src/sage/structure/element.pyx +@@ -219,7 +219,7 @@ the parents:: + sage: x._add_(x) + Traceback (most recent call last): + ... +- AttributeError: 'sage.structure.element.Element' object has no attribute '_add_' ++ AttributeError: 'sage.structure.element.Element' object has no attribute '_add_'... + sage: x + x + Traceback (most recent call last): + ... +@@ -478,13 +478,13 @@ cdef class Element(SageObject): + sage: 1.blah_blah + Traceback (most recent call last): + ... +- AttributeError: 'sage.rings.integer.Integer' object has no attribute 'blah_blah' ++ AttributeError: 'sage.rings.integer.Integer' object has no attribute 'blah_blah'... + sage: Semigroups().example().an_element().is_idempotent + + sage: Semigroups().example().an_element().blah_blah + Traceback (most recent call last): + ... +- AttributeError: 'LeftZeroSemigroup_with_category.element_class' object has no attribute 'blah_blah' ++ AttributeError: 'LeftZeroSemigroup_with_category.element_class' object has no attribute 'blah_blah'... + """ + return self.getattr_from_category(name) + +@@ -1269,7 +1269,7 @@ cdef class Element(SageObject): + sage: e._add_(e) + Traceback (most recent call last): + ... +- AttributeError: 'sage.structure.element.Element' object has no attribute '_add_' ++ AttributeError: 'sage.structure.element.Element' object has no attribute '_add_'... + """ + try: + python_op = (self)._add_ +@@ -1381,7 +1381,7 @@ cdef class Element(SageObject): + sage: e._sub_(e) + Traceback (most recent call last): + ... +- AttributeError: 'sage.structure.element.Element' object has no attribute '_sub_' ++ AttributeError: 'sage.structure.element.Element' object has no attribute '_sub_'... + """ + try: + python_op = (self)._sub_ +@@ -1435,7 +1435,7 @@ cdef class Element(SageObject): + sage: e._neg_() + Traceback (most recent call last): + ... +- AttributeError: 'sage.structure.element.Element' object has no attribute '_neg_' ++ AttributeError: 'sage.structure.element.Element' object has no attribute '_neg_'... + """ + try: + python_op = (self)._neg_ +@@ -1549,7 +1549,7 @@ cdef class Element(SageObject): + sage: e._mul_(e) + Traceback (most recent call last): + ... +- AttributeError: 'sage.structure.element.Element' object has no attribute '_mul_' ++ AttributeError: 'sage.structure.element.Element' object has no attribute '_mul_'... + """ + try: + python_op = (self)._mul_ +@@ -1662,7 +1662,7 @@ cdef class Element(SageObject): + sage: e._matmul_(e) + Traceback (most recent call last): + ... +- AttributeError: 'sage.structure.element.Element' object has no attribute '_matmul_' ++ AttributeError: 'sage.structure.element.Element' object has no attribute '_matmul_'... + """ + try: + python_op = (self)._matmul_ +@@ -1765,7 +1765,7 @@ cdef class Element(SageObject): + sage: e._div_(e) + Traceback (most recent call last): + ... +- AttributeError: 'sage.structure.element.Element' object has no attribute '_div_' ++ AttributeError: 'sage.structure.element.Element' object has no attribute '_div_'... + """ + try: + python_op = (self)._div_ +@@ -1865,7 +1865,7 @@ cdef class Element(SageObject): + sage: e._floordiv_(e) + Traceback (most recent call last): + ... +- AttributeError: 'sage.structure.element.Element' object has no attribute '_floordiv_' ++ AttributeError: 'sage.structure.element.Element' object has no attribute '_floordiv_'... + """ + try: + python_op = (self)._floordiv_ +@@ -1965,7 +1965,7 @@ cdef class Element(SageObject): + sage: e._mod_(e) + Traceback (most recent call last): + ... +- AttributeError: 'sage.structure.element.Element' object has no attribute '_mod_' ++ AttributeError: 'sage.structure.element.Element' object has no attribute '_mod_'... + """ + try: + python_op = (self)._mod_ +@@ -2092,7 +2092,7 @@ cdef class Element(SageObject): + sage: e._pow_(e) + Traceback (most recent call last): + ... +- AttributeError: 'sage.structure.element.Element' object has no attribute '_pow_' ++ AttributeError: 'sage.structure.element.Element' object has no attribute '_pow_'... + """ + try: + python_op = (self)._pow_ +@@ -2122,7 +2122,7 @@ cdef class Element(SageObject): + sage: e._pow_int(e) + Traceback (most recent call last): + ... +- AttributeError: 'sage.structure.element.Element' object has no attribute '_pow_int' ++ AttributeError: 'sage.structure.element.Element' object has no attribute '_pow_int'... + """ + try: + python_op = (self)._pow_int +@@ -2856,7 +2856,7 @@ cdef class RingElement(ModuleElement): + sage: m.is_nilpotent() # needs sage.modules + Traceback (most recent call last): + ... +- AttributeError: ... object has no attribute 'is_nilpotent' ++ AttributeError: '...' object has no attribute 'is_nilpotent'... + """ + if self.is_unit(): + return False +@@ -4671,7 +4671,7 @@ def coerce_binop(method): + sage: x.test_add(CC(2)) + Traceback (most recent call last): + ... +- AttributeError: 'sage.rings.complex_mpfr.ComplexNumber' object has no attribute 'test_add' ++ AttributeError: 'sage.rings.complex_mpfr.ComplexNumber' object has no attribute 'test_add'... + + TESTS: + +diff --git a/src/sage/structure/sequence.py b/src/sage/structure/sequence.py +index 0c700c1fb81..c3972532ac3 100644 +--- a/src/sage/structure/sequence.py ++++ b/src/sage/structure/sequence.py +@@ -854,7 +854,7 @@ def __getattr__(self, name): + sage: S.universe() + Traceback (most recent call last): + ... +- AttributeError: 'Sequence_generic' object has no attribute '_Sequence_generic__universe' ++ AttributeError: 'Sequence_generic' object has no attribute '_Sequence_generic__universe'... + sage: S._Sequence__universe = 'foobar' + sage: S.universe() + 'foobar' +@@ -867,7 +867,7 @@ def __getattr__(self, name): + sage: hash(S) + Traceback (most recent call last): + ... +- AttributeError: 'Sequence_generic' object has no attribute '_Sequence_generic__hash' ++ AttributeError: 'Sequence_generic' object has no attribute '_Sequence_generic__hash'... + sage: S._Sequence__hash = int(34) + sage: hash(S) + 34 +diff --git a/src/sage/symbolic/assumptions.py b/src/sage/symbolic/assumptions.py +index 7dcb15f0d85..15f6fa07ce6 100644 +--- a/src/sage/symbolic/assumptions.py ++++ b/src/sage/symbolic/assumptions.py +@@ -636,7 +636,7 @@ def assume(*args): + Traceback (most recent call last): + ... + AttributeError: 'sage.rings.integer.Integer' object has no +- attribute 'assume' ++ attribute 'assume'... + + Ensure that we can combine the two types of assumptions, as documented:: + +diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx +index 0f251ac4e5c..66f624141b3 100644 +--- a/src/sage/symbolic/expression.pyx ++++ b/src/sage/symbolic/expression.pyx +@@ -13712,7 +13712,7 @@ cdef get_dynamic_class_for_function(unsigned serial): + Traceback (most recent call last): + ... + AttributeError: 'sage.symbolic.expression.Expression' object has no +- attribute 'argp1' ++ attribute 'argp1'... + sage: t = (e + 1).op[0]; t + tfunc(x) + sage: t +diff --git a/src/sage/symbolic/ginac/numeric.cpp b/src/sage/symbolic/ginac/numeric.cpp +index c4152e092e3..4bcf45e8793 100644 +--- a/src/sage/symbolic/ginac/numeric.cpp ++++ b/src/sage/symbolic/ginac/numeric.cpp +@@ -67,6 +67,7 @@ + #include "archive.h" + #include "tostring.h" + #include "utils.h" ++#include "../../cpython/pycore_long.h" + + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wdeprecated-register" +@@ -706,18 +707,12 @@ static long _mpq_pythonhash(mpq_t the_rat) + // Initialize an mpz_t from a Python long integer + static void _mpz_set_pylong(mpz_t z, PyLongObject* l) + { +- Py_ssize_t pylong_size = Py_SIZE(l); +- int sign = 1; +- +- if (pylong_size < 0) { +- pylong_size = -pylong_size; +- sign = -1; +- } ++ Py_ssize_t pylong_size = _PyLong_DigitCount(l); + + mpz_import(z, pylong_size, -1, sizeof(digit), 0, +- 8*sizeof(digit) - PyLong_SHIFT, l->ob_digit); ++ 8*sizeof(digit) - PyLong_SHIFT, ob_digit(l)); + +- if (sign < 0) ++ if (_PyLong_IsNegative(l)) + mpz_neg(z, z); + } + +diff --git a/src/sage/symbolic/pynac_impl.pxi b/src/sage/symbolic/pynac_impl.pxi +index 68c31dcfde7..7fd7c3b314b 100644 +--- a/src/sage/symbolic/pynac_impl.pxi ++++ b/src/sage/symbolic/pynac_impl.pxi +@@ -619,7 +619,7 @@ def tolerant_is_symbol(a): + sage: None.is_symbol() + Traceback (most recent call last): + ... +- AttributeError: 'NoneType' object has no attribute 'is_symbol' ++ AttributeError: 'NoneType' object has no attribute 'is_symbol'... + """ + try: + return a.is_symbol() diff --git a/srcpkgs/sagemath/patches/get_patches b/srcpkgs/sagemath/patches/get_patches index 836d5bf7098..95a69634329 100755 --- a/srcpkgs/sagemath/patches/get_patches +++ b/srcpkgs/sagemath/patches/get_patches @@ -33,5 +33,11 @@ get_pr 36006 "gmp 6.3.0" # merged in 10.2.beta3 get_pr 36235 "ecl 23.9.9" -# positive review +# merged in 10.2.beta4 get_pr 36279 "matplotlib 3.8.0" + +# positive review +#get_pr 36403 "python 3.12" # included in #36407 + +# needs review +get_pr 36407 "python 3.12" diff --git a/srcpkgs/sagemath/template b/srcpkgs/sagemath/template index e180eda47d3..a80d8b7187e 100644 --- a/srcpkgs/sagemath/template +++ b/srcpkgs/sagemath/template @@ -1,7 +1,7 @@ # Template file for 'sagemath' pkgname=sagemath version=10.1 -revision=3 +revision=4 build_wrksrc=pkgs/sagemath-standard build_style=python3-module _bindir=/usr/lib/sagemath/$version/bin @@ -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" +checkdepends="$depends pythran python3-Sphinx meson" short_desc="Open source mathematics software" maintainer="Gonzalo TornarĂ­a " license="GPL-2.0-or-later"