From 0c7db8a2b10065f46733d61e1cd3a95f9b3c5c30 Mon Sep 17 00:00:00 2001 From: Daniel Krenn Date: Tue, 23 Aug 2016 19:19:33 +0200 Subject: [PATCH 001/529] handle mutable structures --- src/sage/combinat/recognizable_series.py | 35 ++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/src/sage/combinat/recognizable_series.py b/src/sage/combinat/recognizable_series.py index f7ed7ab58a8..2b1c51f5a43 100644 --- a/src/sage/combinat/recognizable_series.py +++ b/src/sage/combinat/recognizable_series.py @@ -300,21 +300,52 @@ def __init__(self, parent, mu, left, right): :doc:`recognizable series `, :class:`RecognizableSeriesSpace`. + + TESTS:: + + sage: M0 = Matrix([[3, 6], [0, 1]]) + sage: M1 = Matrix([[0, -6], [1, 5]]) + sage: L = vector([0, 1]) + sage: R = vector([1, 0]) + sage: S = Rec((M0, M1), L, R) + sage: S.mu[0] is M0, S.mu[1] is M1, S.left is L, S.right is R + (False, False, False, False) + sage: S.mu[0].is_immutable(), S.mu[1].is_immutable(), S.left.is_immutable(), S.right.is_immutable() + (True, True, True, True) + sage: M0.set_immutable() + sage: M1.set_immutable() + sage: L.set_immutable() + sage: R.set_immutable() + sage: S = Rec((M0, M1), L, R) + sage: S.mu[0] is M0, S.mu[1] is M1, S.left is L, S.right is R + (True, True, True, True) """ super(RecognizableSeries, self).__init__(parent=parent) + from copy import copy from sage.sets.family import Family A = self.parent().alphabet() if isinstance(mu, (list, tuple)): mu = dict(zip(A, mu)) + + def immutable(m): + if m.is_immutable(): + return m + m = copy(m) + m.set_immutable() + return m + + if isinstance(mu, dict): + mu = dict((a, immutable(M)) for a, M in mu.iteritems()) mu = Family(mu) + if not mu.is_finite(): raise NotImplementedError('mu is not a finite family of matrices.') - self._left_ = left + self._left_ = immutable(left) self._mu_ = mu - self._right_ = right + self._right_ = immutable(right) @property From 1ba61b162a01c400e8352f97dd9f70a57f84b2bc Mon Sep 17 00:00:00 2001 From: Daniel Krenn Date: Tue, 23 Aug 2016 19:19:47 +0200 Subject: [PATCH 002/529] fix doctests --- src/sage/combinat/k_regular_sequence.py | 2 +- src/sage/combinat/recognizable_series.py | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/sage/combinat/k_regular_sequence.py b/src/sage/combinat/k_regular_sequence.py index f7cbe1cd7e8..e8721117d5b 100644 --- a/src/sage/combinat/k_regular_sequence.py +++ b/src/sage/combinat/k_regular_sequence.py @@ -214,7 +214,7 @@ def __getitem__(self, n, **kwds): sage: W = Seq2.indices() sage: M0 = Matrix([[1, 0], [0, 1]]) sage: M1 = Matrix([[0, -1], [1, 2]]) - sage: S = Seq2((M0, M1), [0, 1], [1, 1]) + sage: S = Seq2((M0, M1), vector([0, 1]), vector([1, 1])) sage: S._mu_of_word_(W(0.digits(2))) == M0 True sage: S._mu_of_word_(W(1.digits(2))) == M1 diff --git a/src/sage/combinat/recognizable_series.py b/src/sage/combinat/recognizable_series.py index 2b1c51f5a43..d5027605560 100644 --- a/src/sage/combinat/recognizable_series.py +++ b/src/sage/combinat/recognizable_series.py @@ -361,7 +361,7 @@ def mu(self): sage: Rec = RecognizableSeriesSpace(ZZ, [0, 1]) sage: M0 = Matrix([[1, 0], [0, 1]]) sage: M1 = Matrix([[0, -1], [1, 2]]) - sage: S = Rec((M0, M1), [0, 1], [1, 1]) + sage: S = Rec((M0, M1), vector([0, 1]), vector([1, 1])) sage: S.mu[0] == M0 and S.mu[1] == M1 True """ @@ -540,12 +540,12 @@ def _mu_of_empty_word_(self): sage: W = Rec.indices() sage: M0 = Matrix([[1, 0], [0, 1]]) sage: M1 = Matrix([[0, -1], [1, 2]]) - sage: S = Rec({W([0]): M0, W([1]): M1}, [0, 1], [1, 1]) + sage: S = Rec({W([0]): M0, W([1]): M1}, vector([0, 1]), vector([1, 1])) sage: S._mu_of_empty_word_() [1 0] [0 1] - sage: I = Matrix([[1, 0], [0, 1]]) - sage: T = Rec({W([]): I, W([0]): M0, W([1]): M1}, [0, 1], [1, 1]) + sage: I = Matrix([[1, 0], [0, 1]]); I.set_immutable() + sage: T = Rec({W([]): I, W([0]): M0, W([1]): M1}, vector([0, 1]), vector([1, 1])) sage: T._mu_of_empty_word_() [1 0] [0 1] @@ -579,7 +579,7 @@ def _mu_of_word_(self, w): sage: W = Rec.indices() sage: M0 = Matrix([[1, 0], [0, 1]]) sage: M1 = Matrix([[0, -1], [1, 2]]) - sage: S = Rec((M0, M1), [0, 1], [1, 1]) + sage: S = Rec((M0, M1), vector([0, 1]), vector([1, 1])) sage: S._mu_of_word_(W([0])) == M0 True sage: S._mu_of_word_(W([1])) == M1 @@ -1492,7 +1492,7 @@ def _element_constructor_(self, data, sage: M0 = Matrix([[1, 0], [0, 1]]) sage: M1 = Matrix([[0, -1], [1, 2]]) - sage: S = Rec((M0, M1), [0, 1], [1, 1]) + sage: S = Rec((M0, M1), vector([0, 1]), vector([1, 1])) sage: Rec(S) is S True From 33209daf71fc1cfea2b6178b24b7f7e8210839ce Mon Sep 17 00:00:00 2001 From: Daniel Krenn Date: Tue, 23 Aug 2016 19:20:22 +0200 Subject: [PATCH 003/529] mutability in transposed() --- src/sage/combinat/recognizable_series.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/sage/combinat/recognizable_series.py b/src/sage/combinat/recognizable_series.py index d5027605560..5ce6605852f 100644 --- a/src/sage/combinat/recognizable_series.py +++ b/src/sage/combinat/recognizable_series.py @@ -756,8 +756,17 @@ def transposed(self): [3 6] [ 0 -6] [0 1], [ 1 5], (0, 1), (1, 0) ) + + TESTS:: + + sage: T.mu[0].is_immutable(), T.mu[1].is_immutable(), T.left.is_immutable(), T.right.is_immutable() + (True, True, True, True) """ - return self.parent()(self.mu.map(lambda M: M.transpose()), + def tr(M): + T = M.transpose() + T.set_immutable() + return T + return self.parent()(self.mu.map(tr), left=self.right, right=self.left) From f0de605d0682f31f6b3e9a0c149bfc454e932f69 Mon Sep 17 00:00:00 2001 From: Daniel Krenn Date: Tue, 23 Aug 2016 19:30:01 +0200 Subject: [PATCH 004/529] hashing --- src/sage/combinat/recognizable_series.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/sage/combinat/recognizable_series.py b/src/sage/combinat/recognizable_series.py index 5ce6605852f..b4573a21291 100644 --- a/src/sage/combinat/recognizable_series.py +++ b/src/sage/combinat/recognizable_series.py @@ -723,6 +723,20 @@ def __nonzero__(self): return True + def __hash__(self): + r""" + A hash value of this recognizable series. + + TESTS:: + + sage: Rec = RecognizableSeriesSpace(ZZ, [0, 1]) + sage: S = Rec((Matrix([[1, 0], [0, 1]]), Matrix([[1, 0], [0, 1]])), + ....: left=vector([0, 1]), right=vector([1, 0])) + sage: hash(S) # random + 42 + """ + return hash((self.mu, self.left, self.right)) + def transposed(self): r""" Return the transposed series. From 1882b17f7723f80453a41d60aecd76b225cee0bc Mon Sep 17 00:00:00 2001 From: Daniel Krenn Date: Tue, 23 Aug 2016 19:30:11 +0200 Subject: [PATCH 005/529] equality testing --- src/sage/combinat/recognizable_series.py | 88 ++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/src/sage/combinat/recognizable_series.py b/src/sage/combinat/recognizable_series.py index b4573a21291..029cf9d212e 100644 --- a/src/sage/combinat/recognizable_series.py +++ b/src/sage/combinat/recognizable_series.py @@ -737,6 +737,94 @@ def __hash__(self): """ return hash((self.mu, self.left, self.right)) + + def __eq__(self, other): + r""" + Return whether this recognizable series is equal to ``other``. + + INPUT: + + - ``other`` -- an object. + + OUTPUT: + + A boolean. + + .. NOTE:: + + This function uses the coercion model to find a common + parent for the two operands. + + EXAMPLES:: + + sage: Rec = RecognizableSeriesSpace(ZZ, [0, 1]) + sage: S = Rec((Matrix([[1, 0], [0, 1]]), Matrix([[1, 0], [0, 1]])), + ....: left=vector([1, 1]), right=vector([1, 0])) + sage: S + [] + [0] + [1] + [00] + [01] + [10] + + [11] + [000] + [001] + [010] + ... + sage: Z1 = Rec((Matrix([[1, 0], [0, 1]]), Matrix([[1, 0], [0, 1]])), + ....: left=vector([0, 1]), right=vector([1, 0])) + sage: Z1 + 0 + sage: Z2 = Rec((Matrix([[0, 0], [0, 0]]), Matrix([[0, 0], [0, 0]])), + ....: left=vector([0, 1]), right=vector([1, 0])) + sage: Z2 + 0 + sage: S == Z1 + False + sage: S == Z2 + False + sage: Z1 == Z2 + True + + TESTS:: + + sage: S == S + True + sage: x == None + False + """ + if other is None: + return False + try: + return not bool(self - other) + except (TypeError, ValueError): + return False + + + def __ne__(self, other): + r""" + Return whether this recognizable series is equal to ``other``. + + INPUT: + + - ``other`` -- an object. + + OUTPUT: + + A boolean. + + .. NOTE:: + + This function uses the coercion model to find a common + parent for the two operands. + + EXAMPLES:: + + sage: Rec = RecognizableSeriesSpace(ZZ, [0, 1]) + sage: Z1 = Rec((Matrix([[1, 0], [0, 1]]), Matrix([[1, 0], [0, 1]])), + ....: left=vector([0, 1]), right=vector([1, 0])) + sage: Z2 = Rec((Matrix([[0, 0], [0, 0]]), Matrix([[0, 0], [0, 0]])), + ....: left=vector([0, 1]), right=vector([1, 0])) + sage: Z1 != Z2 + False + sage: Z1 != Z1 + False + """ + return not self == other + + def transposed(self): r""" Return the transposed series. From 1e5754b347f0df578046a7284189a7d39021573f Mon Sep 17 00:00:00 2001 From: Daniel Krenn Date: Thu, 25 Aug 2016 16:51:34 +0200 Subject: [PATCH 006/529] an_element and some_elements --- src/sage/combinat/recognizable_series.py | 71 ++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/src/sage/combinat/recognizable_series.py b/src/sage/combinat/recognizable_series.py index 2e5b454b43b..b4714e48f2e 100644 --- a/src/sage/combinat/recognizable_series.py +++ b/src/sage/combinat/recognizable_series.py @@ -1529,6 +1529,77 @@ def _repr_(self): self.coefficients()) + def _an_element_(self): + r""" + Return an element of this recognizable series. + + OUTPUT: + + A :class:`recognizable_series`. + + EXAMPLES:: + + sage: RecognizableSeriesSpace(ZZ, [0, 1]).an_element() # indirect doctest + [1] + [01] + [10] + 2*[11] + [001] + [010] + + 2*[011] + [100] + 2*[101] + 2*[110] + ... + """ + from sage.matrix.constructor import Matrix + from sage.modules.free_module_element import vector + z = self.coefficients().zero() + o = self.coefficients().one() + e = self.coefficients().an_element() + return self(list(Matrix([[o, z], [i*o, o]]) + for i, _ in enumerate(self.alphabet())), + vector([z, e]), right=vector([e, z])) + + + def some_elements(self): + r""" + Return some elements of this free module. + + See :class:`TestSuite` for a typical use case. + + OUTPUT: + + An iterator. + + EXAMPLES:: + + sage: tuple(RecognizableSeriesSpace(ZZ, [0, 1]).some_elements()) + ([1] + [01] + [10] + 2*[11] + [001] + [010] + + 2*[011] + [100] + 2*[101] + 2*[110] + ..., + [] + [0] + [1] + [00] + [01] + [10] + + [11] + [000] + [001] + [010] + ..., + 0, + -2*[] + 2*[0] - 4*[1] - 2*[00] + 4*[01] + 4*[10] + - 8*[11] + 2*[000] - 4*[001] - 4*[010] + ..., + [] + [0] + 2*[1] + [00] + 2*[01] + [10] + + 4*[11] + [000] + 2*[001] + [010] + ..., + 2*[] + 5*[0] + 11*[1] + 8*[00] + 14*[01] + 14*[10] + + 20*[11] + 11*[000] + 17*[001] + 17*[010] + ..., + ... + [] + [0] + 10*[1] + [00] + 10*[01] + [10] + + 100*[11] + [000] + 10*[001] + [010] + ...) + """ + from itertools import count, islice + from sage.matrix.matrix_space import MatrixSpace + from sage.modules.free_module import FreeModule + yield self.an_element() + + C = self.coefficients() + some_elements_base = iter(C.some_elements()) + k = len(self.alphabet()) + for dim in range(1, 11): + elements_M = MatrixSpace(C, dim).some_elements() + elements_V = FreeModule(C, dim).some_elements() + for _ in range(3): + mu = list(islice(elements_M, k)) + LR = list(islice(elements_V, 2)) + if len(mu) != k or len(LR) != 2: + break + yield self(mu, *LR) + + def zero(self): """ Return the zero of this recognizable series space. From becce48c45ef6456cd4a4805fdf0814ab802160a Mon Sep 17 00:00:00 2001 From: Daniel Krenn Date: Thu, 25 Aug 2016 17:49:07 +0200 Subject: [PATCH 007/529] pickling support --- src/sage/combinat/k_regular_sequence.py | 29 ++++++++++++++++++++++++ src/sage/combinat/recognizable_series.py | 28 +++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/sage/combinat/k_regular_sequence.py b/src/sage/combinat/k_regular_sequence.py index cbf76aaeb5b..cf474e98f1b 100644 --- a/src/sage/combinat/k_regular_sequence.py +++ b/src/sage/combinat/k_regular_sequence.py @@ -250,6 +250,21 @@ def __iter__(self): return iter(self[n] for n in count()) +def _pickle_kRegularSequenceSpace(k, coefficients, category): + r""" + Pickle helper. + + TESTS:: + + sage: Seq2 = kRegularSequenceSpace(2, ZZ) + sage: from sage.combinat.k_regular_sequence import _pickle_kRegularSequenceSpace + sage: _pickle_kRegularSequenceSpace( + ....: Seq2.k, Seq2.coefficients(), Seq2.category()) + Space of 2-regular sequences over Integer Ring + """ + return kRegularSequenceSpace(k, coefficients, category=category) + + class kRegularSequenceSpace(RecognizableSeriesSpace): r""" The space of `k`-regular Sequences over the given ``coefficients``. @@ -335,6 +350,20 @@ def __init__(self, k, *args, **kwds): super(kRegularSequenceSpace, self).__init__(*args, **kwds) + def __reduce__(self): + r""" + Pickling support. + + TESTS:: + + sage: Seq2 = kRegularSequenceSpace(2, ZZ) + sage: loads(dumps(Seq2)) # indirect doctest + Space of 2-regular sequences over Integer Ring + """ + return _pickle_kRegularSequenceSpace, \ + (self.k, self.coefficients(), self.category()) + + def _repr_(self): r""" Return a representation string of this `k`-regular sequence space. diff --git a/src/sage/combinat/recognizable_series.py b/src/sage/combinat/recognizable_series.py index b4714e48f2e..34884c6ee07 100644 --- a/src/sage/combinat/recognizable_series.py +++ b/src/sage/combinat/recognizable_series.py @@ -1296,6 +1296,20 @@ def hadamard_product(self, other, minimize=True): return result +def _pickle_RecognizableSeriesSpace(coefficients, indices, category): + r""" + Pickle helper. + + TESTS:: + + sage: Rec = RecognizableSeriesSpace(ZZ, [0, 1]) + sage: from sage.combinat.recognizable_series import _pickle_RecognizableSeriesSpace + sage: _pickle_RecognizableSeriesSpace( + ....: Rec.coefficients(), Rec.indices(), Rec.category()) + Space of recognizable series on {0, 1} with coefficients in Integer Ring + """ + return RecognizableSeriesSpace(coefficients, indices=indices, category=category) + class RecognizableSeriesSpace(UniqueRepresentation, Parent): r""" @@ -1457,6 +1471,20 @@ def __init__(self, coefficients, indices, category): category=category, base=coefficients) + def __reduce__(self): + r""" + Pickling support. + + TESTS:: + + sage: Rec = RecognizableSeriesSpace(ZZ, [0, 1]) + sage: loads(dumps(Rec)) # indirect doctest + Space of recognizable series on {0, 1} with coefficients in Integer Ring + """ + return _pickle_RecognizableSeriesSpace, \ + (self.coefficients(), self.indices(), self.category()) + + def alphabet(self): r""" Return the alphabet of this recognizable series space. From a4ccbec7d2d16f43342bb44a7fc756bf7d448081 Mon Sep 17 00:00:00 2001 From: Daniel Krenn Date: Thu, 25 Aug 2016 17:49:17 +0200 Subject: [PATCH 008/529] TestSuite --- src/sage/combinat/k_regular_sequence.py | 29 ++++++++++++++++++++++++ src/sage/combinat/recognizable_series.py | 29 ++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/src/sage/combinat/k_regular_sequence.py b/src/sage/combinat/k_regular_sequence.py index cf474e98f1b..33c9fc2793c 100644 --- a/src/sage/combinat/k_regular_sequence.py +++ b/src/sage/combinat/k_regular_sequence.py @@ -341,6 +341,35 @@ def __init__(self, k, *args, **kwds): sage: kRegularSequenceSpace(3, ZZ) Space of 3-regular sequences over Integer Ring + :: + + sage: from itertools import islice + sage: Seq2 = kRegularSequenceSpace(2, ZZ) + sage: TestSuite(Seq2).run( # long time + ....: verbose=True, + ....: elements=tuple(islice(Seq2.some_elements(), 4))) + running ._test_additive_associativity() . . . pass + running ._test_an_element() . . . pass + running ._test_cardinality() . . . pass + running ._test_category() . . . pass + running ._test_elements() . . . + Running the test suite of self.an_element() + running ._test_category() . . . pass + running ._test_eq() . . . pass + running ._test_nonzero_equal() . . . pass + running ._test_not_implemented_methods() . . . pass + running ._test_pickling() . . . pass + pass + running ._test_elements_eq_reflexive() . . . pass + running ._test_elements_eq_symmetric() . . . pass + running ._test_elements_eq_transitive() . . . pass + running ._test_elements_neq() . . . pass + running ._test_eq() . . . pass + running ._test_not_implemented_methods() . . . pass + running ._test_pickling() . . . pass + running ._test_some_elements() . . . pass + running ._test_zero() . . . pass + .. SEEALSO:: :doc:`k-regular sequence `, diff --git a/src/sage/combinat/recognizable_series.py b/src/sage/combinat/recognizable_series.py index 34884c6ee07..b5269c066fe 100644 --- a/src/sage/combinat/recognizable_series.py +++ b/src/sage/combinat/recognizable_series.py @@ -1465,6 +1465,35 @@ def __init__(self, coefficients, indices, category): sage: RecognizableSeriesSpace(ZZ, [0, 1]) Space of recognizable series on {0, 1} with coefficients in Integer Ring + + :: + + sage: from itertools import islice + sage: Rec = RecognizableSeriesSpace(ZZ, [0, 1]) + sage: TestSuite(Rec).run( # long time + ....: verbose=True, + ....: elements=tuple(islice(Rec.some_elements(), 4))) + running ._test_additive_associativity() . . . pass + running ._test_an_element() . . . pass + running ._test_cardinality() . . . pass + running ._test_category() . . . pass + running ._test_elements() . . . + Running the test suite of self.an_element() + running ._test_category() . . . pass + running ._test_eq() . . . pass + running ._test_nonzero_equal() . . . pass + running ._test_not_implemented_methods() . . . pass + running ._test_pickling() . . . pass + pass + running ._test_elements_eq_reflexive() . . . pass + running ._test_elements_eq_symmetric() . . . pass + running ._test_elements_eq_transitive() . . . pass + running ._test_elements_neq() . . . pass + running ._test_eq() . . . pass + running ._test_not_implemented_methods() . . . pass + running ._test_pickling() . . . pass + running ._test_some_elements() . . . pass + running ._test_zero() . . . pass """ self._indices_ = indices super(RecognizableSeriesSpace, self).__init__( From 18c52684895620e08e00fbc49eca28fbf0659179 Mon Sep 17 00:00:00 2001 From: Daniel Krenn Date: Fri, 2 Sep 2016 15:05:58 +0200 Subject: [PATCH 009/529] correct typo in docstring --- src/sage/combinat/recognizable_series.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/combinat/recognizable_series.py b/src/sage/combinat/recognizable_series.py index ab86807e151..12d762c95c8 100644 --- a/src/sage/combinat/recognizable_series.py +++ b/src/sage/combinat/recognizable_series.py @@ -1612,7 +1612,7 @@ def _an_element_(self): def some_elements(self): r""" - Return some elements of this free module. + Return some elements of this recognizable series. See :class:`TestSuite` for a typical use case. From 457aefdfa6b3a3b9b470017e2f4d9dc64bd19391 Mon Sep 17 00:00:00 2001 From: Daniel Krenn Date: Tue, 24 Jan 2017 14:21:03 +0100 Subject: [PATCH 010/529] Python3: fix iteritems --- src/sage/combinat/recognizable_series.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sage/combinat/recognizable_series.py b/src/sage/combinat/recognizable_series.py index 1ec4411e1a8..3d4929036a0 100644 --- a/src/sage/combinat/recognizable_series.py +++ b/src/sage/combinat/recognizable_series.py @@ -73,6 +73,7 @@ # http://www.gnu.org/licenses/ #***************************************************************************** from __future__ import absolute_import +from six import iteritems from sage.misc.cachefunc import cached_method from sage.misc.superseded import experimental @@ -333,7 +334,7 @@ def immutable(m): return m if isinstance(mu, dict): - mu = dict((a, immutable(M)) for a, M in mu.iteritems()) + mu = dict((a, immutable(M)) for a, M in iteritems(mu)) mu = Family(mu) if not mu.is_finite(): From fcb53a3611e27f8f87684af842cc30f07e43d94b Mon Sep 17 00:00:00 2001 From: Daniel Krenn Date: Tue, 24 Jan 2017 14:22:37 +0100 Subject: [PATCH 011/529] fix doctest output of TestSuite (new tests were added) --- src/sage/combinat/k_regular_sequence.py | 2 ++ src/sage/combinat/recognizable_series.py | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/sage/combinat/k_regular_sequence.py b/src/sage/combinat/k_regular_sequence.py index ccf8a56014d..b4e04f23dc0 100644 --- a/src/sage/combinat/k_regular_sequence.py +++ b/src/sage/combinat/k_regular_sequence.py @@ -744,6 +744,7 @@ def __init__(self, k, *args, **kwds): Running the test suite of self.an_element() running ._test_category() . . . pass running ._test_eq() . . . pass + running ._test_new() . . . pass running ._test_nonzero_equal() . . . pass running ._test_not_implemented_methods() . . . pass running ._test_pickling() . . . pass @@ -753,6 +754,7 @@ def __init__(self, k, *args, **kwds): running ._test_elements_eq_transitive() . . . pass running ._test_elements_neq() . . . pass running ._test_eq() . . . pass + running ._test_new() . . . pass running ._test_not_implemented_methods() . . . pass running ._test_pickling() . . . pass running ._test_some_elements() . . . pass diff --git a/src/sage/combinat/recognizable_series.py b/src/sage/combinat/recognizable_series.py index 3d4929036a0..85c0afb484f 100644 --- a/src/sage/combinat/recognizable_series.py +++ b/src/sage/combinat/recognizable_series.py @@ -1487,6 +1487,7 @@ def __init__(self, coefficients, indices, category): Running the test suite of self.an_element() running ._test_category() . . . pass running ._test_eq() . . . pass + running ._test_new() . . . pass running ._test_nonzero_equal() . . . pass running ._test_not_implemented_methods() . . . pass running ._test_pickling() . . . pass @@ -1496,6 +1497,7 @@ def __init__(self, coefficients, indices, category): running ._test_elements_eq_transitive() . . . pass running ._test_elements_neq() . . . pass running ._test_eq() . . . pass + running ._test_new() . . . pass running ._test_not_implemented_methods() . . . pass running ._test_pickling() . . . pass running ._test_some_elements() . . . pass From e2154afabecefcfa68508afd4fa4c9753eedcb8f Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Sat, 16 Sep 2017 19:15:13 +0200 Subject: [PATCH 012/529] return an element of SetPartitions --- src/sage/combinat/dyck_word.py | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/src/sage/combinat/dyck_word.py b/src/sage/combinat/dyck_word.py index bf724ae0ddf..99d356a0059 100644 --- a/src/sage/combinat/dyck_word.py +++ b/src/sage/combinat/dyck_word.py @@ -75,6 +75,7 @@ from sage.combinat.permutation import Permutation, Permutations from sage.combinat.words.word import Word from sage.combinat.alternating_sign_matrix import AlternatingSignMatrices +from sage.combinat.set_partition import SetPartitions from sage.misc.latex import latex open_symbol = 1 @@ -218,7 +219,7 @@ class DyckWord(CombinatorialElement): sage: dw.height() 1 sage: dw.to_noncrossing_partition() - [[1], [2]] + {{1}, {2}} :: @@ -2219,33 +2220,33 @@ def to_noncrossing_partition(self, bijection=None): EXAMPLES:: sage: DyckWord([]).to_noncrossing_partition() - [] + {} sage: DyckWord([1, 0]).to_noncrossing_partition() - [[1]] + {{1}} sage: DyckWord([1, 1, 0, 0]).to_noncrossing_partition() - [[1, 2]] + {{1, 2}} sage: DyckWord([1, 1, 1, 0, 0, 0]).to_noncrossing_partition() - [[1, 2, 3]] + {{1, 2, 3}} sage: DyckWord([1, 0, 1, 0, 1, 0]).to_noncrossing_partition() - [[1], [2], [3]] + {{1}, {2}, {3}} sage: DyckWord([1, 1, 0, 1, 0, 0]).to_noncrossing_partition() - [[2], [1, 3]] + {{1, 3}, {2}} sage: DyckWord([]).to_noncrossing_partition("Stump") - [] + {} sage: DyckWord([1, 0]).to_noncrossing_partition("Stump") - [[1]] + {{1}} sage: DyckWord([1, 1, 0, 0]).to_noncrossing_partition("Stump") - [[1, 2]] + {{1, 2}} sage: DyckWord([1, 1, 1, 0, 0, 0]).to_noncrossing_partition("Stump") - [[1, 3], [2]] + {{1, 3}, {2}} sage: DyckWord([1, 0, 1, 0, 1, 0]).to_noncrossing_partition("Stump") - [[1], [2], [3]] + {{1}, {2}, {3}} sage: DyckWord([1, 1, 0, 1, 0, 0]).to_noncrossing_partition("Stump") - [[1, 2, 3]] + {{1, 2, 3}} """ + P = SetPartitions(self.semilength()) if bijection == "Stump": - return [[v for v in c] - for c in self.to_noncrossing_permutation().cycle_tuples()] + return P(self.to_noncrossing_permutation().cycle_tuples()) partition = [] stack = [] i = 0 @@ -2278,7 +2279,7 @@ def to_noncrossing_partition(self, bijection=None): if stack: raise ValueError("incorrect Dyck word") - return partition + return P(partition) def to_Catalan_code(self): r""" From a7293980c0e1820114f6875d0e468cebab960d71 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Fri, 29 Sep 2017 10:31:29 -0500 Subject: [PATCH 013/529] Using the changes from #23877 to speed things up. --- src/sage/combinat/dyck_word.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/combinat/dyck_word.py b/src/sage/combinat/dyck_word.py index 1c8c49d971a..7fdd3860583 100644 --- a/src/sage/combinat/dyck_word.py +++ b/src/sage/combinat/dyck_word.py @@ -2245,9 +2245,9 @@ def to_noncrossing_partition(self, bijection=None): sage: DyckWord([1, 1, 0, 1, 0, 0]).to_noncrossing_partition("Stump") {{1, 2, 3}} """ - P = SetPartitions(self.semilength()) + P = SetPartitions(len(self) // 2) if bijection == "Stump": - return P(self.to_noncrossing_permutation().cycle_tuples()) + return P(self.to_noncrossing_permutation().cycle_tuples(), check=False) partition = [] stack = [] i = 0 @@ -2280,7 +2280,7 @@ def to_noncrossing_partition(self, bijection=None): if stack: raise ValueError("incorrect Dyck word") - return P(partition) + return P(partition, check=False) def to_Catalan_code(self): r""" From 989c4fc2850c173ea9034f22c7742c614840a770 Mon Sep 17 00:00:00 2001 From: Mckenzie West Date: Fri, 29 Jun 2018 15:27:23 +0200 Subject: [PATCH 014/529] Added test to verify division works --- src/sage/rings/polynomial/multi_polynomial_element.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/sage/rings/polynomial/multi_polynomial_element.py b/src/sage/rings/polynomial/multi_polynomial_element.py index 9158d067953..3628e6c2577 100644 --- a/src/sage/rings/polynomial/multi_polynomial_element.py +++ b/src/sage/rings/polynomial/multi_polynomial_element.py @@ -306,6 +306,15 @@ def _div_(self, right): sage: S.=PolynomialRing(R) sage: x/S(2) 1/2*x + + Ensure that :trac:`17638` is fixed.:: + + sage: R. = PolynomialRing(QQ,order = "neglex") + sage: f = 1+y + sage: g = 1+x + sage: h = f/g + sage: print(h*g == f) + True """ if right in self.base_ring(): inv = self.base_ring().one()/self.base_ring()(right) From 3315205e6e9d41a1ef6c2a331418a628b5abb8aa Mon Sep 17 00:00:00 2001 From: Mckenzie West Date: Sat, 30 Jun 2018 19:30:42 +0200 Subject: [PATCH 015/529] moved test from multi_polynomial_element.py to multi_polynomial libsingular.pyx --- src/sage/rings/polynomial/multi_polynomial_element.py | 9 --------- .../rings/polynomial/multi_polynomial_libsingular.pyx | 9 +++++++++ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_element.py b/src/sage/rings/polynomial/multi_polynomial_element.py index 3628e6c2577..9158d067953 100644 --- a/src/sage/rings/polynomial/multi_polynomial_element.py +++ b/src/sage/rings/polynomial/multi_polynomial_element.py @@ -306,15 +306,6 @@ def _div_(self, right): sage: S.=PolynomialRing(R) sage: x/S(2) 1/2*x - - Ensure that :trac:`17638` is fixed.:: - - sage: R. = PolynomialRing(QQ,order = "neglex") - sage: f = 1+y - sage: g = 1+x - sage: h = f/g - sage: print(h*g == f) - True """ if right in self.base_ring(): inv = self.base_ring().one()/self.base_ring()(right) diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index 809ca72c76f..f1ceed98c6c 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -2402,6 +2402,15 @@ cdef class MPolynomial_libsingular(MPolynomial): Traceback (most recent call last): ... ZeroDivisionError: rational division by zero + + Ensure that :trac:`17638` is fixed:: + + sage: R. = PolynomialRing(QQ,order = "neglex") + sage: f = 1+y + sage: g = 1+x + sage: h = f/g + sage: print(h*g == f) + True """ cdef poly *p cdef MPolynomial_libsingular right = right_ringelement From 4e719b5ae335595fd3d79059f41366a41e7dac71 Mon Sep 17 00:00:00 2001 From: Mckenzie West Date: Sat, 30 Jun 2018 19:31:42 +0200 Subject: [PATCH 016/529] removed multi_polynomial_element.py from tracking --- .../polynomial/multi_polynomial_element.py | 2049 ----------------- 1 file changed, 2049 deletions(-) delete mode 100644 src/sage/rings/polynomial/multi_polynomial_element.py diff --git a/src/sage/rings/polynomial/multi_polynomial_element.py b/src/sage/rings/polynomial/multi_polynomial_element.py deleted file mode 100644 index 9158d067953..00000000000 --- a/src/sage/rings/polynomial/multi_polynomial_element.py +++ /dev/null @@ -1,2049 +0,0 @@ -""" -Generic Multivariate Polynomials - -AUTHORS: - -- David Joyner: first version - -- William Stein: use dict's instead of lists - -- Martin Albrecht malb@informatik.uni-bremen.de: some functions added - -- William Stein (2006-02-11): added better __div__ behavior. - -- Kiran S. Kedlaya (2006-02-12): added Macaulay2 analogues of some - Singular features - -- William Stein (2006-04-19): added e.g., - ``f[1,3]`` to get coeff of `xy^3`; added examples of the new - ``R.x,y = PolynomialRing(QQ,2)`` notation. - -- Martin Albrecht: improved singular coercions (restructured class - hierarchy) and added ETuples - -- Robert Bradshaw (2007-08-14): added support for coercion of - polynomials in a subset of variables (including multi-level - univariate rings) - -- Joel B. Mohler (2008-03): Refactored interactions with ETuples. - -EXAMPLES: - -We verify Lagrange's four squares identity:: - - sage: R. = QQbar[] - sage: (a0^2 + a1^2 + a2^2 + a3^2)*(b0^2 + b1^2 + b2^2 + b3^2) == (a0*b0 - a1*b1 - a2*b2 - a3*b3)^2 + (a0*b1 + a1*b0 + a2*b3 - a3*b2)^2 + (a0*b2 - a1*b3 + a2*b0 + a3*b1)^2 + (a0*b3 + a1*b2 - a2*b1 + a3*b0)^2 - True -""" -#***************************************************************************** -# -# Sage: System for Algebra and Geometry Experimentation -# -# Copyright (C) 2005 William Stein -# -# Distributed under the terms of the GNU General Public License (GPL) -# -# This code is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# The full text of the GPL is available at: -# -# http://www.gnu.org/licenses/ -#***************************************************************************** -from __future__ import absolute_import -from six.moves import range -from six import iteritems, integer_types - -from sage.structure.element import CommutativeRingElement, canonical_coercion, coerce_binop -from sage.misc.all import prod -import sage.rings.integer -from . import polydict -from sage.structure.factorization import Factorization -from sage.rings.polynomial.polynomial_singular_interface import Polynomial_singular_repr -from sage.structure.sequence import Sequence -from .multi_polynomial import MPolynomial -from sage.categories.morphism import Morphism - - -def is_MPolynomial(x): - return isinstance(x, MPolynomial) - - -class MPolynomial_element(MPolynomial): - def __init__(self, parent, x): - """ - EXAMPLES:: - - sage: K. = NumberField(x^3 - 2) - sage: L. = K.extension(x^3 - 3) - sage: S. = L.extension(x^2 - 2) - sage: S - Number Field in sqrt2 with defining polynomial x^2 - 2 over its base field - sage: P. = PolynomialRing(S) # indirect doctest - """ - CommutativeRingElement.__init__(self, parent) - self.__element = x - - def _repr_(self): - """ - EXAMPLES:: - - sage: P. = PolynomialRing(QQbar) - sage: x + QQbar.random_element() # indirect doctest - x - 4 - """ - return "%s"%self.__element - - #################### - - def __call__(self, *x, **kwds): - r""" - Evaluate this multi-variate polynomial at `x`, where - `x` is either the tuple of values to substitute in, or one - can use functional notation `f(a_0,a_1,a_2, \ldots)` to - evaluate `f` with the ith variable replaced by - `a_i`. - - EXAMPLES:: - - sage: R. = CC[] - sage: f = x^2 + y^2 - sage: f(1,2) - 5.00000000000000 - sage: f((1,2)) - 5.00000000000000 - - :: - - sage: x = PolynomialRing(CC,3,'x').gens() - sage: f = x[0] + x[1] - 2*x[1]*x[2] - sage: f - (-2.00000000000000)*x1*x2 + x0 + x1 - sage: f(1,2,0) - 3.00000000000000 - sage: f(1,2,5) - -17.0000000000000 - - AUTHORS: - - - David Kohel (2005-09-27) - """ - if len(kwds) > 0: - f = self.subs(**kwds) - if len(x) > 0: - return f(*x) - else: - return f - if len(x) == 1 and isinstance(x[0], (list, tuple)): - x = x[0] - n = self.parent().ngens() - if len(x) != n: - raise TypeError("x must be of correct length") - if n == 0: - return self - try: - K = x[0].parent() - except AttributeError: - K = self.parent().base_ring() - y = K(0) - for (m,c) in iteritems(self.element().dict()): - y += c*prod([ x[i]**m[i] for i in range(n) if m[i] != 0]) - return y - - def _richcmp_(self, right, op): - """ - Compare ``self`` to ``right`` with respect to the term order of - self.parent(). - - EXAMPLES:: - - sage: R.=PolynomialRing(QQbar,3,order='lex') - sage: x^1*y^2 > y^3*z^4 - True - sage: x^3*y^2*z^4 < x^3*y^2*z^1 - False - - :: - - sage: R.=PolynomialRing(CC,3,order='deglex') - sage: x^1*y^2*z^3 > x^3*y^2*z^0 - True - sage: x^1*y^2*z^4 < x^1*y^1*z^5 - False - - :: - - sage: R.=PolynomialRing(QQbar,3,order='degrevlex') - sage: x^1*y^5*z^2 > x^4*y^1*z^3 - True - sage: x^4*y^7*z^1 < x^4*y^2*z^3 - False - """ - return self.__element.rich_compare(right.__element, op, - self.parent().term_order().sortkey) - - def _im_gens_(self, codomain, im_gens): - """ - EXAMPLES:: - - sage: R. = PolynomialRing(QQbar, 2) - sage: f = R.hom([y,x], R) - sage: f(x^2 + 3*y^5) - 3*x^5 + y^2 - """ - n = self.parent().ngens() - if n == 0: - return codomain._coerce_(self) - y = codomain(0) - for (m,c) in iteritems(self.element().dict()): - y += codomain(c)*prod([ im_gens[i]**m[i] for i in range(n) if m[i] ]) - return y - - def number_of_terms(self): - """ - Return the number of non-zero coefficients of this polynomial. - - This is also called weight, :meth:`hamming_weight` or sparsity. - - EXAMPLES:: - - sage: R. = CC[] - sage: f = x^3 - y - sage: f.number_of_terms() - 2 - sage: R(0).number_of_terms() - 0 - sage: f = (x+y)^100 - sage: f.number_of_terms() - 101 - - The method :meth:`hamming_weight` is an alias:: - - sage: f.hamming_weight() - 101 - """ - return len(self.element().dict()) - - hamming_weight = number_of_terms - - def _add_(self, right): - #return self.parent()(self.__element + right.__element) - return self.__class__(self.parent(),self.__element + right.__element) - - def _sub_(self, right): - # return self.parent()(self.__element - right.__element) - return self.__class__(self.parent(),self.__element - right.__element) - - def _mul_(self, right): - #return self.parent()(self.__element * right.__element) - return self.__class__(self.parent(),self.__element * right.__element) - - def _lmul_(self, a): - """ - Left Scalar Multiplication - - EXAMPLES: - - Note that it is not really possible to do a meaningful - example since sage mpoly rings refuse to have non-commutative - bases. - - :: - - sage: R. = QQbar[] - sage: f = (x + y) - sage: 3*f - 3*x + 3*y - """ - return self.__class__(self.parent(),self.__element.scalar_lmult(a)) - - def _rmul_(self, a): - """ - Right Scalar Multiplication - - EXAMPLES: - - Note that it is not really possible to do a meaningful - example since sage mpoly rings refuse to have non-commutative - bases. - - :: - - sage: R. = QQbar[] - sage: f = (x + y) - sage: f*3 - 3*x + 3*y - """ - return self.__class__(self.parent(),self.__element.scalar_rmult(a)) - - def _div_(self, right): - r""" - EXAMPLES:: - - sage: R. = CC['x,y'] - sage: f = (x + y)/x; f - (x + y)/x - sage: f.parent() - Fraction Field of Multivariate Polynomial Ring in x, y over - Complex Field with 53 bits of precision - - If dividing by a scalar, there is no need to go to the fraction - field of the polynomial ring:: - - sage: f = (x + y)/2; f - 0.500000000000000*x + 0.500000000000000*y - sage: f.parent() - Multivariate Polynomial Ring in x, y over Complex Field with - 53 bits of precision - - TESTS: - - Ensure that :trac:`13704` is fixed.:: - - sage: R.=PolynomialRing(QQ) - sage: S.=PolynomialRing(R) - sage: x/S(2) - 1/2*x - """ - if right in self.base_ring(): - inv = self.base_ring().one()/self.base_ring()(right) - return inv*self - return self.parent().fraction_field()(self, right, coerce=False) - - def __rpow__(self, n): - if not isinstance(n, integer_types + (sage.rings.integer.Integer,)): - raise TypeError("The exponent must be an integer.") - return self.parent()(self.__element**n) - - def element(self): - return self.__element - - def change_ring(self, R): - r""" - Change the base ring of this polynomial to ``R``. - - INPUT: - - - ``R`` -- ring or morphism. - - OUTPUT: a new polynomial converted to ``R``. - - EXAMPLES:: - - sage: R. = QQ[] - sage: f = x^2 + 5*y - sage: f.change_ring(GF(5)) - x^2 - - :: - - sage: K. = CyclotomicField(5) - sage: R. = K[] - sage: f = x^2 + w*y - sage: f.change_ring(K.embeddings(QQbar)[1]) - x^2 + (-0.8090169943749474? + 0.5877852522924731?*I)*y - """ - if isinstance(R, Morphism): - #if we're given a hom of the base ring extend to a poly hom - if R.domain() == self.base_ring(): - R = self.parent().hom(R, self.parent().change_ring(R.codomain())) - return R(self) - else: - return self.parent().change_ring(R)(self) - - -class MPolynomial_polydict(Polynomial_singular_repr, MPolynomial_element): - r""" - Multivariate polynomials implemented in pure python using - polydicts. - """ - def __init__(self, parent, x): - """ - EXAMPLES:: - - sage: R, x = PolynomialRing(QQbar, 10, 'x').objgens() - sage: x - (x0, x1, x2, x3, x4, x5, x6, x7, x8, x9) - sage: loads(dumps(x)) == x - True - """ - if not isinstance(x, polydict.PolyDict): - x = polydict.PolyDict(x, parent.base_ring()(0), remove_zero=True) - MPolynomial_element.__init__(self, parent, x) - - def _new_constant_poly(self, x, P): - """ - Quickly create a new constant polynomial with value x in parent P. - - ASSUMPTION: - - x must be an element of the base ring of P. That assumption is - not verified. - - EXAMPLES:: - - sage: R. = QQ['t'][] - sage: x._new_constant_poly(R.base_ring()(2),R) - 2 - - """ - return MPolynomial_polydict(P, {P._zero_tuple:x}) - - def __neg__(self): - """ - EXAMPLES:: - - sage: R.=QQbar[] - sage: -x - -x - sage: -(y-1) - -y + 1 - """ - return self*(-1) - - def _repr_(self): - """ - EXAMPLES:: - - sage: R.=QQbar[] - sage: repr(-x^2-y+1) # indirect doc-test - '-x^2 - y + 1' - sage: K.=QuadraticField(-1) - sage: R.=K[] - sage: repr(-I*y-x^2) # indirect doc-test - '-x^2 + (-I)*y' - """ - try: - key = self.parent().term_order().sortkey - except AttributeError: - key = None - atomic = self.parent().base_ring()._repr_option('element_is_atomic') - return self.element().poly_repr(self.parent().variable_names(), - atomic_coefficients=atomic, - sortkey=key) - - def _latex_(self): - r""" - EXAMPLES:: - - sage: R.=QQbar[] - sage: latex(-x^2-y+1) - -x^{2} - y + 1 - sage: K.=QuadraticField(-1) - sage: R.=K[] - sage: latex(-I*y+I*x^2) - \left(\sqrt{-1}\right) x^{2} + \left(-\sqrt{-1}\right) y - """ - try: - key = self.parent().term_order().sortkey - except AttributeError: - key = None - atomic = self.parent().base_ring()._repr_option('element_is_atomic') - return self.element().latex(self.parent().latex_variable_names(), - atomic_coefficients=atomic, sortkey=key) - - def _repr_with_changed_varnames(self, varnames): - """ - EXAMPLES:: - - sage: R.=QQbar[] - sage: f=-x^2-y+1 - sage: f._repr_with_changed_varnames(['jack','jill']) - '-jack^2 - jill + 1' - """ - try: - key = self.parent().term_order().sortkey - except AttributeError: - key = None - atomic = self.parent().base_ring()._repr_option('element_is_atomic') - return self.element().poly_repr(varnames, - atomic_coefficients=atomic, sortkey=key) - - def degrees(self): - r""" - Returns a tuple (precisely - an ``ETuple``) with the - degree of each variable in this polynomial. The list of degrees is, - of course, ordered by the order of the generators. - - EXAMPLES:: - - sage: R.=PolynomialRing(QQbar) - sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 - sage: f.degrees() - (2, 2, 0) - sage: f = x^2+z^2 - sage: f.degrees() - (2, 0, 2) - sage: f.total_degree() # this simply illustrates that total degree is not the sum of the degrees - 2 - sage: R.=PolynomialRing(QQbar) - sage: f=(1-x)*(1+y+z+x^3)^5 - sage: f.degrees() - (16, 5, 5, 0) - sage: R(0).degrees() - (0, 0, 0, 0) - """ - if self.is_zero(): - return polydict.ETuple({},self.parent().ngens()) - else: - return self._MPolynomial_element__element.max_exp() - - def degree(self, x=None, std_grading=False): - """ - Return the degree of self in x, where x must be one of the - generators for the parent of self. - - INPUT: - - - ``x`` - multivariate polynomial (a generator of the parent - of self). If ``x`` is not specified (or is None), return - the total degree, which is the maximum degree of any - monomial. Note that a weighted term ordering alters the - grading of the generators of the ring; see the tests below. - To avoid this behavior, set the optional argument ``std_grading=True``. - - OUTPUT: integer - - EXAMPLES:: - - sage: R. = RR[] - sage: f = y^2 - x^9 - x - sage: f.degree(x) - 9 - sage: f.degree(y) - 2 - sage: (y^10*x - 7*x^2*y^5 + 5*x^3).degree(x) - 3 - sage: (y^10*x - 7*x^2*y^5 + 5*x^3).degree(y) - 10 - - Note that total degree takes into account if we are working in a polynomial - ring with a weighted term order. - - :: - - sage: R = PolynomialRing(QQ,'x,y',order=TermOrder('wdeglex',(2,3))) - sage: x,y = R.gens() - sage: x.degree() - 2 - sage: y.degree() - 3 - sage: x.degree(y),x.degree(x),y.degree(x),y.degree(y) - (0, 1, 0, 1) - sage: f = (x^2*y+x*y^2) - sage: f.degree(x) - 2 - sage: f.degree(y) - 2 - sage: f.degree() - 8 - sage: f.degree(std_grading=True) - 3 - - Note that if ``x`` is not a generator of the parent of self, - for example if it is a generator of a polynomial algebra which - maps naturally to this one, then it is converted to an element - of this algebra. (This fixes the problem reported in - :trac:`17366`.) - - :: - - sage: x, y = ZZ['x','y'].gens() - sage: GF(3037000453)['x','y'].gen(0).degree(x) - 1 - - sage: x0, y0 = QQ['x','y'].gens() - sage: GF(3037000453)['x','y'].gen(0).degree(x0) - Traceback (most recent call last): - ... - TypeError: x must canonically coerce to parent - - sage: GF(3037000453)['x','y'].gen(0).degree(x^2) - Traceback (most recent call last): - ... - TypeError: x must be one of the generators of the parent - - TESTS:: - - sage: R = PolynomialRing(GF(2)['t'],'x,y',order=TermOrder('wdeglex',(2,3))) - sage: x,y = R.gens() - sage: x.degree() - 2 - sage: y.degree() - 3 - sage: x.degree(y),x.degree(x),y.degree(x),y.degree(y) - (0, 1, 0, 1) - sage: f = (x^2*y+x*y^2) - sage: f.degree(x) - 2 - sage: f.degree(y) - 2 - sage: f.degree() - 8 - sage: f.degree(std_grading=True) - 3 - sage: R(0).degree() - -1 - - Degree of zero polynomial for other implementation :trac:`20048` :: - - sage: R. = GF(3037000453)[] - sage: R.zero().degree(x) - -1 - """ - if x is None: - if std_grading or not self.parent().term_order().is_weighted_degree_order(): - return self.element().degree(None) - return self.weighted_degree(self.parent().term_order().weights()) - if isinstance(x, MPolynomial): - if not x.parent() is self.parent(): - try: - x = self.parent().coerce(x) - except TypeError: - raise TypeError("x must canonically coerce to parent") - if not x.is_generator(): - raise TypeError("x must be one of the generators of the parent") - else: - raise TypeError("x must be one of the generators of the parent") - return self.element().degree(x.element()) - - def total_degree(self): - """ - Return the total degree of self, which is the maximum degree of any - monomial in self. - - EXAMPLES:: - - sage: R. = QQbar[] - sage: f=2*x*y^3*z^2 - sage: f.total_degree() - 6 - sage: f=4*x^2*y^2*z^3 - sage: f.total_degree() - 7 - sage: f=99*x^6*y^3*z^9 - sage: f.total_degree() - 18 - sage: f=x*y^3*z^6+3*x^2 - sage: f.total_degree() - 10 - sage: f=z^3+8*x^4*y^5*z - sage: f.total_degree() - 10 - sage: f=z^9+10*x^4+y^8*x^2 - sage: f.total_degree() - 10 - """ - return self.degree() - - def monomial_coefficient(self, mon): - """ - Return the coefficient in the base ring of the monomial mon in - self, where mon must have the same parent as self. - - This function contrasts with the function - ``coefficient`` which returns the coefficient of a - monomial viewing this polynomial in a polynomial ring over a base - ring having fewer variables. - - INPUT: - - - ``mon`` - a monomial - - - OUTPUT: coefficient in base ring - - .. SEEALSO:: - - For coefficients in a base ring of fewer variables, look - at :meth:`coefficient`. - - EXAMPLES: - - The parent of the return is a member of the base ring. - - :: - - sage: R.=QQbar[] - - The parent of the return is a member of the base ring. - - :: - - sage: f = 2 * x * y - sage: c = f.monomial_coefficient(x*y); c - 2 - sage: c.parent() - Algebraic Field - - :: - - sage: f = y^2 + y^2*x - x^9 - 7*x + 5*x*y - sage: f.monomial_coefficient(y^2) - 1 - sage: f.monomial_coefficient(x*y) - 5 - sage: f.monomial_coefficient(x^9) - -1 - sage: f.monomial_coefficient(x^10) - 0 - - :: - - sage: var('a') - a - sage: K. = NumberField(a^2+a+1) - sage: P. = K[] - sage: f=(a*x-1)*((a+1)*y-1); f - -x*y + (-a)*x + (-a - 1)*y + 1 - sage: f.monomial_coefficient(x) - -a - """ - if not (isinstance(mon, MPolynomial) and mon.parent() is self.parent() and mon.is_monomial()): - raise TypeError("mon must be a monomial in the parent of self.") - R = self.parent().base_ring() - return R(self.element().monomial_coefficient(mon.element().dict())) - - def dict(self): - """ - Return underlying dictionary with keys the exponents and values - the coefficients of this polynomial. - """ - return self.element().dict() - - #def __iter__(self): - # """ - # Facilitates iterating over the monomials of self, - # returning tuples of the form (coeff, mon) for each - # non-zero monomial. - # - # EXAMPLES:: - - # sage: R = ZZ['t'] - # sage: P. = PolynomialRing(R,3) - # sage: f = 3*x^3*y + 16*x + 7 - # sage: [(c,m) for c,m in f] - # [(3, x^3*y), (16, x), (7, 1)] - # sage: f = P.random_element(10,10) - # sage: sum(c*m for c,m in f) == f - # True - # """ - # exps = self.exponents() - # parent = self.parent() - # for exp in exps: - # yield self.element()[exp], MPolynomial_polydict(parent, {exp: 1}) - - def __getitem__(self, x): - """ - INPUT: - - - - ``x`` - a tuple or, in case of a single-variable - MPolynomial ring x can also be an integer. - - - EXAMPLES:: - - sage: R. = PolynomialRing(QQbar, 2) - sage: f = -10*x^3*y + 17*x*y - sage: f[3,1] - -10 - sage: f[1,1] - 17 - sage: f[0,1] - 0 - - :: - - sage: R. = PolynomialRing(QQbar,1); R - Multivariate Polynomial Ring in x over Algebraic Field - sage: f = 5*x^2 + 3; f - 5*x^2 + 3 - sage: f[2] - 5 - """ - if isinstance(x, MPolynomial): - return self.monomial_coefficient(x) - if not isinstance(x, tuple): - try: - x = tuple(x) - except TypeError: - x = (x, ) - try: - return self.element()[x] - except KeyError: - return self.parent().base_ring()(0) - - def coefficient(self, degrees): - """ - Return the coefficient of the variables with the degrees specified - in the python dictionary ``degrees``. Mathematically, - this is the coefficient in the base ring adjoined by the variables - of this ring not listed in ``degrees``. However, the - result has the same parent as this polynomial. - - This function contrasts with the function - ``monomial_coefficient`` which returns the coefficient - in the base ring of a monomial. - - INPUT: - - - - ``degrees`` - Can be any of: - - - a dictionary of degree restrictions - - - a list of degree restrictions (with None in - the unrestricted variables) - - - a monomial (very fast, but not as flexible) - - - OUTPUT: element of the parent of self - - .. SEEALSO:: - - For coefficients of specific monomials, look at - :meth:`monomial_coefficient`. - - EXAMPLES:: - - sage: R. = QQbar[] - sage: f = 2 * x * y - sage: c = f.coefficient({x:1,y:1}); c - 2 - sage: c.parent() - Multivariate Polynomial Ring in x, y over Algebraic Field - sage: c in PolynomialRing(QQbar, 2, names = ['x','y']) - True - sage: f = y^2 - x^9 - 7*x + 5*x*y - sage: f.coefficient({y:1}) - 5*x - sage: f.coefficient({y:0}) - -x^9 + (-7)*x - sage: f.coefficient({x:0,y:0}) - 0 - sage: f=(1+y+y^2)*(1+x+x^2) - sage: f.coefficient({x:0}) - y^2 + y + 1 - sage: f.coefficient([0,None]) - y^2 + y + 1 - sage: f.coefficient(x) - y^2 + y + 1 - sage: # Be aware that this may not be what you think! - sage: # The physical appearance of the variable x is deceiving -- particularly if the exponent would be a variable. - sage: f.coefficient(x^0) # outputs the full polynomial - x^2*y^2 + x^2*y + x*y^2 + x^2 + x*y + y^2 + x + y + 1 - - :: - - sage: R. = RR[] - sage: f=x*y+5 - sage: c=f.coefficient({x:0,y:0}); c - 5.00000000000000 - sage: parent(c) - Multivariate Polynomial Ring in x, y over Real Field with 53 bits of precision - - AUTHORS: - - - Joel B. Mohler (2007-10-31) - """ - looking_for = None - if isinstance(degrees, MPolynomial) and degrees.parent() == self.parent() and degrees.is_monomial(): - looking_for = [e if e > 0 else None for e in degrees.exponents()[0]] - elif isinstance(degrees, list): - looking_for = degrees - elif isinstance(degrees, dict): - poly_vars = self.parent().gens() - looking_for = [None] * len(poly_vars) - for d, exp in degrees.items(): - for i in range(len(poly_vars)): - if d == poly_vars[i]: - looking_for[i] = exp - if not looking_for: - raise ValueError("You must pass a dictionary list or monomial.") - return self.parent()(self.element().polynomial_coefficient(looking_for)) - - def exponents(self, as_ETuples=True): - """ - Return the exponents of the monomials appearing in self. - - INPUT: - - - as_ETuples (default: ``True``): return the list of exponents as a list - of ETuples. - - OUTPUT: - - Return the list of exponents as a list of ETuples or tuples. - - EXAMPLES:: - - sage: R. = PolynomialRing(QQbar, 3) - sage: f = a^3 + b + 2*b^2 - sage: f.exponents() - [(3, 0, 0), (0, 2, 0), (0, 1, 0)] - - Be default the list of exponents is a list of ETuples:: - - sage: type(f.exponents()[0]) - - sage: type(f.exponents(as_ETuples=False)[0]) - <... 'tuple'> - """ - try: - exp = self.__exponents - if as_ETuples: - return exp - else: - return [tuple(e) for e in exp] - except AttributeError: - self.__exponents = list(self.element().dict()) - try: - self.__exponents.sort(key=self.parent().term_order().sortkey, - reverse=True) - except AttributeError: - pass - if as_ETuples: - return self.__exponents - else: - return [tuple(e) for e in self.__exponents] - - def inverse_of_unit(self): - d = self.element().dict() - k = list(d) - if self.is_unit(): - if len(k) != 1: - raise NotImplementedError - return ~d[k[0]] - raise ArithmeticError("is not a unit") - - def is_homogeneous(self): - """ - Return True if self is a homogeneous polynomial. - - EXAMPLES:: - - sage: R. = QQbar[] - sage: (x+y).is_homogeneous() - True - sage: (x.parent()(0)).is_homogeneous() - True - sage: (x+y^2).is_homogeneous() - False - sage: (x^2 + y^2).is_homogeneous() - True - sage: (x^2 + y^2*x).is_homogeneous() - False - sage: (x^2*y + y^2*x).is_homogeneous() - True - """ - return self.element().is_homogeneous() - - def _homogenize(self, var): - r""" - Return ``self`` if ``self`` is homogeneous. - Otherwise return a homogenized polynomial constructed by modifying - the degree of the variable with index ``var``. - - INPUT: - - - - ``var`` - an integer indicating which variable to - use to homogenize (0 <= var < parent(self).ngens()) - - - OUTPUT: a multivariate polynomial - - EXAMPLES:: - - sage: P. = QQbar[] - sage: f = x^2 + y + 1 + 5*x*y^1 - sage: g = f.homogenize('z'); g # indirect doctest - x^2 + 5*x*y + y*z + z^2 - sage: g.parent() - Multivariate Polynomial Ring in x, y, z over Algebraic Field - - SEE: ``self.homogenize`` - """ - if self.is_homogeneous(): - return self - X = self.element().homogenize(var) - R = self.parent() - return R(X) - - def is_generator(self): - """ - Returns True if self is a generator of it's parent. - - EXAMPLES:: - - sage: R.=QQbar[] - sage: x.is_generator() - True - sage: (x+y-y).is_generator() - True - sage: (x*y).is_generator() - False - """ - d = self.element().dict() - if len(d) == 1: - (e, c), = d.items() - if c.is_one() and len(e.nonzero_positions()) == 1 and e.nonzero_values()[0] == 1: - return True - return False - - def is_monomial(self): - """ - Returns True if self is a monomial, which we define to be a - product of generators with coefficient 1. - - Use is_term to allow the coefficient to not be 1. - - EXAMPLES:: - - sage: R.=QQbar[] - sage: x.is_monomial() - True - sage: (x+2*y).is_monomial() - False - sage: (2*x).is_monomial() - False - sage: (x*y).is_monomial() - True - - To allow a non-1 leading coefficient, use is_term():: - - sage: (2*x*y).is_term() - True - sage: (2*x*y).is_monomial() - False - """ - term = (len(self.element().dict().keys()) == 1) - if term: - if self.coefficients()[0] == 1: - return True - else: - return False - else: - return False - - def is_term(self): - """ - Returns True if self is a term, which we define to be a - product of generators times some coefficient, which need - not be 1. - - Use :meth:`is_monomial` to require that the coefficient be 1. - - EXAMPLES:: - - sage: R.=QQbar[] - sage: x.is_term() - True - sage: (x+2*y).is_term() - False - sage: (2*x).is_term() - True - sage: (7*x^5*y).is_term() - True - - To require leading coefficient 1, use is_monomial():: - - sage: (2*x*y).is_monomial() - False - sage: (2*x*y).is_term() - True - """ - return len(self.element().dict().keys()) == 1 - - def subs(self, fixed=None, **kw): - """ - Fixes some given variables in a given multivariate polynomial and - returns the changed multivariate polynomials. The polynomial itself - is not affected. The variable,value pairs for fixing are to be - provided as a dictionary of the form {variable:value}. - - This is a special case of evaluating the polynomial with some of - the variables constants and the others the original variables. - - INPUT: - - - - ``fixed`` - (optional) dictionary of inputs - - - ``**kw`` - named parameters - - - OUTPUT: new MPolynomial - - EXAMPLES:: - - sage: R. = QQbar[] - sage: f = x^2 + y + x^2*y^2 + 5 - sage: f((5,y)) - 25*y^2 + y + 30 - sage: f.subs({x:5}) - 25*y^2 + y + 30 - """ - variables = list(self.parent().gens()) - for i in range(0,len(variables)): - if str(variables[i]) in kw: - variables[i]=kw[str(variables[i])] - elif fixed and variables[i] in fixed: - variables[i] = fixed[variables[i]] - return self(tuple(variables)) - - def monomials(self): - """ - Returns the list of monomials in self. The returned list is - decreasingly ordered by the term ordering of self.parent(). - - OUTPUT: list of MPolynomials representing Monomials - - EXAMPLES:: - - sage: R. = QQbar[] - sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 - sage: f.monomials() - [x^2*y^2, x^2, y, 1] - - :: - - sage: R. = QQbar[] - sage: F = ((fx*gy - fy*gx)^3) - sage: F - -fy^3*gx^3 + 3*fx*fy^2*gx^2*gy + (-3)*fx^2*fy*gx*gy^2 + fx^3*gy^3 - sage: F.monomials() - [fy^3*gx^3, fx*fy^2*gx^2*gy, fx^2*fy*gx*gy^2, fx^3*gy^3] - sage: F.coefficients() - [-1, 3, -3, 1] - sage: sum(map(mul,zip(F.coefficients(),F.monomials()))) == F - True - """ - ring = self.parent() - one = ring.base_ring()(1) - return [MPolynomial_polydict(ring, polydict.PolyDict({m:one}, force_int_exponents=False, force_etuples=False)) for m in self.exponents()] - try: - return self.__monomials - except AttributeError: - ring = self.parent() - one = self.parent().base_ring()(1) - self.__monomials = sorted([ MPolynomial_polydict(ring, polydict.PolyDict( {m:one}, force_int_exponents=False, force_etuples=False ) ) \ - for m in self._MPolynomial_element__element.dict().keys() ], reverse=True) - return self.__monomials - - def constant_coefficient(self): - """ - Return the constant coefficient of this multivariate polynomial. - - EXAMPLES:: - - sage: R. = QQbar[] - sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 - sage: f.constant_coefficient() - 5 - sage: f = 3*x^2 - sage: f.constant_coefficient() - 0 - """ - #v = (0,)*int(self.parent().ngens()) - d = self.element().dict() - try: - return d[polydict.ETuple({},self.parent().ngens())] - except KeyError: - return self.parent().base_ring()(0) - - def is_univariate(self): - """ - Returns True if this multivariate polynomial is univariate and - False otherwise. - - EXAMPLES:: - - sage: R. = QQbar[] - sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 - sage: f.is_univariate() - False - sage: g = f.subs({x:10}); g - 700*y^2 + (-2)*y + 305 - sage: g.is_univariate() - True - sage: f = x^0 - sage: f.is_univariate() - True - """ - mons = self.element().dict().keys() - - found = -1 - for mon in mons: - for i in mon.nonzero_positions(): - if found != i: - if found != -1: - return False - else: - found = i - return True - - def univariate_polynomial(self, R=None): - """ - Returns a univariate polynomial associated to this multivariate - polynomial. - - INPUT: - - - - ``R`` - (default: None) PolynomialRing - - - If this polynomial is not in at most one variable, then a - ValueError exception is raised. This is checked using the - is_univariate() method. The new Polynomial is over the same base - ring as the given MPolynomial. - - EXAMPLES:: - - sage: R. = QQbar[] - sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 - sage: f.univariate_polynomial() - Traceback (most recent call last): - ... - TypeError: polynomial must involve at most one variable - sage: g = f.subs({x:10}); g - 700*y^2 + (-2)*y + 305 - sage: g.univariate_polynomial () - 700*y^2 - 2*y + 305 - sage: g.univariate_polynomial(PolynomialRing(QQ,'z')) - 700*z^2 - 2*z + 305 - - TESTS:: - - sage: P = PolynomialRing(QQ, 0, '') - sage: P(5).univariate_polynomial() - 5 - """ - if self.parent().ngens() == 0: - if R is None: - return self.base_ring()(self) - else: - return R(self) - - if not self.is_univariate(): - raise TypeError("polynomial must involve at most one variable") - - #construct ring if None - if R is None: - # constant, we just pick first variable from parent - if self.is_constant(): - R = self.base_ring()[self.parent().variable_names()[0]] - else: - R = self.base_ring()[str(self.variables()[0])] - - monomial_coefficients = self._MPolynomial_element__element.dict() - - if( not self.is_constant() ): - var_idx = self.degrees().nonzero_positions()[0] #variable - else: - var_idx = 0; #constant - if( len(monomial_coefficients.keys())==0 ): - return R(0) - - #construct list - lookup = [int(0),] * len(next(iter(monomial_coefficients))) - coefficients = [] - for degree in range(max(m[var_idx] - for m in monomial_coefficients.keys()) + 1): - lookup[var_idx] = int(degree) - try: - coefficients.append( monomial_coefficients[ polydict.ETuple(lookup) ] ) #if we find something, add the coefficient - except KeyError: - coefficients.append( 0 ) #else add zero - - #construct polynomial - return R(coefficients) - - def variables(self): - """ - Returns the tuple of variables occurring in this polynomial. - - EXAMPLES:: - - sage: R. = QQbar[] - sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 - sage: f.variables() - (x, y) - sage: g = f.subs({x:10}); g - 700*y^2 + (-2)*y + 305 - sage: g.variables() - (y,) - - TESTS: - - This shows that the issue at :trac:`7077` is fixed:: - - sage: x,y,z=polygens(QQ,'x,y,z') - sage: (x^2).variables() - (x,) - """ - return tuple([self.parent().gen(index) for index in self.degrees().nonzero_positions()]) - - def variable(self,i): - """ - Returns `i`-th variable occurring in this polynomial. - - EXAMPLES:: - - sage: R. = QQbar[] - sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 - sage: f.variable(0) - x - sage: f.variable(1) - y - """ - return self.variables()[int(i)] - - def nvariables(self): - """ - Number of variables in this polynomial - - EXAMPLES:: - - sage: R. = QQbar[] - sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 - sage: f.nvariables () - 2 - sage: g = f.subs({x:10}); g - 700*y^2 + (-2)*y + 305 - sage: g.nvariables () - 1 - """ - return len(self.degrees().nonzero_positions()) - - def is_constant(self): - """ - True if polynomial is constant, and False otherwise. - - EXAMPLES:: - - sage: R. = QQbar[] - sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 - sage: f.is_constant() - False - sage: g = 10*x^0 - sage: g.is_constant() - True - """ - if len(self.dict()) <= 1 and self.degrees().is_constant(): - return True - else: - return False - - def lm(self): - """ - Returns the lead monomial of self with respect to the term order of - self.parent(). - - EXAMPLES:: - - sage: R.=PolynomialRing(GF(7),3,order='lex') - sage: (x^1*y^2 + y^3*z^4).lm() - x*y^2 - sage: (x^3*y^2*z^4 + x^3*y^2*z^1).lm() - x^3*y^2*z^4 - - :: - - sage: R.=PolynomialRing(CC,3,order='deglex') - sage: (x^1*y^2*z^3 + x^3*y^2*z^0).lm() - x*y^2*z^3 - sage: (x^1*y^2*z^4 + x^1*y^1*z^5).lm() - x*y^2*z^4 - - :: - - sage: R.=PolynomialRing(QQbar,3,order='degrevlex') - sage: (x^1*y^5*z^2 + x^4*y^1*z^3).lm() - x*y^5*z^2 - sage: (x^4*y^7*z^1 + x^4*y^2*z^3).lm() - x^4*y^7*z - - TESTS:: - - sage: from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_polydict - sage: R.=MPolynomialRing_polydict(GF(2),2,order='lex') - sage: f=x+y - sage: f.lm() - x - - """ - try: - return self.__lm - except AttributeError: - if self.is_zero(): - return self - R = self.parent() - f = self._MPolynomial_element__element.lcmt( R.term_order().greater_tuple ) - one = R.base_ring()(1) - self.__lm = MPolynomial_polydict(R,polydict.PolyDict({f:one},zero=R.base_ring().zero(),force_int_exponents=False, force_etuples=False)) - return self.__lm - - def lc(self): - """ - Returns the leading coefficient of self i.e., - self.coefficient(self.lm()) - - EXAMPLES:: - - sage: R.=QQbar[] - sage: f=3*x^2-y^2-x*y - sage: f.lc() - 3 - """ - try: - return self.__lc - except AttributeError: - if self.is_zero(): - return self.base_ring()._zero_element - R = self.parent() - f = self._MPolynomial_element__element.dict() - self.__lc = f[self._MPolynomial_element__element.lcmt( R.term_order().greater_tuple )] - return self.__lc - - def lt(self): - """ - Returns the leading term of self i.e., self.lc()\*self.lm(). The - notion of "leading term" depends on the ordering defined in the - parent ring. - - EXAMPLES:: - - sage: R.=PolynomialRing(QQbar) - sage: f=3*x^2-y^2-x*y - sage: f.lt() - 3*x^2 - sage: R.=PolynomialRing(QQbar,order="invlex") - sage: f=3*x^2-y^2-x*y - sage: f.lt() - -y^2 - - TESTS:: - - sage: from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_polydict - sage: R.=MPolynomialRing_polydict(GF(2),2,order='lex') - sage: f=x+y - sage: f.lt() - x - - """ - try: - return self.__lt - except AttributeError: - if self.is_zero(): - return self - R = self.parent() - f = self._MPolynomial_element__element.dict() - res = self._MPolynomial_element__element.lcmt( R.term_order().greater_tuple ) - self.__lt = MPolynomial_polydict(R,polydict.PolyDict({res:f[res]},zero=R.base_ring().zero(),force_int_exponents=False, force_etuples=False)) - return self.__lt - - def __eq__(self,right): - if not isinstance(right, MPolynomial_polydict): - # we want comparison with zero to be fast - if not right: - return not self._MPolynomial_element__element.dict() - return CommutativeRingElement.__eq__(self, right) - return self._MPolynomial_element__element == right._MPolynomial_element__element - - def __ne__(self,right): - if not isinstance(right, MPolynomial_polydict): - # we want comparison with zero to be fast - if not right: - return not not self._MPolynomial_element__element.dict() - return CommutativeRingElement.__ne__(self, right) - return self._MPolynomial_element__element != right._MPolynomial_element__element - - def __bool__(self): - """ - Returns True if self != 0 - - .. note:: - - This is much faster than actually writing ``self == 0``. - """ - return self._MPolynomial_element__element.dict()!={} - - __nonzero__ = __bool__ - - def _floordiv_(self, right): - r""" - Quotient of division of self by other. This is denoted //. - - .. note:: - - It's not clear to me that this is well-defined if - ``self`` is not exactly divisible by other. - - EXAMPLES:: - - sage: R.=QQbar[] - sage: 2*x*y//y - 2*x - sage: 2*x//y - 0 - sage: 2*x//4 - 1/2*x - sage: type(0//y) - - """ - # handle division by monomials without using Singular - if len(right.dict()) == 1: - P = self.parent() - ret = P(0) - denC,denM = next(iter(right)) - for c,m in self: - t = c*m - if denC.divides(c) and P.monomial_divides(denM, m): - ret += P.monomial_quotient(t, right, coeff=True) - return ret - - Q, _ = self.quo_rem(right) - return Q - - def _derivative(self, var=None): - r""" - Differentiates ``self`` with respect to variable ``var``. - - If ``var`` is not one of the generators of this ring, _derivative(var) - is called recursively on each coefficient of this polynomial. - - .. SEEALSO:: - - :meth:`derivative` - - EXAMPLES:: - - sage: R. = PowerSeriesRing(QQbar) - sage: S. = PolynomialRing(R) - sage: f = (t^2 + O(t^3))*x^2*y^3 + (37*t^4 + O(t^5))*x^3 - sage: f.parent() - Multivariate Polynomial Ring in x, y over Power Series Ring in t over Algebraic Field - sage: f._derivative(x) # with respect to x - (2*t^2 + O(t^3))*x*y^3 + (111*t^4 + O(t^5))*x^2 - sage: f._derivative(x).parent() - Multivariate Polynomial Ring in x, y over Power Series Ring in t over Algebraic Field - sage: f._derivative(y) # with respect to y - (3*t^2 + O(t^3))*x^2*y^2 - sage: f._derivative(t) # with respect to t (recurses into base ring) - (2*t + O(t^2))*x^2*y^3 + (148*t^3 + O(t^4))*x^3 - sage: f._derivative(x)._derivative(y) # with respect to x and then y - (6*t^2 + O(t^3))*x*y^2 - sage: f.derivative(y, 3) # with respect to y three times - (6*t^2 + O(t^3))*x^2 - sage: f._derivative() # can't figure out the variable - Traceback (most recent call last): - ... - ValueError: must specify which variable to differentiate with respect to - """ - if var is None: - raise ValueError("must specify which variable to differentiate with respect to") - - gens = list(self.parent().gens()) - - # check if var is one of the generators - try: - index = gens.index(var) - except ValueError: - # var is not a generator; do term-by-term differentiation recursively - # var may be, for example, a generator of the base ring - d = dict([(e, x._derivative(var)) for (e, x) in iteritems(self.dict())]) - d = polydict.PolyDict(d, self.parent().base_ring()(0), remove_zero=True) - return MPolynomial_polydict(self.parent(), d) - - # differentiate w.r.t. indicated variable - d = {} - v = polydict.ETuple({index:1}, len(gens)) - for (exp, coeff) in iteritems(self.dict()): - if exp[index] > 0: - d[exp.esub(v)] = coeff * exp[index] - d = polydict.PolyDict(d, self.parent().base_ring()(0), remove_zero=True) - return MPolynomial_polydict(self.parent(), d) - - def integral(self, var=None): - r""" - Integrates ``self`` with respect to variable ``var``. - - .. NOTE:: - - The integral is always chosen so the constant term is 0. - - If ``var`` is not one of the generators of this ring, integral(var) - is called recursively on each coefficient of this polynomial. - - EXAMPLES: - - On polynomials with rational coefficients:: - - sage: x, y = PolynomialRing(QQ, 'x, y').gens() - sage: ex = x*y + x - y - sage: it = ex.integral(x); it - 1/2*x^2*y + 1/2*x^2 - x*y - sage: it.parent() == x.parent() - True - - On polynomials with coefficients in power series:: - - sage: R. = PowerSeriesRing(QQbar) - sage: S. = PolynomialRing(R) - sage: f = (t^2 + O(t^3))*x^2*y^3 + (37*t^4 + O(t^5))*x^3 - sage: f.parent() - Multivariate Polynomial Ring in x, y over Power Series Ring in t over Algebraic Field - sage: f.integral(x) # with respect to x - (1/3*t^2 + O(t^3))*x^3*y^3 + (37/4*t^4 + O(t^5))*x^4 - sage: f.integral(x).parent() - Multivariate Polynomial Ring in x, y over Power Series Ring in t over Algebraic Field - - sage: f.integral(y) # with respect to y - (1/4*t^2 + O(t^3))*x^2*y^4 + (37*t^4 + O(t^5))*x^3*y - sage: f.integral(t) # with respect to t (recurses into base ring) - (1/3*t^3 + O(t^4))*x^2*y^3 + (37/5*t^5 + O(t^6))*x^3 - - TESTS:: - - sage: f.integral() # can't figure out the variable - Traceback (most recent call last): - ... - ValueError: must specify which variable to integrate with respect to - """ - if var is None: - raise ValueError("must specify which variable to integrate " - "with respect to") - - gens = list(self.parent().gens()) - - # check if var is one of the generators - try: - index = gens.index(var) - except ValueError: - # var is not a generator; do term-by-term integration recursively - # var may be, for example, a generator of the base ring - d = dict([(e, x.integral(var)) - for (e, x) in iteritems(self.dict())]) - d = polydict.PolyDict(d, self.parent().base_ring()(0), - remove_zero=True) - return MPolynomial_polydict(self.parent(), d) - - # integrate w.r.t. indicated variable - d = {} - v = polydict.ETuple({index:1}, len(gens)) - for (exp, coeff) in iteritems(self.dict()): - d[exp.eadd(v)] = coeff / (1+exp[index]) - d = polydict.PolyDict(d, self.parent().base_ring()(0), remove_zero=True) - return MPolynomial_polydict(self.parent(), d) - - def factor(self, proof=True): - r""" - Compute the irreducible factorization of this polynomial. - - INPUT: - - - ``proof'' - insist on provably correct results (default: ``True``) - - TESTS: - - Check if we can handle polynomials with no variables, see :trac:`7950`:: - - sage: P = PolynomialRing(ZZ,0,'') - sage: res = P(10).factor(); res - 2 * 5 - sage: res[0][0].parent() - Multivariate Polynomial Ring in no variables over Integer Ring - sage: R = PolynomialRing(QQ,0,'') - sage: res = R(10).factor(); res - 10 - sage: res.unit().parent() - Rational Field - sage: P(0).factor() - Traceback (most recent call last): - ... - ArithmeticError: factorization of 0 is not defined - - Check if we can factor a constant polynomial, see :trac:`8207`:: - - sage: R. = CC[] - sage: R(1).factor() - 1.00000000000000 - - Check that we prohibit too large moduli, :trac:`11829`:: - - sage: R. = GF(previous_prime(2^31))[] - sage: factor(x+y+1,proof=False) - Traceback (most recent call last): - ... - NotImplementedError: Factorization of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented. - - We check that the original issue in :trac:`7554` is fixed:: - - sage: K. = PolynomialRing(QQ) - sage: R. = PolynomialRing(FractionField(K)) - sage: factor(x) - x - - In the example below, we set the special method - ``_factor_multivariate_polynomial()`` in the base ring which is called to - factor multivariate polynomials. This facility can be used to easily - extend polynomial factorization to work over new rings you introduce:: - - sage: R. = PolynomialRing(QQ['z']) - sage: (x*y).factor() - Traceback (most recent call last): - ... - NotImplementedError: ... - sage: R.base_ring()._factor_multivariate_polynomial = lambda f, **kwargs: f.change_ring(QQ).factor() - sage: (x*y).factor() - y * x - sage: del R.base_ring()._factor_multivariate_polynomial # clean up - - Check that a "multivariate" polynomial in one variable is factored - correctly:: - - sage: R. = PolynomialRing(CC,1) - sage: f = z^4 - 6*z + 3 - sage: f.factor() - (z - 1.60443920904349) * (z - 0.511399619393097) * (z + 1.05791941421830 - 1.59281852704435*I) * (z + 1.05791941421830 + 1.59281852704435*I) - - """ - R = self.parent() - - # raise error if trying to factor zero - if not self: - raise ArithmeticError("factorization of {!r} is not defined".format(self)) - - # if number of variables is zero ... - if R.ngens() == 0: - base_ring = self.base_ring() - if base_ring.is_field(): - return Factorization([],unit=self.base_ring()(self)) - else: - F = base_ring(self).factor() - return Factorization([(R(f),m) for f,m in F], unit=F.unit()) - - base_ring = self.base_ring() - if hasattr(base_ring, '_factor_multivariate_polynomial'): - return base_ring._factor_multivariate_polynomial(self, proof=proof) - - # try to use univariate factoring - try: - F = self.univariate_polynomial().factor() - return Factorization([(R(f),m) for f,m in F], unit=F.unit()) - except TypeError: - pass - - base_ring = self.base_ring() - if base_ring.is_finite(): - if base_ring.characteristic() > 1<<29: - raise NotImplementedError("Factorization of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented.") - if proof: - raise NotImplementedError("proof = True factorization not implemented. Call factor with proof=False.") - - R._singular_().set_ring() - S = self._singular_().factorize() - factors = S[1] - exponents = S[2] - v = sorted([(R(factors[i+1]), sage.rings.integer.Integer(exponents[i+1])) \ - for i in range(len(factors))]) - unit = R(1) - for i in range(len(v)): - if v[i][0].is_unit(): - unit = unit * v[i][0] - del v[i] - break - F = sorted(Factorization(v, unit=unit)) - return F - - def lift(self,I): - """ - given an ideal I = (f_1,...,f_r) and some g (== self) in I, find - s_1,...,s_r such that g = s_1 f_1 + ... + s_r f_r - - ALGORITHM: Use Singular. - - EXAMPLES:: - - sage: A. = PolynomialRing(CC,2,order='degrevlex') - sage: I = A.ideal([x^10 + x^9*y^2, y^8 - x^2*y^7 ]) - sage: f = x*y^13 + y^12 - sage: M = f.lift(I) - sage: M - [y^7, x^7*y^2 + x^8 + x^5*y^3 + x^6*y + x^3*y^4 + x^4*y^2 + x*y^5 + x^2*y^3 + y^4] - sage: sum( map( mul , zip( M, I.gens() ) ) ) == f - True - """ - fs = self._singular_() - Is = I._singular_() - P = I.ring() - try: - M = Is.lift(fs)._sage_(P) - except TypeError: - raise ArithmeticError("f is not in I") - return Sequence(M.list(), P, check=False, immutable=True) - - @coerce_binop - def quo_rem(self, right): - """ - Returns quotient and remainder of self and right. - - EXAMPLES:: - - sage: R. = CC[] - sage: f = y*x^2 + x + 1 - sage: f.quo_rem(x) - (x*y + 1.00000000000000, 1.00000000000000) - - sage: R = QQ['a','b']['x','y','z'] - sage: p1 = R('a + (1+2*b)*x*y + (3-a^2)*z') - sage: p2 = R('x-1') - sage: p1.quo_rem(p2) - ((2*b + 1)*y, (2*b + 1)*y + (-a^2 + 3)*z + a) - - sage: R. = Qp(5)[] - sage: x.quo_rem(y) - Traceback (most recent call last): - ... - TypeError: no conversion of this ring to a Singular ring defined - - ALGORITHM: Use Singular. - """ - R = self.parent() - try: - R._singular_().set_ring() - except TypeError: - f = self.parent().flattening_morphism() - if f.domain() != f.codomain(): - g = f.section() - q,r = f(self).quo_rem(f(right)) - return g(q), g(r) - else: - raise - else: - X = self._singular_().division(right._singular_()) - return R(X[1][1,1]), R(X[2][1]) - - def resultant(self, other, variable=None): - """ - Compute the resultant of ``self`` and ``other`` with respect - to ``variable``. - - If a second argument is not provided, the first variable of - ``self.parent()`` is chosen. - - INPUT: - - - ``other`` -- polynomial in ``self.parent()`` - - - ``variable`` -- (optional) variable (of type polynomial) in - ``self.parent()`` - - EXAMPLES:: - - sage: P. = PolynomialRing(QQ, 2) - sage: a = x + y - sage: b = x^3 - y^3 - sage: a.resultant(b) - -2*y^3 - sage: a.resultant(b, y) - 2*x^3 - - TESTS:: - - sage: from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_polydict_domain - sage: P. = MPolynomialRing_polydict_domain(QQ, 2, order='degrevlex') - sage: a = x + y - sage: b = x^3 - y^3 - sage: a.resultant(b) - -2*y^3 - sage: a.resultant(b, y) - 2*x^3 - - Check that :trac:`15061` is fixed:: - - sage: R. = AA[] - sage: (x^2 + 1).resultant(x^2 - y) - y^2 + 2*y + 1 - - """ - R = self.parent() - if variable is None: - variable = R.gen(0) - if R._has_singular: - rt = self._singular_().resultant(other._singular_(), variable._singular_()) - r = rt.sage_poly(R) - else: - r = self.sylvester_matrix(other, variable).det() - if R.ngens() <= 1 and r.degree() <= 0: - return R.base_ring()(r[0]) - else: - return r - - def reduce(self, I): - """ - Reduce this polynomial by the polynomials in `I`. - - INPUT: - - - ``I`` - a list of polynomials or an ideal - - EXAMPLES:: - - sage: P. = QQbar[] - sage: f1 = -2 * x^2 + x^3 - sage: f2 = -2 * y + x* y - sage: f3 = -x^2 + y^2 - sage: F = Ideal([f1,f2,f3]) - sage: g = x*y - 3*x*y^2 - sage: g.reduce(F) - (-6)*y^2 + 2*y - sage: g.reduce(F.gens()) - (-6)*y^2 + 2*y - - :: - - sage: f = 3*x - sage: f.reduce([2*x,y]) - 0 - - :: - - sage: k. = CyclotomicField(3) - sage: A. = PolynomialRing(k) - sage: J = [ y9 + y12] - sage: f = y9 - y12; f.reduce(J) - -2*y12 - sage: f = y13*y15; f.reduce(J) - y13*y15 - sage: f = y13*y15 + y9 - y12; f.reduce(J) - y13*y15 - 2*y12 - - Make sure the remainder returns the correct type, fixing :trac:`13903`:: - - sage: R.=PolynomialRing(Qp(5),2, order='lex') - sage: G=[y1^2 + y2^2, y1*y2 + y2^2, y2^3] - sage: type((y2^3).reduce(G)) - - """ - from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal - - k = self.base_ring() - P = self.parent() - - if isinstance(I, MPolynomialIdeal): - I = I.gens() - - if not k.is_field(): - raise TypeError("Can only reduce polynomials over fields.") - - try: - fs = self._singular_() - Is = fs.parent().ideal(I) - return P(fs.reduce(Is)) - except (NotImplementedError, TypeError): - pass - - lI = len(I) - I = list(I) - r = P.zero() - p = self - - while p != 0: - for i in range(lI): - gi = I[i] - plm = p.lm() - gilm = gi.lm() - if P.monomial_divides(gilm, plm): - quot = p.lc()/gi.lc() * P.monomial_quotient(plm, gilm) - p -= quot*I[i] - break - else: - plt = p.lt() - r += plt - p -= plt - return r - -############################################################### -# Useful for some geometry code. -############################################################### - -def degree_lowest_rational_function(r,x): - r""" - INPUT: - - - - ``r`` - a multivariate rational function - - - ``x`` - a multivariate polynomial ring generator x - - - OUTPUT: - - - - ``integer`` - the degree of r in x and its "leading" - (in the x-adic sense) coefficient. - - - .. note:: - - This function is dependent on the ordering of a python dict. - Thus, it isn't really mathematically well-defined. I think that - it should made a method of the FractionFieldElement class and - rewritten. - - EXAMPLES:: - - sage: R1 = PolynomialRing(FiniteField(5), 3, names = ["a","b","c"]) - sage: F = FractionField(R1) - sage: a,b,c = R1.gens() - sage: f = 3*a*b^2*c^3+4*a*b*c - sage: g = a^2*b*c^2+2*a^2*b^4*c^7 - - Consider the quotient - `f/g = \frac{4 + 3 bc^{2}}{ac + 2 ab^{3}c^{6}}` (note the - cancellation). - - :: - - sage: r = f/g; r - (-b*c^2 + 2)/(a*b^3*c^6 - 2*a*c) - sage: degree_lowest_rational_function(r,a) - (-1, 3) - sage: degree_lowest_rational_function(r,b) - (0, 4) - sage: degree_lowest_rational_function(r,c) - (-1, 4) - """ - from sage.rings.fraction_field import FractionField - R = r.parent() - F = FractionField(R) - r = F(r) - if r == 0: - return (0, F(0)) - L = next(iter(x.dict())) - for ix in range(len(L)): - if L[ix] != 0: - break - f = r.numerator() - g = r.denominator() - M = f.dict() - keys = list(M) - numtermsf = len(M) - degreesf = [keys[j][ix] for j in range(numtermsf)] - lowdegf = min(degreesf) - cf = M[keys[degreesf.index(lowdegf)]] ## constant coeff of lowest degree term - M = g.dict() - keys = list(M) - numtermsg = len(M) - degreesg = [keys[j][ix] for j in range(numtermsg)] - lowdegg = min(degreesg) - cg = M[keys[degreesg.index(lowdegg)]] ## constant coeff of lowest degree term - return (lowdegf-lowdegg,cf/cg) - From 347f0efaae84fe4206bb80349cfa3fde96c6bfea Mon Sep 17 00:00:00 2001 From: Mckenzie West Date: Sat, 30 Jun 2018 19:45:06 +0200 Subject: [PATCH 017/529] re-added multi_polynomial_element.py --- .../polynomial/multi_polynomial_element.py | 2049 +++++++++++++++++ 1 file changed, 2049 insertions(+) create mode 100644 src/sage/rings/polynomial/multi_polynomial_element.py diff --git a/src/sage/rings/polynomial/multi_polynomial_element.py b/src/sage/rings/polynomial/multi_polynomial_element.py new file mode 100644 index 00000000000..9158d067953 --- /dev/null +++ b/src/sage/rings/polynomial/multi_polynomial_element.py @@ -0,0 +1,2049 @@ +""" +Generic Multivariate Polynomials + +AUTHORS: + +- David Joyner: first version + +- William Stein: use dict's instead of lists + +- Martin Albrecht malb@informatik.uni-bremen.de: some functions added + +- William Stein (2006-02-11): added better __div__ behavior. + +- Kiran S. Kedlaya (2006-02-12): added Macaulay2 analogues of some + Singular features + +- William Stein (2006-04-19): added e.g., + ``f[1,3]`` to get coeff of `xy^3`; added examples of the new + ``R.x,y = PolynomialRing(QQ,2)`` notation. + +- Martin Albrecht: improved singular coercions (restructured class + hierarchy) and added ETuples + +- Robert Bradshaw (2007-08-14): added support for coercion of + polynomials in a subset of variables (including multi-level + univariate rings) + +- Joel B. Mohler (2008-03): Refactored interactions with ETuples. + +EXAMPLES: + +We verify Lagrange's four squares identity:: + + sage: R. = QQbar[] + sage: (a0^2 + a1^2 + a2^2 + a3^2)*(b0^2 + b1^2 + b2^2 + b3^2) == (a0*b0 - a1*b1 - a2*b2 - a3*b3)^2 + (a0*b1 + a1*b0 + a2*b3 - a3*b2)^2 + (a0*b2 - a1*b3 + a2*b0 + a3*b1)^2 + (a0*b3 + a1*b2 - a2*b1 + a3*b0)^2 + True +""" +#***************************************************************************** +# +# Sage: System for Algebra and Geometry Experimentation +# +# Copyright (C) 2005 William Stein +# +# Distributed under the terms of the GNU General Public License (GPL) +# +# This code is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# The full text of the GPL is available at: +# +# http://www.gnu.org/licenses/ +#***************************************************************************** +from __future__ import absolute_import +from six.moves import range +from six import iteritems, integer_types + +from sage.structure.element import CommutativeRingElement, canonical_coercion, coerce_binop +from sage.misc.all import prod +import sage.rings.integer +from . import polydict +from sage.structure.factorization import Factorization +from sage.rings.polynomial.polynomial_singular_interface import Polynomial_singular_repr +from sage.structure.sequence import Sequence +from .multi_polynomial import MPolynomial +from sage.categories.morphism import Morphism + + +def is_MPolynomial(x): + return isinstance(x, MPolynomial) + + +class MPolynomial_element(MPolynomial): + def __init__(self, parent, x): + """ + EXAMPLES:: + + sage: K. = NumberField(x^3 - 2) + sage: L. = K.extension(x^3 - 3) + sage: S. = L.extension(x^2 - 2) + sage: S + Number Field in sqrt2 with defining polynomial x^2 - 2 over its base field + sage: P. = PolynomialRing(S) # indirect doctest + """ + CommutativeRingElement.__init__(self, parent) + self.__element = x + + def _repr_(self): + """ + EXAMPLES:: + + sage: P. = PolynomialRing(QQbar) + sage: x + QQbar.random_element() # indirect doctest + x - 4 + """ + return "%s"%self.__element + + #################### + + def __call__(self, *x, **kwds): + r""" + Evaluate this multi-variate polynomial at `x`, where + `x` is either the tuple of values to substitute in, or one + can use functional notation `f(a_0,a_1,a_2, \ldots)` to + evaluate `f` with the ith variable replaced by + `a_i`. + + EXAMPLES:: + + sage: R. = CC[] + sage: f = x^2 + y^2 + sage: f(1,2) + 5.00000000000000 + sage: f((1,2)) + 5.00000000000000 + + :: + + sage: x = PolynomialRing(CC,3,'x').gens() + sage: f = x[0] + x[1] - 2*x[1]*x[2] + sage: f + (-2.00000000000000)*x1*x2 + x0 + x1 + sage: f(1,2,0) + 3.00000000000000 + sage: f(1,2,5) + -17.0000000000000 + + AUTHORS: + + - David Kohel (2005-09-27) + """ + if len(kwds) > 0: + f = self.subs(**kwds) + if len(x) > 0: + return f(*x) + else: + return f + if len(x) == 1 and isinstance(x[0], (list, tuple)): + x = x[0] + n = self.parent().ngens() + if len(x) != n: + raise TypeError("x must be of correct length") + if n == 0: + return self + try: + K = x[0].parent() + except AttributeError: + K = self.parent().base_ring() + y = K(0) + for (m,c) in iteritems(self.element().dict()): + y += c*prod([ x[i]**m[i] for i in range(n) if m[i] != 0]) + return y + + def _richcmp_(self, right, op): + """ + Compare ``self`` to ``right`` with respect to the term order of + self.parent(). + + EXAMPLES:: + + sage: R.=PolynomialRing(QQbar,3,order='lex') + sage: x^1*y^2 > y^3*z^4 + True + sage: x^3*y^2*z^4 < x^3*y^2*z^1 + False + + :: + + sage: R.=PolynomialRing(CC,3,order='deglex') + sage: x^1*y^2*z^3 > x^3*y^2*z^0 + True + sage: x^1*y^2*z^4 < x^1*y^1*z^5 + False + + :: + + sage: R.=PolynomialRing(QQbar,3,order='degrevlex') + sage: x^1*y^5*z^2 > x^4*y^1*z^3 + True + sage: x^4*y^7*z^1 < x^4*y^2*z^3 + False + """ + return self.__element.rich_compare(right.__element, op, + self.parent().term_order().sortkey) + + def _im_gens_(self, codomain, im_gens): + """ + EXAMPLES:: + + sage: R. = PolynomialRing(QQbar, 2) + sage: f = R.hom([y,x], R) + sage: f(x^2 + 3*y^5) + 3*x^5 + y^2 + """ + n = self.parent().ngens() + if n == 0: + return codomain._coerce_(self) + y = codomain(0) + for (m,c) in iteritems(self.element().dict()): + y += codomain(c)*prod([ im_gens[i]**m[i] for i in range(n) if m[i] ]) + return y + + def number_of_terms(self): + """ + Return the number of non-zero coefficients of this polynomial. + + This is also called weight, :meth:`hamming_weight` or sparsity. + + EXAMPLES:: + + sage: R. = CC[] + sage: f = x^3 - y + sage: f.number_of_terms() + 2 + sage: R(0).number_of_terms() + 0 + sage: f = (x+y)^100 + sage: f.number_of_terms() + 101 + + The method :meth:`hamming_weight` is an alias:: + + sage: f.hamming_weight() + 101 + """ + return len(self.element().dict()) + + hamming_weight = number_of_terms + + def _add_(self, right): + #return self.parent()(self.__element + right.__element) + return self.__class__(self.parent(),self.__element + right.__element) + + def _sub_(self, right): + # return self.parent()(self.__element - right.__element) + return self.__class__(self.parent(),self.__element - right.__element) + + def _mul_(self, right): + #return self.parent()(self.__element * right.__element) + return self.__class__(self.parent(),self.__element * right.__element) + + def _lmul_(self, a): + """ + Left Scalar Multiplication + + EXAMPLES: + + Note that it is not really possible to do a meaningful + example since sage mpoly rings refuse to have non-commutative + bases. + + :: + + sage: R. = QQbar[] + sage: f = (x + y) + sage: 3*f + 3*x + 3*y + """ + return self.__class__(self.parent(),self.__element.scalar_lmult(a)) + + def _rmul_(self, a): + """ + Right Scalar Multiplication + + EXAMPLES: + + Note that it is not really possible to do a meaningful + example since sage mpoly rings refuse to have non-commutative + bases. + + :: + + sage: R. = QQbar[] + sage: f = (x + y) + sage: f*3 + 3*x + 3*y + """ + return self.__class__(self.parent(),self.__element.scalar_rmult(a)) + + def _div_(self, right): + r""" + EXAMPLES:: + + sage: R. = CC['x,y'] + sage: f = (x + y)/x; f + (x + y)/x + sage: f.parent() + Fraction Field of Multivariate Polynomial Ring in x, y over + Complex Field with 53 bits of precision + + If dividing by a scalar, there is no need to go to the fraction + field of the polynomial ring:: + + sage: f = (x + y)/2; f + 0.500000000000000*x + 0.500000000000000*y + sage: f.parent() + Multivariate Polynomial Ring in x, y over Complex Field with + 53 bits of precision + + TESTS: + + Ensure that :trac:`13704` is fixed.:: + + sage: R.=PolynomialRing(QQ) + sage: S.=PolynomialRing(R) + sage: x/S(2) + 1/2*x + """ + if right in self.base_ring(): + inv = self.base_ring().one()/self.base_ring()(right) + return inv*self + return self.parent().fraction_field()(self, right, coerce=False) + + def __rpow__(self, n): + if not isinstance(n, integer_types + (sage.rings.integer.Integer,)): + raise TypeError("The exponent must be an integer.") + return self.parent()(self.__element**n) + + def element(self): + return self.__element + + def change_ring(self, R): + r""" + Change the base ring of this polynomial to ``R``. + + INPUT: + + - ``R`` -- ring or morphism. + + OUTPUT: a new polynomial converted to ``R``. + + EXAMPLES:: + + sage: R. = QQ[] + sage: f = x^2 + 5*y + sage: f.change_ring(GF(5)) + x^2 + + :: + + sage: K. = CyclotomicField(5) + sage: R. = K[] + sage: f = x^2 + w*y + sage: f.change_ring(K.embeddings(QQbar)[1]) + x^2 + (-0.8090169943749474? + 0.5877852522924731?*I)*y + """ + if isinstance(R, Morphism): + #if we're given a hom of the base ring extend to a poly hom + if R.domain() == self.base_ring(): + R = self.parent().hom(R, self.parent().change_ring(R.codomain())) + return R(self) + else: + return self.parent().change_ring(R)(self) + + +class MPolynomial_polydict(Polynomial_singular_repr, MPolynomial_element): + r""" + Multivariate polynomials implemented in pure python using + polydicts. + """ + def __init__(self, parent, x): + """ + EXAMPLES:: + + sage: R, x = PolynomialRing(QQbar, 10, 'x').objgens() + sage: x + (x0, x1, x2, x3, x4, x5, x6, x7, x8, x9) + sage: loads(dumps(x)) == x + True + """ + if not isinstance(x, polydict.PolyDict): + x = polydict.PolyDict(x, parent.base_ring()(0), remove_zero=True) + MPolynomial_element.__init__(self, parent, x) + + def _new_constant_poly(self, x, P): + """ + Quickly create a new constant polynomial with value x in parent P. + + ASSUMPTION: + + x must be an element of the base ring of P. That assumption is + not verified. + + EXAMPLES:: + + sage: R. = QQ['t'][] + sage: x._new_constant_poly(R.base_ring()(2),R) + 2 + + """ + return MPolynomial_polydict(P, {P._zero_tuple:x}) + + def __neg__(self): + """ + EXAMPLES:: + + sage: R.=QQbar[] + sage: -x + -x + sage: -(y-1) + -y + 1 + """ + return self*(-1) + + def _repr_(self): + """ + EXAMPLES:: + + sage: R.=QQbar[] + sage: repr(-x^2-y+1) # indirect doc-test + '-x^2 - y + 1' + sage: K.=QuadraticField(-1) + sage: R.=K[] + sage: repr(-I*y-x^2) # indirect doc-test + '-x^2 + (-I)*y' + """ + try: + key = self.parent().term_order().sortkey + except AttributeError: + key = None + atomic = self.parent().base_ring()._repr_option('element_is_atomic') + return self.element().poly_repr(self.parent().variable_names(), + atomic_coefficients=atomic, + sortkey=key) + + def _latex_(self): + r""" + EXAMPLES:: + + sage: R.=QQbar[] + sage: latex(-x^2-y+1) + -x^{2} - y + 1 + sage: K.=QuadraticField(-1) + sage: R.=K[] + sage: latex(-I*y+I*x^2) + \left(\sqrt{-1}\right) x^{2} + \left(-\sqrt{-1}\right) y + """ + try: + key = self.parent().term_order().sortkey + except AttributeError: + key = None + atomic = self.parent().base_ring()._repr_option('element_is_atomic') + return self.element().latex(self.parent().latex_variable_names(), + atomic_coefficients=atomic, sortkey=key) + + def _repr_with_changed_varnames(self, varnames): + """ + EXAMPLES:: + + sage: R.=QQbar[] + sage: f=-x^2-y+1 + sage: f._repr_with_changed_varnames(['jack','jill']) + '-jack^2 - jill + 1' + """ + try: + key = self.parent().term_order().sortkey + except AttributeError: + key = None + atomic = self.parent().base_ring()._repr_option('element_is_atomic') + return self.element().poly_repr(varnames, + atomic_coefficients=atomic, sortkey=key) + + def degrees(self): + r""" + Returns a tuple (precisely - an ``ETuple``) with the + degree of each variable in this polynomial. The list of degrees is, + of course, ordered by the order of the generators. + + EXAMPLES:: + + sage: R.=PolynomialRing(QQbar) + sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 + sage: f.degrees() + (2, 2, 0) + sage: f = x^2+z^2 + sage: f.degrees() + (2, 0, 2) + sage: f.total_degree() # this simply illustrates that total degree is not the sum of the degrees + 2 + sage: R.=PolynomialRing(QQbar) + sage: f=(1-x)*(1+y+z+x^3)^5 + sage: f.degrees() + (16, 5, 5, 0) + sage: R(0).degrees() + (0, 0, 0, 0) + """ + if self.is_zero(): + return polydict.ETuple({},self.parent().ngens()) + else: + return self._MPolynomial_element__element.max_exp() + + def degree(self, x=None, std_grading=False): + """ + Return the degree of self in x, where x must be one of the + generators for the parent of self. + + INPUT: + + - ``x`` - multivariate polynomial (a generator of the parent + of self). If ``x`` is not specified (or is None), return + the total degree, which is the maximum degree of any + monomial. Note that a weighted term ordering alters the + grading of the generators of the ring; see the tests below. + To avoid this behavior, set the optional argument ``std_grading=True``. + + OUTPUT: integer + + EXAMPLES:: + + sage: R. = RR[] + sage: f = y^2 - x^9 - x + sage: f.degree(x) + 9 + sage: f.degree(y) + 2 + sage: (y^10*x - 7*x^2*y^5 + 5*x^3).degree(x) + 3 + sage: (y^10*x - 7*x^2*y^5 + 5*x^3).degree(y) + 10 + + Note that total degree takes into account if we are working in a polynomial + ring with a weighted term order. + + :: + + sage: R = PolynomialRing(QQ,'x,y',order=TermOrder('wdeglex',(2,3))) + sage: x,y = R.gens() + sage: x.degree() + 2 + sage: y.degree() + 3 + sage: x.degree(y),x.degree(x),y.degree(x),y.degree(y) + (0, 1, 0, 1) + sage: f = (x^2*y+x*y^2) + sage: f.degree(x) + 2 + sage: f.degree(y) + 2 + sage: f.degree() + 8 + sage: f.degree(std_grading=True) + 3 + + Note that if ``x`` is not a generator of the parent of self, + for example if it is a generator of a polynomial algebra which + maps naturally to this one, then it is converted to an element + of this algebra. (This fixes the problem reported in + :trac:`17366`.) + + :: + + sage: x, y = ZZ['x','y'].gens() + sage: GF(3037000453)['x','y'].gen(0).degree(x) + 1 + + sage: x0, y0 = QQ['x','y'].gens() + sage: GF(3037000453)['x','y'].gen(0).degree(x0) + Traceback (most recent call last): + ... + TypeError: x must canonically coerce to parent + + sage: GF(3037000453)['x','y'].gen(0).degree(x^2) + Traceback (most recent call last): + ... + TypeError: x must be one of the generators of the parent + + TESTS:: + + sage: R = PolynomialRing(GF(2)['t'],'x,y',order=TermOrder('wdeglex',(2,3))) + sage: x,y = R.gens() + sage: x.degree() + 2 + sage: y.degree() + 3 + sage: x.degree(y),x.degree(x),y.degree(x),y.degree(y) + (0, 1, 0, 1) + sage: f = (x^2*y+x*y^2) + sage: f.degree(x) + 2 + sage: f.degree(y) + 2 + sage: f.degree() + 8 + sage: f.degree(std_grading=True) + 3 + sage: R(0).degree() + -1 + + Degree of zero polynomial for other implementation :trac:`20048` :: + + sage: R. = GF(3037000453)[] + sage: R.zero().degree(x) + -1 + """ + if x is None: + if std_grading or not self.parent().term_order().is_weighted_degree_order(): + return self.element().degree(None) + return self.weighted_degree(self.parent().term_order().weights()) + if isinstance(x, MPolynomial): + if not x.parent() is self.parent(): + try: + x = self.parent().coerce(x) + except TypeError: + raise TypeError("x must canonically coerce to parent") + if not x.is_generator(): + raise TypeError("x must be one of the generators of the parent") + else: + raise TypeError("x must be one of the generators of the parent") + return self.element().degree(x.element()) + + def total_degree(self): + """ + Return the total degree of self, which is the maximum degree of any + monomial in self. + + EXAMPLES:: + + sage: R. = QQbar[] + sage: f=2*x*y^3*z^2 + sage: f.total_degree() + 6 + sage: f=4*x^2*y^2*z^3 + sage: f.total_degree() + 7 + sage: f=99*x^6*y^3*z^9 + sage: f.total_degree() + 18 + sage: f=x*y^3*z^6+3*x^2 + sage: f.total_degree() + 10 + sage: f=z^3+8*x^4*y^5*z + sage: f.total_degree() + 10 + sage: f=z^9+10*x^4+y^8*x^2 + sage: f.total_degree() + 10 + """ + return self.degree() + + def monomial_coefficient(self, mon): + """ + Return the coefficient in the base ring of the monomial mon in + self, where mon must have the same parent as self. + + This function contrasts with the function + ``coefficient`` which returns the coefficient of a + monomial viewing this polynomial in a polynomial ring over a base + ring having fewer variables. + + INPUT: + + - ``mon`` - a monomial + + + OUTPUT: coefficient in base ring + + .. SEEALSO:: + + For coefficients in a base ring of fewer variables, look + at :meth:`coefficient`. + + EXAMPLES: + + The parent of the return is a member of the base ring. + + :: + + sage: R.=QQbar[] + + The parent of the return is a member of the base ring. + + :: + + sage: f = 2 * x * y + sage: c = f.monomial_coefficient(x*y); c + 2 + sage: c.parent() + Algebraic Field + + :: + + sage: f = y^2 + y^2*x - x^9 - 7*x + 5*x*y + sage: f.monomial_coefficient(y^2) + 1 + sage: f.monomial_coefficient(x*y) + 5 + sage: f.monomial_coefficient(x^9) + -1 + sage: f.monomial_coefficient(x^10) + 0 + + :: + + sage: var('a') + a + sage: K. = NumberField(a^2+a+1) + sage: P. = K[] + sage: f=(a*x-1)*((a+1)*y-1); f + -x*y + (-a)*x + (-a - 1)*y + 1 + sage: f.monomial_coefficient(x) + -a + """ + if not (isinstance(mon, MPolynomial) and mon.parent() is self.parent() and mon.is_monomial()): + raise TypeError("mon must be a monomial in the parent of self.") + R = self.parent().base_ring() + return R(self.element().monomial_coefficient(mon.element().dict())) + + def dict(self): + """ + Return underlying dictionary with keys the exponents and values + the coefficients of this polynomial. + """ + return self.element().dict() + + #def __iter__(self): + # """ + # Facilitates iterating over the monomials of self, + # returning tuples of the form (coeff, mon) for each + # non-zero monomial. + # + # EXAMPLES:: + + # sage: R = ZZ['t'] + # sage: P. = PolynomialRing(R,3) + # sage: f = 3*x^3*y + 16*x + 7 + # sage: [(c,m) for c,m in f] + # [(3, x^3*y), (16, x), (7, 1)] + # sage: f = P.random_element(10,10) + # sage: sum(c*m for c,m in f) == f + # True + # """ + # exps = self.exponents() + # parent = self.parent() + # for exp in exps: + # yield self.element()[exp], MPolynomial_polydict(parent, {exp: 1}) + + def __getitem__(self, x): + """ + INPUT: + + + - ``x`` - a tuple or, in case of a single-variable + MPolynomial ring x can also be an integer. + + + EXAMPLES:: + + sage: R. = PolynomialRing(QQbar, 2) + sage: f = -10*x^3*y + 17*x*y + sage: f[3,1] + -10 + sage: f[1,1] + 17 + sage: f[0,1] + 0 + + :: + + sage: R. = PolynomialRing(QQbar,1); R + Multivariate Polynomial Ring in x over Algebraic Field + sage: f = 5*x^2 + 3; f + 5*x^2 + 3 + sage: f[2] + 5 + """ + if isinstance(x, MPolynomial): + return self.monomial_coefficient(x) + if not isinstance(x, tuple): + try: + x = tuple(x) + except TypeError: + x = (x, ) + try: + return self.element()[x] + except KeyError: + return self.parent().base_ring()(0) + + def coefficient(self, degrees): + """ + Return the coefficient of the variables with the degrees specified + in the python dictionary ``degrees``. Mathematically, + this is the coefficient in the base ring adjoined by the variables + of this ring not listed in ``degrees``. However, the + result has the same parent as this polynomial. + + This function contrasts with the function + ``monomial_coefficient`` which returns the coefficient + in the base ring of a monomial. + + INPUT: + + + - ``degrees`` - Can be any of: + + - a dictionary of degree restrictions + + - a list of degree restrictions (with None in + the unrestricted variables) + + - a monomial (very fast, but not as flexible) + + + OUTPUT: element of the parent of self + + .. SEEALSO:: + + For coefficients of specific monomials, look at + :meth:`monomial_coefficient`. + + EXAMPLES:: + + sage: R. = QQbar[] + sage: f = 2 * x * y + sage: c = f.coefficient({x:1,y:1}); c + 2 + sage: c.parent() + Multivariate Polynomial Ring in x, y over Algebraic Field + sage: c in PolynomialRing(QQbar, 2, names = ['x','y']) + True + sage: f = y^2 - x^9 - 7*x + 5*x*y + sage: f.coefficient({y:1}) + 5*x + sage: f.coefficient({y:0}) + -x^9 + (-7)*x + sage: f.coefficient({x:0,y:0}) + 0 + sage: f=(1+y+y^2)*(1+x+x^2) + sage: f.coefficient({x:0}) + y^2 + y + 1 + sage: f.coefficient([0,None]) + y^2 + y + 1 + sage: f.coefficient(x) + y^2 + y + 1 + sage: # Be aware that this may not be what you think! + sage: # The physical appearance of the variable x is deceiving -- particularly if the exponent would be a variable. + sage: f.coefficient(x^0) # outputs the full polynomial + x^2*y^2 + x^2*y + x*y^2 + x^2 + x*y + y^2 + x + y + 1 + + :: + + sage: R. = RR[] + sage: f=x*y+5 + sage: c=f.coefficient({x:0,y:0}); c + 5.00000000000000 + sage: parent(c) + Multivariate Polynomial Ring in x, y over Real Field with 53 bits of precision + + AUTHORS: + + - Joel B. Mohler (2007-10-31) + """ + looking_for = None + if isinstance(degrees, MPolynomial) and degrees.parent() == self.parent() and degrees.is_monomial(): + looking_for = [e if e > 0 else None for e in degrees.exponents()[0]] + elif isinstance(degrees, list): + looking_for = degrees + elif isinstance(degrees, dict): + poly_vars = self.parent().gens() + looking_for = [None] * len(poly_vars) + for d, exp in degrees.items(): + for i in range(len(poly_vars)): + if d == poly_vars[i]: + looking_for[i] = exp + if not looking_for: + raise ValueError("You must pass a dictionary list or monomial.") + return self.parent()(self.element().polynomial_coefficient(looking_for)) + + def exponents(self, as_ETuples=True): + """ + Return the exponents of the monomials appearing in self. + + INPUT: + + - as_ETuples (default: ``True``): return the list of exponents as a list + of ETuples. + + OUTPUT: + + Return the list of exponents as a list of ETuples or tuples. + + EXAMPLES:: + + sage: R. = PolynomialRing(QQbar, 3) + sage: f = a^3 + b + 2*b^2 + sage: f.exponents() + [(3, 0, 0), (0, 2, 0), (0, 1, 0)] + + Be default the list of exponents is a list of ETuples:: + + sage: type(f.exponents()[0]) + + sage: type(f.exponents(as_ETuples=False)[0]) + <... 'tuple'> + """ + try: + exp = self.__exponents + if as_ETuples: + return exp + else: + return [tuple(e) for e in exp] + except AttributeError: + self.__exponents = list(self.element().dict()) + try: + self.__exponents.sort(key=self.parent().term_order().sortkey, + reverse=True) + except AttributeError: + pass + if as_ETuples: + return self.__exponents + else: + return [tuple(e) for e in self.__exponents] + + def inverse_of_unit(self): + d = self.element().dict() + k = list(d) + if self.is_unit(): + if len(k) != 1: + raise NotImplementedError + return ~d[k[0]] + raise ArithmeticError("is not a unit") + + def is_homogeneous(self): + """ + Return True if self is a homogeneous polynomial. + + EXAMPLES:: + + sage: R. = QQbar[] + sage: (x+y).is_homogeneous() + True + sage: (x.parent()(0)).is_homogeneous() + True + sage: (x+y^2).is_homogeneous() + False + sage: (x^2 + y^2).is_homogeneous() + True + sage: (x^2 + y^2*x).is_homogeneous() + False + sage: (x^2*y + y^2*x).is_homogeneous() + True + """ + return self.element().is_homogeneous() + + def _homogenize(self, var): + r""" + Return ``self`` if ``self`` is homogeneous. + Otherwise return a homogenized polynomial constructed by modifying + the degree of the variable with index ``var``. + + INPUT: + + + - ``var`` - an integer indicating which variable to + use to homogenize (0 <= var < parent(self).ngens()) + + + OUTPUT: a multivariate polynomial + + EXAMPLES:: + + sage: P. = QQbar[] + sage: f = x^2 + y + 1 + 5*x*y^1 + sage: g = f.homogenize('z'); g # indirect doctest + x^2 + 5*x*y + y*z + z^2 + sage: g.parent() + Multivariate Polynomial Ring in x, y, z over Algebraic Field + + SEE: ``self.homogenize`` + """ + if self.is_homogeneous(): + return self + X = self.element().homogenize(var) + R = self.parent() + return R(X) + + def is_generator(self): + """ + Returns True if self is a generator of it's parent. + + EXAMPLES:: + + sage: R.=QQbar[] + sage: x.is_generator() + True + sage: (x+y-y).is_generator() + True + sage: (x*y).is_generator() + False + """ + d = self.element().dict() + if len(d) == 1: + (e, c), = d.items() + if c.is_one() and len(e.nonzero_positions()) == 1 and e.nonzero_values()[0] == 1: + return True + return False + + def is_monomial(self): + """ + Returns True if self is a monomial, which we define to be a + product of generators with coefficient 1. + + Use is_term to allow the coefficient to not be 1. + + EXAMPLES:: + + sage: R.=QQbar[] + sage: x.is_monomial() + True + sage: (x+2*y).is_monomial() + False + sage: (2*x).is_monomial() + False + sage: (x*y).is_monomial() + True + + To allow a non-1 leading coefficient, use is_term():: + + sage: (2*x*y).is_term() + True + sage: (2*x*y).is_monomial() + False + """ + term = (len(self.element().dict().keys()) == 1) + if term: + if self.coefficients()[0] == 1: + return True + else: + return False + else: + return False + + def is_term(self): + """ + Returns True if self is a term, which we define to be a + product of generators times some coefficient, which need + not be 1. + + Use :meth:`is_monomial` to require that the coefficient be 1. + + EXAMPLES:: + + sage: R.=QQbar[] + sage: x.is_term() + True + sage: (x+2*y).is_term() + False + sage: (2*x).is_term() + True + sage: (7*x^5*y).is_term() + True + + To require leading coefficient 1, use is_monomial():: + + sage: (2*x*y).is_monomial() + False + sage: (2*x*y).is_term() + True + """ + return len(self.element().dict().keys()) == 1 + + def subs(self, fixed=None, **kw): + """ + Fixes some given variables in a given multivariate polynomial and + returns the changed multivariate polynomials. The polynomial itself + is not affected. The variable,value pairs for fixing are to be + provided as a dictionary of the form {variable:value}. + + This is a special case of evaluating the polynomial with some of + the variables constants and the others the original variables. + + INPUT: + + + - ``fixed`` - (optional) dictionary of inputs + + - ``**kw`` - named parameters + + + OUTPUT: new MPolynomial + + EXAMPLES:: + + sage: R. = QQbar[] + sage: f = x^2 + y + x^2*y^2 + 5 + sage: f((5,y)) + 25*y^2 + y + 30 + sage: f.subs({x:5}) + 25*y^2 + y + 30 + """ + variables = list(self.parent().gens()) + for i in range(0,len(variables)): + if str(variables[i]) in kw: + variables[i]=kw[str(variables[i])] + elif fixed and variables[i] in fixed: + variables[i] = fixed[variables[i]] + return self(tuple(variables)) + + def monomials(self): + """ + Returns the list of monomials in self. The returned list is + decreasingly ordered by the term ordering of self.parent(). + + OUTPUT: list of MPolynomials representing Monomials + + EXAMPLES:: + + sage: R. = QQbar[] + sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 + sage: f.monomials() + [x^2*y^2, x^2, y, 1] + + :: + + sage: R. = QQbar[] + sage: F = ((fx*gy - fy*gx)^3) + sage: F + -fy^3*gx^3 + 3*fx*fy^2*gx^2*gy + (-3)*fx^2*fy*gx*gy^2 + fx^3*gy^3 + sage: F.monomials() + [fy^3*gx^3, fx*fy^2*gx^2*gy, fx^2*fy*gx*gy^2, fx^3*gy^3] + sage: F.coefficients() + [-1, 3, -3, 1] + sage: sum(map(mul,zip(F.coefficients(),F.monomials()))) == F + True + """ + ring = self.parent() + one = ring.base_ring()(1) + return [MPolynomial_polydict(ring, polydict.PolyDict({m:one}, force_int_exponents=False, force_etuples=False)) for m in self.exponents()] + try: + return self.__monomials + except AttributeError: + ring = self.parent() + one = self.parent().base_ring()(1) + self.__monomials = sorted([ MPolynomial_polydict(ring, polydict.PolyDict( {m:one}, force_int_exponents=False, force_etuples=False ) ) \ + for m in self._MPolynomial_element__element.dict().keys() ], reverse=True) + return self.__monomials + + def constant_coefficient(self): + """ + Return the constant coefficient of this multivariate polynomial. + + EXAMPLES:: + + sage: R. = QQbar[] + sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 + sage: f.constant_coefficient() + 5 + sage: f = 3*x^2 + sage: f.constant_coefficient() + 0 + """ + #v = (0,)*int(self.parent().ngens()) + d = self.element().dict() + try: + return d[polydict.ETuple({},self.parent().ngens())] + except KeyError: + return self.parent().base_ring()(0) + + def is_univariate(self): + """ + Returns True if this multivariate polynomial is univariate and + False otherwise. + + EXAMPLES:: + + sage: R. = QQbar[] + sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 + sage: f.is_univariate() + False + sage: g = f.subs({x:10}); g + 700*y^2 + (-2)*y + 305 + sage: g.is_univariate() + True + sage: f = x^0 + sage: f.is_univariate() + True + """ + mons = self.element().dict().keys() + + found = -1 + for mon in mons: + for i in mon.nonzero_positions(): + if found != i: + if found != -1: + return False + else: + found = i + return True + + def univariate_polynomial(self, R=None): + """ + Returns a univariate polynomial associated to this multivariate + polynomial. + + INPUT: + + + - ``R`` - (default: None) PolynomialRing + + + If this polynomial is not in at most one variable, then a + ValueError exception is raised. This is checked using the + is_univariate() method. The new Polynomial is over the same base + ring as the given MPolynomial. + + EXAMPLES:: + + sage: R. = QQbar[] + sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 + sage: f.univariate_polynomial() + Traceback (most recent call last): + ... + TypeError: polynomial must involve at most one variable + sage: g = f.subs({x:10}); g + 700*y^2 + (-2)*y + 305 + sage: g.univariate_polynomial () + 700*y^2 - 2*y + 305 + sage: g.univariate_polynomial(PolynomialRing(QQ,'z')) + 700*z^2 - 2*z + 305 + + TESTS:: + + sage: P = PolynomialRing(QQ, 0, '') + sage: P(5).univariate_polynomial() + 5 + """ + if self.parent().ngens() == 0: + if R is None: + return self.base_ring()(self) + else: + return R(self) + + if not self.is_univariate(): + raise TypeError("polynomial must involve at most one variable") + + #construct ring if None + if R is None: + # constant, we just pick first variable from parent + if self.is_constant(): + R = self.base_ring()[self.parent().variable_names()[0]] + else: + R = self.base_ring()[str(self.variables()[0])] + + monomial_coefficients = self._MPolynomial_element__element.dict() + + if( not self.is_constant() ): + var_idx = self.degrees().nonzero_positions()[0] #variable + else: + var_idx = 0; #constant + if( len(monomial_coefficients.keys())==0 ): + return R(0) + + #construct list + lookup = [int(0),] * len(next(iter(monomial_coefficients))) + coefficients = [] + for degree in range(max(m[var_idx] + for m in monomial_coefficients.keys()) + 1): + lookup[var_idx] = int(degree) + try: + coefficients.append( monomial_coefficients[ polydict.ETuple(lookup) ] ) #if we find something, add the coefficient + except KeyError: + coefficients.append( 0 ) #else add zero + + #construct polynomial + return R(coefficients) + + def variables(self): + """ + Returns the tuple of variables occurring in this polynomial. + + EXAMPLES:: + + sage: R. = QQbar[] + sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 + sage: f.variables() + (x, y) + sage: g = f.subs({x:10}); g + 700*y^2 + (-2)*y + 305 + sage: g.variables() + (y,) + + TESTS: + + This shows that the issue at :trac:`7077` is fixed:: + + sage: x,y,z=polygens(QQ,'x,y,z') + sage: (x^2).variables() + (x,) + """ + return tuple([self.parent().gen(index) for index in self.degrees().nonzero_positions()]) + + def variable(self,i): + """ + Returns `i`-th variable occurring in this polynomial. + + EXAMPLES:: + + sage: R. = QQbar[] + sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 + sage: f.variable(0) + x + sage: f.variable(1) + y + """ + return self.variables()[int(i)] + + def nvariables(self): + """ + Number of variables in this polynomial + + EXAMPLES:: + + sage: R. = QQbar[] + sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 + sage: f.nvariables () + 2 + sage: g = f.subs({x:10}); g + 700*y^2 + (-2)*y + 305 + sage: g.nvariables () + 1 + """ + return len(self.degrees().nonzero_positions()) + + def is_constant(self): + """ + True if polynomial is constant, and False otherwise. + + EXAMPLES:: + + sage: R. = QQbar[] + sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 + sage: f.is_constant() + False + sage: g = 10*x^0 + sage: g.is_constant() + True + """ + if len(self.dict()) <= 1 and self.degrees().is_constant(): + return True + else: + return False + + def lm(self): + """ + Returns the lead monomial of self with respect to the term order of + self.parent(). + + EXAMPLES:: + + sage: R.=PolynomialRing(GF(7),3,order='lex') + sage: (x^1*y^2 + y^3*z^4).lm() + x*y^2 + sage: (x^3*y^2*z^4 + x^3*y^2*z^1).lm() + x^3*y^2*z^4 + + :: + + sage: R.=PolynomialRing(CC,3,order='deglex') + sage: (x^1*y^2*z^3 + x^3*y^2*z^0).lm() + x*y^2*z^3 + sage: (x^1*y^2*z^4 + x^1*y^1*z^5).lm() + x*y^2*z^4 + + :: + + sage: R.=PolynomialRing(QQbar,3,order='degrevlex') + sage: (x^1*y^5*z^2 + x^4*y^1*z^3).lm() + x*y^5*z^2 + sage: (x^4*y^7*z^1 + x^4*y^2*z^3).lm() + x^4*y^7*z + + TESTS:: + + sage: from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_polydict + sage: R.=MPolynomialRing_polydict(GF(2),2,order='lex') + sage: f=x+y + sage: f.lm() + x + + """ + try: + return self.__lm + except AttributeError: + if self.is_zero(): + return self + R = self.parent() + f = self._MPolynomial_element__element.lcmt( R.term_order().greater_tuple ) + one = R.base_ring()(1) + self.__lm = MPolynomial_polydict(R,polydict.PolyDict({f:one},zero=R.base_ring().zero(),force_int_exponents=False, force_etuples=False)) + return self.__lm + + def lc(self): + """ + Returns the leading coefficient of self i.e., + self.coefficient(self.lm()) + + EXAMPLES:: + + sage: R.=QQbar[] + sage: f=3*x^2-y^2-x*y + sage: f.lc() + 3 + """ + try: + return self.__lc + except AttributeError: + if self.is_zero(): + return self.base_ring()._zero_element + R = self.parent() + f = self._MPolynomial_element__element.dict() + self.__lc = f[self._MPolynomial_element__element.lcmt( R.term_order().greater_tuple )] + return self.__lc + + def lt(self): + """ + Returns the leading term of self i.e., self.lc()\*self.lm(). The + notion of "leading term" depends on the ordering defined in the + parent ring. + + EXAMPLES:: + + sage: R.=PolynomialRing(QQbar) + sage: f=3*x^2-y^2-x*y + sage: f.lt() + 3*x^2 + sage: R.=PolynomialRing(QQbar,order="invlex") + sage: f=3*x^2-y^2-x*y + sage: f.lt() + -y^2 + + TESTS:: + + sage: from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_polydict + sage: R.=MPolynomialRing_polydict(GF(2),2,order='lex') + sage: f=x+y + sage: f.lt() + x + + """ + try: + return self.__lt + except AttributeError: + if self.is_zero(): + return self + R = self.parent() + f = self._MPolynomial_element__element.dict() + res = self._MPolynomial_element__element.lcmt( R.term_order().greater_tuple ) + self.__lt = MPolynomial_polydict(R,polydict.PolyDict({res:f[res]},zero=R.base_ring().zero(),force_int_exponents=False, force_etuples=False)) + return self.__lt + + def __eq__(self,right): + if not isinstance(right, MPolynomial_polydict): + # we want comparison with zero to be fast + if not right: + return not self._MPolynomial_element__element.dict() + return CommutativeRingElement.__eq__(self, right) + return self._MPolynomial_element__element == right._MPolynomial_element__element + + def __ne__(self,right): + if not isinstance(right, MPolynomial_polydict): + # we want comparison with zero to be fast + if not right: + return not not self._MPolynomial_element__element.dict() + return CommutativeRingElement.__ne__(self, right) + return self._MPolynomial_element__element != right._MPolynomial_element__element + + def __bool__(self): + """ + Returns True if self != 0 + + .. note:: + + This is much faster than actually writing ``self == 0``. + """ + return self._MPolynomial_element__element.dict()!={} + + __nonzero__ = __bool__ + + def _floordiv_(self, right): + r""" + Quotient of division of self by other. This is denoted //. + + .. note:: + + It's not clear to me that this is well-defined if + ``self`` is not exactly divisible by other. + + EXAMPLES:: + + sage: R.=QQbar[] + sage: 2*x*y//y + 2*x + sage: 2*x//y + 0 + sage: 2*x//4 + 1/2*x + sage: type(0//y) + + """ + # handle division by monomials without using Singular + if len(right.dict()) == 1: + P = self.parent() + ret = P(0) + denC,denM = next(iter(right)) + for c,m in self: + t = c*m + if denC.divides(c) and P.monomial_divides(denM, m): + ret += P.monomial_quotient(t, right, coeff=True) + return ret + + Q, _ = self.quo_rem(right) + return Q + + def _derivative(self, var=None): + r""" + Differentiates ``self`` with respect to variable ``var``. + + If ``var`` is not one of the generators of this ring, _derivative(var) + is called recursively on each coefficient of this polynomial. + + .. SEEALSO:: + + :meth:`derivative` + + EXAMPLES:: + + sage: R. = PowerSeriesRing(QQbar) + sage: S. = PolynomialRing(R) + sage: f = (t^2 + O(t^3))*x^2*y^3 + (37*t^4 + O(t^5))*x^3 + sage: f.parent() + Multivariate Polynomial Ring in x, y over Power Series Ring in t over Algebraic Field + sage: f._derivative(x) # with respect to x + (2*t^2 + O(t^3))*x*y^3 + (111*t^4 + O(t^5))*x^2 + sage: f._derivative(x).parent() + Multivariate Polynomial Ring in x, y over Power Series Ring in t over Algebraic Field + sage: f._derivative(y) # with respect to y + (3*t^2 + O(t^3))*x^2*y^2 + sage: f._derivative(t) # with respect to t (recurses into base ring) + (2*t + O(t^2))*x^2*y^3 + (148*t^3 + O(t^4))*x^3 + sage: f._derivative(x)._derivative(y) # with respect to x and then y + (6*t^2 + O(t^3))*x*y^2 + sage: f.derivative(y, 3) # with respect to y three times + (6*t^2 + O(t^3))*x^2 + sage: f._derivative() # can't figure out the variable + Traceback (most recent call last): + ... + ValueError: must specify which variable to differentiate with respect to + """ + if var is None: + raise ValueError("must specify which variable to differentiate with respect to") + + gens = list(self.parent().gens()) + + # check if var is one of the generators + try: + index = gens.index(var) + except ValueError: + # var is not a generator; do term-by-term differentiation recursively + # var may be, for example, a generator of the base ring + d = dict([(e, x._derivative(var)) for (e, x) in iteritems(self.dict())]) + d = polydict.PolyDict(d, self.parent().base_ring()(0), remove_zero=True) + return MPolynomial_polydict(self.parent(), d) + + # differentiate w.r.t. indicated variable + d = {} + v = polydict.ETuple({index:1}, len(gens)) + for (exp, coeff) in iteritems(self.dict()): + if exp[index] > 0: + d[exp.esub(v)] = coeff * exp[index] + d = polydict.PolyDict(d, self.parent().base_ring()(0), remove_zero=True) + return MPolynomial_polydict(self.parent(), d) + + def integral(self, var=None): + r""" + Integrates ``self`` with respect to variable ``var``. + + .. NOTE:: + + The integral is always chosen so the constant term is 0. + + If ``var`` is not one of the generators of this ring, integral(var) + is called recursively on each coefficient of this polynomial. + + EXAMPLES: + + On polynomials with rational coefficients:: + + sage: x, y = PolynomialRing(QQ, 'x, y').gens() + sage: ex = x*y + x - y + sage: it = ex.integral(x); it + 1/2*x^2*y + 1/2*x^2 - x*y + sage: it.parent() == x.parent() + True + + On polynomials with coefficients in power series:: + + sage: R. = PowerSeriesRing(QQbar) + sage: S. = PolynomialRing(R) + sage: f = (t^2 + O(t^3))*x^2*y^3 + (37*t^4 + O(t^5))*x^3 + sage: f.parent() + Multivariate Polynomial Ring in x, y over Power Series Ring in t over Algebraic Field + sage: f.integral(x) # with respect to x + (1/3*t^2 + O(t^3))*x^3*y^3 + (37/4*t^4 + O(t^5))*x^4 + sage: f.integral(x).parent() + Multivariate Polynomial Ring in x, y over Power Series Ring in t over Algebraic Field + + sage: f.integral(y) # with respect to y + (1/4*t^2 + O(t^3))*x^2*y^4 + (37*t^4 + O(t^5))*x^3*y + sage: f.integral(t) # with respect to t (recurses into base ring) + (1/3*t^3 + O(t^4))*x^2*y^3 + (37/5*t^5 + O(t^6))*x^3 + + TESTS:: + + sage: f.integral() # can't figure out the variable + Traceback (most recent call last): + ... + ValueError: must specify which variable to integrate with respect to + """ + if var is None: + raise ValueError("must specify which variable to integrate " + "with respect to") + + gens = list(self.parent().gens()) + + # check if var is one of the generators + try: + index = gens.index(var) + except ValueError: + # var is not a generator; do term-by-term integration recursively + # var may be, for example, a generator of the base ring + d = dict([(e, x.integral(var)) + for (e, x) in iteritems(self.dict())]) + d = polydict.PolyDict(d, self.parent().base_ring()(0), + remove_zero=True) + return MPolynomial_polydict(self.parent(), d) + + # integrate w.r.t. indicated variable + d = {} + v = polydict.ETuple({index:1}, len(gens)) + for (exp, coeff) in iteritems(self.dict()): + d[exp.eadd(v)] = coeff / (1+exp[index]) + d = polydict.PolyDict(d, self.parent().base_ring()(0), remove_zero=True) + return MPolynomial_polydict(self.parent(), d) + + def factor(self, proof=True): + r""" + Compute the irreducible factorization of this polynomial. + + INPUT: + + - ``proof'' - insist on provably correct results (default: ``True``) + + TESTS: + + Check if we can handle polynomials with no variables, see :trac:`7950`:: + + sage: P = PolynomialRing(ZZ,0,'') + sage: res = P(10).factor(); res + 2 * 5 + sage: res[0][0].parent() + Multivariate Polynomial Ring in no variables over Integer Ring + sage: R = PolynomialRing(QQ,0,'') + sage: res = R(10).factor(); res + 10 + sage: res.unit().parent() + Rational Field + sage: P(0).factor() + Traceback (most recent call last): + ... + ArithmeticError: factorization of 0 is not defined + + Check if we can factor a constant polynomial, see :trac:`8207`:: + + sage: R. = CC[] + sage: R(1).factor() + 1.00000000000000 + + Check that we prohibit too large moduli, :trac:`11829`:: + + sage: R. = GF(previous_prime(2^31))[] + sage: factor(x+y+1,proof=False) + Traceback (most recent call last): + ... + NotImplementedError: Factorization of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented. + + We check that the original issue in :trac:`7554` is fixed:: + + sage: K. = PolynomialRing(QQ) + sage: R. = PolynomialRing(FractionField(K)) + sage: factor(x) + x + + In the example below, we set the special method + ``_factor_multivariate_polynomial()`` in the base ring which is called to + factor multivariate polynomials. This facility can be used to easily + extend polynomial factorization to work over new rings you introduce:: + + sage: R. = PolynomialRing(QQ['z']) + sage: (x*y).factor() + Traceback (most recent call last): + ... + NotImplementedError: ... + sage: R.base_ring()._factor_multivariate_polynomial = lambda f, **kwargs: f.change_ring(QQ).factor() + sage: (x*y).factor() + y * x + sage: del R.base_ring()._factor_multivariate_polynomial # clean up + + Check that a "multivariate" polynomial in one variable is factored + correctly:: + + sage: R. = PolynomialRing(CC,1) + sage: f = z^4 - 6*z + 3 + sage: f.factor() + (z - 1.60443920904349) * (z - 0.511399619393097) * (z + 1.05791941421830 - 1.59281852704435*I) * (z + 1.05791941421830 + 1.59281852704435*I) + + """ + R = self.parent() + + # raise error if trying to factor zero + if not self: + raise ArithmeticError("factorization of {!r} is not defined".format(self)) + + # if number of variables is zero ... + if R.ngens() == 0: + base_ring = self.base_ring() + if base_ring.is_field(): + return Factorization([],unit=self.base_ring()(self)) + else: + F = base_ring(self).factor() + return Factorization([(R(f),m) for f,m in F], unit=F.unit()) + + base_ring = self.base_ring() + if hasattr(base_ring, '_factor_multivariate_polynomial'): + return base_ring._factor_multivariate_polynomial(self, proof=proof) + + # try to use univariate factoring + try: + F = self.univariate_polynomial().factor() + return Factorization([(R(f),m) for f,m in F], unit=F.unit()) + except TypeError: + pass + + base_ring = self.base_ring() + if base_ring.is_finite(): + if base_ring.characteristic() > 1<<29: + raise NotImplementedError("Factorization of multivariate polynomials over prime fields with characteristic > 2^29 is not implemented.") + if proof: + raise NotImplementedError("proof = True factorization not implemented. Call factor with proof=False.") + + R._singular_().set_ring() + S = self._singular_().factorize() + factors = S[1] + exponents = S[2] + v = sorted([(R(factors[i+1]), sage.rings.integer.Integer(exponents[i+1])) \ + for i in range(len(factors))]) + unit = R(1) + for i in range(len(v)): + if v[i][0].is_unit(): + unit = unit * v[i][0] + del v[i] + break + F = sorted(Factorization(v, unit=unit)) + return F + + def lift(self,I): + """ + given an ideal I = (f_1,...,f_r) and some g (== self) in I, find + s_1,...,s_r such that g = s_1 f_1 + ... + s_r f_r + + ALGORITHM: Use Singular. + + EXAMPLES:: + + sage: A. = PolynomialRing(CC,2,order='degrevlex') + sage: I = A.ideal([x^10 + x^9*y^2, y^8 - x^2*y^7 ]) + sage: f = x*y^13 + y^12 + sage: M = f.lift(I) + sage: M + [y^7, x^7*y^2 + x^8 + x^5*y^3 + x^6*y + x^3*y^4 + x^4*y^2 + x*y^5 + x^2*y^3 + y^4] + sage: sum( map( mul , zip( M, I.gens() ) ) ) == f + True + """ + fs = self._singular_() + Is = I._singular_() + P = I.ring() + try: + M = Is.lift(fs)._sage_(P) + except TypeError: + raise ArithmeticError("f is not in I") + return Sequence(M.list(), P, check=False, immutable=True) + + @coerce_binop + def quo_rem(self, right): + """ + Returns quotient and remainder of self and right. + + EXAMPLES:: + + sage: R. = CC[] + sage: f = y*x^2 + x + 1 + sage: f.quo_rem(x) + (x*y + 1.00000000000000, 1.00000000000000) + + sage: R = QQ['a','b']['x','y','z'] + sage: p1 = R('a + (1+2*b)*x*y + (3-a^2)*z') + sage: p2 = R('x-1') + sage: p1.quo_rem(p2) + ((2*b + 1)*y, (2*b + 1)*y + (-a^2 + 3)*z + a) + + sage: R. = Qp(5)[] + sage: x.quo_rem(y) + Traceback (most recent call last): + ... + TypeError: no conversion of this ring to a Singular ring defined + + ALGORITHM: Use Singular. + """ + R = self.parent() + try: + R._singular_().set_ring() + except TypeError: + f = self.parent().flattening_morphism() + if f.domain() != f.codomain(): + g = f.section() + q,r = f(self).quo_rem(f(right)) + return g(q), g(r) + else: + raise + else: + X = self._singular_().division(right._singular_()) + return R(X[1][1,1]), R(X[2][1]) + + def resultant(self, other, variable=None): + """ + Compute the resultant of ``self`` and ``other`` with respect + to ``variable``. + + If a second argument is not provided, the first variable of + ``self.parent()`` is chosen. + + INPUT: + + - ``other`` -- polynomial in ``self.parent()`` + + - ``variable`` -- (optional) variable (of type polynomial) in + ``self.parent()`` + + EXAMPLES:: + + sage: P. = PolynomialRing(QQ, 2) + sage: a = x + y + sage: b = x^3 - y^3 + sage: a.resultant(b) + -2*y^3 + sage: a.resultant(b, y) + 2*x^3 + + TESTS:: + + sage: from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_polydict_domain + sage: P. = MPolynomialRing_polydict_domain(QQ, 2, order='degrevlex') + sage: a = x + y + sage: b = x^3 - y^3 + sage: a.resultant(b) + -2*y^3 + sage: a.resultant(b, y) + 2*x^3 + + Check that :trac:`15061` is fixed:: + + sage: R. = AA[] + sage: (x^2 + 1).resultant(x^2 - y) + y^2 + 2*y + 1 + + """ + R = self.parent() + if variable is None: + variable = R.gen(0) + if R._has_singular: + rt = self._singular_().resultant(other._singular_(), variable._singular_()) + r = rt.sage_poly(R) + else: + r = self.sylvester_matrix(other, variable).det() + if R.ngens() <= 1 and r.degree() <= 0: + return R.base_ring()(r[0]) + else: + return r + + def reduce(self, I): + """ + Reduce this polynomial by the polynomials in `I`. + + INPUT: + + - ``I`` - a list of polynomials or an ideal + + EXAMPLES:: + + sage: P. = QQbar[] + sage: f1 = -2 * x^2 + x^3 + sage: f2 = -2 * y + x* y + sage: f3 = -x^2 + y^2 + sage: F = Ideal([f1,f2,f3]) + sage: g = x*y - 3*x*y^2 + sage: g.reduce(F) + (-6)*y^2 + 2*y + sage: g.reduce(F.gens()) + (-6)*y^2 + 2*y + + :: + + sage: f = 3*x + sage: f.reduce([2*x,y]) + 0 + + :: + + sage: k. = CyclotomicField(3) + sage: A. = PolynomialRing(k) + sage: J = [ y9 + y12] + sage: f = y9 - y12; f.reduce(J) + -2*y12 + sage: f = y13*y15; f.reduce(J) + y13*y15 + sage: f = y13*y15 + y9 - y12; f.reduce(J) + y13*y15 - 2*y12 + + Make sure the remainder returns the correct type, fixing :trac:`13903`:: + + sage: R.=PolynomialRing(Qp(5),2, order='lex') + sage: G=[y1^2 + y2^2, y1*y2 + y2^2, y2^3] + sage: type((y2^3).reduce(G)) + + """ + from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal + + k = self.base_ring() + P = self.parent() + + if isinstance(I, MPolynomialIdeal): + I = I.gens() + + if not k.is_field(): + raise TypeError("Can only reduce polynomials over fields.") + + try: + fs = self._singular_() + Is = fs.parent().ideal(I) + return P(fs.reduce(Is)) + except (NotImplementedError, TypeError): + pass + + lI = len(I) + I = list(I) + r = P.zero() + p = self + + while p != 0: + for i in range(lI): + gi = I[i] + plm = p.lm() + gilm = gi.lm() + if P.monomial_divides(gilm, plm): + quot = p.lc()/gi.lc() * P.monomial_quotient(plm, gilm) + p -= quot*I[i] + break + else: + plt = p.lt() + r += plt + p -= plt + return r + +############################################################### +# Useful for some geometry code. +############################################################### + +def degree_lowest_rational_function(r,x): + r""" + INPUT: + + + - ``r`` - a multivariate rational function + + - ``x`` - a multivariate polynomial ring generator x + + + OUTPUT: + + + - ``integer`` - the degree of r in x and its "leading" + (in the x-adic sense) coefficient. + + + .. note:: + + This function is dependent on the ordering of a python dict. + Thus, it isn't really mathematically well-defined. I think that + it should made a method of the FractionFieldElement class and + rewritten. + + EXAMPLES:: + + sage: R1 = PolynomialRing(FiniteField(5), 3, names = ["a","b","c"]) + sage: F = FractionField(R1) + sage: a,b,c = R1.gens() + sage: f = 3*a*b^2*c^3+4*a*b*c + sage: g = a^2*b*c^2+2*a^2*b^4*c^7 + + Consider the quotient + `f/g = \frac{4 + 3 bc^{2}}{ac + 2 ab^{3}c^{6}}` (note the + cancellation). + + :: + + sage: r = f/g; r + (-b*c^2 + 2)/(a*b^3*c^6 - 2*a*c) + sage: degree_lowest_rational_function(r,a) + (-1, 3) + sage: degree_lowest_rational_function(r,b) + (0, 4) + sage: degree_lowest_rational_function(r,c) + (-1, 4) + """ + from sage.rings.fraction_field import FractionField + R = r.parent() + F = FractionField(R) + r = F(r) + if r == 0: + return (0, F(0)) + L = next(iter(x.dict())) + for ix in range(len(L)): + if L[ix] != 0: + break + f = r.numerator() + g = r.denominator() + M = f.dict() + keys = list(M) + numtermsf = len(M) + degreesf = [keys[j][ix] for j in range(numtermsf)] + lowdegf = min(degreesf) + cf = M[keys[degreesf.index(lowdegf)]] ## constant coeff of lowest degree term + M = g.dict() + keys = list(M) + numtermsg = len(M) + degreesg = [keys[j][ix] for j in range(numtermsg)] + lowdegg = min(degreesg) + cg = M[keys[degreesg.index(lowdegg)]] ## constant coeff of lowest degree term + return (lowdegf-lowdegg,cf/cg) + From b958f3606d4518e240ac942d0502c7c9a3efb2c6 Mon Sep 17 00:00:00 2001 From: Mckenzie West Date: Mon, 2 Jul 2018 09:18:57 +0200 Subject: [PATCH 018/529] properly formated :: --- src/sage/rings/polynomial/multi_polynomial_libsingular.pyx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index f1ceed98c6c..16d0d81b4e2 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -2403,7 +2403,9 @@ cdef class MPolynomial_libsingular(MPolynomial): ... ZeroDivisionError: rational division by zero - Ensure that :trac:`17638` is fixed:: + Ensure that :trac:`17638` is fixed + + :: sage: R. = PolynomialRing(QQ,order = "neglex") sage: f = 1+y From 703ad58668b598f6276bd4c4dbfe6c69e36ea08c Mon Sep 17 00:00:00 2001 From: Mckenzie West Date: Mon, 2 Jul 2018 09:31:28 +0200 Subject: [PATCH 019/529] Removed print function from test --- src/sage/rings/polynomial/multi_polynomial_libsingular.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index 16d0d81b4e2..00abe783192 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -2411,7 +2411,7 @@ cdef class MPolynomial_libsingular(MPolynomial): sage: f = 1+y sage: g = 1+x sage: h = f/g - sage: print(h*g == f) + sage: h*g == f True """ cdef poly *p From c2c1e9efd9b678739729fc755e70431e0cdd0f4b Mon Sep 17 00:00:00 2001 From: Mckenzie West Date: Mon, 2 Jul 2018 09:36:39 +0200 Subject: [PATCH 020/529] removed spacing for assignment within function --- src/sage/rings/polynomial/multi_polynomial_libsingular.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index 00abe783192..97d69bcf800 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -2407,7 +2407,7 @@ cdef class MPolynomial_libsingular(MPolynomial): :: - sage: R. = PolynomialRing(QQ,order = "neglex") + sage: R. = PolynomialRing(QQ,order="neglex") sage: f = 1+y sage: g = 1+x sage: h = f/g From 8dd8ebef54d67ec3f7aae96be0cfaa8392ce9278 Mon Sep 17 00:00:00 2001 From: Mckenzie West Date: Mon, 2 Jul 2018 10:58:00 +0200 Subject: [PATCH 021/529] correcting white spacing --- .../rings/polynomial/multi_polynomial_libsingular.pyx | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index 97d69bcf800..085546c0ee5 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -2403,13 +2403,11 @@ cdef class MPolynomial_libsingular(MPolynomial): ... ZeroDivisionError: rational division by zero - Ensure that :trac:`17638` is fixed + Ensure that :trac:`17638` is fixed:: - :: - - sage: R. = PolynomialRing(QQ,order="neglex") - sage: f = 1+y - sage: g = 1+x + sage: R. = PolynomialRing(QQ, order="neglex") + sage: f = 1 + y + sage: g = 1 + x sage: h = f/g sage: h*g == f True From 7130792af60a920ae0cb61bb7d5c0c9f214ebcb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 21 Mar 2019 09:53:54 +0100 Subject: [PATCH 022/529] implement the Conway polynomial of knots and links --- src/sage/knots/link.py | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/sage/knots/link.py b/src/sage/knots/link.py index 3dc3e16137e..e0466ce2cbd 100644 --- a/src/sage/knots/link.py +++ b/src/sage/knots/link.py @@ -1859,6 +1859,8 @@ def alexander_polynomial(self, var='t'): sage: L = Link(B([-2, 4, 1, 6, 1, 4])) sage: L.alexander_polynomial() 0 + + .. SEEALSO:: :meth:`conway_polynomial` """ R = LaurentPolynomialRing(ZZ, var) # The Alexander polynomial of disjoint links are defined to be 0 @@ -1872,6 +1874,45 @@ def alexander_polynomial(self, var='t'): return t ** ((-max(exp) - min(exp)) // 2) * f return f + def conway_polynomial(self): + """ + Return the Conway polynomial of ``self``. + + This is closely related to the Alexander polynomial. + + See : wikipedia:`Alexander_polynomial` for the definition. + + EXAMPLES:: + + sage: B = BraidGroup(3) + sage: L = Link(B([1, -2, 1, -2])) + sage: L.conway_polynomial() + -t + 1 ? + + .. SEEALSO:: :meth:`alexander_polynomial` + """ + alex = self.alexander_polynomial() + L = alex.parent() + R = L.polynomial_ring() + if alex == 0: + return R.zero() + + t = L.gen() + alex = alex(t**2) + exp = alex.exponents() + alex = t**((-max(exp) - min(exp)) // 2) * alex + + conway = R.zero() + t_poly = R.gen() + binom = t - ~t + while alex: + M = max(alex.exponents()) + coeff = alex[M] + alex -= coeff * binom**M + M = M // 2 + conway += coeff * t_poly**M + return conway + def determinant(self): """ Return the determinant of ``self``. From 8c06ebcd075d1b5719da5c11bdcd86b11f2ff9f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 27 Dec 2020 16:52:52 +0100 Subject: [PATCH 023/529] move division to monoids --- src/sage/categories/magmas.py | 53 ++++++---------------------------- src/sage/categories/monoids.py | 53 +++++++++++++++++++++++++++++----- 2 files changed, 54 insertions(+), 52 deletions(-) diff --git a/src/sage/categories/magmas.py b/src/sage/categories/magmas.py index 7541aa60229..c22f5d7b05a 100644 --- a/src/sage/categories/magmas.py +++ b/src/sage/categories/magmas.py @@ -21,6 +21,7 @@ from sage.categories.realizations import RealizationsCategory from sage.cpython.getattr import raw_getattr + class Magmas(Category_singleton): """ The category of (multiplicative) magmas. @@ -366,7 +367,6 @@ def extra_super_categories(self): from sage.categories.magmatic_algebras import MagmaticAlgebras return [MagmaticAlgebras(self.base_ring())] - class ParentMethods: def is_field(self, proof=True): r""" @@ -517,9 +517,9 @@ def _test_one(self, **options): tester.assertEqual(x * one, x) tester.assertEqual(one * x, x) # Check that one is immutable if it looks like we can test this - if hasattr(one,"is_immutable"): + if hasattr(one, "is_immutable"): tester.assertTrue(one.is_immutable()) - if hasattr(one,"is_mutable"): + if hasattr(one, "is_mutable"): tester.assertFalse(one.is_mutable()) def is_empty(self): @@ -549,44 +549,7 @@ def is_empty(self): return False class ElementMethods: - def _div_(left, right): - r""" - Default implementation of division, multiplying (on the right) by the inverse. - - INPUT: - - - ``left``, ``right`` -- two elements of the same unital magma - - .. SEEALSO:: :meth:`__div__` - - EXAMPLES:: - - sage: G = FreeGroup(2) - sage: x0, x1 = G.group_generators() - sage: c1 = cartesian_product([x0, x1]) - sage: c2 = cartesian_product([x1, x0]) - sage: c1._div_(c2) - (x0*x1^-1, x1*x0^-1) - - With this implementation, division will fail as soon - as ``right`` is not invertible, even if ``right`` - actually divides ``left``:: - - sage: x = cartesian_product([2, 1]) - sage: y = cartesian_product([1, 1]) - sage: x / y - (2, 1) - sage: x / x - Traceback (most recent call last): - ... - TypeError: no conversion of this rational to integer - - TESTS:: - - sage: c1._div_.__module__ - 'sage.categories.magmas' - """ - return left * ~right + pass class SubcategoryMethods: @@ -854,7 +817,7 @@ def __init_extra__(self): if E_mul_func is C_mul_func: # self.product is custom, thus, we rely on it E._mul_ = E._mul_parent - else: # E._mul_ has so far been abstract + else: # E._mul_ has so far been abstract E._mul_ = E._mul_parent def multiplication_table(self, names='letters', elements=None): @@ -1006,7 +969,7 @@ def multiplication_table(self, names='letters', elements=None): return OperationTable(self, operation=operator.mul, names=names, elements=elements) class ElementMethods: - @abstract_method(optional = True) + @abstract_method(optional=True) def _mul_(self, right): """ Product of two elements @@ -1116,7 +1079,9 @@ def product(self, left, right): sage: x*y B[(0, [1, 2, 3])] + B[(1, [3, 1, 2])] """ - return self._cartesian_product_of_elements([(a*b) for (a,b) in zip(left.cartesian_factors(), right.cartesian_factors())]) + prods = [(a * b) for (a, b) in zip(left.cartesian_factors(), + right.cartesian_factors())] + return self._cartesian_product_of_elements(prods) class Subquotients(SubquotientsCategory): r""" diff --git a/src/sage/categories/monoids.py b/src/sage/categories/monoids.py index 91886dbe55f..30b27624ee7 100644 --- a/src/sage/categories/monoids.py +++ b/src/sage/categories/monoids.py @@ -1,7 +1,7 @@ r""" Monoids """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2005 David Kohel # William Stein # 2008 Teresa Gomez-Diaz (CNRS) @@ -9,8 +9,8 @@ # 2008-2014 Nicolas M. Thiery # # Distributed under the terms of the GNU General Public License (GPL) -# http://www.gnu.org/licenses/ -#****************************************************************************** +# https://www.gnu.org/licenses/ +# ***************************************************************************** from sage.misc.cachefunc import cached_method from sage.categories.category_with_axiom import CategoryWithAxiom @@ -224,12 +224,48 @@ def submonoid(self, generators, category=None): sage: M2 = R.subsemigroup([R(3),R(5)], one=R.one()) sage: M2 is M True - - """ return self.subsemigroup(generators, one=self.one()) class ElementMethods: + def _div_(left, right): + r""" + Default implementation of division, multiplying (on the right) by the inverse. + + INPUT: + + - ``left``, ``right`` -- two elements of the same unital magma + + .. SEEALSO:: :meth:`__div__` + + EXAMPLES:: + + sage: G = FreeGroup(2) + sage: x0, x1 = G.group_generators() + sage: c1 = cartesian_product([x0, x1]) + sage: c2 = cartesian_product([x1, x0]) + sage: c1._div_(c2) + (x0*x1^-1, x1*x0^-1) + + With this implementation, division will fail as soon + as ``right`` is not invertible, even if ``right`` + actually divides ``left``:: + + sage: x = cartesian_product([2, 1]) + sage: y = cartesian_product([1, 1]) + sage: x / y + (2, 1) + sage: x / x + Traceback (most recent call last): + ... + TypeError: no conversion of this rational to integer + + TESTS:: + + sage: c1._div_.__module__ + 'sage.categories.monoids' + """ + return left * ~right def is_one(self): r""" @@ -574,6 +610,7 @@ def monoid_generators(self): """ F = self.cartesian_factors() ids = tuple(M.one() for M in F) + def lift(i, gen): cur = list(ids) cur[i] = gen @@ -584,7 +621,8 @@ def lift(i, gen): cat = FiniteEnumeratedSets() if all(M.monoid_generators() in cat or isinstance(M.monoid_generators(), (tuple, list)) for M in F): - ret = [lift(i, gen) for i,M in enumerate(F) for gen in M.monoid_generators()] + ret = [lift(i, gen) for i, M in enumerate(F) + for gen in M.monoid_generators()] return Family(ret) # Infinitely generated @@ -593,6 +631,5 @@ def lift(i, gen): from sage.categories.cartesian_product import cartesian_product gens_prod = cartesian_product([Family(M.monoid_generators(), lambda g: (i, g)) - for i,M in enumerate(F)]) + for i, M in enumerate(F)]) return Family(gens_prod, lift, name="gen") - From af072b9e5a524a4c5f002a4f72cae3ba0a05f783 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 27 Dec 2020 21:41:34 +0100 Subject: [PATCH 024/529] one detail in doc --- src/sage/categories/monoids.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/categories/monoids.py b/src/sage/categories/monoids.py index 30b27624ee7..2313fe6fbb4 100644 --- a/src/sage/categories/monoids.py +++ b/src/sage/categories/monoids.py @@ -234,7 +234,7 @@ def _div_(left, right): INPUT: - - ``left``, ``right`` -- two elements of the same unital magma + - ``left``, ``right`` -- two elements of the same unital monoid .. SEEALSO:: :meth:`__div__` From 15b04050855b8052ed1b2d5a2cb504916dad8a39 Mon Sep 17 00:00:00 2001 From: Daniel Krenn Date: Tue, 11 May 2021 16:37:23 +0200 Subject: [PATCH 025/529] Trac #21319: fixup due to changes in dependencies --- src/sage/combinat/k_regular_sequence.py | 10 +++---- src/sage/combinat/recognizable_series.py | 38 ++++++++++++------------ 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/sage/combinat/k_regular_sequence.py b/src/sage/combinat/k_regular_sequence.py index a3a286f2a41..122ec922810 100644 --- a/src/sage/combinat/k_regular_sequence.py +++ b/src/sage/combinat/k_regular_sequence.py @@ -97,7 +97,6 @@ from .recognizable_series import RecognizableSeries from .recognizable_series import RecognizableSeriesSpace from sage.misc.cachefunc import cached_method -from six import iteritems def pad_right(T, length, zero=0): @@ -409,7 +408,7 @@ def subsequence(self, a, b, minimize=True): if a == 0: return sum(c_j * self[b_j] * self.parent().one_hadamard() - for b_j, c_j in iteritems(b)) + for b_j, c_j in b.items()) elif a == 1 and len(b) == 1 and zero in b: return b[zero] * self elif a < 0: @@ -457,7 +456,7 @@ def mu_line(r, i, c): for r in A), sum(c_j * vector( pad_right(pad(tuple(self.left), b_j), ndim, zero=zero)) - for b_j, c_j in iteritems(b)), + for b_j, c_j in b.items()), vector(sum((tuple(self.__getitem__(c, multiply_left=False)) if c >= 0 else dim*(zero,) for c in kernel), tuple()))) @@ -640,7 +639,7 @@ def _pickle_kRegularSequenceSpace(k, coefficients, category): sage: Seq2 = kRegularSequenceSpace(2, ZZ) sage: from sage.combinat.k_regular_sequence import _pickle_kRegularSequenceSpace sage: _pickle_kRegularSequenceSpace( - ....: Seq2.k, Seq2.coefficients(), Seq2.category()) + ....: Seq2.k, Seq2.coefficient_ring(), Seq2.category()) Space of 2-regular sequences over Integer Ring """ return kRegularSequenceSpace(k, coefficients, category=category) @@ -723,6 +722,7 @@ def __init__(self, k, *args, **kwds): running ._test_an_element() . . . pass running ._test_cardinality() . . . pass running ._test_category() . . . pass + running ._test_construction() . . . pass running ._test_elements() . . . Running the test suite of self.an_element() running ._test_category() . . . pass @@ -762,7 +762,7 @@ def __reduce__(self): Space of 2-regular sequences over Integer Ring """ return _pickle_kRegularSequenceSpace, \ - (self.k, self.coefficients(), self.category()) + (self.k, self.coefficient_ring(), self.category()) def _repr_(self): r""" diff --git a/src/sage/combinat/recognizable_series.py b/src/sage/combinat/recognizable_series.py index ffba6e495e6..6d174dd6be9 100644 --- a/src/sage/combinat/recognizable_series.py +++ b/src/sage/combinat/recognizable_series.py @@ -385,7 +385,7 @@ def immutable(m): return m if isinstance(mu, dict): - mu = dict((a, immutable(M)) for a, M in iteritems(mu)) + mu = dict((a, immutable(M)) for a, M in mu.items()) mu = Family(mu) if not mu.is_finite(): @@ -875,7 +875,7 @@ def __eq__(self, other): sage: Z1 = Rec((Matrix([[1, 0], [0, 1]]), Matrix([[1, 0], [0, 1]])), ....: left=vector([0, 1]), right=vector([1, 0])) sage: Z1 - 0 + 0 + ... sage: Z2 = Rec((Matrix([[0, 0], [0, 0]]), Matrix([[0, 0], [0, 0]])), ....: left=vector([0, 1]), right=vector([1, 0])) sage: Z2 @@ -1411,7 +1411,7 @@ def _pickle_RecognizableSeriesSpace(coefficients, indices, category): sage: Rec = RecognizableSeriesSpace(ZZ, [0, 1]) sage: from sage.combinat.recognizable_series import _pickle_RecognizableSeriesSpace sage: _pickle_RecognizableSeriesSpace( - ....: Rec.coefficients(), Rec.indices(), Rec.category()) + ....: Rec.coefficient_ring(), Rec.indices(), Rec.category()) Space of recognizable series on {0, 1} with coefficients in Integer Ring """ return RecognizableSeriesSpace(coefficients, indices=indices, category=category) @@ -1588,6 +1588,7 @@ def __init__(self, coefficient_ring, indices, category): running ._test_an_element() . . . pass running ._test_cardinality() . . . pass running ._test_category() . . . pass + running ._test_construction() . . . pass running ._test_elements() . . . Running the test suite of self.an_element() running ._test_category() . . . pass @@ -1623,7 +1624,7 @@ def __reduce__(self): Space of recognizable series on {0, 1} with coefficients in Integer Ring """ return _pickle_RecognizableSeriesSpace, \ - (self.coefficients(), self.indices(), self.category()) + (self.coefficient_ring(), self.indices(), self.category()) def alphabet(self): @@ -1710,9 +1711,9 @@ def _an_element_(self): """ from sage.matrix.constructor import Matrix from sage.modules.free_module_element import vector - z = self.coefficients().zero() - o = self.coefficients().one() - e = self.coefficients().an_element() + z = self.coefficient_ring().zero() + o = self.coefficient_ring().one() + e = self.coefficient_ring().an_element() return self(list(Matrix([[o, z], [i*o, o]]) for i, _ in enumerate(self.alphabet())), vector([z, e]), right=vector([e, z])) @@ -1733,25 +1734,24 @@ def some_elements(self): sage: tuple(RecognizableSeriesSpace(ZZ, [0, 1]).some_elements()) ([1] + [01] + [10] + 2*[11] + [001] + [010] + 2*[011] + [100] + 2*[101] + 2*[110] + ..., - [] + [0] + [1] + [00] + [01] + [10] - + [11] + [000] + [001] + [010] + ..., - 0, - -2*[] + 2*[0] - 4*[1] - 2*[00] + 4*[01] + 4*[10] - - 8*[11] + 2*[000] - 4*[001] - 4*[010] + ..., - [] + [0] + 2*[1] + [00] + 2*[01] + [10] - + 4*[11] + [000] + 2*[001] + [010] + ..., - 2*[] + 5*[0] + 11*[1] + 8*[00] + 14*[01] + 14*[10] - + 20*[11] + 11*[000] + 17*[001] + 17*[010] + ..., + [] + [1] + [11] + [111] + [1111] + [11111] + [111111] + ..., + [] + [0] + [1] + [00] + [10] + [11] + + [000] - 1*[001] + [100] + [110] + ..., + 2*[] - 1*[1] + 2*[10] - 1*[101] + + 2*[1010] - 1*[10101] + 2*[101010] + ..., + [] + [1] + 6*[00] + [11] - 39*[000] + 5*[001] + 6*[100] + [111] + + 288*[0000] - 33*[0001] + ..., + -5*[] + ..., ... - [] + [0] + 10*[1] + [00] + 10*[01] + [10] - + 100*[11] + [000] + 10*[001] + [010] + ...) + 210*[] + ..., + 2210*[] - 170*[0] + 170*[1] + ...) """ from itertools import count, islice from sage.matrix.matrix_space import MatrixSpace from sage.modules.free_module import FreeModule yield self.an_element() - C = self.coefficients() + C = self.coefficient_ring() some_elements_base = iter(C.some_elements()) k = len(self.alphabet()) for dim in range(1, 11): From 93c6687e4a0332d4c9729ff471a2c2c2d6926bc4 Mon Sep 17 00:00:00 2001 From: Daniel Krenn Date: Fri, 25 Jun 2021 14:51:46 +0200 Subject: [PATCH 026/529] Trac #21319: fix punctuation --- src/sage/combinat/recognizable_series.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/sage/combinat/recognizable_series.py b/src/sage/combinat/recognizable_series.py index 9c7629dc381..17ff5d9bda4 100644 --- a/src/sage/combinat/recognizable_series.py +++ b/src/sage/combinat/recognizable_series.py @@ -923,11 +923,11 @@ def __eq__(self, other): INPUT: - - ``other`` -- an object. + - ``other`` -- an object OUTPUT: - A boolean. + A boolean .. NOTE:: @@ -977,11 +977,11 @@ def __ne__(self, other): INPUT: - - ``other`` -- an object. + - ``other`` -- an object OUTPUT: - A boolean. + A boolean .. NOTE:: @@ -1524,6 +1524,7 @@ def tensor_product(left, right): return result + def _pickle_RecognizableSeriesSpace(coefficients, indices, category): r""" Pickle helper. @@ -1847,7 +1848,7 @@ def _an_element_(self): OUTPUT: - A :class:`recognizable_series`. + A :class:`recognizable_series` EXAMPLES:: @@ -1873,7 +1874,7 @@ def some_elements(self): OUTPUT: - An iterator. + An iterator EXAMPLES:: From ebdd42d665aa018b73254273f752e9f778ab7b8c Mon Sep 17 00:00:00 2001 From: dcoudert Date: Thu, 26 Aug 2021 16:20:18 +0200 Subject: [PATCH 027/529] trac #32426: check if a graph is factor critical --- src/doc/en/reference/references/index.rst | 5 + src/sage/graphs/graph.py | 200 ++++++++++++++++++++++ 2 files changed, 205 insertions(+) diff --git a/src/doc/en/reference/references/index.rst b/src/doc/en/reference/references/index.rst index 53cdd37cbb9..40be19eb530 100644 --- a/src/doc/en/reference/references/index.rst +++ b/src/doc/en/reference/references/index.rst @@ -3938,6 +3938,11 @@ REFERENCES: and of planar binary trees. :arxiv:`math/0102066v1`. +.. [LR2004] Dingjun Lou and Dongning Rao. + *Characterizing factor critical graphs and an algorithm*, + The Australasian Journal of Combinatorics, 30: 51–56, 2004. + http://ajc.maths.uq.edu.au/pdf/30/ajc_v30_p051.pdf + .. [LRS2017] Julien Leroy, Michel Rigo, Manon Stipulanti, *Counting the number of non-zero coefficients in rows of generalized Pascal triangles*, Discrete Math. 340 (2017), no. 5, 862--881. diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index b1fbb941e84..ef98ff6aeee 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -4213,6 +4213,206 @@ def weight(x): else: raise ValueError('algorithm must be set to either "Edmonds" or "LP"') + @doc_index("Leftovers") + def is_factor_critical(self, matching=None, algorithm='Edmonds', solver=None, verbose=0, + *, integrality_tolerance=0.001): + r""" + Check whether this graph is factor-critical. + + A graph of order `n` is factor-critical if every subgraph of `n-1` + vertices have a perfect matching, hence `n` must be odd. See + :wikipedia:`Factor-critical_graph` for more details. + + This method implements the algorithm proposed in [LR2004]_ and we assume + that a graph of order one is factor-critical. The time complexity of the + algorithm is linear if a near perfect matching is given as input (i.e., + a matching such that all vertices but one are incident to an edge of the + matching). Otherwise, the time complexity is dominated by the time + needed to compute a maximum matching of the graph. + + INPUT: + + - ``matching`` -- (default: ``None``); a near perfect matching of the + graph, that is a matching such that all vertices of the graph but one + are incident to an edge of the matching. It can be given using any + valid input format of :class:`~sage.graphs.graph.Graph`. + + If set to ``None``, a matching is computed using the other parameters. + + - ``algorithm`` -- string (default: ``Edmonds``); the algorithm to use + to compute a maximum matching of the graph among + + - ``"Edmonds"`` selects Edmonds' algorithm as implemented in NetworkX + + - ``"LP"`` uses a Linear Program formulation of the matching problem + + - ``solver`` -- string (default: ``None``); specify a Mixed Integer + Linear Programming (MILP) solver to be used. If set to ``None``, the + default one is used. For more information on MILP solvers and which + default solver is used, see the method :meth:`solve + ` of the class + :class:`MixedIntegerLinearProgram + `. + + - ``verbose`` -- integer (default: ``0``); sets the level of verbosity: + set to 0 by default, which means quiet (only useful when ``algorithm + == "LP"``) + + - ``integrality_tolerance`` -- float; parameter for use with MILP + solvers over an inexact base ring; see + :meth:`MixedIntegerLinearProgram.get_values`. + + EXAMPLES: + + Odd length cycles and odd cliques of order at least 3 are + factor-critical graphs:: + + sage: [graphs.CycleGraph(2*i + 1).is_factor_critical() for i in range(5)] + [True, True, True, True, True] + sage: [graphs.CompleteGraph(2*i + 1).is_factor_critical() for i in range(5)] + [True, True, True, True, True] + + More generally, every Hamiltonian graph with an odd number of vertices + is factor-critical:: + + sage: G = graphs.RandomGNP(15, .2) + sage: G.add_path([0..14]) + sage: G.add_edge(14, 0) + sage: G.is_hamiltonian() + True + sage: G.is_factor_critical() + True + + Friendship graphs are non-Hamiltonian factor-critical graphs:: + + sage: [graphs.FriendshipGraph(i).is_factor_critical() for i in range(1, 5)] + [True, True, True, True] + + Bipartite graphs are not factor-critical:: + + sage: G = graphs.RandomBipartite(randint(1, 10), randint(1, 10), .5) + sage: G.is_factor_critical() + False + + Graphs with even order are not factor critical:: + + sage: G = graphs.RandomGNP(10, .5) + sage: G.is_factor_critical() + False + + One can specify a matching:: + + sage: F = graphs.FriendshipGraph(4) + sage: M = F.matching() + sage: F.is_factor_critical(matching=M) + True + sage: F.is_factor_critical(matching=Graph(M)) + True + + TESTS: + + Giving a wrong matching:: + + sage: G = graphs.RandomGNP(15, .2) + sage: M = G.matching() + sage: G.is_factor_critical(matching=M[:-1]) + Traceback (most recent call last): + ... + ValueError: the input is not a near perfect matching of the graph + sage: G.is_factor_critical(matching=G.edges()) + Traceback (most recent call last): + ... + ValueError: the input is not a matching + sage: M = [(2*i, 2*i + 1) for i in range(9)] + sage: G.is_factor_critical(matching=M) + Traceback (most recent call last): + ... + ValueError: the input is not a matching of the graph + """ + if self.order() == 1: + return True + + # The graph must have an odd number of vertices, be 2-edge connected, so + # without bridges, and not bipartite + if (not self.order() % 2 or not self.is_connected() or + list(self.bridges()) or self.is_bipartite()): + return False + + if matching: + # We check that the input matching is a valid near perfect matching + # of the graph. + M = Graph(matching) + if any(d != 1 for d in M.degree()): + raise ValueError("the input is not a matching") + if not M.is_subgraph(self, induced=False): + raise ValueError("the input is not a matching of the graph") + if (self.order() != M.order() + 1) or (self.order() != 2*M.size() + 1): + raise ValueError("the input is not a near perfect matching of the graph") + else: + # We compute a maximum matching of the graph + M = Graph(self.matching(algorithm=algorithm, solver=solver, verbose=verbose, + integrality_tolerance=integrality_tolerance)) + + # It must be a near-perfect matching + if self.order() != M.order() + 1: + return False + + # We find the unsaturated vertex u, i.e., the only vertex of the graph + # not in M + for u in self: + if u not in M: + break + + # We virtually build an M-alternating tree T + from queue import Queue + Q = Queue() + Q.put(u) + even = set([u]) + odd = set() + pred = {u: u} + rank = {u: 0} + + while not Q.empty(): + x = Q.get() + for y in self.neighbor_iterator(x): + if y in odd: + continue + elif y in even: + # Search for the nearest common ancestor t of x and y + P = [x] + R = [y] + while P[-1] != R[-1]: + if rank[P[-1]] > rank[R[-1]]: + P.append(pred[P[-1]]) + elif rank[P[-1]] < rank[R[-1]]: + R.append(pred[R[-1]]) + else: + P.append(pred[P[-1]]) + R.append(pred[R[-1]]) + t = P.pop() + R.pop() + # Set t as pred of all vertices of the chains and add + # vertices marked odd to the queue + for a in itertools.chain(P, R): + pred[a] = t + rank[a] = rank[t] + 1 + if a in odd: + even.add(a) + odd.discard(a) + Q.put(a) + else: # y has not been visited yet + z = next(M.neighbor_iterator(y)) + odd.add(y) + even.add(z) + Q.put(z) + pred[y] = x + pred[z] = y + rank[y] = rank[x] + 1 + rank[z] = rank[y] + 1 + + # The graph is factor critical if all vertices are marked even + return len(even) == self.order() + @doc_index("Algorithmically hard stuff") def has_homomorphism_to(self, H, core=False, solver=None, verbose=0, *, integrality_tolerance=1e-3): From 34f0db2dc7af0935443c931f7c6a730b2d001b98 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sat, 23 Oct 2021 20:08:55 +0200 Subject: [PATCH 028/529] trac #32426: fix test with random input --- src/sage/graphs/graph.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index 950cf251967..ff09cdf2e16 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -4314,7 +4314,9 @@ def is_factor_critical(self, matching=None, algorithm='Edmonds', solver=None, ve Giving a wrong matching:: - sage: G = graphs.RandomGNP(15, .2) + sage: G = graphs.RandomGNP(15, .3) + sage: while not G.is_biconnected(): + ....: G = graphs.RandomGNP(15, .3) sage: M = G.matching() sage: G.is_factor_critical(matching=M[:-1]) Traceback (most recent call last): @@ -4350,6 +4352,7 @@ def is_factor_critical(self, matching=None, algorithm='Edmonds', solver=None, ve if (self.order() != M.order() + 1) or (self.order() != 2*M.size() + 1): raise ValueError("the input is not a near perfect matching of the graph") else: + print(matching) # We compute a maximum matching of the graph M = Graph(self.matching(algorithm=algorithm, solver=solver, verbose=verbose, integrality_tolerance=integrality_tolerance)) @@ -4357,7 +4360,7 @@ def is_factor_critical(self, matching=None, algorithm='Edmonds', solver=None, ve # It must be a near-perfect matching if self.order() != M.order() + 1: return False - + print("blop") # We find the unsaturated vertex u, i.e., the only vertex of the graph # not in M for u in self: From 068e6de2da88a310972a4bbfc0c6122099981a7f Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sun, 24 Oct 2021 00:56:25 +0200 Subject: [PATCH 029/529] trac 32426: small fix --- src/sage/graphs/graph.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index ff09cdf2e16..d3340d2db92 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -4352,7 +4352,6 @@ def is_factor_critical(self, matching=None, algorithm='Edmonds', solver=None, ve if (self.order() != M.order() + 1) or (self.order() != 2*M.size() + 1): raise ValueError("the input is not a near perfect matching of the graph") else: - print(matching) # We compute a maximum matching of the graph M = Graph(self.matching(algorithm=algorithm, solver=solver, verbose=verbose, integrality_tolerance=integrality_tolerance)) @@ -4360,7 +4359,7 @@ def is_factor_critical(self, matching=None, algorithm='Edmonds', solver=None, ve # It must be a near-perfect matching if self.order() != M.order() + 1: return False - print("blop") + # We find the unsaturated vertex u, i.e., the only vertex of the graph # not in M for u in self: From e23edfc46930f74b092abbfbe4d5f7e0c19bcf18 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sat, 20 Nov 2021 15:12:02 +0100 Subject: [PATCH 030/529] trac #32169: restart over 32911 --- src/sage/graphs/generic_graph.py | 259 +++++++++++++++++++++---------- 1 file changed, 173 insertions(+), 86 deletions(-) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index 93264c6a4fd..332fda19d24 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -6295,7 +6295,8 @@ def steiner_tree(self, vertices, weighted=False, solver=None, verbose=0, st.delete_vertices(v for v in g if not st.degree(v)) return st - def edge_disjoint_spanning_trees(self, k, root=None, solver=None, verbose=0): + def edge_disjoint_spanning_trees(self, k, algorithm=None, root=None, solver=None, verbose=0, + *, integrality_tolerance=1e-3): r""" Return the desired number of edge-disjoint spanning trees/arborescences. @@ -6304,14 +6305,27 @@ def edge_disjoint_spanning_trees(self, k, root=None, solver=None, verbose=0): - ``k`` -- integer; the required number of edge-disjoint spanning trees/arborescences + - ``algorithm`` -- string (default: ``None``); specify the + algorithm to use among: + + * ``"Roskind-Tarjan"`` -- use the algorithm proposed by Roskind and + Tarjan [RT1985]_ for finding edge-disjoint spanning-trees in + undirected simple graphs in time `O(m\log{m} + k^2n^2)`. + + * ``"MILP"`` -- use a mixed integer linear programming + formulation. This is the default method for directed graphs. + + * ``None`` -- use ``"Roskind-Tarjan"`` for undirected graphs and + ``"MILP"`` for directed graphs. + - ``root`` -- vertex (default: ``None``); root of the disjoint arborescences when the graph is directed. If set to ``None``, the first vertex in the graph is picked. - - ``solver`` -- string (default: ``None``); specify a Linear Program - (LP) solver to be used. If set to ``None``, the default one is - used. For more information on LP solvers and which default solver is - used, see the method :meth:`solve + - ``solver`` -- string (default: ``None``); specify a Mixed Integer + Linear Programming (MILP) solver to be used. If set to ``None``, the + default one is used. For more information on MILP solvers and which + default solver is used, see the method :meth:`solve ` of the class :class:`MixedIntegerLinearProgram `. @@ -6319,10 +6333,13 @@ def edge_disjoint_spanning_trees(self, k, root=None, solver=None, verbose=0): - ``verbose`` -- integer (default: ``0``); sets the level of verbosity. Set to 0 by default, which means quiet. + - ``integrality_tolerance`` -- float; parameter for use with MILP + solvers over an inexact base ring; see + :meth:`MixedIntegerLinearProgram.get_values`. + ALGORITHM: - Mixed Integer Linear Program. The formulation can be found in - [Coh2019]_. + Mixed Integer Linear Program. There are at least two possible rewritings of this method which do not use Linear Programming: @@ -6374,111 +6391,181 @@ def edge_disjoint_spanning_trees(self, k, root=None, solver=None, verbose=0): sage: trees = g.edge_disjoint_spanning_trees(k) sage: all(t.is_tree() for t in trees) True - """ - from sage.numerical.mip import MixedIntegerLinearProgram, MIPSolverException + Check the validity of the algorithms for undirected graphs:: - p = MixedIntegerLinearProgram(solver=solver) - p.set_objective(None) + sage: g = graphs.RandomGNP(30, .4) + sage: k = Integer(g.edge_connectivity()) // 2 + sage: trees = g.edge_disjoint_spanning_trees(k, algorithm="MILP") + sage: all(t.is_tree() for t in trees) + True + sage: all(g.order() == t.size() + 1 for t in trees) + True + sage: trees = g.edge_disjoint_spanning_trees(k, algorithm="Roskind-Tarjan") + sage: all(t.is_tree() for t in trees) + True + sage: all(g.order() == t.size() + 1 for t in trees) + True - # The colors we can use - colors = list(range(k)) + Example of :trac:`32169`:: - # edges[j,e] is equal to one if and only if edge e belongs to color j - edges = p.new_variable(binary=True) + sage: d6 = r'[E_S?_hKIH@eos[BSg???Q@FShGC?hTHUGM?IPug?JOEYCdOzdkQGo' + sage: d6 += r'@ADA@AAg?GAQW?[aIaSwHYcD@qQb@Dd?\hJTI@OHlJ_?C_OEIKoeC' + sage: d6 += r'R@_BC?Q??YBFosqITEA?IvCU_' + sage: G = DiGraph(d6, format='dig6') + sage: G.edge_connectivity() + 5 + sage: G.edge_disjoint_spanning_trees(5) # long time + [Digraph on 28 vertices, + Digraph on 28 vertices, + Digraph on 28 vertices, + Digraph on 28 vertices, + Digraph on 28 vertices] - if root is None: - root = next(self.vertex_iterator()) + Small cases:: - # r_edges is a relaxed variable greater than edges. It is used to - # check the presence of cycles - r_edges = p.new_variable(nonnegative=True) + sage: Graph().edge_disjoint_spanning_trees(0) + [] + sage: Graph(1).edge_disjoint_spanning_trees(0) + [] + sage: Graph(2).edge_disjoint_spanning_trees(0) + [] + sage: Graph([(0, 1)]).edge_disjoint_spanning_trees(0) + [] + sage: Graph([(0, 1)]).edge_disjoint_spanning_trees(1) + [Graph on 2 vertices] + sage: Graph([(0, 1)]).edge_disjoint_spanning_trees(2) + Traceback (most recent call last): + ... + EmptySetError: this graph does not contain the required number of trees/arborescences - epsilon = 1/(3*(Integer(self.order()))) + TESTS: - if self.is_directed(): - # An edge belongs to at most one arborescence - for e in self.edge_iterator(labels=False): - p.add_constraint(p.sum(edges[j,e] for j in colors), max=1) + Choice of the algorithm:: + sage: Graph().edge_disjoint_spanning_trees(0, algorithm=None) + [] + sage: Graph().edge_disjoint_spanning_trees(0, algorithm="Roskind-Tarjan") + [] + sage: Graph().edge_disjoint_spanning_trees(0, algorithm="MILP") + [] + sage: Graph().edge_disjoint_spanning_trees(0, algorithm="foo") + Traceback (most recent call last): + ... + ValueError: algorithm must be None, "Rosking-Tarjan" or "MILP" for undirected graphs + sage: DiGraph().edge_disjoint_spanning_trees(0, algorithm=None) + [] + sage: DiGraph().edge_disjoint_spanning_trees(0, algorithm="MILP") + [] + sage: DiGraph().edge_disjoint_spanning_trees(0, algorithm="foo") + Traceback (most recent call last): + ... + ValueError: algorithm must be None or "MILP" for directed graphs + """ + self._scream_if_not_simple() + from sage.graphs.digraph import DiGraph + from sage.graphs.graph import Graph + from sage.numerical.mip import MixedIntegerLinearProgram, MIPSolverException + from sage.categories.sets_cat import EmptySetError - for j in colors: - # each color class has self.order()-1 edges - p.add_constraint(p.sum(edges[j,e] for e in self.edge_iterator(labels=None)), min=self.order()-1) + if self.is_directed(): + if algorithm is not None and algorithm != "MILP": + raise ValueError('algorithm must be None or "MILP" for directed graphs') + else: + if algorithm is None or algorithm == "Roskind-Tarjan": + from sage.graphs.spanning_tree import edge_disjoint_spanning_trees + return edge_disjoint_spanning_trees(self, k) + elif algorithm != "MILP": + raise ValueError('algorithm must be None, "Rosking-Tarjan" or "MILP" ' + 'for undirected graphs') + + G = self + n = G.order() - # Each vertex different from the root has indegree equals to one - for v in self: - if v is not root: - p.add_constraint(p.sum(edges[j,e] for e in self.incoming_edge_iterator(v, labels=None)), max=1, min=1) - else: - p.add_constraint(p.sum(edges[j,e] for e in self.incoming_edge_iterator(v, labels=None)), max=0, min=0) - - # r_edges is larger than edges - vertex_to_int = {u:i for i,u in enumerate(self.vertex_iterator())} - for u,v in self.edge_iterator(labels=None): - if self.has_edge(v,u): - if vertex_to_int[v] < vertex_to_int[u]: - p.add_constraint(r_edges[j,(u,v)] + r_edges[j,(v,u)] - edges[j,(u,v)] - edges[j,(v,u)], min=0) - else: - p.add_constraint(r_edges[j,(u,v)] + r_edges[j,(v,u)] - edges[j,(u,v)], min=0) + if not n or not k: + return [] - from sage.graphs.digraph import DiGraph - D = DiGraph() - D.add_vertices(self.vertex_iterator()) - D.set_pos(self.get_pos()) - classes = [D.copy() for j in colors] + if root is None: + root = next(G.vertex_iterator()) - else: - # Turn an edge to a frozenset to ensure that (u, v) and (v, u) - # represent the same edge. + if k == 1: + E = G.min_spanning_tree(starting_vertex=root) + if not E: + raise EmptySetError("this graph does not contain the required " + "number of trees/arborescences") + return [DiGraph(E) if G.is_directed() else Graph(E)] - # An edge belongs to at most one arborescence - for e in self.edge_iterator(labels=False): - p.add_constraint(p.sum(edges[j,frozenset(e)] for j in colors), max=1) + D = G if G.is_directed() else DiGraph(G) + # The colors we can use (one color per tree) + colors = list(range(k)) - for j in colors: - # each color class has self.order()-1 edges - p.add_constraint(p.sum(edges[j,frozenset(e)] for e in self.edge_iterator(labels=None)), min=self.order()-1) + p = MixedIntegerLinearProgram(solver=solver) - # Each vertex is in the tree - for v in self: - p.add_constraint(p.sum(edges[j,frozenset(e)] for e in self.edges_incident(v, labels=None)), min=1) + # edges[e, c] is equal to one if and only if edge e has color c + edge = p.new_variable(binary=True) - # r_edges is larger than edges - for u,v in self.edge_iterator(labels=None): - p.add_constraint(r_edges[j,(u,v)] + r_edges[j,(v,u)] - edges[j,frozenset((u,v))], min=0) + # Define partial ordering of the vertices in each tree to avoid cycles + pos = p.new_variable() - from sage.graphs.graph import Graph - D = Graph() - D.add_vertices(self.vertex_iterator()) - D.set_pos(self.get_pos()) - classes = [D.copy() for j in colors] + # An edge belongs to a single tree + if G.is_directed(): + for e in D.edge_iterator(labels=False): + p.add_constraint(p.sum(edge[e, c] for c in colors) <= 1) + else: + for u, v in G.edge_iterator(labels=False): + p.add_constraint(p.sum(edge[(u, v), c] + edge[(v, u), c] for c in colors) <= 1) + + # Constraints defining a spanning tree in D for each color c + for c in colors: + # A tree has n-1 edges + p.add_constraint(p.sum(edge[e, c] for e in D.edge_iterator(labels=False)) == n - 1) + + # Each vertex has 1 incoming edge, except the root which has none + for u in D: + if u == root: + p.add_constraint(p.sum(edge[e, c] for e in D.incoming_edge_iterator(root, labels=False)) == 0) + else: + p.add_constraint(p.sum(edge[e, c] for e in D.incoming_edge_iterator(u, labels=False)) == 1) + + # A vertex has at least one incident edge + for u in D: + p.add_constraint(p.sum(edge[e, c] for e in D.incoming_edge_iterator(u, labels=False)) + + p.sum(edge[e, c] for e in D.outgoing_edge_iterator(u, labels=False)) + >= 1) + + # We use the Miller-Tucker-Zemlin subtour elimination constraints + # combined with the Desrosiers-Langevin strengthening constraints + for u, v in D.edge_iterator(labels=False): + if D.has_edge(v, u): + # DL + p.add_constraint(pos[u, c] + (n - 1)*edge[(u, v), c] + (n - 3)*edge[(v, u), c] + <= pos[v, c] + n - 2) + else: + # MTZ: If edge uv is selected, v is after u in the partial ordering + p.add_constraint(pos[u, c] + 1 - n * (1 - edge[(u, v), c]) <= pos[v, c]) - # no cycles - for j in colors: - for v in self: - p.add_constraint(p.sum(r_edges[j,(u,v)] for u in self.neighbor_iterator(v)), max=1-epsilon) + # and extra strengthening constraints on the minimum distance + # between the root of the spanning tree and any vertex + BFS = dict(D.breadth_first_search(root, report_distance=True)) + for u in D: + p.add_constraint(pos[root, c] + BFS[u] <= pos[u, c]) + + # We now solve this program and extract the solution try: p.solve(log=verbose) - except MIPSolverException: - from sage.categories.sets_cat import EmptySetError raise EmptySetError("this graph does not contain the required number of trees/arborescences") - edges = p.get_values(edges) - - for j,g in enumerate(classes): - if self.is_directed(): - g.add_edges(e for e in self.edge_iterator(labels=False) if edges[j,e] == 1) - else: - g.add_edges(e for e in self.edge_iterator(labels=False) if edges[j,frozenset(e)] == 1) + H = DiGraph() if G.is_directed() else Graph() + H.add_vertices(G.vertex_iterator()) + H.set_pos(G.get_pos()) + classes = [H.copy() for c in colors] - if len(list(g.breadth_first_search(root))) != self.order(): - raise RuntimeError("The computation seems to have gone wrong somewhere..."+ - "This is probably because of the value of epsilon, but"+ - " in any case please report this bug, with the graph "+ - "that produced it ! ;-)") + edges = p.get_values(edge, convert=bool, tolerance=integrality_tolerance) + for (e, c), b in edges.items(): + if b: + classes[c].add_edge(e) return classes From 477f242ccf5df1a4221bf523d37af7756991aa41 Mon Sep 17 00:00:00 2001 From: Jonathan Kliem Date: Wed, 5 Jan 2022 10:11:32 +0100 Subject: [PATCH 031/529] fix doctests in list_of_faces failing for 32-bit --- .../combinatorial_polyhedron/list_of_faces.pyx | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pyx index 0478b6c146e..41b1b470df8 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pyx @@ -145,7 +145,9 @@ cdef class ListOfFaces: def __dealloc__(self): r""" - TESTS:: + TESTS: + + Check that failed ``cinit`` does not give segmentation fault or similar:: sage: from sage.geometry.polyhedron.combinatorial_polyhedron.list_of_faces import ListOfFaces sage: ListOfFaces(-1, -1, -1) # indirect doctest @@ -156,11 +158,10 @@ cdef class ListOfFaces: sage: from memory_allocator.test import TestMemoryAllocator sage: t = TestMemoryAllocator() sage: m = t.size_t_max() - # The following is only certain to fail on 64-bit - sage: ListOfFaces(1, m, 1) - Traceback (most recent call last): # 64-bit + sage: ListOfFaces(10, m, 10) + Traceback (most recent call last): ... - MemoryError: failed to allocate ... # 64-bit + MemoryError: failed to allocate ... """ face_list_free(self.data) From 9fefcce644286de7edbcf939dbdb6fd84cf10dc1 Mon Sep 17 00:00:00 2001 From: Daniel Krenn Date: Wed, 5 Jan 2022 15:59:29 +0100 Subject: [PATCH 032/529] Follow-up from Trac #21325 review comment 19: shift_left+right: test equality --- src/sage/combinat/k_regular_sequence.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/sage/combinat/k_regular_sequence.py b/src/sage/combinat/k_regular_sequence.py index 849a54e6f28..59297c40665 100644 --- a/src/sage/combinat/k_regular_sequence.py +++ b/src/sage/combinat/k_regular_sequence.py @@ -559,7 +559,8 @@ def shift_left(self, b=1, **kwds): TESTS: - sage: C.shift_left(0) == C # not tested, #21319 + sage: C.shift_left(0) == C + True sage: C.shift_left(2).shift_right(2) 2-regular sequence 0, 0, 2, 3, 4, 5, 6, 7, 8, 9, ... """ @@ -604,11 +605,14 @@ def shift_right(self, b=1, **kwds): TESTS: - sage: C.shift_right(0) == C # not tested, #21319 + sage: C.shift_right(0) == C + True sage: C.shift_right().shift_left() 2-regular sequence 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ... sage: C.shift_right(2).shift_left(2) 2-regular sequence 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ... + sage: _ == C + True """ return self.subsequence(1, -b, **kwds) From e0d9a487e82db468e17047305cd14c7c0060b5ba Mon Sep 17 00:00:00 2001 From: Javier Honrubia Date: Sun, 9 Jan 2022 12:53:40 +0100 Subject: [PATCH 033/529] Added pictures to the documentation --- src/sage/plot/point.py | 138 +++++++++++++++++++++++++++++++++++------ 1 file changed, 119 insertions(+), 19 deletions(-) diff --git a/src/sage/plot/point.py b/src/sage/plot/point.py index 61ee092ac94..9b9660ae3cb 100644 --- a/src/sage/plot/point.py +++ b/src/sage/plot/point.py @@ -31,6 +31,8 @@ # TODO: create _allowed_options for 3D point classes to # improve bad option handling in plot3d? + + class Point(GraphicPrimitive_xydata): """ Primitive class for the point graphics type. See point?, point2d? @@ -90,16 +92,16 @@ def _allowed_options(self): sage: P[0]._allowed_options()['size'] 'How big the point is (i.e., area in points^2=(1/72 inch)^2).' """ - return {'alpha':'How transparent the point is.', + return {'alpha': 'How transparent the point is.', 'faceted': 'If True color the edge of the point. (only for 2D plots)', - 'hue':'The color given as a hue.', - 'legend_color':'The color of the legend text', - 'legend_label':'The label for this item in the legend.', - 'marker':'the marker symbol for 2D plots only (see documentation of plot() for details)', - 'markeredgecolor':'the color of the marker edge (only for 2D plots)', - 'rgbcolor':'The color as an RGB tuple.', + 'hue': 'The color given as a hue.', + 'legend_color': 'The color of the legend text', + 'legend_label': 'The label for this item in the legend.', + 'marker': 'the marker symbol for 2D plots only (see documentation of plot() for details)', + 'markeredgecolor': 'the color of the marker edge (only for 2D plots)', + 'rgbcolor': 'The color as an RGB tuple.', 'size': 'How big the point is (i.e., area in points^2=(1/72 inch)^2).', - 'zorder':'The layer level in which to draw'} + 'zorder': 'The layer level in which to draw'} def _plot3d_options(self, options=None): """ @@ -125,7 +127,7 @@ def _plot3d_options(self, options=None): del options['size'] if options.pop('faceted', False): raise NotImplementedError("3D points cannot be faceted.") - for o in ('marker', 'markeredgecolor'): # remove 2D options + for o in ('marker', 'markeredgecolor'): # remove 2D options if o in options: del options[o] @@ -151,6 +153,12 @@ def plot3d(self, z=0, **kwds): Point set defined by 1 point(s) sage: b=a.plot3d() + .. PLOT:: + + A=point((1,1)) + a=A[0] + sphinx_plot(a.plot3d()) + One point with a height:: sage: A=point((1,1)) @@ -160,6 +168,12 @@ def plot3d(self, z=0, **kwds): sage: b.loc[2] 3.0 + .. PLOT:: + + A=point((1,1)) + a=A[0] + sphinx_plot(a.plot3d(z=3)) + Multiple points:: sage: P=point([(0,0), (1,1)]) @@ -167,6 +181,12 @@ def plot3d(self, z=0, **kwds): Point set defined by 2 point(s) sage: q=p.plot3d(size=22) + .. PLOT:: + + P=point([(0,0), (1,1)]) + p=P[0] + sphinx_plot(p.plot3d(size=22)) + Multiple points with different heights:: sage: P=point([(0,0), (1,1)]) @@ -177,6 +197,12 @@ def plot3d(self, z=0, **kwds): sage: q.all[1].loc[2] 3.0 + .. PLOT:: + + P=point([(0,0), (1,1)]) + p=P[0] + sphinx_plot(p.plot3d(z=[2,3])) + Note that keywords passed must be valid point3d options:: sage: A=point((1,1),size=22) @@ -235,7 +261,7 @@ def _repr_(self): sage: p=P[0]; p Point set defined by 2 point(s) """ - return "Point set defined by %s point(s)"%len(self.xdata) + return "Point set defined by %s point(s)" % len(self.xdata) def __getitem__(self, i): """ @@ -251,7 +277,7 @@ def __getitem__(self, i): """ return self.xdata[i], self.ydata[i] - def _render_on_subplot(self,subplot): + def _render_on_subplot(self, subplot): r""" TESTS: @@ -263,21 +289,21 @@ def _render_on_subplot(self,subplot): """ options = self.options() - #Convert the color to a hex string so that the scatter - #method does not interpret it as a list of 3 floating - #point color specifications when there are - #three points. This is mentioned in the matplotlib 0.98 - #documentation and fixes #2076 + # Convert the color to a hex string so that the scatter + # method does not interpret it as a list of 3 floating + # point color specifications when there are + # three points. This is mentioned in the matplotlib 0.98 + # documentation and fixes #2076 from matplotlib.colors import rgb2hex c = rgb2hex(to_mpl_color(options['rgbcolor'])) a = float(options['alpha']) z = int(options.pop('zorder', 0)) s = int(options['size']) - faceted = options['faceted'] #faceted=True colors the edge of point + faceted = options['faceted'] # faceted=True colors the edge of point markeredgecolor = options['markeredgecolor'] - scatteroptions={} + scatteroptions = {} if not faceted and markeredgecolor is None: scatteroptions['edgecolors'] = 'none' elif markeredgecolor is not None: @@ -310,21 +336,37 @@ def point(points, **kwds): sage: point((1,2)) Graphics object consisting of 1 graphics primitive + .. PLOT:: + + sphinx_plot(point((1,2))) + :: sage: point((1,2,3)) Graphics3d Object + .. PLOT:: + + sphinx_plot(point((1,2,3))) + :: sage: point([(0,0), (1,1)]) Graphics object consisting of 1 graphics primitive + .. PLOT:: + + sphinx_plot(point([(0,0), (1,1)])) + :: sage: point([(0,0,1), (1,1,1)]) Graphics3d Object + .. PLOT:: + + sphinx_plot(point([(0,0,1), (1,1,1)])) + Extra options will get passed on to show(), as long as they are valid:: sage: point([(cos(theta), sin(theta)) for theta in srange(0, 2*pi, pi/8)], frame=True) @@ -349,10 +391,11 @@ def point(points, **kwds): from sage.plot.plot3d.shapes2 import point3d return point3d(points, **kwds) + @rename_keyword(color='rgbcolor', pointsize='size') @options(alpha=1, aspect_ratio='automatic', faceted=False, legend_color=None, legend_label=None, marker='o', - markeredgecolor=None, rgbcolor=(0,0,1), size=10) + markeredgecolor=None, rgbcolor=(0, 0, 1), size=10) def point2d(points, **options): r""" A point of size ``size`` defined by point = `(x, y)`. @@ -390,12 +433,21 @@ def point2d(points, **options): sage: point((0.5, 0.5), rgbcolor=hue(0.75)) Graphics object consisting of 1 graphics primitive + .. PLOT:: + + sphinx_plot(point((0.5, 0.5), rgbcolor=hue(0.75))) + Points with customized markers and edge colors:: sage: r = [(random(), random()) for _ in range(10)] sage: point(r, marker='d', markeredgecolor='red', size=20) Graphics object consisting of 1 graphics primitive + .. PLOT:: + + r = [(random(), random()) for _ in range(10)] + sphinx_plot(point(r, marker='d', markeredgecolor='red', size=20)) + Passing an empty list returns an empty plot:: sage: point([]) @@ -410,40 +462,76 @@ def point2d(points, **options): Point set defined by 1 point(s) sage: b = a.plot3d(z=3) + .. PLOT:: + + A = point((1, 1)) + a = A[0] + b = a.plot3d(z=3) + sphinx_plot(b) + This is also true with multiple points:: sage: P = point([(0, 0), (1, 1)]) sage: p = P[0] sage: q = p.plot3d(z=[2,3]) + .. PLOT:: + + P = point([(0, 0), (1, 1)]) + p = P[0] + q = p.plot3d(z=[2,3]) + sphinx_plot(q) + Here are some random larger red points, given as a list of tuples:: sage: point(((0.5, 0.5), (1, 2), (0.5, 0.9), (-1, -1)), rgbcolor=hue(1), size=30) Graphics object consisting of 1 graphics primitive + .. PLOT:: + + sphinx_plot(point(((0.5, 0.5), (1, 2), (0.5, 0.9), (-1, -1)), rgbcolor=hue(1), size=30)) + And an example with a legend:: sage: point((0, 0), rgbcolor='black', pointsize=40, legend_label='origin') Graphics object consisting of 1 graphics primitive + .. PLOT:: + + sphinx_plot(point((0, 0), rgbcolor='black', pointsize=40, legend_label='origin')) + The legend can be colored:: sage: P = points([(0, 0), (1, 0)], pointsize=40, legend_label='origin', legend_color='red') sage: P + plot(x^2, (x, 0, 1), legend_label='plot', legend_color='green') Graphics object consisting of 2 graphics primitives + .. PLOT:: + + P = points([(0, 0), (1, 0)], pointsize=40, legend_label='origin', legend_color='red') + Q = P + plot(x**2, (x, 0, 1), legend_label='plot', legend_color='green') + sphinx_plot(Q) + Extra options will get passed on to show(), as long as they are valid:: sage: point([(cos(theta), sin(theta)) for theta in srange(0, 2*pi, pi/8)], frame=True) Graphics object consisting of 1 graphics primitive sage: point([(cos(theta), sin(theta)) for theta in srange(0, 2*pi, pi/8)]).show(frame=True) # These are equivalent + .. PLOT:: + + sphinx_plot(point([(cos(theta), sin(theta)) for theta in srange(0, 2*pi, pi/8)], frame=True)) + For plotting data, we can use a logarithmic scale, as long as we are sure not to include any nonpositive points in the logarithmic direction:: sage: point([(1, 2),(2, 4),(3, 4),(4, 8),(4.5, 32)], scale='semilogy', base=2) Graphics object consisting of 1 graphics primitive + .. PLOT:: + + sphinx_plot(point([(1, 2),(2, 4),(3, 4),(4, 8),(4.5, 32)], scale='semilogy', base=2)) + Since Sage Version 4.4 (:trac:`8599`), the size of a 2d point can be given by the argument ``size`` instead of ``pointsize``. The argument ``pointsize`` is still supported:: @@ -463,11 +551,23 @@ def point2d(points, **options): sage: point(sqrt(2) + I, pointsize=100) Graphics object consisting of 1 graphics primitive + .. PLOT:: + + sphinx_plot(point(1 + I, pointsize=100)) + + .. PLOT:: + + sphinx_plot(point(sqrt(2) + I, pointsize=100)) + We can also plot a list of complex numbers:: sage: point([I, 1 + I, 2 + 2*I], pointsize=100) Graphics object consisting of 1 graphics primitive + .. PLOT:: + + sphinx_plot(point([I, 1 + I, 2 + 2*I], pointsize=100)) + TESTS:: sage: point2d(iter([])) From f1cdb5e3658122b544b0eda9b50794a106d25edc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 18 Jan 2022 18:15:26 +0100 Subject: [PATCH 034/529] adding some conversions to/from Fricas functions --- src/sage/functions/gamma.py | 1 + src/sage/functions/jacobi.py | 17 +++----- src/sage/functions/orthogonal_polys.py | 58 +++++++++++++++++--------- src/sage/functions/other.py | 14 +++++-- src/sage/functions/special.py | 8 ++-- 5 files changed, 62 insertions(+), 36 deletions(-) diff --git a/src/sage/functions/gamma.py b/src/sage/functions/gamma.py index dc1eefcc89d..3cb886e12e9 100644 --- a/src/sage/functions/gamma.py +++ b/src/sage/functions/gamma.py @@ -286,6 +286,7 @@ def __init__(self): sympy='loggamma', fricas='logGamma')) + log_gamma = Function_log_gamma() diff --git a/src/sage/functions/jacobi.py b/src/sage/functions/jacobi.py index 39db1ed8efb..4153dd3ee8b 100644 --- a/src/sage/functions/jacobi.py +++ b/src/sage/functions/jacobi.py @@ -185,17 +185,12 @@ def __init__(self, kind): "'ds', 'dc', 'sn', 'sd', 'sc', 'cn', 'cd', 'cs'.") self.kind = kind BuiltinFunction.__init__(self, - name='jacobi_{}'.format(kind), - nargs=2, evalf_params_first=False, - conversions=dict(maple= - ('Jacobi{}' - .format(kind.upper())), - mathematica= - ('Jacobi{}' - .format(kind.upper())), - maxima= - ('jacobi_{}' - .format(kind)))) + name='jacobi_{}'.format(kind), + nargs=2, evalf_params_first=False, + conversions=dict(maple=('Jacobi{}'.format(kind.upper())), + mathematica=('Jacobi{}'.format(kind.upper())), + fricas=('jacobi{}'.format(kind.capitalize())), + maxima=('jacobi_{}'.format(kind)))) def _eval_(self, x, m): r""" diff --git a/src/sage/functions/orthogonal_polys.py b/src/sage/functions/orthogonal_polys.py index 69cb712e777..d7a3dd1a108 100644 --- a/src/sage/functions/orthogonal_polys.py +++ b/src/sage/functions/orthogonal_polys.py @@ -345,8 +345,9 @@ def __init__(self, name, nargs=2, latex_name=None, conversions={}): except KeyError: self._maxima_name = None - super(OrthogonalFunction,self).__init__(name=name, nargs=nargs, - latex_name=latex_name, conversions=conversions) + super(OrthogonalFunction, self).__init__(name=name, nargs=nargs, + latex_name=latex_name, + conversions=conversions) def eval_formula(self, *args): """ @@ -419,7 +420,7 @@ def __call__(self, *args, **kwds): kwds['hold'] = True return maxima(self._eval_(*args, **kwds))._sage_() - return super(OrthogonalFunction,self).__call__(*args, **kwds) + return super(OrthogonalFunction, self).__call__(*args, **kwds) class ChebyshevFunction(OrthogonalFunction): @@ -464,7 +465,7 @@ def __call__(self, n, *args, **kwds): except Exception: pass - return super(ChebyshevFunction,self).__call__(n, *args, **kwds) + return super(ChebyshevFunction, self).__call__(n, *args, **kwds) def _eval_(self, n, x): """ @@ -842,8 +843,10 @@ def _derivative_(self, n, x, diff_param): return n*chebyshev_U(n-1, x) raise ValueError("illegal differentiation parameter {}".format(diff_param)) + chebyshev_T = Func_chebyshev_T() + class Func_chebyshev_U(ChebyshevFunction): """ Class for the Chebyshev polynomial of the second kind. @@ -1203,13 +1206,15 @@ def __init__(self): legendre_P """ BuiltinFunction.__init__(self, 'legendre_P', nargs=2, latex_name=r"P", - conversions={'maxima':'legendre_p', - 'mathematica':'LegendreP', - 'maple':'LegendreP', - 'giac':'legendre'}) + conversions={'maxima': 'legendre_p', + 'mathematica': 'LegendreP', + 'maple': 'LegendreP', + 'giac': 'legendre'}) + legendre_P = Func_legendre_P() + class Func_legendre_Q(BuiltinFunction): def __init__(self): r""" @@ -1221,8 +1226,9 @@ def __init__(self): -29113619535/131072*log(-(x + 1)/(x - 1)) """ BuiltinFunction.__init__(self, "legendre_Q", nargs=2, latex_name=r"Q", - conversions={'maxima':'legendre_q', 'mathematica':'LegendreQ', - 'maple':'LegendreQ'}) + conversions={'maxima': 'legendre_q', + 'mathematica': 'LegendreQ', + 'maple': 'LegendreQ'}) def _eval_(self, n, x, *args, **kwds): r""" @@ -1422,8 +1428,10 @@ def _derivative_(self, n, x, *args,**kwds): else: return (n*x*legendre_Q(n, x) - n*legendre_Q(n-1, x))/(x**2 - 1) + legendre_Q = Func_legendre_Q() + class Func_assoc_legendre_P(BuiltinFunction): r""" Return the Ferrers function `\mathtt{P}_n^m(x)` of first kind for @@ -1545,9 +1553,10 @@ def __init__(self): """ BuiltinFunction.__init__(self, "gen_legendre_P", nargs=3, latex_name=r"\mathtt{P}", - conversions={'maxima':'assoc_legendre_p', - 'mathematica':'LegendreP', - 'maple':'LegendreP'}) + conversions={'maxima': 'assoc_legendre_p', + 'mathematica': 'LegendreP', + 'fricas': 'legendreP', + 'maple': 'LegendreP'}) def _eval_(self, n, m, x, *args, **kwds): r""" @@ -1863,6 +1872,7 @@ def _derivative_(self, n, m, x, *args,**kwds): else: return ((n-m+1)*gen_legendre_Q(n+1, m, x) - (n+1)*x*gen_legendre_Q(n, m, x))/(x**2 - 1) + gen_legendre_Q = Func_assoc_legendre_Q() @@ -1931,8 +1941,12 @@ def __init__(self): hermite(x, x) """ GinacFunction.__init__(self, "hermite", nargs=2, latex_name=r"H", - conversions={'maxima':'hermite', 'mathematica':'HermiteH', - 'maple':'HermiteH', 'sympy':'hermite'}, preserved_arg=2) + conversions={'maxima': 'hermite', + 'mathematica': 'HermiteH', + 'maple': 'HermiteH', + 'fricas': 'hermiteH', + 'sympy': 'hermite'}, preserved_arg=2) + hermite = Func_hermite() @@ -1971,8 +1985,11 @@ def __init__(self): jacobi(n, a, b, x) """ OrthogonalFunction.__init__(self, "jacobi_P", nargs=4, latex_name=r"P", - conversions={'maxima':'jacobi_p', 'mathematica':'JacobiP', - 'maple':'JacobiP', 'sympy':'jacobi'}) + conversions={'maxima': 'jacobi_p', + 'mathematica': 'JacobiP', + 'maple': 'JacobiP', + 'fricas': 'jacobiP', + 'sympy': 'jacobi'}) def _eval_(self, n, a, b, x): """ @@ -2196,8 +2213,11 @@ def __init__(self): laguerre(_SAGE_VAR_n,laguerre(_SAGE_VAR_n,_SAGE_VAR_x)) """ OrthogonalFunction.__init__(self, "laguerre", nargs=2, latex_name=r"L", - conversions={'maxima':'laguerre', 'mathematica':'LaguerreL', - 'maple':'LaguerreL', 'sympy':'laguerre'}) + conversions={'maxima': 'laguerre', + 'mathematica': 'LaguerreL', + # 'fricas': 'laguerreL', 3 arguments ? + 'maple': 'LaguerreL', + 'sympy': 'laguerre'}) def _eval_(self, n, x, *args, **kwds): r""" diff --git a/src/sage/functions/other.py b/src/sage/functions/other.py index 9fec4911120..f0462e9d637 100644 --- a/src/sage/functions/other.py +++ b/src/sage/functions/other.py @@ -1156,7 +1156,8 @@ def __init__(self): GinacFunction.__init__(self, "real_part", conversions=dict(maxima='realpart', sympy='re', - giac='re'), + mathematica='Re', + giac='re', fricas='real'), alt_name="real") def __call__(self, x, **kwargs): @@ -1217,6 +1218,8 @@ def __init__(self): GinacFunction.__init__(self, "imag_part", conversions=dict(maxima='imagpart', sympy='im', + mathematica='Im', + fricas='imag', giac='im'), alt_name="imag") @@ -1232,6 +1235,7 @@ def __call__(self, x, **kwargs): else: return GinacFunction.__call__(self, x, **kwargs) + imag = imag_part = imaginary = Function_imag_part() @@ -1316,7 +1320,10 @@ def __init__(self): """ GinacFunction.__init__(self, "conjugate", conversions=dict(sympy='conjugate', - giac='conj')) + giac='conj', + mathematica='Conjugate', + fricas='conjugate')) + conjugate = Function_conjugate() @@ -2046,13 +2053,14 @@ def _sympy_(self, l): from sympy import Piecewise as pw args = [] for tup in l.operands(): - cond,expr = tup.operands() + cond, expr = tup.operands() if SR(cond).is_numeric(): args.append((SR(expr)._sympy_(), bool(SR(cond)._sympy_()))) else: args.append((SR(expr)._sympy_(), SR(cond)._sympy_())) return pw(*args) + cases = Function_cases() diff --git a/src/sage/functions/special.py b/src/sage/functions/special.py index e507844219e..e5866b29ab2 100644 --- a/src/sage/functions/special.py +++ b/src/sage/functions/special.py @@ -751,8 +751,9 @@ def __init__(self): BuiltinFunction.__init__(self, 'elliptic_f', nargs=2, conversions=dict(mathematica='EllipticF', maxima='elliptic_f', + fricas='ellipticF', sympy='elliptic_f')) - + def _eval_(self, z, m): """ EXAMPLES:: @@ -959,12 +960,13 @@ def __init__(self): BuiltinFunction.__init__(self, 'elliptic_pi', nargs=3, conversions=dict(mathematica='EllipticPi', maxima='EllipticPi', + fricas='ellipticPi', sympy='elliptic_pi')) - + def _eval_(self, n, z, m): """ EXAMPLES:: - + sage: elliptic_pi(x,x,pi) elliptic_pi(x, x, pi) sage: elliptic_pi(0,x,pi) From eabf53c02d2ba43bb73f9105d23ca64afcf83cf5 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Wed, 26 Jan 2022 19:50:07 -0500 Subject: [PATCH 035/529] Trac #33234: fix python-3.10 deprecation warning in polynomial roots. We're passing a float to python's random.randrange, and randrange isn't happy about that in python-3.10: DeprecationWarning: non-integer arguments to randrange() have been deprecated since Python 3.10 and will be removed in a subsequent version Fortunately the float in question is integral, and we can simply replace qdiv = div / 4 with qdiv = div // 4 to get an int that randrange will tolerate. --- src/sage/rings/polynomial/real_roots.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/polynomial/real_roots.pyx b/src/sage/rings/polynomial/real_roots.pyx index ccebbfba87f..68dcdae4d95 100644 --- a/src/sage/rings/polynomial/real_roots.pyx +++ b/src/sage/rings/polynomial/real_roots.pyx @@ -408,9 +408,9 @@ cdef class interval_bernstein_polynomial: # A different algorithm here might be more efficient. div = 1024 - while self.degree() >= div//4: + while self.degree() >= (div // 4): div = div * 2 - qdiv = div/4 + qdiv = div // 4 # divides evenly since div = 1024*2^k rand = Integer(ctx.random.randrange(qdiv, 3*qdiv)) / div (p1, p2, ok) = self.de_casteljau(ctx, rand) ctx.dc_log_append(("div" + self._type_code(), self.scale_log2, self.bitsize, rand, ok, logging_note)) From 23711dbb16b02f524678a944f5d7498be1121cc0 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Sat, 29 Jan 2022 17:41:22 +0800 Subject: [PATCH 036/529] power_mod() works in any ring with %; code tweaks --- src/sage/arith/misc.py | 59 ++++++++++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 20 deletions(-) diff --git a/src/sage/arith/misc.py b/src/sage/arith/misc.py index 664e3ba924f..5f06b95cefe 100644 --- a/src/sage/arith/misc.py +++ b/src/sage/arith/misc.py @@ -2162,24 +2162,36 @@ def get_inverse_mod(order): def power_mod(a, n, m): """ - Return the ``n``-th power of ``a`` modulo the integer ``m``. + Return the `n`-th power of `a` modulo `m`, where `a` and `m` + are elements of a ring that implements the modulo operator ``%``. + + ALGORITHM: square-and-multiply EXAMPLES:: - sage: power_mod(0,0,5) - Traceback (most recent call last): - ... - ArithmeticError: 0^0 is undefined. + sage: power_mod(2,388,389) + 1 sage: power_mod(2,390,391) 285 sage: power_mod(2,-1,7) 4 sage: power_mod(11,1,7) 4 + + This function works for fairly general rings:: + sage: R. = ZZ[] sage: power_mod(3*x, 10, 7) 4*x^10 + sage: power_mod(-3*x^2+4, 7, 2*x^3-5) + x^14 + x^8 + x^6 + x^3 + 962509*x^2 - 791910*x - 698281 + + TESTS:: + sage: power_mod(0,0,5) + Traceback (most recent call last): + ... + ArithmeticError: 0^0 is undefined. sage: power_mod(11,1,0) Traceback (most recent call last): ... @@ -2193,30 +2205,37 @@ def power_mod(a, n, m): sage: from gmpy2 import mpz sage: power_mod(mpz(2),mpz(390),mpz(391)) mpz(285) + """ - if m == 0: + if not m: raise ZeroDivisionError("modulus must be nonzero.") + + a = a % m # this should coerce into a ring containing both a and m + if m == 1: - return 0 - if n < 0: - ainv = inverse_mod(a, m) - return power_mod(ainv, -n, m) - if n == 0: - if a == 0: + return a.parent().zero() + + n = Integer(n) + if not n: + if not a: raise ArithmeticError("0^0 is undefined.") - return 1 + return a.parent().one() + if n < 0: + a = inverse_mod(a, m) + n = -n - apow = a % m - while n&1 == 0: + apow = a + while not n&1: apow = (apow*apow) % m - n = n >> 1 + n >>= 1 + power = apow - n = n >> 1 - while n != 0: + n >>= 1 + while n: apow = (apow*apow) % m - if n&1 != 0: + if n&1: power = (power*apow) % m - n = n >> 1 + n >>= 1 return power From 7fffa61e4604a35a0b8572d9cbcbc9dd30fad95f Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Sat, 29 Jan 2022 19:27:47 +0800 Subject: [PATCH 037/529] 0^0 = 1 --- src/sage/arith/misc.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/sage/arith/misc.py b/src/sage/arith/misc.py index 5f06b95cefe..71eed11de0a 100644 --- a/src/sage/arith/misc.py +++ b/src/sage/arith/misc.py @@ -2217,8 +2217,6 @@ def power_mod(a, n, m): n = Integer(n) if not n: - if not a: - raise ArithmeticError("0^0 is undefined.") return a.parent().one() if n < 0: a = inverse_mod(a, m) From 3d57d6363b7ee473d30a849723517e46a281587d Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Sun, 30 Jan 2022 01:26:57 +0800 Subject: [PATCH 038/529] update test for 0^0 --- src/sage/arith/misc.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/sage/arith/misc.py b/src/sage/arith/misc.py index 71eed11de0a..36393112515 100644 --- a/src/sage/arith/misc.py +++ b/src/sage/arith/misc.py @@ -2189,9 +2189,7 @@ def power_mod(a, n, m): TESTS:: sage: power_mod(0,0,5) - Traceback (most recent call last): - ... - ArithmeticError: 0^0 is undefined. + 1 sage: power_mod(11,1,0) Traceback (most recent call last): ... From 0d0142a560d9904494581f229d5a4eb6bcccb205 Mon Sep 17 00:00:00 2001 From: Clemens Heuberger Date: Mon, 14 Feb 2022 20:53:56 +0100 Subject: [PATCH 039/529] Trac #21319: fix RESt issues --- src/sage/combinat/k_regular_sequence.py | 4 ++-- src/sage/combinat/recognizable_series.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/combinat/k_regular_sequence.py b/src/sage/combinat/k_regular_sequence.py index 59297c40665..520af6ce8d1 100644 --- a/src/sage/combinat/k_regular_sequence.py +++ b/src/sage/combinat/k_regular_sequence.py @@ -557,7 +557,7 @@ def shift_left(self, b=1, **kwds): sage: C.shift_left(-2) 2-regular sequence 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, ... - TESTS: + TESTS:: sage: C.shift_left(0) == C True @@ -603,7 +603,7 @@ def shift_right(self, b=1, **kwds): sage: C.shift_right(-2) 2-regular sequence 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ... - TESTS: + TESTS:: sage: C.shift_right(0) == C True diff --git a/src/sage/combinat/recognizable_series.py b/src/sage/combinat/recognizable_series.py index 405b0dd92ee..6c5d75c6309 100644 --- a/src/sage/combinat/recognizable_series.py +++ b/src/sage/combinat/recognizable_series.py @@ -1848,7 +1848,7 @@ def _an_element_(self): OUTPUT: - A :class:`recognizable_series` + A :class:`RecognizableSeries` EXAMPLES:: From dec24accd7e679bf7156c16edc79f9925bce82c1 Mon Sep 17 00:00:00 2001 From: Clemens Heuberger Date: Mon, 14 Feb 2022 20:54:52 +0100 Subject: [PATCH 040/529] Trac #21319: replace "recognizable series" by "recognizable series space" --- src/sage/combinat/recognizable_series.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/combinat/recognizable_series.py b/src/sage/combinat/recognizable_series.py index 6c5d75c6309..d6e38e7ef65 100644 --- a/src/sage/combinat/recognizable_series.py +++ b/src/sage/combinat/recognizable_series.py @@ -1844,7 +1844,7 @@ def _repr_(self): def _an_element_(self): r""" - Return an element of this recognizable series. + Return an element of this recognizable series space. OUTPUT: @@ -1868,7 +1868,7 @@ def _an_element_(self): def some_elements(self): r""" - Return some elements of this recognizable series. + Return some elements of this recognizable series space. See :class:`TestSuite` for a typical use case. From 671dd6688931b5c598bb7ab8f8b4338b13bfdaf1 Mon Sep 17 00:00:00 2001 From: Clemens Heuberger Date: Mon, 14 Feb 2022 20:55:10 +0100 Subject: [PATCH 041/529] Trac #21319: PEP8 --- src/sage/combinat/recognizable_series.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/sage/combinat/recognizable_series.py b/src/sage/combinat/recognizable_series.py index d6e38e7ef65..3e4592ed1b4 100644 --- a/src/sage/combinat/recognizable_series.py +++ b/src/sage/combinat/recognizable_series.py @@ -1865,7 +1865,6 @@ def _an_element_(self): for i, _ in enumerate(self.alphabet())), vector([z, e]), right=vector([e, z])) - def some_elements(self): r""" Return some elements of this recognizable series space. @@ -1911,7 +1910,6 @@ def some_elements(self): break yield self(mu, *LR) - @cached_method def one_hadamard(self): r""" From eceee9990a556fe5a1f377c695fb4b2294150d1b Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Sat, 19 Feb 2022 17:55:19 +0100 Subject: [PATCH 042/529] Remove method calls on module load --- src/sage/interacts/library.py | 125 +++++++++++++++++++++++++++------- 1 file changed, 99 insertions(+), 26 deletions(-) diff --git a/src/sage/interacts/library.py b/src/sage/interacts/library.py index 9dba11362a4..48aaf7e4fbd 100644 --- a/src/sage/interacts/library.py +++ b/src/sage/interacts/library.py @@ -1022,14 +1022,14 @@ def _newton_method(f, c, maxn, h): @library_interact def trapezoid_integration( - title = text_control('

Trapezoid integration

'), - f = input_box(default = "x^2-5*x + 10", label='$f(x)=$'), - n = slider(1,100,1,5, label='# divisions'), - interval_input = selector(['from slider','from keyboard'], label='Integration interval', buttons=True), - interval_s = range_slider(-10,10,default=(0,8), label="slider: "), - interval_g = input_grid(1,2,default=[[0,8]], label="keyboard: "), - output_form = selector(['traditional','table','none'], label='Computations form', buttons=True) - ): + title=None, + f=None, + n=None, + interval_input=None, + interval_s=None, + interval_g=None, + output_form=None, +): r""" Interact explaining the trapezoid method for definite integrals. @@ -1063,6 +1063,29 @@ def trapezoid_integration( interval_g: Grid(value=[[0, 8]], children=(Label(value='keyboard: '), VBox(children=(EvalText(value='0', layout=Layout(max_width='5em')),)), VBox(children=(EvalText(value='8', layout=Layout(max_width='5em')),)))) output_form: ToggleButtons(description='Computations form', options=('traditional', 'table', 'none'), value='traditional') """ + if title is None: + title = text_control("

Trapezoid integration

") + if f is None: + f = (input_box(default="x^2-5*x + 10", label="$f(x)=$"),) + if n is None: + n = (slider(1, 100, 1, 5, label="# divisions"),) + if interval_input is None: + interval_input = ( + selector( + ["from slider", "from keyboard"], + label="Integration interval", + buttons=True, + ), + ) + if interval_s is None: + interval_s = (range_slider(-10, 10, default=(0, 8), label="slider: "),) + if interval_g is None: + interval_g = (input_grid(1, 2, default=[[0, 8]], label="keyboard: "),) + if output_form is None: + output_form = selector( + ["traditional", "table", "none"], label="Computations form", buttons=True + ) + xs = [] ys = [] if interval_input == 'from slider': @@ -1139,13 +1162,14 @@ def trapezoid_integration( @library_interact def simpson_integration( - title = text_control('

Simpson integration

'), - f = input_box(default = 'x*sin(x)+x+1', label='$f(x)=$'), - n = slider(2,100,2,6, label='# divisions'), - interval_input = selector(['from slider','from keyboard'], label='Integration interval', buttons=True), - interval_s = range_slider(-10,10,default=(0,10), label="slider: "), - interval_g = input_grid(1,2,default=[[0,10]], label="keyboard: "), - output_form = selector(['traditional','table','none'], label='Computations form', buttons=True)): + title=None, + f=None, + n=None, + interval_input=None, + interval_s=None, + interval_g=None, + output_form=None, +): r""" Interact explaining the simpson method for definite integrals. @@ -1179,7 +1203,30 @@ def simpson_integration( interval_g: Grid(value=[[0, 10]], children=(Label(value='keyboard: '), VBox(children=(EvalText(value='0', layout=Layout(max_width='5em')),)), VBox(children=(EvalText(value='10', layout=Layout(max_width='5em')),)))) output_form: ToggleButtons(description='Computations form', options=('traditional', 'table', 'none'), value='traditional') """ - x = SR.var('x') + if title is None: + title = (text_control("

Simpson integration

"),) + if f is None: + f = (input_box(default="x*sin(x)+x+1", label="$f(x)=$"),) + if n is None: + n = (slider(2, 100, 2, 6, label="# divisions"),) + if interval_input is None: + interval_input = ( + selector( + ["from slider", "from keyboard"], + label="Integration interval", + buttons=True, + ), + ) + if interval_s is None: + interval_s = (range_slider(-10, 10, default=(0, 10), label="slider: "),) + if interval_g is None: + interval_g = (input_grid(1, 2, default=[[0, 10]], label="keyboard: "),) + if output_form is None: + output_form = selector( + ["traditional", "table", "none"], label="Computations form", buttons=True + ) + + x = SR.var("x") f = symbolic_expression(f).function(x) if interval_input == 'from slider': interval = interval_s @@ -1271,16 +1318,17 @@ def parabola(a, b, c): @library_interact def riemann_sum( - title = text_control('

Riemann integral with random sampling

'), - f = input_box("x^2+1", label = "$f(x)=$", width=40), - n = slider(1,30,1,5, label='# divisions'), - hr1 = text_control('
'), - interval_input = selector(['from slider','from keyboard'], label='Integration interval', buttons=True), - interval_s = range_slider(-5,10,default=(0,2), label="slider: "), - interval_g = input_grid(1,2,default=[[0,2]], label="keyboard: "), - hr2 = text_control('
'), - list_table = checkbox(default=False, label="List table"), - auto_update = False): + title=None, + f=None, + n=None, + hr1=None, + interval_input=None, + interval_s=None, + interval_g=None, + hr2=None, + list_table=None, + auto_update=False, +): r""" Interact explaining the definition of Riemann integral @@ -1316,6 +1364,31 @@ def riemann_sum( - Robert Marik (2010-08) """ + if title is None: + title = (text_control("

Riemann integral with random sampling

"),) + if f is None: + f = (input_box("x^2+1", label="$f(x)=$", width=40),) + if n is None: + n = (slider(1, 30, 1, 5, label="# divisions"),) + if hr1 is None: + hr1 = (text_control("
"),) + if interval_input is None: + interval_input = ( + selector( + ["from slider", "from keyboard"], + label="Integration interval", + buttons=True, + ), + ) + if interval_s is None: + interval_s = (range_slider(-5, 10, default=(0, 2), label="slider: "),) + if interval_g is None: + interval_g = (input_grid(1, 2, default=[[0, 2]], label="keyboard: "),) + if hr2 is None: + hr2 = (text_control("
"),) + if list_table is None: + list_table = checkbox(default=False, label="List table") + x = SR.var('x') from random import random if interval_input == 'from slider': From 738b703c246b9ca90aeb041633d0b97e168cf6e8 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 19 Feb 2022 13:40:03 -0800 Subject: [PATCH 043/529] src/sage/repl/all.py: Also import get_display_manager --- src/sage/repl/all.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sage/repl/all.py b/src/sage/repl/all.py index 71a012bc190..96fd6de5f6d 100644 --- a/src/sage/repl/all.py +++ b/src/sage/repl/all.py @@ -8,4 +8,6 @@ 'attach', 'detach', 'attached_files', 'load_attach_path', 'reset_load_attach_path', 'load_attach_mode']) +from sage.repl.rich_output.display_manager import get_display_manager + from sage.repl.rich_output.pretty_print import pretty_print, show From d6cf9f6b386fd39dc203cb26b551a157e441bcaa Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 12 Dec 2021 20:15:35 -0800 Subject: [PATCH 044/529] src/sage/interfaces/all.py: Do not re-export get_display_manager; do not fail if get_display_manager cannot be imported --- src/sage/interfaces/all.py | 57 ++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/src/sage/interfaces/all.py b/src/sage/interfaces/all.py index 0a71ed81ae7..73d032ff518 100644 --- a/src/sage/interfaces/all.py +++ b/src/sage/interfaces/all.py @@ -48,30 +48,33 @@ 'mathematica', 'mwrank', 'octave', 'r', \ 'singular', 'sage0', 'sage'] - -from sage.repl.rich_output.display_manager import get_display_manager -if get_display_manager().is_in_terminal(): - from .axiom import axiom_console - from .fricas import fricas_console - from .gap import gap_console - from .gap3 import gap3_console - from .giac import giac_console - from .gp import gp_console - from .gnuplot import gnuplot_console - from .kash import kash_console - from .lisp import lisp_console - from .magma import magma_console - from .macaulay2 import macaulay2_console - from .maple import maple_console - from .maxima_abstract import maxima_console - from .mathematica import mathematica_console - from .mathics import mathics_console - from .matlab import matlab_console - from .mupad import mupad_console - from .mwrank import mwrank_console - from .octave import octave_console - from .qepcad import qepcad_console - from .singular import singular_console - from .sage0 import sage0_console - from .lie import lie_console - from .r import r_console +try: + from sage.repl.rich_output.display_manager import get_display_manager as _get_display_manager +except ImportError: + pass +else: + if _get_display_manager().is_in_terminal(): + from .axiom import axiom_console + from .fricas import fricas_console + from .gap import gap_console + from .gap3 import gap3_console + from .giac import giac_console + from .gp import gp_console + from .gnuplot import gnuplot_console + from .kash import kash_console + from .lisp import lisp_console + from .magma import magma_console + from .macaulay2 import macaulay2_console + from .maple import maple_console + from .maxima_abstract import maxima_console + from .mathematica import mathematica_console + from .mathics import mathics_console + from .matlab import matlab_console + from .mupad import mupad_console + from .mwrank import mwrank_console + from .octave import octave_console + from .qepcad import qepcad_console + from .singular import singular_console + from .sage0 import sage0_console + from .lie import lie_console + from .r import r_console From 177b365f3a61137a7c6aad965ee6399d2cbea5fd Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 23 Feb 2022 22:45:47 +0000 Subject: [PATCH 045/529] Fix single-object tuple > object --- src/sage/interacts/library.py | 44 +++++++++++++++-------------------- 1 file changed, 19 insertions(+), 25 deletions(-) diff --git a/src/sage/interacts/library.py b/src/sage/interacts/library.py index 48aaf7e4fbd..6ee200ce799 100644 --- a/src/sage/interacts/library.py +++ b/src/sage/interacts/library.py @@ -1066,21 +1066,19 @@ def trapezoid_integration( if title is None: title = text_control("

Trapezoid integration

") if f is None: - f = (input_box(default="x^2-5*x + 10", label="$f(x)=$"),) + f = input_box(default="x^2-5*x + 10", label="$f(x)=$") if n is None: - n = (slider(1, 100, 1, 5, label="# divisions"),) + n = slider(1, 100, 1, 5, label="# divisions") if interval_input is None: - interval_input = ( - selector( + interval_input = selector( ["from slider", "from keyboard"], label="Integration interval", buttons=True, - ), ) if interval_s is None: - interval_s = (range_slider(-10, 10, default=(0, 8), label="slider: "),) + interval_s = range_slider(-10, 10, default=(0, 8), label="slider: ") if interval_g is None: - interval_g = (input_grid(1, 2, default=[[0, 8]], label="keyboard: "),) + interval_g = input_grid(1, 2, default=[[0, 8]], label="keyboard: ") if output_form is None: output_form = selector( ["traditional", "table", "none"], label="Computations form", buttons=True @@ -1204,23 +1202,21 @@ def simpson_integration( output_form: ToggleButtons(description='Computations form', options=('traditional', 'table', 'none'), value='traditional') """ if title is None: - title = (text_control("

Simpson integration

"),) + title = text_control("

Simpson integration

") if f is None: - f = (input_box(default="x*sin(x)+x+1", label="$f(x)=$"),) + f = input_box(default="x*sin(x)+x+1", label="$f(x)=$") if n is None: - n = (slider(2, 100, 2, 6, label="# divisions"),) + n = slider(2, 100, 2, 6, label="# divisions") if interval_input is None: - interval_input = ( - selector( + interval_input = selector( ["from slider", "from keyboard"], label="Integration interval", buttons=True, - ), ) if interval_s is None: - interval_s = (range_slider(-10, 10, default=(0, 10), label="slider: "),) + interval_s = range_slider(-10, 10, default=(0, 10), label="slider: ") if interval_g is None: - interval_g = (input_grid(1, 2, default=[[0, 10]], label="keyboard: "),) + interval_g = input_grid(1, 2, default=[[0, 10]], label="keyboard: ") if output_form is None: output_form = selector( ["traditional", "table", "none"], label="Computations form", buttons=True @@ -1365,27 +1361,25 @@ def riemann_sum( - Robert Marik (2010-08) """ if title is None: - title = (text_control("

Riemann integral with random sampling

"),) + title = text_control("

Riemann integral with random sampling

") if f is None: - f = (input_box("x^2+1", label="$f(x)=$", width=40),) + f = input_box("x^2+1", label="$f(x)=$", width=40) if n is None: - n = (slider(1, 30, 1, 5, label="# divisions"),) + n = slider(1, 30, 1, 5, label="# divisions") if hr1 is None: - hr1 = (text_control("
"),) + hr1 = text_control("
") if interval_input is None: - interval_input = ( - selector( + interval_input = selector( ["from slider", "from keyboard"], label="Integration interval", buttons=True, - ), ) if interval_s is None: - interval_s = (range_slider(-5, 10, default=(0, 2), label="slider: "),) + interval_s = range_slider(-5, 10, default=(0, 2), label="slider: ") if interval_g is None: - interval_g = (input_grid(1, 2, default=[[0, 2]], label="keyboard: "),) + interval_g = input_grid(1, 2, default=[[0, 2]], label="keyboard: ") if hr2 is None: - hr2 = (text_control("
"),) + hr2 = text_control("
") if list_table is None: list_table = checkbox(default=False, label="List table") From d747e1d493f6de1949088a623191a0f2de439d73 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Tue, 1 Mar 2022 13:52:01 +0100 Subject: [PATCH 046/529] Convert to decorator factory --- src/sage/interacts/library.py | 510 +++++++++++++---------- src/sage/interacts/test_jupyter.rst | 10 +- src/sage/repl/ipython_kernel/interact.py | 8 +- 3 files changed, 300 insertions(+), 228 deletions(-) diff --git a/src/sage/interacts/library.py b/src/sage/interacts/library.py index d0efe5ba1e7..1fae217f7b6 100644 --- a/src/sage/interacts/library.py +++ b/src/sage/interacts/library.py @@ -35,6 +35,7 @@ # https://www.gnu.org/licenses/ # ***************************************************************************** +from typing import Any, Callable from sage.arith.misc import factor from sage.arith.srange import srange from sage.calculus.all import symbolic_expression @@ -77,30 +78,49 @@ from sage.repl.ipython_kernel.all_jupyter import (interact, checkbox, input_box, input_grid, range_slider, selector, slider, text_control) -def library_interact(f): + +def library_interact(**widgets: Callable[..., Any]): r""" This is a decorator for using interacts in the Sage library. - This is just the ``interact`` function wrapped in an additional - function call: ``library_interact(f)()`` is equivalent to - executing ``interact(f)``. + This is essentially a wrapper around the ``interact`` function. + + INPUT: + + - ``**widgets`` -- keyword arguments that are passed to the + ``interact`` function to create the widgets. Each value must be a callable that + returns a widget. EXAMPLES:: - sage: import sage.interacts.library as library - sage: @library.library_interact - ....: def f(n=5): + sage: from sage.interacts.library import library_interact + sage: @library_interact(n=lambda: slider(-5, 15, None, 5)) + ....: def f(n): ....: print(n) sage: f() # an interact appears if using the notebook, else code Interactive function with 1 widget - n: IntSlider(value=5, description='n', max=15, min=-5) + n: TransformIntSlider(value=5, description='n', max=15, min=-5) + + .. NOTE:: + + We use a callable to construct the widget so that the widget is only + initialized when the function is called and not upon loading the module. """ - @sage_wraps(f) - def library_wrapper(): - # This will display the interact, no need to return anything - interact(f) - return library_wrapper + def decorator(f: Callable[..., Any]): + @sage_wraps(f) + def library_wrapper(): + widgets_constructed = { + key: constructor() for key, constructor in widgets.items() + } + # This will display the interact, no need to return anything + interact(f, **widgets_constructed) + + # Store the widget constructors for later use in tests + library_wrapper._widgets = widgets + return library_wrapper + + return decorator def html(obj): r""" @@ -116,15 +136,15 @@ def html(obj): pretty_print(html(obj)) -@library_interact -def demo(n=slider(range(10)), m=slider(range(10))): +@library_interact(n=lambda: slider(range(10)), m=lambda: slider(range(10))) +def demo(n: int, m: int): r""" This is a demo interact that sums two numbers. INPUT: - - ``n`` -- integer slider - - ``m`` -- integer slider + - ``n`` -- integer + - ``m`` -- integer EXAMPLES: @@ -140,10 +160,13 @@ def demo(n=slider(range(10)), m=slider(range(10))): """ print(n + m) -@library_interact -def taylor_polynomial( - title = text_control('

Taylor polynomial

'), - f=input_box(sin(x)*exp(-x),label="$f(x)=$"), order=slider(range(1,13))): + +@library_interact( + title=lambda: text_control("

Taylor polynomial

"), + f=lambda: input_box(sin(x) * exp(-x), label="$f(x)=$"), + order=lambda: slider(range(1, 13)), +) +def taylor_polynomial(title, f, order: int): r""" Illustrate the Taylor polynomial approximation of various orders around `x=0`. @@ -151,7 +174,7 @@ def taylor_polynomial( INPUT: - ``f`` -- function expression - - ``order`` -- integer slider + - ``order`` -- integer EXAMPLES: @@ -177,14 +200,17 @@ def taylor_polynomial( show(dot + p + pt, ymin = -.5, ymax = 1) -@library_interact -def definite_integral( - title = text_control('

Definite integral

'), - f = input_box(default = "3*x", label = '$f(x)=$'), - g = input_box(default = "x^2", label = '$g(x)=$'), - interval = range_slider(-10,10,default=(0,3), label="Interval"), - x_range = range_slider(-10,10,default=(0,3), label = "plot range (x)"), - selection = selector(["f", "g", "f and g", "f - g"], default="f and g", label="Select")): +@library_interact( + title=lambda: text_control("

Definite integral

"), + f=lambda: input_box(default="3*x", label="$f(x)=$"), + g=lambda: input_box(default="x^2", label="$g(x)=$"), + interval=lambda: range_slider(-10, 10, default=(0, 3), label="Interval"), + x_range=lambda: range_slider(-10, 10, default=(0, 3), label="plot range (x)"), + selection=lambda: selector( + ["f", "g", "f and g", "f - g"], default="f and g", label="Select" + ), +) +def definite_integral(title, f, g, interval, x_range, selection): r""" This is a demo interact for plotting the definite integral of a function based on work by Lauri Ruotsalainen, 2010. @@ -264,12 +290,14 @@ def definite_integral( show(f_plot + g_plot + h_plot, gridlines=True) html(text) -@library_interact -def function_derivative( - title = text_control('

Derivative grapher

'), - function = input_box(default="x^5-3*x^3+1", label="Function:"), - x_range = range_slider(-15,15,0.1, default=(-2,2), label="Range (x)"), - y_range = range_slider(-15,15,0.1, default=(-8,6), label="Range (y)")): + +@library_interact( + title=lambda: text_control("

Derivative grapher

"), + function=lambda: input_box(default="x^5-3*x^3+1", label="Function:"), + x_range=lambda: range_slider(-15, 15, 0.1, default=(-2, 2), label="Range (x)"), + y_range=lambda: range_slider(-15, 15, 0.1, default=(-8, 6), label="Range (y)"), +) +def function_derivative(title, function, x_range, y_range): r""" This is a demo interact for plotting derivatives of a function based on work by Lauri Ruotsalainen, 2010. @@ -309,13 +337,14 @@ def function_derivative( html(r"
$\color{Red}{f''(x) = %s}$
" % latex(ddf(x))) -@library_interact -def difference_quotient( - title = text_control('

Difference quotient

'), - f = input_box(default="sin(x)", label='f(x)'), - interval= range_slider(0, 10, 0.1, default=(0.0,10.0), label="Range"), - a = slider(0, 10, None, 5.5, label = '$a$'), - x0 = slider(0, 10, None, 2.5, label = '$x_0$ (start point)')): +@library_interact( + title=lambda: text_control("

Difference quotient

"), + f=lambda: input_box(default="sin(x)", label="f(x)"), + interval=lambda: range_slider(0, 10, 0.1, default=(0.0, 10.0), label="Range"), + a=lambda: slider(0, 10, None, 5.5, label="$a$"), + x0=lambda: slider(0, 10, None, 2.5, label="$x_0$ (start point)"), +) +def difference_quotient(title, f, interval, a, x0): r""" This is a demo interact for difference quotient based on work by Lauri Ruotsalainen, 2010. @@ -375,8 +404,13 @@ def difference_quotient( html(r"$\text{Slope:}$") html(r"$k = \frac{f(x_0)-f(a)}{x_0-a} = %s$
" % (N(derivative(tanf(x), x), digits=5))) -@library_interact -def quadratic_equation(A = slider(-7, 7, 1, 1), B = slider(-7, 7, 1, 1), C = slider(-7, 7, 1, -2)): + +@library_interact( + A=lambda: slider(-7, 7, 1, 1), + B=lambda: slider(-7, 7, 1, 1), + C=lambda: slider(-7, 7, 1, -2), +) +def quadratic_equation(A, B, C): r""" This is a demo interact for solving quadratic equations based on work by Lauri Ruotsalainen, 2010. @@ -433,11 +467,12 @@ def quadratic_equation(A = slider(-7, 7, 1, 1), B = slider(-7, 7, 1, 1), C = sli r"\frac{-%s\pm\sqrt{%s}}{%s} = %s$" html(calc % (B, dis1, A, B, dis2, (2*A), sol)) -@library_interact -def trigonometric_properties_triangle( - a0 = slider(0, 360, 1, 30, label="A"), - a1 = slider(0, 360, 1, 180, label="B"), - a2 = slider(0, 360, 1, 300, label="C")): +@library_interact( + a0=lambda: slider(0, 360, 1, 30, label="A"), + a1=lambda: slider(0, 360, 1, 180, label="B"), + a2=lambda: slider(0, 360, 1, 300, label="C"), +) +def trigonometric_properties_triangle(a0, a1, a2): r""" This is an interact for demonstrating trigonometric properties in a triangle based on work by Lauri Ruotsalainen, 2010. @@ -514,10 +549,12 @@ def area(alpha, a, b): html(r"$AB = %.6f$, $BC = %.6f$, $CA = %.6f$" % (al[2], al[0], al[1])) html(r"Area of triangle $ABC = %.6f$" % A) -@library_interact -def unit_circle( - function = selector([(0, sin(x)), (1, cos(x)), (2, tan(x))]), - x = slider(0,2*pi, 0.005*pi, 0)): + +@library_interact( + function=lambda: selector([(0, sin(x)), (1, cos(x)), (2, tan(x))]), + x=lambda: slider(0, 2 * pi, 0.005 * pi, 0), +) +def unit_circle(function, x): r""" This is an interact for Sin, Cos and Tan in the Unit Circle based on work by Lauri Ruotsalainen, 2010. @@ -588,18 +625,30 @@ def unit_circle( show(graphics_array([C_graph, G_graph])) -@library_interact +@library_interact( + title=lambda: text_control("

Special points in triangle

"), + a0=lambda: slider(0, 360, 1, 30, label="A"), + a1=lambda: slider(0, 360, 1, 180, label="B"), + a2=lambda: slider(0, 360, 1, 300, label="C"), + show_median=lambda: checkbox(False, label="Medians"), + show_pb=lambda: checkbox(False, label="Perpendicular Bisectors"), + show_alt=lambda: checkbox(False, label="Altitudes"), + show_ab=lambda: checkbox(False, label="Angle Bisectors"), + show_incircle=lambda: checkbox(False, label="Incircle"), + show_euler=lambda: checkbox(False, label="Euler's Line"), +) def special_points( - title = text_control('

Special points in triangle

'), - a0 = slider(0, 360, 1, 30, label="A"), - a1 = slider(0, 360, 1, 180, label="B"), - a2 = slider(0, 360, 1, 300, label="C"), - show_median = checkbox(False, label="Medians"), - show_pb = checkbox(False, label="Perpendicular Bisectors"), - show_alt = checkbox(False, label="Altitudes"), - show_ab = checkbox(False, label="Angle Bisectors"), - show_incircle = checkbox(False, label="Incircle"), - show_euler = checkbox(False, label="Euler's Line")): + title, + a0, + a1, + a2, + show_median, + show_pb, + show_alt, + show_ab, + show_incircle, + show_euler, +): r""" This interact demo shows special points in a triangle based on work by Lauri Ruotsalainen, 2010. @@ -767,8 +816,13 @@ def line_to_points(x1_y1, x2_y2, **plot_kwargs): ) -@library_interact -def coin(n = slider(2,10000, 100, default=1000, label="Number of Tosses"), interval = range_slider(0, 1, default=(0.45, 0.55), label="Plotting range (y)")): +@library_interact( + n=lambda: slider(2, 10000, 100, default=1000, label="Number of Tosses"), + interval=lambda: range_slider( + 0, 1, default=(0.45, 0.55), label="Plotting range (y)" + ), +) +def coin(n, interval): r""" This interact demo simulates repeated tosses of a coin, based on work by Lauri Ruotsalainen, 2010. @@ -805,13 +859,14 @@ def coin(n = slider(2,10000, 100, default=1000, label="Number of Tosses"), inter show(point(c[1:], gridlines=[None, [0.5]], pointsize=1), ymin=interval[0], ymax=interval[1]) -@library_interact -def bisection_method( - title = text_control('

Bisection method

'), - f = input_box("x^2-2", label='f(x)'), - interval = range_slider(-5,5,default=(0, 4), label="range"), - d = slider(1, 8, 1, 3, label="$10^{-d}$ precision"), - maxn = slider(0,50,1,10, label="max iterations")): +@library_interact( + title=lambda: text_control("

Bisection method

"), + f=lambda: input_box("x^2-2", label="f(x)"), + interval=lambda: range_slider(-5, 5, default=(0, 4), label="range"), + d=lambda: slider(1, 8, 1, 3, label="$10^{-d}$ precision"), + maxn=lambda: slider(0, 50, 1, 10, label="max iterations"), +) +def bisection_method(title, f, interval, d, maxn): r""" Interact explaining the bisection method, based on similar interact explaining secant method and Wiliam Stein's example from wiki. @@ -882,13 +937,15 @@ def _bisection_method(f, a, b, maxn, eps): L += sum(line([(d,k*i-k/4), (d,k*i+k/4)]) for i, (c,d) in enumerate(intervals) ) show(P + L, xmin=a, xmax=b) -@library_interact -def secant_method( - title = text_control('

Secant method for numerical root finding

'), - f = input_box("x^2-2", label='f(x)'), - interval = range_slider(-5,5,default=(0, 4), label="range"), - d = slider(1, 16, 1, 3, label="10^-d precision"), - maxn = slider(0,15,1,10, label="max iterations")): + +@library_interact( + title=lambda: text_control("

Secant method for numerical root finding

"), + f=lambda: input_box("x^2-2", label="f(x)"), + interval=lambda: range_slider(-5, 5, default=(0, 4), label="range"), + d=lambda: slider(1, 16, 1, 3, label="10^-d precision"), + maxn=lambda: slider(0, 15, 1, 10, label="max iterations"), +) +def secant_method(title, f, interval, d, maxn): r""" Interact explaining the secant method, based on work by Lauri Ruotsalainen, 2010. @@ -949,15 +1006,17 @@ def _secant_method(f, a, b, maxn, h): S = sum(line([(c,f(c)), (d,f(d)), (d-(d-c)*f(d)/(f(d)-f(c)), 0)], color="green") for (c,d) in intervals) show(P + L + S, xmin=a, xmax=b) -@library_interact -def newton_method( - title = text_control('

Newton method

'), - f = input_box("x^2 - 2"), - c = slider(-10,10, default=6, label='Start ($x$)'), - d = slider(1, 16, 1, 3, label="$10^{-d}$ precision"), - maxn = slider(0, 15, 1, 10, label="max iterations"), - interval = range_slider(-10,10, default = (0,6), label="Interval"), - list_steps = checkbox(default=False, label="List steps")): + +@library_interact( + title=lambda: text_control("

Newton method

"), + f=lambda: input_box("x^2 - 2"), + c=lambda: slider(-10, 10, default=6, label="Start ($x$)"), + d=lambda: slider(1, 16, 1, 3, label="$10^{-d}$ precision"), + maxn=lambda: slider(0, 15, 1, 10, label="max iterations"), + interval=lambda: range_slider(-10, 10, default=(0, 6), label="Interval"), + list_steps=lambda: checkbox(default=False, label="List steps"), +) +def newton_method(title, f, c, d, maxn, interval, list_steps): r""" Interact explaining the Newton method, based on work by Lauri Ruotsalainen, 2010. @@ -1021,15 +1080,24 @@ def _newton_method(f, c, maxn, h): L += line([(midpoints[i], f(midpoints[i])), (midpoints[i+1], 0)], color="red") show(P + L, xmin=interval[0], xmax=interval[1], ymin=P.ymin(), ymax=P.ymax()) -@library_interact + +@library_interact( + title=lambda: text_control("

Trapezoid integration

"), + f=lambda: input_box(default="x^2-5*x + 10", label="$f(x)=$"), + n=lambda: slider(1, 100, 1, 5, label="# divisions"), + interval_input=lambda: selector( + ["from slider", "from keyboard"], + label="Integration interval", + buttons=True, + ), + interval_s=lambda: range_slider(-10, 10, default=(0, 8), label="slider: "), + interval_g=lambda: input_grid(1, 2, default=[[0, 8]], label="keyboard: "), + output_form=lambda: selector( + ["traditional", "table", "none"], label="Computations form", buttons=True + ), +) def trapezoid_integration( - title=None, - f=None, - n=None, - interval_input=None, - interval_s=None, - interval_g=None, - output_form=None, + title, f, n, interval_input, interval_s, interval_g, output_form ): r""" Interact explaining the trapezoid method for definite integrals. @@ -1064,27 +1132,6 @@ def trapezoid_integration( interval_g: Grid(value=[[0, 8]], children=(Label(value='keyboard: '), VBox(children=(EvalText(value='0', layout=Layout(max_width='5em')),)), VBox(children=(EvalText(value='8', layout=Layout(max_width='5em')),)))) output_form: ToggleButtons(description='Computations form', options=('traditional', 'table', 'none'), value='traditional') """ - if title is None: - title = text_control("

Trapezoid integration

") - if f is None: - f = input_box(default="x^2-5*x + 10", label="$f(x)=$") - if n is None: - n = slider(1, 100, 1, 5, label="# divisions") - if interval_input is None: - interval_input = selector( - ["from slider", "from keyboard"], - label="Integration interval", - buttons=True, - ) - if interval_s is None: - interval_s = range_slider(-10, 10, default=(0, 8), label="slider: ") - if interval_g is None: - interval_g = input_grid(1, 2, default=[[0, 8]], label="keyboard: ") - if output_form is None: - output_form = selector( - ["traditional", "table", "none"], label="Computations form", buttons=True - ) - xs = [] ys = [] if interval_input == 'from slider': @@ -1159,15 +1206,30 @@ def trapezoid_integration( s.append([i, xs[i], ys[i],j,N(j*ys[i])]) pretty_print(table(s, header_row=True)) -@library_interact + +@library_interact( + title=lambda: text_control("

Simpson integration

"), + f=lambda: input_box(default="x*sin(x)+x+1", label="$f(x)=$"), + n=lambda: slider(2, 100, 2, 6, label="# divisions"), + interval_input=lambda: selector( + ["from slider", "from keyboard"], + label="Integration interval", + buttons=True, + ), + interval_s=lambda: range_slider(-10, 10, default=(0, 10), label="slider: "), + interval_g=lambda: input_grid(1, 2, default=[[0, 10]], label="keyboard: "), + output_form=lambda: selector( + ["traditional", "table", "none"], label="Computations form", buttons=True + ), +) def simpson_integration( - title=None, - f=None, - n=None, - interval_input=None, - interval_s=None, - interval_g=None, - output_form=None, + title, + f, + n, + interval_input, + interval_s, + interval_g, + output_form, ): r""" Interact explaining the simpson method for definite integrals. @@ -1202,27 +1264,6 @@ def simpson_integration( interval_g: Grid(value=[[0, 10]], children=(Label(value='keyboard: '), VBox(children=(EvalText(value='0', layout=Layout(max_width='5em')),)), VBox(children=(EvalText(value='10', layout=Layout(max_width='5em')),)))) output_form: ToggleButtons(description='Computations form', options=('traditional', 'table', 'none'), value='traditional') """ - if title is None: - title = text_control("

Simpson integration

") - if f is None: - f = input_box(default="x*sin(x)+x+1", label="$f(x)=$") - if n is None: - n = slider(2, 100, 2, 6, label="# divisions") - if interval_input is None: - interval_input = selector( - ["from slider", "from keyboard"], - label="Integration interval", - buttons=True, - ) - if interval_s is None: - interval_s = range_slider(-10, 10, default=(0, 10), label="slider: ") - if interval_g is None: - interval_g = input_grid(1, 2, default=[[0, 10]], label="keyboard: ") - if output_form is None: - output_form = selector( - ["traditional", "table", "none"], label="Computations form", buttons=True - ) - x = SR.var("x") f = symbolic_expression(f).function(x) if interval_input == 'from slider': @@ -1313,17 +1354,33 @@ def parabola(a, b, c): html(r'$\int_{%.2f}^{%.2f} {f(x) \, \mathrm{d}x}\approx\frac {%.2f}{3}\cdot %s=%s$'% (interval[0], interval[1],dx,latex(3/dx*approx),latex(approx))) -@library_interact + +@library_interact( + title=lambda: text_control("

Riemann integral with random sampling

"), + f=lambda: input_box("x^2+1", label="$f(x)=$", width=40), + n=lambda: slider(1, 30, 1, 5, label="# divisions"), + hr1=lambda: text_control("
"), + interval_input=lambda: selector( + ["from slider", "from keyboard"], + label="Integration interval", + buttons=True, + ), + interval_s=lambda: range_slider(-5, 10, default=(0, 2), label="slider: "), + interval_g=lambda: input_grid(1, 2, default=[[0, 2]], label="keyboard: "), + hr2=lambda: text_control("
"), + list_table=lambda: checkbox(default=False, label="List table"), + auto_update=lambda: False, +) def riemann_sum( - title=None, - f=None, - n=None, - hr1=None, - interval_input=None, - interval_s=None, - interval_g=None, - hr2=None, - list_table=None, + title, + f, + n, + hr1, + interval_input, + interval_s, + interval_g, + hr2, + list_table, auto_update=False, ): r""" @@ -1361,29 +1418,6 @@ def riemann_sum( - Robert Marik (2010-08) """ - if title is None: - title = text_control("

Riemann integral with random sampling

") - if f is None: - f = input_box("x^2+1", label="$f(x)=$", width=40) - if n is None: - n = slider(1, 30, 1, 5, label="# divisions") - if hr1 is None: - hr1 = text_control("
") - if interval_input is None: - interval_input = selector( - ["from slider", "from keyboard"], - label="Integration interval", - buttons=True, - ) - if interval_s is None: - interval_s = range_slider(-5, 10, default=(0, 2), label="slider: ") - if interval_g is None: - interval_g = input_grid(1, 2, default=[[0, 2]], label="keyboard: ") - if hr2 is None: - hr2 = text_control("
") - if list_table is None: - list_table = checkbox(default=False, label="List table") - x = SR.var('x') from random import random if interval_input == 'from slider': @@ -1424,16 +1458,44 @@ def riemann_sum( (latex(a),latex(b),latex(func(x)),latex(integral_numerical(func(x),a,b)[0]))) -x = SR.var('x') -@library_interact -def function_tool(f=sin(x), g=cos(x), xrange=range_slider(-3,3,default=(0,1),label='x-range'), - yrange='auto', - a=1, - action=selector(['f', 'df/dx', 'int f', 'num f', 'den f', '1/f', 'finv', - 'f+a', 'f-a', 'f*a', 'f/a', 'f^a', 'f(x+a)', 'f(x*a)', - 'f+g', 'f-g', 'f*g', 'f/g', 'f(g)'], - width=15, nrows=5, label="h = "), - do_plot = ("Draw Plots", True)): +x = SR.var("x") + + +@library_interact( + f=lambda: sin(x), + g=lambda: cos(x), + xrange=lambda: range_slider(-3, 3, default=(0, 1), label="x-range"), + yrange=lambda: "auto", + a=lambda: 1, + action=lambda: selector( + [ + "f", + "df/dx", + "int f", + "num f", + "den f", + "1/f", + "finv", + "f+a", + "f-a", + "f*a", + "f/a", + "f^a", + "f(x+a)", + "f(x*a)", + "f+g", + "f-g", + "f*g", + "f/g", + "f(g)", + ], + width=15, + nrows=5, + label="h = ", + ), + do_plot=lambda: ("Draw Plots", True), +) +def function_tool(f, g, xrange, yrange, a, action, do_plot): r""" `Function Plotting Tool `_ (by William Stein (?)) @@ -1551,15 +1613,18 @@ def function_tool(f=sin(x), g=cos(x), xrange=range_slider(-3,3,default=(0,1),lab yrange = sage_eval(yrange) show(P, xmin=xrange[0], xmax=xrange[1], ymin=yrange[0], ymax=yrange[1]) -@library_interact -def julia(expo = slider(-10,10,0.1,2), - c_real = slider(-2,2,0.01,0.5, label='real part const.'), - c_imag = slider(-2,2,0.01,0.5, label='imag part const.'), - iterations=slider(1,100,1,20, label='# iterations'), - zoom_x = range_slider(-2,2,0.01,(-1.5,1.5), label='Zoom X'), - zoom_y = range_slider(-2,2,0.01,(-1.5,1.5), label='Zoom Y'), - plot_points = slider(20,400,20, default=150, label='plot points'), - dpi = slider(20, 200, 10, default=80, label='dpi')): + +@library_interact( + expo=lambda: slider(-10, 10, 0.1, 2), + c_real=lambda: slider(-2, 2, 0.01, 0.5, label="real part const."), + c_imag=lambda: slider(-2, 2, 0.01, 0.5, label="imag part const."), + iterations=lambda: slider(1, 100, 1, 20, label="# iterations"), + zoom_x=lambda: range_slider(-2, 2, 0.01, (-1.5, 1.5), label="Zoom X"), + zoom_y=lambda: range_slider(-2, 2, 0.01, (-1.5, 1.5), label="Zoom Y"), + plot_points=lambda: slider(20, 400, 20, default=150, label="plot points"), + dpi=lambda: slider(20, 200, 10, default=80, label="dpi"), +) +def julia(expo, c_real, c_imag, iterations, zoom_x, zoom_y, plot_points, dpi): r""" Julia Fractal, based on `Julia by Harald Schilly `_. @@ -1604,13 +1669,16 @@ def julia(expo = slider(-10,10,0.1,2), html(r'Recursive Formula: $z \leftarrow z^{%.2f} + (%.2f+%.2f*\mathbb{I})$' % (expo, c_real, c_imag)) complex_plot(lambda z: julia(ff_j, z, iterations), zoom_x, zoom_y, plot_points=plot_points, dpi=dpi).show(frame=True, aspect_ratio=1) -@library_interact -def mandelbrot(expo = slider(-10,10,0.1,2), - iterations=slider(1,100,1,20, label='# iterations'), - zoom_x = range_slider(-2,2,0.01,(-2,1), label='Zoom X'), - zoom_y = range_slider(-2,2,0.01,(-1.5,1.5), label='Zoom Y'), - plot_points = slider(20,400,20, default=150, label='plot points'), - dpi = slider(20, 200, 10, default=80, label='dpi')): + +@library_interact( + expo=lambda: slider(-10, 10, 0.1, 2), + iterations=lambda: slider(1, 100, 1, 20, label="# iterations"), + zoom_x=lambda: range_slider(-2, 2, 0.01, (-2, 1), label="Zoom X"), + zoom_y=lambda: range_slider(-2, 2, 0.01, (-1.5, 1.5), label="Zoom Y"), + plot_points=lambda: slider(20, 400, 20, default=150, label="plot points"), + dpi=lambda: slider(20, 200, 10, default=80, label="dpi"), +) +def mandelbrot(expo, iterations, zoom_x, zoom_y, plot_points, dpi): r""" Mandelbrot Fractal, based on `Mandelbrot by Harald Schilly `_. @@ -1651,11 +1719,12 @@ def mandelbrot(expo = slider(-10,10,0.1,2), complex_plot(lambda z: mandel(ff_m, z, iterations), zoom_x, zoom_y, plot_points=plot_points, dpi=dpi).show(frame=True, aspect_ratio=1) -@library_interact -def cellular_automaton( - N=slider(1,500,1,label='Number of iterations',default=100), - rule_number=slider(0, 255, 1, default=110, label='Rule number'), - size = slider(1, 11, step_size=1, default=6, label='size of graphic')): +@library_interact( + N=lambda: slider(1, 500, 1, label="Number of iterations", default=100), + rule_number=lambda: slider(0, 255, 1, default=110, label="Rule number"), + size=lambda: slider(1, 11, step_size=1, default=6, label="size of graphic"), +) +def cellular_automaton(N, rule_number, size): r""" Yields a matrix showing the evolution of a `Wolfram's cellular automaton `_. @@ -1703,14 +1772,15 @@ def cellular_automaton( plot_M.show(figsize=[size,size]) -@library_interact -def polar_prime_spiral( - interval = range_slider(1, 4000, 10, default=(1, 1000), label="range"), - show_factors = True, - highlight_primes = True, - show_curves = True, - n = slider(1,200, 1, default=89, label="number $n$"), - dpi = slider(10,300, 10, default=100, label="dpi")): +@library_interact( + interval=lambda: range_slider(1, 4000, 10, default=(1, 1000), label="range"), + show_factors=lambda: True, + highlight_primes=lambda: True, + show_curves=lambda: True, + n=lambda: slider(1, 200, 1, default=89, label="number $n$"), + dpi=lambda: slider(10, 300, 10, default=100, label="dpi"), +) +def polar_prime_spiral(interval, show_factors, highlight_primes, show_curves, n, dpi): r""" Polar Prime Spiral interact, based on work by David Runde. diff --git a/src/sage/interacts/test_jupyter.rst b/src/sage/interacts/test_jupyter.rst index 55c4bfbf97f..0228ea227c1 100644 --- a/src/sage/interacts/test_jupyter.rst +++ b/src/sage/interacts/test_jupyter.rst @@ -19,7 +19,9 @@ which are produced by the interact are not displayed, but text is. :: sage: def test(lib_interact): ....: f = lib_interact.f # Underlying non-wrapped function - ....: w = interact(f).widget # "interactive" widget + ....: widgets = lib_interact._widgets + ....: widgets_constructed = {key: constructor() for key, constructor in widgets.items()} + ....: w = interact(f, **widgets_constructed).widget # "interactive" widget ....: kwargs = {widget._kwarg: widget.get_interact_value() ....: for widget in w.kwargs_widgets} ....: return f(**kwargs) @@ -27,7 +29,7 @@ which are produced by the interact are not displayed, but text is. :: This is just to test that failures in the interact are actually seen:: sage: from sage.interacts.library import library_interact - sage: @library_interact + sage: @library_interact() ....: def failure(): ....: raise Exception("gotcha") sage: test(failure) @@ -284,8 +286,8 @@ Test all interacts from the Sage interact library:: Test matrix control (see :trac:`27735`):: - sage: @library_interact - ....: def matrix_test(A=matrix(QQ, 2, 2, range(4))): + sage: @library_interact(A=lambda: matrix(QQ, 2, 2, range(4))) + ....: def matrix_test(A): ....: print(A) ....: print(parent(A)) sage: test(matrix_test) diff --git a/src/sage/repl/ipython_kernel/interact.py b/src/sage/repl/ipython_kernel/interact.py index 5f8e9912569..e159159aa5e 100644 --- a/src/sage/repl/ipython_kernel/interact.py +++ b/src/sage/repl/ipython_kernel/interact.py @@ -62,7 +62,7 @@ class sage_interactive(interactive): y: Text(value='hello', description='y') z: Dropdown(description='z', options=('one', 'two', 'three'), value=None) """ - def __init__(*args, **kwds): + def __init__(self, *args, **kwds): """ See :class:`ipywidgets.widgets.interaction.interactive` @@ -83,11 +83,11 @@ def __init__(*args, **kwds): Interactive function with 0 widgets """ # Use *args to avoid name clash with keyword arguments - if len(args) < 3: - (self, f) = args + if len(args) < 2: + f = args[0] options = {} else: - (self, f, options) = args + (f, options) = args options = options.copy() # Check for auto_update in signature From eb61abcaf9850aac53f5ed1f9b97b7f2b128ab3a Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Wed, 2 Mar 2022 13:18:58 +0800 Subject: [PATCH 047/529] one more instance of 0^0 = 1 --- src/sage/rings/polynomial/polynomial_template.pxi | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/polynomial/polynomial_template.pxi b/src/sage/rings/polynomial/polynomial_template.pxi index 3027c7e6179..8d5adb3c306 100644 --- a/src/sage/rings/polynomial/polynomial_template.pxi +++ b/src/sage/rings/polynomial/polynomial_template.pxi @@ -597,9 +597,10 @@ cdef class Polynomial_template(Polynomial): elif e < 0: recip = 1 # delay because powering frac field elements is slow e = -e + if not self: - if e == 0: - raise ArithmeticError("0^0 is undefined.") + return (self)._parent(int(not e)) + cdef type T = type(self) cdef Polynomial_template r = T.__new__(T) From 53ed8d19b64cb96f533162908266f795fcf1f314 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 2 Mar 2022 13:14:21 +0100 Subject: [PATCH 048/529] Add backwards compatibility --- src/sage/interacts/library.py | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/src/sage/interacts/library.py b/src/sage/interacts/library.py index 1fae217f7b6..6a2b6e89c01 100644 --- a/src/sage/interacts/library.py +++ b/src/sage/interacts/library.py @@ -36,6 +36,7 @@ # ***************************************************************************** from typing import Any, Callable + from sage.arith.misc import factor from sage.arith.srange import srange from sage.calculus.all import symbolic_expression @@ -79,7 +80,9 @@ input_box, input_grid, range_slider, selector, slider, text_control) -def library_interact(**widgets: Callable[..., Any]): +def library_interact( + decorator_target: Callable[..., Any] = None, **widgets: Callable[..., Any] +): r""" This is a decorator for using interacts in the Sage library. @@ -101,6 +104,21 @@ def library_interact(**widgets: Callable[..., Any]): Interactive function with 1 widget n: TransformIntSlider(value=5, description='n', max=15, min=-5) + TESTS: + Backwards compatibility:: + + sage: from sage.interacts.library import library_interact + sage: @library_interact + ....: def f(n=slider(-5, 15, None, 5)): + ....: print(n) + doctest:warning + ... + DeprecationWarning: Use decorator factory @library_interact(widgets) instead of @library_interact without any arguments. + See https://trac.sagemath.org/33382 for details. + sage: f() # an interact appears if using the notebook, else code + Interactive function with 1 widget + n: TransformIntSlider(value=5, description='n', max=15, min=-5) + .. NOTE:: We use a callable to construct the widget so that the widget is only @@ -120,7 +138,17 @@ def library_wrapper(): library_wrapper._widgets = widgets return library_wrapper - return decorator + if decorator_target is None: + return decorator + else: + from sage.misc.superseded import deprecation + + deprecation( + 33382, + "Use decorator factory @library_interact(widgets) instead of @library_interact without any arguments.", + ) + return decorator(decorator_target) + def html(obj): r""" From fdd51be76399035a88c9a5944c96b60b7411a540 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 2 Mar 2022 17:09:27 +0100 Subject: [PATCH 049/529] Add newline --- src/sage/interacts/library.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/interacts/library.py b/src/sage/interacts/library.py index 6a2b6e89c01..a2d952526ac 100644 --- a/src/sage/interacts/library.py +++ b/src/sage/interacts/library.py @@ -105,6 +105,7 @@ def library_interact( n: TransformIntSlider(value=5, description='n', max=15, min=-5) TESTS: + Backwards compatibility:: sage: from sage.interacts.library import library_interact From e6d8b23abf5952eafca16f98a9cc7a5e59033301 Mon Sep 17 00:00:00 2001 From: Javier Honrubia Date: Sun, 6 Mar 2022 19:15:39 +0100 Subject: [PATCH 050/529] Spaces eliminated --- src/sage/plot/point.py | 96 +++++++++++++++++++++--------------------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/src/sage/plot/point.py b/src/sage/plot/point.py index 9b9660ae3cb..35c9c6c06e1 100644 --- a/src/sage/plot/point.py +++ b/src/sage/plot/point.py @@ -109,13 +109,13 @@ def _plot3d_options(self, options=None): EXAMPLES:: - sage: A=point((1,1),size=22) - sage: a=A[0];a + sage: A = point((1,1),size=22) + sage: a = A[0]; a Point set defined by 1 point(s) - sage: b=a.plot3d() + sage: b = a.plot3d() sage: b.size 22 - sage: b=a.plot3d(size=3) + sage: b = a.plot3d(size=3) sage: b.size 3 """ @@ -148,50 +148,50 @@ def plot3d(self, z=0, **kwds): One point:: - sage: A=point((1,1)) - sage: a=A[0];a + sage: A = point((1, 1)) + sage: a = A[0]; a Point set defined by 1 point(s) - sage: b=a.plot3d() + sage: b = a.plot3d() .. PLOT:: - A=point((1,1)) - a=A[0] + A = point((1, 1)) + a = A[0] sphinx_plot(a.plot3d()) One point with a height:: - sage: A=point((1,1)) - sage: a=A[0];a + sage: A = point((1, 1)) + sage: a = A[0]; a Point set defined by 1 point(s) - sage: b=a.plot3d(z=3) + sage: b = a.plot3d(z=3) sage: b.loc[2] 3.0 .. PLOT:: - A=point((1,1)) - a=A[0] + A = point((1, 1)) + a = A[0] sphinx_plot(a.plot3d(z=3)) Multiple points:: - sage: P=point([(0,0), (1,1)]) - sage: p=P[0]; p + sage: P = point([(0, 0), (1, 1)]) + sage: p = P[0]; p Point set defined by 2 point(s) - sage: q=p.plot3d(size=22) + sage: q = p.plot3d(size=22) .. PLOT:: - P=point([(0,0), (1,1)]) - p=P[0] + P = point([(0, 0), (1, 1)]) + p = P[0] sphinx_plot(p.plot3d(size=22)) Multiple points with different heights:: - sage: P=point([(0,0), (1,1)]) - sage: p=P[0] - sage: q=p.plot3d(z=[2,3]) + sage: P = point([(0, 0), (1, 1)]) + sage: p = P[0] + sage: q = p.plot3d(z=[2,3]) sage: q.all[0].loc[2] 2.0 sage: q.all[1].loc[2] @@ -199,22 +199,22 @@ def plot3d(self, z=0, **kwds): .. PLOT:: - P=point([(0,0), (1,1)]) - p=P[0] + P = point([(0, 0), (1, 1)]) + p = P[0] sphinx_plot(p.plot3d(z=[2,3])) Note that keywords passed must be valid point3d options:: - sage: A=point((1,1),size=22) - sage: a=A[0];a + sage: A = point((1, 1), size=22) + sage: a = A[0]; a Point set defined by 1 point(s) - sage: b=a.plot3d() + sage: b = a.plot3d() sage: b.size 22 - sage: b=a.plot3d(pointsize=23) # only 2D valid option + sage: b = a.plot3d(pointsize=23) # only 2D valid option sage: b.size 22 - sage: b=a.plot3d(size=23) # correct keyword + sage: b = a.plot3d(size=23) # correct keyword sage: b.size 23 @@ -223,12 +223,12 @@ def plot3d(self, z=0, **kwds): Heights passed as a list should have same length as number of points:: - sage: P=point([(0,0), (1,1), (2,3)]) - sage: p=P[0] - sage: q=p.plot3d(z=2) + sage: P = point([(0, 0), (1, 1), (2, 3)]) + sage: p = P[0] + sage: q = p.plot3d(z=2) sage: q.all[1].loc[2] 2.0 - sage: q=p.plot3d(z=[2,-2]) + sage: q = p.plot3d(z=[2,-2]) Traceback (most recent call last): ... ValueError: Incorrect number of heights given @@ -257,8 +257,8 @@ def _repr_(self): EXAMPLES:: - sage: P=point([(0,0), (1,1)]) - sage: p=P[0]; p + sage: P = point([(0, 0), (1, 1)]) + sage: p = P[0]; p Point set defined by 2 point(s) """ return "Point set defined by %s point(s)" % len(self.xdata) @@ -269,8 +269,8 @@ def __getitem__(self, i): EXAMPLES:: - sage: P=point([(0,0), (1,1), (2,3)]) - sage: p=P[0]; p + sage: P = point([(0, 0), (1, 1), (2, 3)]) + sage: p = P[0]; p Point set defined by 3 point(s) sage: p[1] (1.0, 1.0) @@ -284,7 +284,7 @@ def _render_on_subplot(self, subplot): We check to make sure that :trac:`2076` is fixed by verifying all the points are red:: - sage: point(((1,1), (2,2), (3,3)), rgbcolor=hue(1), size=30) + sage: point(((1, 1), (2, 2), (3, 3)), rgbcolor=hue(1), size=30) Graphics object consisting of 1 graphics primitive """ options = self.options() @@ -333,39 +333,39 @@ def point(points, **kwds): EXAMPLES:: - sage: point((1,2)) + sage: point((1, 2)) Graphics object consisting of 1 graphics primitive .. PLOT:: - sphinx_plot(point((1,2))) + sphinx_plot(point((1, 2))) :: - sage: point((1,2,3)) + sage: point((1, 2, 3)) Graphics3d Object .. PLOT:: - sphinx_plot(point((1,2,3))) + sphinx_plot(point((1, 2, 3))) :: - sage: point([(0,0), (1,1)]) + sage: point([(0, 0), (1, 1)]) Graphics object consisting of 1 graphics primitive .. PLOT:: - sphinx_plot(point([(0,0), (1,1)])) + sphinx_plot(point([(0, 0), (1, 1)])) :: - sage: point([(0,0,1), (1,1,1)]) + sage: point([(0, 0, 1), (1, 1, 1)]) Graphics3d Object .. PLOT:: - sphinx_plot(point([(0,0,1), (1,1,1)])) + sphinx_plot(point([(0, 0, 1), (1, 1, 1)])) Extra options will get passed on to show(), as long as they are valid:: @@ -377,9 +377,9 @@ def point(points, **kwds): One can now use iterators (:trac:`13890`):: - sage: point(iter([(1,1,1)])) + sage: point(iter([(1, 1, 1)])) Graphics3d Object - sage: point(iter([(1,2),(3,5)])) + sage: point(iter([(1, 2), (3, 5)])) Graphics object consisting of 1 graphics primitive """ if isinstance(points, Iterator): From 238a482eae419ed7ed1872fc48ab7f97f44be084 Mon Sep 17 00:00:00 2001 From: Vincent Delecroix <20100.delecroix@gmail.com> Date: Sun, 13 Mar 2022 22:21:52 +0100 Subject: [PATCH 051/529] 33497: _coerce_/_coerce_c -> coerce --- src/sage/misc/functional.py | 2 +- .../quadratic_form__evaluate.pyx | 2 +- src/sage/rings/complex_double.pyx | 4 +- .../rings/finite_rings/element_pari_ffelt.pyx | 2 +- .../rings/finite_rings/finite_field_base.pyx | 14 +++--- src/sage/rings/finite_rings/integer_mod.pyx | 2 +- .../rings/finite_rings/integer_mod_ring.py | 4 +- src/sage/rings/integer.pyx | 2 +- .../polynomial/multi_polynomial_element.py | 2 +- .../multi_polynomial_libsingular.pyx | 50 +++++++++---------- .../rings/polynomial/multi_polynomial_ring.py | 4 +- src/sage/rings/polynomial/pbori/pbori.pyx | 8 +-- src/sage/rings/polynomial/plural.pyx | 16 +++--- .../rings/polynomial/polynomial_element.pyx | 6 +-- .../polynomial_integer_dense_ntl.pyx | 2 +- .../polynomial/polynomial_modn_dense_ntl.pyx | 6 +-- .../rings/polynomial/polynomial_template.pxi | 2 +- .../polynomial/polynomial_zmod_flint.pyx | 2 +- src/sage/rings/power_series_ring.py | 16 +++--- src/sage/rings/qqbar.py | 2 +- src/sage/rings/rational.pyx | 2 +- src/sage/rings/rational_field.py | 2 +- src/sage/rings/real_mpfi.pyx | 2 +- src/sage/structure/parent_old.pyx | 4 ++ src/sage/symbolic/expression.pyx | 4 +- src/sage/symbolic/ring.pyx | 10 ++-- 26 files changed, 88 insertions(+), 84 deletions(-) diff --git a/src/sage/misc/functional.py b/src/sage/misc/functional.py index 09d1b05ced9..4c9b9f5683d 100644 --- a/src/sage/misc/functional.py +++ b/src/sage/misc/functional.py @@ -184,7 +184,7 @@ def coerce(P, x): """ try: - return P._coerce_(x) + return P.coerce(x) except AttributeError: return P(x) diff --git a/src/sage/quadratic_forms/quadratic_form__evaluate.pyx b/src/sage/quadratic_forms/quadratic_form__evaluate.pyx index 9ee823da68f..01e9094786f 100644 --- a/src/sage/quadratic_forms/quadratic_form__evaluate.pyx +++ b/src/sage/quadratic_forms/quadratic_form__evaluate.pyx @@ -60,7 +60,7 @@ cdef QFEvaluateVector_cdef(Q, v): tmp_val += Q[i,j] * v[i] * v[j] ## Return the value (over R) - return Q.base_ring()._coerce_(tmp_val) + return Q.base_ring().coerce(tmp_val) diff --git a/src/sage/rings/complex_double.pyx b/src/sage/rings/complex_double.pyx index d8dad014081..4f6f6ce6b8e 100644 --- a/src/sage/rings/complex_double.pyx +++ b/src/sage/rings/complex_double.pyx @@ -415,9 +415,9 @@ cdef class ComplexDoubleField_class(sage.rings.abc.ComplexDoubleField): EXAMPLES:: - sage: CDF._coerce_(5) # indirect doctest + sage: CDF.coerce(5) # indirect doctest 5.0 - sage: CDF._coerce_(RDF(3.4)) + sage: CDF.coerce(RDF(3.4)) 3.4 Thus the sum of a CDF and a symbolic object is symbolic:: diff --git a/src/sage/rings/finite_rings/element_pari_ffelt.pyx b/src/sage/rings/finite_rings/element_pari_ffelt.pyx index 95922cd42d0..76539503b53 100644 --- a/src/sage/rings/finite_rings/element_pari_ffelt.pyx +++ b/src/sage/rings/finite_rings/element_pari_ffelt.pyx @@ -1282,7 +1282,7 @@ cdef class FiniteFieldElement_pari_ffelt(FinitePolyExtElement): sage: F = FiniteField(next_prime(1000)^2, 'a', impl='pari_ffelt') sage: a = F.multiplicative_generator () - sage: gap._coerce_(a) + sage: gap.coerce(a) Traceback (most recent call last): ... TypeError: order must be at most 65536 diff --git a/src/sage/rings/finite_rings/finite_field_base.pyx b/src/sage/rings/finite_rings/finite_field_base.pyx index 2b9e4217fc5..9b0507b85a8 100644 --- a/src/sage/rings/finite_rings/finite_field_base.pyx +++ b/src/sage/rings/finite_rings/finite_field_base.pyx @@ -1312,26 +1312,26 @@ cdef class FiniteField(Field): a + 1 sage: k = GF(4, 'a') - sage: k._coerce_(GF(2)(1)) + sage: k.coerce(GF(2)(1)) 1 - sage: k._coerce_(k.0) + sage: k.coerce(k.0) a - sage: k._coerce_(3) + sage: k.coerce(3) 1 - sage: k._coerce_(2/3) + sage: k.coerce(2/3) Traceback (most recent call last): ... TypeError: no canonical coercion from Rational Field to Finite Field in a of size 2^2 - sage: FiniteField(16)._coerce_(FiniteField(4).0) + sage: FiniteField(16).coerce(FiniteField(4).0) z4^2 + z4 - sage: FiniteField(8, 'a')._coerce_(FiniteField(4, 'a').0) + sage: FiniteField(8, 'a').coerce(FiniteField(4, 'a').0) Traceback (most recent call last): ... TypeError: no canonical coercion from Finite Field in a of size 2^2 to Finite Field in a of size 2^3 - sage: FiniteField(8, 'a')._coerce_(FiniteField(7, 'a')(2)) + sage: FiniteField(8, 'a').coerce(FiniteField(7, 'a')(2)) Traceback (most recent call last): ... TypeError: no canonical coercion from Finite Field of size 7 to Finite Field in a of size 2^3 diff --git a/src/sage/rings/finite_rings/integer_mod.pyx b/src/sage/rings/finite_rings/integer_mod.pyx index 7549886b627..53279b8e309 100644 --- a/src/sage/rings/finite_rings/integer_mod.pyx +++ b/src/sage/rings/finite_rings/integer_mod.pyx @@ -462,7 +462,7 @@ cdef class IntegerMod_abstract(FiniteRingElement): 2 """ # The generators are irrelevant (Zmod(n) is its own base), so we ignore base_map - return codomain._coerce_(self) + return codomain.coerce(self) def __mod__(self, modulus): """ diff --git a/src/sage/rings/finite_rings/integer_mod_ring.py b/src/sage/rings/finite_rings/integer_mod_ring.py index f444add73e2..40eb6413ff4 100644 --- a/src/sage/rings/finite_rings/integer_mod_ring.py +++ b/src/sage/rings/finite_rings/integer_mod_ring.py @@ -1242,7 +1242,7 @@ def _coerce_map_from_(self, S): sage: R = IntegerModRing(17) sage: a = R(3) - sage: b = R._coerce_(3) + sage: b = R.coerce(3) sage: b 3 sage: a==b @@ -1258,7 +1258,7 @@ def _coerce_map_from_(self, S): :: - sage: R._coerce_(2/3) + sage: R.coerce(2/3) Traceback (most recent call last): ... TypeError: no canonical coercion from Rational Field to Ring of integers modulo 17 diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx index c9f7017b8f0..7adfcc1d47d 100644 --- a/src/sage/rings/integer.pyx +++ b/src/sage/rings/integer.pyx @@ -776,7 +776,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): sage: n._im_gens_(R, [R(1)]) 7 """ - return codomain._coerce_(self) + return codomain.coerce(self) cdef _xor(Integer self, Integer other): cdef Integer x diff --git a/src/sage/rings/polynomial/multi_polynomial_element.py b/src/sage/rings/polynomial/multi_polynomial_element.py index 05ba8094a42..d0c5d9fc074 100644 --- a/src/sage/rings/polynomial/multi_polynomial_element.py +++ b/src/sage/rings/polynomial/multi_polynomial_element.py @@ -213,7 +213,7 @@ def _im_gens_(self, codomain, im_gens, base_map=None): """ n = self.parent().ngens() if n == 0: - return codomain._coerce_(self) + return codomain.coerce(self) y = codomain(0) if base_map is None: # Just use conversion diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index 26327f992c7..06c87d7546a 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -527,7 +527,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): We can coerce elements of self to self:: - sage: P._coerce_(x*y + 1/2) + sage: P.coerce(x*y + 1/2) x*y + 1/2 We can coerce elements for a ring with the same algebraic properties:: @@ -540,31 +540,31 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): sage: P is R False - sage: P._coerce_(x*y + 1) + sage: P.coerce(x*y + 1) x*y + 1 We can coerce base ring elements:: - sage: P._coerce_(3/2) + sage: P.coerce(3/2) 3/2 and all kinds of integers:: - sage: P._coerce_(ZZ(1)) + sage: P.coerce(ZZ(1)) 1 - sage: P._coerce_(int(1)) + sage: P.coerce(int(1)) 1 sage: k.
= GF(2^8) sage: P. = PolynomialRing(k,2) - sage: P._coerce_(a) + sage: P.coerce(a) a sage: z = QQ['z'].0 sage: K. = NumberField(z^2 - 2) sage: P. = PolynomialRing(K, 2) - sage: P._coerce_(1/2*s) + sage: P.coerce(1/2*s) (1/2*s) TESTS:: @@ -988,7 +988,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): # we need to do this, to make sure that we actually get an # element in self. - return self._coerce_c(element) + return self.coerce(element) if hasattr(element,'_polynomial_'): # symbolic.expression.Expression return element._polynomial_(self) @@ -1598,9 +1598,9 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): cdef number *denom if self is not f._parent: - f = self._coerce_c(f) + f = self.coerce(f) if self is not g._parent: - g = self._coerce_c(g) + g = self.coerce(g) if not f._poly: return self._zero_element @@ -1653,7 +1653,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): cdef poly *_b cdef ring *_r if a._parent is not b._parent: - b = a._parent._coerce_c(b) + b = a._parent.coerce(b) _a = a._poly _b = b._poly @@ -1702,9 +1702,9 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): cdef poly *m = p_ISet(1,self._ring) if self is not f._parent: - f = self._coerce_c(f) + f = self.coerce(f) if self is not g._parent: - g = self._coerce_c(g) + g = self.coerce(g) if f._poly == NULL: if g._poly == NULL: @@ -1814,7 +1814,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): cdef poly *q if h._parent is not g._parent: - g = h._parent._coerce_c(g) + g = h._parent.coerce(g) r = h._parent_ring p = g._poly @@ -3523,7 +3523,7 @@ cdef class MPolynomial_libsingular(MPolynomial): p_Delete(&_p, _ring) raise TypeError("keys do not match self's parent") try: - v = parent._coerce_c(v) + v = parent.coerce(v) except TypeError: try_symbolic = 1 break @@ -3559,7 +3559,7 @@ cdef class MPolynomial_libsingular(MPolynomial): p_Delete(&_p, _ring) raise TypeError("key does not match") try: - v = parent._coerce_c(v) + v = parent.coerce(v) except TypeError: try_symbolic = 1 break @@ -4528,7 +4528,7 @@ cdef class MPolynomial_libsingular(MPolynomial): if not (isinstance(f,MPolynomial_libsingular) \ and (f)._parent is parent): try: - f = parent._coerce_c(f) + f = parent.coerce(f) except TypeError as msg: id_Delete(&fI,r) id_Delete(&_I,r) @@ -4655,7 +4655,7 @@ cdef class MPolynomial_libsingular(MPolynomial): if not (isinstance(f,MPolynomial_libsingular) \ and (f)._parent is parent): try: - f = parent._coerce_c(f) + f = parent.coerce(f) except TypeError as msg: id_Delete(&_I,r) raise TypeError(msg) @@ -4704,7 +4704,7 @@ cdef class MPolynomial_libsingular(MPolynomial): if not (isinstance(other,MPolynomial_libsingular) \ and (other)._parent is parent): try: - other = parent._coerce_c(other) + other = parent.coerce(other) except TypeError as msg: id_Delete(&_I,r) raise TypeError(msg) @@ -4890,7 +4890,7 @@ cdef class MPolynomial_libsingular(MPolynomial): raise TypeError("LCM over non-integral domains not available.") if self._parent is not g._parent: - _g = self._parent._coerce_c(g) + _g = self._parent.coerce(g) else: _g = g @@ -5043,9 +5043,9 @@ cdef class MPolynomial_libsingular(MPolynomial): cdef ring *r = self._parent_ring if not self._parent is m._parent: - m = self._parent._coerce_c(m) + m = self._parent.coerce(m) if not self._parent is q._parent: - q = self._parent._coerce_c(q) + q = self._parent.coerce(q) if m._poly and m._poly.next: raise ArithmeticError("m must be a monomial.") @@ -5131,9 +5131,9 @@ cdef class MPolynomial_libsingular(MPolynomial): cdef ring *r = self._parent_ring if not self._parent is m._parent: - m = self._parent._coerce_c(m) + m = self._parent.coerce(m) if not self._parent is q._parent: - q = self._parent._coerce_c(q) + q = self._parent.coerce(q) if m._poly and m._poly.next: raise ArithmeticError("m must be a monomial.") @@ -5210,7 +5210,7 @@ cdef class MPolynomial_libsingular(MPolynomial): #TODO: very slow n = self.parent().ngens() if n == 0: - return codomain._coerce_(self) + return codomain.coerce(self) y = codomain(0) if base_map is None: # Just use conversion diff --git a/src/sage/rings/polynomial/multi_polynomial_ring.py b/src/sage/rings/polynomial/multi_polynomial_ring.py index 88f7fc4ca51..adc5c87387d 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring.py +++ b/src/sage/rings/polynomial/multi_polynomial_ring.py @@ -234,7 +234,7 @@ def __call__(self, x=0, check=True): :: - sage: parent(S2._coerce_(S.0)) is S2 + sage: parent(S2.coerce(S.0)) is S2 True Conversion to reduce modulo a prime between rings with different @@ -415,7 +415,7 @@ def __call__(self, x=0, check=True): return self({self._zero_tuple: x}) try: - y = self.base_ring()._coerce_(x) + y = self.base_ring().coerce(x) return MPolynomial_polydict(self, {self._zero_tuple: y}) except TypeError: pass diff --git a/src/sage/rings/polynomial/pbori/pbori.pyx b/src/sage/rings/polynomial/pbori/pbori.pyx index 38d5ac2084b..c1a04d2a7de 100644 --- a/src/sage/rings/polynomial/pbori/pbori.pyx +++ b/src/sage/rings/polynomial/pbori/pbori.pyx @@ -2731,7 +2731,7 @@ cdef class BooleanMonomial(MonoidElement): raise TypeError("BooleanMonomial.__add__ called with not supported types %s and %s" % (type(right), type(left))) res = new_BP_from_PBMonom(monom._ring, monom._pbmonom) - res += monom._ring._coerce_c(other) + res += monom._ring.coerce(other) return res def __floordiv__(BooleanMonomial left, right): @@ -3858,7 +3858,7 @@ cdef class BooleanPolynomial(MPolynomial): """ cdef BooleanPolynomialRing B = self._parent k = B._base - mon = B._coerce_c(mon) + mon = B.coerce(mon) if mon in set(self.set()): return k._one_element else: @@ -8161,9 +8161,9 @@ cdef class PolynomialFactory: elif isinstance(arg, BooleSet): return (arg)._ring._element_constructor_(arg) elif isinstance(arg, BooleanMonomial): - return (arg)._ring._coerce_(arg) + return (arg)._ring.coerce(arg) elif isinstance(ring, BooleanPolynomialRing): - return (ring)._coerce_(arg) + return (ring).coerce(arg) else: if isinstance(arg, int) or isinstance(arg, Integer): return new_BP_from_PBPoly(self._ring, diff --git a/src/sage/rings/polynomial/plural.pyx b/src/sage/rings/polynomial/plural.pyx index 8fbf375fd46..4dcadc0deb7 100644 --- a/src/sage/rings/polynomial/plural.pyx +++ b/src/sage/rings/polynomial/plural.pyx @@ -551,7 +551,7 @@ cdef class NCPolynomialRing_plural(Ring): _p = p_NSet(_n, _ring) else: # fall back to base ring - element = base_ring._coerce_c(element) + element = base_ring.coerce(element) _n = sa2si(element,_ring) _p = p_NSet(_n, _ring) @@ -1062,9 +1062,9 @@ cdef class NCPolynomialRing_plural(Ring): cdef number *denom if self is not f._parent: - f = self._coerce_c(f) + f = self.coerce(f) if self is not g._parent: - g = self._coerce_c(g) + g = self.coerce(g) if(r != currRing): rChangeCurrRing(r) @@ -1130,7 +1130,7 @@ cdef class NCPolynomialRing_plural(Ring): cdef poly *_b cdef ring *_r if a._parent is not b._parent: - b = (a._parent)._coerce_c(b) + b = (a._parent).coerce(b) _a = a._poly _b = b._poly @@ -1191,9 +1191,9 @@ cdef class NCPolynomialRing_plural(Ring): cdef poly *m = p_ISet(1,self._ring) if self is not f._parent: - f = self._coerce_c(f) + f = self.coerce(f) if self is not g._parent: - g = self._coerce_c(g) + g = self.coerce(g) if f._poly == NULL: if g._poly == NULL: @@ -1326,7 +1326,7 @@ cdef class NCPolynomialRing_plural(Ring): cdef poly *q if h._parent is not g._parent: - g = (h._parent)._coerce_c(g) + g = (h._parent).coerce(g) r = (h._parent)._ring p = g._poly @@ -1795,7 +1795,7 @@ cdef class NCPolynomial_plural(RingElement): if not (isinstance(f, NCPolynomial_plural) \ and (f)._parent is parent): try: - f = parent._coerce_c(f) + f = parent.coerce(f) except TypeError as msg: id_Delete(&_I,r) raise TypeError(msg) diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index a5126aa3c48..2e164222a49 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -2321,7 +2321,7 @@ cdef class Polynomial(CommutativeAlgebraElement): if isinstance(left, Polynomial): R = (left)._parent._base try: - x = R._coerce_(right) + x = R.coerce(right) return left * ~x except TypeError: pass @@ -11310,7 +11310,7 @@ cdef class Polynomial_generic_dense(Polynomial): if not self.__coeffs: return self if c._parent is not (self.__coeffs[0])._parent: - c = (self.__coeffs[0])._parent._coerce_c(c) + c = (self.__coeffs[0])._parent.coerce(c) v = [c * a for a in self.__coeffs] cdef Polynomial_generic_dense res = self._new_c(v, self._parent) #if not v[len(v)-1]: @@ -11322,7 +11322,7 @@ cdef class Polynomial_generic_dense(Polynomial): if not self.__coeffs: return self if c._parent is not (self.__coeffs[0])._parent: - c = (self.__coeffs[0])._parent._coerce_c(c) + c = (self.__coeffs[0])._parent.coerce(c) v = [a * c for a in self.__coeffs] cdef Polynomial_generic_dense res = self._new_c(v, self._parent) #if not v[len(v)-1]: diff --git a/src/sage/rings/polynomial/polynomial_integer_dense_ntl.pyx b/src/sage/rings/polynomial/polynomial_integer_dense_ntl.pyx index dd4e3eeaf22..41ddaa92e51 100644 --- a/src/sage/rings/polynomial/polynomial_integer_dense_ntl.pyx +++ b/src/sage/rings/polynomial/polynomial_integer_dense_ntl.pyx @@ -1136,7 +1136,7 @@ cdef class Polynomial_integer_dense_ntl(Polynomial): sage: r.parent() is ZZ True """ - cdef Polynomial_integer_dense_ntl _other = (self.parent()._coerce_(other)) + cdef Polynomial_integer_dense_ntl _other = (self.parent().coerce(other)) cdef ZZ_c* temp = ZZX_resultant(&self.__poly, &_other.__poly, proof) cdef Integer x = Integer.__new__(Integer) ZZ_to_mpz(x.value, temp) diff --git a/src/sage/rings/polynomial/polynomial_modn_dense_ntl.pyx b/src/sage/rings/polynomial/polynomial_modn_dense_ntl.pyx index 3a77ea5ac1c..868f68f2c50 100644 --- a/src/sage/rings/polynomial/polynomial_modn_dense_ntl.pyx +++ b/src/sage/rings/polynomial/polynomial_modn_dense_ntl.pyx @@ -872,7 +872,7 @@ cdef class Polynomial_dense_modn_ntl_zz(Polynomial_dense_mod_n): if do_sig: sig_off() else: if not isinstance(modulus, Polynomial_dense_modn_ntl_zz): - modulus = self.parent()._coerce_(modulus) + modulus = self.parent().coerce(modulus) zz_pX_Modulus_build(mod, (modulus).x) do_sig = zz_pX_deg(self.x) * e * self.c.p_bits > 1e5 @@ -1430,7 +1430,7 @@ cdef class Polynomial_dense_modn_ntl_ZZ(Polynomial_dense_mod_n): if do_sig: sig_off() else: if not isinstance(modulus, Polynomial_dense_modn_ntl_ZZ): - modulus = self.parent()._coerce_(modulus) + modulus = self.parent().coerce(modulus) ZZ_pX_Modulus_build(mod, (modulus).x) do_sig = ZZ_pX_deg(self.x) * e * self.c.p_bits > 1e5 @@ -1841,7 +1841,7 @@ cdef class Polynomial_dense_mod_p(Polynomial_dense_mod_n): sage: r.parent() is GF(19) True """ - other = self.parent()._coerce_(other) + other = self.parent().coerce(other) return self.base_ring()(str(self.ntl_ZZ_pX().resultant(other.ntl_ZZ_pX()))) def discriminant(self): diff --git a/src/sage/rings/polynomial/polynomial_template.pxi b/src/sage/rings/polynomial/polynomial_template.pxi index 3027c7e6179..3806e2aa23e 100644 --- a/src/sage/rings/polynomial/polynomial_template.pxi +++ b/src/sage/rings/polynomial/polynomial_template.pxi @@ -612,7 +612,7 @@ cdef class Polynomial_template(Polynomial): celement_pow(&r.x, &(self).x, e, NULL, (self)._cparent) else: if parent is not (modulus)._parent and parent != (modulus)._parent: - modulus = parent._coerce_(modulus) + modulus = parent.coerce(modulus) celement_pow(&r.x, &(self).x, e, &(modulus).x, (self)._cparent) #assert(r._parent(pari(self)**ee) == r) diff --git a/src/sage/rings/polynomial/polynomial_zmod_flint.pyx b/src/sage/rings/polynomial/polynomial_zmod_flint.pyx index 65cb1a5d630..3fe6f33c18d 100644 --- a/src/sage/rings/polynomial/polynomial_zmod_flint.pyx +++ b/src/sage/rings/polynomial/polynomial_zmod_flint.pyx @@ -456,7 +456,7 @@ cdef class Polynomial_zmod_flint(Polynomial_template): NOTE: This function is a technology preview. It might disappear or be replaced without a deprecation warning. """ - cdef Polynomial_zmod_flint _other = self._parent._coerce_(other) + cdef Polynomial_zmod_flint _other = self._parent.coerce(other) cdef type t = type(self) cdef Polynomial_zmod_flint r = t.__new__(t) diff --git a/src/sage/rings/power_series_ring.py b/src/sage/rings/power_series_ring.py index 4a38cf4e6d2..0000a2daa38 100644 --- a/src/sage/rings/power_series_ring.py +++ b/src/sage/rings/power_series_ring.py @@ -867,24 +867,24 @@ def _coerce_impl(self, x): EXAMPLES:: sage: R. = PowerSeriesRing(ZZ) - sage: R._coerce_(t + t^2) # indirect doctest + sage: R.coerce(t + t^2) # indirect doctest t + t^2 - sage: R._coerce_(1/t) + sage: R.coerce(1/t) Traceback (most recent call last): ... TypeError: no canonical coercion from Laurent Series Ring in t over Rational Field to Power Series Ring in t over Integer Ring - sage: R._coerce_(5) + sage: R.coerce(5) 5 sage: tt = PolynomialRing(ZZ,'t').gen() - sage: R._coerce_(tt^2 + tt - 1) + sage: R.coerce(tt^2 + tt - 1) -1 + t + t^2 - sage: R._coerce_(1/2) + sage: R.coerce(1/2) Traceback (most recent call last): ... TypeError: no canonical coercion from Rational Field to Power Series Ring in t over Integer Ring sage: S. = PowerSeriesRing(ZZ) - sage: R._coerce_(s) + sage: R.coerce(s) Traceback (most recent call last): ... TypeError: no canonical coercion from Power Series Ring in s over Integer Ring to Power Series Ring in t over Integer Ring @@ -896,11 +896,11 @@ def _coerce_impl(self, x): sage: S = PowerSeriesRing(ZZ, 't') sage: f = S([1,2,3,4]); f 1 + 2*t + 3*t^2 + 4*t^3 - sage: g = R._coerce_(f); g + sage: g = R.coerce(f); g 1 + 2*t + 3*t^2 + 4*t^3 sage: parent(g) Power Series Ring in t over Univariate Polynomial Ring in w over Finite Field of size 7 - sage: S._coerce_(g) + sage: S.coerce(g) Traceback (most recent call last): ... TypeError: no canonical coercion from Power Series Ring in t over Univariate Polynomial Ring in w over Finite Field of size 7 to Power Series Ring in t over Integer Ring diff --git a/src/sage/rings/qqbar.py b/src/sage/rings/qqbar.py index d7009674253..56d077381a8 100644 --- a/src/sage/rings/qqbar.py +++ b/src/sage/rings/qqbar.py @@ -1258,7 +1258,7 @@ def _is_valid_homomorphism_(self, codomain, im_gens, base_map=False): False """ try: - return im_gens[0] == codomain._coerce_(self.gen(0)) + return im_gens[0] == codomain.coerce(self.gen(0)) except TypeError: return False diff --git a/src/sage/rings/rational.pyx b/src/sage/rings/rational.pyx index db85e5ed887..c4f06fdb7b8 100644 --- a/src/sage/rings/rational.pyx +++ b/src/sage/rings/rational.pyx @@ -1118,7 +1118,7 @@ cdef class Rational(sage.structure.element.FieldElement): sage: a._im_gens_(QQ, [1/1]) -17/37 """ - return codomain._coerce_(self) + return codomain.coerce(self) def content(self, other): """ diff --git a/src/sage/rings/rational_field.py b/src/sage/rings/rational_field.py index 7c447d4c7ff..50328384776 100644 --- a/src/sage/rings/rational_field.py +++ b/src/sage/rings/rational_field.py @@ -401,7 +401,7 @@ def _is_valid_homomorphism_(self, codomain, im_gens, base_map=None): False """ try: - return im_gens[0] == codomain._coerce_(self.gen(0)) + return im_gens[0] == codomain.coerce(self.gen(0)) except TypeError: return False diff --git a/src/sage/rings/real_mpfi.pyx b/src/sage/rings/real_mpfi.pyx index d212a588486..f4fb14b757b 100644 --- a/src/sage/rings/real_mpfi.pyx +++ b/src/sage/rings/real_mpfi.pyx @@ -959,7 +959,7 @@ cdef class RealIntervalField_class(sage.rings.abc.RealIntervalField): False """ try: - s = codomain._coerce_(self(1)) + s = codomain.coerce(self(1)) except TypeError: return False return s == im_gens[0] diff --git a/src/sage/structure/parent_old.pyx b/src/sage/structure/parent_old.pyx index d8be438a21e..630f0ca8613 100644 --- a/src/sage/structure/parent_old.pyx +++ b/src/sage/structure/parent_old.pyx @@ -176,12 +176,16 @@ cdef class Parent(parent.Parent): def _coerce_(self, x): # Call this from Python (do not override!) if self._element_constructor is not None: + from sage.misc.superseded import deprecation + deprecation(33497, "_coerce_ is deprecated, use coerce instead") return self.coerce(x) check_old_coerce(self) return self._coerce_c(x) cpdef _coerce_c(self, x): # DO NOT OVERRIDE THIS (call it) if self._element_constructor is not None: + from sage.misc.superseded import deprecation + deprecation(33497, "_coerce_c is deprecated, use coerce instead") return self.coerce(x) check_old_coerce(self) try: diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index 385fbbf3ee7..6579c721407 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -3786,7 +3786,7 @@ cdef class Expression(Expression_abc): try: return z except TypeError: - return self._parent._coerce_(z) + return self._parent.coerce(z) cpdef _add_(left, right): """ @@ -13792,7 +13792,7 @@ cpdef new_Expression_from_pyobject(parent, x, bint force=True, bint recursive=Tr if isinstance(x, Expression): return x try: - return parent._coerce_(x) + return parent.coerce(x) except TypeError: pass diff --git a/src/sage/symbolic/ring.pyx b/src/sage/symbolic/ring.pyx index 05694e3b085..6cf7ade03f3 100644 --- a/src/sage/symbolic/ring.pyx +++ b/src/sage/symbolic/ring.pyx @@ -291,18 +291,18 @@ cdef class SymbolicRing(sage.rings.abc.SymbolicRing): TESTS:: - sage: SR._coerce_(int(5)) + sage: SR.coerce(int(5)) 5 - sage: SR._coerce_(5) + sage: SR.coerce(5) 5 - sage: SR._coerce_(float(5)) + sage: SR.coerce(float(5)) 5.0 - sage: SR._coerce_(5.0) + sage: SR.coerce(5.0) 5.00000000000000 An interval arithmetic number:: - sage: SR._coerce_(RIF(pi)) + sage: SR.coerce(RIF(pi)) 3.141592653589794? The complex number `I`:: From 93855017ba6d46a7e83c289b29defc9e82a24d55 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 26 Mar 2022 11:48:50 -0700 Subject: [PATCH 052/529] src/bin/sage: Implement 'sage --pytest' --- src/bin/sage | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/bin/sage b/src/bin/sage index d8432a43c8d..69a157b7d1f 100755 --- a/src/bin/sage +++ b/src/bin/sage @@ -443,6 +443,10 @@ usage_advanced() { echo " --help -- show tox help" command -v tox &>/dev/null || \ echo " (not installed currently, run sage -i tox)" + echo " --pytest [options] -- run pytest on the Sage library" + command -v pytest &>/dev/null || \ + echo " (not installed currently, run sage -i pytest)" + echo " --help -- show pytest help" fi echo echo "Some developer utilities:" @@ -940,10 +944,24 @@ if [ "$1" = '-tox' -o "$1" = '--tox' ]; then if command -v tox >/dev/null ; then exec tox -c "$SAGE_SRC" "$@" else - echo "Run sage -i tox to install" + echo "Run 'sage -i tox' to install" fi else - echo >&2 "error: Sage source directory or tox.ini not avialable" + echo >&2 "error: Sage source directory or tox.ini not available" + exit 1 + fi +fi + +if [ "$1" = '-pytest' -o "$1" = '--pytest' ]; then + shift + if [ -n "$SAGE_SRC" -a -f "$SAGE_SRC/tox.ini" ]; then + if command -v pytest >/dev/null ; then + exec pytest --rootdir="$SAGE_SRC" --import-mode importlib "$@" + else + echo "Run 'sage -i pytest' to install" + fi + else + echo >&2 "error: Sage source directory or tox.ini not available" exit 1 fi fi From 5eb74b47ed2c5e591a3c3b61b6381d4b6cbd6d4a Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Sun, 27 Mar 2022 15:28:13 +0900 Subject: [PATCH 053/529] One more deprecation message for an old coercion system method. --- src/sage/structure/parent_base.pyx | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/sage/structure/parent_base.pyx b/src/sage/structure/parent_base.pyx index 502a9f75760..9a37b596cd2 100644 --- a/src/sage/structure/parent_base.pyx +++ b/src/sage/structure/parent_base.pyx @@ -35,14 +35,17 @@ cdef class ParentWithBase(Parent_old): self._base = base cdef _coerce_c_impl(self,x): - check_old_coerce(self) - if not self._base is self: - return self(self._base._coerce_(x)) - else: - raise TypeError("No canonical coercion found.") + check_old_coerce(self) + from sage.misc.superseded import deprecation + deprecation(33497, "_coerce_c_impl is deprecated, use coerce instead") + if not self._base is self: + return self(self._base._coerce_(x)) + else: + raise TypeError("No canonical coercion found.") # Derived class *must* define base_extend. def base_extend(self, X): check_old_coerce(self) raise CoercionException("BUG: the base_extend method must be defined for '%s' (class '%s')" % (self, type(self))) + From b8677b601a2852b368d4e8f783a8a20130e142fe Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Sun, 27 Mar 2022 15:39:24 +0200 Subject: [PATCH 054/529] Add VS code config for running tests on a file --- .vscode/launch.json | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.vscode/launch.json b/.vscode/launch.json index fcf2e9c45d8..e856e82fece 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -8,6 +8,17 @@ "program": "${file}", "console": "integratedTerminal", "justMyCode": false + }, + { + "name": "Sage: Test", + "type": "python", + "request": "launch", + "program": "${workspaceFolder}/src/bin/sage-runtests", + "args": [ + "${file}" + ], + "console": "integratedTerminal", + "justMyCode": false } ], } From f67476f065a2ef7c4b03fcad486ace6e08d9230c Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Sun, 27 Mar 2022 15:50:44 +0200 Subject: [PATCH 055/529] Add some test and prelimary code --- .vscode/settings.json | 6 +++++- src/test_doctest.py | 11 +++++++++++ src/tox.ini | 1 + 3 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 src/test_doctest.py diff --git a/.vscode/settings.json b/.vscode/settings.json index 5844f80998f..9cdc0e3b980 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -14,9 +14,13 @@ "pkgs/sagemath-objects/sage": true, "pkgs/sagemath-standard/sage": true, }, + "python.testing.pytestPath": "./sage -t", "python.testing.pytestEnabled": true, "python.testing.pytestArgs": [ - "src" + "src/test_doctests.py", + "--rootdir=src/sage", + "-c=src/tox.ini", + "--doctest-modules", ], "python.testing.unittestEnabled": false, } diff --git a/src/test_doctest.py b/src/test_doctest.py new file mode 100644 index 00000000000..37cb7d89995 --- /dev/null +++ b/src/test_doctest.py @@ -0,0 +1,11 @@ +def something(): + """ a doctest in a docstring + >>> something() + 42 + + some other doctest + + >>> something() + 1 + 43 + """ + return 42 diff --git a/src/tox.ini b/src/tox.ini index 58aa21be8a5..e15471fd742 100644 --- a/src/tox.ini +++ b/src/tox.ini @@ -155,6 +155,7 @@ commands = codespell \ [pytest] python_files = *_test.py +norecursedirs = local prefix venv build pkgs .git src/sage/pkgs src/doc src/bin src/sage/src/sage_setup [coverage:run] source = sage From abbb61fd2cb99836ab37448326dab7e7e7f37fd7 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 27 Mar 2022 08:42:42 -0700 Subject: [PATCH 056/529] src/conftest.py: import sage.all to avoid cyclic import errors --- src/conftest.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/conftest.py b/src/conftest.py index 33135c9e333..91a6c31e17a 100644 --- a/src/conftest.py +++ b/src/conftest.py @@ -12,6 +12,9 @@ from typing import Any import pytest +import sage.all # to avoid cyclic import errors + + # Ignore a few test files that are (not yet) using pytest collect_ignore = [ "sage/misc/nested_class_test.py", From a7e1e54f6310e3bf6bd4c6caba97712617d6c474 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sun, 27 Mar 2022 18:06:35 +0200 Subject: [PATCH 057/529] trac #33579: ensure random graph generators use parameter seed --- src/sage/graphs/generators/random.py | 112 ++++++++++++++++------- src/sage/graphs/graph_generators_pyx.pyx | 14 ++- 2 files changed, 91 insertions(+), 35 deletions(-) diff --git a/src/sage/graphs/generators/random.py b/src/sage/graphs/generators/random.py index b6bff1edd0d..a5193667fa5 100644 --- a/src/sage/graphs/generators/random.py +++ b/src/sage/graphs/generators/random.py @@ -33,15 +33,15 @@ def RandomGNP(n, p, seed=None, fast=True, algorithm='Sage'): - ``p`` -- probability of an edge - - ``seed`` - a ``random.Random`` seed or a Python ``int`` for the random - number generator (default: ``None``). + - ``seed`` -- a ``random.Random`` seed or a Python ``int`` for the random + number generator (default: ``None``) - ``fast`` -- boolean set to True (default) to use the algorithm with time complexity in `O(n+m)` proposed in [BB2005a]_. It is designed for generating large sparse graphs. It is faster than other algorithms for *LARGE* instances (try it to know whether it is useful for you). - - ``algorithm`` -- By default (```algorithm='Sage'``), this function uses the + - ``algorithm`` -- By default (``algorithm='Sage'``), this function uses the algorithm implemented in ```sage.graphs.graph_generators_pyx.pyx``. When ``algorithm='networkx'``, this function calls the NetworkX function ``fast_gnp_random_graph``, unless ``fast=False``, then @@ -105,13 +105,13 @@ def RandomGNP(n, p, seed=None, fast=True, algorithm='Sage'): if 0.0 > p or 1.0 < p: raise ValueError("The probability p must be in [0..1].") - if seed is None: - seed = int(current_randstate().long_seed() % sys.maxsize) if p == 1: from sage.graphs.generators.basic import CompleteGraph return CompleteGraph(n) if algorithm == 'networkx': + if seed is None: + seed = int(current_randstate().long_seed() % sys.maxsize) import networkx if fast: G = networkx.fast_gnp_random_graph(n, p, seed=seed) @@ -121,7 +121,7 @@ def RandomGNP(n, p, seed=None, fast=True, algorithm='Sage'): elif algorithm in ['Sage', 'sage']: # We use the Sage generator from sage.graphs.graph_generators_pyx import RandomGNP as sageGNP - return sageGNP(n, p) + return sageGNP(n, p, seed=seed) else: raise ValueError("'algorithm' must be equal to 'networkx' or to 'Sage'.") @@ -183,7 +183,7 @@ def RandomBarabasiAlbert(n, m, seed=None): import networkx return Graph(networkx.barabasi_albert_graph(int(n), int(m), seed=seed)) -def RandomBipartite(n1, n2, p, set_position=False): +def RandomBipartite(n1, n2, p, set_position=False, seed=None): r""" Returns a bipartite graph with `n1+n2` vertices such that any edge from `[n1]` to `[n2]` exists with probability `p`. @@ -198,6 +198,9 @@ def RandomBipartite(n1, n2, p, set_position=False): assign positions to the vertices so that the set of cardinality `n1` is on the line `y=1` and the set of cardinality `n2` is on the line `y=0`. + - ``seed`` -- a ``random.Random`` seed or a Python ``int`` for the random + number generator (default: ``None``) + EXAMPLES:: sage: g = graphs.RandomBipartite(5, 2, 0.5) @@ -235,6 +238,8 @@ def RandomBipartite(n1, n2, p, set_position=False): raise ValueError("parameter p is a probability, and so should be a real value between 0 and 1") if not (n1 > 0 and n2 > 0): raise ValueError("n1 and n2 should be integers strictly greater than 0") + if seed is not None: + set_random_seed(seed) from numpy.random import uniform @@ -261,7 +266,7 @@ def RandomBipartite(n1, n2, p, set_position=False): return g -def RandomRegularBipartite(n1, n2, d1, set_position=False): +def RandomRegularBipartite(n1, n2, d1, set_position=False, seed=None): r""" Return a random regular bipartite graph on `n1 + n2` vertices. @@ -286,6 +291,9 @@ def RandomRegularBipartite(n1, n2, d1, set_position=False): assign positions to the vertices so that the set of cardinality `n1` is on the line `y=1` and the set of cardinality `n2` is on the line `y=0`. + - ``seed`` -- a ``random.Random`` seed or a Python ``int`` for the random + number generator (default: ``None``) + EXAMPLES:: sage: g = graphs.RandomRegularBipartite(4, 6, 3) @@ -326,6 +334,8 @@ def RandomRegularBipartite(n1, n2, d1, set_position=False): d2 = (n1 * d1) // n2 if n1 * d1 != n2 * d2: raise ValueError("the product n1 * d1 must be a multiple of n2") + if seed is not None: + set_random_seed(seed) complement = False if d1 > n2/2 or d2 > n1/2: @@ -418,7 +428,7 @@ def RandomRegularBipartite(n1, n2, d1, set_position=False): return G -def RandomBlockGraph(m, k, kmax=None, incidence_structure=False): +def RandomBlockGraph(m, k, kmax=None, incidence_structure=False, seed=None): r""" Return a Random Block Graph. @@ -449,6 +459,9 @@ def RandomBlockGraph(m, k, kmax=None, incidence_structure=False): graph itself, that is the list of the lists of vertices in each block. This is useful for the creation of some hypergraphs. + - ``seed`` -- a ``random.Random`` seed or a Python ``int`` for the random + number generator (default: ``None``) + OUTPUT: A Graph when ``incidence_structure==False`` (default), and otherwise an @@ -534,6 +547,8 @@ def RandomBlockGraph(m, k, kmax=None, incidence_structure=False): kmax = k elif kmax < k: raise ValueError("the maximum number `kmax` of vertices in a block must be >= `k`") + if seed is not None: + set_random_seed(seed) if m == 1: # A block graph with a single block is a clique @@ -575,7 +590,7 @@ def RandomBlockGraph(m, k, kmax=None, incidence_structure=False): return BG -def RandomBoundedToleranceGraph(n): +def RandomBoundedToleranceGraph(n, seed=None): r""" Return a random bounded tolerance graph. @@ -595,6 +610,9 @@ def RandomBoundedToleranceGraph(n): - ``n`` -- number of vertices of the random graph. + - ``seed`` -- a ``random.Random`` seed or a Python ``int`` for the random + number generator (default: ``None``) + EXAMPLES: Every (bounded) tolerance graph is perfect. Hence, the @@ -619,6 +637,8 @@ def RandomBoundedToleranceGraph(n): """ if n < 0: raise ValueError('the number `n` of vertices must be >= 0') + if seed is not None: + set_random_seed(seed) from sage.graphs.generators.intersection import ToleranceGraph @@ -647,21 +667,17 @@ def RandomGNM(n, m, dense=False, seed=None): - ``dense`` - whether to use NetworkX's dense_gnm_random_graph or gnm_random_graph - - ``seed`` - a ``random.Random`` seed or a Python ``int`` for the random - number generator (default: ``None``). - + - ``seed`` -- a ``random.Random`` seed or a Python ``int`` for the random + number generator (default: ``None``) - EXAMPLES: We show the edge list of a random graph on 5 nodes with - 10 edges. + EXAMPLES: - :: + We show the edge list of a random graph on 5 nodes with 10 edges:: sage: graphs.RandomGNM(5, 10).edges(labels=False) [(0, 1), (0, 2), (0, 3), (0, 4), (1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)] - We plot a random graph on 12 nodes with m = 12. - - :: + We plot a random graph on 12 nodes with m = 12:: sage: gnm = graphs.RandomGNM(12, 12) sage: gnm.show() # long time @@ -809,7 +825,7 @@ def RandomHolmeKim(n, m, p, seed=None): return Graph(networkx.powerlaw_cluster_graph(n, m, p, seed=seed)) -def RandomIntervalGraph(n): +def RandomIntervalGraph(n, seed=None): r""" Returns a random interval graph. @@ -833,8 +849,10 @@ def RandomIntervalGraph(n): INPUT: - - ``n`` (integer) -- the number of vertices in the random - graph. + - ``n`` -- integer; the number of vertices in the random graph + + - ``seed`` -- a ``random.Random`` seed or a Python ``int`` for the random + number generator (default: ``None``) EXAMPLES: @@ -845,7 +863,8 @@ def RandomIntervalGraph(n): sage: g.clique_number() == g.chromatic_number() True """ - + if seed is not None: + set_random_seed(seed) from sage.misc.prandom import random from sage.graphs.generators.intersection import IntervalGraph @@ -1086,7 +1105,7 @@ def pruned_tree(T, f, s): return S -def RandomChordalGraph(n, algorithm="growing", k=None, l=None, f=None, s=None): +def RandomChordalGraph(n, algorithm="growing", k=None, l=None, f=None, s=None, seed=None): r""" Return a random chordal graph of order ``n``. @@ -1151,6 +1170,9 @@ def RandomChordalGraph(n, algorithm="growing", k=None, l=None, f=None, s=None): `0.5`. This parameter is used only when ``algorithm="pruned"``. See :meth:`~sage.graphs.generators.random.pruned_tree` for more details. + - ``seed`` -- a ``random.Random`` seed or a Python ``int`` for the random + number generator (default: ``None``) + EXAMPLES:: sage: from sage.graphs.generators.random import RandomChordalGraph @@ -1202,6 +1224,9 @@ def RandomChordalGraph(n, algorithm="growing", k=None, l=None, f=None, s=None): if n < 2: return Graph(n, name="Random Chordal Graph") + if seed is not None: + set_random_seed(seed) + # 1. Generate a random tree of order n T = RandomTree(n) @@ -1303,7 +1328,7 @@ def RandomLobster(n, p, q, seed=None): return Graph(networkx.random_lobster(n, p, q, seed=seed)) -def RandomTree(n): +def RandomTree(n, seed=None): r""" Returns a random tree on `n` nodes numbered `0` through `n-1`. @@ -1320,7 +1345,10 @@ def RandomTree(n): INPUT: - - ``n`` - number of vertices in the tree + - ``n`` -- number of vertices in the tree + + - ``seed`` -- a ``random.Random`` seed or a Python ``int`` for the random + number generator (default: ``None``) EXAMPLES:: @@ -1348,6 +1376,9 @@ def RandomTree(n): if n <= 1: return g + if seed is not None: + set_random_seed(seed) + # create random Prufer code code = [ randint(0,n-1) for i in range(n-2) ] @@ -1499,7 +1530,7 @@ def RandomShell(constructor, seed=None): import networkx return Graph(networkx.random_shell_graph(constructor, seed=seed)) -def RandomToleranceGraph(n): +def RandomToleranceGraph(n, seed=None): r""" Return a random tolerance graph. @@ -1517,7 +1548,10 @@ def RandomToleranceGraph(n): INPUT: - - ``n`` -- number of vertices of the random graph. + - ``n`` -- number of vertices of the random graph + + - ``seed`` -- a ``random.Random`` seed or a Python ``int`` for the random + number generator (default: ``None``) EXAMPLES: @@ -1539,6 +1573,8 @@ def RandomToleranceGraph(n): if n < 0: raise ValueError('the number `n` of vertices must be >= 0') + if seed is not None: + set_random_seed(seed) W = n**2 * 2**n @@ -1783,7 +1819,7 @@ def _contour_and_graph_from_words(pendant_word, forest_word): G.set_embedding(embedding) return word, G -def RandomTriangulation(n, set_position=False, k=3): +def RandomTriangulation(n, set_position=False, k=3, seed=None): r""" Return a random inner triangulation of an outer face of degree ``k`` with ``n`` vertices in total. @@ -1800,6 +1836,9 @@ def RandomTriangulation(n, set_position=False, k=3): - ``set_position`` -- boolean (default ``False``); if set to ``True``, this will compute coordinates for a planar drawing of the graph. + - ``seed`` -- a ``random.Random`` seed or a Python ``int`` for the random + number generator (default: ``None``) + OUTPUT: A random graph chosen uniformly among the inner triangulations of a *rooted* @@ -1874,6 +1913,8 @@ def RandomTriangulation(n, set_position=False, k=3): if n < k: raise ValueError("The number 'n' of vertices must be at least the size " "'k' of the outer face.") + if seed is not None: + set_random_seed(seed) from sage.misc.prandom import shuffle pendant_word = [0] * (k-1) + [1] * (k-3) @@ -1921,7 +1962,7 @@ def rotate_word_to_next_occurrence(word): return graph -def blossoming_contour(t, shift=0): +def blossoming_contour(t, shift=0, seed=None): """ Return a random blossoming of a binary tree `t`, as a contour word. @@ -1977,6 +2018,9 @@ def blossoming_contour(t, shift=0): """ if not t: raise ValueError('tree must be non-empty') + if seed is not None: + set_random_seed(seed) + t1, t2 = t leaf_xb = ('xb',) leaf_x = ('x',) @@ -2011,7 +2055,7 @@ def blossoming_contour(t, shift=0): return label + tt1 + label + tt2 + label -def RandomBicubicPlanar(n): +def RandomBicubicPlanar(n, seed=None): """ Return the graph of a random bipartite cubic map with `3 n` edges. @@ -2019,6 +2063,9 @@ def RandomBicubicPlanar(n): `n` -- an integer (at least `1`) + - ``seed`` -- a ``random.Random`` seed or a Python ``int`` for the random + number generator (default: ``None``) + OUTPUT: a graph with multiple edges (no embedding is provided) @@ -2068,6 +2115,9 @@ def RandomBicubicPlanar(n): from sage.rings.finite_rings.integer_mod_ring import Zmod if not n: raise ValueError("n must be at least 1") + if seed is not None: + set_random_seed(seed) + # first pick a random binary tree t = BinaryTrees(n).random_element() diff --git a/src/sage/graphs/graph_generators_pyx.pyx b/src/sage/graphs/graph_generators_pyx.pyx index f37fbd6de45..8e9f40cd85a 100644 --- a/src/sage/graphs/graph_generators_pyx.pyx +++ b/src/sage/graphs/graph_generators_pyx.pyx @@ -15,8 +15,9 @@ AUTHORS: ################################################################################ from sage.misc.randstate cimport random +from sage.misc.randstate import set_random_seed -def RandomGNP(n, p, bint directed=False, bint loops=False): +def RandomGNP(n, p, bint directed=False, bint loops=False, seed=None): r""" Return a random graph or a digraph on `n` nodes. @@ -32,7 +33,10 @@ def RandomGNP(n, p, bint directed=False, bint loops=False): directed or undirected (default) - ``loops`` -- boolean (default: ``False``); whether the random digraph may - have loops or not. This value is used only when ``directed == True``. + have loops or not. This value is used only when ``directed == True`` + + - ``seed`` -- a ``random.Random`` seed or a Python ``int`` for the random + number generator (default: ``None``) REFERENCES: @@ -43,8 +47,7 @@ def RandomGNP(n, p, bint directed=False, bint loops=False): EXAMPLES:: sage: from sage.graphs.graph_generators_pyx import RandomGNP - sage: set_random_seed(0) - sage: D = RandomGNP(10, .2, directed=True) + sage: D = RandomGNP(10, .2, directed=True, seed=0) sage: D.num_verts() 10 sage: D.edges(labels=False) @@ -62,6 +65,9 @@ def RandomGNP(n, p, bint directed=False, bint loops=False): """ from sage.graphs.graph import Graph, DiGraph + if seed is not None: + set_random_seed(seed) + # according the sage.misc.randstate.pyx documentation, random # integers are on 31 bits. We thus set the pivot value to p*2^31 cdef float RAND_MAX_f = float(1<<31) From 9bb72ea9ec314940f3c874d492de241fdec96548 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 27 Mar 2022 09:31:36 -0700 Subject: [PATCH 058/529] src/conftest.py: Add # type: ignore, add reference to trac ticket --- src/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/conftest.py b/src/conftest.py index 91a6c31e17a..96d06aa2c04 100644 --- a/src/conftest.py +++ b/src/conftest.py @@ -12,7 +12,7 @@ from typing import Any import pytest -import sage.all # to avoid cyclic import errors +import sage.all # type: ignore # to avoid cyclic import errors, see Trac #33580 # Ignore a few test files that are (not yet) using pytest From 2c167045d66e049751876ddc755304940265c32a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 27 Mar 2022 09:32:11 -0700 Subject: [PATCH 059/529] src/conftest.py: Remove outdated text --- src/conftest.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/conftest.py b/src/conftest.py index 96d06aa2c04..c1dc286fe1a 100644 --- a/src/conftest.py +++ b/src/conftest.py @@ -4,8 +4,6 @@ This file configures pytest and provides some global fixtures. See https://docs.pytest.org/en/latest/index.html for more details. - -At the moment, Sage is not yet using any tests based on pytest. """ from __future__ import annotations From 26fe18687841db9bfcc3ccf101f067f6d984d0fe Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sun, 27 Mar 2022 19:12:06 +0200 Subject: [PATCH 060/529] trac #33579: fix some doctests --- src/sage/graphs/generators/random.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/graphs/generators/random.py b/src/sage/graphs/generators/random.py index a5193667fa5..5c778d04b37 100644 --- a/src/sage/graphs/generators/random.py +++ b/src/sage/graphs/generators/random.py @@ -63,7 +63,7 @@ def RandomGNP(n, p, seed=None, fast=True, algorithm='Sage'): sage: set_random_seed(0) sage: graphs.RandomGNP(6, .4).edges(labels=False) - [(0, 1), (0, 5), (1, 2), (2, 4), (3, 4), (3, 5), (4, 5)] + [(0, 3), (1, 2), (2, 3), (2, 4)] We plot a random graph on 12 nodes with probability `p = .71`:: @@ -98,7 +98,7 @@ def RandomGNP(n, p, seed=None, fast=True, algorithm='Sage'): 243 sage: graphs.RandomGNP(50,.2, algorithm="networkx").size() 260 # 32-bit - 245 # 64-bit + 209 # 64-bit """ if n < 0: raise ValueError("The number of nodes must be positive or null.") From 30642ba190ae9a6a6090b11e51a317a2534028db Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 27 Mar 2022 11:20:06 -0700 Subject: [PATCH 061/529] src/bin/sage: Handle 'sage -pytest' without file args --- src/bin/sage | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/bin/sage b/src/bin/sage index 69a157b7d1f..cd91656e1ea 100755 --- a/src/bin/sage +++ b/src/bin/sage @@ -956,7 +956,14 @@ if [ "$1" = '-pytest' -o "$1" = '--pytest' ]; then shift if [ -n "$SAGE_SRC" -a -f "$SAGE_SRC/tox.ini" ]; then if command -v pytest >/dev/null ; then - exec pytest --rootdir="$SAGE_SRC" --import-mode importlib "$@" + # If no non-option arguments are given, provide one + for a in $*; do + case $a in + -*) ;; + *) exec pytest --rootdir="$SAGE_SRC" --import-mode importlib "$@" + esac + done + exec pytest --rootdir="$SAGE_SRC" --import-mode importlib "$@" "$SAGE_SRC" else echo "Run 'sage -i pytest' to install" fi From fc401f9dd2f7cf85d56368458f68af64b7abd96c Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Mon, 28 Mar 2022 10:50:41 +0200 Subject: [PATCH 062/529] Add verbose --- .vscode/launch.json | 1 + 1 file changed, 1 insertion(+) diff --git a/.vscode/launch.json b/.vscode/launch.json index e856e82fece..15913b0085c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -15,6 +15,7 @@ "request": "launch", "program": "${workspaceFolder}/src/bin/sage-runtests", "args": [ + "--verbose", "${file}" ], "console": "integratedTerminal", From 251cbc3fcb47c45eff2e909533ea859e9c6a8db3 Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Tue, 29 Mar 2022 12:41:56 +0900 Subject: [PATCH 063/529] Fixing last doctest failure. --- src/sage/rings/finite_rings/element_pari_ffelt.pyx | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/sage/rings/finite_rings/element_pari_ffelt.pyx b/src/sage/rings/finite_rings/element_pari_ffelt.pyx index 76539503b53..093b6a2adb3 100644 --- a/src/sage/rings/finite_rings/element_pari_ffelt.pyx +++ b/src/sage/rings/finite_rings/element_pari_ffelt.pyx @@ -1272,7 +1272,7 @@ cdef class FiniteFieldElement_pari_ffelt(FinitePolyExtElement): You can specify the instance of the Gap interpreter that is used:: sage: F = FiniteField(next_prime(200)^2, 'a', impl='pari_ffelt') - sage: a = F.multiplicative_generator () + sage: a = F.multiplicative_generator() sage: a._gap_ (gap) Z(211^2) sage: (a^20)._gap_(gap) @@ -1281,11 +1281,15 @@ cdef class FiniteFieldElement_pari_ffelt(FinitePolyExtElement): Gap only supports relatively small finite fields:: sage: F = FiniteField(next_prime(1000)^2, 'a', impl='pari_ffelt') - sage: a = F.multiplicative_generator () - sage: gap.coerce(a) + sage: a = F.multiplicative_generator() + sage: a._gap_init_() Traceback (most recent call last): ... TypeError: order must be at most 65536 + sage: gap.coerce(a) + Traceback (most recent call last): + ... + TypeError: no canonical coercion from Finite Field in a of size 1009^2 to Gap """ F = self._parent if F.order() > 65536: From 538ead395132b0fde5b9e4ee0738c1883610e82f Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Tue, 29 Mar 2022 16:25:54 +0000 Subject: [PATCH 064/529] First working prototype --- src/bin/sage | 4 +- src/conftest.py | 104 +++++++++++++++++++++++++++++++++++++++++++- src/test_doctest.py | 17 +++++--- 3 files changed, 116 insertions(+), 9 deletions(-) diff --git a/src/bin/sage b/src/bin/sage index cd91656e1ea..1bcf0214ebe 100755 --- a/src/bin/sage +++ b/src/bin/sage @@ -960,10 +960,10 @@ if [ "$1" = '-pytest' -o "$1" = '--pytest' ]; then for a in $*; do case $a in -*) ;; - *) exec pytest --rootdir="$SAGE_SRC" --import-mode importlib "$@" + *) exec pytest --rootdir="$SAGE_SRC" --import-mode importlib --doctest-modules "$@" esac done - exec pytest --rootdir="$SAGE_SRC" --import-mode importlib "$@" "$SAGE_SRC" + exec pytest --rootdir="$SAGE_SRC" --import-mode importlib --doctest-modules "$@" "$SAGE_SRC" else echo "Run 'sage -i pytest' to install" fi diff --git a/src/conftest.py b/src/conftest.py index c1dc286fe1a..5edf6015972 100644 --- a/src/conftest.py +++ b/src/conftest.py @@ -7,11 +7,24 @@ """ from __future__ import annotations -from typing import Any + +from typing import Any, Iterable + import pytest +from _pytest.doctest import ( + DoctestItem, + DoctestModule, + _get_checker, + _get_continue_on_failure, + _get_runner, + _is_mocked, + _patch_unwrap_mock_aware, + get_optionflags, +) +from _pytest.pathlib import import_path import sage.all # type: ignore # to avoid cyclic import errors, see Trac #33580 - +from sage.doctest.parsing import SageDocTestParser # Ignore a few test files that are (not yet) using pytest collect_ignore = [ @@ -21,6 +34,92 @@ ] +def pytest_collect_file(file_path, parent): + if file_path.suffix == ".py": + return SageDoctestModule.from_parent(parent, path=file_path) + + +class SageDoctestModule(DoctestModule): + """ + This is essentially a copy of `DoctestModule` from + https://github.com/pytest-dev/pytest/blob/main/src/_pytest/doctest.py. + The only change is that we use `SageDocTestParser` to extract the doctests. + """ + + def collect(self) -> Iterable[DoctestItem]: + import doctest + + class MockAwareDocTestFinder(doctest.DocTestFinder): + """A hackish doctest finder that overrides stdlib internals to fix a stdlib bug. + https://github.com/pytest-dev/pytest/issues/3456 + https://bugs.python.org/issue25532 + """ + + def __init__(self) -> None: + super().__init__(parser=SageDocTestParser(set(["sage"]))) + + def _find_lineno(self, obj, source_lines): + """Doctest code does not take into account `@property`, this + is a hackish way to fix it. https://bugs.python.org/issue17446 + Wrapped Doctests will need to be unwrapped so the correct + line number is returned. This will be reported upstream. #8796 + """ + if isinstance(obj, property): + obj = getattr(obj, "fget", obj) + + if hasattr(obj, "__wrapped__"): + # Get the main obj in case of it being wrapped + obj = inspect.unwrap(obj) + + # Type ignored because this is a private function. + return super()._find_lineno( # type:ignore[misc] + obj, + source_lines, + ) + + def _find( + self, tests, obj, name, module, source_lines, globs, seen + ) -> None: + if _is_mocked(obj): + return + with _patch_unwrap_mock_aware(): + + # Type ignored because this is a private function. + super()._find( # type:ignore[misc] + tests, obj, name, module, source_lines, globs, seen + ) + + if self.path.name == "conftest.py": + module = self.config.pluginmanager._importconftest( + self.path, + self.config.getoption("importmode"), + rootpath=self.config.rootpath, + ) + else: + try: + module = import_path(self.path, root=self.config.rootpath) + except ImportError: + if self.config.getvalue("doctest_ignore_import_errors"): + pytest.skip("unable to import module %r" % self.path) + else: + raise + # Uses internal doctest module parsing mechanism. + finder = MockAwareDocTestFinder() + optionflags = get_optionflags(self) + runner = _get_runner( + verbose=False, + optionflags=optionflags, + checker=_get_checker(), + continue_on_failure=_get_continue_on_failure(self.config), + ) + + for test in finder.find(module, module.__name__): + if test.examples: # skip empty doctests + yield DoctestItem.from_parent( + self, name=test.name, runner=runner, dtest=test + ) + + @pytest.fixture(autouse=True) def add_imports(doctest_namespace: dict[str, Any]): """ @@ -29,4 +128,5 @@ def add_imports(doctest_namespace: dict[str, Any]): See `pytest documentation `. """ import sage.all # type: ignore # implicitly used below by calling locals() + doctest_namespace.update(**locals()) diff --git a/src/test_doctest.py b/src/test_doctest.py index 37cb7d89995..b0e12f1998e 100644 --- a/src/test_doctest.py +++ b/src/test_doctest.py @@ -1,11 +1,18 @@ +from sage.all import Integer + def something(): """ a doctest in a docstring - >>> something() - 42 + + EXAMPLES:: + + sage: something() + 42 + sage: something() + 1 + 43 - some other doctest + TESTS:: - >>> something() + 1 - 43 + sage: something() + 44 """ return 42 From 7cfefd2734a3db031dcb595c2d86c39bf71668b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 29 Mar 2022 20:32:34 +0200 Subject: [PATCH 065/529] remove some warnings about colored 3d plots --- src/sage/plot/plot3d/implicit_plot3d.py | 6 ------ src/sage/plot/plot3d/parametric_plot3d.py | 7 ------- src/sage/plot/plot3d/parametric_surface.pyx | 6 ------ src/sage/plot/plot3d/revolution_plot3d.py | 6 ------ 4 files changed, 25 deletions(-) diff --git a/src/sage/plot/plot3d/implicit_plot3d.py b/src/sage/plot/plot3d/implicit_plot3d.py index 7d41dc6dd36..2eb18f7d64d 100644 --- a/src/sage/plot/plot3d/implicit_plot3d.py +++ b/src/sage/plot/plot3d/implicit_plot3d.py @@ -184,12 +184,6 @@ def metaball(x0, y0, z0): return 1 / ((x-x0)**2+(y-y0)**2+(z-z0)**2) (y,-2,2),(z,-2,2), contour=4, color=(t,cm), plot_points=40) sphinx_plot(G) - .. WARNING:: - - This kind of coloring using a colormap can be visualized using - Jmol, Tachyon (option ``viewer='tachyon'``) and Canvas3D - (option ``viewer='canvas3d'`` in the notebook). - MANY MORE EXAMPLES: A kind of saddle:: diff --git a/src/sage/plot/plot3d/parametric_plot3d.py b/src/sage/plot/plot3d/parametric_plot3d.py index 2b529b54889..f0411e199fe 100644 --- a/src/sage/plot/plot3d/parametric_plot3d.py +++ b/src/sage/plot/plot3d/parametric_plot3d.py @@ -212,13 +212,6 @@ def c(x,y): return sin(x*y)**2 def g(x,y): return x, y+sin(y), x**2 + y**2 sphinx_plot(ParametricSurface(g, (srange(-10,10,0.1), srange(-5,5.0,0.1)), color=(c,cm))) - .. WARNING:: - - This kind of coloring using a colormap can be visualized - using Jmol, Tachyon (option ``viewer='tachyon'``) and - Canvas3D (option ``viewer='canvas3d'`` in the - notebook). - We call the space curve function but with polynomials instead of symbolic variables. diff --git a/src/sage/plot/plot3d/parametric_surface.pyx b/src/sage/plot/plot3d/parametric_surface.pyx index 4b11ed631b3..e629e15f242 100644 --- a/src/sage/plot/plot3d/parametric_surface.pyx +++ b/src/sage/plot/plot3d/parametric_surface.pyx @@ -50,12 +50,6 @@ Another colored example:: sage: P = ParametricSurface(g, (srange(-10,10,0.1), srange(-5,5.0,0.1)), color=(c,colm)) sage: P.show(viewer='tachyon') -.. WARNING:: - - This kind of coloring using a colormap can be visualized using - Jmol, Tachyon (option ``viewer='tachyon'``) and Canvas3D - (option ``viewer='canvas3d'`` in the notebook). - .. NOTE:: One may override ``eval()`` or ``eval_c()`` in a subclass diff --git a/src/sage/plot/plot3d/revolution_plot3d.py b/src/sage/plot/plot3d/revolution_plot3d.py index 70047b23db1..7c570b985f3 100644 --- a/src/sage/plot/plot3d/revolution_plot3d.py +++ b/src/sage/plot/plot3d/revolution_plot3d.py @@ -187,12 +187,6 @@ def cf(u, phi): return sin(phi+u) ** 2 The first parameter of the coloring function will be identified with the parameter of the curve, and the second with the angle parameter. - .. WARNING:: - - This kind of coloring using a colormap can be visualized using - Jmol, Tachyon (option ``viewer='tachyon'``) and Canvas3D - (option ``viewer='canvas3d'`` in the notebook). - Another colored example, illustrating that one can use (colormap, color function) instead of (color function, colormap):: sage: u, phi = var('u,phi') From 715c93a6121068fc8d52ebc9b20991fbf9c2a9f9 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Tue, 29 Mar 2022 19:51:12 +0000 Subject: [PATCH 066/529] Add furo --- build/pkgs/furo/SPKG.rst | 16 ++++++++++++++++ build/pkgs/furo/checksums.ini | 5 +++++ build/pkgs/furo/dependencies | 4 ++++ build/pkgs/furo/install-requires.txt | 1 + build/pkgs/furo/package-version.txt | 1 + build/pkgs/furo/spkg-install.in | 2 ++ build/pkgs/furo/type | 1 + 7 files changed, 30 insertions(+) create mode 100644 build/pkgs/furo/SPKG.rst create mode 100644 build/pkgs/furo/checksums.ini create mode 100644 build/pkgs/furo/dependencies create mode 100644 build/pkgs/furo/install-requires.txt create mode 100644 build/pkgs/furo/package-version.txt create mode 100644 build/pkgs/furo/spkg-install.in create mode 100644 build/pkgs/furo/type diff --git a/build/pkgs/furo/SPKG.rst b/build/pkgs/furo/SPKG.rst new file mode 100644 index 00000000000..ebbd1bba238 --- /dev/null +++ b/build/pkgs/furo/SPKG.rst @@ -0,0 +1,16 @@ +furo: A clean customisable Sphinx documentation theme. +====================================================== + +Description +----------- + +A clean customisable Sphinx documentation theme. + +License +------- + +Upstream Contact +---------------- + +https://pypi.org/project/furo/ + diff --git a/build/pkgs/furo/checksums.ini b/build/pkgs/furo/checksums.ini new file mode 100644 index 00000000000..e83445623a2 --- /dev/null +++ b/build/pkgs/furo/checksums.ini @@ -0,0 +1,5 @@ +tarball=furo-VERSION.tar.gz +sha1=97bb53a7aa15fc64ae2df9e71c4d8d50f17a1fbc +md5=71d64ed9a33646a0b7ec5753652c16f7 +cksum=2464346896 +upstream_url=https://pypi.io/packages/source/f/furo/furo-VERSION.tar.gz diff --git a/build/pkgs/furo/dependencies b/build/pkgs/furo/dependencies new file mode 100644 index 00000000000..0738c2d7777 --- /dev/null +++ b/build/pkgs/furo/dependencies @@ -0,0 +1,4 @@ +$(PYTHON) | $(PYTHON_TOOLCHAIN) + +---------- +All lines of this file are ignored except the first. diff --git a/build/pkgs/furo/install-requires.txt b/build/pkgs/furo/install-requires.txt new file mode 100644 index 00000000000..a95ae18b4f9 --- /dev/null +++ b/build/pkgs/furo/install-requires.txt @@ -0,0 +1 @@ +furo diff --git a/build/pkgs/furo/package-version.txt b/build/pkgs/furo/package-version.txt new file mode 100644 index 00000000000..fd84d170fbe --- /dev/null +++ b/build/pkgs/furo/package-version.txt @@ -0,0 +1 @@ +2022.3.4 diff --git a/build/pkgs/furo/spkg-install.in b/build/pkgs/furo/spkg-install.in new file mode 100644 index 00000000000..37ac1a53437 --- /dev/null +++ b/build/pkgs/furo/spkg-install.in @@ -0,0 +1,2 @@ +cd src +sdh_pip_install . diff --git a/build/pkgs/furo/type b/build/pkgs/furo/type new file mode 100644 index 00000000000..134d9bc32d5 --- /dev/null +++ b/build/pkgs/furo/type @@ -0,0 +1 @@ +optional From c4a3c28c5347993b7ec86e16cc0c0d99741bd720 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Tue, 29 Mar 2022 20:27:37 +0000 Subject: [PATCH 067/529] Add sphinx-theme-builder --- build/pkgs/furo/dependencies | 2 +- build/pkgs/sphinx_theme_builder/SPKG.rst | 16 ++++++++++++++++ build/pkgs/sphinx_theme_builder/checksums.ini | 5 +++++ build/pkgs/sphinx_theme_builder/dependencies | 4 ++++ .../sphinx_theme_builder/install-requires.txt | 1 + .../sphinx_theme_builder/package-version.txt | 1 + build/pkgs/sphinx_theme_builder/spkg-install.in | 2 ++ build/pkgs/sphinx_theme_builder/type | 1 + 8 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 build/pkgs/sphinx_theme_builder/SPKG.rst create mode 100644 build/pkgs/sphinx_theme_builder/checksums.ini create mode 100644 build/pkgs/sphinx_theme_builder/dependencies create mode 100644 build/pkgs/sphinx_theme_builder/install-requires.txt create mode 100644 build/pkgs/sphinx_theme_builder/package-version.txt create mode 100644 build/pkgs/sphinx_theme_builder/spkg-install.in create mode 100644 build/pkgs/sphinx_theme_builder/type diff --git a/build/pkgs/furo/dependencies b/build/pkgs/furo/dependencies index 0738c2d7777..79eb3e339ae 100644 --- a/build/pkgs/furo/dependencies +++ b/build/pkgs/furo/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) | $(PYTHON_TOOLCHAIN) +$(PYTHON) sphinx_theme_builder | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/sphinx_theme_builder/SPKG.rst b/build/pkgs/sphinx_theme_builder/SPKG.rst new file mode 100644 index 00000000000..47b5e8666f2 --- /dev/null +++ b/build/pkgs/sphinx_theme_builder/SPKG.rst @@ -0,0 +1,16 @@ +sphinx_theme_builder: A tool for authoring Sphinx themes with a simple (opinionated) workflow. +============================================================================================== + +Description +----------- + +A tool for authoring Sphinx themes with a simple (opinionated) workflow. + +License +------- + +Upstream Contact +---------------- + +https://pypi.org/project/sphinx-theme-builder/ + diff --git a/build/pkgs/sphinx_theme_builder/checksums.ini b/build/pkgs/sphinx_theme_builder/checksums.ini new file mode 100644 index 00000000000..5d9ce40163e --- /dev/null +++ b/build/pkgs/sphinx_theme_builder/checksums.ini @@ -0,0 +1,5 @@ +tarball=sphinx-theme-builder-VERSION.tar.gz +sha1=c4962660ccfc47282557359a980f1fb41154c449 +md5=7b7accee558a89f683561f6b3257ae8f +cksum=3904771227 +upstream_url=https://pypi.io/packages/source/s/sphinx_theme_builder/sphinx-theme-builder-VERSION.tar.gz diff --git a/build/pkgs/sphinx_theme_builder/dependencies b/build/pkgs/sphinx_theme_builder/dependencies new file mode 100644 index 00000000000..0738c2d7777 --- /dev/null +++ b/build/pkgs/sphinx_theme_builder/dependencies @@ -0,0 +1,4 @@ +$(PYTHON) | $(PYTHON_TOOLCHAIN) + +---------- +All lines of this file are ignored except the first. diff --git a/build/pkgs/sphinx_theme_builder/install-requires.txt b/build/pkgs/sphinx_theme_builder/install-requires.txt new file mode 100644 index 00000000000..7c7d2d83756 --- /dev/null +++ b/build/pkgs/sphinx_theme_builder/install-requires.txt @@ -0,0 +1 @@ +sphinx-theme-builder diff --git a/build/pkgs/sphinx_theme_builder/package-version.txt b/build/pkgs/sphinx_theme_builder/package-version.txt new file mode 100644 index 00000000000..9ab06c54acc --- /dev/null +++ b/build/pkgs/sphinx_theme_builder/package-version.txt @@ -0,0 +1 @@ +0.2.0a14 diff --git a/build/pkgs/sphinx_theme_builder/spkg-install.in b/build/pkgs/sphinx_theme_builder/spkg-install.in new file mode 100644 index 00000000000..37ac1a53437 --- /dev/null +++ b/build/pkgs/sphinx_theme_builder/spkg-install.in @@ -0,0 +1,2 @@ +cd src +sdh_pip_install . diff --git a/build/pkgs/sphinx_theme_builder/type b/build/pkgs/sphinx_theme_builder/type new file mode 100644 index 00000000000..134d9bc32d5 --- /dev/null +++ b/build/pkgs/sphinx_theme_builder/type @@ -0,0 +1 @@ +optional From 67f127931decc1e79df87f1b5bd83498e3d78eb6 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Tue, 29 Mar 2022 22:02:03 +0000 Subject: [PATCH 068/529] Add initial config --- src/sage/docs/conf.py | 60 +++++++++++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 16 deletions(-) diff --git a/src/sage/docs/conf.py b/src/sage/docs/conf.py index 23ada2b43ca..787cf520343 100644 --- a/src/sage/docs/conf.py +++ b/src/sage/docs/conf.py @@ -17,13 +17,15 @@ # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sage_docbuild.ext.inventory_builder', - 'sage_docbuild.ext.multidocs', - 'sage_docbuild.ext.sage_autodoc', - 'sphinx.ext.todo', - 'sphinx.ext.extlinks', - 'IPython.sphinxext.ipython_directive', - 'matplotlib.sphinxext.plot_directive'] +extensions = [ + "sage_docbuild.ext.inventory_builder", + "sage_docbuild.ext.multidocs", + "sage_docbuild.ext.sage_autodoc", + "sphinx.ext.todo", + "sphinx.ext.extlinks", + "IPython.sphinxext.ipython_directive", + #"matplotlib.sphinxext.plot_directive", +] # This code is executed before each ".. PLOT::" directive in the Sphinx # documentation. It defines a 'sphinx_plot' function that displays a Sage object @@ -142,10 +144,6 @@ def sphinx_plot(graphics, **kwds): # output. They are ignored by default. #show_authors = False -# The name of the Pygments (syntax highlighting) style to use. NOTE: -# This overrides a HTML theme's corresponding setting (see below). -pygments_style = 'sphinx' - # Default lexer to use when highlighting code blocks, using the IPython # console lexers. 'ipycon' is the IPython console, which is what we want # for most code blocks: anything with "sage:" prompts. For other IPython, @@ -200,19 +198,48 @@ def set_intersphinx_mappings(app, config): # Options for HTML output # ----------------------- - +import importlib.util + +if importlib.util.find_spec("furo") is not None: + html_theme = "furo" + + # https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-html_static_path + html_static_path = [ + os.path.join(SAGE_DOC_SRC, "common", "themes", "sage-classic", "static") + ] + + html_theme_options = { + # Hide project’s name in the sidebar of the documentation; + # the logo is enough. + # https://pradyunsg.me/furo/customisation/#sidebar-hide-name + "sidebar_hide_name": True, + # Change accent (used for stylising links, sidebar’s content etc) + "light_css_variables": { + "color-brand-primary": "#0f0fff", + "color-brand-content": "#0f0fff", + }, + # Add sage logo to sidebar + # https://pradyunsg.me/furo/customisation/logo/#different-logos-for-light-and-dark-mode + "light_logo": "logo_sagemath_black.svg", + "dark_logo": "logo_sagemath.svg", + } +else: # Sage default HTML theme. We use a custom theme to set a Pygments style, # stylesheet, and insert MathJax macros. See the directory # doc/common/themes/sage-classic/ for files comprising the custom theme. -html_theme = 'sage-classic' + html_theme = "sage-classic" + + # Add any paths that contain custom themes here, relative to this directory. + html_theme_path = [os.path.join(SAGE_DOC_SRC, "common", "themes")] # Theme options are theme-specific and customize the look and feel of # a theme further. For a list of options available for each theme, # see the documentation. html_theme_options = {} -# Add any paths that contain custom themes here, relative to this directory. -html_theme_path = [os.path.join(SAGE_DOC_SRC, 'common', 'themes')] + # The name of the Pygments (syntax highlighting) style to use. NOTE: + # This overrides a HTML theme's corresponding setting (see below). + pygments_style = "sphinx" # HTML style sheet NOTE: This overrides a HTML theme's corresponding # setting. @@ -246,7 +273,8 @@ def set_intersphinx_mappings(app, config): mathjax_path = 'MathJax.js?config=TeX-AMS_HTML-full,../mathjax_sage.js' from sage.misc.latex_macros import sage_mathjax_macros -html_theme_options['mathjax_macros'] = sage_mathjax_macros() + +#html_theme_options["mathjax_macros"] = sage_mathjax_macros() mathjax_relative = os.path.basename(MATHJAX_DIR) From b90316d145d7eff02092e01bafbf091b269ed8ef Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Tue, 29 Mar 2022 22:33:11 +0000 Subject: [PATCH 069/529] Configure mathjax in sphinx config --- src/sage/docs/conf.py | 35 ++++++++++++++++----------- src/sage/misc/latex_macros.py | 45 +++++++++++++++++++---------------- 2 files changed, 46 insertions(+), 34 deletions(-) diff --git a/src/sage/docs/conf.py b/src/sage/docs/conf.py index 23ada2b43ca..4b939886f10 100644 --- a/src/sage/docs/conf.py +++ b/src/sage/docs/conf.py @@ -1,7 +1,8 @@ import sys import os import sphinx -from sage.env import SAGE_DOC_SRC, SAGE_DOC, SAGE_SRC, THEBE_DIR, PPLPY_DOCS, MATHJAX_DIR +from sage.env import SAGE_DOC_SRC, SAGE_DOC, THEBE_DIR, PPLPY_DOCS, MATHJAX_DIR +from sage.misc.latex_macros import sage_mathjax_macros import sage.version from sage.misc.sagedoc import extlinks import dateutil.parser @@ -12,18 +13,24 @@ import sphinx.ext.intersphinx as intersphinx from IPython.lib.lexers import IPythonConsoleLexer, IPyLexer + # General configuration # --------------------- # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sage_docbuild.ext.inventory_builder', - 'sage_docbuild.ext.multidocs', - 'sage_docbuild.ext.sage_autodoc', - 'sphinx.ext.todo', - 'sphinx.ext.extlinks', - 'IPython.sphinxext.ipython_directive', - 'matplotlib.sphinxext.plot_directive'] +extensions = [ + "sage_docbuild.ext.inventory_builder", + "sage_docbuild.ext.multidocs", + "sage_docbuild.ext.sage_autodoc", + "sphinx.ext.todo", + "sphinx.ext.extlinks", + # Mathjax integration + # https://www.sphinx-doc.org/en/master/usage/extensions/math.html#module-sphinx.ext.mathjax + "sphinx.ext.mathjax", + "IPython.sphinxext.ipython_directive", + "matplotlib.sphinxext.plot_directive", +] # This code is executed before each ".. PLOT::" directive in the Sphinx # documentation. It defines a 'sphinx_plot' function that displays a Sage object @@ -241,12 +248,12 @@ def set_intersphinx_mappings(app, config): html_common_static_path = [os.path.join(SAGE_DOC_SRC, 'common', 'static'), THEBE_DIR, 'static'] -# We use MathJax to build the documentation. -extensions.append('sphinx.ext.mathjax') -mathjax_path = 'MathJax.js?config=TeX-AMS_HTML-full,../mathjax_sage.js' - -from sage.misc.latex_macros import sage_mathjax_macros -html_theme_options['mathjax_macros'] = sage_mathjax_macros() +# Configure MathJax +mathjax3_config = { + "tex": { + "macros": sage_mathjax_macros() + } +} mathjax_relative = os.path.basename(MATHJAX_DIR) diff --git a/src/sage/misc/latex_macros.py b/src/sage/misc/latex_macros.py index f1ac926c235..37d2bee6608 100644 --- a/src/sage/misc/latex_macros.py +++ b/src/sage/misc/latex_macros.py @@ -43,6 +43,7 @@ contain '\newcommand' lines for each of the entries in ``macros``. """ + def produce_latex_macro(name, *sample_args): r""" Produce a string defining a LaTeX macro. @@ -111,34 +112,35 @@ def convert_latex_macro_to_mathjax(macro): - ``macro`` - LaTeX macro definition See the web page - http://www.mathjax.org/docs/1.1/options/TeX.html for a + https://docs.mathjax.org/en/latest/input/tex/macros.html for a description of the format for MathJax macros. EXAMPLES:: sage: from sage.misc.latex_macros import convert_latex_macro_to_mathjax sage: convert_latex_macro_to_mathjax('\\newcommand{\\ZZ}{\\Bold{Z}}') - 'ZZ: "\\\\Bold{Z}"' + ('ZZ', '\\Bold{Z}') sage: convert_latex_macro_to_mathjax('\\newcommand{\\GF}[1]{\\Bold{F}_{#1}}') - 'GF: ["\\\\Bold{F}_{#1}",1]' + ('GF', ['\\Bold{F}_{#1}', 1]) """ - left_bracket = macro.find('[') - right_bracket = macro.find('[') + left_bracket = macro.find("[") + right_bracket = macro.find("[") if left_bracket >= 0: - right_bracket = macro.find(']') - num_args = macro[left_bracket+1:right_bracket] + right_bracket = macro.find("]") + num_args = int(macro[left_bracket + 1 : right_bracket]) else: num_args = 0 - start_name = macro.find('{') + 1 # add one to go past the backslash - end_name = macro.find('}') - name = macro[start_name+1:end_name] - start_defn = macro.find('{', end_name) - end_defn = macro.rfind('}') - defn = macro[start_defn+1: end_defn].replace('\\', '\\\\') + start_name = macro.find("{") + 1 # add one to go past the backslash + end_name = macro.find("}") + name = macro[start_name + 1 : end_name] + start_defn = macro.find("{", end_name) + end_defn = macro.rfind("}") + defn = macro[start_defn + 1 : end_defn] if num_args == 0: - return name + ': "' + defn + '"' + return name, defn else: - return name + ': ["' + defn + '",' + str(num_args) + ']' + return name, [defn, num_args] + # To add a new macro for use in the Sage documentation, add a list or # tuple to the following list. Each list (or tuple) should have the @@ -176,6 +178,7 @@ def convert_latex_macro_to_mathjax(macro): # mathbf vs mathbb. See latex.py for more information. sage_configurable_latex_macros = [r"\newcommand{\Bold}[1]{\mathbf{#1}}"] + def sage_latex_macros(): r""" Return list of LaTeX macros for Sage. This just runs the function @@ -193,15 +196,17 @@ def sage_latex_macros(): def sage_mathjax_macros(): r""" - Return list of MathJax macro definitions for Sage as - JavaScript. This feeds each item output by - :func:`sage_latex_macros` to + Return Sage's macro definitions for usage with MathJax. + + This feeds each item output by :func:`sage_latex_macros` to :func:`convert_latex_macro_to_mathjax`. EXAMPLES:: sage: from sage.misc.latex_macros import sage_mathjax_macros sage: sage_mathjax_macros() - ['ZZ: "\\\\Bold{Z}"', 'NN: "\\\\Bold{N}"', ... + {'Bold': ['\\mathbf{#1}', 1], 'CC': '\\Bold{C}', ... """ - return [convert_latex_macro_to_mathjax(m) for m in sage_latex_macros()] + return dict( + [convert_latex_macro_to_mathjax(m) for m in sage_latex_macros()] + ) From 9bc443204bed20fac922cc758ca51259e2cbfa45 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 30 Mar 2022 13:46:45 +0000 Subject: [PATCH 070/529] Migrate rest of config --- .../sage-classic/static/mathjax_sage.js_t | 23 ------------------- src/doc/common/themes/sage-classic/theme.conf | 2 -- src/sage/docs/conf.py | 18 +++++++++++++-- src/sage/misc/sagedoc.py | 1 - 4 files changed, 16 insertions(+), 28 deletions(-) delete mode 100644 src/doc/common/themes/sage-classic/static/mathjax_sage.js_t diff --git a/src/doc/common/themes/sage-classic/static/mathjax_sage.js_t b/src/doc/common/themes/sage-classic/static/mathjax_sage.js_t deleted file mode 100644 index b261f2265a3..00000000000 --- a/src/doc/common/themes/sage-classic/static/mathjax_sage.js_t +++ /dev/null @@ -1,23 +0,0 @@ -MathJax.Hub.Config({ - imageFont: null, - tex2jax: { - inlineMath: [['$','$'],['\\(','\\)']], - processEscapes: true, - }, - styles: { - ".MathJax .mo, .MathJax .mi": { - color: "inherit ! important" - } - }, - TeX: { - MAXBUFFER: 50*1024, - - Macros: { - {{ theme_mathjax_macros|join(',\n') }} - } - } -}); - -// This path is a little funny because we have to load our local -// config file as '../mathjax_sage' in the theme conf.py -MathJax.Ajax.loadComplete("[MathJax]/config/../mathjax_sage.js") diff --git a/src/doc/common/themes/sage-classic/theme.conf b/src/doc/common/themes/sage-classic/theme.conf index cc6279a2633..fbde86a94ac 100644 --- a/src/doc/common/themes/sage-classic/theme.conf +++ b/src/doc/common/themes/sage-classic/theme.conf @@ -40,5 +40,3 @@ linkcolor = #45529B # Background color for code blocks: very pale yellow codebgcolor = #FFFFE5 -# MathJax settings filled in by conf.py -mathjax_macros = diff --git a/src/sage/docs/conf.py b/src/sage/docs/conf.py index 4b939886f10..e14dce18c8e 100644 --- a/src/sage/docs/conf.py +++ b/src/sage/docs/conf.py @@ -249,11 +249,25 @@ def set_intersphinx_mappings(app, config): THEBE_DIR, 'static'] # Configure MathJax +# https://docs.mathjax.org/en/latest/options/input/tex.html mathjax3_config = { "tex": { - "macros": sage_mathjax_macros() - } + # Add custom sage macros + # http://docs.mathjax.org/en/latest/input/tex/macros.html + "macros": sage_mathjax_macros(), + # Add $...$ as possible inline math + # https://docs.mathjax.org/en/latest/input/tex/delimiters.html#tex-and-latex-math-delimiters + "inlineMath": [["$", "$"], ["\\(", "\\)"]], + # Increase the limit the size of the string to be processed + # https://docs.mathjax.org/en/latest/options/input/tex.html#option-descriptions + "maxBuffer": 50 * 1024, + # Use colorv2 extension instead of built-in color extension + # https://docs.mathjax.org/en/latest/input/tex/extensions/autoload.html#tex-autoload-options + # https://docs.mathjax.org/en/latest/input/tex/extensions/colorv2.html#tex-colorv2 + "autoload": {"color": [], "colorv2": ["color"]}, + }, } +mathjax_path = "https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js" mathjax_relative = os.path.basename(MATHJAX_DIR) diff --git a/src/sage/misc/sagedoc.py b/src/sage/misc/sagedoc.py index 4b3853f3e8d..17fa004f904 100644 --- a/src/sage/misc/sagedoc.py +++ b/src/sage/misc/sagedoc.py @@ -1486,7 +1486,6 @@ def __call__(self, obj, output='html', view=True): - From cc0f093d842a92c6b1f770a36ffb4711d970790a Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 30 Mar 2022 13:55:35 +0000 Subject: [PATCH 071/529] Use furo on ci --- .github/workflows/doc-build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index 1b501600e67..c0093688f00 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -24,6 +24,7 @@ jobs: # Reuse built SAGE_LOCAL contained in the Docker image ./bootstrap ./configure --enable-build-as-root --prefix=/sage/local --with-sage-venv + make furo - name: Build run: make doc-html From 3be9522be5bcc98b6bae68d27d3181ae7c5ceb5a Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 30 Mar 2022 18:50:11 +0000 Subject: [PATCH 072/529] Make furo a pip package --- build/pkgs/furo/checksums.ini | 5 ----- build/pkgs/furo/dependencies | 2 +- build/pkgs/furo/package-version.txt | 1 - .../{install-requires.txt => requirements.txt} | 0 build/pkgs/furo/spkg-install.in | 2 -- build/pkgs/sphinx_theme_builder/SPKG.rst | 16 ---------------- build/pkgs/sphinx_theme_builder/checksums.ini | 5 ----- build/pkgs/sphinx_theme_builder/dependencies | 4 ---- .../sphinx_theme_builder/install-requires.txt | 1 - .../sphinx_theme_builder/package-version.txt | 1 - build/pkgs/sphinx_theme_builder/spkg-install.in | 2 -- build/pkgs/sphinx_theme_builder/type | 1 - 12 files changed, 1 insertion(+), 39 deletions(-) delete mode 100644 build/pkgs/furo/checksums.ini delete mode 100644 build/pkgs/furo/package-version.txt rename build/pkgs/furo/{install-requires.txt => requirements.txt} (100%) delete mode 100644 build/pkgs/furo/spkg-install.in delete mode 100644 build/pkgs/sphinx_theme_builder/SPKG.rst delete mode 100644 build/pkgs/sphinx_theme_builder/checksums.ini delete mode 100644 build/pkgs/sphinx_theme_builder/dependencies delete mode 100644 build/pkgs/sphinx_theme_builder/install-requires.txt delete mode 100644 build/pkgs/sphinx_theme_builder/package-version.txt delete mode 100644 build/pkgs/sphinx_theme_builder/spkg-install.in delete mode 100644 build/pkgs/sphinx_theme_builder/type diff --git a/build/pkgs/furo/checksums.ini b/build/pkgs/furo/checksums.ini deleted file mode 100644 index e83445623a2..00000000000 --- a/build/pkgs/furo/checksums.ini +++ /dev/null @@ -1,5 +0,0 @@ -tarball=furo-VERSION.tar.gz -sha1=97bb53a7aa15fc64ae2df9e71c4d8d50f17a1fbc -md5=71d64ed9a33646a0b7ec5753652c16f7 -cksum=2464346896 -upstream_url=https://pypi.io/packages/source/f/furo/furo-VERSION.tar.gz diff --git a/build/pkgs/furo/dependencies b/build/pkgs/furo/dependencies index 79eb3e339ae..0738c2d7777 100644 --- a/build/pkgs/furo/dependencies +++ b/build/pkgs/furo/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) sphinx_theme_builder | $(PYTHON_TOOLCHAIN) +$(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/furo/package-version.txt b/build/pkgs/furo/package-version.txt deleted file mode 100644 index fd84d170fbe..00000000000 --- a/build/pkgs/furo/package-version.txt +++ /dev/null @@ -1 +0,0 @@ -2022.3.4 diff --git a/build/pkgs/furo/install-requires.txt b/build/pkgs/furo/requirements.txt similarity index 100% rename from build/pkgs/furo/install-requires.txt rename to build/pkgs/furo/requirements.txt diff --git a/build/pkgs/furo/spkg-install.in b/build/pkgs/furo/spkg-install.in deleted file mode 100644 index 37ac1a53437..00000000000 --- a/build/pkgs/furo/spkg-install.in +++ /dev/null @@ -1,2 +0,0 @@ -cd src -sdh_pip_install . diff --git a/build/pkgs/sphinx_theme_builder/SPKG.rst b/build/pkgs/sphinx_theme_builder/SPKG.rst deleted file mode 100644 index 47b5e8666f2..00000000000 --- a/build/pkgs/sphinx_theme_builder/SPKG.rst +++ /dev/null @@ -1,16 +0,0 @@ -sphinx_theme_builder: A tool for authoring Sphinx themes with a simple (opinionated) workflow. -============================================================================================== - -Description ------------ - -A tool for authoring Sphinx themes with a simple (opinionated) workflow. - -License -------- - -Upstream Contact ----------------- - -https://pypi.org/project/sphinx-theme-builder/ - diff --git a/build/pkgs/sphinx_theme_builder/checksums.ini b/build/pkgs/sphinx_theme_builder/checksums.ini deleted file mode 100644 index 5d9ce40163e..00000000000 --- a/build/pkgs/sphinx_theme_builder/checksums.ini +++ /dev/null @@ -1,5 +0,0 @@ -tarball=sphinx-theme-builder-VERSION.tar.gz -sha1=c4962660ccfc47282557359a980f1fb41154c449 -md5=7b7accee558a89f683561f6b3257ae8f -cksum=3904771227 -upstream_url=https://pypi.io/packages/source/s/sphinx_theme_builder/sphinx-theme-builder-VERSION.tar.gz diff --git a/build/pkgs/sphinx_theme_builder/dependencies b/build/pkgs/sphinx_theme_builder/dependencies deleted file mode 100644 index 0738c2d7777..00000000000 --- a/build/pkgs/sphinx_theme_builder/dependencies +++ /dev/null @@ -1,4 +0,0 @@ -$(PYTHON) | $(PYTHON_TOOLCHAIN) - ----------- -All lines of this file are ignored except the first. diff --git a/build/pkgs/sphinx_theme_builder/install-requires.txt b/build/pkgs/sphinx_theme_builder/install-requires.txt deleted file mode 100644 index 7c7d2d83756..00000000000 --- a/build/pkgs/sphinx_theme_builder/install-requires.txt +++ /dev/null @@ -1 +0,0 @@ -sphinx-theme-builder diff --git a/build/pkgs/sphinx_theme_builder/package-version.txt b/build/pkgs/sphinx_theme_builder/package-version.txt deleted file mode 100644 index 9ab06c54acc..00000000000 --- a/build/pkgs/sphinx_theme_builder/package-version.txt +++ /dev/null @@ -1 +0,0 @@ -0.2.0a14 diff --git a/build/pkgs/sphinx_theme_builder/spkg-install.in b/build/pkgs/sphinx_theme_builder/spkg-install.in deleted file mode 100644 index 37ac1a53437..00000000000 --- a/build/pkgs/sphinx_theme_builder/spkg-install.in +++ /dev/null @@ -1,2 +0,0 @@ -cd src -sdh_pip_install . diff --git a/build/pkgs/sphinx_theme_builder/type b/build/pkgs/sphinx_theme_builder/type deleted file mode 100644 index 134d9bc32d5..00000000000 --- a/build/pkgs/sphinx_theme_builder/type +++ /dev/null @@ -1 +0,0 @@ -optional From c0bd95a3f04a2194356794caa0f21a53dfe9b856 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 30 Mar 2022 18:50:59 +0000 Subject: [PATCH 073/529] Fix intend --- src/sage/docs/conf.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/sage/docs/conf.py b/src/sage/docs/conf.py index 787cf520343..45d6fff87b5 100644 --- a/src/sage/docs/conf.py +++ b/src/sage/docs/conf.py @@ -224,18 +224,18 @@ def set_intersphinx_mappings(app, config): "dark_logo": "logo_sagemath.svg", } else: -# Sage default HTML theme. We use a custom theme to set a Pygments style, -# stylesheet, and insert MathJax macros. See the directory -# doc/common/themes/sage-classic/ for files comprising the custom theme. + # Sage default HTML theme. We use a custom theme to set a Pygments style, + # stylesheet, and insert MathJax macros. See the directory + # doc/common/themes/sage-classic/ for files comprising the custom theme. html_theme = "sage-classic" # Add any paths that contain custom themes here, relative to this directory. html_theme_path = [os.path.join(SAGE_DOC_SRC, "common", "themes")] -# Theme options are theme-specific and customize the look and feel of -# a theme further. For a list of options available for each theme, -# see the documentation. -html_theme_options = {} + # Theme options are theme-specific and customize the look and feel of + # a theme further. For a list of options available for each theme, + # see the documentation. + html_theme_options = {} # The name of the Pygments (syntax highlighting) style to use. NOTE: # This overrides a HTML theme's corresponding setting (see below). From 8e8c76b1575ad1304fbb6e5f556cbd67b31e234a Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 30 Mar 2022 20:16:10 +0000 Subject: [PATCH 074/529] Reactivate matplotlib --- src/sage/docs/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/docs/conf.py b/src/sage/docs/conf.py index 45d6fff87b5..b1841006411 100644 --- a/src/sage/docs/conf.py +++ b/src/sage/docs/conf.py @@ -24,7 +24,7 @@ "sphinx.ext.todo", "sphinx.ext.extlinks", "IPython.sphinxext.ipython_directive", - #"matplotlib.sphinxext.plot_directive", + "matplotlib.sphinxext.plot_directive", ] # This code is executed before each ".. PLOT::" directive in the Sphinx From 6260621dc310a0a9312f6b8e77aef92332ff2da3 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 30 Mar 2022 20:17:27 +0000 Subject: [PATCH 075/529] cleanup --- src/sage/docs/conf.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/docs/conf.py b/src/sage/docs/conf.py index b1841006411..e9f490d3d9a 100644 --- a/src/sage/docs/conf.py +++ b/src/sage/docs/conf.py @@ -1,3 +1,4 @@ +import importlib.util import sys import os import sphinx @@ -198,8 +199,6 @@ def set_intersphinx_mappings(app, config): # Options for HTML output # ----------------------- -import importlib.util - if importlib.util.find_spec("furo") is not None: html_theme = "furo" From 516dfe85b21eafae4f042320e5dcf61ad14fe780 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 30 Mar 2022 21:17:40 +0000 Subject: [PATCH 076/529] Try with _static folder --- src/sage_docbuild/__init__.py | 2 +- src/sage_docbuild/ext/inventory_builder.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage_docbuild/__init__.py b/src/sage_docbuild/__init__.py index f2df893ffcb..27ced1dacf5 100644 --- a/src/sage_docbuild/__init__.py +++ b/src/sage_docbuild/__init__.py @@ -1689,7 +1689,7 @@ def main(): # Get the name and type (target format) of the document we are # trying to build. name, typ = args.document, args.format - if not name or not type: + if not name or not typ: parser.print_help() sys.exit(1) diff --git a/src/sage_docbuild/ext/inventory_builder.py b/src/sage_docbuild/ext/inventory_builder.py index a4941c21981..f3fb44bcd35 100644 --- a/src/sage_docbuild/ext/inventory_builder.py +++ b/src/sage_docbuild/ext/inventory_builder.py @@ -87,8 +87,8 @@ def cleanup(self): may be created by the graphviz extension. Its presence will break the docbuild later on, so remove it. """ - if path.isdir(path.join(self.outdir, '_static')): - shutil.rmtree(path.join(self.outdir, '_static')) + #if path.isdir(path.join(self.outdir, '_static')): + # shutil.rmtree(path.join(self.outdir, '_static')) copy_image_files = removed_method_error From e4e1118f3099113768dfee029146e63614a46391 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Thu, 31 Mar 2022 11:53:17 +0000 Subject: [PATCH 077/529] Convert double quotes to single quotes --- src/sage/docs/conf.py | 16 ++++++++-------- src/sage/misc/latex_macros.py | 14 +++++++------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/sage/docs/conf.py b/src/sage/docs/conf.py index e14dce18c8e..d6a72bf1709 100644 --- a/src/sage/docs/conf.py +++ b/src/sage/docs/conf.py @@ -20,16 +20,16 @@ # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [ - "sage_docbuild.ext.inventory_builder", - "sage_docbuild.ext.multidocs", - "sage_docbuild.ext.sage_autodoc", - "sphinx.ext.todo", - "sphinx.ext.extlinks", + 'sage_docbuild.ext.inventory_builder', + 'sage_docbuild.ext.multidocs', + 'sage_docbuild.ext.sage_autodoc', + 'sphinx.ext.todo', + 'sphinx.ext.extlinks', # Mathjax integration # https://www.sphinx-doc.org/en/master/usage/extensions/math.html#module-sphinx.ext.mathjax - "sphinx.ext.mathjax", - "IPython.sphinxext.ipython_directive", - "matplotlib.sphinxext.plot_directive", + 'sphinx.ext.mathjax', + 'IPython.sphinxext.ipython_directive', + 'matplotlib.sphinxext.plot_directive', ] # This code is executed before each ".. PLOT::" directive in the Sphinx diff --git a/src/sage/misc/latex_macros.py b/src/sage/misc/latex_macros.py index 37d2bee6608..729a7ba49f0 100644 --- a/src/sage/misc/latex_macros.py +++ b/src/sage/misc/latex_macros.py @@ -123,18 +123,18 @@ def convert_latex_macro_to_mathjax(macro): sage: convert_latex_macro_to_mathjax('\\newcommand{\\GF}[1]{\\Bold{F}_{#1}}') ('GF', ['\\Bold{F}_{#1}', 1]) """ - left_bracket = macro.find("[") - right_bracket = macro.find("[") + left_bracket = macro.find('[') + right_bracket = macro.find('[') if left_bracket >= 0: - right_bracket = macro.find("]") + right_bracket = macro.find(']') num_args = int(macro[left_bracket + 1 : right_bracket]) else: num_args = 0 - start_name = macro.find("{") + 1 # add one to go past the backslash - end_name = macro.find("}") + start_name = macro.find('{') + 1 # add one to go past the backslash + end_name = macro.find('}') name = macro[start_name + 1 : end_name] - start_defn = macro.find("{", end_name) - end_defn = macro.rfind("}") + start_defn = macro.find('{', end_name) + end_defn = macro.rfind('}') defn = macro[start_defn + 1 : end_defn] if num_args == 0: return name, defn From 6e70cb2fee8530751e73d841b68682c9543bb962 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 23 Mar 2022 10:48:30 +0100 Subject: [PATCH 078/529] Make test methods private --- src/sage/modules/fg_pid/fgp_module.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/sage/modules/fg_pid/fgp_module.py b/src/sage/modules/fg_pid/fgp_module.py index 69f76549430..48f2bab4bc8 100644 --- a/src/sage/modules/fg_pid/fgp_module.py +++ b/src/sage/modules/fg_pid/fgp_module.py @@ -2016,17 +2016,17 @@ def random_fgp_morphism_0(*args, **kwds): return A.hom([ZZ.random_element() * g for g in A.smith_form_gens()]) -def test_morphism_0(*args, **kwds): +def _test_morphism_0(*args, **kwds): """ EXAMPLES:: sage: import sage.modules.fg_pid.fgp_module as fgp sage: s = 0 # we set a seed so results clearly and easily reproducible across runs. - sage: set_random_seed(s); v = [fgp.test_morphism_0(1) for _ in range(30)] - sage: set_random_seed(s); v = [fgp.test_morphism_0(2) for _ in range(30)] - sage: set_random_seed(s); v = [fgp.test_morphism_0(3) for _ in range(10)] - sage: set_random_seed(s); v = [fgp.test_morphism_0(i) for i in range(1,20)] - sage: set_random_seed(s); v = [fgp.test_morphism_0(4) for _ in range(50)] # long time + sage: set_random_seed(s); v = [fgp._test_morphism_0(1) for _ in range(30)] + sage: set_random_seed(s); v = [fgp._test_morphism_0(2) for _ in range(30)] + sage: set_random_seed(s); v = [fgp._test_morphism_0(3) for _ in range(10)] + sage: set_random_seed(s); v = [fgp._test_morphism_0(i) for i in range(1,20)] + sage: set_random_seed(s); v = [fgp._test_morphism_0(4) for _ in range(50)] # long time """ phi = random_fgp_morphism_0(*args, **kwds) K = phi.kernel() From a0e04eb0e1aa6801bf05028a93d2d28bf4d7b2dc Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 31 Mar 2022 21:33:05 -0700 Subject: [PATCH 079/529] src/sage/modules/fg_pid/fgp_module.py: Add deprecated_function_alias test_morphism_0 --- src/sage/modules/fg_pid/fgp_module.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/sage/modules/fg_pid/fgp_module.py b/src/sage/modules/fg_pid/fgp_module.py index 48f2bab4bc8..02cd33d5b48 100644 --- a/src/sage/modules/fg_pid/fgp_module.py +++ b/src/sage/modules/fg_pid/fgp_module.py @@ -221,6 +221,7 @@ from sage.rings.integer import Integer from sage.arith.functions import lcm from sage.misc.cachefunc import cached_method +from sage.misc.superseded import deprecated_function_alias from sage.matrix.constructor import matrix import sage.misc.weak_dict @@ -2038,3 +2039,6 @@ def _test_morphism_0(*args, **kwds): if len(I.smith_form_gens()) > 0: x = phi.lift(I.smith_form_gen(0)) assert phi(x) == I.smith_form_gen(0) + + +test_morphism_0 = deprecated_function_alias(33617, _test_morphism_0) From 66594c286731d529e9e93cf6753e00d07b687a6e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 31 Mar 2022 21:46:41 -0700 Subject: [PATCH 080/529] src/sage/modules/fg_pid/fgp_module.py: Fix doc markup --- src/sage/modules/fg_pid/fgp_module.py | 77 +++++++++++++-------------- 1 file changed, 38 insertions(+), 39 deletions(-) diff --git a/src/sage/modules/fg_pid/fgp_module.py b/src/sage/modules/fg_pid/fgp_module.py index 02cd33d5b48..8dde06dfc62 100644 --- a/src/sage/modules/fg_pid/fgp_module.py +++ b/src/sage/modules/fg_pid/fgp_module.py @@ -11,8 +11,7 @@ tested and debugged over more general PIDs. All algorithms make sense whenever there is a Hermite form implementation. In theory the obstruction to extending the implementation is only that one has to - decide how elements print. If you're annoyed that by this, fix things - and post a patch! + decide how elements print. We represent ``M = V / W`` as a pair ``(V, W)`` with ``W`` contained in ``V``, and we internally represent elements of M non-canonically as elements @@ -25,13 +24,13 @@ Morphisms between finitely generated R modules are well supported. You create a homomorphism by simply giving the images of generators of M0 in M1. Given a morphism phi:M0-->M1, you can compute the image of -phi, the kernel of phi, and using y=phi.lift(x) you can lift an +phi, the kernel of phi, and using ``y = phi.lift(x)`` you can lift an elements x in M1 to an element y in M0, if such a y exists. TECHNICAL NOTE: For efficiency, we introduce a notion of optimized representation for quotient modules. The optimized representation of M=V/W is the quotient V'/W' where V' has as basis lifts of the -generators g[i] for M. We internally store a morphism from M0=V0/W0 +generators ``g[i]`` for M. We internally store a morphism from M0=V0/W0 to M1=V1/W1 by giving a morphism from the optimized representation V0' of M0 to V1 that sends W0 into W1. @@ -268,7 +267,7 @@ def FGP_Module(V, W, check=True): def is_FGP_Module(x): """ - Return true of x is an FGP module, i.e., a finitely generated + Return ``True`` if x is an FGP module, i.e., a finitely generated module over a PID represented as a quotient of finitely generated free modules over a PID. @@ -527,11 +526,11 @@ def __ne__(self, other): This may not be needed for modules created using the function :func:`FGP_Module`, since those have uniqueness built into them, but if the modules are created directly using the - __init__ method for this class, then this may fail; in + ``__init__`` method for this class, then this may fail; in particular, for modules M and N with ``M == N`` returning True, it may be the case that ``M != N`` may also return True. - In particular, for derived classes whose __init__ methods just - call the __init__ method for this class need this. See + In particular, for derived classes whose ``__init__`` methods just + call the ``__init__`` method for this class need this. See :trac:`9940` for illustrations. EXAMPLES: @@ -562,7 +561,7 @@ def __ne__(self, other): def __lt__(self, other): """ - True iff self is a proper submodule of other. + True iff ``self`` is a proper submodule of ``other``. EXAMPLES:: @@ -580,7 +579,7 @@ def __lt__(self, other): def __gt__(self, other): """ - True iff other is a proper submodule of self. + True iff ``other`` is a proper submodule of ``self``. EXAMPLES:: @@ -598,7 +597,7 @@ def __gt__(self, other): def __ge__(self, other): """ - True iff other is a submodule of self. + True iff ``other`` is a submodule of ``self``. EXAMPLES:: @@ -624,7 +623,7 @@ def _element_constructor_(self, x, check=True): corresponding element of V/W - fgp module element: lift to element of ambient vector - space and try to put into V. If x is in self already, + space and try to put into V. If x is in ``self`` already, just return x. - `check` -- bool (default: ``True``) @@ -669,7 +668,7 @@ def linear_combination_of_smith_form_gens(self, x): def __contains__(self, x): """ - Return true if x is contained in self. + Return true if x is contained in ``self``. EXAMPLES:: @@ -756,12 +755,12 @@ def submodule(self, x): def has_canonical_map_to(self, A): """ - Return True if self has a canonical map to A, relative to the - given presentation of A. + Return ``True`` if ``self`` has a canonical map to ``A``, relative to the + given presentation of ``A``. - This means that A is a finitely - generated quotient module, self.V() is a submodule of A.V() - and self.W() is a submodule of A.W(), i.e., that there is a + This means that ``A`` is a finitely + generated quotient module, ``self.V()`` is a submodule of ``A.V()`` + and ``self.W()`` is a submodule of ``A.W()``, i.e., that there is a natural map induced by inclusion of the V's. Note that we do *not* require that this natural map be injective; for this use :meth:`is_submodule`. @@ -826,7 +825,7 @@ def is_submodule(self, A): def V(self): """ - If this module was constructed as a quotient V/W, returns V. + If this module was constructed as a quotient V/W, return V. EXAMPLES:: @@ -844,9 +843,9 @@ def V(self): def cover(self): """ - If this module was constructed as V/W, returns the cover module V. + If this module was constructed as V/W, return the cover module V. - This is the same as self.V(). + This is the same as ``self.V()``. EXAMPLES:: @@ -863,7 +862,7 @@ def cover(self): def W(self): """ - If this module was constructed as a quotient V/W, returns W. + If this module was constructed as a quotient V/W, return W. EXAMPLES:: @@ -962,7 +961,7 @@ def base_ring(self): def invariants(self, include_ones=False): """ Return the diagonal entries of the smith form of the relative - matrix that defines self (see :meth:`._relative_matrix`) + matrix that defines ``self`` (see :meth:`._relative_matrix`) padded with zeros, excluding 1's by default. Thus if v is the list of integers returned, then self is abstractly isomorphic to the product of cyclic groups `Z/nZ` where `n` is in `v`. @@ -1145,7 +1144,7 @@ def smith_to_gens(self): [0 1 0] [0 0 1] - We create some element of our FGP_module:: + We create some element of our FGP module:: sage: x = D.linear_combination_of_smith_form_gens((1,2,3)) sage: x @@ -1247,9 +1246,9 @@ def coordinate_vector(self, x, reduce=False): - ``x`` -- element of self - - ``reduce`` -- (default: False); if True, reduce + - ``reduce`` -- (default: False); if ``True``, reduce coefficients modulo invariants; this is - ignored if the base ring is not ZZ. + ignored if the base ring is not ``ZZ``. OUTPUT: @@ -1397,10 +1396,10 @@ def smith_form_gen(self, i): def optimized(self): """ Return a module isomorphic to this one, but with V replaced by - a submodule of V such that the generators of self all lift + a submodule of V such that the generators of ``self`` all lift trivially to generators of V. Replace W by the intersection of V and W. This has the advantage that V has small dimension - and any homomorphism from self trivially extends to a + and any homomorphism from ``self`` trivially extends to a homomorphism from V. OUTPUT: @@ -1408,9 +1407,9 @@ def optimized(self): - ``Q`` -- an optimized quotient V0/W0 with V0 a submodule of V such that phi: V0/W0 --> V/W is an isomorphism - - ``Z`` -- matrix such that if x is in self.V() and + - ``Z`` -- matrix such that if x is in ``self.V()`` and c gives the coordinates of x in terms of the - basis for self.V(), then c*Z is in V0 + basis for ``self.V()``, then c*Z is in V0 and c*Z maps to x via phi above. EXAMPLES:: @@ -1704,10 +1703,10 @@ def _Hom_(self, N, category=None): def random_element(self, *args, **kwds): """ - Create a random element of self=V/W, by creating a random element of V and + Create a random element of ``self`` = V/W, by creating a random element of V and reducing it modulo W. - All arguments are passed onto the random_element method of V. + All arguments are passed onto the method :meth:`random_element` of V. EXAMPLES:: @@ -1835,7 +1834,7 @@ def construction(self): def is_finite(self): """ - Return True if self is finite and False otherwise. + Return ``True`` if ``self`` is finite and ``False`` otherwise. EXAMPLES:: @@ -1853,9 +1852,9 @@ def is_finite(self): def annihilator(self): """ - Return the ideal of the base ring that annihilates self. This + Return the ideal of the base ring that annihilates ``self``. This is precisely the ideal generated by the LCM of the invariants - of self if self is finite, and is 0 otherwise. + of ``self`` if ``self`` is finite, and is 0 otherwise. EXAMPLES:: @@ -1886,7 +1885,7 @@ def annihilator(self): def ngens(self): r""" - Return the number of generators of self. + Return the number of generators of ``self``. (Note for developers: This is just the length of :meth:`.gens`, rather than of the minimal set of generators as returned by @@ -1949,9 +1948,9 @@ def random_fgp_module(n, R=ZZ, finite=False): - ``n`` -- nonnegative integer - - ``R`` -- base ring (default: ZZ) + - ``R`` -- base ring (default: ``ZZ``) - - ``finite`` -- bool (default: True); if True, make the random module finite. + - ``finite`` -- bool (default: ``True``); if True, make the random module finite. EXAMPLES:: @@ -1991,7 +1990,7 @@ def random_fgp_module(n, R=ZZ, finite=False): def random_fgp_morphism_0(*args, **kwds): """ - Construct a random fgp module using random_fgp_module, + Construct a random fgp module using :func:`random_fgp_module`, then construct a random morphism that sends each generator to a random multiple of itself. From 2269f1981d9f4de55482e487a3eded4a72c4ed4b Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Fri, 1 Apr 2022 16:32:21 +0000 Subject: [PATCH 081/529] Add dependencies --- build/pkgs/furo/dependencies | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/build/pkgs/furo/dependencies b/build/pkgs/furo/dependencies index 0738c2d7777..9544f8d9e55 100644 --- a/build/pkgs/furo/dependencies +++ b/build/pkgs/furo/dependencies @@ -1,4 +1,9 @@ -$(PYTHON) | $(PYTHON_TOOLCHAIN) +$(PYTHON) beautifulsoup4 sphinx pygments | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. + +From https://github.com/pradyunsg/furo/blob/b4c8010cff5e494a93d617069897964c60b820e9/pyproject.toml#L18-L22 + "beautifulsoup4", + "sphinx ~= 4.0", + "pygments ~= 2.7", From a7ecb880bf1bd952383fbbe640413001e18140c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 1 Apr 2022 21:46:20 +0200 Subject: [PATCH 082/529] reviewer's commit --- src/sage/combinat/k_regular_sequence.py | 25 ------------------------ src/sage/combinat/recognizable_series.py | 7 +++---- 2 files changed, 3 insertions(+), 29 deletions(-) diff --git a/src/sage/combinat/k_regular_sequence.py b/src/sage/combinat/k_regular_sequence.py index 8beb5ce6dd0..3bef6f4d84f 100644 --- a/src/sage/combinat/k_regular_sequence.py +++ b/src/sage/combinat/k_regular_sequence.py @@ -855,32 +855,7 @@ def __init__(self, k, *args, **kwds): sage: from itertools import islice sage: Seq2 = kRegularSequenceSpace(2, ZZ) sage: TestSuite(Seq2).run( # long time - ....: verbose=True, ....: elements=tuple(islice(Seq2.some_elements(), 4))) - running ._test_additive_associativity() . . . pass - running ._test_an_element() . . . pass - running ._test_cardinality() . . . pass - running ._test_category() . . . pass - running ._test_construction() . . . pass - running ._test_elements() . . . - Running the test suite of self.an_element() - running ._test_category() . . . pass - running ._test_eq() . . . pass - running ._test_new() . . . pass - running ._test_nonzero_equal() . . . pass - running ._test_not_implemented_methods() . . . pass - running ._test_pickling() . . . pass - pass - running ._test_elements_eq_reflexive() . . . pass - running ._test_elements_eq_symmetric() . . . pass - running ._test_elements_eq_transitive() . . . pass - running ._test_elements_neq() . . . pass - running ._test_eq() . . . pass - running ._test_new() . . . pass - running ._test_not_implemented_methods() . . . pass - running ._test_pickling() . . . pass - running ._test_some_elements() . . . pass - running ._test_zero() . . . pass .. SEEALSO:: diff --git a/src/sage/combinat/recognizable_series.py b/src/sage/combinat/recognizable_series.py index d39891e3435..4dc36a9cbca 100644 --- a/src/sage/combinat/recognizable_series.py +++ b/src/sage/combinat/recognizable_series.py @@ -961,7 +961,7 @@ def __eq__(self, other): sage: S == S True - sage: x == None + sage: S == None False """ if other is None: @@ -973,7 +973,7 @@ def __eq__(self, other): def __ne__(self, other): r""" - Return whether this recognizable series is equal to ``other``. + Return whether this recognizable series is not equal to ``other``. INPUT: @@ -1891,13 +1891,12 @@ def some_elements(self): 210*[] + ..., 2210*[] - 170*[0] + 170*[1] + ...) """ - from itertools import count, islice + from itertools import islice from sage.matrix.matrix_space import MatrixSpace from sage.modules.free_module import FreeModule yield self.an_element() C = self.coefficient_ring() - some_elements_base = iter(C.some_elements()) k = len(self.alphabet()) for dim in range(1, 11): elements_M = MatrixSpace(C, dim).some_elements() From 2f3f304f44af47b3f80fe03c8224bf2a2b40e288 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Tue, 5 Apr 2022 18:58:45 +0200 Subject: [PATCH 083/529] trac #33579: fix doctests in sagebook --- .../graphtheory_doctest.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/sage/tests/books/computational-mathematics-with-sagemath/graphtheory_doctest.py b/src/sage/tests/books/computational-mathematics-with-sagemath/graphtheory_doctest.py index fe526d8ec87..8a6fa7609c1 100644 --- a/src/sage/tests/books/computational-mathematics-with-sagemath/graphtheory_doctest.py +++ b/src/sage/tests/books/computational-mathematics-with-sagemath/graphtheory_doctest.py @@ -219,12 +219,12 @@ sage: # Number of colors used sage: max(color.values()) + 1 - 6 + 5 Sage example in ./graphtheory.tex, line 1635:: sage: P = Permutations([0,1,2,3]); P.random_element() - [2, 0, 1, 3] + [3, 2, 1, 0] Sage example in ./graphtheory.tex, line 1646:: @@ -257,7 +257,7 @@ Sage example in ./graphtheory.tex, line 1697:: sage: best_chromatic_number # Number of colors used - 4 + 5 Sage example in ./graphtheory.tex, line 1718:: @@ -283,7 +283,7 @@ sage: n_colors, coloration = min([greedy_coloring(g, P.random_element()) ....: for i in range(50)], key=lambda c: c[0]) sage: n_colors - 4 + 5 Sage example in ./graphtheory.tex, line 1782:: @@ -342,14 +342,14 @@ Sage example in ./graphtheory.tex, line 2012:: - sage: set_random_seed(3) + sage: set_random_seed(4) Sage example in ./graphtheory.tex, line 2021:: sage: H = graphs.PetersenGraph() sage: G = graphs.RandomGNP(500,0.5) sage: find_induced(H,G) - {0: 0, 1: 4, 2: 3, 3: 7, 4: 35, 5: 10, 6: 67, 7: 108, 8: 240, 9: 39} + {0: 0, 1: 1, 2: 3, 3: 13, 4: 7, 5: 62, 6: 24, 7: 232, 8: 67, 9: 45} Sage example in ./graphtheory.tex, line 2070:: From d36adf4084c117fbb3da87232c74ba6b155d0307 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Tue, 5 Apr 2022 18:11:48 +0000 Subject: [PATCH 084/529] Fix import of sage.all in tests --- src/conftest.py | 8 ++++---- src/test_doctest.py | 2 -- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/conftest.py b/src/conftest.py index 13b9ff568d9..c80e06b2f23 100644 --- a/src/conftest.py +++ b/src/conftest.py @@ -22,6 +22,7 @@ get_optionflags, ) from _pytest.pathlib import import_path +import inspect import sage.all # type: ignore # to avoid cyclic import errors, see Trac #33580 from sage.doctest.parsing import SageDocTestParser @@ -113,7 +114,7 @@ def _find( ) -import sage.all # type: ignore # to avoid cyclic import errors, see Trac #33580 +from sage.all import * # type: ignore # to avoid cyclic import errors, see Trac #33580, and is implicitly used below by calling globals() @pytest.fixture(autouse=True) @@ -123,6 +124,5 @@ def add_imports(doctest_namespace: dict[str, Any]): See `pytest documentation `. """ - import sage.all # type: ignore # implicitly used below by calling locals() - - doctest_namespace.update(**locals()) + # Inject sage.all into each doctest + doctest_namespace.update(**globals()) diff --git a/src/test_doctest.py b/src/test_doctest.py index b0e12f1998e..d3f5d5cdfb2 100644 --- a/src/test_doctest.py +++ b/src/test_doctest.py @@ -1,5 +1,3 @@ -from sage.all import Integer - def something(): """ a doctest in a docstring From 813a5416f05702eecfe5fd1b54f3ae379ca1981a Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Tue, 5 Apr 2022 18:12:03 +0000 Subject: [PATCH 085/529] Add vs code config to debug pytest --- .vscode/launch.json | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index fcf2e9c45d8..677f3a243cd 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,6 +1,17 @@ { "version": "0.2.0", "configurations": [ + { + "name": "Sage: Pytest", + "type": "python", + "request": "launch", + "module": "pytest", + "args": [ + "${file}" + ], + "console": "integratedTerminal", + "justMyCode": false + }, { "name": "Python: Current File", "type": "python", @@ -10,4 +21,4 @@ "justMyCode": false } ], -} +} \ No newline at end of file From d3fdd951e5c37ebdac17f8d1fbc86ed8f36dff7e Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Tue, 5 Apr 2022 19:08:36 +0000 Subject: [PATCH 086/529] Cleanup vscode config --- .vscode/settings.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 9cdc0e3b980..562b8dc479b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -14,10 +14,8 @@ "pkgs/sagemath-objects/sage": true, "pkgs/sagemath-standard/sage": true, }, - "python.testing.pytestPath": "./sage -t", "python.testing.pytestEnabled": true, "python.testing.pytestArgs": [ - "src/test_doctests.py", "--rootdir=src/sage", "-c=src/tox.ini", "--doctest-modules", From 58e11d707764c4e7c85bf1c5beb8bf257c0318d8 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Tue, 5 Apr 2022 19:09:14 +0000 Subject: [PATCH 087/529] Fix checker and namespace injection --- src/conftest.py | 28 ++++++++++++++++++---------- src/tox.ini | 1 + 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/conftest.py b/src/conftest.py index c80e06b2f23..913c53ae91f 100644 --- a/src/conftest.py +++ b/src/conftest.py @@ -14,7 +14,6 @@ from _pytest.doctest import ( DoctestItem, DoctestModule, - _get_checker, _get_continue_on_failure, _get_runner, _is_mocked, @@ -24,9 +23,11 @@ from _pytest.pathlib import import_path import inspect -import sage.all # type: ignore # to avoid cyclic import errors, see Trac #33580 -from sage.doctest.parsing import SageDocTestParser - +# Import sage.all is necessary to: +# - avoid cyclic import errors, see Trac #33580 +# - inject it into globals namespace for doctests +import sage.all +from sage.doctest.parsing import SageDocTestParser, SageOutputChecker def pytest_collect_file(file_path, parent): if file_path.suffix == ".py": @@ -37,7 +38,8 @@ class SageDoctestModule(DoctestModule): """ This is essentially a copy of `DoctestModule` from https://github.com/pytest-dev/pytest/blob/main/src/_pytest/doctest.py. - The only change is that we use `SageDocTestParser` to extract the doctests. + The only change is that we use `SageDocTestParser` to extract the doctests + and `SageOutputChecker` to verify the output. """ def collect(self) -> Iterable[DoctestItem]: @@ -103,7 +105,7 @@ def _find( runner = _get_runner( verbose=False, optionflags=optionflags, - checker=_get_checker(), + checker=SageOutputChecker(), continue_on_failure=_get_continue_on_failure(self.config), ) @@ -114,9 +116,6 @@ def _find( ) -from sage.all import * # type: ignore # to avoid cyclic import errors, see Trac #33580, and is implicitly used below by calling globals() - - @pytest.fixture(autouse=True) def add_imports(doctest_namespace: dict[str, Any]): """ @@ -125,4 +124,13 @@ def add_imports(doctest_namespace: dict[str, Any]): See `pytest documentation `. """ # Inject sage.all into each doctest - doctest_namespace.update(**globals()) + dict_all = sage.all.__dict__ + + # Remove '__package__' item from the globals since it is not + # always in the globals in an actual Sage session. + dict_all.pop('__package__', None) + + sage_namespace = dict(dict_all) + sage_namespace['__name__'] = '__main__' + + doctest_namespace.update(**sage_namespace) diff --git a/src/tox.ini b/src/tox.ini index 43d50ae7b9d..fa8e5b76024 100644 --- a/src/tox.ini +++ b/src/tox.ini @@ -158,6 +158,7 @@ commands = codespell \ python_files = *_test.py norecursedirs = local prefix venv build pkgs .git src/sage/pkgs src/doc src/bin src/sage/src/sage_setup addopts = --import-mode importlib +doctest_optionflags = NORMALIZE_WHITESPACE ELLIPSIS [coverage:run] source = sage From 097c034ada7ce77afedb20da5705e50f5d3a0737 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Wed, 6 Apr 2022 10:24:30 +0900 Subject: [PATCH 088/529] Minor edits --- src/sage/docs/conf.py | 2 -- src/sage/misc/latex_macros.py | 13 ++++++------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/sage/docs/conf.py b/src/sage/docs/conf.py index aeb7ef7ee45..e9730488d12 100644 --- a/src/sage/docs/conf.py +++ b/src/sage/docs/conf.py @@ -25,8 +25,6 @@ 'sage_docbuild.ext.sage_autodoc', 'sphinx.ext.todo', 'sphinx.ext.extlinks', - # Mathjax integration - # https://www.sphinx-doc.org/en/master/usage/extensions/math.html#module-sphinx.ext.mathjax 'sphinx.ext.mathjax', 'IPython.sphinxext.ipython_directive', 'matplotlib.sphinxext.plot_directive', diff --git a/src/sage/misc/latex_macros.py b/src/sage/misc/latex_macros.py index 729a7ba49f0..22d1f2efe30 100644 --- a/src/sage/misc/latex_macros.py +++ b/src/sage/misc/latex_macros.py @@ -50,8 +50,9 @@ def produce_latex_macro(name, *sample_args): INPUT: - - ``name`` - name of macro to be defined, also name of corresponding Sage object - - ``sample_args`` - (optional) sample arguments for this Sage object + - ``name`` -- name of macro to be defined, also name of corresponding Sage object + + - ``sample_args`` -- (optional) sample arguments for this Sage object EXAMPLES:: @@ -109,7 +110,7 @@ def convert_latex_macro_to_mathjax(macro): INPUT: - - ``macro`` - LaTeX macro definition + - ``macro`` -- LaTeX macro definition See the web page https://docs.mathjax.org/en/latest/input/tex/macros.html for a @@ -197,7 +198,7 @@ def sage_latex_macros(): def sage_mathjax_macros(): r""" Return Sage's macro definitions for usage with MathJax. - + This feeds each item output by :func:`sage_latex_macros` to :func:`convert_latex_macro_to_mathjax`. @@ -207,6 +208,4 @@ def sage_mathjax_macros(): sage: sage_mathjax_macros() {'Bold': ['\\mathbf{#1}', 1], 'CC': '\\Bold{C}', ... """ - return dict( - [convert_latex_macro_to_mathjax(m) for m in sage_latex_macros()] - ) + return dict(convert_latex_macro_to_mathjax(m) for m in sage_latex_macros()) From 9b7399db2912fb538afb595483ba0114f7dc0f4a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 6 Apr 2022 19:45:53 -0700 Subject: [PATCH 089/529] src/doc/en/installation/launching.rst (system jupyter): Never use plain 'sagemath' as the kernel name --- src/doc/en/installation/launching.rst | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/doc/en/installation/launching.rst b/src/doc/en/installation/launching.rst index 56b61e12660..ebc6f864178 100644 --- a/src/doc/en/installation/launching.rst +++ b/src/doc/en/installation/launching.rst @@ -133,21 +133,21 @@ Assuming that SageMath can be invoked by typing ``sage``, you can use to find the location of the SageMath kernel description. -Assuming that the Jupyter notebook can be started by typing ``jupyter notebook``, -the following command will install SageMath as a new kernel. +Now pick a name for the kernel that identifies it clearly and uniquely. -.. CODE-BLOCK:: bash - - jupyter kernelspec install --user $(sage -sh -c 'ls -d $SAGE_VENV/share/jupyter/kernels/sagemath') +For example, if you install Sage from source tarballs, you could decide +include the version number in the name, such as ``sagemath-9.6``. +If you build Sage from a clone of the git repository, it is better to +choose a name that identifies the directory, perhaps ``sagemath-dev`` +or ``sagemath-teaching`` because the version will change. -This installs the kernel under the name ``sagemath``. If you wish to -rename it to something more specific in order to distinguish between -different installations of SageMath, you can use the additional option -``--name``, for example +Now assuming that the Jupyter notebook can be started by typing +``jupyter notebook``, the following command will install SageMath as a +new kernel. .. CODE-BLOCK:: bash - jupyter kernelspec install --user $(sage -sh -c 'ls -d $SAGE_VENV/share/jupyter/kernels/sagemath') --name sagemath-dev-worktree + jupyter kernelspec install --user $(sage -sh -c 'ls -d $SAGE_VENV/share/jupyter/kernels/sagemath') --name sagemath-dev The ``jupyter kernelspec`` approach by default does lead to about 2Gb of SageMath documentation being copied into your personal jupyter configuration @@ -163,7 +163,7 @@ A command along the lines of .. CODE-BLOCK:: bash - ln -s $(sage -sh -c 'ls -d $SAGE_VENV/share/jupyter/kernels/sagemath') $HOME/.local/share/jupyter + ln -s $(sage -sh -c 'ls -d $SAGE_VENV/share/jupyter/kernels/sagemath') $HOME/.local/share/jupyter/sagemath-dev can then be used to create a symlink to the SageMath kernel description in a location where your own ``jupyter`` can find it. @@ -172,7 +172,7 @@ If you have installed SageMath from source, the alternative command .. CODE-BLOCK:: bash - ln -s $(sage -sh -c 'ls -d $SAGE_ROOT/venv/share/jupyter/kernels/sagemath') $HOME/.local/share/jupyter + ln -s $(sage -sh -c 'ls -d $SAGE_ROOT/venv/share/jupyter/kernels/sagemath') $HOME/.local/share/jupyter/sagemath-dev creates a symlink that will stay current even if you switch to a different Python version later. From b4e789569eb7178dde7c7d87bae7740d44818d0d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 6 Apr 2022 20:26:13 -0700 Subject: [PATCH 090/529] src/bin/sage-notebook, src/sage/repl/ipython_kernel/install.py: Check that the SageMath kernel can be discovered --- src/bin/sage-notebook | 5 ++++- src/sage/repl/ipython_kernel/install.py | 30 +++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/bin/sage-notebook b/src/bin/sage-notebook index 4dd1998aabc..d0ee270c72d 100755 --- a/src/bin/sage-notebook +++ b/src/bin/sage-notebook @@ -1,5 +1,5 @@ #!/usr/bin/env sage-python -# -*- coding: utf-8 -*- +# -*- coding: utf-8; mode: python -*- import os import sys @@ -261,6 +261,9 @@ if __name__ == '__main__': 'to Jupyter') sys.exit(1) + from sage.repl.ipython_kernel.install import SageKernelSpec + SageKernelSpec.check() + try: launcher = notebook_launcher[args.notebook] except KeyError: diff --git a/src/sage/repl/ipython_kernel/install.py b/src/sage/repl/ipython_kernel/install.py index ab336e8a7e5..76d73c3f94d 100644 --- a/src/sage/repl/ipython_kernel/install.py +++ b/src/sage/repl/ipython_kernel/install.py @@ -16,6 +16,7 @@ import os import errno +import warnings from sage.env import ( SAGE_DOC, SAGE_VENV, SAGE_EXTCODE, @@ -242,6 +243,35 @@ def update(cls, *args, **kwds): instance._install_spec() instance._symlink_resources() + @classmethod + def check(cls): + """ + Check that the SageMath kernel can be discovered by its name (sagemath). + + This method issues a warning if it cannot -- either because it is not installed, + or it is shadowed by a different kernel of this name, or Jupyter is + misconfigured in a different way. + + EXAMPLES:: + + sage: from sage.repl.ipython_kernel.install import SageKernelSpec + sage: SageKernelSpec.check() # random + """ + from jupyter_client.kernelspec import get_kernel_spec, NoSuchKernel + ident = cls.identifier() + try: + spec = get_kernel_spec(ident) + except NoSuchKernel: + warnings.warn(f'no kernel named {ident} is accessible; ' + 'check your Jupyter configuration ' + '(see https://docs.jupyter.org/en/latest/use/jupyter-directories.html)') + else: + from pathlib import Path + if Path(spec.argv[0]).resolve() != Path(os.path.join(SAGE_VENV, 'bin', 'sage')).resolve(): + warnings.warn(f'the kernel named {ident} does not seem to correspond to this ' + 'installation of SageMath; check your Jupyter configuration ' + '(see https://docs.jupyter.org/en/latest/use/jupyter-directories.html)') + def have_prerequisites(debug=True): """ From 46d0d69257a0aec45e1a0b139390f56dba72ff2f Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Thu, 7 Apr 2022 13:50:19 +0900 Subject: [PATCH 091/529] Add sage package mathjax3 --- .../mathjax3/MathJax-3.2.0/CONTRIBUTING.md | 314 ++++++++++++++++++ build/pkgs/mathjax3/MathJax-3.2.0/LICENSE | 202 +++++++++++ build/pkgs/mathjax3/MathJax-3.2.0/README.md | 237 +++++++++++++ build/pkgs/mathjax3/MathJax-3.2.0/bower.json | 11 + .../pkgs/mathjax3/MathJax-3.2.0/composer.json | 14 + .../pkgs/mathjax3/MathJax-3.2.0/package.json | 59 ++++ build/pkgs/mathjax3/SPKG.rst | 32 ++ build/pkgs/mathjax3/checksums.ini | 4 + build/pkgs/mathjax3/distros/conda.txt | 1 + build/pkgs/mathjax3/distros/opensuse.txt | 1 + build/pkgs/mathjax3/distros/repology.txt | 1 + build/pkgs/mathjax3/distros/void.txt | 1 + build/pkgs/mathjax3/package-version.txt | 1 + build/pkgs/mathjax3/spkg-install.in | 4 + build/pkgs/mathjax3/spkg-src | 34 ++ build/pkgs/mathjax3/type | 1 + 16 files changed, 917 insertions(+) create mode 100644 build/pkgs/mathjax3/MathJax-3.2.0/CONTRIBUTING.md create mode 100644 build/pkgs/mathjax3/MathJax-3.2.0/LICENSE create mode 100644 build/pkgs/mathjax3/MathJax-3.2.0/README.md create mode 100644 build/pkgs/mathjax3/MathJax-3.2.0/bower.json create mode 100644 build/pkgs/mathjax3/MathJax-3.2.0/composer.json create mode 100644 build/pkgs/mathjax3/MathJax-3.2.0/package.json create mode 100644 build/pkgs/mathjax3/SPKG.rst create mode 100644 build/pkgs/mathjax3/checksums.ini create mode 100644 build/pkgs/mathjax3/distros/conda.txt create mode 100644 build/pkgs/mathjax3/distros/opensuse.txt create mode 100644 build/pkgs/mathjax3/distros/repology.txt create mode 100644 build/pkgs/mathjax3/distros/void.txt create mode 100644 build/pkgs/mathjax3/package-version.txt create mode 100644 build/pkgs/mathjax3/spkg-install.in create mode 100755 build/pkgs/mathjax3/spkg-src create mode 100644 build/pkgs/mathjax3/type diff --git a/build/pkgs/mathjax3/MathJax-3.2.0/CONTRIBUTING.md b/build/pkgs/mathjax3/MathJax-3.2.0/CONTRIBUTING.md new file mode 100644 index 00000000000..7153d85d6b6 --- /dev/null +++ b/build/pkgs/mathjax3/MathJax-3.2.0/CONTRIBUTING.md @@ -0,0 +1,314 @@ +# Contributing to MathJax + +You are interested in giving us a hand? That's awesome! We've put +together some brief guidelines that should help you get started +quickly and easily. + +There are lots and lots of ways to get involved, this document covers: + +* [reporting an issue](#reporting-an-issue) + * [bug reports](#bug-reports) + * [feature requests](#feature-requests) + * [change requests](#change-requests) +* [working on MathJax core](#working-on-mathjax-core) + * [key branches and tags](#key-branches--tags) + * [submitting pull requests](#submitting-pull-requests) + * [testing and quality assurance](#testing-and-quality-assurance) + * [writing documentation](#writing-documentation) + * [translation](#translation) +* [Conduct](#conduct) + + +## Reporting An Issue + +If you're about to raise an issue because you think you've found a +problem with MathJax, or you'd like to make a request for a new +feature in the codebase, or any other reason, please read this first. + +The [MathJax issue +tracker](https://github.com/mathjax/MathJax/issues) is the +preferred channel for [bug reports](#bug-reports), [feature +requests](#feature-requests), [change requests](#change-requests), and +[submitting pull requests](#submitting-pull-requests), but please +respect the following restrictions: + +* Please **search for existing issues**. Help us keep duplicate issues + to a minimum by checking to see if someone has already reported your + problem or requested your idea. + +* Please **do not** use the issue tracker for personal support + requests (use [the MathJax User Group](https://groups.google.com/forum/#!forum/mathjax-users)). + +* Please **be civil**. Keep the discussion on topic and respect the + opinions of others. See also our [Conduct Guidelines](#conduct) + +### Bug Reports + +A bug is a *demonstrable problem* that is caused by the code in the +repository. Good bug reports are extremely helpful — thank you! + +Guidelines for bug reports: + +1. **Use the GitHub issue search** — check if the issue has already been + reported. + +2. **Check if the issue has been fixed** — look for [closed + issues in the current + milestone](https://github.com/mathjax/MathJax/issues?q=is%3Aclosed) + or try to reproduce it using the latest `develop` branch. Please + note that you will need to + [compile MathJax and make the components](https://docs.mathjax.org/en/latest/web/hosting.html#getting-mathjax-via-git) + in order to test MathJax from the source repository. + +3. **Share a live sample of the problem** — without a live page + it is usually impossible to debug problems; see also the [Bug Report + Template](#template) below. + +4. **Isolate the problem** — a live sample is a starting point + but if you want to speed things up, create a [reduced test + case](http://css-tricks.com/6263-reduced-test-cases/). Be specific + about your setup (browser, OS versions, etc). Use services like + [jsbin](http://jsbin.com), [CodePen](http://codepen.io), or + [jsFiddle](http://jsfiddle.com) to make collaboration on minimal + test cases easier for everyone. + +5. **Include a screenshot/cast as a last resort** — Is your + issue about a layout or design feature or bug that is hard to reproduce + or isolate? Then please provide a screenshot or screencast. Tools + like [LICEcap](http://www.cockos.com/licecap/) or + [SauceLabs](http://www.saucelabs.com) allow you to quickly and + easily record a screencasts. If you make it an animated gif, you can + embed it directly into your GitHub issue. + +6. Use the [Bug Report Template](#template) below or [click this + link](https://github.com/MathJax/MathJax/issues/new?title=Bug%3A&body=%23%23%23%20Issue%20Summary%0A%0A%23%23%23%20Steps%20to%20Reproduce%0A%0A1.%20This%20is%20the%20first%20step%0A%0AThis%20is%20a%20bug%20because...%0A%0A%23%23%23%20Technical%20details%0A%0A*%20MathJax%20Version%3A%20master%20-%20latest%20commit%3A%20%20INSERT%20COMMIT%20REF%0A*%20Client%20OS%3A%20%0A*%20Browser%3A%20%0A*%20) + to start creating a bug report with the template automatically. + +A good bug report shouldn't leave others needing to request +more information from you. Be sure to include the details of your environment. + + + +Template Example ([click to use](https://github.com/MathJax/MathJax/issues/new?title=Bug%3A&body=%23%23%23%20Issue%20Summary%0A%0A%23%23%23%20Steps%20to%20Reproduce%0A%0A1.%20This%20is%20the%20first%20step%0A%0AThis%20is%20a%20bug%20because...%0A%0A%23%23%23%20Technical%20details%0A%0A*%20MathJax%20Version%3A%20master%20-%20latest%20commit%3A%20%20INSERT%20COMMIT%20REF%0A*%20Client%20OS%3A%20%0A*%20Browser%3A%20%0A*%20)): + +``` +Short and descriptive example bug report title + +### Issue Summary + +A summary of the issue and the browser/OS environment in which it occurs. If +suitable, include the steps required to reproduce the bug. + +### Steps to Reproduce + +1. This is the first step +2. This is the second step +3. Further steps, etc. + +Any other information you want to share that is relevant to the issue +being reported. Especially, why do you consider this to be a bug? What +do you expect to happen instead? + +### Technical details: + +* MathJax Version: 2.3 (latest commit: f3aaf3a2a3e964df2770dc4aaaa9c87ce5f47e2c) +* Client OS: Mac OS X 10.8.4 +* Browser: Chrome 29.0.1547.57 +``` + + +### Feature Requests + +Feature requests are welcome. Before you submit one, be sure to have: + +1. **Used the GitHub search** to check that the feature hasn't already + been requested. +2. Take a moment to think about whether your idea fits with the scope + and aims of the project, or if it might better fit being a [custom + extension](https://github.com/mathjax/MathJax-third-party-extensions). +3. Remember, it's up to *you* to make a strong case to convince the + project's leaders of the merits of this feature. Please provide as + much detail and context as possible, this means explaining the use + case and why it is likely to be common. + +### Change Requests + +Change requests cover both architectural and functional changes to how +MathJax works. If you have an idea for a new or different dependency, +a refactor, or an improvement to a feature, etc., please be sure to: + +1. **Use the GitHub search** to check that someone else didn't get there first. +2. Take a moment to think about the best way to make a case for, and + explain what you're thinking. Are you sure this shouldn't really be + a [bug report](#bug-reports) or a [feature + request](#feature-requests)? Is it really one idea or is it many? + What's the context? What problem are you solving? Why is what you + are suggesting better than what's already there? + +## Working on MathJax core + +You want to contribute code? We describe how below. First, note that +the MathJax source code is in the + repository, not the + repository, which contains the +packaged component files for distribution on CDNs and the [mathjax npm +package](https://www.npmjs.com/package/mathjax) (the source code is +included in the [mathjax-full npm +package](https://www.npmjs.com/package/mathjax-full)). + +### Key Branches & Tags + +MathJax uses several permanent branches in the [MathJax source repository](https://github.com/mathjax/MathJax-src): + +- **[develop](https://github.com/mathjax/MathJax-src/tree/develop)** + is the development branch. All work on the next release happens here + so you should generally branch off `develop` if you are going to + submit a pull request. Do **NOT** use this branch for a production + site. + +- **[master](https://github.com/mathjax/MathJax-src)** contains the latest + release of MathJax. This branch may be used in production. Do + **NOT** use this branch to work on MathJax's source. + +These branches reflect version 3 of MathJax, which is substantially +different from the version 2 codebase. Version 2 will continue to be +maintained while web sites transition to version 3, with work being +done using the following branches in the [MathJax distribution +repository](https://github.com/mathjax/MathJax): + +- **[legacy-v2-develop](https://github.com/mathjax/MathJax/tree/legacy-v2-develop)** + is the development branch for changes to the legacy version 2 code. + Any pull requests for version 2 should be branched from here. Do + **NOT** use this branch for a production site. + +- **[legacy-v2](https://github.com/mathjax/MathJax/tree/legacy-v2)** + is the branch that contains any updates to version 2 following + the release of version 3. Do **NOT** use this branch to work on + MathJax's source. + +In addition to these branches, MathJax uses tags to identify the +various versions. These can be checked out to obtain the specified +release; for example, `git checkout 2.7.5` would get you the files for +version 2.7.5 of MathJax. + +Note that version 3 is written in Typescript, and so must be compiled +to obtain usable javascript files, and that the components need to be +built once that is done. See the +[documentation](https://docs.mathjax.org/en/latest/web/hosting.html#getting-mathjax-via-git) +for details. For version 2, the source javascript files are not +compressed until a release is made, so you should use the copies in +the `unpacked` directory during development. + + +### Submitting Pull Requests + +Pull requests are welcome. If you're looking to submit a PR for +something that doesn't have an open issue, please consider [raising an +issue](#reporting-an-issue) that your PR can close, especially if +you're fixing a bug. This makes it more likely that there will be +enough information available for your PR to be properly tested and +merged. + +##### Need Help? + +If you're not completely clear on how to submit/update/*do* Pull +Requests, please check out our [source control +policies](https://github.com/mathjax/MathJax/wiki/Source-control-policies). For +more insights, check the excellent in depth [Git Workflow +guide](https://github.com/TryGhost/Ghost/wiki/Git-Workflow) from +Ghost, in particular + +* [Ghost Workflow guide: commit messages](https://github.com/TryGhost/Ghost/wiki/Git-workflow#commit-messages) + +### Testing and Quality Assurance + +If you're +looking to get involved with the code base and don't know where to +start, checking out and testing a pull request is one of the most +useful things you could do. + +These are some [excellent +instructions](https://gist.github.com/piscisaureus/3342247) on +configuring your GitHub repository to allow you to checkout pull +requests in the same way as branches. + + +### Writing documentation + +MathJax's main documentation can be found at [docs.mathjax.org](http://docs.mathjax.org). +The source of the docs is hosted in the +[mathjax/MathJax-docs](http://github.com/mathjax/MathJax-docs) repo here on GitHub. + +The documentation is generated using +[Sphinx-doc](http://sphinx-doc.org/) and hosted on [Read the +docs](http://readthedocs.org). You can clone the repo and submit pull +requests following the [pull-request](#submitting-pull-requests) +guidelines. + + +### Translation + +If you wish to add or update translations of MathJax, please do it on +[TranslateWiki.net](https://translatewiki.net/w/i.php?title=Special:Translate&group=out-mathjax-0-all) +(and while you're there you can help other open source projects, +too). + +For bug reports and other questions that don't fit on +TranslateWiki.net, head over to the +[mathjax/mathjax-i18n](https://github.com/mathjax/MathJax-i18n) +repository. + +The translation files currently are for version 2, as localization +hasn't been added to version 3 yet. + +## Conduct + +As a NumFOCUS fiscally sponsored project, MathJax is governed by the +[NumFOCUS code of conduct](https://numfocus.org/code-of-conduct), +which we summarize as follows: + +We are committed to providing a friendly, safe and welcoming +environment for all, regardless of gender, sexual orientation, +disability, ethnicity, religion, or similar personal characteristic. + +Please be kind and courteous. There's no need to be mean or rude. +Respect that people have differences of opinion and that every design +or implementation choice carries a trade-off and numerous costs. There +is seldom a right answer, merely an optimal answer given a set of +values and circumstances. + +Please keep unstructured critique to a minimum. If you have solid +ideas you want to experiment with, make a fork and see how it works. + +We will exclude you from interaction if you insult, demean or harass +anyone. That is not welcome behaviour. We interpret the term +"harassment" as including the definition in the [Unacceptable +Behavior](https://numfocus.org/code-of-conduct#unacceptable-behavior) +section of the [NumFOCUS code of +conduct](https://numfocus.org/code-of-conduct); if you have any lack +of clarity about what might be included in that concept, please read +that definition. In particular, we don't tolerate behavior that +excludes people in socially marginalized groups. + +Private harassment is also unacceptable. No matter who you are, if you +feel you have been or are being harassed or made uncomfortable by a +community member, please contact one of the channel ops or any of the +[MathJax](https://github.com/MathJax/MathJax) core team +immediately. Whether you're a regular contributor or a newcomer, we +care about making this community a safe place for you and we've got +your back. + +Likewise any spamming, trolling, flaming, baiting, or other +attention-stealing behaviour is not welcome. + +We also recommend that you read [discourse's +rules](http://blog.discourse.org/2013/03/the-universal-rules-of-civilized-discourse/) +for further suggestions on appropriate behavior. + +## References + +* We heavily borrowed from Mozilla and Ghost -- thank you! + * + * +* +* diff --git a/build/pkgs/mathjax3/MathJax-3.2.0/LICENSE b/build/pkgs/mathjax3/MathJax-3.2.0/LICENSE new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/build/pkgs/mathjax3/MathJax-3.2.0/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/build/pkgs/mathjax3/MathJax-3.2.0/README.md b/build/pkgs/mathjax3/MathJax-3.2.0/README.md new file mode 100644 index 00000000000..94186007ac0 --- /dev/null +++ b/build/pkgs/mathjax3/MathJax-3.2.0/README.md @@ -0,0 +1,237 @@ +# MathJax +## Beautiful math in all browsers + +![GitHub release version](https://img.shields.io/github/v/release/mathjax/MathJax-src.svg?sort=semver) +![GitHub release version (v2)](https://img.shields.io/github/package-json/v/mathjax/MathJax/legacy-v2.svg?label=release-v2) +![NPM version](https://img.shields.io/npm/v/mathjax.svg?style=flat) +![powered by NumFOCUS](https://img.shields.io/badge/powered%20by-NumFOCUS-orange.svg?style=flat) +![jsdelivr rank](https://flat.badgen.net/jsdelivr/rank/npm/mathjax?color=green) +![jsDelivr hits (npm)](https://img.shields.io/jsdelivr/npm/hm/mathjax) +![npm monthly downloads (full)](https://img.shields.io/npm/dm/mathjax?label=npm) +![npm total downloads](https://img.shields.io/npm/dt/mathjax.svg?style=flat&label=npm%20total) + +MathJax is an open-source JavaScript display engine for LaTeX, MathML, +and AsciiMath notation that works in all modern browsers. It was +designed with the goal of consolidating the recent advances in web +technologies into a single, definitive, math-on-the-web platform +supporting the major browsers and operating systems. It requires no +setup on the part of the user (no plugins to download or software to +install), so the page author can write web documents that include +mathematics and be confident that users will be able to view it +naturally and easily. Simply include MathJax and some mathematics in +a web page, and MathJax does the rest. + +Some of the main features of MathJax include: + +- High-quality display of LaTeX, MathML, and AsciiMath notation in HTML pages + +- Supported in most browsers with no plug-ins, extra fonts, or special + setup for the reader + +- Easy for authors, flexible for publishers, extensible for developers + +- Supports math accessibility, cut-and-paste interoperability, and other + advanced functionality + +- Powerful API for integration with other web applications + +See for additional details about MathJax, +and for the MathJax documentation. + +## MathJax Components + +MathJax version 3 uses files called *components* that contain the +various MathJax modules that you can include in your web pages or +access on a server through NodeJS. Some components combine all the +pieces you need to run MathJax with one or more input formats and a +particular output format, while other components are pieces that can +be loaded on demand when needed, or by a configuration that specifies +the pieces you want to combine in a custom way. For usage +instructions, see the [MathJax documentation](https://docs.mathjax.org). + +Components provide a convenient packaging of MathJax's modules, but it +is possible for you to form your own custom components, or to use +MathJax's modules directly in a node application on a server. There +are [web examples](https://github.com/mathjax/MathJax-demos-web) +showing how to use MathJax in web pages and how to build your own +components, and [node +examples](https://github.com/mathjax/MathJax-demos-node) illustrating +how to use components in node applications or call MathJax modules +directly. + +## What's in this Repository + +This repository contains only the component files for MathJax, not the +source code for MathJax (which are available in a separate [MathJax +source repository](https://github.com/mathjax/MathJax-src/)). These +component files are the ones served by the CDNs that offer MathJax to +the web. In version 2, the files used on the web were also the source +files for MathJax, but in version 3, the source files are no longer on +the CDN, as they are not what are run in the browser. + +The components are stored in the `es5` directory, and are in ES5 format +for the widest possible compatibility. In the future, we may make an +`es6` directory containing ES6 versions of the components. + +## Installation and Use + +### Using MathJax components from a CDN on the web + +If you are loading MathJax from a CDN into a web page, there is no +need to install anything. Simply use a `script` tag that loads +MathJax from the CDN. E.g., + +``` html + +``` + +See the [MathJax +documentation](https://docs.mathjax.org/en/latest/index.html#browser-components), +the [MathJax Web Demos](https://github.com/mathjax/MathJax-demos-web), +and the [MathJax Component +Repository](https://github.com/mathjax/MathJax-demos-web) for more information. + +### Hosting your own copy of the MathJax Components + +If you want to host MathJax from your own server, you can do so by +installing the `mathjax` package using `npm` and moving the `es5` +directory to an appropriate location on your server: + +``` bash +npm install mathjax@3 +mv node_modules/mathjax/es5 /mathjax +``` + +Note that we are still making updates to version 2, so include `@3` +when you install, since the latest chronological version may not be +version 3. + +Alternatively, you can get the files via GitHub: + +``` bash +git clone https://github.com/mathjax/MathJax.git mj-tmp +mv mj-tmp/es5 /mathjax +rm -rf mj-tmp +``` + +Then (in either case) you can use a script tag like the following: + +``` html + +``` + +where `` is replaced by the URL to the location +where you moved the MathJax files above. + +See the +[documentation](https://docs.mathjax.org/en/latest/web/hosting.html) +for details. + +### Using MathJax components in a node application + +To use MathJax components in a node application, install the `mathjax` package: + +``` bash +npm install mathjax@3 +``` + +(we are still making updates to version 2, so you should include `@3` +since the latest chronological version may not be version 3). + +Then require `mathjax` within your application: + +```js +require('mathjax').init({ ... }).then((MathJax) => { ... }); +``` + +where the first `{ ... }` is a MathJax configuration, and the second +`{ ... }` is the code to run after MathJax has been loaded. E.g. + +```js +require('mathjax').init({ + loader: {load: ['input/tex', 'output/svg']} +}).then((MathJax) => { + const svg = MathJax.tex2svg('\\frac{1}{x^2-1}', {display: true}); + console.log(MathJax.startup.adaptor.outerHTML(svg)); +}).catch((err) => console.log(err.message)); +``` + +**Note:** this technique is for node-based application only, not for +browser applications. This method sets up an alternative DOM +implementation, which you don't need in the browser, and tells MathJax +to use node's `require()` command to load external modules. This +setup will not work properly in the browser, even if you webpack it or +bundle it in other ways. + +See the +[documentation](https://docs.mathjax.org/en/latest/index.html#server-nodejs) +and the [MathJax Node +Repository](https://github.com/mathjax/MathJax-demos-node) for more details. + +## Reducing the Size of the Components Directory + +Since the `es5` directory contains *all* the component files, so if +you are only planning one use one configuration, you can reduce the +size of the MathJax directory by removing unused components. For +example, if you are using the `tex-chtml.js` component, then you can +remove the `tex-mml-chtml.js`, `tex-svg.js`, `tex-mml-svg.js`, +`tex-chtml-full.js`, and `tex-svg-full.js` configurations, which will +save considerable space. Indeed, you should be able to remove +everything other than `tex-chtml.js`, and the `input/tex/extensions`, +`output/chtml/fonts/woff-v2`, `adaptors`, `a11y`, and `sre` +directories. If you are using the results only on the web, you can +remove `adaptors` as well. + +If you are not using A11Y support (e.g., speech generation, or +semantic enrichment), then you can remove `a11y` and `sre` as well +(though in this case you may need to disable the assistive tools in +the MathJax contextual menu in order to avoid MathJax trying to load +them when they aren't there). + +If you are using SVG rather than CommonHTML output (e.g., `tex-svg.js` +rather than `tex-chtml.js`), you can remove the +`output/chtml/fonts/woff-v2` directory. If you are using MathML input +rather than TeX (e.g., `mml-chtml.js` rather than `tex-chtml.js`), +then you can remove `input/tex/extensions` as well. + + +## The Component Files and Pull Requests + +The `es5` directory is generated automatically from the contents of the +MathJax source repository. You can rebuild the components using the +command + +``` bash +npm run make-es5 --silent +``` + +Note that since the contents of this repository are generated +automatically, you should not submit pull requests that modify the +contents of the `es5` directory. If you wish to submit a modification +to MathJax, you should make a pull request in the [MathJax source +repository](https://github.com/mathjax/MathJax-src). + +## MathJax Community + +The main MathJax website is , and it includes +announcements and other important information. A [MathJax user +forum](http://groups.google.com/group/mathjax-users) for asking +questions and getting assistance is hosted at Google, and the [MathJax +bug tracker](https://github.com/mathjax/MathJax/issues) is hosted +at GitHub. + +Before reporting a bug, please check that it has not already been +reported. Also, please use the bug tracker (rather than the help +forum) for reporting bugs, and use the user's forum (rather than the +bug tracker) for questions about how to use MathJax. + +## MathJax Resources + +* [MathJax Documentation](https://docs.mathjax.org) +* [MathJax Components](https://github.com/mathjax/MathJax) +* [MathJax Source Code](https://github.com/mathjax/MathJax-src) +* [MathJax Web Examples](https://github.com/mathjax/MathJax-demos-web) +* [MathJax Node Examples](https://github.com/mathjax/MathJax-demos-node) +* [MathJax Bug Tracker](https://github.com/mathjax/MathJax/issues) +* [MathJax Users' Group](http://groups.google.com/group/mathjax-users) + diff --git a/build/pkgs/mathjax3/MathJax-3.2.0/bower.json b/build/pkgs/mathjax3/MathJax-3.2.0/bower.json new file mode 100644 index 00000000000..6b214b933ea --- /dev/null +++ b/build/pkgs/mathjax3/MathJax-3.2.0/bower.json @@ -0,0 +1,11 @@ +{ + "name": "MathJax", + "main": "./MathJax.js", + "homepage": "http://www.mathjax.org/", + "ignore": [ + "**/.*", + "node_modules", + "components" + ], + "keywords": ["math", "js", "LaTeX", "MathML", "AsciiMath"] +} diff --git a/build/pkgs/mathjax3/MathJax-3.2.0/composer.json b/build/pkgs/mathjax3/MathJax-3.2.0/composer.json new file mode 100644 index 00000000000..b1b9d27aed6 --- /dev/null +++ b/build/pkgs/mathjax3/MathJax-3.2.0/composer.json @@ -0,0 +1,14 @@ +{ + "name": "mathjax/mathjax", + "type": "library", + "description": "MathJax is an open-source JavaScript display engine for LaTeX, MathML, and AsciiMath notation that works in all modern browsers.", + "keywords": ["math", "js", "LaTeX", "MathML", "AsciiMath"], + "homepage": "http://www.mathjax.org/", + "license": "Apache-2.0", + "authors": [ + { + "name": "MathJax Consortium", + "homepage": "https://github.com/mathjax" + } + ] +} diff --git a/build/pkgs/mathjax3/MathJax-3.2.0/package.json b/build/pkgs/mathjax3/MathJax-3.2.0/package.json new file mode 100644 index 00000000000..6706949557b --- /dev/null +++ b/build/pkgs/mathjax3/MathJax-3.2.0/package.json @@ -0,0 +1,59 @@ +{ + "name": "mathjax", + "version": "3.2.0", + "description": "Beautiful and accessible math in all browsers. MathJax is an open-source JavaScript display engine for LaTeX, MathML, and AsciiMath notation that works in all browsers. This package includes the packaged components (install mathjax-full to get the source code).", + "keywords": [ + "math", + "svg", + "mathml", + "tex", + "latex", + "asciimath", + "browser", + "node" + ], + "devDependencies": { + "mathjax-full": "3.2.0" + }, + "maintainers": [ + "MathJax Consortium (http://www.mathjax.org)" + ], + "bugs": { + "url": "http://github.com/mathjax/MathJax/issues" + }, + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "git://github.com/mathjax/MathJax.git" + }, + "main": "es5/node-main.js", + "files": [ + "/es5" + ], + "scripts": { + "test": "echo 'No tests defined'", + "clean": "npm run --silent clean:es5 && npm run --silent clean:node", + "clean:es5": "rm -rf es5", + "clean:node": "rm -rf node_modules package-lock.json", + "message": "echo \"$(tput setaf 4)${npm_package_config_message}$(tput setaf 0)\" && echo", + "line": "echo '--------------------------------------------'", + "title": "npm run --silent line && npm run --silent message --mathjax:message=\"${npm_package_config_title}\"", + "preinstall:mj3": "npm run --silent title --mathjax:title='Installing MathJax...'", + "install:mj3": "npm install", + "preinstall:mj3-deps": "npm run --silent message --mathjax:message='Installing MathJax Dependencies...'", + "install:mj3-deps": "cd node_modules/mathjax-full && npm install", + "install:all": "npm run --silent install:mj3 && npm run --silent install:mj3-deps", + "precompile": "npm run --silent title --mathjax:title='Compiling MathJax...'", + "compile": "cd node_modules/mathjax-full && npm run --silent compile", + "precomponents": "npm run --silent title --mathjax:title='Building MathJax Components...'", + "components": "cd node_modules/mathjax-full && npm run --silent make-components", + "premove": "npm run --silent title --mathjax:title='Moving MathJax Components...'", + "move": "npm run --silent clean:es5 && mv node_modules/mathjax-full/es5 .", + "premake-es5": "npm run --silent clean:node", + "make-es5": "npm run --silent install:all && npm run --silent compile && npm run --silent components && npm run --silent move", + "postmake-es5": "npm run --silent title --mathjax:title='Cleaning Up...' && npm run --silent clean:node", + "preget-es5": "npm run --silent clean:node", + "get-es5": "npm run --silent install:mj3 && npm run --silent move", + "postget-es5": "npm run --silent title --mathjax:title='Cleaning Up...' && npm run --silent clean:node" + } +} diff --git a/build/pkgs/mathjax3/SPKG.rst b/build/pkgs/mathjax3/SPKG.rst new file mode 100644 index 00000000000..b957186a448 --- /dev/null +++ b/build/pkgs/mathjax3/SPKG.rst @@ -0,0 +1,32 @@ +mathjax3: A JavaScript library for displaying mathematical formulas +=================================================================== + +Description +----------- + +MathJax3 is a JavaScript library for displaying mathematical formulas. + +MathJax3 is used by the Sage documentation built by Sphinx. + +License +------- + +Apache License, version 2.0 + + +Upstream Contact +---------------- + +Home page: https://www.mathjax.org/ + +Dependencies +------------ + +None + + +Special Update/Build Instructions +--------------------------------- + +None + diff --git a/build/pkgs/mathjax3/checksums.ini b/build/pkgs/mathjax3/checksums.ini new file mode 100644 index 00000000000..4ffadfb32b1 --- /dev/null +++ b/build/pkgs/mathjax3/checksums.ini @@ -0,0 +1,4 @@ +tarball=mathjax-VERSION.tar.gz +sha1=4fec236527498c480b92032afe36d06d2741973c +md5=6eb4395cd91b71be846623d30a9bff70 +cksum=2042371852 diff --git a/build/pkgs/mathjax3/distros/conda.txt b/build/pkgs/mathjax3/distros/conda.txt new file mode 100644 index 00000000000..37aaaac759c --- /dev/null +++ b/build/pkgs/mathjax3/distros/conda.txt @@ -0,0 +1 @@ +mathjax diff --git a/build/pkgs/mathjax3/distros/opensuse.txt b/build/pkgs/mathjax3/distros/opensuse.txt new file mode 100644 index 00000000000..37aaaac759c --- /dev/null +++ b/build/pkgs/mathjax3/distros/opensuse.txt @@ -0,0 +1 @@ +mathjax diff --git a/build/pkgs/mathjax3/distros/repology.txt b/build/pkgs/mathjax3/distros/repology.txt new file mode 100644 index 00000000000..37aaaac759c --- /dev/null +++ b/build/pkgs/mathjax3/distros/repology.txt @@ -0,0 +1 @@ +mathjax diff --git a/build/pkgs/mathjax3/distros/void.txt b/build/pkgs/mathjax3/distros/void.txt new file mode 100644 index 00000000000..37aaaac759c --- /dev/null +++ b/build/pkgs/mathjax3/distros/void.txt @@ -0,0 +1 @@ +mathjax diff --git a/build/pkgs/mathjax3/package-version.txt b/build/pkgs/mathjax3/package-version.txt new file mode 100644 index 00000000000..944880fa15e --- /dev/null +++ b/build/pkgs/mathjax3/package-version.txt @@ -0,0 +1 @@ +3.2.0 diff --git a/build/pkgs/mathjax3/spkg-install.in b/build/pkgs/mathjax3/spkg-install.in new file mode 100644 index 00000000000..4429a680a53 --- /dev/null +++ b/build/pkgs/mathjax3/spkg-install.in @@ -0,0 +1,4 @@ +TARGET="${SAGE_SHARE}/mathjax3" +# Cleanup installed version +rm -rf "${TARGET}" +sdh_install src/* "${TARGET}" diff --git a/build/pkgs/mathjax3/spkg-src b/build/pkgs/mathjax3/spkg-src new file mode 100755 index 00000000000..dadb1411c6f --- /dev/null +++ b/build/pkgs/mathjax3/spkg-src @@ -0,0 +1,34 @@ +#!/usr/bin/env bash + +set -e + +[ -n "${SAGE_ROOT}" ] || SAGE_ROOT="$(pwd)/../../../" + + +# determine latest version. +GIT_VERSION="$(curl https://github.com/mathjax/MathJax/releases | grep 'MathJax v' | head -1 | sed 's|^.*MathJax v||g' | sed 's/\s*$//g')" +echo "GIT_VERSION=$GIT_VERSION" + +# fetch and rename latest version. +URL="https://github.com/mathjax/MathJax/archive/refs/tags/${GIT_VERSION}.zip" +echo "Downloading $URL" +rm -rf src +if [ -z "$UPSTREAM_SOURCE_TARBALL" ]; then + tar xzf <( curl -L "$URL" ) +else + tar xzf "$UPSTREAM_SOURCE_TARBALL" +fi + +mv MathJax-${GIT_VERSION}/es5 src + +PACKAGE_VERSION=${GIT_VERSION} + +# repack +tar czf "$SAGE_ROOT/upstream/mathjax-${PACKAGE_VERSION}.tar.gz" src +rm -rf src + +# update package info +echo "${PACKAGE_VERSION}" > 'package-version.txt' +"$SAGE_ROOT"/sage --package fix-checksum mathjax3 + + diff --git a/build/pkgs/mathjax3/type b/build/pkgs/mathjax3/type new file mode 100644 index 00000000000..a6a7b9cd726 --- /dev/null +++ b/build/pkgs/mathjax3/type @@ -0,0 +1 @@ +standard From 6da197eaba5d868ee70a71819b7ce4572a679d6d Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Thu, 7 Apr 2022 14:07:39 +0900 Subject: [PATCH 092/529] Remove garbage files --- .../mathjax3/MathJax-3.2.0/CONTRIBUTING.md | 314 ------------------ build/pkgs/mathjax3/MathJax-3.2.0/LICENSE | 202 ----------- build/pkgs/mathjax3/MathJax-3.2.0/README.md | 237 ------------- build/pkgs/mathjax3/MathJax-3.2.0/bower.json | 11 - .../pkgs/mathjax3/MathJax-3.2.0/composer.json | 14 - .../pkgs/mathjax3/MathJax-3.2.0/package.json | 59 ---- build/pkgs/mathjax3/checksums.ini | 6 +- build/pkgs/mathjax3/spkg-src | 1 + 8 files changed, 4 insertions(+), 840 deletions(-) delete mode 100644 build/pkgs/mathjax3/MathJax-3.2.0/CONTRIBUTING.md delete mode 100644 build/pkgs/mathjax3/MathJax-3.2.0/LICENSE delete mode 100644 build/pkgs/mathjax3/MathJax-3.2.0/README.md delete mode 100644 build/pkgs/mathjax3/MathJax-3.2.0/bower.json delete mode 100644 build/pkgs/mathjax3/MathJax-3.2.0/composer.json delete mode 100644 build/pkgs/mathjax3/MathJax-3.2.0/package.json diff --git a/build/pkgs/mathjax3/MathJax-3.2.0/CONTRIBUTING.md b/build/pkgs/mathjax3/MathJax-3.2.0/CONTRIBUTING.md deleted file mode 100644 index 7153d85d6b6..00000000000 --- a/build/pkgs/mathjax3/MathJax-3.2.0/CONTRIBUTING.md +++ /dev/null @@ -1,314 +0,0 @@ -# Contributing to MathJax - -You are interested in giving us a hand? That's awesome! We've put -together some brief guidelines that should help you get started -quickly and easily. - -There are lots and lots of ways to get involved, this document covers: - -* [reporting an issue](#reporting-an-issue) - * [bug reports](#bug-reports) - * [feature requests](#feature-requests) - * [change requests](#change-requests) -* [working on MathJax core](#working-on-mathjax-core) - * [key branches and tags](#key-branches--tags) - * [submitting pull requests](#submitting-pull-requests) - * [testing and quality assurance](#testing-and-quality-assurance) - * [writing documentation](#writing-documentation) - * [translation](#translation) -* [Conduct](#conduct) - - -## Reporting An Issue - -If you're about to raise an issue because you think you've found a -problem with MathJax, or you'd like to make a request for a new -feature in the codebase, or any other reason, please read this first. - -The [MathJax issue -tracker](https://github.com/mathjax/MathJax/issues) is the -preferred channel for [bug reports](#bug-reports), [feature -requests](#feature-requests), [change requests](#change-requests), and -[submitting pull requests](#submitting-pull-requests), but please -respect the following restrictions: - -* Please **search for existing issues**. Help us keep duplicate issues - to a minimum by checking to see if someone has already reported your - problem or requested your idea. - -* Please **do not** use the issue tracker for personal support - requests (use [the MathJax User Group](https://groups.google.com/forum/#!forum/mathjax-users)). - -* Please **be civil**. Keep the discussion on topic and respect the - opinions of others. See also our [Conduct Guidelines](#conduct) - -### Bug Reports - -A bug is a *demonstrable problem* that is caused by the code in the -repository. Good bug reports are extremely helpful — thank you! - -Guidelines for bug reports: - -1. **Use the GitHub issue search** — check if the issue has already been - reported. - -2. **Check if the issue has been fixed** — look for [closed - issues in the current - milestone](https://github.com/mathjax/MathJax/issues?q=is%3Aclosed) - or try to reproduce it using the latest `develop` branch. Please - note that you will need to - [compile MathJax and make the components](https://docs.mathjax.org/en/latest/web/hosting.html#getting-mathjax-via-git) - in order to test MathJax from the source repository. - -3. **Share a live sample of the problem** — without a live page - it is usually impossible to debug problems; see also the [Bug Report - Template](#template) below. - -4. **Isolate the problem** — a live sample is a starting point - but if you want to speed things up, create a [reduced test - case](http://css-tricks.com/6263-reduced-test-cases/). Be specific - about your setup (browser, OS versions, etc). Use services like - [jsbin](http://jsbin.com), [CodePen](http://codepen.io), or - [jsFiddle](http://jsfiddle.com) to make collaboration on minimal - test cases easier for everyone. - -5. **Include a screenshot/cast as a last resort** — Is your - issue about a layout or design feature or bug that is hard to reproduce - or isolate? Then please provide a screenshot or screencast. Tools - like [LICEcap](http://www.cockos.com/licecap/) or - [SauceLabs](http://www.saucelabs.com) allow you to quickly and - easily record a screencasts. If you make it an animated gif, you can - embed it directly into your GitHub issue. - -6. Use the [Bug Report Template](#template) below or [click this - link](https://github.com/MathJax/MathJax/issues/new?title=Bug%3A&body=%23%23%23%20Issue%20Summary%0A%0A%23%23%23%20Steps%20to%20Reproduce%0A%0A1.%20This%20is%20the%20first%20step%0A%0AThis%20is%20a%20bug%20because...%0A%0A%23%23%23%20Technical%20details%0A%0A*%20MathJax%20Version%3A%20master%20-%20latest%20commit%3A%20%20INSERT%20COMMIT%20REF%0A*%20Client%20OS%3A%20%0A*%20Browser%3A%20%0A*%20) - to start creating a bug report with the template automatically. - -A good bug report shouldn't leave others needing to request -more information from you. Be sure to include the details of your environment. - - - -Template Example ([click to use](https://github.com/MathJax/MathJax/issues/new?title=Bug%3A&body=%23%23%23%20Issue%20Summary%0A%0A%23%23%23%20Steps%20to%20Reproduce%0A%0A1.%20This%20is%20the%20first%20step%0A%0AThis%20is%20a%20bug%20because...%0A%0A%23%23%23%20Technical%20details%0A%0A*%20MathJax%20Version%3A%20master%20-%20latest%20commit%3A%20%20INSERT%20COMMIT%20REF%0A*%20Client%20OS%3A%20%0A*%20Browser%3A%20%0A*%20)): - -``` -Short and descriptive example bug report title - -### Issue Summary - -A summary of the issue and the browser/OS environment in which it occurs. If -suitable, include the steps required to reproduce the bug. - -### Steps to Reproduce - -1. This is the first step -2. This is the second step -3. Further steps, etc. - -Any other information you want to share that is relevant to the issue -being reported. Especially, why do you consider this to be a bug? What -do you expect to happen instead? - -### Technical details: - -* MathJax Version: 2.3 (latest commit: f3aaf3a2a3e964df2770dc4aaaa9c87ce5f47e2c) -* Client OS: Mac OS X 10.8.4 -* Browser: Chrome 29.0.1547.57 -``` - - -### Feature Requests - -Feature requests are welcome. Before you submit one, be sure to have: - -1. **Used the GitHub search** to check that the feature hasn't already - been requested. -2. Take a moment to think about whether your idea fits with the scope - and aims of the project, or if it might better fit being a [custom - extension](https://github.com/mathjax/MathJax-third-party-extensions). -3. Remember, it's up to *you* to make a strong case to convince the - project's leaders of the merits of this feature. Please provide as - much detail and context as possible, this means explaining the use - case and why it is likely to be common. - -### Change Requests - -Change requests cover both architectural and functional changes to how -MathJax works. If you have an idea for a new or different dependency, -a refactor, or an improvement to a feature, etc., please be sure to: - -1. **Use the GitHub search** to check that someone else didn't get there first. -2. Take a moment to think about the best way to make a case for, and - explain what you're thinking. Are you sure this shouldn't really be - a [bug report](#bug-reports) or a [feature - request](#feature-requests)? Is it really one idea or is it many? - What's the context? What problem are you solving? Why is what you - are suggesting better than what's already there? - -## Working on MathJax core - -You want to contribute code? We describe how below. First, note that -the MathJax source code is in the - repository, not the - repository, which contains the -packaged component files for distribution on CDNs and the [mathjax npm -package](https://www.npmjs.com/package/mathjax) (the source code is -included in the [mathjax-full npm -package](https://www.npmjs.com/package/mathjax-full)). - -### Key Branches & Tags - -MathJax uses several permanent branches in the [MathJax source repository](https://github.com/mathjax/MathJax-src): - -- **[develop](https://github.com/mathjax/MathJax-src/tree/develop)** - is the development branch. All work on the next release happens here - so you should generally branch off `develop` if you are going to - submit a pull request. Do **NOT** use this branch for a production - site. - -- **[master](https://github.com/mathjax/MathJax-src)** contains the latest - release of MathJax. This branch may be used in production. Do - **NOT** use this branch to work on MathJax's source. - -These branches reflect version 3 of MathJax, which is substantially -different from the version 2 codebase. Version 2 will continue to be -maintained while web sites transition to version 3, with work being -done using the following branches in the [MathJax distribution -repository](https://github.com/mathjax/MathJax): - -- **[legacy-v2-develop](https://github.com/mathjax/MathJax/tree/legacy-v2-develop)** - is the development branch for changes to the legacy version 2 code. - Any pull requests for version 2 should be branched from here. Do - **NOT** use this branch for a production site. - -- **[legacy-v2](https://github.com/mathjax/MathJax/tree/legacy-v2)** - is the branch that contains any updates to version 2 following - the release of version 3. Do **NOT** use this branch to work on - MathJax's source. - -In addition to these branches, MathJax uses tags to identify the -various versions. These can be checked out to obtain the specified -release; for example, `git checkout 2.7.5` would get you the files for -version 2.7.5 of MathJax. - -Note that version 3 is written in Typescript, and so must be compiled -to obtain usable javascript files, and that the components need to be -built once that is done. See the -[documentation](https://docs.mathjax.org/en/latest/web/hosting.html#getting-mathjax-via-git) -for details. For version 2, the source javascript files are not -compressed until a release is made, so you should use the copies in -the `unpacked` directory during development. - - -### Submitting Pull Requests - -Pull requests are welcome. If you're looking to submit a PR for -something that doesn't have an open issue, please consider [raising an -issue](#reporting-an-issue) that your PR can close, especially if -you're fixing a bug. This makes it more likely that there will be -enough information available for your PR to be properly tested and -merged. - -##### Need Help? - -If you're not completely clear on how to submit/update/*do* Pull -Requests, please check out our [source control -policies](https://github.com/mathjax/MathJax/wiki/Source-control-policies). For -more insights, check the excellent in depth [Git Workflow -guide](https://github.com/TryGhost/Ghost/wiki/Git-Workflow) from -Ghost, in particular - -* [Ghost Workflow guide: commit messages](https://github.com/TryGhost/Ghost/wiki/Git-workflow#commit-messages) - -### Testing and Quality Assurance - -If you're -looking to get involved with the code base and don't know where to -start, checking out and testing a pull request is one of the most -useful things you could do. - -These are some [excellent -instructions](https://gist.github.com/piscisaureus/3342247) on -configuring your GitHub repository to allow you to checkout pull -requests in the same way as branches. - - -### Writing documentation - -MathJax's main documentation can be found at [docs.mathjax.org](http://docs.mathjax.org). -The source of the docs is hosted in the -[mathjax/MathJax-docs](http://github.com/mathjax/MathJax-docs) repo here on GitHub. - -The documentation is generated using -[Sphinx-doc](http://sphinx-doc.org/) and hosted on [Read the -docs](http://readthedocs.org). You can clone the repo and submit pull -requests following the [pull-request](#submitting-pull-requests) -guidelines. - - -### Translation - -If you wish to add or update translations of MathJax, please do it on -[TranslateWiki.net](https://translatewiki.net/w/i.php?title=Special:Translate&group=out-mathjax-0-all) -(and while you're there you can help other open source projects, -too). - -For bug reports and other questions that don't fit on -TranslateWiki.net, head over to the -[mathjax/mathjax-i18n](https://github.com/mathjax/MathJax-i18n) -repository. - -The translation files currently are for version 2, as localization -hasn't been added to version 3 yet. - -## Conduct - -As a NumFOCUS fiscally sponsored project, MathJax is governed by the -[NumFOCUS code of conduct](https://numfocus.org/code-of-conduct), -which we summarize as follows: - -We are committed to providing a friendly, safe and welcoming -environment for all, regardless of gender, sexual orientation, -disability, ethnicity, religion, or similar personal characteristic. - -Please be kind and courteous. There's no need to be mean or rude. -Respect that people have differences of opinion and that every design -or implementation choice carries a trade-off and numerous costs. There -is seldom a right answer, merely an optimal answer given a set of -values and circumstances. - -Please keep unstructured critique to a minimum. If you have solid -ideas you want to experiment with, make a fork and see how it works. - -We will exclude you from interaction if you insult, demean or harass -anyone. That is not welcome behaviour. We interpret the term -"harassment" as including the definition in the [Unacceptable -Behavior](https://numfocus.org/code-of-conduct#unacceptable-behavior) -section of the [NumFOCUS code of -conduct](https://numfocus.org/code-of-conduct); if you have any lack -of clarity about what might be included in that concept, please read -that definition. In particular, we don't tolerate behavior that -excludes people in socially marginalized groups. - -Private harassment is also unacceptable. No matter who you are, if you -feel you have been or are being harassed or made uncomfortable by a -community member, please contact one of the channel ops or any of the -[MathJax](https://github.com/MathJax/MathJax) core team -immediately. Whether you're a regular contributor or a newcomer, we -care about making this community a safe place for you and we've got -your back. - -Likewise any spamming, trolling, flaming, baiting, or other -attention-stealing behaviour is not welcome. - -We also recommend that you read [discourse's -rules](http://blog.discourse.org/2013/03/the-universal-rules-of-civilized-discourse/) -for further suggestions on appropriate behavior. - -## References - -* We heavily borrowed from Mozilla and Ghost -- thank you! - * - * -* -* diff --git a/build/pkgs/mathjax3/MathJax-3.2.0/LICENSE b/build/pkgs/mathjax3/MathJax-3.2.0/LICENSE deleted file mode 100644 index d6456956733..00000000000 --- a/build/pkgs/mathjax3/MathJax-3.2.0/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/build/pkgs/mathjax3/MathJax-3.2.0/README.md b/build/pkgs/mathjax3/MathJax-3.2.0/README.md deleted file mode 100644 index 94186007ac0..00000000000 --- a/build/pkgs/mathjax3/MathJax-3.2.0/README.md +++ /dev/null @@ -1,237 +0,0 @@ -# MathJax -## Beautiful math in all browsers - -![GitHub release version](https://img.shields.io/github/v/release/mathjax/MathJax-src.svg?sort=semver) -![GitHub release version (v2)](https://img.shields.io/github/package-json/v/mathjax/MathJax/legacy-v2.svg?label=release-v2) -![NPM version](https://img.shields.io/npm/v/mathjax.svg?style=flat) -![powered by NumFOCUS](https://img.shields.io/badge/powered%20by-NumFOCUS-orange.svg?style=flat) -![jsdelivr rank](https://flat.badgen.net/jsdelivr/rank/npm/mathjax?color=green) -![jsDelivr hits (npm)](https://img.shields.io/jsdelivr/npm/hm/mathjax) -![npm monthly downloads (full)](https://img.shields.io/npm/dm/mathjax?label=npm) -![npm total downloads](https://img.shields.io/npm/dt/mathjax.svg?style=flat&label=npm%20total) - -MathJax is an open-source JavaScript display engine for LaTeX, MathML, -and AsciiMath notation that works in all modern browsers. It was -designed with the goal of consolidating the recent advances in web -technologies into a single, definitive, math-on-the-web platform -supporting the major browsers and operating systems. It requires no -setup on the part of the user (no plugins to download or software to -install), so the page author can write web documents that include -mathematics and be confident that users will be able to view it -naturally and easily. Simply include MathJax and some mathematics in -a web page, and MathJax does the rest. - -Some of the main features of MathJax include: - -- High-quality display of LaTeX, MathML, and AsciiMath notation in HTML pages - -- Supported in most browsers with no plug-ins, extra fonts, or special - setup for the reader - -- Easy for authors, flexible for publishers, extensible for developers - -- Supports math accessibility, cut-and-paste interoperability, and other - advanced functionality - -- Powerful API for integration with other web applications - -See for additional details about MathJax, -and for the MathJax documentation. - -## MathJax Components - -MathJax version 3 uses files called *components* that contain the -various MathJax modules that you can include in your web pages or -access on a server through NodeJS. Some components combine all the -pieces you need to run MathJax with one or more input formats and a -particular output format, while other components are pieces that can -be loaded on demand when needed, or by a configuration that specifies -the pieces you want to combine in a custom way. For usage -instructions, see the [MathJax documentation](https://docs.mathjax.org). - -Components provide a convenient packaging of MathJax's modules, but it -is possible for you to form your own custom components, or to use -MathJax's modules directly in a node application on a server. There -are [web examples](https://github.com/mathjax/MathJax-demos-web) -showing how to use MathJax in web pages and how to build your own -components, and [node -examples](https://github.com/mathjax/MathJax-demos-node) illustrating -how to use components in node applications or call MathJax modules -directly. - -## What's in this Repository - -This repository contains only the component files for MathJax, not the -source code for MathJax (which are available in a separate [MathJax -source repository](https://github.com/mathjax/MathJax-src/)). These -component files are the ones served by the CDNs that offer MathJax to -the web. In version 2, the files used on the web were also the source -files for MathJax, but in version 3, the source files are no longer on -the CDN, as they are not what are run in the browser. - -The components are stored in the `es5` directory, and are in ES5 format -for the widest possible compatibility. In the future, we may make an -`es6` directory containing ES6 versions of the components. - -## Installation and Use - -### Using MathJax components from a CDN on the web - -If you are loading MathJax from a CDN into a web page, there is no -need to install anything. Simply use a `script` tag that loads -MathJax from the CDN. E.g., - -``` html - -``` - -See the [MathJax -documentation](https://docs.mathjax.org/en/latest/index.html#browser-components), -the [MathJax Web Demos](https://github.com/mathjax/MathJax-demos-web), -and the [MathJax Component -Repository](https://github.com/mathjax/MathJax-demos-web) for more information. - -### Hosting your own copy of the MathJax Components - -If you want to host MathJax from your own server, you can do so by -installing the `mathjax` package using `npm` and moving the `es5` -directory to an appropriate location on your server: - -``` bash -npm install mathjax@3 -mv node_modules/mathjax/es5 /mathjax -``` - -Note that we are still making updates to version 2, so include `@3` -when you install, since the latest chronological version may not be -version 3. - -Alternatively, you can get the files via GitHub: - -``` bash -git clone https://github.com/mathjax/MathJax.git mj-tmp -mv mj-tmp/es5 /mathjax -rm -rf mj-tmp -``` - -Then (in either case) you can use a script tag like the following: - -``` html - -``` - -where `` is replaced by the URL to the location -where you moved the MathJax files above. - -See the -[documentation](https://docs.mathjax.org/en/latest/web/hosting.html) -for details. - -### Using MathJax components in a node application - -To use MathJax components in a node application, install the `mathjax` package: - -``` bash -npm install mathjax@3 -``` - -(we are still making updates to version 2, so you should include `@3` -since the latest chronological version may not be version 3). - -Then require `mathjax` within your application: - -```js -require('mathjax').init({ ... }).then((MathJax) => { ... }); -``` - -where the first `{ ... }` is a MathJax configuration, and the second -`{ ... }` is the code to run after MathJax has been loaded. E.g. - -```js -require('mathjax').init({ - loader: {load: ['input/tex', 'output/svg']} -}).then((MathJax) => { - const svg = MathJax.tex2svg('\\frac{1}{x^2-1}', {display: true}); - console.log(MathJax.startup.adaptor.outerHTML(svg)); -}).catch((err) => console.log(err.message)); -``` - -**Note:** this technique is for node-based application only, not for -browser applications. This method sets up an alternative DOM -implementation, which you don't need in the browser, and tells MathJax -to use node's `require()` command to load external modules. This -setup will not work properly in the browser, even if you webpack it or -bundle it in other ways. - -See the -[documentation](https://docs.mathjax.org/en/latest/index.html#server-nodejs) -and the [MathJax Node -Repository](https://github.com/mathjax/MathJax-demos-node) for more details. - -## Reducing the Size of the Components Directory - -Since the `es5` directory contains *all* the component files, so if -you are only planning one use one configuration, you can reduce the -size of the MathJax directory by removing unused components. For -example, if you are using the `tex-chtml.js` component, then you can -remove the `tex-mml-chtml.js`, `tex-svg.js`, `tex-mml-svg.js`, -`tex-chtml-full.js`, and `tex-svg-full.js` configurations, which will -save considerable space. Indeed, you should be able to remove -everything other than `tex-chtml.js`, and the `input/tex/extensions`, -`output/chtml/fonts/woff-v2`, `adaptors`, `a11y`, and `sre` -directories. If you are using the results only on the web, you can -remove `adaptors` as well. - -If you are not using A11Y support (e.g., speech generation, or -semantic enrichment), then you can remove `a11y` and `sre` as well -(though in this case you may need to disable the assistive tools in -the MathJax contextual menu in order to avoid MathJax trying to load -them when they aren't there). - -If you are using SVG rather than CommonHTML output (e.g., `tex-svg.js` -rather than `tex-chtml.js`), you can remove the -`output/chtml/fonts/woff-v2` directory. If you are using MathML input -rather than TeX (e.g., `mml-chtml.js` rather than `tex-chtml.js`), -then you can remove `input/tex/extensions` as well. - - -## The Component Files and Pull Requests - -The `es5` directory is generated automatically from the contents of the -MathJax source repository. You can rebuild the components using the -command - -``` bash -npm run make-es5 --silent -``` - -Note that since the contents of this repository are generated -automatically, you should not submit pull requests that modify the -contents of the `es5` directory. If you wish to submit a modification -to MathJax, you should make a pull request in the [MathJax source -repository](https://github.com/mathjax/MathJax-src). - -## MathJax Community - -The main MathJax website is , and it includes -announcements and other important information. A [MathJax user -forum](http://groups.google.com/group/mathjax-users) for asking -questions and getting assistance is hosted at Google, and the [MathJax -bug tracker](https://github.com/mathjax/MathJax/issues) is hosted -at GitHub. - -Before reporting a bug, please check that it has not already been -reported. Also, please use the bug tracker (rather than the help -forum) for reporting bugs, and use the user's forum (rather than the -bug tracker) for questions about how to use MathJax. - -## MathJax Resources - -* [MathJax Documentation](https://docs.mathjax.org) -* [MathJax Components](https://github.com/mathjax/MathJax) -* [MathJax Source Code](https://github.com/mathjax/MathJax-src) -* [MathJax Web Examples](https://github.com/mathjax/MathJax-demos-web) -* [MathJax Node Examples](https://github.com/mathjax/MathJax-demos-node) -* [MathJax Bug Tracker](https://github.com/mathjax/MathJax/issues) -* [MathJax Users' Group](http://groups.google.com/group/mathjax-users) - diff --git a/build/pkgs/mathjax3/MathJax-3.2.0/bower.json b/build/pkgs/mathjax3/MathJax-3.2.0/bower.json deleted file mode 100644 index 6b214b933ea..00000000000 --- a/build/pkgs/mathjax3/MathJax-3.2.0/bower.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "MathJax", - "main": "./MathJax.js", - "homepage": "http://www.mathjax.org/", - "ignore": [ - "**/.*", - "node_modules", - "components" - ], - "keywords": ["math", "js", "LaTeX", "MathML", "AsciiMath"] -} diff --git a/build/pkgs/mathjax3/MathJax-3.2.0/composer.json b/build/pkgs/mathjax3/MathJax-3.2.0/composer.json deleted file mode 100644 index b1b9d27aed6..00000000000 --- a/build/pkgs/mathjax3/MathJax-3.2.0/composer.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "mathjax/mathjax", - "type": "library", - "description": "MathJax is an open-source JavaScript display engine for LaTeX, MathML, and AsciiMath notation that works in all modern browsers.", - "keywords": ["math", "js", "LaTeX", "MathML", "AsciiMath"], - "homepage": "http://www.mathjax.org/", - "license": "Apache-2.0", - "authors": [ - { - "name": "MathJax Consortium", - "homepage": "https://github.com/mathjax" - } - ] -} diff --git a/build/pkgs/mathjax3/MathJax-3.2.0/package.json b/build/pkgs/mathjax3/MathJax-3.2.0/package.json deleted file mode 100644 index 6706949557b..00000000000 --- a/build/pkgs/mathjax3/MathJax-3.2.0/package.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "name": "mathjax", - "version": "3.2.0", - "description": "Beautiful and accessible math in all browsers. MathJax is an open-source JavaScript display engine for LaTeX, MathML, and AsciiMath notation that works in all browsers. This package includes the packaged components (install mathjax-full to get the source code).", - "keywords": [ - "math", - "svg", - "mathml", - "tex", - "latex", - "asciimath", - "browser", - "node" - ], - "devDependencies": { - "mathjax-full": "3.2.0" - }, - "maintainers": [ - "MathJax Consortium (http://www.mathjax.org)" - ], - "bugs": { - "url": "http://github.com/mathjax/MathJax/issues" - }, - "license": "Apache-2.0", - "repository": { - "type": "git", - "url": "git://github.com/mathjax/MathJax.git" - }, - "main": "es5/node-main.js", - "files": [ - "/es5" - ], - "scripts": { - "test": "echo 'No tests defined'", - "clean": "npm run --silent clean:es5 && npm run --silent clean:node", - "clean:es5": "rm -rf es5", - "clean:node": "rm -rf node_modules package-lock.json", - "message": "echo \"$(tput setaf 4)${npm_package_config_message}$(tput setaf 0)\" && echo", - "line": "echo '--------------------------------------------'", - "title": "npm run --silent line && npm run --silent message --mathjax:message=\"${npm_package_config_title}\"", - "preinstall:mj3": "npm run --silent title --mathjax:title='Installing MathJax...'", - "install:mj3": "npm install", - "preinstall:mj3-deps": "npm run --silent message --mathjax:message='Installing MathJax Dependencies...'", - "install:mj3-deps": "cd node_modules/mathjax-full && npm install", - "install:all": "npm run --silent install:mj3 && npm run --silent install:mj3-deps", - "precompile": "npm run --silent title --mathjax:title='Compiling MathJax...'", - "compile": "cd node_modules/mathjax-full && npm run --silent compile", - "precomponents": "npm run --silent title --mathjax:title='Building MathJax Components...'", - "components": "cd node_modules/mathjax-full && npm run --silent make-components", - "premove": "npm run --silent title --mathjax:title='Moving MathJax Components...'", - "move": "npm run --silent clean:es5 && mv node_modules/mathjax-full/es5 .", - "premake-es5": "npm run --silent clean:node", - "make-es5": "npm run --silent install:all && npm run --silent compile && npm run --silent components && npm run --silent move", - "postmake-es5": "npm run --silent title --mathjax:title='Cleaning Up...' && npm run --silent clean:node", - "preget-es5": "npm run --silent clean:node", - "get-es5": "npm run --silent install:mj3 && npm run --silent move", - "postget-es5": "npm run --silent title --mathjax:title='Cleaning Up...' && npm run --silent clean:node" - } -} diff --git a/build/pkgs/mathjax3/checksums.ini b/build/pkgs/mathjax3/checksums.ini index 4ffadfb32b1..c46436941ad 100644 --- a/build/pkgs/mathjax3/checksums.ini +++ b/build/pkgs/mathjax3/checksums.ini @@ -1,4 +1,4 @@ tarball=mathjax-VERSION.tar.gz -sha1=4fec236527498c480b92032afe36d06d2741973c -md5=6eb4395cd91b71be846623d30a9bff70 -cksum=2042371852 +sha1=60445ab91fdec88b5bff750e604adca1defe0019 +md5=84145ea49e91b5317385705d37060c4e +cksum=3733185847 diff --git a/build/pkgs/mathjax3/spkg-src b/build/pkgs/mathjax3/spkg-src index dadb1411c6f..266e5e2554d 100755 --- a/build/pkgs/mathjax3/spkg-src +++ b/build/pkgs/mathjax3/spkg-src @@ -20,6 +20,7 @@ else fi mv MathJax-${GIT_VERSION}/es5 src +rm -r MathJax-${GIT_VERSION} PACKAGE_VERSION=${GIT_VERSION} From bd60742011ccf822629c8dda8a35315da839459d Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Thu, 7 Apr 2022 16:32:34 +0900 Subject: [PATCH 093/529] Put into mathjax subdirectory --- build/pkgs/mathjax3/checksums.ini | 6 +++--- build/pkgs/mathjax3/spkg-src | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build/pkgs/mathjax3/checksums.ini b/build/pkgs/mathjax3/checksums.ini index c46436941ad..2cfe5869dd5 100644 --- a/build/pkgs/mathjax3/checksums.ini +++ b/build/pkgs/mathjax3/checksums.ini @@ -1,4 +1,4 @@ tarball=mathjax-VERSION.tar.gz -sha1=60445ab91fdec88b5bff750e604adca1defe0019 -md5=84145ea49e91b5317385705d37060c4e -cksum=3733185847 +sha1=ed325638d807fac93e4b1b9d052e2a72164bbaba +md5=7a78a9e649f69a295ad11cb476857cd5 +cksum=1951447424 diff --git a/build/pkgs/mathjax3/spkg-src b/build/pkgs/mathjax3/spkg-src index 266e5e2554d..b20462e48d1 100755 --- a/build/pkgs/mathjax3/spkg-src +++ b/build/pkgs/mathjax3/spkg-src @@ -4,7 +4,6 @@ set -e [ -n "${SAGE_ROOT}" ] || SAGE_ROOT="$(pwd)/../../../" - # determine latest version. GIT_VERSION="$(curl https://github.com/mathjax/MathJax/releases | grep 'MathJax v' | head -1 | sed 's|^.*MathJax v||g' | sed 's/\s*$//g')" echo "GIT_VERSION=$GIT_VERSION" @@ -19,7 +18,8 @@ else tar xzf "$UPSTREAM_SOURCE_TARBALL" fi -mv MathJax-${GIT_VERSION}/es5 src +mkdir src +mv MathJax-${GIT_VERSION}/es5 src/mathjax rm -r MathJax-${GIT_VERSION} PACKAGE_VERSION=${GIT_VERSION} From d647ea6665a878e0edf2d4a732fba53d13773304 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Thu, 7 Apr 2022 13:50:19 +0900 Subject: [PATCH 094/529] Add sage package mathjax3 --- .../mathjax3/MathJax-3.2.0/CONTRIBUTING.md | 314 ++++++++++++++++++ build/pkgs/mathjax3/MathJax-3.2.0/LICENSE | 202 +++++++++++ build/pkgs/mathjax3/MathJax-3.2.0/README.md | 237 +++++++++++++ build/pkgs/mathjax3/MathJax-3.2.0/bower.json | 11 + .../pkgs/mathjax3/MathJax-3.2.0/composer.json | 14 + .../pkgs/mathjax3/MathJax-3.2.0/package.json | 59 ++++ build/pkgs/mathjax3/SPKG.rst | 32 ++ build/pkgs/mathjax3/checksums.ini | 4 + build/pkgs/mathjax3/distros/conda.txt | 1 + build/pkgs/mathjax3/distros/opensuse.txt | 1 + build/pkgs/mathjax3/distros/repology.txt | 1 + build/pkgs/mathjax3/distros/void.txt | 1 + build/pkgs/mathjax3/package-version.txt | 1 + build/pkgs/mathjax3/spkg-install.in | 4 + build/pkgs/mathjax3/spkg-src | 34 ++ build/pkgs/mathjax3/type | 1 + 16 files changed, 917 insertions(+) create mode 100644 build/pkgs/mathjax3/MathJax-3.2.0/CONTRIBUTING.md create mode 100644 build/pkgs/mathjax3/MathJax-3.2.0/LICENSE create mode 100644 build/pkgs/mathjax3/MathJax-3.2.0/README.md create mode 100644 build/pkgs/mathjax3/MathJax-3.2.0/bower.json create mode 100644 build/pkgs/mathjax3/MathJax-3.2.0/composer.json create mode 100644 build/pkgs/mathjax3/MathJax-3.2.0/package.json create mode 100644 build/pkgs/mathjax3/SPKG.rst create mode 100644 build/pkgs/mathjax3/checksums.ini create mode 100644 build/pkgs/mathjax3/distros/conda.txt create mode 100644 build/pkgs/mathjax3/distros/opensuse.txt create mode 100644 build/pkgs/mathjax3/distros/repology.txt create mode 100644 build/pkgs/mathjax3/distros/void.txt create mode 100644 build/pkgs/mathjax3/package-version.txt create mode 100644 build/pkgs/mathjax3/spkg-install.in create mode 100755 build/pkgs/mathjax3/spkg-src create mode 100644 build/pkgs/mathjax3/type diff --git a/build/pkgs/mathjax3/MathJax-3.2.0/CONTRIBUTING.md b/build/pkgs/mathjax3/MathJax-3.2.0/CONTRIBUTING.md new file mode 100644 index 00000000000..7153d85d6b6 --- /dev/null +++ b/build/pkgs/mathjax3/MathJax-3.2.0/CONTRIBUTING.md @@ -0,0 +1,314 @@ +# Contributing to MathJax + +You are interested in giving us a hand? That's awesome! We've put +together some brief guidelines that should help you get started +quickly and easily. + +There are lots and lots of ways to get involved, this document covers: + +* [reporting an issue](#reporting-an-issue) + * [bug reports](#bug-reports) + * [feature requests](#feature-requests) + * [change requests](#change-requests) +* [working on MathJax core](#working-on-mathjax-core) + * [key branches and tags](#key-branches--tags) + * [submitting pull requests](#submitting-pull-requests) + * [testing and quality assurance](#testing-and-quality-assurance) + * [writing documentation](#writing-documentation) + * [translation](#translation) +* [Conduct](#conduct) + + +## Reporting An Issue + +If you're about to raise an issue because you think you've found a +problem with MathJax, or you'd like to make a request for a new +feature in the codebase, or any other reason, please read this first. + +The [MathJax issue +tracker](https://github.com/mathjax/MathJax/issues) is the +preferred channel for [bug reports](#bug-reports), [feature +requests](#feature-requests), [change requests](#change-requests), and +[submitting pull requests](#submitting-pull-requests), but please +respect the following restrictions: + +* Please **search for existing issues**. Help us keep duplicate issues + to a minimum by checking to see if someone has already reported your + problem or requested your idea. + +* Please **do not** use the issue tracker for personal support + requests (use [the MathJax User Group](https://groups.google.com/forum/#!forum/mathjax-users)). + +* Please **be civil**. Keep the discussion on topic and respect the + opinions of others. See also our [Conduct Guidelines](#conduct) + +### Bug Reports + +A bug is a *demonstrable problem* that is caused by the code in the +repository. Good bug reports are extremely helpful — thank you! + +Guidelines for bug reports: + +1. **Use the GitHub issue search** — check if the issue has already been + reported. + +2. **Check if the issue has been fixed** — look for [closed + issues in the current + milestone](https://github.com/mathjax/MathJax/issues?q=is%3Aclosed) + or try to reproduce it using the latest `develop` branch. Please + note that you will need to + [compile MathJax and make the components](https://docs.mathjax.org/en/latest/web/hosting.html#getting-mathjax-via-git) + in order to test MathJax from the source repository. + +3. **Share a live sample of the problem** — without a live page + it is usually impossible to debug problems; see also the [Bug Report + Template](#template) below. + +4. **Isolate the problem** — a live sample is a starting point + but if you want to speed things up, create a [reduced test + case](http://css-tricks.com/6263-reduced-test-cases/). Be specific + about your setup (browser, OS versions, etc). Use services like + [jsbin](http://jsbin.com), [CodePen](http://codepen.io), or + [jsFiddle](http://jsfiddle.com) to make collaboration on minimal + test cases easier for everyone. + +5. **Include a screenshot/cast as a last resort** — Is your + issue about a layout or design feature or bug that is hard to reproduce + or isolate? Then please provide a screenshot or screencast. Tools + like [LICEcap](http://www.cockos.com/licecap/) or + [SauceLabs](http://www.saucelabs.com) allow you to quickly and + easily record a screencasts. If you make it an animated gif, you can + embed it directly into your GitHub issue. + +6. Use the [Bug Report Template](#template) below or [click this + link](https://github.com/MathJax/MathJax/issues/new?title=Bug%3A&body=%23%23%23%20Issue%20Summary%0A%0A%23%23%23%20Steps%20to%20Reproduce%0A%0A1.%20This%20is%20the%20first%20step%0A%0AThis%20is%20a%20bug%20because...%0A%0A%23%23%23%20Technical%20details%0A%0A*%20MathJax%20Version%3A%20master%20-%20latest%20commit%3A%20%20INSERT%20COMMIT%20REF%0A*%20Client%20OS%3A%20%0A*%20Browser%3A%20%0A*%20) + to start creating a bug report with the template automatically. + +A good bug report shouldn't leave others needing to request +more information from you. Be sure to include the details of your environment. + + + +Template Example ([click to use](https://github.com/MathJax/MathJax/issues/new?title=Bug%3A&body=%23%23%23%20Issue%20Summary%0A%0A%23%23%23%20Steps%20to%20Reproduce%0A%0A1.%20This%20is%20the%20first%20step%0A%0AThis%20is%20a%20bug%20because...%0A%0A%23%23%23%20Technical%20details%0A%0A*%20MathJax%20Version%3A%20master%20-%20latest%20commit%3A%20%20INSERT%20COMMIT%20REF%0A*%20Client%20OS%3A%20%0A*%20Browser%3A%20%0A*%20)): + +``` +Short and descriptive example bug report title + +### Issue Summary + +A summary of the issue and the browser/OS environment in which it occurs. If +suitable, include the steps required to reproduce the bug. + +### Steps to Reproduce + +1. This is the first step +2. This is the second step +3. Further steps, etc. + +Any other information you want to share that is relevant to the issue +being reported. Especially, why do you consider this to be a bug? What +do you expect to happen instead? + +### Technical details: + +* MathJax Version: 2.3 (latest commit: f3aaf3a2a3e964df2770dc4aaaa9c87ce5f47e2c) +* Client OS: Mac OS X 10.8.4 +* Browser: Chrome 29.0.1547.57 +``` + + +### Feature Requests + +Feature requests are welcome. Before you submit one, be sure to have: + +1. **Used the GitHub search** to check that the feature hasn't already + been requested. +2. Take a moment to think about whether your idea fits with the scope + and aims of the project, or if it might better fit being a [custom + extension](https://github.com/mathjax/MathJax-third-party-extensions). +3. Remember, it's up to *you* to make a strong case to convince the + project's leaders of the merits of this feature. Please provide as + much detail and context as possible, this means explaining the use + case and why it is likely to be common. + +### Change Requests + +Change requests cover both architectural and functional changes to how +MathJax works. If you have an idea for a new or different dependency, +a refactor, or an improvement to a feature, etc., please be sure to: + +1. **Use the GitHub search** to check that someone else didn't get there first. +2. Take a moment to think about the best way to make a case for, and + explain what you're thinking. Are you sure this shouldn't really be + a [bug report](#bug-reports) or a [feature + request](#feature-requests)? Is it really one idea or is it many? + What's the context? What problem are you solving? Why is what you + are suggesting better than what's already there? + +## Working on MathJax core + +You want to contribute code? We describe how below. First, note that +the MathJax source code is in the + repository, not the + repository, which contains the +packaged component files for distribution on CDNs and the [mathjax npm +package](https://www.npmjs.com/package/mathjax) (the source code is +included in the [mathjax-full npm +package](https://www.npmjs.com/package/mathjax-full)). + +### Key Branches & Tags + +MathJax uses several permanent branches in the [MathJax source repository](https://github.com/mathjax/MathJax-src): + +- **[develop](https://github.com/mathjax/MathJax-src/tree/develop)** + is the development branch. All work on the next release happens here + so you should generally branch off `develop` if you are going to + submit a pull request. Do **NOT** use this branch for a production + site. + +- **[master](https://github.com/mathjax/MathJax-src)** contains the latest + release of MathJax. This branch may be used in production. Do + **NOT** use this branch to work on MathJax's source. + +These branches reflect version 3 of MathJax, which is substantially +different from the version 2 codebase. Version 2 will continue to be +maintained while web sites transition to version 3, with work being +done using the following branches in the [MathJax distribution +repository](https://github.com/mathjax/MathJax): + +- **[legacy-v2-develop](https://github.com/mathjax/MathJax/tree/legacy-v2-develop)** + is the development branch for changes to the legacy version 2 code. + Any pull requests for version 2 should be branched from here. Do + **NOT** use this branch for a production site. + +- **[legacy-v2](https://github.com/mathjax/MathJax/tree/legacy-v2)** + is the branch that contains any updates to version 2 following + the release of version 3. Do **NOT** use this branch to work on + MathJax's source. + +In addition to these branches, MathJax uses tags to identify the +various versions. These can be checked out to obtain the specified +release; for example, `git checkout 2.7.5` would get you the files for +version 2.7.5 of MathJax. + +Note that version 3 is written in Typescript, and so must be compiled +to obtain usable javascript files, and that the components need to be +built once that is done. See the +[documentation](https://docs.mathjax.org/en/latest/web/hosting.html#getting-mathjax-via-git) +for details. For version 2, the source javascript files are not +compressed until a release is made, so you should use the copies in +the `unpacked` directory during development. + + +### Submitting Pull Requests + +Pull requests are welcome. If you're looking to submit a PR for +something that doesn't have an open issue, please consider [raising an +issue](#reporting-an-issue) that your PR can close, especially if +you're fixing a bug. This makes it more likely that there will be +enough information available for your PR to be properly tested and +merged. + +##### Need Help? + +If you're not completely clear on how to submit/update/*do* Pull +Requests, please check out our [source control +policies](https://github.com/mathjax/MathJax/wiki/Source-control-policies). For +more insights, check the excellent in depth [Git Workflow +guide](https://github.com/TryGhost/Ghost/wiki/Git-Workflow) from +Ghost, in particular + +* [Ghost Workflow guide: commit messages](https://github.com/TryGhost/Ghost/wiki/Git-workflow#commit-messages) + +### Testing and Quality Assurance + +If you're +looking to get involved with the code base and don't know where to +start, checking out and testing a pull request is one of the most +useful things you could do. + +These are some [excellent +instructions](https://gist.github.com/piscisaureus/3342247) on +configuring your GitHub repository to allow you to checkout pull +requests in the same way as branches. + + +### Writing documentation + +MathJax's main documentation can be found at [docs.mathjax.org](http://docs.mathjax.org). +The source of the docs is hosted in the +[mathjax/MathJax-docs](http://github.com/mathjax/MathJax-docs) repo here on GitHub. + +The documentation is generated using +[Sphinx-doc](http://sphinx-doc.org/) and hosted on [Read the +docs](http://readthedocs.org). You can clone the repo and submit pull +requests following the [pull-request](#submitting-pull-requests) +guidelines. + + +### Translation + +If you wish to add or update translations of MathJax, please do it on +[TranslateWiki.net](https://translatewiki.net/w/i.php?title=Special:Translate&group=out-mathjax-0-all) +(and while you're there you can help other open source projects, +too). + +For bug reports and other questions that don't fit on +TranslateWiki.net, head over to the +[mathjax/mathjax-i18n](https://github.com/mathjax/MathJax-i18n) +repository. + +The translation files currently are for version 2, as localization +hasn't been added to version 3 yet. + +## Conduct + +As a NumFOCUS fiscally sponsored project, MathJax is governed by the +[NumFOCUS code of conduct](https://numfocus.org/code-of-conduct), +which we summarize as follows: + +We are committed to providing a friendly, safe and welcoming +environment for all, regardless of gender, sexual orientation, +disability, ethnicity, religion, or similar personal characteristic. + +Please be kind and courteous. There's no need to be mean or rude. +Respect that people have differences of opinion and that every design +or implementation choice carries a trade-off and numerous costs. There +is seldom a right answer, merely an optimal answer given a set of +values and circumstances. + +Please keep unstructured critique to a minimum. If you have solid +ideas you want to experiment with, make a fork and see how it works. + +We will exclude you from interaction if you insult, demean or harass +anyone. That is not welcome behaviour. We interpret the term +"harassment" as including the definition in the [Unacceptable +Behavior](https://numfocus.org/code-of-conduct#unacceptable-behavior) +section of the [NumFOCUS code of +conduct](https://numfocus.org/code-of-conduct); if you have any lack +of clarity about what might be included in that concept, please read +that definition. In particular, we don't tolerate behavior that +excludes people in socially marginalized groups. + +Private harassment is also unacceptable. No matter who you are, if you +feel you have been or are being harassed or made uncomfortable by a +community member, please contact one of the channel ops or any of the +[MathJax](https://github.com/MathJax/MathJax) core team +immediately. Whether you're a regular contributor or a newcomer, we +care about making this community a safe place for you and we've got +your back. + +Likewise any spamming, trolling, flaming, baiting, or other +attention-stealing behaviour is not welcome. + +We also recommend that you read [discourse's +rules](http://blog.discourse.org/2013/03/the-universal-rules-of-civilized-discourse/) +for further suggestions on appropriate behavior. + +## References + +* We heavily borrowed from Mozilla and Ghost -- thank you! + * + * +* +* diff --git a/build/pkgs/mathjax3/MathJax-3.2.0/LICENSE b/build/pkgs/mathjax3/MathJax-3.2.0/LICENSE new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/build/pkgs/mathjax3/MathJax-3.2.0/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/build/pkgs/mathjax3/MathJax-3.2.0/README.md b/build/pkgs/mathjax3/MathJax-3.2.0/README.md new file mode 100644 index 00000000000..94186007ac0 --- /dev/null +++ b/build/pkgs/mathjax3/MathJax-3.2.0/README.md @@ -0,0 +1,237 @@ +# MathJax +## Beautiful math in all browsers + +![GitHub release version](https://img.shields.io/github/v/release/mathjax/MathJax-src.svg?sort=semver) +![GitHub release version (v2)](https://img.shields.io/github/package-json/v/mathjax/MathJax/legacy-v2.svg?label=release-v2) +![NPM version](https://img.shields.io/npm/v/mathjax.svg?style=flat) +![powered by NumFOCUS](https://img.shields.io/badge/powered%20by-NumFOCUS-orange.svg?style=flat) +![jsdelivr rank](https://flat.badgen.net/jsdelivr/rank/npm/mathjax?color=green) +![jsDelivr hits (npm)](https://img.shields.io/jsdelivr/npm/hm/mathjax) +![npm monthly downloads (full)](https://img.shields.io/npm/dm/mathjax?label=npm) +![npm total downloads](https://img.shields.io/npm/dt/mathjax.svg?style=flat&label=npm%20total) + +MathJax is an open-source JavaScript display engine for LaTeX, MathML, +and AsciiMath notation that works in all modern browsers. It was +designed with the goal of consolidating the recent advances in web +technologies into a single, definitive, math-on-the-web platform +supporting the major browsers and operating systems. It requires no +setup on the part of the user (no plugins to download or software to +install), so the page author can write web documents that include +mathematics and be confident that users will be able to view it +naturally and easily. Simply include MathJax and some mathematics in +a web page, and MathJax does the rest. + +Some of the main features of MathJax include: + +- High-quality display of LaTeX, MathML, and AsciiMath notation in HTML pages + +- Supported in most browsers with no plug-ins, extra fonts, or special + setup for the reader + +- Easy for authors, flexible for publishers, extensible for developers + +- Supports math accessibility, cut-and-paste interoperability, and other + advanced functionality + +- Powerful API for integration with other web applications + +See for additional details about MathJax, +and for the MathJax documentation. + +## MathJax Components + +MathJax version 3 uses files called *components* that contain the +various MathJax modules that you can include in your web pages or +access on a server through NodeJS. Some components combine all the +pieces you need to run MathJax with one or more input formats and a +particular output format, while other components are pieces that can +be loaded on demand when needed, or by a configuration that specifies +the pieces you want to combine in a custom way. For usage +instructions, see the [MathJax documentation](https://docs.mathjax.org). + +Components provide a convenient packaging of MathJax's modules, but it +is possible for you to form your own custom components, or to use +MathJax's modules directly in a node application on a server. There +are [web examples](https://github.com/mathjax/MathJax-demos-web) +showing how to use MathJax in web pages and how to build your own +components, and [node +examples](https://github.com/mathjax/MathJax-demos-node) illustrating +how to use components in node applications or call MathJax modules +directly. + +## What's in this Repository + +This repository contains only the component files for MathJax, not the +source code for MathJax (which are available in a separate [MathJax +source repository](https://github.com/mathjax/MathJax-src/)). These +component files are the ones served by the CDNs that offer MathJax to +the web. In version 2, the files used on the web were also the source +files for MathJax, but in version 3, the source files are no longer on +the CDN, as they are not what are run in the browser. + +The components are stored in the `es5` directory, and are in ES5 format +for the widest possible compatibility. In the future, we may make an +`es6` directory containing ES6 versions of the components. + +## Installation and Use + +### Using MathJax components from a CDN on the web + +If you are loading MathJax from a CDN into a web page, there is no +need to install anything. Simply use a `script` tag that loads +MathJax from the CDN. E.g., + +``` html + +``` + +See the [MathJax +documentation](https://docs.mathjax.org/en/latest/index.html#browser-components), +the [MathJax Web Demos](https://github.com/mathjax/MathJax-demos-web), +and the [MathJax Component +Repository](https://github.com/mathjax/MathJax-demos-web) for more information. + +### Hosting your own copy of the MathJax Components + +If you want to host MathJax from your own server, you can do so by +installing the `mathjax` package using `npm` and moving the `es5` +directory to an appropriate location on your server: + +``` bash +npm install mathjax@3 +mv node_modules/mathjax/es5 /mathjax +``` + +Note that we are still making updates to version 2, so include `@3` +when you install, since the latest chronological version may not be +version 3. + +Alternatively, you can get the files via GitHub: + +``` bash +git clone https://github.com/mathjax/MathJax.git mj-tmp +mv mj-tmp/es5 /mathjax +rm -rf mj-tmp +``` + +Then (in either case) you can use a script tag like the following: + +``` html + +``` + +where `` is replaced by the URL to the location +where you moved the MathJax files above. + +See the +[documentation](https://docs.mathjax.org/en/latest/web/hosting.html) +for details. + +### Using MathJax components in a node application + +To use MathJax components in a node application, install the `mathjax` package: + +``` bash +npm install mathjax@3 +``` + +(we are still making updates to version 2, so you should include `@3` +since the latest chronological version may not be version 3). + +Then require `mathjax` within your application: + +```js +require('mathjax').init({ ... }).then((MathJax) => { ... }); +``` + +where the first `{ ... }` is a MathJax configuration, and the second +`{ ... }` is the code to run after MathJax has been loaded. E.g. + +```js +require('mathjax').init({ + loader: {load: ['input/tex', 'output/svg']} +}).then((MathJax) => { + const svg = MathJax.tex2svg('\\frac{1}{x^2-1}', {display: true}); + console.log(MathJax.startup.adaptor.outerHTML(svg)); +}).catch((err) => console.log(err.message)); +``` + +**Note:** this technique is for node-based application only, not for +browser applications. This method sets up an alternative DOM +implementation, which you don't need in the browser, and tells MathJax +to use node's `require()` command to load external modules. This +setup will not work properly in the browser, even if you webpack it or +bundle it in other ways. + +See the +[documentation](https://docs.mathjax.org/en/latest/index.html#server-nodejs) +and the [MathJax Node +Repository](https://github.com/mathjax/MathJax-demos-node) for more details. + +## Reducing the Size of the Components Directory + +Since the `es5` directory contains *all* the component files, so if +you are only planning one use one configuration, you can reduce the +size of the MathJax directory by removing unused components. For +example, if you are using the `tex-chtml.js` component, then you can +remove the `tex-mml-chtml.js`, `tex-svg.js`, `tex-mml-svg.js`, +`tex-chtml-full.js`, and `tex-svg-full.js` configurations, which will +save considerable space. Indeed, you should be able to remove +everything other than `tex-chtml.js`, and the `input/tex/extensions`, +`output/chtml/fonts/woff-v2`, `adaptors`, `a11y`, and `sre` +directories. If you are using the results only on the web, you can +remove `adaptors` as well. + +If you are not using A11Y support (e.g., speech generation, or +semantic enrichment), then you can remove `a11y` and `sre` as well +(though in this case you may need to disable the assistive tools in +the MathJax contextual menu in order to avoid MathJax trying to load +them when they aren't there). + +If you are using SVG rather than CommonHTML output (e.g., `tex-svg.js` +rather than `tex-chtml.js`), you can remove the +`output/chtml/fonts/woff-v2` directory. If you are using MathML input +rather than TeX (e.g., `mml-chtml.js` rather than `tex-chtml.js`), +then you can remove `input/tex/extensions` as well. + + +## The Component Files and Pull Requests + +The `es5` directory is generated automatically from the contents of the +MathJax source repository. You can rebuild the components using the +command + +``` bash +npm run make-es5 --silent +``` + +Note that since the contents of this repository are generated +automatically, you should not submit pull requests that modify the +contents of the `es5` directory. If you wish to submit a modification +to MathJax, you should make a pull request in the [MathJax source +repository](https://github.com/mathjax/MathJax-src). + +## MathJax Community + +The main MathJax website is , and it includes +announcements and other important information. A [MathJax user +forum](http://groups.google.com/group/mathjax-users) for asking +questions and getting assistance is hosted at Google, and the [MathJax +bug tracker](https://github.com/mathjax/MathJax/issues) is hosted +at GitHub. + +Before reporting a bug, please check that it has not already been +reported. Also, please use the bug tracker (rather than the help +forum) for reporting bugs, and use the user's forum (rather than the +bug tracker) for questions about how to use MathJax. + +## MathJax Resources + +* [MathJax Documentation](https://docs.mathjax.org) +* [MathJax Components](https://github.com/mathjax/MathJax) +* [MathJax Source Code](https://github.com/mathjax/MathJax-src) +* [MathJax Web Examples](https://github.com/mathjax/MathJax-demos-web) +* [MathJax Node Examples](https://github.com/mathjax/MathJax-demos-node) +* [MathJax Bug Tracker](https://github.com/mathjax/MathJax/issues) +* [MathJax Users' Group](http://groups.google.com/group/mathjax-users) + diff --git a/build/pkgs/mathjax3/MathJax-3.2.0/bower.json b/build/pkgs/mathjax3/MathJax-3.2.0/bower.json new file mode 100644 index 00000000000..6b214b933ea --- /dev/null +++ b/build/pkgs/mathjax3/MathJax-3.2.0/bower.json @@ -0,0 +1,11 @@ +{ + "name": "MathJax", + "main": "./MathJax.js", + "homepage": "http://www.mathjax.org/", + "ignore": [ + "**/.*", + "node_modules", + "components" + ], + "keywords": ["math", "js", "LaTeX", "MathML", "AsciiMath"] +} diff --git a/build/pkgs/mathjax3/MathJax-3.2.0/composer.json b/build/pkgs/mathjax3/MathJax-3.2.0/composer.json new file mode 100644 index 00000000000..b1b9d27aed6 --- /dev/null +++ b/build/pkgs/mathjax3/MathJax-3.2.0/composer.json @@ -0,0 +1,14 @@ +{ + "name": "mathjax/mathjax", + "type": "library", + "description": "MathJax is an open-source JavaScript display engine for LaTeX, MathML, and AsciiMath notation that works in all modern browsers.", + "keywords": ["math", "js", "LaTeX", "MathML", "AsciiMath"], + "homepage": "http://www.mathjax.org/", + "license": "Apache-2.0", + "authors": [ + { + "name": "MathJax Consortium", + "homepage": "https://github.com/mathjax" + } + ] +} diff --git a/build/pkgs/mathjax3/MathJax-3.2.0/package.json b/build/pkgs/mathjax3/MathJax-3.2.0/package.json new file mode 100644 index 00000000000..6706949557b --- /dev/null +++ b/build/pkgs/mathjax3/MathJax-3.2.0/package.json @@ -0,0 +1,59 @@ +{ + "name": "mathjax", + "version": "3.2.0", + "description": "Beautiful and accessible math in all browsers. MathJax is an open-source JavaScript display engine for LaTeX, MathML, and AsciiMath notation that works in all browsers. This package includes the packaged components (install mathjax-full to get the source code).", + "keywords": [ + "math", + "svg", + "mathml", + "tex", + "latex", + "asciimath", + "browser", + "node" + ], + "devDependencies": { + "mathjax-full": "3.2.0" + }, + "maintainers": [ + "MathJax Consortium (http://www.mathjax.org)" + ], + "bugs": { + "url": "http://github.com/mathjax/MathJax/issues" + }, + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "git://github.com/mathjax/MathJax.git" + }, + "main": "es5/node-main.js", + "files": [ + "/es5" + ], + "scripts": { + "test": "echo 'No tests defined'", + "clean": "npm run --silent clean:es5 && npm run --silent clean:node", + "clean:es5": "rm -rf es5", + "clean:node": "rm -rf node_modules package-lock.json", + "message": "echo \"$(tput setaf 4)${npm_package_config_message}$(tput setaf 0)\" && echo", + "line": "echo '--------------------------------------------'", + "title": "npm run --silent line && npm run --silent message --mathjax:message=\"${npm_package_config_title}\"", + "preinstall:mj3": "npm run --silent title --mathjax:title='Installing MathJax...'", + "install:mj3": "npm install", + "preinstall:mj3-deps": "npm run --silent message --mathjax:message='Installing MathJax Dependencies...'", + "install:mj3-deps": "cd node_modules/mathjax-full && npm install", + "install:all": "npm run --silent install:mj3 && npm run --silent install:mj3-deps", + "precompile": "npm run --silent title --mathjax:title='Compiling MathJax...'", + "compile": "cd node_modules/mathjax-full && npm run --silent compile", + "precomponents": "npm run --silent title --mathjax:title='Building MathJax Components...'", + "components": "cd node_modules/mathjax-full && npm run --silent make-components", + "premove": "npm run --silent title --mathjax:title='Moving MathJax Components...'", + "move": "npm run --silent clean:es5 && mv node_modules/mathjax-full/es5 .", + "premake-es5": "npm run --silent clean:node", + "make-es5": "npm run --silent install:all && npm run --silent compile && npm run --silent components && npm run --silent move", + "postmake-es5": "npm run --silent title --mathjax:title='Cleaning Up...' && npm run --silent clean:node", + "preget-es5": "npm run --silent clean:node", + "get-es5": "npm run --silent install:mj3 && npm run --silent move", + "postget-es5": "npm run --silent title --mathjax:title='Cleaning Up...' && npm run --silent clean:node" + } +} diff --git a/build/pkgs/mathjax3/SPKG.rst b/build/pkgs/mathjax3/SPKG.rst new file mode 100644 index 00000000000..b957186a448 --- /dev/null +++ b/build/pkgs/mathjax3/SPKG.rst @@ -0,0 +1,32 @@ +mathjax3: A JavaScript library for displaying mathematical formulas +=================================================================== + +Description +----------- + +MathJax3 is a JavaScript library for displaying mathematical formulas. + +MathJax3 is used by the Sage documentation built by Sphinx. + +License +------- + +Apache License, version 2.0 + + +Upstream Contact +---------------- + +Home page: https://www.mathjax.org/ + +Dependencies +------------ + +None + + +Special Update/Build Instructions +--------------------------------- + +None + diff --git a/build/pkgs/mathjax3/checksums.ini b/build/pkgs/mathjax3/checksums.ini new file mode 100644 index 00000000000..4ffadfb32b1 --- /dev/null +++ b/build/pkgs/mathjax3/checksums.ini @@ -0,0 +1,4 @@ +tarball=mathjax-VERSION.tar.gz +sha1=4fec236527498c480b92032afe36d06d2741973c +md5=6eb4395cd91b71be846623d30a9bff70 +cksum=2042371852 diff --git a/build/pkgs/mathjax3/distros/conda.txt b/build/pkgs/mathjax3/distros/conda.txt new file mode 100644 index 00000000000..37aaaac759c --- /dev/null +++ b/build/pkgs/mathjax3/distros/conda.txt @@ -0,0 +1 @@ +mathjax diff --git a/build/pkgs/mathjax3/distros/opensuse.txt b/build/pkgs/mathjax3/distros/opensuse.txt new file mode 100644 index 00000000000..37aaaac759c --- /dev/null +++ b/build/pkgs/mathjax3/distros/opensuse.txt @@ -0,0 +1 @@ +mathjax diff --git a/build/pkgs/mathjax3/distros/repology.txt b/build/pkgs/mathjax3/distros/repology.txt new file mode 100644 index 00000000000..37aaaac759c --- /dev/null +++ b/build/pkgs/mathjax3/distros/repology.txt @@ -0,0 +1 @@ +mathjax diff --git a/build/pkgs/mathjax3/distros/void.txt b/build/pkgs/mathjax3/distros/void.txt new file mode 100644 index 00000000000..37aaaac759c --- /dev/null +++ b/build/pkgs/mathjax3/distros/void.txt @@ -0,0 +1 @@ +mathjax diff --git a/build/pkgs/mathjax3/package-version.txt b/build/pkgs/mathjax3/package-version.txt new file mode 100644 index 00000000000..944880fa15e --- /dev/null +++ b/build/pkgs/mathjax3/package-version.txt @@ -0,0 +1 @@ +3.2.0 diff --git a/build/pkgs/mathjax3/spkg-install.in b/build/pkgs/mathjax3/spkg-install.in new file mode 100644 index 00000000000..4429a680a53 --- /dev/null +++ b/build/pkgs/mathjax3/spkg-install.in @@ -0,0 +1,4 @@ +TARGET="${SAGE_SHARE}/mathjax3" +# Cleanup installed version +rm -rf "${TARGET}" +sdh_install src/* "${TARGET}" diff --git a/build/pkgs/mathjax3/spkg-src b/build/pkgs/mathjax3/spkg-src new file mode 100755 index 00000000000..dadb1411c6f --- /dev/null +++ b/build/pkgs/mathjax3/spkg-src @@ -0,0 +1,34 @@ +#!/usr/bin/env bash + +set -e + +[ -n "${SAGE_ROOT}" ] || SAGE_ROOT="$(pwd)/../../../" + + +# determine latest version. +GIT_VERSION="$(curl https://github.com/mathjax/MathJax/releases | grep 'MathJax v' | head -1 | sed 's|^.*MathJax v||g' | sed 's/\s*$//g')" +echo "GIT_VERSION=$GIT_VERSION" + +# fetch and rename latest version. +URL="https://github.com/mathjax/MathJax/archive/refs/tags/${GIT_VERSION}.zip" +echo "Downloading $URL" +rm -rf src +if [ -z "$UPSTREAM_SOURCE_TARBALL" ]; then + tar xzf <( curl -L "$URL" ) +else + tar xzf "$UPSTREAM_SOURCE_TARBALL" +fi + +mv MathJax-${GIT_VERSION}/es5 src + +PACKAGE_VERSION=${GIT_VERSION} + +# repack +tar czf "$SAGE_ROOT/upstream/mathjax-${PACKAGE_VERSION}.tar.gz" src +rm -rf src + +# update package info +echo "${PACKAGE_VERSION}" > 'package-version.txt' +"$SAGE_ROOT"/sage --package fix-checksum mathjax3 + + diff --git a/build/pkgs/mathjax3/type b/build/pkgs/mathjax3/type new file mode 100644 index 00000000000..a6a7b9cd726 --- /dev/null +++ b/build/pkgs/mathjax3/type @@ -0,0 +1 @@ +standard From 7c2984dab2fe058b448ff6eb8178a235c1c28eca Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Thu, 7 Apr 2022 14:07:39 +0900 Subject: [PATCH 095/529] Remove garbage files --- .../mathjax3/MathJax-3.2.0/CONTRIBUTING.md | 314 ------------------ build/pkgs/mathjax3/MathJax-3.2.0/LICENSE | 202 ----------- build/pkgs/mathjax3/MathJax-3.2.0/README.md | 237 ------------- build/pkgs/mathjax3/MathJax-3.2.0/bower.json | 11 - .../pkgs/mathjax3/MathJax-3.2.0/composer.json | 14 - .../pkgs/mathjax3/MathJax-3.2.0/package.json | 59 ---- build/pkgs/mathjax3/checksums.ini | 6 +- build/pkgs/mathjax3/spkg-src | 1 + 8 files changed, 4 insertions(+), 840 deletions(-) delete mode 100644 build/pkgs/mathjax3/MathJax-3.2.0/CONTRIBUTING.md delete mode 100644 build/pkgs/mathjax3/MathJax-3.2.0/LICENSE delete mode 100644 build/pkgs/mathjax3/MathJax-3.2.0/README.md delete mode 100644 build/pkgs/mathjax3/MathJax-3.2.0/bower.json delete mode 100644 build/pkgs/mathjax3/MathJax-3.2.0/composer.json delete mode 100644 build/pkgs/mathjax3/MathJax-3.2.0/package.json diff --git a/build/pkgs/mathjax3/MathJax-3.2.0/CONTRIBUTING.md b/build/pkgs/mathjax3/MathJax-3.2.0/CONTRIBUTING.md deleted file mode 100644 index 7153d85d6b6..00000000000 --- a/build/pkgs/mathjax3/MathJax-3.2.0/CONTRIBUTING.md +++ /dev/null @@ -1,314 +0,0 @@ -# Contributing to MathJax - -You are interested in giving us a hand? That's awesome! We've put -together some brief guidelines that should help you get started -quickly and easily. - -There are lots and lots of ways to get involved, this document covers: - -* [reporting an issue](#reporting-an-issue) - * [bug reports](#bug-reports) - * [feature requests](#feature-requests) - * [change requests](#change-requests) -* [working on MathJax core](#working-on-mathjax-core) - * [key branches and tags](#key-branches--tags) - * [submitting pull requests](#submitting-pull-requests) - * [testing and quality assurance](#testing-and-quality-assurance) - * [writing documentation](#writing-documentation) - * [translation](#translation) -* [Conduct](#conduct) - - -## Reporting An Issue - -If you're about to raise an issue because you think you've found a -problem with MathJax, or you'd like to make a request for a new -feature in the codebase, or any other reason, please read this first. - -The [MathJax issue -tracker](https://github.com/mathjax/MathJax/issues) is the -preferred channel for [bug reports](#bug-reports), [feature -requests](#feature-requests), [change requests](#change-requests), and -[submitting pull requests](#submitting-pull-requests), but please -respect the following restrictions: - -* Please **search for existing issues**. Help us keep duplicate issues - to a minimum by checking to see if someone has already reported your - problem or requested your idea. - -* Please **do not** use the issue tracker for personal support - requests (use [the MathJax User Group](https://groups.google.com/forum/#!forum/mathjax-users)). - -* Please **be civil**. Keep the discussion on topic and respect the - opinions of others. See also our [Conduct Guidelines](#conduct) - -### Bug Reports - -A bug is a *demonstrable problem* that is caused by the code in the -repository. Good bug reports are extremely helpful — thank you! - -Guidelines for bug reports: - -1. **Use the GitHub issue search** — check if the issue has already been - reported. - -2. **Check if the issue has been fixed** — look for [closed - issues in the current - milestone](https://github.com/mathjax/MathJax/issues?q=is%3Aclosed) - or try to reproduce it using the latest `develop` branch. Please - note that you will need to - [compile MathJax and make the components](https://docs.mathjax.org/en/latest/web/hosting.html#getting-mathjax-via-git) - in order to test MathJax from the source repository. - -3. **Share a live sample of the problem** — without a live page - it is usually impossible to debug problems; see also the [Bug Report - Template](#template) below. - -4. **Isolate the problem** — a live sample is a starting point - but if you want to speed things up, create a [reduced test - case](http://css-tricks.com/6263-reduced-test-cases/). Be specific - about your setup (browser, OS versions, etc). Use services like - [jsbin](http://jsbin.com), [CodePen](http://codepen.io), or - [jsFiddle](http://jsfiddle.com) to make collaboration on minimal - test cases easier for everyone. - -5. **Include a screenshot/cast as a last resort** — Is your - issue about a layout or design feature or bug that is hard to reproduce - or isolate? Then please provide a screenshot or screencast. Tools - like [LICEcap](http://www.cockos.com/licecap/) or - [SauceLabs](http://www.saucelabs.com) allow you to quickly and - easily record a screencasts. If you make it an animated gif, you can - embed it directly into your GitHub issue. - -6. Use the [Bug Report Template](#template) below or [click this - link](https://github.com/MathJax/MathJax/issues/new?title=Bug%3A&body=%23%23%23%20Issue%20Summary%0A%0A%23%23%23%20Steps%20to%20Reproduce%0A%0A1.%20This%20is%20the%20first%20step%0A%0AThis%20is%20a%20bug%20because...%0A%0A%23%23%23%20Technical%20details%0A%0A*%20MathJax%20Version%3A%20master%20-%20latest%20commit%3A%20%20INSERT%20COMMIT%20REF%0A*%20Client%20OS%3A%20%0A*%20Browser%3A%20%0A*%20) - to start creating a bug report with the template automatically. - -A good bug report shouldn't leave others needing to request -more information from you. Be sure to include the details of your environment. - - - -Template Example ([click to use](https://github.com/MathJax/MathJax/issues/new?title=Bug%3A&body=%23%23%23%20Issue%20Summary%0A%0A%23%23%23%20Steps%20to%20Reproduce%0A%0A1.%20This%20is%20the%20first%20step%0A%0AThis%20is%20a%20bug%20because...%0A%0A%23%23%23%20Technical%20details%0A%0A*%20MathJax%20Version%3A%20master%20-%20latest%20commit%3A%20%20INSERT%20COMMIT%20REF%0A*%20Client%20OS%3A%20%0A*%20Browser%3A%20%0A*%20)): - -``` -Short and descriptive example bug report title - -### Issue Summary - -A summary of the issue and the browser/OS environment in which it occurs. If -suitable, include the steps required to reproduce the bug. - -### Steps to Reproduce - -1. This is the first step -2. This is the second step -3. Further steps, etc. - -Any other information you want to share that is relevant to the issue -being reported. Especially, why do you consider this to be a bug? What -do you expect to happen instead? - -### Technical details: - -* MathJax Version: 2.3 (latest commit: f3aaf3a2a3e964df2770dc4aaaa9c87ce5f47e2c) -* Client OS: Mac OS X 10.8.4 -* Browser: Chrome 29.0.1547.57 -``` - - -### Feature Requests - -Feature requests are welcome. Before you submit one, be sure to have: - -1. **Used the GitHub search** to check that the feature hasn't already - been requested. -2. Take a moment to think about whether your idea fits with the scope - and aims of the project, or if it might better fit being a [custom - extension](https://github.com/mathjax/MathJax-third-party-extensions). -3. Remember, it's up to *you* to make a strong case to convince the - project's leaders of the merits of this feature. Please provide as - much detail and context as possible, this means explaining the use - case and why it is likely to be common. - -### Change Requests - -Change requests cover both architectural and functional changes to how -MathJax works. If you have an idea for a new or different dependency, -a refactor, or an improvement to a feature, etc., please be sure to: - -1. **Use the GitHub search** to check that someone else didn't get there first. -2. Take a moment to think about the best way to make a case for, and - explain what you're thinking. Are you sure this shouldn't really be - a [bug report](#bug-reports) or a [feature - request](#feature-requests)? Is it really one idea or is it many? - What's the context? What problem are you solving? Why is what you - are suggesting better than what's already there? - -## Working on MathJax core - -You want to contribute code? We describe how below. First, note that -the MathJax source code is in the - repository, not the - repository, which contains the -packaged component files for distribution on CDNs and the [mathjax npm -package](https://www.npmjs.com/package/mathjax) (the source code is -included in the [mathjax-full npm -package](https://www.npmjs.com/package/mathjax-full)). - -### Key Branches & Tags - -MathJax uses several permanent branches in the [MathJax source repository](https://github.com/mathjax/MathJax-src): - -- **[develop](https://github.com/mathjax/MathJax-src/tree/develop)** - is the development branch. All work on the next release happens here - so you should generally branch off `develop` if you are going to - submit a pull request. Do **NOT** use this branch for a production - site. - -- **[master](https://github.com/mathjax/MathJax-src)** contains the latest - release of MathJax. This branch may be used in production. Do - **NOT** use this branch to work on MathJax's source. - -These branches reflect version 3 of MathJax, which is substantially -different from the version 2 codebase. Version 2 will continue to be -maintained while web sites transition to version 3, with work being -done using the following branches in the [MathJax distribution -repository](https://github.com/mathjax/MathJax): - -- **[legacy-v2-develop](https://github.com/mathjax/MathJax/tree/legacy-v2-develop)** - is the development branch for changes to the legacy version 2 code. - Any pull requests for version 2 should be branched from here. Do - **NOT** use this branch for a production site. - -- **[legacy-v2](https://github.com/mathjax/MathJax/tree/legacy-v2)** - is the branch that contains any updates to version 2 following - the release of version 3. Do **NOT** use this branch to work on - MathJax's source. - -In addition to these branches, MathJax uses tags to identify the -various versions. These can be checked out to obtain the specified -release; for example, `git checkout 2.7.5` would get you the files for -version 2.7.5 of MathJax. - -Note that version 3 is written in Typescript, and so must be compiled -to obtain usable javascript files, and that the components need to be -built once that is done. See the -[documentation](https://docs.mathjax.org/en/latest/web/hosting.html#getting-mathjax-via-git) -for details. For version 2, the source javascript files are not -compressed until a release is made, so you should use the copies in -the `unpacked` directory during development. - - -### Submitting Pull Requests - -Pull requests are welcome. If you're looking to submit a PR for -something that doesn't have an open issue, please consider [raising an -issue](#reporting-an-issue) that your PR can close, especially if -you're fixing a bug. This makes it more likely that there will be -enough information available for your PR to be properly tested and -merged. - -##### Need Help? - -If you're not completely clear on how to submit/update/*do* Pull -Requests, please check out our [source control -policies](https://github.com/mathjax/MathJax/wiki/Source-control-policies). For -more insights, check the excellent in depth [Git Workflow -guide](https://github.com/TryGhost/Ghost/wiki/Git-Workflow) from -Ghost, in particular - -* [Ghost Workflow guide: commit messages](https://github.com/TryGhost/Ghost/wiki/Git-workflow#commit-messages) - -### Testing and Quality Assurance - -If you're -looking to get involved with the code base and don't know where to -start, checking out and testing a pull request is one of the most -useful things you could do. - -These are some [excellent -instructions](https://gist.github.com/piscisaureus/3342247) on -configuring your GitHub repository to allow you to checkout pull -requests in the same way as branches. - - -### Writing documentation - -MathJax's main documentation can be found at [docs.mathjax.org](http://docs.mathjax.org). -The source of the docs is hosted in the -[mathjax/MathJax-docs](http://github.com/mathjax/MathJax-docs) repo here on GitHub. - -The documentation is generated using -[Sphinx-doc](http://sphinx-doc.org/) and hosted on [Read the -docs](http://readthedocs.org). You can clone the repo and submit pull -requests following the [pull-request](#submitting-pull-requests) -guidelines. - - -### Translation - -If you wish to add or update translations of MathJax, please do it on -[TranslateWiki.net](https://translatewiki.net/w/i.php?title=Special:Translate&group=out-mathjax-0-all) -(and while you're there you can help other open source projects, -too). - -For bug reports and other questions that don't fit on -TranslateWiki.net, head over to the -[mathjax/mathjax-i18n](https://github.com/mathjax/MathJax-i18n) -repository. - -The translation files currently are for version 2, as localization -hasn't been added to version 3 yet. - -## Conduct - -As a NumFOCUS fiscally sponsored project, MathJax is governed by the -[NumFOCUS code of conduct](https://numfocus.org/code-of-conduct), -which we summarize as follows: - -We are committed to providing a friendly, safe and welcoming -environment for all, regardless of gender, sexual orientation, -disability, ethnicity, religion, or similar personal characteristic. - -Please be kind and courteous. There's no need to be mean or rude. -Respect that people have differences of opinion and that every design -or implementation choice carries a trade-off and numerous costs. There -is seldom a right answer, merely an optimal answer given a set of -values and circumstances. - -Please keep unstructured critique to a minimum. If you have solid -ideas you want to experiment with, make a fork and see how it works. - -We will exclude you from interaction if you insult, demean or harass -anyone. That is not welcome behaviour. We interpret the term -"harassment" as including the definition in the [Unacceptable -Behavior](https://numfocus.org/code-of-conduct#unacceptable-behavior) -section of the [NumFOCUS code of -conduct](https://numfocus.org/code-of-conduct); if you have any lack -of clarity about what might be included in that concept, please read -that definition. In particular, we don't tolerate behavior that -excludes people in socially marginalized groups. - -Private harassment is also unacceptable. No matter who you are, if you -feel you have been or are being harassed or made uncomfortable by a -community member, please contact one of the channel ops or any of the -[MathJax](https://github.com/MathJax/MathJax) core team -immediately. Whether you're a regular contributor or a newcomer, we -care about making this community a safe place for you and we've got -your back. - -Likewise any spamming, trolling, flaming, baiting, or other -attention-stealing behaviour is not welcome. - -We also recommend that you read [discourse's -rules](http://blog.discourse.org/2013/03/the-universal-rules-of-civilized-discourse/) -for further suggestions on appropriate behavior. - -## References - -* We heavily borrowed from Mozilla and Ghost -- thank you! - * - * -* -* diff --git a/build/pkgs/mathjax3/MathJax-3.2.0/LICENSE b/build/pkgs/mathjax3/MathJax-3.2.0/LICENSE deleted file mode 100644 index d6456956733..00000000000 --- a/build/pkgs/mathjax3/MathJax-3.2.0/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/build/pkgs/mathjax3/MathJax-3.2.0/README.md b/build/pkgs/mathjax3/MathJax-3.2.0/README.md deleted file mode 100644 index 94186007ac0..00000000000 --- a/build/pkgs/mathjax3/MathJax-3.2.0/README.md +++ /dev/null @@ -1,237 +0,0 @@ -# MathJax -## Beautiful math in all browsers - -![GitHub release version](https://img.shields.io/github/v/release/mathjax/MathJax-src.svg?sort=semver) -![GitHub release version (v2)](https://img.shields.io/github/package-json/v/mathjax/MathJax/legacy-v2.svg?label=release-v2) -![NPM version](https://img.shields.io/npm/v/mathjax.svg?style=flat) -![powered by NumFOCUS](https://img.shields.io/badge/powered%20by-NumFOCUS-orange.svg?style=flat) -![jsdelivr rank](https://flat.badgen.net/jsdelivr/rank/npm/mathjax?color=green) -![jsDelivr hits (npm)](https://img.shields.io/jsdelivr/npm/hm/mathjax) -![npm monthly downloads (full)](https://img.shields.io/npm/dm/mathjax?label=npm) -![npm total downloads](https://img.shields.io/npm/dt/mathjax.svg?style=flat&label=npm%20total) - -MathJax is an open-source JavaScript display engine for LaTeX, MathML, -and AsciiMath notation that works in all modern browsers. It was -designed with the goal of consolidating the recent advances in web -technologies into a single, definitive, math-on-the-web platform -supporting the major browsers and operating systems. It requires no -setup on the part of the user (no plugins to download or software to -install), so the page author can write web documents that include -mathematics and be confident that users will be able to view it -naturally and easily. Simply include MathJax and some mathematics in -a web page, and MathJax does the rest. - -Some of the main features of MathJax include: - -- High-quality display of LaTeX, MathML, and AsciiMath notation in HTML pages - -- Supported in most browsers with no plug-ins, extra fonts, or special - setup for the reader - -- Easy for authors, flexible for publishers, extensible for developers - -- Supports math accessibility, cut-and-paste interoperability, and other - advanced functionality - -- Powerful API for integration with other web applications - -See for additional details about MathJax, -and for the MathJax documentation. - -## MathJax Components - -MathJax version 3 uses files called *components* that contain the -various MathJax modules that you can include in your web pages or -access on a server through NodeJS. Some components combine all the -pieces you need to run MathJax with one or more input formats and a -particular output format, while other components are pieces that can -be loaded on demand when needed, or by a configuration that specifies -the pieces you want to combine in a custom way. For usage -instructions, see the [MathJax documentation](https://docs.mathjax.org). - -Components provide a convenient packaging of MathJax's modules, but it -is possible for you to form your own custom components, or to use -MathJax's modules directly in a node application on a server. There -are [web examples](https://github.com/mathjax/MathJax-demos-web) -showing how to use MathJax in web pages and how to build your own -components, and [node -examples](https://github.com/mathjax/MathJax-demos-node) illustrating -how to use components in node applications or call MathJax modules -directly. - -## What's in this Repository - -This repository contains only the component files for MathJax, not the -source code for MathJax (which are available in a separate [MathJax -source repository](https://github.com/mathjax/MathJax-src/)). These -component files are the ones served by the CDNs that offer MathJax to -the web. In version 2, the files used on the web were also the source -files for MathJax, but in version 3, the source files are no longer on -the CDN, as they are not what are run in the browser. - -The components are stored in the `es5` directory, and are in ES5 format -for the widest possible compatibility. In the future, we may make an -`es6` directory containing ES6 versions of the components. - -## Installation and Use - -### Using MathJax components from a CDN on the web - -If you are loading MathJax from a CDN into a web page, there is no -need to install anything. Simply use a `script` tag that loads -MathJax from the CDN. E.g., - -``` html - -``` - -See the [MathJax -documentation](https://docs.mathjax.org/en/latest/index.html#browser-components), -the [MathJax Web Demos](https://github.com/mathjax/MathJax-demos-web), -and the [MathJax Component -Repository](https://github.com/mathjax/MathJax-demos-web) for more information. - -### Hosting your own copy of the MathJax Components - -If you want to host MathJax from your own server, you can do so by -installing the `mathjax` package using `npm` and moving the `es5` -directory to an appropriate location on your server: - -``` bash -npm install mathjax@3 -mv node_modules/mathjax/es5 /mathjax -``` - -Note that we are still making updates to version 2, so include `@3` -when you install, since the latest chronological version may not be -version 3. - -Alternatively, you can get the files via GitHub: - -``` bash -git clone https://github.com/mathjax/MathJax.git mj-tmp -mv mj-tmp/es5 /mathjax -rm -rf mj-tmp -``` - -Then (in either case) you can use a script tag like the following: - -``` html - -``` - -where `` is replaced by the URL to the location -where you moved the MathJax files above. - -See the -[documentation](https://docs.mathjax.org/en/latest/web/hosting.html) -for details. - -### Using MathJax components in a node application - -To use MathJax components in a node application, install the `mathjax` package: - -``` bash -npm install mathjax@3 -``` - -(we are still making updates to version 2, so you should include `@3` -since the latest chronological version may not be version 3). - -Then require `mathjax` within your application: - -```js -require('mathjax').init({ ... }).then((MathJax) => { ... }); -``` - -where the first `{ ... }` is a MathJax configuration, and the second -`{ ... }` is the code to run after MathJax has been loaded. E.g. - -```js -require('mathjax').init({ - loader: {load: ['input/tex', 'output/svg']} -}).then((MathJax) => { - const svg = MathJax.tex2svg('\\frac{1}{x^2-1}', {display: true}); - console.log(MathJax.startup.adaptor.outerHTML(svg)); -}).catch((err) => console.log(err.message)); -``` - -**Note:** this technique is for node-based application only, not for -browser applications. This method sets up an alternative DOM -implementation, which you don't need in the browser, and tells MathJax -to use node's `require()` command to load external modules. This -setup will not work properly in the browser, even if you webpack it or -bundle it in other ways. - -See the -[documentation](https://docs.mathjax.org/en/latest/index.html#server-nodejs) -and the [MathJax Node -Repository](https://github.com/mathjax/MathJax-demos-node) for more details. - -## Reducing the Size of the Components Directory - -Since the `es5` directory contains *all* the component files, so if -you are only planning one use one configuration, you can reduce the -size of the MathJax directory by removing unused components. For -example, if you are using the `tex-chtml.js` component, then you can -remove the `tex-mml-chtml.js`, `tex-svg.js`, `tex-mml-svg.js`, -`tex-chtml-full.js`, and `tex-svg-full.js` configurations, which will -save considerable space. Indeed, you should be able to remove -everything other than `tex-chtml.js`, and the `input/tex/extensions`, -`output/chtml/fonts/woff-v2`, `adaptors`, `a11y`, and `sre` -directories. If you are using the results only on the web, you can -remove `adaptors` as well. - -If you are not using A11Y support (e.g., speech generation, or -semantic enrichment), then you can remove `a11y` and `sre` as well -(though in this case you may need to disable the assistive tools in -the MathJax contextual menu in order to avoid MathJax trying to load -them when they aren't there). - -If you are using SVG rather than CommonHTML output (e.g., `tex-svg.js` -rather than `tex-chtml.js`), you can remove the -`output/chtml/fonts/woff-v2` directory. If you are using MathML input -rather than TeX (e.g., `mml-chtml.js` rather than `tex-chtml.js`), -then you can remove `input/tex/extensions` as well. - - -## The Component Files and Pull Requests - -The `es5` directory is generated automatically from the contents of the -MathJax source repository. You can rebuild the components using the -command - -``` bash -npm run make-es5 --silent -``` - -Note that since the contents of this repository are generated -automatically, you should not submit pull requests that modify the -contents of the `es5` directory. If you wish to submit a modification -to MathJax, you should make a pull request in the [MathJax source -repository](https://github.com/mathjax/MathJax-src). - -## MathJax Community - -The main MathJax website is , and it includes -announcements and other important information. A [MathJax user -forum](http://groups.google.com/group/mathjax-users) for asking -questions and getting assistance is hosted at Google, and the [MathJax -bug tracker](https://github.com/mathjax/MathJax/issues) is hosted -at GitHub. - -Before reporting a bug, please check that it has not already been -reported. Also, please use the bug tracker (rather than the help -forum) for reporting bugs, and use the user's forum (rather than the -bug tracker) for questions about how to use MathJax. - -## MathJax Resources - -* [MathJax Documentation](https://docs.mathjax.org) -* [MathJax Components](https://github.com/mathjax/MathJax) -* [MathJax Source Code](https://github.com/mathjax/MathJax-src) -* [MathJax Web Examples](https://github.com/mathjax/MathJax-demos-web) -* [MathJax Node Examples](https://github.com/mathjax/MathJax-demos-node) -* [MathJax Bug Tracker](https://github.com/mathjax/MathJax/issues) -* [MathJax Users' Group](http://groups.google.com/group/mathjax-users) - diff --git a/build/pkgs/mathjax3/MathJax-3.2.0/bower.json b/build/pkgs/mathjax3/MathJax-3.2.0/bower.json deleted file mode 100644 index 6b214b933ea..00000000000 --- a/build/pkgs/mathjax3/MathJax-3.2.0/bower.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "MathJax", - "main": "./MathJax.js", - "homepage": "http://www.mathjax.org/", - "ignore": [ - "**/.*", - "node_modules", - "components" - ], - "keywords": ["math", "js", "LaTeX", "MathML", "AsciiMath"] -} diff --git a/build/pkgs/mathjax3/MathJax-3.2.0/composer.json b/build/pkgs/mathjax3/MathJax-3.2.0/composer.json deleted file mode 100644 index b1b9d27aed6..00000000000 --- a/build/pkgs/mathjax3/MathJax-3.2.0/composer.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "mathjax/mathjax", - "type": "library", - "description": "MathJax is an open-source JavaScript display engine for LaTeX, MathML, and AsciiMath notation that works in all modern browsers.", - "keywords": ["math", "js", "LaTeX", "MathML", "AsciiMath"], - "homepage": "http://www.mathjax.org/", - "license": "Apache-2.0", - "authors": [ - { - "name": "MathJax Consortium", - "homepage": "https://github.com/mathjax" - } - ] -} diff --git a/build/pkgs/mathjax3/MathJax-3.2.0/package.json b/build/pkgs/mathjax3/MathJax-3.2.0/package.json deleted file mode 100644 index 6706949557b..00000000000 --- a/build/pkgs/mathjax3/MathJax-3.2.0/package.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "name": "mathjax", - "version": "3.2.0", - "description": "Beautiful and accessible math in all browsers. MathJax is an open-source JavaScript display engine for LaTeX, MathML, and AsciiMath notation that works in all browsers. This package includes the packaged components (install mathjax-full to get the source code).", - "keywords": [ - "math", - "svg", - "mathml", - "tex", - "latex", - "asciimath", - "browser", - "node" - ], - "devDependencies": { - "mathjax-full": "3.2.0" - }, - "maintainers": [ - "MathJax Consortium (http://www.mathjax.org)" - ], - "bugs": { - "url": "http://github.com/mathjax/MathJax/issues" - }, - "license": "Apache-2.0", - "repository": { - "type": "git", - "url": "git://github.com/mathjax/MathJax.git" - }, - "main": "es5/node-main.js", - "files": [ - "/es5" - ], - "scripts": { - "test": "echo 'No tests defined'", - "clean": "npm run --silent clean:es5 && npm run --silent clean:node", - "clean:es5": "rm -rf es5", - "clean:node": "rm -rf node_modules package-lock.json", - "message": "echo \"$(tput setaf 4)${npm_package_config_message}$(tput setaf 0)\" && echo", - "line": "echo '--------------------------------------------'", - "title": "npm run --silent line && npm run --silent message --mathjax:message=\"${npm_package_config_title}\"", - "preinstall:mj3": "npm run --silent title --mathjax:title='Installing MathJax...'", - "install:mj3": "npm install", - "preinstall:mj3-deps": "npm run --silent message --mathjax:message='Installing MathJax Dependencies...'", - "install:mj3-deps": "cd node_modules/mathjax-full && npm install", - "install:all": "npm run --silent install:mj3 && npm run --silent install:mj3-deps", - "precompile": "npm run --silent title --mathjax:title='Compiling MathJax...'", - "compile": "cd node_modules/mathjax-full && npm run --silent compile", - "precomponents": "npm run --silent title --mathjax:title='Building MathJax Components...'", - "components": "cd node_modules/mathjax-full && npm run --silent make-components", - "premove": "npm run --silent title --mathjax:title='Moving MathJax Components...'", - "move": "npm run --silent clean:es5 && mv node_modules/mathjax-full/es5 .", - "premake-es5": "npm run --silent clean:node", - "make-es5": "npm run --silent install:all && npm run --silent compile && npm run --silent components && npm run --silent move", - "postmake-es5": "npm run --silent title --mathjax:title='Cleaning Up...' && npm run --silent clean:node", - "preget-es5": "npm run --silent clean:node", - "get-es5": "npm run --silent install:mj3 && npm run --silent move", - "postget-es5": "npm run --silent title --mathjax:title='Cleaning Up...' && npm run --silent clean:node" - } -} diff --git a/build/pkgs/mathjax3/checksums.ini b/build/pkgs/mathjax3/checksums.ini index 4ffadfb32b1..c46436941ad 100644 --- a/build/pkgs/mathjax3/checksums.ini +++ b/build/pkgs/mathjax3/checksums.ini @@ -1,4 +1,4 @@ tarball=mathjax-VERSION.tar.gz -sha1=4fec236527498c480b92032afe36d06d2741973c -md5=6eb4395cd91b71be846623d30a9bff70 -cksum=2042371852 +sha1=60445ab91fdec88b5bff750e604adca1defe0019 +md5=84145ea49e91b5317385705d37060c4e +cksum=3733185847 diff --git a/build/pkgs/mathjax3/spkg-src b/build/pkgs/mathjax3/spkg-src index dadb1411c6f..266e5e2554d 100755 --- a/build/pkgs/mathjax3/spkg-src +++ b/build/pkgs/mathjax3/spkg-src @@ -20,6 +20,7 @@ else fi mv MathJax-${GIT_VERSION}/es5 src +rm -r MathJax-${GIT_VERSION} PACKAGE_VERSION=${GIT_VERSION} From 321c8b5ae2ba3265e803c77c9b66d43f8dace092 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Thu, 7 Apr 2022 16:32:34 +0900 Subject: [PATCH 096/529] Put into mathjax subdirectory --- build/pkgs/mathjax3/checksums.ini | 6 +++--- build/pkgs/mathjax3/spkg-src | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/build/pkgs/mathjax3/checksums.ini b/build/pkgs/mathjax3/checksums.ini index c46436941ad..2cfe5869dd5 100644 --- a/build/pkgs/mathjax3/checksums.ini +++ b/build/pkgs/mathjax3/checksums.ini @@ -1,4 +1,4 @@ tarball=mathjax-VERSION.tar.gz -sha1=60445ab91fdec88b5bff750e604adca1defe0019 -md5=84145ea49e91b5317385705d37060c4e -cksum=3733185847 +sha1=ed325638d807fac93e4b1b9d052e2a72164bbaba +md5=7a78a9e649f69a295ad11cb476857cd5 +cksum=1951447424 diff --git a/build/pkgs/mathjax3/spkg-src b/build/pkgs/mathjax3/spkg-src index 266e5e2554d..bf5d7e4144b 100755 --- a/build/pkgs/mathjax3/spkg-src +++ b/build/pkgs/mathjax3/spkg-src @@ -4,7 +4,6 @@ set -e [ -n "${SAGE_ROOT}" ] || SAGE_ROOT="$(pwd)/../../../" - # determine latest version. GIT_VERSION="$(curl https://github.com/mathjax/MathJax/releases | grep 'MathJax v' | head -1 | sed 's|^.*MathJax v||g' | sed 's/\s*$//g')" echo "GIT_VERSION=$GIT_VERSION" @@ -19,9 +18,11 @@ else tar xzf "$UPSTREAM_SOURCE_TARBALL" fi -mv MathJax-${GIT_VERSION}/es5 src +mkdir src +mv MathJax-${GIT_VERSION}/es5 src/mathjax rm -r MathJax-${GIT_VERSION} + PACKAGE_VERSION=${GIT_VERSION} # repack From 7cc5eb75f791eabf5a594e9fc548d324fb23d7ac Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Thu, 7 Apr 2022 16:48:21 +0900 Subject: [PATCH 097/529] Build doc with mathjax3 (default: offline) --- build/pkgs/mathjax3/spkg-src | 1 - src/sage/docs/conf.py | 19 ++++++++++--------- src/sage/env.py | 2 +- src/sage_docbuild/__init__.py | 13 ++++++++++++- 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/build/pkgs/mathjax3/spkg-src b/build/pkgs/mathjax3/spkg-src index bf5d7e4144b..b20462e48d1 100755 --- a/build/pkgs/mathjax3/spkg-src +++ b/build/pkgs/mathjax3/spkg-src @@ -22,7 +22,6 @@ mkdir src mv MathJax-${GIT_VERSION}/es5 src/mathjax rm -r MathJax-${GIT_VERSION} - PACKAGE_VERSION=${GIT_VERSION} # repack diff --git a/src/sage/docs/conf.py b/src/sage/docs/conf.py index e9730488d12..828d50c6064 100644 --- a/src/sage/docs/conf.py +++ b/src/sage/docs/conf.py @@ -1,7 +1,7 @@ import sys import os import sphinx -from sage.env import SAGE_DOC_SRC, SAGE_DOC, THEBE_DIR, PPLPY_DOCS, MATHJAX_DIR +from sage.env import SAGE_SHARE, SAGE_DOC_SRC, SAGE_DOC, THEBE_DIR, PPLPY_DOCS from sage.misc.latex_macros import sage_mathjax_macros import sage.version from sage.misc.sagedoc import extlinks @@ -284,16 +284,17 @@ def set_intersphinx_mappings(app, config): "autoload": {"color": [], "colorv2": ["color"]}, }, } -mathjax_path = "https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js" -mathjax_relative = os.path.basename(MATHJAX_DIR) +if os.environ.get('SAGE_OFFLINE_DOC', 'no') == 'yes': + mathjax_path = 'mathjax/tex-chtml.js' + html_common_static_path += [os.path.join(SAGE_SHARE, 'mathjax3')] +else: + mathjax_path = "https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js" -# It would be really nice if sphinx would copy the entire mathjax -# directory, (so we could have a _static/mathjax directory), rather than -# the contents of the directory -html_common_static_path.append(MATHJAX_DIR) -exclude_patterns += ['**/' + os.path.join(mathjax_relative, i) - for i in ('docs', 'README*', 'test', 'unpacked', 'LICENSE')] +# A list of glob-style patterns that should be excluded when looking for source +# files. They are matched against the source file names relative to the +# source directory, using slashes as directory separators on all platforms. +exclude_patterns = [] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. diff --git a/src/sage/env.py b/src/sage/env.py index 1b8aacc87b1..98d1e520eb2 100644 --- a/src/sage/env.py +++ b/src/sage/env.py @@ -203,7 +203,7 @@ def var(key: str, *fallbacks: Optional[str], force: bool = False) -> Optional[st CREMONA_MINI_DATA_DIR = var("CREMONA_MINI_DATA_DIR", join(SAGE_SHARE, "cremona")) CREMONA_LARGE_DATA_DIR = var("CREMONA_LARGE_DATA_DIR", join(SAGE_SHARE, "cremona")) JMOL_DIR = var("JMOL_DIR", join(SAGE_SHARE, "jmol")) -MATHJAX_DIR = var("MATHJAX_DIR", join(SAGE_SHARE, "mathjax")) +MATHJAX_DIR = var("MATHJAX_DIR", join(SAGE_SHARE, "mathjax3")) MTXLIB = var("MTXLIB", join(SAGE_SHARE, "meataxe")) THREEJS_DIR = var("THREEJS_DIR", join(SAGE_SHARE, "threejs-sage")) PPLPY_DOCS = var("PPLPY_DOCS", join(SAGE_SHARE, "doc", "pplpy")) diff --git a/src/sage_docbuild/__init__.py b/src/sage_docbuild/__init__.py index 75978e7c63d..fd61ef9b268 100644 --- a/src/sage_docbuild/__init__.py +++ b/src/sage_docbuild/__init__.py @@ -47,6 +47,7 @@ import time import types import warnings +from pathlib import Path import sphinx.util.console import sphinx.ext.intersphinx @@ -54,7 +55,7 @@ import sage.all from sage.misc.cachefunc import cached_method # Do not import SAGE_DOC globally as it interferes with doctesting with a random replacement -from sage.env import SAGE_DOC_SRC, SAGE_SRC, DOT_SAGE +from sage.env import SAGE_SHARE, SAGE_DOC_SRC, SAGE_SRC, DOT_SAGE from .build_options import (LANGUAGES, SPHINXOPTS, OMIT, ALLSPHINXOPTS, NUM_THREADS, WEBSITESPHINXOPTS, @@ -153,6 +154,11 @@ def f(self, *args, **kwds): if ABORT_ON_ERROR: raise Exception("Non-exception during docbuild: %s" % (e,), e) +# if type == 'html' and os.environ.get('SAGE_OFFLINE_DOC', 'no') == 'yes': +# if Path(self.dir).parent.parent.name == 'doc': +# logger.warning("Copying mathjax files...") +# shutil.copytree(os.path.join(SAGE_SHARE, 'mathjax3'), output_dir) + if "/latex" in output_dir: logger.warning("LaTeX file written to {}".format(output_dir)) else: @@ -1576,6 +1582,9 @@ def setup_parser(): standard.add_argument("-N", "--no-colors", dest="color", action="store_false", help="do not color output; does not affect children") + standard.add_argument("--offline-doc", dest="offline_doc", default=True, + action="store_true", + help="do not assume internet connection; in particular, do not use MathJax CDN") standard.add_argument("-q", "--quiet", dest="verbose", action="store_const", const=0, help="work quietly; same as --verbose=0") @@ -1741,6 +1750,8 @@ def excepthook(*exc_info): os.environ['SAGE_SKIP_PLOT_DIRECTIVE'] = 'yes' if args.skip_tests: os.environ['SAGE_SKIP_TESTS_BLOCKS'] = 'True' + if args.offline_doc: + os.environ['SAGE_OFFLINE_DOC'] = 'yes' ABORT_ON_ERROR = not args.keep_going From c92b6c0bc236152687c2b9b03a20941901bb4057 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Thu, 7 Apr 2022 17:07:27 +0900 Subject: [PATCH 098/529] Remove commented-out lines --- src/sage_docbuild/__init__.py | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/sage_docbuild/__init__.py b/src/sage_docbuild/__init__.py index fd61ef9b268..5161009da35 100644 --- a/src/sage_docbuild/__init__.py +++ b/src/sage_docbuild/__init__.py @@ -47,7 +47,6 @@ import time import types import warnings -from pathlib import Path import sphinx.util.console import sphinx.ext.intersphinx @@ -154,11 +153,6 @@ def f(self, *args, **kwds): if ABORT_ON_ERROR: raise Exception("Non-exception during docbuild: %s" % (e,), e) -# if type == 'html' and os.environ.get('SAGE_OFFLINE_DOC', 'no') == 'yes': -# if Path(self.dir).parent.parent.name == 'doc': -# logger.warning("Copying mathjax files...") -# shutil.copytree(os.path.join(SAGE_SHARE, 'mathjax3'), output_dir) - if "/latex" in output_dir: logger.warning("LaTeX file written to {}".format(output_dir)) else: @@ -1579,12 +1573,12 @@ def setup_parser(): standard.add_argument("--no-prune-empty-dirs", dest="no_prune_empty_dirs", action="store_true", help="do not prune empty directories in the documentation sources") - standard.add_argument("-N", "--no-colors", dest="color", - action="store_false", - help="do not color output; does not affect children") standard.add_argument("--offline-doc", dest="offline_doc", default=True, action="store_true", help="do not assume internet connection; in particular, do not use MathJax CDN") + standard.add_argument("-N", "--no-colors", dest="color", + action="store_false", + help="do not color output; does not affect children") standard.add_argument("-q", "--quiet", dest="verbose", action="store_const", const=0, help="work quietly; same as --verbose=0") From bac4ef1320779fac2c418e22d4ae4247b2c1c215 Mon Sep 17 00:00:00 2001 From: Vincent Delecroix <20100.delecroix@gmail.com> Date: Thu, 7 Apr 2022 11:37:42 +0200 Subject: [PATCH 099/529] 33652: transpose and left eigenvectors for acb_mat --- src/sage/matrix/matrix_complex_ball_dense.pyx | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/src/sage/matrix/matrix_complex_ball_dense.pyx b/src/sage/matrix/matrix_complex_ball_dense.pyx index 1d8c85f1137..76668a01110 100644 --- a/src/sage/matrix/matrix_complex_ball_dense.pyx +++ b/src/sage/matrix/matrix_complex_ball_dense.pyx @@ -551,6 +551,26 @@ cdef class Matrix_complex_ball_dense(Matrix_dense): else: raise ZeroDivisionError("unable to compute the inverse, is the matrix singular?") + def transpose(self): + r""" + Returns the transpose of ``self``. + + EXAMPLES:: + + sage: m = matrix(CBF, 2, 3, [1, 2, 3, 4, 5, 6]) + sage: m.transpose() + [1.000000000000000 4.000000000000000] + [2.000000000000000 5.000000000000000] + [3.000000000000000 6.000000000000000] + sage: m.transpose().parent() + Full MatrixSpace of 3 by 2 dense matrices over Complex ball field with 53 bits of precision + """ + cdef Py_ssize_t nc = self._ncols + cdef Py_ssize_t nr = self._nrows + cdef Matrix_complex_ball_dense trans = self._new_matrix(nc, nr) + acb_mat_transpose(trans.value, self.value) + return trans + def _solve_right_nonsingular_square(self, Matrix_complex_ball_dense rhs, check_rank=None): r""" TESTS:: @@ -849,6 +869,82 @@ cdef class Matrix_complex_ball_dense(Matrix_dense): _acb_vec_clear(eigval_approx, n) return [(l, [v], 1) for l, v in zip(eigval, eigvec.columns())] + def eigenvectors_left_approx(self, other=None, *, extend=None): + r""" + (Experimental.) Compute *non-rigorous* approximations of the + left eigenvalues and eigenvectors of this matrix. + + INPUT: + + - ``self`` -- an `n \times n` matrix + - ``other`` -- unsupported (generalized eigenvalue problem), should be ``None`` + - ``extend`` -- ignored + + OUTPUT: + + A list of triples of the form ``(eigenvalue, [eigenvector], 1)``. The + eigenvalue and the entries of the eigenvector are complex balls with + zero radius. + + No guarantees are made about the accuracy of the output. + + See the `Arb documentation `__ + for more information. + + EXAMPLES:: + + sage: mat = matrix(CBF, 3, [2, 3, 5, 7, 11, 13, 17, 19, 23]) + sage: eigval, eigvec, _ = mat.eigenvectors_left_approx()[0] + sage: eigval + [1.1052996349... +/- ...] + sage: eigvec[0] + ([0.69817246751...], [-0.67419514369...], [0.240865343781...]) + sage: eigvec[0] * (mat - eigval) + ([+/- ...], [+/- ...], [+/- ...]) + + .. SEEALSO:: :meth:`eigenvectors_left` + """ + return self.transpose().eigenvectors_right_approx(other=None, extend=extend) + + def eigenvectors_left(self, other=None, *, extend=True): + r""" + (Experimental.) Compute rigorous enclosures of the eigenvalues and + left eigenvectors of this matrix. + + INPUT: + + - ``self`` -- an `n \times n` matrix + - ``other`` -- unsupported (generalized eigenvalue problem), should be ``None`` + - ``extend`` -- ignored + + OUTPUT: + + A list of triples of the form ``(eigenvalue, [eigenvector], 1)``. + + Unlike :meth:`eigenvalues` and :meth:`eigenvectors_right_approx`, this + method currently fails in the presence of multiple eigenvalues. + + Additionally, there is currently no guarantee that the algorithm + converges as the working precision is increased. + + See the `Arb documentation `__ + for more information. + + EXAMPLES:: + + sage: mat = matrix(CBF, 3, [2, 3, 5, 7, 11, 13, 17, 19, 23]) + sage: eigval, eigvec, _ = mat.eigenvectors_left()[0] + sage: eigval + [1.1052996349...] + [+/- ...]*I + sage: eigvec[0] + ([0.69817246751...] + [+/- ...]*I, [-0.67419514369...] + [+/- ...]*I, [0.240865343781...] + [+/- ...]*I) + sage: eigvec[0] * (mat - eigval) + ([+/- ...] + [+/- ...]*I, [+/- ...] + [+/- ...]*I, [+/- ...] + [+/- ...]*I) + + .. SEEALSO:: :meth:`eigenvectors_right`, :meth:`eigenvalues`, :meth:`eigenvectors_left_approx` + """ + return self.transpose().eigenvectors_right(other=other, extend=extend) + def exp(self): r""" Compute the exponential of this matrix. From 0add420904a558e029ced8d17a730ac9b6448315 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Thu, 7 Apr 2022 22:52:14 +0900 Subject: [PATCH 100/529] Some edits --- src/doc/en/installation/launching.rst | 10 +++++----- src/sage/repl/ipython_kernel/install.py | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/doc/en/installation/launching.rst b/src/doc/en/installation/launching.rst index ebc6f864178..acbc377fcba 100644 --- a/src/doc/en/installation/launching.rst +++ b/src/doc/en/installation/launching.rst @@ -95,13 +95,13 @@ This is a final nicety that lets you start the Jupyter or JupyterLab server in o * Open Windows explorer, and type ``%APPDATA%\Microsoft\Windows\Start Menu\Programs`` in the address bar and press enter. This is the folder that contains you start menu shortcuts. If you want the sage shortcut somewhere else (like your desktop), open that folder instead. * Open a separate window and go to ``%LOCALAPPDATA%\Microsoft\WindowsApps\`` -* Right-click-drag the ``ubuntu.exe`` icon from the second window into the first, then choose ``Create shortcuts here`` from the context menu when you drop it. +* Right-click-drag the ``ubuntu.exe`` icon from the second window into the first, then choose ``Create shortcuts here`` from the context menu when you drop it. * To customize this shortcut, right-click on it and choose properties. * On the General tab: * Change the name to whatever you want, e.g. "Sage 9.2 JupyterLab" - + * On the Shortcut tab: * Change Target to: ``ubuntu.exe run ~/sage_nb.sh`` @@ -136,14 +136,14 @@ to find the location of the SageMath kernel description. Now pick a name for the kernel that identifies it clearly and uniquely. For example, if you install Sage from source tarballs, you could decide -include the version number in the name, such as ``sagemath-9.6``. -If you build Sage from a clone of the git repository, it is better to +to include the version number in the name, such as ``sagemath-9.6``. +If you build SageMath from a clone of the git repository, it is better to choose a name that identifies the directory, perhaps ``sagemath-dev`` or ``sagemath-teaching`` because the version will change. Now assuming that the Jupyter notebook can be started by typing ``jupyter notebook``, the following command will install SageMath as a -new kernel. +new kernel named ``sagemath-dev``. .. CODE-BLOCK:: bash diff --git a/src/sage/repl/ipython_kernel/install.py b/src/sage/repl/ipython_kernel/install.py index 76d73c3f94d..684139afb66 100644 --- a/src/sage/repl/ipython_kernel/install.py +++ b/src/sage/repl/ipython_kernel/install.py @@ -263,14 +263,14 @@ def check(cls): spec = get_kernel_spec(ident) except NoSuchKernel: warnings.warn(f'no kernel named {ident} is accessible; ' - 'check your Jupyter configuration ' - '(see https://docs.jupyter.org/en/latest/use/jupyter-directories.html)') + 'check your Jupyter configuration ' + '(see https://docs.jupyter.org/en/latest/use/jupyter-directories.html)') else: from pathlib import Path if Path(spec.argv[0]).resolve() != Path(os.path.join(SAGE_VENV, 'bin', 'sage')).resolve(): warnings.warn(f'the kernel named {ident} does not seem to correspond to this ' - 'installation of SageMath; check your Jupyter configuration ' - '(see https://docs.jupyter.org/en/latest/use/jupyter-directories.html)') + 'installation of SageMath; check your Jupyter configuration ' + '(see https://docs.jupyter.org/en/latest/use/jupyter-directories.html)') def have_prerequisites(debug=True): From dd05cc2bda4fdfb8d9b2205838ac3fc898b80ca8 Mon Sep 17 00:00:00 2001 From: Jonathan Kliem Date: Thu, 7 Apr 2022 15:53:02 +0200 Subject: [PATCH 101/529] expose algorithm --- src/sage/geometry/polyhedron/base3.py | 36 ++++- src/sage/geometry/polyhedron/base4.py | 16 +- .../combinatorial_polyhedron/base.pxd | 3 +- .../combinatorial_polyhedron/base.pyx | 149 +++++++++++++----- .../face_iterator.pyx | 2 +- 5 files changed, 153 insertions(+), 53 deletions(-) diff --git a/src/sage/geometry/polyhedron/base3.py b/src/sage/geometry/polyhedron/base3.py index 1ba89ade3a1..f581cbd2326 100644 --- a/src/sage/geometry/polyhedron/base3.py +++ b/src/sage/geometry/polyhedron/base3.py @@ -781,8 +781,8 @@ def facets(self): return () return self.faces(self.dimension()-1) - @cached_method(do_pickle=True) - def f_vector(self, num_threads=None, parallelization_depth=None): + @cached_method(do_pickle=True, key=lambda self, x, y, z: None) + def f_vector(self, num_threads=None, parallelization_depth=None, algorithm=None): r""" Return the f-vector. @@ -794,6 +794,12 @@ def f_vector(self, num_threads=None, parallelization_depth=None): - ``parallelization_depth`` -- integer (optional); specify how deep in the lattice the parallelization is done + - ``algorithm`` -- string (optional); + specify whether the face iterator starts with facets or vertices: + * ``'primal'`` -- start with the facets + * ``'dual'`` -- start with the vertices + * ``None`` -- choose automatically + OUTPUT: Return a vector whose `i`-th entry is the number of @@ -849,7 +855,7 @@ def f_vector(self, num_threads=None, parallelization_depth=None): sage: Q.f_vector.is_in_cache() True """ - return self.combinatorial_polyhedron().f_vector(num_threads, parallelization_depth) + return self.combinatorial_polyhedron().f_vector(num_threads, parallelization_depth, algorithm=algorithm) def bounded_edges(self): """ @@ -879,10 +885,18 @@ def bounded_edges(self): yield (obj[i], obj[j]) @cached_method - def vertex_adjacency_matrix(self): + def vertex_adjacency_matrix(self, algorithm=None): """ Return the binary matrix of vertex adjacencies. + INPUT: + + - ``algorithm`` -- string (optional); + specify whether the face iterator starts with facets or vertices: + * ``'primal'`` -- start with the facets + * ``'dual'`` -- start with the vertices + * ``None`` -- choose automatically + EXAMPLES:: sage: polytopes.simplex(4).vertex_adjacency_matrix() @@ -1003,15 +1017,23 @@ def vertex_adjacency_matrix(self): sage: P.adjacency_matrix().is_immutable() True """ - return self.combinatorial_polyhedron().vertex_adjacency_matrix() + return self.combinatorial_polyhedron().vertex_adjacency_matrix(algorithm=algorithm) adjacency_matrix = vertex_adjacency_matrix @cached_method - def facet_adjacency_matrix(self): + def facet_adjacency_matrix(self, algorithm=None): """ Return the adjacency matrix for the facets. + INPUT: + + - ``algorithm`` -- string (optional); + specify whether the face iterator starts with facets or vertices: + * ``'primal'`` -- start with the facets + * ``'dual'`` -- start with the vertices + * ``None`` -- choose automatically + EXAMPLES:: sage: s4 = polytopes.simplex(4, project=True) @@ -1053,7 +1075,7 @@ def facet_adjacency_matrix(self): [1 0 1] [1 1 0] """ - return self.combinatorial_polyhedron().facet_adjacency_matrix() + return self.combinatorial_polyhedron().facet_adjacency_matrix(algorithm=algorithm) def a_maximal_chain(self): r""" diff --git a/src/sage/geometry/polyhedron/base4.py b/src/sage/geometry/polyhedron/base4.py index 51efa9586c0..b49bb349e87 100644 --- a/src/sage/geometry/polyhedron/base4.py +++ b/src/sage/geometry/polyhedron/base4.py @@ -139,11 +139,23 @@ def vertex_facet_graph(self, labels=True): """ return self.combinatorial_polyhedron().vertex_facet_graph(names=labels) - def vertex_graph(self): + def vertex_graph(self, **kwds): """ Return a graph in which the vertices correspond to vertices of the polyhedron, and edges to edges. + INPUT: + + - ``names`` -- boolean (default: ``True``); if ``False``, + then the nodes of the graph are labeld by the + indices of the Vrepresentation + + - ``algorithm`` -- string (optional); + specify whether the face iterator starts with facets or vertices: + * ``'primal'`` -- start with the facets + * ``'dual'`` -- start with the vertices + * ``None`` -- choose automatically + ..NOTE:: The graph of a polyhedron with lines has no vertices, @@ -184,7 +196,7 @@ def vertex_graph(self): sage: polytopes.simplex(1).graph().edges() [(A vertex at (0, 1), A vertex at (1, 0), None)] """ - return self.combinatorial_polyhedron().vertex_graph() + return self.combinatorial_polyhedron().vertex_graph(**kwds) graph = vertex_graph diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pxd b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pxd index 94de99c4036..7c2a14192da 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pxd +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pxd @@ -51,13 +51,14 @@ cdef class CombinatorialPolyhedron(SageObject): cdef ListOfFaces bitrep_facets(self) cdef ListOfFaces bitrep_Vrep(self) cdef tuple far_face_tuple(self) + cdef int _algorithm_to_dual(self, algorithm) except -2 # Methods to obtain a different combinatorial polyhedron. cpdef CombinatorialPolyhedron dual(self) cpdef CombinatorialPolyhedron pyramid(self, new_vertex=*, new_facet=*) cdef FaceIterator _face_iter(self, bint dual, int dimension) - cdef int _compute_f_vector(self, size_t num_threads, size_t parallelization_depth) except -1 + cdef int _compute_f_vector(self, size_t num_threads, size_t parallelization_depth, int dual) except -1 cdef inline int _compute_edges(self, dual) except -1: return self._compute_edges_or_ridges(dual, True) diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx index 7546330d8ec..dd86be3dc44 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx @@ -1158,12 +1158,33 @@ cdef class CombinatorialPolyhedron(SageObject): return incidence_matrix - def edges(self, names=True): + cdef int _algorithm_to_dual(self, algorithm) except -2: + if algorithm == 'primal': + return 0 + elif algorithm == 'dual': + if not self.is_bounded(): + raise ValueError("dual algorithm only available for bounded polyhedra") + return 1 + elif algorithm is None: + return -1 + else: + raise ValueError("algorithm must be 'primal', 'dual' or None") + + def edges(self, names=True, algorithm=None): r""" Return the edges of the polyhedron, i.e. the rank 1 faces. - If ``names`` is set to ``False``, then the Vrepresentatives in the edges - are given by their indices in the Vrepresentation. + INPUT: + + - ``names`` -- boolean (default: ``True``); if ``True``, + then the Vrepresentatives in the edges are given by + their indices in the Vrepresentation + + - ``algorithm`` -- string (optional); + specify whether the face iterator starts with facets or vertices: + * ``'primal'`` -- start with the facets + * ``'dual'`` -- start with the vertices + * ``None`` -- choose automatically .. NOTE:: @@ -1213,7 +1234,7 @@ cdef class CombinatorialPolyhedron(SageObject): ('a', 'c'), ('a', 'b')) """ - self._compute_edges(-1) + self._compute_edges(self._algorithm_to_dual(algorithm)) # Mapping the indices of the Vrep to the names, if requested. if self.Vrep() is not None and names is True: @@ -1232,13 +1253,22 @@ cdef class CombinatorialPolyhedron(SageObject): cdef size_t j return tuple((vertex_one(j), vertex_two(j)) for j in range(self._n_edges)) - def vertex_graph(self, names=True): + def vertex_graph(self, names=True, algorithm=None): r""" Return a graph in which the vertices correspond to vertices of the polyhedron, and edges to bounded rank 1 faces. - If ``names`` is set to ``False``, the Vrepresentatives will - carry names according to the indexing of the Vrepresentation. + INPUT: + + - ``names`` -- boolean (default: ``True``); if ``False``, + then the nodes of the graph are labeld by the + indices of the Vrepresentation + + - ``algorithm`` -- string (optional); + specify whether the face iterator starts with facets or vertices: + * ``'primal'`` -- start with the facets + * ``'dual'`` -- start with the vertices + * ``None`` -- choose automatically EXAMPLES:: @@ -1258,7 +1288,7 @@ cdef class CombinatorialPolyhedron(SageObject): vertices = self.vertices(names=names) # Getting the bounded edges. - edges = tuple(edge for edge in self.edges(names=names) + edges = tuple(edge for edge in self.edges(names=names, algorithm=algorithm) if edge[0] in vertices and edge[1] in vertices) return Graph([vertices, edges], format="vertices_and_edges") @@ -1266,10 +1296,18 @@ cdef class CombinatorialPolyhedron(SageObject): graph = vertex_graph @cached_method - def vertex_adjacency_matrix(self): + def vertex_adjacency_matrix(self, algorithm=None): """ Return the binary matrix of vertex adjacencies. + INPUT: + + - ``algorithm`` -- string (optional); + specify whether the face iterator starts with facets or vertices: + * ``'primal'`` -- start with the facets + * ``'dual'`` -- start with the vertices + * ``None`` -- choose automatically + .. SEEALSO:: :meth:`~sage.geometry.polyhedron.base.Polyhedron_base.vertex_adjacency_matrix`. @@ -1303,7 +1341,7 @@ cdef class CombinatorialPolyhedron(SageObject): ZZ, self.n_Vrepresentation(), self.n_Vrepresentation(), 0) cdef size_t i, a, b - self._compute_edges(-1) + self._compute_edges(self._algorithm_to_dual(algorithm)) for i in range(self._n_edges): a = self._get_edge(self._edges, i, 0) b = self._get_edge(self._edges, i, 1) @@ -1312,7 +1350,7 @@ cdef class CombinatorialPolyhedron(SageObject): adjacency_matrix.set_immutable() return adjacency_matrix - def ridges(self, add_equations=False, names=True, add_equalities=False): + def ridges(self, add_equations=False, names=True, add_equalities=False, algorithm=None): r""" Return the ridges. @@ -1329,7 +1367,14 @@ cdef class CombinatorialPolyhedron(SageObject): - ``add_equations`` -- if ``True``, then equations of the polyhedron will be added (only applicable when ``names`` is ``True``) - - ``names`` -- if ``False``, then the facets are given by their indices + - ``names`` -- boolean (default: `True`); + if ``False``, then the facets are given by their indices + + - ``algorithm`` -- string (optional); + specify whether the face iterator starts with facets or vertices: + * ``'primal'`` -- start with the facets + * ``'dual'`` -- start with the vertices + * ``None`` -- choose automatically .. NOTE:: @@ -1413,7 +1458,7 @@ cdef class CombinatorialPolyhedron(SageObject): from sage.misc.superseded import deprecation deprecation(31834, "the keyword ``add_equalities`` is deprecated; use ``add_equations``", 3) add_equations = True - self._compute_ridges(-1) + self._compute_ridges(self._algorithm_to_dual(algorithm)) n_ridges = self._n_ridges # Mapping the indices of the Vepr to the names, if requested. @@ -1442,10 +1487,18 @@ cdef class CombinatorialPolyhedron(SageObject): for i in range(n_ridges)) @cached_method - def facet_adjacency_matrix(self): + def facet_adjacency_matrix(self, algorithm=None): """ Return the binary matrix of facet adjacencies. + INPUT: + + - ``algorithm`` -- string (optional); + specify whether the face iterator starts with facets or vertices: + * ``'primal'`` -- start with the facets + * ``'dual'`` -- start with the vertices + * ``None`` -- choose automatically + .. SEEALSO:: :meth:`~sage.geometry.polyhedron.base.Polyhedron_base.vertex_adjacency_matrix`. @@ -1477,7 +1530,7 @@ cdef class CombinatorialPolyhedron(SageObject): ZZ, self.n_facets(), self.n_facets(), 0) cdef size_t i, a, b - self._compute_ridges(-1) + self._compute_ridges(self._algorithm_to_dual(algorithm)) for i in range(self._n_ridges): a = self._get_edge(self._ridges, i, 0) b = self._get_edge(self._ridges, i, 1) @@ -1486,13 +1539,21 @@ cdef class CombinatorialPolyhedron(SageObject): adjacency_matrix.set_immutable() return adjacency_matrix - def facet_graph(self, names=True): + def facet_graph(self, names=True, algorithm=None): r""" Return the facet graph. The facet graph of a polyhedron consists of ridges as edges and facets as vertices. + INPUT: + + - ``algorithm`` -- string (optional); + specify whether the face iterator starts with facets or vertices: + * ``'primal'`` -- start with the facets + * ``'dual'`` -- start with the vertices + * ``None`` -- choose automatically + If ``names`` is ``False``, the ``vertices`` of the graph will be the incidences of the facets in the Hrepresentation. @@ -1526,7 +1587,7 @@ cdef class CombinatorialPolyhedron(SageObject): V = list(facet.ambient_Hrepresentation() for facet in face_iter) else: V = list(facet.ambient_V_indices() for facet in face_iter) - E = self.ridges(names=names, add_equations=True) + E = self.ridges(names=names, add_equations=True, algorithm=algorithm) if not names: # If names is false, the ridges are given as tuple of indices, # i.e. (1,2) instead of (('f1',), ('f2',)). @@ -1643,7 +1704,7 @@ cdef class CombinatorialPolyhedron(SageObject): return DiGraph([vertices, edges], format='vertices_and_edges', immutable=True) @cached_method - def f_vector(self, num_threads=None, parallelization_depth=None): + def f_vector(self, num_threads=None, parallelization_depth=None, algorithm=None): r""" Compute the ``f_vector`` of the polyhedron. @@ -1657,6 +1718,12 @@ cdef class CombinatorialPolyhedron(SageObject): - ``parallelization_depth`` -- integer (optional); specify how deep in the lattice the parallelization is done + - ``algorithm`` -- string (optional); + specify whether the face iterator starts with facets or vertices: + * ``'primal'`` -- start with the facets + * ``'dual'`` -- start with the vertices + * ``None`` -- choose automatically + .. NOTE:: To obtain edges and/or ridges as well, first do so. This might @@ -1702,7 +1769,7 @@ cdef class CombinatorialPolyhedron(SageObject): parallelization_depth = 3 if not self._f_vector: - self._compute_f_vector(num_threads, parallelization_depth) + self._compute_f_vector(num_threads, parallelization_depth, self._algorithm_to_dual(algorithm)) if not self._f_vector: raise ValueError("could not determine f_vector") from sage.modules.free_module_element import vector @@ -2605,8 +2672,9 @@ cdef class CombinatorialPolyhedron(SageObject): INPUT: - ``dimension`` -- if specified, then iterate over only this dimension + - ``algorithm`` -- string (optional); - specify whether to start with facets or vertices: + specify whether the face iterator starts with facets or vertices: * ``'primal'`` -- start with the facets * ``'dual'`` -- start with the vertices * ``None`` -- choose automatically @@ -2697,31 +2765,28 @@ cdef class CombinatorialPolyhedron(SageObject): :class:`~sage.geometry.polyhedron.combinatorial_polyhedron.face_iterator.FaceIterator`, :class:`~sage.geometry.polyhedron.combinatorial_polyhedron.combinatorial_face.CombinatorialFace`. """ - dual = None - if algorithm == 'primal': - dual = False - elif algorithm == 'dual': - dual = True - elif algorithm in (False, True): + cdef int dual + + if algorithm in (False, True): from sage.misc.superseded import deprecation deprecation(33646, "the keyword dual is deprecated; use algorithm instead") - dual = algorithm - elif algorithm is not None: - raise ValueError("algorithm must be 'primal', 'dual' or None") + dual = int(algorithm) + else: + dual = self._algorithm_to_dual(algorithm) if kwds: from sage.misc.superseded import deprecation deprecation(33646, "the keyword dual is deprecated; use algorithm instead") - if 'dual' in kwds and dual is None: - dual = kwds['dual'] + if 'dual' in kwds and dual == -1 and kwds['dual'] in (False, True): + dual = int(kwds['dual']) cdef FaceIterator face_iter - if dual is None: + if dual == -1: # Determine the faster way, to iterate through all faces. if not self.is_bounded() or self.n_facets() <= self.n_Vrepresentation(): - dual = False + dual = 0 else: - dual = True + dual = 1 return FaceIterator(self, dual, output_dimension=dimension) @@ -3414,7 +3479,7 @@ cdef class CombinatorialPolyhedron(SageObject): # Internal methods. - cdef int _compute_f_vector(self, size_t num_threads, size_t parallelization_depth) except -1: + cdef int _compute_f_vector(self, size_t num_threads, size_t parallelization_depth, int dual) except -1: r""" Compute the ``f_vector`` of the polyhedron. @@ -3435,13 +3500,13 @@ cdef class CombinatorialPolyhedron(SageObject): # Is a very bad choice anyway, but prevent segmenation faults. parallelization_depth = dim - 1 - cdef bint dual - if not self.is_bounded() or self.n_facets() <= self.n_Vrepresentation(): - # In this case the non-dual approach is faster.. - dual = False - else: - # In this case the dual approach is faster. - dual = True + if dual == -1: + if not self.is_bounded() or self.n_facets() <= self.n_Vrepresentation(): + # In this case the non-dual approach is faster. + dual = 0 + else: + # In this case the dual approach is faster. + dual = 1 cdef FaceIterator face_iter cdef iter_t* structs = mem.allocarray(num_threads, sizeof(iter_t)) diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx index 88a46b50d57..01992ac3a7b 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx @@ -1371,7 +1371,7 @@ cdef class FaceIterator(FaceIterator_base): sage: it = C.face_generator(algorithm='dual') Traceback (most recent call last): ... - ValueError: cannot iterate over dual of unbounded Polyedron + ValueError: dual algorithm only available for bounded polyhedra Construct a face iterator only yielding dimension `2` faces:: From 860d335175d8beffe70f27f9de8c0b8b3ef4112a Mon Sep 17 00:00:00 2001 From: Jonathan Kliem Date: Thu, 7 Apr 2022 16:56:04 +0200 Subject: [PATCH 102/529] use better heuristic to select dual/non-dual algorithm for edges/ridges --- .../combinatorial_polyhedron/base.pyx | 39 ++++++++++++------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx index dd86be3dc44..b6061189f0c 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx @@ -3561,22 +3561,33 @@ cdef class CombinatorialPolyhedron(SageObject): # Determine whether to use dual mode or not. if not self.is_bounded(): dual = 0 - elif do_edges: - if self.n_Vrepresentation() > self.n_facets()*self.n_facets(): - # This is a wild estimate - # that in this case it is better not to use the dual. - dual = 0 - else: - # In most bounded cases, one should use the dual. - dual = 1 + else: - if self.n_Vrepresentation()*self.n_Vrepresentation() < self.n_facets(): - # This is a wild estimate - # that in this case it is better to use the dual. - dual = 1 + if self.is_simple(): + per_face_primal = self.n_Vrepresentation() * self.n_facets() + else: + per_face_primal = self.n_Vrepresentation() * self.n_facets() ** 2 + + if self.is_simplicial(): + per_face_dual = self.n_Vrepresentation() * self.n_facets() + else: + per_face_dual = self.n_Vrepresentation() ** 2 * self.n_facets() + + from sage.arith.misc import binomial + estimate_n_faces = self.dimension() * binomial(min(self.n_facets(), self.n_Vrepresentation()), + self.dimension() // 2) + + # Note that the runtime per face already computes the coatoms of the next level, i.e. + # the runtime for each facet suffices to compute all ridges in primal, + # the runtime for each vertex suffices to compute all edges in dual. + if do_edges: + estimate_primal = estimate_n_faces * per_face_primal + estimate_dual = self.n_Vrepresentation() * per_face_dual else: - # In most bounded cases, one should not use the dual. - dual = 0 + estimate_primal = self.n_facets() * per_face_primal + estimate_dual = estimate_n_faces * per_face_dual + + dual = int(estimate_dual < estimate_primal) cdef FaceIterator face_iter cdef int dim = self.dimension() From eb9e55485755203ccd654bf898039c6abcb03aaa Mon Sep 17 00:00:00 2001 From: Jonathan Kliem Date: Thu, 7 Apr 2022 17:28:13 +0200 Subject: [PATCH 103/529] fix two doctests --- .../geometry/polyhedron/combinatorial_polyhedron/base.pyx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx index b6061189f0c..8d28c62ac84 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx @@ -35,10 +35,10 @@ Construction:: Obtaining edges and ridges:: sage: C.edges()[:2] - ((A vertex at (-1, -1, -1, 1), A vertex at (-1, -1, -1, -1)), - (A vertex at (-1, 1, -1, -1), A vertex at (-1, -1, -1, -1))) + ((A vertex at (1, -1, -1, -1), A vertex at (-1, -1, -1, -1)), + (A vertex at (-1, -1, -1, 1), A vertex at (-1, -1, -1, -1))) sage: C.edges(names=False)[:2] - ((14, 15), (10, 15)) + ((6, 15), (14, 15)) sage: C.ridges()[:2] ((An inequality (0, 0, 1, 0) x + 1 >= 0, From 46ee5588cb69e60af67dcdf661bd6ee6af8381e7 Mon Sep 17 00:00:00 2001 From: Vincent Delecroix <20100.delecroix@gmail.com> Date: Thu, 7 Apr 2022 18:38:45 +0200 Subject: [PATCH 104/529] 33625: _new_matrix -> _new --- src/sage/matrix/matrix_complex_ball_dense.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/matrix/matrix_complex_ball_dense.pyx b/src/sage/matrix/matrix_complex_ball_dense.pyx index 76668a01110..1554217f7cc 100644 --- a/src/sage/matrix/matrix_complex_ball_dense.pyx +++ b/src/sage/matrix/matrix_complex_ball_dense.pyx @@ -567,7 +567,7 @@ cdef class Matrix_complex_ball_dense(Matrix_dense): """ cdef Py_ssize_t nc = self._ncols cdef Py_ssize_t nr = self._nrows - cdef Matrix_complex_ball_dense trans = self._new_matrix(nc, nr) + cdef Matrix_complex_ball_dense trans = self._new(nc, nr) acb_mat_transpose(trans.value, self.value) return trans From 4012cd2dff4888c6482a3894db6da8b89f274684 Mon Sep 17 00:00:00 2001 From: Vincent Delecroix <20100.delecroix@gmail.com> Date: Thu, 7 Apr 2022 18:38:48 +0200 Subject: [PATCH 105/529] 33625: fix in the doc _right_ -> _left_ --- src/sage/matrix/matrix_complex_ball_dense.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/matrix/matrix_complex_ball_dense.pyx b/src/sage/matrix/matrix_complex_ball_dense.pyx index 1554217f7cc..8034aba2b43 100644 --- a/src/sage/matrix/matrix_complex_ball_dense.pyx +++ b/src/sage/matrix/matrix_complex_ball_dense.pyx @@ -921,7 +921,7 @@ cdef class Matrix_complex_ball_dense(Matrix_dense): A list of triples of the form ``(eigenvalue, [eigenvector], 1)``. - Unlike :meth:`eigenvalues` and :meth:`eigenvectors_right_approx`, this + Unlike :meth:`eigenvalues` and :meth:`eigenvectors_left_approx`, this method currently fails in the presence of multiple eigenvalues. Additionally, there is currently no guarantee that the algorithm From d27aad672cbd22b81b5b91f23f618f3b681f301c Mon Sep 17 00:00:00 2001 From: Jonathan Kliem Date: Thu, 7 Apr 2022 20:23:47 +0200 Subject: [PATCH 106/529] typo --- .../geometry/polyhedron/combinatorial_polyhedron/base.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx index 8d28c62ac84..b1eb7bff42b 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx @@ -1554,8 +1554,8 @@ cdef class CombinatorialPolyhedron(SageObject): * ``'dual'`` -- start with the vertices * ``None`` -- choose automatically - If ``names`` is ``False``, the ``vertices`` of the graph will - be the incidences of the facets in the Hrepresentation. + If ``names`` is ``False``, the ``vertices`` of the graph will + be the indices of the facets in the Hrepresentation. EXAMPLES:: From f986979ad764084fcf43050bb4fa5e8a9ebb1807 Mon Sep 17 00:00:00 2001 From: Jonathan Kliem Date: Thu, 7 Apr 2022 20:33:10 +0200 Subject: [PATCH 107/529] use "face generator" in the documentation --- src/sage/geometry/polyhedron/base3.py | 6 +++--- src/sage/geometry/polyhedron/base4.py | 2 +- .../polyhedron/combinatorial_polyhedron/base.pyx | 16 ++++++++-------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/sage/geometry/polyhedron/base3.py b/src/sage/geometry/polyhedron/base3.py index f581cbd2326..3a70cf79afc 100644 --- a/src/sage/geometry/polyhedron/base3.py +++ b/src/sage/geometry/polyhedron/base3.py @@ -795,7 +795,7 @@ def f_vector(self, num_threads=None, parallelization_depth=None, algorithm=None) how deep in the lattice the parallelization is done - ``algorithm`` -- string (optional); - specify whether the face iterator starts with facets or vertices: + specify whether the face generator starts with facets or vertices: * ``'primal'`` -- start with the facets * ``'dual'`` -- start with the vertices * ``None`` -- choose automatically @@ -892,7 +892,7 @@ def vertex_adjacency_matrix(self, algorithm=None): INPUT: - ``algorithm`` -- string (optional); - specify whether the face iterator starts with facets or vertices: + specify whether the face generator starts with facets or vertices: * ``'primal'`` -- start with the facets * ``'dual'`` -- start with the vertices * ``None`` -- choose automatically @@ -1029,7 +1029,7 @@ def facet_adjacency_matrix(self, algorithm=None): INPUT: - ``algorithm`` -- string (optional); - specify whether the face iterator starts with facets or vertices: + specify whether the face generator starts with facets or vertices: * ``'primal'`` -- start with the facets * ``'dual'`` -- start with the vertices * ``None`` -- choose automatically diff --git a/src/sage/geometry/polyhedron/base4.py b/src/sage/geometry/polyhedron/base4.py index b49bb349e87..8c7dd0c2836 100644 --- a/src/sage/geometry/polyhedron/base4.py +++ b/src/sage/geometry/polyhedron/base4.py @@ -151,7 +151,7 @@ def vertex_graph(self, **kwds): indices of the Vrepresentation - ``algorithm`` -- string (optional); - specify whether the face iterator starts with facets or vertices: + specify whether the face generator starts with facets or vertices: * ``'primal'`` -- start with the facets * ``'dual'`` -- start with the vertices * ``None`` -- choose automatically diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx index b1eb7bff42b..9e104faea5c 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx @@ -1181,7 +1181,7 @@ cdef class CombinatorialPolyhedron(SageObject): their indices in the Vrepresentation - ``algorithm`` -- string (optional); - specify whether the face iterator starts with facets or vertices: + specify whether the face generator starts with facets or vertices: * ``'primal'`` -- start with the facets * ``'dual'`` -- start with the vertices * ``None`` -- choose automatically @@ -1265,7 +1265,7 @@ cdef class CombinatorialPolyhedron(SageObject): indices of the Vrepresentation - ``algorithm`` -- string (optional); - specify whether the face iterator starts with facets or vertices: + specify whether the face generator starts with facets or vertices: * ``'primal'`` -- start with the facets * ``'dual'`` -- start with the vertices * ``None`` -- choose automatically @@ -1303,7 +1303,7 @@ cdef class CombinatorialPolyhedron(SageObject): INPUT: - ``algorithm`` -- string (optional); - specify whether the face iterator starts with facets or vertices: + specify whether the face generator starts with facets or vertices: * ``'primal'`` -- start with the facets * ``'dual'`` -- start with the vertices * ``None`` -- choose automatically @@ -1371,7 +1371,7 @@ cdef class CombinatorialPolyhedron(SageObject): if ``False``, then the facets are given by their indices - ``algorithm`` -- string (optional); - specify whether the face iterator starts with facets or vertices: + specify whether the face generator starts with facets or vertices: * ``'primal'`` -- start with the facets * ``'dual'`` -- start with the vertices * ``None`` -- choose automatically @@ -1494,7 +1494,7 @@ cdef class CombinatorialPolyhedron(SageObject): INPUT: - ``algorithm`` -- string (optional); - specify whether the face iterator starts with facets or vertices: + specify whether the face generator starts with facets or vertices: * ``'primal'`` -- start with the facets * ``'dual'`` -- start with the vertices * ``None`` -- choose automatically @@ -1549,7 +1549,7 @@ cdef class CombinatorialPolyhedron(SageObject): INPUT: - ``algorithm`` -- string (optional); - specify whether the face iterator starts with facets or vertices: + specify whether the face generator starts with facets or vertices: * ``'primal'`` -- start with the facets * ``'dual'`` -- start with the vertices * ``None`` -- choose automatically @@ -1719,7 +1719,7 @@ cdef class CombinatorialPolyhedron(SageObject): how deep in the lattice the parallelization is done - ``algorithm`` -- string (optional); - specify whether the face iterator starts with facets or vertices: + specify whether the face generator starts with facets or vertices: * ``'primal'`` -- start with the facets * ``'dual'`` -- start with the vertices * ``None`` -- choose automatically @@ -2674,7 +2674,7 @@ cdef class CombinatorialPolyhedron(SageObject): - ``dimension`` -- if specified, then iterate over only this dimension - ``algorithm`` -- string (optional); - specify whether the face iterator starts with facets or vertices: + specify whether the face generator starts with facets or vertices: * ``'primal'`` -- start with the facets * ``'dual'`` -- start with the vertices * ``None`` -- choose automatically From 3bccc276294a25ef8106156cabfb9e1df0bdd864 Mon Sep 17 00:00:00 2001 From: Jonathan Kliem Date: Thu, 7 Apr 2022 20:34:00 +0200 Subject: [PATCH 108/529] fix documentation error --- src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx index 9e104faea5c..30d3bd8ac26 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx @@ -1176,7 +1176,7 @@ cdef class CombinatorialPolyhedron(SageObject): INPUT: - - ``names`` -- boolean (default: ``True``); if ``True``, + - ``names`` -- boolean (default: ``True``); if ``False``, then the Vrepresentatives in the edges are given by their indices in the Vrepresentation From 5b47d224f3c41232f73f64467288ca191ec75244 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Fri, 8 Apr 2022 10:05:36 +0900 Subject: [PATCH 109/529] Fix checksums --- build/pkgs/mathjax3/checksums.ini | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build/pkgs/mathjax3/checksums.ini b/build/pkgs/mathjax3/checksums.ini index 2cfe5869dd5..d901f9b84de 100644 --- a/build/pkgs/mathjax3/checksums.ini +++ b/build/pkgs/mathjax3/checksums.ini @@ -1,4 +1,4 @@ tarball=mathjax-VERSION.tar.gz -sha1=ed325638d807fac93e4b1b9d052e2a72164bbaba -md5=7a78a9e649f69a295ad11cb476857cd5 -cksum=1951447424 +sha1=19aacb6eab541724db8f718c4ad160a182145454 +md5=7ba585fa20cbc6fb893a90e1b2ce4d1f +cksum=2990336228 From 5412dcb00418d1c1eacf161393837f56237e369d Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Fri, 8 Apr 2022 10:16:53 +0900 Subject: [PATCH 110/529] Rename config variable to --use-cdns --- src/sage/docs/conf.py | 6 +++--- src/sage_docbuild/__init__.py | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/sage/docs/conf.py b/src/sage/docs/conf.py index 828d50c6064..0ff96e19984 100644 --- a/src/sage/docs/conf.py +++ b/src/sage/docs/conf.py @@ -285,11 +285,11 @@ def set_intersphinx_mappings(app, config): }, } -if os.environ.get('SAGE_OFFLINE_DOC', 'no') == 'yes': +if os.environ.get('SAGE_USE_CDNS', 'no') == 'yes': + mathjax_path = "https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js" +else: mathjax_path = 'mathjax/tex-chtml.js' html_common_static_path += [os.path.join(SAGE_SHARE, 'mathjax3')] -else: - mathjax_path = "https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js" # A list of glob-style patterns that should be excluded when looking for source # files. They are matched against the source file names relative to the diff --git a/src/sage_docbuild/__init__.py b/src/sage_docbuild/__init__.py index 5161009da35..ad857d0f078 100644 --- a/src/sage_docbuild/__init__.py +++ b/src/sage_docbuild/__init__.py @@ -54,7 +54,7 @@ import sage.all from sage.misc.cachefunc import cached_method # Do not import SAGE_DOC globally as it interferes with doctesting with a random replacement -from sage.env import SAGE_SHARE, SAGE_DOC_SRC, SAGE_SRC, DOT_SAGE +from sage.env import SAGE_DOC_SRC, SAGE_SRC, DOT_SAGE from .build_options import (LANGUAGES, SPHINXOPTS, OMIT, ALLSPHINXOPTS, NUM_THREADS, WEBSITESPHINXOPTS, @@ -1573,9 +1573,9 @@ def setup_parser(): standard.add_argument("--no-prune-empty-dirs", dest="no_prune_empty_dirs", action="store_true", help="do not prune empty directories in the documentation sources") - standard.add_argument("--offline-doc", dest="offline_doc", default=True, + standard.add_argument("--use-cdns", dest="use-cdns", default=False, action="store_true", - help="do not assume internet connection; in particular, do not use MathJax CDN") + help="assume internet connection and use CDNs; in particular, use MathJax CDN") standard.add_argument("-N", "--no-colors", dest="color", action="store_false", help="do not color output; does not affect children") @@ -1744,8 +1744,8 @@ def excepthook(*exc_info): os.environ['SAGE_SKIP_PLOT_DIRECTIVE'] = 'yes' if args.skip_tests: os.environ['SAGE_SKIP_TESTS_BLOCKS'] = 'True' - if args.offline_doc: - os.environ['SAGE_OFFLINE_DOC'] = 'yes' + if args.use_cdns: + os.environ['SAGE_USE_CDNS'] = 'yes' ABORT_ON_ERROR = not args.keep_going From 2a186d24b571358b52340e6b908b4f0f23d7544d Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Fri, 8 Apr 2022 10:34:17 +0900 Subject: [PATCH 111/529] Fix a typo --- src/sage_docbuild/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage_docbuild/__init__.py b/src/sage_docbuild/__init__.py index ad857d0f078..f11842feca8 100644 --- a/src/sage_docbuild/__init__.py +++ b/src/sage_docbuild/__init__.py @@ -1573,7 +1573,7 @@ def setup_parser(): standard.add_argument("--no-prune-empty-dirs", dest="no_prune_empty_dirs", action="store_true", help="do not prune empty directories in the documentation sources") - standard.add_argument("--use-cdns", dest="use-cdns", default=False, + standard.add_argument("--use-cdns", dest="use_cdns", default=False, action="store_true", help="assume internet connection and use CDNs; in particular, use MathJax CDN") standard.add_argument("-N", "--no-colors", dest="color", From c42ec232510584689911696655f18b4395acdd81 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Fri, 8 Apr 2022 15:11:34 +0900 Subject: [PATCH 112/529] Use MATHJAX_DIR --- src/sage/docs/conf.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/docs/conf.py b/src/sage/docs/conf.py index 0ff96e19984..e1b471aa917 100644 --- a/src/sage/docs/conf.py +++ b/src/sage/docs/conf.py @@ -1,7 +1,7 @@ import sys import os import sphinx -from sage.env import SAGE_SHARE, SAGE_DOC_SRC, SAGE_DOC, THEBE_DIR, PPLPY_DOCS +from sage.env import SAGE_DOC_SRC, SAGE_DOC, THEBE_DIR, PPLPY_DOCS, MATHJAX_DIR from sage.misc.latex_macros import sage_mathjax_macros import sage.version from sage.misc.sagedoc import extlinks @@ -289,7 +289,7 @@ def set_intersphinx_mappings(app, config): mathjax_path = "https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js" else: mathjax_path = 'mathjax/tex-chtml.js' - html_common_static_path += [os.path.join(SAGE_SHARE, 'mathjax3')] + html_common_static_path += [MATHJAX_DIR] # A list of glob-style patterns that should be excluded when looking for source # files. They are matched against the source file names relative to the From 8df9661a421c7a735c667c7e5457638b3847c557 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Fri, 8 Apr 2022 21:18:42 +0900 Subject: [PATCH 113/529] Upgrade mathjax package to mathjax3 --- build/pkgs/mathjax/SPKG.rst | 12 +--- build/pkgs/mathjax/checksums.ini | 6 +- build/pkgs/mathjax/package-version.txt | 2 +- build/pkgs/mathjax/spkg-src | 88 +++++++++++++----------- build/pkgs/mathjax3/SPKG.rst | 32 --------- build/pkgs/mathjax3/checksums.ini | 4 -- build/pkgs/mathjax3/distros/conda.txt | 1 - build/pkgs/mathjax3/distros/opensuse.txt | 1 - build/pkgs/mathjax3/distros/repology.txt | 1 - build/pkgs/mathjax3/distros/void.txt | 1 - build/pkgs/mathjax3/package-version.txt | 1 - build/pkgs/mathjax3/spkg-install.in | 4 -- build/pkgs/mathjax3/spkg-src | 35 ---------- build/pkgs/mathjax3/type | 1 - src/sage/docs/conf.py | 14 ++-- 15 files changed, 61 insertions(+), 142 deletions(-) delete mode 100644 build/pkgs/mathjax3/SPKG.rst delete mode 100644 build/pkgs/mathjax3/checksums.ini delete mode 100644 build/pkgs/mathjax3/distros/conda.txt delete mode 100644 build/pkgs/mathjax3/distros/opensuse.txt delete mode 100644 build/pkgs/mathjax3/distros/repology.txt delete mode 100644 build/pkgs/mathjax3/distros/void.txt delete mode 100644 build/pkgs/mathjax3/package-version.txt delete mode 100644 build/pkgs/mathjax3/spkg-install.in delete mode 100755 build/pkgs/mathjax3/spkg-src delete mode 100644 build/pkgs/mathjax3/type diff --git a/build/pkgs/mathjax/SPKG.rst b/build/pkgs/mathjax/SPKG.rst index e7c0a7edb27..2cb2508b733 100644 --- a/build/pkgs/mathjax/SPKG.rst +++ b/build/pkgs/mathjax/SPKG.rst @@ -6,7 +6,7 @@ Description MathJax is a JavaScript library for displaying mathematical formulas. -MathJax is used by the Jupyter notebook and the Sphinx documentation. +MathJax is used by the Sage documentation built by Sphinx. License ------- @@ -22,17 +22,11 @@ Home page: https://www.mathjax.org/ Dependencies ------------ -None. +None Special Update/Build Instructions --------------------------------- -None. +None -Patches -------- - -- nopng_config.patch: prevent font warning messages since png files are - removed. See section "Trimming II -- not strictly necessary" of - https://github.com/mathjax/MathJax-docs/wiki/Guide%3A-reducing-size-of-a-mathjax-installation diff --git a/build/pkgs/mathjax/checksums.ini b/build/pkgs/mathjax/checksums.ini index 4a2ee5ab7da..6a6b233b2ae 100644 --- a/build/pkgs/mathjax/checksums.ini +++ b/build/pkgs/mathjax/checksums.ini @@ -1,4 +1,4 @@ tarball=mathjax-VERSION.tar.gz -sha1=a1b31066a541167c65d6b43f24f3a06f03760662 -md5=02d1067dc06d9ca7d380457a49404766 -cksum=1204309472 +sha1=3f7abecf8cacd7f5d7f9ae6c3baca7739101c17d +md5=ba1a65ab58aaad6c84f39735c619bc34 +cksum=1142131398 diff --git a/build/pkgs/mathjax/package-version.txt b/build/pkgs/mathjax/package-version.txt index 65f95911c0b..944880fa15e 100644 --- a/build/pkgs/mathjax/package-version.txt +++ b/build/pkgs/mathjax/package-version.txt @@ -1 +1 @@ -2.7.4.p0 +3.2.0 diff --git a/build/pkgs/mathjax/spkg-src b/build/pkgs/mathjax/spkg-src index f77a8d88360..49f81e7a993 100755 --- a/build/pkgs/mathjax/spkg-src +++ b/build/pkgs/mathjax/spkg-src @@ -4,13 +4,12 @@ set -e [ -n "${SAGE_ROOT}" ] || SAGE_ROOT="$(pwd)/../../../" - -# determine latest version. -GIT_VERSION="$(curl http://docs.mathjax.org/en/latest/installation.html | grep 'Current Version' | sed 's|^.*archive/||g' | sed 's/.zip".*//g')" +# Determine the latest version +GIT_VERSION="$(curl https://github.com/mathjax/MathJax/releases | grep 'MathJax v' | head -1 | sed 's|^.*MathJax v||g' | sed 's/\s*$//g')" echo "GIT_VERSION=$GIT_VERSION" -# fetch and rename latest version. -URL="https://github.com/mathjax/MathJax/archive/${GIT_VERSION}.zip" +# Fetch and rename the latest version +URL="https://github.com/mathjax/MathJax/archive/refs/tags/${GIT_VERSION}.zip" echo "Downloading $URL" rm -rf src if [ -z "$UPSTREAM_SOURCE_TARBALL" ]; then @@ -18,43 +17,52 @@ if [ -z "$UPSTREAM_SOURCE_TARBALL" ]; then else tar xzf "$UPSTREAM_SOURCE_TARBALL" fi -mv MathJax-${GIT_VERSION} src - -# Strip mathjax according to -# https://github.com/mathjax/MathJax-docs/wiki/Guide%3A-reducing-size-of-a-mathjax-installation - -# Trimming I -- removing files unnecessary for deployment -FILEDIRS_TO_REMOVE='docs/ test/ unpacked/ .gitignore README-branch.txt README.md bower.json' -for filedir in ${FILEDIRS_TO_REMOVE} ; do - rm -rf "src/${filedir}" -done - -# Trimming II -- not strictly necessary (requires the patch nopng_config.patch) -rm -rf 'src/fonts/HTML-CSS/TeX/png/' - -# Trimming III -- fonts -FONTS_TO_REMOVE='Asana-Math Gyre-Pagella Gyre-Termes Latin-Modern Neo-Euler' -for font in ${FONTS_TO_REMOVE} ; do - find . -type d -name "${font}" -prune -exec rm -rf {} \; -done - -FONT_FORMATS_TO_REMOVE='eot otf svg' -for fontformat in ${FONT_FORMATS_TO_REMOVE} ; do - find . -type d -name "${fontformat}" -prune -exec rm -rf {} \; -done - -# Trimming IV -- reducing input and output options -OUTPUT_OPTIONS_TO_REMOVE='NativeMML SVG' -for output in ${OUTPUT_OPTIONS_TO_REMOVE} ; do - rm -rf "src/jax/output/${output}" -done - -# repack -tar czf "$SAGE_ROOT/upstream/mathjax-${GIT_VERSION}.tar.gz" src + +# Put files under mathjax directory +mkdir src +mv MathJax-${GIT_VERSION}/es5 src/mathjax +rm -r MathJax-${GIT_VERSION} + + +# The following block of commented-out lines were used to reduce the package +# size of MathJax2. We keep these lines for the future when we will want to +# reuse and rewrite them to remove unnecessary font files from MathJax3. + +## Trimming I -- removing files unnecessary for deployment +#FILEDIRS_TO_REMOVE='docs/ test/ unpacked/ .gitignore README-branch.txt README.md bower.json' +#for filedir in ${FILEDIRS_TO_REMOVE} ; do +# rm -rf "src/${filedir}" +#done +# +## Trimming II -- not strictly necessary (requires the patch nopng_config.patch) +#rm -rf 'src/fonts/HTML-CSS/TeX/png/' +# +## Trimming III -- fonts +#FONTS_TO_REMOVE='Asana-Math Gyre-Pagella Gyre-Termes Latin-Modern Neo-Euler' +#for font in ${FONTS_TO_REMOVE} ; do +# find . -type d -name "${font}" -prune -exec rm -rf {} \; +#done +# +#FONT_FORMATS_TO_REMOVE='eot otf svg' +#for fontformat in ${FONT_FORMATS_TO_REMOVE} ; do +# find . -type d -name "${fontformat}" -prune -exec rm -rf {} \; +#done +# +## Trimming IV -- reducing input and output options +#OUTPUT_OPTIONS_TO_REMOVE='NativeMML SVG' +#for output in ${OUTPUT_OPTIONS_TO_REMOVE} ; do +# rm -rf "src/jax/output/${output}" +#done + + +PACKAGE_VERSION=${GIT_VERSION} + +# Repackage. +tar czf "$SAGE_ROOT/upstream/mathjax-${PACKAGE_VERSION}.tar.gz" src rm -rf src -# update package info -echo "${GIT_VERSION}" > 'package-version.txt' +# Update package info +echo "${PACKAGE_VERSION}" > 'package-version.txt' "$SAGE_ROOT"/sage --package fix-checksum mathjax diff --git a/build/pkgs/mathjax3/SPKG.rst b/build/pkgs/mathjax3/SPKG.rst deleted file mode 100644 index b957186a448..00000000000 --- a/build/pkgs/mathjax3/SPKG.rst +++ /dev/null @@ -1,32 +0,0 @@ -mathjax3: A JavaScript library for displaying mathematical formulas -=================================================================== - -Description ------------ - -MathJax3 is a JavaScript library for displaying mathematical formulas. - -MathJax3 is used by the Sage documentation built by Sphinx. - -License -------- - -Apache License, version 2.0 - - -Upstream Contact ----------------- - -Home page: https://www.mathjax.org/ - -Dependencies ------------- - -None - - -Special Update/Build Instructions ---------------------------------- - -None - diff --git a/build/pkgs/mathjax3/checksums.ini b/build/pkgs/mathjax3/checksums.ini deleted file mode 100644 index d901f9b84de..00000000000 --- a/build/pkgs/mathjax3/checksums.ini +++ /dev/null @@ -1,4 +0,0 @@ -tarball=mathjax-VERSION.tar.gz -sha1=19aacb6eab541724db8f718c4ad160a182145454 -md5=7ba585fa20cbc6fb893a90e1b2ce4d1f -cksum=2990336228 diff --git a/build/pkgs/mathjax3/distros/conda.txt b/build/pkgs/mathjax3/distros/conda.txt deleted file mode 100644 index 37aaaac759c..00000000000 --- a/build/pkgs/mathjax3/distros/conda.txt +++ /dev/null @@ -1 +0,0 @@ -mathjax diff --git a/build/pkgs/mathjax3/distros/opensuse.txt b/build/pkgs/mathjax3/distros/opensuse.txt deleted file mode 100644 index 37aaaac759c..00000000000 --- a/build/pkgs/mathjax3/distros/opensuse.txt +++ /dev/null @@ -1 +0,0 @@ -mathjax diff --git a/build/pkgs/mathjax3/distros/repology.txt b/build/pkgs/mathjax3/distros/repology.txt deleted file mode 100644 index 37aaaac759c..00000000000 --- a/build/pkgs/mathjax3/distros/repology.txt +++ /dev/null @@ -1 +0,0 @@ -mathjax diff --git a/build/pkgs/mathjax3/distros/void.txt b/build/pkgs/mathjax3/distros/void.txt deleted file mode 100644 index 37aaaac759c..00000000000 --- a/build/pkgs/mathjax3/distros/void.txt +++ /dev/null @@ -1 +0,0 @@ -mathjax diff --git a/build/pkgs/mathjax3/package-version.txt b/build/pkgs/mathjax3/package-version.txt deleted file mode 100644 index 944880fa15e..00000000000 --- a/build/pkgs/mathjax3/package-version.txt +++ /dev/null @@ -1 +0,0 @@ -3.2.0 diff --git a/build/pkgs/mathjax3/spkg-install.in b/build/pkgs/mathjax3/spkg-install.in deleted file mode 100644 index 4429a680a53..00000000000 --- a/build/pkgs/mathjax3/spkg-install.in +++ /dev/null @@ -1,4 +0,0 @@ -TARGET="${SAGE_SHARE}/mathjax3" -# Cleanup installed version -rm -rf "${TARGET}" -sdh_install src/* "${TARGET}" diff --git a/build/pkgs/mathjax3/spkg-src b/build/pkgs/mathjax3/spkg-src deleted file mode 100755 index b20462e48d1..00000000000 --- a/build/pkgs/mathjax3/spkg-src +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env bash - -set -e - -[ -n "${SAGE_ROOT}" ] || SAGE_ROOT="$(pwd)/../../../" - -# determine latest version. -GIT_VERSION="$(curl https://github.com/mathjax/MathJax/releases | grep 'MathJax v' | head -1 | sed 's|^.*MathJax v||g' | sed 's/\s*$//g')" -echo "GIT_VERSION=$GIT_VERSION" - -# fetch and rename latest version. -URL="https://github.com/mathjax/MathJax/archive/refs/tags/${GIT_VERSION}.zip" -echo "Downloading $URL" -rm -rf src -if [ -z "$UPSTREAM_SOURCE_TARBALL" ]; then - tar xzf <( curl -L "$URL" ) -else - tar xzf "$UPSTREAM_SOURCE_TARBALL" -fi - -mkdir src -mv MathJax-${GIT_VERSION}/es5 src/mathjax -rm -r MathJax-${GIT_VERSION} - -PACKAGE_VERSION=${GIT_VERSION} - -# repack -tar czf "$SAGE_ROOT/upstream/mathjax-${PACKAGE_VERSION}.tar.gz" src -rm -rf src - -# update package info -echo "${PACKAGE_VERSION}" > 'package-version.txt' -"$SAGE_ROOT"/sage --package fix-checksum mathjax3 - - diff --git a/build/pkgs/mathjax3/type b/build/pkgs/mathjax3/type deleted file mode 100644 index a6a7b9cd726..00000000000 --- a/build/pkgs/mathjax3/type +++ /dev/null @@ -1 +0,0 @@ -standard diff --git a/src/sage/docs/conf.py b/src/sage/docs/conf.py index d067335e489..8f9fceb4d94 100644 --- a/src/sage/docs/conf.py +++ b/src/sage/docs/conf.py @@ -262,19 +262,17 @@ def set_intersphinx_mappings(app, config): # We use MathJax to build the documentation. extensions.append('sphinx.ext.mathjax') -mathjax_path = 'MathJax.js?config=TeX-AMS_HTML-full,../mathjax_sage.js' +mathjax_path = 'mathjax/tex-chtml.js' from sage.misc.latex_macros import sage_mathjax_macros html_theme_options['mathjax_macros'] = sage_mathjax_macros() -mathjax_relative = os.path.basename(MATHJAX_DIR) - -# It would be really nice if sphinx would copy the entire mathjax -# directory, (so we could have a _static/mathjax directory), rather than -# the contents of the directory html_common_static_path.append(MATHJAX_DIR) -exclude_patterns += ['**/' + os.path.join(mathjax_relative, i) - for i in ('docs', 'README*', 'test', 'unpacked', 'LICENSE')] + +# A list of glob-style patterns that should be excluded when looking for source +# files. They are matched against the source file names relative to the +# source directory, using slashes as directory separators on all platforms. +exclude_patterns = [] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. From 89ec41751c94cd12136596e15375b2a1a183258d Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Fri, 8 Apr 2022 21:49:15 +0900 Subject: [PATCH 114/529] Fix MATHJAX_DIR env variable --- src/sage/env.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/env.py b/src/sage/env.py index 98d1e520eb2..1b8aacc87b1 100644 --- a/src/sage/env.py +++ b/src/sage/env.py @@ -203,7 +203,7 @@ def var(key: str, *fallbacks: Optional[str], force: bool = False) -> Optional[st CREMONA_MINI_DATA_DIR = var("CREMONA_MINI_DATA_DIR", join(SAGE_SHARE, "cremona")) CREMONA_LARGE_DATA_DIR = var("CREMONA_LARGE_DATA_DIR", join(SAGE_SHARE, "cremona")) JMOL_DIR = var("JMOL_DIR", join(SAGE_SHARE, "jmol")) -MATHJAX_DIR = var("MATHJAX_DIR", join(SAGE_SHARE, "mathjax3")) +MATHJAX_DIR = var("MATHJAX_DIR", join(SAGE_SHARE, "mathjax")) MTXLIB = var("MTXLIB", join(SAGE_SHARE, "meataxe")) THREEJS_DIR = var("THREEJS_DIR", join(SAGE_SHARE, "threejs-sage")) PPLPY_DOCS = var("PPLPY_DOCS", join(SAGE_SHARE, "doc", "pplpy")) From 7d3fd94853b5ae08ebb7ab979a97536a7f988854 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 10 Apr 2022 10:25:25 +0200 Subject: [PATCH 115/529] fix and activate pycodestyle E703 in pyx files --- src/sage/combinat/combinat_cython.pyx | 21 ++++++++++++------- src/sage/combinat/debruijn_sequence.pyx | 4 +++- .../designs/gen_quadrangles_with_spread.pyx | 3 ++- .../orthogonal_arrays_find_recursive.pyx | 3 ++- src/sage/combinat/matrices/dancing_links.pyx | 4 ++-- src/sage/combinat/words/word_char.pyx | 4 +++- src/sage/libs/giac/giac.pyx | 7 +++---- src/sage/libs/singular/singular.pyx | 16 +++++++------- src/sage/rings/finite_rings/integer_mod.pyx | 4 ++-- src/tox.ini | 1 + 10 files changed, 40 insertions(+), 27 deletions(-) diff --git a/src/sage/combinat/combinat_cython.pyx b/src/sage/combinat/combinat_cython.pyx index cc9ba2ba501..3d8e8042311 100644 --- a/src/sage/combinat/combinat_cython.pyx +++ b/src/sage/combinat/combinat_cython.pyx @@ -481,12 +481,14 @@ cdef void _linear_extension_switch(list _le, list _a, list _b, list _is_plus, Py if i == -1: _is_plus[0] = not _is_plus[0] else: - a = _a[i]; b = _b[i] + a = _a[i] + b = _b[i] a_index = _le.index(a) b_index = _le.index(b) _le[a_index] = b _le[b_index] = a - _b[i] = a; _a[i] = b + _b[i] = a + _a[i] = b @cython.wraparound(False) @cython.boundscheck(False) @@ -572,7 +574,8 @@ def _linear_extension_gen(_D, list _le, list _a, list _b, list _is_plus, Py_ssiz while _linear_extension_right_b(_D, _le, _a, _b, i): mrb += 1 # move_right - index = _le.index(_b[i]); index1 = index + 1 + index = _le.index(_b[i]) + index1 = index + 1 _le[index] = _le[index1] _le[index1] = _b[i] if _is_plus[0]: @@ -585,7 +588,8 @@ def _linear_extension_gen(_D, list _le, list _a, list _b, list _is_plus, Py_ssiz typical = True mra += 1 # move_right - index = _le.index(_a[i]); index1 = index+1 + index = _le.index(_a[i]) + index1 = index+1 _le[index] = _le[index1] _le[index1] = _a[i] if _is_plus[0]: @@ -607,7 +611,8 @@ def _linear_extension_gen(_D, list _le, list _a, list _b, list _is_plus, Py_ssiz mla = mra + 1 for _ in range(mla): # move_left - index = _le.index(_a[i]); index1 = index-1 + index = _le.index(_a[i]) + index1 = index-1 _le[index] = _le[index1] _le[index1] = _a[i] if _is_plus[0]: @@ -618,7 +623,8 @@ def _linear_extension_gen(_D, list _le, list _a, list _b, list _is_plus, Py_ssiz if typical and (mrb % 2 == 1): # move_left - index = _le.index(_a[i]); index1 = index-1 + index = _le.index(_a[i]) + index1 = index-1 _le[index] = _le[index1] _le[index1] = _a[i] if _is_plus[0]: @@ -631,7 +637,8 @@ def _linear_extension_gen(_D, list _le, list _a, list _b, list _is_plus, Py_ssiz yield e for _ in range(mrb): # move_left - index = _le.index(_b[i]); index1 = index-1 + index = _le.index(_b[i]) + index1 = index-1 _le[index] = _le[index1] _le[index1] = _b[i] if _is_plus[0]: diff --git a/src/sage/combinat/debruijn_sequence.pyx b/src/sage/combinat/debruijn_sequence.pyx index 9dbf16238ee..6b96c2f6a8b 100644 --- a/src/sage/combinat/debruijn_sequence.pyx +++ b/src/sage/combinat/debruijn_sequence.pyx @@ -101,7 +101,8 @@ cdef gen(int t, int p, k, n): cdef int j if t > n: if n % p == 0: - for j in range(1, p + 1): sequence.append(a[j]) + for j in range(1, p + 1): + sequence.append(a[j]) else: a[t] = a[t - p] gen(t + 1, p, k, n) @@ -109,6 +110,7 @@ cdef gen(int t, int p, k, n): a[t] = j gen(t + 1, t, k, n) + def is_debruijn_sequence(seq, k, n): r""" Given a sequence of integer elements in `0..k-1`, tests whether it diff --git a/src/sage/combinat/designs/gen_quadrangles_with_spread.pyx b/src/sage/combinat/designs/gen_quadrangles_with_spread.pyx index 4646caa80db..1d2035eeba0 100644 --- a/src/sage/combinat/designs/gen_quadrangles_with_spread.pyx +++ b/src/sage/combinat/designs/gen_quadrangles_with_spread.pyx @@ -103,7 +103,8 @@ def generalised_quadrangle_with_spread(const int s, const int t, raise RuntimeError(f"No GQ of order ({s}, {t}) exists") if s == 1 and t == 1: # we have a square - if existence: return True + if existence: + return True D = IncidenceStructure([[0, 1], [1, 2], [2, 3], [3, 0]]) return (D, [[0, 1], [2, 3]]) diff --git a/src/sage/combinat/designs/orthogonal_arrays_find_recursive.pyx b/src/sage/combinat/designs/orthogonal_arrays_find_recursive.pyx index d1cd3561a1c..5743fc2f7d7 100644 --- a/src/sage/combinat/designs/orthogonal_arrays_find_recursive.pyx +++ b/src/sage/combinat/designs/orthogonal_arrays_find_recursive.pyx @@ -801,10 +801,11 @@ cdef dict ioa_indexed_by_n_minus_x = {} for x in _QDM.itervalues(): for (n,_,_,u),(k,_) in x.items(): if u>1: - if not n in ioa_indexed_by_n_minus_x: + if n not in ioa_indexed_by_n_minus_x: ioa_indexed_by_n_minus_x[n] = [] ioa_indexed_by_n_minus_x[n].append((k,u)) + def int_as_sum(int value, list S, int k_max): r""" Return a tuple `(s_1, s_2, \ldots, s_k)` of less then `k_max` elements of `S` such diff --git a/src/sage/combinat/matrices/dancing_links.pyx b/src/sage/combinat/matrices/dancing_links.pyx index d3b406751d7..93859dce9b9 100644 --- a/src/sage/combinat/matrices/dancing_links.pyx +++ b/src/sage/combinat/matrices/dancing_links.pyx @@ -674,9 +674,9 @@ cdef class dancing_linksWrapper: else: return None - indices = [i for (i,row) in enumerate(self._rows) if column in row] + indices = [i for (i, row) in enumerate(self._rows) if column in row] for (args_kwds, val) in first_solution(indices): - if not val is None: + if val is not None: return val def all_solutions(self, ncpus=None, column=None): diff --git a/src/sage/combinat/words/word_char.pyx b/src/sage/combinat/words/word_char.pyx index 11bb29d1d1c..494976a9f92 100644 --- a/src/sage/combinat/words/word_char.pyx +++ b/src/sage/combinat/words/word_char.pyx @@ -534,7 +534,9 @@ cdef class WordDatatype_char(WordDatatype): if exp == float('inf'): from sage.rings.infinity import Infinity - fcn = lambda n: self[n % self.length()] + + def fcn(n): + return self[n % self.length()] return self._parent.shift()(fcn, datatype='callable') if exp < 0: diff --git a/src/sage/libs/giac/giac.pyx b/src/sage/libs/giac/giac.pyx index 6e7664f1151..b9811cae273 100644 --- a/src/sage/libs/giac/giac.pyx +++ b/src/sage/libs/giac/giac.pyx @@ -1926,8 +1926,7 @@ cdef gen pylongtogen(a) except +: # when cythonizing with cython 0.24: # g=-g gives an Invalid operand type for '-' (gen) g=GIAC_neg(g) - return g; - + return g ############################################################# @@ -2033,8 +2032,8 @@ class GiacFunctionNoEV(Pygen): ############################################################# # Some convenient settings ############################################################ -Pygen('printpow(1)').eval() ; # default power is ^ -Pygen('add_language(1)').eval(); # Add the french keywords in the giac library language. +Pygen('printpow(1)').eval() # default power is ^ +Pygen('add_language(1)').eval() # Add the french keywords in the giac library language. # FIXME: print I for sqrt(-1) instead of i # GIAC_try_parse_i(False,context_ptr); (does not work??) diff --git a/src/sage/libs/singular/singular.pyx b/src/sage/libs/singular/singular.pyx index 610435634df..f57126a6be4 100644 --- a/src/sage/libs/singular/singular.pyx +++ b/src/sage/libs/singular/singular.pyx @@ -783,7 +783,7 @@ cdef number *sa2si_GFqNTLGF2E(FFgf2eE elem, ring *_ring): apow2 = _ring.cf.cfMult(coeff, apow1,_ring.cf) n2 = _ring.cf.cfAdd(apow2, n1,_ring.cf) _ring.cf.cfDelete(&apow2, _ring.cf) - _ring.cf.cfDelete(&n1, _ring.cf); + _ring.cf.cfDelete(&n1, _ring.cf) n1 = n2 apow2 = _ring.cf.cfMult(apow1, a,_ring.cf) @@ -849,7 +849,7 @@ cdef number *sa2si_GFq_generic(object elem, ring *_ring): apow2 = _ring.cf.cfMult(coeff, apow1,_ring.cf) n2 = _ring.cf.cfAdd(apow2, n1,_ring.cf) _ring.cf.cfDelete(&apow2, _ring.cf) - _ring.cf.cfDelete(&n1, _ring.cf); + _ring.cf.cfDelete(&n1, _ring.cf) n1 = n2 apow2 = _ring.cf.cfMult(apow1, a,_ring.cf) @@ -938,7 +938,7 @@ cdef number *sa2si_transext_QQ(object elem, ring *_ring): cdef number *power cdef int ngens cdef int ex - cdef nMapFunc nMapFuncPtr = NULL; + cdef nMapFunc nMapFuncPtr = NULL if _ring != currRing: rChangeCurrRing(_ring) @@ -1057,7 +1057,7 @@ cdef number *sa2si_transext_FF(object elem, ring *_ring): cdef number *aux2 cdef int ngens cdef int ex - cdef nMapFunc nMapFuncPtr = NULL; + cdef nMapFunc nMapFuncPtr = NULL if _ring != currRing: rChangeCurrRing(_ring) @@ -1163,7 +1163,7 @@ cdef number *sa2si_NF(object elem, ring *_ring): cdef number *apow1 cdef number *apow2 - cdef nMapFunc nMapFuncPtr = NULL; + cdef nMapFunc nMapFuncPtr = NULL nMapFuncPtr = naSetMap(_ring.cf, currRing.cf) # choose correct mapping function @@ -1188,7 +1188,7 @@ cdef number *sa2si_NF(object elem, ring *_ring): cdef char **_ext_names _ext_names = omAlloc0(sizeof(char*)) _ext_names[0] = omStrDup(_name) - qqr = rDefault( 0, 1, _ext_names); + qqr = rDefault( 0, 1, _ext_names) rComplete(qqr,1) qqr.ShortOut = 0 @@ -1203,7 +1203,7 @@ cdef number *sa2si_NF(object elem, ring *_ring): apow2 = _ring.cf.cfMult(naCoeff, apow1,_ring.cf) n2 = _ring.cf.cfAdd(apow2, n1,_ring.cf) _ring.cf.cfDelete(&apow2, _ring.cf) - _ring.cf.cfDelete(&n1, _ring.cf); + _ring.cf.cfDelete(&n1, _ring.cf) _ring.cf.cfDelete(&naCoeff, _ring.cf) n1 = n2 @@ -1302,7 +1302,7 @@ cdef inline number *sa2si_ZZmod(IntegerMod_abstract d, ring *_ring): cdef char *_name cdef char **_ext_names - cdef nMapFunc nMapFuncPtr = NULL; + cdef nMapFunc nMapFuncPtr = NULL if _ring.cf.type == n_Z2m: _d = long(d) diff --git a/src/sage/rings/finite_rings/integer_mod.pyx b/src/sage/rings/finite_rings/integer_mod.pyx index f8b9bacc4f6..3d285a017ac 100644 --- a/src/sage/rings/finite_rings/integer_mod.pyx +++ b/src/sage/rings/finite_rings/integer_mod.pyx @@ -2174,7 +2174,7 @@ cdef class IntegerMod_gmp(IntegerMod_abstract): mpz_add(x.value, self.value, (right).value) if mpz_cmp(x.value, self.__modulus.sageInteger.value) >= 0: mpz_sub(x.value, x.value, self.__modulus.sageInteger.value) - return x; + return x cpdef _sub_(self, right): """ @@ -2189,7 +2189,7 @@ cdef class IntegerMod_gmp(IntegerMod_abstract): mpz_sub(x.value, self.value, (right).value) if mpz_sgn(x.value) == -1: mpz_add(x.value, x.value, self.__modulus.sageInteger.value) - return x; + return x cpdef _neg_(self): """ diff --git a/src/tox.ini b/src/tox.ini index d68df4848bd..7a8e44c5011 100644 --- a/src/tox.ini +++ b/src/tox.ini @@ -90,6 +90,7 @@ description = # See https://pycodestyle.pycqa.org/en/latest/intro.html#error-codes deps = pycodestyle commands = pycodestyle --select E111,E401,E701,E702,E703,W605,E711,E712,E713,E721,E722 {posargs:{toxinidir}/sage/} + pycodestyle --select E703 --filename *.pyx {posargs:{toxinidir}/sage/} [pycodestyle] max-line-length = 160 From 60f974c379e6829dd393aaf8a756b68a87a7c585 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 10 Apr 2022 11:38:05 +0200 Subject: [PATCH 116/529] remove class inheritance from object in various places --- src/sage/algebras/lie_algebras/heisenberg.py | 2 +- src/sage/categories/category.py | 4 ++-- src/sage/functions/hypergeometric.py | 6 ++--- src/sage/functions/piecewise.py | 2 +- src/sage/game_theory/matching_game.py | 2 +- src/sage/games/hexad.py | 2 +- .../hyperplane_arrangement/library.py | 2 +- src/sage/geometry/triangulation/data.pxd | 2 +- src/sage/graphs/schnyder.py | 2 +- src/sage/graphs/tutte_polynomial.py | 4 ++-- src/sage/groups/finitely_presented.py | 2 +- src/sage/groups/libgap_mixin.py | 2 +- src/sage/groups/pari_group.py | 2 +- .../groups/perm_gps/symgp_conjugacy_class.py | 2 +- src/sage/homology/chains.py | 2 +- src/sage/lfunctions/pari.py | 2 +- src/sage/modular/hypergeometric_motive.py | 2 +- src/sage/modular/modsym/p1list.pyx | 2 +- src/sage/modular/pollack_stevens/manin_map.py | 2 +- src/sage/modules/free_module.py | 2 +- src/sage/parallel/decorate.py | 10 ++++----- src/sage/parallel/map_reduce.py | 6 ++--- src/sage/parallel/use_fork.py | 4 ++-- src/sage/plot/animate.py | 2 +- src/sage/plot/arrow.py | 2 +- src/sage/plot/colors.py | 2 +- src/sage/plot/plot3d/plot3d.py | 2 +- src/sage/plot/plot3d/tachyon.py | 22 +++++++++---------- src/sage/quadratic_forms/genera/genus.py | 4 ++-- src/sage/sandpiles/examples.py | 2 +- src/sage/sat/converters/anf2cnf.py | 2 +- .../elliptic_curves/weierstrass_morphism.py | 2 +- .../riemann_surfaces/riemann_surface.py | 2 +- src/sage/schemes/toric/points.py | 6 ++--- src/sage/schemes/toric/sheaf/constructor.py | 2 +- src/sage/sets/family.py | 2 +- src/sage/sets/set_from_iterator.py | 4 ++-- src/sage/symbolic/comparison_impl.pxi | 6 ++--- src/sage/symbolic/constants.py | 2 +- src/sage/symbolic/expression.pyx | 4 ++-- src/sage/symbolic/expression_conversions.py | 4 ++-- src/sage/symbolic/operators.py | 2 +- .../topology/simplicial_set_constructions.py | 2 +- 43 files changed, 72 insertions(+), 72 deletions(-) diff --git a/src/sage/algebras/lie_algebras/heisenberg.py b/src/sage/algebras/lie_algebras/heisenberg.py index 3f2b8082d16..e1566cd6ca7 100644 --- a/src/sage/algebras/lie_algebras/heisenberg.py +++ b/src/sage/algebras/lie_algebras/heisenberg.py @@ -178,7 +178,7 @@ def step(self): class Element(LieAlgebraElement): pass -class HeisenbergAlgebra_fd(object): +class HeisenbergAlgebra_fd(): """ Common methods for finite-dimensional Heisenberg algebras. """ diff --git a/src/sage/categories/category.py b/src/sage/categories/category.py index d17ff95ce98..a52b95dda00 100644 --- a/src/sage/categories/category.py +++ b/src/sage/categories/category.py @@ -338,7 +338,7 @@ class inheritance from ``C.parent_class``. ....: Parent.__init__(self, category=Ds()) ....: def g(self): ....: return "myparent" - ....: class Element(object): + ....: class Element(): ....: pass sage: D = myparent() sage: D.__class__ @@ -1561,7 +1561,7 @@ def _make_named_class(self, name, method_provider, cache=False, picklable=True): ....: ParentMethods = 1 ....: class ElementMethods(A): ....: pass - ....: class MorphismMethods(object): + ....: class MorphismMethods(): ....: pass sage: C = BrokenCategory() sage: C._make_named_class("parent_class", "ParentMethods") diff --git a/src/sage/functions/hypergeometric.py b/src/sage/functions/hypergeometric.py index 651d43974bc..795a1ab7228 100644 --- a/src/sage/functions/hypergeometric.py +++ b/src/sage/functions/hypergeometric.py @@ -388,7 +388,7 @@ def _tderivative_(self, a, b, z, *args, **kwargs): return (t * derivative(z, diff_param) * hypergeometric([c + 1 for c in a], [c + 1 for c in b], z)) - class EvaluationMethods(object): + class EvaluationMethods(): def _fast_callable_(self, a, b, z, etb): """ @@ -1004,7 +1004,7 @@ def _derivative_(self, a, b, z, diff_param): raise NotImplementedError('derivative of hypergeometric function ' 'with respect to parameters') - class EvaluationMethods(object): + class EvaluationMethods(): def generalized(self, a, b, z): """ Return as a generalized hypergeometric function. @@ -1109,7 +1109,7 @@ def _derivative_(self, a, b, z, diff_param): raise NotImplementedError('derivative of hypergeometric function ' 'with respect to parameters') - class EvaluationMethods(object): + class EvaluationMethods(): def generalized(self, a, b, z): """ Return in terms of the generalized hypergeometric function. diff --git a/src/sage/functions/piecewise.py b/src/sage/functions/piecewise.py index 540162de07f..a3e607c9f6d 100644 --- a/src/sage/functions/piecewise.py +++ b/src/sage/functions/piecewise.py @@ -315,7 +315,7 @@ def _tderivative_(self, parameters, variable, *args, **kwds): for domain, func in parameters], var=variable) - class EvaluationMethods(object): + class EvaluationMethods(): def __pow__(self, parameters, variable, n): """ diff --git a/src/sage/game_theory/matching_game.py b/src/sage/game_theory/matching_game.py index 8dcd3eb14a2..11c04f6e5b1 100644 --- a/src/sage/game_theory/matching_game.py +++ b/src/sage/game_theory/matching_game.py @@ -938,7 +938,7 @@ def solve(self, invert=False): return {key: self._sol_dict[key][0] for key in self._suitors} -class Player(object): +class Player(): r""" A class to act as a data holder for the players used of the matching games. diff --git a/src/sage/games/hexad.py b/src/sage/games/hexad.py index 967d313dd09..dff95e8e6b8 100644 --- a/src/sage/games/hexad.py +++ b/src/sage/games/hexad.py @@ -124,7 +124,7 @@ def picture_set(A, L): return set([A[x] for x in L]) -class Minimog(object): +class Minimog(): r""" This implements the Conway/Curtis minimog idea for describing the Steiner triple system `S(5, 6, 12)`. diff --git a/src/sage/geometry/hyperplane_arrangement/library.py b/src/sage/geometry/hyperplane_arrangement/library.py index 14c5b747215..60fd9579875 100644 --- a/src/sage/geometry/hyperplane_arrangement/library.py +++ b/src/sage/geometry/hyperplane_arrangement/library.py @@ -66,7 +66,7 @@ def make_parent(base_ring, dimension, names=None): -class HyperplaneArrangementLibrary(object): +class HyperplaneArrangementLibrary(): """ The library of hyperplane arrangements. """ diff --git a/src/sage/geometry/triangulation/data.pxd b/src/sage/geometry/triangulation/data.pxd index 779c77f0a8d..1baf9381ef7 100644 --- a/src/sage/geometry/triangulation/data.pxd +++ b/src/sage/geometry/triangulation/data.pxd @@ -1,3 +1,3 @@ cdef extern from "data.h": - cdef cppclass compact_simplices(object): + cdef cppclass compact_simplices(): void push_back(int encoded_simplex) diff --git a/src/sage/graphs/schnyder.py b/src/sage/graphs/schnyder.py index f384720696d..31eadf7a77a 100644 --- a/src/sage/graphs/schnyder.py +++ b/src/sage/graphs/schnyder.py @@ -558,7 +558,7 @@ def _compute_coordinates(g, x): g.set_pos(coordinates) # Setting _pos attribute to store coordinates -class TreeNode(object): +class TreeNode(): """ A class to represent each node in the trees used by ``_realizer`` and ``_compute_coordinates`` when finding a planar geometric embedding in diff --git a/src/sage/graphs/tutte_polynomial.py b/src/sage/graphs/tutte_polynomial.py index 297b1347481..863ad8d282c 100644 --- a/src/sage/graphs/tutte_polynomial.py +++ b/src/sage/graphs/tutte_polynomial.py @@ -219,7 +219,7 @@ def edge_multiplicities(G): ######## -class Ear(object): +class Ear(): r""" An ear is a sequence of vertices @@ -373,7 +373,7 @@ def removed_from(self, G): ################## -class EdgeSelection(object): +class EdgeSelection(): pass diff --git a/src/sage/groups/finitely_presented.py b/src/sage/groups/finitely_presented.py index 10f52fc6d80..0a824d09cd1 100644 --- a/src/sage/groups/finitely_presented.py +++ b/src/sage/groups/finitely_presented.py @@ -414,7 +414,7 @@ def wrap_FpGroup(libgap_fpgroup): return FinitelyPresentedGroup(free_group, relations) -class RewritingSystem(object): +class RewritingSystem(): """ A class that wraps GAP's rewriting systems. diff --git a/src/sage/groups/libgap_mixin.py b/src/sage/groups/libgap_mixin.py index e72b5a7aeb3..018d438fffe 100644 --- a/src/sage/groups/libgap_mixin.py +++ b/src/sage/groups/libgap_mixin.py @@ -18,7 +18,7 @@ from sage.groups.class_function import ClassFunction_libgap from sage.groups.libgap_wrapper import ElementLibGAP -class GroupMixinLibGAP(object): +class GroupMixinLibGAP(): def __contains__(self, elt): r""" TESTS:: diff --git a/src/sage/groups/pari_group.py b/src/sage/groups/pari_group.py index 027bb04b321..c54cd4885df 100644 --- a/src/sage/groups/pari_group.py +++ b/src/sage/groups/pari_group.py @@ -9,7 +9,7 @@ from sage.groups.perm_gps.permgroup_named import TransitiveGroup -class PariGroup(object): +class PariGroup(): def __init__(self, x, degree): """ EXAMPLES:: diff --git a/src/sage/groups/perm_gps/symgp_conjugacy_class.py b/src/sage/groups/perm_gps/symgp_conjugacy_class.py index 0175d17b647..7fc0dbd0e14 100644 --- a/src/sage/groups/perm_gps/symgp_conjugacy_class.py +++ b/src/sage/groups/perm_gps/symgp_conjugacy_class.py @@ -15,7 +15,7 @@ import itertools -class SymmetricGroupConjugacyClassMixin(object): +class SymmetricGroupConjugacyClassMixin(): r""" Mixin class which contains methods for conjugacy classes of the symmetric group. diff --git a/src/sage/homology/chains.py b/src/sage/homology/chains.py index 35df385f23d..7bd375f35fd 100644 --- a/src/sage/homology/chains.py +++ b/src/sage/homology/chains.py @@ -25,7 +25,7 @@ from sage.structure.element import coercion_model -class CellComplexReference(object): +class CellComplexReference(): def __init__(self, cell_complex, degree, cells=None): """ diff --git a/src/sage/lfunctions/pari.py b/src/sage/lfunctions/pari.py index 33d526697f9..34959343cff 100644 --- a/src/sage/lfunctions/pari.py +++ b/src/sage/lfunctions/pari.py @@ -27,7 +27,7 @@ from sage.rings.all import (ZZ, RealField, ComplexField, PowerSeriesRing) -class lfun_generic(object): +class lfun_generic(): r""" Create a PARI `L`-function (:pari:`lfun` instance). diff --git a/src/sage/modular/hypergeometric_motive.py b/src/sage/modular/hypergeometric_motive.py index 9a8cac396b9..066869a1c57 100644 --- a/src/sage/modular/hypergeometric_motive.py +++ b/src/sage/modular/hypergeometric_motive.py @@ -392,7 +392,7 @@ def gamma_list_to_cyclotomic(galist): sorted(d for d in resu for k in range(-resu[d]))) -class HypergeometricData(object): +class HypergeometricData(): _gauss_table = {} def __init__(self, cyclotomic=None, alpha_beta=None, gamma_list=None): diff --git a/src/sage/modular/modsym/p1list.pyx b/src/sage/modular/modsym/p1list.pyx index fbe461c269d..7ec9aa65394 100644 --- a/src/sage/modular/modsym/p1list.pyx +++ b/src/sage/modular/modsym/p1list.pyx @@ -655,7 +655,7 @@ cdef int p1_normalize_xgcdtable(int N, int u, int v, return 0 -cdef class P1List(object): +cdef class P1List(): """ The class for `\mathbb{P}^1(\ZZ/N\ZZ)`, the projective line modulo `N`. diff --git a/src/sage/modular/pollack_stevens/manin_map.py b/src/sage/modular/pollack_stevens/manin_map.py index 21defc771d6..74de1b039f3 100644 --- a/src/sage/modular/pollack_stevens/manin_map.py +++ b/src/sage/modular/pollack_stevens/manin_map.py @@ -161,7 +161,7 @@ def unimod_matrices_from_infty(r, s): return [] -class ManinMap(object): +class ManinMap(): r""" Map from a set of right coset representatives of `\Gamma_0(N)` in `SL_2(\ZZ)` to a coefficient module that satisfies the Manin diff --git a/src/sage/modules/free_module.py b/src/sage/modules/free_module.py index 11d14885978..495d296c29e 100644 --- a/src/sage/modules/free_module.py +++ b/src/sage/modules/free_module.py @@ -7542,7 +7542,7 @@ def element_class(R, is_sparse): return free_module_element.FreeModuleElement_generic_dense @richcmp_method -class EchelonMatrixKey(object): +class EchelonMatrixKey(): r""" A total ordering on free modules for sorting. diff --git a/src/sage/parallel/decorate.py b/src/sage/parallel/decorate.py index 43dd7a8142c..28a758b4134 100644 --- a/src/sage/parallel/decorate.py +++ b/src/sage/parallel/decorate.py @@ -51,7 +51,7 @@ def normalize_input(a): return ((a,), {}) -class Parallel(object): +class Parallel(): r""" Create a ``parallel``-decorated function. This is the object created by :func:`parallel`. @@ -121,7 +121,7 @@ def __call__(self, f): @instancedoc -class ParallelFunction(object): +class ParallelFunction(): """ Class which parallelizes a function or class method. This is typically accessed indirectly through @@ -182,7 +182,7 @@ def __get__(self, instance, owner): methods, classmethods, and staticmethods, for both the parallel and non-parallel versions:: - sage: class Foo(object): + sage: class Foo(): ....: @parallel(2) ....: def square(self, n): ....: return n*n @@ -383,7 +383,7 @@ def parallel(p_iter='fork', ncpus=None, **kwds): staticmethods. Be sure to apply the parallel decorator after ("above") either the ``classmethod`` or ``staticmethod`` decorators:: - sage: class Foo(object): + sage: class Foo(): ....: @parallel(2) ....: def square(self, n): ....: return n*n @@ -429,7 +429,7 @@ def parallel(p_iter='fork', ncpus=None, **kwds): # def f(...): ... ################################################################### -class Fork(object): +class Fork(): """ A ``fork`` decorator class. """ diff --git a/src/sage/parallel/map_reduce.py b/src/sage/parallel/map_reduce.py index dbb92129caf..5063e7d400e 100644 --- a/src/sage/parallel/map_reduce.py +++ b/src/sage/parallel/map_reduce.py @@ -626,7 +626,7 @@ class AbortError(Exception): pass -class ActiveTaskCounterDarwin(object): +class ActiveTaskCounterDarwin(): r""" Handling the number of active tasks. @@ -739,7 +739,7 @@ def abort(self): self._active_tasks.value = 0 -class ActiveTaskCounterPosix(object): +class ActiveTaskCounterPosix(): r""" Handling the number of active tasks. @@ -882,7 +882,7 @@ def abort(self): # ActiveTaskCounter = ActiveTaskCounterDarwin # to debug Darwin implementation -class RESetMapReduce(object): +class RESetMapReduce(): r""" Map-Reduce on recursively enumerated sets. diff --git a/src/sage/parallel/use_fork.py b/src/sage/parallel/use_fork.py index e1439b1e3bf..758a572a2c2 100644 --- a/src/sage/parallel/use_fork.py +++ b/src/sage/parallel/use_fork.py @@ -20,7 +20,7 @@ from sage.misc.misc import walltime -class WorkerData(object): +class WorkerData(): """ Simple class which stores data about a running ``p_iter_fork`` worker. @@ -55,7 +55,7 @@ def __init__(self, input, starttime=None, failure=""): self.failure = failure -class p_iter_fork(object): +class p_iter_fork(): """ A parallel iterator implemented using ``fork()``. diff --git a/src/sage/plot/animate.py b/src/sage/plot/animate.py index 15922ce9bd4..c835ab823a4 100644 --- a/src/sage/plot/animate.py +++ b/src/sage/plot/animate.py @@ -1206,7 +1206,7 @@ def interactive(self, **kwds): return KeyframeAnimationGroup(g3d_frames, **kwds) -class APngAssembler(object): +class APngAssembler(): r""" Builds an APNG_ (Animated PNG) from a sequence of PNG files. This is used by the :meth:`sage.plot.animate.Animation.apng` method. diff --git a/src/sage/plot/arrow.py b/src/sage/plot/arrow.py index 93c57f991a0..a332b0578c5 100644 --- a/src/sage/plot/arrow.py +++ b/src/sage/plot/arrow.py @@ -395,7 +395,7 @@ def _render_on_subplot(self, subplot): import matplotlib.patheffects as pe - class CheckNthSubPath(object): + class CheckNthSubPath(): def __init__(self, patch, n): """ creates an callable object that returns True if the diff --git a/src/sage/plot/colors.py b/src/sage/plot/colors.py index 2017e7a44a5..e3f54f53277 100644 --- a/src/sage/plot/colors.py +++ b/src/sage/plot/colors.py @@ -358,7 +358,7 @@ def rgbcolor(c, space='rgb'): to_mpl_color = rgbcolor -class Color(object): +class Color(): def __init__(self, r='#0000ff', g=None, b=None, space='rgb'): """ An Red-Green-Blue (RGB) color model color object. For most diff --git a/src/sage/plot/plot3d/plot3d.py b/src/sage/plot/plot3d/plot3d.py index 60aeb4f4ac2..5fa37f21459 100644 --- a/src/sage/plot/plot3d/plot3d.py +++ b/src/sage/plot/plot3d/plot3d.py @@ -224,7 +224,7 @@ def f(x,y): return math.exp(x/5)*math.cos(y) from sage.misc.sageinspect import sage_getargspec, is_function_or_cython_function -class _Coordinates(object): +class _Coordinates(): """ This abstract class encapsulates a new coordinate system for plotting. Sub-classes must implement the :meth:`transform` method which, given diff --git a/src/sage/plot/plot3d/tachyon.py b/src/sage/plot/plot3d/tachyon.py index 3c3ff81dc9f..88c8eba2d51 100644 --- a/src/sage/plot/plot3d/tachyon.py +++ b/src/sage/plot/plot3d/tachyon.py @@ -1055,7 +1055,7 @@ def parametric_plot(self, f, t_0, t_f, tex, r=.1, cylinders=True, e_rel=.01, e_abs=.01)) -class Light(object): +class Light(): r""" Represent lighting objects. @@ -1105,7 +1105,7 @@ def str(self): tostr(self._color)) -class Texfunc(object): +class Texfunc(): def __init__(self, ttype=0, center=(0, 0, 0), rotate=(0, 0, 0), scale=(1, 1, 1), imagefile=''): @@ -1167,7 +1167,7 @@ def str(self): raise ValueError -class Texture(object): +class Texture(): def __init__(self, name, ambient=0.2, diffuse=0.8, specular=0.0, opacity=1.0, @@ -1242,7 +1242,7 @@ def str(self): self._texfunc) -class Sphere(object): +class Sphere(): r""" A class for creating spheres in tachyon. """ @@ -1282,7 +1282,7 @@ def str(self): """ % (tostr(self._center), self._radius, self._texture) -class Ring(object): +class Ring(): r""" An annulus of zero thickness. """ @@ -1323,7 +1323,7 @@ def str(self): self._inner, self._outer, self._texture) -class FractalLandscape(object): +class FractalLandscape(): r""" Axis-aligned fractal landscape. @@ -1365,7 +1365,7 @@ def str(self): tostr(self._center), self._texture) -class Cylinder(object): +class Cylinder(): r""" An infinite cylinder. """ @@ -1405,7 +1405,7 @@ def str(self): """ % (tostr(self._center), tostr(self._axis), self._radius, self._texture) -class Plane(object): +class Plane(): r""" An infinite plane. """ @@ -1442,7 +1442,7 @@ def str(self): """ % (tostr(self._center), tostr(self._normal), self._texture) -class FCylinder(object): +class FCylinder(): r""" A finite cylinder. """ @@ -1480,7 +1480,7 @@ def str(self): """ % (tostr(self._center), tostr(self._axis), self._radius, self._texture) -class Axis_aligned_box(object): +class Axis_aligned_box(): r""" Box with axis-aligned edges with the given min and max coordinates. """ @@ -1635,7 +1635,7 @@ def get_colors(self, list): return self._tachyon.texture_recolor(self._texture, list) -class ParametricPlot(object): +class ParametricPlot(): r""" Parametric plotting routines. """ diff --git a/src/sage/quadratic_forms/genera/genus.py b/src/sage/quadratic_forms/genera/genus.py index d30d6d57b1f..a3e6fd7c9e5 100644 --- a/src/sage/quadratic_forms/genera/genus.py +++ b/src/sage/quadratic_forms/genera/genus.py @@ -1222,7 +1222,7 @@ def two_adic_symbol(A, val): return [ [s[0]+m0] + s[1:] for s in sym + two_adic_symbol(A, val) ] -class Genus_Symbol_p_adic_ring(object): +class Genus_Symbol_p_adic_ring(): r""" Local genus symbol over a p-adic ring. @@ -2369,7 +2369,7 @@ def compartments(self): symbol = self._symbol return canonical_2_adic_compartments(symbol) -class GenusSymbol_global_ring(object): +class GenusSymbol_global_ring(): r""" This represents a collection of local genus symbols (at primes) and signature information which represent the genus of a diff --git a/src/sage/sandpiles/examples.py b/src/sage/sandpiles/examples.py index a40a4e946b9..af7516ab42c 100644 --- a/src/sage/sandpiles/examples.py +++ b/src/sage/sandpiles/examples.py @@ -25,7 +25,7 @@ from sage.sandpiles.sandpile import Sandpile from sage.graphs.graph_generators import graphs -class SandpileExamples(object): +class SandpileExamples(): """ Some examples of sandpiles. diff --git a/src/sage/sat/converters/anf2cnf.py b/src/sage/sat/converters/anf2cnf.py index 5590b149b38..e6dd330feff 100644 --- a/src/sage/sat/converters/anf2cnf.py +++ b/src/sage/sat/converters/anf2cnf.py @@ -8,5 +8,5 @@ - Martin Albrecht (2012): first version """ -class ANF2CNFConverter(object): +class ANF2CNFConverter(): pass diff --git a/src/sage/schemes/elliptic_curves/weierstrass_morphism.py b/src/sage/schemes/elliptic_curves/weierstrass_morphism.py index e41fc86a1ed..dd363cd7349 100644 --- a/src/sage/schemes/elliptic_curves/weierstrass_morphism.py +++ b/src/sage/schemes/elliptic_curves/weierstrass_morphism.py @@ -34,7 +34,7 @@ @richcmp_method -class baseWI(object): +class baseWI(): r""" This class implements the basic arithmetic of isomorphisms between Weierstrass models of elliptic curves. diff --git a/src/sage/schemes/riemann_surfaces/riemann_surface.py b/src/sage/schemes/riemann_surfaces/riemann_surface.py index f9d1e2bdce6..c0e15b2e8cf 100644 --- a/src/sage/schemes/riemann_surfaces/riemann_surface.py +++ b/src/sage/schemes/riemann_surfaces/riemann_surface.py @@ -322,7 +322,7 @@ def differential_basis_baker(f): if P.interior_contains(a)] -class RiemannSurface(object): +class RiemannSurface(): r""" Construct a Riemann Surface. This is specified by the zeroes of a bivariate polynomial with rational coefficients `f(z,w) = 0`. diff --git a/src/sage/schemes/toric/points.py b/src/sage/schemes/toric/points.py index c54f1fcd3ec..8d79a7760c6 100644 --- a/src/sage/schemes/toric/points.py +++ b/src/sage/schemes/toric/points.py @@ -44,7 +44,7 @@ from sage.parallel.decorate import Parallel -class InfinitePointEnumerator(object): +class InfinitePointEnumerator(): def __init__(self, fan, ring): """ @@ -107,7 +107,7 @@ def __iter__(self): yield tuple(p) -class NaiveFinitePointEnumerator(object): +class NaiveFinitePointEnumerator(): def __init__(self, fan, ring): """ @@ -758,7 +758,7 @@ def cardinality(self): return n -class NaiveSubschemePointEnumerator(object): +class NaiveSubschemePointEnumerator(): def __init__(self, polynomials, ambient): """ diff --git a/src/sage/schemes/toric/sheaf/constructor.py b/src/sage/schemes/toric/sheaf/constructor.py index d78f0b7af7e..74aa578d422 100644 --- a/src/sage/schemes/toric/sheaf/constructor.py +++ b/src/sage/schemes/toric/sheaf/constructor.py @@ -137,7 +137,7 @@ def LineBundle(X, D): return klyachko.Bundle(X, filtrations, check=True) -class SheafLibrary(object): +class SheafLibrary(): def __init__(self, toric_variety): """ diff --git a/src/sage/sets/family.py b/src/sage/sets/family.py index cb975e075b0..f67273d8738 100644 --- a/src/sage/sets/family.py +++ b/src/sage/sets/family.py @@ -968,7 +968,7 @@ def __hash__(self): :: - sage: class X(object): + sage: class X(): ....: def __call__(self, x): ....: return x ....: __hash__ = None diff --git a/src/sage/sets/set_from_iterator.py b/src/sage/sets/set_from_iterator.py index 281fdd61210..a4ca4574c49 100644 --- a/src/sage/sets/set_from_iterator.py +++ b/src/sage/sets/set_from_iterator.py @@ -442,7 +442,7 @@ def clear_cache(self): #TODO: move it in sage.misc ? @instancedoc -class Decorator(object): +class Decorator(): r""" Abstract class that manage documentation and sources of the wrapped object. @@ -836,7 +836,7 @@ def __get__(self, inst, cls): self.name, **self.options) -class EnumeratedSetFromIterator_method_decorator(object): +class EnumeratedSetFromIterator_method_decorator(): r""" Decorator for enumerated set built from a method. diff --git a/src/sage/symbolic/comparison_impl.pxi b/src/sage/symbolic/comparison_impl.pxi index 2b112b271cd..d2c3dcc6cd7 100644 --- a/src/sage/symbolic/comparison_impl.pxi +++ b/src/sage/symbolic/comparison_impl.pxi @@ -86,7 +86,7 @@ cpdef int print_order(lhs, rhs) except -2: return print_order_c(lhs, rhs) -class _print_key(object): +class _print_key(): def __init__(self, ex): """ @@ -154,7 +154,7 @@ cpdef print_sorted(expressions): return sorted(expressions, key=_print_key) -class _math_key(object): +class _math_key(): def __init__(self, ex): """ @@ -297,7 +297,7 @@ cpdef int mixed_order(lhs, rhs) except -2: return 0 -class _mixed_key(object): +class _mixed_key(): def __init__(self, ex): """ diff --git a/src/sage/symbolic/constants.py b/src/sage/symbolic/constants.py index 647a36fbd9e..0dc189a0b50 100644 --- a/src/sage/symbolic/constants.py +++ b/src/sage/symbolic/constants.py @@ -266,7 +266,7 @@ def unpickle_Constant(class_name, name, conversions, latex, mathml, domain): return cls(name=name) @richcmp_method -class Constant(object): +class Constant(): def __init__(self, name, conversions=None, latex=None, mathml="", domain='complex'): """ diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index 0fd0eeea6bd..3fe291f7cb5 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -13557,7 +13557,7 @@ cdef get_dynamic_class_for_function(unsigned serial): ....: def __init__(self): ....: BuiltinFunction.__init__(self, 'tfunc', nargs=1) ....: - ....: class EvaluationMethods(object): + ....: class EvaluationMethods(): ....: def argp1(self, x): ....: ''' ....: Some documentation about a bogus function. @@ -13602,7 +13602,7 @@ cdef get_dynamic_class_for_function(unsigned serial): ....: def __init__(self): ....: BuiltinFunction.__init__(self, 'tfunc', nargs=2) ....: - ....: class EvaluationMethods(object): + ....: class EvaluationMethods(): ....: def argsum(self, x, y): ....: return x + y ....: diff --git a/src/sage/symbolic/expression_conversions.py b/src/sage/symbolic/expression_conversions.py index 8a9dcce889f..678347e42a5 100644 --- a/src/sage/symbolic/expression_conversions.py +++ b/src/sage/symbolic/expression_conversions.py @@ -26,7 +26,7 @@ from functools import reduce -class FakeExpression(object): +class FakeExpression(): r""" Pynac represents `x/y` as `xy^{-1}`. Often, tree-walkers would prefer to see divisions instead of multiplications and negative exponents. @@ -124,7 +124,7 @@ def _fast_callable_(self, etb): return fast_callable(self, etb) -class Converter(object): +class Converter(): def __init__(self, use_fake_div=False): """ If use_fake_div is set to True, then the converter will try to diff --git a/src/sage/symbolic/operators.py b/src/sage/symbolic/operators.py index 2fa839149dc..986ad38ad6c 100644 --- a/src/sage/symbolic/operators.py +++ b/src/sage/symbolic/operators.py @@ -67,7 +67,7 @@ def mul_vararg(first,*rest): operator.le:'<=', operator.ge:'>='} -class FDerivativeOperator(object): +class FDerivativeOperator(): def __init__(self, function, parameter_set): """ EXAMPLES:: diff --git a/src/sage/topology/simplicial_set_constructions.py b/src/sage/topology/simplicial_set_constructions.py index 4d635475ade..5b192d019bc 100644 --- a/src/sage/topology/simplicial_set_constructions.py +++ b/src/sage/topology/simplicial_set_constructions.py @@ -703,7 +703,7 @@ def universal_property(self, *maps): data[sigma] = translate[target].apply_degeneracies(*in_common) return domain.Hom(self)(data) -class Factors(object): +class Factors(): """ Classes which inherit from this should define a ``_factors`` attribute for their instances, and this class accesses that From 6cbdf913dcbef441110c7936fb5f0d70d16be248 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sun, 10 Apr 2022 12:55:33 +0200 Subject: [PATCH 117/529] trac #33579: fix doctest for 32-bit --- src/sage/graphs/generators/random.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/graphs/generators/random.py b/src/sage/graphs/generators/random.py index 5c778d04b37..de1148f0bf2 100644 --- a/src/sage/graphs/generators/random.py +++ b/src/sage/graphs/generators/random.py @@ -97,7 +97,7 @@ def RandomGNP(n, p, seed=None, fast=True, algorithm='Sage'): sage: graphs.RandomGNP(50,.2, algorithm="Sage").size() 243 sage: graphs.RandomGNP(50,.2, algorithm="networkx").size() - 260 # 32-bit + 279 # 32-bit 209 # 64-bit """ if n < 0: From 1cbfad543b9e35654e3ab8d6db764adb5a71f6c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 10 Apr 2022 16:13:44 +0200 Subject: [PATCH 118/529] cleaning tableau_tuple (pep8, unused code) --- src/sage/combinat/tableau_tuple.py | 559 +++++++++++++++-------------- 1 file changed, 291 insertions(+), 268 deletions(-) diff --git a/src/sage/combinat/tableau_tuple.py b/src/sage/combinat/tableau_tuple.py index 68d54c2948b..f911ca60535 100644 --- a/src/sage/combinat/tableau_tuple.py +++ b/src/sage/combinat/tableau_tuple.py @@ -201,7 +201,7 @@ """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2012,2016 Andrew Mathas # # This program is free software: you can redistribute it and/or modify @@ -209,7 +209,7 @@ # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # http://www.gnu.org/licenses/ -#***************************************************************************** +# **************************************************************************** from sage.combinat.combinat import CombinatorialElement from sage.combinat.words.word import Word @@ -227,7 +227,7 @@ from sage.misc.flatten import flatten from sage.misc.lazy_attribute import lazy_attribute from sage.misc.misc_c import prod -from sage.misc.prandom import random +from sage.misc.prandom import randint from sage.arith.all import factorial from sage.rings.finite_rings.integer_mod_ring import IntegerModRing from sage.rings.integer import Integer @@ -240,9 +240,10 @@ from sage.combinat import permutation -#-------------------------------------------------- + +# ------------------------------------------------- # Tableau tuple - element class -#-------------------------------------------------- +# ------------------------------------------------- class TableauTuple(CombinatorialElement): """ A class to model a tuple of tableaux. @@ -372,7 +373,7 @@ def __classcall_private__(self, t): sage: TableauTuples(level=4)(t).parent() Tableau tuples of level 4 """ - if isinstance(t, (Tableau,TableauTuple)): + if isinstance(t, (Tableau, TableauTuple)): return t # one way or another these two cases need to be treated separately @@ -385,7 +386,7 @@ def __classcall_private__(self, t): # then try to think of t as a tableau. try: t = [Tableau(s) for s in t] - except (TypeError,ValueError): + except (TypeError, ValueError): try: t = [Tableau(t)] except ValueError: @@ -393,14 +394,11 @@ def __classcall_private__(self, t): if len(t) == 1: return Tableaux_all().element_class(Tableaux_all(), t[0]) - else: - return TableauTuples_all().element_class(TableauTuples_all(), t) - - raise ValueError( '%s is not a Tableau tuple' % t ) + return TableauTuples_all().element_class(TableauTuples_all(), t) def __init__(self, parent, t, check=True): r""" - Initializes a tableau. + Initialize a tableau. EXAMPLES:: @@ -437,7 +435,7 @@ def _repr_(self): sage: TableauTuple([[],[],[],[]]) ([], [], [], []) """ - return self.parent().options._dispatch(self,'_repr_','display') + return self.parent().options._dispatch(self, '_repr_', 'display') def _repr_list(self): """ @@ -448,7 +446,7 @@ def _repr_list(self): sage: TableauTuple([[],[],[],[]])._repr_list() '([], [], [], [])' """ - return '('+', '.join('%s'%s for s in self)+')' + return '(' + ', '.join('%s' % s for s in self) + ')' def _repr_compact(self): """ @@ -461,7 +459,7 @@ def _repr_compact(self): sage: TableauTuple([[[1,2,3],[4,5]],[],[[6]],[]])._repr_compact() '1,2,3/4,5|-|6|-' """ - return '|'.join('%s'%s._repr_compact() for s in self) + return '|'.join('%s' % s._repr_compact() for s in self) def _repr_diagram(self): """ @@ -503,7 +501,7 @@ def _repr_diagram(self): diag = [' '.join(' ' * widths[j] if i >= len(T_str) else "{:<{width}}".format(T_str[i], width=widths[j]) - for j,T_str in enumerate(str_tt)) + for j, T_str in enumerate(str_tt)) for i in range(num_cols)] if TableauTuples.options('convention') == "English": @@ -524,7 +522,7 @@ def _ascii_art_(self): def _latex_(self): r""" - Returns a LaTeX version of ``self``. + Return a LaTeX version of ``self``. EXAMPLES:: @@ -552,7 +550,7 @@ def _latex_(self): } \Bigg) sage: TableauTuples.options._reset() """ - return self.parent().options._dispatch(self,'_latex_','latex') + return self.parent().options._dispatch(self, '_latex_', 'latex') _latex_list = _repr_list @@ -577,12 +575,12 @@ def _latex_diagram(self): from sage.combinat.output import tex_from_array_tuple return r'\Bigg( %s \Bigg)' % tex_from_array_tuple(self) - def components(self): """ - Return a list of the components of tableau tuple ``self``. The - `components` are the individual :class:`Tableau` which are contained - in the tuple ``self``. + Return a list of the components of tableau tuple ``self``. + + The `components` are the individual :class:`Tableau` which are + contained in the tuple ``self``. For compatibility with :class:`TableauTuples` of :meth:`level` 1, :meth:`components` should be used to iterate over the components of @@ -640,18 +638,19 @@ def __call__(self, *cell): IndexError: The cell (3, 3, 3) is not contained in the tableau """ if isinstance(cell[0], (int, Integer)): - k,r,c = cell[0], cell[1], cell[2] + k, r, c = cell[0], cell[1], cell[2] else: - k,r,c = cell[0] + k, r, c = cell[0] try: return self[k][r][c] except IndexError: - raise IndexError("The cell (%s, %s, %s) is not contained in the tableau"% (k,r,c)) + raise IndexError("The cell (%s, %s, %s) is not contained in the tableau" % (k, r, c)) def level(self): """ - Return the level of the tableau ``self``, which is just the number of - components in the tableau tuple ``self``. + Return the level of the tableau ``self``. + + This is just the number of components in the tableau tuple ``self``. EXAMPLES:: @@ -662,7 +661,7 @@ def level(self): def shape(self): r""" - Returns the :class:`PartitionTuple` which is the shape of the tableau + Return the :class:`PartitionTuple` which is the shape of the tableau tuple ``self``. EXAMPLES:: @@ -676,8 +675,9 @@ def shape(self): def size(self): """ - Returns the size of the tableau tuple ``self``, which is just the - number of boxes, or the size, of the underlying + Return the size of the tableau tuple ``self``. + + This is just the number of boxes, or the size, of the underlying :class:`PartitionTuple`. EXAMPLES:: @@ -744,7 +744,7 @@ def pp(self): def to_word_by_row(self): """ - Returns a word obtained from a row reading of the tableau tuple + Return a word obtained from a row reading of the tableau tuple ``self``. EXAMPLES:: @@ -755,15 +755,15 @@ def to_word_by_row(self): w = [] for t in self.components()[::-1]: for row in reversed(t): - w+=row + w += row return Word(w) # an alias -- should remove? - to_word=to_word_by_row + to_word = to_word_by_row def to_word_by_column(self): """ - Returns the word obtained from a column reading of the tableau tuple + Return the word obtained from a column reading of the tableau tuple ``self``. EXAMPLES:: @@ -779,8 +779,9 @@ def to_word_by_column(self): def to_permutation(self): """ - Returns a permutation with the entries in the tableau tuple ``self`` - which is obtained by ``self`` obtained by reading the entries of the + Return a permutation with the entries in the tableau tuple ``self``. + + The permutation is obtained from ``self`` by reading the entries of the tableau tuple in order from left to right along the rows, and then top to bottom, in each component and then left to right along the components. @@ -922,9 +923,9 @@ def first_column_descent(self): True """ for k in range(len(self)): - cell=self[k].first_column_descent() + cell = self[k].first_column_descent() if cell is not None: - return (k,cell[0],cell[1]) + return (k, cell[0], cell[1]) return None def is_standard(self): @@ -1027,7 +1028,8 @@ def cells_containing(self, m): sage: t.cells_containing(6) [] """ - return [(k,r,c) for k in range(len(self)) for (r,c) in self[k].cells_containing(m)] + return [(k, r, c) for k in range(len(self)) + for (r, c) in self[k].cells_containing(m)] def up(self, n=None): """ @@ -1053,13 +1055,13 @@ def up(self, n=None): # (We could call shape().addable_cells() but this seems more efficient) for k in range(len(self)): for row in range(len(self[k])): - if row==0 or self.shape()[k][row]2: - raise ValueError('too man arguments!') + size = args[1] + elif len(args) > 2: + raise ValueError('too many arguments') # now check that the arguments are consistent - if level is not None and (not isinstance(level, (int,Integer)) or level < 1): + if level is not None and (not isinstance(level, (int, Integer)) or level < 1): raise ValueError('the level must be a positive integer') - if size is not None and (not isinstance(size, (int,Integer)) or size < 0): + if size is not None and (not isinstance(size, (int, Integer)) or size < 0): raise ValueError('the size must be a non-negative integer') if shape is not None: @@ -2857,10 +2859,10 @@ def __classcall_private__(cls, *args, **kwargs): elif shape is not None: return RowStandardTableauTuples_shape(shape) elif level is not None and size is not None: - return RowStandardTableauTuples_level_size(level,size) + return RowStandardTableauTuples_level_size(level, size) elif level is not None: return RowStandardTableauTuples_level(level) - elif size is not None: + elif size is not None: return RowStandardTableauTuples_size(size) else: return RowStandardTableauTuples_all() @@ -2889,9 +2891,9 @@ def __getitem__(self, r): Implement slices with step size different from `1` and make this a method for enumerate sets. """ - if isinstance(r, (int,Integer)): + if isinstance(r, (int, Integer)): return self.unrank(r) - elif isinstance(r,slice): + elif isinstance(r, slice): start = 0 if r.start is None else r.start stop = r.stop if stop is None and not self.is_finite(): @@ -2943,12 +2945,11 @@ def __contains__(self, t): return True elif TableauTuples.__contains__(self, t) or isinstance(t, (list, tuple)): if all(s in Tableaux() for s in t): - flatt = sorted(sum((list(row) for s in t for row in s),[])) - return (flatt == list(range(1, len(flatt)+1)) - and all(len(s) == 0 or all(row[i] < row[i+1] - for row in s for i in range(len(row)-1)) - for s in t) - ) + flatt = sorted(sum((list(row) for s in t for row in s), [])) + return (flatt == list(range(1, len(flatt) + 1)) + and all(len(s) == 0 or all(row[i] < row[i + 1] + for row in s for i in range(len(row) - 1)) + for s in t)) else: return t in RowStandardTableaux() else: @@ -2973,6 +2974,7 @@ def shape(self): """ return self._shape + class RowStandardTableauTuples_all(RowStandardTableauTuples, DisjointUnionEnumeratedSets): """ Default class of all :class:`RowStandardTableauTuples` with an arbitrary @@ -2995,8 +2997,8 @@ def __init__(self): RowStandardTableauTuples.__init__(self) from sage.combinat.partition_tuple import PartitionTuples DisjointUnionEnumeratedSets.__init__(self, - Family(PartitionTuples(), RowStandardTableauTuples_shape), - facade=True, keepkey=False) + Family(PartitionTuples(), RowStandardTableauTuples_shape), + facade=True, keepkey=False) def _repr_(self): """ @@ -3012,14 +3014,16 @@ def _repr_(self): def an_element(self): r""" - Returns a particular element of the class. + Return a particular element of the class. EXAMPLES:: sage: RowStandardTableauTuples().an_element() ([[4, 5, 6, 7]], [[2, 3]], [[1]]) """ - return self.element_class(self, reversed([[range(2**(i-1),2**i)] for i in range(1,4)])) + return self.element_class(self, reversed([[range(2**(i - 1), 2**i)] + for i in range(1, 4)])) + class RowStandardTableauTuples_level(RowStandardTableauTuples, DisjointUnionEnumeratedSets): """ @@ -3057,8 +3061,8 @@ def __init__(self, level): RowStandardTableauTuples.__init__(self) from sage.combinat.partition_tuple import PartitionTuples_level DisjointUnionEnumeratedSets.__init__(self, - Family(PartitionTuples_level(level), RowStandardTableauTuples_shape), - facade=True, keepkey=False) + Family(PartitionTuples_level(level), RowStandardTableauTuples_shape), + facade=True, keepkey=False) self._level = level def _repr_(self): @@ -3097,15 +3101,15 @@ def __contains__(self, t): return self.level() == t.level() elif RowStandardTableauTuples.__contains__(self, t): if all(s in Tableaux() for s in t): - return len(t)==self.level() + return len(t) == self.level() else: - return self.level()==1 + return self.level() == 1 else: return False def an_element(self): r""" - Returns a particular element of the class. + Return a particular element of the class. EXAMPLES:: @@ -3114,7 +3118,9 @@ def an_element(self): sage: RowStandardTableauTuples(3).an_element() ([[1]], [[2, 3]], [[4, 5, 6, 7]]) """ - return self.element_class(self, [ [range(2**(i-1),2**i)] for i in range(1,self.level()+1)]) + return self.element_class(self, [[range(2**(i - 1), 2**i)] + for i in range(1, self.level() + 1)]) + class RowStandardTableauTuples_size(RowStandardTableauTuples, DisjointUnionEnumeratedSets): """ @@ -3152,8 +3158,8 @@ def __init__(self, size): RowStandardTableauTuples.__init__(self) from sage.combinat.partition_tuple import PartitionTuples_size DisjointUnionEnumeratedSets.__init__(self, - Family(PartitionTuples_size(size), RowStandardTableauTuples_shape), - facade=True, keepkey=False) + Family(PartitionTuples_size(size), RowStandardTableauTuples_shape), + facade=True, keepkey=False) self._size = size def _repr_(self): @@ -3190,15 +3196,15 @@ def __contains__(self, t): return self.size() == t.size() elif t in RowStandardTableauTuples(): if all(s in Tableaux() for s in t): - return sum(sum(map(len,s)) for s in t) == self.size() + return sum(sum(map(len, s)) for s in t) == self.size() else: - return self.size() == sum(map(len,t)) + return self.size() == sum(map(len, t)) else: return False def an_element(self): r""" - Returns a particular element of the class. + Return a particular element of the class. EXAMPLES:: @@ -3208,18 +3214,19 @@ def an_element(self): ([[1]], [[2, 3, 4]], [], []) """ if self.size() == 0: - return self.element_class(self, [[],[],[],[]]) + return self.element_class(self, [[], [], [], []]) elif self.size() == 1: - return self.element_class(self, [[[1]],[],[],[]]) - else: - return self.element_class(self, [[[1]],[range(2,self.size()+1)],[],[]]) + return self.element_class(self, [[[1]], [], [], []]) + return self.element_class(self, [[[1]], [range(2, self.size() + 1)], + [], []]) + class RowStandardTableauTuples_level_size(RowStandardTableauTuples, DisjointUnionEnumeratedSets): """ Class of all :class:`RowStandardTableauTuples` with a fixed ``level`` and a fixed ``size``. """ - def __init__(self,level,size): + def __init__(self, level, size): r""" Initializes the class of row standard tableaux of level ``level`` and size ``size``. @@ -3257,10 +3264,11 @@ def __init__(self,level,size): RowStandardTableauTuples.__init__(self) from sage.combinat.partition_tuple import PartitionTuples_level_size DisjointUnionEnumeratedSets.__init__(self, - Family(PartitionTuples_level_size(level, size), RowStandardTableauTuples_shape), - facade=True, keepkey=False) - self._level=level - self._size=size + Family(PartitionTuples_level_size(level, size), + RowStandardTableauTuples_shape), + facade=True, keepkey=False) + self._level = level + self._size = size def _repr_(self): """ @@ -3299,15 +3307,15 @@ def __contains__(self, t): return self.size() == t.size() and self.level() == t.level() elif t in RowStandardTableauTuples(): if all(s in Tableaux() for s in t): - return len(t) == self.level() and sum(sum(map(len,s)) for s in t) == self.size() + return len(t) == self.level() and sum(sum(map(len, s)) for s in t) == self.size() else: - return self.level() == 1 and self.size() == sum(map(len,t)) + return self.level() == 1 and self.size() == sum(map(len, t)) else: return False def an_element(self): r""" - Returns a particular element of ``self``. + Return a particular element of ``self``. EXAMPLES:: @@ -3319,12 +3327,13 @@ def an_element(self): if self.size() == 0: return self.element_class(self, [[] for _ in range(self.level())]) elif self.size() == 1: - return self.element_class(self, sum([[[[1]]]],[[] for _ in range(self.level()-1)])) + return self.element_class(self, sum([[[[1]]]], [[] for _ in range(self.level() - 1)])) elif self.size() == 2: - return self.element_class(self, sum([[[[1],[2]]]],[[] for _ in range(self.level()-1)])) - else: - return self.element_class(self, sum([[[[1]]], - [[range(2,self.size()),[self.size()]]]],[[] for _ in range(self.level()-2)])) + return self.element_class(self, sum([[[[1], [2]]]], [[] for _ in range(self.level() - 1)])) + return self.element_class(self, sum([[[[1]]], + [[range(2, self.size()), + [self.size()]]]], [[] for _ in range(self.level() - 2)])) + class RowStandardTableauTuples_shape(RowStandardTableauTuples): """ @@ -3380,7 +3389,7 @@ def __contains__(self, t): if all(s in Tableaux() for s in t): return [[len(l) for l in s] for s in t] == self.shape() else: - return list(self.shape()) == sum(map(len,t)) + return list(self.shape()) == sum(map(len, t)) else: return False @@ -3466,14 +3475,14 @@ def __iter__(self): # tab[ clen[c]:clen[c+1] ][ cclen[c][r]: cclen[c][r+1] ] # where tab=[1,2,...,n] as above relations = [] - clen = [0]*(len(mu)+1) - cclen = [[0]*(len(mu[c])+1) for c in range(len(mu))] + clen = [0] * (len(mu) + 1) + cclen = [[0] * (len(mu[c]) + 1) for c in range(len(mu))] for c in range(len(mu)): for r in range(len(mu[c])): - cclen[c][r+1] = cclen[c][r] + mu[c][r] + cclen[c][r + 1] = cclen[c][r] + mu[c][r] relations += [(clen[c]+cclen[c][r]+i+1, clen[c]+cclen[c][r]+i+2) for i in range(mu[c][r]-1)] - clen[c+1] = clen[c] + cclen[c][-1] + clen[c + 1] = clen[c] + cclen[c][-1] # To generate the row standard tableau tuples we are going to generate # them from linearisations of the poset from the rows of the tableau. We @@ -3486,9 +3495,9 @@ def tableau_from_list(tab): in each component and then left to right along the components. """ return self.element_class(self, - [ [tab[clen[c]:clen[c+1]][cclen[c][r]:cclen[c][r+1]] - for r in range(len(mu[c]))] - for c in range(len(mu)) ], + [[tab[clen[c]:clen[c+1]][cclen[c][r]:cclen[c][r+1]] + for r in range(len(mu[c]))] + for c in range(len(mu))], check=False) # now run through the linear extensions and return the corresponding tableau @@ -3518,7 +3527,7 @@ def cardinality(self): def an_element(self): r""" - Returns a particular element of ``self``. + Return a particular element of ``self``. EXAMPLES:: @@ -3528,7 +3537,8 @@ def an_element(self): ([[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]], [], []) """ c = self.cardinality() - return self[c>3 and 4 or (c>1 and -1 or 0)] + return self[c > 3 and 4 or (c > 1 and -1 or 0)] + class RowStandardTableauTuples_residue(RowStandardTableauTuples): r""" @@ -3612,8 +3622,8 @@ def __contains__(self, t): except ValueError: return False - return (t.residue_sequence(self._quantum_characteristic, self._multicharge) - == self._residue) + return (t.residue_sequence(self._quantum_characteristic, + self._multicharge) == self._residue) def __iter__(self): r""" @@ -3767,6 +3777,7 @@ def an_element(self): except ValueError: return None + class RowStandardTableauTuples_residue_shape(RowStandardTableauTuples_residue): """ All row standard tableau tuples with a fixed residue and shape. @@ -3859,8 +3870,8 @@ def __contains__(self, t): except ValueError: return False return (t.shape() == self._shape - and t.residue_sequence(self._quantum_characteristic,self._multicharge) - == self._residue) + and t.residue_sequence(self._quantum_characteristic, + self._multicharge) == self._residue) def _repr_(self): """ @@ -3908,14 +3919,16 @@ def __iter__higher_levels(self): ([[1, 3]], [[4, 5], [2]])] """ if self._size == 0: - yield self.element_class(self, [[] for _ in range(self._level)], check=False) # the empty tableaux + yield self.element_class(self, [[] for _ in range(self._level)], + check=False) # the empty tableau return for t in self._standard_tableaux: yield self.element_class(self, - [ [ t[r][0] for r in range(self._cumulative_lengths[c], self._cumulative_lengths[c+1])] - for c in range(self._level)], - check=False) + [[t[r][0] for r in range(self._cumulative_lengths[c], + self._cumulative_lengths[c + 1])] + for c in range(self._level)], + check=False) @lazy_attribute def __iter__(self): @@ -3940,9 +3953,10 @@ def __iter__(self): else: return self.__iter__higher_levels -#-------------------------------------------------- + +# ------------------------------------------------- # Standard tableau tuples - parent classes -#-------------------------------------------------- +# ------------------------------------------------- class StandardTableauTuples(RowStandardTableauTuples): """ A factory class for the various classes of tuples of standard tableau. @@ -4066,12 +4080,12 @@ def __classcall_private__(cls, *args, **kwargs): size = kwargs.get('size', None) for key in kwargs: - if key not in ['level','shape','size']: + if key not in ['level', 'shape', 'size']: raise ValueError('%s is not a valid argument for StandardTableauTuples' % key) # now process the positional arguments if args: - #the first argument could be either the level or the shape + # the first argument could be either the level or the shape if isinstance(args[0], (int, Integer)): if level is not None: raise ValueError('the level was specified more than once') @@ -4092,10 +4106,10 @@ def __classcall_private__(cls, *args, **kwargs): raise ValueError('too man arguments!') # now check that the arguments are consistent - if level is not None and (not isinstance(level, (int,Integer)) or level < 1): + if level is not None and (not isinstance(level, (int, Integer)) or level < 1): raise ValueError('the level must be a positive integer') - if size is not None and (not isinstance(size, (int,Integer)) or size < 0): + if size is not None and (not isinstance(size, (int, Integer)) or size < 0): raise ValueError('the size must be a non-negative integer') if shape is not None: @@ -4126,15 +4140,14 @@ def __classcall_private__(cls, *args, **kwargs): elif shape is not None: return StandardTableauTuples_shape(shape) elif level is not None and size is not None: - return StandardTableauTuples_level_size(level,size) + return StandardTableauTuples_level_size(level, size) elif level is not None: return StandardTableauTuples_level(level) - elif size is not None: + elif size is not None: return StandardTableauTuples_size(size) else: return StandardTableauTuples_all() - def __getitem__(self, r): r""" The default implementation of ``__getitem__`` for enumerated sets does @@ -4159,9 +4172,9 @@ def __getitem__(self, r): Implement slices with step size different from `1` and make this a method for enumerate sets. """ - if isinstance(r,(int,Integer)): + if isinstance(r, (int, Integer)): return self.unrank(r) - elif isinstance(r,slice): + elif isinstance(r, slice): start = 0 if r.start is None else r.start stop = r.stop if stop is None and not self.is_finite(): @@ -4213,12 +4226,11 @@ def __contains__(self, t): return True elif TableauTuples.__contains__(self, t) or isinstance(t, (list, tuple)): if all(s in Tableaux() for s in t): - flatt=sorted(sum((list(row) for s in t for row in s),[])) - return flatt==list(range(1,len(flatt)+1)) and all(len(x)==0 or + flatt = sorted(sum((list(row) for s in t for row in s), [])) + return flatt == list(range(1, len(flatt)+1)) and all(len(x) == 0 or (all(row[i]c) - ) for x in t) + for r in range(len(x)-1) if len(x[r+1]) > c)) for x in t) else: return t in StandardTableaux() else: @@ -4243,6 +4255,7 @@ def shape(self): """ return self._shape + class StandardTableauTuples_all(StandardTableauTuples, DisjointUnionEnumeratedSets): """ Default class of all :class:`StandardTableauTuples` with an arbitrary @@ -4296,7 +4309,7 @@ def __iter__(self): EXAMPLES:: - sage: stt=StandardTableauTuples() + sage: stt = StandardTableauTuples() sage: stt[0:8] [(), ([[1]]), @@ -4320,6 +4333,7 @@ def __iter__(self): for t in StandardTableauTuples(shape): yield self.element_class(self, t, check=False) + class StandardTableauTuples_level(StandardTableauTuples, DisjointUnionEnumeratedSets): """ Class of all :class:`StandardTableauTuples` with a fixed ``level`` @@ -4383,13 +4397,12 @@ def __contains__(self, t): return self.level() == t.level() elif StandardTableauTuples.__contains__(self, t): if all(s in Tableaux() for s in t): - return len(t)==self.level() + return len(t) == self.level() else: - return self.level()==1 + return self.level() == 1 else: return False - def __iter__(self): """ Iterate through the infinite class of all @@ -4422,7 +4435,7 @@ def __iter__(self): def an_element(self): r""" - Returns a particular element of the class. + Return a particular element of the class. EXAMPLES:: @@ -4431,7 +4444,9 @@ def an_element(self): sage: StandardTableauTuples(size=4).an_element() ([[1]], [[2, 3, 4]], [], []) """ - return self.element_class(self, [ [list(range(2**(i-1),2**i))] for i in range(1,self.level()+1)]) + return self.element_class(self, [[list(range(2**(i - 1), 2**i))] + for i in range(1, self.level() + 1)]) + class StandardTableauTuples_size(StandardTableauTuples, DisjointUnionEnumeratedSets): """ @@ -4491,12 +4506,12 @@ def __contains__(self, t): False """ if isinstance(t, self.element_class): - return self.size()==t.size() + return self.size() == t.size() elif t in StandardTableauTuples(): if all(s in Tableaux() for s in t): - return sum(sum(map(len,s)) for s in t)==self.size() + return sum(sum(map(len, s)) for s in t) == self.size() else: - return self.size()==sum(map(len,t)) + return self.size() == sum(map(len, t)) else: return False @@ -4542,7 +4557,7 @@ def __iter__(self): def an_element(self): r""" - Returns a particular element of the class. + Return a particular element of the class. EXAMPLES:: @@ -4551,12 +4566,14 @@ def an_element(self): sage: StandardTableauTuples(size=4).an_element() ([[1]], [[2, 3, 4]], [], []) """ - if self.size()==0: - return self.element_class(self, [[],[],[],[]]) - elif self.size()==1: - return self.element_class(self, [[[1]],[],[],[]]) - else: - return self.element_class(self, [[[1]],[list(range(2,self.size()+1))],[],[]]) + if self.size() == 0: + return self.element_class(self, [[], [], [], []]) + elif self.size() == 1: + return self.element_class(self, [[[1]], [], [], []]) + return self.element_class(self, [[[1]], + [list(range(2, self.size() + 1))], + [], []]) + class StandardTableauTuples_level_size(StandardTableauTuples, DisjointUnionEnumeratedSets): """ @@ -4564,7 +4581,7 @@ class StandardTableauTuples_level_size(StandardTableauTuples, DisjointUnionEnume fixed ``size``. """ - def __init__(self,level,size): + def __init__(self, level, size): r""" Initializes the class of semistandard tableaux of level ``level`` and size ``size``. Input is not checked; please use @@ -4622,18 +4639,18 @@ def __contains__(self, t): False """ if isinstance(t, self.element_class): - return self.size()==t.size() and self.level()==t.level() + return self.size() == t.size() and self.level() == t.level() elif t in StandardTableauTuples(): if all(s in Tableaux() for s in t): - return len(t)==self.level() and sum(sum(map(len,s)) for s in t)==self.size() + return len(t) == self.level() and sum(sum(map(len, s)) for s in t) == self.size() else: - return self.level()==1 and self.size()==sum(map(len,t)) + return self.level() == 1 and self.size() == sum(map(len, t)) else: return False def cardinality(self): """ - Returns the number of elements in this set of tableaux. + Return the number of elements in this set of tableaux. EXAMPLES:: @@ -4644,7 +4661,7 @@ def cardinality(self): """ from sage.combinat.partition_tuple import PartitionTuples return sum(StandardTableauTuples_shape(shape).cardinality() - for shape in PartitionTuples(self.level(), self.size())) + for shape in PartitionTuples(self.level(), self.size())) def __iter__(self): """ @@ -4679,7 +4696,7 @@ def __iter__(self): def an_element(self): r""" - Returns a particular element of the class. + Return a particular element of the class. EXAMPLES:: @@ -4691,13 +4708,14 @@ def an_element(self): if self.size() == 0: return self.element_class(self, [[] for _ in range(self.level())]) elif self.size() == 1: - return self.element_class(self, sum([[[[1]]]],[[] for _ in range(self.level()-1)])) + return self.element_class(self, sum([[[[1]]]], [[] for _ in range(self.level() - 1)])) elif self.size() == 2: - return self.element_class(self, sum([[[[1],[2]]]],[[] for _ in range(self.level()-1)])) - else: - return self.element_class(self, sum([[[[1]]], - [[list(range(2,self.size())), - [self.size()]]]],[[] for _ in range(self.level()-2)])) + return self.element_class(self, sum([[[[1], [2]]]], [[] for _ in range(self.level() - 1)])) + + return self.element_class(self, sum([[[[1]]], + [[list(range(2, self.size())), + [self.size()]]]], [[] for _ in range(self.level() - 2)])) + class StandardTableauTuples_shape(StandardTableauTuples): """ @@ -4835,9 +4853,9 @@ def tableau_from_list(tab): inserting t_1,..,t_n in order into the rows of mu, from left to right in each component and then left to right along the components. """ - return self.element_class(self, [ [tab[clen[c]:clen[c+1]][cclen[c][r]:cclen[c][r+1]] - for r in range(len(mu[c]))] - for c in range(len(mu)) ], + return self.element_class(self, [[tab[clen[c]:clen[c+1]][cclen[c][r]:cclen[c][r+1]] + for r in range(len(mu[c]))] + for c in range(len(mu))], check=False) # We're now ready to start generating the tableaux. Here's the first one: @@ -4852,7 +4870,6 @@ def tableau_from_list(tab): # corresponding to the initial tableau. cols = [0]*(n+1) # cols[m] is the column index of m in tab mins = [0]*n # the kth position of tab is always larger than mins[k] - c = len(mu) offset = 0 for t in initial_tableau[::-1]: for row in range(len(t)): @@ -4872,8 +4889,9 @@ def tableau_from_list(tab): # that r swaps with. # define a list so the index i appears in component component[i] - component = flatten([[i+1]*mu[i].size() for i in range(len(mu))]) - def max_row_in_component(tab,r): + component = flatten([[i + 1] * mu[i].size() for i in range(len(mu))]) + + def max_row_in_component(tab, r): """ Return the largest integer less than r which has higher column index and is in the same or an earlier component, with the component index as @@ -4890,27 +4908,29 @@ def max_row_in_component(tab,r): while True: # loop until we drop! We'll break out of the loop when done r = 1 # find the smallest r with cols[r] r or i in changed): i += 1 new_tab[i] = t new_cols[t] = cols[tab[i]] - changed[t-1] = i + changed[t - 1] = i tab = new_tab cols = new_cols yield tableau_from_list(tab) @@ -4920,8 +4940,10 @@ def max_row_in_component(tab,r): def last(self): r""" - Returns the last standard tableau tuple in ``self``, with respect to - the order that they are generated by the iterator. This is just the + Return the last standard tableau tuple in ``self``, with respect to + the order that they are generated by the iterator. + + This is just the standard tableau tuple with the numbers `1,2, \ldots, n`, where `n` is :meth:`~TableauTuples.size`, entered in order down the columns form right to left along the components. @@ -4936,7 +4958,7 @@ def last(self): def cardinality(self): r""" - Returns the number of standard Young tableau tuples of with the same + Return the number of standard Young tableau tuples of with the same shape as the partition tuple ``self``. Let `\mu=(\mu^{(1)},\dots,\mu^{(l)})` be the ``shape`` of the @@ -4972,7 +4994,7 @@ def cardinality(self): def an_element(self): r""" - Returns a particular element of the class. + Return a particular element of the class. EXAMPLES:: @@ -4986,10 +5008,10 @@ def an_element(self): def random_element(self): r""" - Returns a random standard tableau in ``self``. + Return a random standard tableau in ``self``. We do this by randomly selecting addable nodes to place - `1, 2, \ldots, n`. Of course we could do this recursively, but it's + `1, 2, \ldots, n`. Of course we could do this recursively, but it is more efficient to keep track of the (changing) list of addable nodes as we go. @@ -5001,12 +5023,12 @@ def random_element(self): tab = [[] for _ in range(self.level())] # start with the empty tableau and add nodes mu = self.shape() cells = mu.cells() - addables = [[i,0,0] for i in range(self.level()) if mu[i] != {}] + addables = [[i, 0, 0] for i in range(self.level()) if mu[i]] m = 0 while m < mu.size(): m += 1 - i = int(round(random()*(len(addables)-1))) # index for a random addable cell - (k,r,c) = addables[i] # the actual cell + i = randint(0, len(addables) - 1) # index for a random addable cell + (k, r, c) = addables[i] # the actual cell # remove the cell we just added from the list addable nodes addables.pop(i) # add m into the tableau @@ -5016,10 +5038,10 @@ def random_element(self): tab[k].append([]) tab[k][r].append(m) # now update the list of addable cells - note they must also be in mu - if (k,r,c+1) in cells and (r == 0 or (r > 0 and len(tab[k][r-1]) > c+1)): - addables.append([k,r,c+1]) - if (k,r+1,c) in cells and (c == 0 or (c > 0 and len(tab[k]) > r+1 and len(tab[k][r+1]) == c)): - addables.append([k,r+1,c]) + if (k, r, c + 1) in cells and (r == 0 or (r > 0 and len(tab[k][r - 1]) > c + 1)): + addables.append([k, r, c + 1]) + if (k, r + 1, c) in cells and (c == 0 or (c > 0 and len(tab[k]) > r + 1 and len(tab[k][r + 1]) == c)): + addables.append([k, r + 1, c]) # Just to be safe we check that tab is standard and has shape mu by # using the class StandardTableauTuples(mu) to construct the tableau @@ -5107,8 +5129,8 @@ def __contains__(self, t): except ValueError: return False - return (t.residue_sequence(self._quantum_characteristic,self._multicharge) - == self._residue) + return (t.residue_sequence(self._quantum_characteristic, + self._multicharge) == self._residue) def __iter__(self): r""" @@ -5147,7 +5169,7 @@ def __iter__(self): yield StandardTableauTuple([[] for _ in range(self._level)]) # the empty tableaux return - for t in StandardTableaux_residue(self._residue.restrict(self._size-1)): + for t in StandardTableaux_residue(self._residue.restrict(self._size - 1)): for cell in t.shape().addable_cells(): if self._residue[self._size] == self._residue.parent().cell_residue(*cell): # a cell of the right residue @@ -5157,6 +5179,7 @@ def __iter__(self): tab = _add_entry_fast(t, cell, self._size) yield self.element_class(self, tab, check=False) + class StandardTableaux_residue_shape(StandardTableaux_residue): """ All standard tableau tuples with a fixed residue and shape. @@ -5227,8 +5250,8 @@ def __contains__(self, t): except ValueError: return False return (t.shape() == self._shape - and t.residue_sequence(self._quantum_characteristic,self._multicharge) - == self._residue) + and t.residue_sequence(self._quantum_characteristic, + self._multicharge) == self._residue) def _repr_(self): """ @@ -5261,7 +5284,7 @@ def __iter__(self): for cell in self._shape.removable_cells(): if self._residue[self._size] == self._residue.parent().cell_residue(*cell): # a cell of the right residue - for t in StandardTableaux_residue_shape(self._residue.restrict(self._size-1), + for t in StandardTableaux_residue_shape(self._residue.restrict(self._size - 1), self._shape.remove_cell(*cell)): if self._level == 1: yield t.add_entry(cell, self._size) @@ -5285,6 +5308,7 @@ def an_element(self): except ValueError: return None + def _add_entry_fast(T, cell, m): """ Helper function to set ``cell`` to ``m`` in ``T`` or add the @@ -5323,7 +5347,7 @@ def _add_entry_fast(T, cell, m): 6 8 12 14 2 11 10 """ - (k,r,c) = cell + (k, r, c) = cell tab = T.to_list() try: @@ -5337,4 +5361,3 @@ def _add_entry_fast(T, cell, m): tab[k][r].append(m) return tab - From 077a46f41f0a87fa5c8fb9d43cae70c4d8f2e9b2 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sun, 10 Apr 2022 17:22:58 +0200 Subject: [PATCH 119/529] trac #33670: add interface to nauty's gentreeg --- build/pkgs/nauty/spkg-configure.m4 | 2 +- src/sage/features/nauty.py | 2 +- src/sage/graphs/generators/families.py | 124 +++++++++++++++++++++++++ src/sage/graphs/graph_generators.py | 2 + 4 files changed, 128 insertions(+), 2 deletions(-) diff --git a/build/pkgs/nauty/spkg-configure.m4 b/build/pkgs/nauty/spkg-configure.m4 index 64a038910ef..d986105f2e3 100644 --- a/build/pkgs/nauty/spkg-configure.m4 +++ b/build/pkgs/nauty/spkg-configure.m4 @@ -2,7 +2,7 @@ # only detect nauty >= 2.6 because we use the digraph6 format from # that version -- and converseg was added in nauty-2.6. AC_DEFUN([SAGE_TEST_NAUTY_PROGS], [ - m4_foreach([nautyprog], [directg, gentourng, geng, genbg, converseg], [ + m4_foreach([nautyprog], [directg, gentourng, geng, genbg, gentreeg, converseg], [ AC_PATH_PROG([$2]nautyprog, [[$1]nautyprog]) AS_IF([test x$[$2]nautyprog = x], [sage_spkg_install_nauty=yes]) ]) diff --git a/src/sage/features/nauty.py b/src/sage/features/nauty.py index 7a3bf87b6cc..86683eb29df 100644 --- a/src/sage/features/nauty.py +++ b/src/sage/features/nauty.py @@ -52,7 +52,7 @@ def __init__(self): """ JoinFeature.__init__(self, "nauty", [NautyExecutable(name) - for name in ('directg', 'gentourng', 'geng', 'genbg', 'converseg')]) + for name in ('directg', 'gentourng', 'geng', 'genbg', 'gentreeg', 'converseg')]) def all_features(): diff --git a/src/sage/graphs/generators/families.py b/src/sage/graphs/generators/families.py index 17e3ece32c2..a779aca2420 100644 --- a/src/sage/graphs/generators/families.py +++ b/src/sage/graphs/generators/families.py @@ -22,6 +22,7 @@ from math import sin, cos, pi from sage.graphs.graph import Graph from itertools import combinations +import subprocess def JohnsonGraph(n, k): @@ -3414,6 +3415,129 @@ def trees(vertices): from sage.graphs.trees import TreeIterator return iter(TreeIterator(vertices)) +def nauty_gentreeg(options="", debug=False): + r""" + Return a generator which creates non-isomorphic trees from nauty's gentreeg + program. + + INPUT: + + - ``options`` -- string (default: ``""``); a string passed to ``gentreeg`` + as if it was run at a system command line. At a minimum, you *must* pass + the number of vertices you desire. Sage expects the graphs to be in + nauty's "sparse6" format, do not set an option to change this default or + results will be unpredictable. + + - ``debug`` -- boolean (default: ``False``); if ``True`` the first line of + ``gentreeg``'s output to standard error is captured and the first call to + the generator's ``next()`` function will return this line as a string. A + line leading with ">A" indicates a successful initiation of the program + with some information on the arguments, while a line beginning with ">E" + indicates an error with the input. + + The possible options, obtained as output of ``gentreeg -help``:: + + n : the number of vertices. Must be in range 1..128 + res/mod : only generate subset res out of subsets 0..mod-1 + -D : an upper bound for the maximum degree + -Z: : bounds on the diameter + -q : suppress auxiliary output + + Options which cause ``gentreeg`` to use an output format different than the + sparse6 format are not listed above (-p, -l, -u) as they will confuse the + creation of a Sage graph. The res/mod option can be useful when using the + output in a routine run several times in parallel. + + OUTPUT: + + A generator which will produce the graphs as Sage graphs. These will be + simple graphs: no loops, no multiple edges, no directed edges. + + .. SEEALSO:: + + :meth:`trees` -- another generator of trees + + EXAMPLES: + + The generator can be used to construct trees for testing, one at a time + (usually inside a loop). Or it can be used to create an entire list all at + once if there is sufficient memory to contain it:: + + sage: gen = graphs.nauty_gentreeg("4") + sage: next(gen) + Graph on 4 vertices + sage: next(gen) + Graph on 4 vertices + sage: next(gen) + Traceback (most recent call last): + ... + StopIteration + + The number of trees on the first few vertex counts. This aggrees with + :oeis:`A000055`:: + + sage: [len(list(graphs.nauty_gentreeg(str(i)))) for i in range(1, 15)] + [1, 1, 1, 2, 3, 6, 11, 23, 47, 106, 235, 551, 1301, 3159] + + The ``debug`` switch can be used to examine ``gentreeg``'s reaction to the + input in the ``options`` string. We illustrate success. (A failure will be + a string beginning with ">E".) Passing the "-q" switch to ``gentreeg`` will + suppress the indicator of a successful initiation, and so the first returned + value might be an empty string if ``debug`` is ``True``:: + + sage: gen = graphs.nauty_gentreeg("4", debug=True) + sage: print(next(gen)) + >A ...gentreeg Z=2:3 D=3 n=4 + sage: gen = graphs.nauty_gentreeg("4 -q", debug=True) + sage: next(gen) + '' + + TESTS: + + The number `n` of vertices must be in range 1..128:: + + sage: list(graphs.nauty_gentreeg("0", debug=False)) + Traceback (most recent call last): + ... + ValueError: wrong format of parameter options + sage: list(graphs.nauty_gentreeg("0", debug=True)) + ['>E gentreeg: n must be in the range 1..128\n'] + sage: list(graphs.nauty_gentreeg("200", debug=True)) + ['>E gentreeg: n must be in the range 1..128\n'] + + Wrong input:: + + sage: list(graphs.nauty_gentreeg("3 -x", debug=False)) + Traceback (most recent call last): + ... + ValueError: wrong format of parameter options + sage: list(graphs.nauty_gentreeg("3 -x", debug=True)) + ['>E Usage: ...gentreeg [-D#] [-Z#:#] [-ulps] [-q] n [res/mod] ... + sage: list(graphs.nauty_gentreeg("3", debug=True)) + ['>A ...gentreeg Z=2:2 D=2 n=3\n', Graph on 3 vertices] + """ + import shlex + from sage.features.nauty import NautyExecutable + gen_path = NautyExecutable("gentreeg").absolute_filename() + sp = subprocess.Popen(shlex.quote(gen_path) + " {0}".format(options), shell=True, + stdin=subprocess.PIPE, stdout=subprocess.PIPE, + stderr=subprocess.PIPE, close_fds=True, + encoding='latin-1') + msg = sp.stderr.readline() + if debug: + yield msg + elif msg.startswith('>E'): + raise ValueError('wrong format of parameter options') + gen = sp.stdout + while True: + try: + s = next(gen) + except StopIteration: + # Exhausted list of graphs from nauty geng + return + G = Graph(s[:-1], format='sparse6', loops=False, multiedges=False) + yield G + def RingedTree(k, vertex_labels = True): r""" Return the ringed tree on k-levels. diff --git a/src/sage/graphs/graph_generators.py b/src/sage/graphs/graph_generators.py index 8dcceb07fe4..6d4ebea4f1b 100644 --- a/src/sage/graphs/graph_generators.py +++ b/src/sage/graphs/graph_generators.py @@ -276,6 +276,7 @@ def __append_to_doc(methods): "SwitchedSquaredSkewHadamardMatrixGraph", "strongly_regular_graph", "trees", + "nauty_gentreeg", "triangulations", "TuranGraph", "UstimenkoGraph", @@ -2342,6 +2343,7 @@ def quadrangulations(self, order, minimum_degree=None, minimum_connectivity=None TabacjnGraph = staticmethod(families.TabacjnGraph) TadpoleGraph = staticmethod(families.TadpoleGraph) trees = staticmethod(families.trees) + nauty_gentreeg = staticmethod(families.nauty_gentreeg) TuranGraph = staticmethod(families.TuranGraph) UstimenkoGraph = staticmethod(distance_regular.UstimenkoGraph) WheelGraph = staticmethod(families.WheelGraph) From fb8f1650e190bc5e723eb6ffaee3ab9798a3bc3e Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Mon, 11 Apr 2022 11:36:45 +0800 Subject: [PATCH 120/529] add Integer.bit_length() --- src/sage/rings/integer.pyx | 56 +++++++++++++++++++++++++++++--------- 1 file changed, 43 insertions(+), 13 deletions(-) diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx index 23f4fc7d325..58766ff0bb2 100644 --- a/src/sage/rings/integer.pyx +++ b/src/sage/rings/integer.pyx @@ -1273,9 +1273,8 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): .. SEEALSO:: - :func:`nbits` (number of bits; a faster way to compute - ``len(x.bits())``; and :func:`binary`, which returns a string in - more-familiar notation. + - :meth:`bit_length`, a faster way to compute ``len(x.bits())`` + - :meth:`binary`, which returns a string in perhaps more familiar notation EXAMPLES:: @@ -1288,26 +1287,57 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): """ return self.digits(base=2) - def nbits(self): + def bit_length(self): """ - Return the number of bits in ``self``. + Return the number of bits required to represent this integer. + + Identical to :meth:`int.bit_length`. EXAMPLES:: - sage: 500.nbits() + sage: 500.bit_length() 9 - sage: 5.nbits() + sage: 5.bit_length() 3 - sage: 0.nbits() == len(0.bits()) == 0.ndigits(base=2) + sage: 0.bit_length() == len(0.bits()) == 0.ndigits(base=2) + True + sage: 12345.bit_length() == len(12345.binary()) + True + sage: 1023.bit_length() + 10 + sage: 1024.bit_length() + 11 + + TESTS:: + + sage: {ZZ(n).bit_length() == int(n).bit_length() for n in range(-9999, 9999)} + {True} + sage: n = randrange(-2^99, 2^99) + sage: ZZ(n).bit_length() == int(n).bit_length() True - sage: 12345.nbits() == len(12345.binary()) + sage: n = randrange(-2^999, 2^999) + sage: ZZ(n).bit_length() == int(n).bit_length() + True + sage: n = randrange(-2^9999, 2^9999) + sage: ZZ(n).bit_length() == int(n).bit_length() True """ - # mpz_sizeinbase(0,2) always returns 1 - if mpz_cmp_si(self.value,0) == 0: + # mpz_sizeinbase(0, 2) == 1, but int(0).bit_length() == 0 + if mpz_sgn(self.value) == 0: return int(0) - else: - return int(mpz_sizeinbase(self.value, 2)) + + return int(mpz_sizeinbase(self.value, 2)) + + def nbits(self): + r""" + Alias for :meth:`bit_length`. + + TESTS:: + + sage: {ZZ(n).nbits() == ZZ(n).bit_length() for n in range(-9999, 9999)} + {True} + """ + return self.bit_length() def trailing_zero_bits(self): """ From 6e8740ff4717ef85e2357f82cc73eb1114dbc81a Mon Sep 17 00:00:00 2001 From: Jonathan Kliem Date: Mon, 11 Apr 2022 10:54:12 +0200 Subject: [PATCH 121/529] use types directly from representation.py --- src/sage/geometry/polyhedron/backend_ppl.py | 35 ++++++++++--------- .../geometry/polyhedron/representation.py | 18 +++++++--- 2 files changed, 32 insertions(+), 21 deletions(-) diff --git a/src/sage/geometry/polyhedron/backend_ppl.py b/src/sage/geometry/polyhedron/backend_ppl.py index 3ac2bb267f7..b4f1a5e5945 100644 --- a/src/sage/geometry/polyhedron/backend_ppl.py +++ b/src/sage/geometry/polyhedron/backend_ppl.py @@ -10,6 +10,7 @@ from .base_mutable import Polyhedron_mutable from .base_QQ import Polyhedron_QQ from .base_ZZ import Polyhedron_ZZ +from .representation import VERTEX, RAY, LINE, INEQUALITY, EQUATION from sage.misc.lazy_import import lazy_import from sage.features import PythonModule @@ -99,15 +100,15 @@ def _init_from_Vrepresentation(self, vertices, rays, lines, minimize=True, verbo if vertices is None: vertices = [] for v in vertices: - gs.insert(self._convert_generator_to_ppl(v, 2)) + gs.insert(self._convert_generator_to_ppl(v, VERTEX)) if rays is None: rays = [] for r in rays: - gs.insert(self._convert_generator_to_ppl(r, 3)) + gs.insert(self._convert_generator_to_ppl(r, RAY)) if lines is None: lines = [] for l in lines: - gs.insert(self._convert_generator_to_ppl(l, 4)) + gs.insert(self._convert_generator_to_ppl(l, LINE)) if gs.empty(): ppl_polyhedron = C_Polyhedron(self.ambient_dim(), 'empty') else: @@ -141,11 +142,11 @@ def _init_from_Hrepresentation(self, ieqs, eqns, minimize=True, verbose=False): if ieqs is None: ieqs = [] for ieq in ieqs: - cs.insert(self._convert_constraint_to_ppl(ieq, 0)) + cs.insert(self._convert_constraint_to_ppl(ieq, INEQUALITY)) if eqns is None: eqns = [] for eqn in eqns: - cs.insert(self._convert_constraint_to_ppl(eqn, 1)) + cs.insert(self._convert_constraint_to_ppl(eqn, EQUATION)) if cs.empty(): ppl_polyhedron = C_Polyhedron(self.ambient_dim(), 'universe') else: @@ -371,21 +372,22 @@ def _convert_generator_to_ppl(v, typ): - ``v`` -- a vertex, ray, or line. - - ``typ`` -- integer; 2 -- vertex; 3 -- ray; 4 -- line + - ``typ`` -- integer according to `:sage:`~sage.geometry.polyhedron.representation.LINE` etc. EXAMPLES:: + sage: from sage.geometry.polyhedron.representation import VERTEX, RAY, LINE sage: P = Polyhedron() - sage: P._convert_generator_to_ppl([1, 1/2, 3], 2) + sage: P._convert_generator_to_ppl([1, 1/2, 3], VERTEX) point(2/2, 1/2, 6/2) - sage: P._convert_generator_to_ppl([1, 1/2, 3], 3) + sage: P._convert_generator_to_ppl([1, 1/2, 3], RAY) ray(2, 1, 6) - sage: P._convert_generator_to_ppl([1, 1/2, 3], 4) + sage: P._convert_generator_to_ppl([1, 1/2, 3], LINE) line(2, 1, 6) """ - if typ == 2: + if typ == VERTEX: ob = point - elif typ == 3: + elif typ == RAY: ob = ray else: ob = line @@ -395,7 +397,7 @@ def _convert_generator_to_ppl(v, typ): return ob(Linear_Expression(v, 0)) else: dv = [ d*v_i for v_i in v ] - if typ == 2: + if typ == VERTEX: return ob(Linear_Expression(dv, 0), d) else: return ob(Linear_Expression(dv, 0)) @@ -409,21 +411,22 @@ def _convert_constraint_to_ppl(c, typ): - ``c`` -- an inequality or equation. - - ``typ`` -- integer; 0 -- inequality; 3 -- equation + - ``typ`` -- integer according to `:sage:`~sage.geometry.polyhedron.representation.INEQUALITY` etc. EXAMPLES:: + sage: from sage.geometry.polyhedron.representation import INEQUALITY, EQUATION sage: P = Polyhedron() - sage: P._convert_constraint_to_ppl([1, 1/2, 3], 0) + sage: P._convert_constraint_to_ppl([1, 1/2, 3], INEQUALITY) x0+6*x1+2>=0 - sage: P._convert_constraint_to_ppl([1, 1/2, 3], 1) + sage: P._convert_constraint_to_ppl([1, 1/2, 3], EQUATION) x0+6*x1+2==0 """ d = LCM_list([denominator(c_i) for c_i in c]) dc = [ ZZ(d*c_i) for c_i in c ] b = dc[0] A = dc[1:] - if typ == 0: + if typ == INEQUALITY: return Linear_Expression(A, b) >= 0 else: return Linear_Expression(A, b) == 0 diff --git a/src/sage/geometry/polyhedron/representation.py b/src/sage/geometry/polyhedron/representation.py index 42d6fd8cbb8..336c1900db5 100644 --- a/src/sage/geometry/polyhedron/representation.py +++ b/src/sage/geometry/polyhedron/representation.py @@ -22,6 +22,14 @@ from copy import copy +# Numeric values to distinguish representation types +INEQUALITY = 0 +EQUATION = 1 +VERTEX = 2 +RAY = 3 +LINE = 4 + + ######################################################################### # PolyhedronRepresentation # / \ @@ -51,11 +59,11 @@ class PolyhedronRepresentation(SageObject): """ # Numeric values for the output of the type() method - INEQUALITY = 0 - EQUATION = 1 - VERTEX = 2 - RAY = 3 - LINE = 4 + INEQUALITY = INEQUALITY + EQUATION = EQUATION + VERTEX = VERTEX + RAY = RAY + LINE = LINE def __len__(self): """ From 94bd1ee515bed34817ba9a593eb1bc14dcb6e15b Mon Sep 17 00:00:00 2001 From: Jonathan Kliem Date: Mon, 11 Apr 2022 11:11:44 +0200 Subject: [PATCH 122/529] outsource creating of ppl generator/constraint system --- src/sage/geometry/polyhedron/backend_ppl.py | 85 +++++++++++++++------ 1 file changed, 63 insertions(+), 22 deletions(-) diff --git a/src/sage/geometry/polyhedron/backend_ppl.py b/src/sage/geometry/polyhedron/backend_ppl.py index b4f1a5e5945..68b02703cd3 100644 --- a/src/sage/geometry/polyhedron/backend_ppl.py +++ b/src/sage/geometry/polyhedron/backend_ppl.py @@ -96,19 +96,7 @@ def _init_from_Vrepresentation(self, vertices, rays, lines, minimize=True, verbo sage: from sage.geometry.polyhedron.backend_ppl import Polyhedron_ppl sage: Polyhedron_ppl._init_from_Vrepresentation(p, [], [], []) """ - gs = Generator_System() - if vertices is None: - vertices = [] - for v in vertices: - gs.insert(self._convert_generator_to_ppl(v, VERTEX)) - if rays is None: - rays = [] - for r in rays: - gs.insert(self._convert_generator_to_ppl(r, RAY)) - if lines is None: - lines = [] - for l in lines: - gs.insert(self._convert_generator_to_ppl(l, LINE)) + gs = self._convert_generators_to_ppl(vertices, rays, lines) if gs.empty(): ppl_polyhedron = C_Polyhedron(self.ambient_dim(), 'empty') else: @@ -138,15 +126,7 @@ def _init_from_Hrepresentation(self, ieqs, eqns, minimize=True, verbose=False): sage: from sage.geometry.polyhedron.backend_ppl import Polyhedron_ppl sage: Polyhedron_ppl._init_from_Hrepresentation(p, [], []) """ - cs = Constraint_System() - if ieqs is None: - ieqs = [] - for ieq in ieqs: - cs.insert(self._convert_constraint_to_ppl(ieq, INEQUALITY)) - if eqns is None: - eqns = [] - for eqn in eqns: - cs.insert(self._convert_constraint_to_ppl(eqn, EQUATION)) + cs = self._convert_constraints_to_ppl(ieqs, eqns) if cs.empty(): ppl_polyhedron = C_Polyhedron(self.ambient_dim(), 'universe') else: @@ -402,6 +382,40 @@ def _convert_generator_to_ppl(v, typ): else: return ob(Linear_Expression(dv, 0)) + @staticmethod + def _convert_generators_to_ppl(vertices, rays, lines): + r""" + Convert generators to a ``ppl`` generator system. + + INPUT: + + - ``vertices`` -- iterable of vertices or ``None`` + + - ``rays`` -- iterable of rays or ``None`` + + - ``lines`` -- iterable of lines or ``None`` + + EXAMPLES:: + + sage: P = Polyhedron() + sage: P._convert_generators_to_ppl([[1, 1/2, 3]], [[0, 1, 3/2]], [[0, 0, 1]]) + Generator_System {point(2/2, 1/2, 6/2), ray(0, 2, 3), line(0, 0, 1)} + """ + gs = Generator_System() + if vertices is None: + vertices = [] + for v in vertices: + gs.insert(Polyhedron_ppl._convert_generator_to_ppl(v, VERTEX)) + if rays is None: + rays = [] + for r in rays: + gs.insert(Polyhedron_ppl._convert_generator_to_ppl(r, RAY)) + if lines is None: + lines = [] + for l in lines: + gs.insert(Polyhedron_ppl._convert_generator_to_ppl(l, LINE)) + return gs + @staticmethod def _convert_constraint_to_ppl(c, typ): r""" @@ -431,6 +445,33 @@ def _convert_constraint_to_ppl(c, typ): else: return Linear_Expression(A, b) == 0 + @staticmethod + def _convert_constraints_to_ppl(ieqs, eqns): + r""" + Convert constraints to a ``ppl`` constraint system. + + INPUT: + + - ``ieqs`` -- iterable of inequalities or ``None`` + + - ``eqns`` -- iterable of equations or ``None`` + + EXAMPLES:: + + sage: P = Polyhedron() + sage: P._convert_constraints_to_ppl([[1, 1/2, 3]], None) + Constraint_System {x0+6*x1+2>=0} + """ + cs = Constraint_System() + if ieqs is None: + ieqs = [] + for ieq in ieqs: + cs.insert(Polyhedron_ppl._convert_constraint_to_ppl(ieq, INEQUALITY)) + if eqns is None: + eqns = [] + for eqn in eqns: + cs.insert(Polyhedron_ppl._convert_constraint_to_ppl(eqn, EQUATION)) + return cs From 5d0cbf888ee3edada8888a295e6cfc8ef231e1ed Mon Sep 17 00:00:00 2001 From: Jonathan Kliem Date: Mon, 11 Apr 2022 11:49:44 +0200 Subject: [PATCH 123/529] use abstract_method for Polyhedra --- src/sage/geometry/polyhedron/base0.py | 9 +++++---- src/sage/geometry/polyhedron/base_mutable.py | 14 ++++++++------ 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/sage/geometry/polyhedron/base0.py b/src/sage/geometry/polyhedron/base0.py index b088ab0ef8f..2e0f6a716cf 100644 --- a/src/sage/geometry/polyhedron/base0.py +++ b/src/sage/geometry/polyhedron/base0.py @@ -33,6 +33,7 @@ # **************************************************************************** from sage.misc.cachefunc import cached_method +from sage.misc.abstract_method import abstract_method from sage.structure.element import Element import sage.geometry.abc @@ -181,6 +182,7 @@ def __init__(self, parent, Vrep, Hrep, Vrep_minimal=None, Hrep_minimal=None, pre else: self._init_empty_polyhedron() + @abstract_method def _init_from_Vrepresentation(self, vertices, rays, lines, **kwds): """ Construct polyhedron from V-representation data. @@ -206,10 +208,10 @@ def _init_from_Vrepresentation(self, vertices, rays, lines, **kwds): sage: Polyhedron_base._init_from_Vrepresentation(p, [], [], []) Traceback (most recent call last): ... - NotImplementedError: a derived class must implement this method + TypeError: 'AbstractMethod' object is not callable """ - raise NotImplementedError('a derived class must implement this method') + @abstract_method def _init_from_Hrepresentation(self, ieqs, eqns, **kwds): """ Construct polyhedron from H-representation data. @@ -231,9 +233,8 @@ def _init_from_Hrepresentation(self, ieqs, eqns, **kwds): sage: Polyhedron_base._init_from_Hrepresentation(p, [], []) Traceback (most recent call last): ... - NotImplementedError: a derived class must implement this method + TypeError: 'AbstractMethod' object is not callable """ - raise NotImplementedError('a derived class must implement this method') def _init_empty_polyhedron(self): """ diff --git a/src/sage/geometry/polyhedron/base_mutable.py b/src/sage/geometry/polyhedron/base_mutable.py index 6cf6a911eda..42e77a8fcf0 100644 --- a/src/sage/geometry/polyhedron/base_mutable.py +++ b/src/sage/geometry/polyhedron/base_mutable.py @@ -5,6 +5,8 @@ The constructor does this by default. """ +from sage.misc.abstract_method import abstract_method + from .base import Polyhedron_base @@ -162,6 +164,7 @@ def is_immutable(self): """ return not self._is_mutable + @abstract_method def set_immutable(self): r""" Make this polyhedron immutable. This operation cannot be undone. @@ -173,10 +176,10 @@ def set_immutable(self): sage: Polyhedron_mutable.set_immutable(p) Traceback (most recent call last): ... - NotImplementedError: a derived class must implement this + TypeError: 'AbstractMethod' object is not callable """ - raise NotImplementedError("a derived class must implement this") + @abstract_method def Vrepresentation(self): r""" A derived class must overwrite such that it restores Vrepresentation @@ -189,11 +192,11 @@ def Vrepresentation(self): sage: Polyhedron_mutable.Vrepresentation(p) Traceback (most recent call last): ... - NotImplementedError: a derived class must implement this + TypeError: 'AbstractMethod' object is not callable """ # A derived class must implemented it to recalculate, if necessary. - raise NotImplementedError("a derived class must implement this") + @abstract_method def Hrepresentation(self): r""" A derived class must overwrite such that it restores Hrepresentation @@ -206,7 +209,6 @@ def Hrepresentation(self): sage: Polyhedron_mutable.Hrepresentation(p) Traceback (most recent call last): ... - NotImplementedError: a derived class must implement this + TypeError: 'AbstractMethod' object is not callable """ # A derived class must implemented it to recalculate, if necessary. - raise NotImplementedError("a derived class must implement this") From b61836d1c23add03997baf518fdfc9e6ad8f2885 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 11 Apr 2022 15:05:57 +0200 Subject: [PATCH 124/529] more doctests for fricas conversions --- src/sage/functions/jacobi.py | 7 +++++++ src/sage/functions/special.py | 22 +++++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/sage/functions/jacobi.py b/src/sage/functions/jacobi.py index 4153dd3ee8b..470f00c3989 100644 --- a/src/sage/functions/jacobi.py +++ b/src/sage/functions/jacobi.py @@ -178,6 +178,13 @@ def __init__(self, kind): sage: N(jacobi("sn", I, 1/2)) # abs tol 1e-12 -8.59454886300046e-73 + 1.34737147138542*I + + sage: fricas(jacobi('cn',x, 2)) # optional - fricas + jacobiCn(x,2) + sage: fricas(jacobi('sn',x, 2)) # optional - fricas + jacobiSn(x,2) + sage: fricas(jacobi('dn',x, 2)) # optional - fricas + jacobiDn(x,2) """ if kind not in ['nd', 'ns', 'nc', 'dn', 'ds', 'dc', 'sn', 'sd', 'sc', 'cn', 'cd', 'cs']: diff --git a/src/sage/functions/special.py b/src/sage/functions/special.py index e28437c11a3..3c1f6875335 100644 --- a/src/sage/functions/special.py +++ b/src/sage/functions/special.py @@ -237,7 +237,7 @@ def __init__(self): BuiltinFunction.__init__(self, 'spherical_harmonic', nargs=4, conversions=dict( maple='SphericalY', - mathematica= 'SphericalHarmonicY', + mathematica='SphericalHarmonicY', maxima='spherical_harmonic', sympy='Ynm')) @@ -608,6 +608,11 @@ def __init__(self): elliptic_ec sage: elliptic_ec(x)._sympy_() elliptic_e(x) + + TESTS:: + + sage: fricas(elliptic_ec(x)) # optional - fricas + ellipticE(x) """ BuiltinFunction.__init__(self, 'elliptic_ec', nargs=1, latex_name='E', conversions=dict(mathematica='EllipticE', @@ -818,6 +823,11 @@ def __init__(self): elliptic_f sage: elliptic_f(x, 2)._sympy_() elliptic_f(x, 2) + + TESTS:: + + sage: fricas(elliptic_f(x,2)) # optional - fricas + ellipticF(x,2) """ BuiltinFunction.__init__(self, 'elliptic_f', nargs=2, conversions=dict(mathematica='EllipticF', @@ -926,6 +936,11 @@ def __init__(self): elliptic_kc sage: elliptic_kc(x)._sympy_() elliptic_k(x) + + TESTS:: + + sage: fricas(elliptic_kc(x)) # optional - fricas + ellipticK(x) """ BuiltinFunction.__init__(self, 'elliptic_kc', nargs=1, latex_name='K', conversions=dict(mathematica='EllipticK', @@ -1027,6 +1042,11 @@ def __init__(self): elliptic_pi sage: elliptic_pi(x, pi/4, 1)._sympy_() elliptic_pi(x, pi/4, 1) + + TESTS:: + + sage: fricas(elliptic_pi(x, 2, 2)) # optional - fricas + ellipticPi(x,2,2) """ BuiltinFunction.__init__(self, 'elliptic_pi', nargs=3, conversions=dict(mathematica='EllipticPi', From 772487a77f54002cc52838e4ce207a475ec3aad3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 11 Apr 2022 19:06:03 +0200 Subject: [PATCH 125/529] more doctests for fricas conversions of orthogonal polynomials --- src/sage/functions/orthogonal_polys.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/sage/functions/orthogonal_polys.py b/src/sage/functions/orthogonal_polys.py index c988f61b92c..66c23c360a3 100644 --- a/src/sage/functions/orthogonal_polys.py +++ b/src/sage/functions/orthogonal_polys.py @@ -1645,6 +1645,13 @@ def __init__(self): gen_legendre_P sage: maxima(gen_legendre_P(20,6,x, hold=True))._sage_().expand().coefficient(x,10) 2508866163428625/128 + + TESTS:: + + sage: fricas(gen_legendre_P(2,1/2,x)) # optional - fricas + 1 + legendreP(2,-,x) + 2 """ BuiltinFunction.__init__(self, "gen_legendre_P", nargs=3, latex_name=r"\mathtt{P}", @@ -2034,6 +2041,11 @@ def __init__(self): hermite sage: hermite(x, x)._sympy_() hermite(x, x) + + TESTS:: + + sage: fricas(hermite(x, 5)) # optional - fricas + hermiteH(x,5) """ GinacFunction.__init__(self, "hermite", nargs=2, latex_name=r"H", conversions={'maxima': 'hermite', @@ -2078,6 +2090,13 @@ def __init__(self): jacobi_P sage: jacobi_P(n, a, b, x, hold=True)._sympy_() jacobi(n, a, b, x) + + TESTS:: + + sage: fricas(jacobi_P(1/2,4,1/3,x)) # optional - fricas + 1 1 + jacobiP(-,4,-,x) + 2 3 """ OrthogonalFunction.__init__(self, "jacobi_P", nargs=4, latex_name=r"P", conversions={'maxima': 'jacobi_p', From 193fa9e64bebf39a9b44e007d6b2d34748d7c092 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 11 Apr 2022 21:38:05 +0200 Subject: [PATCH 126/529] little clean-up for zero_sums.pyx (pycodestyle and doc) --- src/sage/lfunctions/zero_sums.pyx | 487 +++++++++++++++--------------- 1 file changed, 240 insertions(+), 247 deletions(-) diff --git a/src/sage/lfunctions/zero_sums.pyx b/src/sage/lfunctions/zero_sums.pyx index 489c3ffb7cf..7558561d9c2 100644 --- a/src/sage/lfunctions/zero_sums.pyx +++ b/src/sage/lfunctions/zero_sums.pyx @@ -1,5 +1,6 @@ r""" Class file for computing sums over zeros of motivic L-functions. + All computations are done to double precision. AUTHORS: @@ -7,8 +8,7 @@ AUTHORS: - Simon Spicer (2014-10): first version """ - -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2014 Simon Spicer # # This program is free software: you can redistribute it and/or modify @@ -16,7 +16,7 @@ AUTHORS: # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # https://www.gnu.org/licenses/ -#***************************************************************************** +# **************************************************************************** from sage.structure.sage_object cimport SageObject from sage.rings.integer_ring import ZZ @@ -60,6 +60,7 @@ cdef class LFunctionZeroSum_abstract(SageObject): def ncpus(self, n=None): r""" Set or return the number of CPUs to be used in parallel computations. + If called with no input, the number of CPUs currently set is returned; else this value is set to n. If n is 0 then the number of CPUs is set to the max available. @@ -88,13 +89,12 @@ cdef class LFunctionZeroSum_abstract(SageObject): sage: Z.ncpus(0) sage: Z.ncpus() # random 4 - """ if n is None: return self._ncpus - elif n<0: - raise ValueError("Input must be positive integer") - elif n==0: + elif n < 0: + raise ValueError("input must be positive integer") + elif n == 0: self._ncpus = num_cpus() NCPUS = self._ncpus else: @@ -103,8 +103,10 @@ cdef class LFunctionZeroSum_abstract(SageObject): def level(self): r""" - Return the level of the form attached to self. If self was constructed - from an elliptic curve, then this is equal to the conductor of `E`. + Return the level of the form attached to ``self``. + + If ``self`` was constructed from an elliptic curve, + then this is equal to the conductor of `E`. EXAMPLES:: @@ -112,13 +114,14 @@ cdef class LFunctionZeroSum_abstract(SageObject): sage: Z = LFunctionZeroSum(E) sage: Z.level() 389 - """ return self._level def weight(self): r""" - Return the weight of the form attached to self. If self was constructed + Return the weight of the form attached to ``self``. + + If ``self`` was constructed from an elliptic curve, then this is 2. EXAMPLES:: @@ -127,22 +130,23 @@ cdef class LFunctionZeroSum_abstract(SageObject): sage: Z = LFunctionZeroSum(E) sage: Z.weight() 2 - """ return self._k def C0(self, include_euler_gamma=True): r""" Return the constant term of the logarithmic derivative of the - completed `L`-function attached to self. This is equal to + completed `L`-function attached to ``self``. + + This is equal to `-\eta + \log(N)/2 - \log(2\pi)`, where `\eta` is the Euler-Mascheroni constant `= 0.5772...` - and `N` is the level of the form attached to self. + and `N` is the level of the form attached to ``self``. INPUT: - - ``include_euler_gamma`` -- bool (default: True); if set to - False, return the constant `\log(N)/2 - \log(2\pi)`, i.e., do + - ``include_euler_gamma`` -- bool (default: ``True``); if set to + ``False``, return the constant `\log(N)/2 - \log(2\pi)`, i.e., do not subtract off the Euler-Mascheroni constant. EXAMPLES:: @@ -153,26 +157,24 @@ cdef class LFunctionZeroSum_abstract(SageObject): 0.5666969404983447 sage: Z.C0(include_euler_gamma=False) # tol 1.0e-13 1.1439126053998776 - """ # Computed at initialization - if not include_euler_gamma: - return self._C1 - else: - return self._C0 + return self._C1 if not include_euler_gamma else self._C0 def cnlist(self, n, python_floats=False): r""" Return a list of Dirichlet coefficient of the logarithmic - derivative of the `L`-function attached to self, shifted so that + derivative of the `L`-function attached to ``self``, shifted so that the critical line lies on the imaginary axis, up to and - including n. The i-th element of the return list is a[i]. + including n. + + The i-th element of the returned list is a[i]. INPUT: - ``n`` -- non-negative integer - - ``python_floats`` -- bool (default: False); if True return a list of + - ``python_floats`` -- bool (default: ``False``); if ``True`` return a list of Python floats instead of Sage Real Double Field elements. OUTPUT: @@ -205,26 +207,28 @@ cdef class LFunctionZeroSum_abstract(SageObject): (9, 0.6103401603711721) (10, 0.0) (11, -0.21799047934530644) - """ if not python_floats: return [self.cn(i) for i in xrange(n + 1)] - else: - return [float(self.cn(i)) for i in xrange(n + 1)] + return [float(self.cn(i)) for i in xrange(n + 1)] def digamma(self, s, include_constant_term=True): r""" - Return the digamma function `\digamma(s)` on the complex input s, given by + Return the digamma function `\digamma(s)` on the complex input s. + + This is given by `\digamma(s) = -\eta + \sum_{k=1}^{\infty} \frac{s-1}{k(k+s-1)}`, where `\eta` is the Euler-Mascheroni constant `=0.5772156649\ldots`. + This function is needed in the computing the logarithmic derivative - of the `L`-function attached to self. + of the `L`-function attached to ``self``. INPUT: - ``s`` -- A complex number - - ``include_constant_term`` -- (default: True) boolean; if set False, + - ``include_constant_term`` -- (default: ``True``) boolean; if set + to ``False``, only the value of the sum over `k` is returned without subtracting off the Euler-Mascheroni constant, i.e. the returned value is equal to `\sum_{k=1}^{\infty} \frac{s-1}{k(k+s-1)}`. @@ -256,19 +260,18 @@ cdef class LFunctionZeroSum_abstract(SageObject): 1.5 sage: Z.digamma(6,include_constant_term=False) 2.283333333333333 - """ # imported here so as to avoid importing Numpy on Sage startup from scipy.special import psi - if real(s)<0 and imag(s)==0: + if real(s) < 0 and imag(s) == 0: try: z = ZZ(s) return PlusInfinity() except Exception: pass - if imag(s)==0: + if imag(s) == 0: F = RDF else: F = CDF @@ -283,7 +286,7 @@ cdef class LFunctionZeroSum_abstract(SageObject): r""" Compute the value of the logarithmic derivative `\frac{L^{\prime}}{L}` at the point s to *low* precision, where `L` - is the `L`-function attached to self. + is the `L`-function attached to ``self``. .. WARNING:: @@ -363,39 +366,39 @@ cdef class LFunctionZeroSum_abstract(SageObject): F = CDF # Inputs left of the critical line are handled via the functional # equation of the logarithmic derivative - if real(s-1)<0: - a = -2*self._C1-self.digamma(s)-self.digamma(2-s) - b,err = self.logarithmic_derivative(2-s,num_terms=num_terms) - return (a+b,err) + if real(s - 1) < 0: + a = -2 * self._C1 - self.digamma(s) - self.digamma(2 - s) + b, err = self.logarithmic_derivative(2 - s, num_terms=num_terms) + return (a + b, err) - z = s-1 + z = s - 1 sigma = RDF(real(z)) log2 = log(RDF(2)) # Compute maximum possible Dirichlet series truncation error # When s is in the critical strip: no guaranteed precision - if abs(sigma)<=0.5: + if abs(sigma) <= 0.5: err = PlusInfinity() else: - a = RDF(sigma)-RDF(0.5) - b = log(RDF(num_terms))*a - err = (b+1)*exp(-b)/a**2 + a = RDF(sigma) - RDF(0.5) + b = log(RDF(num_terms)) * a + err = (b + 1) * exp(-b) / a**2 - y = F(0) + y = F.zero() n = ZZ(2) while n <= num_terms: if n.is_prime_power(): cn = self.cn(n) - y += cn/F(n)**z + y += cn / F(n)**z n += 1 - return (y,err) + return (y, err) def completed_logarithmic_derivative(self, s, num_terms=10000): r""" Compute the value of the completed logarithmic derivative `\frac{\Lambda^{\prime}}{\Lambda}` at the point s to *low* precision, where `\Lambda = N^{s/2}(2\pi)^s \Gamma(s) L(s)` - and `L` is the `L`-function attached to self. + and `L` is the `L`-function attached to ``self``. .. WARNING:: @@ -448,20 +451,20 @@ cdef class LFunctionZeroSum_abstract(SageObject): (-6.898080633125154 + 0.22557015394248361*I, 5.623853049808912e-11) sage: Z.completed_logarithmic_derivative(complex(4.2,-1)) # tol 1.0e-13 (6.898080633125154 - 0.22557015394248361*I, 5.623853049808912e-11) - """ - if real(s-1)>=0: - Ls = self.logarithmic_derivative(s,num_terms) + if real(s - 1) >= 0: + Ls = self.logarithmic_derivative(s, num_terms) return (self._C1 + self.digamma(s) + Ls[0], Ls[1]) else: - Ls = self.logarithmic_derivative(2-s,num_terms) - return (-self._C1 - self.digamma(2-s) - Ls[0], Ls[1]) + Ls = self.logarithmic_derivative(2 - s, num_terms) + return (-self._C1 - self.digamma(2 - s) - Ls[0], Ls[1]) def zerosum(self, Delta=1, tau=0, function="sincsquared_fast", ncpus=None): r""" - Bound from above the analytic rank of the form attached to self - by computing `\sum_{\gamma} f(\Delta(\gamma-\tau))`, where - `\gamma` ranges over the imaginary parts of the zeros of `L_E(s)` + Bound from above the analytic rank of the form attached to ``self``. + + This bound is obtained by computing `\sum_{\gamma} f(\Delta(\gamma-\tau))`, + where `\gamma` ranges over the imaginary parts of the zeros of `L_E(s)` along the critical strip, and `f(x)` is an appropriate even continuous `L_2` function such that `f(0)=1`. @@ -502,9 +505,9 @@ cdef class LFunctionZeroSum_abstract(SageObject): - ``cauchy`` -- `f(x) = \frac{1}{1+x^2}`; this is only computable to low precision, and only when `\Delta < 2`. - - ``ncpus`` - (default: None) If not None, a positive integer + - ``ncpus`` - (default: ``None``) If not ``None``, a positive integer defining the number of CPUs to be used for the computation. If left as - None, the maximum available number of CPUs will be used. + ``None``, the maximum available number of CPUs will be used. Only implemented for algorithm="sincsquared_parallel"; ignored otherwise. @@ -547,31 +550,30 @@ cdef class LFunctionZeroSum_abstract(SageObject): 0.10831555377490683 sage: Z.zerosum(Delta=1,function="gaussian") # tol 1.0e-13 2.056890425029435 - """ - # If Delta>6.95, then exp(2*pi*Delta)>sys.maxsize, so we get overflow # when summing over the logarithmic derivative coefficients if Delta > 6.95: raise ValueError("Delta value too large; will result in overflow") if function == "sincsquared_parallel": - return self._zerosum_sincsquared_parallel(Delta=Delta,ncpus=ncpus) + return self._zerosum_sincsquared_parallel(Delta=Delta, ncpus=ncpus) elif function == "sincsquared_fast": return self._zerosum_sincsquared_fast(Delta=Delta) elif function == "sincsquared": - return self._zerosum_sincsquared(Delta=Delta,tau=tau) + return self._zerosum_sincsquared(Delta=Delta, tau=tau) elif function == "gaussian": return self._zerosum_gaussian(Delta=Delta) elif function == "cauchy": - return self._zerosum_cauchy(Delta=Delta,tau=tau) + return self._zerosum_cauchy(Delta=Delta, tau=tau) else: - raise ValueError("Input function not recognized.") + raise ValueError("input function not recognized") def _zerosum_sincsquared(self, Delta=1, tau=0): r""" - Bound from above the analytic rank of the form attached to self - by computing `\sum_{\gamma} f(\Delta \cdot (\gamma-\tau))`, + Bound from above the analytic rank of the form attached to ``self``. + + This bound is obtained by computing `\sum_{\gamma} f(\Delta \cdot (\gamma-\tau))`, where `\gamma` ranges over the imaginary parts of the zeros of `L_E(s)` along the critical strip, and `f(x) = \sin(\pi x)/(\pi x)` @@ -648,61 +650,59 @@ cdef class LFunctionZeroSum_abstract(SageObject): sage: Z._zerosum_sincsquared(Delta=1,tau=2.5) # tol 1.0e-13 0.058058210806477814 - """ - npi = self._pi - twopi = 2*npi + twopi = 2 * npi eg = self._euler_gamma - t = RDF(Delta*twopi) + t = RDF(Delta * twopi) expt = RDF(exp(t)) - u = t*self.C0() + u = t * self.C0() # No offset: formulae are simpler - if tau==0: - w = npi**2/6-(RDF(1)/expt).dilog() + if tau == 0: + w = npi**2 / 6 - (RDF.one() / expt).dilog() y = RDF(0) n = int(1) while n < expt: - cn = self.cn(n) - if cn!=0: - logn = log(RDF(n)) - y += cn*(t-logn) + cn = self.cn(n) + if cn != 0: + logn = RDF(n).log() + y += cn * (t - logn) n += 1 # When offset is nonzero, the digamma transform (w) must # be computed as an infinite sum else: tau = RDF(tau) - cos_tau_t = (tau*t).cos() - sin_tau_t = (tau*t).sin() - w = RDF(0) + cos_tau_t = (tau * t).cos() + sin_tau_t = (tau * t).sin() + w = RDF.zero() for k in range(1, 1001): - a1 = tau**2/(k*(k**2+tau**2)) - a2 = (k**2-tau**2)/(k**2+tau**2)**2 - a3 = (2*k*tau)/(k**2+tau**2)**2 + a1 = tau**2 / (k * (k**2 + tau**2)) + a2 = (k**2 - tau**2) / (k**2 + tau**2)**2 + a3 = (2 * k * tau) / (k**2 + tau**2)**2 - w0 = a1*t + a2 - w0 -= (a2*cos_tau_t-a3*sin_tau_t)*exp(-k*t) + w0 = a1 * t + a2 + w0 -= (a2 * cos_tau_t - a3 * sin_tau_t) * exp(-k * t) w += w0 - y = RDF(0) + y = RDF.zero() n = int(1) while n < expt: - cn = self.cn(n) - if cn!=0: - logn = log(RDF(n)) - y += cn*(t-logn)*(tau*logn).cos() + cn = self.cn(n) + if cn != 0: + logn = RDF(n).log() + y += cn * (t - logn) * (tau * logn).cos() n += 1 - return (u+w+y)*2/(t**2) + return (u + w + y) * 2 / (t**2) def _zerosum_gaussian(self, Delta=1): r""" Return an upper bound on the analytic rank of the L-series attached - to self by computing `\sum_{\gamma} f(\Delta*\gamma)`, + to ``self`` by computing `\sum_{\gamma} f(\Delta*\gamma)`, where `\gamma` ranges over the imaginary parts of the zeros of `L_E(s)` along the critical strip, and `f(x) = \exp(-x^2)`. @@ -714,7 +714,7 @@ cdef class LFunctionZeroSum_abstract(SageObject): - ``Delta`` -- positive real number (default: 1) parameter defining the tightness of the zero sum, and thus the closeness of the returned - estimate to the actual analytic rank of the form attached to self. + estimate to the actual analytic rank of the form attached to ``self``. .. WARNING:: @@ -727,7 +727,7 @@ cdef class LFunctionZeroSum_abstract(SageObject): OUTPUT: A positive real number that bounds the analytic rank of the modular form - attached to self from above. + attached to ``self`` from above. .. SEEALSO:: @@ -741,44 +741,43 @@ cdef class LFunctionZeroSum_abstract(SageObject): sage: Z = LFunctionZeroSum(E) sage: Z._zerosum_gaussian(Delta=1) # tol 1.0e-13 1.0563950773441664 - """ # imported here so as to avoid importing Numpy on Sage startup from scipy.special import erfcx npi = self._pi eg = self._euler_gamma - Deltasqrtpi = Delta*npi.sqrt() + Deltasqrtpi = Delta * npi.sqrt() - t = RDF(Delta*npi*2) - expt = RDF(exp(t)) + t = RDF(Delta * npi * 2) + expt = t.exp() u = self.C0() - w = RDF(0) + w = RDF.zero() for k in range(1, 1001): - w += RDF(1)/k - erfcx(Delta*k)*Deltasqrtpi + w += RDF.one() / k - erfcx(Delta * k) * Deltasqrtpi - y = RDF(0) + y = RDF.zero() n = int(1) # TO DO: Error analysis to make sure this bound is good enough to # avoid non-negligible truncation error while n < expt: - cn = self.cn(n) + cn = self.cn(n) if cn != 0: logn = log(RDF(n)) - y += cn*exp(-(logn/(2*Delta))**2) + y += cn * exp(-(logn / (2 * Delta))**2) n += 1 # y is the truncation of an infinite sum, so we must add a value which # exceeds the max amount we could have left out. # WARNING: Truncation error analysis has *not* been done; the value of # 0.1 is empirical. - return RDF(u+w+y+0.1)/Deltasqrtpi + return RDF(u + w + y + 0.1) / Deltasqrtpi def _zerosum_cauchy(self, Delta=1, tau=0, num_terms=None): r""" - Bound from above the analytic rank of the form attached to self + Bound from above the analytic rank of the form attached to ``self`` by computing `\sum_{\gamma} f(\Delta*(\gamma-\tau))`, where `\gamma` ranges over the imaginary parts of the zeros of `L_E(s)` along the critical strip, and `f(x) = \frac{1}{1+x^2}`. @@ -801,7 +800,7 @@ cdef class LFunctionZeroSum_abstract(SageObject): - ``num_terms`` -- positive integer (default: None): the number of terms computed in the truncated Dirichlet series for the L-function - attached to self. If left at None, this is set to + attached to ``self``. If left at None, this is set to `\ceil(e^{2 \pi \Delta})`, the same number of terms used in the other zero sum methods for this value of Delta. Increase num_terms to get more accuracy. @@ -878,51 +877,49 @@ cdef class LFunctionZeroSum_abstract(SageObject): sage: Z._zerosum_cauchy(Delta=2) Traceback (most recent call last): ... - ValueError: Bound not provably computable for Delta >= 2 - + ValueError: bound not provably computable for Delta >= 2 """ - if Delta >= 2: - raise ValueError("Bound not provably computable for Delta >= 2") + raise ValueError("bound not provably computable for Delta >= 2") Del = RDF(Delta) if num_terms is None: - num_terms = int(exp(2*self._pi*Del)) + num_terms = int(exp(2 * self._pi * Del)) - if tau==0: - one = RDF(1) - s = one/Del+one - u,err = self.completed_logarithmic_derivative(s, num_terms) + if tau == 0: + one = RDF.one() + s = one / Del + one + u, err = self.completed_logarithmic_derivative(s, num_terms) else: - one = CDF(1) - s = CDF(one/Del+one, tau) - u,err = self.completed_logarithmic_derivative(s, num_terms) + one = CDF.one() + s = CDF(one / Del + one, tau) + u, err = self.completed_logarithmic_derivative(s, num_terms) u = u.real() - return (u+err)/Del + return (u + err) / Del + cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): r""" Subclass for computing certain sums over zeros of an elliptic curve L-function without having to determine the zeros themselves. - """ cdef _E # The Elliptic curve attached to self cdef _e # PARI ellcurve object used to compute a_p values def __init__(self, E, N=None, ncpus=1): r""" - Initializes self. + Initialize self. INPUT: - ``E`` -- An elliptic curve defined over the rational numbers - - ``N`` -- (default: None) If not None, a positive integer equal to + - ``N`` -- (default: ``None``) If not ``None``, a positive integer equal to the conductor of E. This is passable so that rank estimation can be done for curves whose (large) conductor has been precomputed. - ``ncpus`` -- (default: 1) The number of CPUs to use for computations. - If set to None, the max available amount will be used. + If set to ``None``, the max available amount will be used. EXAMPLES:: @@ -933,9 +930,7 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): sage: E = EllipticCurve("5077a") sage: Z = LFunctionZeroSum_EllipticCurve(E); Z Zero sum estimator for L-function attached to Elliptic Curve defined by y^2 + y = x^3 - 7*x + 6 over Rational Field - """ - self._k = ZZ(2) self._E = E if N is not None: @@ -949,7 +944,7 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): self._euler_gamma = RDF(euler_gamma) # These constants feature in most (all?) sums over the L-function's zeros - self._C1 = log(RDF(self._level))/2 - log(self._pi*2) + self._C1 = RDF(self._level).log() / 2 - log(self._pi * 2) self._C0 = self._C1 - self._euler_gamma # Number of CPUs to use for computations @@ -962,20 +957,19 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): def __repr__(self): r""" - Representation of self. + Representation of ``self``. EXAMPLES:: sage: Z = LFunctionZeroSum(EllipticCurve("37a")); Z Zero sum estimator for L-function attached to Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field - """ s = "Zero sum estimator for L-function attached to " - return s+str(self._E) + return s + str(self._E) def elliptic_curve(self): r""" - Return the elliptic curve associated with self. + Return the elliptic curve associated with ``self``. EXAMPLES:: @@ -983,13 +977,12 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): sage: Z = LFunctionZeroSum(E) sage: Z.elliptic_curve() Elliptic Curve defined by y^2 = x^3 + 23*x + 100 over Rational Field - """ return self._E def lseries(self): r""" - Return the `L`-series associated with self. + Return the `L`-series associated with ``self``. EXAMPLES:: @@ -997,15 +990,16 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): sage: Z = LFunctionZeroSum(E) sage: Z.lseries() Complex L-series of the Elliptic Curve defined by y^2 = x^3 + 23*x + 100 over Rational Field - """ return self._E.lseries() def cn(self, n): r""" Return the nth Dirichlet coefficient of the logarithmic - derivative of the L-function attached to self, shifted so that - the critical line lies on the imaginary axis. The returned value is + derivative of the L-function attached to ``self``, shifted so that + the critical line lies on the imaginary axis. + + The returned value is zero if `n` is not a perfect prime power; when `n=p^e` for `p` a prime of bad reduction it is `-a_p^e log(p)/p^e`, where `a_p` is `+1, -1` or `0` according to the reduction type of $p$; @@ -1040,30 +1034,29 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): (9, 0.6103401603711721) (10, 0.0) (11, -0.21799047934530644) - """ n = ZZ(n) - if n==0 or n==1: - return RDF(0) + if n == 0 or n == 1: + return RDF.zero() if not n.is_prime_power(): - return RDF(0) + return RDF.zero() n_float = RDF(n) if n.is_prime(): logn = log(n_float) ap = self._E.ap(n) - return -ap*logn/n_float + return -ap * logn / n_float else: - p,e = n.perfect_power() + p, e = n.perfect_power() ap = self._E.ap(p) - logp = log(RDF(p)) + logp = RDF(p).log() if p.divides(self._level): - return - ap**e*logp/n_float - a,b = ap,2 + return - ap**e * logp / n_float + a, b = ap, 2 # Coefficients for higher powers obey recursion relation - for n in range(2, e+1): - a,b = ap*a-p*b, a - return -a*logp/n_float + for n in range(2, e + 1): + a, b = ap * a - p * b, a + return -a * logp / n_float cdef double _sincsquared_summand_1(self, unsigned long n, @@ -1082,12 +1075,11 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): summand for the sinc^2 sum at prime values for when n <= sqrt(bound), bound = exp(t) Called in self._zerosum_sincsquared_fast() method - """ ap = self._e.ellap(n) p = n sqrtp = c_sqrt(p) - thetap = c_acos(ap/(2*sqrtp)) + thetap = c_acos(ap / (2 * sqrtp)) logp = c_log(p) sqrtq = 1 @@ -1098,9 +1090,9 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): while logq < t: sqrtq *= sqrtp thetaq += thetap - z += 2*c_cos(thetaq)*(t-logq)/sqrtq + z += 2 * c_cos(thetaq) * (t - logq) / sqrtq logq += logp - return -z*logp + return -z * logp cdef double _sincsquared_summand_2(self, unsigned long n, @@ -1118,7 +1110,7 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): ap = self._e.ellap(n) p = n logp = c_log(p) - return -(t-logp)*(logp/p)*ap + return -(t - logp) * (logp / p) * ap cpdef _zerosum_sincsquared_fast(self, Delta=1, bad_primes=None): r""" @@ -1127,23 +1119,23 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): .. NOTE:: This will only produce correct output if self._E is given by its - global minimal model, i.e., if self._E.is_minimal()==True. + global minimal model, i.e., if self._E.is_minimal() is ``True``. INPUT: - ``Delta`` -- positive real parameter defining the tightness of the zero sum, and thus the closeness of the returned - estimate to the actual analytic rank of the form attached to self + estimate to the actual analytic rank of the form attached to ``self`` - - ``bad_primes`` -- (default: None) If not None, a list of primes dividing - the level of the form attached to self. This is passable so that this + - ``bad_primes`` -- (default: ``None``) If not ``None``, a list of primes dividing + the level of the form attached to ``self``. This is passable so that this method can be run on curves whose conductor is large enough to warrant precomputing bad primes. OUTPUT: A positive real number that bounds the analytic rank of the modular form - attached to self from above. + attached to ``self`` from above. .. SEEALSO:: @@ -1163,7 +1155,6 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): sage: Z = LFunctionZeroSum(E) sage: print((E.rank(),Z._zerosum_sincsquared_fast(Delta=1.5))) # tol 1.0e-13 (0, 0.0104712060086507) - """ # If Delta>6.619, then we will most likely get overflow: some ap values # will be too large to fit into a c int @@ -1171,7 +1162,7 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): raise ValueError("Delta value too large; will result in overflow") cdef double npi = self._pi - cdef double twopi = npi*2 + cdef double twopi = npi * 2 cdef double eg = self._euler_gamma cdef double t, u, w, y, z, expt, bound1, logp, logq @@ -1181,24 +1172,24 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): cdef unsigned long n cdef double N_double = self._level - t = twopi*Delta + t = twopi * Delta expt = c_exp(t) - u = t*(-eg + c_log(N_double)/2 - c_log(twopi)) - w = npi**2/6-(RDF(1)/expt).dilog() + u = t * (-eg + c_log(N_double) / 2 - c_log(twopi)) + w = npi**2 / 6 - (RDF.one() / expt).dilog() y = 0 # Do bad primes first. Add correct contributions and subtract # incorrect contribution, since we'll add them back later on. if bad_primes is None: bad_primes = self._level.prime_divisors() - bad_primes = [prime for prime in bad_primes if prime bound1: - if n_is_prime(n-4): - y += self._sincsquared_summand_1(n-4, t, ap, p, logp, thetap, + if n - 4 <= bound1 < n: + if n_is_prime(n - 4): + y += self._sincsquared_summand_1(n - 4, t, ap, p, logp, thetap, sqrtp, logq, thetaq, sqrtq, z) if n <= expt and n_is_prime(n): y += self._sincsquared_summand_2(n, t, ap, p, logp) @@ -1253,17 +1244,17 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): # Now sqrt(bound)< n < bound, so we don't need to consider higher # prime power logarithmic derivative coefficients while n <= expt: - if n_is_prime(n-4): - y += self._sincsquared_summand_2(n-4, t, ap, p, logp) + if n_is_prime(n - 4): + y += self._sincsquared_summand_2(n - 4, t, ap, p, logp) if n_is_prime(n): y += self._sincsquared_summand_2(n, t, ap, p, logp) n += 6 # Case where n-4 <= t but n isn't - n = n-4 + n = n - 4 if n <= expt and n_is_prime(n): y += self._sincsquared_summand_2(n, t, ap, p, logp) - return RDF(2*(u+w+y)/(t**2)) + return RDF(2 * (u + w + y) / (t**2)) def _get_residue_data(self, n): r""" @@ -1303,7 +1294,6 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): [23, 59, 97, 131, 167, 197], [29, 61, 101, 137, 169, 199], [31, 67, 103, 139, 173, 209]]) - """ # If n <=48, primes are sieved for modulo 210 if n <= 48: @@ -1318,24 +1308,25 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): else: from sage.rings.finite_rings.integer_mod import mod - modulus,p = 2,2 - small_primes,residue_list = [2],[1] + modulus, p = 2, 2 + small_primes, residue_list = [2], [1] num_residues = 1 # Enlarge residue_list by repeatedly applying Chinese Remainder # Theorem - while num_residues= ~1.75. .. NOTE:: This will only produce correct output if self._E is given by its - global minimal model, i.e. if self._E.is_minimal()==True. + global minimal model, i.e. if self._E.is_minimal() is ``True``. INPUT: - ``Delta`` -- positive real parameter defining the tightness of the zero sum, and thus the closeness of the returned - estimate to the actual analytic rank of the form attached to self. + estimate to the actual analytic rank of the form attached to ``self``. - - ``bad_primes`` -- (default: None) If not None, a list of primes dividing - the level of the form attached to self. This is passable so that this + - ``bad_primes`` -- (default: ``None``) If not ``None``, a list of primes dividing + the level of the form attached to ``self``. This is passable so that this method can be run on curves whose conductor is large enough to warrant precomputing bad primes. - - ``ncpus`` - (default: None) If not None, a positive integer + - ``ncpus`` - (default: ``None``) If not ``None``, a positive integer defining the number of CPUs to be used for the computation. If left as - None, the maximum available number of CPUs will be used. + ``None``, the maximum available number of CPUs will be used. OUTPUT: A positive real number that bounds the analytic rank of the modular form - attached to self from above. + attached to ``self`` from above. .. SEEALSO:: @@ -1456,7 +1448,7 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): raise ValueError("Delta value too large; will result in overflow") cdef double npi = self._pi - cdef double twopi = npi*2 + cdef double twopi = npi * 2 cdef double eg = self._euler_gamma cdef double N_double = self._level @@ -1466,11 +1458,11 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): cdef unsigned long n # Compute bounds and smooth part of sum - t = twopi*Delta + t = twopi * Delta expt = c_exp(t) - bound1 = c_exp(t/2) - u = t*(-eg + c_log(N_double)/2 - c_log(twopi)) - w = npi**2/6-(RDF(1)/expt).dilog() + bound1 = c_exp(t / 2) + u = t * (-eg + c_log(N_double) / 2 - c_log(twopi)) + w = npi**2 / 6 - (RDF.one() / expt).dilog() # Oscillating part of sum y = 0 @@ -1478,13 +1470,13 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): # incorrect contribution; the latter are added back later on. if bad_primes is None: bad_primes = self._level.prime_divisors() - bad_primes = [prime for prime in bad_primes if prime= 1.75. @@ -1733,9 +1727,9 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): ....: root_number=1,bad_primes=bad_primes,ncpus=2) # long time 32 """ - #Helper function: compute zero sum and apply parity if not False + # Helper function: compute zero sum and apply parity if not False def run_computation(Delta): - verbose("Computing zero sum with Delta = %s"%Delta) + verbose("Computing zero sum with Delta = %s" % Delta) # Empirically, the non-parallelized zero sum method runs faster # for Delta <= 1.75, regardless of the number of available CPUs. if Delta <= 1.75: @@ -1745,35 +1739,35 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): bound = self._zerosum_sincsquared_parallel(Delta=Delta, bad_primes=bad_primes, ncpus=ncpus) - verbose("Sum value is %s"%bound) + verbose("Sum value is %s" % bound) bound = bound.floor() # parity is set to -1 when we're not taking root number into # account - if parity==-1: - verbose("Without invoking parity, rank bound is %s"%bound) + if parity == -1: + verbose("Without invoking parity, rank bound is %s" % bound) return bound # parity is 0 if E has even analytic rank, and 1 if odd # analytic rank. The returned value must have the same parity # as the parity parameter. - if bound%2!=parity: + if bound % 2 != parity: bound -= 1 - verbose("Invoking parity, rank bound is %s"%bound) + verbose("Invoking parity, rank bound is %s" % bound) return bound # Get/compute parity - if root_number==1 or root_number==-1: - parity = (1-root_number)//2 - verbose("Parity set to %s."%parity) - elif root_number=="compute": + if root_number == 1 or root_number == -1: + parity = (1 - root_number) // 2 + verbose("Parity set to %s." % parity) + elif root_number == "compute": verbose("Computing curve parity...") - parity = (1-self._e.ellrootno())//2 - verbose("Curve has parity %s."%parity) - elif root_number=="ignore": + parity = (1 - self._e.ellrootno()) // 2 + verbose("Curve has parity %s." % parity) + elif root_number == "ignore": verbose("Curve parity ignored.") parity = -1 else: raise ValueError("root_number parameter not recognized") - if parity==1: + if parity == 1: halt_bound = 1 verbose("Computation will halt if at any point bound is <= 1.") else: @@ -1784,19 +1778,19 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): if max_Delta is None: verbose("Computing maximum Delta value") pi, eg = self._pi, self._euler_gamma - #1000 is arbitrary - increases Delta for small N - max_Delta = (log(RDF(self._level+1000))/2-log(2*pi)-eg)/pi + # 1000 is arbitrary - increases Delta for small N + max_Delta = (RDF(self._level + 1000).log() / 2 - log(2 * pi) - eg) / pi if max_Delta > 2.5: max_Delta = 2.5 verbose("Computed max Delta value too big; setting to 2.5") else: - verbose("Maximum Delta value to be used set at %s"%max_Delta) + verbose("Maximum Delta value to be used set at %s" % max_Delta) else: - verbose("Maximum Delta value to be used set at %s"%max_Delta) + verbose("Maximum Delta value to be used set at %s" % max_Delta) # When max_Delta <= 1 it's not worth running the computation # multiple times, as it's so quick anyway - if not adaptive or max_Delta<=1: + if not adaptive or max_Delta <= 1: return run_computation(max_Delta) else: bound_list = [] @@ -1820,9 +1814,10 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): # Since the zero sum is not strictly decreasing in Delta, # the last value is not necessarily the smallest smallest_bound = min(bound_list) - verbose("Smallest bound computed is %s"%smallest_bound) + verbose("Smallest bound computed is %s" % smallest_bound) return smallest_bound + def LFunctionZeroSum(X, *args, **kwds): r""" Constructor for the LFunctionZeroSum class. @@ -1848,20 +1843,18 @@ def LFunctionZeroSum(X, *args, **kwds): sage: LFunctionZeroSum(E) Traceback (most recent call last): ... - NotImplementedError: Currently only implemented for elliptic curves over QQ + NotImplementedError: currently only implemented for elliptic curves over QQ sage: f = Newforms(46)[0] sage: LFunctionZeroSum(f) Traceback (most recent call last): ... - NotImplementedError: Currently only implemented for elliptic curves over QQ - + NotImplementedError: currently only implemented for elliptic curves over QQ """ - # Here to avoid import recursion from sage.schemes.elliptic_curves.ell_rational_field import EllipticCurve_rational_field - if isinstance(X,EllipticCurve_rational_field): + if isinstance(X, EllipticCurve_rational_field): return LFunctionZeroSum_EllipticCurve(X, *args, **kwds) - raise NotImplementedError("Currently only implemented for elliptic curves over QQ") + raise NotImplementedError("currently only implemented for elliptic curves over QQ") From 106603ea6ce35f19435b5ae17eef9617b01705ec Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 11 Apr 2022 17:31:05 -0700 Subject: [PATCH 127/529] src/doc/en/developer/trac.rst: Expand GitHub account instructions, remove legacy account instructions (duplicated from trac main page) --- src/doc/en/developer/trac.rst | 41 +++++++++++++++++------------------ 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/src/doc/en/developer/trac.rst b/src/doc/en/developer/trac.rst index ad7b5f1db8a..dcd827e5f99 100644 --- a/src/doc/en/developer/trac.rst +++ b/src/doc/en/developer/trac.rst @@ -38,27 +38,26 @@ the :trac:`Sage trac timeline `. Obtaining an Account ==================== -**New:** Previously, it was necessary to manually request a Trac account in -order to post anything to Sage's Trac. Now, if you have a GitHub account, you -may log in using it to create and comment on tickets, and edit wiki pages on -Sage's Trac. - -A manual account request is currently only necessary if you prefer not to -use GitHub or if you want to log into the old `Sage Wiki -`_. This may change as well in the future. - -To obtain a non-GitHub account, send an email to -``sage-trac-account@googlegroups.com`` containing: - -* your full name, -* preferred username, -* contact email, -* and reason for needing a trac account - -Your trac account also grants you access to the `sage wiki -`_. Make sure you understand the review process, and -the procedures for opening and closing tickets before making changes. The -remainder of this chapter contains various guidelines on using the trac server. +If you do not have an account on GitHub yet, choose a user name and +`create an account `_. + +Using your GitHub account, you can log in to: + +- `the Sage trac server `_. + + On the Sage trac server, click the link "GitHub Login" in the top + right corner and follow the prompts. + + Within the Sage trac server, your GitHub user name will be prefixed + with the letters ``gh-`` (which stand for "GitHub"). + +- GitLab, where the mirror repository `sagemath/sage + `_ accepts Merge Requests. + + In GitLab, click the button "Sign in / Register" in the top right + corner, and then use the button "Sign in with GitHub" and follow the + prompts. + Trac authentication through SSH =============================== From e500597cb8953f34d1d4ffaf249befc54812ae71 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 11 Apr 2022 17:45:10 -0700 Subject: [PATCH 128/529] src/doc/en/developer/trac.rst: Clarify Authors field, purpose of tickets --- src/doc/en/developer/trac.rst | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/doc/en/developer/trac.rst b/src/doc/en/developer/trac.rst index dcd827e5f99..6f72a6a2f00 100644 --- a/src/doc/en/developer/trac.rst +++ b/src/doc/en/developer/trac.rst @@ -43,7 +43,8 @@ If you do not have an account on GitHub yet, choose a user name and Using your GitHub account, you can log in to: -- `the Sage trac server `_. +- `the Sage trac server `_, so that you can + open tickets and participate in discussions on existing tickets. On the Sage trac server, click the link "GitHub Login" in the top right corner and follow the prompts. @@ -287,7 +288,8 @@ of fields that can be changed. Here is a comprehensive overview (for the * **Merged in:** The Sage release where the ticket was merged in. Only changed by the release manager. -* **Authors:** Real name of the ticket author(s). +* **Authors:** Real name of the ticket author(s). Set this field only if you + intend to provide code. * **Reviewers:** Real name of the ticket reviewer(s). @@ -323,8 +325,9 @@ of its page. It indicates who has to work on it. - **new** -- the ticket has only been created (or the author forgot to change the status to something else). - If you want to work on it yourself it is better to leave a comment to say - so. It could avoid having two persons doing the same job. + If you intend to work on the code yourself, put your name in the Authors + field, or leave a comment to say so. It could avoid having two persons doing + the same job. - **needs_review** -- the code is ready to be peer-reviewed. If the code is not yours, then you can review it. See :ref:`chapter-review`. From 94717ee20571f408f482d2008cab3cf1dd2f3129 Mon Sep 17 00:00:00 2001 From: Jean-Florent Raymond Date: Tue, 12 Apr 2022 08:33:25 +0200 Subject: [PATCH 129/529] ticket 33639: replacing the deprecated graph editor with a call to phitigra --- src/sage/graphs/graph_editor.py | 148 +++----------------------------- 1 file changed, 14 insertions(+), 134 deletions(-) diff --git a/src/sage/graphs/graph_editor.py b/src/sage/graphs/graph_editor.py index e56c443b8f5..4246b3c441f 100644 --- a/src/sage/graphs/graph_editor.py +++ b/src/sage/graphs/graph_editor.py @@ -2,7 +2,7 @@ Graph editor """ # **************************************************************************** -# Copyright (C) 2009 Radoslav Kirov +# Copyright (C) 2021 Jean-Florent Raymond # # Distributed under the terms of the GNU General Public License (GPL) # @@ -15,154 +15,34 @@ # # https://www.gnu.org/licenses/ # **************************************************************************** -import sys -from .graph_generators import graphs -from sage.misc.html import html - -def graph_to_js(g): - """ - Returns a string representation of a :class:`Graph` instance - usable by the :func:`graph_editor`. The encoded information is - the number of vertices, their 2D positions, and a list of edges. - - INPUT: - - - ``g`` - a :class:`Graph` instance - - OUTPUT: - - - a string - - EXAMPLES:: - - sage: from sage.graphs.graph_editor import graph_to_js - sage: G = graphs.CompleteGraph(4) - sage: graph_to_js(G) - 'num_vertices=4;edges=[[0,1],[0,2],[0,3],[1,2],[1,3],[2,3]];pos=[[0.5,0.0],[0.0,0.5],[0.5,1.0],[1.0,0.5]];' - sage: graph_to_js(graphs.StarGraph(2)) - 'num_vertices=3;edges=[[0,1],[0,2]];pos=[[0.0,0.5],[0.0,0.0],[0.0,1.0]];' - """ - string = '' - vertex_list = list(g.get_vertices()) - string += 'num_vertices=' + str(len(vertex_list)) + ';' - string += 'edges=[' - for i, e in enumerate(g.edges()): - if i: - string += ',' - string += '[' + str(vertex_list.index(e[0])) + ',' + str(vertex_list.index(e[1])) + ']' - string += '];' - string += 'pos=[' - pos = g.get_pos() - max_x = max([i[0] for i in pos.values()]) - max_y = max([i[1] for i in pos.values()]) - min_x = min([i[0] for i in pos.values()]) - min_y = min([i[1] for i in pos.values()]) - if max_x == 0: - max_x = 1 - if max_y == 0: - max_y = 1 - for i, v in enumerate(vertex_list): - if i: - string += ',' - new_pos = [float(pos[v][0] - min_x) / (max_x - min_x), - 1.0 - float(pos[v][1] - min_y) / (max_y - min_y)] - string += str(new_pos) - string += '];' - string = string.replace(' ', '') - return string - - -def graph_editor(graph=None, graph_name=None, - replace_input=True, **layout_options): +def graph_editor(graph=None, **editor_options): """ - Opens a graph editor in the Sage notebook. + Open a graph editor in the Jupyter notebook. INPUT: - - ``graph`` - a :class:`Graph` instance (default: - graphs.CompleteGraph(2)); the graph to edit + - ``graph`` - a :class:`Graph` instance (default: `None'); the + graph to edit. - - ``graph_name`` - a string (default: None); the variable name to - use for the updated instance; by default, this function attempts - to determine the name automatically - - - ``replace_input`` - a boolean (default: True); whether to - replace the text in the input cell with the updated graph data - when "Save" is clicked; if this is False, the data is **still** - evaluated as if it had been entered in the cell + - ``layout_options`` - options for the editor. EXAMPLES:: sage: g = graphs.CompleteGraph(3) sage: graph_editor(g) # not tested sage: graph_editor(graphs.HouseGraph()) # not tested - sage: graph_editor(graph_name='my_graph') # not tested sage: h = graphs.StarGraph(6) - sage: graph_editor(h, replace_input=False) # not tested """ - import sagenb.notebook.interact - if graph is None: - graph = graphs.CompleteGraph(2) - - return "This graph editor only runs in the deprecated Sage notebook." - - graph.layout(save_pos=True, **layout_options) - - if graph_name is None: - graph_name = '' - locs = sys._getframe(1).f_locals - for var in locs: - if id(locs[var]) == id(graph): - graph_name = var - - cell_id = sagenb.notebook.interact.SAGE_CELL_ID - - # TODO: Put reasonable checks for large graphs, before disaster - # occurs (i.e., breaks browser). + try: + from phitigra import GraphEditor + except ModuleNotFoundError: + raise ModuleNotFoundError("The graph editor is provided by the optional package phitigra, which currently not installed.") - close_button = r"""""" % locals() + from .graph import Graph - if replace_input: - eval_strategy = r""" - f += ' graph_editor(' + g[2] + ');' - \$('#cell_input_%(cell_id)s').val(f); - cell_input_resize(%(cell_id)s); - evaluate_cell(%(cell_id)s, false); -""" % locals() - else: - eval_strategy = r""" - saved_input = \$('#cell_input_%(cell_id)s').val(); - \$('#cell_input_%(cell_id)s').val(f); - evaluate_cell(%(cell_id)s, false); - \$('#cell_input_%(cell_id)s').val(saved_input); - send_cell_input(%(cell_id)s); - cell_input_resize(%(cell_id)s); -""" % locals() - - update_button = r"""""" % locals() - - graph_js = graph_to_js(graph) - data_fields = """""" % locals() - - return html(r"""
- - -
%(data_fields)s
%(update_button)s%(close_button)s
""" % locals()) - -# This is commented out because the mouse_out call raises an error in -# Firebug's console when the event fires but the function itself has -# not yet been loaded. + if graph is None: + graph = Graph(0) -# %(data_fields)s + return GraphEditor(graph, **editor_options) From e3e6227bce275c5828c22177f167eb046e08138c Mon Sep 17 00:00:00 2001 From: adarsh-kishore786 Date: Tue, 12 Apr 2022 13:11:18 +0530 Subject: [PATCH 130/529] Corrected the error --- src/sage/graphs/spanning_tree.pyx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/graphs/spanning_tree.pyx b/src/sage/graphs/spanning_tree.pyx index 662e416773e..644729b7622 100644 --- a/src/sage/graphs/spanning_tree.pyx +++ b/src/sage/graphs/spanning_tree.pyx @@ -14,7 +14,6 @@ including minimum spanning trees. .. TODO:: - - Rewrite :func:`kruskal` to use priority queues. - Parallel version of Boruvka's algorithm. - Randomized spanning tree construction. @@ -1381,7 +1380,7 @@ def edge_disjoint_spanning_trees(G, k, by_weight=False, weight_function=None, ch # We find the unlabeled edges of Fi(e) by ascending through the # tree one vertex at a time from z toward x, until reaching # either x or a previously labeled edge. - + # Stack of edges to be labeled edges_to_label = [] while u != x and (u in p[i] and frozenset((u, p[i][u])) not in edge_label): From 4c32fff6c941dae64404714ba9f5270d620f18d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 12 Apr 2022 09:45:29 +0200 Subject: [PATCH 131/529] add inverse of continued fractions --- src/sage/rings/continued_fraction.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/sage/rings/continued_fraction.py b/src/sage/rings/continued_fraction.py index 4146fa6ed74..a0cc3bba82a 100644 --- a/src/sage/rings/continued_fraction.py +++ b/src/sage/rings/continued_fraction.py @@ -1269,6 +1269,19 @@ def __neg__(self): """ return self.apply_homography(-1, 0, 0, 1) + def __invert__(self): + """ + Return the multiplicative inverse of ``self``. + + EXAMPLES:: + + sage: ~continued_fraction(e) + [0; 2, 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, 1, 1, 10, 1, 1, 12, 1...] + sage: ~continued_fraction(sqrt(7)) + [0; 2, 1, 1, 1, 4, 1, 1, 1, 4, 1, 1, 1, 4, 1, 1, 1, 4, 1, 1...] + """ + return self.apply_homography(0, 1, 1, 0) + class ContinuedFraction_periodic(ContinuedFraction_base): r""" From ffcb36912ef9585f84e538b959c32a7f2b550f41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 12 Apr 2022 11:47:40 +0200 Subject: [PATCH 132/529] bunch of code formatting in symbolic/ --- src/sage/symbolic/comparison_impl.pxi | 4 +- src/sage/symbolic/expression.pyx | 49 +++++----- src/sage/symbolic/function.pyx | 13 ++- src/sage/symbolic/pynac_impl.pxi | 136 +++++++++++++++++++------- src/sage/symbolic/ring.pyx | 13 ++- 5 files changed, 138 insertions(+), 77 deletions(-) diff --git a/src/sage/symbolic/comparison_impl.pxi b/src/sage/symbolic/comparison_impl.pxi index 2b112b271cd..50582351505 100644 --- a/src/sage/symbolic/comparison_impl.pxi +++ b/src/sage/symbolic/comparison_impl.pxi @@ -374,7 +374,7 @@ class _mixed_key(object): except TypeError: break if not isinstance(det_ex, Expression): - return det_ex < 0 + return det_ex < 0 from sage.rings.qqbar import QQbar try: from sage.rings.qqbar import QQbar @@ -398,7 +398,6 @@ class _mixed_key(object): return num < 0 - cpdef mixed_sorted(expressions): """ Sort a list of symbolic numbers in the "Mixed" order @@ -423,4 +422,3 @@ cpdef mixed_sorted(expressions): [1, sqrt(2), e, pi, sin(1/x), sqrt(x), x] """ return sorted(expressions, key=_mixed_key) - diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index 0fd0eeea6bd..3395870d5dd 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -616,7 +616,7 @@ def _subs_make_dict(s): msg = "can only substitute equality, not inequalities; got {}" raise TypeError(msg.format(s)) return {s.lhs(): s.rhs()} - elif isinstance(s, (tuple,list)): + elif isinstance(s, (tuple, list)): result = {} for d in s: _dict_update_check_duplicate(result, _subs_make_dict(d)) @@ -625,6 +625,7 @@ def _subs_make_dict(s): msg = "not able to determine a substitution from {}" raise TypeError(msg.format(s)) + def _subs_fun_make_dict(s): r""" There are a few ways we can represent a substitution. The first is @@ -695,7 +696,7 @@ def _subs_fun_make_dict(s): raise TypeError(msg.format(s)) temp_fun = s.rhs().function(*s.lhs().operands()) return {s.lhs().operator(): temp_fun} - elif isinstance(s, (tuple,list)): + elif isinstance(s, (tuple, list)): result = {} for d in s: _dict_update_check_duplicate(result, _subs_fun_make_dict(d)) @@ -759,9 +760,12 @@ cdef class Expression(Expression_abc): return constants_name_table[ccrepr(self._gobj)] if is_a_infinity(self._gobj): - if (ex_to_infinity(self._gobj).is_unsigned_infinity()): return unsigned_infinity - if (ex_to_infinity(self._gobj).is_plus_infinity()): return infinity - if (ex_to_infinity(self._gobj).is_minus_infinity()): return minus_infinity + if (ex_to_infinity(self._gobj).is_unsigned_infinity()): + return unsigned_infinity + if (ex_to_infinity(self._gobj).is_plus_infinity()): + return infinity + if (ex_to_infinity(self._gobj).is_minus_infinity()): + return minus_infinity raise TypeError('Python infinity cannot have complex phase.') if not is_a_numeric(self._gobj): @@ -930,8 +934,8 @@ cdef class Expression(Expression_abc): # get variables cdef GExList sym_lst for name in state[1]: - sym_lst.append_sym(\ - ex_to_symbol((SR.symbol(name))._gobj)) + sym_lst.append_sym( + ex_to_symbol((SR.symbol(name))._gobj)) # initialize archive cdef GArchive ar @@ -2444,10 +2448,10 @@ cdef class Expression(Expression_abc): l = self.lhs()._assume_str() r = self.rhs()._assume_str() op = self.operator() - if op is operator.eq: - m = 'equal(%s, %s)'%(l, r) + if op is operator.eq: + m = 'equal(%s, %s)' % (l, r) elif op is operator.ne: - m = 'notequal(%s, %s)'%(l, r) + m = 'notequal(%s, %s)' % (l, r) else: m = '(%s)%s(%s)' % (l, maxima._relation_symbols()[op], r) return m @@ -3516,7 +3520,6 @@ cdef class Expression(Expression_abc): else: return not bool(self == self._parent.zero()) - def test_relation(self, int ntests=20, domain=None, proof=True): """ Test this relation at several random values, attempting to find @@ -4768,7 +4771,6 @@ cdef class Expression(Expression_abc): return matrix([[g.derivative(x) for x in self.arguments()] for g in self.gradient()]) - def series(self, symbol, order=None): r""" Return the power series expansion of self in terms of the @@ -5059,8 +5061,6 @@ cdef class Expression(Expression_abc): l = self._maxima_().taylor(B) return self.parent()(l) - - def truncate(self): """ Given a power series or expression, return the corresponding @@ -5458,7 +5458,6 @@ cdef class Expression(Expression_abc): itr.inc() return rdict - def find(self, pattern): """ Find all occurrences of the given pattern in this expression. @@ -6100,7 +6099,7 @@ cdef class Expression(Expression_abc): sage: x = SR.var("x") sage: f = function("f") - sage: bool(f(exp(I*x)).diff(x).demoivre() == + sage: bool(f(exp(I*x)).diff(x).demoivre() == ....: f(exp(I*x)).demoivre().diff(x)) True """ @@ -6370,8 +6369,8 @@ cdef class Expression(Expression_abc): [a, b^2, c] """ from sage.symbolic.ring import SR - return [new_Expression_from_GEx(SR, self._gobj.op(i)) \ - for i from 0 <= i < self._gobj.nops()] + return [new_Expression_from_GEx(SR, self._gobj.op(i)) + for i in range(self._gobj.nops())] def operator(self): """ @@ -6657,6 +6656,7 @@ cdef class Expression(Expression_abc): prec = digits_to_bits(digits) from sage.symbolic.expression_conversions import ExpressionTreeWalker + class DefiniteSumExpander(ExpressionTreeWalker): def composition(self, ex, operator): if hasattr(operator, 'name') and operator.name() == 'sum' and ( @@ -6673,8 +6673,8 @@ cdef class Expression(Expression_abc): kwds = {'parent': R, 'algorithm': algorithm} try: x = x._convert(kwds) - except TypeError: # numerical approximation for real number failed - pass # try again with complex + except TypeError: # numerical approximation for real number failed + pass # try again with complex kwds['parent'] = R.complex_field() x = x._convert(kwds) @@ -6682,7 +6682,7 @@ cdef class Expression(Expression_abc): # in pynac if is_a_numeric(x._gobj): res = py_object_from_numeric(x._gobj) - elif is_a_constant(x._gobj): + elif is_a_constant(x._gobj): res = x.pyobject() else: raise TypeError("cannot evaluate symbolic expression numerically") @@ -6690,7 +6690,7 @@ cdef class Expression(Expression_abc): # Important -- the we get might not be a valid output for numerical_approx in # the case when one gets infinity. if isinstance(res, AnInfinity): - return res.n(prec=prec,digits=digits) + return res.n(prec=prec, digits=digits) return res def round(self): @@ -10700,7 +10700,6 @@ cdef class Expression(Expression_abc): full_simplify = simplify_full - def simplify_hypergeometric(self, algorithm='maxima'): """ Simplify an expression containing hypergeometric or confluent @@ -10774,8 +10773,7 @@ cdef class Expression(Expression_abc): hypergeometric_simplify = simplify_hypergeometric - - def simplify_rectform(self, complexity_measure = string_length): + def simplify_rectform(self, complexity_measure=string_length): r""" Attempt to simplify this expression by expressing it in the form `a + bi` where both `a` and `b` are real. This @@ -13957,6 +13955,7 @@ cdef class ExpressionIterator: cdef Expression _ex cdef int _ind cdef int _len + def __iter__(self): """ Return this iterator object itself. diff --git a/src/sage/symbolic/function.pyx b/src/sage/symbolic/function.pyx index 480a6019e7c..eab16acf08d 100644 --- a/src/sage/symbolic/function.pyx +++ b/src/sage/symbolic/function.pyx @@ -113,7 +113,7 @@ is attempted, and after that ``sin()`` which succeeds:: """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2008 William Stein # Copyright (C) 2008-2012 Burcin Erocal # Copyright (C) 2009 Mike Hansen @@ -135,8 +135,8 @@ is attempted, and after that ``sin()`` which succeeds:: # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.structure.sage_object cimport SageObject from sage.structure.element cimport Element, parent, Expression @@ -225,7 +225,7 @@ cdef class Function(SageObject): raise ValueError("only one of _derivative_ or _tderivative_ should be defined.") for fname in sfunctions_funcs: - real_fname = '_%s_'%fname + real_fname = '_%s_' % fname if hasattr(self, real_fname) and not \ callable(getattr(self, real_fname)): raise ValueError(real_fname + " parameter must be callable") @@ -1188,7 +1188,6 @@ cdef class SymbolicFunction(Function): Function.__init__(self, name, nargs, latex_name, conversions, evalf_params_first) - cdef _is_registered(SymbolicFunction self): # see if there is already a SymbolicFunction with the same state cdef long myhash = self._hash_() @@ -1357,7 +1356,7 @@ cdef class SymbolicFunction(Function): foo(x, y) """ # check input - if not ((state[0] == 1 and len(state) == 6) or \ + if not ((state[0] == 1 and len(state) == 6) or (state[0] == 2 and len(state) == 7)): raise ValueError("unknown state information") @@ -1403,6 +1402,7 @@ def pickle_wrapper(f): return None return pickle_function(f) + def unpickle_wrapper(p): """ Return a unpickled version of the function defined by ``p``. @@ -1425,4 +1425,3 @@ def unpickle_wrapper(p): if p is None: return None return unpickle_function(p) - diff --git a/src/sage/symbolic/pynac_impl.pxi b/src/sage/symbolic/pynac_impl.pxi index dceb5be4d8c..fba8c3d1495 100644 --- a/src/sage/symbolic/pynac_impl.pxi +++ b/src/sage/symbolic/pynac_impl.pxi @@ -2,7 +2,7 @@ Pynac interface """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2008 William Stein # Copyright (C) 2008-2014 Burcin Erocal # Copyright (C) 2009 Carl Witty @@ -30,7 +30,7 @@ Pynac interface # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # https://www.gnu.org/licenses/ -#***************************************************************************** +# **************************************************************************** from cpython cimport * from libc cimport math @@ -117,6 +117,7 @@ cdef exprseq_to_PyTuple(GEx seq): res.append(new_Expression_from_GEx(SR, seq.op(i))) return tuple(res) + def unpack_operands(Expression ex): """ EXAMPLES:: @@ -137,6 +138,7 @@ def unpack_operands(Expression ex): """ return exprseq_to_PyTuple(ex._gobj) + cdef exvector_to_PyTuple(GExVector seq): """ Converts arguments list given to a function to a PyTuple. @@ -252,6 +254,7 @@ cdef int py_get_ginac_serial(): global GINAC_FN_SERIAL return GINAC_FN_SERIAL + def get_ginac_serial(): """ Number of C++ level functions defined by GiNaC. (Defined mainly for testing.) @@ -263,12 +266,14 @@ def get_ginac_serial(): """ return py_get_ginac_serial() + cdef get_fn_serial_c(): """ Return overall size of Pynac function registry. """ return g_registered_functions().size() + def get_fn_serial(): """ Return the overall size of the Pynac function registry which @@ -287,6 +292,7 @@ def get_fn_serial(): """ return get_fn_serial_c() + cdef subs_args_to_PyTuple(const GExMap& map, unsigned options, const GExVector& seq): """ Convert arguments from ``GiNaC::subs()`` to a PyTuple. @@ -356,11 +362,12 @@ cdef stdstring* py_repr(o, int level): # Python complexes are always printed with parentheses # we try to avoid double parentheses if not isinstance(o, complex) and \ - (' ' in t or '/' in t or '+' in t or '-' in t or '*' in t \ - or '^' in t): - s = '(%s)'%s + (' ' in t or '/' in t or '+' in t or '-' in t or '*' in t + or '^' in t): + s = '(%s)' % s return string_from_pystr(s) + cdef stdstring* py_latex(o, int level): """ Return latex string representation of o. If level > 0, possibly @@ -370,9 +377,10 @@ cdef stdstring* py_latex(o, int level): s = latex(o) if level >= 20: if ' ' in s or '/' in s or '+' in s or '-' in s or '*' in s or '^' in s or '\\frac' in s: - s = '\\left(%s\\right)'%s + s = '\\left(%s\\right)' % s return string_from_pystr(s) + cdef stdstring* string_from_pystr(py_str) except NULL: """ Creates a C++ string with the same contents as the given python string. @@ -393,8 +401,8 @@ cdef stdstring* string_from_pystr(py_str) except NULL: return new stdstring(s) cdef stdstring* py_latex_variable(var_name): - """ - Returns a c++ string containing the latex representation of the given + r""" + Return a c++ string containing the latex representation of the given variable name. Real work is done by the function sage.misc.latex.latex_variable_name. @@ -421,8 +429,9 @@ cdef stdstring* py_latex_variable(var_name): py_vlatex = latex_variable_name(var_name) return string_from_pystr(py_vlatex) + def py_latex_variable_for_doctests(x): - """ + r""" Internal function used so we can doctest a certain cdef'd method. EXAMPLES:: @@ -436,6 +445,7 @@ def py_latex_variable_for_doctests(x): print(char_to_str(ostr.c_str())) del ostr + def py_print_function_pystring(id, args, fname_paren=False): """ Return a string with the representation of the symbolic function specified @@ -500,9 +510,11 @@ def py_print_function_pystring(id, args, fname_paren=False): olist.extend(['(', ', '.join(map(repr, args)), ')']) return ''.join(olist) + cdef stdstring* py_print_function(unsigned id, args): return string_from_pystr(py_print_function_pystring(id, args)) + def py_latex_function_pystring(id, args, fname_paren=False): r""" Return a string with the latex representation of the symbolic function @@ -587,12 +599,14 @@ def py_latex_function_pystring(id, args, fname_paren=False): # print the arguments from sage.misc.latex import latex olist.extend([r'\left(', ', '.join([latex(x) for x in args]), - r'\right)'] ) + r'\right)']) return ''.join(olist) + cdef stdstring* py_latex_function(unsigned id, args): return string_from_pystr(py_latex_function_pystring(id, args)) + def tolerant_is_symbol(a): """ Utility function to test if something is a symbol. @@ -617,6 +631,7 @@ def tolerant_is_symbol(a): except AttributeError: return False + cdef stdstring* py_print_fderivative(unsigned id, params, args): """ @@ -711,11 +726,13 @@ cdef stdstring* py_latex_fderivative(unsigned id, params, operator_string=r"\frac{\partial^{%s}}{%s}"%(len(params),''.join(diff_args)) py_res = operator_string+py_latex_function_pystring(id,args,False) else: - ostr = ''.join(['\mathrm{D}_{',', '.join([repr(int(x)) for x in params]), '}']) + ostr = ''.join([r'\mathrm{D}_{', + ', '.join(repr(int(x)) for x in params), '}']) fstr = py_latex_function_pystring(id, args, True) py_res = ostr + fstr return string_from_pystr(py_res) + def py_latex_fderivative_for_doctests(id, params, args): r""" Used internally for writing doctests for certain cdef'd functions. @@ -904,6 +921,7 @@ cdef py_binomial(n, k): else: return ans + def test_binomial(n, k): """ The Binomial coefficients. It computes the binomial coefficients. For @@ -931,21 +949,22 @@ def test_binomial(n, k): """ return py_binomial(n, k) + ################################################################# # GCD ################################################################# cdef py_gcd(n, k): if isinstance(n, Integer) and isinstance(k, Integer): - if mpz_cmp_si((n).value,1) == 0: + if mpz_cmp_si((n).value, 1) == 0: return n - elif mpz_cmp_si((k).value,1) == 0: + elif mpz_cmp_si((k).value, 1) == 0: return k return n.gcd(k) if type(n) is Rational and type(k) is Rational: return n.content(k) try: - return gcd(n,k) + return gcd(n, k) except (TypeError, ValueError, AttributeError): # some strange meaning in case of weird things with no usual lcm. return 1 @@ -956,13 +975,13 @@ cdef py_gcd(n, k): ################################################################# cdef py_lcm(n, k): if isinstance(n, Integer) and isinstance(k, Integer): - if mpz_cmp_si((n).value,1) == 0: + if mpz_cmp_si((n).value, 1) == 0: return k - elif mpz_cmp_si((k).value,1) == 0: + elif mpz_cmp_si((k).value, 1) == 0: return n return n.lcm(k) try: - return lcm(n,k) + return lcm(n, k) except (TypeError, ValueError, AttributeError): # some strange meaning in case of weird things with no usual lcm, e.g., # elements of finite fields. @@ -1012,7 +1031,8 @@ cdef py_real(x): except AttributeError: pass - return x # assume x is real + return x # assume x is real + def py_real_for_doctests(x): """ @@ -1026,6 +1046,7 @@ def py_real_for_doctests(x): """ return py_real(x) + ################################################################# # Imaginary Part ################################################################# @@ -1067,8 +1088,8 @@ cdef py_imag(x): except AttributeError: pass + return 0 # assume x is real - return 0 # assume x is real def py_imag_for_doctests(x): """ @@ -1090,18 +1111,21 @@ cdef py_conjugate(x): try: return x.conjugate() except AttributeError: - return x # assume is real since it doesn't have an imag attribute. + return x # assume is real since it doesn't have an imag attribute. + cdef bint py_is_rational(x): return (type(x) is Rational or type(x) is Integer or isinstance(x, (int, long))) + cdef bint py_is_equal(x, y): """ Return True precisely if x and y are equal. """ - return bool(x==y) + return bool(x == y) + cdef bint py_is_integer(x): r""" @@ -1155,12 +1179,13 @@ def py_is_integer_for_doctests(x): """ return py_is_integer(x) + cdef bint py_is_even(x): try: - return not(x%2) + return not(x % 2) except Exception: try: - return not(ZZ(x)%2) + return not(ZZ(x) % 2) except Exception: pass return 0 @@ -1169,14 +1194,12 @@ cdef bint py_is_even(x): cdef bint py_is_crational(x): if py_is_rational(x): return True - elif isinstance(x, Element) and (x)._parent is pynac_I._parent: - return True - else: - return False + return isinstance(x, Element) and (x)._parent is pynac_I._parent + def py_is_crational_for_doctest(x): - """ - Returns True if pynac should treat this object as an element of `\QQ(i)`. + r""" + Return True if pynac should treat this object as an element of `\QQ(i)`. TESTS:: @@ -1194,6 +1217,7 @@ def py_is_crational_for_doctest(x): """ return py_is_crational(x) + cdef bint py_is_real(a): if isinstance(a, (int, long, Integer, float)): return True @@ -1207,6 +1231,7 @@ cdef bint py_is_real(a): pass return py_imag(a) == 0 + cdef bint py_is_prime(n): try: return n.is_prime() @@ -1300,6 +1325,7 @@ cdef py_denom(n): except AttributeError: return 1 + def py_denom_for_doctests(n): """ This function is used to test py_denom(). @@ -1312,11 +1338,13 @@ def py_denom_for_doctests(n): """ return py_denom(n) + cdef bint py_is_cinteger(x): return py_is_integer(x) or (py_is_crational(x) and py_denom(x) == 1) + def py_is_cinteger_for_doctest(x): - """ + r""" Returns True if pynac should treat this object as an element of `\ZZ(i)`. TESTS:: @@ -1785,18 +1813,21 @@ cdef py_asin(x): except AttributeError: return RR(x).arcsin() + cdef py_acos(x): try: return x.arccos() except AttributeError: return RR(x).arccos() + cdef py_atan(x): try: return x.arctan() except AttributeError: return RR(x).arctan() + cdef py_atan2(x, y): """ Return the value of the two argument arctan function at the given values. @@ -1868,6 +1899,7 @@ cdef py_atan2(x, y): else: return P(NaN) + def py_atan2_for_doctests(x, y): """ Wrapper function to test py_atan2. @@ -1880,6 +1912,7 @@ def py_atan2_for_doctests(x, y): """ return py_atan2(x, y) + cdef py_sinh(x): try: return x.sinh() @@ -1895,6 +1928,7 @@ cdef py_cosh(x): except AttributeError: return RR(x).cosh() + cdef py_tanh(x): try: return x.tanh() @@ -1912,6 +1946,7 @@ cdef py_asinh(x): except TypeError: return CC(x).arcsinh() + cdef py_acosh(x): try: return x.arccosh() @@ -1933,6 +1968,7 @@ cdef py_atanh(x): except TypeError: return CC(x).arctanh() + cdef py_lgamma(x): """ Return the value of the principal branch of the log gamma function at the @@ -1966,6 +2002,7 @@ cdef py_lgamma(x): except TypeError: return mpmath_utils.call(loggamma, x, parent=parent(x)) + def py_lgamma_for_doctests(x): """ This function tests py_lgamma. @@ -1978,9 +2015,11 @@ def py_lgamma_for_doctests(x): """ return py_lgamma(x) + cdef py_isqrt(x): return Integer(x).isqrt() + cdef py_sqrt(x): try: # WORRY: What if Integer's sqrt calls symbolic one and we go in circle? @@ -1988,9 +2027,11 @@ cdef py_sqrt(x): except AttributeError as msg: return math.sqrt(float(x)) + cdef py_abs(x): return abs(x) + cdef py_mod(x, n): """ Return x mod n. Both x and n are assumed to be integers. @@ -2024,6 +2065,7 @@ cdef py_mod(x, n): """ return Integer(x) % Integer(n) + def py_mod_for_doctests(x, n): """ This function is a python wrapper so py_mod can be tested. The real tests @@ -2037,25 +2079,31 @@ def py_mod_for_doctests(x, n): """ return py_mod(x, n) + cdef py_smod(a, b): # Modulus (in symmetric representation). # Equivalent to Maple's mods. # returns a mod b in the range [-iquo(abs(b)-1,2), iquo(abs(b),2)] - a = Integer(a); b = Integer(b) + a = Integer(a) + b = Integer(b) b = abs(b) c = a % b - if c > b//2: + if c > b // 2: c -= b return c + cdef py_irem(x, n): return Integer(x) % Integer(n) + cdef py_iquo(x, n): return Integer(x)//Integer(n) + cdef py_iquo2(x, n): - x = Integer(x); n = Integer(n) + x = Integer(x) + n = Integer(n) try: q = x//n r = x - q*n @@ -2063,12 +2111,14 @@ cdef py_iquo2(x, n): except (TypeError, ValueError): return 0, 0 + cdef int py_int_length(x) except -1: # Size in binary notation. For integers, this is the smallest n >= 0 such # that -2^n <= x < 2^n. If x > 0, this is the unique n > 0 such that # 2^(n-1) <= x < 2^n. This returns 0 if x is not an integer. return Integer(x).nbits() + cdef py_li(x, n, parent): """ Returns a numerical approximation of polylog(n, x) with precision given @@ -2091,6 +2141,7 @@ cdef py_li(x, n, parent): prec = 53 return mpmath_utils.call(mpmath.polylog, n, x, prec=prec) + def py_li_for_doctests(x, n, parent): """ This function is a python wrapper so py_li can be tested. The real tests @@ -2104,6 +2155,7 @@ def py_li_for_doctests(x, n, parent): """ return py_li(x, n, parent) + cdef py_psi(x): """ EXAMPLES:: @@ -2125,6 +2177,7 @@ cdef py_psi(x): prec = 53 return mpmath_utils.call(mpmath.psi, 0, x, prec=prec) + def py_psi_for_doctests(x): """ This function is a python wrapper so py_psi can be tested. The real tests @@ -2195,6 +2248,7 @@ def py_li2_for_doctests(x): """ return py_li2(x) + ################################################################## # Constants ################################################################## @@ -2297,19 +2351,26 @@ cdef py_rational_from_mpq(mpq_t bigrat): mpq_canonicalize(rat.value) return rat + cdef bint py_is_Integer(x): return isinstance(x, Integer) + cdef bint py_is_Rational(x): return isinstance(x, Rational) + cdef mpz_ptr py_mpz_from_integer(x): return ((x).value) + cdef mpq_ptr py_mpq_from_rational(x): return ((x).value) -symbol_table = {'functions':{}} + +symbol_table = {'functions': {}} + + def register_symbol(obj, conversions): """ Add an object to the symbol table, along with how to convert it to @@ -2345,7 +2406,6 @@ def register_symbol(obj, conversions): system_table[value] = obj - import sage.rings.integer ginac_pyinit_Integer(sage.rings.integer.Integer) @@ -2355,6 +2415,7 @@ ginac_pyinit_Float(sage.rings.real_double.RDF) cdef Element pynac_I I = None + def init_pynac_I(): """ Initialize the numeric I object in pynac. We use the generator of QQ(i). @@ -2539,10 +2600,11 @@ def init_function_table(): py_funcs.py_get_serial_for_new_sfunction = &py_get_serial_for_new_sfunction py_funcs.py_get_constant = &py_get_constant - py_funcs.py_print_fderivative = &py_print_fderivative - py_funcs.py_latex_fderivative = &py_latex_fderivative + py_funcs.py_print_fderivative = &py_print_fderivative + py_funcs.py_latex_fderivative = &py_latex_fderivative py_funcs.paramset_to_PyTuple = ¶mset_to_PyTuple + init_function_table() init_pynac_I() diff --git a/src/sage/symbolic/ring.pyx b/src/sage/symbolic/ring.pyx index 05694e3b085..1a2891dbb50 100644 --- a/src/sage/symbolic/ring.pyx +++ b/src/sage/symbolic/ring.pyx @@ -67,7 +67,7 @@ cdef class SymbolicRing(sage.rings.abc.SymbolicRing): """ Symbolic Ring, parent object for all symbolic expressions. """ - def __init__(self, base_ring = None): + def __init__(self, base_ring=None): """ Initialize the Symbolic Ring. @@ -192,8 +192,8 @@ cdef class SymbolicRing(sage.rings.abc.SymbolicRing): if is_numpy_type(R): import numpy if (issubclass(R, numpy.integer) or - issubclass(R, numpy.floating) or - issubclass(R, numpy.complexfloating)): + issubclass(R, numpy.floating) or + issubclass(R, numpy.complexfloating)): return NumpyToSRMorphism(R) else: return None @@ -544,7 +544,7 @@ cdef class SymbolicRing(sage.rings.abc.SymbolicRing): """ return self.symbol('some_variable') - def is_field(self, proof = True): + def is_field(self, proof=True): """ Returns True, since the symbolic expression ring is (for the most part) a field. @@ -745,7 +745,7 @@ cdef class SymbolicRing(sage.rings.abc.SymbolicRing): True """ from sage.symbolic.assumptions import assumptions - if isinstance(symbol,list) or isinstance(symbol,tuple): + if isinstance(symbol, (list, tuple)): for s in symbol: self.cleanup_var(s) else: @@ -1309,6 +1309,7 @@ def the_SymbolicRing(): """ return SR + def is_SymbolicExpressionRing(R): """ Return True if ``R`` is the symbolic expression ring. @@ -1335,6 +1336,7 @@ def is_SymbolicExpressionRing(R): deprecation(32665, 'is_SymbolicExpressionRing is deprecated; use "... is SR" or isinstance(..., sage.rings.abc.SymbolicRing instead') return R is SR + def var(name, **kwds): """ EXAMPLES:: @@ -1410,6 +1412,7 @@ def isidentifier(x): return False return x.isidentifier() + class TemporaryVariables(tuple): """ Instances of this class can be used with Python `with` to From 266ef46f221bf6a49dc0e2de40d919c595256f03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 12 Apr 2022 14:40:48 +0200 Subject: [PATCH 133/529] various code formatting details in pyx files --- .../free_algebra_element_letterplace.pyx | 3 +- .../letterplace/free_algebra_letterplace.pyx | 3 +- .../quatalg/quaternion_algebra_cython.pyx | 9 +++-- .../quatalg/quaternion_algebra_element.pyx | 9 +++-- src/sage/calculus/interpolation.pyx | 3 +- src/sage/calculus/transforms/dwt.pyx | 9 +++-- .../combinatorial_polyhedron/base.pyx | 9 +++-- src/sage/interacts/library_cython.pyx | 3 +- src/sage/interfaces/sagespawn.pyx | 15 ++++--- src/sage/misc/binary_tree.pyx | 28 +++++++------ src/sage/misc/c3_controlled.pyx | 6 ++- src/sage/misc/persist.pyx | 6 ++- src/sage/misc/session.pyx | 4 +- src/sage/plot/complex_plot.pyx | 5 ++- src/sage/plot/plot3d/base.pyx | 40 ++++++++++++------- src/sage/plot/plot3d/implicit_surface.pyx | 25 ++++++++---- .../probability/probability_distribution.pyx | 3 +- 17 files changed, 112 insertions(+), 68 deletions(-) diff --git a/src/sage/algebras/letterplace/free_algebra_element_letterplace.pyx b/src/sage/algebras/letterplace/free_algebra_element_letterplace.pyx index fddd5a8308b..fc1d43c574c 100644 --- a/src/sage/algebras/letterplace/free_algebra_element_letterplace.pyx +++ b/src/sage/algebras/letterplace/free_algebra_element_letterplace.pyx @@ -230,7 +230,7 @@ cdef class FreeAlgebraElement_letterplace(AlgebraElement): return '0' def _latex_(self): - """ + r""" TESTS:: sage: K. = GF(25) @@ -239,7 +239,6 @@ cdef class FreeAlgebraElement_letterplace(AlgebraElement): (2*z + 1)*a*b*a*b + (z + 1)*a*b*c + (z + 1)*c*a*b - c*c sage: latex(-(a*b*(z+1)-c)^2) # indirect doctest \left(2 z + 1\right) a b a b + \left(z + 1\right) a b c + \left(z + 1\right) c a b - c c - """ cdef list L = [] cdef FreeAlgebra_letterplace P = self._parent diff --git a/src/sage/algebras/letterplace/free_algebra_letterplace.pyx b/src/sage/algebras/letterplace/free_algebra_letterplace.pyx index 6137ac6ff52..7c83201cedb 100644 --- a/src/sage/algebras/letterplace/free_algebra_letterplace.pyx +++ b/src/sage/algebras/letterplace/free_algebra_letterplace.pyx @@ -618,7 +618,7 @@ cdef class FreeAlgebra_letterplace(Algebra): # Auxiliar methods cdef str exponents_to_latex(self, E): - """ + r""" This auxiliary method is used for the representation of elements of this free algebra as a latex string. EXAMPLES:: @@ -629,7 +629,6 @@ cdef class FreeAlgebra_letterplace(Algebra): (2*z + 1)*a*b*a*b + (z + 1)*a*b*c + (z + 1)*c*a*b - c*c sage: latex(-(a*b*(z+1)-c)^2) # indirect doctest \left(2 z + 1\right) a b a b + \left(z + 1\right) a b c + \left(z + 1\right) c a b - c c - """ cdef int ngens = self.__ngens cdef int nblocks = len(E)/ngens diff --git a/src/sage/algebras/quatalg/quaternion_algebra_cython.pyx b/src/sage/algebras/quatalg/quaternion_algebra_cython.pyx index 40c55c7a071..88f65813eac 100644 --- a/src/sage/algebras/quatalg/quaternion_algebra_cython.pyx +++ b/src/sage/algebras/quatalg/quaternion_algebra_cython.pyx @@ -82,13 +82,15 @@ def integral_matrix_and_denom_from_rational_quaternions(v, reverse=False): cdef Py_ssize_t i, n=len(v) M = MatrixSpace(ZZ, n, 4) cdef Matrix_integer_dense A = M.zero_matrix().__copy__() - if n == 0: return A + if n == 0: + return A # Find least common multiple of the denominators cdef QuaternionAlgebraElement_rational_field x cdef Integer d = Integer() # set denom to the denom of the first quaternion - x = v[0]; mpz_set(d.value, x.d) + x = v[0] + mpz_set(d.value, x.d) for x in v[1:]: mpz_lcm(d.value, d.value, x.d) @@ -152,7 +154,8 @@ def rational_matrix_from_rational_quaternions(v, reverse=False): cdef Py_ssize_t i, j, n=len(v) M = MatrixSpace(QQ, n, 4) cdef Matrix_rational_dense A = M.zero_matrix().__copy__() - if n == 0: return A + if n == 0: + return A cdef QuaternionAlgebraElement_rational_field x if reverse: diff --git a/src/sage/algebras/quatalg/quaternion_algebra_element.pyx b/src/sage/algebras/quatalg/quaternion_algebra_element.pyx index f6e7cfe48b5..4d4f0ead756 100644 --- a/src/sage/algebras/quatalg/quaternion_algebra_element.pyx +++ b/src/sage/algebras/quatalg/quaternion_algebra_element.pyx @@ -353,11 +353,14 @@ cdef class QuaternionAlgebraElement_abstract(AlgebraElement): if x: v.append(str(x)) c = print_coeff(y,i,atomic) - if c: v.append(c) + if c: + v.append(c) c = print_coeff(z,j,atomic) - if c: v.append(c) + if c: + v.append(c) c = print_coeff(w,k,atomic) - if c: v.append(c) + if c: + v.append(c) if not v: return '0' return ' + '.join(v).replace('+ -','- ') diff --git a/src/sage/calculus/interpolation.pyx b/src/sage/calculus/interpolation.pyx index 1c81a072f0e..e703f78d7c0 100644 --- a/src/sage/calculus/interpolation.pyx +++ b/src/sage/calculus/interpolation.pyx @@ -384,7 +384,8 @@ cdef class Spline: I = gsl_spline_eval_integ(self.spline, a, b, self.acc) sig_off() - if bounds_swapped: I = -I + if bounds_swapped: + I = -I return I spline = Spline diff --git a/src/sage/calculus/transforms/dwt.pyx b/src/sage/calculus/transforms/dwt.pyx index cb24f071ad7..6c34b1a288f 100644 --- a/src/sage/calculus/transforms/dwt.pyx +++ b/src/sage/calculus/transforms/dwt.pyx @@ -11,20 +11,21 @@ AUTHOR: """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2006 Joshua Kantor # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** import sage.plot.all + def WaveletTransform(n, wavelet_type, wavelet_k): - """ + r""" This function initializes an GSLDoubleArray of length n which can perform a discrete wavelet transform. diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx index 7546330d8ec..c1d418aa7ab 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx @@ -922,9 +922,9 @@ cdef class CombinatorialPolyhedron(SageObject): # The Polyhedron has no vertex. return () if names and self.Vrep(): - return tuple(self.Vrep()[i] for i in range(self.n_Vrepresentation()) if not i in self.far_face_tuple()) + return tuple(self.Vrep()[i] for i in range(self.n_Vrepresentation()) if i not in self.far_face_tuple()) else: - return tuple(smallInteger(i) for i in range(self.n_Vrepresentation()) if not i in self.far_face_tuple()) + return tuple(smallInteger(i) for i in range(self.n_Vrepresentation()) if i not in self.far_face_tuple()) def n_facets(self): r""" @@ -2095,7 +2095,8 @@ cdef class CombinatorialPolyhedron(SageObject): sage: C.is_simple() False """ - if not self.is_bounded(): return False + if not self.is_bounded(): + return False cdef ListOfFaces vertices = self._bitrep_Vrep cdef size_t n_vertices = vertices.n_faces() @@ -2180,7 +2181,7 @@ cdef class CombinatorialPolyhedron(SageObject): @cached_method def is_lawrence_polytope(self): - """ + r""" Return ``True`` if ``self`` is a Lawrence polytope. A polytope is called a Lawrence polytope if it has a centrally diff --git a/src/sage/interacts/library_cython.pyx b/src/sage/interacts/library_cython.pyx index 205ea0a0b30..daf20c648c8 100644 --- a/src/sage/interacts/library_cython.pyx +++ b/src/sage/interacts/library_cython.pyx @@ -69,7 +69,8 @@ cpdef mandel(ff_m, z, int iterations): c = z for i in range(iterations): z = ff_m(z, c) - if z.abs() > 2: break + if z.abs() > 2: + break return z diff --git a/src/sage/interfaces/sagespawn.pyx b/src/sage/interfaces/sagespawn.pyx index 136a42810ed..33236a8e9ea 100644 --- a/src/sage/interfaces/sagespawn.pyx +++ b/src/sage/interfaces/sagespawn.pyx @@ -266,12 +266,17 @@ class SagePtyProcess(PtyProcess): # If any of these killpg() calls fail, it's most likely # because the process is actually killed. - if killpg(pg, SIGCONT): return + if killpg(pg, SIGCONT): + return sleep(interval) - if killpg(pg, SIGINT): return + if killpg(pg, SIGINT): + return sleep(interval) - if killpg(pg, SIGHUP): return + if killpg(pg, SIGHUP): + return sleep(interval) - if killpg(pg, SIGTERM): return + if killpg(pg, SIGTERM): + return sleep(interval) - if killpg(pg, SIGKILL): return + if killpg(pg, SIGKILL): + return diff --git a/src/sage/misc/binary_tree.pyx b/src/sage/misc/binary_tree.pyx index 0a2131298b8..943960f5413 100644 --- a/src/sage/misc/binary_tree.pyx +++ b/src/sage/misc/binary_tree.pyx @@ -420,6 +420,7 @@ cdef class BinaryTree: min = cur.left.value cur.left = binary_tree_left_excise(cur.left) return min + def is_empty(BinaryTree self): """ Returns True if the tree has no nodes. @@ -434,12 +435,9 @@ cdef class BinaryTree: sage: t.is_empty() False """ - if self.head == NULL: - return True - else: - return False + return self.head == NULL: - def keys(BinaryTree self, order = "inorder"): + def keys(BinaryTree self, order="inorder"): """ Returns the keys sorted according to "order" parameter, which can be one of "inorder", "preorder", or "postorder" @@ -447,13 +445,16 @@ cdef class BinaryTree: if self.head == NULL: return [] - if order == "postorder": o = LIST_POSTORDER - elif order == "inorder": o = LIST_INORDER - else: o = LIST_PREORDER + if order == "postorder": + o = LIST_POSTORDER + elif order == "inorder": + o = LIST_INORDER + else: + o = LIST_PREORDER return binary_tree_list(self.head, LIST_KEYS + o) - def values(BinaryTree self, order = "inorder"): + def values(BinaryTree self, order="inorder"): """ Returns the keys sorted according to "order" parameter, which can be one of "inorder", "preorder", or "postorder" @@ -461,9 +462,12 @@ cdef class BinaryTree: if self.head == NULL: return [] - if order == "postorder": o = LIST_POSTORDER - elif order == "inorder": o = LIST_INORDER - else: o = LIST_PREORDER + if order == "postorder": + o = LIST_POSTORDER + elif order == "inorder": + o = LIST_INORDER + else: + o = LIST_PREORDER return binary_tree_list(self.head, LIST_VALUES + o) diff --git a/src/sage/misc/c3_controlled.pyx b/src/sage/misc/c3_controlled.pyx index 3e70e529ad2..1b16dd62b8e 100644 --- a/src/sage/misc/c3_controlled.pyx +++ b/src/sage/misc/c3_controlled.pyx @@ -875,12 +875,14 @@ cpdef tuple C3_sorted_merge(list lists, key=identity): if O_key in tailsets[j]: cont = True break - if cont: continue + if cont: + continue for j from i key(max_bad): diff --git a/src/sage/misc/persist.pyx b/src/sage/misc/persist.pyx index e7744d62f5b..bdc84445e7f 100644 --- a/src/sage/misc/persist.pyx +++ b/src/sage/misc/persist.pyx @@ -37,8 +37,10 @@ from textwrap import dedent # change to import zlib to use zlib instead; but this # slows down loading any data stored in the other format -import zlib; comp = zlib -import bz2; comp_other = bz2 +import zlib +import bz2 +comp = zlib +comp_other = bz2 from .sage_unittest import TestSuite diff --git a/src/sage/misc/session.pyx b/src/sage/misc/session.pyx index 610dbdc0f2e..6b1054e639f 100644 --- a/src/sage/misc/session.pyx +++ b/src/sage/misc/session.pyx @@ -99,11 +99,13 @@ def init(state=None): sage: show_identifiers() [] """ - if state is None: state = caller_locals() # use locals() by default + if state is None: + state = caller_locals() # use locals() by default global state_at_init # Make a *copy* of the state dict, since it is mutable state_at_init = dict(state) + def _is_new_var(x, v, hidden): """ Return whether or not the variable named ``x`` with value ``v`` is diff --git a/src/sage/plot/complex_plot.pyx b/src/sage/plot/complex_plot.pyx index f32858f7763..47617d9a353 100644 --- a/src/sage/plot/complex_plot.pyx +++ b/src/sage/plot/complex_plot.pyx @@ -206,7 +206,7 @@ cdef inline double cyclic_linear_mag_to_lightness(double r, double base=10): cdef inline double mag_and_arg_to_lightness(double r, double arg, double base=2, int nphases=10): - """ + r""" Return a lightness for the given magnitude and argument. This modifies the lightness around magnitudes of size ``base^n`` for @@ -428,7 +428,8 @@ def complex_to_rgb(z_values, contoured=False, tiled=False, # for this setup, but in Cython hue = 3*arg/PI - if hue < 0: hue += 6 # usual hsv hue is thus h=arg/(2*pi) for positive, h=arg/(2*PI)+1 for negative + if hue < 0: + hue += 6 # usual hsv hue is thus h=arg/(2*pi) for positive, h=arg/(2*PI)+1 for negative ihue = hue if ihue == 0: r = top diff --git a/src/sage/plot/plot3d/base.pyx b/src/sage/plot/plot3d/base.pyx index 3b65867bd17..ae1fd739499 100644 --- a/src/sage/plot/plot3d/base.pyx +++ b/src/sage/plot/plot3d/base.pyx @@ -154,11 +154,15 @@ cdef class Graphics3d(SageObject): if viewer is None: viewer = SHOW_DEFAULTS['viewer'] # fall back to 2d image if necessary - if viewer == 'canvas3d' and not can_view_canvas3d: viewer = 'jmol' - if viewer == 'wavefront' and not can_view_wavefront: viewer = 'jmol' - if viewer == 'threejs' and not can_view_threejs: viewer = 'jmol' - if viewer == 'jmol' and not can_view_jmol: viewer = 'tachyon' - ### Second, return the corresponding graphics file + if viewer == 'canvas3d' and not can_view_canvas3d: + viewer = 'jmol' + if viewer == 'wavefront' and not can_view_wavefront: + viewer = 'jmol' + if viewer == 'threejs' and not can_view_threejs: + viewer = 'jmol' + if viewer == 'jmol' and not can_view_jmol: + viewer = 'tachyon' + # Second, return the corresponding graphics file if viewer == 'threejs': return self._rich_repr_threejs(**opts) elif viewer == 'jmol': @@ -736,7 +740,8 @@ cdef class Graphics3d(SageObject): ([-1.0, -1.0, 0.0], [1.0, 1.0, 1.0]) """ a_min, a_max = self.bounding_box() - a_min = list(a_min); a_max = list(a_max) + a_min = list(a_min) + a_max = list(a_max) for i in range(3): if a_min[i] == a_max[i]: a_min[i] = a_min[i] - 1 @@ -1252,7 +1257,6 @@ end_scene""".format( f.write('wireframe off; spacefill off\n') f.write('set labelOffset 0 0\n') - # Set the scene background color f.write('background [%s,%s,%s]\n'%tuple([int(a*255) for a in background])) if spin: @@ -1260,14 +1264,15 @@ end_scene""".format( else: f.write('spin OFF\n') if stereo: - if stereo is True: stereo = "redblue" + if stereo is True: + stereo = "redblue" f.write('stereo %s\n' % stereo) if orientation: - f.write('moveto 0 %s %s %s %s\n'%tuple(orientation)) + f.write('moveto 0 %s %s %s %s\n' % tuple(orientation)) f.write('centerAt absolute {0 0 0}\n') f.write('zoom {0}\n'.format(zoom * 100)) - f.write('frank OFF\n') # jmol logo + f.write('frank OFF\n') # jmol logo if perspective_depth: f.write('set perspectivedepth ON\n') @@ -1485,8 +1490,10 @@ end_scene""".format( if aspect_ratio == "automatic" or aspect_ratio == [1.0]*3: return a_min, a_max - longest_side = 0; longest_length = a_max[0] - a_min[0] - shortest_side = 0; shortest_length = a_max[0] - a_min[0] + longest_side = 0 + longest_length = a_max[0] - a_min[0] + shortest_side = 0 + shortest_length = a_max[0] - a_min[0] for i in range(3): s = a_max[i] - a_min[i] @@ -1528,7 +1535,8 @@ end_scene""".format( def _transform_to_bounding_box(self, xyz_min, xyz_max, a_min, a_max, frame, axes, thickness, labels): - a_min_orig = a_min; a_max_orig = a_max + a_min_orig = a_min + a_max_orig = a_max # Rescale in each direction scale = [float(xyz_max[i] - xyz_min[i]) / (a_max[i] - a_min[i]) for i in range(3)] @@ -3252,8 +3260,10 @@ def flatten_list(L): if type(L) is not list: return [L] flat = [] - L_stack = []; L_pop = L_stack.pop - i_stack = []; i_pop = i_stack.pop + L_stack = [] + L_pop = L_stack.pop + i_stack = [] + i_pop = i_stack.pop cdef Py_ssize_t i = 0 while i < PyList_GET_SIZE(L) or PyList_GET_SIZE(L_stack) > 0: while i < PyList_GET_SIZE(L): diff --git a/src/sage/plot/plot3d/implicit_surface.pyx b/src/sage/plot/plot3d/implicit_surface.pyx index a9212bbed3a..a3b4a2ea27a 100644 --- a/src/sage/plot/plot3d/implicit_surface.pyx +++ b/src/sage/plot/plot3d/implicit_surface.pyx @@ -254,11 +254,16 @@ cdef class MarchingCubes: self.eval_scale_inv.z = 1/self.eval_scale.z cdef point_c zero_pt, origin, plus_x, plus_y, plus_z - zero_pt.x = 0; zero_pt.y = 0; zero_pt.z = 0 + zero_pt.x = 0 + zero_pt.y = 0 + zero_pt.z = 0 origin = self.eval_min - plus_x = zero_pt; plus_x.x = self.eval_scale.x - plus_y = zero_pt; plus_y.y = self.eval_scale.y - plus_z = zero_pt; plus_z.z = self.eval_scale.z + plus_x = zero_pt + plus_x.x = self.eval_scale.x + plus_y = zero_pt + plus_y.y = self.eval_scale.y + plus_z = zero_pt + plus_z.z = self.eval_scale.z if self.transform is not None: self.transform.transform_point_c(&self.out_origin, origin) self.transform.transform_point_c(&self.out_plus_x, plus_x) @@ -669,9 +674,12 @@ cdef class MarchingCubesTriangles(MarchingCubes): cdef double gy = dy * self.eval_scale_inv.y cdef double gz = dz * self.eval_scale_inv.z - if x > 0 and x < self.nx - 1: gx *= 0.5 - if y > 0 and y < self.ny - 1: gy *= 0.5 - if z > 0 and z < self.nz - 1: gz *= 0.5 + if x > 0 and x < self.nx - 1: + gx *= 0.5 + if y > 0 and y < self.ny - 1: + gy *= 0.5 + if z > 0 and z < self.nz - 1: + gz *= 0.5 g[0].x = gx g[0].y = gy @@ -752,7 +760,8 @@ cdef class MarchingCubesTriangles(MarchingCubes): insideMask |= marching_is_inside(right[y+1,z+1], self.contour)<<6 insideMask |= marching_is_inside(left[y+1,z+1], self.contour)<<7 - if insideMask == 0 or insideMask == 255: continue + if insideMask == 0 or insideMask == 255: + continue # OK, we have a cube on the surface. Copy all of the vertex # info into an array for easier reference. diff --git a/src/sage/probability/probability_distribution.pyx b/src/sage/probability/probability_distribution.pyx index ecc22e9bb86..84e684f8de6 100644 --- a/src/sage/probability/probability_distribution.pyx +++ b/src/sage/probability/probability_distribution.pyx @@ -1176,6 +1176,7 @@ cdef class GeneralDiscreteDistribution(ProbabilityDistribution): sage: [T.get_random_element() for _ in range(10)] [2, 2, 2, 2, 2, 1, 2, 2, 1, 2] """ - if self.r != NULL: gsl_rng_free(self.r) + if self.r != NULL: + gsl_rng_free(self.r) self.r = gsl_rng_alloc(self.T) self.set_seed(self.seed) From 46d0501479d03c6276fd506825dc8e5d0f0e6f35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 12 Apr 2022 15:34:39 +0200 Subject: [PATCH 134/529] doctest fricas conversions, comment out some dubious ones --- src/sage/functions/jacobi.py | 6 +++++- src/sage/functions/orthogonal_polys.py | 20 ++++++++++++++++++++ src/sage/functions/special.py | 24 ++++++++++++------------ 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/sage/functions/jacobi.py b/src/sage/functions/jacobi.py index 470f00c3989..19a1981136d 100644 --- a/src/sage/functions/jacobi.py +++ b/src/sage/functions/jacobi.py @@ -179,8 +179,12 @@ def __init__(self, kind): sage: N(jacobi("sn", I, 1/2)) # abs tol 1e-12 -8.59454886300046e-73 + 1.34737147138542*I - sage: fricas(jacobi('cn',x, 2)) # optional - fricas + sage: CN = fricas(jacobi('cn',x, 2)); CN # optional - fricas jacobiCn(x,2) + sage: fricas.series(CN, x=0) # optional - fricas + 1 2 3 4 17 6 79 8 1381 10 11 + 1 - - x + - x - -- x + --- x - ----- x + O(x ) + 2 8 80 640 19200 sage: fricas(jacobi('sn',x, 2)) # optional - fricas jacobiSn(x,2) sage: fricas(jacobi('dn',x, 2)) # optional - fricas diff --git a/src/sage/functions/orthogonal_polys.py b/src/sage/functions/orthogonal_polys.py index 66c23c360a3..aace3cc767d 100644 --- a/src/sage/functions/orthogonal_polys.py +++ b/src/sage/functions/orthogonal_polys.py @@ -1652,6 +1652,13 @@ def __init__(self): 1 legendreP(2,-,x) 2 + + sage: gen_legendre_P(3,0,x) + 5/2*x^3 - 3/2*x + sage: fricas.legendreP(3,x) # optional - fricas + 5 3 3 + - x - - x + 2 2 """ BuiltinFunction.__init__(self, "gen_legendre_P", nargs=3, latex_name=r"\mathtt{P}", @@ -2046,6 +2053,12 @@ def __init__(self): sage: fricas(hermite(x, 5)) # optional - fricas hermiteH(x,5) + + sage: hermite(5,x) + 32*x^5 - 160*x^3 + 120*x + sage: fricas.hermiteH(5,x) # optional - fricas + 5 3 + 32 x - 160 x + 120 x """ GinacFunction.__init__(self, "hermite", nargs=2, latex_name=r"H", conversions={'maxima': 'hermite', @@ -2097,6 +2110,13 @@ def __init__(self): 1 1 jacobiP(-,4,-,x) 2 3 + + sage: jacobi_P(1,2,3,x) + 7/2*x - 1/2 + sage: fricas.jacobiP(1,2,3,x) # optional - fricas + 7 x - 1 + ------- + 2 """ OrthogonalFunction.__init__(self, "jacobi_P", nargs=4, latex_name=r"P", conversions={'maxima': 'jacobi_p', diff --git a/src/sage/functions/special.py b/src/sage/functions/special.py index 3c1f6875335..7c004c29028 100644 --- a/src/sage/functions/special.py +++ b/src/sage/functions/special.py @@ -613,6 +613,11 @@ def __init__(self): sage: fricas(elliptic_ec(x)) # optional - fricas ellipticE(x) + + sage: elliptic_ec(0.5) # abs tol 1e-8 + 1.35064388104768 + sage: fricas.ellipticE(0.5).sage() # abs tol 1e-8 # optional - fricas + 1.3506438810476755025201749 """ BuiltinFunction.__init__(self, 'elliptic_ec', nargs=1, latex_name='E', conversions=dict(mathematica='EllipticE', @@ -823,16 +828,11 @@ def __init__(self): elliptic_f sage: elliptic_f(x, 2)._sympy_() elliptic_f(x, 2) - - TESTS:: - - sage: fricas(elliptic_f(x,2)) # optional - fricas - ellipticF(x,2) """ BuiltinFunction.__init__(self, 'elliptic_f', nargs=2, conversions=dict(mathematica='EllipticF', maxima='elliptic_f', - fricas='ellipticF', + # fricas='ellipticF', buggy sympy='elliptic_f')) def _eval_(self, z, m): @@ -941,6 +941,11 @@ def __init__(self): sage: fricas(elliptic_kc(x)) # optional - fricas ellipticK(x) + + sage: elliptic_kc(0.3) # abs tol 1e-8 + 1.71388944817879 + sage: fricas.ellipticK(0.3).sage() # abs tol 1e-3 # optional - fricas + 1.7138894481787910555457043 """ BuiltinFunction.__init__(self, 'elliptic_kc', nargs=1, latex_name='K', conversions=dict(mathematica='EllipticK', @@ -1042,16 +1047,11 @@ def __init__(self): elliptic_pi sage: elliptic_pi(x, pi/4, 1)._sympy_() elliptic_pi(x, pi/4, 1) - - TESTS:: - - sage: fricas(elliptic_pi(x, 2, 2)) # optional - fricas - ellipticPi(x,2,2) """ BuiltinFunction.__init__(self, 'elliptic_pi', nargs=3, conversions=dict(mathematica='EllipticPi', maxima='EllipticPi', - fricas='ellipticPi', + # fricas='ellipticPi', doubt sympy='elliptic_pi')) def _eval_(self, n, z, m): From 49a26246f0af7256627a2b44963a42d57bb7b3c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 12 Apr 2022 16:46:37 +0200 Subject: [PATCH 135/529] fix typo --- src/sage/misc/binary_tree.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/misc/binary_tree.pyx b/src/sage/misc/binary_tree.pyx index 943960f5413..8827cac9ef2 100644 --- a/src/sage/misc/binary_tree.pyx +++ b/src/sage/misc/binary_tree.pyx @@ -435,7 +435,7 @@ cdef class BinaryTree: sage: t.is_empty() False """ - return self.head == NULL: + return self.head == NULL def keys(BinaryTree self, order="inorder"): """ From 1747c1040a0021497bc5b16c62a9109af83c6353 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 12 Apr 2022 20:18:52 +0200 Subject: [PATCH 136/529] simplify some isinstance or isinstance --- src/sage/categories/pushout.py | 2 +- src/sage/dynamics/arithmetic_dynamics/affine_ds.py | 2 +- src/sage/geometry/polyhedron/backend_normaliz.py | 2 +- src/sage/interfaces/maxima_lib.py | 2 +- src/sage/libs/giac/giac.pyx | 2 +- src/sage/libs/mpmath/ext_main.pyx | 6 +++--- src/sage/libs/mpmath/utils.pyx | 2 +- src/sage/libs/ntl/ntl_GF2.pyx | 2 +- src/sage/libs/ntl/ntl_ZZX.pyx | 2 +- src/sage/libs/ntl/ntl_ZZ_pE.pyx | 2 +- src/sage/libs/ntl/ntl_ZZ_pEX.pyx | 2 +- src/sage/libs/singular/function.pyx | 5 ++--- src/sage/matroids/utilities.py | 2 +- src/sage/modular/cusps.py | 2 +- .../modular/modform_hecketriangle/analytic_type.py | 2 +- src/sage/modular/modform_hecketriangle/subspace.py | 2 +- src/sage/modules/vector_mod2_dense.pyx | 2 +- src/sage/numerical/mip.pyx | 2 +- src/sage/numerical/optimize.py | 6 +++--- src/sage/rings/complex_mpc.pyx | 2 +- src/sage/rings/complex_mpfr.pyx | 2 +- src/sage/rings/convert/mpfi.pyx | 2 +- src/sage/rings/finite_rings/element_ntl_gf2e.pyx | 4 +--- src/sage/rings/polynomial/groebner_fan.py | 2 +- src/sage/rings/polynomial/pbori/pbori.pyx | 2 +- src/sage/rings/polynomial/polynomial_zmod_flint.pyx | 2 +- src/sage/rings/polynomial/polynomial_zz_pex.pyx | 2 +- src/sage/rings/polynomial/term_order.py | 8 +++++--- src/sage/sandpiles/sandpile.py | 10 +++++----- src/sage/schemes/berkovich/berkovich_cp_element.py | 2 +- src/sage/schemes/plane_conics/con_rational_field.py | 2 +- src/sage/stats/time_series.pyx | 2 +- src/sage/structure/parent.pyx | 2 +- src/sage/symbolic/ring.pyx | 2 +- 34 files changed, 47 insertions(+), 48 deletions(-) diff --git a/src/sage/categories/pushout.py b/src/sage/categories/pushout.py index f4bb28d14e1..29aefc9d4a6 100644 --- a/src/sage/categories/pushout.py +++ b/src/sage/categories/pushout.py @@ -1378,7 +1378,7 @@ def __mul__(self, other): # even respecting the order. Note that, if the pushout is computed, only *one* variable # will occur in the polynomial constructor. Hence, any order is fine, which is exactly # what we need in order to have coercion maps for different orderings. - if isinstance(other, MultiPolynomialFunctor) or isinstance(other, PolynomialFunctor): + if isinstance(other, (MultiPolynomialFunctor, PolynomialFunctor)): if isinstance(other, MultiPolynomialFunctor): othervars = other.vars else: diff --git a/src/sage/dynamics/arithmetic_dynamics/affine_ds.py b/src/sage/dynamics/arithmetic_dynamics/affine_ds.py index a4f03f439bf..ec130e75a3b 100644 --- a/src/sage/dynamics/arithmetic_dynamics/affine_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/affine_ds.py @@ -718,7 +718,7 @@ def orbit(self, P, n): ((-t^16 + 3*t^13 - 3*t^10 + t^7 + t^5 + t^3 - 1)/(t^5 + t^3 - 1), -t^9 - t^7 + t^4)] """ Q = P - if isinstance(n, list) or isinstance(n, tuple): + if isinstance(n, (list, tuple)): bounds = list(n) else: bounds = [0,n] diff --git a/src/sage/geometry/polyhedron/backend_normaliz.py b/src/sage/geometry/polyhedron/backend_normaliz.py index e53560aa7ca..73da73c4d0e 100644 --- a/src/sage/geometry/polyhedron/backend_normaliz.py +++ b/src/sage/geometry/polyhedron/backend_normaliz.py @@ -1196,7 +1196,7 @@ def format_number(x): return '({})'.format(x.polynomial('a')) def format_field(key, value): - if isinstance(value, list) or isinstance(value, tuple): + if isinstance(value, (list, tuple)): s = '{} {}\n'.format(key, len(value)) for e in value: for x in e: diff --git a/src/sage/interfaces/maxima_lib.py b/src/sage/interfaces/maxima_lib.py index c9a778a6ca4..3b190cc79f6 100644 --- a/src/sage/interfaces/maxima_lib.py +++ b/src/sage/interfaces/maxima_lib.py @@ -1589,7 +1589,7 @@ def sr_to_max(expr): """ global sage_op_dict, max_op_dict global sage_sym_dict, max_sym_dict - if isinstance(expr,list) or isinstance(expr,tuple): + if isinstance(expr, (list, tuple)): return EclObject(([mlist],[sr_to_max(e) for e in expr])) op = expr.operator() if op: diff --git a/src/sage/libs/giac/giac.pyx b/src/sage/libs/giac/giac.pyx index 6e7664f1151..7148549dcd9 100644 --- a/src/sage/libs/giac/giac.pyx +++ b/src/sage/libs/giac/giac.pyx @@ -978,7 +978,7 @@ cdef class Pygen(GiacMethods_base): cdef gen result if(self._type == 7) or (self._type == 12): #if self is a list or a string - if isinstance(i,int) or isinstance(i,Integer): + if isinstance(i, (int, Integer)): n=len(self) if(ix).re) MPF_set(im, &(x).im) return 2 - if isinstance(x, int) or isinstance(x, long) or isinstance(x, Integer): + if isinstance(x, (int, Integer)): MPF_set_int(re, x) return 1 if isinstance(x, float): @@ -995,7 +995,7 @@ cdef class Context: """ cdef MPF v cdef bint ismpf, ismpc - if isinstance(x, int) or isinstance(x, long) or isinstance(x, Integer): + if isinstance(x, (int, Integer)): return int(x), 'Z' if isinstance(x, tuple): p, q = x @@ -1072,7 +1072,7 @@ cdef class Context: """ cdef int typ - if isinstance(x, int) or isinstance(x, long) or isinstance(x, Integer): + if isinstance(x, (int, Integer)): mpz_set_integer(tmp_opx_re.man, x) if mpz_sgn(tmp_opx_re.man) == 0: return global_context.ninf diff --git a/src/sage/libs/mpmath/utils.pyx b/src/sage/libs/mpmath/utils.pyx index f7b50db3c36..466334e929a 100644 --- a/src/sage/libs/mpmath/utils.pyx +++ b/src/sage/libs/mpmath/utils.pyx @@ -334,7 +334,7 @@ def sage_to_mpmath(x, prec): from sage.rings.complex_mpfr import ComplexField x = ComplexField(prec)(x) return x._mpmath_() - if isinstance(x, tuple) or isinstance(x, list): + if isinstance(x, (tuple, list)): return type(x)([sage_to_mpmath(v, prec) for v in x]) if isinstance(x, dict): return dict([(k, sage_to_mpmath(v, prec)) for (k, v) in x.items()]) diff --git a/src/sage/libs/ntl/ntl_GF2.pyx b/src/sage/libs/ntl/ntl_GF2.pyx index b899f21548f..605bd3ad936 100644 --- a/src/sage/libs/ntl/ntl_GF2.pyx +++ b/src/sage/libs/ntl/ntl_GF2.pyx @@ -56,7 +56,7 @@ cdef class ntl_GF2(object): """ if isinstance(v, ntl_GF2): self.x = (v).x - elif isinstance(v, int) or isinstance(v, long) or isinstance(v, Integer): + elif isinstance(v, (int, Integer)): GF2_conv_long(self.x, int(v) % 2) elif v is not None: ccreadstr(self.x, str(v)) diff --git a/src/sage/libs/ntl/ntl_ZZX.pyx b/src/sage/libs/ntl/ntl_ZZX.pyx index ac3e3d10271..8c596bd23a6 100644 --- a/src/sage/libs/ntl/ntl_ZZX.pyx +++ b/src/sage/libs/ntl/ntl_ZZX.pyx @@ -131,7 +131,7 @@ cdef class ntl_ZZX(object): if v is None: return - elif isinstance(v, list) or isinstance(v, tuple): + elif isinstance(v, (list, tuple)): for i from 0 <= i < len(v): x = v[i] if not isinstance(x, ntl_ZZ): diff --git a/src/sage/libs/ntl/ntl_ZZ_pE.pyx b/src/sage/libs/ntl/ntl_ZZ_pE.pyx index c2802a3391b..6e3684521de 100644 --- a/src/sage/libs/ntl/ntl_ZZ_pE.pyx +++ b/src/sage/libs/ntl/ntl_ZZ_pE.pyx @@ -113,7 +113,7 @@ cdef class ntl_ZZ_pE(object): if (v).c is not self.c.pc: raise ValueError("You cannot cast between rings with different moduli") self.x = ZZ_pX_to_ZZ_pE((v).x) - elif isinstance(v, list) or isinstance(v, tuple): + elif isinstance(v, (list, tuple)): tmp_zzpx = ntl_ZZ_pX(v, self.c.pc) self.c.restore_c() # allocating tmp_zzpx can change the current modulus trac #25790 self.x = ZZ_pX_to_ZZ_pE(tmp_zzpx.x) diff --git a/src/sage/libs/ntl/ntl_ZZ_pEX.pyx b/src/sage/libs/ntl/ntl_ZZ_pEX.pyx index b83d6f062f1..a23d84bd4ad 100644 --- a/src/sage/libs/ntl/ntl_ZZ_pEX.pyx +++ b/src/sage/libs/ntl/ntl_ZZ_pEX.pyx @@ -87,7 +87,7 @@ cdef class ntl_ZZ_pEX(object): if v is None: return - elif isinstance(v, list) or isinstance(v, tuple): + elif isinstance(v, (list, tuple)): for i from 0 <= i < len(v): x = v[i] if not isinstance(x, ntl_ZZ_pE): diff --git a/src/sage/libs/singular/function.pyx b/src/sage/libs/singular/function.pyx index d8332743485..44ce07d13c3 100644 --- a/src/sage/libs/singular/function.pyx +++ b/src/sage/libs/singular/function.pyx @@ -531,7 +531,7 @@ cdef class Converter(SageObject): isinstance(a, NCPolynomialIdeal): v = self.append_ideal(a) - elif isinstance(a, int) or isinstance(a, long): + elif isinstance(a, int): v = self.append_int(a) elif isinstance(a, str): @@ -1427,8 +1427,7 @@ The Singular documentation for '%s' is given below. continue elif isinstance(a, Matrix_mpolynomial_dense): ring2 = a.base_ring() - elif isinstance(a, list) or isinstance(a, tuple)\ - or isinstance(a, Sequence_generic): + elif isinstance(a, (list, tuple, Sequence_generic)): #TODO: catch exception, if recursion finds no ring ring2 = self.common_ring(tuple(a), ring) elif isinstance(a, Resolution): diff --git a/src/sage/matroids/utilities.py b/src/sage/matroids/utilities.py index 751d96592b2..eb2999ea07b 100644 --- a/src/sage/matroids/utilities.py +++ b/src/sage/matroids/utilities.py @@ -123,7 +123,7 @@ def setprint_s(X, toplevel=False): sage: setprint_s(X, toplevel=True) 'abcd' """ - if isinstance(X, frozenset) or isinstance(X, set): + if isinstance(X, (frozenset, set)): return '{' + ', '.join(sorted(setprint_s(x) for x in X)) + '}' elif isinstance(X, dict): return '{' + ', '.join(sorted(setprint_s(key) + ': ' + setprint_s(val) diff --git a/src/sage/modular/cusps.py b/src/sage/modular/cusps.py index ef1b8e250d6..0a40b57294c 100644 --- a/src/sage/modular/cusps.py +++ b/src/sage/modular/cusps.py @@ -214,7 +214,7 @@ def __init__(self, a, b=None, parent=None, check=True): self.__b = ZZ.zero() return - if isinstance(a, Integer) or isinstance(a, Rational): + if isinstance(a, (Integer, Rational)): r = a / ZZ(b) elif is_InfinityElement(a): self.__a = ZZ.one() diff --git a/src/sage/modular/modform_hecketriangle/analytic_type.py b/src/sage/modular/modform_hecketriangle/analytic_type.py index 9b80337749f..00207502ad4 100644 --- a/src/sage/modular/modform_hecketriangle/analytic_type.py +++ b/src/sage/modular/modform_hecketriangle/analytic_type.py @@ -528,7 +528,7 @@ def _element_constructor_(self, element): if isinstance(element, str): element=[element] - if isinstance(element,list) or isinstance(element,tuple): + if isinstance(element, (list, tuple)): element = Set(self._base_poset.order_ideal([self._base_poset(s) for s in element])) return super(AnalyticType, self)._element_constructor_(element) diff --git a/src/sage/modular/modform_hecketriangle/subspace.py b/src/sage/modular/modform_hecketriangle/subspace.py index 853d4ecfb9c..758a154f14b 100644 --- a/src/sage/modular/modform_hecketriangle/subspace.py +++ b/src/sage/modular/modform_hecketriangle/subspace.py @@ -84,7 +84,7 @@ def ModularFormsSubSpace(*args, **kwargs): generators = [] for arg in args: - if isinstance(arg, list) or isinstance(arg, tuple): + if isinstance(arg, (list, tuple)): generators += arg else: generators.append(arg) diff --git a/src/sage/modules/vector_mod2_dense.pyx b/src/sage/modules/vector_mod2_dense.pyx index 8389d851239..61ae0eb1a69 100644 --- a/src/sage/modules/vector_mod2_dense.pyx +++ b/src/sage/modules/vector_mod2_dense.pyx @@ -505,7 +505,7 @@ def unpickle_v0(parent, entries, degree, is_immutable): cdef int xi for i from 0 <= i < degree: - if isinstance(entries[i], IntegerMod_int) or isinstance(entries[i], int) or isinstance(entries[i], Integer): + if isinstance(entries[i], (IntegerMod_int, int, Integer)): xi = entries[i] mzd_write_bit(v._entries, 0, i, xi%2) else: diff --git a/src/sage/numerical/mip.pyx b/src/sage/numerical/mip.pyx index 05c2de57742..541361b90a9 100644 --- a/src/sage/numerical/mip.pyx +++ b/src/sage/numerical/mip.pyx @@ -1004,7 +1004,7 @@ cdef class MixedIntegerLinearProgram(SageObject): indices = list(xrange(b.nrows())) # Only one constraint - if isinstance(indices, int) or isinstance(indices, Integer): + if isinstance(indices, (int, Integer)): lb, ub = b.row_bounds(indices) return (lb, b.row(indices), ub) diff --git a/src/sage/numerical/optimize.py b/src/sage/numerical/optimize.py index ecb1304a98f..7a24fb6ab55 100644 --- a/src/sage/numerical/optimize.py +++ b/src/sage/numerical/optimize.py @@ -542,8 +542,8 @@ def minimize_constrained(func,cons,x0,gradient=None,algorithm='default', **args) else: f = func - if isinstance(cons,list): - if isinstance(cons[0], tuple) or isinstance(cons[0], list) or cons[0] is None: + if isinstance(cons, list): + if isinstance(cons[0], (tuple, list)) or cons[0] is None: if gradient is not None: if algorithm == 'l-bfgs-b': min = optimize.fmin_l_bfgs_b(f, x0, gradient, bounds=cons, iprint=-1, **args)[0] @@ -554,7 +554,7 @@ def minimize_constrained(func,cons,x0,gradient=None,algorithm='default', **args) min = optimize.fmin_l_bfgs_b(f, x0, approx_grad=True, bounds=cons, iprint=-1, **args)[0] else: min = optimize.fmin_tnc(f, x0, approx_grad=True, bounds=cons, messages=0, **args)[0] - elif isinstance(cons[0], function_type) or isinstance(cons[0], Expression): + elif isinstance(cons[0], (function_type, Expression)): min = optimize.fmin_cobyla(f, x0, cons, **args) elif isinstance(cons, function_type) or isinstance(cons, Expression): min = optimize.fmin_cobyla(f, x0, cons, **args) diff --git a/src/sage/rings/complex_mpc.pyx b/src/sage/rings/complex_mpc.pyx index 8cf8c6344fb..49109af92c6 100644 --- a/src/sage/rings/complex_mpc.pyx +++ b/src/sage/rings/complex_mpc.pyx @@ -846,7 +846,7 @@ cdef class MPComplexNumber(sage.structure.element.FieldElement): return elif isinstance(z, sage.libs.pari.all.pari_gen): real, imag = z.real(), z.imag() - elif isinstance(z, list) or isinstance(z, tuple): + elif isinstance(z, (list, tuple)): real, imag = z elif isinstance(z, complex): real, imag = z.real, z.imag diff --git a/src/sage/rings/complex_mpfr.pyx b/src/sage/rings/complex_mpfr.pyx index 62b58ce8c8e..21b32326aa3 100644 --- a/src/sage/rings/complex_mpfr.pyx +++ b/src/sage/rings/complex_mpfr.pyx @@ -958,7 +958,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement): real, imag = (real).real(), (real).imag() elif isinstance(real, sage.libs.pari.all.pari_gen): real, imag = real.real(), real.imag() - elif isinstance(real, list) or isinstance(real, tuple): + elif isinstance(real, (list, tuple)): re, imag = real real = re elif isinstance(real, complex): diff --git a/src/sage/rings/convert/mpfi.pyx b/src/sage/rings/convert/mpfi.pyx index 1f16b866862..3dbe12da224 100644 --- a/src/sage/rings/convert/mpfi.pyx +++ b/src/sage/rings/convert/mpfi.pyx @@ -86,7 +86,7 @@ cdef int mpfi_set_sage(mpfi_ptr re, mpfi_ptr im, x, field, int base) except -1: mpfi_set_sage(re, NULL, x[0], field, base) mpfi_set_sage(im, NULL, x[1], field, base) return 0 - if isinstance(x, list) or isinstance(x, tuple): + if isinstance(x, (list, tuple)): # Interpret entries in x as endpoints of interval if len(x) != 2: raise TypeError("list defining an interval must have length 2") diff --git a/src/sage/rings/finite_rings/element_ntl_gf2e.pyx b/src/sage/rings/finite_rings/element_ntl_gf2e.pyx index f6d6ec9c446..beda02aea78 100644 --- a/src/sage/rings/finite_rings/element_ntl_gf2e.pyx +++ b/src/sage/rings/finite_rings/element_ntl_gf2e.pyx @@ -308,9 +308,7 @@ cdef class Cache_ntl_gf2e(Cache_base): if is_IntegerMod(e): e = e.lift() - if isinstance(e, int) or \ - isinstance(e, Integer) or \ - isinstance(e, long): + if isinstance(e, (int, Integer)): GF2E_conv_long(res.x,int(e&1)) return res diff --git a/src/sage/rings/polynomial/groebner_fan.py b/src/sage/rings/polynomial/groebner_fan.py index f35af7630bb..6c6548d9e85 100644 --- a/src/sage/rings/polynomial/groebner_fan.py +++ b/src/sage/rings/polynomial/groebner_fan.py @@ -1331,7 +1331,7 @@ def render(self, file=None, larger=False, shift=0, rgbcolor=(0, 0, 0), r_lines = r_lines + line(x, rgbcolor=rgbcolor) if polyfill: vals = [polyfill(q) for q in self.reduced_groebner_bases()] - if isinstance(vals[0], list) or isinstance(vals[0], tuple): + if isinstance(vals[0], (list, tuple)): if scale_colors: vmins = [min([q[i] for q in vals]) for i in (0, 1, 2)] vmaxs = [max([q[i] for q in vals]) for i in (0, 1, 2)] diff --git a/src/sage/rings/polynomial/pbori/pbori.pyx b/src/sage/rings/polynomial/pbori/pbori.pyx index 98afedfa785..b634fc3b56e 100644 --- a/src/sage/rings/polynomial/pbori/pbori.pyx +++ b/src/sage/rings/polynomial/pbori/pbori.pyx @@ -8165,7 +8165,7 @@ cdef class PolynomialFactory: elif isinstance(ring, BooleanPolynomialRing): return (ring)._coerce_(arg) else: - if isinstance(arg, int) or isinstance(arg, Integer): + if isinstance(arg, (int, Integer)): return new_BP_from_PBPoly(self._ring, self._factory(arg)) diff --git a/src/sage/rings/polynomial/polynomial_zmod_flint.pyx b/src/sage/rings/polynomial/polynomial_zmod_flint.pyx index 65cb1a5d630..f9c04f5cd6e 100644 --- a/src/sage/rings/polynomial/polynomial_zmod_flint.pyx +++ b/src/sage/rings/polynomial/polynomial_zmod_flint.pyx @@ -100,7 +100,7 @@ cdef class Polynomial_zmod_flint(Polynomial_template): """ cdef long nlen - if isinstance(x, list) or isinstance(x, tuple): + if isinstance(x, (list, tuple)): k = parent._base if check: lst = [k(i) for i in x] diff --git a/src/sage/rings/polynomial/polynomial_zz_pex.pyx b/src/sage/rings/polynomial/polynomial_zz_pex.pyx index 5db4b9d84d4..853ca0629c3 100644 --- a/src/sage/rings/polynomial/polynomial_zz_pex.pyx +++ b/src/sage/rings/polynomial/polynomial_zz_pex.pyx @@ -138,7 +138,7 @@ cdef class Polynomial_ZZ_pEX(Polynomial_template): if isinstance(x, Polynomial): x = x.list() - if isinstance(x, list) or isinstance(x, tuple): + if isinstance(x, (list, tuple)): Polynomial.__init__(self, parent, is_gen=is_gen) (self)._cparent = get_cparent(parent) celement_construct(&self.x, (self)._cparent) diff --git a/src/sage/rings/polynomial/term_order.py b/src/sage/rings/polynomial/term_order.py index 64cdec1443e..6763f2016c7 100644 --- a/src/sage/rings/polynomial/term_order.py +++ b/src/sage/rings/polynomial/term_order.py @@ -706,7 +706,7 @@ def __init__(self, name='lex', n=0, force=False): name = name.lower() else: try: - if not isinstance(name, (tuple,list)): + if not isinstance(name, (tuple, list)): name = name.list() # name may be a matrix name = tuple(name) except Exception: @@ -766,7 +766,8 @@ def __init__(self, name='lex', n=0, force=False): self._macaulay2_str = "{" + ",".join(macaulay2_str) + "}" self._magma_str = "" # Magma does not support block order self._blocks = tuple(blocks) - elif isinstance(name, str) and not (isinstance(n, tuple) or isinstance(n,list)): # string representation of simple or block orders + elif isinstance(name, str) and not isinstance(n, (tuple, list)): + # string representation of simple or block orders if force: self._length = n self._name = name @@ -817,7 +818,8 @@ def __init__(self, name='lex', n=0, force=False): if n and length != n: raise ValueError("term order length does not match the number of generators") self.__copy(TermOrder('block', blocks)) - elif isinstance(name, str) and (isinstance(n, tuple) or isinstance(n,list)): # weighted degree term orders + elif isinstance(name, str) and isinstance(n, (tuple, list)): + # weighted degree term orders if name not in print_name_mapping.keys() and name not in singular_name_mapping.values() and not force: raise ValueError("unknown term order {!r}".format(name)) weights = tuple(int(w) for w in n) # n is a tuple of weights diff --git a/src/sage/sandpiles/sandpile.py b/src/sage/sandpiles/sandpile.py index 8270261cbe3..da3955bf6f2 100644 --- a/src/sage/sandpiles/sandpile.py +++ b/src/sage/sandpiles/sandpile.py @@ -593,7 +593,7 @@ def __init__(self, g, sink=None): TypeError: ...__init__() got an unexpected keyword argument 'weighted' """ # set graph name - if isinstance(g, Graph) or isinstance(g, DiGraph): + if isinstance(g, (Graph, DiGraph)): name = g.name() if name == '': name = 'sandpile graph' @@ -612,7 +612,7 @@ def __init__(self, g, sink=None): elif isinstance(g, dict) and isinstance(next(iter(g.values())), list): processed_g = {i: dict(Counter(g[i])) for i in g} g = processed_g - elif isinstance(g, Graph) or isinstance(g, DiGraph): + elif isinstance(g, (Graph, DiGraph)): if not g.weighted(): h = g.to_dictionary(multiple_edges=True) g = {i: dict(Counter(h[i])) for i in h} @@ -2254,7 +2254,7 @@ def markov_chain(self,state, distrib=None): st = deepcopy(state) V = self.vertices() n = len(V) - if isinstance(st,list): + if isinstance(st, list): if len(st)==self.num_verts()-1: st = SandpileConfig(self,st) elif len(st)==self.num_verts(): @@ -2264,7 +2264,7 @@ def markov_chain(self,state, distrib=None): if distrib is None: # default = uniform distribution distrib = [QQ.one() / n] * n X = GeneralDiscreteDistribution(distrib) - if isinstance(st,SandpileConfig): + if isinstance(st, SandpileConfig): while True: i = X.get_random_element() if V[i] != self.sink(): @@ -2963,7 +2963,7 @@ def __init__(self, S, c): {1: 2, 2: 2, 3: 0} """ if len(c)==S.num_verts()-1: - if isinstance(c, dict) or isinstance(c, SandpileConfig): + if isinstance(c, (dict, SandpileConfig)): dict.__init__(self,c) elif isinstance(c, list): c.reverse() diff --git a/src/sage/schemes/berkovich/berkovich_cp_element.py b/src/sage/schemes/berkovich/berkovich_cp_element.py index 1f868be527d..9587901c476 100644 --- a/src/sage/schemes/berkovich/berkovich_cp_element.py +++ b/src/sage/schemes/berkovich/berkovich_cp_element.py @@ -88,7 +88,7 @@ def __init__(self, parent, center, radius=None, power=None, prec=20, space_type= self._type = None # if radius is a list or a tuple, this is a type 4 point - if isinstance(radius, list) or isinstance(radius, tuple): + if isinstance(radius, (list, tuple)): if error_check: if not (isinstance(center, list) or isinstance(center, tuple)): raise TypeError("center was passed a list but radius was not a list") diff --git a/src/sage/schemes/plane_conics/con_rational_field.py b/src/sage/schemes/plane_conics/con_rational_field.py index d24bd59898c..5c35f342c14 100644 --- a/src/sage/schemes/plane_conics/con_rational_field.py +++ b/src/sage/schemes/plane_conics/con_rational_field.py @@ -230,7 +230,7 @@ def is_locally_solvable(self, p) -> bool: return True a = -abc[0] / abc[2] b = -abc[1] / abc[2] - if isinstance(p, sage.rings.abc.RealField) or isinstance(p, InfinityElement): + if isinstance(p, (sage.rings.abc.RealField, InfinityElement)): p = -1 elif isinstance(p, Map) and p.category_for().is_subcategory(Rings()): # p is a morphism of Rings diff --git a/src/sage/stats/time_series.pyx b/src/sage/stats/time_series.pyx index 234925fb478..7045ed8b09d 100644 --- a/src/sage/stats/time_series.pyx +++ b/src/sage/stats/time_series.pyx @@ -131,7 +131,7 @@ cdef class TimeSeries: if isinstance(values, (int, long, Integer)): self._length = values values = None - elif isinstance(values, Vector_real_double_dense) or isinstance(values, cnumpy.ndarray): + elif isinstance(values, (Vector_real_double_dense, cnumpy.ndarray)): if isinstance(values, Vector_real_double_dense): np = values._vector_numpy else: diff --git a/src/sage/structure/parent.pyx b/src/sage/structure/parent.pyx index 483ca9b776e..0c97d4622c6 100644 --- a/src/sage/structure/parent.pyx +++ b/src/sage/structure/parent.pyx @@ -1740,7 +1740,7 @@ cdef class Parent(sage.structure.category_object.CategoryObject): raise ValueError("Map's codomain must be self") self._convert_from_list.append(mor) self._convert_from_hash.set(mor.domain(), mor) - elif isinstance(mor, Parent) or isinstance(mor, type): + elif isinstance(mor, (Parent, type)): t = mor mor = self._generic_convert_map(mor) self._convert_from_list.append(mor) diff --git a/src/sage/symbolic/ring.pyx b/src/sage/symbolic/ring.pyx index 05694e3b085..8da8df00ec9 100644 --- a/src/sage/symbolic/ring.pyx +++ b/src/sage/symbolic/ring.pyx @@ -745,7 +745,7 @@ cdef class SymbolicRing(sage.rings.abc.SymbolicRing): True """ from sage.symbolic.assumptions import assumptions - if isinstance(symbol,list) or isinstance(symbol,tuple): + if isinstance(symbol, (list, tuple)): for s in symbol: self.cleanup_var(s) else: From d7d7bdaf9e0f54b6906d127ba2e68b532a835ca9 Mon Sep 17 00:00:00 2001 From: Dave Witte Morris Date: Tue, 12 Apr 2022 13:40:15 -0600 Subject: [PATCH 137/529] trac 33697: equality of SR vectors --- src/sage/modules/free_module_element.pyx | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index 93689cddf23..33d38b29185 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -1754,12 +1754,23 @@ cdef class FreeModuleElement(Vector): # abstract base class True sage: vector(F, [0,0,0,0]) == vector(F, [0,2,0,y]) False + + Verify that :trac:`33697` is fixed:: + + sage: v = vector(SR, [x]) + sage: w = vector(SR, [1]) + sage: v == w + False + sage: assume(x > 0) + sage: v == w + False + sage: forget() """ cdef Py_ssize_t i for i in range(left._degree): lx = left[i] rx = right[i] - if lx != rx: + if not(lx == rx): return richcmp_not_equal(lx, rx, op) return rich_to_bool(op, 0) From 77d1e538c532bd4f15b705d16dc9b7f9a15eb0b5 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 11 Apr 2022 18:30:26 -0700 Subject: [PATCH 138/529] src/doc/en/developer/manual_git.rst: Move section on SSH keys here from trac.rst, add links to GitLab instructions --- src/doc/en/developer/manual_git.rst | 123 +++++++++++++++++++++++++++- src/doc/en/developer/trac.rst | 111 ------------------------- 2 files changed, 121 insertions(+), 113 deletions(-) diff --git a/src/doc/en/developer/manual_git.rst b/src/doc/en/developer/manual_git.rst index f82d557758e..c08c44ec793 100644 --- a/src/doc/en/developer/manual_git.rst +++ b/src/doc/en/developer/manual_git.rst @@ -7,6 +7,8 @@ Using Git with the Sage Trac Server =================================== Now we continue our introduction to git from :ref:`chapter-walkthrough`. +We discuss how to push your local changes to a remote repository +so that your changes can be reviewed for inclusion in Sage. In the following, we assume that you are in the source directory of Sage (``SAGE_ROOT``), obtained either from a source tarball or by cloning a Sage git repository @@ -22,11 +24,128 @@ are associated with this local repository:: origin https://github.com/sagemath/sage.git (fetch) origin https://github.com/sagemath/sage.git (push) +.. _section-git-ssh: + +Git authentication through SSH +============================== + +In order to push changes securely to a remote repository, git uses +public-key cryptography. This section will show you how to set up the +necessary cryptographic keys for Secure Shell (SSH). + + +Checking whether you have already have suitable SSH keys +-------------------------------------------------------- + +Follow the instructions in +https://docs.gitlab.com/ee/user/ssh.html#see-if-you-have-an-existing-ssh-key-pair. + + +Generating your SSH Keys +------------------------ + +If you don't have suitable SSH keys yet, you can create a key pair +with the ``ssh-keygen`` tool. + +Follow either the detailed instructions at +https://docs.gitlab.com/ee/user/ssh.html#generate-an-ssh-key-pair +or the following brief instructions:: + + [user@localhost ~]$ ssh-keygen + Generating public/private rsa key pair. + Enter file in which to save the key (/home/user/.ssh/id_rsa): + Enter passphrase (empty for no passphrase): + Enter same passphrase again: + Your identification has been saved in /home/user/.ssh/id_rsa. + Your public key has been saved in /home/user/.ssh/id_rsa.pub. + The key fingerprint is: + ce:32:b3:de:38:56:80:c9:11:f0:b3:88:f2:1c:89:0a user@localhost + The key's randomart image is: + +--[ RSA 2048]----+ + | .... | + | .. | + | .o+ | + | o o+o. | + |E + . .S | + |+o . o. | + |. o +.o | + | oB | + | o+.. | + +-----------------+ + +This will generate a new random private RSA key +in the ``.ssh`` folder in your home directory. By default, they are + +``~/.ssh/id_rsa`` + Your private key. Keep safe. **Never** hand it out to anybody. + +``~/.ssh/id_rsa.pub`` + The corresponding public key. This and only this file can be safely + disclosed to third parties. + +The ``ssh-keygen`` tool will let you generate a key with a different +file name, or protect it with a passphrase. Depending on how much you +trust your own computer or system administrator, you can leave the +passphrase empty to be able to login without any human intervention. + + +.. _section-trac-ssh-key: + +Linking your Public Key to your Trac Account +-------------------------------------------- + +In order to push your code directly to a branch on the git repository +trac.sagemath.org, the Sage trac server needs to know your public +key. You can upload it in the preferences, that is + +1. Go to https://trac.sagemath.org + +2. Log in with your trac username/password + +3. Click on "Preferences" + +4. Go to the "SSH Keys" tab + +5. Paste the content of your public key file + (e.g. ``~/.ssh/id_rsa.pub``) + +6. Click on "Save changes" + +Note that this does **not** allow you to ssh into any account on trac, +it is only used to authenticate you to the gitolite installation on +trac. You can test that you are being authenticated correctly by +issuing some basic gitolite commands, for example:: + + [user@localhost ~]$ ssh git@trac.sagemath.org info + hello user, this is git@trac running gitolite3 (unknown) on git 1.7.9.5 + + R W sage + [user@localhost ~]$ ssh git@trac.sagemath.org help + hello user, this is gitolite3 (unknown) on git 1.7.9.5 + + list of remote commands available: + + desc + help + info + perms + writable + +Adding your Public Key for authentication on another server +----------------------------------------------------------- + +If you have an account on a lab or department computer that allows you +to log in remotely via SSH, you can now also use your SSH keys to +log in. Just copy the **public** key file (ending in ``.pub``) to +``~/.ssh/authorized_keys`` on the remote computer and make sure that +the file is only read/writeable by yourself. Voila, the next time you +ssh into that machine you don't have to provide your password. + .. _section-git-trac: -The Trac Server -=============== +The git repository trac.sagemath.org +==================================== The Sage trac server is another git repository for the Sage source tree, it is served via the ssh protocol. To add it as a remote repository to your local git diff --git a/src/doc/en/developer/trac.rst b/src/doc/en/developer/trac.rst index 6f72a6a2f00..1c70d172599 100644 --- a/src/doc/en/developer/trac.rst +++ b/src/doc/en/developer/trac.rst @@ -59,117 +59,6 @@ Using your GitHub account, you can log in to: corner, and then use the button "Sign in with GitHub" and follow the prompts. - -Trac authentication through SSH -=============================== - -There are two avenues to prove to the trac server that you are who you -claim to be. First, to change the ticket web pages you need to log in -to trac using a username/password. Second, there is public key -cryptography used by git when copying new source files to the -repository. This section will show you how to set up both. - -Generating and Uploading your SSH Keys --------------------------------------- - -The git installation on the development server uses SSH keys to decide if and -where you are allowed to upload code. No SSH key is required to report a bug or -comment on a ticket, but as soon as you want to contribute code yourself you -need to provide trac with the public half of your own personal key. -Details are described in the following two sections. - - -Generating your SSH Keys ---------------------------------- - -If you don't have a private key yet, you can -create it with the ``ssh-keygen`` tool:: - - [user@localhost ~]$ ssh-keygen - Generating public/private rsa key pair. - Enter file in which to save the key (/home/user/.ssh/id_rsa): - Enter passphrase (empty for no passphrase): - Enter same passphrase again: - Your identification has been saved in /home/user/.ssh/id_rsa. - Your public key has been saved in /home/user/.ssh/id_rsa.pub. - The key fingerprint is: - ce:32:b3:de:38:56:80:c9:11:f0:b3:88:f2:1c:89:0a user@localhost - The key's randomart image is: - +--[ RSA 2048]----+ - | .... | - | .. | - | .o+ | - | o o+o. | - |E + . .S | - |+o . o. | - |. o +.o | - | oB | - | o+.. | - +-----------------+ - -This will generate a new random private RSA key -in the ``.ssh`` folder in your home directory. By default, they are - -``~/.ssh/id_rsa`` - Your private key. Keep safe. **Never** hand it out to anybody. - -``~/.ssh/id_rsa.pub`` - The corresponding public key. This and only this file can be safely - disclosed to third parties. - -The ``ssh-keygen`` tool will let you generate a key with a different -file name, or protect it with a passphrase. Depending on how much you -trust your own computer or system administrator, you can leave the -passphrase empty to be able to login without any human intervention. - -If you have accounts on multiple computers you can use the SSH keys to -log in. Just copy the **public** key file (ending in ``.pub``) to -``~/.ssh/authorized_keys`` on the remote computer and make sure that -the file is only read/writeable by yourself. Voila, the next time you -ssh into that machine you don't have to provide your password. - - -.. _section-trac-ssh-key: - -Linking your Public Key to your Trac Account ------------------------------------------------------ - -The Sage trac server needs to know one of your public keys. You can -upload it in the preferences, that is - -1. Go to https://trac.sagemath.org - -2. Log in with your trac username/password - -3. Click on "Preferences" - -4. Go to the "SSH Keys" tab - -5. Paste the content of your public key file - (e.g. ``~/.ssh/id_rsa.pub``) - -6. Click on "Save changes" - -Note that this does **not** allow you to ssh into any account on trac, -it is only used to authenticate you to the gitolite installation on -trac. You can test that you are being authenticated correctly by -issuing some basic gitolite commands, for example:: - - [user@localhost ~]$ ssh git@trac.sagemath.org info - hello user, this is git@trac running gitolite3 (unknown) on git 1.7.9.5 - - R W sage - [user@localhost ~]$ ssh git@trac.sagemath.org help - hello user, this is gitolite3 (unknown) on git 1.7.9.5 - - list of remote commands available: - - desc - help - info - perms - writable - .. _trac-bug-report: Reporting Bugs From 56c63db07ac2c5872a28eb5d55af034979f44072 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 12 Apr 2022 21:50:59 -0700 Subject: [PATCH 139/529] configure.ac (--enable-doc): Fix --- configure.ac | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index ab4f066fa99..eca011d746e 100644 --- a/configure.ac +++ b/configure.ac @@ -491,8 +491,9 @@ AC_ARG_ENABLE([doc], for pkg in sage_docbuild alabaster babel snowballstemmer imagesize sphinx sphinxcontrib_devhelp sphinxcontrib_jsmath sphinxcontrib_serializinghtml sphinxcontrib_applehelp sphinxcontrib_htmlhelp sphinxcontrib_qthelp sphinxcontrib_websupport jupyter_sphinx; do AS_VAR_SET([SAGE_ENABLE_$pkg], [$enableval]) done - dnl Disable the docbuild by disabling the install tree for documentation - AS_VAR_SET([SAGE_DOCS], []) + AS_VAR_IF([enableval], [no], [dnl Disable the docbuild by disabling the install tree for documentation + AS_VAR_SET([SAGE_DOCS], [])dnl + ]) ]) AC_ARG_ENABLE([sagelib], From d1f7eae1f2fc258b45e8cc435af7cecf351993d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 13 Apr 2022 08:49:08 +0200 Subject: [PATCH 140/529] more tweaks in doc in zero_sums --- src/sage/lfunctions/zero_sums.pyx | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/sage/lfunctions/zero_sums.pyx b/src/sage/lfunctions/zero_sums.pyx index 7558561d9c2..4a71c1e84eb 100644 --- a/src/sage/lfunctions/zero_sums.pyx +++ b/src/sage/lfunctions/zero_sums.pyx @@ -67,11 +67,11 @@ cdef class LFunctionZeroSum_abstract(SageObject): INPUT: - ``n`` -- (default: None) If not None, a nonnegative integer + - ``n`` -- (default: ``None``) If not ``None``, a nonnegative integer OUTPUT: - If n is not None, returns a positive integer + If n is not ``None``, returns a positive integer EXAMPLES:: @@ -505,7 +505,7 @@ cdef class LFunctionZeroSum_abstract(SageObject): - ``cauchy`` -- `f(x) = \frac{1}{1+x^2}`; this is only computable to low precision, and only when `\Delta < 2`. - - ``ncpus`` - (default: ``None``) If not ``None``, a positive integer + - ``ncpus`` -- (default: ``None``) If not ``None``, a positive integer defining the number of CPUs to be used for the computation. If left as ``None``, the maximum available number of CPUs will be used. Only implemented for algorithm="sincsquared_parallel"; ignored @@ -798,9 +798,9 @@ cdef class LFunctionZeroSum_abstract(SageObject): be 1 (assuming GRH, the zero is simple); otherwise the limit will be 0. - - ``num_terms`` -- positive integer (default: None): the number of + - ``num_terms`` -- positive integer (default: ``None``): the number of terms computed in the truncated Dirichlet series for the L-function - attached to ``self``. If left at None, this is set to + attached to ``self``. If left at ``None``, this is set to `\ceil(e^{2 \pi \Delta})`, the same number of terms used in the other zero sum methods for this value of Delta. Increase num_terms to get more accuracy. @@ -1411,7 +1411,7 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): method can be run on curves whose conductor is large enough to warrant precomputing bad primes. - - ``ncpus`` - (default: ``None``) If not ``None``, a positive integer + - ``ncpus`` -- (default: ``None``) If not ``None``, a positive integer defining the number of CPUs to be used for the computation. If left as ``None``, the maximum available number of CPUs will be used. @@ -1549,10 +1549,10 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): INPUT: - - ``max_Delta`` -- (default: None) If not None, a positive real value + - ``max_Delta`` -- (default: ``None``) If not ``None``, a positive real value specifying the maximum Delta value used in the zero sum; larger values of Delta yield better bounds - but runtime is exponential in - Delta. If left as None, Delta is set + Delta. If left as ``None``, Delta is set to `\min\left\{\frac{1}{\pi}\left(\log(N+1000)/2-\log(2\pi)-\eta\right), 2.5\right\}`, where `N` is the conductor of the curve attached to ``self``, and `\eta` is the Euler-Mascheroni constant `= 0.5772...`; the crossover @@ -1560,14 +1560,14 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): results show that for about 99.7% of all curves the returned value is the actual analytic rank. - - ``adaptive`` -- (default: True) Boolean + - ``adaptive`` -- (default: ``True``) Boolean - - If True, the computation is first run with small and then + - If ``True``, the computation is first run with small and then successively larger Delta values up to max_Delta. If at any point the computed bound is 0 (or 1 when root_number is -1 - or True), the computation halts and that value is returned; + or ``True``), the computation halts and that value is returned; otherwise the minimum of the computed bounds is returned. - - If False, the computation is run a single time with + - If ``False``, the computation is run a single time with Delta=max_Delta, and the resulting bound returned. - ``root_number`` -- (default: "compute") String or integer @@ -1589,7 +1589,7 @@ cdef class LFunctionZeroSum_EllipticCurve(LFunctionZeroSum_abstract): - ``ncpus`` -- (default: ``None``) If not ``None``, a positive integer defining the maximum number of CPUs to be used for the computation. - If left as None, the maximum available number of CPUs will be used. + If left as ``None``, the maximum available number of CPUs will be used. Note: Multiple processors will only be used for Delta values >= 1.75. .. NOTE:: From d1bf23e314fd1d0116ca132ce5986273a685e099 Mon Sep 17 00:00:00 2001 From: adarsh-kishore786 Date: Wed, 13 Apr 2022 19:25:04 +0530 Subject: [PATCH 141/529] Removed the random spanning tree construction line --- src/sage/graphs/spanning_tree.pyx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sage/graphs/spanning_tree.pyx b/src/sage/graphs/spanning_tree.pyx index 644729b7622..7a2a9153b90 100644 --- a/src/sage/graphs/spanning_tree.pyx +++ b/src/sage/graphs/spanning_tree.pyx @@ -15,7 +15,6 @@ including minimum spanning trees. .. TODO:: - Parallel version of Boruvka's algorithm. - - Randomized spanning tree construction. Methods From 0ee4555b63dd8f858c047b45bc8d2dd46a81d896 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 13 Apr 2022 21:23:48 +0200 Subject: [PATCH 142/529] about Stein-Watkins database --- src/sage/databases/stein_watkins.py | 31 +++++++++++++++-------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/sage/databases/stein_watkins.py b/src/sage/databases/stein_watkins.py index f326925ac95..2936fd6da1d 100644 --- a/src/sage/databases/stein_watkins.py +++ b/src/sage/databases/stein_watkins.py @@ -29,7 +29,7 @@ - The command ``SteinWatkinsPrimeData(n)`` returns an iterator over the curves in the `n^{th}` Stein-Watkins prime table, which contains prime conductor - elliptic curves of conductor between `n10^6` and `(n+1)10^6`. Here `n` + elliptic curves of conductor between `n10^8` and `(n+1)10^8`. Here `n` varies between 0 and 99, inclusive. @@ -118,7 +118,7 @@ - [SW2002]_ """ -#***************************************************************************** +# **************************************************************************** # # Sage: Copyright (C) 2005 William Stein # @@ -132,19 +132,20 @@ # The full text of the GPL is available at: # # http://www.gnu.org/licenses/ -#***************************************************************************** +# **************************************************************************** import bz2 import os from sage.env import SAGE_SHARE + class SteinWatkinsIsogenyClass: def __init__(self, conductor): self.conductor = conductor def __repr__(self): - return "Stein-Watkins isogeny class of conductor %s"%self.conductor + return "Stein-Watkins isogeny class of conductor %s" % self.conductor def __len__(self): try: @@ -167,7 +168,7 @@ def _lines(s): yield "" return line = s[:i] - s = s[i+1:] + s = s[i + 1:] yield line @@ -180,10 +181,10 @@ def __init__(self, num): num = int(num) self.num = num if num < 0: - raise RuntimeError("num (=%s) must be a nonnegative integer"%num) + raise RuntimeError("num (=%s) must be a nonnegative integer" % num) name = str(num) - name = '0'*(3-len(name)) + name - self._file = os.path.join(SAGE_SHARE, 'stein_watkins', 'a.%s.bz2'%name) + name = '0' * (3 - len(name)) + name + self._file = os.path.join(SAGE_SHARE, 'stein_watkins', 'a.%s.bz2' % name) self._iter = iter(self) def __repr__(self): @@ -194,7 +195,7 @@ def __repr__(self): sage: d Stein-Watkins Database a.1 Iterator """ - return "Stein-Watkins Database a.%s Iterator"%self.num + return "Stein-Watkins Database a.%s Iterator" % self.num def __iter__(self): """ @@ -214,12 +215,12 @@ def __iter__(self): try: file = bz2.open(self._file, 'rt', encoding="utf-8") except IOError: - raise IOError("The Stein-Watkins data file %s must be installed."%self._file) + raise IOError("The Stein-Watkins data file %s must be installed." % self._file) C = None for L in file: if len(L) == 0: continue - if L[0] != '[': # new curve + if L[0] != '[': # new curve if C is not None: yield C x = L.split() @@ -314,10 +315,10 @@ def __init__(self, num): num = int(num) self.num = num if num < 0: - raise RuntimeError("num (=%s) must be a nonnegative integer"%num) + raise RuntimeError("num (=%s) must be a nonnegative integer" % num) name = str(num) - name = '0'*(2-len(name)) + name - self._file = os.path.join(SAGE_SHARE,'stein_watkins', 'p.%s.bz2'%name) + name = '0' * (2 - len(name)) + name + self._file = os.path.join(SAGE_SHARE, 'stein_watkins', 'p.%s.bz2' % name) self._iter = iter(self) def __repr__(self): @@ -328,7 +329,7 @@ def __repr__(self): sage: d Stein-Watkins Prime Conductor Database p.1 Iterator """ - return "Stein-Watkins Prime Conductor Database p.%s Iterator"%self.num + return "Stein-Watkins Prime Conductor Database p.%s Iterator" % self.num def ecdb_num_curves(max_level=200000): From 3347fb1ea5ca5c1d2d05c9c44776b8db0fc501c8 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Thu, 14 Apr 2022 14:12:22 +0800 Subject: [PATCH 143/529] add .montgomery_model() for elliptic curves --- src/doc/en/reference/references/index.rst | 6 + .../schemes/elliptic_curves/ell_generic.py | 214 ++++++++++++++++++ 2 files changed, 220 insertions(+) diff --git a/src/doc/en/reference/references/index.rst b/src/doc/en/reference/references/index.rst index 46e46557a02..32de0b77d7a 100644 --- a/src/doc/en/reference/references/index.rst +++ b/src/doc/en/reference/references/index.rst @@ -1778,6 +1778,9 @@ REFERENCES: Proceedings: F.Hess, S.Pauli and M.Pohst (eds.), ANTS VII, Lecture Notes in Computer Science 4076 (2006), pages 275-286. +.. [CS2018] Craig Costello and Benjamin Smith: Montgomery curves and + their arithmetic. J. Cryptogr. Eng. 8 (2018), 227-240. + .. [CST2010] Tullio Ceccherini-Silberstein, Fabio Scarabotti, Filippo Tolli. *Representation Theory of the Symmetric Groups: The @@ -4343,6 +4346,9 @@ REFERENCES: .. [Mon2010] \T. Monteil, The asymptotic language of smooth curves, talk at LaCIM2010. +.. [Mont1987] Peter L. Montgomery: Speeding the Pollard and elliptic curve + methods of factorization. Math. Comp. 48 (1987), 243-264. + .. [Mo2009] \D. Moody, Des. Codes Cryptogr. (2009) 52: 381. :doi:`10.1007/s10623-009-9287-x` diff --git a/src/sage/schemes/elliptic_curves/ell_generic.py b/src/sage/schemes/elliptic_curves/ell_generic.py index a7385b05ad9..08a0907cc7a 100644 --- a/src/sage/schemes/elliptic_curves/ell_generic.py +++ b/src/sage/schemes/elliptic_curves/ell_generic.py @@ -31,6 +31,7 @@ - Julian Rueth (2014-04-11): improved caching +- Lorenz Panny (2022-04-14): :meth:`~sage.schemes.elliptic_curves.ell_generic.EllipticCurve_generic.montgomery_model` """ # **************************************************************************** @@ -2662,6 +2663,219 @@ def short_weierstrass_model(self, complete_cube=True): b2, b4, b6, _ = self.b_invariants() return constructor.EllipticCurve([0,b2,0,8*b4,16*b6]) + def montgomery_model(self, twisted=False, morphism=False): + r""" + Return a (twisted or untwisted) Montgomery model for this + elliptic curve, if possible. + + A Montgomery curve is a smooth projective curve of the form + + .. MATH:: + + BY^2 = X^3 + AX^2 + X + \,\text. + + The Montgomery curve is called *untwisted* if `B=1`. + + INPUT: + + - ``twisted`` (boolean, default: ``False``) -- allow `B \neq 1` + + - ``morphism`` (boolean, default: ``False``) -- also return an + isomorphism from this curve to the computed Montgomery model + + OUTPUT: + + If ``twisted`` is not set (the default), an + :class:`EllipticCurve_generic` + object encapsulating an untwisted Montgomery curve. + Otherwise, a + :class:`~sage.schemes.curves.projective_curve.ProjectivePlaneCurve` + object encapsulating a (potentially twisted) Montgomery curve. + + If ``morphism`` is set, this method returns a tuple consisting + of such a curve together with an isomorphism of suitable type + (either + :class:`~sage.schemes.elliptic_curves.weierstrass_morphism.WeierstrassIsomorphism` + or + :class:`~sage.schemes.elliptic_curves.weierstrass_transform.WeierstrassTransformationWithInverse`) + from this curve to the Montgomery model. + + EXAMPLES:: + + sage: E = EllipticCurve(QQbar, '11a1') + sage: E.montgomery_model() + Elliptic Curve defined by y^2 = x^3 + (-1.953522420987248?)*x^2 + x over Algebraic Field + + :: + + sage: E = EllipticCurve(GF(431^2), [7,7]) + sage: E.montgomery_model() + Elliptic Curve defined by y^2 = x^3 + (51*z2+190)*x^2 + x over Finite Field in z2 of size 431^2 + + An isomorphism between the Montgomery and Weierstrass form can + be obtained using the ``morphism`` parameter:: + + sage: E.montgomery_model(morphism=True) + (Elliptic Curve defined by y^2 = x^3 + (51*z2+190)*x^2 + x over Finite Field in z2 of size 431^2, + Elliptic-curve morphism: + From: Elliptic Curve defined by y^2 = x^3 + 7*x + 7 over Finite Field in z2 of size 431^2 + To: Elliptic Curve defined by y^2 = x^3 + (51*z2+190)*x^2 + x over Finite Field in z2 of size 431^2 + Via: (u,r,s,t) = (64*z2 + 407, 159, 0, 0)) + + Not all elliptic curves have a Montgomery model over their field + of definition:: + + sage: E = EllipticCurve(GF(257), [1,1]) + sage: E.montgomery_model() + Traceback (most recent call last): + ... + ValueError: Elliptic Curve defined by y^2 = x^3 + x + 1 over Finite Field of size 257 has no Montgomery model + + :: + + sage: E = EllipticCurve(GF(257), [10,10]) + sage: E.montgomery_model() + Traceback (most recent call last): + ... + ValueError: Elliptic Curve defined by y^2 = x^3 + 10*x + 10 over Finite Field of size 257 has no untwisted Montgomery model + + However, as hinted by the error message, the latter curve does + admit a *twisted* Montgomery model, which can be computed by + passing ``twisted=True``:: + + sage: E.montgomery_model(twisted=True) + Projective Plane Curve over Finite Field of size 257 defined by -x^3 + 8*x^2*z - 127*y^2*z - x*z^2 + + Since Sage internally represents elliptic curves as (long) + Weierstrass curves, which do not feature the Montgomery `B` + coefficient, the returned curve in this case is merely a + :class:`~sage.schemes.curves.projective_curve.ProjectivePlaneCurve` + rather than the usual + :class:`EllipticCurve_generic`. + + Arithmetic on curves of this type is not implemented natively, + but can easily be emulated by mapping back and forth to the + corresponding Weierstrass curve:: + + sage: C, f = E.montgomery_model(twisted=True, morphism=True) + sage: f + Scheme morphism: + From: Elliptic Curve defined by y^2 = x^3 + 10*x + 10 over Finite Field of size 257 + To: Projective Plane Curve over Finite Field of size 257 defined by -x^3 + 8*x^2*z - 127*y^2*z - x*z^2 + Defn: Defined on coordinates by sending (x : y : z) to + (x + 116*z : -y : -85*z) + sage: g = f.inverse(); g + Scheme morphism: + From: Projective Plane Curve over Finite Field of size 257 defined by -x^3 + 8*x^2*z - 127*y^2*z - x*z^2 + To: Elliptic Curve defined by y^2 = x^3 + 10*x + 10 over Finite Field of size 257 + Defn: Defined on coordinates by sending (x : y : z) to + (-85*x - 116*z : 85*y : z) + sage: P = C(70, 8) + sage: Q = C(17, 17) + sage: P + Q # this doesn't work... + Traceback (most recent call last): + ... + TypeError: unsupported operand parent(s) for +: ... + sage: f(g(P) + g(Q)) # ...but this does + (107 : 168 : 1) + + Using the fact that the Weil pairing satisfies + `e(\psi(P),\psi(Q)) = e(P,Q)^{\deg\psi}`, + even pairings can be emulated in this way + (note that isomorphisms have degree `1`):: + + sage: F. = GF(257^2) + sage: C_ = C.change_ring(F) + sage: g_ = g.change_ring(F) + sage: g_(P).order() + 12 + sage: T = C_(-7*z2-57, 31*z2-52, 1) + sage: g_(T).order() + 12 + sage: g_(P).weil_pairing(g_(T), 12) + 15*z2 + 204 + + Another alternative is to simply extend the base field enough + for the curve to have an untwisted Montgomery model:: + + sage: C_ = E.change_ring(F).montgomery_model(); C_ + Elliptic Curve defined by y^2 = x^3 + 249*x^2 + x over Finite Field in z2 of size 257^2 + sage: h = C.defining_polynomial().change_ring(F); h + -x^3 + 8*x^2*z - 127*y^2*z - x*z^2 + sage: C_.is_isomorphic(EllipticCurve_from_cubic(h).codomain()) + True + + .. SEEALSO:: + + The inverse conversion --- + computing a Weierstrass model for a given Montgomery curve --- + can be performed using + :func:`~sage.schemes.elliptic_curves.constructor.EllipticCurve_from_cubic`. + + ALGORITHM: [CS2018]_, §2.4 + + REFERENCES: + + - Original publication: [Mont1987]_, §10.3.1 + - More recent survey article: [CS2018]_ + """ + Ew = self.short_weierstrass_model() + _,_,_, a,b = Ew.a_invariants() + + R = self.base_ring() + P = PolynomialRing(R, 'v') + + sols = [] + for r in P([b, a, 0, 1]).roots(multiplicities=False): + for s in P([3*r**2 + a, 0, -1]).roots(multiplicities=False): + sols.append((r,s)) + + if not sols: + raise ValueError(f'{self} has no Montgomery model') + + # square s allows us to take B=1 + r,s = max(sols, key=lambda t: t[1].is_square()) + + A = 3 * r / s + if s.is_square(): + B = R.one() + else: + B = 1/s + + if not twisted: + if B != 1: + raise ValueError(f'{self} has no untwisted Montgomery model') + from sage.schemes.elliptic_curves.constructor import EllipticCurve + E = EllipticCurve([0, A, 0, 1, 0]) + if morphism: + return E, self.isomorphism_to(E) + return E + + P2, (x,y,z) = self.ambient_space().objgens() + f = B*y**2*z - x * (x * (x + A*z) + z**2) + C = plane_curve.ProjectivePlaneCurve(P2, f) + + if not morphism: + return C + + t = 1 / (B*s).sqrt() + iso_maps = (x - r*z, t*y , s*z) + inv_maps = (x*s + r*z, s*y/t, z) + + w = self.isomorphism_to(Ew) + wmap, winv = w.rational_maps(), (~w).rational_maps() + wmap, winv = (tuple(f(x,y) for f in fs) + (z,) for fs in (wmap, winv)) + + iso = [f(*wmap) for f in iso_maps] + inv = [f(*inv_maps) for f in winv] + + from sage.schemes.elliptic_curves.weierstrass_transform \ + import WeierstrassTransformationWithInverse as WTI + iso = WTI(self, C, iso, 1, inv, s**-3) + return C, iso + + # Plotting def plot(self, xmin=None, xmax=None, components='both', **args): From adab07b6807cb3a06f8c2a2f6914e18f236827ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 14 Apr 2022 21:57:31 +0200 Subject: [PATCH 144/529] adjust error messages in arith/ --- src/sage/arith/misc.py | 18 +++++++++--------- src/sage/arith/multi_modular.pyx | 4 ++-- src/sage/arith/srange.pyx | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/sage/arith/misc.py b/src/sage/arith/misc.py index 9966d0b8571..0926e20b590 100644 --- a/src/sage/arith/misc.py +++ b/src/sage/arith/misc.py @@ -1407,7 +1407,7 @@ def random_prime(n, proof=None, lbound=2): else: smallest_prime = ZZ(lbound-1).next_probable_prime() if smallest_prime > n: - raise ValueError("There are no primes between %s and %s (inclusive)" % (lbound, n)) + raise ValueError("there are no primes between %s and %s (inclusive)" % (lbound, n)) if proof: prime_test = is_prime @@ -2050,7 +2050,7 @@ def xkcd(n=""): data = f.read() except HTTPError as error: if error.getcode() == 400: # this error occurs when asking for a non valid comic number - raise RuntimeError("Could not obtain comic data from {}. Maybe you should enable time travel!".format(url)) + raise RuntimeError("could not obtain comic data from {}".format(url)) except URLError: pass @@ -2196,7 +2196,7 @@ def power_mod(a, n, m): mpz(285) """ if m == 0: - raise ZeroDivisionError("modulus must be nonzero.") + raise ZeroDivisionError("modulus must be nonzero") if m == 1: return 0 if n < 0: @@ -2204,7 +2204,7 @@ def power_mod(a, n, m): return power_mod(ainv, -n, m) if n == 0: if a == 0: - raise ArithmeticError("0^0 is undefined.") + raise ArithmeticError("0^0 is undefined") return 1 apow = a % m @@ -3201,7 +3201,7 @@ def crt(a, b, m=None, n=None): g, alpha, beta = XGCD(m, n) q, r = f(g) if r != 0: - raise ValueError("No solution to crt problem since gcd(%s,%s) does not divide %s-%s" % (m, n, a, b)) + raise ValueError("no solution to crt problem since gcd(%s,%s) does not divide %s-%s" % (m, n, a, b)) from sage.arith.functions import lcm x = a + q*alpha*py_scalar_to_element(m) @@ -3278,9 +3278,9 @@ def CRT_list(v, moduli): 23 """ if not isinstance(v, list) or not isinstance(moduli, list): - raise ValueError("Arguments to CRT_list should be lists") + raise ValueError("arguments to CRT_list should be lists") if len(v) != len(moduli): - raise ValueError("Arguments to CRT_list should be lists of the same length") + raise ValueError("arguments to CRT_list should be lists of the same length") if not v: return ZZ.zero() if len(v) == 1: @@ -4611,10 +4611,10 @@ def hilbert_symbol(a, b, p, algorithm="pari"): ans_pari = hilbert_symbol(a,b,p,algorithm='pari') ans_direct = hilbert_symbol(a,b,p,algorithm='direct') if ans_pari != ans_direct: - raise RuntimeError("There is a bug in hilbert_symbol; two ways of computing the Hilbert symbol (%s,%s)_%s disagree" % (a,b,p)) + raise RuntimeError("there is a bug in hilbert_symbol; two ways of computing the Hilbert symbol (%s,%s)_%s disagree" % (a,b,p)) return ans_pari else: - raise ValueError("Algorithm %s not defined" % algorithm) + raise ValueError(f"algorithm {algorithm} not defined") def hilbert_conductor(a, b): diff --git a/src/sage/arith/multi_modular.pyx b/src/sage/arith/multi_modular.pyx index a65949fdd4d..88c9406cdc2 100644 --- a/src/sage/arith/multi_modular.pyx +++ b/src/sage/arith/multi_modular.pyx @@ -197,7 +197,7 @@ cdef class MultiModularBasis_base(object): cdef mod_int p while True: if len(known_primes) >= self._num_primes: - raise RuntimeError("there are not enough primes in the interval [%s, %s] to complete this multimodular computation"%(self._l_bound, self._u_bound)) + raise RuntimeError("there are not enough primes in the interval [%s, %s] to complete this multimodular computation" % (self._l_bound, self._u_bound)) p = random_prime(self._u_bound, lbound =self._l_bound) if p not in known_primes: return p @@ -219,7 +219,7 @@ cdef class MultiModularBasis_base(object): if isinstance(plist, GeneratorType): plist = list(plist) elif not isinstance(plist, (tuple, list)): - raise TypeError("plist should be a list, tuple or a generator, got: %s"%(str(type(plist)))) + raise TypeError("plist should be a list, tuple or a generator, got: %s" % (str(type(plist)))) cdef Py_ssize_t len_plist = len(plist) diff --git a/src/sage/arith/srange.pyx b/src/sage/arith/srange.pyx index 1603b87ca68..041d96996d8 100644 --- a/src/sage/arith/srange.pyx +++ b/src/sage/arith/srange.pyx @@ -543,7 +543,7 @@ def ellipsis_range(*args, step=None): skip = False elif args[i] is Ellipsis: if len(args) == i+1: - raise IndexError("Ellipsis range must have an endpoint, use (n..) for infinite sequence.") + raise IndexError("ellipsis range must have an endpoint, use (n..) for infinite sequence") start, end = args[i-1], args[i+1] if i < 2 or args[i-2] is not Ellipsis: L.pop() From 7a5e122acb3fa71017044d1dcda154120e078b8b Mon Sep 17 00:00:00 2001 From: dcoudert Date: Thu, 14 Apr 2022 22:32:26 +0200 Subject: [PATCH 145/529] trac #33670: fix typo --- src/sage/graphs/generators/families.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/graphs/generators/families.py b/src/sage/graphs/generators/families.py index a779aca2420..4e8ad05527b 100644 --- a/src/sage/graphs/generators/families.py +++ b/src/sage/graphs/generators/families.py @@ -3473,7 +3473,7 @@ def nauty_gentreeg(options="", debug=False): ... StopIteration - The number of trees on the first few vertex counts. This aggrees with + The number of trees on the first few vertex counts. This agrees with :oeis:`A000055`:: sage: [len(list(graphs.nauty_gentreeg(str(i)))) for i in range(1, 15)] From 8f98f49951932a1decdc3d014802a37f9c371b1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 15 Apr 2022 08:46:16 +0200 Subject: [PATCH 146/529] fix doctests --- src/sage/arith/misc.py | 21 +++++++++---------- .../numbertheory_doctest.py | 2 +- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/sage/arith/misc.py b/src/sage/arith/misc.py index 0926e20b590..0cd0684994d 100644 --- a/src/sage/arith/misc.py +++ b/src/sage/arith/misc.py @@ -1374,8 +1374,7 @@ def random_prime(n, proof=None, lbound=2): sage: random_prime(126, lbound=114) Traceback (most recent call last): ... - ValueError: There are no primes between 114 and 126 (inclusive) - + ValueError: there are no primes between 114 and 126 (inclusive) AUTHORS: @@ -2170,7 +2169,7 @@ def power_mod(a, n, m): sage: power_mod(0,0,5) Traceback (most recent call last): ... - ArithmeticError: 0^0 is undefined. + ArithmeticError: 0^0 is undefined sage: power_mod(2,390,391) 285 sage: power_mod(2,-1,7) @@ -2184,7 +2183,7 @@ def power_mod(a, n, m): sage: power_mod(11,1,0) Traceback (most recent call last): ... - ZeroDivisionError: modulus must be nonzero. + ZeroDivisionError: modulus must be nonzero Tests with numpy and gmpy2 numbers:: @@ -3160,7 +3159,7 @@ def crt(a, b, m=None, n=None): sage: crt(4,6,8,12) Traceback (most recent call last): ... - ValueError: No solution to crt problem since gcd(8,12) does not divide 4-6 + ValueError: no solution to crt problem since gcd(8,12) does not divide 4-6 sage: x = polygen(QQ) sage: crt(2,3,x-1,x+1) @@ -3170,7 +3169,7 @@ def crt(a, b, m=None, n=None): sage: crt(2,x,x^2-1,x^3-1) Traceback (most recent call last): ... - ValueError: No solution to crt problem since gcd(x^2 - 1,x^3 - 1) does not divide 2-x + ValueError: no solution to crt problem since gcd(x^2 - 1,x^3 - 1) does not divide 2-x sage: crt(int(2), int(3), int(7), int(11)) 58 @@ -3240,18 +3239,18 @@ def CRT_list(v, moduli): sage: CRT_list([32,2,1],[60,90,150]) Traceback (most recent call last): ... - ValueError: No solution to crt problem since gcd(180,150) does not divide 92-1 + ValueError: no solution to crt problem since gcd(180,150) does not divide 92-1 The arguments must be lists:: sage: CRT_list([1,2,3],"not a list") Traceback (most recent call last): ... - ValueError: Arguments to CRT_list should be lists + ValueError: arguments to CRT_list should be lists sage: CRT_list("not a list",[2,3]) Traceback (most recent call last): ... - ValueError: Arguments to CRT_list should be lists + ValueError: arguments to CRT_list should be lists The list of moduli must have the same length as the list of elements:: @@ -3260,11 +3259,11 @@ def CRT_list(v, moduli): sage: CRT_list([1,2,3],[2,3]) Traceback (most recent call last): ... - ValueError: Arguments to CRT_list should be lists of the same length + ValueError: arguments to CRT_list should be lists of the same length sage: CRT_list([1,2,3],[2,3,5,7]) Traceback (most recent call last): ... - ValueError: Arguments to CRT_list should be lists of the same length + ValueError: arguments to CRT_list should be lists of the same length TESTS:: diff --git a/src/sage/tests/books/computational-mathematics-with-sagemath/numbertheory_doctest.py b/src/sage/tests/books/computational-mathematics-with-sagemath/numbertheory_doctest.py index 1c5f363d103..8a1bed213bc 100644 --- a/src/sage/tests/books/computational-mathematics-with-sagemath/numbertheory_doctest.py +++ b/src/sage/tests/books/computational-mathematics-with-sagemath/numbertheory_doctest.py @@ -139,7 +139,7 @@ sage: crt(15,2,30,4) Traceback (most recent call last): ... - ValueError: No solution to crt problem since gcd(30,4) does not divide 15-2 + ValueError: no solution to crt problem since gcd(30,4) does not divide 15-2 Sage example in ./numbertheory.tex, line 1008:: From 1264c3fbe38569a82333a33779af77651f938c96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 15 Apr 2022 11:52:11 +0200 Subject: [PATCH 147/529] clean group_semidirect_product.py (pep8 and doc) --- src/sage/groups/group_semidirect_product.py | 87 ++++++++++----------- 1 file changed, 42 insertions(+), 45 deletions(-) diff --git a/src/sage/groups/group_semidirect_product.py b/src/sage/groups/group_semidirect_product.py index bb736a9b3db..adaed8baa7e 100644 --- a/src/sage/groups/group_semidirect_product.py +++ b/src/sage/groups/group_semidirect_product.py @@ -5,20 +5,21 @@ - Mark Shimozono (2013) initial version """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2013 Mark Shimozono # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.categories.commutative_additive_groups import CommutativeAdditiveGroups from sage.categories.groups import Groups from sage.sets.cartesian_product import CartesianProduct from sage.misc.cachefunc import cached_method + class GroupSemidirectProductElement(CartesianProduct.Element): r""" Element class for :class:`GroupSemidirectProduct`. @@ -35,11 +36,10 @@ def _repr_(self): sage: GroupSemidirectProduct(WeylGroup(['A',2],prefix="s"), WeylGroup(['A',3],prefix="t"),twist) # indirect doctest Semidirect product of Weyl Group of type ['A', 2] (as a matrix group acting on the ambient space) acting on Weyl Group of type ['A', 3] (as a matrix group acting on the ambient space) """ - def wrapper(prefix, s): if prefix is None: return s - return "%s[%s]"%(prefix,s) + return "%s[%s]" % (prefix, s) par = self.parent() @@ -48,7 +48,7 @@ def wrapper(prefix, s): gstr = wrapper(par._prefix0, repr(g)) hstr = wrapper(par._prefix1, repr(h)) if par._print_tuple: - return "(%s, %s)"%(gstr,hstr) + return "(%s, %s)" % (gstr, hstr) if self == par.one(): return "1" @@ -75,17 +75,16 @@ def inverse(self): s1*s2 * t[2*alpha[1] + 2*alpha[2]] sage: g.inverse() s2*s1 * t[2*alpha[1]] - """ par = self.parent() g = self.cartesian_projection(0) h = self.cartesian_projection(1) if par.act_to_right(): - return self.__class__(par,(~g, par._twist(g,~h))) + return self.__class__(par, (~g, par._twist(g, ~h))) else: hi = ~h - return self.__class__(par,(par._twist(hi,~g),hi)) + return self.__class__(par, (par._twist(hi, ~g), hi)) __invert__ = inverse @@ -121,8 +120,8 @@ def to_opposite(self): g = self.cartesian_projection(0) h = self.cartesian_projection(1) if par.act_to_right(): - return Gop((par._twist(g,h),g)) - return Gop((h,par._twist(~h,g))) + return Gop((par._twist(g, h), g)) + return Gop((h, par._twist(~h, g))) class GroupSemidirectProduct(CartesianProduct): @@ -132,11 +131,11 @@ class GroupSemidirectProduct(CartesianProduct): INPUT: - ``G`` and ``H`` -- multiplicative groups - - ``twist`` -- (default: None) a function defining a homomorphism (see below) - - ``act_to_right`` -- True or False (default: True) - - ``prefix0`` -- (default: None) optional string - - ``prefix1`` -- (default: None) optional string - - ``print_tuple`` -- True or False (default: False) + - ``twist`` -- (default: ``None``) a function defining a homomorphism (see below) + - ``act_to_right`` -- ``True`` or ``False`` (default: ``True``) + - ``prefix0`` -- (default: ``None``) optional string + - ``prefix1`` -- (default: ``None``) optional string + - ``print_tuple`` -- ``True`` or ``False`` (default: ``False``) - ``category`` -- A category (default: Groups()) A semidirect product of groups `G` and `H` is a group structure on the Cartesian product `G \times H` @@ -144,23 +143,23 @@ class GroupSemidirectProduct(CartesianProduct): either `1_G \times H` or `G \times 1_H` is a normal subgroup. In the former case the group is denoted `G \ltimes H` and in the latter, `G \rtimes H`. - If ``act_to_right`` is True, this indicates the group `G \ltimes H` in which `G` acts on `H` by - automorphisms. In this case there is a + If ``act_to_right`` is ``True``, this indicates the group `G \ltimes H` + in which `G` acts on `H` by automorphisms. In this case there is a group homomorphism `\phi \in \mathrm{Hom}(G, \mathrm{Aut}(H))` such that .. MATH:: g h g^{-1} = \phi(g)(h). - The homomorphism `\phi` is specified by the input ``twist``, which syntactically is the function `G\times H\to H` - defined by + The homomorphism `\phi` is specified by the input ``twist``, which + syntactically is the function `G\times H\to H` defined by .. MATH:: twist(g,h) = \phi(g)(h). The product on `G \ltimes H` is defined by - + .. MATH:: \begin{aligned} @@ -169,7 +168,7 @@ class GroupSemidirectProduct(CartesianProduct): &= (g_1g_2, twist(g_2^{-1}, h_1) h_2) \end{aligned} - If ``act_to_right`` is False, the group `G \rtimes H` is specified by a homomorphism `\psi\in \mathrm{Hom}(H,\mathrm{Aut}(G))` + If ``act_to_right`` is ``False``, the group `G \rtimes H` is specified by a homomorphism `\psi\in \mathrm{Hom}(H,\mathrm{Aut}(G))` such that .. MATH:: @@ -192,9 +191,10 @@ class GroupSemidirectProduct(CartesianProduct): &= (g_1 twist(h_1,g_2), h_1 h_2) \end{aligned} - If ``prefix0`` (resp. ``prefixl``) is not None then it is used as a wrapper for - printing elements of ``G`` (resp. ``H``). If ``print_tuple`` is True then elements are printed - in the style `(g,h)` and otherwise in the style `g * h`. + If ``prefix0`` (resp. ``prefixl``) is not ``None`` then it is used + as a wrapper for printing elements of ``G`` (resp. ``H``). If + ``print_tuple`` is ``True`` then elements are printed in the style + `(g,h)` and otherwise in the style `g * h`. EXAMPLES:: @@ -228,9 +228,10 @@ class GroupSemidirectProduct(CartesianProduct): - Twofold Direct product as a special case of semidirect product """ - def __init__(self, G, H, twist = None, act_to_right = True, prefix0 = None, prefix1 = None, print_tuple = False, category = Groups()): + def __init__(self, G, H, twist=None, act_to_right=True, prefix0=None, + prefix1=None, print_tuple=False, category=Groups()): r""" - + EXAMPLES:: sage: def twist(x,y): @@ -240,17 +241,17 @@ def __init__(self, G, H, twist = None, act_to_right = True, prefix0 = None, pref sage: G = GroupSemidirectProduct(WeylGroup(['A',2],prefix="s"), WeylGroup(['A',3],prefix="t"),twist) sage: TestSuite(G).run() - The ``__main__`` business is a trick to pass the picking test. - + The ``__main__`` business is a trick to pass the pickling test. """ self._act_to_right = act_to_right + def check_implemented_group(x): if x in Groups(): return error = "The semidirect product construction for groups is implemented only for multiplicative groups" if x in CommutativeAdditiveGroups(): - error = error + ". Please change the commutative additive group %s into a multiplicative group using the functor sage.groups.group_exp.GroupExp"%x + error = error + ". Please change the commutative additive group %s into a multiplicative group using the functor sage.groups.group_exp.GroupExp" % x raise TypeError(error) check_implemented_group(G) @@ -278,7 +279,6 @@ def act_to_right(self): ....: return y sage: GroupSemidirectProduct(WeylGroup(['A',2],prefix="s"), WeylGroup(['A',3],prefix="t"),twist).act_to_right() True - """ return self._act_to_right @@ -310,7 +310,6 @@ def _element_constructor_(self, x): sage: __main__.twist = twist sage: g = GroupSemidirectProduct(WeylGroup(['A',2],prefix="s"), WeylGroup(['A',3],prefix="t"),twist).an_element() sage: TestSuite(g).run() - """ def type_error(): raise TypeError("%s cannot be converted into an element of %s" % (x, self)) @@ -328,8 +327,7 @@ def type_error(): h = x.cartesian_projection(1) gg = self.cartesian_factors()[0](g) hh = self.cartesian_factors()[1](h) -# return self._cartesian_product_of_elements((gg,hh)) - return self.element_class(self,(gg,hh)) + return self.element_class(self, (gg, hh)) @cached_method def one(self): @@ -350,9 +348,9 @@ def one(self): [0 1] sage: one.cartesian_projection(1) (0, 0) - """ - return self((self.cartesian_factors()[0].one(), self.cartesian_factors()[1].one())) + return self((self.cartesian_factors()[0].one(), + self.cartesian_factors()[1].one())) def group_generators(self): r""" @@ -366,7 +364,6 @@ def group_generators(self): sage: EZ = GroupExp()(ZZ) sage: GroupSemidirectProduct(EZ,EZ,twist,print_tuple=True).group_generators() ((1, 0), (0, 1)) - """ def has_gens(G): if not hasattr(G, 'group_generators'): @@ -378,8 +375,9 @@ def has_gens(G): if g0 is not False: g1 = has_gens(factors[1]) if g1 is not False: - return tuple([self((x,factors[1].one())) for x in g0] + [self((factors[0].one(),x)) for x in g1]) - raise NotImplementedError("One of the factors does not implement 'group_generators'") + return tuple([self((x, factors[1].one())) for x in g0] + + [self((factors[0].one(), x)) for x in g1]) + raise NotImplementedError("one of the factors does not implement 'group_generators'") def product(self, x, y): r""" @@ -411,11 +409,11 @@ def product(self, x, y): yh = y.cartesian_projection(1) if self.act_to_right(): g = xg * yg - h = self._twist(~yg,xh) * yh + h = self._twist(~yg, xh) * yh else: h = xh * yh - g = xg * self._twist(xh,yg) - return self((g,h)) + g = xg * self._twist(xh, yg) + return self((g, h)) @cached_method def opposite_semidirect_product(self): @@ -439,9 +437,8 @@ def opposite_semidirect_product(self): [1 0] sage: hop in Hop True - """ - return GroupSemidirectProduct(self.cartesian_factors()[1], self.cartesian_factors()[0], twist=self._twist, act_to_right = not self.act_to_right(), prefix0 = self._prefix1, prefix1 = self._prefix0, print_tuple = self._print_tuple, category=self._category) + return GroupSemidirectProduct(self.cartesian_factors()[1], self.cartesian_factors()[0], twist=self._twist, act_to_right=not self.act_to_right(), prefix0=self._prefix1, prefix1=self._prefix0, print_tuple=self._print_tuple, category=self._category) def construction(self): r""" @@ -455,8 +452,8 @@ def construction(self): ....: return y sage: H = GroupSemidirectProduct(WeylGroup(['A',2],prefix="s"), WeylGroup(['A',3],prefix="t"), twist) sage: H.construction() - """ return None + GroupSemidirectProduct.Element = GroupSemidirectProductElement From 73799f05ec3b6bab40d28e1b868e0e89533b3db6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 15 Apr 2022 13:01:16 +0200 Subject: [PATCH 148/529] various details in pyx files in combinat --- src/sage/combinat/crystals/letters.pyx | 9 +++++---- src/sage/combinat/crystals/pbw_datum.pyx | 5 ++--- src/sage/combinat/crystals/spins.pyx | 5 ++--- src/sage/combinat/crystals/tensor_product_element.pyx | 5 ++--- src/sage/combinat/degree_sequences.pyx | 1 - src/sage/combinat/fast_vector_partitions.pyx | 1 - src/sage/combinat/integer_lists/base.pyx | 4 ++-- src/sage/combinat/integer_lists/invlex.pyx | 3 +-- src/sage/combinat/partitions.pyx | 1 - src/sage/combinat/permutation_cython.pyx | 1 - .../combinat/rigged_configurations/rigged_partition.pyx | 9 ++++----- src/sage/combinat/root_system/braid_orbit.pyx | 2 +- src/sage/combinat/root_system/reflection_group_c.pyx | 6 +++--- src/sage/combinat/subword_complex_c.pyx | 6 +++--- src/sage/combinat/words/word_datatypes.pyx | 1 - 15 files changed, 25 insertions(+), 34 deletions(-) diff --git a/src/sage/combinat/crystals/letters.pyx b/src/sage/combinat/crystals/letters.pyx index 67a7edb7dac..537abc2e6a3 100644 --- a/src/sage/combinat/crystals/letters.pyx +++ b/src/sage/combinat/crystals/letters.pyx @@ -509,8 +509,9 @@ cdef class Letter(Element): return self.value == x.value or x._parent.lt_elements(x, self) return False + cdef class EmptyLetter(Element): - """ + r""" The affine letter `\emptyset` thought of as a classical crystal letter in classical type `B_n` and `C_n`. @@ -558,7 +559,7 @@ cdef class EmptyLetter(Element): return 'E' def _latex_(self): - """ + r""" Return a latex representation of ``self``. EXAMPLES:: @@ -2492,8 +2493,9 @@ cdef class BKKLetter(Letter): return -ret return ret + class CrystalOfBKKLetters(ClassicalCrystalOfLetters): - """ + r""" Crystal of letters for Benkart-Kang-Kashiwara supercrystals. This implements the `\mathfrak{gl}(m|n)` crystal of @@ -3046,4 +3048,3 @@ class ClassicalCrystalOfLettersWrapped(ClassicalCrystalOfLetters): False """ return {elt._to_tuple(): elt for elt in self} - diff --git a/src/sage/combinat/crystals/pbw_datum.pyx b/src/sage/combinat/crystals/pbw_datum.pyx index e06a856e7a6..55dfd49a0ac 100644 --- a/src/sage/combinat/crystals/pbw_datum.pyx +++ b/src/sage/combinat/crystals/pbw_datum.pyx @@ -477,8 +477,7 @@ cpdef list enhance_braid_move_chain(braid_move_chain, cartan_type): last = k + 1 break - cartan_sub_matrix = (cartan_matrix[i,j], cartan_matrix[j,i]) - output_list.append( ((first, last), cartan_sub_matrix) ) + cartan_sub_matrix = (cartan_matrix[i, j], cartan_matrix[j, i]) + output_list.append(((first, last), cartan_sub_matrix)) previous_word = current_word return output_list - diff --git a/src/sage/combinat/crystals/spins.pyx b/src/sage/combinat/crystals/spins.pyx index 1417a728502..4e52064f12a 100644 --- a/src/sage/combinat/crystals/spins.pyx +++ b/src/sage/combinat/crystals/spins.pyx @@ -748,6 +748,5 @@ cdef class Spin_crystal_type_D_element(Spin): if i < 1 or i > self._n: raise ValueError("i is not in the index set") if i == self._n: - return not self._value[i-1] and not self._value[i-2] - return self._value[i] and not self._value[i-1] - + return not self._value[i - 1] and not self._value[i - 2] + return self._value[i] and not self._value[i - 1] diff --git a/src/sage/combinat/crystals/tensor_product_element.pyx b/src/sage/combinat/crystals/tensor_product_element.pyx index d1028554e6e..98083ecc9e4 100644 --- a/src/sage/combinat/crystals/tensor_product_element.pyx +++ b/src/sage/combinat/crystals/tensor_product_element.pyx @@ -144,8 +144,8 @@ cdef class TensorProductOfCrystalsElement(ImmutableListWithParent): """ from sage.misc.latex import latex if self._parent.options.convention == "Kashiwara": - return ' \otimes '.join(latex(c) for c in reversed(self)) - return ' \otimes '.join(latex(c) for c in self) + return r' \otimes '.join(latex(c) for c in reversed(self)) + return r' \otimes '.join(latex(c) for c in self) def _ascii_art_(self): """ @@ -1876,4 +1876,3 @@ cdef Py_ssize_t count_leading(list row, letter): # for unpickling from sage.misc.persist import register_unpickle_override register_unpickle_override('sage.combinat.crystals.tensor_product', 'ImmutableListWithParent', ImmutableListWithParent) - diff --git a/src/sage/combinat/degree_sequences.pyx b/src/sage/combinat/degree_sequences.pyx index b8dbf876e3c..ed750198dc7 100644 --- a/src/sage/combinat/degree_sequences.pyx +++ b/src/sage/combinat/degree_sequences.pyx @@ -587,4 +587,3 @@ cdef void enum(int k, int M): seq[i] = seq[i+1] sig_off() - diff --git a/src/sage/combinat/fast_vector_partitions.pyx b/src/sage/combinat/fast_vector_partitions.pyx index ca855ac2362..d25a1d1d445 100644 --- a/src/sage/combinat/fast_vector_partitions.pyx +++ b/src/sage/combinat/fast_vector_partitions.pyx @@ -343,4 +343,3 @@ def fast_vector_partitions(v, min_vals=None): if len(v) != len(min_vals): raise ValueError("the length of v and min_vals must be equal") return recursive_vector_partitions(list(v), list(min_vals)) - diff --git a/src/sage/combinat/integer_lists/base.pyx b/src/sage/combinat/integer_lists/base.pyx index cb6f65d30aa..bfdfc5b7d7e 100644 --- a/src/sage/combinat/integer_lists/base.pyx +++ b/src/sage/combinat/integer_lists/base.pyx @@ -269,7 +269,7 @@ cdef class IntegerListsBackend(): cdef class Envelope(): - """ + r""" The (currently approximated) upper (lower) envelope of a function under the specified constraints. @@ -523,7 +523,7 @@ cdef class Envelope(): return self.f_limit_start def limit(self): - """ + r""" Return a bound on the limit of ``self``. OUTPUT: a nonnegative integer or `\infty` diff --git a/src/sage/combinat/integer_lists/invlex.pyx b/src/sage/combinat/integer_lists/invlex.pyx index f73014012c2..93ee9e6422c 100644 --- a/src/sage/combinat/integer_lists/invlex.pyx +++ b/src/sage/combinat/integer_lists/invlex.pyx @@ -516,7 +516,7 @@ class IntegerListsLex(IntegerLists, metaclass=ClasscallMetaclass): A variant is to specify a class for the elements. With the default element constructor, this class should take as input the parent - ``self`` and a list. + ``self`` and a list. .. WARNING:: @@ -1643,4 +1643,3 @@ class IntegerListsLexIter(builtins.object): k += 1 return False - diff --git a/src/sage/combinat/partitions.pyx b/src/sage/combinat/partitions.pyx index c528131892a..c26ccdb3ddb 100644 --- a/src/sage/combinat/partitions.pyx +++ b/src/sage/combinat/partitions.pyx @@ -177,4 +177,3 @@ def ZS1_iterator_nk(int n, int k): x[m] = t yield x[:m+1] #free(x) - diff --git a/src/sage/combinat/permutation_cython.pyx b/src/sage/combinat/permutation_cython.pyx index 62f7be60102..dca680b143b 100644 --- a/src/sage/combinat/permutation_cython.pyx +++ b/src/sage/combinat/permutation_cython.pyx @@ -414,4 +414,3 @@ cpdef list right_action_product(list S, list rp): for i in range(len(rp)+1, len(S)+1): rp.append(i) return right_action_same_n(S, rp) - diff --git a/src/sage/combinat/rigged_configurations/rigged_partition.pyx b/src/sage/combinat/rigged_configurations/rigged_partition.pyx index 1cc0d70b5c6..d5ecb7c778d 100644 --- a/src/sage/combinat/rigged_configurations/rigged_partition.pyx +++ b/src/sage/combinat/rigged_configurations/rigged_partition.pyx @@ -161,7 +161,7 @@ cdef class RiggedPartition(SageObject): \begin{array}[t]{r|c|c|l} \cline{2-3} 0 &\phantom{|}&\phantom{|}& 0 \\ \cline{2-3} -1 &\phantom{|}& \multicolumn{2 }{l}{ -1 } \\ - \cline{2-2} + \cline{2-2} \end{array} } @@ -621,7 +621,7 @@ cdef class RiggedPartitionTypeB(RiggedPartition): { \begin{array}[t]{r|c|c|l} \cline{2-3} -4 &\phantom{a}&\phantom{a}& -4 \\ - \cline{2-3} + \cline{2-3} \end{array} } sage: RiggedConfigurations.options.half_width_boxes_type_B=False @@ -629,7 +629,7 @@ cdef class RiggedPartitionTypeB(RiggedPartition): { \begin{array}[t]{r|c|c|l} \cline{2-3} -4 &\phantom{X|}&\phantom{X|}& -4 \\ - \cline{2-3} + \cline{2-3} \end{array} } sage: RiggedConfigurations.options._reset() @@ -637,7 +637,7 @@ cdef class RiggedPartitionTypeB(RiggedPartition): num_rows = len(self._list) if num_rows == 0: return "{\\emptyset}" - + from sage.combinat.rigged_configurations.rigged_configurations import RiggedConfigurations if RiggedConfigurations.options.half_width_boxes_type_B: box_str = "\\phantom{a}&" @@ -680,4 +680,3 @@ cdef class RiggedPartitionTypeB(RiggedPartition): ret_string += "\\cline{2-%s}\n\\end{array}\n}"%(1 + num_cols) return ret_string - diff --git a/src/sage/combinat/root_system/braid_orbit.pyx b/src/sage/combinat/root_system/braid_orbit.pyx index 702590a799e..f3efeb357ce 100644 --- a/src/sage/combinat/root_system/braid_orbit.pyx +++ b/src/sage/combinat/root_system/braid_orbit.pyx @@ -73,6 +73,7 @@ cpdef set BraidOrbit(list word, list rels): list_len += 1 return words + cdef inline bint pattern_match(tuple L, int i, tuple X, int l): r""" Return ``True`` if ``L[i:i+l] == X``. @@ -85,4 +86,3 @@ cdef inline bint pattern_match(tuple L, int i, tuple X, int l): if L[i+ind] != X[ind]: return False return True - diff --git a/src/sage/combinat/root_system/reflection_group_c.pyx b/src/sage/combinat/root_system/reflection_group_c.pyx index e3395a74e81..49175591edc 100644 --- a/src/sage/combinat/root_system/reflection_group_c.pyx +++ b/src/sage/combinat/root_system/reflection_group_c.pyx @@ -165,7 +165,7 @@ cdef class Iterator(): True """ # the breadth search iterator is ~2x slower as it - # uses a deque with popleft + # uses a deque with popleft if self.algorithm == "depth": if self.tracking_words: return self.iter_words_depth() @@ -457,9 +457,10 @@ cdef int first_descent_in_parabolic(PermutationGroupElement w, list parabolic, return i return -1 + cpdef PermutationGroupElement reduce_in_coset(PermutationGroupElement w, tuple S, list parabolic, int N, bint right): - """ + r""" Return the minimal length coset representative of ``w`` of the parabolic subgroup indexed by ``parabolic`` (with indices `\{0, \ldots, n\}`). @@ -610,4 +611,3 @@ cdef PermutationGroupElement _new_mul_(PermutationGroupElement left, Permutation prod.perm[i] = right.perm[left.perm[i]] return prod - diff --git a/src/sage/combinat/subword_complex_c.pyx b/src/sage/combinat/subword_complex_c.pyx index 32c15fb2247..dacff3a55e0 100644 --- a/src/sage/combinat/subword_complex_c.pyx +++ b/src/sage/combinat/subword_complex_c.pyx @@ -87,17 +87,17 @@ cpdef list _construct_facets_c(tuple Q, w, int n=-1, int pos=0, int l=-1): l = w.length() else: first = False - + if l == 0: return [list(xrange(pos, n))] elif n < l + pos: return [] - + s = Q[pos] X = _construct_facets_c(Q, w, n=n, pos=pos + 1, l=l) for f in X: f.append(pos) - + if w.has_left_descent(s): Y = _construct_facets_c(Q, w.apply_simple_reflection_left(s), n=n, pos=pos + 1, l=l - 1) diff --git a/src/sage/combinat/words/word_datatypes.pyx b/src/sage/combinat/words/word_datatypes.pyx index 547eecea6f3..98d0df2616c 100644 --- a/src/sage/combinat/words/word_datatypes.pyx +++ b/src/sage/combinat/words/word_datatypes.pyx @@ -1123,4 +1123,3 @@ cdef class WordDatatype_tuple(WordDatatype): return super(WordDatatype_tuple, self).__mul__(other) __add__ = __mul__ - From e4f814d3bc3775229d3ada62e63bb8fcb3e9f18b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Fri, 15 Apr 2022 12:59:52 -0300 Subject: [PATCH 149/529] Trac #33717: accept giac-1.9.x from the system --- build/pkgs/giac/spkg-configure.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/giac/spkg-configure.m4 b/build/pkgs/giac/spkg-configure.m4 index d229feeb5e8..8c04d25e90e 100644 --- a/build/pkgs/giac/spkg-configure.m4 +++ b/build/pkgs/giac/spkg-configure.m4 @@ -2,7 +2,7 @@ SAGE_SPKG_CONFIGURE([giac], [ SAGE_SPKG_DEPCHECK([pari], [ dnl giac does not seem to reveal its patchlevel m4_pushdef([GIAC_MIN_VERSION], [1.5.0]) - m4_pushdef([GIAC_MAX_VERSION], [1.7.999]) + m4_pushdef([GIAC_MAX_VERSION], [1.9.999]) AC_CACHE_CHECK([for giac >= ]GIAC_MIN_VERSION[, <= ]GIAC_MAX_VERSION, [ac_cv_path_GIAC], [ AC_PATH_PROGS_FEATURE_CHECK([GIAC], [giac], [ giac_version=$($ac_path_GIAC --version 2> /dev/null | tail -1) From 4d275afd7adb166cef14391855066b4971c978b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 15 Apr 2022 20:59:43 +0200 Subject: [PATCH 150/529] some tweaks in pbori --- src/sage/rings/polynomial/pbori/PyPolyBoRi.py | 7 ++-- src/sage/rings/polynomial/pbori/__init__.py | 2 +- src/sage/rings/polynomial/pbori/blocks.py | 31 ++++++++-------- src/sage/rings/polynomial/pbori/cnf.py | 18 ++++------ src/sage/rings/polynomial/pbori/frontend.py | 2 +- src/sage/rings/polynomial/pbori/gbcore.py | 35 +++++++------------ src/sage/rings/polynomial/pbori/gbrefs.py | 28 ++++++--------- src/sage/rings/polynomial/pbori/heuristics.py | 11 +++--- src/sage/rings/polynomial/pbori/interred.py | 4 +-- src/sage/rings/polynomial/pbori/ll.py | 22 +++++------- src/sage/rings/polynomial/pbori/nf.py | 27 +++++++------- src/sage/rings/polynomial/pbori/parallel.py | 6 ++-- src/sage/rings/polynomial/pbori/rank.py | 4 +-- 13 files changed, 83 insertions(+), 114 deletions(-) diff --git a/src/sage/rings/polynomial/pbori/PyPolyBoRi.py b/src/sage/rings/polynomial/pbori/PyPolyBoRi.py index e3f15d58ad6..18ca366fb85 100644 --- a/src/sage/rings/polynomial/pbori/PyPolyBoRi.py +++ b/src/sage/rings/polynomial/pbori/PyPolyBoRi.py @@ -67,8 +67,8 @@ from .pbori import (order_dict, TermOrder_from_pb_order, BooleanPolynomialRing, BooleanPolynomialVector, MonomialFactory, - PolynomialFactory, VariableFactory, add_up_polynomials, - gauss_on_polys) + PolynomialFactory, VariableFactory, add_up_polynomials) +from .pbori import gauss_on_polys as _gauss_on_polys import weakref @@ -115,9 +115,6 @@ def add_up_polynomials(polys, init): return _add_up_polynomials(polys, init) -_gauss_on_polys = gauss_on_polys - - def gauss_on_polys(l): vec = BoolePolynomialVector(l) return list(_gauss_on_polys(vec)) diff --git a/src/sage/rings/polynomial/pbori/__init__.py b/src/sage/rings/polynomial/pbori/__init__.py index 34f33571cca..f168ecd4617 100644 --- a/src/sage/rings/polynomial/pbori/__init__.py +++ b/src/sage/rings/polynomial/pbori/__init__.py @@ -29,7 +29,7 @@ http://www.ricam.oeaw.ac.at/mega2007/electronic/electronic.html """ from sage.misc.lazy_import import lazy_import -from .PyPolyBoRi import * +from .PyPolyBoRi import Ring, Polynomial, Monomial, Variable # Get all-inclusive groebner routine from .gbcore import groebner_basis diff --git a/src/sage/rings/polynomial/pbori/blocks.py b/src/sage/rings/polynomial/pbori/blocks.py index 9e189de5ce5..4115c35f832 100644 --- a/src/sage/rings/polynomial/pbori/blocks.py +++ b/src/sage/rings/polynomial/pbori/blocks.py @@ -5,7 +5,7 @@ from .PyPolyBoRi import (Ring, Polynomial, VariableFactory, Variable) -class Block(object): +class Block(): r""" The block class represents a block of variables (start_index,...,start_index+size-1), it is the preferred @@ -42,7 +42,7 @@ def register(self, start, context): context[self.var_name] = var_func -class AlternatingBlock(object): +class AlternatingBlock(): r""" The Alternating Block class is used for doing tricky variable schemes,where base names vary, e.g. @@ -62,7 +62,7 @@ def __init__(self, var_names, size_per_variable, start_index=0, for n in var_names: names.append(n + "(" + str(i) + ")") self.indices = indices - self.index2pos = dict([(v, k) for (k, v) in enumerate(indices)]) + self.index2pos = {v: k for k, v in enumerate(indices)} self.names = names def __len__(self): @@ -77,7 +77,7 @@ def __getitem__(self, i): def register(self, start, context): def gen_var_func(var_pos): - class var_factory(object): + class var_factory(): def __init__(self, ring, index2pos, size): self.ring = ring self.index2pos = index2pos @@ -119,7 +119,7 @@ def __init__(self, adder_bits, sums="s", carries="c", input1="a", self.adder_bits = adder_bits def register(self, start, context): - super(AdderBlock, self).register(start, context) + super().register(start, context) a = context[self.input1] b = context[self.input2] self.s = shift(context[self.sums], self.start_index) @@ -149,7 +149,7 @@ def implement(self, equations): equations.append(self.c(i) + self.carries_polys[i]) -class HigherOrderBlock(object): +class HigherOrderBlock(): r""" HigherOrderBlocks are multidimensional blocks of variables. @@ -175,7 +175,7 @@ def __init__(self, var_name, size_tuple, start_index_tuple=None, if reverse: cart.reverse() self.cart = cart - self.cart2index = dict([(v, k) for (k, v) in enumerate(cart)]) + self.cart2index = {v: k for k, v in enumerate(cart)} self.var_name = var_name self.names = [var_name + str(c) for c in cart] @@ -195,7 +195,7 @@ def var_func(*indices): context[self.var_name] = var_func -class InOutBlock(object): +class InOutBlock(): def __init__(self, out_size, in_size, output="out", input="in", in_start_index=0, out_start_index=0, out_reverse=False, in_reverse=False): @@ -211,10 +211,9 @@ def __iter__(self): return chain(self.output, self.input) def __getitem__(self, i): - if (i < len(self.output)): + if i < len(self.output): return self.output[i] - else: - return self.input[i - len(self.output)] + return self.input[i - len(self.output)] def __len__(self): return len(self.output) + len(self.input) @@ -227,7 +226,7 @@ def register(self, start, context): self.in_vars = shift(context[self.input.var_name], self.in_start_index) -class MultiBlock(object): +class MultiBlock(): def __init__(self, sizes=None, var_names=["v"], start_indices=[], reverses=None): if reverses is None: @@ -263,11 +262,11 @@ def register(self, start, context): start_indices[idx]) for idx in range(len(self.blocks))] -class PrefixedDictProxy(object): +class PrefixedDictProxy(): """docstring for PrefixedDictProxy""" def __init__(self, wrapped, prefix): - super(PrefixedDictProxy, self).__init__() + super().__init__() self.wrapped = wrapped self.prefix = prefix @@ -282,7 +281,7 @@ def __setitem__(self, k, v): self.wrapped[self.prefix + k] = v -class MacroBlock(object): +class MacroBlock(): def __init__(self, prefix): self.prefix = prefix @@ -328,7 +327,7 @@ def implement(self, equations): equations += self.connections -class IfThen(object): +class IfThen(): def __init__(self, ifpart, thenpart, supposed_to_be_valid=True): self.ifpart = [Polynomial(p) for p in ifpart] self.thenpart = [Polynomial(p) for p in thenpart] diff --git a/src/sage/rings/polynomial/pbori/cnf.py b/src/sage/rings/polynomial/pbori/cnf.py index 3e0c2ba78b0..9f9e670a4c9 100644 --- a/src/sage/rings/polynomial/pbori/cnf.py +++ b/src/sage/rings/polynomial/pbori/cnf.py @@ -4,7 +4,7 @@ from .statistics import used_vars_set -class CNFEncoder(object): +class CNFEncoder(): def __init__(self, r, random_seed=16): self.random_generator = Random(random_seed) self.one_set = r.one().set() @@ -31,7 +31,7 @@ def zero_blocks(self, f): variables = list(variables.variables()) zeros = f.zeros_in(space) rest = zeros - res = list() + res = [] # inefficient compared to polynomials lex_lead def choose(s): @@ -64,7 +64,7 @@ def get_val(var): if var in l_variables: return 1 return 0 - block_dict = dict([(v, get_val(v)) for v in variables]) + block_dict = {v: get_val(v) for v in variables} l = l.set() self.random_generator.shuffle(variables) @@ -208,19 +208,15 @@ def dimacs_encode_polynomial(self, p): ['x1 2 -3 0\nc g 2 x + y + z + 1'] """ if p.deg() != 1 or len(p) <= 1: - res = super(CryptoMiniSatEncoder, self).dimacs_encode_polynomial(p) + res = super().dimacs_encode_polynomial(p) else: - - if p.has_constant_part(): - invert_last = True - else: - invert_last = False + invert_last = bool(p.has_constant_part()) variables = list(p.vars_as_monomial().variables()) indices = [self.to_dimacs_index(v) for v in variables] if invert_last: indices[-1] = -indices[-1] indices.append(0) - res = ["x" + " ".join([str(v) for v in indices])] + res = ["x" + " ".join(str(v) for v in indices)] self.group_counter = self.group_counter + 1 group_comment = "\nc g %s %s" % (self.group_counter, str(p)[:30]) return [c + group_comment for c in res] @@ -242,7 +238,7 @@ def dimacs_cnf(self, polynomial_system): 'c cnf generated by PolyBoRi\np cnf 3 2\n-1 -2 -3 0\nc g 3 x*y*z\nx1 2 0\nc g 4 x + y\nc v 1 x\nc v 2 y\nc v 3 z' """ uv = list(used_vars_set(polynomial_system).variables()) - res = super(CryptoMiniSatEncoder, self).dimacs_cnf(polynomial_system) + res = super().dimacs_cnf(polynomial_system) res = res + "\n" + "\n".join(["c v %s %s" % (self.to_dimacs_index(v), v) for v in uv]) return res diff --git a/src/sage/rings/polynomial/pbori/frontend.py b/src/sage/rings/polynomial/pbori/frontend.py index 870407dada1..b0072cd5abf 100644 --- a/src/sage/rings/polynomial/pbori/frontend.py +++ b/src/sage/rings/polynomial/pbori/frontend.py @@ -40,7 +40,7 @@ def block_scheme_names(blocks): r""" Helper for Singular interface. """ - context = dict() + context = {} from .blocks import declare_block_scheme declare_block_scheme(blocks, context) diff --git a/src/sage/rings/polynomial/pbori/gbcore.py b/src/sage/rings/polynomial/pbori/gbcore.py index 6acc44db81e..5880a6811a7 100644 --- a/src/sage/rings/polynomial/pbori/gbcore.py +++ b/src/sage/rings/polynomial/pbori/gbcore.py @@ -20,7 +20,7 @@ def get_options_from_function(f): def filter_oldstyle_options(**options): - filtered = dict() + filtered = {} for key in options: newkey = key for prefix in ['use_', 'opt_allow_', 'opt_']: @@ -31,7 +31,7 @@ def filter_oldstyle_options(**options): def filter_newstyle_options(func, **options): allowed = get_options_from_function(func).keys() - filtered = dict() + filtered = {} for key in options.keys(): for prefix in ['', 'use_', 'opt_', 'opt_allow_']: if prefix + key in allowed: @@ -59,8 +59,7 @@ def ll_is_good(I): if len(lex_lead) > 0.9 * uv: if uv - len(lex_lead) > 16: return "llfirstonthefly" - else: - return "llfirst" + return "llfirst" return False @@ -153,7 +152,7 @@ def trivial_heuristic(d): return d -class HeuristicalFunction(object): +class HeuristicalFunction(): def __call__(self, *args, **kwds): complete_dict = copy(kwds) heuristic = True @@ -203,11 +202,7 @@ def wrapper(I, **kwds): groebner_basis.options[o]): option_set = False if "option_set" not in locals(): - if option in kwds: - - option_set = kwds[option] - else: - option_set = default + option_set = kwds.get(option, default) kwds = dict(((o, kwds[o]) for o in kwds if o != option)) state = None @@ -218,8 +213,8 @@ def wrapper(I, **kwds): print("preprocessing for option:", option) local_symbols = copy(locals()) - (I, state) = pre(**dict([(k, v) for (k, v) in - local_symbols.items() if k in pre_args])) + (I, state) = pre(**{k: v for (k, v) in local_symbols.items() + if k in pre_args}) I = f(I, **kwds) if option_set: if post: @@ -247,15 +242,13 @@ def wrapper(I, **kwds): def redsb_post(I, state): if not I: return [] - else: - return I.minimalize_and_tail_reduce() + return I.minimalize_and_tail_reduce() def minsb_post(I, state): if not I: return [] - else: - return I.minimalize() + return I.minimalize() def invert_all(I): @@ -453,8 +446,7 @@ def result_to_list_post(I, state): def fix_deg_bound_post(I, state): if isinstance(I, GroebnerStrategy): return I.all_generators() - else: - return I + return I def incremental_pre(I, prot, kwds): @@ -481,15 +473,14 @@ def eliminate_identical_variables_pre(I, prot): treated_linears = set() while changed: changed = False - rules = dict() + rules = {} for p in I: t = p + p.lead() if p.lead_deg() == 1: l = p.lead() if l in treated_linears: continue - else: - treated_linears.add(l) + treated_linears.add(l) if t.deg() > 0: rules.setdefault(t, []) leads = rules[t] @@ -506,7 +497,7 @@ def my_sort_key(l): ll_system.append(chosen + v) if len(ll_system) > 0: ll_encoded = ll_encode(ll_system, reduce=True) - I = set([ll_red_nf_redsb(p, ll_encoded) for p in I]) + I = set(ll_red_nf_redsb(p, ll_encoded) for p in I) return (I, ll_system) diff --git a/src/sage/rings/polynomial/pbori/gbrefs.py b/src/sage/rings/polynomial/pbori/gbrefs.py index 761cf0e700e..76e3924715d 100644 --- a/src/sage/rings/polynomial/pbori/gbrefs.py +++ b/src/sage/rings/polynomial/pbori/gbrefs.py @@ -33,9 +33,8 @@ def load_ref_raw(s): s = re.sub(r"\.", "/", s) ref_file = "ref/" + s + ".ref" - res_f = open(ref_file) - res = res_f.read() - res_f.close() + with open(ref_file) as res_f: + res = res_f.read() return res @@ -46,11 +45,9 @@ def load_ref(s, ordering="lp", blocks=SINGLE): def ordering_suffix(o, blocks=None): if o == "lp": return "" - else: - if re.match("block", o): - return "." + o + "_" + reencode_blocks(blocks) - else: - return "." + o + if re.match("block", o): + return "." + o + "_" + reencode_blocks(blocks) + return "." + o def number_of_declared_vars(data): @@ -83,9 +80,8 @@ def convert_refs(ref_file_orig): zipped.write(content) zipped.close() val = buf_out.getvalue() - out = open(ref_file_orig + ".gz.uu", "w") - uu.encode(out_file=out, in_file=StringIO(val)) - out.close() + with open(ref_file_orig + ".gz.uu", "w") as out: + uu.encode(out_file=out, in_file=StringIO(val)) def dyn_generate(content, name): @@ -117,14 +113,12 @@ def load_data(file_name, base_dir="./"): in_file = re.sub(r".py$", "", in_file) in_file = re.sub(r"\.", "/", in_file) in_file = in_file + ".py" - in_file = open(base_dir + in_file).read() + with open(base_dir + in_file) as f: + in_file = f.read() return dyn_generate(in_file, "pb_data") def load_file(file_name): - - in_file = file_name - - in_file = open(in_file).read() - + with open(file_name) as f: + in_file = f.read() return dyn_generate(in_file, "pb_data") diff --git a/src/sage/rings/polynomial/pbori/heuristics.py b/src/sage/rings/polynomial/pbori/heuristics.py index 6172b5f6845..5dcfca16f87 100644 --- a/src/sage/rings/polynomial/pbori/heuristics.py +++ b/src/sage/rings/polynomial/pbori/heuristics.py @@ -6,14 +6,13 @@ def dense_system(I): I = (p for p in I if not p.is_zero()) for p in I: d = p.deg() - if p.deg() == 1: + if d == 1: continue - else: - try: - if len(p) > 2 ** d + 5: - return True - except OverflowError: + try: + if len(p) > 2**d + 5: return True + except OverflowError: + return True return False diff --git a/src/sage/rings/polynomial/pbori/interred.py b/src/sage/rings/polynomial/pbori/interred.py index 4cc8a67f8bf..fe59be30896 100644 --- a/src/sage/rings/polynomial/pbori/interred.py +++ b/src/sage/rings/polynomial/pbori/interred.py @@ -10,7 +10,7 @@ def interred(l, completely=False): The system is interreduced: For i!=j: gi.lead() does not divide any leading term of gj. - If completely is set to True, then also terms in the + If completely is set to ``True``, then also terms in the tail are not reducible by other polynomials. """ l = [Polynomial(p) for p in l if not p == 0] @@ -29,5 +29,5 @@ def interred(l, completely=False): p = g.nf(p) if not p.is_zero(): g.add_generator(p) - l = tuple([e.p for e in g]) + l = tuple(e.p for e in g) return list(l) diff --git a/src/sage/rings/polynomial/pbori/ll.py b/src/sage/rings/polynomial/pbori/ll.py index e7d7e5e6347..b12985797a7 100644 --- a/src/sage/rings/polynomial/pbori/ll.py +++ b/src/sage/rings/polynomial/pbori/ll.py @@ -26,10 +26,10 @@ def llredsb_Cudd_style(polys): reductors = None linear_lead = sorted(polys, key=lead_index, reverse=True) - assert len(set([p.lex_lead() for p in linear_lead])) == len(polys) + assert len(set(p.lex_lead() for p in linear_lead)) == len(polys) assert not any(p.constant() for p in polys) assert len([p for p in polys if p.lex_lead_deg() == 1]) == len(polys) - assert len(set([p.navigation().value() for p in polys])) == len(polys) + assert len(set(p.navigation().value() for p in polys)) == len(polys) for p in linear_lead: reductors = combine(reductors, p, reduce=ll_red_nf_redsb) return reductors @@ -38,10 +38,10 @@ def llredsb_Cudd_style(polys): def ll_encode(polys, reduce=False, prot=False, reduce_by_linear=True): polys = [Polynomial(p) for p in polys] linear_lead = sorted(polys, key=lead_index, reverse=True) - assert len(set([p.lex_lead() for p in linear_lead])) == len(polys) + assert len(set(p.lex_lead() for p in linear_lead)) == len(polys) assert not any(p.constant() for p in polys) assert len([p for p in polys if p.lex_lead_deg() == 1]) == len(polys) - assert len(set([p.navigation().value() for p in polys])) == len(polys) + assert len(set(p.navigation().value() for p in polys)) == len(polys) if (not reduce) and reduce_by_linear: linear_polys = [p for p in polys if p.deg() == 1] if linear_polys: @@ -123,8 +123,7 @@ def llnf(p): if p.is_one(): reduced_list = [p] break - else: - reduced_list.append(p) + reduced_list.append(p) return (linear_leads, llnf, reduced_list) @@ -161,10 +160,8 @@ def var_index(v): return next(iter(Monomial(v).variables())).index() to_ring = Ring(len(sorted_vars)) - map_back_indices = dict([(i, var_index(v)) for (i, v) in enumerate( - sorted_vars)]) - map_from_indices = dict([(var_index(v), i) for (i, v) in enumerate( - sorted_vars)]) + map_back_indices = {i: var_index(v) for i, v in enumerate(sorted_vars)} + map_from_indices = {var_index(v): i for i, v in enumerate(sorted_vars)} var_names = [str(v) for v in sorted_vars] try: @@ -198,7 +195,7 @@ def llnf(p): return (llnf, opt_eliminated) -class RingMap(object): +class RingMap(): r""" Define a mapping between two rings by common variable names. @@ -241,12 +238,11 @@ def __init__(self, to_ring, from_ring): sage: mapping(x(1)+1) x(1) + 1 """ - def vars(ring): return [ring.variable(i) for i in range(ring.n_variables())] def indices(vars): - return dict([(str(v), idx) for (idx, v) in enumerate(vars)]) + return {str(v): idx for idx, v in enumerate(vars)} self.to_ring = to_ring self.from_ring = from_ring diff --git a/src/sage/rings/polynomial/pbori/nf.py b/src/sage/rings/polynomial/pbori/nf.py index 55f71b0686d..ac6e447c525 100644 --- a/src/sage/rings/polynomial/pbori/nf.py +++ b/src/sage/rings/polynomial/pbori/nf.py @@ -51,8 +51,8 @@ def build_and_print_matrices(v, strat): v.append(p2) polys_in_mat.append(p) treated = treated.union(p.set()) - m2i = dict([(v, k) for (k, v) in enumerate(list(Polynomial(BooleSet( - treated)).terms()))]) + m2i = {v: k + for k, v in enumerate(list(Polynomial(BooleSet(treated)).terms()))} polys_in_mat.sort(key=Polynomial.lead, reverse=True) polys_in_mat = [[m2i[t] for t in p.terms()] for p in polys_in_mat] @@ -129,11 +129,11 @@ def build_and_print_matrices_deg_colored(v, strat): v.append(p2) polys_in_mat.append(p) treated = treated.union(p.set()) - m2i = dict([(v, k) for (k, v) in enumerate(BooleSet(treated))]) + m2i = {v: k for k, v in enumerate(BooleSet(treated))} max_deg = max([m.deg() for m in BooleSet(treated)]) if max_deg == 0: max_deg = 1 - i2deg = dict([(m2i[m], m.deg()) for m in BooleSet(treated)]) + i2deg = {m2i[m]: m.deg() for m in BooleSet(treated)} polys_in_mat = [[m2i[t] for t in p.terms()] for p in polys_in_mat] polys_in_mat.sort(key=pkey) global mat_counter @@ -394,8 +394,7 @@ def step(strat, trace, var, val): print("!!!!!!! SOLUTION", trace) raise Exception # yield trace - else: - branch(strat, trace + [(var, val)], var - 1) + branch(strat, trace + [(var, val)], var - 1) def branch(strat, trace, var): while strat.variableHasValue(var): @@ -447,8 +446,7 @@ def step(strat, trace, proof_path, pos, val): print("!!!!!!! SOLUTION", trace) raise Exception # yield trace - else: - branch(strat, trace + [(pos, val)], proof_path, pos) + branch(strat, trace + [(pos, val)], proof_path, pos) def branch(strat, trace, proof_path, pos): @@ -485,8 +483,8 @@ def branch(strat, trace): if index < 0: uv = set(used_vars_set(strat)) - lv = set([next(iter(p.lead())).index() for p in strat if p. - lead_deg() == 1]) + lv = set(next(iter(p.lead())).index() + for p in strat if p.lead_deg() == 1) candidates = uv.difference(lv) if candidates: index = next(iter(candidates)).index() @@ -566,11 +564,10 @@ def step(strat, trace, proof_path, pos, choice): print("!!!!!!! SOLUTION", trace) raise Exception # yield trace - else: - branch(strat, trace + [(pos, choice)], proof_path, pos) - # workaround because of stack depth - # step(strat,trace+[(var,val)],var-1, 0) - # step(strat,trace+[(var,val)],var-1, 1) + branch(strat, trace + [(pos, choice)], proof_path, pos) + # workaround because of stack depth + # step(strat,trace+[(var,val)],var-1, 0) + # step(strat,trace+[(var,val)],var-1, 1) def branch(strat, trace, proof_path, pos): for i in range(len(proof_path[pos])): diff --git a/src/sage/rings/polynomial/pbori/parallel.py b/src/sage/rings/polynomial/pbori/parallel.py index bd3c4730b05..be10865dd50 100644 --- a/src/sage/rings/polynomial/pbori/parallel.py +++ b/src/sage/rings/polynomial/pbori/parallel.py @@ -183,7 +183,7 @@ def pickle_bset(self): def pickle_monom(self): - return (Monomial, ([var for var in self.variables()], )) + return (Monomial, (list(self.variables()),)) copyreg.pickle(Monomial, pickle_monom) @@ -204,7 +204,7 @@ def _decode_ring(code): try: _polybori_parallel_rings except NameError: - _polybori_parallel_rings = dict() + _polybori_parallel_rings = {} for key in [key for key in _polybori_parallel_rings if not _polybori_parallel_rings[key][0]()]: @@ -234,7 +234,7 @@ def _encode_ring(ring): try: _polybori_parallel_rings except NameError: - _polybori_parallel_rings = dict() + _polybori_parallel_rings = {} for key in [key for key in _polybori_parallel_rings if not _polybori_parallel_rings[key][0]()]: diff --git a/src/sage/rings/polynomial/pbori/rank.py b/src/sage/rings/polynomial/pbori/rank.py index 0c6c1c2f089..bf16e6220ce 100644 --- a/src/sage/rings/polynomial/pbori/rank.py +++ b/src/sage/rings/polynomial/pbori/rank.py @@ -7,8 +7,8 @@ def output_signal(p): def rank(data): - parents = dict() - res = dict() + parents = {} + res = {} for p in data: out = output_signal(p) parents.setdefault(out, []) From 94b5a61da18e8fbd9af80268140e1f3b7fb5ac2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 16 Apr 2022 11:12:33 +0200 Subject: [PATCH 151/529] better boolean statements --- src/sage/algebras/steenrod/steenrod_algebra.py | 4 ++-- .../algebras/steenrod/steenrod_algebra_bases.py | 12 ++++++------ .../algebras/steenrod/steenrod_algebra_misc.py | 6 +++--- .../algebras/steenrod/steenrod_algebra_mult.py | 2 +- src/sage/combinat/composition_tableau.py | 2 +- src/sage/combinat/sf/ns_macdonald.py | 2 +- src/sage/geometry/polyhedron/backend_ppl.py | 2 +- src/sage/graphs/graph_input.py | 5 +++-- src/sage/interfaces/latte.py | 8 ++++---- src/sage/rings/number_field/galois_group.py | 2 +- .../rings/polynomial/multi_polynomial_ideal.py | 16 ++++++++-------- 11 files changed, 31 insertions(+), 30 deletions(-) diff --git a/src/sage/algebras/steenrod/steenrod_algebra.py b/src/sage/algebras/steenrod/steenrod_algebra.py index e8920c0ef1b..f18797dc0de 100644 --- a/src/sage/algebras/steenrod/steenrod_algebra.py +++ b/src/sage/algebras/steenrod/steenrod_algebra.py @@ -500,7 +500,7 @@ def __classcall__(self, p=2, basis='milnor', **kwds): truncation_type = kwds.get('truncation_type', 'auto') generic = kwds.get('generic', 'auto') if generic == 'auto': - std_generic = False if p == 2 else True + std_generic = p != 2 else: std_generic = generic if p != 2: @@ -4149,7 +4149,7 @@ def SteenrodAlgebra(p=2, basis='milnor', generic='auto', **kwds): True """ if generic == 'auto': - generic = False if p == 2 else True + generic = p != 2 if not generic: return SteenrodAlgebra_mod_two(p=2, basis=basis, **kwds) else: diff --git a/src/sage/algebras/steenrod/steenrod_algebra_bases.py b/src/sage/algebras/steenrod/steenrod_algebra_bases.py index 65b5fc89f6a..14efe70258b 100644 --- a/src/sage/algebras/steenrod/steenrod_algebra_bases.py +++ b/src/sage/algebras/steenrod/steenrod_algebra_bases.py @@ -166,7 +166,7 @@ def convert_to_milnor_matrix(n, basis, p=2, generic='auto'): from sage.rings.finite_rings.finite_field_constructor import GF from .steenrod_algebra import SteenrodAlgebra if generic == 'auto': - generic = False if p==2 else True + generic = p != 2 if n == 0: return matrix(GF(p), 1, 1, [[1]]) milnor_base = steenrod_algebra_basis(n,'milnor',p, generic=generic) @@ -337,7 +337,7 @@ def steenrod_algebra_basis(n, basis='milnor', p=2, **kwds): except TypeError: return () - generic = kwds.get("generic", False if p==2 else True) + generic = kwds.get("generic", p != 2) basis_name = get_basis_name(basis, p, generic=generic) if basis_name.find('long') >= 0: @@ -563,7 +563,7 @@ def milnor_basis(n, p=2, **kwds): sage: len(milnor_basis(240,7, profile=((),()), truncation_type=0)) 0 """ - generic = kwds.get('generic', False if p==2 else True) + generic = kwds.get('generic', p != 2) if n == 0: if not generic: @@ -701,7 +701,7 @@ def serre_cartan_basis(n, p=2, bound=1, **kwds): sage: serre_cartan_basis(13, 3, bound=3) ((1, 3, 0),) """ - generic = kwds.get('generic', False if p==2 else True ) + generic = kwds.get('generic', p != 2) if n == 0: return ((),) @@ -1022,7 +1022,7 @@ def sorting_pair(s,t,basis): # pair used for sorting the basis elif basis.find('revz') >= 0: return (s+t,s) - generic = kwds.get('generic', False if p==2 else True ) + generic = kwds.get('generic', p != 2) if n == 0: if not generic: return ((),) @@ -1117,7 +1117,7 @@ def steenrod_basis_error_check(dim, p, **kwds): sage: steenrod_basis_error_check(80,5) # long time """ from sage.misc.verbose import verbose - generic = kwds.get('generic', False if p==2 else True ) + generic = kwds.get('generic', p != 2) if not generic: bases = ('adem','woody', 'woodz', 'wall', 'arnona', 'arnonc', diff --git a/src/sage/algebras/steenrod/steenrod_algebra_misc.py b/src/sage/algebras/steenrod/steenrod_algebra_misc.py index 2a1ec0ea80a..850081f6e67 100644 --- a/src/sage/algebras/steenrod/steenrod_algebra_misc.py +++ b/src/sage/algebras/steenrod/steenrod_algebra_misc.py @@ -128,7 +128,7 @@ def get_basis_name(basis, p, generic=None): ValueError: woody is not a recognized basis for the generic Steenrod algebra at the prime 2 """ if generic is None: - generic = False if p==2 else True + generic = p != 2 basis = basis.lower() if basis in _steenrod_milnor_basis_names: result = 'milnor' @@ -257,7 +257,7 @@ def is_valid_profile(profile, truncation_type, p=2, generic=None): """ from sage.rings.infinity import Infinity if generic is None: - generic = False if p==2 else True + generic = p != 2 if not generic: pro = list(profile) + [truncation_type]*len(profile) r = 0 @@ -465,7 +465,7 @@ def normalize_profile(profile, precision=None, truncation_type='auto', p=2, gene if truncation_type == 'infinity': truncation_type = Infinity if generic is None: - generic = False if p==2 else True + generic = p != 2 if not generic: if profile is None or profile == Infinity: # no specified profile or infinite profile: return profile diff --git a/src/sage/algebras/steenrod/steenrod_algebra_mult.py b/src/sage/algebras/steenrod/steenrod_algebra_mult.py index 2a359410217..e2c1e888b66 100644 --- a/src/sage/algebras/steenrod/steenrod_algebra_mult.py +++ b/src/sage/algebras/steenrod/steenrod_algebra_mult.py @@ -892,7 +892,7 @@ def make_mono_admissible(mono, p=2, generic=None): """ from sage.rings.finite_rings.finite_field_constructor import GF if generic is None: - generic = False if p==2 else True + generic = p != 2 F = GF(p) if len(mono) == 1: return {mono: 1} diff --git a/src/sage/combinat/composition_tableau.py b/src/sage/combinat/composition_tableau.py index b1038a61ab7..53d22a50346 100644 --- a/src/sage/combinat/composition_tableau.py +++ b/src/sage/combinat/composition_tableau.py @@ -817,7 +817,7 @@ def _rec(self, obj, state): # Get the next state new_state = self.get_next_pos(i, j) - yld = True if new_state is None else False + yld = bool(new_state is None) for k in range(1,self.max_entry +1): #We check to make sure that k does not violate the rule weak decrease in rows diff --git a/src/sage/combinat/sf/ns_macdonald.py b/src/sage/combinat/sf/ns_macdonald.py index 842cd56c32d..1013718d4b5 100644 --- a/src/sage/combinat/sf/ns_macdonald.py +++ b/src/sage/combinat/sf/ns_macdonald.py @@ -738,7 +738,7 @@ def _rec(self, obj, state): # Get the next state new_state = self.get_next_pos(i, j) - yld = True if new_state is None else False + yld = bool(new_state is None) for k in range(1, len(self._shape) + 1): # We check to make sure that k does not diff --git a/src/sage/geometry/polyhedron/backend_ppl.py b/src/sage/geometry/polyhedron/backend_ppl.py index 3ac2bb267f7..8e27c639e1a 100644 --- a/src/sage/geometry/polyhedron/backend_ppl.py +++ b/src/sage/geometry/polyhedron/backend_ppl.py @@ -61,7 +61,7 @@ def __init__(self, parent, Vrep, Hrep, ppl_polyhedron=None, mutable=False, **kwd if Hrep is not None or Vrep is not None: raise ValueError("only one of Vrep, Hrep, or ppl_polyhedron can be different from None") Element.__init__(self, parent=parent) - minimize = True if 'minimize' in kwds and kwds['minimize'] else False + minimize = bool('minimize' in kwds and kwds['minimize']) self._init_from_ppl_polyhedron(ppl_polyhedron, minimize) else: Polyhedron_mutable.__init__(self, parent, Vrep, Hrep, **kwds) diff --git a/src/sage/graphs/graph_input.py b/src/sage/graphs/graph_input.py index 52f61775e7b..82545956b36 100644 --- a/src/sage/graphs/graph_input.py +++ b/src/sage/graphs/graph_input.py @@ -420,15 +420,16 @@ def from_oriented_incidence_matrix(G, M, loops=False, multiedges=False, weighted else: positions.append((NZ[1], NZ[0])) if weighted is None: - weighted = False + weighted = False if multiedges is None: total = len(positions) multiedges = len(set(positions)) < total - G.allow_loops(True if loops else False, check=False) + G.allow_loops(bool(loops), check=False) G.allow_multiple_edges(multiedges, check=False) G.add_vertices(range(M.nrows())) G.add_edges(positions) + def from_dict_of_dicts(G, M, loops=False, multiedges=False, weighted=False, convert_empty_dict_labels_to_None=False): r""" Fill ``G`` with the data of a dictionary of dictionaries. diff --git a/src/sage/interfaces/latte.py b/src/sage/interfaces/latte.py index 391d1a4d63c..6cc592db3ee 100644 --- a/src/sage/interfaces/latte.py +++ b/src/sage/interfaces/latte.py @@ -333,22 +333,22 @@ def integrate(arg, polynomial=None, algorithm='triangulate', raw_output=False, v args = [Latte_integrate().absolute_filename()] - got_polynomial = True if polynomial is not None else False + got_polynomial = bool(polynomial is not None) if got_polynomial: args.append('--valuation=integrate') else: args.append('--valuation=volume') - if algorithm=='triangulate': + if algorithm == 'triangulate': args.append('--triangulate') - elif algorithm=='cone-decompose': + elif algorithm == 'cone-decompose': args.append('--cone-decompose') if 'redundancy_check' not in kwds: args.append('--redundancy-check=none') - for key,value in kwds.items(): + for key, value in kwds.items(): if value is None or value is False: continue diff --git a/src/sage/rings/number_field/galois_group.py b/src/sage/rings/number_field/galois_group.py index 45d6bf21d4c..23301495062 100644 --- a/src/sage/rings/number_field/galois_group.py +++ b/src/sage/rings/number_field/galois_group.py @@ -287,7 +287,7 @@ def __init__(self, number_field, algorithm='pari', names=None, gc_numbering=None # We eventually want to support relative Galois groups, which currently just create the Galois group of the absolute field deprecation(28782, "Use .absolute_field().galois_group() if you want the Galois group of the absolute field") if gc_numbering is None: - gc_numbering = False if algorithm == 'magma' else True + gc_numbering = algorithm != 'magma' # For the deprecated group() method of GaloisGroup_v1 self._type = _type super(GaloisGroup_v2, self).__init__(number_field, algorithm, names, gc_numbering) diff --git a/src/sage/rings/polynomial/multi_polynomial_ideal.py b/src/sage/rings/polynomial/multi_polynomial_ideal.py index 8006df3a989..9ab0fcc76ec 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ideal.py +++ b/src/sage/rings/polynomial/multi_polynomial_ideal.py @@ -407,9 +407,9 @@ def _groebner_basis_magma(self, deg_bound=None, prot=False, magma=magma_default) else: log_parser = None - ctx = StdOutContext(magma, silent=False if prot else True, stdout=log_parser) + ctx = StdOutContext(magma, silent=not prot, stdout=log_parser) if prot: - magma.SetVerbose('Groebner',1) + magma.SetVerbose('Groebner', 1) with ctx: if deg_bound: mgb = mself.GroebnerBasis(deg_bound) @@ -1457,18 +1457,18 @@ def _groebner_basis_singular_raw(self, algorithm="groebner", singular=singular_d else: log_parser = None - ctx = StdOutContext(singular, silent=False if prot else True, stdout=log_parser) + ctx = StdOutContext(singular, silent=not prot, stdout=log_parser) with ctx: - if algorithm=="groebner": + if algorithm == "groebner": S = obj.groebner() - elif algorithm=="std": + elif algorithm == "std": S = obj.std() - elif algorithm=="slimgb": + elif algorithm == "slimgb": S = obj.slimgb() - elif algorithm=="stdhilb": + elif algorithm == "stdhilb": S = obj.stdhilb() - elif algorithm=="stdfglm": + elif algorithm == "stdfglm": S = obj.stdfglm() else: raise TypeError("algorithm '%s' unknown"%algorithm) From 4c03af303e121d901c0a9efc995419fd5ff2524a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 16 Apr 2022 12:34:06 -0700 Subject: [PATCH 152/529] src/doc/en/developer/trac.rst: Login info for users with legacy sage-trac accounts --- src/doc/en/developer/trac.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/doc/en/developer/trac.rst b/src/doc/en/developer/trac.rst index 1c70d172599..ef6bfe8693f 100644 --- a/src/doc/en/developer/trac.rst +++ b/src/doc/en/developer/trac.rst @@ -59,6 +59,12 @@ Using your GitHub account, you can log in to: corner, and then use the button "Sign in with GitHub" and follow the prompts. +Users with legacy sage-trac accounts (account names not starting with +"gh-") should use the Login link. Do not to use GitHub login, as it +will be treated as a separate user from their original account (unless +you actively prefer to switch). + + .. _trac-bug-report: Reporting Bugs From aa5108410f38f3dd9c6556346a5bbf8e468cb736 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 18 Apr 2022 12:56:46 +0200 Subject: [PATCH 153/529] get rid of some iteritems --- .../algebras/lie_algebras/lie_algebra_element.pyx | 12 ++++++------ .../finite_dimensional_lie_algebras_with_basis.py | 4 ++-- src/sage/symbolic/relation.py | 12 ++++++------ 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/sage/algebras/lie_algebras/lie_algebra_element.pyx b/src/sage/algebras/lie_algebras/lie_algebra_element.pyx index c2d9aaaf9fe..2e48c4aa6c5 100644 --- a/src/sage/algebras/lie_algebras/lie_algebra_element.pyx +++ b/src/sage/algebras/lie_algebras/lie_algebra_element.pyx @@ -946,7 +946,7 @@ cdef class UntwistedAffineLieAlgebraElement(Element): ret = style('') mult = style(mult) tensor_symb = style(tensor_symb) - for t,g in self._t_dict.iteritems(): + for t,g in self._t_dict.items(): if ret: ret += style(' + ') if coeff == str: @@ -1260,7 +1260,7 @@ cdef class UntwistedAffineLieAlgebraElement(Element): 'd'] """ cdef dict d = {} - for t,g in self._t_dict.iteritems(): + for t,g in self._t_dict.items(): for k,c in g.monomial_coefficients(copy=False).iteritems(): d[k,t] = c if self._c_coeff: @@ -1326,7 +1326,7 @@ cdef class UntwistedAffineLieAlgebraElement(Element): cdef dict d = {} cdef UntwistedAffineLieAlgebraElement rt = (y) c = self._parent.base_ring().zero() - for tl,gl in self._t_dict.iteritems(): + for tl,gl in self._t_dict.items(): # d contribution from the left if rt._d_coeff: if tl in d: @@ -1336,7 +1336,7 @@ cdef class UntwistedAffineLieAlgebraElement(Element): if not d[tl]: del d[tl] # main bracket of the central extension - for tr,gr in rt._t_dict.iteritems(): + for tr,gr in rt._t_dict.items(): b = gl.bracket(gr) if b: if tl+tr in d: @@ -1350,7 +1350,7 @@ cdef class UntwistedAffineLieAlgebraElement(Element): # d contribution from the right if self._d_coeff: - for tr,gr in rt._t_dict.iteritems(): + for tr,gr in rt._t_dict.items(): if tr in d: d[tr] += self._d_coeff * gr * tr else: @@ -1381,7 +1381,7 @@ cdef class UntwistedAffineLieAlgebraElement(Element): sage: x.canonical_derivation() (5*E[alpha[2] + alpha[3] + 2*alpha[4] + alpha[5]])#t^5 """ - cdef dict d = {tl: tl * gl for tl,gl in self._t_dict.iteritems() if tl != 0} + cdef dict d = {tl: tl * gl for tl,gl in self._t_dict.items() if tl != 0} zero = self._parent.base_ring().zero() return type(self)(self._parent, d, zero, zero) diff --git a/src/sage/categories/finite_dimensional_lie_algebras_with_basis.py b/src/sage/categories/finite_dimensional_lie_algebras_with_basis.py index 80349d9658a..09f0e7ef9c3 100644 --- a/src/sage/categories/finite_dimensional_lie_algebras_with_basis.py +++ b/src/sage/categories/finite_dimensional_lie_algebras_with_basis.py @@ -1190,12 +1190,12 @@ def compute_diff(k): # an earlier element from X. Z = tuple(Y[:j-1] + Y[j:]) elt = mone**(i+j) * B[X[i]].bracket(B[X[j]]) - for key, coeff in elt.to_vector().iteritems(): + for key, coeff in elt.to_vector().items(): s, A = sgn(key, Z) if A is None: continue if sparse: - coords = (row,indices[A]) + coords = (row, indices[A]) if coords in data: data[coords] += s * coeff else: diff --git a/src/sage/symbolic/relation.py b/src/sage/symbolic/relation.py index 4801c05856e..24ded86bdf7 100644 --- a/src/sage/symbolic/relation.py +++ b/src/sage/symbolic/relation.py @@ -1116,7 +1116,7 @@ def solve(f, *args, **kwds): return l else: return [[v._sage_() == ex._sage_() - for v, ex in d.iteritems()] + for v, ex in d.items()] for d in ret] elif isinstance(ret, list): l = [] @@ -1154,7 +1154,7 @@ def solve(f, *args, **kwds): if len(s) == 0: # if to_poly_solve gave no solutions, try use_grobner try: - s = m.to_poly_solve(variables,'use_grobner=true') + s = m.to_poly_solve(variables, 'use_grobner=true') except Exception: # if that gives an error, stick with no solutions s = [] @@ -1300,7 +1300,7 @@ def has_integer_assumption(v): from sage.symbolic.assumptions import assumptions, GenericDeclaration alist = assumptions() return any(isinstance(a, GenericDeclaration) and a.has(v) and - a._assumption in ['even','odd','integer','integervalued'] + a._assumption in ['even', 'odd', 'integer', 'integervalued'] for a in alist) if len(ex.variables()) and all(has_integer_assumption(var) for var in ex.variables()): return f.solve_diophantine(x, solution_dict=solution_dict) @@ -1588,11 +1588,11 @@ def solve_mod(eqns, modulus, solution_dict=False): return ans factors = modulus.factor() - crt_basis = vector(Integers(modulus), crt_basis([p**i for p,i in factors])) + crt_basis = vector(Integers(modulus), crt_basis([p**i for p, i in factors])) solutions = [] has_solution = True - for p,i in factors: + for p, i in factors: solution = _solve_mod_prime_power(eqns, p, i, vars) if len(solution) > 0: solutions.append(solution) @@ -1817,7 +1817,7 @@ def solve_ineq_fourier(ineq, vars=None): vars = [i for i in setvars] ineq0 = [i._maxima_() for i in ineq] ineq0[0].parent().eval("if fourier_elim_loaded#true then (fourier_elim_loaded:true,load(\"fourier_elim\"))") - sol = ineq0[0].parent().fourier_elim(ineq0,vars) + sol = ineq0[0].parent().fourier_elim(ineq0, vars) ineq0[0].parent().eval("or_to_list(x):=\ if not atom(x) and op(x)=\"or\" then args(x) \ else [x]") From 933ab142a203f94ab2198f52accc17180909e5c6 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Mon, 18 Apr 2022 21:19:48 +0000 Subject: [PATCH 154/529] Inital try --- .gitpod.yml | 53 +++-------- src/environment-dev.yml | 196 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 209 insertions(+), 40 deletions(-) create mode 100644 src/environment-dev.yml diff --git a/.gitpod.yml b/.gitpod.yml index f57b047b8e1..89b581262bc 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -1,12 +1,5 @@ -# Use custom docker image. https://www.gitpod.io/docs/config-docker -image: -# Each of these two options works: -# - Directly use the "-with-targets" image built by .github/workflows/tox.yml -# image: ghcr.io/sagemath/sage/sage-docker-gitpod-standard-with-targets:dev -# - or go through a custom Dockerfile, which builds a smaller image -# based on the "-with-system-packages" image built by .github/workflows/tox.yml -# with the built SAGE_LOCAL from the "-with-targets" image copied in. - file: docker/.gitpod.Dockerfile +# Use minimal Ubuntu installation that includes mamba +image: condaforge/mambaforge # We use the following layout: # @@ -64,39 +57,19 @@ tasks: ## No need for pyenv pyenv shell --unset 2> /dev/null pyenv global system 2> /dev/null - if [ -d local ]; then - mkdir -p logs && echo '### .gitpod.yml Setup.before: Prebuild init script has been run. Running "make" again in case the build had timed out.' >> logs/install.log - # The init script has already populated the SAGE_LOCAL, - # but only /workspace is preserved; and the $HOME/sage-local may contain a resurrected - # copy of sage-local. Replace it again by a symlink. - rm -Rf $HOME/sage-local - ln -sf $(pwd)/local $HOME/sage-local - # Now run make. No timeout here. - MAKE='make -j24' make build V=0 - else - # Prebuild init script has not been run - # Only /workspace is preserved during build. - # If the Docker image contains a built SAGE_LOCAL, use it to populate the SAGE_LOCAL in the workspace. - if [ -d $HOME/sage-local ]; then - mv $HOME/sage-local local - fi - rm -Rf $HOME/sage-local - ln -sf $(pwd)/local $HOME/sage-local - # Save the logs of the source tree used by the Docker build - if [ -d $HOME/sage/logs ]; then - mv $HOME/sage/logs logs - fi - fi - # Remove the source tree used by the Docker build and replace it by a symlink - rm -Rf $HOME/sage - ln -s $(pwd) $HOME/sage + + # Create conda environment + mamba create --name sage-dev --file src/environment-dev.yml + conda activate sage-dev + + # Build sage + ./configure --enable-build-as-root --with-python=$CONDA_PREFIX/bin/python --prefix=$CONDA_PREFIX + pip install --no-build-isolation -v -v -e pkgs/sage-conf pkgs/sage-setup + pip install --no-build-isolation -v -v -e src + init: | # Start build - mkdir -p logs && echo '### .gitpod.yml Setup.init: Starting build' >> logs/install.log - ./bootstrap - ./configure --enable-editable --enable-download-from-upstream-url --prefix=$HOME/sage-local --with-sage-venv - ## Gitpod has a timeout of 1h, so make sure we are below this to ensure that the prebuild is always successful - MAKE='make -j24' timeout 51m make build V=0 || echo "(ignoring error)" + env: SAGE_NUM_THREADS: 8 diff --git a/src/environment-dev.yml b/src/environment-dev.yml new file mode 100644 index 00000000000..3ee62968cec --- /dev/null +++ b/src/environment-dev.yml @@ -0,0 +1,196 @@ +name: sage +channels: + - conda-forge + - nodefaults +dependencies: + - compilers + - make + - m4 + - perl + - python + - tar + - bc + - pkg-config + - arb + - boost-cpp + - brial + - bzip2 + - cddlib + - cliquer + - cmake + - curl + - ecl + - eclib + - ecm + - fflas-ffpack + - libflint + - flintqs + - fplll + - freetype + - bdw-gc + - gengetopt + - gf2x + - gfan + - fortran-compiler + - giac + - givaro + - glpk + - gmp + - gsl + - iml + - lcalc + - libatomic_ops + - libbraiding + - libffi + - libgd + - libhomfly + - xz + - libpng + - linbox + - lrcalc + - m4ri + - m4rie + - mpc + - mpfi + - mpfr + - nauty + - ncurses + - ntl + - openblas + - blas=2.*=openblas + - openssl + - palp + - pari + - pari-elldata + - pari-galdata + - pari-galpol + - pari-seadata + - pari-galdata + - pari-seadata-small + - patch + - pcre + - pkg-config + - planarity + - ppl + - primecount + - primesieve + - qhull + - r + - r-essentials + - readline + - rw + - singular + - sqlite + - suitesparse + - symmetrica + - sympow + - tachyon + - tox + - xz + - zeromq + - zlib + - zn_poly + - alabaster + - attrs + - babel + - backcall + - beautifulsoup4 + - bleach + - certifi + - cffi + - sagemath-db-combinatorial-designs + - sagemath-db-conway-polynomials + - cvxopt + - cycler + - cypari2 + - cysignals + - cython + - python-dateutil + - decorator + - defusedxml + - docutils + - sagemath-db-elliptic-curves + - entrypoints + - fpylll + - gap-defaults + - gmpy2 + - sagemath-db-graphs + - html5lib + - imagesize + - importlib_metadata + - ipykernel + - ipython + - ipython_genutils + - ipywidgets + - jedi + - jinja2 + - jmol + - jsonschema + - jupyter_client + - jupyter_core + - kiwisolver + - python-lrcalc + - markupsafe + - mathjax + - "matplotlib>=3.5.1" + - maxima + - memory-allocator + - mistune + - mpmath + - nbconvert + - nbformat + - networkx + - notebook + - numpy + - packaging + - pandocfilters + - parso + - pexpect + - pickleshare + - pillow + - pip + - pkgconfig + - sagemath-db-polytopes + - pplpy + - primecountpy + - prometheus_client + - prompt_toolkit + - ptyprocess + - pybind11 + - pycparser + - pygments + - pyparsing + - pyrsistent + - pytz + - pyzmq + - requests + - rpy2 + - sagetex + - scipy + - send2trash + - setuptools + - setuptools_scm + - simplegeneric + - six + - snowballstemmer + - sphinx + - sphinxcontrib-applehelp + - sphinxcontrib-devhelp + - sphinxcontrib-htmlhelp + - sphinxcontrib-jsmath + - sphinxcontrib-qthelp + - sphinxcontrib-serializinghtml + - sphinxcontrib-websupport + - sympy + - terminado + - testpath + - three.js + - tornado + - traitlets + - tzlocal + - vcversioner + - wcwidth + - webencodings + - wheel + - widgetsnbextension + - zipp From c3400241873b0ff322159c9cd74702d097db4ba1 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Mon, 18 Apr 2022 21:28:22 +0000 Subject: [PATCH 155/529] Remove init completly --- .gitpod.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.gitpod.yml b/.gitpod.yml index 89b581262bc..30e2d09b4dc 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -67,9 +67,6 @@ tasks: pip install --no-build-isolation -v -v -e pkgs/sage-conf pkgs/sage-setup pip install --no-build-isolation -v -v -e src - init: | - # Start build - env: SAGE_NUM_THREADS: 8 From accc23258416cb7bea10bb688765dd5c2c482dfd Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Mon, 18 Apr 2022 21:43:23 +0000 Subject: [PATCH 156/529] Remove name in conda env config --- src/environment-dev.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/src/environment-dev.yml b/src/environment-dev.yml index 3ee62968cec..aa45b3a444b 100644 --- a/src/environment-dev.yml +++ b/src/environment-dev.yml @@ -1,4 +1,3 @@ -name: sage channels: - conda-forge - nodefaults From 419c787e787b0fc11f474f99b4287e50dbfae546 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Mon, 18 Apr 2022 22:10:44 +0000 Subject: [PATCH 157/529] Fix conda env creation --- .gitpod.yml | 2 +- src/environment-dev.yml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitpod.yml b/.gitpod.yml index 30e2d09b4dc..e5e2e7f5a01 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -59,7 +59,7 @@ tasks: pyenv global system 2> /dev/null # Create conda environment - mamba create --name sage-dev --file src/environment-dev.yml + mamba env create --name sage-dev --file src/environment-dev.yml conda activate sage-dev # Build sage diff --git a/src/environment-dev.yml b/src/environment-dev.yml index aa45b3a444b..6019cdd5371 100644 --- a/src/environment-dev.yml +++ b/src/environment-dev.yml @@ -1,3 +1,4 @@ +name: sage-dev channels: - conda-forge - nodefaults From e924e71b397512f2b9c25397202d9033a0eae854 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Mon, 18 Apr 2022 22:11:36 +0000 Subject: [PATCH 158/529] Also install openssh --- src/environment-dev.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/environment-dev.yml b/src/environment-dev.yml index 6019cdd5371..3c68c458194 100644 --- a/src/environment-dev.yml +++ b/src/environment-dev.yml @@ -194,3 +194,5 @@ dependencies: - wheel - widgetsnbextension - zipp + # Additional dev tools + - openssh From 1d84ec2d447c5b9a19e7cef145f681e967779cc8 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Mon, 18 Apr 2022 22:20:53 +0000 Subject: [PATCH 159/529] Create conda env already at start --- .gitpod.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitpod.yml b/.gitpod.yml index e5e2e7f5a01..85bcac5b2e0 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -29,6 +29,10 @@ image: condaforge/mambaforge tasks: - name: Setup before: | + # Create conda environment + mamba env create --name sage-dev --file src/environment-dev.yml + conda activate sage-dev + # Setup trac as remote ## In order to push to trac, generate a new key with `ssh-keygen -f tempkey` and save the private key to gitpod `gp env PRIVATE_SSH_KEY="$( /dev/null pyenv global system 2> /dev/null - # Create conda environment - mamba env create --name sage-dev --file src/environment-dev.yml - conda activate sage-dev - # Build sage ./configure --enable-build-as-root --with-python=$CONDA_PREFIX/bin/python --prefix=$CONDA_PREFIX pip install --no-build-isolation -v -v -e pkgs/sage-conf pkgs/sage-setup From 638e5bd1c13a13b9d178f78ace357c807c5e4011 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Mon, 18 Apr 2022 22:22:51 +0000 Subject: [PATCH 160/529] Run bootstrap before configure --- .gitpod.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitpod.yml b/.gitpod.yml index 85bcac5b2e0..f89f23dcea5 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -63,6 +63,7 @@ tasks: pyenv global system 2> /dev/null # Build sage + ./bootstrap ./configure --enable-build-as-root --with-python=$CONDA_PREFIX/bin/python --prefix=$CONDA_PREFIX pip install --no-build-isolation -v -v -e pkgs/sage-conf pkgs/sage-setup pip install --no-build-isolation -v -v -e src From a35455a46e247ca8ead14cb89cbfd24349f64d1f Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Mon, 18 Apr 2022 22:48:05 +0000 Subject: [PATCH 161/529] Add packages needed for bootstrap --- src/environment-dev.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/environment-dev.yml b/src/environment-dev.yml index 3c68c458194..31f80ec7399 100644 --- a/src/environment-dev.yml +++ b/src/environment-dev.yml @@ -194,5 +194,10 @@ dependencies: - wheel - widgetsnbextension - zipp + # Packages needed for ./bootstrap + - gettext + - autoconf + - automake + - libtool # Additional dev tools - openssh From eade9f41710493ecc072df31c2140528f68e7dc6 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Mon, 18 Apr 2022 23:13:39 +0000 Subject: [PATCH 162/529] Create conda env in local folder --- .gitpod.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitpod.yml b/.gitpod.yml index f89f23dcea5..ce3e3a8d090 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -30,7 +30,7 @@ tasks: - name: Setup before: | # Create conda environment - mamba env create --name sage-dev --file src/environment-dev.yml + mamba env create --name sage-dev --file src/environment-dev.yml --prefix venv conda activate sage-dev # Setup trac as remote From d99bcabeb534fa4c3c7106af0c47c8f679501af7 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Mon, 18 Apr 2022 23:25:02 +0000 Subject: [PATCH 163/529] Remove name argument which is incompatible with prefix --- .gitpod.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitpod.yml b/.gitpod.yml index ce3e3a8d090..14e737d7cc3 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -30,7 +30,7 @@ tasks: - name: Setup before: | # Create conda environment - mamba env create --name sage-dev --file src/environment-dev.yml --prefix venv + mamba env create --file src/environment-dev.yml --prefix venv conda activate sage-dev # Setup trac as remote From 072e5ec5576f1499500e5911f11d0d6d7c362f75 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Mon, 18 Apr 2022 23:29:31 +0000 Subject: [PATCH 164/529] Correct name of conda env --- .gitpod.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitpod.yml b/.gitpod.yml index 14e737d7cc3..e3784f740e7 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -31,7 +31,7 @@ tasks: before: | # Create conda environment mamba env create --file src/environment-dev.yml --prefix venv - conda activate sage-dev + conda activate /workspace/sagetrac-mirror/venv # Setup trac as remote ## In order to push to trac, generate a new key with `ssh-keygen -f tempkey` and save the private key to gitpod `gp env PRIVATE_SSH_KEY="$( Date: Mon, 18 Apr 2022 23:29:58 +0000 Subject: [PATCH 165/529] Remove special treatment of pyenv --- .gitpod.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.gitpod.yml b/.gitpod.yml index e3784f740e7..2725826c9fb 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -58,10 +58,6 @@ tasks: git remote set-url --push trac pushing-needs-ssh-key fi - ## No need for pyenv - pyenv shell --unset 2> /dev/null - pyenv global system 2> /dev/null - # Build sage ./bootstrap ./configure --enable-build-as-root --with-python=$CONDA_PREFIX/bin/python --prefix=$CONDA_PREFIX From 8e912cb8987b7b344d928a0a22f67ccaf521e3d6 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Tue, 19 Apr 2022 00:24:07 +0000 Subject: [PATCH 166/529] Use init and command instead of before --- .gitpod.yml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/.gitpod.yml b/.gitpod.yml index 2725826c9fb..16e2f0586ee 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -28,11 +28,18 @@ image: condaforge/mambaforge # Start up tasks. https://www.gitpod.io/docs/config-start-tasks/ tasks: - name: Setup - before: | + init: | # Create conda environment mamba env create --file src/environment-dev.yml --prefix venv conda activate /workspace/sagetrac-mirror/venv + + # Build sage + ./bootstrap + ./configure --enable-build-as-root --with-python=$CONDA_PREFIX/bin/python --prefix=$CONDA_PREFIX + pip install --no-build-isolation -v -v -e pkgs/sage-conf pkgs/sage-setup + pip install --no-build-isolation -v -v -e src + command: | # Setup trac as remote ## In order to push to trac, generate a new key with `ssh-keygen -f tempkey` and save the private key to gitpod `gp env PRIVATE_SSH_KEY="$( Date: Mon, 18 Apr 2022 19:30:45 -0700 Subject: [PATCH 167/529] Trac #25626: Add doctest for integrating exp(t)/(t + 1)^2 with giac URL: https://trac.sagemath.org/25626 Reported by: gh-nasser1 Ticket author(s): Rajat Sirohi Reviewer(s): --- src/sage/calculus/calculus.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/sage/calculus/calculus.py b/src/sage/calculus/calculus.py index fbef15ce543..686f2a8fb8e 100644 --- a/src/sage/calculus/calculus.py +++ b/src/sage/calculus/calculus.py @@ -381,6 +381,12 @@ sage: integrate(sqrt(cos(x)^2 + sin(x)^2), x, 0, 2*pi) 2*pi +Ensure that :trac:`25626` is fixed:: + + sage: t = SR.var('t') + sage: integrate(exp(t)/(t + 1)^2, t, algorithm="giac") + (t*Ei(t + 1) + Ei(t + 1) - e^(t + 1))/(t*e + e) + Check if maxima has redundant variables defined after initialization, see :trac:`9538`:: From 0d580e574300e7ee44eb22c4856a51e97c413cad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 19 Apr 2022 09:18:20 +0200 Subject: [PATCH 168/529] more spaces after comma --- .../lie_algebras/lie_algebra_element.pyx | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/sage/algebras/lie_algebras/lie_algebra_element.pyx b/src/sage/algebras/lie_algebras/lie_algebra_element.pyx index 2e48c4aa6c5..bb2859ba6bd 100644 --- a/src/sage/algebras/lie_algebras/lie_algebra_element.pyx +++ b/src/sage/algebras/lie_algebras/lie_algebra_element.pyx @@ -946,7 +946,7 @@ cdef class UntwistedAffineLieAlgebraElement(Element): ret = style('') mult = style(mult) tensor_symb = style(tensor_symb) - for t,g in self._t_dict.items(): + for t, g in self._t_dict.items(): if ret: ret += style(' + ') if coeff == str: @@ -1260,8 +1260,8 @@ cdef class UntwistedAffineLieAlgebraElement(Element): 'd'] """ cdef dict d = {} - for t,g in self._t_dict.items(): - for k,c in g.monomial_coefficients(copy=False).iteritems(): + for t, g in self._t_dict.items(): + for k, c in g.monomial_coefficients(copy=False).iteritems(): d[k,t] = c if self._c_coeff: d['c'] = self._c_coeff @@ -1326,7 +1326,7 @@ cdef class UntwistedAffineLieAlgebraElement(Element): cdef dict d = {} cdef UntwistedAffineLieAlgebraElement rt = (y) c = self._parent.base_ring().zero() - for tl,gl in self._t_dict.items(): + for tl, gl in self._t_dict.items(): # d contribution from the left if rt._d_coeff: if tl in d: @@ -1336,7 +1336,7 @@ cdef class UntwistedAffineLieAlgebraElement(Element): if not d[tl]: del d[tl] # main bracket of the central extension - for tr,gr in rt._t_dict.items(): + for tr, gr in rt._t_dict.items(): b = gl.bracket(gr) if b: if tl+tr in d: @@ -1350,7 +1350,7 @@ cdef class UntwistedAffineLieAlgebraElement(Element): # d contribution from the right if self._d_coeff: - for tr,gr in rt._t_dict.items(): + for tr, gr in rt._t_dict.items(): if tr in d: d[tr] += self._d_coeff * gr * tr else: @@ -1381,10 +1381,12 @@ cdef class UntwistedAffineLieAlgebraElement(Element): sage: x.canonical_derivation() (5*E[alpha[2] + alpha[3] + 2*alpha[4] + alpha[5]])#t^5 """ - cdef dict d = {tl: tl * gl for tl,gl in self._t_dict.items() if tl != 0} + cdef dict d = {tl: tl * gl + for tl, gl in self._t_dict.items() if tl != 0} zero = self._parent.base_ring().zero() return type(self)(self._parent, d, zero, zero) + def _build_untwisted_affine_element(P, t_dict, c, d): """ Used to unpickle an element. From 0e6626382ca12e86996e15c810edadcc137cc261 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 19 Apr 2022 11:18:00 +0200 Subject: [PATCH 169/529] simplify empty sets and empty tuples --- src/sage/combinat/alternating_sign_matrix.py | 2 +- src/sage/combinat/descent_algebra.py | 2 +- src/sage/combinat/enumeration_mod_permgroup.pyx | 6 +++--- src/sage/combinat/knutson_tao_puzzles.py | 6 +++--- src/sage/combinat/path_tableaux/path_tableau.py | 4 ++-- src/sage/combinat/perfect_matching.py | 2 +- src/sage/combinat/posets/posets.py | 2 +- src/sage/combinat/root_system/fundamental_group.py | 5 ++--- src/sage/combinat/shifted_primed_tableau.py | 4 ++-- src/sage/databases/jones.py | 2 +- src/sage/groups/fqf_orthogonal.py | 2 +- src/sage/modular/btquotients/btquotient.py | 2 +- src/sage/modular/dirichlet.py | 2 +- src/sage/modular/multiple_zeta.py | 6 +++--- src/sage/parallel/decorate.py | 4 ++-- src/sage/parallel/reference.py | 2 +- src/sage/rings/number_field/bdd_height.py | 4 ++-- src/sage/rings/number_field/class_group.py | 2 +- src/sage/rings/number_field/number_field.py | 2 +- src/sage/rings/polynomial/symmetric_ideal.py | 4 ++-- src/sage/rings/polynomial/toy_d_basis.py | 2 +- src/sage/rings/rational_field.py | 2 +- src/sage/rings/real_mpfr.pyx | 2 +- src/sage/rings/ring_extension.pyx | 2 +- src/sage/rings/ring_extension_morphism.pyx | 2 +- src/sage/symbolic/callable.py | 2 +- src/sage/symbolic/ring.pyx | 2 +- 27 files changed, 39 insertions(+), 40 deletions(-) diff --git a/src/sage/combinat/alternating_sign_matrix.py b/src/sage/combinat/alternating_sign_matrix.py index 59bde271032..146ff0cdfce 100644 --- a/src/sage/combinat/alternating_sign_matrix.py +++ b/src/sage/combinat/alternating_sign_matrix.py @@ -1364,7 +1364,7 @@ def from_contre_tableau(self, comps): n = len(comps) M = [[0 for _ in range(n)] for _ in range(n)] - previous_set = set([]) + previous_set = set() for col in range(n-1, -1, -1): s = set(comps[col]) for x in s.difference(previous_set): diff --git a/src/sage/combinat/descent_algebra.py b/src/sage/combinat/descent_algebra.py index 14554ddd991..3707a258e47 100644 --- a/src/sage/combinat/descent_algebra.py +++ b/src/sage/combinat/descent_algebra.py @@ -275,7 +275,7 @@ def one_basis(self): ....: for U in DescentAlgebra(QQ, 3).D().basis() ) True """ - return tuple([]) + return tuple() @cached_method def to_B_basis(self, S): diff --git a/src/sage/combinat/enumeration_mod_permgroup.pyx b/src/sage/combinat/enumeration_mod_permgroup.pyx index 8f563da95b7..312026ca4c6 100644 --- a/src/sage/combinat/enumeration_mod_permgroup.pyx +++ b/src/sage/combinat/enumeration_mod_permgroup.pyx @@ -169,7 +169,7 @@ cpdef bint is_canonical(list sgs, ClonableIntArray v) except -1: l = len(v) to_analyse = set([v]) for i in range(l-1): - new_to_analyse = set([]) + new_to_analyse = set() transversal = sgs[i] for list_test in to_analyse: for x in transversal: @@ -218,7 +218,7 @@ cpdef ClonableIntArray canonical_representative_of_orbit_of(list sgs, ClonableIn l = len(v) to_analyse = set([v]) for i in range(l-1): - new_to_analyse = set([]) + new_to_analyse = set() for list_test in to_analyse: for x in sgs[i]: child = x._act_on_array_on_position(list_test) @@ -278,7 +278,7 @@ cpdef set orbit(list sgs, ClonableIntArray v): l = len(v) to_analyse = set([v]) for i in range(l-1): - new_to_analyse = set([]) + new_to_analyse = set() for list_test in to_analyse: for x in sgs[i]: child = x._act_on_array_on_position(list_test) diff --git a/src/sage/combinat/knutson_tao_puzzles.py b/src/sage/combinat/knutson_tao_puzzles.py index 6cb3fff4539..9e8b5557eb6 100644 --- a/src/sage/combinat/knutson_tao_puzzles.py +++ b/src/sage/combinat/knutson_tao_puzzles.py @@ -670,8 +670,8 @@ def __init__(self, forbidden_border_labels=None): ... TypeError: Input must be a list """ - self._nabla_pieces = set([]) - self._delta_pieces = set([]) + self._nabla_pieces = set() + self._delta_pieces = set() if forbidden_border_labels is None: forbidden_border_labels = [] if not isinstance(forbidden_border_labels, list): @@ -865,7 +865,7 @@ def rhombus_pieces(self) -> set: sage: sorted([p for p in pieces.rhombus_pieces()], key=str) [a/\b b\/a, b/\c c\/b, c/\a a\/c] """ - rhombi = set([]) + rhombi = set() for nabla in self._nabla_pieces: for delta in self._delta_pieces: if delta['south'] == nabla['north']: diff --git a/src/sage/combinat/path_tableaux/path_tableau.py b/src/sage/combinat/path_tableaux/path_tableau.py index 5455d205708..691882350c2 100644 --- a/src/sage/combinat/path_tableaux/path_tableau.py +++ b/src/sage/combinat/path_tableaux/path_tableau.py @@ -362,10 +362,10 @@ def orbit(self): [0, 1, 2, 1, 2, 1, 0], [0, 1, 2, 3, 2, 1, 0]} """ - orb = set([]) + orb = set() rec = set([self]) while rec: - new = set([]) + new = set() for a in rec: for i in range(2, self.size()): b = a.cactus(1, i) diff --git a/src/sage/combinat/perfect_matching.py b/src/sage/combinat/perfect_matching.py index 25dab396fd3..975a682b233 100644 --- a/src/sage/combinat/perfect_matching.py +++ b/src/sage/combinat/perfect_matching.py @@ -552,7 +552,7 @@ class PerfectMatchings(SetPartitions_set): Test that ``x = M.an_element()`` is actually a perfect matching:: - sage: set([]).union(*x) == M.base_set() + sage: set().union(*x) == M.base_set() True sage: sum([len(a) for a in x]) == M.base_set().cardinality() True diff --git a/src/sage/combinat/posets/posets.py b/src/sage/combinat/posets/posets.py index 4d03a102f7c..6b7aed790b8 100644 --- a/src/sage/combinat/posets/posets.py +++ b/src/sage/combinat/posets/posets.py @@ -5052,7 +5052,7 @@ def ordinal_summands(self): H = self._hasse_diagram cut_points = [-1] in_degrees = H.in_degree() - lower = set([]) + lower = set() upper = set(H.sources()) for e in range(n): diff --git a/src/sage/combinat/root_system/fundamental_group.py b/src/sage/combinat/root_system/fundamental_group.py index 0f378d7e510..80d5915eaa1 100644 --- a/src/sage/combinat/root_system/fundamental_group.py +++ b/src/sage/combinat/root_system/fundamental_group.py @@ -371,7 +371,7 @@ def leading_support(beta): auto_dict[special_node,i] = i # dictionary for the finite Weyl component of the special automorphisms reduced_words_dict = {} - reduced_words_dict[0] = tuple([]) + reduced_words_dict[0] = tuple() if cartan_type.dual().is_untwisted_affine(): # this combines the computations for an untwisted affine @@ -779,7 +779,6 @@ def reduced_word(self, i): """ i = i % self._n if i == 0: - return tuple([]) + return tuple() om = self.cartan_type().classical().root_system().weight_lattice().fundamental_weight(i) return tuple((-om).reduced_word()) - diff --git a/src/sage/combinat/shifted_primed_tableau.py b/src/sage/combinat/shifted_primed_tableau.py index 5fed1789092..5b8eb900ece 100644 --- a/src/sage/combinat/shifted_primed_tableau.py +++ b/src/sage/combinat/shifted_primed_tableau.py @@ -121,11 +121,11 @@ def __classcall_private__(cls, T, skew=None, primed_diagonal=False): sage: ShiftedPrimedTableau([]) [] - sage: ShiftedPrimedTableau([tuple([])]) + sage: ShiftedPrimedTableau([tuple()]) [] sage: ShiftedPrimedTableau([], primed_diagonal=True) [] - sage: ShiftedPrimedTableau([tuple([])], primed_diagonal=True) + sage: ShiftedPrimedTableau([tuple()], primed_diagonal=True) [] """ if (isinstance(T, ShiftedPrimedTableau) and T._skew == skew diff --git a/src/sage/databases/jones.py b/src/sage/databases/jones.py index da1e730c65c..97741e98be5 100644 --- a/src/sage/databases/jones.py +++ b/src/sage/databases/jones.py @@ -147,7 +147,7 @@ def _init(self, path): """ x = PolynomialRing(RationalField(), 'x').gen() self.root = {} - self.root[tuple([])] = [x - 1] + self.root[tuple()] = [x - 1] if not os.path.exists(path): raise IOError("Path %s does not exist." % path) for X in os.listdir(path): diff --git a/src/sage/groups/fqf_orthogonal.py b/src/sage/groups/fqf_orthogonal.py index 05f76e582d1..75de4089120 100644 --- a/src/sage/groups/fqf_orthogonal.py +++ b/src/sage/groups/fqf_orthogonal.py @@ -546,7 +546,7 @@ def orbits(G, L): # separating the different primes here would speed things up b_cand = [[b for b in B if b.q()==a.q() and b.order() == a.order()] for a in A.smith_form_gens()] - G = B.orthogonal_group(tuple([])) + G = B.orthogonal_group(tuple()) ambient = G.ambient() waiting = [[]] while len(waiting) > 0: diff --git a/src/sage/modular/btquotients/btquotient.py b/src/sage/modular/btquotients/btquotient.py index 9c61a8c1bef..cb95caf420d 100644 --- a/src/sage/modular/btquotients/btquotient.py +++ b/src/sage/modular/btquotients/btquotient.py @@ -3607,7 +3607,7 @@ def _compute_quotient(self, check=True): - Cameron Franc (2012-02-20) - Marc Masdeu """ - nontorsion_generators = set([]) + nontorsion_generators = set() genus = self.genus() num_verts = 0 num_edges = 0 diff --git a/src/sage/modular/dirichlet.py b/src/sage/modular/dirichlet.py index 85e71683726..25565d0eeab 100644 --- a/src/sage/modular/dirichlet.py +++ b/src/sage/modular/dirichlet.py @@ -2995,7 +2995,7 @@ def galois_orbits(self, v=None, reps_only=False, sort=True, check=True): v = [self(x) for x in v] G = [] - seen_so_far = set([]) + seen_so_far = set() for x in v: z = x.element() e = tuple(z) # change when there are immutable vectors (and below) diff --git a/src/sage/modular/multiple_zeta.py b/src/sage/modular/multiple_zeta.py index fe654b94e48..8080c1b689e 100644 --- a/src/sage/modular/multiple_zeta.py +++ b/src/sage/modular/multiple_zeta.py @@ -275,7 +275,7 @@ def composition_to_iterated(w, reverse=False): sage: composition_to_iterated((1,2), True) (1, 0, 1) """ - word = tuple([]) + word = tuple() loop_over = reversed(w) if reverse else w for letter in loop_over: word += (1,) + (0,) * (letter - 1) @@ -575,7 +575,7 @@ def basis_f_odd_iterator(n): (3, 11)] """ if n == 0: - yield tuple([]) + yield tuple() return if n == 1: return @@ -1839,7 +1839,7 @@ def phi_extended(self, w): TESTS:: - sage: M.phi_extended(tuple([])) + sage: M.phi_extended(tuple()) Z[] """ # this is now hardcoded diff --git a/src/sage/parallel/decorate.py b/src/sage/parallel/decorate.py index 43dd7a8142c..6485da49c19 100644 --- a/src/sage/parallel/decorate.py +++ b/src/sage/parallel/decorate.py @@ -18,7 +18,7 @@ def normalize_input(a): - if already of that form, leave that way. - if ``a`` is a tuple make ``(a,{})`` - - if ``a`` is a dict make ``(tuple([]),a)`` + - if ``a`` is a dict make ``(tuple(),a)`` - otherwise make ``((a,),{})`` INPUT: @@ -46,7 +46,7 @@ def normalize_input(a): elif isinstance(a, tuple): return (a, {}) elif isinstance(a, dict): - return (tuple([]), a) + return (tuple(), a) else: return ((a,), {}) diff --git a/src/sage/parallel/reference.py b/src/sage/parallel/reference.py index a37dd66f40e..36dd7a8bb76 100644 --- a/src/sage/parallel/reference.py +++ b/src/sage/parallel/reference.py @@ -29,7 +29,7 @@ def parallel_iter(f, inputs): EXAMPLES:: sage: def f(N,M=10): return N*M - sage: inputs = [((2,3),{}), (tuple([]), {'M':5,'N':3}), ((2,),{})] + sage: inputs = [((2,3),{}), (tuple(), {'M':5,'N':3}), ((2,),{})] sage: set_random_seed(0) sage: for a, val in sage.parallel.reference.parallel_iter(f, inputs): ....: print((a, val)) diff --git a/src/sage/rings/number_field/bdd_height.py b/src/sage/rings/number_field/bdd_height.py index 87799f2b1d2..39ab3ceca09 100644 --- a/src/sage/rings/number_field/bdd_height.py +++ b/src/sage/rings/number_field/bdd_height.py @@ -186,7 +186,7 @@ def bdd_height_iq(K, height_bound): class_number = len(class_group_reps) # Find principal ideals of bounded norm - possible_norm_set = set([]) + possible_norm_set = set() for n in range(class_number): for m in range(1, int(height_bound + 1)): possible_norm_set.add(m*class_group_rep_norms[n]) @@ -524,7 +524,7 @@ def packet_height(n, pair, u): # Step 2 # Find generators for principal ideals of bounded norm - possible_norm_set = set([]) + possible_norm_set = set() for n in range(class_number): for m in range(1, (B + 1).ceil()): possible_norm_set.add(m * class_group_rep_norms[n]) diff --git a/src/sage/rings/number_field/class_group.py b/src/sage/rings/number_field/class_group.py index 34e801aad2a..cdb35e88944 100644 --- a/src/sage/rings/number_field/class_group.py +++ b/src/sage/rings/number_field/class_group.py @@ -673,7 +673,7 @@ def S(self): sage: S = (I,) sage: CS = K.S_class_group(S);CS S-class group of order 2 with structure C2 of Number Field in a with defining polynomial x^2 + 14 with a = 3.741657386773942?*I - sage: T = tuple([]) + sage: T = tuple() sage: CT = K.S_class_group(T);CT S-class group of order 4 with structure C4 of Number Field in a with defining polynomial x^2 + 14 with a = 3.741657386773942?*I sage: CS.S() diff --git a/src/sage/rings/number_field/number_field.py b/src/sage/rings/number_field/number_field.py index 1866d3e05d1..78e0eb50e92 100644 --- a/src/sage/rings/number_field/number_field.py +++ b/src/sage/rings/number_field/number_field.py @@ -4686,7 +4686,7 @@ def S_class_group(self, S, proof=None, names='c'): sage: S = (I,) sage: CS = K.S_class_group(S);CS S-class group of order 2 with structure C2 of Number Field in a with defining polynomial x^2 + 14 with a = 3.741657386773942?*I - sage: T = tuple([]) + sage: T = tuple() sage: CT = K.S_class_group(T);CT S-class group of order 4 with structure C4 of Number Field in a with defining polynomial x^2 + 14 with a = 3.741657386773942?*I sage: K.class_group() diff --git a/src/sage/rings/polynomial/symmetric_ideal.py b/src/sage/rings/polynomial/symmetric_ideal.py index 9800107e4b9..f96a7b57e39 100644 --- a/src/sage/rings/polynomial/symmetric_ideal.py +++ b/src/sage/rings/polynomial/symmetric_ideal.py @@ -914,7 +914,7 @@ def groebner_basis(self, tailreduce=False, reduced=True, algorithm=None, report= OUT = self.symmetrisation(tailreduce=tailreduce,report=report,use_full_group=use_full_group) if not (report is None): print("Symmetrisation done") - VarList = set([]) + VarList = set() for P in OUT.gens(): if P._p!=0: if P.is_unit(): @@ -931,7 +931,7 @@ def groebner_basis(self, tailreduce=False, reduced=True, algorithm=None, report= if hasattr(PARENT,'_P'): CommonR = PARENT._P else: - VarList = set([]) + VarList = set() for P in OUT.gens(): if P._p!=0: if P.is_unit(): diff --git a/src/sage/rings/polynomial/toy_d_basis.py b/src/sage/rings/polynomial/toy_d_basis.py index 39d7bedb746..15cfd4eea52 100644 --- a/src/sage/rings/polynomial/toy_d_basis.py +++ b/src/sage/rings/polynomial/toy_d_basis.py @@ -324,7 +324,7 @@ def update(G, B, h): sage: from sage.rings.polynomial.toy_d_basis import update sage: A. = PolynomialRing(ZZ, 2) sage: G = set([3*x^2 + 7, 2*y + 1, x^3 - y^2 + 7*x - y + 1]) - sage: B = set([]) + sage: B = set() sage: h = x^2*y - x^2 + y - 3 sage: update(G,B,h) ({2*y + 1, 3*x^2 + 7, x^2*y - x^2 + y - 3, x^3 - y^2 + 7*x - y + 1}, diff --git a/src/sage/rings/rational_field.py b/src/sage/rings/rational_field.py index 7c447d4c7ff..faab5c96fe8 100644 --- a/src/sage/rings/rational_field.py +++ b/src/sage/rings/rational_field.py @@ -285,7 +285,7 @@ def __reduce__(self): sage: loads(dumps(QQ)) is QQ True """ - return RationalField, tuple([]) + return RationalField, tuple() def __len__(self): """ diff --git a/src/sage/rings/real_mpfr.pyx b/src/sage/rings/real_mpfr.pyx index 142794268bd..e9c94e4eba2 100644 --- a/src/sage/rings/real_mpfr.pyx +++ b/src/sage/rings/real_mpfr.pyx @@ -538,7 +538,7 @@ cdef class RealField_class(sage.rings.abc.RealField): self.rnd_str = char_to_str(rnd_str + 5) # Strip "MPFR_" from sage.categories.fields import Fields - ParentWithGens.__init__(self, self, tuple([]), False, category=Fields().Infinite().Metric().Complete()) + ParentWithGens.__init__(self, self, tuple(), False, category=Fields().Infinite().Metric().Complete()) # Initialize zero and one cdef RealNumber rn diff --git a/src/sage/rings/ring_extension.pyx b/src/sage/rings/ring_extension.pyx index e6708a2f81f..d4c8e179ed8 100644 --- a/src/sage/rings/ring_extension.pyx +++ b/src/sage/rings/ring_extension.pyx @@ -2601,7 +2601,7 @@ cdef class RingExtensionWithGen(RingExtensionWithBasis): if base is None: return (self(self._gen),) base = self._check_base(base) - gens = tuple([]) + gens = tuple() b = self while b is not base: gens += b.gens() diff --git a/src/sage/rings/ring_extension_morphism.pyx b/src/sage/rings/ring_extension_morphism.pyx index c5e6b556e56..2cde5d9502d 100644 --- a/src/sage/rings/ring_extension_morphism.pyx +++ b/src/sage/rings/ring_extension_morphism.pyx @@ -160,7 +160,7 @@ cdef class RingExtensionHomomorphism(RingMap): gens = domain.gens(base) else: base = domain - gens = tuple([]) + gens = tuple() while True: if len(gens) == len(defn): break diff --git a/src/sage/symbolic/callable.py b/src/sage/symbolic/callable.py index f06670083dd..1b1cf8d5bb1 100644 --- a/src/sage/symbolic/callable.py +++ b/src/sage/symbolic/callable.py @@ -260,7 +260,7 @@ def unify_arguments(self, x): else: done = True - temp = set([]) + temp = set() # Sorting remaining variables. for j in range(i, len(a)): if not a[j] in temp: diff --git a/src/sage/symbolic/ring.pyx b/src/sage/symbolic/ring.pyx index 05694e3b085..905c588154d 100644 --- a/src/sage/symbolic/ring.pyx +++ b/src/sage/symbolic/ring.pyx @@ -96,7 +96,7 @@ cdef class SymbolicRing(sage.rings.abc.SymbolicRing): sage: loads(dumps(SR)) == SR # indirect doctest True """ - return the_SymbolicRing, tuple([]) + return the_SymbolicRing, tuple() def _repr_(self): """ From 40e8513a3e09320891164db5cd67384c344751a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 19 Apr 2022 12:10:39 +0200 Subject: [PATCH 170/529] avoid list(of a list) --- src/doc/en/faq/faq-usage.rst | 2 +- src/doc/it/faq/faq-usage.rst | 2 +- src/sage/combinat/posets/hasse_diagram.py | 2 +- src/sage/numerical/knapsack.py | 4 ++-- src/sage/rings/integer.pyx | 2 +- src/sage/rings/polynomial/pbori/pbori.pyx | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/doc/en/faq/faq-usage.rst b/src/doc/en/faq/faq-usage.rst index e72ffc01707..9d5f2cbeb95 100644 --- a/src/doc/en/faq/faq-usage.rst +++ b/src/doc/en/faq/faq-usage.rst @@ -321,7 +321,7 @@ ints. For example:: sage: RealNumber = float; Integer = int sage: from scipy import stats - sage: stats.ttest_ind(list([1,2,3,4,5]),list([2,3,4,5,.6])) + sage: stats.ttest_ind([1,2,3,4,5], [2,3,4,5,.6]) Ttest_indResult(statistic=0.0767529..., pvalue=0.940704...) sage: stats.uniform(0,15).ppf([0.5,0.7]) array([ 7.5, 10.5]) diff --git a/src/doc/it/faq/faq-usage.rst b/src/doc/it/faq/faq-usage.rst index 8d81273d690..0b6c75644ce 100644 --- a/src/doc/it/faq/faq-usage.rst +++ b/src/doc/it/faq/faq-usage.rst @@ -303,7 +303,7 @@ anziché Integer di Sage. Ad esempio:: sage: RealNumber = float; Integer = int sage: from scipy import stats - sage: stats.ttest_ind(list([1,2,3,4,5]),list([2,3,4,5,.6])) + sage: stats.ttest_ind([1,2,3,4,5], [2,3,4,5,.6]) Ttest_indResult(statistic=0.0767529..., pvalue=0.940704...) sage: stats.uniform(0,15).ppf([0.5,0.7]) array([ 7.5, 10.5]) diff --git a/src/sage/combinat/posets/hasse_diagram.py b/src/sage/combinat/posets/hasse_diagram.py index 93d254b245c..901e82cef9e 100644 --- a/src/sage/combinat/posets/hasse_diagram.py +++ b/src/sage/combinat/posets/hasse_diagram.py @@ -2018,7 +2018,7 @@ def orthocomplementations_iterator(self): for chain 0-1-6-11 would be 11-7-8-0, which is not a chain:: sage: H = HasseDiagram('KTGG_?AAC?O?o?@?@?E?@?@??') - sage: list([_ for _ in H.orthocomplementations_iterator()]) + sage: list(H.orthocomplementations_iterator()) [] """ n = self.order() diff --git a/src/sage/numerical/knapsack.py b/src/sage/numerical/knapsack.py index 7090b58f416..f334c24b94b 100644 --- a/src/sage/numerical/knapsack.py +++ b/src/sage/numerical/knapsack.py @@ -134,7 +134,7 @@ class Superincreasing(SageObject): An empty sequence. sage: seq = Superincreasing([1, 3, 6]); seq Super-increasing sequence of length 3 - sage: seq = Superincreasing(list([1, 2, 5, 21, 69, 189, 376, 919])); seq + sage: seq = Superincreasing([1, 2, 5, 21, 69, 189, 376, 919]); seq Super-increasing sequence of length 8 """ @@ -212,7 +212,7 @@ def __repr__(self): An empty sequence. sage: seq = Superincreasing([1, 3, 6]); seq Super-increasing sequence of length 3 - sage: seq = Superincreasing(list([1, 2, 5, 21, 69, 189, 376, 919])); seq + sage: seq = Superincreasing([1, 2, 5, 21, 69, 189, 376, 919]); seq Super-increasing sequence of length 8 """ if self._seq is None: diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx index 23f4fc7d325..45241cce032 100644 --- a/src/sage/rings/integer.pyx +++ b/src/sage/rings/integer.pyx @@ -50,7 +50,7 @@ Multiplication:: :: - sage: list([2,3]) * 4 + sage: [2,3] * 4 [2, 3, 2, 3, 2, 3, 2, 3] :: diff --git a/src/sage/rings/polynomial/pbori/pbori.pyx b/src/sage/rings/polynomial/pbori/pbori.pyx index 98afedfa785..6a9bd64e3d5 100644 --- a/src/sage/rings/polynomial/pbori/pbori.pyx +++ b/src/sage/rings/polynomial/pbori/pbori.pyx @@ -6247,7 +6247,7 @@ cdef class ReductionStrategy: sage: B. = BooleanPolynomialRing() sage: red = ReductionStrategy(B) sage: red.add_generator(x) - sage: list([f.p for f in red]) + sage: [f.p for f in red] [x] TESTS: From 41aae7976b4c99e3cdee41aa366d3b1924163a45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 19 Apr 2022 13:36:58 +0200 Subject: [PATCH 171/529] get rid of unused variables in algebra (pylint W0612) --- src/sage/algebras/free_algebra_element.py | 6 +++--- src/sage/algebras/free_algebra_quotient_element.py | 7 ++++--- .../algebras/lie_algebras/classical_lie_algebra.py | 6 +++--- src/sage/algebras/lie_algebras/subalgebra.py | 2 +- src/sage/algebras/quatalg/quaternion_algebra.py | 8 ++++---- src/sage/algebras/splitting_algebra.py | 4 ++-- src/sage/algebras/steenrod/steenrod_algebra_bases.py | 2 +- src/sage/algebras/weyl_algebra.py | 4 ++-- src/sage/algebras/yangian.py | 10 +++++----- 9 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/sage/algebras/free_algebra_element.py b/src/sage/algebras/free_algebra_element.py index e68fd5e332e..2748f4b5ed2 100644 --- a/src/sage/algebras/free_algebra_element.py +++ b/src/sage/algebras/free_algebra_element.py @@ -246,9 +246,9 @@ def variables(self): sage: elt.variables() [x, y, z] """ - v = set([]) - for s in self._monomial_coefficients: # Only gets the keys - for var,exp in s: + v = set() + for s in self._monomial_coefficients: # Only gets the keys + for var, _ in s: v.add(var) A = self.parent() return sorted(map(A, v)) diff --git a/src/sage/algebras/free_algebra_quotient_element.py b/src/sage/algebras/free_algebra_quotient_element.py index 7d6f59370eb..b76538c3381 100644 --- a/src/sage/algebras/free_algebra_quotient_element.py +++ b/src/sage/algebras/free_algebra_quotient_element.py @@ -240,11 +240,12 @@ def _mul_(self, y): -5459/25 + 40*i - 12*j + 340*k """ A = self.parent() - def monomial_product(X,w,m): + + def monomial_product(X, w, m): mats = X._FreeAlgebraQuotient__matrix_action - for (j,k) in m._element_list: + for (j, k) in m._element_list: M = mats[int(j)] - for l in range(k): + for _ in range(k): w *= M return w u = self.__vector.__copy__() diff --git a/src/sage/algebras/lie_algebras/classical_lie_algebra.py b/src/sage/algebras/lie_algebras/classical_lie_algebra.py index fe62f9527ee..e157153e905 100644 --- a/src/sage/algebras/lie_algebras/classical_lie_algebra.py +++ b/src/sage/algebras/lie_algebras/classical_lie_algebra.py @@ -295,7 +295,7 @@ def highest_root_basis_elt(self, pos=True): gens = self._f cur = gens[i] for j in reversed(w): - for k in range(-r.scalar(coroots[j])): + for _ in range(-r.scalar(coroots[j])): cur = self.bracket(gens[j], cur) r = r.reflection(coroots[j], True) return cur @@ -1724,9 +1724,9 @@ def _test_structure_coeffs(self, **options): # Setup the GAP objects from sage.libs.gap.libgap import libgap L = libgap.SimpleLieAlgebra(ct.letter, ct.n, libgap(self.base_ring())) - pos_B, neg_B, h_B = libgap.ChevalleyBasis(L) + pos_B, neg_B, _ = libgap.ChevalleyBasis(L) gap_p_roots = libgap.PositiveRoots(libgap.RootSystem(L)).sage() - #E, F, H = libgap.CanonicalGenerators(L) + # E, F, H = libgap.CanonicalGenerators(L) # Setup the conversion between the Sage roots and GAP roots. # The GAP roots are given in terms of the weight lattice. diff --git a/src/sage/algebras/lie_algebras/subalgebra.py b/src/sage/algebras/lie_algebras/subalgebra.py index 3653d7f034e..c9e9748a7d6 100644 --- a/src/sage/algebras/lie_algebras/subalgebra.py +++ b/src/sage/algebras/lie_algebras/subalgebra.py @@ -916,7 +916,7 @@ def reduce(self, X): X = X - X[k] / c * Y else: try: - q, r = X[k].quo_rem(c) + q, _ = X[k].quo_rem(c) X = X - q * Y except AttributeError: pass diff --git a/src/sage/algebras/quatalg/quaternion_algebra.py b/src/sage/algebras/quatalg/quaternion_algebra.py index 93692a9faf4..bbdab484b43 100644 --- a/src/sage/algebras/quatalg/quaternion_algebra.py +++ b/src/sage/algebras/quatalg/quaternion_algebra.py @@ -798,7 +798,7 @@ def maximal_order(self, take_shortcuts=True): e_new_gens = [] # For each prime at which R is not yet maximal, make it bigger - for (p, p_val) in d_R.factor(): + for (p, _) in d_R.factor(): e = R.basis() while self.quaternion_order(e).discriminant().valuation(p) > d_A.valuation(p): # Compute a normalized basis at p @@ -1221,7 +1221,7 @@ def modp_splitting_data(self, p): if self.discriminant() % p == 0: raise ValueError("p (=%s) must be an unramified prime" % p) - i, j, k = self.gens() + i, j, _ = self.gens() F = GF(p) i2 = F(i * i) j2 = F(j * j) @@ -1230,7 +1230,7 @@ def modp_splitting_data(self, p): I = M([0, i2, 1, 0]) if i2 == 0: raise NotImplementedError("algorithm for computing local splittings not implemented in general (currently require the first invariant to be coprime to p)") - i2inv = 1/i2 + i2inv = ~i2 a = None for b in list(F): if not b: @@ -2865,7 +2865,7 @@ def cyclic_right_subideals(self, p, alpha=None): else: x = alpha lines = [] - for i in range(p+1): + for _ in range(p + 1): lines.append(P1.normalize(x[0, 0], x[0, 1])) x *= alpha diff --git a/src/sage/algebras/splitting_algebra.py b/src/sage/algebras/splitting_algebra.py index 0370d6a76ff..0eb2fed7746 100644 --- a/src/sage/algebras/splitting_algebra.py +++ b/src/sage/algebras/splitting_algebra.py @@ -283,8 +283,8 @@ def __init__(self, monic_polynomial, names='X', iterate=True, warning=True): root_names_reduces.remove(root_name) P = base_ring_step[root_names_reduces[0]] - p = P(monic_polynomial.dict()) - q, r = p.quo_rem( (P.gen()-first_root) ) + p = P(monic_polynomial.dict()) + q, _ = p.quo_rem((P.gen() - first_root)) verbose("Invoking recursion with: %s" % (q,)) diff --git a/src/sage/algebras/steenrod/steenrod_algebra_bases.py b/src/sage/algebras/steenrod/steenrod_algebra_bases.py index 65b5fc89f6a..e4a2b496e26 100644 --- a/src/sage/algebras/steenrod/steenrod_algebra_bases.py +++ b/src/sage/algebras/steenrod/steenrod_algebra_bases.py @@ -1074,7 +1074,7 @@ def sorting_pair(s,t,basis): # pair used for sorting the basis okay = False break - for ((s,t), exp) in p_mono: + for ((s, t), _) in p_mono: if ((len(profile[0]) > t-1 and profile[0][t-1] <= s) or (len(profile[0]) <= t-1 and trunc < Infinity)): okay = False diff --git a/src/sage/algebras/weyl_algebra.py b/src/sage/algebras/weyl_algebra.py index 183699e5e84..21cf81c0b84 100644 --- a/src/sage/algebras/weyl_algebra.py +++ b/src/sage/algebras/weyl_algebra.py @@ -403,8 +403,8 @@ def _mul_(self, other): for mr in other.__monomials: cr = other.__monomials[mr] cur = [ ((mr[0], t), cl * cr) ] - for i,p in enumerate(ml[1]): - for j in range(p): + for i, p in enumerate(ml[1]): + for _ in range(p): next = [] for m, c in cur: # Distribute and apply the derivative diff = list(m[1]) diff --git a/src/sage/algebras/yangian.py b/src/sage/algebras/yangian.py index 1d6df948b18..e7d1945ab31 100644 --- a/src/sage/algebras/yangian.py +++ b/src/sage/algebras/yangian.py @@ -654,12 +654,12 @@ def product_on_basis(self, x, y): return self.monomial(x * y) # The computation is done on generators, so apply generators one at - # a time until all have been applied + # a time until all have been applied if len(x) != 1: I = self._indices cur = self.monomial(y) - for gen,exp in reversed(x._sorted_items()): - for i in range(exp): + for gen, exp in reversed(x._sorted_items()): + for _ in range(exp): cur = self.monomial(I.gen(gen)) * cur return cur @@ -670,8 +670,8 @@ def product_on_basis(self, x, y): # Otherwise we need to commute it along I = self._indices cur = self.monomial(x) - for gen,exp in y._sorted_items(): - for i in range(exp): + for gen, exp in y._sorted_items(): + for _ in range(exp): cur = cur * self.monomial(I.gen(gen)) return cur From adf124483735f8ef246f75393adc76e874d32a61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 19 Apr 2022 17:11:38 +0200 Subject: [PATCH 172/529] allow to use flint for Stirling numbers of both kind --- src/sage/combinat/combinat.py | 81 ++++++++++++++++++++++------------- src/sage/libs/flint/arith.pxd | 6 ++- src/sage/libs/flint/arith.pyx | 50 +++++++++++++++++++++ 3 files changed, 105 insertions(+), 32 deletions(-) diff --git a/src/sage/combinat/combinat.py b/src/sage/combinat/combinat.py index 42fed39d896..15d2705ce9a 100644 --- a/src/sage/combinat/combinat.py +++ b/src/sage/combinat/combinat.py @@ -854,16 +854,23 @@ def lucas_number2(n, P, Q): return libgap.Lucas(P, Q, n)[1].sage() -def stirling_number1(n, k) -> Integer: +def stirling_number1(n, k, algorithm=None) -> Integer: r""" Return the `n`-th Stirling number `S_1(n,k)` of the first kind. This is the number of permutations of `n` points with `k` cycles. - This wraps GAP's ``Stirling1``. - See :wikipedia:`Stirling_numbers_of_the_first_kind`. + INPUT: + + - ``n`` -- nonnegative machine-size integer + - ``k`` -- nonnegative machine-size integer + - ``algorithm``: + + * ``"gap"`` (default) -- use GAP's Stirling1 function + * ``"flint"`` -- use flint's arith_stirling_number_1u function + EXAMPLES:: sage: stirling_number1(3,2) @@ -876,31 +883,49 @@ def stirling_number1(n, k) -> Integer: 269325 Indeed, `S_1(n,k) = S_1(n-1,k-1) + (n-1)S_1(n-1,k)`. + + TESTS:: + + sage: stirling_number1(10,5, algorithm='flint') + 269325 + + sage: s_sage = stirling_number1(50,3, algorithm="mutta") + Traceback (most recent call last): + ... + ValueError: unknown algorithm: mutta """ n = ZZ(n) k = ZZ(k) - from sage.libs.gap.libgap import libgap - return libgap.Stirling1(n, k).sage() + if algorithm is None: + algorithm = 'gap' + if algorithm == 'gap': + from sage.libs.gap.libgap import libgap + return libgap.Stirling1(n, k).sage() + if algorithm == 'flint': + import sage.libs.flint.arith + return sage.libs.flint.arith.stirling_number_1(n, k) + raise ValueError("unknown algorithm: %s" % algorithm) def stirling_number2(n, k, algorithm=None) -> Integer: r""" - Return the `n`-th Stirling number `S_2(n,k)` of the second - kind. + Return the `n`-th Stirling number `S_2(n,k)` of the second kind. This is the number of ways to partition a set of `n` elements into `k` pairwise disjoint nonempty subsets. The `n`-th Bell number is the sum of the `S_2(n,k)`'s, `k=0,...,n`. + See :wikipedia:`Stirling_numbers_of_the_second_kind`. + INPUT: - * ``n`` - nonnegative machine-size integer - * ``k`` - nonnegative machine-size integer - * ``algorithm``: + - ``n`` -- nonnegative machine-size integer + - ``k`` -- nonnegative machine-size integer + - ``algorithm``: - * None (default) - use native implementation - * ``"maxima"`` - use Maxima's stirling2 function - * ``"gap"`` - use GAP's Stirling2 function + * ``None`` (default) -- use native implementation + * ``"flint"`` -- use flint's arith_stirling_number_2 function + * ``"gap"`` -- use GAP's Stirling2 function EXAMPLES: @@ -961,7 +986,7 @@ def stirling_number2(n, k, algorithm=None) -> Integer: 1900842429486 sage: type(n) - sage: n = stirling_number2(20,11,algorithm='maxima') + sage: n = stirling_number2(20,11,algorithm='flint') sage: n 1900842429486 sage: type(n) @@ -969,16 +994,16 @@ def stirling_number2(n, k, algorithm=None) -> Integer: Sage's implementation splitting the computation of the Stirling numbers of the second kind in two cases according to `n`, let us - check the result it gives agree with both maxima and gap. + check the result it gives agree with both flint and gap. For `n<200`:: sage: for n in Subsets(range(100,200), 5).random_element(): ....: for k in Subsets(range(n), 5).random_element(): ....: s_sage = stirling_number2(n,k) - ....: s_maxima = stirling_number2(n,k, algorithm = "maxima") + ....: s_flint = stirling_number2(n,k, algorithm = "flint") ....: s_gap = stirling_number2(n,k, algorithm = "gap") - ....: if not (s_sage == s_maxima and s_sage == s_gap): + ....: if not (s_sage == s_flint and s_sage == s_gap): ....: print("Error with n<200") For `n\geq 200`:: @@ -986,33 +1011,29 @@ def stirling_number2(n, k, algorithm=None) -> Integer: sage: for n in Subsets(range(200,300), 5).random_element(): ....: for k in Subsets(range(n), 5).random_element(): ....: s_sage = stirling_number2(n,k) - ....: s_maxima = stirling_number2(n,k, algorithm = "maxima") + ....: s_flint = stirling_number2(n,k, algorithm = "flint") ....: s_gap = stirling_number2(n,k, algorithm = "gap") - ....: if not (s_sage == s_maxima and s_sage == s_gap): + ....: if not (s_sage == s_flint and s_sage == s_gap): ....: print("Error with n<200") - TESTS: - Checking an exception is raised whenever a wrong value is given - for ``algorithm``:: - - sage: s_sage = stirling_number2(50,3, algorithm = "CloudReading") + sage: s_sage = stirling_number2(50,3, algorithm="namba") Traceback (most recent call last): ... - ValueError: unknown algorithm: CloudReading + ValueError: unknown algorithm: namba """ n = ZZ(n) k = ZZ(k) if algorithm is None: return _stirling_number2(n, k) - elif algorithm == 'gap': + if algorithm == 'gap': from sage.libs.gap.libgap import libgap return libgap.Stirling2(n, k).sage() - elif algorithm == 'maxima': - return ZZ(maxima.stirling2(n, k)) # type:ignore - else: - raise ValueError("unknown algorithm: %s" % algorithm) + if algorithm == 'flint': + import sage.libs.flint.arith + return sage.libs.flint.arith.stirling_number_2(n, k) + raise ValueError("unknown algorithm: %s" % algorithm) def polygonal_number(s, n): diff --git a/src/sage/libs/flint/arith.pxd b/src/sage/libs/flint/arith.pxd index d4c63fcaf13..c8e1fb35566 100644 --- a/src/sage/libs/flint/arith.pxd +++ b/src/sage/libs/flint/arith.pxd @@ -1,13 +1,15 @@ # distutils: libraries = flint # distutils: depends = flint/arith.h -from sage.libs.flint.types cimport fmpz_t, fmpq_t, ulong +from sage.libs.flint.types cimport fmpz_t, fmpq_t, ulong, slong # flint/arith.h cdef extern from "flint_wrap.h": void arith_bell_number(fmpz_t b, ulong n) void arith_bernoulli_number(fmpq_t x, ulong n) - void arith_euler_number ( fmpz_t res , ulong n ) + void arith_euler_number(fmpz_t res, ulong n) + void arith_stirling_number_1u(fmpz_t res, slong n, slong k) + void arith_stirling_number_2(fmpz_t res, slong n, slong k) void arith_number_of_partitions(fmpz_t x, ulong n) void arith_dedekind_sum(fmpq_t, fmpz_t, fmpz_t) void arith_harmonic_number(fmpq_t, unsigned long n) diff --git a/src/sage/libs/flint/arith.pyx b/src/sage/libs/flint/arith.pyx index 4a378ce9862..f24446b4ae4 100644 --- a/src/sage/libs/flint/arith.pyx +++ b/src/sage/libs/flint/arith.pyx @@ -116,6 +116,56 @@ def euler_number(unsigned long n): return ans +def stirling_number_1(long n, long k): + """ + Return the unsigned Stirling number of the first kind. + + EXAMPLES:: + + sage: from sage.libs.flint.arith import stirling_number_1 + sage: [stirling_number_1(8,i) for i in range(9)] + [0, 5040, 13068, 13132, 6769, 1960, 322, 28, 1] + """ + cdef fmpz_t ans_fmpz + cdef Integer ans = Integer(0) + + fmpz_init(ans_fmpz) + + if n > 1000: + sig_on() + arith_stirling_number_1u(ans_fmpz, n, k) + fmpz_get_mpz(ans.value, ans_fmpz) + fmpz_clear(ans_fmpz) + if n > 1000: + sig_off() + return ans + + +def stirling_number_2(long n, long k): + """ + Return the Stirling number of the second kind. + + EXAMPLES:: + + sage: from sage.libs.flint.arith import stirling_number_2 + sage: [stirling_number_2(8,i) for i in range(9)] + [0, 1, 127, 966, 1701, 1050, 266, 28, 1] + """ + cdef fmpz_t ans_fmpz + cdef Integer ans = Integer(0) + + fmpz_init(ans_fmpz) + + if n > 1000: + sig_on() + arith_stirling_number_2(ans_fmpz, n, k) + fmpz_get_mpz(ans.value, ans_fmpz) + fmpz_clear(ans_fmpz) + if n > 1000: + sig_off() + return ans + + def number_of_partitions(unsigned long n): """ Return the number of partitions of the integer `n`. From 722c2db180aa6f8c6d2f1ebf8cda1ff0571abe32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 19 Apr 2022 17:15:30 +0200 Subject: [PATCH 173/529] fix indentation --- src/sage/combinat/combinat.py | 64 +++++++++++++++++------------------ 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/src/sage/combinat/combinat.py b/src/sage/combinat/combinat.py index 15d2705ce9a..3363eb1dbad 100644 --- a/src/sage/combinat/combinat.py +++ b/src/sage/combinat/combinat.py @@ -889,10 +889,10 @@ def stirling_number1(n, k, algorithm=None) -> Integer: sage: stirling_number1(10,5, algorithm='flint') 269325 - sage: s_sage = stirling_number1(50,3, algorithm="mutta") - Traceback (most recent call last): - ... - ValueError: unknown algorithm: mutta + sage: s_sage = stirling_number1(50,3, algorithm="mutta") + Traceback (most recent call last): + ... + ValueError: unknown algorithm: mutta """ n = ZZ(n) k = ZZ(k) @@ -947,10 +947,10 @@ def stirling_number2(n, k, algorithm=None) -> Integer: Stirling numbers satisfy `S_2(n,k) = S_2(n-1,k-1) + kS_2(n-1,k)`:: - sage: 5*stirling_number2(9,5) + stirling_number2(9,4) - 42525 - sage: stirling_number2(10,5) - 42525 + sage: 5*stirling_number2(9,5) + stirling_number2(9,4) + 42525 + sage: stirling_number2(10,5) + 42525 TESTS:: @@ -992,36 +992,36 @@ def stirling_number2(n, k, algorithm=None) -> Integer: sage: type(n) - Sage's implementation splitting the computation of the Stirling - numbers of the second kind in two cases according to `n`, let us - check the result it gives agree with both flint and gap. + Sage's implementation splitting the computation of the Stirling + numbers of the second kind in two cases according to `n`, let us + check the result it gives agree with both flint and gap. - For `n<200`:: + For `n<200`:: - sage: for n in Subsets(range(100,200), 5).random_element(): - ....: for k in Subsets(range(n), 5).random_element(): - ....: s_sage = stirling_number2(n,k) - ....: s_flint = stirling_number2(n,k, algorithm = "flint") - ....: s_gap = stirling_number2(n,k, algorithm = "gap") - ....: if not (s_sage == s_flint and s_sage == s_gap): - ....: print("Error with n<200") + sage: for n in Subsets(range(100,200), 5).random_element(): + ....: for k in Subsets(range(n), 5).random_element(): + ....: s_sage = stirling_number2(n,k) + ....: s_flint = stirling_number2(n,k, algorithm = "flint") + ....: s_gap = stirling_number2(n,k, algorithm = "gap") + ....: if not (s_sage == s_flint and s_sage == s_gap): + ....: print("Error with n<200") - For `n\geq 200`:: + For `n\geq 200`:: - sage: for n in Subsets(range(200,300), 5).random_element(): - ....: for k in Subsets(range(n), 5).random_element(): - ....: s_sage = stirling_number2(n,k) - ....: s_flint = stirling_number2(n,k, algorithm = "flint") - ....: s_gap = stirling_number2(n,k, algorithm = "gap") - ....: if not (s_sage == s_flint and s_sage == s_gap): - ....: print("Error with n<200") + sage: for n in Subsets(range(200,300), 5).random_element(): + ....: for k in Subsets(range(n), 5).random_element(): + ....: s_sage = stirling_number2(n,k) + ....: s_flint = stirling_number2(n,k, algorithm = "flint") + ....: s_gap = stirling_number2(n,k, algorithm = "gap") + ....: if not (s_sage == s_flint and s_sage == s_gap): + ....: print("Error with n<200") - TESTS: + TESTS: - sage: s_sage = stirling_number2(50,3, algorithm="namba") - Traceback (most recent call last): - ... - ValueError: unknown algorithm: namba + sage: s_sage = stirling_number2(50,3, algorithm="namba") + Traceback (most recent call last): + ... + ValueError: unknown algorithm: namba """ n = ZZ(n) k = ZZ(k) From 384ac6eb47efd51f63297a9bf165534bbe29c01d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 19 Apr 2022 17:17:01 +0200 Subject: [PATCH 174/529] remove duplicate TEST --- src/sage/combinat/combinat.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/sage/combinat/combinat.py b/src/sage/combinat/combinat.py index 3363eb1dbad..ae86cf37315 100644 --- a/src/sage/combinat/combinat.py +++ b/src/sage/combinat/combinat.py @@ -1016,8 +1016,6 @@ def stirling_number2(n, k, algorithm=None) -> Integer: ....: if not (s_sage == s_flint and s_sage == s_gap): ....: print("Error with n<200") - TESTS: - sage: s_sage = stirling_number2(50,3, algorithm="namba") Traceback (most recent call last): ... From bdc5b914eb95d6aaa568dde17bf2d1eab2f74237 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Tue, 19 Apr 2022 20:12:50 +0000 Subject: [PATCH 175/529] Cleanup --- .gitpod.yml | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/.gitpod.yml b/.gitpod.yml index 16e2f0586ee..1546cd23f99 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -1,30 +1,6 @@ # Use minimal Ubuntu installation that includes mamba image: condaforge/mambaforge -# We use the following layout: -# -# $HOME/sage Source tree used by the Docker build; see SAGE_ROOT/tox.ini (gitpod). -# - We delete it in every invocation of the 'before' script -# and replace it by a symlink to /workspace/... -# (This symlink is needed because the package-removal scripts -# ({prefix,venv}/var/lib/sage/scripts/*/{spkg-piprm,spkg-prerm,spkg-postrm) -# hardcode SAGE_ROOT and SAGE_SRC from package installation time) -# $HOME/sage/logs Logs of the Docker build. -# - In the first invocation of the 'before' script, we move it -# to /workspace/.../logs -# $HOME/sage-local The configured prefix (SAGE_LOCAL) of the Sage installation. -# - During the Docker build, this is the physical location. -# - In the first invocation of the 'before' script, we move it -# to the new physical location /workspace/.../local -# (because gitpod only preserves the contents of /workspace) -# and replace it by a symlink to the new physical location. -# - In subsequent invocations of the 'before' script, we -# remove it and replace it by a symlink to the physical -# location /workspace/.../local -# /worktree/.../local The physical location of the Sage installation, -# established in the first run of the 'before' script and -# preserved by gitpod. - # Start up tasks. https://www.gitpod.io/docs/config-start-tasks/ tasks: - name: Setup From ea0a92e3956d63be8e819bf84fff08c762580adf Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Tue, 19 Apr 2022 20:13:37 +0000 Subject: [PATCH 176/529] Activate conda env in cmd task --- .gitpod.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitpod.yml b/.gitpod.yml index 1546cd23f99..cd689be86f7 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -16,6 +16,9 @@ tasks: pip install --no-build-isolation -v -v -e src command: | + # Activate conda environment + conda activate /workspace/sagetrac-mirror/venv + # Setup trac as remote ## In order to push to trac, generate a new key with `ssh-keygen -f tempkey` and save the private key to gitpod `gp env PRIVATE_SSH_KEY="$( Date: Tue, 19 Apr 2022 20:31:19 +0000 Subject: [PATCH 177/529] Start ssh agent --- .gitpod.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitpod.yml b/.gitpod.yml index cd689be86f7..5865e65ae63 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -25,12 +25,15 @@ tasks: ## Afterwards, create a new gitpod workspace. git remote remove trac 2> /dev/null # might still exists from a previous run/prebuild if [[ -n "${PRIVATE_SSH_KEY}" ]]; then + # Start ssh agent + eval $(ssh-agent -s) + # Setup ssh key for authentication with trac mkdir -p ~/.ssh echo $PRIVATE_SSH_KEY | sed 's/\(-----\(BEGIN\|END\) OPENSSH PRIVATE KEY-----\)/\n\1\n/g' > ~/.ssh/id_rsa sed -i '/^$/d' ~/.ssh/id_rsa chmod 600 ~/.ssh/id_rsa - unset PRIVATE_SSH_KEY + ssh-add ~/.ssh/id_rsa ssh-keyscan -H trac.sagemath.org >> ~/.ssh/known_hosts # Setup trac repo From 617b443c5a78abed98c45b299f67fad23db9b204 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Tue, 19 Apr 2022 21:20:05 +0000 Subject: [PATCH 178/529] Enable deprecated rsa algo --- .gitpod.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.gitpod.yml b/.gitpod.yml index 5865e65ae63..6f103e44672 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -25,15 +25,12 @@ tasks: ## Afterwards, create a new gitpod workspace. git remote remove trac 2> /dev/null # might still exists from a previous run/prebuild if [[ -n "${PRIVATE_SSH_KEY}" ]]; then - # Start ssh agent - eval $(ssh-agent -s) - # Setup ssh key for authentication with trac mkdir -p ~/.ssh echo $PRIVATE_SSH_KEY | sed 's/\(-----\(BEGIN\|END\) OPENSSH PRIVATE KEY-----\)/\n\1\n/g' > ~/.ssh/id_rsa sed -i '/^$/d' ~/.ssh/id_rsa chmod 600 ~/.ssh/id_rsa - ssh-add ~/.ssh/id_rsa + echo "PubkeyAcceptedKeyTypes +ssh-rsa" > ~/.ssh/config ssh-keyscan -H trac.sagemath.org >> ~/.ssh/known_hosts # Setup trac repo From 6323a380d6c1952ef4a0d312002afe642097b968 Mon Sep 17 00:00:00 2001 From: Jean-Florent Raymond Date: Wed, 20 Apr 2022 10:00:50 +0200 Subject: [PATCH 179/529] 33639: use of lazy import + examples --- src/sage/graphs/graph_editor.py | 60 +++++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 14 deletions(-) diff --git a/src/sage/graphs/graph_editor.py b/src/sage/graphs/graph_editor.py index 4246b3c441f..daf0ea9e47e 100644 --- a/src/sage/graphs/graph_editor.py +++ b/src/sage/graphs/graph_editor.py @@ -1,8 +1,16 @@ r""" -Graph editor +Graph editor widget + +The ``phitigra`` package should be installed on your Sage installation. + +AUTHORS: + +- Radoslav Kirov (2009) -- initial version of the editor for use with sagenb +- Jean-Florent Raymond (2022) -- replacement with the ``phitigra`` package + """ # **************************************************************************** -# Copyright (C) 2021 Jean-Florent Raymond +# Copyright (C) 2022 Jean-Florent Raymond # # Distributed under the terms of the GNU General Public License (GPL) # @@ -16,33 +24,57 @@ # https://www.gnu.org/licenses/ # **************************************************************************** +from sage.misc.lazy_import import lazy_import +from sage.features import PythonModule +lazy_import('phitigra', 'GraphEditor', + feature=PythonModule('phitigra', spkg='phitigra')) + -def graph_editor(graph=None, **editor_options): +def graph_editor(graph=None, **display_options): """ - Open a graph editor in the Jupyter notebook. + Return a graph editor widget. INPUT: - ``graph`` - a :class:`Graph` instance (default: `None'); the graph to edit. - - ``layout_options`` - options for the editor. + - ``display_options`` - options for the widget. + + The graph editor widget can be displayed with Jupyter or JupyterLab. + It is provided by the `phitigra` optional package, see + https://github.com/jfraymond/phitigra for details about the + possible options (changing the width/height of the canvas, the + default size and color of vertices, etc.). EXAMPLES:: - sage: g = graphs.CompleteGraph(3) - sage: graph_editor(g) # not tested - sage: graph_editor(graphs.HouseGraph()) # not tested - sage: h = graphs.StarGraph(6) + sage: e = graph_editor() + sage: e.show() # not tested + + Opening an existing graph:: + + sage: G = graphs.PetersenGraph() + sage: e = graph_editor(G) + sage: e.show() # not tested + + Retrieving a copy of the drawn graph:: + + sage: G = graphs.RandomGNP(10, 0.5) + sage: e = graph_editor(G) + sage: H = e.get_graph() + sage: H == G and not H is G + True + + Use different display options:: + + sage: e = graph_editor(graphs.PetersenGraph(), width=300, height=300, default_radius=12, default_vertex_color='orange', default_edge_color='#666', show_vertex_labels=False) + sage: e.show() # not tested """ - try: - from phitigra import GraphEditor - except ModuleNotFoundError: - raise ModuleNotFoundError("The graph editor is provided by the optional package phitigra, which currently not installed.") from .graph import Graph if graph is None: graph = Graph(0) - return GraphEditor(graph, **editor_options) + return GraphEditor(graph, **display_options) From 8a58884c62b4ee6c4d0ad47a8ff40e2ce8fb6863 Mon Sep 17 00:00:00 2001 From: Jean-Florent Raymond Date: Wed, 20 Apr 2022 11:04:16 +0200 Subject: [PATCH 180/529] 33639: minor improvements in documentation --- src/sage/graphs/graph_editor.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/sage/graphs/graph_editor.py b/src/sage/graphs/graph_editor.py index daf0ea9e47e..a959a9cfaf6 100644 --- a/src/sage/graphs/graph_editor.py +++ b/src/sage/graphs/graph_editor.py @@ -7,7 +7,6 @@ - Radoslav Kirov (2009) -- initial version of the editor for use with sagenb - Jean-Florent Raymond (2022) -- replacement with the ``phitigra`` package - """ # **************************************************************************** # Copyright (C) 2022 Jean-Florent Raymond @@ -36,13 +35,13 @@ def graph_editor(graph=None, **display_options): INPUT: - - ``graph`` - a :class:`Graph` instance (default: `None'); the + - ``graph`` - a :class:`Graph` instance (default: ``None``); the graph to edit. - ``display_options`` - options for the widget. The graph editor widget can be displayed with Jupyter or JupyterLab. - It is provided by the `phitigra` optional package, see + It is provided by the ``phitigra`` optional package, see https://github.com/jfraymond/phitigra for details about the possible options (changing the width/height of the canvas, the default size and color of vertices, etc.). @@ -66,7 +65,7 @@ def graph_editor(graph=None, **display_options): sage: H == G and not H is G True - Use different display options:: + Using different display options:: sage: e = graph_editor(graphs.PetersenGraph(), width=300, height=300, default_radius=12, default_vertex_color='orange', default_edge_color='#666', show_vertex_labels=False) sage: e.show() # not tested From dee54036d85b37c56fad81cb707a1e21407ba57f Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 20 Apr 2022 10:05:51 +0000 Subject: [PATCH 181/529] Tell conda about our env --- .gitpod.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitpod.yml b/.gitpod.yml index 6f103e44672..de1a2a6b06b 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -7,6 +7,7 @@ tasks: init: | # Create conda environment mamba env create --file src/environment-dev.yml --prefix venv + conda config --append envs_dirs /workspace/sagetrac-mirror conda activate /workspace/sagetrac-mirror/venv # Build sage From ce2cc77dc451a884fddbded1e16b0b6b0895ad6b Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 20 Apr 2022 10:06:11 +0000 Subject: [PATCH 182/529] Add testing and linting to env --- .vscode/settings.json | 2 ++ src/environment-dev.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/.vscode/settings.json b/.vscode/settings.json index 5844f80998f..05cf388c093 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -19,4 +19,6 @@ "src" ], "python.testing.unittestEnabled": false, + "python.linting.pycodestyleEnabled": true, + "python.linting.enabled": true, } diff --git a/src/environment-dev.yml b/src/environment-dev.yml index 31f80ec7399..f16d0b4f589 100644 --- a/src/environment-dev.yml +++ b/src/environment-dev.yml @@ -201,3 +201,5 @@ dependencies: - libtool # Additional dev tools - openssh + - pycodestyle + - pytest From f2adae67566313d5fe58e0a1b283d44eab642c03 Mon Sep 17 00:00:00 2001 From: Jean-Florent Raymond Date: Wed, 20 Apr 2022 12:08:07 +0200 Subject: [PATCH 183/529] 33639: added live widget examples in the docstrings with ".. JUPYTER-EXECUTE" --- src/sage/graphs/graph_editor.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/sage/graphs/graph_editor.py b/src/sage/graphs/graph_editor.py index a959a9cfaf6..63d05890c12 100644 --- a/src/sage/graphs/graph_editor.py +++ b/src/sage/graphs/graph_editor.py @@ -53,10 +53,17 @@ def graph_editor(graph=None, **display_options): Opening an existing graph:: - sage: G = graphs.PetersenGraph() + sage: G = graphs.RandomGNP(10, 0.5) sage: e = graph_editor(G) sage: e.show() # not tested + .. ONLY:: html + + .. JUPYTER-EXECUTE:: + :hide-code: + + graph_editor(graphs.RandomGNP(10, 0.5)).show() + Retrieving a copy of the drawn graph:: sage: G = graphs.RandomGNP(10, 0.5) @@ -69,6 +76,13 @@ def graph_editor(graph=None, **display_options): sage: e = graph_editor(graphs.PetersenGraph(), width=300, height=300, default_radius=12, default_vertex_color='orange', default_edge_color='#666', show_vertex_labels=False) sage: e.show() # not tested + + .. ONLY:: html + + .. JUPYTER-EXECUTE:: + :hide-code: + + graph_editor(graphs.PetersenGraph(), width=300, height=300, default_radius=12, default_vertex_color='orange', default_edge_color='#666', show_vertex_labels=False).show() """ from .graph import Graph From 9d6374e52b28ddc61f132b2039e9397ab6944ef4 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 20 Apr 2022 11:32:44 +0000 Subject: [PATCH 184/529] Add esbonio --- src/environment-dev.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/environment-dev.yml b/src/environment-dev.yml index f16d0b4f589..6eadda66b05 100644 --- a/src/environment-dev.yml +++ b/src/environment-dev.yml @@ -203,3 +203,4 @@ dependencies: - openssh - pycodestyle - pytest + - esbonio From a8aaf487526b7a0c6f50fb243ef145d22cb98b48 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 20 Apr 2022 11:34:44 +0000 Subject: [PATCH 185/529] Add conda config also in cmd to persist it --- .gitpod.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitpod.yml b/.gitpod.yml index de1a2a6b06b..32d536b2f68 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -18,6 +18,7 @@ tasks: command: | # Activate conda environment + conda config --append envs_dirs /workspace/sagetrac-mirror conda activate /workspace/sagetrac-mirror/venv # Setup trac as remote From 2970e5e6f859ff90dd5a16428f3c89d66dcc69fc Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 20 Apr 2022 18:50:21 +0000 Subject: [PATCH 186/529] Install esbonio via pip --- .gitpod.yml | 2 ++ src/environment-dev.yml | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitpod.yml b/.gitpod.yml index 32d536b2f68..f04efbeea31 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -9,6 +9,8 @@ tasks: mamba env create --file src/environment-dev.yml --prefix venv conda config --append envs_dirs /workspace/sagetrac-mirror conda activate /workspace/sagetrac-mirror/venv + ## Install esbonio via pip as long as there is no conda package for it: https://github.com/swyddfa/esbonio/issues/371 + pip install esbonio # Build sage ./bootstrap diff --git a/src/environment-dev.yml b/src/environment-dev.yml index 6eadda66b05..f16d0b4f589 100644 --- a/src/environment-dev.yml +++ b/src/environment-dev.yml @@ -203,4 +203,3 @@ dependencies: - openssh - pycodestyle - pytest - - esbonio From f9169c7437f64f1bccc1bd3ad66c28fea984add9 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 20 Apr 2022 21:25:18 +0000 Subject: [PATCH 187/529] Try to auto-activate conda env --- .gitpod.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitpod.yml b/.gitpod.yml index f04efbeea31..210dab82b53 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -11,6 +11,7 @@ tasks: conda activate /workspace/sagetrac-mirror/venv ## Install esbonio via pip as long as there is no conda package for it: https://github.com/swyddfa/esbonio/issues/371 pip install esbonio + echo 'conda activate /workspace/sagetrac-mirror/venv' >> ~/.bash_profile # Build sage ./bootstrap From 5f2c355eaeac3b299d7dc808076dfacda99af56d Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 20 Apr 2022 21:51:43 +0000 Subject: [PATCH 188/529] Add jupyter_sphinx for esbonio --- src/environment-dev.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/environment-dev.yml b/src/environment-dev.yml index f16d0b4f589..6d99447b852 100644 --- a/src/environment-dev.yml +++ b/src/environment-dev.yml @@ -203,3 +203,4 @@ dependencies: - openssh - pycodestyle - pytest + - jupyter_sphinx From 9c3b38b80e2203b221fbe88a73f2bf30ae812bb6 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 20 Apr 2022 22:05:46 +0000 Subject: [PATCH 189/529] Try to set path in docker image --- .gitpod.yml | 3 ++- docker/.gitpod.Dockerfile | 15 +++------------ 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/.gitpod.yml b/.gitpod.yml index 210dab82b53..1e727383ae0 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -1,5 +1,6 @@ # Use minimal Ubuntu installation that includes mamba -image: condaforge/mambaforge +image: + file: .gitpod.Dockerfile # Start up tasks. https://www.gitpod.io/docs/config-start-tasks/ tasks: diff --git a/docker/.gitpod.Dockerfile b/docker/.gitpod.Dockerfile index 56f2370ea0d..7939c88dfd0 100644 --- a/docker/.gitpod.Dockerfile +++ b/docker/.gitpod.Dockerfile @@ -1,12 +1,3 @@ -ARG BASE_GITHUB_REPOSITORY=sagemath/sage -ARG BASE_TAG=dev -FROM ghcr.io/${BASE_GITHUB_REPOSITORY}/sage-docker-gitpod-standard-with-targets:${BASE_TAG} as with-targets -RUN sudo rm -rf /var/cache/debconf/* /var/lib/apt/lists/* /tmp/* /var/tmp/* -# Fast doc rebuilds do not work because -# "loading pickled environment... failed; source directory has changed" -# Until this is fixed, we can as well remove the whole documentation, which saves a lot of space. -RUN rm -Rf /home/gitpod/sage-local/share/doc/sage - -FROM ghcr.io/${BASE_GITHUB_REPOSITORY}/sage-docker-gitpod-standard-with-system-packages:${BASE_TAG} -COPY --chown=gitpod:gitpod --from=with-targets /home/gitpod/sage/logs /home/gitpod/sage/logs -COPY --chown=gitpod:gitpod --from=with-targets /home/gitpod/sage-local /home/gitpod/sage-local +FROM condaforge/mambaforge +ENV PATH $PATH:/workspace/sagetrac-mirror/venv/bin +USER gitpod \ No newline at end of file From abf784e89037346fc8f7a5ad7fc774b24c34b233 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 20 Apr 2022 22:18:31 +0000 Subject: [PATCH 190/529] Fix path to docker file --- .gitpod.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitpod.yml b/.gitpod.yml index 1e727383ae0..bccea4bafdd 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -1,6 +1,6 @@ # Use minimal Ubuntu installation that includes mamba image: - file: .gitpod.Dockerfile + file: docker/.gitpod.Dockerfile # Start up tasks. https://www.gitpod.io/docs/config-start-tasks/ tasks: From 005f923365b17f27e7c4e1b92029185bccb401a8 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 11 Jun 2021 13:14:05 -0700 Subject: [PATCH 191/529] build/pkgs/markupsafe: Update to 2.0.1 --- build/pkgs/markupsafe/checksums.ini | 9 +++++---- build/pkgs/markupsafe/package-version.txt | 2 +- build/pkgs/markupsafe/spkg-install.in | 12 ------------ 3 files changed, 6 insertions(+), 17 deletions(-) diff --git a/build/pkgs/markupsafe/checksums.ini b/build/pkgs/markupsafe/checksums.ini index 3f0471b552e..8037d765361 100644 --- a/build/pkgs/markupsafe/checksums.ini +++ b/build/pkgs/markupsafe/checksums.ini @@ -1,4 +1,5 @@ -tarball=markupsafe-VERSION.tar.gz -sha1=f70e5fd3c120a1b108d4347ea1115e3962c42026 -md5=43fd756864fe42063068e092e220c57b -cksum=310980784 +tarball=MarkupSafe-VERSION.tar.gz +sha1=e1b766b2b1601fde67b3b19ed2f13b9746bb1cca +md5=892e0fefa3c488387e5cc0cad2daa523 +cksum=124987148 +upstream_url=https://pypi.io/packages/source/m/markupsafe/MarkupSafe-VERSION.tar.gz diff --git a/build/pkgs/markupsafe/package-version.txt b/build/pkgs/markupsafe/package-version.txt index 524cb55242b..38f77a65b30 100644 --- a/build/pkgs/markupsafe/package-version.txt +++ b/build/pkgs/markupsafe/package-version.txt @@ -1 +1 @@ -1.1.1 +2.0.1 diff --git a/build/pkgs/markupsafe/spkg-install.in b/build/pkgs/markupsafe/spkg-install.in index b9bfecbfd50..37ac1a53437 100644 --- a/build/pkgs/markupsafe/spkg-install.in +++ b/build/pkgs/markupsafe/spkg-install.in @@ -1,14 +1,2 @@ -if [ -z "$SAGE_LOCAL" ]; then - echo >&2 "SAGE_LOCAL undefined ... exiting" - echo >&2 "Maybe run 'sage --sh'?" - exit 1 -fi - cd src - sdh_pip_install . - -if [ $? -ne 0 ]; then - echo "Error installing markupsafe ... exiting" - exit 1 -fi From 3fd3429919fe2df3c3698200682649e5de90fa3c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 11 Jun 2021 13:15:54 -0700 Subject: [PATCH 192/529] build/pkgs/jinja2: Update to 3.0.1 --- build/pkgs/jinja2/checksums.ini | 10 +++++----- build/pkgs/jinja2/package-version.txt | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/build/pkgs/jinja2/checksums.ini b/build/pkgs/jinja2/checksums.ini index e84600dd23a..e8ed52c3b83 100644 --- a/build/pkgs/jinja2/checksums.ini +++ b/build/pkgs/jinja2/checksums.ini @@ -1,5 +1,5 @@ -tarball=jinja2-VERSION.tar.gz -sha1=1017138fd4cb627204d3109b75c107c3d6f3f7fb -md5=0362203b22547abca06ed1082bc1e7b4 -cksum=1208782876 -upstream_url=https://pypi.io/packages/source/J/Jinja2/Jinja2-VERSION.tar.gz +tarball=Jinja2-VERSION.tar.gz +sha1=f001b6056a0d95c5d1ff1cec7a0df22426de8ed3 +md5=25ba6ef98c164878acff1036fbd72a1d +cksum=3023773642 +upstream_url=https://pypi.io/packages/source/j/jinja2/Jinja2-VERSION.tar.gz diff --git a/build/pkgs/jinja2/package-version.txt b/build/pkgs/jinja2/package-version.txt index 9e5bb77a3ba..cb2b00e4f7a 100644 --- a/build/pkgs/jinja2/package-version.txt +++ b/build/pkgs/jinja2/package-version.txt @@ -1 +1 @@ -2.11.2 +3.0.1 From dd9604c6764e676aa006cef20363cf639cff95e4 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 20 Apr 2022 21:24:25 -0700 Subject: [PATCH 193/529] build/pkgs/jinja2: Update to 3.1.1 --- build/pkgs/jinja2/checksums.ini | 6 +++--- build/pkgs/jinja2/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/jinja2/checksums.ini b/build/pkgs/jinja2/checksums.ini index e8ed52c3b83..1e2005c59d9 100644 --- a/build/pkgs/jinja2/checksums.ini +++ b/build/pkgs/jinja2/checksums.ini @@ -1,5 +1,5 @@ tarball=Jinja2-VERSION.tar.gz -sha1=f001b6056a0d95c5d1ff1cec7a0df22426de8ed3 -md5=25ba6ef98c164878acff1036fbd72a1d -cksum=3023773642 +sha1=40278c4dfbbd6d21dc570bee0c63e32504e5442e +md5=964afcd0853f67f20f7b2e34e5935564 +cksum=380272436 upstream_url=https://pypi.io/packages/source/j/jinja2/Jinja2-VERSION.tar.gz diff --git a/build/pkgs/jinja2/package-version.txt b/build/pkgs/jinja2/package-version.txt index cb2b00e4f7a..94ff29cc4de 100644 --- a/build/pkgs/jinja2/package-version.txt +++ b/build/pkgs/jinja2/package-version.txt @@ -1 +1 @@ -3.0.1 +3.1.1 From 6dbbf393d0271d9a946441100b49e0cc3162f4db Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 20 Apr 2022 21:26:10 -0700 Subject: [PATCH 194/529] build/pkgs/markupsafe: Update to 2.1.1 --- build/pkgs/markupsafe/checksums.ini | 6 +++--- build/pkgs/markupsafe/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/markupsafe/checksums.ini b/build/pkgs/markupsafe/checksums.ini index 8037d765361..5939d7266eb 100644 --- a/build/pkgs/markupsafe/checksums.ini +++ b/build/pkgs/markupsafe/checksums.ini @@ -1,5 +1,5 @@ tarball=MarkupSafe-VERSION.tar.gz -sha1=e1b766b2b1601fde67b3b19ed2f13b9746bb1cca -md5=892e0fefa3c488387e5cc0cad2daa523 -cksum=124987148 +sha1=8bd9855f5b92145b6bc0d38cc241d0253cccc5a8 +md5=9809f9fdd98bc835b0c21aa8f79cbf30 +cksum=928883078 upstream_url=https://pypi.io/packages/source/m/markupsafe/MarkupSafe-VERSION.tar.gz diff --git a/build/pkgs/markupsafe/package-version.txt b/build/pkgs/markupsafe/package-version.txt index 38f77a65b30..3e3c2f1e5ed 100644 --- a/build/pkgs/markupsafe/package-version.txt +++ b/build/pkgs/markupsafe/package-version.txt @@ -1 +1 @@ -2.0.1 +2.1.1 From a1602c9b06c66281c9221a79d1e4857e48db8ed9 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Thu, 21 Apr 2022 11:01:02 +0000 Subject: [PATCH 195/529] Disable python recommendation dialog --- .gitpod.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitpod.yml b/.gitpod.yml index bccea4bafdd..8e19fd993c3 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -25,6 +25,10 @@ tasks: conda config --append envs_dirs /workspace/sagetrac-mirror conda activate /workspace/sagetrac-mirror/venv + # RestructuredText extension recommends python extension, although we have already installed it + ## So disable the recommendation dialog + echo "{\"restructuredtext.pythonRecommendation.disabled\": true}" > /workspace/.vscode-remote/data/Machine/settings.json + # Setup trac as remote ## In order to push to trac, generate a new key with `ssh-keygen -f tempkey` and save the private key to gitpod `gp env PRIVATE_SSH_KEY="$( Date: Thu, 21 Apr 2022 11:26:25 +0000 Subject: [PATCH 196/529] Cleanup --- .gitpod.yml | 5 +++-- docker/.gitpod.Dockerfile | 5 ++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.gitpod.yml b/.gitpod.yml index 8e19fd993c3..3bb3366443a 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -1,4 +1,4 @@ -# Use minimal Ubuntu installation that includes mamba +# Use custom docker image. https://www.gitpod.io/docs/config-docker image: file: docker/.gitpod.Dockerfile @@ -12,7 +12,6 @@ tasks: conda activate /workspace/sagetrac-mirror/venv ## Install esbonio via pip as long as there is no conda package for it: https://github.com/swyddfa/esbonio/issues/371 pip install esbonio - echo 'conda activate /workspace/sagetrac-mirror/venv' >> ~/.bash_profile # Build sage ./bootstrap @@ -66,6 +65,8 @@ vscode: - lextudio.restructuredtext - streetsidesoftware.code-spell-checker - ms-toolsai.jupyter + - ms-toolsai.jupyter-keymap + - ms-toolsai.jupyter-renderers # https://www.gitpod.io/docs/prebuilds#github-specific-configuration github: diff --git a/docker/.gitpod.Dockerfile b/docker/.gitpod.Dockerfile index 7939c88dfd0..ff17d331515 100644 --- a/docker/.gitpod.Dockerfile +++ b/docker/.gitpod.Dockerfile @@ -1,3 +1,6 @@ +# Use minimal Ubuntu installation that includes mamba FROM condaforge/mambaforge +# Workaround so that vscode internals (such as git) find things installed in the conda env (notably ssh which is required to contribute to trac) ENV PATH $PATH:/workspace/sagetrac-mirror/venv/bin -USER gitpod \ No newline at end of file +# Default to non-admin user +USER gitpod From bd2f3d3bc7829f1ccc30f1aa274259d8ab138603 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Thu, 21 Apr 2022 11:28:47 +0000 Subject: [PATCH 197/529] Remove gitpod docker image build --- .github/workflows/tox.yml | 2 +- tox.ini | 16 ---------------- 2 files changed, 1 insertion(+), 17 deletions(-) diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index 3050255d228..ef221e42719 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -38,7 +38,7 @@ jobs: fail-fast: false max-parallel: 20 matrix: - tox_system_factor: [gitpod, ubuntu-trusty, ubuntu-xenial, ubuntu-bionic, ubuntu-focal, ubuntu-hirsute, ubuntu-impish, ubuntu-jammy, debian-stretch, debian-buster, debian-bullseye, debian-bookworm, debian-sid, linuxmint-17, linuxmint-18, linuxmint-19, linuxmint-19.3, linuxmint-20.1, linuxmint-20.2, linuxmint-20.3, fedora-26, fedora-27, fedora-28, fedora-29, fedora-30, fedora-31, fedora-32, fedora-33, fedora-34, fedora-35, fedora-36, centos-7, centos-stream-8, gentoo-python3.9, gentoo-python3.10, archlinux-latest, opensuse-15.3, opensuse-tumbleweed, slackware-14.2, conda-forge, ubuntu-bionic-i386, manylinux-2_24-i686, debian-buster-i386, centos-7-i386] + tox_system_factor: [ubuntu-trusty, ubuntu-xenial, ubuntu-bionic, ubuntu-focal, ubuntu-hirsute, ubuntu-impish, ubuntu-jammy, debian-stretch, debian-buster, debian-bullseye, debian-bookworm, debian-sid, linuxmint-17, linuxmint-18, linuxmint-19, linuxmint-19.3, linuxmint-20.1, linuxmint-20.2, linuxmint-20.3, fedora-26, fedora-27, fedora-28, fedora-29, fedora-30, fedora-31, fedora-32, fedora-33, fedora-34, fedora-35, fedora-36, centos-7, centos-stream-8, gentoo-python3.9, gentoo-python3.10, archlinux-latest, opensuse-15.3, opensuse-tumbleweed, slackware-14.2, conda-forge, ubuntu-bionic-i386, manylinux-2_24-i686, debian-buster-i386, centos-7-i386] tox_packages_factor: [minimal, standard] env: TOX_ENV: docker-${{ matrix.tox_system_factor }}-${{ matrix.tox_packages_factor }} diff --git a/tox.ini b/tox.ini index 47c10c364ef..d0975b516dc 100644 --- a/tox.ini +++ b/tox.ini @@ -438,22 +438,6 @@ setenv = ubuntu-bionic-nvidia-cuda: BASE_TAG=ubuntu18.04 ubuntu-xenial-nvidia-cuda: BASE_TAG=ubuntu16.04 # - # https://hub.docker.com/r/gitpod/ - # - gitpod: SYSTEM=debian - gitpod: BASE_IMAGE=gitpod/workspace-base - gitpod-full: BASE_IMAGE=gitpod/workspace-full - gitpod: CONFIG_CONFIGURE_ARGS_ROOT=--prefix=/home/gitpod/sage-local --with-sage-venv - gitpod: __SUDO=--sudo - gitpod: __CHOWN=--chown=gitpod:gitpod - # Play safe and make sure that the image build succeeds even - # if packages that do not exist on ubuntu-focal are added to debian.txt - gitpod: IGNORE_MISSING_SYSTEM_PACKAGES=yes - # As of 2022-01, gitpod/workspace-base is based on ubuntu-focal. - # To save space, we filter out some packages that are too old and - # will be rejected by our configure script. - gitpod-standard: SAGE_PACKAGE_LIST_ARGS=--has-file=spkg-configure.m4 :standard: --exclude pari --exclude eclib --exclude lcalc --exclude giac --exclude singular - # # Resulting full image:tag name # docker: FULL_BASE_IMAGE_AND_TAG={env:ARCH_IMAGE_PREFIX:}{env:BASE_IMAGE}{env:ARCH_IMAGE_SUFFIX:}:{env:ARCH_TAG_PREFIX:}{env:BASE_TAG}{env:ARCH_TAG_SUFFIX:} From 413b081b16ace2392d362ed54d12f166ad30cf6a Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Thu, 21 Apr 2022 11:54:53 +0000 Subject: [PATCH 198/529] Add conda dev environment --- src/doc/bootstrap | 14 ++- src/environment-dev.yml | 206 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 219 insertions(+), 1 deletion(-) create mode 100644 src/environment-dev.yml diff --git a/src/doc/bootstrap b/src/doc/bootstrap index 4a85f15d57e..a00811223fa 100755 --- a/src/doc/bootstrap +++ b/src/doc/bootstrap @@ -65,7 +65,7 @@ for SYSTEM in arch debian fedora cygwin homebrew conda; do done if [ "${SYSTEM}" = "conda" ]; then if [ "${BOOTSTRAP_QUIET}" = "no" ]; then - echo >&2 $0:$LINENO: installing environment.yml, environment-optional.yml, src/environment.yml and src/environment-optional.yml + echo >&2 $0:$LINENO: generate conda enviroment files fi echo "name: sage-build" > environment.yml echo "channels:" >> environment.yml @@ -79,6 +79,18 @@ for SYSTEM in arch debian fedora cygwin homebrew conda; do for pkg in $SAGELIB_SYSTEM_PACKAGES; do echo " - $pkg" >> src/environment.yml done + sed 's/name: sage/name: sage-dev/' src/environment.yml > src/environment-dev.yml + echo " # Packages needed for ./bootstrap" >> src/environment-dev.yml + BOOTSTRAP_PACKAGES=$(echo $(${STRIP_COMMENTS} build/pkgs/_bootstrap/distros/conda.txt)) + for pkg in $BOOTSTRAP_PACKAGES; do + echo " - $pkg" >> src/environment-dev.yml + done + echo " # Additional dev tools" >> src/environment-dev.yml + echo " - openssh" >> src/environment-dev.yml + echo " - pycodestyle" >> src/environment-dev.yml + echo " - pytest" >> src/environment-dev.yml + echo " - jupyter_sphinx" >> src/environment-dev.yml + cp environment.yml environment-optional.yml echo " # optional packages" >> environment-optional.yml for pkg in $OPTIONAL_SYSTEM_PACKAGES; do diff --git a/src/environment-dev.yml b/src/environment-dev.yml new file mode 100644 index 00000000000..6d99447b852 --- /dev/null +++ b/src/environment-dev.yml @@ -0,0 +1,206 @@ +name: sage-dev +channels: + - conda-forge + - nodefaults +dependencies: + - compilers + - make + - m4 + - perl + - python + - tar + - bc + - pkg-config + - arb + - boost-cpp + - brial + - bzip2 + - cddlib + - cliquer + - cmake + - curl + - ecl + - eclib + - ecm + - fflas-ffpack + - libflint + - flintqs + - fplll + - freetype + - bdw-gc + - gengetopt + - gf2x + - gfan + - fortran-compiler + - giac + - givaro + - glpk + - gmp + - gsl + - iml + - lcalc + - libatomic_ops + - libbraiding + - libffi + - libgd + - libhomfly + - xz + - libpng + - linbox + - lrcalc + - m4ri + - m4rie + - mpc + - mpfi + - mpfr + - nauty + - ncurses + - ntl + - openblas + - blas=2.*=openblas + - openssl + - palp + - pari + - pari-elldata + - pari-galdata + - pari-galpol + - pari-seadata + - pari-galdata + - pari-seadata-small + - patch + - pcre + - pkg-config + - planarity + - ppl + - primecount + - primesieve + - qhull + - r + - r-essentials + - readline + - rw + - singular + - sqlite + - suitesparse + - symmetrica + - sympow + - tachyon + - tox + - xz + - zeromq + - zlib + - zn_poly + - alabaster + - attrs + - babel + - backcall + - beautifulsoup4 + - bleach + - certifi + - cffi + - sagemath-db-combinatorial-designs + - sagemath-db-conway-polynomials + - cvxopt + - cycler + - cypari2 + - cysignals + - cython + - python-dateutil + - decorator + - defusedxml + - docutils + - sagemath-db-elliptic-curves + - entrypoints + - fpylll + - gap-defaults + - gmpy2 + - sagemath-db-graphs + - html5lib + - imagesize + - importlib_metadata + - ipykernel + - ipython + - ipython_genutils + - ipywidgets + - jedi + - jinja2 + - jmol + - jsonschema + - jupyter_client + - jupyter_core + - kiwisolver + - python-lrcalc + - markupsafe + - mathjax + - "matplotlib>=3.5.1" + - maxima + - memory-allocator + - mistune + - mpmath + - nbconvert + - nbformat + - networkx + - notebook + - numpy + - packaging + - pandocfilters + - parso + - pexpect + - pickleshare + - pillow + - pip + - pkgconfig + - sagemath-db-polytopes + - pplpy + - primecountpy + - prometheus_client + - prompt_toolkit + - ptyprocess + - pybind11 + - pycparser + - pygments + - pyparsing + - pyrsistent + - pytz + - pyzmq + - requests + - rpy2 + - sagetex + - scipy + - send2trash + - setuptools + - setuptools_scm + - simplegeneric + - six + - snowballstemmer + - sphinx + - sphinxcontrib-applehelp + - sphinxcontrib-devhelp + - sphinxcontrib-htmlhelp + - sphinxcontrib-jsmath + - sphinxcontrib-qthelp + - sphinxcontrib-serializinghtml + - sphinxcontrib-websupport + - sympy + - terminado + - testpath + - three.js + - tornado + - traitlets + - tzlocal + - vcversioner + - wcwidth + - webencodings + - wheel + - widgetsnbextension + - zipp + # Packages needed for ./bootstrap + - gettext + - autoconf + - automake + - libtool + # Additional dev tools + - openssh + - pycodestyle + - pytest + - jupyter_sphinx From bbd7807cf9aa149776067cde757b2a81bc85f3e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 21 Apr 2022 20:17:34 +0200 Subject: [PATCH 199/529] re-add maxima algo for Stirling --- src/sage/combinat/combinat.py | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/sage/combinat/combinat.py b/src/sage/combinat/combinat.py index ae86cf37315..48475d117dc 100644 --- a/src/sage/combinat/combinat.py +++ b/src/sage/combinat/combinat.py @@ -364,9 +364,9 @@ def bell_number(n, algorithm='flint', **options) -> Integer: TESTS:: - sage: all(bell_number(n) == bell_number(n,'dobinski') for n in range(200)) + sage: all(bell_number(n) == bell_number(n,'dobinski') for n in range(100)) True - sage: all(bell_number(n) == bell_number(n,'gap') for n in range(200)) + sage: all(bell_number(n) == bell_number(n,'gap') for n in range(100)) True sage: all(bell_number(n) == bell_number(n,'mpmath', prec=500) for n in range(200, 220)) True @@ -854,7 +854,7 @@ def lucas_number2(n, P, Q): return libgap.Lucas(P, Q, n)[1].sage() -def stirling_number1(n, k, algorithm=None) -> Integer: +def stirling_number1(n, k, algorithm="gap") -> Integer: r""" Return the `n`-th Stirling number `S_1(n,k)` of the first kind. @@ -868,8 +868,8 @@ def stirling_number1(n, k, algorithm=None) -> Integer: - ``k`` -- nonnegative machine-size integer - ``algorithm``: - * ``"gap"`` (default) -- use GAP's Stirling1 function - * ``"flint"`` -- use flint's arith_stirling_number_1u function + * ``"gap"`` (default) -- use GAP's ``Stirling1`` function + * ``"flint"`` -- use flint's ``arith_stirling_number_1u`` function EXAMPLES:: @@ -896,8 +896,6 @@ def stirling_number1(n, k, algorithm=None) -> Integer: """ n = ZZ(n) k = ZZ(k) - if algorithm is None: - algorithm = 'gap' if algorithm == 'gap': from sage.libs.gap.libgap import libgap return libgap.Stirling1(n, k).sage() @@ -924,8 +922,9 @@ def stirling_number2(n, k, algorithm=None) -> Integer: - ``algorithm``: * ``None`` (default) -- use native implementation - * ``"flint"`` -- use flint's arith_stirling_number_2 function - * ``"gap"`` -- use GAP's Stirling2 function + * ``"flint"`` -- use flint's ``arith_stirling_number_2`` function + * ``"gap"`` -- use GAP's ``Stirling2`` function + * ``"maxima"`` -- use Maxima's ``stirling2`` function EXAMPLES: @@ -1016,7 +1015,10 @@ def stirling_number2(n, k, algorithm=None) -> Integer: ....: if not (s_sage == s_flint and s_sage == s_gap): ....: print("Error with n<200") - sage: s_sage = stirling_number2(50,3, algorithm="namba") + sage: stirling_number2(20,3, algorithm="maxima") + 580606446 + + sage: s_sage = stirling_number2(5,3, algorithm="namba") Traceback (most recent call last): ... ValueError: unknown algorithm: namba @@ -1031,6 +1033,8 @@ def stirling_number2(n, k, algorithm=None) -> Integer: if algorithm == 'flint': import sage.libs.flint.arith return sage.libs.flint.arith.stirling_number_2(n, k) + if algorithm == 'maxima': + return ZZ(maxima.stirling2(n, k)) # type:ignore raise ValueError("unknown algorithm: %s" % algorithm) @@ -1423,8 +1427,6 @@ def __bool__(self) -> bool: """ return bool(self._list) - - def __len__(self) -> Integer: """ EXAMPLES:: @@ -2461,7 +2463,6 @@ def __iter__(self): ############################################################################## from sage.sets.image_set import ImageSubobject -from sage.categories.map import is_Map class MapCombinatorialClass(ImageSubobject, CombinatorialClass): From aa144e6c45fa9a76ebfbe69b011d4da0b8a76b7c Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Fri, 22 Apr 2022 10:11:52 +0000 Subject: [PATCH 200/529] Add distros/conda for jupyter_sphinx --- build/pkgs/jupyter_sphinx/distros/conda.txt | 1 + src/doc/bootstrap | 1 - src/environment-dev.yml | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 build/pkgs/jupyter_sphinx/distros/conda.txt diff --git a/build/pkgs/jupyter_sphinx/distros/conda.txt b/build/pkgs/jupyter_sphinx/distros/conda.txt new file mode 100644 index 00000000000..e9b59e89755 --- /dev/null +++ b/build/pkgs/jupyter_sphinx/distros/conda.txt @@ -0,0 +1 @@ +jupyter_sphinx diff --git a/src/doc/bootstrap b/src/doc/bootstrap index a00811223fa..14886524d58 100755 --- a/src/doc/bootstrap +++ b/src/doc/bootstrap @@ -89,7 +89,6 @@ for SYSTEM in arch debian fedora cygwin homebrew conda; do echo " - openssh" >> src/environment-dev.yml echo " - pycodestyle" >> src/environment-dev.yml echo " - pytest" >> src/environment-dev.yml - echo " - jupyter_sphinx" >> src/environment-dev.yml cp environment.yml environment-optional.yml echo " # optional packages" >> environment-optional.yml diff --git a/src/environment-dev.yml b/src/environment-dev.yml index 6d99447b852..bef6a1f4a2b 100644 --- a/src/environment-dev.yml +++ b/src/environment-dev.yml @@ -128,6 +128,7 @@ dependencies: - jsonschema - jupyter_client - jupyter_core + - jupyter_sphinx - kiwisolver - python-lrcalc - markupsafe @@ -203,4 +204,3 @@ dependencies: - openssh - pycodestyle - pytest - - jupyter_sphinx From 80ed44f5b6ee127c26b16e5d1f128aca97085459 Mon Sep 17 00:00:00 2001 From: jf Date: Fri, 22 Apr 2022 13:25:34 +0200 Subject: [PATCH 201/529] 33639: removed live examples + added feature file --- src/sage/features/phitigra.py | 31 +++++++++++++++++++++++++++++++ src/sage/graphs/graph_editor.py | 26 ++++++-------------------- 2 files changed, 37 insertions(+), 20 deletions(-) create mode 100644 src/sage/features/phitigra.py diff --git a/src/sage/features/phitigra.py b/src/sage/features/phitigra.py new file mode 100644 index 00000000000..f792d7b47cd --- /dev/null +++ b/src/sage/features/phitigra.py @@ -0,0 +1,31 @@ +r""" +Check for phitigra +""" +from . import PythonModule + + +class Phitigra(PythonModule): + r""" + A :class:`sage.features.Feature` describing the presence of phitigra. + + Phitigra is provided by an optional package in the Sage distribution. + + EXAMPLES:: + + sage: from sage.features.phitigra import Phitigra + sage: Phitigra().is_present() # optional - phitigra + FeatureTestResult('phitigra', True) + """ + def __init__(self): + r""" + TESTS:: + + sage: from sage.features.phitigra import Phitigra + sage: isinstance(Phitigra(), Phitigra) + True + """ + PythonModule.__init__(self, 'phitigra', spkg='phitigra') + + +def all_features(): + return [Phitigra()] diff --git a/src/sage/graphs/graph_editor.py b/src/sage/graphs/graph_editor.py index 63d05890c12..ea10fe47cfe 100644 --- a/src/sage/graphs/graph_editor.py +++ b/src/sage/graphs/graph_editor.py @@ -48,41 +48,27 @@ def graph_editor(graph=None, **display_options): EXAMPLES:: - sage: e = graph_editor() + sage: e = graph_editor() # optional - phitigra sage: e.show() # not tested Opening an existing graph:: sage: G = graphs.RandomGNP(10, 0.5) - sage: e = graph_editor(G) + sage: e = graph_editor(G) # optional - phitigra sage: e.show() # not tested - .. ONLY:: html - - .. JUPYTER-EXECUTE:: - :hide-code: - - graph_editor(graphs.RandomGNP(10, 0.5)).show() - Retrieving a copy of the drawn graph:: sage: G = graphs.RandomGNP(10, 0.5) - sage: e = graph_editor(G) - sage: H = e.get_graph() - sage: H == G and not H is G + sage: e = graph_editor(G) # optional - phitigra + sage: H = e.get_graph() # optional - phitigra + sage: H == G and not H is G # optional - phitigra True Using different display options:: - sage: e = graph_editor(graphs.PetersenGraph(), width=300, height=300, default_radius=12, default_vertex_color='orange', default_edge_color='#666', show_vertex_labels=False) + sage: e = graph_editor(graphs.PetersenGraph(), width=300, height=300, default_radius=12, default_vertex_color='orange', default_edge_color='#666', show_vertex_labels=False) # optional - phitigra sage: e.show() # not tested - - .. ONLY:: html - - .. JUPYTER-EXECUTE:: - :hide-code: - - graph_editor(graphs.PetersenGraph(), width=300, height=300, default_radius=12, default_vertex_color='orange', default_edge_color='#666', show_vertex_labels=False).show() """ from .graph import Graph From 961ec2f8cde876384eef8b8a3a2c0cfa65c17282 Mon Sep 17 00:00:00 2001 From: jf Date: Fri, 22 Apr 2022 13:38:07 +0200 Subject: [PATCH 202/529] 33639: updated headings --- src/sage/graphs/graph_editor.py | 38 +++++++++++++++++---------------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/src/sage/graphs/graph_editor.py b/src/sage/graphs/graph_editor.py index ea10fe47cfe..48ce620c567 100644 --- a/src/sage/graphs/graph_editor.py +++ b/src/sage/graphs/graph_editor.py @@ -1,25 +1,23 @@ r""" Graph editor widget -The ``phitigra`` package should be installed on your Sage installation. +This file adds an interface to ``phitigra``, a graph editor widget for +jupyter and jupyterlab. The ``phitigra`` optional package should be installed +on your Sage installation. AUTHORS: -- Radoslav Kirov (2009) -- initial version of the editor for use with sagenb -- Jean-Florent Raymond (2022) -- replacement with the ``phitigra`` package +- Radoslav Kirov (2009): initial version of the editor for use with sagenb +- Jean-Florent Raymond (2022-04-12): replacement with the ``phitigra`` package """ + # **************************************************************************** # Copyright (C) 2022 Jean-Florent Raymond # -# Distributed under the terms of the GNU General Public License (GPL) -# -# This code is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# The full text of the GPL is available at: -# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** @@ -33,6 +31,12 @@ def graph_editor(graph=None, **display_options): """ Return a graph editor widget. + The graph editor widget can be displayed with Jupyter or JupyterLab. + It is provided by the ``phitigra`` optional package, see + https://github.com/jfraymond/phitigra for details about the + possible options (changing the width/height of the canvas, the + default size and color of vertices, etc.). + INPUT: - ``graph`` - a :class:`Graph` instance (default: ``None``); the @@ -40,12 +44,6 @@ def graph_editor(graph=None, **display_options): - ``display_options`` - options for the widget. - The graph editor widget can be displayed with Jupyter or JupyterLab. - It is provided by the ``phitigra`` optional package, see - https://github.com/jfraymond/phitigra for details about the - possible options (changing the width/height of the canvas, the - default size and color of vertices, etc.). - EXAMPLES:: sage: e = graph_editor() # optional - phitigra @@ -69,6 +67,10 @@ def graph_editor(graph=None, **display_options): sage: e = graph_editor(graphs.PetersenGraph(), width=300, height=300, default_radius=12, default_vertex_color='orange', default_edge_color='#666', show_vertex_labels=False) # optional - phitigra sage: e.show() # not tested + + .. NOTE:: + + The editor does not support multigraphs. """ from .graph import Graph From 693c0d8f72380a6f73571b3354c4db583dfb40cb Mon Sep 17 00:00:00 2001 From: dcoudert Date: Fri, 22 Apr 2022 14:10:50 +0200 Subject: [PATCH 203/529] trac #33742: see also blocks in orientation methods --- src/sage/graphs/digraph_generators.py | 3 +++ src/sage/graphs/graph.py | 14 ++++++++++++++ src/sage/graphs/orientations.py | 9 +++++++++ 3 files changed, 26 insertions(+) diff --git a/src/sage/graphs/digraph_generators.py b/src/sage/graphs/digraph_generators.py index b8a6fc1cc0a..4f1c9900eb3 100644 --- a/src/sage/graphs/digraph_generators.py +++ b/src/sage/graphs/digraph_generators.py @@ -627,6 +627,9 @@ def nauty_directg(self, graphs, options="", debug=False): .. SEEALSO:: - :meth:`~sage.graphs.graph.Graph.orientations` + - :meth:`~sage.graphs.graph.Graph.strong_orientation` + - :meth:`~sage.graphs.orientations.strong_orientations_iterator` + - :meth:`~sage.graphs.orientations.random_orientation` """ if '-u' in options or '-T' in options or '-G' in options: raise ValueError("directg output options [-u|-T|-G] are not allowed") diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index a4de61e3c0f..53657b1fd2e 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -3012,6 +3012,13 @@ def strong_orientation(self): - This method assumes the graph is connected. - This algorithm works in O(m). + .. SEEALSO:: + + - :meth:`~sage.graphs.graph.Graph.orientations` + - :meth:`~sage.graphs.orientations.strong_orientations_iterator` + - :meth:`~sage.graphs.digraph_generators.DiGraphGenerators.nauty_directg` + - :meth:`~sage.graphs.orientations.random_orientation` + EXAMPLES: For a 2-regular graph, a strong orientation gives to each vertex an @@ -3399,6 +3406,13 @@ def orientations(self, data_structure=None, sparse=None): This always considers multiple edges of graphs as distinguishable, and hence, may have repeated digraphs. + .. SEEALSO:: + + - :meth:`~sage.graphs.graph.Graph.strong_orientation` + - :meth:`~sage.graphs.orientations.strong_orientations_iterator` + - :meth:`~sage.graphs.digraph_generators.DiGraphGenerators.nauty_directg` + - :meth:`~sage.graphs.orientations.random_orientation` + EXAMPLES:: sage: G = Graph([[1,2,3], [(1, 2, 'a'), (1, 3, 'b')]], format='vertices_and_edges') diff --git a/src/sage/graphs/orientations.py b/src/sage/graphs/orientations.py index fd05c5b08d9..884ed43ccf7 100644 --- a/src/sage/graphs/orientations.py +++ b/src/sage/graphs/orientations.py @@ -66,6 +66,12 @@ def strong_orientations_iterator(G): Works only for simple graphs (no multiple edges). To avoid symmetries an orientation of an arbitrary edge is fixed. + .. SEEALSO:: + + - :meth:`~Graph.orientations` + - :meth:`~Graph.strong_orientation` + - :meth:`~sage.graphs.digraph_generators.DiGraphGenerators.nauty_directg` + - :meth:`~sage.graphs.orientations.random_orientation` EXAMPLES: @@ -274,6 +280,9 @@ def random_orientation(G): .. SEEALSO:: - :meth:`~Graph.orientations` + - :meth:`~Graph.strong_orientation` + - :meth:`~sage.graphs.orientations.strong_orientations_iterator` + - :meth:`~sage.graphs.digraph_generators.DiGraphGenerators.nauty_directg` """ from sage.graphs.graph import Graph if not isinstance(G, Graph): From ada25e362e4c5b24b5001a96e9669dc068d5b3e3 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Fri, 22 Apr 2022 18:49:23 +0200 Subject: [PATCH 204/529] trac #33743: faster random tree generator --- src/sage/graphs/generators/random.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/sage/graphs/generators/random.py b/src/sage/graphs/generators/random.py index da61da75ccf..e3eb3e220cc 100644 --- a/src/sage/graphs/generators/random.py +++ b/src/sage/graphs/generators/random.py @@ -1380,10 +1380,10 @@ def RandomTree(n, seed=None): set_random_seed(seed) # create random Prufer code - code = [ randint(0,n-1) for i in range(n-2) ] + code = [randint(0, n - 1) for i in range(n - 2)] # We count the number of symbols of each type. - # count[k] is the no. of times k appears in code + # count[k] is the number of times k appears in code # # (count[k] is set to -1 when the corresponding vertex is not # available anymore) @@ -1391,18 +1391,22 @@ def RandomTree(n, seed=None): for k in code: count[k] += 1 - for s in code: - for x in range(n): - if count[x] == 0: - break + # We use a heap to store vertices for which count[k] == 0 and get the vertex + # with smallest index + from heapq import heapify, heappop, heappush + zeros = [x for x in range(n) if not count[x]] + heapify(zeros) + for s in code: + x = heappop(zeros) + g.add_edge(x, s) count[x] = -1 - g.add_edge(x,s) count[s] -= 1 + if not count[s]: + heappush(zeros, s) # Adding as an edge the last two available vertices - last_edge = [ v for v in range(n) if count[v] != -1 ] - g.add_edge(last_edge) + g.add_edge(zeros) return g From 8b86a033ef7d6c69532ce397f2cb625aacb1a17f Mon Sep 17 00:00:00 2001 From: Jean-Florent Raymond Date: Sat, 23 Apr 2022 10:01:33 +0200 Subject: [PATCH 205/529] 33639: using sage.phitigra.feature --- src/sage/graphs/graph_editor.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/graphs/graph_editor.py b/src/sage/graphs/graph_editor.py index 48ce620c567..e9d3b0e2dbb 100644 --- a/src/sage/graphs/graph_editor.py +++ b/src/sage/graphs/graph_editor.py @@ -8,6 +8,7 @@ AUTHORS: - Radoslav Kirov (2009): initial version of the editor for use with sagenb + - Jean-Florent Raymond (2022-04-12): replacement with the ``phitigra`` package """ @@ -22,9 +23,8 @@ # **************************************************************************** from sage.misc.lazy_import import lazy_import -from sage.features import PythonModule -lazy_import('phitigra', 'GraphEditor', - feature=PythonModule('phitigra', spkg='phitigra')) +from sage.features.phitigra import Phitigra +lazy_import('phitigra', 'GraphEditor', feature=Phitigra()) def graph_editor(graph=None, **display_options): From d3f8af62510b60ad0a4f76fc343c186fd959c585 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Sat, 23 Apr 2022 16:35:04 +0800 Subject: [PATCH 206/529] easier access to coefficients of finite-field elements --- src/sage/rings/finite_rings/element_base.pyx | 94 +++++++++++++++++++- 1 file changed, 92 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/finite_rings/element_base.pyx b/src/sage/rings/finite_rings/element_base.pyx index 492a30983c9..bf72ca7a94d 100755 --- a/src/sage/rings/finite_rings/element_base.pyx +++ b/src/sage/rings/finite_rings/element_base.pyx @@ -211,10 +211,100 @@ cdef class FinitePolyExtElement(FiniteRingElement): """ return self.minpoly(var) + def __getitem__(self, n): + r""" + Return the `n`th coefficient of this finite-field element when + written as a polynomial in the generator. + + EXAMPLES:: + + sage: x = polygen(GF(19)) + sage: F. = GF(19^2, modulus=x^2+1) + sage: a = 5 + 7*i + sage: a[0] + 5 + sage: a[1] + 7 + sage: list(a) # implicit doctest + [5, 7] + sage: tuple(a) # implicit doctest + (5, 7) + + :: + + sage: b = F(11) + sage: b[0] + 11 + sage: b[1] + 0 + sage: list(b) # implicit doctest + [11, 0] + sage: tuple(b) # implicit doctest + (11, 0) + sage: list(b.polynomial()) + [11] + + TESTS:: + + sage: F. = GF(17^60) + sage: a = F.random_element() + sage: a == sum(c*t^i for i,c in enumerate(a)) + True + + :: + + sage: F. = GF((2^127-1)^10, 't') + sage: a = F.random_element() + sage: a == sum(c*t^i for i,c in enumerate(a)) + True + """ + if n < 0 or n >= self.parent().degree(): + raise IndexError("index must lie between 0 and the degree minus 1") + return self.polynomial()[n] + + def list(self): + r""" + Return the list of coefficients (in little-endian) of this + finite-field element when written as a polynomial in the + generator. + + Equivalent to calling ``list()`` on this element. + + EXAMPLES:: + + sage: x = polygen(GF(71)) + sage: F. = GF(71^7, modulus=x^7+x+1) + sage: a = 3 + u + 3*u^2 + 3*u^3 + 7*u^4 + sage: a.list() + [3, 1, 3, 3, 7, 0, 0] + sage: a.list() == list(a) == [a[i] for i in range(F.degree())] + True + + The coefficients returned are those of a fully reduced + representative of the finite-field element:: + + sage: b = u^777 + sage: b.list() + [9, 69, 4, 27, 40, 10, 56] + sage: (u.polynomial()^777).list() + [0, 0, 0, 0, ..., 0, 1] + + TESTS:: + + sage: R. = GF(17)[] + sage: F. = GF(17^60) + sage: a = F.random_element() + sage: a == R(a.list())(t) + True + sage: list(a) == a.list() + True + """ + return self.polynomial().padded_list(self.parent().degree()) + def _vector_(self, reverse=False): """ Return a vector matching this element in the vector space attached - to the parent. The most significant bit is to the right. + to the parent. The most significant coefficient is to the right. INPUT: @@ -250,7 +340,7 @@ cdef class FinitePolyExtElement(FiniteRingElement): k = self.parent() p = self.polynomial() - ret = p.list() + [0] * (k.degree() - p.degree() - 1) + ret = self.polynomial().padded_list(k.degree()) if reverse: ret.reverse() From 04ca0ae6cbf839c19604b2c62546ebcb9e3fe668 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sat, 23 Apr 2022 12:19:13 +0200 Subject: [PATCH 207/529] trac #33749: improve butterfly digraph generator --- src/sage/graphs/digraph_generators.py | 43 +++++++++++++++++++-------- 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/src/sage/graphs/digraph_generators.py b/src/sage/graphs/digraph_generators.py index b8a6fc1cc0a..da9b7dec81f 100644 --- a/src/sage/graphs/digraph_generators.py +++ b/src/sage/graphs/digraph_generators.py @@ -53,15 +53,18 @@ --------------------- """ - -################################################################################ +# **************************************************************************** # Copyright (C) 2006 Robert L. Miller # and Emily A. Kirkman # Copyright (C) 2009 Michael C. Yurko +# Copyright (C) 2012 David Coudert # -# Distributed under the terms of the GNU General Public License (GPL) -# http://www.gnu.org/licenses/ -################################################################################ +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.cpython.string import bytes_to_str import sys @@ -212,7 +215,7 @@ def ButterflyGraph(self, n, vertices='strings'): INPUT: - - ``n`` -- integer; + - ``n`` -- a non negative integer; the dimension of the butterfly graph - ``vertices`` -- string (default: ``'strings'``); specifies whether the vertices are zero-one strings (default) or tuples over GF(2) @@ -254,6 +257,7 @@ def ButterflyGraph(self, n, vertices='strings'): (((1, 1), 0), ((1, 1), 1)), (((1, 1), 1), ((1, 0), 2)), (((1, 1), 1), ((1, 1), 2))] + sage: digraphs.ButterflyGraph(3).show() # long time TESTS:: @@ -274,33 +278,47 @@ def ButterflyGraph(self, n, vertices='strings'): if n >= 31: raise NotImplementedError("vertices='strings' is only valid for n <= 30") from sage.graphs.generic_graph_pyx import int_to_binary_string - butterfly = {} + V = [] + E = [] for v in range(2 ** n): bv = int_to_binary_string(v) # pad and reverse the string padded_bv = ('0' * (n - len(bv)) + bv)[::-1] + V.append(padded_bv) for i in range(n): w = v w ^= (1 << i) # push 1 to the left by i and xor with w bw = int_to_binary_string(w) padded_bw = ('0' * (n - len(bw)) + bw)[::-1] - butterfly[(padded_bv, i)] = [(padded_bv, i + 1), (padded_bw, i + 1)] + E.append(((padded_bv, i), (padded_bv, i + 1))) + E.append(((padded_bv, i), (padded_bw, i + 1))) elif vertices == 'vectors': from sage.modules.free_module import VectorSpace from sage.rings.finite_rings.finite_field_constructor import FiniteField from copy import copy - butterfly = {} + V = [] + E = [] for v in VectorSpace(FiniteField(2), n): # We must call tuple since vectors are mutable. To obtain a # vector from the tuple tv, just call vector(tv). tv = tuple(v) + V.append(tv) + w = copy(v) for i in range(n): - w = copy(v) w[i] += 1 # Flip the ith bit - butterfly[(tv, i)] = [(tv, i + 1), (tuple(w), i + 1)] + E.append(((tv, i), (tv, i + 1))) + E.append(((tv, i), (tuple(w), i + 1))) + w[i] += 1 # Flip the ith bit back else: raise NotImplementedError("vertices must be 'strings' or 'vectors'") - return DiGraph(butterfly, name="{}-dimensional Butterfly".format(n)) + # Set position of vertices + pos = dict() + dec = 2**n // n + for i, v in enumerate(sorted(V, reverse=True)): + for x in range(n + 1): + pos[v, x] = (dec * x, i) + return DiGraph([pos.keys(), E], format='vertices_and_edges', pos=pos, + name="{}-dimensional Butterfly".format(n)) def Path(self, n): r""" @@ -737,6 +755,7 @@ def Circuit(self, n): elif n: g.add_edges(zip(range(n - 1), range(1, n))) g.add_edge(n - 1, 0) + g._circle_embedding(list(range(n))) return g def Circulant(self, n, integers): From d3a87508f52177be21a98069f7b7266737e6db46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Moreno-Soc=C3=ADas?= Date: Sun, 24 Apr 2022 00:03:39 +0200 Subject: [PATCH 208/529] Replace obsolete link http://www.schorn.ch/howto.html -> https://schorn.ch/lagrange.html --- src/sage/arith/misc.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/arith/misc.py b/src/sage/arith/misc.py index 9966d0b8571..d8ce326cda4 100644 --- a/src/sage/arith/misc.py +++ b/src/sage/arith/misc.py @@ -5103,7 +5103,7 @@ def two_squares(n): ALGORITHM: - See http://www.schorn.ch/howto.html + See https://schorn.ch/lagrange.html """ n = ZZ(n) @@ -5228,7 +5228,7 @@ def three_squares(n): ALGORITHM: - See http://www.schorn.ch/howto.html + See https://schorn.ch/lagrange.html """ n = ZZ(n) From 967cd5d6023a90b1f8c4613756e68400bff866ca Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Sun, 24 Apr 2022 18:01:34 +0900 Subject: [PATCH 209/529] Reviewer edits --- src/sage/graphs/graph_editor.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/sage/graphs/graph_editor.py b/src/sage/graphs/graph_editor.py index e9d3b0e2dbb..f66f3ffa76e 100644 --- a/src/sage/graphs/graph_editor.py +++ b/src/sage/graphs/graph_editor.py @@ -1,8 +1,8 @@ r""" Graph editor widget -This file adds an interface to ``phitigra``, a graph editor widget for -jupyter and jupyterlab. The ``phitigra`` optional package should be installed +This module adds an interface to ``phitigra``, a graph editor widget for +Jupyter and JupyterLab. The ``phitigra`` optional package should be installed on your Sage installation. AUTHORS: @@ -39,10 +39,9 @@ def graph_editor(graph=None, **display_options): INPUT: - - ``graph`` - a :class:`Graph` instance (default: ``None``); the - graph to edit. + - ``graph`` -- a graph to edit (default: ``None``) - - ``display_options`` - options for the widget. + - ``display_options`` -- options for the widget EXAMPLES:: @@ -65,14 +64,15 @@ def graph_editor(graph=None, **display_options): Using different display options:: - sage: e = graph_editor(graphs.PetersenGraph(), width=300, height=300, default_radius=12, default_vertex_color='orange', default_edge_color='#666', show_vertex_labels=False) # optional - phitigra - sage: e.show() # not tested + sage: e = graph_editor(graphs.PetersenGraph(), width=300, height=300, # optional - phitigra + ....: default_radius=12, default_vertex_color='orange', # optional - phitigra + ....: default_edge_color='#666', show_vertex_labels=False) # optional - phitigra + sage: e.show() # not tested .. NOTE:: The editor does not support multigraphs. """ - from .graph import Graph if graph is None: From 778bef39469b94db17b4565fca8c0b0db4f97b47 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Sun, 24 Apr 2022 19:08:43 +0800 Subject: [PATCH 210/529] move .__divmod__() up to RingElement --- src/sage/structure/element.pyx | 86 ++++++++++++++++++++++++++-------- 1 file changed, 66 insertions(+), 20 deletions(-) diff --git a/src/sage/structure/element.pyx b/src/sage/structure/element.pyx index a618957e095..dfd6583b149 100644 --- a/src/sage/structure/element.pyx +++ b/src/sage/structure/element.pyx @@ -2738,6 +2738,72 @@ cdef class RingElement(ModuleElement): raise bin_op_exception('/', self, other) return frac(self, other) + def __divmod__(self, other): + """ + Return the quotient and remainder of ``self`` divided by ``other``. + + This operation may not be defined in all rings. + + EXAMPLES:: + + sage: divmod(5,3) + (1, 2) + sage: divmod(25r,12) + (2, 1) + sage: divmod(25,12r) + (2, 1) + + :: + + sage: R. = QQ[] + sage: f = -19/13*x^5 - x^4 - 2/3*x^3 + 6*x^2 - 2 + sage: g = 3*x^2 + 5 + sage: q,r = divmod(f,g) + sage: q + -19/39*x^3 - 1/3*x^2 + 23/39*x + 23/9 + sage: r + -115/39*x - 133/9 + sage: f == q*g + r + True + + :: + + sage: R. = ZZ[] + sage: f = -2*x^5 + x^4 - 9*x^3 - 5*x^2 + 7*x + 4 + sage: g = x^2 + 5 + sage: q,r = divmod(f,g) + sage: q + -2*x^3 + x^2 + x - 10 + sage: r + 2*x + 54 + sage: f == q*g + r + True + sage: h = 3*x^2 + 5 + sage: q,r = divmod(f,h) + sage: q + -3*x - 2 + sage: r + -2*x^5 + x^4 + x^2 + 22*x + 14 + sage: f == q*h + r + True + + :: + + sage: R. = GF(7)[] + sage: divmod(x^2, x-1) + (x + 1, 1) + + :: + + sage: divmod(22./7, RR(pi)) + (1.00040249943477, 0.000000000000000) + """ + try: + return self.quo_rem(other) + except (AttributeError, NotImplementedError): + pass + return (self // other, self % other) + def __invert__(self): return self._parent.one() / self @@ -4015,26 +4081,6 @@ cdef class EuclideanDomainElement(PrincipalIdealDomainElement): def quo_rem(self, other): raise NotImplementedError - def __divmod__(self, other): - """ - Return the quotient and remainder of ``self`` divided by ``other``. - - EXAMPLES:: - - sage: divmod(5,3) - (1, 2) - sage: divmod(25r,12) - (2, 1) - sage: divmod(25,12r) - (2, 1) - - """ - if isinstance(self, Element): - return self.quo_rem(other) - else: - x, y = canonical_coercion(self, other) - return x.quo_rem(y) - cpdef _floordiv_(self, right): """ Quotient of division of ``self`` by other. This is denoted //. From 7750e081e43d62d926858e6d1a3876e3a4b52ff0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 24 Apr 2022 16:04:04 +0200 Subject: [PATCH 211/529] details --- src/sage/algebras/free_algebra_quotient_element.py | 2 +- src/sage/algebras/quatalg/quaternion_algebra.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/algebras/free_algebra_quotient_element.py b/src/sage/algebras/free_algebra_quotient_element.py index b76538c3381..c841a9210cf 100644 --- a/src/sage/algebras/free_algebra_quotient_element.py +++ b/src/sage/algebras/free_algebra_quotient_element.py @@ -243,7 +243,7 @@ def _mul_(self, y): def monomial_product(X, w, m): mats = X._FreeAlgebraQuotient__matrix_action - for (j, k) in m._element_list: + for j, k in m._element_list: M = mats[int(j)] for _ in range(k): w *= M diff --git a/src/sage/algebras/quatalg/quaternion_algebra.py b/src/sage/algebras/quatalg/quaternion_algebra.py index bbdab484b43..3bde7b21536 100644 --- a/src/sage/algebras/quatalg/quaternion_algebra.py +++ b/src/sage/algebras/quatalg/quaternion_algebra.py @@ -798,7 +798,7 @@ def maximal_order(self, take_shortcuts=True): e_new_gens = [] # For each prime at which R is not yet maximal, make it bigger - for (p, _) in d_R.factor(): + for p, _ in d_R.factor(): e = R.basis() while self.quaternion_order(e).discriminant().valuation(p) > d_A.valuation(p): # Compute a normalized basis at p From 6768cb82173608c79fa8b83becedd47f2c58decd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 24 Apr 2022 16:21:05 +0200 Subject: [PATCH 212/529] details, 80 char --- src/sage/groups/group_semidirect_product.py | 68 +++++++++++++++------ 1 file changed, 48 insertions(+), 20 deletions(-) diff --git a/src/sage/groups/group_semidirect_product.py b/src/sage/groups/group_semidirect_product.py index adaed8baa7e..e5439ce0366 100644 --- a/src/sage/groups/group_semidirect_product.py +++ b/src/sage/groups/group_semidirect_product.py @@ -34,7 +34,10 @@ def _repr_(self): sage: def twist(x,y): ....: return y sage: GroupSemidirectProduct(WeylGroup(['A',2],prefix="s"), WeylGroup(['A',3],prefix="t"),twist) # indirect doctest - Semidirect product of Weyl Group of type ['A', 2] (as a matrix group acting on the ambient space) acting on Weyl Group of type ['A', 3] (as a matrix group acting on the ambient space) + Semidirect product of Weyl Group of type ['A', 2] + (as a matrix group acting on the ambient space) acting on + Weyl Group of type ['A', 3] + (as a matrix group acting on the ambient space) """ def wrapper(prefix, s): if prefix is None: @@ -99,11 +102,14 @@ def to_opposite(self): sage: from sage.groups.group_exp import GroupExp sage: EL = GroupExp()(L) sage: W = L.weyl_group(prefix="s"); W - Weyl Group of type ['A', 2] (as a matrix group acting on the root lattice) + Weyl Group of type ['A', 2] + (as a matrix group acting on the root lattice) sage: def twist(w,v): ....: return EL(w.action(v.value)) sage: G = GroupSemidirectProduct(W, EL, twist, prefix1='t'); G - Semidirect product of Weyl Group of type ['A', 2] (as a matrix group acting on the root lattice) acting on Multiplicative form of Root lattice of the Root system of type ['A', 2] + Semidirect product of Weyl Group of type ['A', 2] (as a matrix + group acting on the root lattice) acting on Multiplicative form of + Root lattice of the Root system of type ['A', 2] sage: mu = L.an_element(); mu 2*alpha[1] + 2*alpha[2] sage: w = W.an_element(); w @@ -126,22 +132,25 @@ def to_opposite(self): class GroupSemidirectProduct(CartesianProduct): r""" - Return the semidirect product of the groups ``G`` and ``H`` using the homomorphism ``twist``. + Return the semidirect product of the groups ``G`` and ``H``using the homomorphism ``twist``. INPUT: - ``G`` and ``H`` -- multiplicative groups - - ``twist`` -- (default: ``None``) a function defining a homomorphism (see below) + - ``twist`` -- (default: ``None``) a function defining + a homomorphism (see below) - ``act_to_right`` -- ``True`` or ``False`` (default: ``True``) - ``prefix0`` -- (default: ``None``) optional string - ``prefix1`` -- (default: ``None``) optional string - ``print_tuple`` -- ``True`` or ``False`` (default: ``False``) - ``category`` -- A category (default: Groups()) - A semidirect product of groups `G` and `H` is a group structure on the Cartesian product `G \times H` - whose product agrees with that of `G` on `G \times 1_H` and with that of `H` on `1_G \times H`, such that - either `1_G \times H` or `G \times 1_H` is a normal subgroup. In the former case the group is denoted - `G \ltimes H` and in the latter, `G \rtimes H`. + A semidirect product of groups `G` and `H` is a group structure on + the Cartesian product `G \times H` whose product agrees with that + of `G` on `G \times 1_H` and with that of `H` on `1_G \times H`, + such that either `1_G \times H` or `G \times 1_H` is a normal + subgroup. In the former case, the group is denoted `G \ltimes H` + and in the latter, `G \rtimes H`. If ``act_to_right`` is ``True``, this indicates the group `G \ltimes H` in which `G` acts on `H` by automorphisms. In this case there is a @@ -168,8 +177,8 @@ class GroupSemidirectProduct(CartesianProduct): &= (g_1g_2, twist(g_2^{-1}, h_1) h_2) \end{aligned} - If ``act_to_right`` is ``False``, the group `G \rtimes H` is specified by a homomorphism `\psi\in \mathrm{Hom}(H,\mathrm{Aut}(G))` - such that + If ``act_to_right`` is ``False``, the group `G \rtimes H` is specified by + a homomorphism `\psi\in \mathrm{Hom}(H,\mathrm{Aut}(G))` such that .. MATH:: @@ -204,7 +213,9 @@ class GroupSemidirectProduct(CartesianProduct): sage: def twist(g,v): ....: return EV(g*v.value) sage: H = GroupSemidirectProduct(G, EV, twist=twist, prefix1 = 't'); H - Semidirect product of General Linear Group of degree 2 over Rational Field acting on Multiplicative form of Vector space of dimension 2 over Rational Field + Semidirect product of General Linear Group of degree 2 + over Rational Field acting on Multiplicative form of Vector space + of dimension 2 over Rational Field sage: x = H.an_element(); x t[(1, 0)] sage: x^2 @@ -291,14 +302,18 @@ def _repr_(self): sage: def twist(x,y): ....: return y sage: GroupSemidirectProduct(WeylGroup(['A',2],prefix="s"), WeylGroup(['A',3],prefix="t"),twist) # indirect doctest - Semidirect product of Weyl Group of type ['A', 2] (as a matrix group acting on the ambient space) acting on Weyl Group of type ['A', 3] (as a matrix group acting on the ambient space) + Semidirect product of Weyl Group of type ['A', 2] (as a matrix + group acting on the ambient space) acting on Weyl Group + of type ['A', 3] (as a matrix group acting on the ambient space) """ cartesian_factors = self.cartesian_factors() if self.act_to_right(): act_string = "acting on" else: act_string = "acted upon by" - return "Semidirect product of %s %s %s" % (cartesian_factors[0], act_string, cartesian_factors[1]) + return "Semidirect product of %s %s %s" % (cartesian_factors[0], + act_string, + cartesian_factors[1]) def _element_constructor_(self, x): r""" @@ -312,7 +327,7 @@ def _element_constructor_(self, x): sage: TestSuite(g).run() """ def type_error(): - raise TypeError("%s cannot be converted into an element of %s" % (x, self)) + raise TypeError(f"{x} cannot be converted into an element of {self}") if isinstance(x, self.element_class) and x.parent() == self: return x @@ -377,7 +392,8 @@ def has_gens(G): if g1 is not False: return tuple([self((x, factors[1].one())) for x in g0] + [self((factors[0].one(), x)) for x in g1]) - raise NotImplementedError("one of the factors does not implement 'group_generators'") + raise NotImplementedError("one of the factors does not " + "implement 'group_generators'") def product(self, x, y): r""" @@ -426,25 +442,37 @@ def opposite_semidirect_product(self): sage: L = QQ^2 sage: EL = GroupExp()(L) sage: H = GroupSemidirectProduct(G, EL, twist = lambda g,v: EL(g*v.value), prefix1 = 't'); H - Semidirect product of General Linear Group of degree 2 over Rational Field acting on Multiplicative form of Vector space of dimension 2 over Rational Field + Semidirect product of General Linear Group of degree 2 + over Rational Field acting on Multiplicative form of Vector space + of dimension 2 over Rational Field sage: h = H((Matrix([[0,1],[1,0]]), EL.an_element())); h [0 1] [1 0] * t[(1, 0)] sage: Hop = H.opposite_semidirect_product(); Hop - Semidirect product of Multiplicative form of Vector space of dimension 2 over Rational Field acted upon by General Linear Group of degree 2 over Rational Field + Semidirect product of Multiplicative form of Vector space + of dimension 2 over Rational Field acted upon by + General Linear Group of degree 2 over Rational Field sage: hop = h.to_opposite(); hop t[(0, 1)] * [0 1] [1 0] sage: hop in Hop True """ - return GroupSemidirectProduct(self.cartesian_factors()[1], self.cartesian_factors()[0], twist=self._twist, act_to_right=not self.act_to_right(), prefix0=self._prefix1, prefix1=self._prefix0, print_tuple=self._print_tuple, category=self._category) + return GroupSemidirectProduct(self.cartesian_factors()[1], + self.cartesian_factors()[0], + twist=self._twist, + act_to_right=not self.act_to_right(), + prefix0=self._prefix1, + prefix1=self._prefix0, + print_tuple=self._print_tuple, + category=self._category) def construction(self): r""" Return ``None``. - This overrides the construction functor inherited from ``CartesianProduct``. + This overrides the construction functor inherited from + ``CartesianProduct``. EXAMPLES:: From 372464b3867a09c6646951391799886917157599 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Mon, 25 Apr 2022 11:16:14 +0800 Subject: [PATCH 213/529] fix doc syntax --- src/sage/rings/finite_rings/element_base.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/finite_rings/element_base.pyx b/src/sage/rings/finite_rings/element_base.pyx index bf72ca7a94d..6be6a097501 100755 --- a/src/sage/rings/finite_rings/element_base.pyx +++ b/src/sage/rings/finite_rings/element_base.pyx @@ -213,7 +213,7 @@ cdef class FinitePolyExtElement(FiniteRingElement): def __getitem__(self, n): r""" - Return the `n`th coefficient of this finite-field element when + Return the `n`\th coefficient of this finite-field element when written as a polynomial in the generator. EXAMPLES:: From 121d0ab40f778e2d2f204ed3bbcbb383492b352e Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Mon, 25 Apr 2022 11:31:31 +0800 Subject: [PATCH 214/529] add .__iter__() method to finite-field elements --- src/sage/rings/finite_rings/element_base.pyx | 75 +++++++++++++++----- 1 file changed, 57 insertions(+), 18 deletions(-) diff --git a/src/sage/rings/finite_rings/element_base.pyx b/src/sage/rings/finite_rings/element_base.pyx index 6be6a097501..d4dd6b22ee4 100755 --- a/src/sage/rings/finite_rings/element_base.pyx +++ b/src/sage/rings/finite_rings/element_base.pyx @@ -225,10 +225,6 @@ cdef class FinitePolyExtElement(FiniteRingElement): 5 sage: a[1] 7 - sage: list(a) # implicit doctest - [5, 7] - sage: tuple(a) # implicit doctest - (5, 7) :: @@ -237,25 +233,14 @@ cdef class FinitePolyExtElement(FiniteRingElement): 11 sage: b[1] 0 - sage: list(b) # implicit doctest - [11, 0] - sage: tuple(b) # implicit doctest - (11, 0) - sage: list(b.polynomial()) - [11] TESTS:: - sage: F. = GF(17^60) + sage: F,t = GF(random_prime(99)^randrange(2,99), 't').objgen() sage: a = F.random_element() - sage: a == sum(c*t^i for i,c in enumerate(a)) + sage: all(a[i] == a.polynomial()[i] for i in range(F.degree())) True - - :: - - sage: F. = GF((2^127-1)^10, 't') - sage: a = F.random_element() - sage: a == sum(c*t^i for i,c in enumerate(a)) + sage: a == sum(a[i]*t^i for i in range(F.degree())) True """ if n < 0 or n >= self.parent().degree(): @@ -301,6 +286,60 @@ cdef class FinitePolyExtElement(FiniteRingElement): """ return self.polynomial().padded_list(self.parent().degree()) + def __iter__(self): + r""" + Return an iterator over the coefficients of this finite-field + element, in the same order as :meth:`list`. + + EXAMPLES:: + + sage: x = polygen(GF(19)) + sage: F. = GF(19^2, modulus=x^2+1) + sage: a = 5 + 7*i + sage: it = iter(a) + sage: next(it) + 5 + sage: next(it) + 7 + sage: next(it) + Traceback (most recent call last): + ... + StopIteration + sage: list(a) # implicit doctest + [5, 7] + sage: tuple(a) # implicit doctest + (5, 7) + sage: b = F(11) + sage: list(b) # implicit doctest + [11, 0] + sage: tuple(b) # implicit doctest + (11, 0) + sage: list(b.polynomial()) + [11] + + TESTS:: + + sage: F = GF(random_prime(333)^randrange(111,999),'t') + sage: a = F.random_element() + sage: list(a) == a.list() # implicit doctest + True + + :: + + sage: F. = GF(17^60) + sage: a = F.random_element() + sage: a == sum(c*t^i for i,c in enumerate(a)) # implicit doctest + True + + :: + + sage: F. = GF((2^127-1)^10, 't') + sage: a = F.random_element() + sage: a == sum(c*t^i for i,c in enumerate(a)) # implicit doctest + True + """ + return iter(self.list()) + def _vector_(self, reverse=False): """ Return a vector matching this element in the vector space attached From 60adee640c3ba76a8a57c63152cd3eab70ffa660 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 24 Apr 2022 22:19:10 -0700 Subject: [PATCH 215/529] .github/workflows/tox.yml: Fix test of optional/experimental packages --- .github/workflows/tox.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index 3050255d228..beb4e91a027 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -169,12 +169,12 @@ jobs: 2-optional*) export TARGETS_PRE="build/make/Makefile" TARGETS="build/make/Makefile" targets_pattern="${{ matrix.stage }}" targets_pattern="${targets_pattern#2-optional-}" - export TARGETS_OPTIONAL=$( echo $(export PATH=build/bin:$PATH && (for a in spkg-install.in spkg-install requirements.txt; do sage-package list :optional: --has-file $a --no-file huge --no-file has_nonfree_dependencies; done) | grep -v ^_ | grep -v sagemath_doc | grep '^[${{ matrix.targets_pattern }}]' ) ) + export TARGETS_OPTIONAL=$( echo $(export PATH=build/bin:$PATH && (for a in spkg-install.in spkg-install requirements.txt; do sage-package list :optional: --has-file $a --no-file huge --no-file has_nonfree_dependencies; done) | grep -v ^_ | grep -v sagemath_doc | grep "^[$targets_pattern]" ) ) ;; 2-experimental*) export TARGETS_PRE="build/make/Makefile" TARGETS="build/make/Makefile" targets_pattern="${{ matrix.stage }}" targets_pattern="${targets_pattern#2-experimental-}" - export TARGETS_OPTIONAL=$( echo $(export PATH=build/bin:$PATH && (for a in spkg-install.in spkg-install requirements.txt; do sage-package list :experimental: --has-file $a --no-file huge --no-file has_nonfree_dependencies; done) | grep -v ^_ | grep -v sagemath_doc | grep '^[${{ matrix.targets_pattern }}]' ) ) + export TARGETS_OPTIONAL=$( echo $(export PATH=build/bin:$PATH && (for a in spkg-install.in spkg-install requirements.txt; do sage-package list :experimental: --has-file $a --no-file huge --no-file has_nonfree_dependencies; done) | grep -v ^_ | grep -v sagemath_doc | grep "^[$targets_pattern]" ) ) ;; esac MAKE="make -j12" tox -e $TOX_ENV -- SAGE_NUM_THREADS=4 $TARGETS From 7ac22ad241f631db06e2f725f23c67130f8f19b6 Mon Sep 17 00:00:00 2001 From: Jonathan Kliem Date: Mon, 25 Apr 2022 07:36:46 +0200 Subject: [PATCH 216/529] catch value error of probable_hnf --- src/sage/matrix/matrix_integer_dense_hnf.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/sage/matrix/matrix_integer_dense_hnf.py b/src/sage/matrix/matrix_integer_dense_hnf.py index e1ce64d5605..735e7016eda 100644 --- a/src/sage/matrix/matrix_integer_dense_hnf.py +++ b/src/sage/matrix/matrix_integer_dense_hnf.py @@ -1103,13 +1103,18 @@ def hnf(A, include_zero_rows=True, proof=True): return H.matrix_from_rows(range(len(pivots))), pivots while True: - H, pivots = probable_hnf(A, include_zero_rows=include_zero_rows, + try: + H, pivots = probable_hnf(A, include_zero_rows=include_zero_rows, proof=True) + except ValueError: + verbose("The attempt failed since the pivots must have been wrong. We try again.") + continue + if is_in_hnf_form(H, pivots): if not include_zero_rows and len(pivots) > H.nrows(): H = H.matrix_from_rows(range(len(pivots))) return H, pivots - verbose("After attempt the return matrix is not in HNF form since pivots must have been wrong. We try again.") + verbose("After attempt the return matrix is not in HNF form since pivots must have been wrong. We try again.") def hnf_with_transformation(A, proof=True): From 4a76ffbc23338e4ffc97c6c006e52340ea7723e3 Mon Sep 17 00:00:00 2001 From: Marc Mezzarobba Date: Tue, 20 Apr 2021 19:13:51 +0200 Subject: [PATCH 217/529] #33734 variety(): prepare for multiple algorithm options --- .../polynomial/multi_polynomial_ideal.py | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_ideal.py b/src/sage/rings/polynomial/multi_polynomial_ideal.py index 8006df3a989..5762b701e80 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ideal.py +++ b/src/sage/rings/polynomial/multi_polynomial_ideal.py @@ -2283,7 +2283,7 @@ def saturation(self, other): return (R.ideal(ideal), ZZ(expo)) @require_field - def variety(self, ring=None): + def variety(self, ring=None, *, algorithm="triangular_decomposition"): r""" Return the variety of this ideal. @@ -2432,6 +2432,23 @@ def variety(self, ring=None): sage: v["y"] -7.464101615137755? + ALGORITHM: + + Uses triangular decomposition. + """ + if algorithm == "triangular_decomposition": + return self._variety_triangular_decomposition(ring) + else: + raise ValueError(f"unknown algorithm {algorithm!r}") + + def _variety_triangular_decomposition(self, ring): + r""" + Compute the variety of this ideal by triangular decomposition. + + The triangular decomposition is computed using Singular when conversion + of the ideal to Singular is supported, falling back to a toy Python + implementation otherwise. + TESTS:: sage: K. = GF(27) @@ -2531,10 +2548,8 @@ def variety(self, ring=None): sage: len(I.variety()) 4 - ALGORITHM: - - Uses triangular decomposition. """ + def _variety(T, V, v=None): """ Return variety ``V`` for one triangular set of @@ -2571,7 +2586,7 @@ def _variety(T, V, v=None): return [] if isinstance(self.base_ring(), sage.rings.abc.ComplexField): - verbose("Warning: computations in the complex field are inexact; variety may be computed partially or incorrectly.", level=0) + verbose("Warning: computations in the complex field are inexact; variety may be computed partially or incorrectly.", level=0, caller_name="variety") P = self.ring() if ring is not None: P = P.change_ring(ring) @@ -2580,7 +2595,7 @@ def _variety(T, V, v=None): T = [list(each.gens()) for each in TI] except TypeError: # conversion to Singular not supported if self.ring().term_order().is_global(): - verbose("Warning: falling back to very slow toy implementation.", level=0) + verbose("Warning: falling back to very slow toy implementation.", level=0, caller_name="variety") T = toy_variety.triangular_factorization(self.groebner_basis()) else: raise TypeError("Local/unknown orderings not supported by 'toy_buchberger' implementation.") From dc858c51c259363bbf4ff29f226dab3009bb396c Mon Sep 17 00:00:00 2001 From: Marc Mezzarobba Date: Wed, 21 Apr 2021 18:11:11 +0200 Subject: [PATCH 218/529] =?UTF-8?q?#33734=20variety()=20over=20=E2=84=9A?= =?UTF-8?q?=20using=20msolve?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/sage/rings/polynomial/msolve.py | 220 ++++++++++++++++++ .../polynomial/multi_polynomial_ideal.py | 22 +- 2 files changed, 239 insertions(+), 3 deletions(-) create mode 100644 src/sage/rings/polynomial/msolve.py diff --git a/src/sage/rings/polynomial/msolve.py b/src/sage/rings/polynomial/msolve.py new file mode 100644 index 00000000000..f7381a8697d --- /dev/null +++ b/src/sage/rings/polynomial/msolve.py @@ -0,0 +1,220 @@ +# coding: utf-8 +r""" +Solution of polynomial systems using msolve + +`msolve `_ is a multivariate polynomial system solver +developed mainly by Jérémy Berthomieu (Sorbonne University), Christian Eder +(TU Kaiserslautern), and Mohab Safey El Din (Sorbonne University). + +This module provide implementations of some operations on polynomial ideals +based on msolve. Currently the only supported operation is the computation of +the variety of zero-dimensional ideal over the rationals. + +Note that msolve is currently not part of Sage and must be installed +separately. The present interface looks for a binary named ``msolve`` in the +system program path (``$PATH``). + +.. SEEALSO:: :mod:`sage.rings.polynomial.multi_polynomial_ideal` +""" + +import os +import tempfile +import subprocess + +import sage.structure.proof.proof + +from sage.misc.all import SAGE_TMP +from sage.misc.converting_dict import KeyConvertingDict +from sage.misc.sage_eval import sage_eval +from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing +from sage.rings.rational_field import QQ +from sage.rings.real_arb import RealBallField +from sage.rings.real_double import RealDoubleField_class +from sage.rings.real_mpfr import RealField_class +from sage.rings.real_mpfi import RealIntervalField_class, RealIntervalField + + +def _variety(ideal, ring, proof): + r""" + Compute the variety of a zero-dimensional ideal using msolve. + + Part of the initial implementation was loosely based on the example + interfaces available as part of msolve, with the authors' permission. + + TESTS:: + + sage: K. = PolynomialRing(QQ, 2, order='lex') + sage: I = Ideal([ x*y - 1, (x-2)^2 + (y-1)^2 - 1]) + + sage: I.variety(algorithm='msolve', proof=False) # optional - msolve + [{x: 1, y: 1}] + sage: I.variety(RealField(100), algorithm='msolve', proof=False) # optional - msolve + [{x: 2.7692923542386314152404094643, y: 0.36110308052864737763464656216}, + {x: 1.0000000000000000000000000000, y: 1.0000000000000000000000000000}] + sage: I.variety(RealIntervalField(100), algorithm='msolve', proof=False) # optional - msolve + [{x: 2.76929235423863141524040946434?, y: 0.361103080528647377634646562159?}, + {x: 1, y: 1}] + sage: I.variety(RBF, algorithm='msolve', proof=False) # optional - msolve + [{x: [2.76929235423863 +/- 2.08e-15], y: [0.361103080528647 +/- 4.53e-16]}, + {x: 1.000000000000000, y: 1.000000000000000}] + sage: I.variety(RDF, algorithm='msolve', proof=False) # optional - msolve + [{x: 2.7692923542386314, y: 0.36110308052864737}, {x: 1.0, y: 1.0}] + sage: I.variety(AA, algorithm='msolve', proof=False) # optional - msolve + [{x: 2.769292354238632?, y: 0.3611030805286474?}, + {x: 1.000000000000000?, y: 1.000000000000000?}] + sage: I.variety(QQbar, algorithm='msolve', proof=False) # optional - msolve + [{x: 2.769292354238632?, y: 0.3611030805286474?}, + {x: 1, y: 1}, + {x: 0.11535382288068429? + 0.5897428050222055?*I, y: 0.3194484597356763? - 1.633170240915238?*I}, + {x: 0.11535382288068429? - 0.5897428050222055?*I, y: 0.3194484597356763? + 1.633170240915238?*I}] + sage: I.variety(ComplexField(100)) + [{y: 1.0000000000000000000000000000, x: 1.0000000000000000000000000000}, + {y: 0.36110308052864737763464656216, x: 2.7692923542386314152404094643}, + {y: 0.31944845973567631118267671892 - 1.6331702409152376561188467320*I, x: 0.11535382288068429237979526783 + 0.58974280502220550164728074602*I}, + {y: 0.31944845973567631118267671892 + 1.6331702409152376561188467320*I, x: 0.11535382288068429237979526783 - 0.58974280502220550164728074602*I}] + + sage: Ideal(x^2 + y^2 - 1, x - y).variety(RBF, algorithm='msolve', proof=False) # optional - msolve + [{x: [-0.707106781186547 +/- 6.29e-16], y: [-0.707106781186547 +/- 6.29e-16]}, + {x: [0.707106781186547 +/- 6.29e-16], y: [0.707106781186547 +/- 6.29e-16]}] + sage: sorted(Ideal(x^2 - 1, y^2 - 1).variety(QQ, algorithm='msolve', proof=False), key=str) # optional - msolve + [{x: -1, y: -1}, {x: -1, y: 1}, {x: 1, y: -1}, {x: 1, y: 1}] + sage: Ideal(x^2-1, y^2-2).variety(CC, algorithm='msolve', proof=False) # optional - msolve + [{x: 1.00000000000000, y: 1.41421356237310}, + {x: -1.00000000000000, y: 1.41421356237309}, + {x: 1.00000000000000, y: -1.41421356237309}, + {x: -1.00000000000000, y: -1.41421356237310}] + + sage: Ideal([x, y, x + y]).variety(algorithm='msolve', proof=False) # optional - msolve + [{x: 0, y: 0}] + + sage: Ideal([x, y, x + y - 1]).variety(algorithm='msolve', proof=False) # optional - msolve + [] + sage: Ideal([x, y, x + y - 1]).variety(RR, algorithm='msolve', proof=False) # optional - msolve + [] + + sage: Ideal([x*y - 1]).variety(QQbar, algorithm='msolve', proof=False) # optional - msolve + Traceback (most recent call last): + ... + ValueError: positive-dimensional ideal + + sage: K. = PolynomialRing(RR, 2, order='lex') + sage: Ideal(x, y).variety(algorithm='msolve', proof=False) + Traceback (most recent call last): + ... + NotImplementedError: unsupported base field: Real Field with 53 bits of precision + + sage: K. = PolynomialRing(QQ, 2, order='lex') + sage: Ideal(x, y).variety(ZZ, algorithm='msolve', proof=False) + Traceback (most recent call last): + ... + ValueError: no coercion from base field Rational Field to output ring Integer Ring + """ + + # Normalize and check input + + base = ideal.base_ring() + if ring is None: + ring = base + proof = sage.structure.proof.proof.get_flag(proof, "polynomial") + if proof: + raise ValueError("msolve relies on heuristics; please use proof=False") + # As of msolve 0.2.4, prime fields seem to be supported, by I cannot + # make sense of msolve's output in the positive characteristic case. + # if not (base is QQ or isinstance(base, FiniteField) and + # base.is_prime_field() and base.characteristic() < 2**31): + if base is not QQ: + raise NotImplementedError(f"unsupported base field: {base}") + if not ring.has_coerce_map_from(base): + raise ValueError( + f"no coercion from base field {base} to output ring {ring}") + + # Run msolve + + drlpolring = ideal.ring().change_ring(order='degrevlex') + polys = ideal.change_ring(drlpolring).gens() + msolve_in = tempfile.NamedTemporaryFile(dir=SAGE_TMP, mode='w', + encoding='ascii', delete=False) + command = ["msolve", "-f", msolve_in.name] + if isinstance(ring, (RealIntervalField_class, RealBallField, + RealField_class, RealDoubleField_class)): + parameterization = False + command += ["-p", str(ring.precision())] + else: + parameterization = True + command += ["-P", "1"] + try: + print(",".join(drlpolring.variable_names()), file=msolve_in) + print(base.characteristic(), file=msolve_in) + print(*(pol._repr_().replace(" ", "") for pol in polys), + sep=',\n', file=msolve_in) + msolve_in.close() + msolve_out = subprocess.run(command, capture_output=True) + except FileNotFoundError: + raise RuntimeError( + "could not find the msolve binary. Please install msolve " + "(https://msolve.lip6.fr/) and try again.") + finally: + os.unlink(msolve_in.name) + msolve_out.check_returncode() + + # Interpret output + + data = sage_eval(msolve_out.stdout[:-2].decode('ascii')) + + dim = data[0] + if dim == -1: + return [] + elif dim > 0: + raise ValueError("positive-dimensional ideal") + else: + assert dim.is_zero() + + out_ring = ideal.ring().change_ring(ring) + + if parameterization: + + def to_poly(p, upol=PolynomialRing(base, 't')): + assert len(p[1]) == p[0] + 1 + return upol(p[1]) + + if len(data) != 3: + raise NotImplementedError( + f"unsupported msolve output format: {data}") + [dim1, nvars, _, vars, _, [one, elim, den, param]] = data[1] + assert dim1.is_zero() + assert one.is_one() + assert len(vars) == nvars + ringvars = out_ring.variable_names() + assert sorted(vars[:len(ringvars)]) == sorted(ringvars) + vars = [out_ring(name) for name in vars[:len(ringvars)]] + elim = to_poly(elim) + den = to_poly(den) + param = [to_poly(f)/d for [f, d] in param] + elim_roots = elim.roots(ring, multiplicities=False) + variety = [] + for rt in elim_roots: + den_of_rt = den(rt) + point = [-p(rt)/den_of_rt for p in param] + if len(param) != len(vars): + point.append(rt) + assert len(point) == len(vars) + variety.append(point) + + else: + + if len(data) != 2 or data[1][0] != 1: + raise NotImplementedError( + f"unsupported msolve output format: {data}") + _, [_, variety] = data + if isinstance(ring, (RealIntervalField_class, RealBallField)): + to_out_ring = ring + else: + assert isinstance(ring, (RealField_class, RealDoubleField_class)) + myRIF = RealIntervalField(ring.precision()) + to_out_ring = lambda iv: ring.coerce(myRIF(iv).center()) + vars = out_ring.gens() + variety = [[to_out_ring(iv) for iv in point] + for point in variety] + + return [KeyConvertingDict(out_ring, zip(vars, point)) for point in variety] + diff --git a/src/sage/rings/polynomial/multi_polynomial_ideal.py b/src/sage/rings/polynomial/multi_polynomial_ideal.py index 5762b701e80..a32b9fe3d1f 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ideal.py +++ b/src/sage/rings/polynomial/multi_polynomial_ideal.py @@ -232,6 +232,7 @@ # https://www.gnu.org/licenses/ # **************************************************************************** + from sage.interfaces.singular import singular as singular_default from sage.interfaces.magma import magma as magma_default @@ -2283,7 +2284,7 @@ def saturation(self, other): return (R.ideal(ideal), ZZ(expo)) @require_field - def variety(self, ring=None, *, algorithm="triangular_decomposition"): + def variety(self, ring=None, *, algorithm="triangular_decomposition", proof=True): r""" Return the variety of this ideal. @@ -2317,6 +2318,8 @@ def variety(self, ring=None, *, algorithm="triangular_decomposition"): - ``ring`` - return roots in the ``ring`` instead of the base ring of this ideal (default: ``None``) + - ``algorithm`` - algorithm or implementation to use; see below for + supported values - ``proof`` - return a provably correct result (default: ``True``) EXAMPLES:: @@ -2370,7 +2373,9 @@ def variety(self, ring=None, *, algorithm="triangular_decomposition"): sage: I.variety(ring=AA) [{y: 1, x: 1}, {y: 0.3611030805286474?, x: 2.769292354238632?}] - + sage: I.variety(RBF, algorithm='msolve', proof=False) # optional - msolve + [{x: [2.76929235423863 +/- 2.08e-15], y: [0.361103080528647 +/- 4.53e-16]}, + {x: 1.000000000000000, y: 1.000000000000000}] and a total of four intersections:: @@ -2434,10 +2439,21 @@ def variety(self, ring=None, *, algorithm="triangular_decomposition"): ALGORITHM: - Uses triangular decomposition. + - With ``algorithm`` = ``"triangular_decomposition"`` (default), + uses triangular decomposition, via Singular if possible, falling back + on a toy implementation otherwise. + + - With ``algorithm`` = ``"msolve"``, calls the external program + `msolve `_ (if available in the system + program search path). Note that msolve uses heuristics and therefore + requires setting the ``proof`` flag to ``False``. See + :mod:`~sage.rings.polynomial.msolve` for more information. """ if algorithm == "triangular_decomposition": return self._variety_triangular_decomposition(ring) + elif algorithm == "msolve": + from . import msolve + return msolve._variety(self, ring, proof) else: raise ValueError(f"unknown algorithm {algorithm!r}") From 43f9458f40012e3d456a1a3f5e0bd2117f7952f1 Mon Sep 17 00:00:00 2001 From: Marc Mezzarobba Date: Wed, 20 Apr 2022 13:49:54 +0200 Subject: [PATCH 219/529] #33734 sage.features.msolve --- src/sage/features/msolve.py | 57 +++++++++++++++++++++++++++++ src/sage/rings/polynomial/msolve.py | 16 ++++---- 2 files changed, 65 insertions(+), 8 deletions(-) create mode 100644 src/sage/features/msolve.py diff --git a/src/sage/features/msolve.py b/src/sage/features/msolve.py new file mode 100644 index 00000000000..fa6679c2014 --- /dev/null +++ b/src/sage/features/msolve.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +r""" +Feature for testing the presence of msolve + +`msolve `_ is a multivariate polynomial system solver +developed mainly by Jérémy Berthomieu (Sorbonne University), Christian Eder +(TU Kaiserslautern), and Mohab Safey El Din (Sorbonne University). +""" + +import subprocess +from . import Executable +from . import FeatureTestResult + +class msolve(Executable): + r""" + A :class:`~sage.features.Feature` describing the presence of msolve + + EXAMPLES:: + + sage: from sage.features.msolve import msolve + sage: msolve().is_present() # optional - msolve + FeatureTestResult('msolve', True) + """ + def __init__(self): + r""" + TESTS:: + + sage: from sage.features.msolve import msolve + sage: isinstance(msolve(), msolve) + True + """ + Executable.__init__(self, "msolve", executable="msolve", + url="https://msolve.lip6.fr/") + + def is_functional(self): + r""" + Test if our installation of msolve is working + + EXAMPLES:: + + sage: from sage.features.msolve import msolve + sage: msolve().is_functional() # optional - msolve + FeatureTestResult('msolve', True) + """ + msolve_out = subprocess.run(["msolve", "-h"], capture_output=True) + + if msolve_out.returncode != 0: + return FeatureTestResult(self, False, reason="msolve -h returned " + f"non-zero exit status {msolve_out.returncode}") + elif (msolve_out.stdout[:46] != + b'\nmsolve library for polynomial system solving\n'): + return FeatureTestResult(self, False, + reason="output of msolve -h not recognized") + return FeatureTestResult(self, True) + +def all_features(): + return [msolve()] diff --git a/src/sage/rings/polynomial/msolve.py b/src/sage/rings/polynomial/msolve.py index f7381a8697d..6e0ccf4ead0 100644 --- a/src/sage/rings/polynomial/msolve.py +++ b/src/sage/rings/polynomial/msolve.py @@ -10,11 +10,12 @@ based on msolve. Currently the only supported operation is the computation of the variety of zero-dimensional ideal over the rationals. -Note that msolve is currently not part of Sage and must be installed -separately. The present interface looks for a binary named ``msolve`` in the -system program path (``$PATH``). +Note that msolve must be installed separately. -.. SEEALSO:: :mod:`sage.rings.polynomial.multi_polynomial_ideal` +.. SEEALSO:: + +- :mod:`sage.features.msolve` +- :mod:`sage.rings.polynomial.multi_polynomial_ideal` """ import os @@ -23,6 +24,7 @@ import sage.structure.proof.proof +from sage.features.msolve import msolve from sage.misc.all import SAGE_TMP from sage.misc.converting_dict import KeyConvertingDict from sage.misc.sage_eval import sage_eval @@ -130,6 +132,8 @@ def _variety(ideal, ring, proof): # Run msolve + msolve().require() + drlpolring = ideal.ring().change_ring(order='degrevlex') polys = ideal.change_ring(drlpolring).gens() msolve_in = tempfile.NamedTemporaryFile(dir=SAGE_TMP, mode='w', @@ -149,10 +153,6 @@ def _variety(ideal, ring, proof): sep=',\n', file=msolve_in) msolve_in.close() msolve_out = subprocess.run(command, capture_output=True) - except FileNotFoundError: - raise RuntimeError( - "could not find the msolve binary. Please install msolve " - "(https://msolve.lip6.fr/) and try again.") finally: os.unlink(msolve_in.name) msolve_out.check_returncode() From 0312ac6af931b936bdf0476f522078f6e55c2622 Mon Sep 17 00:00:00 2001 From: Marc Mezzarobba Date: Thu, 21 Apr 2022 17:46:42 +0200 Subject: [PATCH 220/529] #33734 minor style change following reviewer comment --- src/sage/rings/polynomial/msolve.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/polynomial/msolve.py b/src/sage/rings/polynomial/msolve.py index 6e0ccf4ead0..cbdf084cfa5 100644 --- a/src/sage/rings/polynomial/msolve.py +++ b/src/sage/rings/polynomial/msolve.py @@ -152,14 +152,14 @@ def _variety(ideal, ring, proof): print(*(pol._repr_().replace(" ", "") for pol in polys), sep=',\n', file=msolve_in) msolve_in.close() - msolve_out = subprocess.run(command, capture_output=True) + msolve_out = subprocess.run(command, capture_output=True, text=True) finally: os.unlink(msolve_in.name) msolve_out.check_returncode() # Interpret output - data = sage_eval(msolve_out.stdout[:-2].decode('ascii')) + data = sage_eval(msolve_out.stdout[:-2]) dim = data[0] if dim == -1: From 8ebbe460122993aac172cce0cf975ef17b643766 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Mon, 25 Apr 2022 15:00:44 +0200 Subject: [PATCH 221/529] trac #33749: doctest on position dictionary --- src/sage/graphs/digraph_generators.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/sage/graphs/digraph_generators.py b/src/sage/graphs/digraph_generators.py index da9b7dec81f..0624a393625 100644 --- a/src/sage/graphs/digraph_generators.py +++ b/src/sage/graphs/digraph_generators.py @@ -257,7 +257,19 @@ def ButterflyGraph(self, n, vertices='strings'): (((1, 1), 0), ((1, 1), 1)), (((1, 1), 1), ((1, 0), 2)), (((1, 1), 1), ((1, 1), 2))] - sage: digraphs.ButterflyGraph(3).show() # long time + sage: digraphs.ButterflyGraph(2).get_pos() + {('11', 0): (0, 0), + ('11', 1): (2, 0), + ('11', 2): (4, 0), + ('10', 0): (0, 1), + ('10', 1): (2, 1), + ('10', 2): (4, 1), + ('01', 0): (0, 2), + ('01', 1): (2, 2), + ('01', 2): (4, 2), + ('00', 0): (0, 3), + ('00', 1): (2, 3), + ('00', 2): (4, 3)} TESTS:: From 5cbb17bdec5979f0220dae3dd8c79a115dae7896 Mon Sep 17 00:00:00 2001 From: Vincent Delecroix <20100.delecroix@gmail.com> Date: Mon, 25 Apr 2022 22:56:19 +0200 Subject: [PATCH 222/529] 33759: correctly clean embedding --- src/sage/graphs/generic_graph.py | 36 +++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index a57e74c632a..dde46ee0f5c 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -10290,19 +10290,39 @@ def delete_vertices(self, vertices): ... ValueError: vertex (1) not in the graph + TESTS: + + Test that :trac:`33759` is fixed:: + + sage: G = Graph([(1, 4), (2, 3)]) + sage: G.is_planar(set_embedding=True) + True + sage: G.delete_vertices([3]) + sage: G.is_planar() + True """ vertices = list(vertices) - for vertex in vertices: - if vertex not in self: - raise ValueError("vertex (%s) not in the graph"%str(vertex)) + for v in vertices: + if v not in self: + raise ValueError("vertex (%s) not in the graph"%str(v)) - self._backend.del_vertices(vertices) - attributes_to_update = ('_pos', '_assoc', '_embedding') - for attr in attributes_to_update: + for attr in ('_pos', '_assoc'): if hasattr(self, attr) and getattr(self, attr) is not None: attr_dict = getattr(self, attr) - for vertex in vertices: - attr_dict.pop(vertex, None) + for v in vertices: + del attr_dict[v] + + if hasattr(self, '_embedding'): + embedding = self._embedding + if self._embedding is not None: + neighbors = set().union(*[self.neighbor_iterator(v) for v in vertices]) + neighbors.difference_update(vertices) + for w in neighbors: + embedding[w] = [x for x in embedding[w] if x not in vertices] + for v in vertices: + del embedding[v] + + self._backend.del_vertices(vertices) def has_vertex(self, vertex): """ From 8cc16103c6943c5df7f2ead403e10d4cdc52a9e8 Mon Sep 17 00:00:00 2001 From: "John H. Palmieri" Date: Mon, 25 Apr 2022 15:07:17 -0700 Subject: [PATCH 223/529] trac 33735: remove some deprecated (and now undocumented) modules from the ref manual --- src/doc/en/reference/calculus/index.rst | 6 ------ src/doc/en/reference/constants/index.rst | 1 - src/doc/en/reference/finance/index.rst | 1 - 3 files changed, 8 deletions(-) diff --git a/src/doc/en/reference/calculus/index.rst b/src/doc/en/reference/calculus/index.rst index c49c4bd8dd4..abbb408f6e9 100644 --- a/src/doc/en/reference/calculus/index.rst +++ b/src/doc/en/reference/calculus/index.rst @@ -25,7 +25,6 @@ Using calculus - :doc:`Main operations on symbolic expressions ` - :doc:`Assumptions about symbols and functions ` - :doc:`sage/symbolic/relation` -- :doc:`sage/symbolic/series` - :doc:`sage/symbolic/integration/integral` - :doc:`sage/calculus/desolvers` - :doc:`sage/calculus/ode` @@ -49,7 +48,6 @@ Internal functionality supporting calculus - :doc:`sage/symbolic/ring` - :doc:`sage/symbolic/subring` - :doc:`sage/symbolic/operators` -- :doc:`sage/symbolic/getitem` - :doc:`sage/symbolic/function` - :doc:`sage/calculus/functional` - :doc:`sage/symbolic/function_factory` @@ -58,7 +56,6 @@ Internal functionality supporting calculus - :doc:`sage/symbolic/substitution_map` - :doc:`sage/symbolic/benchmark` - :doc:`sage/symbolic/random_tests` -- :doc:`sage/libs/pynac/pynac` - :doc:`sage/symbolic/maxima_wrapper` - :doc:`External integrators ` - :doc:`External interpolators ` @@ -78,7 +75,6 @@ Internal functionality supporting calculus sage/symbolic/function sage/symbolic/function_factory sage/calculus/functional - sage/symbolic/series sage/symbolic/integration/integral sage/symbolic/integration/external sage/calculus/test_sympy @@ -97,12 +93,10 @@ Internal functionality supporting calculus sage/calculus/interpolators sage/calculus/functions sage/calculus/var - sage/symbolic/getitem sage/symbolic/maxima_wrapper sage/symbolic/operators sage/symbolic/substitution_map sage/symbolic/benchmark sage/symbolic/random_tests - sage/libs/pynac/pynac .. include:: ../footer.txt diff --git a/src/doc/en/reference/constants/index.rst b/src/doc/en/reference/constants/index.rst index a10ee041555..96ae5e256ae 100644 --- a/src/doc/en/reference/constants/index.rst +++ b/src/doc/en/reference/constants/index.rst @@ -5,6 +5,5 @@ Constants :maxdepth: 2 sage/symbolic/constants - sage/symbolic/constants_c .. include:: ../footer.txt diff --git a/src/doc/en/reference/finance/index.rst b/src/doc/en/reference/finance/index.rst index 28bddb84cd8..bba570a13ae 100644 --- a/src/doc/en/reference/finance/index.rst +++ b/src/doc/en/reference/finance/index.rst @@ -4,7 +4,6 @@ Quantitative Finance .. toctree:: :maxdepth: 2 - sage/finance/time_series sage/finance/stock sage/finance/option sage/finance/fractal From e15e83a2974894a886bc38bf1c6c87a1e04dcccc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 26 Apr 2022 10:01:20 +0200 Subject: [PATCH 224/529] typo and wrap --- src/sage/groups/group_semidirect_product.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/sage/groups/group_semidirect_product.py b/src/sage/groups/group_semidirect_product.py index e5439ce0366..120f6f96bbc 100644 --- a/src/sage/groups/group_semidirect_product.py +++ b/src/sage/groups/group_semidirect_product.py @@ -132,7 +132,7 @@ def to_opposite(self): class GroupSemidirectProduct(CartesianProduct): r""" - Return the semidirect product of the groups ``G`` and ``H``using the homomorphism ``twist``. + Return the semidirect product of the groups ``G`` and ``H`` using the homomorphism ``twist``. INPUT: @@ -260,9 +260,12 @@ def __init__(self, G, H, twist=None, act_to_right=True, prefix0=None, def check_implemented_group(x): if x in Groups(): return - error = "The semidirect product construction for groups is implemented only for multiplicative groups" + error = ("The semidirect product construction for groups " + "is implemented only for multiplicative groups") if x in CommutativeAdditiveGroups(): - error = error + ". Please change the commutative additive group %s into a multiplicative group using the functor sage.groups.group_exp.GroupExp" % x + error += (f". Please change the commutative additive group {x}" + " into a multiplicative group " + "using the functor sage.groups.group_exp.GroupExp") raise TypeError(error) check_implemented_group(G) From 68de80fb77b510f49cc942b7d1424cadd535b9d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 15 Apr 2022 15:59:36 +0200 Subject: [PATCH 225/529] details in interval posets --- src/sage/combinat/interval_posets.py | 56 +++++++++++++--------------- 1 file changed, 26 insertions(+), 30 deletions(-) diff --git a/src/sage/combinat/interval_posets.py b/src/sage/combinat/interval_posets.py index 129709c82cb..d2b8449017d 100644 --- a/src/sage/combinat/interval_posets.py +++ b/src/sage/combinat/interval_posets.py @@ -186,7 +186,7 @@ class TamariIntervalPoset(Element, The Tamari interval of size 0 induced by relations [] """ @staticmethod - def __classcall_private__(cls, *args, **opts): + def __classcall_private__(cls, *args, **opts) -> TIP: r""" Ensure that interval-posets created by the enumerated sets and directly are the same and that they are instances of @@ -246,7 +246,7 @@ def __init__(self, parent, size, relations=None, check=True): Element.__init__(self, parent) self._cover_relations = tuple(self._poset.cover_relations()) - self._latex_options = dict() + self._latex_options = {} def set_latex_options(self, D): r""" @@ -537,7 +537,7 @@ def draw_decreasing(i, j) -> str: return start + nodes + relations + end - def poset(self): + def poset(self) -> Poset: r""" Return ``self`` as a labelled poset. @@ -2531,8 +2531,8 @@ def extract_tree(x, y, tilt, common): break return BinaryTree([left_tree, right_tree], check=False) - TIP = self.parent() - return [TIP.from_binary_trees(extract_tree(cx, cy, t_low, common), + tip = self.parent() + return [tip.from_binary_trees(extract_tree(cx, cy, t_low, common), extract_tree(cx, cy, t_up, common)) for cx, cy in common] @@ -3042,12 +3042,12 @@ def final_forest(element) -> TIP: """ if isinstance(element, TamariIntervalPoset): return element.final_forest() - elif element in DyckWords(): + if element in DyckWords(): binary_tree = element.to_binary_tree_tamari() elif element in BinaryTrees() or element in LabelledBinaryTrees(): binary_tree = element else: - raise ValueError("do not know how to construct the final forest of {}".format(element)) + raise ValueError(f"do not know how to construct the final forest of {element}") def get_relations(bt, start=1): r""" @@ -3074,7 +3074,7 @@ def get_relations(bt, start=1): relations.extend([(j, index) for j in rroots]) return roots, relations, rindex - roots, relations, index = get_relations(binary_tree) + _, relations, index = get_relations(binary_tree) P = FinitePoset(DiGraph([list(range(1, index)), relations], format='vertices_and_edges')) # type:ignore return TamariIntervalPoset(P, check=False) # type:ignore @@ -3146,16 +3146,15 @@ def initial_forest(element) -> TIP: Traceback (most recent call last): ... ValueError: do not know how to construct the initial forest of mont - """ if isinstance(element, TamariIntervalPoset): return element.initial_forest() - elif element in DyckWords(): + if element in DyckWords(): binary_tree = element.to_binary_tree_tamari() elif element in BinaryTrees() or element in LabelledBinaryTrees(): binary_tree = element else: - raise ValueError("do not know how to construct the initial forest of {}".format(element)) + raise ValueError(f"do not know how to construct the initial forest of {element}") def get_relations(bt, start=1): r""" @@ -3182,7 +3181,7 @@ def get_relations(bt, start=1): relations.extend([(j, index) for j in lroots]) return roots, relations, rindex - roots, relations, index = get_relations(binary_tree) + _, relations, index = get_relations(binary_tree) P = FinitePoset(DiGraph([list(range(1, index)), relations], format='vertices_and_edges')) # type:ignore return TamariIntervalPoset(P, check=False) # type:ignore @@ -3437,7 +3436,6 @@ def from_minimal_schnyder_wood(graph) -> TIP: sage: TIP.from_minimal_schnyder_wood(G) The Tamari interval of size 3 induced by relations [(2, 3), (2, 1)] """ - from sage.graphs.digraph import DiGraph from sage.combinat.dyck_word import DyckWord color_a = graph.incoming_edges(-1)[0][2] color_b = graph.incoming_edges(-2)[0][2] @@ -3468,20 +3466,18 @@ def from_minimal_schnyder_wood(graph) -> TIP: def clockwise_labelling(gr, vertex): if len(gr) == 1: return [vertex] - else: - lbl = [vertex] - for w in voisins_in[vertex]: - lbl += clockwise_labelling(gr, w) - return lbl + lbl = [vertex] + for w in voisins_in[vertex]: + lbl += clockwise_labelling(gr, w) + return lbl def profil(gr, vertex): if len(gr) == 1: return [] - else: - lbl = [] - for w in voisins_in[vertex]: - lbl += [1] + profil(gr, w) + [0] - return lbl + lbl = [] + for w in voisins_in[vertex]: + lbl += [1] + profil(gr, w) + [0] + return lbl dyckword_bottom = profil(graph0, -1) # this is the profile of the planar graph graph0 @@ -3503,8 +3499,8 @@ def profil(gr, vertex): dyckword_bottom = DyckWord(dyckword_bottom) # type:ignore dyckword_top = DyckWord(dyckword_top) # type:ignore - TIP = TamariIntervalPosets(len(dyckword_bottom) // 2) - return TIP.from_dyck_words(dyckword_bottom, dyckword_top) + tip = TamariIntervalPosets(len(dyckword_bottom) // 2) + return tip.from_dyck_words(dyckword_bottom, dyckword_top) def __call__(self, *args, **keywords): r""" @@ -3534,7 +3530,7 @@ def __call__(self, *args, **keywords): if len(args) == 1 and isinstance(args[0], FinitePoset): return self.element_class(self, args[0]) - return super(TamariIntervalPosets, self).__call__(*args, **keywords) + return super().__call__(*args, **keywords) def le(self, el1, el2) -> bool: r""" @@ -3669,7 +3665,7 @@ def __init__(self, size): """ # there is a natural order on interval-posets through inclusions # that is why we use the FinitePosets category - super(TamariIntervalPosets_size, self).__init__(category=(FinitePosets(), FiniteEnumeratedSets())) + super().__init__(category=(FinitePosets(), FiniteEnumeratedSets())) self._size = size @@ -3680,7 +3676,7 @@ def _repr_(self) -> str: sage: TamariIntervalPosets(3) Interval-posets of size 3 """ - return "Interval-posets of size {}".format(self._size) + return f"Interval-posets of size {self._size}" def __contains__(self, x) -> bool: r""" @@ -3813,10 +3809,10 @@ def random_element(self) -> TIP: from sage.graphs.generators.random import RandomTriangulation n = self._size tri = RandomTriangulation(n + 3) - TIP = TamariIntervalPosets + tip = TamariIntervalPosets schnyder = minimal_schnyder_wood(tri, root_edge=(-1, -2), check=False) - return TIP.from_minimal_schnyder_wood(schnyder) + return tip.from_minimal_schnyder_wood(schnyder) @lazy_attribute def _parent_for(self): From 35b802869fa90f03a17198f7b5e14f5a8cd44621 Mon Sep 17 00:00:00 2001 From: Vincent Delecroix <20100.delecroix@gmail.com> Date: Tue, 26 Apr 2022 20:33:19 +0200 Subject: [PATCH 226/529] 33759: use d.pop(v) instead of del d[v] --- src/sage/graphs/generic_graph.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index dde46ee0f5c..26f0ead24f3 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -10310,7 +10310,7 @@ def delete_vertices(self, vertices): if hasattr(self, attr) and getattr(self, attr) is not None: attr_dict = getattr(self, attr) for v in vertices: - del attr_dict[v] + attr_dict.pop(v, None) if hasattr(self, '_embedding'): embedding = self._embedding @@ -10320,7 +10320,7 @@ def delete_vertices(self, vertices): for w in neighbors: embedding[w] = [x for x in embedding[w] if x not in vertices] for v in vertices: - del embedding[v] + embedding.pop(v, None) self._backend.del_vertices(vertices) From 85113706cfab44bd22842cc2825152d1510a4980 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Tue, 26 Apr 2022 18:15:27 +0900 Subject: [PATCH 227/529] Refactor sage/docs --- src/doc/ca/intro/conf.py | 6 +- src/doc/de/a_tour_of_sage/conf.py | 6 +- src/doc/de/thematische_anleitungen/conf.py | 6 +- src/doc/de/tutorial/conf.py | 6 +- src/doc/en/a_tour_of_sage/conf.py | 6 +- src/doc/en/constructions/conf.py | 6 +- src/doc/en/developer/conf.py | 6 +- src/doc/en/faq/conf.py | 6 +- src/doc/en/installation/conf.py | 6 +- src/doc/en/prep/conf.py | 6 +- src/doc/en/reference/conf.py | 6 +- src/doc/en/reference/conf_sub.py | 6 +- src/doc/en/reference/documentation/conf.py | 1 + src/doc/en/reference/documentation/index.rst | 12 + src/doc/en/reference/index.rst | 7 +- src/doc/en/thematic_tutorials/conf.py | 6 +- .../explicit_methods_in_number_theory/conf.py | 6 +- .../thematic_tutorials/numerical_sage/conf.py | 6 +- src/doc/en/tutorial/conf.py | 6 +- src/doc/en/website/conf.py | 6 +- src/doc/es/a_tour_of_sage/conf.py | 6 +- src/doc/es/tutorial/conf.py | 6 +- src/doc/fr/a_tour_of_sage/conf.py | 6 +- src/doc/fr/tutorial/conf.py | 6 +- src/doc/hu/a_tour_of_sage/conf.py | 6 +- src/doc/it/a_tour_of_sage/conf.py | 6 +- src/doc/it/faq/conf.py | 6 +- src/doc/it/tutorial/conf.py | 6 +- src/doc/ja/a_tour_of_sage/conf.py | 6 +- src/doc/ja/tutorial/conf.py | 6 +- src/doc/pt/a_tour_of_sage/conf.py | 6 +- src/doc/pt/tutorial/conf.py | 6 +- src/doc/ru/tutorial/conf.py | 6 +- src/doc/tr/a_tour_of_sage/conf.py | 6 +- src/sage/docs/conf.py | 3 + src/sage/docs/instancedoc.pyx | 217 +- src/sage/interfaces/axiom.py | 2 +- src/sage/interfaces/expect.py | 2 +- src/sage/interfaces/fricas.py | 2 +- src/sage/interfaces/gap.py | 2 +- src/sage/interfaces/giac.py | 2 +- src/sage/interfaces/gp.py | 2 +- src/sage/interfaces/interface.py | 2 +- src/sage/interfaces/kash.py | 2 +- src/sage/interfaces/lie.py | 2 +- src/sage/interfaces/lisp.py | 2 +- src/sage/interfaces/macaulay2.py | 2 +- src/sage/interfaces/magma.py | 20 +- src/sage/interfaces/maple.py | 2 +- src/sage/interfaces/mathematica.py | 2 +- src/sage/interfaces/mathics.py | 2 +- src/sage/interfaces/matlab.py | 2 +- src/sage/interfaces/maxima.py | 4 +- src/sage/interfaces/maxima_abstract.py | 2 +- src/sage/interfaces/maxima_lib.py | 2 +- src/sage/interfaces/mupad.py | 2 +- src/sage/interfaces/octave.py | 2 +- src/sage/interfaces/qepcad.py | 2 +- src/sage/interfaces/r.py | 2 +- src/sage/interfaces/sage0.py | 2 +- src/sage/interfaces/scilab.py | 2 +- src/sage/interfaces/singular.py | 2 +- src/sage/libs/gap/element.pyx | 2 +- src/sage/libs/singular/function.pyx | 2 +- src/sage/misc/cachefunc.pyx | 2 +- src/sage/misc/instancedoc.pyx | 330 +++ src/sage/misc/latex_macros.py | 2 +- src/sage/misc/lazy_import.pyx | 2 +- src/sage/misc/sagedoc.py | 2 +- src/sage/misc/sphinxify.py | 2 +- src/sage/parallel/decorate.py | 2 +- src/sage/sets/set_from_iterator.py | 2 +- src/sage/structure/global_options.py | 2 +- src/sage/symbolic/maxima_wrapper.py | 2 +- src/sage/symbolic/units.py | 2 +- src/sage_docbuild/__init__.py | 1761 ----------------- src/sage_docbuild/__main__.py | 497 ++++- src/sage_docbuild/build_options.py | 9 +- src/sage_docbuild/builders.py | 1358 +++++++++++++ src/sage_docbuild/conf.py | 968 +++++++++ src/sage_docbuild/sphinxbuild.py | 5 +- src/sage_docbuild/utils.py | 12 +- 82 files changed, 3334 insertions(+), 2128 deletions(-) create mode 120000 src/doc/en/reference/documentation/conf.py create mode 100644 src/doc/en/reference/documentation/index.rst create mode 100644 src/sage/misc/instancedoc.pyx create mode 100644 src/sage_docbuild/builders.py create mode 100644 src/sage_docbuild/conf.py diff --git a/src/doc/ca/intro/conf.py b/src/doc/ca/intro/conf.py index 9cafb361385..2f4eb7f1873 100644 --- a/src/doc/ca/intro/conf.py +++ b/src/doc/ca/intro/conf.py @@ -10,13 +10,13 @@ # All configuration values have a default; values that are commented out # serve to show the default. -from sage.docs.conf import release -from sage.docs.conf import * # NOQA +from sage_docbuild.conf import release +from sage_docbuild.conf import * # NOQA # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the -# builtin "default.css". html_common_static_path imported from sage.docs.conf +# builtin "default.css". html_common_static_path imported from sage_docbuild.conf # contains common paths. html_static_path = [] + html_common_static_path diff --git a/src/doc/de/a_tour_of_sage/conf.py b/src/doc/de/a_tour_of_sage/conf.py index a3724e5d1f8..47355ae5a22 100644 --- a/src/doc/de/a_tour_of_sage/conf.py +++ b/src/doc/de/a_tour_of_sage/conf.py @@ -12,13 +12,13 @@ # All configuration values have a default; values that are commented out # serve to show the default. -from sage.docs.conf import release -from sage.docs.conf import * # NOQA +from sage_docbuild.conf import release +from sage_docbuild.conf import * # NOQA # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the -# builtin "default.css". html_common_static_path imported from sage.docs.conf +# builtin "default.css". html_common_static_path imported from sage_docbuild.conf # contains common paths. html_static_path = [] + html_common_static_path diff --git a/src/doc/de/thematische_anleitungen/conf.py b/src/doc/de/thematische_anleitungen/conf.py index 82a9ec207b2..114346944d5 100644 --- a/src/doc/de/thematische_anleitungen/conf.py +++ b/src/doc/de/thematische_anleitungen/conf.py @@ -10,13 +10,13 @@ # All configuration values have a default; values that are commented out # serve to show the default. -from sage.docs.conf import release -from sage.docs.conf import * # NOQA +from sage_docbuild.conf import release +from sage_docbuild.conf import * # NOQA # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the -# builtin "default.css". html_common_static_path imported from sage.docs.conf +# builtin "default.css". html_common_static_path imported from sage_docbuild.conf # contains common paths. html_static_path = [] + html_common_static_path diff --git a/src/doc/de/tutorial/conf.py b/src/doc/de/tutorial/conf.py index 4b7ade4d394..16804d981c9 100644 --- a/src/doc/de/tutorial/conf.py +++ b/src/doc/de/tutorial/conf.py @@ -10,13 +10,13 @@ # All configuration values have a default; values that are commented out # serve to show the default. -from sage.docs.conf import release -from sage.docs.conf import * # NOQA +from sage_docbuild.conf import release +from sage_docbuild.conf import * # NOQA # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the -# builtin "default.css". html_common_static_path imported from sage.docs.conf +# builtin "default.css". html_common_static_path imported from sage_docbuild.conf # contains common paths. html_static_path = [] + html_common_static_path diff --git a/src/doc/en/a_tour_of_sage/conf.py b/src/doc/en/a_tour_of_sage/conf.py index 60f8b638750..89225513782 100644 --- a/src/doc/en/a_tour_of_sage/conf.py +++ b/src/doc/en/a_tour_of_sage/conf.py @@ -10,13 +10,13 @@ # All configuration values have a default; values that are commented out # serve to show the default. -from sage.docs.conf import release -from sage.docs.conf import * # NOQA +from sage_docbuild.conf import release +from sage_docbuild.conf import * # NOQA # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the -# builtin "default.css". html_common_static_path imported from sage.docs.conf +# builtin "default.css". html_common_static_path imported from sage_docbuild.conf # contains common paths. html_static_path = [] + html_common_static_path diff --git a/src/doc/en/constructions/conf.py b/src/doc/en/constructions/conf.py index d50acf00386..eee2feb033a 100644 --- a/src/doc/en/constructions/conf.py +++ b/src/doc/en/constructions/conf.py @@ -10,13 +10,13 @@ # All configuration values have a default; values that are commented out # serve to show the default. -from sage.docs.conf import release -from sage.docs.conf import * # NOQA +from sage_docbuild.conf import release +from sage_docbuild.conf import * # NOQA # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the -# builtin "default.css". html_common_static_path imported from sage.docs.conf +# builtin "default.css". html_common_static_path imported from sage_docbuild.conf # contains common paths. html_static_path = [] + html_common_static_path diff --git a/src/doc/en/developer/conf.py b/src/doc/en/developer/conf.py index 3be07cc7d3e..1ee9e105947 100644 --- a/src/doc/en/developer/conf.py +++ b/src/doc/en/developer/conf.py @@ -10,13 +10,13 @@ # All configuration values have a default; values that are commented out # serve to show the default. -from sage.docs.conf import release -from sage.docs.conf import * # NOQA +from sage_docbuild.conf import release +from sage_docbuild.conf import * # NOQA # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the -# builtin "default.css". html_common_static_path imported from sage.docs.conf +# builtin "default.css". html_common_static_path imported from sage_docbuild.conf # contains common paths. html_static_path = [] + html_common_static_path diff --git a/src/doc/en/faq/conf.py b/src/doc/en/faq/conf.py index 8b70e81e4b6..42c3378b129 100644 --- a/src/doc/en/faq/conf.py +++ b/src/doc/en/faq/conf.py @@ -12,13 +12,13 @@ # All configuration values have a default; values that are commented out # serve to show the default. -from sage.docs.conf import release -from sage.docs.conf import * +from sage_docbuild.conf import release +from sage_docbuild.conf import * # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the -# builtin "default.css". html_common_static_path imported from sage.docs.conf +# builtin "default.css". html_common_static_path imported from sage_docbuild.conf # contains common paths. html_static_path = [] + html_common_static_path diff --git a/src/doc/en/installation/conf.py b/src/doc/en/installation/conf.py index 268f9fa4648..33ed20fa8e9 100644 --- a/src/doc/en/installation/conf.py +++ b/src/doc/en/installation/conf.py @@ -10,13 +10,13 @@ # All configuration values have a default; values that are commented out # serve to show the default. -from sage.docs.conf import release -from sage.docs.conf import * # NOQA +from sage_docbuild.conf import release +from sage_docbuild.conf import * # NOQA # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the -# builtin "default.css". html_common_static_path imported from sage.docs.conf +# builtin "default.css". html_common_static_path imported from sage_docbuild.conf # contains common paths. html_static_path = [] + html_common_static_path diff --git a/src/doc/en/prep/conf.py b/src/doc/en/prep/conf.py index 4891ddc7868..bbc6663b3df 100644 --- a/src/doc/en/prep/conf.py +++ b/src/doc/en/prep/conf.py @@ -10,13 +10,13 @@ # All configuration values have a default; values that are commented out # serve to show the default. -from sage.docs.conf import release -from sage.docs.conf import * # NOQA +from sage_docbuild.conf import release +from sage_docbuild.conf import * # NOQA # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the -# builtin "default.css". html_common_static_path imported from sage.docs.conf +# builtin "default.css". html_common_static_path imported from sage_docbuild.conf # contains common paths. html_static_path = [] + html_common_static_path diff --git a/src/doc/en/reference/conf.py b/src/doc/en/reference/conf.py index 6ce70316d9f..86aa0b05a81 100644 --- a/src/doc/en/reference/conf.py +++ b/src/doc/en/reference/conf.py @@ -12,13 +12,13 @@ import os from sage.env import SAGE_DOC_SRC, SAGE_DOC -from sage.docs.conf import release, latex_elements, exclude_patterns -from sage.docs.conf import * +from sage_docbuild.conf import release, latex_elements, exclude_patterns +from sage_docbuild.conf import * # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the -# builtin "default.css". html_common_static_path imported from sage.docs.conf +# builtin "default.css". html_common_static_path imported from sage_docbuild.conf # contains common paths. html_static_path = [] + html_common_static_path diff --git a/src/doc/en/reference/conf_sub.py b/src/doc/en/reference/conf_sub.py index 9d22a36e497..b6f20311d68 100644 --- a/src/doc/en/reference/conf_sub.py +++ b/src/doc/en/reference/conf_sub.py @@ -12,13 +12,13 @@ import os from sage.env import SAGE_DOC_SRC, SAGE_DOC -from sage.docs.conf import release, exclude_patterns -from sage.docs.conf import * +from sage_docbuild.conf import release, exclude_patterns +from sage_docbuild.conf import * # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the -# builtin "default.css". html_common_static_path imported from sage.docs.conf +# builtin "default.css". html_common_static_path imported from sage_docbuild.conf # contains common paths. html_static_path = [] + html_common_static_path diff --git a/src/doc/en/reference/documentation/conf.py b/src/doc/en/reference/documentation/conf.py new file mode 120000 index 00000000000..2bdf7e68470 --- /dev/null +++ b/src/doc/en/reference/documentation/conf.py @@ -0,0 +1 @@ +../conf_sub.py \ No newline at end of file diff --git a/src/doc/en/reference/documentation/index.rst b/src/doc/en/reference/documentation/index.rst new file mode 100644 index 00000000000..13d17594db3 --- /dev/null +++ b/src/doc/en/reference/documentation/index.rst @@ -0,0 +1,12 @@ +Documentation System +==================== + +.. toctree:: + :maxdepth: 1 + + sage_docbuild/__main__ + sage_docbuild/builders + sage_docbuild/build_options + sage_docbuild/sphinxbuild + sage_docbuild/conf + sage_docbuild/utils diff --git a/src/doc/en/reference/index.rst b/src/doc/en/reference/index.rst index 9cb0d0b47e1..d7667e195ea 100644 --- a/src/doc/en/reference/index.rst +++ b/src/doc/en/reference/index.rst @@ -97,7 +97,7 @@ Geometry, Topology, and Homological Algebra * :doc:`Euclidean Spaces and Vector Calculus ` * :doc:`Combinatorial and Discrete Geometry ` -* :doc:`Cell Complexes, Simplicial Complexes, and +* :doc:`Cell Complexes, Simplicial Complexes, and Simplicial Sets ` * :doc:`Manifolds and Differential Geometry ` * :doc:`Hyperbolic Geometry ` @@ -157,6 +157,11 @@ Interfaces * :doc:`C/C++ Library Interfaces ` * :doc:`Python Technicalities ` +Documentation System +-------------------- + +* :doc:`Documentation System ` + General Information =================== diff --git a/src/doc/en/thematic_tutorials/conf.py b/src/doc/en/thematic_tutorials/conf.py index f5c5af6cb62..3b638d40173 100644 --- a/src/doc/en/thematic_tutorials/conf.py +++ b/src/doc/en/thematic_tutorials/conf.py @@ -12,13 +12,13 @@ # All configuration values have a default; values that are commented out # serve to show the default. -from sage.docs.conf import release -from sage.docs.conf import * +from sage_docbuild.conf import release +from sage_docbuild.conf import * # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the -# builtin "default.css". html_common_static_path imported from sage.docs.conf +# builtin "default.css". html_common_static_path imported from sage_docbuild.conf # contains common paths. html_static_path = [] + html_common_static_path diff --git a/src/doc/en/thematic_tutorials/explicit_methods_in_number_theory/conf.py b/src/doc/en/thematic_tutorials/explicit_methods_in_number_theory/conf.py index 0fba6acc072..cdcbdb584c9 100644 --- a/src/doc/en/thematic_tutorials/explicit_methods_in_number_theory/conf.py +++ b/src/doc/en/thematic_tutorials/explicit_methods_in_number_theory/conf.py @@ -10,13 +10,13 @@ # All configuration values have a default; values that are commented out # serve to show the default. -from sage.docs.conf import release -from sage.docs.conf import * # NOQA +from sage_docbuild.conf import release +from sage_docbuild.conf import * # NOQA # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the -# builtin "default.css". html_common_static_path imported from sage.docs.conf +# builtin "default.css". html_common_static_path imported from sage_docbuild.conf # contains common paths. html_static_path = [] + html_common_static_path diff --git a/src/doc/en/thematic_tutorials/numerical_sage/conf.py b/src/doc/en/thematic_tutorials/numerical_sage/conf.py index da30268c1b4..08e174fde3b 100644 --- a/src/doc/en/thematic_tutorials/numerical_sage/conf.py +++ b/src/doc/en/thematic_tutorials/numerical_sage/conf.py @@ -10,13 +10,13 @@ # All configuration values have a default; values that are commented out # serve to show the default. -from sage.docs.conf import release -from sage.docs.conf import * # NOQA +from sage_docbuild.conf import release +from sage_docbuild.conf import * # NOQA # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the -# builtin "default.css". html_common_static_path imported from sage.docs.conf +# builtin "default.css". html_common_static_path imported from sage_docbuild.conf # contains common paths. html_static_path = [] + html_common_static_path diff --git a/src/doc/en/tutorial/conf.py b/src/doc/en/tutorial/conf.py index d3f2ddf1204..b2b525d2c2a 100644 --- a/src/doc/en/tutorial/conf.py +++ b/src/doc/en/tutorial/conf.py @@ -10,13 +10,13 @@ # All configuration values have a default; values that are commented out # serve to show the default. -from sage.docs.conf import release -from sage.docs.conf import * # NOQA +from sage_docbuild.conf import release +from sage_docbuild.conf import * # NOQA # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the -# builtin "default.css". html_common_static_path imported from sage.docs.conf +# builtin "default.css". html_common_static_path imported from sage_docbuild.conf # contains common paths. html_static_path = [] + html_common_static_path diff --git a/src/doc/en/website/conf.py b/src/doc/en/website/conf.py index caf790a3977..7794fb9324a 100644 --- a/src/doc/en/website/conf.py +++ b/src/doc/en/website/conf.py @@ -10,13 +10,13 @@ # All configuration values have a default; values that are commented out # serve to show the default. -from sage.docs.conf import release -from sage.docs.conf import * # NOQA +from sage_docbuild.conf import release +from sage_docbuild.conf import * # NOQA # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the -# builtin "default.css". html_common_static_path imported from sage.docs.conf +# builtin "default.css". html_common_static_path imported from sage_docbuild.conf # contains common paths. html_static_path = [] + html_common_static_path diff --git a/src/doc/es/a_tour_of_sage/conf.py b/src/doc/es/a_tour_of_sage/conf.py index c2be75b677d..1bf598c11f5 100644 --- a/src/doc/es/a_tour_of_sage/conf.py +++ b/src/doc/es/a_tour_of_sage/conf.py @@ -12,13 +12,13 @@ # All configuration values have a default; values that are commented # out serve to show the default. -from sage.docs.conf import release -from sage.docs.conf import * +from sage_docbuild.conf import release +from sage_docbuild.conf import * # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the -# builtin "default.css". html_common_static_path imported from sage.docs.conf +# builtin "default.css". html_common_static_path imported from sage_docbuild.conf # contains common paths. html_static_path = [] + html_common_static_path diff --git a/src/doc/es/tutorial/conf.py b/src/doc/es/tutorial/conf.py index dccc97346e1..bbebf61f532 100644 --- a/src/doc/es/tutorial/conf.py +++ b/src/doc/es/tutorial/conf.py @@ -10,13 +10,13 @@ # All configuration values have a default; values that are commented out # serve to show the default. -from sage.docs.conf import release -from sage.docs.conf import * +from sage_docbuild.conf import release +from sage_docbuild.conf import * # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the -# builtin "default.css". html_common_static_path imported from sage.docs.conf +# builtin "default.css". html_common_static_path imported from sage_docbuild.conf # contains common paths. html_static_path = [] + html_common_static_path diff --git a/src/doc/fr/a_tour_of_sage/conf.py b/src/doc/fr/a_tour_of_sage/conf.py index f7879744766..f6438ea695a 100644 --- a/src/doc/fr/a_tour_of_sage/conf.py +++ b/src/doc/fr/a_tour_of_sage/conf.py @@ -10,13 +10,13 @@ # All configuration values have a default; values that are commented out # serve to show the default. -from sage.docs.conf import release, latex_elements -from sage.docs.conf import * # NOQA +from sage_docbuild.conf import release, latex_elements +from sage_docbuild.conf import * # NOQA # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the -# builtin "default.css". html_common_static_path imported from sage.docs.conf +# builtin "default.css". html_common_static_path imported from sage_docbuild.conf # contains common paths. html_static_path = [] + html_common_static_path diff --git a/src/doc/fr/tutorial/conf.py b/src/doc/fr/tutorial/conf.py index b14c1d9d74b..b23aaf6841c 100644 --- a/src/doc/fr/tutorial/conf.py +++ b/src/doc/fr/tutorial/conf.py @@ -10,13 +10,13 @@ # All configuration values have a default; values that are commented out # serve to show the default. -from sage.docs.conf import release, latex_elements -from sage.docs.conf import * # NOQA +from sage_docbuild.conf import release, latex_elements +from sage_docbuild.conf import * # NOQA # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the -# builtin "default.css". html_common_static_path imported from sage.docs.conf +# builtin "default.css". html_common_static_path imported from sage_docbuild.conf # contains common paths. html_static_path = [] + html_common_static_path diff --git a/src/doc/hu/a_tour_of_sage/conf.py b/src/doc/hu/a_tour_of_sage/conf.py index 7d34844db4d..90517269f2e 100644 --- a/src/doc/hu/a_tour_of_sage/conf.py +++ b/src/doc/hu/a_tour_of_sage/conf.py @@ -12,13 +12,13 @@ # All configuration values have a default; values that are commented # out serve to show the default. -from sage.docs.conf import release -from sage.docs.conf import * # NOQA +from sage_docbuild.conf import release +from sage_docbuild.conf import * # NOQA # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the -# builtin "default.css". html_common_static_path imported from sage.docs.conf +# builtin "default.css". html_common_static_path imported from sage_docbuild.conf # contains common paths. html_static_path = [] + html_common_static_path diff --git a/src/doc/it/a_tour_of_sage/conf.py b/src/doc/it/a_tour_of_sage/conf.py index 1abf405fe91..f897b790c2a 100644 --- a/src/doc/it/a_tour_of_sage/conf.py +++ b/src/doc/it/a_tour_of_sage/conf.py @@ -10,13 +10,13 @@ # All configuration values have a default; values that are commented out # serve to show the default. -from sage.docs.conf import release, latex_elements -from sage.docs.conf import * # NOQA +from sage_docbuild.conf import release, latex_elements +from sage_docbuild.conf import * # NOQA # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the -# builtin "default.css". html_common_static_path imported from sage.docs.conf +# builtin "default.css". html_common_static_path imported from sage_docbuild.conf # contains common paths. html_static_path = [] + html_common_static_path diff --git a/src/doc/it/faq/conf.py b/src/doc/it/faq/conf.py index ede8fa15aac..b5a536d383b 100644 --- a/src/doc/it/faq/conf.py +++ b/src/doc/it/faq/conf.py @@ -12,13 +12,13 @@ # All configuration values have a default; values that are commented out # serve to show the default. -from sage.docs.conf import release -from sage.docs.conf import * +from sage_docbuild.conf import release +from sage_docbuild.conf import * # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the -# builtin "default.css". html_common_static_path imported from sage.docs.conf +# builtin "default.css". html_common_static_path imported from sage_docbuild.conf # contains common paths. html_static_path = [] + html_common_static_path diff --git a/src/doc/it/tutorial/conf.py b/src/doc/it/tutorial/conf.py index 54404e43c53..1f3bdec9367 100644 --- a/src/doc/it/tutorial/conf.py +++ b/src/doc/it/tutorial/conf.py @@ -10,13 +10,13 @@ # All configuration values have a default; values that are commented out # serve to show the default. -from sage.docs.conf import release, latex_elements -from sage.docs.conf import * # NOQA +from sage_docbuild.conf import release, latex_elements +from sage_docbuild.conf import * # NOQA # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the -# builtin "default.css". html_common_static_path imported from sage.docs.conf +# builtin "default.css". html_common_static_path imported from sage_docbuild.conf # contains common paths. html_static_path = [] + html_common_static_path diff --git a/src/doc/ja/a_tour_of_sage/conf.py b/src/doc/ja/a_tour_of_sage/conf.py index a405fcbed15..bf1f84bf962 100644 --- a/src/doc/ja/a_tour_of_sage/conf.py +++ b/src/doc/ja/a_tour_of_sage/conf.py @@ -10,13 +10,13 @@ # All configuration values have a default; values that are commented out # serve to show the default. -from sage.docs.conf import release, latex_elements -from sage.docs.conf import * # NOQA +from sage_docbuild.conf import release, latex_elements +from sage_docbuild.conf import * # NOQA # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the -# builtin "default.css". html_common_static_path imported from sage.docs.conf +# builtin "default.css". html_common_static_path imported from sage_docbuild.conf # contains common paths. html_static_path = [] + html_common_static_path diff --git a/src/doc/ja/tutorial/conf.py b/src/doc/ja/tutorial/conf.py index 83a607cfc2e..9521bc91828 100644 --- a/src/doc/ja/tutorial/conf.py +++ b/src/doc/ja/tutorial/conf.py @@ -10,13 +10,13 @@ # All configuration values have a default; values that are commented out # serve to show the default. -from sage.docs.conf import release, latex_elements -from sage.docs.conf import * # NOQA +from sage_docbuild.conf import release, latex_elements +from sage_docbuild.conf import * # NOQA # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the -# builtin "default.css". html_common_static_path imported from sage.docs.conf +# builtin "default.css". html_common_static_path imported from sage_docbuild.conf # contains common paths. html_static_path = [] + html_common_static_path diff --git a/src/doc/pt/a_tour_of_sage/conf.py b/src/doc/pt/a_tour_of_sage/conf.py index 8557dcfb873..10d9367f942 100644 --- a/src/doc/pt/a_tour_of_sage/conf.py +++ b/src/doc/pt/a_tour_of_sage/conf.py @@ -10,13 +10,13 @@ # All configuration values have a default; values that are commented out # serve to show the default. -from sage.docs.conf import release -from sage.docs.conf import * # NOQA +from sage_docbuild.conf import release +from sage_docbuild.conf import * # NOQA # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the -# builtin "default.css". html_common_static_path imported from sage.docs.conf +# builtin "default.css". html_common_static_path imported from sage_docbuild.conf # contains common paths. html_static_path = [] + html_common_static_path diff --git a/src/doc/pt/tutorial/conf.py b/src/doc/pt/tutorial/conf.py index fb748f0636d..f299582db9a 100644 --- a/src/doc/pt/tutorial/conf.py +++ b/src/doc/pt/tutorial/conf.py @@ -10,13 +10,13 @@ # All configuration values have a default; values that are commented out # serve to show the default. -from sage.docs.conf import release -from sage.docs.conf import * # NOQA +from sage_docbuild.conf import release +from sage_docbuild.conf import * # NOQA # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the -# builtin "default.css". html_common_static_path imported from sage.docs.conf +# builtin "default.css". html_common_static_path imported from sage_docbuild.conf # contains common paths. html_static_path = [] + html_common_static_path diff --git a/src/doc/ru/tutorial/conf.py b/src/doc/ru/tutorial/conf.py index a2b5d8252e1..c237e769ed4 100644 --- a/src/doc/ru/tutorial/conf.py +++ b/src/doc/ru/tutorial/conf.py @@ -10,13 +10,13 @@ # All configuration values have a default; values that are commented out # serve to show the default. -from sage.docs.conf import release -from sage.docs.conf import * # NOQA +from sage_docbuild.conf import release +from sage_docbuild.conf import * # NOQA # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the -# builtin "default.css". html_common_static_path imported from sage.docs.conf +# builtin "default.css". html_common_static_path imported from sage_docbuild.conf # contains common paths. html_static_path = [] + html_common_static_path diff --git a/src/doc/tr/a_tour_of_sage/conf.py b/src/doc/tr/a_tour_of_sage/conf.py index 9a5d8f95cbc..adb526f1c78 100644 --- a/src/doc/tr/a_tour_of_sage/conf.py +++ b/src/doc/tr/a_tour_of_sage/conf.py @@ -10,13 +10,13 @@ # All configuration values have a default; values that are commented out # serve to show the default. -from sage.docs.conf import release -from sage.docs.conf import * # NOQA +from sage_docbuild.conf import release +from sage_docbuild.conf import * # NOQA # Add any paths that contain custom static files (such as style sheets), # relative to this directory to html_static_path. They are copied after the # builtin static files, so a file named "default.css" will overwrite the -# builtin "default.css". html_common_static_path imported from sage.docs.conf +# builtin "default.css". html_common_static_path imported from sage_docbuild.conf # contains common paths. html_static_path = [] + html_common_static_path diff --git a/src/sage/docs/conf.py b/src/sage/docs/conf.py index d067335e489..be9c4fb278d 100644 --- a/src/sage/docs/conf.py +++ b/src/sage/docs/conf.py @@ -1,3 +1,6 @@ +from sage.misc.superseded import deprecation +deprecation(33763, "This module is deprecated. Use sage_docbuild.conf instead.") + import sys import os import sphinx diff --git a/src/sage/docs/instancedoc.pyx b/src/sage/docs/instancedoc.pyx index 57f5e737b24..86f796600de 100644 --- a/src/sage/docs/instancedoc.pyx +++ b/src/sage/docs/instancedoc.pyx @@ -22,7 +22,7 @@ the class. EXAMPLES:: - sage: from sage.docs.instancedoc import instancedoc + sage: from sage.misc.instancedoc import instancedoc sage: @instancedoc ....: class X(object): ....: "Class docstring" @@ -37,7 +37,7 @@ For a Cython ``cdef class``, a decorator cannot be used. Instead, call :func:`instancedoc` as a function after defining the class:: sage: cython(''' - ....: from sage.docs.instancedoc import instancedoc + ....: from sage.misc.instancedoc import instancedoc ....: cdef class Y: ....: "Class docstring" ....: def _instancedoc_(self): @@ -116,214 +116,5 @@ Check that inheritance works (after passing the subclass to # https://www.gnu.org/licenses/ #***************************************************************************** -from cpython.object cimport PyObject, PyTypeObject - -cdef extern from *: - cdef int PyDict_SetItemString(PyObject*, const char*, object) except -1 - cdef void PyType_Modified(PyTypeObject*) - -cdef inline PyTypeObject* TypeObject(cls) except NULL: - if not isinstance(cls, type): - raise TypeError(f"expected type, got {cls!r}") - return cls - - -cdef class InstanceDocDescriptor: - """ - Descriptor for dynamic documentation, to be installed as the - ``__doc__`` attribute. - - INPUT: - - - ``classdoc`` -- (string) class documentation - - - ``instancedoc`` -- (method) documentation for an instance - - - ``attr`` -- (string, default ``__doc__``) attribute name to use - for custom docstring on the instance. - - EXAMPLES:: - - sage: from sage.docs.instancedoc import InstanceDocDescriptor - sage: def instancedoc(self): - ....: return "Instance doc" - sage: docattr = InstanceDocDescriptor("Class doc", instancedoc) - sage: class Z(object): - ....: __doc__ = InstanceDocDescriptor("Class doc", instancedoc) - sage: Z.__doc__ - 'Class doc' - sage: Z().__doc__ - 'Instance doc' - - We can still override the ``__doc__`` attribute of the instance:: - - sage: obj = Z() - sage: obj.__doc__ = "Custom doc" - sage: obj.__doc__ - 'Custom doc' - sage: del obj.__doc__ - sage: obj.__doc__ - 'Instance doc' - """ - cdef classdoc - cdef instancedoc - cdef attr - - def __init__(self, classdoc, instancedoc, attr="__doc__"): - """ - TESTS:: - - sage: from sage.docs.instancedoc import InstanceDocDescriptor - sage: InstanceDocDescriptor(None, None) - - """ - self.classdoc = classdoc - self.instancedoc = instancedoc - self.attr = intern(attr) - - def __get__(self, obj, typ): - """ - TESTS:: - - sage: from sage.docs.instancedoc import InstanceDocDescriptor - sage: def instancedoc(self): - ....: return "Doc for {!r}".format(self) - sage: descr = InstanceDocDescriptor("Class doc", instancedoc) - sage: descr.__get__(None, object) - 'Class doc' - sage: descr.__get__(42, type(42)) - 'Doc for 42' - """ - if obj is None: - return self.classdoc - - # First, try the attribute self.attr (typically __doc__) - # on the instance - try: - objdict = obj.__dict__ - except AttributeError: - pass - else: - doc = objdict.get(self.attr) - if doc is not None: - return doc - - return self.instancedoc(obj) - - def __set__(self, obj, value): - """ - TESTS:: - - sage: from sage.docs.instancedoc import InstanceDocDescriptor - sage: def instancedoc(self): - ....: return "Doc for {!r}".format(self) - sage: descr = InstanceDocDescriptor("Class doc", instancedoc) - sage: class X(object): pass - sage: obj = X() - sage: descr.__set__(obj, "Custom doc") - sage: obj.__doc__ - 'Custom doc' - - sage: descr.__set__([], "Custom doc") - Traceback (most recent call last): - ... - AttributeError: attribute '__doc__' of 'list' objects is not writable - sage: descr.__set__(object, "Custom doc") - Traceback (most recent call last): - ... - AttributeError: attribute '__doc__' of 'type' objects is not writable - """ - try: - obj.__dict__[self.attr] = value - except (AttributeError, TypeError): - raise AttributeError(f"attribute '{self.attr}' of '{type(obj).__name__}' objects is not writable") - - def __delete__(self, obj): - """ - TESTS:: - - sage: from sage.docs.instancedoc import InstanceDocDescriptor - sage: def instancedoc(self): - ....: return "Doc for {!r}".format(self) - sage: descr = InstanceDocDescriptor("Class doc", instancedoc) - sage: class X(object): pass - sage: obj = X() - sage: obj.__doc__ = "Custom doc" - sage: descr.__delete__(obj) - sage: print(obj.__doc__) - None - sage: descr.__delete__(obj) - Traceback (most recent call last): - ... - AttributeError: 'X' object has no attribute '__doc__' - - sage: descr.__delete__([]) - Traceback (most recent call last): - ... - AttributeError: attribute '__doc__' of 'list' objects is not writable - sage: descr.__delete__(object) - Traceback (most recent call last): - ... - AttributeError: attribute '__doc__' of 'type' objects is not writable - """ - try: - del obj.__dict__[self.attr] - except (AttributeError, TypeError): - raise AttributeError(f"attribute '{self.attr}' of '{type(obj).__name__}' objects is not writable") - except KeyError: - raise AttributeError(f"'{type(obj).__name__}' object has no attribute '{self.attr}'") - - -def instancedoc(cls): - """ - Add support for ``_instancedoc_`` to the class ``cls``. - - Typically, this will be used as decorator. - - INPUT: - - - ``cls`` -- a new-style class - - OUTPUT: ``cls`` - - .. WARNING:: - - ``instancedoc`` mutates the given class. So you are *not* supposed - to use it as ``newcls = instancedoc(cls)`` because that would - mutate ``cls`` (and ``newcls`` would be the same object as ``cls``) - - TESTS: - - We get a useful error message if ``_instancedoc_`` is not defined:: - - sage: from sage.docs.instancedoc import instancedoc - sage: class X(object): pass - sage: instancedoc(X) - Traceback (most recent call last): - ... - TypeError: instancedoc requires to have an '_instancedoc_' attribute - - This does not work on old-style classes or things which are not a - class at all:: - - sage: instancedoc(7) - Traceback (most recent call last): - ... - TypeError: expected type, got 7 - - sage: class OldStyle: pass - sage: instancedoc(OldStyle) - Traceback (most recent call last): - ... - TypeError: instancedoc requires to have an '_instancedoc_' attribute - """ - cdef PyTypeObject* tp = TypeObject(cls) - try: - instdoc = cls._instancedoc_ - except AttributeError: - raise TypeError(f"instancedoc requires {cls!r} to have an '_instancedoc_' attribute") - docattr = InstanceDocDescriptor(cls.__doc__, instdoc) - PyDict_SetItemString(tp.tp_dict, "__doc__", docattr) - tp.tp_doc = NULL - PyType_Modified(tp) - return cls +from sage.misc.lazy_import import lazy_import +lazy_import('sage.misc.instancedoc', 'instancedoc', deprecation=33763) diff --git a/src/sage/interfaces/axiom.py b/src/sage/interfaces/axiom.py index 51be4328cf2..c6ef330ae63 100644 --- a/src/sage/interfaces/axiom.py +++ b/src/sage/interfaces/axiom.py @@ -184,7 +184,7 @@ from pexpect import EOF from sage.misc.multireplace import multiple_replace from sage.interfaces.tab_completion import ExtraTabCompletion -from sage.docs.instancedoc import instancedoc +from sage.misc.instancedoc import instancedoc from sage.structure.richcmp import rich_to_bool diff --git a/src/sage/interfaces/expect.py b/src/sage/interfaces/expect.py index 5497e94dabc..17c56551fed 100644 --- a/src/sage/interfaces/expect.py +++ b/src/sage/interfaces/expect.py @@ -62,7 +62,7 @@ from sage.misc.misc import SAGE_TMP_INTERFACE from sage.env import SAGE_EXTCODE, LOCAL_IDENTIFIER from sage.misc.object_multiplexer import Multiplex -from sage.docs.instancedoc import instancedoc +from sage.misc.instancedoc import instancedoc from sage.cpython.string import str_to_bytes, bytes_to_str diff --git a/src/sage/interfaces/fricas.py b/src/sage/interfaces/fricas.py index 69a9364c394..53109a3bf02 100644 --- a/src/sage/interfaces/fricas.py +++ b/src/sage/interfaces/fricas.py @@ -202,7 +202,7 @@ from sage.interfaces.expect import Expect, ExpectElement, FunctionElement, ExpectFunction from sage.misc.misc import SAGE_TMP_INTERFACE from sage.env import DOT_SAGE, LOCAL_IDENTIFIER -from sage.docs.instancedoc import instancedoc +from sage.misc.instancedoc import instancedoc from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ from sage.misc.lazy_import import lazy_import diff --git a/src/sage/interfaces/gap.py b/src/sage/interfaces/gap.py index 69a624b496e..b5662a28acf 100644 --- a/src/sage/interfaces/gap.py +++ b/src/sage/interfaces/gap.py @@ -182,7 +182,7 @@ from sage.env import SAGE_EXTCODE from sage.misc.misc import is_in_string from sage.misc.cachefunc import cached_method -from sage.docs.instancedoc import instancedoc +from sage.misc.instancedoc import instancedoc from sage.interfaces.tab_completion import ExtraTabCompletion from sage.structure.element import ModuleElement diff --git a/src/sage/interfaces/giac.py b/src/sage/interfaces/giac.py index 37e0d6955de..73601ca7ff2 100644 --- a/src/sage/interfaces/giac.py +++ b/src/sage/interfaces/giac.py @@ -243,7 +243,7 @@ from sage.cpython.string import bytes_to_str from sage.env import DOT_SAGE from sage.misc.pager import pager -from sage.docs.instancedoc import instancedoc +from sage.misc.instancedoc import instancedoc from sage.structure.richcmp import rich_to_bool diff --git a/src/sage/interfaces/gp.py b/src/sage/interfaces/gp.py index 2eadf976506..6d95499640e 100644 --- a/src/sage/interfaces/gp.py +++ b/src/sage/interfaces/gp.py @@ -144,7 +144,7 @@ from sage.interfaces.tab_completion import ExtraTabCompletion from sage.libs.pari.all import pari import sage.rings.complex_mpfr -from sage.docs.instancedoc import instancedoc +from sage.misc.instancedoc import instancedoc class Gp(ExtraTabCompletion, Expect): diff --git a/src/sage/interfaces/interface.py b/src/sage/interfaces/interface.py index 13ce9233fc6..a61c2389b4f 100644 --- a/src/sage/interfaces/interface.py +++ b/src/sage/interfaces/interface.py @@ -47,7 +47,7 @@ import sage.misc.sage_eval from sage.misc.fast_methods import WithEqualityById -from sage.docs.instancedoc import instancedoc +from sage.misc.instancedoc import instancedoc class AsciiArtString(str): diff --git a/src/sage/interfaces/kash.py b/src/sage/interfaces/kash.py index 9f5e5e15591..8cfc1dd8483 100644 --- a/src/sage/interfaces/kash.py +++ b/src/sage/interfaces/kash.py @@ -426,7 +426,7 @@ # **************************************************************************** from .expect import Expect, ExpectElement -from sage.docs.instancedoc import instancedoc +from sage.misc.instancedoc import instancedoc import os from sage.misc.sage_eval import sage_eval diff --git a/src/sage/interfaces/lie.py b/src/sage/interfaces/lie.py index 82bba30aa5c..3d3a0ded886 100644 --- a/src/sage/interfaces/lie.py +++ b/src/sage/interfaces/lie.py @@ -291,7 +291,7 @@ from sage.env import DOT_SAGE, LIE_INFO_DIR from sage.misc.sage_eval import sage_eval from sage.interfaces.tab_completion import ExtraTabCompletion -from sage.docs.instancedoc import instancedoc +from sage.misc.instancedoc import instancedoc import os diff --git a/src/sage/interfaces/lisp.py b/src/sage/interfaces/lisp.py index 2b01063237f..668b35640df 100644 --- a/src/sage/interfaces/lisp.py +++ b/src/sage/interfaces/lisp.py @@ -55,7 +55,7 @@ from .expect import Expect, ExpectElement, ExpectFunction, FunctionElement, gc_disabled from sage.structure.element import RingElement, parent -from sage.docs.instancedoc import instancedoc +from sage.misc.instancedoc import instancedoc from sage.structure.richcmp import rich_to_bool diff --git a/src/sage/interfaces/macaulay2.py b/src/sage/interfaces/macaulay2.py index 1b8b5e0ce69..2389aa7ab10 100644 --- a/src/sage/interfaces/macaulay2.py +++ b/src/sage/interfaces/macaulay2.py @@ -126,7 +126,7 @@ from sage.misc.multireplace import multiple_replace from sage.misc.superseded import deprecated_function_alias from sage.interfaces.tab_completion import ExtraTabCompletion -from sage.docs.instancedoc import instancedoc +from sage.misc.instancedoc import instancedoc from sage.structure.global_options import GlobalOptions diff --git a/src/sage/interfaces/magma.py b/src/sage/interfaces/magma.py index 69f91ef236d..7376f317ff2 100644 --- a/src/sage/interfaces/magma.py +++ b/src/sage/interfaces/magma.py @@ -226,7 +226,7 @@ import sage.misc.misc import sage.misc.sage_eval from sage.interfaces.tab_completion import ExtraTabCompletion -from sage.docs.instancedoc import instancedoc +from sage.misc.instancedoc import instancedoc INTRINSIC_CACHE = '%s/magma_intrinsic_cache.sobj' % DOT_SAGE EXTCODE_DIR = None @@ -1982,7 +1982,7 @@ def _sage_(self): sage: m.sage() # optional - magma [1 2 3] [4 5 6] - + Multivariate polynomials:: sage: R. = QQ[] # optional - magma @@ -2057,9 +2057,9 @@ def _sage_(self): sage: R = Zmod(137) sage: magma(R).sage() # optional - magma Ring of integers modulo 137 - + TESTS: - + Tests for :trac:`30341`:: sage: P. = PolynomialRing(QQ) @@ -2067,7 +2067,7 @@ def _sage_(self): sage: u = P(l) sage: u == P(magma(u).sage()) # optional - magma True - + sage: P. = PolynomialRing(QQ, 2) sage: u = x + 27563611963/4251528*y sage: magma(u).sage() # optional - magma @@ -2626,17 +2626,17 @@ def __bool__(self): True sage: bool(magma(0)) # optional - magma False - + TESTS:: - + Verify that :trac:`32602` is fixed:: - + sage: magma("1 eq 0").bool() # optional - magma False sage: magma("1 eq 1").bool() # optional - magma True - sage: Q. = PolynomialRing(GF(3)) - sage: u = x^6+x^4+2*x^3+2*x+1 + sage: Q. = PolynomialRing(GF(3)) + sage: u = x^6+x^4+2*x^3+2*x+1 sage: F0 = magma.FunctionField(GF(3)) # optional - magma sage: bool(F0.1) # optional - magma True diff --git a/src/sage/interfaces/maple.py b/src/sage/interfaces/maple.py index bd6b7a73f93..6916024eb92 100644 --- a/src/sage/interfaces/maple.py +++ b/src/sage/interfaces/maple.py @@ -242,7 +242,7 @@ from sage.env import DOT_SAGE from sage.misc.pager import pager from sage.interfaces.tab_completion import ExtraTabCompletion -from sage.docs.instancedoc import instancedoc +from sage.misc.instancedoc import instancedoc from sage.structure.richcmp import rich_to_bool diff --git a/src/sage/interfaces/mathematica.py b/src/sage/interfaces/mathematica.py index 83c90418c46..b6200856c3e 100644 --- a/src/sage/interfaces/mathematica.py +++ b/src/sage/interfaces/mathematica.py @@ -394,7 +394,7 @@ FunctionElement) from sage.interfaces.interface import AsciiArtString from sage.interfaces.tab_completion import ExtraTabCompletion -from sage.docs.instancedoc import instancedoc +from sage.misc.instancedoc import instancedoc from sage.structure.richcmp import rich_to_bool diff --git a/src/sage/interfaces/mathics.py b/src/sage/interfaces/mathics.py index 58c8be858c3..11acc86e5f7 100644 --- a/src/sage/interfaces/mathics.py +++ b/src/sage/interfaces/mathics.py @@ -389,7 +389,7 @@ from sage.misc.cachefunc import cached_method from sage.interfaces.interface import Interface, InterfaceElement, InterfaceFunction, InterfaceFunctionElement from sage.interfaces.tab_completion import ExtraTabCompletion -from sage.docs.instancedoc import instancedoc +from sage.misc.instancedoc import instancedoc from sage.structure.richcmp import rich_to_bool diff --git a/src/sage/interfaces/matlab.py b/src/sage/interfaces/matlab.py index c8150823baf..0f930905656 100644 --- a/src/sage/interfaces/matlab.py +++ b/src/sage/interfaces/matlab.py @@ -150,7 +150,7 @@ import os from .expect import Expect, ExpectElement -from sage.docs.instancedoc import instancedoc +from sage.misc.instancedoc import instancedoc class Matlab(Expect): diff --git a/src/sage/interfaces/maxima.py b/src/sage/interfaces/maxima.py index a27d80c29d4..5044771eb7d 100644 --- a/src/sage/interfaces/maxima.py +++ b/src/sage/interfaces/maxima.py @@ -165,7 +165,7 @@ Here is an example of solving an algebraic equation:: - sage: maxima('x^2+y^2=1').solve('y') + sage: maxima('x^2+y^2=1').solve('y') [y = -sqrt(1-x^2),y = sqrt(1-x^2)] sage: maxima('x^2 + y^2 = (x^2 - y^2)/sqrt(x^2 + y^2)').solve('y') [y = -sqrt(((-y^2)-x^2)*sqrt(y^2+x^2)+x^2), y = sqrt(((-y^2)-x^2)*sqrt(y^2+x^2)+x^2)] @@ -504,7 +504,7 @@ MaximaAbstractElement, MaximaAbstractFunctionElement, MaximaAbstractElementFunction) -from sage.docs.instancedoc import instancedoc +from sage.misc.instancedoc import instancedoc # Thanks to the MRO for multiple inheritance used by the Sage's Python, diff --git a/src/sage/interfaces/maxima_abstract.py b/src/sage/interfaces/maxima_abstract.py index 50de848e04a..14cf31e9b98 100644 --- a/src/sage/interfaces/maxima_abstract.py +++ b/src/sage/interfaces/maxima_abstract.py @@ -66,7 +66,7 @@ from .interface import (Interface, InterfaceElement, InterfaceFunctionElement, InterfaceFunction, AsciiArtString) from sage.interfaces.tab_completion import ExtraTabCompletion -from sage.docs.instancedoc import instancedoc +from sage.misc.instancedoc import instancedoc # The Maxima "apropos" command, e.g., apropos(det) gives a list # of all identifiers that begin in a certain way. This could diff --git a/src/sage/interfaces/maxima_lib.py b/src/sage/interfaces/maxima_lib.py index c9a778a6ca4..449f9751abf 100644 --- a/src/sage/interfaces/maxima_lib.py +++ b/src/sage/interfaces/maxima_lib.py @@ -101,7 +101,7 @@ from .maxima_abstract import (MaximaAbstract, MaximaAbstractFunction, MaximaAbstractElement, MaximaAbstractFunctionElement, MaximaAbstractElementFunction) -from sage.docs.instancedoc import instancedoc +from sage.misc.instancedoc import instancedoc from sage.env import MAXIMA_FAS diff --git a/src/sage/interfaces/mupad.py b/src/sage/interfaces/mupad.py index cdf0a8290d7..4c14187ec78 100644 --- a/src/sage/interfaces/mupad.py +++ b/src/sage/interfaces/mupad.py @@ -97,7 +97,7 @@ from sage.interfaces.interface import AsciiArtString from sage.interfaces.tab_completion import ExtraTabCompletion from sage.env import DOT_SAGE -from sage.docs.instancedoc import instancedoc +from sage.misc.instancedoc import instancedoc COMMANDS_CACHE = '%s/mupad_commandlist_cache.sobj' % DOT_SAGE PROMPT = ">>" diff --git a/src/sage/interfaces/octave.py b/src/sage/interfaces/octave.py index 727e7445f79..8f12f515ce4 100644 --- a/src/sage/interfaces/octave.py +++ b/src/sage/interfaces/octave.py @@ -145,7 +145,7 @@ from .expect import Expect, ExpectElement import pexpect from sage.misc.verbose import verbose -from sage.docs.instancedoc import instancedoc +from sage.misc.instancedoc import instancedoc from sage.cpython.string import bytes_to_str diff --git a/src/sage/interfaces/qepcad.py b/src/sage/interfaces/qepcad.py index 38d9c8c646a..c2e6c00ec48 100644 --- a/src/sage/interfaces/qepcad.py +++ b/src/sage/interfaces/qepcad.py @@ -615,7 +615,7 @@ from sage.misc.sage_eval import sage_eval from sage.repl.preparse import implicit_mul from sage.interfaces.tab_completion import ExtraTabCompletion -from sage.docs.instancedoc import instancedoc +from sage.misc.instancedoc import instancedoc from .expect import Expect, ExpectFunction from sage.interfaces.interface import AsciiArtString diff --git a/src/sage/interfaces/r.py b/src/sage/interfaces/r.py index a9b889fdab6..1e0d6ff73b1 100644 --- a/src/sage/interfaces/r.py +++ b/src/sage/interfaces/r.py @@ -270,7 +270,7 @@ import re from sage.structure.element import parent from sage.interfaces.tab_completion import ExtraTabCompletion -from sage.docs.instancedoc import instancedoc +from sage.misc.instancedoc import instancedoc # see the _lazy_init for some reasoning behind the lazy imports from sage.misc.lazy_import import lazy_import diff --git a/src/sage/interfaces/sage0.py b/src/sage/interfaces/sage0.py index 5a303d57745..a43a059e0ec 100644 --- a/src/sage/interfaces/sage0.py +++ b/src/sage/interfaces/sage0.py @@ -25,7 +25,7 @@ from sage.interfaces.tab_completion import ExtraTabCompletion from sage.misc.persist import dumps, load -from sage.docs.instancedoc import instancedoc +from sage.misc.instancedoc import instancedoc class Sage(ExtraTabCompletion, Expect): diff --git a/src/sage/interfaces/scilab.py b/src/sage/interfaces/scilab.py index 610f64f8d81..c1144d40ab0 100644 --- a/src/sage/interfaces/scilab.py +++ b/src/sage/interfaces/scilab.py @@ -190,7 +190,7 @@ import os from .expect import Expect, ExpectElement -from sage.docs.instancedoc import instancedoc +from sage.misc.instancedoc import instancedoc class Scilab(Expect): diff --git a/src/sage/interfaces/singular.py b/src/sage/interfaces/singular.py index 5569e4bdf77..41e9c9ff251 100644 --- a/src/sage/interfaces/singular.py +++ b/src/sage/interfaces/singular.py @@ -354,7 +354,7 @@ import sage.rings.integer from sage.misc.verbose import get_verbose -from sage.docs.instancedoc import instancedoc +from sage.misc.instancedoc import instancedoc class SingularError(RuntimeError): diff --git a/src/sage/libs/gap/element.pyx b/src/sage/libs/gap/element.pyx index 92444e0c314..0c12bc4d9e7 100644 --- a/src/sage/libs/gap/element.pyx +++ b/src/sage/libs/gap/element.pyx @@ -3314,6 +3314,6 @@ cdef class GapElement_RecordIterator(object): # Add support for _instancedoc_ -from sage.docs.instancedoc import instancedoc +from sage.misc.instancedoc import instancedoc instancedoc(GapElement_Function) instancedoc(GapElement_MethodProxy) diff --git a/src/sage/libs/singular/function.pyx b/src/sage/libs/singular/function.pyx index d8332743485..ddb4fdad783 100644 --- a/src/sage/libs/singular/function.pyx +++ b/src/sage/libs/singular/function.pyx @@ -1890,7 +1890,7 @@ cdef inline RingWrap new_RingWrap(ring* r): # Add support for _instancedoc_ -from sage.docs.instancedoc import instancedoc +from sage.misc.instancedoc import instancedoc instancedoc(SingularFunction) instancedoc(SingularLibraryFunction) instancedoc(SingularKernelFunction) diff --git a/src/sage/misc/cachefunc.pyx b/src/sage/misc/cachefunc.pyx index 0165c0be5c6..c74d9d83fd0 100644 --- a/src/sage/misc/cachefunc.pyx +++ b/src/sage/misc/cachefunc.pyx @@ -3723,7 +3723,7 @@ class disk_cached_function: # Add support for _instancedoc_ -from sage.docs.instancedoc import instancedoc +from sage.misc.instancedoc import instancedoc instancedoc(CachedFunction) instancedoc(WeakCachedFunction) instancedoc(CachedMethodCaller) diff --git a/src/sage/misc/instancedoc.pyx b/src/sage/misc/instancedoc.pyx new file mode 100644 index 00000000000..a58fde0e081 --- /dev/null +++ b/src/sage/misc/instancedoc.pyx @@ -0,0 +1,330 @@ +r""" +Dynamic documentation for instances of classes + +The functionality in this module allows to define specific docstrings +of *instances* of a class, which are different from the class docstring. +A typical use case is given by cached methods: the documentation of a +cached method should not be the documentation of the class +:class:`CachedMethod`; it should be the documentation of the underlying +method. + +In order to use this, define a class docstring as usual. Also define a +method ``def _instancedoc_(self)`` which should return the docstring of +the instance ``self``. Finally, add the decorator ``@instancedoc`` to +the class. + +.. WARNING:: + + Since the ``__doc__`` attribute is never inherited, the decorator + ``@instancedoc`` must be added to all subclasses of the class + defining ``_instancedoc_``. Doing it on the base class is not + sufficient. + +EXAMPLES:: + + sage: from sage.misc.instancedoc import instancedoc + sage: @instancedoc + ....: class X(object): + ....: "Class docstring" + ....: def _instancedoc_(self): + ....: return "Instance docstring" + sage: X.__doc__ + 'Class docstring' + sage: X().__doc__ + 'Instance docstring' + +For a Cython ``cdef class``, a decorator cannot be used. Instead, call +:func:`instancedoc` as a function after defining the class:: + + sage: cython(''' + ....: from sage.misc.instancedoc import instancedoc + ....: cdef class Y: + ....: "Class docstring" + ....: def _instancedoc_(self): + ....: return "Instance docstring" + ....: instancedoc(Y) + ....: ''') + sage: Y.__doc__ + 'File:...\nClass docstring' + sage: Y().__doc__ + 'Instance docstring' + +One can still add a custom ``__doc__`` attribute on a particular +instance:: + + sage: obj = X() + sage: obj.__doc__ = "Very special doc" + sage: print(obj.__doc__) + Very special doc + +This normally does not work on extension types:: + + sage: Y().__doc__ = "Very special doc" + Traceback (most recent call last): + ... + AttributeError: attribute '__doc__' of 'Y' objects is not writable + +This is an example involving a metaclass, where the instances are +classes. In this case, the ``_instancedoc_`` from the metaclass is only +used if the instance of the metaclass (the class) does not have a +docstring:: + + sage: @instancedoc + ....: class Meta(type): + ....: "Metaclass doc" + ....: def _instancedoc_(self): + ....: return "Docstring for {}".format(self) + sage: class T(metaclass=Meta): + ....: pass + sage: print(T.__doc__) + Docstring for + sage: class U(metaclass=Meta): + ....: "Special doc for U" + sage: print(U.__doc__) + Special doc for U + +TESTS: + +Check that inheritance works (after passing the subclass to +:func:`instancedoc`):: + + sage: @instancedoc + ....: class A(object): + ....: "Class A docstring" + ....: def _instancedoc_(self): + ....: return "Instance docstring" + sage: class B(A): + ....: "Class B docstring" + sage: B.__doc__ + 'Class B docstring' + sage: B().__doc__ # Ideally, this would return the instance docstring + 'Class B docstring' + sage: B = instancedoc(B) + sage: B.__doc__ + 'Class B docstring' + sage: B().__doc__ + 'Instance docstring' +""" + +#***************************************************************************** +# Copyright (C) 2017 Jeroen Demeyer +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# https://www.gnu.org/licenses/ +#***************************************************************************** + +from cpython.object cimport PyObject, PyTypeObject + +cdef extern from *: + cdef int PyDict_SetItemString(PyObject*, const char*, object) except -1 + cdef void PyType_Modified(PyTypeObject*) + +cdef inline PyTypeObject* TypeObject(cls) except NULL: + if not isinstance(cls, type): + raise TypeError(f"expected type, got {cls!r}") + return cls + + +cdef class InstanceDocDescriptor: + """ + Descriptor for dynamic documentation, to be installed as the + ``__doc__`` attribute. + + INPUT: + + - ``classdoc`` -- (string) class documentation + + - ``instancedoc`` -- (method) documentation for an instance + + - ``attr`` -- (string, default ``__doc__``) attribute name to use + for custom docstring on the instance. + + EXAMPLES:: + + sage: from sage.misc.instancedoc import InstanceDocDescriptor + sage: def instancedoc(self): + ....: return "Instance doc" + sage: docattr = InstanceDocDescriptor("Class doc", instancedoc) + sage: class Z(object): + ....: __doc__ = InstanceDocDescriptor("Class doc", instancedoc) + sage: Z.__doc__ + 'Class doc' + sage: Z().__doc__ + 'Instance doc' + + We can still override the ``__doc__`` attribute of the instance:: + + sage: obj = Z() + sage: obj.__doc__ = "Custom doc" + sage: obj.__doc__ + 'Custom doc' + sage: del obj.__doc__ + sage: obj.__doc__ + 'Instance doc' + """ + cdef classdoc + cdef instancedoc + cdef attr + + def __init__(self, classdoc, instancedoc, attr="__doc__"): + """ + TESTS:: + + sage: from sage.misc.instancedoc import InstanceDocDescriptor + sage: InstanceDocDescriptor(None, None) + + """ + self.classdoc = classdoc + self.instancedoc = instancedoc + self.attr = intern(attr) + + def __get__(self, obj, typ): + """ + TESTS:: + + sage: from sage.misc.instancedoc import InstanceDocDescriptor + sage: def instancedoc(self): + ....: return "Doc for {!r}".format(self) + sage: descr = InstanceDocDescriptor("Class doc", instancedoc) + sage: descr.__get__(None, object) + 'Class doc' + sage: descr.__get__(42, type(42)) + 'Doc for 42' + """ + if obj is None: + return self.classdoc + + # First, try the attribute self.attr (typically __doc__) + # on the instance + try: + objdict = obj.__dict__ + except AttributeError: + pass + else: + doc = objdict.get(self.attr) + if doc is not None: + return doc + + return self.instancedoc(obj) + + def __set__(self, obj, value): + """ + TESTS:: + + sage: from sage.misc.instancedoc import InstanceDocDescriptor + sage: def instancedoc(self): + ....: return "Doc for {!r}".format(self) + sage: descr = InstanceDocDescriptor("Class doc", instancedoc) + sage: class X(object): pass + sage: obj = X() + sage: descr.__set__(obj, "Custom doc") + sage: obj.__doc__ + 'Custom doc' + + sage: descr.__set__([], "Custom doc") + Traceback (most recent call last): + ... + AttributeError: attribute '__doc__' of 'list' objects is not writable + sage: descr.__set__(object, "Custom doc") + Traceback (most recent call last): + ... + AttributeError: attribute '__doc__' of 'type' objects is not writable + """ + try: + obj.__dict__[self.attr] = value + except (AttributeError, TypeError): + raise AttributeError(f"attribute '{self.attr}' of '{type(obj).__name__}' objects is not writable") + + def __delete__(self, obj): + """ + TESTS:: + + sage: from sage.misc.instancedoc import InstanceDocDescriptor + sage: def instancedoc(self): + ....: return "Doc for {!r}".format(self) + sage: descr = InstanceDocDescriptor("Class doc", instancedoc) + sage: class X(object): pass + sage: obj = X() + sage: obj.__doc__ = "Custom doc" + sage: descr.__delete__(obj) + sage: print(obj.__doc__) + None + sage: descr.__delete__(obj) + Traceback (most recent call last): + ... + AttributeError: 'X' object has no attribute '__doc__' + + sage: descr.__delete__([]) + Traceback (most recent call last): + ... + AttributeError: attribute '__doc__' of 'list' objects is not writable + sage: descr.__delete__(object) + Traceback (most recent call last): + ... + AttributeError: attribute '__doc__' of 'type' objects is not writable + """ + try: + del obj.__dict__[self.attr] + except (AttributeError, TypeError): + raise AttributeError(f"attribute '{self.attr}' of '{type(obj).__name__}' objects is not writable") + except KeyError: + raise AttributeError(f"'{type(obj).__name__}' object has no attribute '{self.attr}'") + + +def instancedoc(cls): + """ + Add support for ``_instancedoc_`` to the class ``cls``. + + Typically, this will be used as decorator. + + INPUT: + + - ``cls`` -- a new-style class + + OUTPUT: ``cls`` + + .. WARNING:: + + ``instancedoc`` mutates the given class. So you are *not* supposed + to use it as ``newcls = instancedoc(cls)`` because that would + mutate ``cls`` (and ``newcls`` would be the same object as ``cls``) + + TESTS: + + We get a useful error message if ``_instancedoc_`` is not defined:: + + sage: from sage.misc.instancedoc import instancedoc + sage: class X(object): pass + sage: instancedoc(X) + Traceback (most recent call last): + ... + TypeError: instancedoc requires to have an '_instancedoc_' attribute + + This does not work on old-style classes or things which are not a + class at all:: + + sage: instancedoc(7) + Traceback (most recent call last): + ... + TypeError: expected type, got 7 + + sage: class OldStyle: pass + sage: instancedoc(OldStyle) + Traceback (most recent call last): + ... + TypeError: instancedoc requires to have an '_instancedoc_' attribute + """ + cdef PyTypeObject* tp = TypeObject(cls) + try: + instdoc = cls._instancedoc_ + except AttributeError: + raise TypeError(f"instancedoc requires {cls!r} to have an '_instancedoc_' attribute") + docattr = InstanceDocDescriptor(cls.__doc__, instdoc) + PyDict_SetItemString(tp.tp_dict, "__doc__", docattr) + tp.tp_doc = NULL + PyType_Modified(tp) + return cls + diff --git a/src/sage/misc/latex_macros.py b/src/sage/misc/latex_macros.py index f1ac926c235..eaaf77a0f18 100644 --- a/src/sage/misc/latex_macros.py +++ b/src/sage/misc/latex_macros.py @@ -14,7 +14,7 @@ the ``_latex_`` method for each Sage object listed in ``macros``, and the MathJax macros are produced from the LaTeX macros. The list of LaTeX macros is used in the file -``sage.docs.conf`` to add to the preambles of +``sage_docbuild.conf`` to add to the preambles of both the LaTeX file used to build the PDF version of the documentation and the LaTeX file used to build the HTML version. diff --git a/src/sage/misc/lazy_import.pyx b/src/sage/misc/lazy_import.pyx index 4286e5b7b9f..bc6078d24f2 100644 --- a/src/sage/misc/lazy_import.pyx +++ b/src/sage/misc/lazy_import.pyx @@ -1151,5 +1151,5 @@ def get_star_imports(module_name): # Add support for _instancedoc_ -from sage.docs.instancedoc import instancedoc +from sage.misc.instancedoc import instancedoc instancedoc(LazyImport) diff --git a/src/sage/misc/sagedoc.py b/src/sage/misc/sagedoc.py index 08c4225b87f..6e326a1c329 100644 --- a/src/sage/misc/sagedoc.py +++ b/src/sage/misc/sagedoc.py @@ -511,7 +511,7 @@ def process_extlinks(s, embedded=False): Sphinx extlinks extension. For example, replace ``:trac:`NUM``` with ``https://trac.sagemath.org/NUM``, and similarly with ``:python:TEXT`` and ``:wikipedia:TEXT``, looking up the url from - the dictionary ``extlinks`` in ``sage.docs.conf``. + the dictionary ``extlinks`` in ``sage_docbuild.conf``. If ``TEXT`` is of the form ``blah ``, then it uses ``LINK`` rather than ``TEXT`` to construct the url. diff --git a/src/sage/misc/sphinxify.py b/src/sage/misc/sphinxify.py index 0804be33bf3..d19696560eb 100644 --- a/src/sage/misc/sphinxify.py +++ b/src/sage/misc/sphinxify.py @@ -87,7 +87,7 @@ def sphinxify(docstring, format='html'): os.makedirs(confdir) with open(os.path.join(confdir, 'conf.py'), 'w') as filed: filed.write(r""" -from sage.docs.conf import * +from sage_docbuild.conf import * extensions = ['sphinx.ext.autodoc', 'sphinx.ext.mathjax', 'sphinx.ext.todo', 'sphinx.ext.extlinks'] templates_path = ['templates'] diff --git a/src/sage/parallel/decorate.py b/src/sage/parallel/decorate.py index 43dd7a8142c..31a697d2ab6 100644 --- a/src/sage/parallel/decorate.py +++ b/src/sage/parallel/decorate.py @@ -9,7 +9,7 @@ from .reference import parallel_iter as p_iter_reference from .use_fork import p_iter_fork from . import multiprocessing_sage -from sage.docs.instancedoc import instancedoc +from sage.misc.instancedoc import instancedoc def normalize_input(a): diff --git a/src/sage/sets/set_from_iterator.py b/src/sage/sets/set_from_iterator.py index 281fdd61210..3171032399c 100644 --- a/src/sage/sets/set_from_iterator.py +++ b/src/sage/sets/set_from_iterator.py @@ -66,7 +66,7 @@ from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets from sage.misc.function_mangling import ArgumentFixer from sage.misc.lazy_list import lazy_list -from sage.docs.instancedoc import instancedoc +from sage.misc.instancedoc import instancedoc class EnumeratedSetFromIterator(Parent): diff --git a/src/sage/structure/global_options.py b/src/sage/structure/global_options.py index 0d0345984f6..e2ee4834050 100644 --- a/src/sage/structure/global_options.py +++ b/src/sage/structure/global_options.py @@ -511,7 +511,7 @@ class options(GlobalOptions): from pickle import PicklingError from textwrap import dedent -from sage.docs.instancedoc import instancedoc +from sage.misc.instancedoc import instancedoc class Option(object): diff --git a/src/sage/symbolic/maxima_wrapper.py b/src/sage/symbolic/maxima_wrapper.py index 8fc3a840ca9..e2e5a18562b 100644 --- a/src/sage/symbolic/maxima_wrapper.py +++ b/src/sage/symbolic/maxima_wrapper.py @@ -10,7 +10,7 @@ from sage.structure.sage_object import SageObject from sage.interfaces.maxima import MaximaFunctionElement -from sage.docs.instancedoc import instancedoc +from sage.misc.instancedoc import instancedoc @instancedoc diff --git a/src/sage/symbolic/units.py b/src/sage/symbolic/units.py index c5259354d9a..9618739f6ba 100644 --- a/src/sage/symbolic/units.py +++ b/src/sage/symbolic/units.py @@ -93,7 +93,7 @@ from .ring import SR from .expression import Expression from sage.interfaces.tab_completion import ExtraTabCompletion -from sage.docs.instancedoc import instancedoc +from sage.misc.instancedoc import instancedoc ############################################################################### # Unit conversions dictionary. diff --git a/src/sage_docbuild/__init__.py b/src/sage_docbuild/__init__.py index b12d56a3c93..8b137891791 100644 --- a/src/sage_docbuild/__init__.py +++ b/src/sage_docbuild/__init__.py @@ -1,1762 +1 @@ -""" -The documentation builder -It is the starting point for building documentation, and is -responsible to figure out what to build and with which options. The -actual documentation build for each individual document is then done -in a subprocess call to sphinx, see :func:`builder_helper`. - -* The builder can be configured in build_options.py -* The sphinx subprocesses are configured in conf.py -""" -# **************************************************************************** -# Copyright (C) 2008-2009 Mike Hansen -# 2009-2010 Mitesh Patel -# 2009-2015 J. H. Palmieri -# 2009 Carl Witty -# 2010-2017 Jeroen Demeyer -# 2012 William Stein -# 2012-2014 Nicolas M. Thiery -# 2012-2015 André Apitzsch -# 2012 Florent Hivert -# 2013-2014 Volker Braun -# 2013 R. Andrew Ohana -# 2015 Thierry Monteil -# 2015 Marc Mezzarobba -# 2015 Travis Scrimshaw -# 2016-2017 Frédéric Chapoton -# 2016 Erik M. Bray -# 2017 Kwankyu Lee -# 2017 François Bissey -# 2018 Julian Rüth -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 2 of the License, or -# (at your option) any later version. -# https://www.gnu.org/licenses/ -# **************************************************************************** -import logging -import argparse -import os -import pickle -import re -import shutil -import subprocess -import sys -import time -import types -import warnings - -import sphinx.util.console -import sphinx.ext.intersphinx - -import sage.all -from sage.misc.cachefunc import cached_method -# Do not import SAGE_DOC globally as it interferes with doctesting with a random replacement -from sage.env import SAGE_DOC_SRC, SAGE_SRC, DOT_SAGE - -from .build_options import (LANGUAGES, SPHINXOPTS, OMIT, - ALLSPHINXOPTS, NUM_THREADS, WEBSITESPHINXOPTS, - INCREMENTAL_BUILD, ABORT_ON_ERROR) - -from .utils import build_many as _build_many - -logger = logging.getLogger(__name__) - - -########################################## -# Parallel Building Ref Manual # -########################################## - -def build_ref_doc(args): - doc = args[0] - lang = args[1] - format = args[2] - kwds = args[3] - args = args[4:] - if format == 'inventory': # you must not use the inventory to build the inventory - kwds['use_multidoc_inventory'] = False - getattr(ReferenceSubBuilder(doc, lang), format)(*args, **kwds) - - -########################################## -# Builders # -########################################## - -def builder_helper(type): - """ - Return a function which builds the documentation for - output type ``type``. - - TESTS: - - Check that :trac:`25161` has been resolved:: - - sage: from sage_docbuild import DocBuilder, setup_parser - sage: DocBuilder._options = setup_parser().parse_args([]) # builder_helper needs _options to be set - - sage: import sage_docbuild.sphinxbuild - sage: def raiseBaseException(): - ....: raise BaseException("abort pool operation") - sage: original_runsphinx, sage_docbuild.sphinxbuild.runsphinx = sage_docbuild.sphinxbuild.runsphinx, raiseBaseException - - sage: from sage.misc.temporary_file import tmp_dir - sage: os.environ['SAGE_DOC'] = tmp_dir() - sage: sage.env.var('SAGE_DOC') # random - sage: from sage_docbuild import builder_helper, build_ref_doc - sage: from sage_docbuild import _build_many as build_many - sage: helper = builder_helper("html") - sage: try: # optional - sagemath_doc_html - ....: build_many(build_ref_doc, [("docname", "en", "html", {})]) - ....: except Exception as E: - ....: "Non-exception during docbuild: abort pool operation" in str(E) - True - """ - def f(self, *args, **kwds): - output_dir = self._output_dir(type) - - options = ALLSPHINXOPTS - - if self.name == 'website': - # WEBSITESPHINXOPTS is either empty or " -A hide_pdf_links=1 " - options += WEBSITESPHINXOPTS - - if kwds.get('use_multidoc_inventory', True) and type != 'inventory': - options += ' -D multidoc_first_pass=0' - else: - options += ' -D multidoc_first_pass=1' - - - build_command = '-b %s -d %s %s %s %s' % (type, self._doctrees_dir(), - options, self.dir, - output_dir) - - # Provide "pdf" tag to be used with "only" directive as an alias of "latex" - if type == 'latex': - build_command = '-t pdf ' + build_command - - logger.debug(build_command) - - # Run Sphinx with Sage's special logger - sys.argv = ["sphinx-build"] + build_command.split() - from .sphinxbuild import runsphinx - try: - runsphinx() - except Exception: - if ABORT_ON_ERROR: - raise - except BaseException as e: - # We need to wrap a BaseException that is not an Exception in a - # regular Exception. Otherwise multiprocessing.Pool.get hangs, see - # #25161 - if ABORT_ON_ERROR: - raise Exception("Non-exception during docbuild: %s" % (e,), e) - - if "/latex" in output_dir: - logger.warning("LaTeX file written to {}".format(output_dir)) - else: - logger.warning( - "Build finished. The built documents can be found in {}". - format(output_dir)) - - f.is_output_format = True - return f - - -class DocBuilder(object): - def __init__(self, name, lang='en'): - """ - INPUT: - - - ``name`` - the name of a subdirectory in SAGE_DOC_SRC, such as - 'tutorial' or 'bordeaux_2008' - - - ``lang`` - (default "en") the language of the document. - """ - doc = name.split(os.path.sep) - - if doc[0] in LANGUAGES: - lang = doc[0] - doc.pop(0) - - self.name = os.path.join(*doc) - self.lang = lang - self.dir = os.path.join(SAGE_DOC_SRC, self.lang, self.name) - - def _output_dir(self, type): - """ - Return the directory where the output of type ``type`` is stored. - - If the directory does not exist, then it will automatically be - created. - - EXAMPLES:: - - sage: from sage_docbuild import DocBuilder - sage: b = DocBuilder('tutorial') - sage: b._output_dir('html') # optional - sagemath_doc_html - '.../html/en/tutorial' - """ - from sage.env import SAGE_DOC - d = os.path.join(SAGE_DOC, type, self.lang, self.name) - os.makedirs(d, exist_ok=True) - return d - - def _doctrees_dir(self): - """ - Return the directory where the doctrees are stored. - - If the directory does not exist, then it will automatically be - created. - - EXAMPLES:: - - sage: from sage_docbuild import DocBuilder - sage: b = DocBuilder('tutorial') - sage: b._doctrees_dir() # optional - sagemath_doc_html - '.../doctrees/en/tutorial' - """ - from sage.env import SAGE_DOC - d = os.path.join(SAGE_DOC, 'doctrees', self.lang, self.name) - os.makedirs(d, exist_ok=True) - return d - - def _output_formats(self): - """ - Return a list of the possible output formats. - - EXAMPLES:: - - sage: from sage_docbuild import DocBuilder - sage: b = DocBuilder('tutorial') - sage: b._output_formats() - ['changes', 'html', 'htmlhelp', 'inventory', 'json', 'latex', 'linkcheck', 'pickle', 'web'] - """ - # Go through all the attributes of self and check to - # see which ones have an 'is_output_format' attribute. These - # are the ones created with builder_helper. - output_formats = [] - for attr in dir(self): - if hasattr(getattr(self, attr), 'is_output_format'): - output_formats.append(attr) - output_formats.sort() - return output_formats - - def pdf(self): - """ - Build the PDF files for this document. - - This is done by first (re)-building the LaTeX output, going - into that LaTeX directory, and running 'make all-pdf' there. - - EXAMPLES:: - - sage: from sage_docbuild import DocBuilder - sage: b = DocBuilder('tutorial') - sage: b.pdf() #not tested - """ - self.latex() - tex_dir = self._output_dir('latex') - pdf_dir = self._output_dir('pdf') - - if self.name == 'reference': - # recover maths in tex, undoing what Sphinx did (trac #29993) - tex_file = os.path.join(tex_dir, 'reference.tex') - with open(tex_file) as f: - ref = f.read() - ref = re.sub(r'\\textbackslash{}', r'\\', ref) - ref = re.sub(r'\\textbackslash{}', r'\\', ref) - ref = re.sub(r'\\{', r'{', ref) - ref = re.sub(r'\\}', r'}', ref) - ref = re.sub(r'\\_', r'_', ref) - ref = re.sub(r'\\textasciicircum{}', r'^', ref) - with open(tex_file, 'w') as f: - f.write(ref) - - make_target = "cd '%s' && $MAKE %s && mv -f *.pdf '%s'" - error_message = "failed to run $MAKE %s in %s" - command = 'all-pdf' - - if subprocess.call(make_target % (tex_dir, command, pdf_dir), close_fds=False, shell=True): - raise RuntimeError(error_message % (command, tex_dir)) - logger.warning("Build finished. The built documents can be found in %s", pdf_dir) - - def clean(self, *args): - shutil.rmtree(self._doctrees_dir()) - output_formats = list(args) if args else self._output_formats() - for format in output_formats: - shutil.rmtree(self._output_dir(format), ignore_errors=True) - - html = builder_helper('html') - pickle = builder_helper('pickle') - web = pickle - json = builder_helper('json') - htmlhelp = builder_helper('htmlhelp') - latex = builder_helper('latex') - changes = builder_helper('changes') - linkcheck = builder_helper('linkcheck') - # import the customized builder for object.inv files - inventory = builder_helper('inventory') - - -def build_many(target, args, processes=None): - """ - Thin wrapper around `sage_docbuild.utils.build_many` which uses the - docbuild settings ``NUM_THREADS`` and ``ABORT_ON_ERROR``. - """ - if processes is None: - processes = NUM_THREADS - try: - _build_many(target, args, processes=processes) - except BaseException: - if ABORT_ON_ERROR: - raise - - -########################################## -# Parallel Building Ref Manual # -########################################## - -def build_other_doc(args): - document = args[0] - name = args[1] - kwds = args[2] - args = args[3:] - logger.warning("\nBuilding %s.\n" % document) - getattr(get_builder(document), name)(*args, **kwds) - - -class AllBuilder(object): - """ - A class used to build all of the documentation. - """ - def __getattr__(self, attr): - """ - For any attributes not explicitly defined, we just go through - all of the documents and call their attr. For example, - 'AllBuilder().json()' will go through all of the documents - and call the json() method on their builders. - """ - from functools import partial - return partial(self._wrapper, attr) - - def _wrapper(self, name, *args, **kwds): - """ - This is the function which goes through all of the documents - and does the actual building. - """ - start = time.time() - docs = self.get_all_documents() - refs = [x for x in docs if x.endswith('reference')] - others = [x for x in docs if not x.endswith('reference')] - - # Build the reference manual twice to resolve references. That is, - # build once with the inventory builder to construct the intersphinx - # inventory files, and then build the second time for real. So the - # first build should be as fast as possible; - logger.warning("\nBuilding reference manual, first pass.\n") - for document in refs: - getattr(get_builder(document), 'inventory')(*args, **kwds) - - from sage.env import SAGE_DOC - logger.warning("Building reference manual, second pass.\n") - os.makedirs(os.path.join(SAGE_DOC, "html", "en", "reference", "_static"), exist_ok=True) - for document in refs: - getattr(get_builder(document), name)(*args, **kwds) - - # build the other documents in parallel - L = [(doc, name, kwds) + args for doc in others] - - # Trac #31344: Work around crashes from multiprocessing - if sys.platform == 'darwin': - for target in L: - build_other_doc(target) - else: - build_many(build_other_doc, L) - logger.warning("Elapsed time: %.1f seconds." % (time.time() - start)) - logger.warning("Done building the documentation!") - - def get_all_documents(self): - """ - Return a list of all of the documents. - - A document is a directory within one of the language - subdirectories of SAGE_DOC_SRC specified by the global - LANGUAGES variable. - - EXAMPLES:: - - sage: from sage_docbuild import AllBuilder - sage: documents = AllBuilder().get_all_documents() - sage: 'en/tutorial' in documents # optional - sage_spkg - True - sage: documents[0] == 'en/reference' - True - """ - documents = [] - for lang in LANGUAGES: - for document in os.listdir(os.path.join(SAGE_DOC_SRC, lang)): - if (document not in OMIT - and os.path.isdir(os.path.join(SAGE_DOC_SRC, lang, document))): - documents.append(os.path.join(lang, document)) - - # Ensure that the reference guide is compiled first so that links from - # the other documents to it are correctly resolved. - if 'en/reference' in documents: - documents.remove('en/reference') - documents.insert(0, 'en/reference') - - return documents - - -class WebsiteBuilder(DocBuilder): - def html(self): - """ - After we have finished building the website index page, we copy - everything one directory up. - - In addition, an index file is installed into the root doc directory. - """ - DocBuilder.html(self) - html_output_dir = self._output_dir('html') - for f in os.listdir(html_output_dir): - src = os.path.join(html_output_dir, f) - dst = os.path.join(html_output_dir, '..', f) - if os.path.isdir(src): - shutil.rmtree(dst, ignore_errors=True) - shutil.copytree(src, dst) - else: - shutil.copy2(src, dst) - - root_index_file = os.path.join(html_output_dir, '../../../index.html') - shutil.copy2(os.path.join(SAGE_DOC_SRC, self.lang, 'website', 'root_index.html'), - root_index_file) - - def clean(self): - """ - When we clean the output for the website index, we need to - remove all of the HTML that were placed in the parent - directory. - - In addition, remove the index file installed into the root doc directory. - """ - html_output_dir = self._output_dir('html') - parent_dir = os.path.realpath(os.path.join(html_output_dir, '..')) - for filename in os.listdir(html_output_dir): - parent_filename = os.path.join(parent_dir, filename) - if not os.path.exists(parent_filename): - continue - if os.path.isdir(parent_filename): - shutil.rmtree(parent_filename, ignore_errors=True) - else: - os.unlink(parent_filename) - - root_index_file = os.path.join(html_output_dir, '../../../index.html') - if os.path.exists(root_index_file): - os.remove(root_index_file) - - DocBuilder.clean(self) - - -class ReferenceBuilder(AllBuilder): - """ - This class builds the reference manual. It uses DocBuilder to - build the top-level page and ReferenceSubBuilder for each - sub-component. - """ - def __init__(self, name, lang='en'): - """ - Record the reference manual's name, in case it's not - identical to 'reference'. - """ - AllBuilder.__init__(self) - doc = name.split(os.path.sep) - - if doc[0] in LANGUAGES: - lang = doc[0] - doc.pop(0) - - self.name = doc[0] - self.lang = lang - - def _output_dir(self, type, lang=None): - """ - Return the directory where the output of type ``type`` is stored. - - If the directory does not exist, then it will automatically be - created. - - EXAMPLES:: - - sage: from sage_docbuild import ReferenceBuilder - sage: b = ReferenceBuilder('reference') - sage: b._output_dir('html') # optional - sagemath_doc_html - '.../html/en/reference' - """ - from sage.env import SAGE_DOC - if lang is None: - lang = self.lang - d = os.path.join(SAGE_DOC, type, lang, self.name) - os.makedirs(d, exist_ok=True) - return d - - def _refdir(self): - return os.path.join(SAGE_DOC_SRC, self.lang, self.name) - - def _build_bibliography(self, format, *args, **kwds): - """ - Build the bibliography only - - The bibliography references.aux is referenced by the other - manuals and needs to be built first. - """ - refdir = self._refdir() - references = [ - (doc, self.lang, format, kwds) + args for doc in self.get_all_documents(refdir) - if doc == 'reference/references' - ] - build_many(build_ref_doc, references) - - def _build_everything_except_bibliography(self, format, *args, **kwds): - """ - Build the entire reference manual except the bibliography - """ - refdir = self._refdir() - non_references = [ - (doc, self.lang, format, kwds) + args for doc in self.get_all_documents(refdir) - if doc != 'reference/references' - ] - build_many(build_ref_doc, non_references) - - def _build_top_level(self, format, *args, **kwds): - """ - Build top-level document. - """ - getattr(ReferenceTopBuilder('reference'), format)(*args, **kwds) - - def _wrapper(self, format, *args, **kwds): - """ - Build reference manuals: build the - top-level document and its components. - """ - logger.info('Building bibliography') - self._build_bibliography(format, *args, **kwds) - logger.info('Bibliography finished, building dependent manuals') - self._build_everything_except_bibliography(format, *args, **kwds) - # The html refman must be build at the end to ensure correct - # merging of indexes and inventories. - # Sphinx is run here in the current process (not in a - # subprocess) and the IntersphinxCache gets populated to be - # used for the second pass of the reference manual and for - # the other documents. - self._build_top_level(format, *args, **kwds) - - def get_all_documents(self, refdir): - """ - Return a list of all reference manual components to build. - - We add a component name if it's a subdirectory of the manual's - directory and contains a file named 'index.rst'. - - We return the largest component (most subdirectory entries) - first since they will take the longest to build. - - EXAMPLES:: - - sage: from sage_docbuild import ReferenceBuilder - sage: b = ReferenceBuilder('reference') - sage: refdir = os.path.join(os.environ['SAGE_DOC_SRC'], 'en', b.name) # optional - sage_spkg - sage: sorted(b.get_all_documents(refdir)) # optional - sage_spkg - ['reference/algebras', - 'reference/arithgroup', - ..., - 'reference/valuations'] - """ - documents = [] - - for doc in os.listdir(refdir): - directory = os.path.join(refdir, doc) - if os.path.exists(os.path.join(directory, 'index.rst')): - n = len(os.listdir(directory)) - documents.append((-n, os.path.join(self.name, doc))) - - return [doc[1] for doc in sorted(documents)] - - -class ReferenceTopBuilder(DocBuilder): - """ - This class builds the top-level page of the reference manual. - """ - def __init__(self, *args, **kwds): - DocBuilder.__init__(self, *args, **kwds) - self.name = 'reference' - self.lang = 'en' - - def _output_dir(self, type, lang=None): - """ - Return the directory where the output of type ``type`` is stored. - - If the directory does not exist, then it will automatically be - created. - - EXAMPLES:: - - sage: from sage_docbuild import ReferenceTopBuilder - sage: b = ReferenceTopBuilder('reference') - sage: b._output_dir('html') # optional - sagemath_doc_html - '.../html/en/reference' - """ - from sage.env import SAGE_DOC - if lang is None: - lang = self.lang - d = os.path.join(SAGE_DOC, type, lang, self.name) - os.makedirs(d, exist_ok=True) - return d - - def pdf(self): - """ - Build top-level document. - """ - super().pdf() - - # we need to build master index file which lists all - # of the PDF file. So we create an html file, based on - # the file index.html from the "reference_top" target. - - # First build the top reference page. This only takes a few seconds. - getattr(get_builder('reference_top'), 'html')() - - from sage.env import SAGE_DOC - reference_dir = os.path.join(SAGE_DOC, 'html', 'en', 'reference') - output_dir = self._output_dir('pdf') - - # Install in output_dir a symlink to the directory containing static files. - # Prefer relative path for symlinks. - relpath = os.path.relpath(reference_dir, output_dir) - try: - os.symlink(os.path.join(relpath, '_static'), os.path.join(output_dir, '_static')) - except FileExistsError: - pass - - # Now modify top reference index.html page and write it to output_dir. - with open(os.path.join(reference_dir, 'index.html')) as f: - html = f.read() - html_output_dir = os.path.dirname(reference_dir) - - # Fix links in navigation bar - html = re.sub(r'Sage(.*)Documentation', - r'Sage\2Documentation', - html) - html = re.sub(r'Reference Manual', - r'Reference Manual (PDF version)', - html) - html = re.sub(r'
  • ', r'
  • ; change rst headers to html headers - rst_toc = re.sub(r'\*(.*)\n', - r'
  • \1
  • \n', rst_toc) - rst_toc = re.sub(r'\n([A-Z][a-zA-Z, ]*)\n[=]*\n', - r'\n\n\n

    \1

    \n\n
      \n', rst_toc) - rst_toc = re.sub(r'\n([A-Z][a-zA-Z, ]*)\n[-]*\n', - r'
    \n\n\n

    \1

    \n\n
      \n', rst_toc) - # now write the file. - with open(os.path.join(output_dir, 'index.html'), 'w') as new_index: - new_index.write(html[:html_end_preamble]) - new_index.write('

      Sage Reference Manual (PDF version)

      ') - new_index.write(rst_body) - new_index.write('
        ') - new_index.write(rst_toc) - new_index.write('
      \n\n') - new_index.write(html[html_bottom:]) - logger.warning(''' -PDF documents have been created in subdirectories of - - %s - -Alternatively, you can open - - %s - -for a webpage listing all of the documents.''' % (output_dir, - os.path.join(output_dir, - 'index.html'))) - - -class ReferenceSubBuilder(DocBuilder): - """ - This class builds sub-components of the reference manual. It is - responsible for making sure that the auto generated reST files for the - Sage library are up to date. - - When building any output, we must first go through and check - to see if we need to update any of the autogenerated reST - files. There are two cases where this would happen: - - 1. A new module gets added to one of the toctrees. - - 2. The actual module gets updated and possibly contains a new - title. - """ - def __init__(self, *args, **kwds): - DocBuilder.__init__(self, *args, **kwds) - self._wrap_builder_helpers() - - def _wrap_builder_helpers(self): - from functools import partial, update_wrapper - for attr in dir(self): - if hasattr(getattr(self, attr), 'is_output_format'): - f = partial(self._wrapper, attr) - f.is_output_format = True - update_wrapper(f, getattr(self, attr)) - setattr(self, attr, f) - - def _wrapper(self, build_type, *args, **kwds): - """ - This is the wrapper around the builder_helper methods that - goes through and makes sure things are up to date. - """ - # Force regeneration of all modules if the inherited - # and/or underscored members options have changed. - cache = self.get_cache() - force = False - try: - if (cache['option_inherited'] != self._options.inherited or - cache['option_underscore'] != self._options.underscore): - logger.info("Detected change(s) in inherited and/or underscored members option(s).") - force = True - except KeyError: - force = True - cache['option_inherited'] = self._options.inherited - cache['option_underscore'] = self._options.underscore - self.save_cache() - - # After "sage -clone", refresh the reST file mtimes in - # environment.pickle. - if self._options.update_mtimes: - logger.info("Checking for reST file mtimes to update...") - self.update_mtimes() - - if force: - # Write reST files for all modules from scratch. - self.clean_auto() - for module_name in self.get_all_included_modules(): - self.write_auto_rest_file(module_name) - else: - # Write reST files for new and updated modules. - for module_name in self.get_new_and_updated_modules(): - self.write_auto_rest_file(module_name) - - # Copy over the custom reST files from _sage - _sage = os.path.join(self.dir, '_sage') - if os.path.exists(_sage): - logger.info("Copying over custom reST files from %s ...", _sage) - shutil.copytree(_sage, os.path.join(self.dir, 'sage')) - - getattr(DocBuilder, build_type)(self, *args, **kwds) - - def cache_filename(self): - """ - Return the filename where the pickle of the reference cache - is stored. - """ - return os.path.join(self._doctrees_dir(), 'reference.pickle') - - @cached_method - def get_cache(self): - """ - Retrieve the reference cache which contains the options previously used - by the reference builder. - - If it doesn't exist, then we just return an empty dictionary. If it - is corrupted, return an empty dictionary. - """ - filename = self.cache_filename() - if not os.path.exists(filename): - return {} - with open(self.cache_filename(), 'rb') as file: - try: - cache = pickle.load(file) - except Exception: - logger.debug("Cache file '%s' is corrupted; ignoring it..." % filename) - cache = {} - else: - logger.debug("Loaded the reference cache: %s", filename) - return cache - - def save_cache(self): - """ - Pickle the current reference cache for later retrieval. - """ - cache = self.get_cache() - try: - with open(self.cache_filename(), 'wb') as file: - pickle.dump(cache, file) - logger.debug("Saved the reference cache: %s", self.cache_filename()) - except PermissionError: - logger.debug("Permission denied for the reference cache: %s", self.cache_filename()) - - def get_sphinx_environment(self): - """ - Return the Sphinx environment for this project. - """ - class FakeConfig(object): - values = tuple() - - class FakeApp(object): - def __init__(self, dir): - self.srcdir = dir - self.config = FakeConfig() - - env_pickle = os.path.join(self._doctrees_dir(), 'environment.pickle') - try: - with open(env_pickle, 'rb') as f: - env = pickle.load(f) - env.app = FakeApp(self.dir) - env.config.values = env.app.config.values - logger.debug("Opened Sphinx environment: %s", env_pickle) - return env - except (IOError, EOFError) as err: - logger.debug( - f"Failed to open Sphinx environment '{env_pickle}'", exc_info=True) - - def update_mtimes(self): - """ - Update the modification times for reST files in the Sphinx - environment for this project. - """ - env = self.get_sphinx_environment() - if env is not None: - for doc in env.all_docs: - env.all_docs[doc] = time.time() - logger.info("Updated %d reST file mtimes", len(env.all_docs)) - # This is the only place we need to save (as opposed to - # load) Sphinx's pickle, so we do it right here. - env_pickle = os.path.join(self._doctrees_dir(), - 'environment.pickle') - - # When cloning a new branch (see - # SAGE_LOCAL/bin/sage-clone), we hard link the doc output. - # To avoid making unlinked, potentially inconsistent - # copies of the environment, we *don't* use - # env.topickle(env_pickle), which first writes a temporary - # file. We adapt sphinx.environment's - # BuildEnvironment.topickle: - - # remove unpicklable attributes - env.set_warnfunc(None) - del env.config.values - with open(env_pickle, 'wb') as picklefile: - # remove potentially pickling-problematic values from config - for key, val in vars(env.config).items(): - if key.startswith('_') or isinstance(val, (types.ModuleType, - types.FunctionType, - type)): - del env.config[key] - pickle.dump(env, picklefile, pickle.HIGHEST_PROTOCOL) - - logger.debug("Saved Sphinx environment: %s", env_pickle) - - def get_modified_modules(self): - """ - Return an iterator for all the modules that have been modified - since the documentation was last built. - """ - env = self.get_sphinx_environment() - if env is None: - logger.debug("Stopped check for modified modules.") - return - try: - added, changed, removed = env.get_outdated_files(False) - logger.info("Sphinx found %d modified modules", len(changed)) - except OSError as err: - logger.debug("Sphinx failed to determine modified modules: %s", err) - return - for name in changed: - # Only pay attention to files in a directory sage/... In - # particular, don't treat a file like 'sagetex.rst' in - # doc/en/reference/misc as an autogenerated file: see - # #14199. - if name.startswith('sage' + os.sep): - yield name - - def print_modified_modules(self): - """ - Print a list of all the modules that have been modified since - the documentation was last built. - """ - for module_name in self.get_modified_modules(): - print(module_name) - - def get_all_rst_files(self, exclude_sage=True): - """ - Return an iterator for all rst files which are not - autogenerated. - """ - for directory, subdirs, files in os.walk(self.dir): - if exclude_sage and directory.startswith(os.path.join(self.dir, 'sage')): - continue - for filename in files: - if not filename.endswith('.rst'): - continue - yield os.path.join(directory, filename) - - def get_all_included_modules(self): - """ - Return an iterator for all modules which are included in the - reference manual. - """ - for filename in self.get_all_rst_files(): - for module in self.get_modules(filename): - yield module - - def get_new_and_updated_modules(self): - """ - Return an iterator for all new and updated modules that appear in - the toctrees, and remove obsolete old modules. - """ - env = self.get_sphinx_environment() - if env is None: - all_docs = {} - else: - all_docs = env.all_docs - - new_modules = [] - updated_modules = [] - old_modules = [] - for module_name in self.get_all_included_modules(): - docname = module_name.replace('.', os.path.sep) - - if docname not in all_docs: - new_modules.append(module_name) - yield module_name - continue - - # get the modification timestamp of the reST doc for the module - mtime = all_docs[docname] - try: - with warnings.catch_warnings(): - # primarily intended to ignore deprecation warnings - warnings.simplefilter("ignore") - __import__(module_name) - except ImportError as err: - logger.error("Warning: Could not import %s %s", module_name, err) - raise - - module_filename = sys.modules[module_name].__file__ - if (module_filename.endswith('.pyc') or module_filename.endswith('.pyo')): - source_filename = module_filename[:-1] - if (os.path.exists(source_filename)): - module_filename = source_filename - newtime = os.path.getmtime(module_filename) - - if newtime > mtime: - updated_modules.append(module_name) - yield module_name - else: # keep good old module - old_modules.append(module_name) - - removed_modules = [] - for docname in all_docs.keys(): - if docname.startswith('sage' + os.path.sep): - module_name = docname.replace(os.path.sep, '.') - if not (module_name in old_modules or module_name in updated_modules): - try: - os.remove(os.path.join(self.dir, docname) + '.rst') - except OSError: # already removed - pass - logger.debug("Deleted auto-generated reST file {}".format(docname)) - removed_modules.append(module_name) - - logger.info("Found %d new modules", len(new_modules)) - logger.info("Found %d updated modules", len(updated_modules)) - logger.info("Removed %d obsolete modules", len(removed_modules)) - - def print_new_and_updated_modules(self): - """ - Print all the modules that appear in the toctrees that - are newly included or updated. - """ - for module_name in self.get_new_and_updated_modules(): - print(module_name) - - def get_modules(self, filename): - """ - Given a filename for a reST file, return an iterator for - all of the autogenerated reST files that it includes. - """ - # Create the regular expression used to detect an autogenerated file - auto_re = re.compile(r'^\s*(..\/)*(sage(nb)?\/[\w\/]*)\s*$') - - # Read the lines - with open(filename) as f: - lines = f.readlines() - for line in lines: - match = auto_re.match(line) - if match: - yield match.group(2).replace(os.path.sep, '.') - - def get_module_docstring_title(self, module_name): - """ - Return the title of the module from its docstring. - """ - # Try to import the module - try: - __import__(module_name) - except ImportError as err: - logger.error("Warning: Could not import %s %s", module_name, err) - return "UNABLE TO IMPORT MODULE" - module = sys.modules[module_name] - - # Get the docstring - doc = module.__doc__ - if doc is None: - doc = module.doc if hasattr(module, 'doc') else "" - - # Extract the title - i = doc.find('\n') - if i != -1: - return doc[i + 1:].lstrip().splitlines()[0] - else: - return doc - - def auto_rest_filename(self, module_name): - """ - Return the name of the file associated to a given module - - EXAMPLES:: - - sage: from sage_docbuild import ReferenceSubBuilder - sage: ReferenceSubBuilder("reference").auto_rest_filename("sage.combinat.partition") - '.../en/reference/sage/combinat/partition.rst' - """ - return self.dir + os.path.sep + module_name.replace('.', os.path.sep) + '.rst' - - def write_auto_rest_file(self, module_name): - """ - Write the autogenerated reST file for module_name. - """ - if not module_name.startswith('sage'): - return - filename = self.auto_rest_filename(module_name) - os.makedirs(os.path.dirname(filename), exist_ok=True) - - title = self.get_module_docstring_title(module_name) - - if title == '': - logger.error("Warning: Missing title for %s", module_name) - title = "MISSING TITLE" - - with open(filename, 'w') as outfile: - # Don't doctest the autogenerated file. - outfile.write(".. nodoctest\n\n") - # Now write the actual content. - outfile.write(".. _%s:\n\n" % (module_name.replace(".__init__", ""))) - outfile.write(title + '\n') - outfile.write('=' * len(title) + "\n\n") - outfile.write('.. This file has been autogenerated.\n\n') - - inherited = ':inherited-members:' if self._options.inherited else '' - - automodule = ''' -.. automodule:: %s - :members: - :undoc-members: - :show-inheritance: - %s - -''' - outfile.write(automodule % (module_name, inherited)) - - def clean_auto(self): - """ - Remove all autogenerated reST files. - """ - try: - shutil.rmtree(os.path.join(self.dir, 'sage')) - logger.debug("Deleted auto-generated reST files in: %s", - os.path.join(self.dir, 'sage')) - except OSError: - pass - - def get_unincluded_modules(self): - """ - Return an iterator for all the modules in the Sage library - which are not included in the reference manual. - """ - # Make a dictionary of the included modules - included_modules = {} - for module_name in self.get_all_included_modules(): - included_modules[module_name] = True - - base_path = os.path.join(SAGE_SRC, 'sage') - for directory, subdirs, files in os.walk(base_path): - for filename in files: - if not (filename.endswith('.py') or - filename.endswith('.pyx')): - continue - - path = os.path.join(directory, filename) - - # Create the module name - module_name = path[len(base_path):].replace(os.path.sep, '.') - module_name = 'sage' + module_name - module_name = module_name[:-4] if module_name.endswith('pyx') else module_name[:-3] - - # Exclude some ones -- we don't want init the manual - if module_name.endswith('__init__') or module_name.endswith('all'): - continue - - if module_name not in included_modules: - yield module_name - - def print_unincluded_modules(self): - """ - Print all of the modules which are not included in the Sage - reference manual. - """ - for module_name in self.get_unincluded_modules(): - print(module_name) - - def print_included_modules(self): - """ - Print all of the modules that are included in the Sage reference - manual. - """ - for module_name in self.get_all_included_modules(): - print(module_name) - - -class SingleFileBuilder(DocBuilder): - """ - This is the class used to build the documentation for a single - user-specified file. If the file is called 'foo.py', then the - documentation is built in ``DIR/foo/`` if the user passes the - command line option "-o DIR", or in ``DOT_SAGE/docbuild/foo/`` - otherwise. - """ - def __init__(self, path): - """ - INPUT: - - - ``path`` - the path to the file for which documentation - should be built - """ - self.lang = 'en' - self.name = 'single_file' - path = os.path.abspath(path) - - # Create docbuild and relevant subdirectories, e.g., - # the static and templates directories in the output directory. - # By default, this is DOT_SAGE/docbuild/MODULE_NAME, but can - # also be specified at the command line. - module_name = os.path.splitext(os.path.basename(path))[0] - latex_name = module_name.replace('_', r'\\_') - - if self._options.output_dir: - base_dir = os.path.join(self._options.output_dir, module_name) - if os.path.exists(base_dir): - logger.warning('Warning: Directory %s exists. It is safer to build in a new directory.' % base_dir) - else: - base_dir = os.path.join(DOT_SAGE, 'docbuild', module_name) - try: - shutil.rmtree(base_dir) - except OSError: - pass - self.dir = os.path.join(base_dir, 'source') - - os.makedirs(os.path.join(self.dir, "static"), exist_ok=True) - os.makedirs(os.path.join(self.dir, "templates"), exist_ok=True) - # Write self.dir/conf.py - conf = r"""# This file is automatically generated by {}, do not edit! - -import sys, os, contextlib -sys.path.append({!r}) - -from sage.docs.conf import * -html_static_path = [] + html_common_static_path - -project = 'Documentation for {}' -release = 'unknown' -name = {!r} -html_title = project -html_short_title = project -htmlhelp_basename = name - -with contextlib.suppress(ValueError): - extensions.remove('multidocs') # see #29651 - extensions.remove('inventory_builder') - -latex_domain_indices = False -latex_documents = [ - ('index', name + '.tex', 'Documentation for {}', - 'unknown', 'manual'), -] -""".format(__file__, self.dir, module_name, module_name, latex_name) - - if 'SAGE_DOC_UNDERSCORE' in os.environ: - conf += r""" -def setup(app): - app.connect('autodoc-skip-member', skip_member) -""" - - with open(os.path.join(self.dir, 'conf.py'), 'w') as conffile: - conffile.write(conf) - - # Write self.dir/index.rst - title = 'Docs for file %s' % path - heading = title + "\n" + ("=" * len(title)) - index = r"""{} - -.. This file is automatically generated by {}, do not edit! - -.. automodule:: {} - :members: - :undoc-members: - :show-inheritance: - -""".format(heading, __file__, module_name) - with open(os.path.join(self.dir, 'index.rst'), 'w') as indexfile: - indexfile.write(index) - - # Create link from original file to self.dir. Note that we - # append self.dir to sys.path in conf.py. This is reasonably - # safe (but not perfect), since we just created self.dir. - try: - os.symlink(path, os.path.join(self.dir, os.path.basename(path))) - except OSError: - pass - - def _output_dir(self, type): - """ - Return the directory where the output of type ``type`` is stored. - - If the directory does not exist, then it will automatically be - created. - """ - base_dir = os.path.split(self.dir)[0] - d = os.path.join(base_dir, "output", type) - os.makedirs(d, exist_ok=True) - return d - - def _doctrees_dir(self): - """ - Return the directory where the doctrees are stored. - - If the directory does not exist, then it will automatically be - created. - """ - return self._output_dir('doctrees') - - -def get_builder(name): - """ - Return an appropriate *Builder object for the document ``name``. - - DocBuilder and its subclasses do all the real work in building the - documentation. - """ - if name == 'all': - from sage.misc.superseded import deprecation - deprecation(31948, 'avoid using "sage --docbuild all html" and "sage --docbuild all pdf"; ' - 'use "make doc" and "make doc-pdf" instead, if available.') - return AllBuilder() - elif name == 'reference_top': - return ReferenceTopBuilder('reference') - elif name.endswith('reference'): - return ReferenceBuilder(name) - elif 'reference' in name and os.path.exists(os.path.join(SAGE_DOC_SRC, 'en', name)): - return ReferenceSubBuilder(name) - elif name.endswith('website'): - return WebsiteBuilder(name) - elif name.startswith('file='): - path = name[5:] - if path.endswith('.sage') or path.endswith('.pyx'): - raise NotImplementedError('Building documentation for a single file only works for Python files.') - return SingleFileBuilder(path) - elif name in get_documents() or name in AllBuilder().get_all_documents(): - return DocBuilder(name) - else: - print("'%s' is not a recognized document. Type 'sage --docbuild -D' for a list" % name) - print("of documents, or 'sage --docbuild --help' for more help.") - sys.exit(1) - - -def format_columns(lst, align='<', cols=None, indent=4, pad=3, width=80): - """ - Utility function that formats a list as a simple table and returns - a Unicode string representation. - - The number of columns is - computed from the other options, unless it's passed as a keyword - argument. For help on Python's string formatter, see - - https://docs.python.org/library/string.html#format-string-syntax - """ - # Can we generalize this (efficiently) to other / multiple inputs - # and generators? - size = max(map(len, lst)) + pad - if cols is None: - import math - cols = math.trunc((width - indent) / size) - s = " " * indent - for i in range(len(lst)): - if i != 0 and i % cols == 0: - s += "\n" + " " * indent - s += "{0:{1}{2}}".format(lst[i], align, size) - s += "\n" - return s - - -def help_usage(s="", compact=False): - """ - Append and return a brief usage message for the Sage documentation builder. - - If 'compact' is False, the function adds a final newline character. - """ - s += "sage --docbuild [OPTIONS] DOCUMENT (FORMAT | COMMAND)" - if not compact: - s += "\n" - return s - - -def help_description(s="", compact=False): - """ - Append and return a brief description of the Sage documentation builder. - - If 'compact' is ``False``, the function adds a final newline character. - """ - s += "Build or return information about Sage documentation. " - s += "A DOCUMENT and either a FORMAT or a COMMAND are required." - if not compact: - s += "\n" - return s - - -def help_examples(s=""): - """ - Append and return some usage examples for the Sage documentation builder. - """ - s += "Examples:\n" - s += " sage --docbuild -C all\n" - s += " sage --docbuild constructions pdf\n" - s += " sage --docbuild reference html -jv3\n" - s += " sage --docbuild reference print_unincluded_modules\n" - s += " sage --docbuild developer html --sphinx-opts='-q,-aE' --verbose 2" - return s - - -def get_documents(): - """ - Return a list of document names the Sage documentation builder - will accept as command-line arguments. - """ - all_b = AllBuilder() - docs = all_b.get_all_documents() - docs = [(d[3:] if d[0:3] == 'en/' else d) for d in docs] - return docs - - -def help_documents(): - """ - Append and return a tabular list of documents, including a - shortcut 'all' for all documents, available to the Sage - documentation builder. - """ - docs = get_documents() - s = "DOCUMENTs:\n" - s += format_columns(docs) - s += "\n" - if 'reference' in docs: - s += "Other valid document names take the form 'reference/DIR', where\n" - s += "DIR is a subdirectory of SAGE_DOC_SRC/en/reference/.\n" - s += "This builds just the specified part of the reference manual.\n" - s += "DOCUMENT may also have the form 'file=/path/to/FILE', which builds\n" - s += "the documentation for the specified file.\n" - return s - - -def get_formats(): - """ - Return a list of output formats the Sage documentation builder - will accept on the command-line. - """ - tut_b = DocBuilder('en/tutorial') - formats = tut_b._output_formats() - formats.remove('html') - return ['html', 'pdf'] + formats - - -def help_formats(): - """ - Append and return a tabular list of output formats available to - the Sage documentation builder. - """ - return "FORMATs:\n" + format_columns(get_formats()) - - -def help_commands(name='all'): - """ - Append and return a tabular list of commands, if any, the Sage - documentation builder can run on the indicated document. The - default is to list all commands for all documents. - """ - # To do: Generate the lists dynamically, using class attributes, - # as with the Builders above. - s = "" - command_dict = {'reference': [ - 'print_included_modules', 'print_modified_modules (*)', - 'print_unincluded_modules', 'print_new_and_updated_modules (*)']} - for doc in command_dict: - if name == 'all' or doc == name: - s += "COMMANDs for the DOCUMENT '" + doc + "':\n" - s += format_columns(command_dict[doc]) - s += "(*) Since the last build.\n" - return s - - -class help_message_long(argparse.Action): - """ - Print an extended help message for the Sage documentation builder - and exits. - """ - def __call__(self, parser, namespace, values, option_string=None): - help_funcs = [help_usage, help_description, help_documents, - help_formats, help_commands] - for f in help_funcs: - print(f()) - parser.print_help() - print(help_examples()) - sys.exit(0) - - -class help_message_short(argparse.Action): - """ - Print a help message for the Sage documentation builder. - - The message includes command-line usage and a list of options. - The message is printed only on the first call. If error is True - during this call, the message is printed only if the user hasn't - requested a list (e.g., documents, formats, commands). - """ - def __call__(self, parser, namespace, values, option_string=None): - if not hasattr(namespace, 'printed_help'): - parser.print_help() - setattr(namespace, 'printed_help', 1) - sys.exit(0) - - -class help_wrapper(argparse.Action): - """ - A helper wrapper for command-line options to the Sage - documentation builder that print lists, such as document names, - formats, and document-specific commands. - """ - def __call__(self, parser, namespace, values, option_string=None): - if option_string in ['-D', '--documents']: - print(help_documents(), end="") - if option_string in ['-F', '--formats']: - print(help_formats(), end="") - if self.dest == 'commands': - print(help_commands(values), end="") - if self.dest == 'all_documents': - if values == 'reference': - b = ReferenceBuilder('reference') - refdir = os.path.join(os.environ['SAGE_DOC_SRC'], 'en', b.name) - s = b.get_all_documents(refdir) - # Put the bibliography first, because it needs to be built first: - s.remove('reference/references') - s.insert(0, 'reference/references') - elif values == 'all': - s = get_documents() - # Put the reference manual first, because it needs to be built first: - s.remove('reference') - s.insert(0, 'reference') - for d in s: - print(d) - setattr(namespace, 'printed_list', 1) - sys.exit(0) - - -def setup_parser(): - """ - Set up and return a command-line ArgumentParser instance for the - Sage documentation builder. - """ - # Documentation: https://docs.python.org/library/argparse.html - parser = argparse.ArgumentParser(usage=help_usage(compact=True), - description=help_description(compact=True), - add_help=False) - # Standard options. Note: We use explicit option.dest names - # to avoid ambiguity. - standard = parser.add_argument_group("Standard") - standard.add_argument("-h", "--help", nargs=0, action=help_message_short, - help="show a help message and exit") - standard.add_argument("-H", "--help-all", nargs=0, action=help_message_long, - help="show an extended help message and exit") - standard.add_argument("-D", "--documents", nargs=0, action=help_wrapper, - help="list all available DOCUMENTs") - standard.add_argument("-F", "--formats", nargs=0, action=help_wrapper, - help="list all output FORMATs") - standard.add_argument("-C", "--commands", dest="commands", - type=str, metavar="DOC", action=help_wrapper, - help="list all COMMANDs for DOCUMENT DOC; use 'all' to list all") - standard.add_argument("-i", "--inherited", dest="inherited", - action="store_true", - help="include inherited members in reference manual; may be slow, may fail for PDF output") - standard.add_argument("-u", "--underscore", dest="underscore", - action="store_true", - help="include variables prefixed with '_' in reference manual; may be slow, may fail for PDF output") - standard.add_argument("-j", "--mathjax", "--jsmath", dest="mathjax", - action="store_true", - help="ignored for backwards compatibility") - standard.add_argument("--no-plot", dest="no_plot", - action="store_true", - help="do not include graphics auto-generated using the '.. plot' markup") - standard.add_argument("--include-tests-blocks", dest="skip_tests", default=True, - action="store_false", - help="include TESTS blocks in the reference manual") - standard.add_argument("--no-pdf-links", dest="no_pdf_links", - action="store_true", - help="do not include PDF links in DOCUMENT 'website'; FORMATs: html, json, pickle, web") - standard.add_argument("--warn-links", dest="warn_links", - action="store_true", - help="issue a warning whenever a link is not properly resolved; equivalent to '--sphinx-opts -n' (sphinx option: nitpicky)") - standard.add_argument("--check-nested", dest="check_nested", - action="store_true", - help="check picklability of nested classes in DOCUMENT 'reference'") - standard.add_argument("--no-prune-empty-dirs", dest="no_prune_empty_dirs", - action="store_true", - help="do not prune empty directories in the documentation sources") - standard.add_argument("-N", "--no-colors", dest="color", - action="store_false", - help="do not color output; does not affect children") - standard.add_argument("-q", "--quiet", dest="verbose", - action="store_const", const=0, - help="work quietly; same as --verbose=0") - standard.add_argument("-v", "--verbose", dest="verbose", - type=int, default=1, metavar="LEVEL", - action="store", - help="report progress at LEVEL=0 (quiet), 1 (normal), 2 (info), or 3 (debug); does not affect children") - standard.add_argument("-o", "--output", dest="output_dir", default=None, - metavar="DIR", action="store", - help="if DOCUMENT is a single file ('file=...'), write output to this directory") - - # Advanced options. - advanced = parser.add_argument_group("Advanced", - "Use these options with care.") - advanced.add_argument("-S", "--sphinx-opts", dest="sphinx_opts", - type=str, metavar="OPTS", - action="store", - help="pass comma-separated OPTS to sphinx-build; must precede OPTS with '=', as in '-S=-q,-aE' or '-S=\"-q,-aE\"'") - advanced.add_argument("-U", "--update-mtimes", dest="update_mtimes", - action="store_true", - help="before building reference manual, update modification times for auto-generated reST files") - advanced.add_argument("-k", "--keep-going", dest="keep_going", - action="store_true", - help="Do not abort on errors but continue as much as possible after an error") - advanced.add_argument("--all-documents", dest="all_documents", - type=str, metavar="ARG", - choices=['all', 'reference'], - action=help_wrapper, - help="if ARG is 'reference', list all subdocuments" - " of en/reference. If ARG is 'all', list all main" - " documents") - parser.add_argument("document", nargs='?', type=str, metavar="DOCUMENT", - help="name of the document to build. It can be either one of the documents listed by -D or 'file=/path/to/FILE' to build documentation for this specific file.") - parser.add_argument("format", nargs='?', type=str, - metavar="FORMAT or COMMAND", help='document output format (or command)') - return parser - - -def setup_logger(verbose=1, color=True): - r""" - Set up a Python Logger instance for the Sage documentation builder. - - The optional argument sets logger's level and message format. - - EXAMPLES:: - - sage: from sage_docbuild import setup_logger, logger - sage: setup_logger() - sage: type(logger) - - """ - # Set up colors. Adapted from sphinx.cmdline. - import sphinx.util.console as c - if not color or not sys.stdout.isatty() or not c.color_terminal(): - c.nocolor() - - # Available colors: black, darkgray, (dark)red, dark(green), - # brown, yellow, (dark)blue, purple, fuchsia, turquoise, teal, - # lightgray, white. Available styles: reset, bold, faint, - # standout, underline, blink. - - # Set up log record formats. - format_std = "%(message)s" - formatter = logging.Formatter(format_std) - - # format_debug = "%(module)s #%(lineno)s %(funcName)s() %(message)s" - fields = ['%(module)s', '#%(lineno)s', '%(funcName)s()', '%(message)s'] - colors = ['darkblue', 'darkred', 'brown', 'reset'] - styles = ['reset', 'reset', 'reset', 'reset'] - format_debug = "" - for i in range(len(fields)): - format_debug += c.colorize(styles[i], c.colorize(colors[i], fields[i])) - if i != len(fields): - format_debug += " " - - # Note: There's also Handler.setLevel(). The argument is the - # lowest severity message that the respective logger or handler - # will pass on. The default levels are DEBUG, INFO, WARNING, - # ERROR, and CRITICAL. We use "WARNING" for normal verbosity and - # "ERROR" for quiet operation. It's possible to define custom - # levels. See the documentation for details. - if verbose == 0: - logger.setLevel(logging.ERROR) - if verbose == 1: - logger.setLevel(logging.WARNING) - if verbose == 2: - logger.setLevel(logging.INFO) - if verbose == 3: - logger.setLevel(logging.DEBUG) - formatter = logging.Formatter(format_debug) - - handler = logging.StreamHandler() - handler.setFormatter(formatter) - logger.addHandler(handler) - - -class IntersphinxCache: - """ - Replace sphinx.ext.intersphinx.fetch_inventory by an in-memory - cached version. - """ - def __init__(self): - self.inventories = {} - self.real_fetch_inventory = sphinx.ext.intersphinx.fetch_inventory - sphinx.ext.intersphinx.fetch_inventory = self.fetch_inventory - - def fetch_inventory(self, app, uri, inv): - """ - Return the result of ``sphinx.ext.intersphinx.fetch_inventory()`` - from a cache if possible. Otherwise, call - ``sphinx.ext.intersphinx.fetch_inventory()`` and cache the result. - """ - t = (uri, inv) - try: - return self.inventories[t] - except KeyError: - i = self.real_fetch_inventory(app, uri, inv) - self.inventories[t] = i - return i - - -def main(): - # Parse the command-line. - parser = setup_parser() - args = parser.parse_args() - DocBuilder._options = args - - # Get the name and type (target format) of the document we are - # trying to build. - name, typ = args.document, args.format - if not name or not typ: - parser.print_help() - sys.exit(1) - - # Set up module-wide logging. - setup_logger(args.verbose, args.color) - - def excepthook(*exc_info): - logger.error('Error building the documentation.', exc_info=exc_info) - if INCREMENTAL_BUILD: - logger.error(''' - Note: incremental documentation builds sometimes cause spurious - error messages. To be certain that these are real errors, run - "make doc-clean doc-uninstall" first and try again.''') - - sys.excepthook = excepthook - - # Process selected options. - if args.check_nested: - os.environ['SAGE_CHECK_NESTED'] = 'True' - - if args.underscore: - os.environ['SAGE_DOC_UNDERSCORE'] = "True" - - global ALLSPHINXOPTS, WEBSITESPHINXOPTS, ABORT_ON_ERROR - if args.sphinx_opts: - ALLSPHINXOPTS += args.sphinx_opts.replace(',', ' ') + " " - if args.no_pdf_links: - WEBSITESPHINXOPTS = " -A hide_pdf_links=1 " - if args.warn_links: - ALLSPHINXOPTS += "-n " - if args.no_plot: - os.environ['SAGE_SKIP_PLOT_DIRECTIVE'] = 'yes' - if args.skip_tests: - os.environ['SAGE_SKIP_TESTS_BLOCKS'] = 'True' - - ABORT_ON_ERROR = not args.keep_going - - if not args.no_prune_empty_dirs: - # Delete empty directories. This is needed in particular for empty - # directories due to "git checkout" which never deletes empty - # directories it leaves behind. See Trac #20010. - # Trac #31948: This is not parallelization-safe; use the option - # --no-prune-empty-dirs to turn it off - for dirpath, dirnames, filenames in os.walk(SAGE_DOC_SRC, topdown=False): - if not dirnames + filenames: - logger.warning('Deleting empty directory {0}'.format(dirpath)) - os.rmdir(dirpath) - - # Set up Intersphinx cache - _ = IntersphinxCache() - - builder = getattr(get_builder(name), typ) - builder() diff --git a/src/sage_docbuild/__main__.py b/src/sage_docbuild/__main__.py index 031df43e1f1..c551e345406 100644 --- a/src/sage_docbuild/__main__.py +++ b/src/sage_docbuild/__main__.py @@ -1,2 +1,495 @@ -from . import main -main() +r""" +Sage docbuild main + +This module defines the Sage documentation build command:: + + sage --docbuild [OPTIONS] DOCUMENT (FORMAT | COMMAND) + +If ``FORMAT`` is given, ``DOCUMENT`` in given ``FORMAT`` is built. If +``COMMAND`` is given, it returns information about ``DOCUMENT``. + +To get started, run ``sage --docbuild`` to get detailed explanations about +arguments and options. + +Positional arguments:: + + DOCUMENT name of the document to build. It can be either one + of the documents listed by -D or 'file=/path/to/FILE' to build documentation + for this specific file. + FORMAT or COMMAND document output format (or command) + +Standard options:: + + -h, --help show a help message and exit + -H, --help-all show an extended help message and exit + -D, --documents list all available DOCUMENTs + -F, --formats list all output FORMATs + -C DOC, --commands DOC list all COMMANDs for DOCUMENT DOC; use 'all' to list all + -i, --inherited include inherited members in reference manual; may be slow, may fail for PDF output + -u, --underscore include variables prefixed with '_' in reference + manual; may be slow, may fail for PDF output + -j, --mathjax, --jsmath ignored for backwards compatibility + --no-plot do not include graphics auto-generated using the '.. plot' markup + --include-tests-blocks include TESTS blocks in the reference manual + --no-pdf-links do not include PDF links in DOCUMENT 'website'; + FORMATs: html, json, pickle, web + --warn-links issue a warning whenever a link is not properly + resolved; equivalent to '--sphinx-opts -n' (sphinx option: nitpicky) + --check-nested check picklability of nested classes in DOCUMENT 'reference' + --no-prune-empty-dirs do not prune empty directories in the documentation sources + -N, --no-colors do not color output; does not affect children + -q, --quiet work quietly; same as --verbose=0 + -v LEVEL, --verbose LEVEL report progress at LEVEL=0 (quiet), 1 (normal), 2 + (info), or 3 (debug); does not affect children + -o DIR, --output DIR if DOCUMENT is a single file ('file=...'), write output to this directory + +Advanced options:: + + -S OPTS, --sphinx-opts OPTS pass comma-separated OPTS to sphinx-build; must + precede OPTS with '=', as in '-S=-q,-aE' or '-S="-q,-aE"' + -U, --update-mtimes before building reference manual, update + modification times for auto-generated reST files + -k, --keep-going do not abort on errors but continue as much as + possible after an error + --all-documents ARG if ARG is 'reference', list all subdocuments of + en/reference. If ARG is 'all', list all main documents + +""" + +import logging +import argparse +import os +import sys +import sphinx.ext.intersphinx +from sage.env import SAGE_DOC_SRC +from .builders import DocBuilder, ReferenceBuilder, get_builder, get_documents +from .build_options import (INCREMENTAL_BUILD, + ALLSPHINXOPTS, WEBSITESPHINXOPTS, ABORT_ON_ERROR) + +logger = logging.getLogger(__name__) + +def format_columns(lst, align='<', cols=None, indent=4, pad=3, width=80): + """ + Utility function that formats a list as a simple table and returns + a Unicode string representation. + + The number of columns is + computed from the other options, unless it's passed as a keyword + argument. For help on Python's string formatter, see + + https://docs.python.org/library/string.html#format-string-syntax + """ + # Can we generalize this (efficiently) to other / multiple inputs + # and generators? + size = max(map(len, lst)) + pad + if cols is None: + import math + cols = math.trunc((width - indent) / size) + s = " " * indent + for i in range(len(lst)): + if i != 0 and i % cols == 0: + s += "\n" + " " * indent + s += "{0:{1}{2}}".format(lst[i], align, size) + s += "\n" + return s + + +def help_usage(s="", compact=False): + """ + Append and return a brief usage message for the Sage documentation builder. + + If 'compact' is False, the function adds a final newline character. + """ + s += "sage --docbuild [OPTIONS] DOCUMENT (FORMAT | COMMAND)" + if not compact: + s += "\n" + return s + + +def help_description(s="", compact=False): + """ + Append and return a brief description of the Sage documentation builder. + + If 'compact' is ``False``, the function adds a final newline character. + """ + s += "Build or return information about Sage documentation. " + s += "A DOCUMENT and either a FORMAT or a COMMAND are required." + if not compact: + s += "\n" + return s + + +def help_examples(s=""): + """ + Append and return some usage examples for the Sage documentation builder. + """ + s += "Examples:\n" + s += " sage --docbuild -C all\n" + s += " sage --docbuild constructions pdf\n" + s += " sage --docbuild reference html -jv3\n" + s += " sage --docbuild reference print_unincluded_modules\n" + s += " sage --docbuild developer html --sphinx-opts='-q,-aE' --verbose 2" + return s + + +def help_documents(): + """ + Append and return a tabular list of documents, including a + shortcut 'all' for all documents, available to the Sage + documentation builder. + """ + docs = get_documents() + s = "DOCUMENTs:\n" + s += format_columns(docs) + s += "\n" + if 'reference' in docs: + s += "Other valid document names take the form 'reference/DIR', where\n" + s += "DIR is a subdirectory of SAGE_DOC_SRC/en/reference/.\n" + s += "This builds just the specified part of the reference manual.\n" + s += "DOCUMENT may also have the form 'file=/path/to/FILE', which builds\n" + s += "the documentation for the specified file.\n" + return s + + +def get_formats(): + """ + Return a list of output formats the Sage documentation builder + will accept on the command-line. + """ + tut_b = DocBuilder('en/tutorial') + formats = tut_b._output_formats() + formats.remove('html') + return ['html', 'pdf'] + formats + + +def help_formats(): + """ + Append and return a tabular list of output formats available to + the Sage documentation builder. + """ + return "FORMATs:\n" + format_columns(get_formats()) + + +def help_commands(name='all'): + """ + Append and return a tabular list of commands, if any, the Sage + documentation builder can run on the indicated document. The + default is to list all commands for all documents. + """ + # To do: Generate the lists dynamically, using class attributes, + # as with the Builders above. + s = "" + command_dict = {'reference': [ + 'print_included_modules', 'print_modified_modules (*)', + 'print_unincluded_modules', 'print_new_and_updated_modules (*)']} + for doc in command_dict: + if name == 'all' or doc == name: + s += "COMMANDs for the DOCUMENT '" + doc + "':\n" + s += format_columns(command_dict[doc]) + s += "(*) Since the last build.\n" + return s + + +class help_message_long(argparse.Action): + """ + Print an extended help message for the Sage documentation builder + and exits. + """ + def __call__(self, parser, namespace, values, option_string=None): + help_funcs = [help_usage, help_description, help_documents, + help_formats, help_commands] + for f in help_funcs: + print(f()) + parser.print_help() + print(help_examples()) + sys.exit(0) + + +class help_message_short(argparse.Action): + """ + Print a help message for the Sage documentation builder. + + The message includes command-line usage and a list of options. + The message is printed only on the first call. If error is True + during this call, the message is printed only if the user hasn't + requested a list (e.g., documents, formats, commands). + """ + def __call__(self, parser, namespace, values, option_string=None): + if not hasattr(namespace, 'printed_help'): + parser.print_help() + setattr(namespace, 'printed_help', 1) + sys.exit(0) + + +class help_wrapper(argparse.Action): + """ + A helper wrapper for command-line options to the Sage + documentation builder that print lists, such as document names, + formats, and document-specific commands. + """ + def __call__(self, parser, namespace, values, option_string=None): + if option_string in ['-D', '--documents']: + print(help_documents(), end="") + if option_string in ['-F', '--formats']: + print(help_formats(), end="") + if self.dest == 'commands': + print(help_commands(values), end="") + if self.dest == 'all_documents': + if values == 'reference': + b = ReferenceBuilder('reference') + refdir = os.path.join(os.environ['SAGE_DOC_SRC'], 'en', b.name) + s = b.get_all_documents(refdir) + # Put the bibliography first, because it needs to be built first: + s.remove('reference/references') + s.insert(0, 'reference/references') + elif values == 'all': + s = get_documents() + # Put the reference manual first, because it needs to be built first: + s.remove('reference') + s.insert(0, 'reference') + for d in s: + print(d) + setattr(namespace, 'printed_list', 1) + sys.exit(0) + + +def setup_parser(): + """ + Set up and return a command-line ArgumentParser instance for the + Sage documentation builder. + """ + # Documentation: https://docs.python.org/library/argparse.html + parser = argparse.ArgumentParser(usage=help_usage(compact=True), + description=help_description(compact=True), + add_help=False) + # Standard options. Note: We use explicit option.dest names + # to avoid ambiguity. + standard = parser.add_argument_group("Standard") + standard.add_argument("-h", "--help", nargs=0, action=help_message_short, + help="show a help message and exit") + standard.add_argument("-H", "--help-all", nargs=0, action=help_message_long, + help="show an extended help message and exit") + standard.add_argument("-D", "--documents", nargs=0, action=help_wrapper, + help="list all available DOCUMENTs") + standard.add_argument("-F", "--formats", nargs=0, action=help_wrapper, + help="list all output FORMATs") + standard.add_argument("-C", "--commands", dest="commands", + type=str, metavar="DOC", action=help_wrapper, + help="list all COMMANDs for DOCUMENT DOC; use 'all' to list all") + standard.add_argument("-i", "--inherited", dest="inherited", + action="store_true", + help="include inherited members in reference manual; may be slow, may fail for PDF output") + standard.add_argument("-u", "--underscore", dest="underscore", + action="store_true", + help="include variables prefixed with '_' in reference manual; may be slow, may fail for PDF output") + standard.add_argument("-j", "--mathjax", "--jsmath", dest="mathjax", + action="store_true", + help="ignored for backwards compatibility") + standard.add_argument("--no-plot", dest="no_plot", + action="store_true", + help="do not include graphics auto-generated using the '.. plot' markup") + standard.add_argument("--include-tests-blocks", dest="skip_tests", default=True, + action="store_false", + help="include TESTS blocks in the reference manual") + standard.add_argument("--no-pdf-links", dest="no_pdf_links", + action="store_true", + help="do not include PDF links in DOCUMENT 'website'; FORMATs: html, json, pickle, web") + standard.add_argument("--warn-links", dest="warn_links", + action="store_true", + help="issue a warning whenever a link is not properly resolved; equivalent to '--sphinx-opts -n' (sphinx option: nitpicky)") + standard.add_argument("--check-nested", dest="check_nested", + action="store_true", + help="check picklability of nested classes in DOCUMENT 'reference'") + standard.add_argument("--no-prune-empty-dirs", dest="no_prune_empty_dirs", + action="store_true", + help="do not prune empty directories in the documentation sources") + standard.add_argument("-N", "--no-colors", dest="color", + action="store_false", + help="do not color output; does not affect children") + standard.add_argument("-q", "--quiet", dest="verbose", + action="store_const", const=0, + help="work quietly; same as --verbose=0") + standard.add_argument("-v", "--verbose", dest="verbose", + type=int, default=1, metavar="LEVEL", + action="store", + help="report progress at LEVEL=0 (quiet), 1 (normal), 2 (info), or 3 (debug); does not affect children") + standard.add_argument("-o", "--output", dest="output_dir", default=None, + metavar="DIR", action="store", + help="if DOCUMENT is a single file ('file=...'), write output to this directory") + + # Advanced options. + advanced = parser.add_argument_group("Advanced", + "Use these options with care.") + advanced.add_argument("-S", "--sphinx-opts", dest="sphinx_opts", + type=str, metavar="OPTS", + action="store", + help="pass comma-separated OPTS to sphinx-build; must precede OPTS with '=', as in '-S=-q,-aE' or '-S=\"-q,-aE\"'") + advanced.add_argument("-U", "--update-mtimes", dest="update_mtimes", + action="store_true", + help="before building reference manual, update modification times for auto-generated reST files") + advanced.add_argument("-k", "--keep-going", dest="keep_going", + action="store_true", + help="Do not abort on errors but continue as much as possible after an error") + advanced.add_argument("--all-documents", dest="all_documents", + type=str, metavar="ARG", + choices=['all', 'reference'], + action=help_wrapper, + help="if ARG is 'reference', list all subdocuments" + " of en/reference. If ARG is 'all', list all main" + " documents") + parser.add_argument("document", nargs='?', type=str, metavar="DOCUMENT", + help="name of the document to build. It can be either one of the documents listed by -D or 'file=/path/to/FILE' to build documentation for this specific file.") + parser.add_argument("format", nargs='?', type=str, + metavar="FORMAT or COMMAND", help='document output format (or command)') + return parser + + +def setup_logger(verbose=1, color=True): + r""" + Set up a Python Logger instance for the Sage documentation builder. + + The optional argument sets logger's level and message format. + + EXAMPLES:: + + sage: from sage_docbuild.__main__ import setup_logger, logger + sage: setup_logger() + sage: type(logger) + + """ + # Set up colors. Adapted from sphinx.cmdline. + import sphinx.util.console as c + if not color or not sys.stdout.isatty() or not c.color_terminal(): + c.nocolor() + + # Available colors: black, darkgray, (dark)red, dark(green), + # brown, yellow, (dark)blue, purple, fuchsia, turquoise, teal, + # lightgray, white. Available styles: reset, bold, faint, + # standout, underline, blink. + + # Set up log record formats. + format_std = "%(message)s" + formatter = logging.Formatter(format_std) + + # format_debug = "%(module)s #%(lineno)s %(funcName)s() %(message)s" + fields = ['%(module)s', '#%(lineno)s', '%(funcName)s()', '%(message)s'] + colors = ['darkblue', 'darkred', 'brown', 'reset'] + styles = ['reset', 'reset', 'reset', 'reset'] + format_debug = "" + for i in range(len(fields)): + format_debug += c.colorize(styles[i], c.colorize(colors[i], fields[i])) + if i != len(fields): + format_debug += " " + + # Note: There's also Handler.setLevel(). The argument is the + # lowest severity message that the respective logger or handler + # will pass on. The default levels are DEBUG, INFO, WARNING, + # ERROR, and CRITICAL. We use "WARNING" for normal verbosity and + # "ERROR" for quiet operation. It's possible to define custom + # levels. See the documentation for details. + if verbose == 0: + logger.setLevel(logging.ERROR) + if verbose == 1: + logger.setLevel(logging.WARNING) + if verbose == 2: + logger.setLevel(logging.INFO) + if verbose == 3: + logger.setLevel(logging.DEBUG) + formatter = logging.Formatter(format_debug) + + handler = logging.StreamHandler() + handler.setFormatter(formatter) + logger.addHandler(handler) + + +class IntersphinxCache: + """ + Replace sphinx.ext.intersphinx.fetch_inventory by an in-memory + cached version. + """ + def __init__(self): + self.inventories = {} + self.real_fetch_inventory = sphinx.ext.intersphinx.fetch_inventory + sphinx.ext.intersphinx.fetch_inventory = self.fetch_inventory + + def fetch_inventory(self, app, uri, inv): + """ + Return the result of ``sphinx.ext.intersphinx.fetch_inventory()`` + from a cache if possible. Otherwise, call + ``sphinx.ext.intersphinx.fetch_inventory()`` and cache the result. + """ + t = (uri, inv) + try: + return self.inventories[t] + except KeyError: + i = self.real_fetch_inventory(app, uri, inv) + self.inventories[t] = i + return i + + +def main(): + # Parse the command-line. + parser = setup_parser() + args = parser.parse_args() + DocBuilder._options = args + + # Get the name and type (target format) of the document we are + # trying to build. + name, typ = args.document, args.format + if not name or not typ: + parser.print_help() + sys.exit(1) + + # Set up module-wide logging. + setup_logger(args.verbose, args.color) + + def excepthook(*exc_info): + logger.error('Error building the documentation.', exc_info=exc_info) + if INCREMENTAL_BUILD: + logger.error(''' + Note: incremental documentation builds sometimes cause spurious + error messages. To be certain that these are real errors, run + "make doc-clean doc-uninstall" first and try again.''') + + sys.excepthook = excepthook + + # Process selected options. + if args.check_nested: + os.environ['SAGE_CHECK_NESTED'] = 'True' + + if args.underscore: + os.environ['SAGE_DOC_UNDERSCORE'] = "True" + + global ALLSPHINXOPTS, WEBSITESPHINXOPTS, ABORT_ON_ERROR + if args.sphinx_opts: + ALLSPHINXOPTS += args.sphinx_opts.replace(',', ' ') + " " + if args.no_pdf_links: + WEBSITESPHINXOPTS = " -A hide_pdf_links=1 " + if args.warn_links: + ALLSPHINXOPTS += "-n " + if args.no_plot: + os.environ['SAGE_SKIP_PLOT_DIRECTIVE'] = 'yes' + if args.skip_tests: + os.environ['SAGE_SKIP_TESTS_BLOCKS'] = 'True' + + ABORT_ON_ERROR = not args.keep_going + + if not args.no_prune_empty_dirs: + # Delete empty directories. This is needed in particular for empty + # directories due to "git checkout" which never deletes empty + # directories it leaves behind. See Trac #20010. + # Trac #31948: This is not parallelization-safe; use the option + # --no-prune-empty-dirs to turn it off + for dirpath, dirnames, filenames in os.walk(SAGE_DOC_SRC, topdown=False): + if not dirnames + filenames: + logger.warning('Deleting empty directory {0}'.format(dirpath)) + os.rmdir(dirpath) + + # Set up Intersphinx cache + _ = IntersphinxCache() + + builder = getattr(get_builder(name), typ) + builder() + +if __name__ == '__main__': + sys.exit(main()) diff --git a/src/sage_docbuild/build_options.py b/src/sage_docbuild/build_options.py index 50bac1737b7..4857c1ed125 100644 --- a/src/sage_docbuild/build_options.py +++ b/src/sage_docbuild/build_options.py @@ -1,6 +1,9 @@ -############################################### -# Options for building the Sage documentation # -############################################### +r""" +Build options + +This module defines options for building Sage documentation. +""" + import os import re diff --git a/src/sage_docbuild/builders.py b/src/sage_docbuild/builders.py new file mode 100644 index 00000000000..672a2bf00fe --- /dev/null +++ b/src/sage_docbuild/builders.py @@ -0,0 +1,1358 @@ +""" +Documentation builders + +This module is the starting point for building documentation, and is +responsible to figure out what to build and with which options. The +actual documentation build for each individual document is then done +in a subprocess call to Sphinx, see :func:`builder_helper`. Note that + +* The builder can be configured in ``build_options.py``; +* The Sphinx subprocesses are configured in ``conf.py``. + +:class:`DocBuilder` is the base class of all Builders. It has builder helpers +:meth:`html()`, :meth:`latex`, :meth:`pdf`, :meth:`inventory`, etc, which are +invoked depending on the output type. Each type corresponds with the Sphinx +builder format, except that ``pdf`` is latex Sphinx builder plus compiling +latex to pdf. Note that ``inventory`` Sphinx builder is not native to Sphinx +but provided by Sage. See ``sage_docbuild/ext/inventory_builder.py``. The +Sphinx inventory builder is the html builder with no actual output but produces +doctree files in ``local/share/doctree`` and ``inventory.inv`` inventory files +in ``local/share/inventory``. + +The reference manual is built in two passes, first by :class:`ReferenceBuilder` +with format ``inventory`` and secondly with format ``html``. The +:class:`ReferenceBuilder` itself uses :class:`ReferenceTopBuilder` and +:class:`ReferenceSubBuilder` to build subcomponents of the reference manual. +The :class:`ReferenceSubBuilder` examines modules of the Sage library by +comparing the modification times of the module files with the times saved in +``local/share/doctree/reference.pickle`` from the previous build. New rst +files are autogenerated for new and updated modules. See +:meth:`get_new_and_updated_modules()`. + +After :trac:`31948`, when Sage is built, :class:`ReferenceBuilder` is not used +and its responsibility is now taken by the ``Makefile`` in ``$SAGE_ROOT/src/doc``. +""" +# **************************************************************************** +# Copyright (C) 2008-2009 Mike Hansen +# 2009-2010 Mitesh Patel +# 2009-2015 J. H. Palmieri +# 2009 Carl Witty +# 2010-2017 Jeroen Demeyer +# 2012 William Stein +# 2012-2014 Nicolas M. Thiery +# 2012-2015 André Apitzsch +# 2012 Florent Hivert +# 2013-2014 Volker Braun +# 2013 R. Andrew Ohana +# 2015 Thierry Monteil +# 2015 Marc Mezzarobba +# 2015 Travis Scrimshaw +# 2016-2017 Frédéric Chapoton +# 2016 Erik M. Bray +# 2017 Kwankyu Lee +# 2017 François Bissey +# 2018 Julian Rüth +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# https://www.gnu.org/licenses/ +# **************************************************************************** +import logging +import os +import pickle +import re +import shutil +import subprocess +import sys +import time +import types +import warnings + +import sage.all +from sage.misc.cachefunc import cached_method +# Do not import SAGE_DOC globally as it interferes with doctesting with a random replacement +from sage.env import SAGE_DOC_SRC, SAGE_SRC, DOT_SAGE + +from .build_options import (LANGUAGES, OMIT, + ALLSPHINXOPTS, NUM_THREADS, WEBSITESPHINXOPTS, + ABORT_ON_ERROR) + +from .utils import build_many as _build_many + +logger = logging.getLogger(__name__) + + +########################################## +# Parallel Building Ref Manual # +########################################## + +def build_ref_doc(args): + doc = args[0] + lang = args[1] + format = args[2] + kwds = args[3] + args = args[4:] + if format == 'inventory': # you must not use the inventory to build the inventory + kwds['use_multidoc_inventory'] = False + getattr(ReferenceSubBuilder(doc, lang), format)(*args, **kwds) + + +########################################## +# Builders # +########################################## + +def builder_helper(type): + """ + Return a function which builds the documentation for + output type ``type``. + + TESTS: + + Check that :trac:`25161` has been resolved:: + + sage: from sage_docbuild.builders import DocBuilder + sage: from sage_docbuild.__main__ import setup_parser + sage: DocBuilder._options = setup_parser().parse_args([]) # builder_helper needs _options to be set + + sage: import sage_docbuild.sphinxbuild + sage: def raiseBaseException(): + ....: raise BaseException("abort pool operation") + sage: original_runsphinx, sage_docbuild.sphinxbuild.runsphinx = sage_docbuild.sphinxbuild.runsphinx, raiseBaseException + + sage: from sage.misc.temporary_file import tmp_dir + sage: os.environ['SAGE_DOC'] = tmp_dir() + sage: sage.env.var('SAGE_DOC') # random + sage: from sage_docbuild.builders import builder_helper, build_ref_doc + sage: from sage_docbuild.builders import _build_many as build_many + sage: helper = builder_helper("html") + sage: try: # optional - sagemath_doc_html + ....: build_many(build_ref_doc, [("docname", "en", "html", {})]) + ....: except Exception as E: + ....: "Non-exception during docbuild: abort pool operation" in str(E) + True + """ + def f(self, *args, **kwds): + output_dir = self._output_dir(type) + + options = ALLSPHINXOPTS + + if self.name == 'website': + # WEBSITESPHINXOPTS is either empty or " -A hide_pdf_links=1 " + options += WEBSITESPHINXOPTS + + if kwds.get('use_multidoc_inventory', True) and type != 'inventory': + options += ' -D multidoc_first_pass=0' + else: + options += ' -D multidoc_first_pass=1' + + + build_command = '-b %s -d %s %s %s %s' % (type, self._doctrees_dir(), + options, self.dir, + output_dir) + + # Provide "pdf" tag to be used with "only" directive as an alias of "latex" + if type == 'latex': + build_command = '-t pdf ' + build_command + + logger.debug(build_command) + + # Run Sphinx with Sage's special logger + sys.argv = ["sphinx-build"] + build_command.split() + from .sphinxbuild import runsphinx + try: + runsphinx() + except Exception: + if ABORT_ON_ERROR: + raise + except BaseException as e: + # We need to wrap a BaseException that is not an Exception in a + # regular Exception. Otherwise multiprocessing.Pool.get hangs, see + # #25161 + if ABORT_ON_ERROR: + raise Exception("Non-exception during docbuild: %s" % (e,), e) + + if "/latex" in output_dir: + logger.warning("LaTeX file written to {}".format(output_dir)) + else: + logger.warning( + "Build finished. The built documents can be found in {}". + format(output_dir)) + + f.is_output_format = True + return f + + +class DocBuilder(object): + def __init__(self, name, lang='en'): + """ + INPUT: + + - ``name`` - the name of a subdirectory in SAGE_DOC_SRC, such as + 'tutorial' or 'bordeaux_2008' + + - ``lang`` - (default "en") the language of the document. + """ + doc = name.split(os.path.sep) + + if doc[0] in LANGUAGES: + lang = doc[0] + doc.pop(0) + + self.name = os.path.join(*doc) + self.lang = lang + self.dir = os.path.join(SAGE_DOC_SRC, self.lang, self.name) + + def _output_dir(self, type): + """ + Return the directory where the output of type ``type`` is stored. + + If the directory does not exist, then it will automatically be + created. + + EXAMPLES:: + + sage: from sage_docbuild.builders import DocBuilder + sage: b = DocBuilder('tutorial') + sage: b._output_dir('html') # optional - sagemath_doc_html + '.../html/en/tutorial' + """ + from sage.env import SAGE_DOC + d = os.path.join(SAGE_DOC, type, self.lang, self.name) + os.makedirs(d, exist_ok=True) + return d + + def _doctrees_dir(self): + """ + Return the directory where the doctrees are stored. + + If the directory does not exist, then it will automatically be + created. + + EXAMPLES:: + + sage: from sage_docbuild.builders import DocBuilder + sage: b = DocBuilder('tutorial') + sage: b._doctrees_dir() # optional - sagemath_doc_html + '.../doctrees/en/tutorial' + """ + from sage.env import SAGE_DOC + d = os.path.join(SAGE_DOC, 'doctrees', self.lang, self.name) + os.makedirs(d, exist_ok=True) + return d + + def _output_formats(self): + """ + Return a list of the possible output formats. + + EXAMPLES:: + + sage: from sage_docbuild.builders import DocBuilder + sage: b = DocBuilder('tutorial') + sage: b._output_formats() + ['changes', 'html', 'htmlhelp', 'inventory', 'json', 'latex', 'linkcheck', 'pickle', 'web'] + """ + # Go through all the attributes of self and check to + # see which ones have an 'is_output_format' attribute. These + # are the ones created with builder_helper. + output_formats = [] + for attr in dir(self): + if hasattr(getattr(self, attr), 'is_output_format'): + output_formats.append(attr) + output_formats.sort() + return output_formats + + def pdf(self): + """ + Build the PDF files for this document. + + This is done by first (re)-building the LaTeX output, going + into that LaTeX directory, and running 'make all-pdf' there. + + EXAMPLES:: + + sage: from sage_docbuild.builders import DocBuilder + sage: b = DocBuilder('tutorial') + sage: b.pdf() #not tested + """ + self.latex() + tex_dir = self._output_dir('latex') + pdf_dir = self._output_dir('pdf') + + if self.name == 'reference': + # recover maths in tex, undoing what Sphinx did (trac #29993) + tex_file = os.path.join(tex_dir, 'reference.tex') + with open(tex_file) as f: + ref = f.read() + ref = re.sub(r'\\textbackslash{}', r'\\', ref) + ref = re.sub(r'\\textbackslash{}', r'\\', ref) + ref = re.sub(r'\\{', r'{', ref) + ref = re.sub(r'\\}', r'}', ref) + ref = re.sub(r'\\_', r'_', ref) + ref = re.sub(r'\\textasciicircum{}', r'^', ref) + with open(tex_file, 'w') as f: + f.write(ref) + + make_target = "cd '%s' && $MAKE %s && mv -f *.pdf '%s'" + error_message = "failed to run $MAKE %s in %s" + command = 'all-pdf' + + if subprocess.call(make_target % (tex_dir, command, pdf_dir), close_fds=False, shell=True): + raise RuntimeError(error_message % (command, tex_dir)) + logger.warning("Build finished. The built documents can be found in %s", pdf_dir) + + def clean(self, *args): + shutil.rmtree(self._doctrees_dir()) + output_formats = list(args) if args else self._output_formats() + for format in output_formats: + shutil.rmtree(self._output_dir(format), ignore_errors=True) + + html = builder_helper('html') + pickle = builder_helper('pickle') + web = pickle + json = builder_helper('json') + htmlhelp = builder_helper('htmlhelp') + latex = builder_helper('latex') + changes = builder_helper('changes') + linkcheck = builder_helper('linkcheck') + # import the customized builder for object.inv files + inventory = builder_helper('inventory') + + +def build_many(target, args, processes=None): + """ + Thin wrapper around `sage_docbuild.utils.build_many` which uses the + docbuild settings ``NUM_THREADS`` and ``ABORT_ON_ERROR``. + """ + if processes is None: + processes = NUM_THREADS + try: + _build_many(target, args, processes=processes) + except BaseException: + if ABORT_ON_ERROR: + raise + + +########################################## +# Parallel Building Ref Manual # +########################################## + +def build_other_doc(args): + document = args[0] + name = args[1] + kwds = args[2] + args = args[3:] + logger.warning("\nBuilding %s.\n" % document) + getattr(get_builder(document), name)(*args, **kwds) + + +class AllBuilder(object): + """ + A class used to build all of the documentation. + """ + def __getattr__(self, attr): + """ + For any attributes not explicitly defined, we just go through + all of the documents and call their attr. For example, + 'AllBuilder().json()' will go through all of the documents + and call the json() method on their builders. + """ + from functools import partial + return partial(self._wrapper, attr) + + def _wrapper(self, name, *args, **kwds): + """ + This is the function which goes through all of the documents + and does the actual building. + """ + start = time.time() + docs = self.get_all_documents() + refs = [x for x in docs if x.endswith('reference')] + others = [x for x in docs if not x.endswith('reference')] + + # Build the reference manual twice to resolve references. That is, + # build once with the inventory builder to construct the intersphinx + # inventory files, and then build the second time for real. So the + # first build should be as fast as possible; + logger.warning("\nBuilding reference manual, first pass.\n") + for document in refs: + getattr(get_builder(document), 'inventory')(*args, **kwds) + + from sage.env import SAGE_DOC + logger.warning("Building reference manual, second pass.\n") + os.makedirs(os.path.join(SAGE_DOC, "html", "en", "reference", "_static"), exist_ok=True) + for document in refs: + getattr(get_builder(document), name)(*args, **kwds) + + # build the other documents in parallel + L = [(doc, name, kwds) + args for doc in others] + + # Trac #31344: Work around crashes from multiprocessing + if sys.platform == 'darwin': + for target in L: + build_other_doc(target) + else: + build_many(build_other_doc, L) + logger.warning("Elapsed time: %.1f seconds." % (time.time() - start)) + logger.warning("Done building the documentation!") + + def get_all_documents(self): + """ + Return a list of all of the documents. + + A document is a directory within one of the language + subdirectories of SAGE_DOC_SRC specified by the global + LANGUAGES variable. + + EXAMPLES:: + + sage: from sage_docbuild.builders import AllBuilder + sage: documents = AllBuilder().get_all_documents() + sage: 'en/tutorial' in documents # optional - sage_spkg + True + sage: documents[0] == 'en/reference' + True + """ + documents = [] + for lang in LANGUAGES: + for document in os.listdir(os.path.join(SAGE_DOC_SRC, lang)): + if (document not in OMIT + and os.path.isdir(os.path.join(SAGE_DOC_SRC, lang, document))): + documents.append(os.path.join(lang, document)) + + # Ensure that the reference guide is compiled first so that links from + # the other documents to it are correctly resolved. + if 'en/reference' in documents: + documents.remove('en/reference') + documents.insert(0, 'en/reference') + + return documents + + +class WebsiteBuilder(DocBuilder): + def html(self): + """ + After we have finished building the website index page, we copy + everything one directory up. + + In addition, an index file is installed into the root doc directory. + """ + DocBuilder.html(self) + html_output_dir = self._output_dir('html') + for f in os.listdir(html_output_dir): + src = os.path.join(html_output_dir, f) + dst = os.path.join(html_output_dir, '..', f) + if os.path.isdir(src): + shutil.rmtree(dst, ignore_errors=True) + shutil.copytree(src, dst) + else: + shutil.copy2(src, dst) + + root_index_file = os.path.join(html_output_dir, '../../../index.html') + shutil.copy2(os.path.join(SAGE_DOC_SRC, self.lang, 'website', 'root_index.html'), + root_index_file) + + def clean(self): + """ + When we clean the output for the website index, we need to + remove all of the HTML that were placed in the parent + directory. + + In addition, remove the index file installed into the root doc directory. + """ + html_output_dir = self._output_dir('html') + parent_dir = os.path.realpath(os.path.join(html_output_dir, '..')) + for filename in os.listdir(html_output_dir): + parent_filename = os.path.join(parent_dir, filename) + if not os.path.exists(parent_filename): + continue + if os.path.isdir(parent_filename): + shutil.rmtree(parent_filename, ignore_errors=True) + else: + os.unlink(parent_filename) + + root_index_file = os.path.join(html_output_dir, '../../../index.html') + if os.path.exists(root_index_file): + os.remove(root_index_file) + + DocBuilder.clean(self) + + +class ReferenceBuilder(AllBuilder): + """ + This class builds the reference manual. It uses DocBuilder to + build the top-level page and ReferenceSubBuilder for each + sub-component. + """ + def __init__(self, name, lang='en'): + """ + Record the reference manual's name, in case it's not + identical to 'reference'. + """ + AllBuilder.__init__(self) + doc = name.split(os.path.sep) + + if doc[0] in LANGUAGES: + lang = doc[0] + doc.pop(0) + + self.name = doc[0] + self.lang = lang + + def _output_dir(self, type, lang=None): + """ + Return the directory where the output of type ``type`` is stored. + + If the directory does not exist, then it will automatically be + created. + + EXAMPLES:: + + sage: from sage_docbuild.builders import ReferenceBuilder + sage: b = ReferenceBuilder('reference') + sage: b._output_dir('html') # optional - sagemath_doc_html + '.../html/en/reference' + """ + from sage.env import SAGE_DOC + if lang is None: + lang = self.lang + d = os.path.join(SAGE_DOC, type, lang, self.name) + os.makedirs(d, exist_ok=True) + return d + + def _refdir(self): + return os.path.join(SAGE_DOC_SRC, self.lang, self.name) + + def _build_bibliography(self, format, *args, **kwds): + """ + Build the bibliography only + + The bibliography references.aux is referenced by the other + manuals and needs to be built first. + """ + refdir = self._refdir() + references = [ + (doc, self.lang, format, kwds) + args for doc in self.get_all_documents(refdir) + if doc == 'reference/references' + ] + build_many(build_ref_doc, references) + + def _build_everything_except_bibliography(self, format, *args, **kwds): + """ + Build the entire reference manual except the bibliography + """ + refdir = self._refdir() + non_references = [ + (doc, self.lang, format, kwds) + args for doc in self.get_all_documents(refdir) + if doc != 'reference/references' + ] + build_many(build_ref_doc, non_references) + + def _build_top_level(self, format, *args, **kwds): + """ + Build top-level document. + """ + getattr(ReferenceTopBuilder('reference'), format)(*args, **kwds) + + def _wrapper(self, format, *args, **kwds): + """ + Build reference manuals: build the + top-level document and its components. + """ + logger.info('Building bibliography') + self._build_bibliography(format, *args, **kwds) + logger.info('Bibliography finished, building dependent manuals') + self._build_everything_except_bibliography(format, *args, **kwds) + # The html refman must be build at the end to ensure correct + # merging of indexes and inventories. + # Sphinx is run here in the current process (not in a + # subprocess) and the IntersphinxCache gets populated to be + # used for the second pass of the reference manual and for + # the other documents. + self._build_top_level(format, *args, **kwds) + + def get_all_documents(self, refdir): + """ + Return a list of all reference manual components to build. + + We add a component name if it's a subdirectory of the manual's + directory and contains a file named 'index.rst'. + + We return the largest component (most subdirectory entries) + first since they will take the longest to build. + + EXAMPLES:: + + sage: from sage_docbuild.builders import ReferenceBuilder + sage: b = ReferenceBuilder('reference') + sage: refdir = os.path.join(os.environ['SAGE_DOC_SRC'], 'en', b.name) # optional - sage_spkg + sage: sorted(b.get_all_documents(refdir)) # optional - sage_spkg + ['reference/algebras', + 'reference/arithgroup', + ..., + 'reference/valuations'] + """ + documents = [] + + for doc in os.listdir(refdir): + directory = os.path.join(refdir, doc) + if os.path.exists(os.path.join(directory, 'index.rst')): + n = len(os.listdir(directory)) + documents.append((-n, os.path.join(self.name, doc))) + + return [doc[1] for doc in sorted(documents)] + + +class ReferenceTopBuilder(DocBuilder): + """ + This class builds the top-level page of the reference manual. + """ + def __init__(self, *args, **kwds): + DocBuilder.__init__(self, *args, **kwds) + self.name = 'reference' + self.lang = 'en' + + def _output_dir(self, type, lang=None): + """ + Return the directory where the output of type ``type`` is stored. + + If the directory does not exist, then it will automatically be + created. + + EXAMPLES:: + + sage: from sage_docbuild.builders import ReferenceTopBuilder + sage: b = ReferenceTopBuilder('reference') + sage: b._output_dir('html') # optional - sagemath_doc_html + '.../html/en/reference' + """ + from sage.env import SAGE_DOC + if lang is None: + lang = self.lang + d = os.path.join(SAGE_DOC, type, lang, self.name) + os.makedirs(d, exist_ok=True) + return d + + def pdf(self): + """ + Build top-level document. + """ + super().pdf() + + # we need to build master index file which lists all + # of the PDF file. So we create an html file, based on + # the file index.html from the "reference_top" target. + + # First build the top reference page. This only takes a few seconds. + getattr(get_builder('reference_top'), 'html')() + + from sage.env import SAGE_DOC + reference_dir = os.path.join(SAGE_DOC, 'html', 'en', 'reference') + output_dir = self._output_dir('pdf') + + # Install in output_dir a symlink to the directory containing static files. + # Prefer relative path for symlinks. + relpath = os.path.relpath(reference_dir, output_dir) + try: + os.symlink(os.path.join(relpath, '_static'), os.path.join(output_dir, '_static')) + except FileExistsError: + pass + + # Now modify top reference index.html page and write it to output_dir. + with open(os.path.join(reference_dir, 'index.html')) as f: + html = f.read() + html_output_dir = os.path.dirname(reference_dir) + + # Fix links in navigation bar + html = re.sub(r'Sage(.*)Documentation', + r'Sage\2Documentation', + html) + html = re.sub(r'Reference Manual', + r'Reference Manual (PDF version)', + html) + html = re.sub(r'
    • ', r'
    • ; change rst headers to html headers + rst_toc = re.sub(r'\*(.*)\n', + r'
    • \1
    • \n', rst_toc) + rst_toc = re.sub(r'\n([A-Z][a-zA-Z, ]*)\n[=]*\n', + r'
    \n\n\n

    \1

    \n\n
      \n', rst_toc) + rst_toc = re.sub(r'\n([A-Z][a-zA-Z, ]*)\n[-]*\n', + r'
    \n\n\n

    \1

    \n\n
      \n', rst_toc) + # now write the file. + with open(os.path.join(output_dir, 'index.html'), 'w') as new_index: + new_index.write(html[:html_end_preamble]) + new_index.write('

      Sage Reference Manual (PDF version)

      ') + new_index.write(rst_body) + new_index.write('
        ') + new_index.write(rst_toc) + new_index.write('
      \n\n') + new_index.write(html[html_bottom:]) + logger.warning(''' +PDF documents have been created in subdirectories of + + %s + +Alternatively, you can open + + %s + +for a webpage listing all of the documents.''' % (output_dir, + os.path.join(output_dir, + 'index.html'))) + + +class ReferenceSubBuilder(DocBuilder): + """ + This class builds sub-components of the reference manual. It is + responsible for making sure that the auto generated reST files for the + Sage library are up to date. + + When building any output, we must first go through and check + to see if we need to update any of the autogenerated reST + files. There are two cases where this would happen: + + 1. A new module gets added to one of the toctrees. + + 2. The actual module gets updated and possibly contains a new + title. + """ + def __init__(self, *args, **kwds): + DocBuilder.__init__(self, *args, **kwds) + self._wrap_builder_helpers() + + def _wrap_builder_helpers(self): + from functools import partial, update_wrapper + for attr in dir(self): + if hasattr(getattr(self, attr), 'is_output_format'): + f = partial(self._wrapper, attr) + f.is_output_format = True + update_wrapper(f, getattr(self, attr)) + setattr(self, attr, f) + + def _wrapper(self, build_type, *args, **kwds): + """ + This is the wrapper around the builder_helper methods that + goes through and makes sure things are up to date. + """ + # Force regeneration of all modules if the inherited + # and/or underscored members options have changed. + cache = self.get_cache() + force = False + try: + if (cache['option_inherited'] != self._options.inherited or + cache['option_underscore'] != self._options.underscore): + logger.info("Detected change(s) in inherited and/or underscored members option(s).") + force = True + except KeyError: + force = True + cache['option_inherited'] = self._options.inherited + cache['option_underscore'] = self._options.underscore + self.save_cache() + + # After "sage -clone", refresh the reST file mtimes in + # environment.pickle. + if self._options.update_mtimes: + logger.info("Checking for reST file mtimes to update...") + self.update_mtimes() + + if force: + # Write reST files for all modules from scratch. + self.clean_auto() + for module_name in self.get_all_included_modules(): + self.write_auto_rest_file(module_name) + else: + # Write reST files for new and updated modules. + for module_name in self.get_new_and_updated_modules(): + self.write_auto_rest_file(module_name) + + # Copy over the custom reST files from _sage + _sage = os.path.join(self.dir, '_sage') + if os.path.exists(_sage): + logger.info("Copying over custom reST files from %s ...", _sage) + shutil.copytree(_sage, os.path.join(self.dir, 'sage')) + + getattr(DocBuilder, build_type)(self, *args, **kwds) + + def cache_filename(self): + """ + Return the filename where the pickle of the reference cache + is stored. + """ + return os.path.join(self._doctrees_dir(), 'reference.pickle') + + @cached_method + def get_cache(self): + """ + Retrieve the reference cache which contains the options previously used + by the reference builder. + + If it doesn't exist, then we just return an empty dictionary. If it + is corrupted, return an empty dictionary. + """ + filename = self.cache_filename() + if not os.path.exists(filename): + return {} + with open(self.cache_filename(), 'rb') as file: + try: + cache = pickle.load(file) + except Exception: + logger.debug("Cache file '%s' is corrupted; ignoring it..." % filename) + cache = {} + else: + logger.debug("Loaded the reference cache: %s", filename) + return cache + + def save_cache(self): + """ + Pickle the current reference cache for later retrieval. + """ + cache = self.get_cache() + try: + with open(self.cache_filename(), 'wb') as file: + pickle.dump(cache, file) + logger.debug("Saved the reference cache: %s", self.cache_filename()) + except PermissionError: + logger.debug("Permission denied for the reference cache: %s", self.cache_filename()) + + def get_sphinx_environment(self): + """ + Return the Sphinx environment for this project. + """ + class FakeConfig(object): + values = tuple() + + class FakeApp(object): + def __init__(self, dir): + self.srcdir = dir + self.config = FakeConfig() + + env_pickle = os.path.join(self._doctrees_dir(), 'environment.pickle') + try: + with open(env_pickle, 'rb') as f: + env = pickle.load(f) + env.app = FakeApp(self.dir) + env.config.values = env.app.config.values + logger.debug("Opened Sphinx environment: %s", env_pickle) + return env + except (IOError, EOFError) as err: + logger.debug( + f"Failed to open Sphinx environment '{env_pickle}'", exc_info=True) + + def update_mtimes(self): + """ + Update the modification times for reST files in the Sphinx + environment for this project. + """ + env = self.get_sphinx_environment() + if env is not None: + for doc in env.all_docs: + env.all_docs[doc] = time.time() + logger.info("Updated %d reST file mtimes", len(env.all_docs)) + # This is the only place we need to save (as opposed to + # load) Sphinx's pickle, so we do it right here. + env_pickle = os.path.join(self._doctrees_dir(), + 'environment.pickle') + + # When cloning a new branch (see + # SAGE_LOCAL/bin/sage-clone), we hard link the doc output. + # To avoid making unlinked, potentially inconsistent + # copies of the environment, we *don't* use + # env.topickle(env_pickle), which first writes a temporary + # file. We adapt sphinx.environment's + # BuildEnvironment.topickle: + + # remove unpicklable attributes + env.set_warnfunc(None) + del env.config.values + with open(env_pickle, 'wb') as picklefile: + # remove potentially pickling-problematic values from config + for key, val in vars(env.config).items(): + if key.startswith('_') or isinstance(val, (types.ModuleType, + types.FunctionType, + type)): + del env.config[key] + pickle.dump(env, picklefile, pickle.HIGHEST_PROTOCOL) + + logger.debug("Saved Sphinx environment: %s", env_pickle) + + def get_modified_modules(self): + """ + Return an iterator for all the modules that have been modified + since the documentation was last built. + """ + env = self.get_sphinx_environment() + if env is None: + logger.debug("Stopped check for modified modules.") + return + try: + added, changed, removed = env.get_outdated_files(False) + logger.info("Sphinx found %d modified modules", len(changed)) + except OSError as err: + logger.debug("Sphinx failed to determine modified modules: %s", err) + return + for name in changed: + # Only pay attention to files in a directory sage/... In + # particular, don't treat a file like 'sagetex.rst' in + # doc/en/reference/misc as an autogenerated file: see + # #14199. + if name.startswith('sage' + os.sep): + yield name + + def print_modified_modules(self): + """ + Print a list of all the modules that have been modified since + the documentation was last built. + """ + for module_name in self.get_modified_modules(): + print(module_name) + + def get_all_rst_files(self, exclude_sage=True): + """ + Return an iterator for all rst files which are not + autogenerated. + """ + for directory, subdirs, files in os.walk(self.dir): + if exclude_sage and directory.startswith(os.path.join(self.dir, 'sage')): + continue + for filename in files: + if not filename.endswith('.rst'): + continue + yield os.path.join(directory, filename) + + def get_all_included_modules(self): + """ + Return an iterator for all modules which are included in the + reference manual. + """ + for filename in self.get_all_rst_files(): + for module in self.get_modules(filename): + yield module + + def get_new_and_updated_modules(self): + """ + Return an iterator for all new and updated modules that appear in + the toctrees, and remove obsolete old modules. + """ + env = self.get_sphinx_environment() + if env is None: + all_docs = {} + else: + all_docs = env.all_docs + + new_modules = [] + updated_modules = [] + old_modules = [] + for module_name in self.get_all_included_modules(): + docname = module_name.replace('.', os.path.sep) + + if docname not in all_docs: + new_modules.append(module_name) + yield module_name + continue + + # get the modification timestamp of the reST doc for the module + mtime = all_docs[docname] + try: + with warnings.catch_warnings(): + # primarily intended to ignore deprecation warnings + warnings.simplefilter("ignore") + __import__(module_name) + except ImportError as err: + logger.error("Warning: Could not import %s %s", module_name, err) + raise + + module_filename = sys.modules[module_name].__file__ + if (module_filename.endswith('.pyc') or module_filename.endswith('.pyo')): + source_filename = module_filename[:-1] + if (os.path.exists(source_filename)): + module_filename = source_filename + newtime = os.path.getmtime(module_filename) + + if newtime > mtime: + updated_modules.append(module_name) + yield module_name + else: # keep good old module + old_modules.append(module_name) + + removed_modules = [] + for docname in all_docs.keys(): + if docname.startswith('sage' + os.path.sep): + module_name = docname.replace(os.path.sep, '.') + if not (module_name in old_modules or module_name in updated_modules): + try: + os.remove(os.path.join(self.dir, docname) + '.rst') + except OSError: # already removed + pass + logger.debug("Deleted auto-generated reST file {}".format(docname)) + removed_modules.append(module_name) + + logger.info("Found %d new modules", len(new_modules)) + logger.info("Found %d updated modules", len(updated_modules)) + logger.info("Removed %d obsolete modules", len(removed_modules)) + + def print_new_and_updated_modules(self): + """ + Print all the modules that appear in the toctrees that + are newly included or updated. + """ + for module_name in self.get_new_and_updated_modules(): + print(module_name) + + def get_modules(self, filename): + """ + Given a filename for a reST file, return an iterator for + all of the autogenerated reST files that it includes. + """ + # Create the regular expression used to detect an autogenerated file + auto_re = re.compile(r'^\s*(..\/)*(sage(_docbuild)?\/[\w\/]*)\s*$') + + # Read the lines + with open(filename) as f: + lines = f.readlines() + for line in lines: + match = auto_re.match(line) + if match: + yield match.group(2).replace(os.path.sep, '.') + + def get_module_docstring_title(self, module_name): + """ + Return the title of the module from its docstring. + """ + # Try to import the module + try: + __import__(module_name) + except ImportError as err: + logger.error("Warning: Could not import %s %s", module_name, err) + return "UNABLE TO IMPORT MODULE" + module = sys.modules[module_name] + + # Get the docstring + doc = module.__doc__ + if doc is None: + doc = module.doc if hasattr(module, 'doc') else "" + + # Extract the title + i = doc.find('\n') + if i != -1: + return doc[i + 1:].lstrip().splitlines()[0] + else: + return doc + + def auto_rest_filename(self, module_name): + """ + Return the name of the file associated to a given module + + EXAMPLES:: + + sage: from sage_docbuild.builders import ReferenceSubBuilder + sage: ReferenceSubBuilder("reference").auto_rest_filename("sage.combinat.partition") + '.../en/reference/sage/combinat/partition.rst' + """ + return self.dir + os.path.sep + module_name.replace('.', os.path.sep) + '.rst' + + def write_auto_rest_file(self, module_name): + """ + Write the autogenerated reST file for module_name. + """ + if not module_name.startswith('sage'): + return + filename = self.auto_rest_filename(module_name) + os.makedirs(os.path.dirname(filename), exist_ok=True) + + title = self.get_module_docstring_title(module_name) + + if title == '': + logger.error("Warning: Missing title for %s", module_name) + title = "MISSING TITLE" + + with open(filename, 'w') as outfile: + # Don't doctest the autogenerated file. + outfile.write(".. nodoctest\n\n") + # Now write the actual content. + outfile.write(".. _%s:\n\n" % (module_name.replace(".__init__", ""))) + outfile.write(title + '\n') + outfile.write('=' * len(title) + "\n\n") + outfile.write('.. This file has been autogenerated.\n\n') + + inherited = ':inherited-members:' if self._options.inherited else '' + + automodule = ''' +.. automodule:: %s + :members: + :undoc-members: + :show-inheritance: + %s + +''' + outfile.write(automodule % (module_name, inherited)) + + def clean_auto(self): + """ + Remove all autogenerated reST files. + """ + try: + shutil.rmtree(os.path.join(self.dir, 'sage')) + logger.debug("Deleted auto-generated reST files in: %s", + os.path.join(self.dir, 'sage')) + except OSError: + pass + + def get_unincluded_modules(self): + """ + Return an iterator for all the modules in the Sage library + which are not included in the reference manual. + """ + # Make a dictionary of the included modules + included_modules = {} + for module_name in self.get_all_included_modules(): + included_modules[module_name] = True + + base_path = os.path.join(SAGE_SRC, 'sage') + for directory, subdirs, files in os.walk(base_path): + for filename in files: + if not (filename.endswith('.py') or + filename.endswith('.pyx')): + continue + + path = os.path.join(directory, filename) + + # Create the module name + module_name = path[len(base_path):].replace(os.path.sep, '.') + module_name = 'sage' + module_name + module_name = module_name[:-4] if module_name.endswith('pyx') else module_name[:-3] + + # Exclude some ones -- we don't want init the manual + if module_name.endswith('__init__') or module_name.endswith('all'): + continue + + if module_name not in included_modules: + yield module_name + + def print_unincluded_modules(self): + """ + Print all of the modules which are not included in the Sage + reference manual. + """ + for module_name in self.get_unincluded_modules(): + print(module_name) + + def print_included_modules(self): + """ + Print all of the modules that are included in the Sage reference + manual. + """ + for module_name in self.get_all_included_modules(): + print(module_name) + + +class SingleFileBuilder(DocBuilder): + """ + This is the class used to build the documentation for a single + user-specified file. If the file is called 'foo.py', then the + documentation is built in ``DIR/foo/`` if the user passes the + command line option "-o DIR", or in ``DOT_SAGE/docbuild/foo/`` + otherwise. + """ + def __init__(self, path): + """ + INPUT: + + - ``path`` - the path to the file for which documentation + should be built + """ + self.lang = 'en' + self.name = 'single_file' + path = os.path.abspath(path) + + # Create docbuild and relevant subdirectories, e.g., + # the static and templates directories in the output directory. + # By default, this is DOT_SAGE/docbuild/MODULE_NAME, but can + # also be specified at the command line. + module_name = os.path.splitext(os.path.basename(path))[0] + latex_name = module_name.replace('_', r'\\_') + + if self._options.output_dir: + base_dir = os.path.join(self._options.output_dir, module_name) + if os.path.exists(base_dir): + logger.warning('Warning: Directory %s exists. It is safer to build in a new directory.' % base_dir) + else: + base_dir = os.path.join(DOT_SAGE, 'docbuild', module_name) + try: + shutil.rmtree(base_dir) + except OSError: + pass + self.dir = os.path.join(base_dir, 'source') + + os.makedirs(os.path.join(self.dir, "static"), exist_ok=True) + os.makedirs(os.path.join(self.dir, "templates"), exist_ok=True) + # Write self.dir/conf.py + conf = r"""# This file is automatically generated by {}, do not edit! + +import sys, os, contextlib +sys.path.append({!r}) + +from sage.docs.conf import * +html_static_path = [] + html_common_static_path + +project = 'Documentation for {}' +release = 'unknown' +name = {!r} +html_title = project +html_short_title = project +htmlhelp_basename = name + +with contextlib.suppress(ValueError): + extensions.remove('multidocs') # see #29651 + extensions.remove('inventory_builder') + +latex_domain_indices = False +latex_documents = [ + ('index', name + '.tex', 'Documentation for {}', + 'unknown', 'manual'), +] +""".format(__file__, self.dir, module_name, module_name, latex_name) + + if 'SAGE_DOC_UNDERSCORE' in os.environ: + conf += r""" +def setup(app): + app.connect('autodoc-skip-member', skip_member) +""" + + with open(os.path.join(self.dir, 'conf.py'), 'w') as conffile: + conffile.write(conf) + + # Write self.dir/index.rst + title = 'Docs for file %s' % path + heading = title + "\n" + ("=" * len(title)) + index = r"""{} + +.. This file is automatically generated by {}, do not edit! + +.. automodule:: {} + :members: + :undoc-members: + :show-inheritance: + +""".format(heading, __file__, module_name) + with open(os.path.join(self.dir, 'index.rst'), 'w') as indexfile: + indexfile.write(index) + + # Create link from original file to self.dir. Note that we + # append self.dir to sys.path in conf.py. This is reasonably + # safe (but not perfect), since we just created self.dir. + try: + os.symlink(path, os.path.join(self.dir, os.path.basename(path))) + except OSError: + pass + + def _output_dir(self, type): + """ + Return the directory where the output of type ``type`` is stored. + + If the directory does not exist, then it will automatically be + created. + """ + base_dir = os.path.split(self.dir)[0] + d = os.path.join(base_dir, "output", type) + os.makedirs(d, exist_ok=True) + return d + + def _doctrees_dir(self): + """ + Return the directory where the doctrees are stored. + + If the directory does not exist, then it will automatically be + created. + """ + return self._output_dir('doctrees') + + +def get_builder(name): + """ + Return an appropriate *Builder* object for the document ``name``. + + DocBuilder and its subclasses do all the real work in building the + documentation. + """ + if name == 'all': + from sage.misc.superseded import deprecation + deprecation(31948, 'avoid using "sage --docbuild all html" and "sage --docbuild all pdf"; ' + 'use "make doc" and "make doc-pdf" instead, if available.') + return AllBuilder() + elif name == 'reference_top': + return ReferenceTopBuilder('reference') + elif name.endswith('reference'): + return ReferenceBuilder(name) + elif 'reference' in name and os.path.exists(os.path.join(SAGE_DOC_SRC, 'en', name)): + return ReferenceSubBuilder(name) + elif name.endswith('website'): + return WebsiteBuilder(name) + elif name.startswith('file='): + path = name[5:] + if path.endswith('.sage') or path.endswith('.pyx'): + raise NotImplementedError('Building documentation for a single file only works for Python files.') + return SingleFileBuilder(path) + elif name in get_documents() or name in AllBuilder().get_all_documents(): + return DocBuilder(name) + else: + print("'%s' is not a recognized document. Type 'sage --docbuild -D' for a list" % name) + print("of documents, or 'sage --docbuild --help' for more help.") + sys.exit(1) + + +def get_documents(): + """ + Return a list of document names the Sage documentation builder + will accept as command-line arguments. + """ + all_b = AllBuilder() + docs = all_b.get_all_documents() + docs = [(d[3:] if d[0:3] == 'en/' else d) for d in docs] + return docs diff --git a/src/sage_docbuild/conf.py b/src/sage_docbuild/conf.py new file mode 100644 index 00000000000..e34c1d88aca --- /dev/null +++ b/src/sage_docbuild/conf.py @@ -0,0 +1,968 @@ +r""" +Sphinx configurations +""" + +import sys +import os +import sphinx +from sage.env import SAGE_DOC_SRC, SAGE_DOC, SAGE_SRC, THEBE_DIR, PPLPY_DOCS, MATHJAX_DIR +import sage.version +from sage.misc.sagedoc import extlinks +import dateutil.parser +from docutils import nodes +from docutils.transforms import Transform +from sphinx.ext.doctest import blankline_re +from sphinx import highlighting +import sphinx.ext.intersphinx as intersphinx +from IPython.lib.lexers import IPythonConsoleLexer, IPyLexer + +# General configuration +# --------------------- + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = ['sage_docbuild.ext.inventory_builder', + 'sage_docbuild.ext.multidocs', + 'sage_docbuild.ext.sage_autodoc', + 'sphinx.ext.todo', + 'sphinx.ext.extlinks', + 'IPython.sphinxext.ipython_directive', + 'matplotlib.sphinxext.plot_directive', + 'jupyter_sphinx'] + +jupyter_execute_default_kernel = 'sagemath' + +jupyter_sphinx_thebelab_config = { + 'requestKernel': True, + 'binderOptions': { + 'repo': "sagemath/sage-binder-env", + }, + 'kernelOptions': { + 'name': "sagemath", + 'kernelName': "sagemath", + 'path': ".", + }, +} + +# This code is executed before each ".. PLOT::" directive in the Sphinx +# documentation. It defines a 'sphinx_plot' function that displays a Sage object +# through matplotlib, so that it will be displayed in the HTML doc +plot_html_show_source_link = False +plot_pre_code = r""" +# Set locale to prevent having commas in decimal numbers +# in tachyon input (see https://trac.sagemath.org/ticket/28971) +import locale +locale.setlocale(locale.LC_NUMERIC, 'C') +def sphinx_plot(graphics, **kwds): + import matplotlib.image as mpimg + import matplotlib.pyplot as plt + from sage.misc.temporary_file import tmp_filename + from sage.plot.graphics import _parse_figsize + if os.environ.get('SAGE_SKIP_PLOT_DIRECTIVE', 'no') != 'yes': + ## Option handling is taken from Graphics.save + options = dict() + if isinstance(graphics, sage.plot.graphics.Graphics): + options.update(sage.plot.graphics.Graphics.SHOW_OPTIONS) + options.update(graphics._extra_kwds) + options.update(kwds) + elif isinstance(graphics, sage.plot.multigraphics.MultiGraphics): + options.update(kwds) + else: + graphics = graphics.plot(**kwds) + dpi = options.pop('dpi', None) + transparent = options.pop('transparent', None) + fig_tight = options.pop('fig_tight', None) + figsize = options.pop('figsize', None) + if figsize is not None: + figsize = _parse_figsize(figsize) + plt.figure(figsize=figsize) + figure = plt.gcf() + if isinstance(graphics, (sage.plot.graphics.Graphics, + sage.plot.multigraphics.MultiGraphics)): + graphics.matplotlib(figure=figure, figsize=figsize, **options) + if isinstance(graphics, (sage.plot.graphics.Graphics, + sage.plot.multigraphics.GraphicsArray)): + # for Graphics and GraphicsArray, tight_layout adjusts the + # *subplot* parameters so ticks aren't cut off, etc. + figure.tight_layout() + else: + # 3d graphics via png + import matplotlib as mpl + mpl.rcParams['image.interpolation'] = 'bilinear' + mpl.rcParams['image.resample'] = False + mpl.rcParams['figure.figsize'] = [8.0, 6.0] + mpl.rcParams['figure.dpi'] = 80 + mpl.rcParams['savefig.dpi'] = 100 + fn = tmp_filename(ext=".png") + graphics.save(fn) + img = mpimg.imread(fn) + plt.imshow(img) + plt.axis("off") + plt.margins(0) + if not isinstance(graphics, sage.plot.multigraphics.MultiGraphics): + plt.tight_layout(pad=0) + +from sage.all_cmdline import * +""" + +plot_html_show_formats = False +plot_formats = ['svg', 'pdf', 'png'] + +# We do *not* fully initialize intersphinx since we call it by hand +# in find_sage_dangling_links. +#, 'sphinx.ext.intersphinx'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = [os.path.join(SAGE_DOC_SRC, 'common', 'templates'), 'templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = "" +copyright = "2005--{}, The Sage Development Team".format(dateutil.parser.parse(sage.version.date).year) + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +version = sage.version.version +release = sage.version.version + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of glob-style patterns that should be excluded when looking for +# source files. [1] They are matched against the source file names +# relative to the source directory, using slashes as directory +# separators on all platforms. +exclude_patterns = ['.build'] + +# The reST default role (used for this markup: `text`) to use for all documents. +default_role = 'math' + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. NOTE: +# This overrides a HTML theme's corresponding setting (see below). +pygments_style = 'sphinx' + +# Default lexer to use when highlighting code blocks, using the IPython +# console lexers. 'ipycon' is the IPython console, which is what we want +# for most code blocks: anything with "sage:" prompts. For other IPython, +# like blocks which might appear in a notebook cell, use 'ipython'. +highlighting.lexers['ipycon'] = IPythonConsoleLexer(in1_regex=r'sage: ', in2_regex=r'[.][.][.][.]: ') +highlighting.lexers['ipython'] = IPyLexer() +highlight_language = 'ipycon' + +# Extension configuration +# ----------------------- + +# include the todos +todo_include_todos = True + +# Cross-links to other project's online documentation. +python_version = sys.version_info.major + +def set_intersphinx_mappings(app, config): + """ + Add precompiled inventory (the objects.inv) + """ + refpath = os.path.join(SAGE_DOC, "html", "en", "reference") + invpath = os.path.join(SAGE_DOC, "inventory", "en", "reference") + if app.config.multidoc_first_pass == 1 or \ + not (os.path.exists(refpath) and os.path.exists(invpath)): + app.config.intersphinx_mapping = {} + return + + app.config.intersphinx_mapping = { + 'python': ('https://docs.python.org/', + os.path.join(SAGE_DOC_SRC, "common", + "python{}.inv".format(python_version))), + 'pplpy': (PPLPY_DOCS, None)} + + # Add master intersphinx mapping + dst = os.path.join(invpath, 'objects.inv') + app.config.intersphinx_mapping['sagemath'] = (refpath, dst) + + # Add intersphinx mapping for subdirectories + # We intentionally do not name these such that these get higher + # priority in case of conflicts + for directory in os.listdir(os.path.join(invpath)): + if directory == 'jupyter_execute': + # This directory is created by jupyter-sphinx extension for + # internal use and should be ignored here. See trac #33507. + continue + if os.path.isdir(os.path.join(invpath, directory)): + src = os.path.join(refpath, directory) + dst = os.path.join(invpath, directory, 'objects.inv') + app.config.intersphinx_mapping[src] = dst + + intersphinx.normalize_intersphinx_mapping(app, config) + +# By default document are not master. +multidocs_is_master = True + +# Options for HTML output +# ----------------------- + +# Sage default HTML theme. We use a custom theme to set a Pygments style, +# stylesheet, and insert MathJax macros. See the directory +# doc/common/themes/sage-classic/ for files comprising the custom theme. +html_theme = 'sage-classic' + +# Theme options are theme-specific and customize the look and feel of +# a theme further. For a list of options available for each theme, +# see the documentation. +html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +html_theme_path = [os.path.join(SAGE_DOC_SRC, 'common', 'themes')] + +# HTML style sheet NOTE: This overrides a HTML theme's corresponding +# setting. +#html_style = 'default.css' + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (within the static path) to place at the top of +# the sidebar. +#html_logo = 'sagelogo-word.ico' + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +html_favicon = 'favicon.ico' + +# html_static_path defined here and imported in the actual configuration file +# conf.py read by Sphinx was the cause of subtle bugs in builders (see #30418 for +# instance). Hence now html_common_static_path contains the common paths to static +# files, and is combined to html_static_path in each conf.py file read by Sphinx. +html_common_static_path = [os.path.join(SAGE_DOC_SRC, 'common', 'static'), + THEBE_DIR, 'static'] + +# We use MathJax to build the documentation. +extensions.append('sphinx.ext.mathjax') +mathjax_path = 'MathJax.js?config=TeX-AMS_HTML-full,../mathjax_sage.js' + +from sage.misc.latex_macros import sage_mathjax_macros +html_theme_options['mathjax_macros'] = sage_mathjax_macros() + +mathjax_relative = os.path.basename(MATHJAX_DIR) + +# It would be really nice if sphinx would copy the entire mathjax +# directory, (so we could have a _static/mathjax directory), rather than +# the contents of the directory +html_common_static_path.append(MATHJAX_DIR) +exclude_patterns += ['**/' + os.path.join(mathjax_relative, i) + for i in ('docs', 'README*', 'test', 'unpacked', 'LICENSE')] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_use_modindex = True + +# A list of prefixes that are ignored for sorting the Python module index ( if +# this is set to ['foo.'], then foo.bar is shown under B, not F). Works only +# for the HTML builder currently. +modindex_common_prefix = ['sage.'] + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +html_split_index = True + +# If true, the reST sources are included in the HTML build as _sources/. +#html_copy_source = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = '' + +# Output file base name for HTML help builder. +#htmlhelp_basename = '' + +# Options for LaTeX output +# ------------------------ +# See http://sphinx-doc.org/config.html#confval-latex_elements +latex_elements = {} + +# The paper size ('letterpaper' or 'a4paper'). +#latex_elements['papersize'] = 'letterpaper' + +# The font size ('10pt', '11pt' or '12pt'). +#latex_elements['pointsize'] = '10pt' + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, document class [howto/manual]). +latex_documents = [] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = 'sagelogo-word.png' + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# Additional stuff for the LaTeX preamble. +latex_elements['preamble'] = r""" +\usepackage{amsmath} +\usepackage{amssymb} +\usepackage{textcomp} +\usepackage{mathrsfs} +\usepackage{iftex} + +% Only declare unicode characters when compiling with pdftex; E.g. japanese +% tutorial does not use pdftex +\ifPDFTeX + \DeclareUnicodeCharacter{01CE}{\capitalcaron a} + \DeclareUnicodeCharacter{0428}{cyrillic Sha} + \DeclareUnicodeCharacter{250C}{+} + \DeclareUnicodeCharacter{2510}{+} + \DeclareUnicodeCharacter{2514}{+} + \DeclareUnicodeCharacter{2518}{+} + \DeclareUnicodeCharacter{253C}{+} + + \DeclareUnicodeCharacter{03B1}{\ensuremath{\alpha}} + \DeclareUnicodeCharacter{03B2}{\ensuremath{\beta}} + \DeclareUnicodeCharacter{03B3}{\ensuremath{\gamma}} + \DeclareUnicodeCharacter{0393}{\ensuremath{\Gamma}} + \DeclareUnicodeCharacter{03B4}{\ensuremath{\delta}} + \DeclareUnicodeCharacter{0394}{\ensuremath{\Delta}} + \DeclareUnicodeCharacter{03B5}{\ensuremath{\varepsilon}} + \DeclareUnicodeCharacter{03B6}{\ensuremath{\zeta}} + \DeclareUnicodeCharacter{03B7}{\ensuremath{\eta}} + \DeclareUnicodeCharacter{03B8}{\ensuremath{\vartheta}} + \DeclareUnicodeCharacter{0398}{\ensuremath{\Theta}} + \DeclareUnicodeCharacter{03BA}{\ensuremath{\kappa}} + \DeclareUnicodeCharacter{03BB}{\ensuremath{\lambda}} + \DeclareUnicodeCharacter{039B}{\ensuremath{\Lambda}} + \DeclareUnicodeCharacter{00B5}{\ensuremath{\mu}} % micron sign + \DeclareUnicodeCharacter{03BC}{\ensuremath{\mu}} + \DeclareUnicodeCharacter{03BD}{\ensuremath{\nu}} + \DeclareUnicodeCharacter{03BE}{\ensuremath{\xi}} + \DeclareUnicodeCharacter{039E}{\ensuremath{\Xi}} + \DeclareUnicodeCharacter{03B9}{\ensuremath{\iota}} + \DeclareUnicodeCharacter{03C0}{\ensuremath{\pi}} + \DeclareUnicodeCharacter{03A0}{\ensuremath{\Pi}} + \DeclareUnicodeCharacter{03C1}{\ensuremath{\rho}} + \DeclareUnicodeCharacter{03C3}{\ensuremath{\sigma}} + \DeclareUnicodeCharacter{03A3}{\ensuremath{\Sigma}} + \DeclareUnicodeCharacter{03C4}{\ensuremath{\tau}} + \DeclareUnicodeCharacter{03C6}{\ensuremath{\varphi}} + \DeclareUnicodeCharacter{03A6}{\ensuremath{\Phi}} + \DeclareUnicodeCharacter{03C7}{\ensuremath{\chi}} + \DeclareUnicodeCharacter{03C8}{\ensuremath{\psi}} + \DeclareUnicodeCharacter{03A8}{\ensuremath{\Psi}} + \DeclareUnicodeCharacter{03C9}{\ensuremath{\omega}} + \DeclareUnicodeCharacter{03A9}{\ensuremath{\Omega}} + \DeclareUnicodeCharacter{03C5}{\ensuremath{\upsilon}} + \DeclareUnicodeCharacter{03A5}{\ensuremath{\Upsilon}} + \DeclareUnicodeCharacter{2113}{\ell} + + \DeclareUnicodeCharacter{2148}{\ensuremath{\id}} + \DeclareUnicodeCharacter{2202}{\ensuremath{\partial}} + \DeclareUnicodeCharacter{2205}{\ensuremath{\emptyset}} + \DeclareUnicodeCharacter{2208}{\ensuremath{\in}} + \DeclareUnicodeCharacter{2209}{\ensuremath{\notin}} + \DeclareUnicodeCharacter{2211}{\ensuremath{\sum}} + \DeclareUnicodeCharacter{221A}{\ensuremath{\sqrt{}}} + \DeclareUnicodeCharacter{221E}{\ensuremath{\infty}} + \DeclareUnicodeCharacter{2227}{\ensuremath{\wedge}} + \DeclareUnicodeCharacter{2228}{\ensuremath{\vee}} + \DeclareUnicodeCharacter{2229}{\ensuremath{\cap}} + \DeclareUnicodeCharacter{222A}{\ensuremath{\cup}} + \DeclareUnicodeCharacter{222B}{\ensuremath{\int}} + \DeclareUnicodeCharacter{2248}{\ensuremath{\approx}} + \DeclareUnicodeCharacter{2260}{\ensuremath{\neq}} + \DeclareUnicodeCharacter{2264}{\ensuremath{\leq}} + \DeclareUnicodeCharacter{2265}{\ensuremath{\geq}} + \DeclareUnicodeCharacter{2293}{\ensuremath{\sqcap}} + \DeclareUnicodeCharacter{2294}{\ensuremath{\sqcup}} + \DeclareUnicodeCharacter{22C0}{\ensuremath{\bigwedge}} + \DeclareUnicodeCharacter{22C1}{\ensuremath{\bigvee}} + \DeclareUnicodeCharacter{22C2}{\ensuremath{\bigcap}} + \DeclareUnicodeCharacter{22C3}{\ensuremath{\bigcup}} + \DeclareUnicodeCharacter{2323}{\ensuremath{\smile}} % cup product + \DeclareUnicodeCharacter{00B1}{\ensuremath{\pm}} + \DeclareUnicodeCharacter{2A02}{\ensuremath{\bigotimes}} + \DeclareUnicodeCharacter{2297}{\ensuremath{\otimes}} + \DeclareUnicodeCharacter{2A01}{\ensuremath{\oplus}} + \DeclareUnicodeCharacter{00BD}{\ensuremath{\nicefrac{1}{2}}} + \DeclareUnicodeCharacter{00D7}{\ensuremath{\times}} + \DeclareUnicodeCharacter{00B7}{\ensuremath{\cdot}} + \DeclareUnicodeCharacter{230A}{\ensuremath{\lfloor}} + \DeclareUnicodeCharacter{230B}{\ensuremath{\rfloor}} + \DeclareUnicodeCharacter{2308}{\ensuremath{\lceil}} + \DeclareUnicodeCharacter{2309}{\ensuremath{\rceil}} + \DeclareUnicodeCharacter{22C5}{\ensuremath{\cdot}} + \DeclareUnicodeCharacter{2227}{\ensuremath{\wedge}} + \DeclareUnicodeCharacter{22C0}{\ensuremath{\bigwedge}} + \DeclareUnicodeCharacter{2192}{\ensuremath{\to}} + \DeclareUnicodeCharacter{21A6}{\ensuremath{\mapsto}} + \DeclareUnicodeCharacter{2102}{\ensuremath{\mathbb{C}}} + \DeclareUnicodeCharacter{211A}{\ensuremath{\mathbb{Q}}} + \DeclareUnicodeCharacter{211D}{\ensuremath{\mathbb{R}}} + \DeclareUnicodeCharacter{2124}{\ensuremath{\mathbb{Z}}} + \DeclareUnicodeCharacter{2202}{\ensuremath{\partial}} + + \DeclareUnicodeCharacter{2070}{\ensuremath{{}^0}} + \DeclareUnicodeCharacter{00B9}{\ensuremath{{}^1}} + \DeclareUnicodeCharacter{00B2}{\ensuremath{{}^2}} + \DeclareUnicodeCharacter{00B3}{\ensuremath{{}^3}} + \DeclareUnicodeCharacter{2074}{\ensuremath{{}^4}} + \DeclareUnicodeCharacter{2075}{\ensuremath{{}^5}} + \DeclareUnicodeCharacter{2076}{\ensuremath{{}^6}} + \DeclareUnicodeCharacter{2077}{\ensuremath{{}^7}} + \DeclareUnicodeCharacter{2078}{\ensuremath{{}^8}} + \DeclareUnicodeCharacter{2079}{\ensuremath{{}^9}} + \DeclareUnicodeCharacter{207A}{\ensuremath{{}^+}} + \DeclareUnicodeCharacter{207B}{\ensuremath{{}^-}} + \DeclareUnicodeCharacter{141F}{\ensuremath{{}^/}} + \DeclareUnicodeCharacter{2080}{\ensuremath{{}_0}} + \DeclareUnicodeCharacter{2081}{\ensuremath{{}_1}} + \DeclareUnicodeCharacter{2082}{\ensuremath{{}_2}} + \DeclareUnicodeCharacter{2083}{\ensuremath{{}_3}} + \DeclareUnicodeCharacter{2084}{\ensuremath{{}_4}} + \DeclareUnicodeCharacter{2085}{\ensuremath{{}_5}} + \DeclareUnicodeCharacter{2086}{\ensuremath{{}_6}} + \DeclareUnicodeCharacter{2087}{\ensuremath{{}_7}} + \DeclareUnicodeCharacter{2088}{\ensuremath{{}_8}} + \DeclareUnicodeCharacter{2089}{\ensuremath{{}_9}} + \DeclareUnicodeCharacter{208A}{\ensuremath{{}_+}} + \DeclareUnicodeCharacter{208B}{\ensuremath{{}_-}} + \DeclareUnicodeCharacter{1D62}{\ensuremath{{}_i}} + \DeclareUnicodeCharacter{2C7C}{\ensuremath{{}_j}} + + \newcommand{\sageMexSymbol}[1] + {{\fontencoding{OMX}\fontfamily{cmex}\selectfont\raisebox{0.75em}{\symbol{#1}}}} + \DeclareUnicodeCharacter{239B}{\sageMexSymbol{"30}} % parenlefttp + \DeclareUnicodeCharacter{239C}{\sageMexSymbol{"42}} % parenleftex + \DeclareUnicodeCharacter{239D}{\sageMexSymbol{"40}} % parenleftbt + \DeclareUnicodeCharacter{239E}{\sageMexSymbol{"31}} % parenrighttp + \DeclareUnicodeCharacter{239F}{\sageMexSymbol{"43}} % parenrightex + \DeclareUnicodeCharacter{23A0}{\sageMexSymbol{"41}} % parenrightbt + \DeclareUnicodeCharacter{23A1}{\sageMexSymbol{"32}} % bracketlefttp + \DeclareUnicodeCharacter{23A2}{\sageMexSymbol{"36}} % bracketleftex + \DeclareUnicodeCharacter{23A3}{\sageMexSymbol{"34}} % bracketleftbt + \DeclareUnicodeCharacter{23A4}{\sageMexSymbol{"33}} % bracketrighttp + \DeclareUnicodeCharacter{23A5}{\sageMexSymbol{"37}} % bracketrightex + \DeclareUnicodeCharacter{23A6}{\sageMexSymbol{"35}} % bracketrightbt + + \DeclareUnicodeCharacter{23A7}{\sageMexSymbol{"38}} % curly brace left top + \DeclareUnicodeCharacter{23A8}{\sageMexSymbol{"3C}} % curly brace left middle + \DeclareUnicodeCharacter{23A9}{\sageMexSymbol{"3A}} % curly brace left bottom + \DeclareUnicodeCharacter{23AA}{\sageMexSymbol{"3E}} % curly brace extension + \DeclareUnicodeCharacter{23AB}{\sageMexSymbol{"39}} % curly brace right top + \DeclareUnicodeCharacter{23AC}{\sageMexSymbol{"3D}} % curly brace right middle + \DeclareUnicodeCharacter{23AD}{\sageMexSymbol{"3B}} % curly brace right bottom + \DeclareUnicodeCharacter{23B0}{\{} % 2-line curly brace left top half (not in cmex) + \DeclareUnicodeCharacter{23B1}{\}} % 2-line curly brace right top half (not in cmex) + + \DeclareUnicodeCharacter{2320}{\ensuremath{\int}} % top half integral + \DeclareUnicodeCharacter{2321}{\ensuremath{\int}} % bottom half integral + \DeclareUnicodeCharacter{23AE}{\ensuremath{\|}} % integral extenison + + % Box drawings light + \DeclareUnicodeCharacter{2500}{-} % h + \DeclareUnicodeCharacter{2502}{|} % v + \DeclareUnicodeCharacter{250C}{+} % dr + \DeclareUnicodeCharacter{2510}{+} % dl + \DeclareUnicodeCharacter{2514}{+} % ur + \DeclareUnicodeCharacter{2518}{+} % ul + \DeclareUnicodeCharacter{251C}{+} % vr + \DeclareUnicodeCharacter{2524}{+} % vl + \DeclareUnicodeCharacter{252C}{+} % dh + \DeclareUnicodeCharacter{2534}{+} % uh + \DeclareUnicodeCharacter{253C}{+} % vh + \DeclareUnicodeCharacter{2571}{/} % upper right to lower left + \DeclareUnicodeCharacter{2571}{\setminus} % upper left to lower right + + \DeclareUnicodeCharacter{25CF}{\ensuremath{\bullet}} % medium black circle + \DeclareUnicodeCharacter{26AC}{\ensuremath{\circ}} % medium small white circle + \DeclareUnicodeCharacter{256D}{+} + \DeclareUnicodeCharacter{256E}{+} + \DeclareUnicodeCharacter{256F}{+} + \DeclareUnicodeCharacter{2570}{+} +\fi + +\let\textLaTeX\LaTeX +\AtBeginDocument{\renewcommand*{\LaTeX}{\hbox{\textLaTeX}}} + +% Workaround for a LaTeX bug -- see trac #31397 and +% https://tex.stackexchange.com/questions/583391/mactex-2020-error-with-report-hyperref-mathbf-in-chapter. +\makeatletter +\pdfstringdefDisableCommands{% + \let\mathbf\@firstofone +} +\makeatother +""" + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_use_modindex = True + +##################################################### +# add LaTeX macros for Sage + +from sage.misc.latex_macros import sage_latex_macros + +try: + pngmath_latex_preamble # check whether this is already defined +except NameError: + pngmath_latex_preamble = "" + +for macro in sage_latex_macros(): + # used when building latex and pdf versions + latex_elements['preamble'] += macro + '\n' + # used when building html version + pngmath_latex_preamble += macro + '\n' + +##################################################### +# add custom context variables for templates + +def add_page_context(app, pagename, templatename, context, doctree): + # # The template function + # def template_function(arg): + # return "Your string is " + arg + # # Add it to the page's context + # context['template_function'] = template_function + path1 = os.path.dirname(app.builder.get_outfilename(pagename)) + path2 = os.path.join(SAGE_DOC, 'html', 'en') + relpath = os.path.relpath(path2, path1) + context['release'] = release + context['documentation_title'] = 'Sage {}'.format(release) + ' Documentation' + context['documentation_root'] = os.path.join(relpath, 'index.html') + if 'website' in path1: + context['title'] = 'Documentation' + context['website'] = True + + if 'reference' in path1 and not path1.endswith('reference'): + path2 = os.path.join(SAGE_DOC, 'html', 'en', 'reference') + relpath = os.path.relpath(path2, path1) + context['reference_title'] = 'Reference Manual' + context['reference_root'] = os.path.join(relpath, 'index.html') + context['refsub'] = True + +##################################################### + +def process_docstring_aliases(app, what, name, obj, options, docstringlines): + """ + Change the docstrings for aliases to point to the original object. + """ + basename = name.rpartition('.')[2] + if hasattr(obj, '__name__') and obj.__name__ != basename: + docstringlines[:] = ['See :obj:`%s`.' % name] + +def process_directives(app, what, name, obj, options, docstringlines): + """ + Remove 'nodetex' and other directives from the first line of any + docstring where they appear. + """ + if len(docstringlines) == 0: + return + first_line = docstringlines[0] + directives = [ d.lower() for d in first_line.split(',') ] + if 'nodetex' in directives: + docstringlines.pop(0) + +def process_docstring_cython(app, what, name, obj, options, docstringlines): + """ + Remove Cython's filename and location embedding. + """ + if len(docstringlines) <= 1: + return + + first_line = docstringlines[0] + if first_line.startswith('File:') and '(starting at' in first_line: + #Remove the first two lines + docstringlines.pop(0) + docstringlines.pop(0) + +def process_docstring_module_title(app, what, name, obj, options, docstringlines): + """ + Removes the first line from the beginning of the module's docstring. This + corresponds to the title of the module's documentation page. + """ + if what != "module": + return + + #Remove any additional blank lines at the beginning + title_removed = False + while len(docstringlines) > 1 and not title_removed: + if docstringlines[0].strip() != "": + title_removed = True + docstringlines.pop(0) + + #Remove any additional blank lines at the beginning + while len(docstringlines) > 1: + if docstringlines[0].strip() == "": + docstringlines.pop(0) + else: + break + +skip_picklability_check_modules = [ + #'sage.misc.test_nested_class', # for test only + 'sage.misc.latex', + 'sage.misc.explain_pickle', + '__builtin__', +] + +def check_nested_class_picklability(app, what, name, obj, skip, options): + """ + Print a warning if pickling is broken for nested classes. + """ + if hasattr(obj, '__dict__') and hasattr(obj, '__module__'): + # Check picklability of nested classes. Adapted from + # sage.misc.nested_class.modify_for_nested_pickle. + module = sys.modules[obj.__module__] + for (nm, v) in obj.__dict__.items(): + if (isinstance(v, type) and + v.__name__ == nm and + v.__module__ == module.__name__ and + getattr(module, nm, None) is not v and + v.__module__ not in skip_picklability_check_modules): + # OK, probably this is an *unpicklable* nested class. + app.warn('Pickling of nested class %r is probably broken. ' + 'Please set the metaclass of the parent class to ' + 'sage.misc.nested_class.NestedClassMetaclass.' % ( + v.__module__ + '.' + name + '.' + nm)) + + +def skip_member(app, what, name, obj, skip, options): + """ + To suppress Sphinx warnings / errors, we + + - Don't include [aliases of] builtins. + + - Don't include the docstring for any nested class which has been + inserted into its module by + :class:`sage.misc.NestedClassMetaclass` only for pickling. The + class will be properly documented inside its surrounding class. + + - Optionally, check whether pickling is broken for nested classes. + + - Optionally, include objects whose name begins with an underscore + ('_'), i.e., "private" or "hidden" attributes, methods, etc. + + Otherwise, we abide by Sphinx's decision. Note: The object + ``obj`` is excluded (included) if this handler returns True + (False). + """ + if 'SAGE_CHECK_NESTED' in os.environ: + check_nested_class_picklability(app, what, name, obj, skip, options) + + if getattr(obj, '__module__', None) == '__builtin__': + return True + + objname = getattr(obj, "__name__", None) + if objname is not None: + # check if name was inserted to the module by NestedClassMetaclass + if name.find('.') != -1 and objname.find('.') != -1: + if objname.split('.')[-1] == name.split('.')[-1]: + return True + + if 'SAGE_DOC_UNDERSCORE' in os.environ: + if name.split('.')[-1].startswith('_'): + return False + + return skip + + +def process_dollars(app, what, name, obj, options, docstringlines): + r""" + Replace dollar signs with backticks. + + See sage.misc.sagedoc.process_dollars for more information. + """ + if len(docstringlines) and name.find("process_dollars") == -1: + from sage.misc.sagedoc import process_dollars as sagedoc_dollars + s = sagedoc_dollars("\n".join(docstringlines)) + lines = s.split("\n") + for i in range(len(lines)): + docstringlines[i] = lines[i] + +def process_inherited(app, what, name, obj, options, docstringlines): + """ + If we're including inherited members, omit their docstrings. + """ + if not options.get('inherited-members'): + return + + if what in ['class', 'data', 'exception', 'function', 'module']: + return + + name = name.split('.')[-1] + + if what == 'method' and hasattr(obj, 'im_class'): + if name in obj.im_class.__dict__.keys(): + return + + if what == 'attribute' and hasattr(obj, '__objclass__'): + if name in obj.__objclass__.__dict__.keys(): + return + + for i in range(len(docstringlines)): + docstringlines.pop() + +dangling_debug = False + +def debug_inf(app, message): + if dangling_debug: + app.info(message) + +def call_intersphinx(app, env, node, contnode): + r""" + Call intersphinx and make links between Sage manuals relative. + + TESTS: + + Check that the link from the thematic tutorials to the reference + manual is relative, see :trac:`20118`:: + + sage: from sage.env import SAGE_DOC + sage: thematic_index = os.path.join(SAGE_DOC, "html", "en", "thematic_tutorials", "index.html") + sage: for line in open(thematic_index).readlines(): # optional - sagemath_doc_html + ....: if "padics" in line: + ....: _ = sys.stdout.write(line) +
    • Introduction to the p-adics

    • + """ + debug_inf(app, "???? Trying intersphinx for %s" % node['reftarget']) + builder = app.builder + res = intersphinx.missing_reference( + app, env, node, contnode) + if res: + # Replace absolute links to $SAGE_DOC by relative links: this + # allows to copy the whole documentation tree somewhere else + # without breaking links, see Trac #20118. + if res['refuri'].startswith(SAGE_DOC): + here = os.path.dirname(os.path.join(builder.outdir, + node['refdoc'])) + res['refuri'] = os.path.relpath(res['refuri'], here) + debug_inf(app, "++++ Found at %s" % res['refuri']) + else: + debug_inf(app, "---- Intersphinx: %s not Found" % node['reftarget']) + return res + +def find_sage_dangling_links(app, env, node, contnode): + r""" + Try to find dangling link in local module imports or all.py. + """ + debug_inf(app, "==================== find_sage_dangling_links ") + + reftype = node['reftype'] + reftarget = node['reftarget'] + try: + doc = node['refdoc'] + except KeyError: + debug_inf(app, "-- no refdoc in node %s" % node) + return None + + debug_inf(app, "Searching %s from %s"%(reftarget, doc)) + + # Workaround: in Python's doc 'object', 'list', ... are documented as a + # function rather than a class + if reftarget in base_class_as_func and reftype == 'class': + node['reftype'] = 'func' + + res = call_intersphinx(app, env, node, contnode) + if res: + debug_inf(app, "++ DONE %s"%(res['refuri'])) + return res + + if node.get('refdomain') != 'py': # not a python file + return None + + try: + module = node['py:module'] + cls = node['py:class'] + except KeyError: + debug_inf(app, "-- no module or class for :%s:%s"%(reftype, reftarget)) + return None + + basename = reftarget.split(".")[0] + try: + target_module = getattr(sys.modules['sage.all'], basename).__module__ + debug_inf(app, "++ found %s using sage.all in %s" % (basename, target_module)) + except AttributeError: + try: + target_module = getattr(sys.modules[node['py:module']], basename).__module__ + debug_inf(app, "++ found %s in this module" % (basename,)) + except AttributeError: + debug_inf(app, "-- %s not found in sage.all or this module" % (basename)) + return None + except KeyError: + target_module = None + if target_module is None: + target_module = "" + debug_inf(app, "?? found in None !!!") + + newtarget = target_module+'.'+reftarget + node['reftarget'] = newtarget + + # adapted from sphinx/domains/python.py + builder = app.builder + searchmode = node.hasattr('refspecific') and 1 or 0 + matches = builder.env.domains['py'].find_obj( + builder.env, module, cls, newtarget, reftype, searchmode) + if not matches: + debug_inf(app, "?? no matching doc for %s"%newtarget) + return call_intersphinx(app, env, node, contnode) + elif len(matches) > 1: + env.warn(target_module, + 'more than one target found for cross-reference ' + '%r: %s' % (newtarget, + ', '.join(match[0] for match in matches)), + node.line) + name, obj = matches[0] + debug_inf(app, "++ match = %s %s"%(name, obj)) + + from docutils import nodes + newnode = nodes.reference('', '', internal=True) + if name == target_module: + newnode['refid'] = name + else: + newnode['refuri'] = builder.get_relative_uri(node['refdoc'], obj[0]) + newnode['refuri'] += '#' + name + debug_inf(app, "++ DONE at URI %s"%(newnode['refuri'])) + newnode['reftitle'] = name + newnode.append(contnode) + return newnode + +# lists of basic Python class which are documented as functions +base_class_as_func = [ + 'bool', 'complex', 'dict', 'file', 'float', + 'frozenset', 'int', 'list', 'long', 'object', + 'set', 'slice', 'str', 'tuple', 'type', 'unicode', 'xrange'] + +# Nit picky option configuration: Put here broken links we want to ignore. For +# link to the Python documentation several links where broken because there +# where class listed as functions. Expand the list 'base_class_as_func' above +# instead of marking the link as broken. +nitpick_ignore = [ + ('py:class', 'twisted.web2.resource.Resource'), + ('py:class', 'twisted.web2.resource.PostableResource')] + +def nitpick_patch_config(app): + """ + Patch the default config for nitpicky + + Calling path_config ensure that nitpicky is not considered as a Sphinx + environment variable but rather as a Sage environment variable. As a + consequence, changing it doesn't force the recompilation of the entire + documentation. + """ + app.config.values['nitpicky'] = (False, 'sage') + app.config.values['nitpick_ignore'] = ([], 'sage') + +def skip_TESTS_block(app, what, name, obj, options, docstringlines): + """ + Skip blocks labeled "TESTS:". + + See sage.misc.sagedoc.skip_TESTS_block for more information. + """ + from sage.misc.sagedoc import skip_TESTS_block as sagedoc_skip_TESTS + if not docstringlines: + # No docstring, so don't do anything. See Trac #19932. + return + s = sagedoc_skip_TESTS("\n".join(docstringlines)) + lines = s.split("\n") + for i in range(len(lines)): + docstringlines[i] = lines[i] + while len(docstringlines) > len(lines): + del docstringlines[len(lines)] + +class SagemathTransform(Transform): + """ + Transform for code-blocks. + + This allows Sphinx to treat code-blocks with prompt "sage:" as + associated with the pycon lexer, and in particular, to change + "" to a blank line. + """ + default_priority = 500 + + def apply(self): + for node in self.document.traverse(nodes.literal_block): + if node.get('language') is None and node.astext().startswith('sage:'): + node['language'] = 'ipycon' + source = node.rawsource + source = blankline_re.sub('', source) + node.rawsource = source + node[:] = [nodes.Text(source)] + +from sage.misc.sageinspect import sage_getargspec +autodoc_builtin_argspec = sage_getargspec + +def setup(app): + app.connect('autodoc-process-docstring', process_docstring_cython) + app.connect('autodoc-process-docstring', process_directives) + app.connect('autodoc-process-docstring', process_docstring_module_title) + app.connect('autodoc-process-docstring', process_dollars) + app.connect('autodoc-process-docstring', process_inherited) + if os.environ.get('SAGE_SKIP_TESTS_BLOCKS', False): + app.connect('autodoc-process-docstring', skip_TESTS_block) + app.connect('autodoc-skip-member', skip_member) + app.add_transform(SagemathTransform) + + # When building the standard docs, app.srcdir is set to SAGE_DOC_SRC + + # 'LANGUAGE/DOCNAME', but when doing introspection, app.srcdir is + # set to a temporary directory. We don't want to use intersphinx, + # etc., when doing introspection. + if app.srcdir.startswith(SAGE_DOC_SRC): + app.add_config_value('intersphinx_mapping', {}, False) + app.add_config_value('intersphinx_cache_limit', 5, False) + app.add_config_value('intersphinx_disabled_reftypes', [], False) + app.connect('config-inited', set_intersphinx_mappings) + app.connect('builder-inited', intersphinx.load_mappings) + # We do *not* fully initialize intersphinx since we call it by hand + # in find_sage_dangling_links. + # app.connect('missing-reference', missing_reference) + app.connect('missing-reference', find_sage_dangling_links) + app.connect('builder-inited', nitpick_patch_config) + app.connect('html-page-context', add_page_context) + diff --git a/src/sage_docbuild/sphinxbuild.py b/src/sage_docbuild/sphinxbuild.py index a39c99ffe9f..5c2b20c102a 100644 --- a/src/sage_docbuild/sphinxbuild.py +++ b/src/sage_docbuild/sphinxbuild.py @@ -1,8 +1,9 @@ # -*- coding: utf-8 -*- r""" -This is Sage's version of the sphinx-build script +Sphinx build script -We redirect stdout and stderr to our own logger, and remove some unwanted chatter. +This is Sage's version of the ``sphinx-build`` script. We redirect ``stdout`` and +``stderr`` to our own logger, and remove some unwanted chatter. """ # **************************************************************************** # Copyright (C) 2013-2014 Volker Braun diff --git a/src/sage_docbuild/utils.py b/src/sage_docbuild/utils.py index 4d815f9dd4e..ac7bd544c47 100644 --- a/src/sage_docbuild/utils.py +++ b/src/sage_docbuild/utils.py @@ -1,4 +1,6 @@ -"""Miscellaneous utilities for running the docbuilder.""" +r""" +Utilities +""" import errno import os @@ -96,7 +98,7 @@ def build_many(target, args, processes=None): This is a simplified version of ``multiprocessing.Pool.map`` from the Python standard library which avoids a couple of its pitfalls. In - particular, it can abort (with a `RuntimeError`) without hanging if one of + particular, it can abort (with a ``RuntimeError``) without hanging if one of the worker processes unexpectedly dies. It also has semantics equivalent to ``maxtasksperchild=1``; that is, one process is started per argument. As such, this is inefficient for processing large numbers of fast tasks, @@ -107,11 +109,11 @@ def build_many(target, args, processes=None): least two known issues: * On versions of Cygwin prior to 3.0.0 there were bugs in mmap handling - on threads (see https://trac.sagemath.org/ticket/27214#comment:25). + on threads (see :trac:`ticket/27214#comment:25`). * When PARI is built with multi-threading support, forking a Sage process from a thread leaves the main Pari interface instance broken - (see https://trac.sagemath.org/ticket/26608#comment:38). + (see :trac:`ticket/26608#comment:38`). In the future this may be replaced by a generalized version of the more robust parallel processing implementation from ``sage.doctest.forker``. @@ -173,7 +175,7 @@ def build_many(target, args, processes=None): Similarly, if one of the worker processes dies unexpectedly otherwise exits non-zero (e.g. killed by a signal) any in-progress tasks will be completed - gracefully, but then a `RuntimeError` is raised and pending tasks are not + gracefully, but then a ``RuntimeError`` is raised and pending tasks are not started:: sage: def target(N): From 4b0fae47181138da11dd9cc01a9b1b8233ab4cdb Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Wed, 27 Apr 2022 18:27:25 +0900 Subject: [PATCH 228/529] Some obvious edits --- src/sage_docbuild/utils.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/sage_docbuild/utils.py b/src/sage_docbuild/utils.py index ac7bd544c47..196f761650e 100644 --- a/src/sage_docbuild/utils.py +++ b/src/sage_docbuild/utils.py @@ -108,12 +108,12 @@ def build_many(target, args, processes=None): It also avoids starting new processes from a pthread, which results in at least two known issues: - * On versions of Cygwin prior to 3.0.0 there were bugs in mmap handling - on threads (see :trac:`ticket/27214#comment:25`). + * On versions of Cygwin prior to 3.0.0 there were bugs in mmap handling + on threads (see :trac:`27214#comment:25`). - * When PARI is built with multi-threading support, forking a Sage - process from a thread leaves the main Pari interface instance broken - (see :trac:`ticket/26608#comment:38`). + * When PARI is built with multi-threading support, forking a Sage + process from a thread leaves the main Pari interface instance broken + (see :trac:`26608#comment:38`). In the future this may be replaced by a generalized version of the more robust parallel processing implementation from ``sage.doctest.forker``. @@ -135,9 +135,9 @@ def build_many(target, args, processes=None): Processed task ... Processed task ... - Unlike the first version of `build_many` which was only intended to get + Unlike the first version of ``build_many`` which was only intended to get around the Cygwin bug, this version can also return a result, and thus can - be used as a replacement for `multiprocessing.Pool.map` (i.e. it still + be used as a replacement for ``multiprocessing.Pool.map`` (i.e. it still blocks until the result is ready):: sage: def square(N): @@ -146,7 +146,7 @@ def build_many(target, args, processes=None): [0, 1, 4, 9, ..., 9604, 9801] If the target function raises an exception in any of the workers, - `build_many` raises that exception and all other results are discarded. + ``build_many`` raises that exception and all other results are discarded. Any in-progress tasks may still be allowed to complete gracefully before the exception is raised:: From 0e1b3f5b5880e25a2aa3cc8ba2b27e8417345d7b Mon Sep 17 00:00:00 2001 From: Vincent Delecroix <20100.delecroix@gmail.com> Date: Wed, 27 Apr 2022 12:27:43 +0200 Subject: [PATCH 229/529] 33759: also fix delete_vertex --- src/sage/graphs/generic_graph.py | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index 26f0ead24f3..dbfd6ec7f98 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -10257,18 +10257,40 @@ def delete_vertex(self, vertex, in_order=False): {0: 'no delete', 2: None, 3: None, 4: None} sage: G.get_pos() {0: (0, 0), 2: (2, 0), 3: (3, 0), 4: (4, 0)} + + TESTS: + + Test that :trac:`33759` is fixed:: + + sage: G = Graph([(1, 4), (2, 3)]) + sage: G.is_planar(set_embedding=True) + True + sage: G.delete_vertex([3]) + sage: G.is_planar() + True + """ if in_order: vertex = self.vertices()[vertex] if vertex not in self: raise ValueError("vertex (%s) not in the graph"%str(vertex)) - self._backend.del_vertex(vertex) - attributes_to_update = ('_pos', '_assoc', '_embedding') + attributes_to_update = ('_pos', '_assoc') for attr in attributes_to_update: if hasattr(self, attr) and getattr(self, attr) is not None: getattr(self, attr).pop(vertex, None) + if hasattr(self, '_embedding'): + embedding = self._embedding + if self._embedding is not None: + neighbors = set(self.neighbor_iterator(vertex)) + neighbors.difference_update([vertex]) + for w in neighbors: + embedding[w] = [x for x in embedding[w] if x != vertex] + embedding.pop(vertex, None) + + self._backend.del_vertex(vertex) + def delete_vertices(self, vertices): """ Delete vertices from the (di)graph taken from an iterable container of From 6517de2d8c7f541c0614c7ec79b7446f9ab438bc Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Wed, 27 Apr 2022 23:04:03 +0900 Subject: [PATCH 230/529] More edits --- src/sage_docbuild/__main__.py | 6 +++--- src/sage_docbuild/builders.py | 26 ++++++++++++++------------ 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/sage_docbuild/__main__.py b/src/sage_docbuild/__main__.py index c551e345406..a46a858b11a 100644 --- a/src/sage_docbuild/__main__.py +++ b/src/sage_docbuild/__main__.py @@ -5,10 +5,10 @@ sage --docbuild [OPTIONS] DOCUMENT (FORMAT | COMMAND) -If ``FORMAT`` is given, ``DOCUMENT`` in given ``FORMAT`` is built. If -``COMMAND`` is given, it returns information about ``DOCUMENT``. +If ``FORMAT`` is given, it builds ``DOCUMENT`` in ``FORMAT``. If ``COMMAND`` is +given, it returns information about ``DOCUMENT``. -To get started, run ``sage --docbuild`` to get detailed explanations about +Run ``sage --docbuild`` to get detailed explanations about arguments and options. Positional arguments:: diff --git a/src/sage_docbuild/builders.py b/src/sage_docbuild/builders.py index 672a2bf00fe..b6b723976cd 100644 --- a/src/sage_docbuild/builders.py +++ b/src/sage_docbuild/builders.py @@ -2,36 +2,37 @@ Documentation builders This module is the starting point for building documentation, and is -responsible to figure out what to build and with which options. The -actual documentation build for each individual document is then done -in a subprocess call to Sphinx, see :func:`builder_helper`. Note that +responsible to figure out what to build and with which options. The actual +documentation build for each individual document is then done in a subprocess +call to Sphinx, see :func:`builder_helper`. Note that -* The builder can be configured in ``build_options.py``; +* The builders are configured with ``build_options.py``; * The Sphinx subprocesses are configured in ``conf.py``. :class:`DocBuilder` is the base class of all Builders. It has builder helpers :meth:`html()`, :meth:`latex`, :meth:`pdf`, :meth:`inventory`, etc, which are invoked depending on the output type. Each type corresponds with the Sphinx -builder format, except that ``pdf`` is latex Sphinx builder plus compiling -latex to pdf. Note that ``inventory`` Sphinx builder is not native to Sphinx +builder format, except that ``pdf`` is Sphinx latex builder plus compiling +latex to pdf. Note that Sphinx inventory builder is not native to Sphinx but provided by Sage. See ``sage_docbuild/ext/inventory_builder.py``. The -Sphinx inventory builder is the html builder with no actual output but produces +Sphinx inventory builder is a dummy builder with no actual output but produces doctree files in ``local/share/doctree`` and ``inventory.inv`` inventory files in ``local/share/inventory``. The reference manual is built in two passes, first by :class:`ReferenceBuilder` -with format ``inventory`` and secondly with format ``html``. The +with ``inventory`` output type and secondly with``html`` output type. The :class:`ReferenceBuilder` itself uses :class:`ReferenceTopBuilder` and :class:`ReferenceSubBuilder` to build subcomponents of the reference manual. -The :class:`ReferenceSubBuilder` examines modules of the Sage library by -comparing the modification times of the module files with the times saved in -``local/share/doctree/reference.pickle`` from the previous build. New rst -files are autogenerated for new and updated modules. See +The :class:`ReferenceSubBuilder` examines the modules included in the +subcomponent by comparing the modification times of the module files with the +times saved in ``local/share/doctree/reference.pickle`` from the previous +build. Then new rst files are generated for new and updated modules. See :meth:`get_new_and_updated_modules()`. After :trac:`31948`, when Sage is built, :class:`ReferenceBuilder` is not used and its responsibility is now taken by the ``Makefile`` in ``$SAGE_ROOT/src/doc``. """ + # **************************************************************************** # Copyright (C) 2008-2009 Mike Hansen # 2009-2010 Mitesh Patel @@ -59,6 +60,7 @@ # (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** + import logging import os import pickle From 281155921993173a75e18c7c23af782acc6a902e Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Wed, 27 Apr 2022 17:17:32 +0000 Subject: [PATCH 231/529] Introduce new bootstrap-conda command --- .gitignore | 1 + bootstrap-conda | 78 +++++++++++++++ src/doc/bootstrap | 52 ++-------- src/environment-dev.yml | 206 ---------------------------------------- 4 files changed, 86 insertions(+), 251 deletions(-) create mode 100755 bootstrap-conda delete mode 100644 src/environment-dev.yml diff --git a/.gitignore b/.gitignore index 942a4388eeb..84c0c28eca8 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,7 @@ /environment.yml /environment-optional.yml /src/environment.yml +/src/environment-dev.yml /src/environment-optional.yml /src/setup.cfg diff --git a/bootstrap-conda b/bootstrap-conda new file mode 100755 index 00000000000..9fac4e8d58a --- /dev/null +++ b/bootstrap-conda @@ -0,0 +1,78 @@ +#!/bin/bash + +######################################################################## +# Generate auto-generated conda environment files +######################################################################### + +STRIP_COMMENTS="sed s/#.*//;" +RECOMMENDED_SPKG_PATTERN="@(_recommended$(for a in $(head -n 1 build/pkgs/_recommended/dependencies); do echo -n "|"$a; done))" + +BOOTSTRAP_PACKAGES=$(echo $(${STRIP_COMMENTS} build/pkgs/_bootstrap/distros/conda.txt)) +SYSTEM_PACKAGES= +OPTIONAL_SYSTEM_PACKAGES= +SAGELIB_SYSTEM_PACKAGES= +SAGELIB_OPTIONAL_SYSTEM_PACKAGES= +RECOMMENDED_SYSTEM_PACKAGES= +for PKG_BASE in $(./sage --package list --has-file distros/conda.txt); do + PKG_SCRIPTS=build/pkgs/$PKG_BASE + SYSTEM_PACKAGES_FILE=$PKG_SCRIPTS/distros/conda.txt + PKG_TYPE=$(cat $PKG_SCRIPTS/type) + PKG_SYSTEM_PACKAGES=$(echo $(${STRIP_COMMENTS} $SYSTEM_PACKAGES_FILE)) + if [ -n "PKG_SYSTEM_PACKAGES" ]; then + if [ -f $PKG_SCRIPTS/spkg-configure.m4 ]; then + case "$PKG_BASE:$PKG_TYPE" in + *:standard) + SYSTEM_PACKAGES+=" $PKG_SYSTEM_PACKAGES" + ;; + $RECOMMENDED_SPKG_PATTERN:*) + RECOMMENDED_SYSTEM_PACKAGES+=" $PKG_SYSTEM_PACKAGES" + ;; + *) + OPTIONAL_SYSTEM_PACKAGES+=" $PKG_SYSTEM_PACKAGES" + ;; + esac + else + case "$PKG_TYPE" in + standard) + SAGELIB_SYSTEM_PACKAGES+=" $PKG_SYSTEM_PACKAGES" + ;; + *) + SAGELIB_OPTIONAL_SYSTEM_PACKAGES+=" $PKG_SYSTEM_PACKAGES" + ;; + esac + fi + fi +done +echo >&2 $0:$LINENO: generate conda enviroment files +echo "name: sage-build" > environment.yml +echo "channels:" >> environment.yml +echo " - conda-forge" >> environment.yml +echo " - nodefaults" >> environment.yml +echo "dependencies:" >> environment.yml +for pkg in $SYSTEM_PACKAGES; do + echo " - $pkg" >> environment.yml +done +echo " # Packages needed for ./bootstrap" >> environment.yml +for pkg in $BOOTSTRAP_PACKAGES; do + echo " - $pkg" >> environment.yml +done +sed 's/name: sage-build/name: sage/' environment.yml > src/environment.yml +for pkg in $SAGELIB_SYSTEM_PACKAGES; do + echo " - $pkg" >> src/environment.yml +done +sed 's/name: sage/name: sage-dev/' src/environment.yml > src/environment-dev.yml +echo " # Additional dev tools" >> src/environment-dev.yml +echo " - openssh" >> src/environment-dev.yml +echo " - pycodestyle" >> src/environment-dev.yml +echo " - pytest" >> src/environment-dev.yml + +cp environment.yml environment-optional.yml + echo " # optional packages" >> environment-optional.yml +for pkg in $OPTIONAL_SYSTEM_PACKAGES; do + echo " - $pkg" >> environment-optional.yml + done +cp src/environment.yml src/environment-optional.yml + echo " # optional packages" >> src/environment-optional.yml +for pkg in $OPTIONAL_SYSTEM_PACKAGES $SAGELIB_OPTIONAL_SYSTEM_PACKAGES; do + echo " - $pkg" >> src/environment-optional.yml +done diff --git a/src/doc/bootstrap b/src/doc/bootstrap index 14886524d58..90ae09160ba 100755 --- a/src/doc/bootstrap +++ b/src/doc/bootstrap @@ -27,7 +27,7 @@ shopt -s extglob RECOMMENDED_SPKG_PATTERN="@(_recommended$(for a in $(head -n 1 build/pkgs/_recommended/dependencies); do echo -n "|"$a; done))" -for SYSTEM in arch debian fedora cygwin homebrew conda; do +for SYSTEM in arch debian fedora cygwin homebrew; do SYSTEM_PACKAGES= OPTIONAL_SYSTEM_PACKAGES= SAGELIB_SYSTEM_PACKAGES= @@ -63,51 +63,13 @@ for SYSTEM in arch debian fedora cygwin homebrew conda; do fi fi done - if [ "${SYSTEM}" = "conda" ]; then - if [ "${BOOTSTRAP_QUIET}" = "no" ]; then - echo >&2 $0:$LINENO: generate conda enviroment files - fi - echo "name: sage-build" > environment.yml - echo "channels:" >> environment.yml - echo " - conda-forge" >> environment.yml - echo " - nodefaults" >> environment.yml - echo "dependencies:" >> environment.yml - for pkg in $SYSTEM_PACKAGES; do - echo " - $pkg" >> environment.yml - done - sed 's/name: sage-build/name: sage/' environment.yml > src/environment.yml - for pkg in $SAGELIB_SYSTEM_PACKAGES; do - echo " - $pkg" >> src/environment.yml - done - sed 's/name: sage/name: sage-dev/' src/environment.yml > src/environment-dev.yml - echo " # Packages needed for ./bootstrap" >> src/environment-dev.yml - BOOTSTRAP_PACKAGES=$(echo $(${STRIP_COMMENTS} build/pkgs/_bootstrap/distros/conda.txt)) - for pkg in $BOOTSTRAP_PACKAGES; do - echo " - $pkg" >> src/environment-dev.yml - done - echo " # Additional dev tools" >> src/environment-dev.yml - echo " - openssh" >> src/environment-dev.yml - echo " - pycodestyle" >> src/environment-dev.yml - echo " - pytest" >> src/environment-dev.yml - - cp environment.yml environment-optional.yml - echo " # optional packages" >> environment-optional.yml - for pkg in $OPTIONAL_SYSTEM_PACKAGES; do - echo " - $pkg" >> environment-optional.yml - done - cp src/environment.yml src/environment-optional.yml - echo " # optional packages" >> src/environment-optional.yml - for pkg in $OPTIONAL_SYSTEM_PACKAGES $SAGELIB_OPTIONAL_SYSTEM_PACKAGES; do - echo " - $pkg" >> src/environment-optional.yml - done - else - if [ "${BOOTSTRAP_QUIET}" = "no" ]; then - echo >&2 $0:$LINENO: installing "$OUTPUT_DIR"/$SYSTEM"*.txt" - fi - echo "$(sage-print-system-package-command $SYSTEM --prompt --sudo install $(echo $(echo $SYSTEM_PACKAGES | xargs -n 1 echo | sort | uniq)))" > "$OUTPUT_DIR"/$SYSTEM.txt - echo "$(sage-print-system-package-command $SYSTEM --prompt --sudo install $(echo $(echo $OPTIONAL_SYSTEM_PACKAGES | xargs -n 1 echo | sort | uniq)))" > "$OUTPUT_DIR"/$SYSTEM-optional.txt - echo "$(sage-print-system-package-command $SYSTEM --prompt --sudo install $(echo $(echo $RECOMMENDED_SYSTEM_PACKAGES | xargs -n 1 echo | sort | uniq)))" > "$OUTPUT_DIR"/$SYSTEM-recommended.txt + + if [ "${BOOTSTRAP_QUIET}" = "no" ]; then + echo >&2 $0:$LINENO: installing "$OUTPUT_DIR"/$SYSTEM"*.txt" fi + echo "$(sage-print-system-package-command $SYSTEM --prompt --sudo install $(echo $(echo $SYSTEM_PACKAGES | xargs -n 1 echo | sort | uniq)))" > "$OUTPUT_DIR"/$SYSTEM.txt + echo "$(sage-print-system-package-command $SYSTEM --prompt --sudo install $(echo $(echo $OPTIONAL_SYSTEM_PACKAGES | xargs -n 1 echo | sort | uniq)))" > "$OUTPUT_DIR"/$SYSTEM-optional.txt + echo "$(sage-print-system-package-command $SYSTEM --prompt --sudo install $(echo $(echo $RECOMMENDED_SYSTEM_PACKAGES | xargs -n 1 echo | sort | uniq)))" > "$OUTPUT_DIR"/$SYSTEM-recommended.txt done OUTPUT_DIR="src/doc/en/reference/spkg" diff --git a/src/environment-dev.yml b/src/environment-dev.yml deleted file mode 100644 index bef6a1f4a2b..00000000000 --- a/src/environment-dev.yml +++ /dev/null @@ -1,206 +0,0 @@ -name: sage-dev -channels: - - conda-forge - - nodefaults -dependencies: - - compilers - - make - - m4 - - perl - - python - - tar - - bc - - pkg-config - - arb - - boost-cpp - - brial - - bzip2 - - cddlib - - cliquer - - cmake - - curl - - ecl - - eclib - - ecm - - fflas-ffpack - - libflint - - flintqs - - fplll - - freetype - - bdw-gc - - gengetopt - - gf2x - - gfan - - fortran-compiler - - giac - - givaro - - glpk - - gmp - - gsl - - iml - - lcalc - - libatomic_ops - - libbraiding - - libffi - - libgd - - libhomfly - - xz - - libpng - - linbox - - lrcalc - - m4ri - - m4rie - - mpc - - mpfi - - mpfr - - nauty - - ncurses - - ntl - - openblas - - blas=2.*=openblas - - openssl - - palp - - pari - - pari-elldata - - pari-galdata - - pari-galpol - - pari-seadata - - pari-galdata - - pari-seadata-small - - patch - - pcre - - pkg-config - - planarity - - ppl - - primecount - - primesieve - - qhull - - r - - r-essentials - - readline - - rw - - singular - - sqlite - - suitesparse - - symmetrica - - sympow - - tachyon - - tox - - xz - - zeromq - - zlib - - zn_poly - - alabaster - - attrs - - babel - - backcall - - beautifulsoup4 - - bleach - - certifi - - cffi - - sagemath-db-combinatorial-designs - - sagemath-db-conway-polynomials - - cvxopt - - cycler - - cypari2 - - cysignals - - cython - - python-dateutil - - decorator - - defusedxml - - docutils - - sagemath-db-elliptic-curves - - entrypoints - - fpylll - - gap-defaults - - gmpy2 - - sagemath-db-graphs - - html5lib - - imagesize - - importlib_metadata - - ipykernel - - ipython - - ipython_genutils - - ipywidgets - - jedi - - jinja2 - - jmol - - jsonschema - - jupyter_client - - jupyter_core - - jupyter_sphinx - - kiwisolver - - python-lrcalc - - markupsafe - - mathjax - - "matplotlib>=3.5.1" - - maxima - - memory-allocator - - mistune - - mpmath - - nbconvert - - nbformat - - networkx - - notebook - - numpy - - packaging - - pandocfilters - - parso - - pexpect - - pickleshare - - pillow - - pip - - pkgconfig - - sagemath-db-polytopes - - pplpy - - primecountpy - - prometheus_client - - prompt_toolkit - - ptyprocess - - pybind11 - - pycparser - - pygments - - pyparsing - - pyrsistent - - pytz - - pyzmq - - requests - - rpy2 - - sagetex - - scipy - - send2trash - - setuptools - - setuptools_scm - - simplegeneric - - six - - snowballstemmer - - sphinx - - sphinxcontrib-applehelp - - sphinxcontrib-devhelp - - sphinxcontrib-htmlhelp - - sphinxcontrib-jsmath - - sphinxcontrib-qthelp - - sphinxcontrib-serializinghtml - - sphinxcontrib-websupport - - sympy - - terminado - - testpath - - three.js - - tornado - - traitlets - - tzlocal - - vcversioner - - wcwidth - - webencodings - - wheel - - widgetsnbextension - - zipp - # Packages needed for ./bootstrap - - gettext - - autoconf - - automake - - libtool - # Additional dev tools - - openssh - - pycodestyle - - pytest From db6ac255f58d69c109eaea7c4452ce639663a776 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Wed, 27 Apr 2022 18:22:51 +0100 Subject: [PATCH 232/529] suppress system-wide sympow warning on Fedora 32 and later --- src/sage/doctest/parsing.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/sage/doctest/parsing.py b/src/sage/doctest/parsing.py index d2939218bb9..8c8f48bd827 100644 --- a/src/sage/doctest/parsing.py +++ b/src/sage/doctest/parsing.py @@ -43,6 +43,7 @@ ld_warning_regex = re.compile(r'^.*dylib.*was built for newer macOS version.*than being linked.*') # :trac:`30845` -- suppress warning on conda about ld ld_pie_warning_regex = re.compile(r'ld: warning: -pie being ignored. It is only used when linking a main executable') +sympow_cache_warning_regex = re.compile(r'\*\*WARNING\*\* /var/cache/sympow/datafiles/le64 yields insufficient permissions') find_sage_prompt = re.compile(r"^(\s*)sage: ", re.M) find_sage_continuation = re.compile(r"^(\s*)\.\.\.\.:", re.M) find_python_continuation = re.compile(r"^(\s*)\.\.\.([^\.])", re.M) @@ -116,6 +117,9 @@ def fake_RIFtol(*args): (lambda g, w: "Long-step" in g, lambda g, w: (glpk_simplex_warning_regex.sub('', g), w)), + (lambda g, w: "insufficient permissions" in g, + lambda g, w: (sympow_cache_warning_regex.sub('', g), w)), + (lambda g, w: "dylib" in g, lambda g, w: (ld_warning_regex.sub('', g), w)), From c77ecb07a599287d5e6577fa87f1faf71bc5e6ef Mon Sep 17 00:00:00 2001 From: "John H. Palmieri" Date: Wed, 27 Apr 2022 11:55:04 -0700 Subject: [PATCH 233/529] trac 30207: deprecate install_scripts (from sage.misc.dist) --- build/make/install | 13 ------------- src/doc/en/installation/source.rst | 5 ----- src/sage/misc/dist.py | 17 ++++++++++++----- 3 files changed, 12 insertions(+), 23 deletions(-) diff --git a/build/make/install b/build/make/install index f0bbd3348c3..80805935546 100755 --- a/build/make/install +++ b/build/make/install @@ -137,16 +137,3 @@ fi # Build succeeded. echo "Sage build/upgrade complete!" - -if [ "$1" = "all" ]; then - echo - echo "To install small scripts to directly run Sage's versions of GAP," - echo "the PARI/GP interpreter, Maxima, or Singular etc. (by typing e.g." - echo "just 'gap' or 'gp') into a standard 'bin' directory, start Sage" - echo "by typing 'sage' (or './sage') and enter something like" - echo - echo " install_scripts('/usr/local/bin')" - echo - echo "at the Sage command prompt ('sage:')." - echo -fi diff --git a/src/doc/en/installation/source.rst b/src/doc/en/installation/source.rst index dc24eb9f0dd..cea96dbdbdc 100644 --- a/src/doc/en/installation/source.rst +++ b/src/doc/en/installation/source.rst @@ -735,11 +735,6 @@ General procedure Then type ``sage -i `` to automatically download and install a given package. -#. Optional: - Run the ``install_scripts`` command from within Sage to create GAP, GP, - Maxima, Singular, etc., scripts in your :envvar:`PATH`. - Type ``install_scripts?`` in Sage for details. - #. Have fun! Discover some amazing conjectures! Rebasing issues on Cygwin diff --git a/src/sage/misc/dist.py b/src/sage/misc/dist.py index 84e94b77b8d..6b0a1d7a611 100644 --- a/src/sage/misc/dist.py +++ b/src/sage/misc/dist.py @@ -4,8 +4,12 @@ import os +from sage.misc.superseded import deprecation + def install_scripts(directory=None, ignore_existing=False): r""" + This function has been deprecated. + Running ``install_scripts(directory)`` creates scripts in the given directory that run various software components included with Sage. Each of these scripts essentially just runs ``sage --CMD`` @@ -13,15 +17,12 @@ def install_scripts(directory=None, ignore_existing=False): - 'gap' runs GAP - 'gp' runs the PARI/GP interpreter - - 'hg' runs Mercurial - 'ipython' runs IPython - 'maxima' runs Maxima - 'mwrank' runs mwrank - 'R' runs R - 'singular' runs Singular - 'sqlite3' runs SQLite version 3 - - 'kash' runs Kash if it is installed - - 'M2' runs Macaulay2 if it is installed This command: @@ -69,9 +70,15 @@ def install_scripts(directory=None, ignore_existing=False): EXAMPLES:: sage: install_scripts(str(SAGE_TMP), ignore_existing=True) + doctest:warning... + the function install_scripts has been deprecated and will be removed in a future version of Sage + See https://trac.sagemath.org/30207 for details. Checking that Sage has the command 'gap' installed ... """ + deprecation(30207, 'the function install_scripts has been deprecated and ' + 'will be removed in a future version of Sage') + if directory is None: # We do this since the intended user of install_scripts # will likely be pretty clueless about how to use Sage or @@ -110,8 +117,8 @@ def install_scripts(directory=None, ignore_existing=False): dir_in_path = any(os.path.samefile(directory, d) for d in PATH) PATH = os.pathsep.join(d for d in PATH if not os.path.samefile(d, SAGE_BIN)) - for cmd in ['gap', 'gp', 'hg', 'ipython', 'maxima', - 'mwrank', 'R', 'singular', 'sqlite3', 'M2', 'kash']: + for cmd in ['gap', 'gp', 'ipython', 'maxima', + 'mwrank', 'R', 'singular', 'sqlite3']: print(f"Checking that Sage has the command '{cmd}' installed") # Check to see if Sage includes cmd. cmd_inside_sage = have_program(cmd, path=SAGE_BIN) From 9132f37186dde2e4ed1f5898a5eb9c5e6db0954b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 27 Apr 2022 14:25:19 -0700 Subject: [PATCH 234/529] src/sage/libs/pynac, src/sage/symbolic: Add titles to deprecated modules --- src/sage/libs/pynac/pynac.py | 8 ++++++++ src/sage/symbolic/comparison.py | 8 ++++++++ src/sage/symbolic/constant.py | 8 ++++++++ src/sage/symbolic/constants_c.py | 8 ++++++++ src/sage/symbolic/getitem.py | 8 ++++++++ src/sage/symbolic/series.py | 8 ++++++++ 6 files changed, 48 insertions(+) diff --git a/src/sage/libs/pynac/pynac.py b/src/sage/libs/pynac/pynac.py index 5ea76961bc6..ae39f63c4c2 100644 --- a/src/sage/libs/pynac/pynac.py +++ b/src/sage/libs/pynac/pynac.py @@ -1,3 +1,11 @@ +r""" +Interface to the pynac library (deprecated module) + +This module consists only of deprecated lazy imports from +:mod:`sage.symbolic.expression`. +""" + + from sage.misc.lazy_import import lazy_import lazy_import('sage.symbolic.expression', diff --git a/src/sage/symbolic/comparison.py b/src/sage/symbolic/comparison.py index ea0737146b6..38c23b97d6c 100644 --- a/src/sage/symbolic/comparison.py +++ b/src/sage/symbolic/comparison.py @@ -1,3 +1,11 @@ +r""" +Comparison of Symbolic Expressions (deprecated module) + +This module consists only of deprecated lazy imports from +:mod:`sage.symbolic.expression`. +""" + + from sage.misc.lazy_import import lazy_import lazy_import('sage.symbolic.expression', ['print_order', '_print_key', 'print_sorted', '_math_key', diff --git a/src/sage/symbolic/constant.py b/src/sage/symbolic/constant.py index d8774c858f2..53571b8beb0 100644 --- a/src/sage/symbolic/constant.py +++ b/src/sage/symbolic/constant.py @@ -1,2 +1,10 @@ +r""" +Symbolic constants (deprecated module) + +This module consists only of deprecated lazy imports from +:mod:`sage.symbolic.expression`. +""" + + from sage.misc.lazy_import import lazy_import lazy_import('sage.symbolic.expression', 'PynacConstant', deprecation=32386) diff --git a/src/sage/symbolic/constants_c.py b/src/sage/symbolic/constants_c.py index 553f35f4227..b18d0d0eb2f 100644 --- a/src/sage/symbolic/constants_c.py +++ b/src/sage/symbolic/constants_c.py @@ -1,2 +1,10 @@ +r""" +The constant `e` (deprecated module) + +This module consists only of deprecated lazy imports from +:mod:`sage.symbolic.expression`. +""" + + from sage.misc.lazy_import import lazy_import lazy_import('sage.symbolic.expression', 'E', deprecation=32386) diff --git a/src/sage/symbolic/getitem.py b/src/sage/symbolic/getitem.py index 390a87853cd..3ff5e400fba 100644 --- a/src/sage/symbolic/getitem.py +++ b/src/sage/symbolic/getitem.py @@ -1,3 +1,11 @@ +r""" +Operands (deprecated module) + +This module consists only of deprecated lazy imports from +:mod:`sage.symbolic.expression`. +""" + + from sage.misc.lazy_import import lazy_import lazy_import('sage.symbolic.expression', ['normalize_index_for_doctests', 'OperandsWrapper', 'restore_op_wrapper'], diff --git a/src/sage/symbolic/series.py b/src/sage/symbolic/series.py index c562d6bb9ae..943631c52f2 100644 --- a/src/sage/symbolic/series.py +++ b/src/sage/symbolic/series.py @@ -1,2 +1,10 @@ +r""" +Symbolic Series + +This module consists only of deprecated lazy imports from +:mod:`sage.symbolic.expression`. +""" + + from sage.misc.lazy_import import lazy_import lazy_import('sage.symbolic.expression', 'SymbolicSeries', deprecation=32386) From f2b86c7a888d55d2d27585441f05863505628221 Mon Sep 17 00:00:00 2001 From: Vincent Delecroix <20100.delecroix@gmail.com> Date: Thu, 28 Apr 2022 17:29:46 +0200 Subject: [PATCH 235/529] 33759: more embedding fixes --- src/sage/graphs/generic_graph.py | 102 +++++++++++++++++++++---------- src/sage/graphs/planarity.pyx | 63 +++++++++---------- 2 files changed, 100 insertions(+), 65 deletions(-) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index dbfd6ec7f98..112f57457c5 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -5116,6 +5116,15 @@ def is_planar(self, on_embedding=None, kuratowski=False, set_embedding=False, se sage: posets.BooleanLattice(3).cover_relations_graph().is_planar() True + :trac:`33759`:: + + sage: G = Graph([(1, 2)]) + sage: for set_embedding, set_pos in ((True,True), (True,False), (False, True), (False, False)): + ....: G = Graph([(1, 2)]) + ....: assert G.is_planar(set_embedding=set_embedding, set_pos=set_pos) + ....: assert (hasattr(G, '_embedding') and G._embedding is not None) == set_embedding, (set_embedding, set_pos) + ....: assert (hasattr(G, '_pos') and G._pos is not None) == set_pos, (set_embedding, set_pos) + Corner cases:: sage: graphs.EmptyGraph().is_planar() @@ -5239,13 +5248,13 @@ def is_circular_planar(self, on_embedding=None, kuratowski=False, sage: g439.is_circular_planar(kuratowski=True, boundary=[1, 2, 3]) (True, None) sage: g439.get_embedding() - {1: [7, 5], - 2: [5, 6], - 3: [6, 7], - 4: [7, 6, 5], - 5: [1, 4, 2], - 6: [2, 4, 3], - 7: [3, 4, 1]} + {1: [5, 7], + 2: [6, 5], + 3: [7, 6], + 4: [5, 6, 7], + 5: [2, 4, 1], + 6: [3, 4, 2], + 7: [1, 4, 3]} Order matters:: @@ -5262,6 +5271,22 @@ def is_circular_planar(self, on_embedding=None, kuratowski=False, TESTS: + Non-simple graphs:: + + sage: Graph([(1, 1)], loops=True).is_circular_planar(set_embedding=True) + Traceback (most recent call last): + ... + NotImplementedError: cannot compute with embeddings of multiple-edged or looped graphs + + Argument saving:: + + sage: G = Graph([(1, 2)]) + sage: for set_embedding, set_pos in ((True,True), (True,False), (False, True), (False, False)): + ....: G = Graph([(1, 2)]) + ....: assert G.is_circular_planar(set_embedding=set_embedding, set_pos=set_pos) + ....: assert (hasattr(G, '_embedding') and G._embedding is not None) == set_embedding, (set_embedding, set_pos) + ....: assert (hasattr(G, '_pos') and G._pos is not None) == set_pos, (set_embedding, set_pos) + Corner cases:: sage: graphs.EmptyGraph().is_circular_planar() @@ -5279,6 +5304,12 @@ def is_circular_planar(self, on_embedding=None, kuratowski=False, if self.order() > 3 and self.size() > 2 * self.order() - 3: return False + if self.has_multiple_edges() or self.has_loops(): + if set_embedding or (on_embedding is not None) or set_pos: + raise NotImplementedError("cannot compute with embeddings of multiple-edged or looped graphs") + else: + return self.to_simple().is_circular_planar(kuratowski=kuratowski, boundary=boundary, ordered=ordered) + if boundary is None: boundary = self @@ -5287,7 +5318,7 @@ def is_circular_planar(self, on_embedding=None, kuratowski=False, from sage.graphs.planarity import is_planar graph = Graph(self) if hasattr(graph, '_embedding'): - del(graph._embedding) + del graph._embedding # Adds a new vertex to the graph and connects it to all vertices of the # boundary @@ -5308,7 +5339,7 @@ def is_circular_planar(self, on_embedding=None, kuratowski=False, graph.add_edges(extra_edges) - result = is_planar(graph, kuratowski=kuratowski, set_embedding=set_embedding, circular=True) + result = is_planar(graph, kuratowski=kuratowski, set_embedding=set_embedding, set_pos=set_pos) if kuratowski: bool_result = result[0] @@ -5316,24 +5347,21 @@ def is_circular_planar(self, on_embedding=None, kuratowski=False, bool_result = result if bool_result: - graph.delete_vertex(extra) - graph.delete_edges(extra_edges) - - if hasattr(graph,'_embedding'): + if set_embedding: # strip the embedding to fit original graph - for u,v in extra_edges: - graph._embedding[u].pop(graph._embedding[u].index(v)) - graph._embedding[v].pop(graph._embedding[v].index(u)) - for w in boundary: - graph._embedding[w].pop(graph._embedding[w].index(extra)) - - if set_embedding: - self._embedding = graph._embedding.copy() - - if (set_pos and set_embedding): - self.layout(layout="planar", save_pos=True, test=False) + del graph._embedding[extra] + for u, v in extra_edges: + graph._embedding[u].remove(v) + graph._embedding[v].remove(u) + for v in boundary: + graph._embedding[v].remove(extra) + self._embedding = graph._embedding + + if set_pos: + # strip the position + del graph._pos[extra] + self._pos = graph._pos - del graph return result def layout_planar(self, set_embedding=False, on_embedding=None, @@ -5538,7 +5566,7 @@ def layout_planar(self, set_embedding=False, on_embedding=None, embedding_copy = {v: neighbors[:] for v, neighbors in G._embedding.items()} else: if on_embedding is not None: - G._check_embedding_validity(on_embedding,boolean=False) + G._check_embedding_validity(on_embedding, boolean=False) if not G.is_planar(on_embedding=on_embedding): raise ValueError('provided embedding is not a planar embedding for %s'%self ) G.set_embedding(on_embedding) @@ -10265,10 +10293,9 @@ def delete_vertex(self, vertex, in_order=False): sage: G = Graph([(1, 4), (2, 3)]) sage: G.is_planar(set_embedding=True) True - sage: G.delete_vertex([3]) + sage: G.delete_vertex(3) sage: G.is_planar() True - """ if in_order: vertex = self.vertices()[vertex] @@ -10282,9 +10309,9 @@ def delete_vertex(self, vertex, in_order=False): if hasattr(self, '_embedding'): embedding = self._embedding - if self._embedding is not None: + if embedding is not None: neighbors = set(self.neighbor_iterator(vertex)) - neighbors.difference_update([vertex]) + neighbors.discard(vertex) for w in neighbors: embedding[w] = [x for x in embedding[w] if x != vertex] embedding.pop(vertex, None) @@ -10336,7 +10363,7 @@ def delete_vertices(self, vertices): if hasattr(self, '_embedding'): embedding = self._embedding - if self._embedding is not None: + if embedding is not None: neighbors = set().union(*[self.neighbor_iterator(v) for v in vertices]) neighbors.difference_update(vertices) for w in neighbors: @@ -11471,6 +11498,7 @@ def delete_edge(self, u, v=None, label=None): except Exception: u, v = u label = None + self._backend.del_edge(u, v, label, self._directed) def delete_edges(self, edges): @@ -19066,6 +19094,11 @@ def layout(self, layout=None, pos=None, dim=2, save_pos=False, **options): ('1', 1): [2.26..., -0.87...]} sage: g.layout(layout="acyclic_dummy", save_pos=True) + {('0', 0): [0.3..., 0], + ('0', 1): [0.3..., 1], + ('1', 0): [0.6..., 0], + ('1', 1): [0.6..., 1]} + sage: g.get_pos() {('0', 0): [0.3..., 0], ('0', 1): [0.3..., 1], ('1', 0): [0.6..., 0], @@ -19127,6 +19160,13 @@ def layout(self, layout=None, pos=None, dim=2, save_pos=False, **options): use this feature for all the predefined graphs classes (like for the Petersen graph, ...), rather than systematically building the layout at construction time. + + TESTS:: + + sage: for style in ('spring', 'planar', 'circular', 'forest'): + ....: for G in [Graph([(1, 2)]), Graph([(1, 2), (2, 3), (3, 4)])]: + ....: pos = G.layout(style, save_pos=True) + ....: assert G._pos is not None """ if layout is None: if pos is None: diff --git a/src/sage/graphs/planarity.pyx b/src/sage/graphs/planarity.pyx index f761281c0ea..4b14aa25796 100644 --- a/src/sage/graphs/planarity.pyx +++ b/src/sage/graphs/planarity.pyx @@ -29,7 +29,7 @@ cdef extern from "planarity/graph.h": cdef int gp_Embed(graphP theGraph, int embedFlags) cdef int gp_SortVertices(graphP theGraph) -def is_planar(g, kuratowski=False, set_pos=False, set_embedding=False, circular=False): +def is_planar(g, kuratowski=False, set_pos=False, set_embedding=False, circular=None): r""" Check whether ``g`` is planar using Boyer's planarity algorithm. @@ -54,8 +54,7 @@ def is_planar(g, kuratowski=False, set_pos=False, set_embedding=False, circular= combinatorial embedding returned (see :meth:`~sage.graphs.generic_graph.GenericGraph.get_embedding`) - - ``circular`` -- boolean (default: ``False``); whether to test for circular - planarity + - ``circular`` -- deprecated argument EXAMPLES:: @@ -86,7 +85,21 @@ def is_planar(g, kuratowski=False, set_pos=False, set_embedding=False, circular= ....: if (not g.is_connected() or i == 0): ....: continue ....: _ = g.is_planar(set_embedding=True, set_pos=True) + + Argument saving:: + + sage: G = Graph([(1, 2)]) + sage: for set_embedding, set_pos in ((True,True), (True,False), (False, True), (False, False)): + ....: G = Graph([(1, 2)]) + ....: assert is_planar(G, set_embedding=set_embedding, set_pos=set_pos) + ....: assert (hasattr(G, '_embedding') and G._embedding is not None) == set_embedding, (set_embedding, set_pos) + ....: assert (hasattr(G, '_pos') and G._pos is not None) == set_pos, (set_embedding, set_pos) + """ + if circular is not None: + from sage.misc.superseded import deprecation + deprecation(33759, 'the circular argument of is_planar is deprecated and has no effect') + if set_pos and not g.is_connected(): raise ValueError("is_planar() cannot set vertex positions for a disconnected graph") @@ -158,41 +171,23 @@ def is_planar(g, kuratowski=False, set_pos=False, set_embedding=False, circular= else: return False else: - if not circular: + if set_pos or set_embedding: + emb_dict = {} + #for i in range(theGraph.N): + for i in range(1, theGraph.N + 1): + linked_list = [] + j = theGraph.V[i].link[1] + while j: + linked_list.append(to[theGraph.E[j].neighbor]) + j = theGraph.E[j].link[1] + emb_dict[to[i]] = linked_list if set_embedding: - emb_dict = {} - #for i in range(theGraph.N): - for i in range(1, theGraph.N + 1): - linked_list = [] - j = theGraph.V[i].link[1] - while j: - linked_list.append(to[theGraph.E[j].neighbor]) - j = theGraph.E[j].link[1] - emb_dict[to[i]] = linked_list g._embedding = emb_dict if set_pos: - g.layout(layout='planar', save_pos=True) - else: - if set_embedding: - # Take counter-clockwise embedding if circular planar test - # Also, pos must be set after removing extra vertex and edges - - # This is separated out here for now because in the circular case, - # setting positions would have to come into play while the extra - # "wheel" or "star" is still part of the graph. - - emb_dict = {} - #for i in range(theGraph.N): - for i in range(1, theGraph.N + 1): - linked_list = [] - j = theGraph.V[i].link[0] - while j: - linked_list.append(to[theGraph.E[j].neighbor]) - j = theGraph.E[j].link[0] - emb_dict[to[i]] = linked_list - g._embedding = emb_dict + g.layout(layout='planar', save_pos=True, on_embedding=emb_dict) + gp_Free(&theGraph) if kuratowski: - return (True,None) + return (True, None) else: return True From bcad83281cdb922749a043467de1eed0974d4603 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 28 Apr 2022 10:46:02 -0700 Subject: [PATCH 236/529] src/sage/finance/time_series.py: Add title to deprecated module --- src/sage/finance/time_series.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/sage/finance/time_series.py b/src/sage/finance/time_series.py index 977a13b5e65..ab2d836d1fa 100644 --- a/src/sage/finance/time_series.py +++ b/src/sage/finance/time_series.py @@ -1,3 +1,10 @@ -from sage.misc.lazy_import import lazy_import +r""" +Time Series (deprecated module) + +This module consists only of deprecated lazy imports from +:mod:`sage.stats.time_series`. +""" + +from sage.misc.lazy_import import lazy_import lazy_import('sage.stats.time_series', ('TimeSeries', 'autoregressive_fit'), deprecation=32427) From f66333a83dd310007fac21429b38c1be8023dcee Mon Sep 17 00:00:00 2001 From: "Linden Disney-Hogg (Work)" Date: Thu, 28 Apr 2022 18:48:31 +0100 Subject: [PATCH 237/529] Update to caching strategy in gauss_legendre Numerics in Bruin-DisneyHogg-Gao suggest that the caching strategy previously implemented for ``integrate_vector_N``, which is used in the Riemann surfaces module and currently nowhere else, was not helpful so it is removed. This is done by renaming ``nodes`` to ``nodes_uncached``, retaining a cached version ``nodes`` for ``integrate_vector``, which profits from the caching procedure. --- src/sage/numerical/gauss_legendre.pyx | 80 +++++++++++++++++++++++---- 1 file changed, 69 insertions(+), 11 deletions(-) diff --git a/src/sage/numerical/gauss_legendre.pyx b/src/sage/numerical/gauss_legendre.pyx index 72d3d815118..347a47a61d4 100644 --- a/src/sage/numerical/gauss_legendre.pyx +++ b/src/sage/numerical/gauss_legendre.pyx @@ -51,8 +51,7 @@ from sage.rings.real_mpfr import RealField from sage.misc.cachefunc import cached_function from sage.rings.real_mpfr cimport RealNumber, RealField_class -@cached_function -def nodes(degree, prec): +def nodes_uncached(degree, prec): r""" Compute the integration nodes and weights for the Gauss-Legendre quadrature scheme @@ -78,8 +77,8 @@ def nodes(degree, prec): a derivative of a Legendre polynomial isn't particularly numerically stable, so the results from this routine are actually more accurate than what the values the closed formula produces):: - sage: from sage.numerical.gauss_legendre import nodes - sage: L1 = nodes(24, 53) + sage: from sage.numerical.gauss_legendre import nodes_uncached + sage: L1 = nodes_uncached(24, 53) sage: P = RR['x'](sage.functions.orthogonal_polys.legendre_P(24, x)) sage: Pdif = P.diff() sage: L2 = [((r + 1)/2, 1/(1 - r^2)/Pdif(r)^2) @@ -90,14 +89,14 @@ def nodes(degree, prec): TESTS:: - sage: from sage.numerical.gauss_legendre import nodes - sage: nodes(1,100) + sage: from sage.numerical.gauss_legendre import nodes_uncached + sage: nodes_uncached(1,100) Traceback (most recent call last): ... ValueError: degree=1 not supported (degree must be 3 or even) - sage: from sage.numerical.gauss_legendre import nodes - sage: nodes(3,100) + sage: from sage.numerical.gauss_legendre import nodes_uncached + sage: nodes_uncached(3,100) [(0.11270166537925831148207346002, 0.27777777777777777777777777778), (0.50000000000000000000000000000, 0.44444444444444444444444444444), (0.88729833462074168851792653998, 0.27777777777777777777777777778)] @@ -161,6 +160,59 @@ def nodes(degree, prec): mpfr_clear(v) return nodes +@cached_function +def nodes(degree, prec): + r""" + Compute the integration nodes and weights for the Gauss-Legendre quadrature + scheme, caching the output + + Works by calling ``nodes_uncached``. + + INPUT: + + - ``degree`` -- integer. The number of nodes. Must be 3 or even. + + - ``prec`` -- integer (minimal value 53). Binary precision with which the + nodes and weights are computed. + + OUTPUT: + + A list of (node, weight) pairs. + + EXAMPLES: + + The nodes for the Gauss-Legendre scheme are roots of Legendre polynomials. + The weights can be computed by a straightforward formula (note that evaluating + a derivative of a Legendre polynomial isn't particularly numerically stable, so the results + from this routine are actually more accurate than what the values the closed formula produces):: + + sage: from sage.numerical.gauss_legendre import nodes + sage: L1 = nodes(24, 53) + sage: P = RR['x'](sage.functions.orthogonal_polys.legendre_P(24, x)) + sage: Pdif = P.diff() + sage: L2 = [((r + 1)/2, 1/(1 - r^2)/Pdif(r)^2) + ....: for r, _ in RR['x'](P).roots()] + sage: all((a[0] - b[0]).abs() < 1e-15 and (a[1] - b[1]).abs() < 1e-9 + ....: for a, b in zip(L1, L2)) + True + + TESTS:: + + sage: from sage.numerical.gauss_legendre import nodes + sage: nodes(1,100) + Traceback (most recent call last): + ... + ValueError: degree=1 not supported (degree must be 3 or even) + + sage: from sage.numerical.gauss_legendre import nodes + sage: nodes(3,100) + [(0.11270166537925831148207346002, 0.27777777777777777777777777778), + (0.50000000000000000000000000000, 0.44444444444444444444444444444), + (0.88729833462074168851792653998, 0.27777777777777777777777777778)] + + """ + return nodes_uncached(degree, prec) + def estimate_error(results, prec, epsilon): r""" Routine to estimate the error in a list of quadrature approximations. @@ -253,7 +305,10 @@ def integrate_vector_N(f, prec, N=3): is over a field which is incompatible with this field (e.g. a finite field) then a TypeError occurs. """ - nodelist = nodes(N, prec) + # We use nodes_uncached, because caching takes up memory, and numerics in + # Bruin-DisneyHogg-Gao suggest that caching provides little benefit in the + # use in the Riemann surfaces module. + nodelist = nodes_uncached(N, prec) I = nodelist[0][1]*f(nodelist[0][0]) for i in range(1,len(nodelist)): I += nodelist[i][1]*f(nodelist[i][0]) @@ -311,13 +366,16 @@ def integrate_vector(f, prec, epsilon=None): if epsilon is None: epsilon = Rout(2)**(-prec+3) while True: - nodelist = nodes(degree,prec) + # We use nodes, because if this function is being called + # multiple times, then it will always go through the same degree + # values, so it will be very useful, approximately halving the runtime + nodelist = nodes(degree, prec) I = nodelist[0][1]*f(nodelist[0][0]) for i in range(1,len(nodelist)): I += nodelist[i][1]*f(nodelist[i][0]) results.append(I) if degree > 3: - err = estimate_error(results,prec,epsilon) + err = estimate_error(results, prec, epsilon) if err <= epsilon: return I #double the degree to double expected precision From b11b70dda785495ea2df777966608f5f14f836e8 Mon Sep 17 00:00:00 2001 From: "Linden Disney-Hogg (Work)" Date: Thu, 28 Apr 2022 20:18:02 +0100 Subject: [PATCH 238/529] Modify splitting method of rigorous_line_integral to be inline with new best technique --- .../riemann_surfaces/riemann_surface.py | 127 +++++++++--------- 1 file changed, 64 insertions(+), 63 deletions(-) diff --git a/src/sage/schemes/riemann_surfaces/riemann_surface.py b/src/sage/schemes/riemann_surfaces/riemann_surface.py index f9d1e2bdce6..45f3f9825a2 100644 --- a/src/sage/schemes/riemann_surfaces/riemann_surface.py +++ b/src/sage/schemes/riemann_surfaces/riemann_surface.py @@ -425,19 +425,6 @@ class RiemannSurface(object): sage: ct2 = time.time()-ct sage: ct2/ct1 # random 1.2429363969691192 - sage: p = 500 - sage: Sh = RiemannSurface(f, prec=p, integration_method='heuristic') - sage: Sr = RiemannSurface(f, prec=p, integration_method='rigorous') - sage: nodes.cache.clear() - sage: ct = time.time() - sage: Rh = Sh.riemann_matrix() # long time (6 seconds) - sage: ct1 = time.time()-ct - sage: nodes.cache.clear() - sage: ct = time.time() - sage: Rr = Sr.riemann_matrix() # long time (4 seconds) - sage: ct2 = time.time()-ct - sage: ct2/ct1 # random - 0.6627716056083879 This disparity in timings can get increasingly worse, and testing has shown that even for random quadrics the heuristic method can be as bad as 30 times @@ -1733,14 +1720,11 @@ def rigorous_line_integral(self, upstairs_edge, differentials, bounding_data): zwt, z1_minus_z0 = self.make_zw_interpolator(upstairs_edge) # list of (centre, radius) pairs that still need to be processed - ball_stack = [(self._RR(1/2), self._RR(1/2))] + ball_stack = [(self._RR(1/2), self._RR(1/2), 0)] alpha = self._RR(912/1000) # alpha set manually for scaling purposes. Basic benchmarking shows # that ~0.9 is a sensible value. E_global = self._RR(2)**(-self._prec+3) - K = 2 - # The parameter K could be tuned, but basic benchmarking seems to show - # that 2 is a sensible choice # Output will iteratively store the output of the integral. V = VectorSpace(self._CC, len(differentials)) @@ -1764,55 +1748,72 @@ def rigorous_line_integral(self, upstairs_edge, differentials, bounding_data): # loop does exactly this, repeatedly bisecting a segment if it is not # possible to cover it entirely in a ball which encompasses an appropriate # ellipse. - while ball_stack: - ct, rt = ball_stack.pop() + def local_N(ct, rt): cz = (1-ct)*z0+ct*z1 # This is the central z-value of our ball. - # Distance to the discriminant points distances = [(cz-b).abs() for b in self.branch_locus] rho_z = min(distances) - rho_t = rho_z/(z1-z0).abs() - if rho_t > rt: - rho_t = alpha*rho_t+(1-alpha)*rt # sqrt(rho_t*rt) could also work - rho_z = rho_t*(z1-z0).abs() - delta_z = (alpha*rho_t+(1-alpha)*rt)*(z1-z0).abs() - expr = rho_t/rt+((rho_t/rt)**2-1).sqrt() # Note this is really exp(arcosh(rho_t/rt)) - N = 3 - cw = zwt(ct)[1] - for g, dgdz, minpoly,(a0lc,a0roots) in bounding_data_list: - z_1 = a0lc.abs()*prod((cz-r).abs()-rho_z for r in a0roots) - n = minpoly.degree(CCzg.gen(1)) - # Note the structure of the code is currently s.t 'z' has to be the variable in - # the minpolys. - ai_new = [(minpoly.coefficient({CCzg.gen(1):i}))(z=cz+self._CCz.gen(0)) for i - in range(n)] - ai_pos = [ self._RRz([c.abs() for c in h.list()]) for h in ai_new] - m = [a(rho_z)/z_1 for a in ai_pos] - l = len(m) - M_tilde = 2*max((m[i].abs())**(1/self._RR(l-i)) for i in range(l)) - cg = g(cz,cw) - cdgdz = dgdz(cz,cg) - Delta = delta_z*cdgdz.abs()+ (delta_z**2)*M_tilde/(rho_z*(rho_z-delta_z)) - M = Delta - N_required = ((64*M/(15*(1-1/expr)*E_global)).log()/(2*expr.log())).ceil() - N = max(N,N_required) - - N = (K*(self._RR(N).sqrt()/K).ceil())**2 - # Rounding is sensible as it allows the cache of nodes in - # sage.numerical.gauss_legendre to be used. - # Quadratic rounding can be shown to be a sensible choice through the - # basic argument that nodes is quadratic in N - - ct_minus_rt = ct-rt - two_rt = 2*rt - def integrand(t): - zt, wt = zwt(ct_minus_rt+t*two_rt) - dfdwt = self._fastcall_dfdw(zt, wt) - return V([h(zt,wt)/dfdwt for h in differentials]) - - output += two_rt*integrate_vector_N(integrand, self._prec,N) - else: - ball_stack.append((ct-rt/2, rt/2)) - ball_stack.append((ct+rt/2, rt/2)) + rho_t = rho_z/(z1_minus_z0).abs() + rho_t = alpha*rho_t+(1-alpha)*rt # sqrt(rho_t*rt) could also work + rho_z = rho_t*(z1-z0).abs() + delta_z = (alpha*rho_t+(1-alpha)*rt)*(z1_minus_z0).abs() + expr = rho_t/rt+((rho_t/rt)**2-1).sqrt() # Note this is really exp(arcosh(rho_t/rt)) + Ni = 3 + cw = zwt(ct)[1] + for g, dgdz, minpoly,(a0lc,a0roots) in bounding_data_list: + z_1 = a0lc.abs()*prod((cz-r).abs()-rho_z for r in a0roots) + n = minpoly.degree(CCzg.gen(1)) + ai_new = [(minpoly.coefficient({CCzg.gen(1):i}))(z=cz+self._CCz.gen(0)) + for i in range(n)] + ai_pos = [self._RRz([c.abs() for c in h.list()]) + for h in ai_new] + m = [a(rho_z)/z_1 for a in ai_pos] + l = len(m) + M_tilde = 2*max((m[i].abs())**(1/self._RR(l-i)) + for i in range(l)) + cg = g(cz,cw) + cdgdz = dgdz(cz,cg) + Delta = delta_z*cdgdz.abs() + (delta_z**2)*M_tilde/(rho_z*(rho_z-delta_z)) + M = Delta + N_required = ((M*(self._RR.pi()+64/(15*(expr**2-1)))/E_global).log()/(2*expr.log())).ceil() + Ni = max(Ni, N_required) + return Ni + + while ball_stack: + ct, rt, lN = ball_stack.pop() + ncts = [ct-rt/2, ct+rt/2] + nrt = rt/2 + + if not lN: + cz = (1-ct)*z0+ct*z1 + distances = [(cz-b).abs() for b in self.branch_locus] + rho_z = min(distances) + rho_t = rho_z/(z1_minus_z0).abs() + + if rho_t <= rt: + ball_stack.append((ncts[0], nrt, 0)) + ball_stack.append((ncts[1], nrt, 0)) + continue + + lN = local_N(ct, rt) + + nNs = [local_N(nct, nrt) for nct in ncts] + + if sum(nNs) < lN: + ball_stack.append((ncts[0], nrt, nNs[0])) + ball_stack.append((ncts[1], nrt, nNs[1])) + continue + + if lN % 2 and not lN==3: + lN += 1 + + ct_minus_rt = ct-rt + two_rt = 2*rt + def integrand(t): + zt, wt = zwt(ct_minus_rt+t*two_rt) + dfdwt = self._fastcall_dfdw(zt, wt) + return V([h(zt,wt)/dfdwt for h in differentials]) + + output += two_rt*integrate_vector_N(integrand, self._prec, lN) return output*z1_minus_z0 From 3bf8620258a6c3431cea12ee2f65cbb0513535af Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Thu, 28 Apr 2022 21:51:26 +0000 Subject: [PATCH 239/529] Clean furo package description --- .vscode/settings.json | 3 +++ build/pkgs/furo/SPKG.rst | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 5844f80998f..c3f2f466c35 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -19,4 +19,7 @@ "src" ], "python.testing.unittestEnabled": false, + "cSpell.words": [ + "furo" + ], } diff --git a/build/pkgs/furo/SPKG.rst b/build/pkgs/furo/SPKG.rst index ebbd1bba238..368eff31748 100644 --- a/build/pkgs/furo/SPKG.rst +++ b/build/pkgs/furo/SPKG.rst @@ -1,10 +1,10 @@ -furo: A clean customisable Sphinx documentation theme. -====================================================== +furo: A clean customizable Sphinx documentation theme +===================================================== Description ----------- -A clean customisable Sphinx documentation theme. +A clean customizable Sphinx documentation theme. License ------- From d8a645fecaaf234635e31149cc61998302ed3998 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Fri, 29 Apr 2022 09:52:37 +0900 Subject: [PATCH 240/529] Added instancedoc.py to sagemath-objects/MANIFEST.in --- pkgs/sagemath-objects/MANIFEST.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkgs/sagemath-objects/MANIFEST.in b/pkgs/sagemath-objects/MANIFEST.in index fb7c047d6c6..ee82e1ae64c 100644 --- a/pkgs/sagemath-objects/MANIFEST.in +++ b/pkgs/sagemath-objects/MANIFEST.in @@ -62,7 +62,7 @@ include sage/misc/flatten.* # dep of sage/categories/coxeter_groups. include sage/misc/lazy_import*.* include sage/misc/sageinspect.* # dep of sage/misc/lazy_import -graft sage/docs # dep of sage/misc/lazy_import +include sage/misc/instancedoc.* # dep of sage/misc/lazy_import include sage/misc/persist.* include sage/misc/sage_unittest.* # dep of sage/misc/persist From 8b28eeace8e453b58562f05889d83b464e8aa420 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Sat, 9 Apr 2022 08:51:27 +0900 Subject: [PATCH 241/529] Upgrade to MathJax3 --- build/pkgs/mathjax/SPKG.rst | 7 +- build/pkgs/mathjax/checksums.ini | 6 +- build/pkgs/mathjax/package-version.txt | 2 +- build/pkgs/mathjax/spkg-src | 86 ++++++++++--------- .../sage-classic/static/mathjax_sage.js_t | 23 ----- src/doc/common/themes/sage-classic/theme.conf | 2 - src/sage/docs/conf.py | 64 +++++++++----- src/sage/misc/latex_macros.py | 36 ++++---- src/sage/misc/sagedoc.py | 1 - src/sage_docbuild/__init__.py | 1 - src/sage_docbuild/__main__.py | 5 ++ 11 files changed, 121 insertions(+), 112 deletions(-) delete mode 100644 src/doc/common/themes/sage-classic/static/mathjax_sage.js_t diff --git a/build/pkgs/mathjax/SPKG.rst b/build/pkgs/mathjax/SPKG.rst index e7c0a7edb27..9ffa178b269 100644 --- a/build/pkgs/mathjax/SPKG.rst +++ b/build/pkgs/mathjax/SPKG.rst @@ -6,7 +6,7 @@ Description MathJax is a JavaScript library for displaying mathematical formulas. -MathJax is used by the Jupyter notebook and the Sphinx documentation. +MathJax is used in the Sage documentation built by Sphinx. License ------- @@ -30,9 +30,8 @@ Special Update/Build Instructions None. + Patches ------- -- nopng_config.patch: prevent font warning messages since png files are - removed. See section "Trimming II -- not strictly necessary" of - https://github.com/mathjax/MathJax-docs/wiki/Guide%3A-reducing-size-of-a-mathjax-installation +None. diff --git a/build/pkgs/mathjax/checksums.ini b/build/pkgs/mathjax/checksums.ini index 4a2ee5ab7da..6a6b233b2ae 100644 --- a/build/pkgs/mathjax/checksums.ini +++ b/build/pkgs/mathjax/checksums.ini @@ -1,4 +1,4 @@ tarball=mathjax-VERSION.tar.gz -sha1=a1b31066a541167c65d6b43f24f3a06f03760662 -md5=02d1067dc06d9ca7d380457a49404766 -cksum=1204309472 +sha1=3f7abecf8cacd7f5d7f9ae6c3baca7739101c17d +md5=ba1a65ab58aaad6c84f39735c619bc34 +cksum=1142131398 diff --git a/build/pkgs/mathjax/package-version.txt b/build/pkgs/mathjax/package-version.txt index 65f95911c0b..944880fa15e 100644 --- a/build/pkgs/mathjax/package-version.txt +++ b/build/pkgs/mathjax/package-version.txt @@ -1 +1 @@ -2.7.4.p0 +3.2.0 diff --git a/build/pkgs/mathjax/spkg-src b/build/pkgs/mathjax/spkg-src index f77a8d88360..b1bfa4cdefe 100755 --- a/build/pkgs/mathjax/spkg-src +++ b/build/pkgs/mathjax/spkg-src @@ -4,13 +4,12 @@ set -e [ -n "${SAGE_ROOT}" ] || SAGE_ROOT="$(pwd)/../../../" - -# determine latest version. -GIT_VERSION="$(curl http://docs.mathjax.org/en/latest/installation.html | grep 'Current Version' | sed 's|^.*archive/||g' | sed 's/.zip".*//g')" +# determine the latest version +GIT_VERSION="$(curl https://github.com/mathjax/MathJax/releases | grep 'MathJax v' | head -1 | sed 's|^.*MathJax v||g' | sed 's/\s*$//g')" echo "GIT_VERSION=$GIT_VERSION" -# fetch and rename latest version. -URL="https://github.com/mathjax/MathJax/archive/${GIT_VERSION}.zip" +# fetch and rename the latest version +URL="https://github.com/mathjax/MathJax/archive/refs/tags/${GIT_VERSION}.zip" echo "Downloading $URL" rm -rf src if [ -z "$UPSTREAM_SOURCE_TARBALL" ]; then @@ -18,43 +17,52 @@ if [ -z "$UPSTREAM_SOURCE_TARBALL" ]; then else tar xzf "$UPSTREAM_SOURCE_TARBALL" fi -mv MathJax-${GIT_VERSION} src - -# Strip mathjax according to -# https://github.com/mathjax/MathJax-docs/wiki/Guide%3A-reducing-size-of-a-mathjax-installation - -# Trimming I -- removing files unnecessary for deployment -FILEDIRS_TO_REMOVE='docs/ test/ unpacked/ .gitignore README-branch.txt README.md bower.json' -for filedir in ${FILEDIRS_TO_REMOVE} ; do - rm -rf "src/${filedir}" -done - -# Trimming II -- not strictly necessary (requires the patch nopng_config.patch) -rm -rf 'src/fonts/HTML-CSS/TeX/png/' - -# Trimming III -- fonts -FONTS_TO_REMOVE='Asana-Math Gyre-Pagella Gyre-Termes Latin-Modern Neo-Euler' -for font in ${FONTS_TO_REMOVE} ; do - find . -type d -name "${font}" -prune -exec rm -rf {} \; -done - -FONT_FORMATS_TO_REMOVE='eot otf svg' -for fontformat in ${FONT_FORMATS_TO_REMOVE} ; do - find . -type d -name "${fontformat}" -prune -exec rm -rf {} \; -done - -# Trimming IV -- reducing input and output options -OUTPUT_OPTIONS_TO_REMOVE='NativeMML SVG' -for output in ${OUTPUT_OPTIONS_TO_REMOVE} ; do - rm -rf "src/jax/output/${output}" -done - -# repack -tar czf "$SAGE_ROOT/upstream/mathjax-${GIT_VERSION}.tar.gz" src + +# put files under mathjax directory +mkdir src +mv MathJax-${GIT_VERSION}/es5 src/mathjax +rm -r MathJax-${GIT_VERSION} + + +# The following block of commented-out lines were used to reduce the package +# size of MathJax2. We keep these lines for the future when we will want to +# reuse and rewrite them to remove unnecessary font files from MathJax3. + +## Trimming I -- removing files unnecessary for deployment +#FILEDIRS_TO_REMOVE='docs/ test/ unpacked/ .gitignore README-branch.txt README.md bower.json' +#for filedir in ${FILEDIRS_TO_REMOVE} ; do +# rm -rf "src/${filedir}" +#done +# +## Trimming II -- not strictly necessary (requires the patch nopng_config.patch) +#rm -rf 'src/fonts/HTML-CSS/TeX/png/' +# +## Trimming III -- fonts +#FONTS_TO_REMOVE='Asana-Math Gyre-Pagella Gyre-Termes Latin-Modern Neo-Euler' +#for font in ${FONTS_TO_REMOVE} ; do +# find . -type d -name "${font}" -prune -exec rm -rf {} \; +#done +# +#FONT_FORMATS_TO_REMOVE='eot otf svg' +#for fontformat in ${FONT_FORMATS_TO_REMOVE} ; do +# find . -type d -name "${fontformat}" -prune -exec rm -rf {} \; +#done +# +## Trimming IV -- reducing input and output options +#OUTPUT_OPTIONS_TO_REMOVE='NativeMML SVG' +#for output in ${OUTPUT_OPTIONS_TO_REMOVE} ; do +# rm -rf "src/jax/output/${output}" +#done + + +PACKAGE_VERSION=${GIT_VERSION} + +# repackage +tar czf "$SAGE_ROOT/upstream/mathjax-${PACKAGE_VERSION}.tar.gz" src rm -rf src # update package info -echo "${GIT_VERSION}" > 'package-version.txt' +echo "${PACKAGE_VERSION}" > 'package-version.txt' "$SAGE_ROOT"/sage --package fix-checksum mathjax diff --git a/src/doc/common/themes/sage-classic/static/mathjax_sage.js_t b/src/doc/common/themes/sage-classic/static/mathjax_sage.js_t deleted file mode 100644 index b261f2265a3..00000000000 --- a/src/doc/common/themes/sage-classic/static/mathjax_sage.js_t +++ /dev/null @@ -1,23 +0,0 @@ -MathJax.Hub.Config({ - imageFont: null, - tex2jax: { - inlineMath: [['$','$'],['\\(','\\)']], - processEscapes: true, - }, - styles: { - ".MathJax .mo, .MathJax .mi": { - color: "inherit ! important" - } - }, - TeX: { - MAXBUFFER: 50*1024, - - Macros: { - {{ theme_mathjax_macros|join(',\n') }} - } - } -}); - -// This path is a little funny because we have to load our local -// config file as '../mathjax_sage' in the theme conf.py -MathJax.Ajax.loadComplete("[MathJax]/config/../mathjax_sage.js") diff --git a/src/doc/common/themes/sage-classic/theme.conf b/src/doc/common/themes/sage-classic/theme.conf index cc6279a2633..fbde86a94ac 100644 --- a/src/doc/common/themes/sage-classic/theme.conf +++ b/src/doc/common/themes/sage-classic/theme.conf @@ -40,5 +40,3 @@ linkcolor = #45529B # Background color for code blocks: very pale yellow codebgcolor = #FFFFE5 -# MathJax settings filled in by conf.py -mathjax_macros = diff --git a/src/sage/docs/conf.py b/src/sage/docs/conf.py index be9c4fb278d..58db12dff41 100644 --- a/src/sage/docs/conf.py +++ b/src/sage/docs/conf.py @@ -4,7 +4,8 @@ import sys import os import sphinx -from sage.env import SAGE_DOC_SRC, SAGE_DOC, SAGE_SRC, THEBE_DIR, PPLPY_DOCS, MATHJAX_DIR +from sage.env import SAGE_DOC_SRC, SAGE_DOC, THEBE_DIR, PPLPY_DOCS, MATHJAX_DIR +from sage.misc.latex_macros import sage_mathjax_macros import sage.version from sage.misc.sagedoc import extlinks import dateutil.parser @@ -15,19 +16,23 @@ import sphinx.ext.intersphinx as intersphinx from IPython.lib.lexers import IPythonConsoleLexer, IPyLexer + # General configuration # --------------------- # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sage_docbuild.ext.inventory_builder', - 'sage_docbuild.ext.multidocs', - 'sage_docbuild.ext.sage_autodoc', - 'sphinx.ext.todo', - 'sphinx.ext.extlinks', - 'IPython.sphinxext.ipython_directive', - 'matplotlib.sphinxext.plot_directive', - 'jupyter_sphinx'] +extensions = [ + 'sage_docbuild.ext.inventory_builder', + 'sage_docbuild.ext.multidocs', + 'sage_docbuild.ext.sage_autodoc', + 'sphinx.ext.todo', + 'sphinx.ext.extlinks', + 'sphinx.ext.mathjax', + 'IPython.sphinxext.ipython_directive', + 'matplotlib.sphinxext.plot_directive', + 'jupyter_sphinx', +] jupyter_execute_default_kernel = 'sagemath' @@ -263,21 +268,36 @@ def set_intersphinx_mappings(app, config): html_common_static_path = [os.path.join(SAGE_DOC_SRC, 'common', 'static'), THEBE_DIR, 'static'] -# We use MathJax to build the documentation. -extensions.append('sphinx.ext.mathjax') -mathjax_path = 'MathJax.js?config=TeX-AMS_HTML-full,../mathjax_sage.js' - -from sage.misc.latex_macros import sage_mathjax_macros -html_theme_options['mathjax_macros'] = sage_mathjax_macros() +# Configure MathJax +# https://docs.mathjax.org/en/latest/options/input/tex.html +mathjax3_config = { + "tex": { + # Add custom sage macros + # http://docs.mathjax.org/en/latest/input/tex/macros.html + "macros": sage_mathjax_macros(), + # Add $...$ as possible inline math + # https://docs.mathjax.org/en/latest/input/tex/delimiters.html#tex-and-latex-math-delimiters + "inlineMath": [["$", "$"], ["\\(", "\\)"]], + # Increase the limit the size of the string to be processed + # https://docs.mathjax.org/en/latest/options/input/tex.html#option-descriptions + "maxBuffer": 50 * 1024, + # Use colorv2 extension instead of built-in color extension + # https://docs.mathjax.org/en/latest/input/tex/extensions/autoload.html#tex-autoload-options + # https://docs.mathjax.org/en/latest/input/tex/extensions/colorv2.html#tex-colorv2 + "autoload": {"color": [], "colorv2": ["color"]}, + }, +} -mathjax_relative = os.path.basename(MATHJAX_DIR) +if os.environ.get('SAGE_USE_CDNS', 'no') == 'yes': + mathjax_path = "https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js" +else: + mathjax_path = 'mathjax/tex-chtml.js' + html_common_static_path += [MATHJAX_DIR] -# It would be really nice if sphinx would copy the entire mathjax -# directory, (so we could have a _static/mathjax directory), rather than -# the contents of the directory -html_common_static_path.append(MATHJAX_DIR) -exclude_patterns += ['**/' + os.path.join(mathjax_relative, i) - for i in ('docs', 'README*', 'test', 'unpacked', 'LICENSE')] +# A list of glob-style patterns that should be excluded when looking for source +# files. They are matched against the source file names relative to the +# source directory, using slashes as directory separators on all platforms. +exclude_patterns = [] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. diff --git a/src/sage/misc/latex_macros.py b/src/sage/misc/latex_macros.py index eaaf77a0f18..1605d8a22f5 100644 --- a/src/sage/misc/latex_macros.py +++ b/src/sage/misc/latex_macros.py @@ -43,14 +43,16 @@ contain '\newcommand' lines for each of the entries in ``macros``. """ + def produce_latex_macro(name, *sample_args): r""" Produce a string defining a LaTeX macro. INPUT: - - ``name`` - name of macro to be defined, also name of corresponding Sage object - - ``sample_args`` - (optional) sample arguments for this Sage object + - ``name`` -- name of macro to be defined, also name of corresponding Sage object + + - ``sample_args`` -- (optional) sample arguments for this Sage object EXAMPLES:: @@ -108,37 +110,38 @@ def convert_latex_macro_to_mathjax(macro): INPUT: - - ``macro`` - LaTeX macro definition + - ``macro`` -- LaTeX macro definition See the web page - http://www.mathjax.org/docs/1.1/options/TeX.html for a + https://docs.mathjax.org/en/latest/input/tex/macros.html for a description of the format for MathJax macros. EXAMPLES:: sage: from sage.misc.latex_macros import convert_latex_macro_to_mathjax sage: convert_latex_macro_to_mathjax('\\newcommand{\\ZZ}{\\Bold{Z}}') - 'ZZ: "\\\\Bold{Z}"' + ('ZZ', '\\Bold{Z}') sage: convert_latex_macro_to_mathjax('\\newcommand{\\GF}[1]{\\Bold{F}_{#1}}') - 'GF: ["\\\\Bold{F}_{#1}",1]' + ('GF', ['\\Bold{F}_{#1}', 1]) """ left_bracket = macro.find('[') right_bracket = macro.find('[') if left_bracket >= 0: right_bracket = macro.find(']') - num_args = macro[left_bracket+1:right_bracket] + num_args = int(macro[left_bracket + 1 : right_bracket]) else: num_args = 0 start_name = macro.find('{') + 1 # add one to go past the backslash end_name = macro.find('}') - name = macro[start_name+1:end_name] + name = macro[start_name + 1 : end_name] start_defn = macro.find('{', end_name) end_defn = macro.rfind('}') - defn = macro[start_defn+1: end_defn].replace('\\', '\\\\') + defn = macro[start_defn + 1 : end_defn] if num_args == 0: - return name + ': "' + defn + '"' + return name, defn else: - return name + ': ["' + defn + '",' + str(num_args) + ']' + return name, [defn, num_args] + # To add a new macro for use in the Sage documentation, add a list or # tuple to the following list. Each list (or tuple) should have the @@ -176,6 +179,7 @@ def convert_latex_macro_to_mathjax(macro): # mathbf vs mathbb. See latex.py for more information. sage_configurable_latex_macros = [r"\newcommand{\Bold}[1]{\mathbf{#1}}"] + def sage_latex_macros(): r""" Return list of LaTeX macros for Sage. This just runs the function @@ -193,15 +197,15 @@ def sage_latex_macros(): def sage_mathjax_macros(): r""" - Return list of MathJax macro definitions for Sage as - JavaScript. This feeds each item output by - :func:`sage_latex_macros` to + Return Sage's macro definitions for usage with MathJax. + + This feeds each item output by :func:`sage_latex_macros` to :func:`convert_latex_macro_to_mathjax`. EXAMPLES:: sage: from sage.misc.latex_macros import sage_mathjax_macros sage: sage_mathjax_macros() - ['ZZ: "\\\\Bold{Z}"', 'NN: "\\\\Bold{N}"', ... + {'Bold': ['\\mathbf{#1}', 1], 'CC': '\\Bold{C}', ... """ - return [convert_latex_macro_to_mathjax(m) for m in sage_latex_macros()] + return dict(convert_latex_macro_to_mathjax(m) for m in sage_latex_macros()) diff --git a/src/sage/misc/sagedoc.py b/src/sage/misc/sagedoc.py index 6e326a1c329..37fd5d8b6e6 100644 --- a/src/sage/misc/sagedoc.py +++ b/src/sage/misc/sagedoc.py @@ -1486,7 +1486,6 @@ def __call__(self, obj, output='html', view=True): - diff --git a/src/sage_docbuild/__init__.py b/src/sage_docbuild/__init__.py index 8b137891791..e69de29bb2d 100644 --- a/src/sage_docbuild/__init__.py +++ b/src/sage_docbuild/__init__.py @@ -1 +0,0 @@ - diff --git a/src/sage_docbuild/__main__.py b/src/sage_docbuild/__main__.py index a46a858b11a..8c6e9031b82 100644 --- a/src/sage_docbuild/__main__.py +++ b/src/sage_docbuild/__main__.py @@ -303,6 +303,9 @@ def setup_parser(): standard.add_argument("--no-prune-empty-dirs", dest="no_prune_empty_dirs", action="store_true", help="do not prune empty directories in the documentation sources") + standard.add_argument("--use-cdns", dest="use_cdns", default=False, + action="store_true", + help="assume internet connection and use CDNs; in particular, use MathJax CDN") standard.add_argument("-N", "--no-colors", dest="color", action="store_false", help="do not color output; does not affect children") @@ -471,6 +474,8 @@ def excepthook(*exc_info): os.environ['SAGE_SKIP_PLOT_DIRECTIVE'] = 'yes' if args.skip_tests: os.environ['SAGE_SKIP_TESTS_BLOCKS'] = 'True' + if args.use_cdns: + os.environ['SAGE_USE_CDNS'] = 'yes' ABORT_ON_ERROR = not args.keep_going From c34be8ebf5653143da5efaab98049babe3641fe3 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Sat, 9 Apr 2022 11:43:07 +0900 Subject: [PATCH 242/529] Fix mathjax3 bug in website/templates/index.html --- src/doc/en/website/templates/index.html | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/doc/en/website/templates/index.html b/src/doc/en/website/templates/index.html index 5f34a99dc62..d8895243052 100644 --- a/src/doc/en/website/templates/index.html +++ b/src/doc/en/website/templates/index.html @@ -15,6 +15,13 @@ display: none; {%- endif %} } + table.contentstable { + align: center; + border-spacing: 20px; + } + table.contentstable span { {# trac #33600 comment:22 #} + border-spacing: initial; + } {% endblock %} @@ -33,7 +40,7 @@

      Tutorials and FAQ

      - +
    • Introduction to the p-adics

    • - """ - debug_inf(app, "???? Trying intersphinx for %s" % node['reftarget']) - builder = app.builder - res = intersphinx.missing_reference( - app, env, node, contnode) - if res: - # Replace absolute links to $SAGE_DOC by relative links: this - # allows to copy the whole documentation tree somewhere else - # without breaking links, see Trac #20118. - if res['refuri'].startswith(SAGE_DOC): - here = os.path.dirname(os.path.join(builder.outdir, - node['refdoc'])) - res['refuri'] = os.path.relpath(res['refuri'], here) - debug_inf(app, "++++ Found at %s" % res['refuri']) - else: - debug_inf(app, "---- Intersphinx: %s not Found" % node['reftarget']) - return res - -def find_sage_dangling_links(app, env, node, contnode): - r""" - Try to find dangling link in local module imports or all.py. - """ - debug_inf(app, "==================== find_sage_dangling_links ") - - reftype = node['reftype'] - reftarget = node['reftarget'] - try: - doc = node['refdoc'] - except KeyError: - debug_inf(app, "-- no refdoc in node %s" % node) - return None - - debug_inf(app, "Searching %s from %s"%(reftarget, doc)) - - # Workaround: in Python's doc 'object', 'list', ... are documented as a - # function rather than a class - if reftarget in base_class_as_func and reftype == 'class': - node['reftype'] = 'func' - - res = call_intersphinx(app, env, node, contnode) - if res: - debug_inf(app, "++ DONE %s"%(res['refuri'])) - return res - - if node.get('refdomain') != 'py': # not a python file - return None - - try: - module = node['py:module'] - cls = node['py:class'] - except KeyError: - debug_inf(app, "-- no module or class for :%s:%s"%(reftype, reftarget)) - return None - - basename = reftarget.split(".")[0] - try: - target_module = getattr(sys.modules['sage.all'], basename).__module__ - debug_inf(app, "++ found %s using sage.all in %s" % (basename, target_module)) - except AttributeError: - try: - target_module = getattr(sys.modules[node['py:module']], basename).__module__ - debug_inf(app, "++ found %s in this module" % (basename,)) - except AttributeError: - debug_inf(app, "-- %s not found in sage.all or this module" % (basename)) - return None - except KeyError: - target_module = None - if target_module is None: - target_module = "" - debug_inf(app, "?? found in None !!!") - - newtarget = target_module+'.'+reftarget - node['reftarget'] = newtarget - - # adapted from sphinx/domains/python.py - builder = app.builder - searchmode = node.hasattr('refspecific') and 1 or 0 - matches = builder.env.domains['py'].find_obj( - builder.env, module, cls, newtarget, reftype, searchmode) - if not matches: - debug_inf(app, "?? no matching doc for %s"%newtarget) - return call_intersphinx(app, env, node, contnode) - elif len(matches) > 1: - env.warn(target_module, - 'more than one target found for cross-reference ' - '%r: %s' % (newtarget, - ', '.join(match[0] for match in matches)), - node.line) - name, obj = matches[0] - debug_inf(app, "++ match = %s %s"%(name, obj)) - - from docutils import nodes - newnode = nodes.reference('', '', internal=True) - if name == target_module: - newnode['refid'] = name - else: - newnode['refuri'] = builder.get_relative_uri(node['refdoc'], obj[0]) - newnode['refuri'] += '#' + name - debug_inf(app, "++ DONE at URI %s"%(newnode['refuri'])) - newnode['reftitle'] = name - newnode.append(contnode) - return newnode - -# lists of basic Python class which are documented as functions -base_class_as_func = [ - 'bool', 'complex', 'dict', 'file', 'float', - 'frozenset', 'int', 'list', 'long', 'object', - 'set', 'slice', 'str', 'tuple', 'type', 'unicode', 'xrange'] - -# Nit picky option configuration: Put here broken links we want to ignore. For -# link to the Python documentation several links where broken because there -# where class listed as functions. Expand the list 'base_class_as_func' above -# instead of marking the link as broken. -nitpick_ignore = [ - ('py:class', 'twisted.web2.resource.Resource'), - ('py:class', 'twisted.web2.resource.PostableResource')] - -def nitpick_patch_config(app): - """ - Patch the default config for nitpicky - - Calling path_config ensure that nitpicky is not considered as a Sphinx - environment variable but rather as a Sage environment variable. As a - consequence, changing it doesn't force the recompilation of the entire - documentation. - """ - app.config.values['nitpicky'] = (False, 'sage') - app.config.values['nitpick_ignore'] = ([], 'sage') - -def skip_TESTS_block(app, what, name, obj, options, docstringlines): - """ - Skip blocks labeled "TESTS:". - - See sage.misc.sagedoc.skip_TESTS_block for more information. - """ - from sage.misc.sagedoc import skip_TESTS_block as sagedoc_skip_TESTS - if not docstringlines: - # No docstring, so don't do anything. See Trac #19932. - return - s = sagedoc_skip_TESTS("\n".join(docstringlines)) - lines = s.split("\n") - for i in range(len(lines)): - docstringlines[i] = lines[i] - while len(docstringlines) > len(lines): - del docstringlines[len(lines)] - -class SagemathTransform(Transform): - """ - Transform for code-blocks. - - This allows Sphinx to treat code-blocks with prompt "sage:" as - associated with the pycon lexer, and in particular, to change - "" to a blank line. - """ - default_priority = 500 - - def apply(self): - for node in self.document.traverse(nodes.literal_block): - if node.get('language') is None and node.astext().startswith('sage:'): - node['language'] = 'ipycon' - source = node.rawsource - source = blankline_re.sub('', source) - node.rawsource = source - node[:] = [nodes.Text(source)] - -from sage.misc.sageinspect import sage_getargspec -autodoc_builtin_argspec = sage_getargspec - -def setup(app): - app.connect('autodoc-process-docstring', process_docstring_cython) - app.connect('autodoc-process-docstring', process_directives) - app.connect('autodoc-process-docstring', process_docstring_module_title) - app.connect('autodoc-process-docstring', process_dollars) - app.connect('autodoc-process-docstring', process_inherited) - if os.environ.get('SAGE_SKIP_TESTS_BLOCKS', False): - app.connect('autodoc-process-docstring', skip_TESTS_block) - app.connect('autodoc-skip-member', skip_member) - app.add_transform(SagemathTransform) - - # When building the standard docs, app.srcdir is set to SAGE_DOC_SRC + - # 'LANGUAGE/DOCNAME', but when doing introspection, app.srcdir is - # set to a temporary directory. We don't want to use intersphinx, - # etc., when doing introspection. - if app.srcdir.startswith(SAGE_DOC_SRC): - app.add_config_value('intersphinx_mapping', {}, False) - app.add_config_value('intersphinx_cache_limit', 5, False) - app.add_config_value('intersphinx_disabled_reftypes', [], False) - app.connect('config-inited', set_intersphinx_mappings) - app.connect('builder-inited', intersphinx.load_mappings) - # We do *not* fully initialize intersphinx since we call it by hand - # in find_sage_dangling_links. - # app.connect('missing-reference', missing_reference) - app.connect('missing-reference', find_sage_dangling_links) - app.connect('builder-inited', nitpick_patch_config) - app.connect('html-page-context', add_page_context) +from sage_docbuild.conf import * diff --git a/src/sage_docbuild/conf.py b/src/sage_docbuild/conf.py index 13c969a0ec8..c0866c0af75 100644 --- a/src/sage_docbuild/conf.py +++ b/src/sage_docbuild/conf.py @@ -1,3 +1,4 @@ +import importlib import sys import os import sphinx @@ -162,10 +163,6 @@ def sphinx_plot(graphics, **kwds): # output. They are ignored by default. #show_authors = False -# The name of the Pygments (syntax highlighting) style to use. NOTE: -# This overrides a HTML theme's corresponding setting (see below). -pygments_style = 'sphinx' - # Default lexer to use when highlighting code blocks, using the IPython # console lexers. 'ipycon' is the IPython console, which is what we want # for most code blocks: anything with "sage:" prompts. For other IPython, @@ -224,19 +221,46 @@ def set_intersphinx_mappings(app, config): # Options for HTML output # ----------------------- - -# Sage default HTML theme. We use a custom theme to set a Pygments style, -# stylesheet, and insert MathJax macros. See the directory -# doc/common/themes/sage-classic/ for files comprising the custom theme. -html_theme = 'sage-classic' - -# Theme options are theme-specific and customize the look and feel of -# a theme further. For a list of options available for each theme, -# see the documentation. -html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -html_theme_path = [os.path.join(SAGE_DOC_SRC, 'common', 'themes')] +if importlib.util.find_spec("furo") is not None: + html_theme = "furo" + + # https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-html_static_path + html_static_path = [ + os.path.join(SAGE_DOC_SRC, "common", "themes", "sage-classic", "static") + ] + + html_theme_options = { + # Hide project’s name in the sidebar of the documentation; + # the logo is enough. + # https://pradyunsg.me/furo/customisation/#sidebar-hide-name + "sidebar_hide_name": True, + # Change accent (used for stylising links, sidebar’s content etc) + "light_css_variables": { + "color-brand-primary": "#0f0fff", + "color-brand-content": "#0f0fff", + }, + # Add sage logo to sidebar + # https://pradyunsg.me/furo/customisation/logo/#different-logos-for-light-and-dark-mode + "light_logo": "logo_sagemath_black.svg", + "dark_logo": "logo_sagemath.svg", + } +else: + # Sage default HTML theme. We use a custom theme to set a Pygments style, + # stylesheet, and insert MathJax macros. See the directory + # doc/common/themes/sage-classic/ for files comprising the custom theme. + html_theme = "sage-classic" + + # Add any paths that contain custom themes here, relative to this directory. + html_theme_path = [os.path.join(SAGE_DOC_SRC, "common", "themes")] + + # Theme options are theme-specific and customize the look and feel of + # a theme further. For a list of options available for each theme, + # see the documentation. + html_theme_options = {} + + # The name of the Pygments (syntax highlighting) style to use. NOTE: + # This overrides a HTML theme's corresponding setting (see below). + pygments_style = "sphinx" # HTML style sheet NOTE: This overrides a HTML theme's corresponding # setting. From b8882f2105662881e0220ad27197d864b33500b3 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 8 May 2022 05:46:53 -0700 Subject: [PATCH 367/529] build/pkgs/sagemath_objects/install-requires.txt: Update --- build/pkgs/sagemath_objects/install-requires.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/sagemath_objects/install-requires.txt b/build/pkgs/sagemath_objects/install-requires.txt index a94dfc6cb08..06766454a53 100644 --- a/build/pkgs/sagemath_objects/install-requires.txt +++ b/build/pkgs/sagemath_objects/install-requires.txt @@ -1,2 +1,2 @@ # Pinned in Trac #29941 until proper namespace packages are supported in #28925. -sagemath-objects == 9.6rc3.post3 +sagemath-objects == 9.6rc3.post4 From 560aedc459f4721336b10a3a36a08cc3e9fe1c1b Mon Sep 17 00:00:00 2001 From: Nils Bruin Date: Sun, 8 May 2022 22:33:39 -0700 Subject: [PATCH 368/529] set 'rigorous' to be the default integration method --- src/sage/schemes/riemann_surfaces/riemann_surface.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/schemes/riemann_surfaces/riemann_surface.py b/src/sage/schemes/riemann_surfaces/riemann_surface.py index 45f3f9825a2..48946af5f27 100644 --- a/src/sage/schemes/riemann_surfaces/riemann_surface.py +++ b/src/sage/schemes/riemann_surfaces/riemann_surface.py @@ -349,7 +349,7 @@ class RiemannSurface(object): For a nonsingular plane curve of degree `d`, an appropriate set is given by the monomials of degree up to `d-3`. - - ``integration_method`` -- (default: ``'heuristic'``). String specifying the + - ``integration_method`` -- (default: ``'rigorous'``). String specifying the integration method to use when calculating the integrals of differentials. The options are ``'heuristic'`` and ``'rigorous'``, the latter of which is often the most efficient. @@ -450,7 +450,7 @@ class RiemannSurface(object): sage: tau.algdep(6).degree() == 2 True """ - def __init__(self, f, prec=53, certification=True, differentials=None, integration_method="heuristic"): + def __init__(self, f, prec=53, certification=True, differentials=None, integration_method="rigorous"): r""" TESTS:: From 3f650721ac09c827a65423df58f9c13b1d9e605b Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Mon, 9 May 2022 10:34:41 +0200 Subject: [PATCH 369/529] make PermutationGroup_generic.orbits return a tuple of tuples, for immutability --- src/sage/groups/perm_gps/permgroup.py | 168 ++++++++++++++---------- src/sage/topology/simplicial_complex.py | 2 +- 2 files changed, 98 insertions(+), 72 deletions(-) diff --git a/src/sage/groups/perm_gps/permgroup.py b/src/sage/groups/perm_gps/permgroup.py index f10fb48f933..c23a5114e64 100644 --- a/src/sage/groups/perm_gps/permgroup.py +++ b/src/sage/groups/perm_gps/permgroup.py @@ -541,7 +541,7 @@ def construction(self): @cached_method def _has_natural_domain(self): """ - Returns True if the underlying domain is of the form (1,...,n) + Return whether the underlying domain is of the form (1,...,n) EXAMPLES:: @@ -560,7 +560,7 @@ def _has_natural_domain(self): def _gap_init_(self): r""" - Returns a string showing how to declare / initialize ``self`` in Gap. + Return a string showing how to declare / initialize ``self`` in Gap. Stored in the ``self._gap_string`` attribute. EXAMPLES: @@ -661,7 +661,7 @@ def _Hom_(self, G, category=None, check=True): def _magma_init_(self, magma): r""" - Returns a string showing how to declare / initialize self in Magma. + Return a string showing how to declare / initialize self in Magma. EXAMPLES: @@ -988,7 +988,7 @@ def list(self): def __contains__(self, item): """ - Returns boolean value of ``item in self``. + Return whether ``item`` is an element of this group. EXAMPLES:: @@ -1018,8 +1018,8 @@ def __contains__(self, item): def has_element(self, item): """ - Returns boolean value of ``item in self`` - however *ignores* - parentage. + Return whether ``item`` is an element of this group - + however *ignores* parentage. EXAMPLES:: @@ -1244,7 +1244,7 @@ def gens_small(self): def gen(self, i=None): r""" - Returns the i-th generator of ``self``; that is, the i-th element of + Return the i-th generator of ``self``; that is, the i-th element of the list ``self.gens()``. The argument `i` may be omitted if there is only one generator (but @@ -1371,7 +1371,7 @@ def largest_moved_point(self): def degree(self): """ - Returns the degree of this permutation group. + Return the degree of this permutation group. EXAMPLES:: @@ -1393,7 +1393,7 @@ def degree(self): def domain(self): r""" - Returns the underlying set that this permutation group acts + Return the underlying set that this permutation group acts on. EXAMPLES:: @@ -1409,8 +1409,12 @@ def domain(self): def _domain_gap(self, domain=None): """ - Returns a GAP string representation of the underlying set - that this group acts on. See also :meth:`domain`. + Return a GAP string representation of the underlying set + that this group acts on. + + .. SEEALSO:: + + - :meth:`domain` EXAMPLES:: @@ -1488,21 +1492,21 @@ def representative_action(self,x,y): @cached_method def orbits(self): """ - Returns the orbits of the elements of the domain under the + Return the orbits of the elements of the domain under the default group action. EXAMPLES:: sage: G = PermutationGroup([ [(3,4)], [(1,3)] ]) sage: G.orbits() - [[1, 3, 4], [2]] + ((1, 3, 4), (2,)) sage: G = PermutationGroup([[(1,2),(3,4)], [(1,2,3,4,10)]]) sage: G.orbits() - [[1, 2, 3, 4, 10], [5], [6], [7], [8], [9]] + ((1, 2, 3, 4, 10), (5,), (6,), (7,), (8,), (9,)) sage: G = PermutationGroup([ [('c','d')], [('a','c')],[('b',)]]) sage: G.orbits() - [['a', 'c', 'd'], ['b']] + (('a', 'c', 'd'), ('b',)) The answer is cached:: @@ -1514,8 +1518,8 @@ def orbits(self): - Nathan Dunfield """ orbits = self._libgap_().Orbits(libgap.eval(self._domain_gap())) - return [[self._domain_from_gap[x] for x in orbit] - for orbit in orbits.sage()] + return tuple(tuple(self._domain_from_gap[x] for x in orbit) + for orbit in orbits.sage()) @cached_method def orbit(self, point, action="OnPoints"): @@ -1767,14 +1771,18 @@ def stabilizer(self, point, action="OnPoints"): def base(self, seed=None): r""" - Returns a (minimum) base of this permutation group. A base $B$ - of a permutation group is a subset of the domain of the group - such that the only group element stabilizing all of $B$ is the - identity. + Return a (minimum) base of this permutation group. - The argument `seed` is optional and must be a subset of the domain - of `base`. When used, an attempt to create a base containing all or part - of `seed` will be made. + A base $B$ of a permutation group is a subset of the domain + of the group such that the only group element stabilizing all + of $B$ is the identity. + + INPUT: + + - ``seed`` (optional, default: ``None``), if given must be a + subset of the domain of `base`. When used, an attempt to + create a base containing all or part of `seed` will be + made. EXAMPLES:: @@ -1797,6 +1805,7 @@ def base(self, seed=None): [1, 2, 3, 4, 5] sage: S.base([1,3,5,7,9,11]) # create a base for M12 with only odd integers [1, 3, 5, 7, 9] + """ if seed is None: seed = self.domain() @@ -1974,7 +1983,7 @@ def strong_generating_system(self, base_of_group=None, implementation="sage"): def _repr_(self): r""" - Returns a string describing ``self``. + Return a string describing ``self``. EXAMPLES: @@ -2239,8 +2248,10 @@ def center(self): def socle(self): r""" - Returns the socle of ``self``. The socle of a group $G$ is - the subgroup generated by all minimal normal subgroups. + Return the socle of ``self``. + + The socle of a group $G$ is the subgroup generated by all + minimal normal subgroups. EXAMPLES:: @@ -2254,7 +2265,7 @@ def socle(self): def frattini_subgroup(self): r""" - Returns the Frattini subgroup of ``self``. + Return the Frattini subgroup of ``self``. The Frattini subgroup of a group $G$ is the intersection of all maximal subgroups of `G`. @@ -2273,7 +2284,7 @@ def frattini_subgroup(self): def fitting_subgroup(self): r""" - Returns the Fitting subgroup of ``self``. + Return the Fitting subgroup of ``self``. The Fitting subgroup of a group $G$ is the largest nilpotent normal subgroup of `G`. @@ -2292,9 +2303,10 @@ def fitting_subgroup(self): def solvable_radical(self): r""" - Returns the solvable radical of ``self``. The solvable - radical (or just radical) of a group $G$ is the largest - solvable normal subgroup of $G$. + Return the solvable radical of ``self``. + + The solvable radical (or just radical) of a group $G$ is the + largest solvable normal subgroup of $G$. EXAMPLES:: @@ -2310,7 +2322,7 @@ def solvable_radical(self): def intersection(self, other): r""" - Returns the permutation group that is the intersection of + Return the permutation group that is the intersection of ``self`` and ``other``. INPUT: @@ -2356,6 +2368,7 @@ def intersection(self, other): Traceback (most recent call last): ... TypeError: junk is not a permutation group + """ from sage.categories.finite_permutation_groups import FinitePermutationGroups @@ -2405,7 +2418,7 @@ def conjugacy_classes(self): def conjugate(self, g): r""" - Returns the group formed by conjugating ``self`` with ``g``. + Return the group formed by conjugating ``self`` with ``g``. INPUT: @@ -2759,7 +2772,7 @@ def holomorph(self): OUTPUT: - Returns the holomorph of a given group as permutation group + Return the holomorph of a given group as permutation group via a wrapping of GAP's semidirect product function. EXAMPLES: @@ -2972,7 +2985,7 @@ def as_finitely_presented_group(self, reduced=False): def quotient(self, N, **kwds): """ - Returns the quotient of this permutation group by the normal + Return the quotient of this permutation group by the normal subgroup `N`, as a permutation group. Further named arguments are passed to the permutation group constructor. @@ -2997,7 +3010,7 @@ def quotient(self, N, **kwds): def commutator(self, other=None): r""" - Returns the commutator subgroup of a group, or of a pair of groups. + Return the commutator subgroup of a group, or of a pair of groups. INPUT: @@ -3260,9 +3273,9 @@ def homology_part(self, n, p = 0): def character_table(self): r""" - Returns the matrix of values of the irreducible characters of a - permutation group `G` at the conjugacy classes of - `G`. + Return the matrix of values of the irreducible + characters of a permutation group `G` at the conjugacy + classes of `G`. The columns represent the conjugacy classes of `G` and the rows represent the different irreducible @@ -3357,7 +3370,7 @@ def character_table(self): def irreducible_characters(self): r""" - Returns a list of the irreducible characters of ``self``. + Return a list of the irreducible characters of ``self``. EXAMPLES:: @@ -3369,7 +3382,7 @@ def irreducible_characters(self): def trivial_character(self): r""" - Returns the trivial character of ``self``. + Return the trivial character of ``self``. EXAMPLES:: @@ -3381,7 +3394,7 @@ def trivial_character(self): def character(self, values): r""" - Returns a group character from ``values``, where ``values`` is + Return a group character from ``values``, where ``values`` is a list of the values of the character evaluated on the conjugacy classes. @@ -3396,7 +3409,7 @@ def character(self, values): def conjugacy_classes_representatives(self): """ - Returns a complete list of representatives of conjugacy classes in + Return a complete list of representatives of conjugacy classes in a permutation group `G`. The ordering is that given by GAP. @@ -3430,7 +3443,7 @@ def conjugacy_classes_representatives(self): def conjugacy_classes_subgroups(self): """ - Returns a complete list of representatives of conjugacy classes of + Return a complete list of representatives of conjugacy classes of subgroups in a permutation group `G`. The ordering is that given by GAP. @@ -3467,7 +3480,7 @@ def conjugacy_classes_subgroups(self): def subgroups(self): r""" - Returns a list of all the subgroups of ``self``. + Return a list of all the subgroups of ``self``. OUTPUT: @@ -3600,7 +3613,7 @@ def has_regular_subgroup(self, return_group = False): def blocks_all(self, representatives = True): r""" - Returns the list of block systems of imprimitivity. + Return the list of block systems of imprimitivity. For more information on primitivity, see the :wikipedia:`Wikipedia article on primitive group actions `. @@ -3675,7 +3688,7 @@ def blocks_all(self, representatives = True): def cosets(self, S, side='right'): r""" - Returns a list of the cosets of ``S`` in ``self``. + Return a list of the cosets of ``S`` in ``self``. INPUT: @@ -3865,7 +3878,7 @@ def minimal_generating_set(self): def normalizer(self, g): """ - Returns the normalizer of ``g`` in ``self``. + Return the normalizer of ``g`` in ``self``. EXAMPLES:: @@ -3884,7 +3897,7 @@ def normalizer(self, g): def centralizer(self, g): """ - Returns the centralizer of ``g`` in ``self``. + Return the centralizer of ``g`` in ``self``. EXAMPLES:: @@ -4087,7 +4100,7 @@ def is_isomorphic(self, right): def is_monomial(self): """ - Returns ``True`` if the group is monomial. A finite group is monomial + Return ``True`` if the group is monomial. A finite group is monomial if every irreducible complex character is induced from a linear character of a subgroup. @@ -4148,16 +4161,18 @@ def is_perfect(self): return bool(self._libgap_().IsPerfectGroup()) def is_pgroup(self): - """ - Returns ``True`` if this group is a `p`-group. A finite group is - a `p`-group if its order is of the form `p^n` for a prime integer - `p` and a nonnegative integer `n`. + r""" + Return ``True`` if this group is a `p`-group. + + A finite group is a `p`-group if its order is of the form + `p^n` for a prime integer `p` and a nonnegative integer `n`. EXAMPLES:: sage: G = PermutationGroup(['(1,2,3,4,5)']) sage: G.is_pgroup() True + """ return bool(self._libgap_().IsPGroup()) @@ -4181,20 +4196,22 @@ def is_polycyclic(self): def is_simple(self): """ - Returns ``True`` if the group is simple. A group is simple if it has no - proper normal subgroups. + Return ``True`` if the group is simple. + + A group is simple if it has no proper normal subgroups. EXAMPLES:: sage: G = PermutationGroup(['(1,2,3)(4,5)']) sage: G.is_simple() False + """ return bool(self._libgap_().IsSimpleGroup()) def is_solvable(self): """ - Returns ``True`` if the group is solvable. + Return ``True`` if the group is solvable. EXAMPLES:: @@ -4206,7 +4223,7 @@ def is_solvable(self): def is_subgroup(self, other): """ - Returns ``True`` if ``self`` is a subgroup of ``other``. + Return ``True`` if ``self`` is a subgroup of ``other``. EXAMPLES:: @@ -4219,8 +4236,10 @@ def is_subgroup(self, other): def is_supersolvable(self): """ - Returns ``True`` if the group is supersolvable. A finite group is - supersolvable if it has a normal series with cyclic factors. + Return ``True`` if the group is supersolvable. + + A finite group is supersolvable if it has a normal series + with cyclic factors. EXAMPLES:: @@ -4274,7 +4293,8 @@ def fixed_points(self): def is_transitive(self, domain=None): r""" - Returns ``True`` if ``self`` acts transitively on ``domain``. + Return ``True`` if ``self`` acts transitively on ``domain``. + A group $G$ acts transitively on set $S$ if for all `x,y\in S` there is some `g\in G` such that `x^g=y`. @@ -4323,7 +4343,8 @@ def is_transitive(self, domain=None): def is_primitive(self, domain=None): r""" - Returns ``True`` if ``self`` acts primitively on ``domain``. + Return ``True`` if ``self`` acts primitively on ``domain``. + A group $G$ acts primitively on a set $S$ if 1. $G$ acts transitively on $S$ and @@ -4372,7 +4393,8 @@ def is_primitive(self, domain=None): def is_semi_regular(self, domain=None): r""" - Returns ``True`` if ``self`` acts semi-regularly on ``domain``. + Return ``True`` if ``self`` acts semi-regularly on ``domain``. + A group $G$ acts semi-regularly on a set $S$ if the point stabilizers of $S$ in $G$ are trivial. @@ -4404,7 +4426,8 @@ def is_semi_regular(self, domain=None): def is_regular(self, domain=None): r""" - Returns ``True`` if ``self`` acts regularly on ``domain``. + Return ``True`` if ``self`` acts regularly on ``domain``. + A group $G$ acts regularly on a set $S$ if 1. $G$ acts transitively on $S$ and @@ -4437,7 +4460,8 @@ def is_regular(self, domain=None): def normalizes(self, other): r""" - Returns ``True`` if the group ``other`` is normalized by ``self``. + Return ``True`` if the group ``other`` is normalized by ``self``. + Wraps GAP's ``IsNormal`` function. A group `G` normalizes a group `U` if and only if for every @@ -4665,9 +4689,11 @@ def poincare_series(self, p=2, n=10): def sylow_subgroup(self, p): """ - Returns a Sylow `p`-subgroup of the finite group `G`, where `p` is a - prime. This is a `p`-subgroup of `G` whose index in `G` is coprime to - `p`. + Return a Sylow `p`-subgroup of the finite group `G`, where `p` is a + prime. + + This is a `p`-subgroup of `G` whose index in `G` is coprime + to `p`. Wraps the GAP function ``SylowSubgroup``. @@ -4686,6 +4712,7 @@ def sylow_subgroup(self, p): sage: PSL(10,2).sylow_subgroup(7) Subgroup generated by... + """ return self.subgroup(gap_group=self._libgap_().SylowSubgroup(p)) @@ -4904,8 +4931,7 @@ def __richcmp__(self, other, op): def _repr_(self): r""" - Returns a string representation / description of the permutation - subgroup. + Return a string describing the permutation subgroup. EXAMPLES: diff --git a/src/sage/topology/simplicial_complex.py b/src/sage/topology/simplicial_complex.py index 1f154ffd201..e41c35e3552 100644 --- a/src/sage/topology/simplicial_complex.py +++ b/src/sage/topology/simplicial_complex.py @@ -4261,7 +4261,7 @@ def fixed_complex(self, G): gens = G G = self.automorphism_group().subgroup(gens) - invariant_f = [list(u) for u in self.face_iterator() + invariant_f = [tuple(u) for u in self.face_iterator() if all(sorted(sigma(j) for j in u) == sorted(u) for sigma in gens)] new_verts = [min(o) for o in G.orbits() if o in invariant_f] From 87f360ca7a4703b6c45ad3427363ccf4ae531b2c Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Mon, 9 May 2022 11:47:37 +0000 Subject: [PATCH 370/529] Readd name arg --- src/doc/en/installation/conda.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/doc/en/installation/conda.rst b/src/doc/en/installation/conda.rst index 36b1834cca3..b9f70332a0d 100644 --- a/src/doc/en/installation/conda.rst +++ b/src/doc/en/installation/conda.rst @@ -62,7 +62,7 @@ from source as follows: - Create a new conda environment including all standard packages recognized by sage, and activate it:: - $ conda env create --file environment.yml + $ conda env create --file environment.yml --name sage-build $ conda activate sage-build Alternatively, use ``environment-optional.yml`` in place of @@ -98,7 +98,7 @@ Here we assume that you are using a git checkout. $ export SAGE_NUM_THREADS=24 - - As a recommended step, install the ``mamba`` package manager. If + - As a recommended step, install the ``mamba`` package manager. If you skip this step, replace ``mamba`` by ``conda`` in the following steps:: @@ -112,7 +112,7 @@ Here we assume that you are using a git checkout. - Create and activate a new conda environment with the dependencies of Sage and a few additional developer tools:: - $ mamba env create --file src/environment-dev.yml + $ mamba env create --file src/environment-dev.yml --name sage-dev $ conda activate sage-dev Alternatively, you can use ``src/environment.yml`` or @@ -121,7 +121,7 @@ Here we assume that you are using a git checkout. By default, the most recent version of Python supported by Sage is installed. You can use the additional option ``python=3.9`` in the above - ``env create`` command to use another Python version (here 3.9). + ``env create`` command to select another Python version (here 3.9). - Run the ``configure`` script:: From cc19e927a49efbd31d693b2f70bad48203ea8a25 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Mon, 9 May 2022 12:35:35 +0000 Subject: [PATCH 371/529] Specify importlib as import mode to be consistent --- src/conftest.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/conftest.py b/src/conftest.py index 5ec6bc953b9..f12f0aa0cbc 100644 --- a/src/conftest.py +++ b/src/conftest.py @@ -22,7 +22,7 @@ _patch_unwrap_mock_aware, get_optionflags, ) -from _pytest.pathlib import import_path +from _pytest.pathlib import import_path, ImportMode # Import sage.all is necessary to: # - avoid cyclic import errors, see Trac #33580 @@ -90,7 +90,11 @@ def _find( ) else: try: - module = import_path(self.path, root=self.config.rootpath) + module = import_path( + self.path, + mode=ImportMode.importlib, + root=self.config.rootpath, + ) except ImportError: if self.config.getvalue("doctest_ignore_import_errors"): pytest.skip("unable to import module %r" % self.path) From d5f83fd8279263eedd87468350952518fc0a5b09 Mon Sep 17 00:00:00 2001 From: Sebastian Oehms Date: Mon, 9 May 2022 17:29:10 +0200 Subject: [PATCH 372/529] 27522: typo --- src/sage/knots/link.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/knots/link.py b/src/sage/knots/link.py index ad63b313dc0..5769ef7557f 100644 --- a/src/sage/knots/link.py +++ b/src/sage/knots/link.py @@ -1917,7 +1917,7 @@ def conway_polynomial(self): This is closely related to the Alexander polynomial. - See : wikipedia:`Alexander_polynomial` for the definition. + See :wikipedia:`Alexander_polynomial` for the definition. EXAMPLES:: From da2c2e5b60c08f6a127be34cb08331d674f667db Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Mon, 9 May 2022 19:18:50 +0200 Subject: [PATCH 373/529] make PermutationGroup_generic.gens return a tuple, to ensure immutability --- src/sage/categories/pushout.py | 6 ++-- .../coding/codecan/autgroup_can_label.pyx | 8 +++--- src/sage/graphs/generic_graph.py | 22 +++++++-------- src/sage/groups/perm_gps/permgroup.py | 28 +++++++++---------- .../groups/perm_gps/permgroup_morphism.py | 2 +- src/sage/groups/perm_gps/permgroup_named.py | 16 +++++------ .../polynomial/polynomial_rational_flint.pyx | 2 +- .../judson-abstract-algebra/actions-sage.py | 4 +-- .../judson-abstract-algebra/galois-sage.py | 20 ++++++------- .../homomorph-sage-exercises.py | 2 +- .../judson-abstract-algebra/homomorph-sage.py | 6 ++-- 11 files changed, 58 insertions(+), 58 deletions(-) diff --git a/src/sage/categories/pushout.py b/src/sage/categories/pushout.py index f4bb28d14e1..f8aa1aa646a 100644 --- a/src/sage/categories/pushout.py +++ b/src/sage/categories/pushout.py @@ -3522,7 +3522,7 @@ def __init__(self, gens, domain): PermutationGroupFunctor[(1,2)] """ Functor.__init__(self, Groups(), Groups()) - self._gens = gens + self._gens = tuple(gens) self._domain = domain def _repr_(self): @@ -3534,7 +3534,7 @@ def _repr_(self): sage: PF PermutationGroupFunctor[(1,2)] """ - return "PermutationGroupFunctor%s" % self.gens() + return "PermutationGroupFunctor%s" % list(self.gens()) def __call__(self, R): """ @@ -3556,7 +3556,7 @@ def gens(self): sage: P1 = PermutationGroup([[(1,2)]]) sage: PF, P = P1.construction() sage: PF.gens() - [(1,2)] + ((1,2),) """ return self._gens diff --git a/src/sage/coding/codecan/autgroup_can_label.pyx b/src/sage/coding/codecan/autgroup_can_label.pyx index 5ed4459e7cf..de5db985e0b 100644 --- a/src/sage/coding/codecan/autgroup_can_label.pyx +++ b/src/sage/coding/codecan/autgroup_can_label.pyx @@ -73,10 +73,10 @@ columns do share the same coloring:: sage: A = [a.get_perm() for a in P.get_autom_gens()] sage: H = SymmetricGroup(21).subgroup(A) sage: H.orbits() - [[1], - [2], - [3, 5, 4], - [6, 19, 16, 9, 21, 10, 8, 15, 14, 11, 20, 13, 12, 7, 17, 18]] + ((1,), + (2,), + (3, 5, 4), + (6, 19, 16, 9, 21, 10, 8, 15, 14, 11, 20, 13, 12, 7, 17, 18)) We can also restrict the group action to linear isometries:: diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index a57e74c632a..93aa33714ac 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -22250,17 +22250,17 @@ def automorphism_group(self, partition=None, verbosity=0, sage: for g in L: ....: G = g.automorphism_group() ....: G.order(), G.gens() - (24, [(2,3), (1,2), (0,1)]) - (4, [(2,3), (0,1)]) - (2, [(1,2)]) - (6, [(1,2), (0,1)]) - (6, [(2,3), (1,2)]) - (8, [(1,2), (0,1)(2,3)]) - (2, [(0,1)(2,3)]) - (2, [(1,2)]) - (8, [(2,3), (0,1), (0,2)(1,3)]) - (4, [(2,3), (0,1)]) - (24, [(2,3), (1,2), (0,1)]) + (24, ((2,3), (1,2), (0,1))) + (4, ((2,3), (0,1))) + (2, ((1,2),)) + (6, ((1,2), (0,1))) + (6, ((2,3), (1,2))) + (8, ((1,2), (0,1)(2,3))) + (2, ((0,1)(2,3),)) + (2, ((1,2),)) + (8, ((2,3), (0,1), (0,2)(1,3))) + (4, ((2,3), (0,1))) + (24, ((2,3), (1,2), (0,1))) sage: C = graphs.CubeGraph(4) sage: G = C.automorphism_group() sage: M = G.character_table() # random order of rows, thus abs() below diff --git a/src/sage/groups/perm_gps/permgroup.py b/src/sage/groups/perm_gps/permgroup.py index c23a5114e64..4f2c01eb68c 100644 --- a/src/sage/groups/perm_gps/permgroup.py +++ b/src/sage/groups/perm_gps/permgroup.py @@ -292,7 +292,7 @@ def PermutationGroup(gens=None, *args, **kwds): sage: H = PermutationGroup(G); H Transitive group number 3 of degree 4 sage: H.gens() - [(1,2,3,4), (1,3)] + ((1,2,3,4), (1,3)) We can also create permutation groups whose generators are Gap permutation objects:: @@ -486,9 +486,9 @@ def __init__(self, gens=None, gap_group=None, canonicalize=True, if not gens: # length 0 gens = [()] - gens = [self.element_class(x, self, check=False) for x in gens] + gens = tuple(self.element_class(x, self, check=False) for x in gens) if canonicalize: - gens = sorted(set(gens)) + gens = tuple(sorted(set(gens))) self._gens = gens _libgap = None @@ -1181,14 +1181,14 @@ def gens(self): sage: G = PermutationGroup([[(1,2,3)], [(1,2)]]) sage: G.gens() - [(1,2), (1,2,3)] + ((1,2), (1,2,3)) Note that the generators need not be minimal, though duplicates are removed:: sage: G = PermutationGroup([[(1,2)], [(1,3)], [(2,3)], [(1,2)]]) sage: G.gens() - [(2,3), (1,2), (1,3)] + ((2,3), (1,2), (1,3)) We can use index notation to access the generators returned by ``self.gens``:: @@ -1258,7 +1258,7 @@ def gen(self, i=None): sage: A4 = PermutationGroup([[(1,2,3)],[(2,3,4)]]); A4 Permutation Group with generators [(2,3,4), (1,2,3)] sage: A4.gens() - [(2,3,4), (1,2,3)] + ((2,3,4), (1,2,3)) sage: A4.gen(0) (2,3,4) sage: A4.gen(1) @@ -1998,7 +1998,7 @@ def _repr_(self): sage: AlternatingGroup(4)._repr_() 'Alternating group of order 4!/2 as a permutation group' """ - return "Permutation Group with generators %s"%self.gens() + return "Permutation Group with generators %s" % list(self.gens()) def _latex_(self): r""" @@ -2645,7 +2645,7 @@ def semidirect_product(self, N, mapping, check=True): sage: S.is_isomorphic(DihedralGroup(8)) True sage: S.gens() - [(3,4,5,6,7,8,9,10), (1,2)(4,10)(5,9)(6,8)] + ((3,4,5,6,7,8,9,10), (1,2)(4,10)(5,9)(6,8)) A more complicated example can be drawn from [TW1980]_. It is there given that a semidirect product of $D_4$ and $C_3$ @@ -2745,7 +2745,7 @@ def semidirect_product(self, N, mapping, check=True): raise ValueError(msg) # create a parallel list of the automorphisms of N in GAP - libgap.eval('N := Group({})'.format(N.gens())) + libgap.eval('N := Group({})'.format(list(N.gens()))) gens_string = ",".join(str(x) for x in N.gens()) homomorphism_cmd = 'alpha := GroupHomomorphismByImages(N, N, [{0}],[{1}])' libgap.eval('morphisms := []') @@ -2799,7 +2799,7 @@ def holomorph(self): sage: D4 = DihedralGroup(4) sage: H = D4.holomorph() sage: H.gens() - [(3,8)(4,7), (2,3,5,8), (2,5)(3,8), (1,4,6,7)(2,3,5,8), (1,8)(2,7)(3,6)(4,5)] + ((3,8)(4,7), (2,3,5,8), (2,5)(3,8), (1,4,6,7)(2,3,5,8), (1,8)(2,7)(3,6)(4,5)) sage: G = H.subgroup([H.gens()[0],H.gens()[1],H.gens()[2]]) sage: N = H.subgroup([H.gens()[3],H.gens()[4]]) sage: N.is_normal(H) @@ -2820,7 +2820,7 @@ def holomorph(self): - Kevin Halasz (2012-08-14) """ - libgap.eval('G := Group({})'.format(self.gens())) + libgap.eval('G := Group({})'.format(list(self.gens()))) libgap.eval('aut := AutomorphismGroup(G)') libgap.eval('alpha := InverseGeneralMapping(NiceMonomorphism(aut))') libgap.eval('product := SemidirectProduct(NiceObject(aut),alpha,G)') @@ -4777,7 +4777,7 @@ class PermutationGroup_subgroup(PermutationGroup_generic): sage: K.ambient_group() Dihedral group of order 8 as a permutation group sage: K.gens() - [(1,2,3,4)] + ((1,2,3,4),) """ def __init__(self, ambient, gens=None, gap_group=None, domain=None, category=None, canonicalize=True, check=True): @@ -4809,7 +4809,7 @@ def __init__(self, ambient, gens=None, gap_group=None, domain=None, sage: G = DihedralGroup(4) sage: H = CyclicPermutationGroup(4) sage: gens = H.gens(); gens - [(1,2,3,4)] + ((1,2,3,4),) sage: S = G.subgroup(gens) sage: S Subgroup generated by [(1,2,3,4)] of (Dihedral group of order 8 as a permutation group) @@ -4947,7 +4947,7 @@ def _repr_(self): sage: S._repr_() 'Subgroup generated by [(1,2,3,4)] of (Dihedral group of order 8 as a permutation group)' """ - return "Subgroup generated by %s of (%s)" % (self.gens(), self.ambient_group()) + return "Subgroup generated by %s of (%s)" % (list(self.gens()), self.ambient_group()) def _latex_(self): r""" diff --git a/src/sage/groups/perm_gps/permgroup_morphism.py b/src/sage/groups/perm_gps/permgroup_morphism.py index 6206aad34d0..d190df81614 100644 --- a/src/sage/groups/perm_gps/permgroup_morphism.py +++ b/src/sage/groups/perm_gps/permgroup_morphism.py @@ -281,7 +281,7 @@ def _repr_defn(self): sage: phi._repr_defn() '[(1,2,3,4)] -> [(1,2,3,4)]' """ - return "%s -> %s"%(self.domain().gens(), self._images) + return "%s -> %s"%(list(self.domain().gens()), self._images) def _gap_(self): """ diff --git a/src/sage/groups/perm_gps/permgroup_named.py b/src/sage/groups/perm_gps/permgroup_named.py index 51b5f96521c..703251d8d34 100644 --- a/src/sage/groups/perm_gps/permgroup_named.py +++ b/src/sage/groups/perm_gps/permgroup_named.py @@ -1191,7 +1191,7 @@ class GeneralDihedralGroup(PermutationGroup_generic): sage: G.order() 18 sage: G.gens() - [(4,5,6), (2,3)(5,6), (1,2,3)] + ((4,5,6), (2,3)(5,6), (1,2,3)) sage: a = G.gens()[2]; b = G.gens()[0]; c = G.gens()[1] sage: a.order() == 3, b.order() == 3, c.order() == 2 (True, True, True) @@ -1212,7 +1212,7 @@ class GeneralDihedralGroup(PermutationGroup_generic): sage: G.order() 16 sage: G.gens() - [(7,8), (5,6), (3,4), (1,2)] + ((7,8), (5,6), (3,4), (1,2)) sage: G.is_abelian() True sage: H = KleinFourGroup() @@ -1385,10 +1385,10 @@ def __init__(self, n): sage: DihedralGroup(2) Dihedral group of order 4 as a permutation group sage: DihedralGroup(2).gens() - [(3,4), (1,2)] + ((3,4), (1,2)) sage: DihedralGroup(5).gens() - [(1,2,3,4,5), (1,5)(2,4)] + ((1,2,3,4,5), (1,5)(2,4)) sage: sorted(DihedralGroup(5)) [(), (2,5)(3,4), (1,2)(3,5), (1,2,3,4,5), (1,3)(4,5), (1,3,5,2,4), (1,4)(2,3), (1,4,2,5,3), (1,5,4,3,2), (1,5)(2,4)] @@ -1401,7 +1401,7 @@ def __init__(self, n): sage: G Dihedral group of order 10 as a permutation group sage: G.gens() - [(1,2,3,4,5), (1,5)(2,4)] + ((1,2,3,4,5), (1,5)(2,4)) sage: DihedralGroup(0) Traceback (most recent call last): @@ -1644,7 +1644,7 @@ def __init__(self,m): sage: len([H for H in G.subgroups() if H.is_cyclic() and H.order() == 8]) 1 sage: G.gens() - [(2,4)(3,7)(6,8), (1,2,3,4,5,6,7,8)] + ((2,4)(3,7)(6,8), (1,2,3,4,5,6,7,8)) sage: x = G.gens()[1]; y = G.gens()[0] sage: x.order() == 2^3; y.order() == 2 True @@ -1783,7 +1783,7 @@ def __init__(self, d, n): sage: G = TransitiveGroup(5, 2); G Transitive group number 2 of degree 5 sage: G.gens() - [(1,2,3,4,5), (1,4)(2,3)] + ((1,2,3,4,5), (1,4)(2,3)) sage: G.category() Category of finite enumerated permutation groups @@ -2170,7 +2170,7 @@ class PrimitiveGroup(PermutationGroup_unique): sage: G = PrimitiveGroup(5, 2); G D(2*5) sage: G.gens() - [(2,4)(3,5), (1,2,3,5,4)] + ((2,4)(3,5), (1,2,3,5,4)) sage: G.category() Category of finite enumerated permutation groups diff --git a/src/sage/rings/polynomial/polynomial_rational_flint.pyx b/src/sage/rings/polynomial/polynomial_rational_flint.pyx index b54383a8637..cfe230ad974 100644 --- a/src/sage/rings/polynomial/polynomial_rational_flint.pyx +++ b/src/sage/rings/polynomial/polynomial_rational_flint.pyx @@ -2107,7 +2107,7 @@ cdef class Polynomial_rational_flint(Polynomial): sage: G = f.galois_group(); G Transitive group number 5 of degree 4 sage: G.gens() - [(1,2), (1,2,3,4)] + ((1,2), (1,2,3,4)) sage: G.order() 24 diff --git a/src/sage/tests/books/judson-abstract-algebra/actions-sage.py b/src/sage/tests/books/judson-abstract-algebra/actions-sage.py index bc26e3e56a1..98eb03fcc64 100644 --- a/src/sage/tests/books/judson-abstract-algebra/actions-sage.py +++ b/src/sage/tests/books/judson-abstract-algebra/actions-sage.py @@ -152,7 +152,7 @@ ~~~~~~~~~~~~~~~~~~~~~~ :: sage: A.orbits() - [[0, 10], [1, 9], [2, 8], [3, 7], [4, 6], [5]] + ((0, 10), (1, 9), (2, 8), (3, 7), (4, 6), (5,)) ~~~~~~~~~~~~~~~~~~~~~~ :: @@ -169,6 +169,6 @@ sage: G = SymmetricGroup(4) sage: S = G.stabilizer(4) sage: S.orbits() - [[1, 2, 3], [4]] + ((1, 2, 3), (4,)) """ diff --git a/src/sage/tests/books/judson-abstract-algebra/galois-sage.py b/src/sage/tests/books/judson-abstract-algebra/galois-sage.py index 6996d34012d..036b0a390c0 100644 --- a/src/sage/tests/books/judson-abstract-algebra/galois-sage.py +++ b/src/sage/tests/books/judson-abstract-algebra/galois-sage.py @@ -265,16 +265,16 @@ sage: sg = P.subgroups() sage: [H.gens() for H in sg] - [[()], - [(1,4)(2,3)], - [(2,3)], - [(1,4)], - [(1,2)(3,4)], - [(1,3)(2,4)], - [(2,3), (1,4)(2,3)], - [(1,2,4,3), (1,4)(2,3)], - [(1,2)(3,4), (1,4)(2,3)], - [(2,3), (1,2,4,3), (1,4)(2,3)]] + [((),), + ((1,4)(2,3),), + ((2,3),), + ((1,4),), + ((1,2)(3,4),), + ((1,3)(2,4),), + ((2,3), (1,4)(2,3)), + ((1,2,4,3), (1,4)(2,3)), + ((1,2)(3,4), (1,4)(2,3)), + ((2,3), (1,2,4,3), (1,4)(2,3))] ~~~~~~~~~~~~~~~~~~~~~~ :: diff --git a/src/sage/tests/books/judson-abstract-algebra/homomorph-sage-exercises.py b/src/sage/tests/books/judson-abstract-algebra/homomorph-sage-exercises.py index 84ed1005a25..31c4f1818fe 100644 --- a/src/sage/tests/books/judson-abstract-algebra/homomorph-sage-exercises.py +++ b/src/sage/tests/books/judson-abstract-algebra/homomorph-sage-exercises.py @@ -45,7 +45,7 @@ sage: results = G.direct_product(H) sage: phi = results[2] sage: H.gens() - [(1,2,3,4), (1,4)(2,3)] + ((1,2,3,4), (1,4)(2,3)) ~~~~~~~~~~~~~~~~~~~~~~ :: diff --git a/src/sage/tests/books/judson-abstract-algebra/homomorph-sage.py b/src/sage/tests/books/judson-abstract-algebra/homomorph-sage.py index 822fd2bbdce..29b25d1efde 100644 --- a/src/sage/tests/books/judson-abstract-algebra/homomorph-sage.py +++ b/src/sage/tests/books/judson-abstract-algebra/homomorph-sage.py @@ -104,13 +104,13 @@ sage: G = DihedralGroup(5) sage: H = DihedralGroup(20) sage: G.gens() - [(1,2,3,4,5), (1,5)(2,4)] + ((1,2,3,4,5), (1,5)(2,4)) ~~~~~~~~~~~~~~~~~~~~~~ :: sage: H.gens() - [(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20), - (1,20)(2,19)(3,18)(4,17)(5,16)(6,15)(7,14)(8,13)(9,12)(10,11)] + ((1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20), + (1,20)(2,19)(3,18)(4,17)(5,16)(6,15)(7,14)(8,13)(9,12)(10,11)) ~~~~~~~~~~~~~~~~~~~~~~ :: From 67c74f2bc1ed80e81ceb599e7d5cb64570157378 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Mon, 9 May 2022 22:50:01 +0000 Subject: [PATCH 374/529] Update based on recent changes in deps --- .gitpod.yml | 5 +- src/environment-dev.yml | 206 ---------------------------------------- 2 files changed, 3 insertions(+), 208 deletions(-) delete mode 100644 src/environment-dev.yml diff --git a/.gitpod.yml b/.gitpod.yml index 3bb3366443a..c3d5a05087d 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -7,6 +7,7 @@ tasks: - name: Setup init: | # Create conda environment + ./bootstrap-conda mamba env create --file src/environment-dev.yml --prefix venv conda config --append envs_dirs /workspace/sagetrac-mirror conda activate /workspace/sagetrac-mirror/venv @@ -16,8 +17,8 @@ tasks: # Build sage ./bootstrap ./configure --enable-build-as-root --with-python=$CONDA_PREFIX/bin/python --prefix=$CONDA_PREFIX - pip install --no-build-isolation -v -v -e pkgs/sage-conf pkgs/sage-setup - pip install --no-build-isolation -v -v -e src + pip install --no-build-isolation -v -v -e ./pkgs/sage-conf ./pkgs/sage-setup + pip install --no-build-isolation -v -v -e ./src command: | # Activate conda environment diff --git a/src/environment-dev.yml b/src/environment-dev.yml deleted file mode 100644 index 6d99447b852..00000000000 --- a/src/environment-dev.yml +++ /dev/null @@ -1,206 +0,0 @@ -name: sage-dev -channels: - - conda-forge - - nodefaults -dependencies: - - compilers - - make - - m4 - - perl - - python - - tar - - bc - - pkg-config - - arb - - boost-cpp - - brial - - bzip2 - - cddlib - - cliquer - - cmake - - curl - - ecl - - eclib - - ecm - - fflas-ffpack - - libflint - - flintqs - - fplll - - freetype - - bdw-gc - - gengetopt - - gf2x - - gfan - - fortran-compiler - - giac - - givaro - - glpk - - gmp - - gsl - - iml - - lcalc - - libatomic_ops - - libbraiding - - libffi - - libgd - - libhomfly - - xz - - libpng - - linbox - - lrcalc - - m4ri - - m4rie - - mpc - - mpfi - - mpfr - - nauty - - ncurses - - ntl - - openblas - - blas=2.*=openblas - - openssl - - palp - - pari - - pari-elldata - - pari-galdata - - pari-galpol - - pari-seadata - - pari-galdata - - pari-seadata-small - - patch - - pcre - - pkg-config - - planarity - - ppl - - primecount - - primesieve - - qhull - - r - - r-essentials - - readline - - rw - - singular - - sqlite - - suitesparse - - symmetrica - - sympow - - tachyon - - tox - - xz - - zeromq - - zlib - - zn_poly - - alabaster - - attrs - - babel - - backcall - - beautifulsoup4 - - bleach - - certifi - - cffi - - sagemath-db-combinatorial-designs - - sagemath-db-conway-polynomials - - cvxopt - - cycler - - cypari2 - - cysignals - - cython - - python-dateutil - - decorator - - defusedxml - - docutils - - sagemath-db-elliptic-curves - - entrypoints - - fpylll - - gap-defaults - - gmpy2 - - sagemath-db-graphs - - html5lib - - imagesize - - importlib_metadata - - ipykernel - - ipython - - ipython_genutils - - ipywidgets - - jedi - - jinja2 - - jmol - - jsonschema - - jupyter_client - - jupyter_core - - kiwisolver - - python-lrcalc - - markupsafe - - mathjax - - "matplotlib>=3.5.1" - - maxima - - memory-allocator - - mistune - - mpmath - - nbconvert - - nbformat - - networkx - - notebook - - numpy - - packaging - - pandocfilters - - parso - - pexpect - - pickleshare - - pillow - - pip - - pkgconfig - - sagemath-db-polytopes - - pplpy - - primecountpy - - prometheus_client - - prompt_toolkit - - ptyprocess - - pybind11 - - pycparser - - pygments - - pyparsing - - pyrsistent - - pytz - - pyzmq - - requests - - rpy2 - - sagetex - - scipy - - send2trash - - setuptools - - setuptools_scm - - simplegeneric - - six - - snowballstemmer - - sphinx - - sphinxcontrib-applehelp - - sphinxcontrib-devhelp - - sphinxcontrib-htmlhelp - - sphinxcontrib-jsmath - - sphinxcontrib-qthelp - - sphinxcontrib-serializinghtml - - sphinxcontrib-websupport - - sympy - - terminado - - testpath - - three.js - - tornado - - traitlets - - tzlocal - - vcversioner - - wcwidth - - webencodings - - wheel - - widgetsnbextension - - zipp - # Packages needed for ./bootstrap - - gettext - - autoconf - - automake - - libtool - # Additional dev tools - - openssh - - pycodestyle - - pytest - - jupyter_sphinx From e19f7ad4ea48e158d3c498972706d3722de5cb35 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 9 May 2022 18:13:57 -0700 Subject: [PATCH 375/529] build/pkgs/pari/distros/conda.txt: Use pthread version of pari --- build/pkgs/pari/distros/conda.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/pari/distros/conda.txt b/build/pkgs/pari/distros/conda.txt index ef882b39cb0..88ec4bef346 100644 --- a/build/pkgs/pari/distros/conda.txt +++ b/build/pkgs/pari/distros/conda.txt @@ -1,3 +1,3 @@ -pari +pari=*=*_pthread # We add these data packages because they are checked by spkg-configure.m4 pari-elldata pari-galdata pari-galpol pari-seadata From 15142186552be11eb23933945ed6f2f6503086aa Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 9 May 2022 18:17:09 -0700 Subject: [PATCH 376/529] src/doc/en/installation/conda.rst: Where to report failures with conda --- src/doc/en/installation/conda.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/doc/en/installation/conda.rst b/src/doc/en/installation/conda.rst index 2d5d8e7bdef..a335c4fc7d9 100644 --- a/src/doc/en/installation/conda.rst +++ b/src/doc/en/installation/conda.rst @@ -55,6 +55,10 @@ To use Sage from there, * Enter the new environment: ``conda activate sage`` * Start SageMath: ``sage`` +If there are any installation failures, please report them to +the conda-forge maintainers by opening a `GitHub Issue for +conda-forge/sage-feedstock `_. + .. _sec-installation-conda-source: From d5adcb077d3f03e1aac68260315c8dc4feb4ff2e Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Tue, 10 May 2022 11:39:51 +0200 Subject: [PATCH 377/529] replace $...$ with `...` --- src/sage/groups/perm_gps/permgroup.py | 48 +++++++++++++-------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/sage/groups/perm_gps/permgroup.py b/src/sage/groups/perm_gps/permgroup.py index 4f2c01eb68c..0a310047116 100644 --- a/src/sage/groups/perm_gps/permgroup.py +++ b/src/sage/groups/perm_gps/permgroup.py @@ -1773,9 +1773,9 @@ def base(self, seed=None): r""" Return a (minimum) base of this permutation group. - A base $B$ of a permutation group is a subset of the domain + A base `B` of a permutation group is a subset of the domain of the group such that the only group element stabilizing all - of $B$ is the identity. + of `B` is the identity. INPUT: @@ -2250,7 +2250,7 @@ def socle(self): r""" Return the socle of ``self``. - The socle of a group $G$ is the subgroup generated by all + The socle of a group `G` is the subgroup generated by all minimal normal subgroups. EXAMPLES:: @@ -2267,7 +2267,7 @@ def frattini_subgroup(self): r""" Return the Frattini subgroup of ``self``. - The Frattini subgroup of a group $G$ is the intersection of all maximal + The Frattini subgroup of a group `G` is the intersection of all maximal subgroups of `G`. EXAMPLES:: @@ -2286,7 +2286,7 @@ def fitting_subgroup(self): r""" Return the Fitting subgroup of ``self``. - The Fitting subgroup of a group $G$ is the largest nilpotent normal + The Fitting subgroup of a group `G` is the largest nilpotent normal subgroup of `G`. EXAMPLES:: @@ -2305,8 +2305,8 @@ def solvable_radical(self): r""" Return the solvable radical of ``self``. - The solvable radical (or just radical) of a group $G$ is the - largest solvable normal subgroup of $G$. + The solvable radical (or just radical) of a group `G` is the + largest solvable normal subgroup of `G`. EXAMPLES:: @@ -2632,9 +2632,9 @@ def semidirect_product(self, N, mapping, check=True): Perhaps the most common example of a semidirect product comes from the family of dihedral groups. Each dihedral group is the - semidirect product of $C_2$ with $C_n$, where, by convention, - $3 \leq n$. In this case, the nontrivial element of $C_2$ acts - on $C_n$ so as to send each element to its inverse. :: + semidirect product of `C_2` with `C_n`, where, by convention, + `3 \leq n`. In this case, the nontrivial element of `C_2` acts + on `C_n` so as to send each element to its inverse. :: sage: C2 = CyclicPermutationGroup(2) sage: C8 = CyclicPermutationGroup(8) @@ -2648,8 +2648,8 @@ def semidirect_product(self, N, mapping, check=True): ((3,4,5,6,7,8,9,10), (1,2)(4,10)(5,9)(6,8)) A more complicated example can be drawn from [TW1980]_. - It is there given that a semidirect product of $D_4$ and $C_3$ - is isomorphic to one of $C_2$ and the dicyclic group of order + It is there given that a semidirect product of `D_4` and `C_3` + is isomorphic to one of `C_2` and the dicyclic group of order 12. This nonabelian group of order 24 has very similar structure to the dicyclic and dihedral groups of order 24, the three being the only groups of order 24 with a two-element @@ -3018,14 +3018,14 @@ def commutator(self, other=None): OUTPUT: - Let $G$ denote ``self``. If ``other`` is ``None`` then this method - returns the subgroup of $G$ generated by the set of commutators, + Let `G` denote ``self``. If ``other`` is ``None`` then this method + returns the subgroup of `G` generated by the set of commutators, .. MATH:: \{[g_1,g_2]\vert g_1, g_2\in G\} = \{g_1^{-1}g_2^{-1}g_1g_2\vert g_1, g_2\in G\} - Let $H$ denote ``other``, in the case that it is not ``None``. Then + Let `H` denote ``other``, in the case that it is not ``None``. Then this method returns the group generated by the set of commutators, .. MATH:: @@ -4295,7 +4295,7 @@ def is_transitive(self, domain=None): r""" Return ``True`` if ``self`` acts transitively on ``domain``. - A group $G$ acts transitively on set $S$ if for all `x,y\in S` + A group `G` acts transitively on set `S` if for all `x,y\in S` there is some `g\in G` such that `x^g=y`. EXAMPLES:: @@ -4345,11 +4345,11 @@ def is_primitive(self, domain=None): r""" Return ``True`` if ``self`` acts primitively on ``domain``. - A group $G$ acts primitively on a set $S$ if + A group `G` acts primitively on a set `S` if - 1. $G$ acts transitively on $S$ and + 1. `G` acts transitively on `S` and - 2. the action induces no non-trivial block system on $S$. + 2. the action induces no non-trivial block system on `S`. INPUT: @@ -4395,8 +4395,8 @@ def is_semi_regular(self, domain=None): r""" Return ``True`` if ``self`` acts semi-regularly on ``domain``. - A group $G$ acts semi-regularly on a set $S$ if the point - stabilizers of $S$ in $G$ are trivial. + A group `G` acts semi-regularly on a set `S` if the point + stabilizers of `S` in `G` are trivial. ``domain`` is optional and may take several forms. See examples. @@ -4428,10 +4428,10 @@ def is_regular(self, domain=None): r""" Return ``True`` if ``self`` acts regularly on ``domain``. - A group $G$ acts regularly on a set $S$ if + A group `G` acts regularly on a set `S` if - 1. $G$ acts transitively on $S$ and - 2. $G$ acts semi-regularly on $S$. + 1. `G` acts transitively on `S` and + 2. `G` acts semi-regularly on `S`. EXAMPLES:: From 90005e7773626f2a50b5c885161a4a4ff8259059 Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Tue, 10 May 2022 11:48:43 +0200 Subject: [PATCH 378/529] remove unused import --- src/sage/topology/simplicial_complex.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/topology/simplicial_complex.py b/src/sage/topology/simplicial_complex.py index e41c35e3552..e4b61bb9474 100644 --- a/src/sage/topology/simplicial_complex.py +++ b/src/sage/topology/simplicial_complex.py @@ -173,7 +173,7 @@ from sage.matrix.constructor import matrix from sage.homology.chain_complex import ChainComplex from sage.graphs.graph import Graph -from functools import reduce, total_ordering +from functools import total_ordering from itertools import combinations, chain lazy_import('sage.categories.simplicial_complexes', 'SimplicialComplexes') From fdea936a8c038820368a79e4c153745c0b442f8d Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Tue, 10 May 2022 12:04:25 +0200 Subject: [PATCH 379/529] fix doctests --- src/sage/groups/perm_gps/permgroup.py | 28 +++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/sage/groups/perm_gps/permgroup.py b/src/sage/groups/perm_gps/permgroup.py index 81f308bfef5..13c46398d7e 100644 --- a/src/sage/groups/perm_gps/permgroup.py +++ b/src/sage/groups/perm_gps/permgroup.py @@ -336,9 +336,9 @@ def PermutationGroup(gens=None, *args, **kwds): sage: a = lambda x: (2*x) % 7 sage: H = PermutationGroup(action=a, domain=range(7)) sage: H.orbits() - [[0], [1, 2, 4], [3, 6, 5]] + ((0,), (1, 2, 4), (3, 6, 5)) sage: H.gens() - [(1,2,4), (3,6,5)] + ((1,2,4), (3,6,5)) Note that we provide generators for the acting group. The permutation group we construct is its homomorphic image:: @@ -352,10 +352,10 @@ def PermutationGroup(gens=None, *args, **kwds): ) sage: H = PermutationGroup(G.gens(), action=a, domain=X) sage: H.orbits() - [[(0, 0)], [(1, 0), (2, 0), (0, 1), (1, 1), (2, 1), (0, 2), (1, 2), (2, 2)]] + (((0, 0),), ((1, 0), (2, 0), (0, 1), (1, 1), (2, 1), (0, 2), (1, 2), (2, 2))) sage: H.gens() - [((0,1),(1,1),(2,1))((0,2),(2,2),(1,2)), - ((1,0),(0,2),(2,0),(0,1))((1,1),(1,2),(2,2),(2,1))] + (((0,1),(1,1),(2,1))((0,2),(2,2),(1,2)), + ((1,0),(0,2),(2,0),(0,1))((1,1),(1,2),(2,2),(2,1))) The orbits of the conjugation action are the conjugacy classes, i.e., in bijection with integer partitions:: @@ -5067,9 +5067,9 @@ class PermutationGroup_action(PermutationGroup_generic): sage: S = SetPartitions(n) sage: G = PermutationGroup(action=a, domain=S) sage: G.orbits() - [[{{1}, {2}, {3}}], - [{{1, 2}, {3}}, {{1}, {2, 3}}, {{1, 3}, {2}}], - [{{1, 2, 3}}]] + (({{1}, {2}, {3}},), + ({{1, 2}, {3}}, {{1}, {2, 3}}, {{1, 3}, {2}}), + ({{1, 2, 3}},)) The regular action of the symmetric group:: @@ -5077,7 +5077,7 @@ class PermutationGroup_action(PermutationGroup_generic): sage: S = SymmetricGroup(3) sage: G = PermutationGroup(S.gens(), action=a, domain=S) sage: G.orbits() - [[()], [(1,3,2), (1,2,3)], [(2,3), (1,3), (1,2)]] + (((),), ((1,3,2), (1,2,3)), ((2,3), (1,3), (1,2))) The trivial action of the symmetric group:: @@ -5113,7 +5113,7 @@ def __init__(self, gens, action, domain, gap_group=None, category=None, canonica sage: a = lambda x: (2*x) % 7 sage: G = PermutationGroup(action=a, domain=range(7)) sage: G.orbits() - [[0], [1, 2, 4], [3, 6, 5]] + ((0,), (1, 2, 4), (3, 6, 5)) """ from sage.combinat.cyclic_sieving_phenomenon import orbit_decomposition @@ -5121,8 +5121,8 @@ def __init__(self, gens, action, domain, gap_group=None, category=None, canonica if gap_group is not None: raise ValueError("gap_group is not supported with action") if gens is None: - self._orbits = orbit_decomposition(domain, action) - gens = [tuple(o) for o in self._orbits if len(o) > 1] + self._orbits = tuple(tuple(o) for o in orbit_decomposition(domain, action)) + gens = [o for o in self._orbits if len(o) > 1] else: g_orbits = [orbit_decomposition(domain, lambda x: action(g, x)) for g in gens] @@ -5137,7 +5137,7 @@ def __init__(self, gens, action, domain, gap_group=None, category=None, canonica for o in g_orbit: for i in range(1, len(o)): D.union(o[0], o[i]) - self._orbits = list(D) + self._orbits = tuple(tuple(o) for o in D) PermutationGroup_generic.__init__(self, gens=gens, gap_group=gap_group, domain=domain, @@ -5154,7 +5154,7 @@ def orbits(self): sage: a = lambda x: (2*x) % 7 sage: G = PermutationGroup(action=a, domain=range(7)) sage: G.orbits() - [[0], [1, 2, 4], [3, 6, 5]] + ((0,), (1, 2, 4), (3, 6, 5)) """ return self._orbits From 8a4ae369d72a4ad246de5ec61b43fdd26809f83c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 10 May 2022 12:52:17 +0200 Subject: [PATCH 380/529] some use of pathlib.Path in combinat and groups --- .../cluster_algebra_quiver/mutation_type.py | 12 +-- .../quiver_mutation_type.py | 8 +- src/sage/groups/perm_gps/permgroup_named.py | 83 ++++++++++--------- 3 files changed, 53 insertions(+), 50 deletions(-) diff --git a/src/sage/combinat/cluster_algebra_quiver/mutation_type.py b/src/sage/combinat/cluster_algebra_quiver/mutation_type.py index 6ff5777a0a6..3e27b9efe32 100644 --- a/src/sage/combinat/cluster_algebra_quiver/mutation_type.py +++ b/src/sage/combinat/cluster_algebra_quiver/mutation_type.py @@ -20,7 +20,7 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -import os +from pathlib import Path import pickle from copy import copy @@ -1276,16 +1276,16 @@ def load_data(n, user=True): # we check # - if the data is stored by the user, and if this is not the case # - if the data is stored by the optional package install - paths = [SAGE_SHARE] + paths = [Path(SAGE_SHARE)] if user: - paths.append(DOT_SAGE) + paths.append(Path(DOT_SAGE)) data = {} for path in paths: - filename = os.path.join(path, 'cluster_algebra_quiver', 'mutation_classes_%s.dig6'%n) + file = path / 'cluster_algebra_quiver' / f'mutation_classes_{n}.dig6' try: - with open(filename, 'rb') as fobj: + with open(file, 'rb') as fobj: data_new = pickle.load(fobj) - except Exception: + except (OSError, FileNotFoundError, pickle.UnpicklingError): # File does not exist, corrupt pickle, wrong Python version... pass else: diff --git a/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py b/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py index 4969d141b65..087abdbc7fe 100644 --- a/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py +++ b/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py @@ -16,7 +16,7 @@ # https://www.gnu.org/licenses/ # *************************************************************************** from __future__ import annotations -import os +from pathlib import Path import pickle from sage.structure.sage_object import SageObject @@ -2272,9 +2272,9 @@ def _save_data_dig6(n, types='ClassicalExceptional', verbose=False): data.update(_construct_exceptional_mutation_classes(n)) from sage.env import DOT_SAGE - types_path = os.path.join(DOT_SAGE, 'cluster_algebra_quiver') - types_file = os.path.join(types_path, 'mutation_classes_%s.dig6' % n) - os.makedirs(types_path, exist_ok=True) + types_path = Path(DOT_SAGE) / 'cluster_algebra_quiver' + types_path.mkdir(exist_ok=True) + types_file = types_path / f'mutation_classes_{n}.dig6' from sage.misc.temporary_file import atomic_write with atomic_write(types_file, binary=True) as f: pickle.dump(data, f) diff --git a/src/sage/groups/perm_gps/permgroup_named.py b/src/sage/groups/perm_gps/permgroup_named.py index 51b5f96521c..b50b9581f00 100644 --- a/src/sage/groups/perm_gps/permgroup_named.py +++ b/src/sage/groups/perm_gps/permgroup_named.py @@ -77,18 +77,16 @@ permutation groups - the construction is too slow - unless (for small values or the parameter) they are made using explicit generators. """ - -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2006 William Stein # David Joyner # # Distributed under the terms of the GNU General Public License (GPL) -# http://www.gnu.org/licenses/ -#***************************************************************************** - -import os +# https://www.gnu.org/licenses/ +# **************************************************************************** +from pathlib import Path -from sage.rings.all import Integer +from sage.rings.all import Integer from sage.libs.gap.libgap import libgap from sage.rings.finite_rings.finite_field_constructor import FiniteField as GF from sage.arith.all import factor, valuation @@ -259,9 +257,9 @@ def __init__(self, domain=None): from sage.categories.finite_permutation_groups import FinitePermutationGroups from sage.categories.category import Category - #Note that we skip the call to the superclass initializer in order to - #avoid infinite recursion since SymmetricGroup is called by - #PermutationGroupElement + # Note that we skip the call to the superclass initializer in order to + # avoid infinite recursion since SymmetricGroup is called by + # PermutationGroupElement cat = Category.join([FinitePermutationGroups(), FiniteWeylGroups().Irreducible()]) super(PermutationGroup_generic, self).__init__(category=cat) @@ -270,7 +268,7 @@ def __init__(self, domain=None): self._domain_to_gap = {key: i+1 for i, key in enumerate(self._domain)} self._domain_from_gap = {i+1: key for i, key in enumerate(self._domain)} - #Create the generators for the symmetric group + # Create the generators for the symmetric group gens = [tuple(self._domain)] if len(self._domain) > 2: gens.append(tuple(self._domain[:2])) @@ -348,7 +346,7 @@ def cartan_type(self): ['A', 0] """ from sage.combinat.root_system.cartan_type import CartanType - return CartanType(['A', max(self.degree() - 1,0)]) + return CartanType(['A', max(self.degree() - 1, 0)]) def coxeter_matrix(self): r""" @@ -493,8 +491,8 @@ def conjugacy_classes_representatives(self): from sage.combinat.partition import Partitions_n from sage.groups.perm_gps.symgp_conjugacy_class import default_representative n = len(self.domain()) - return [ default_representative(la, self) - for la in reversed(Partitions_n(n)) ] + return [default_representative(la, self) + for la in reversed(Partitions_n(n))] def conjugacy_classes_iterator(self): """ @@ -922,12 +920,12 @@ def __init__(self, n): a = [tuple(range(1, halfr+1)), tuple(range(halfr+1, r+1))] # With an odd part, a cycle of length m will give the right order for a if m > 1: - a.append( tuple(range(r+1, r+m+1)) ) + a.append(tuple(range(r + 1, r + m + 1))) # Representation of x # Four-cycles that will conjugate the generator a properly - x = [(i+1, (-i)%halfr + halfr + 1, (fourthr+i)%halfr + 1, (-fourthr-i)%halfr + halfr + 1) - for i in range(0, fourthr)] + x = [(i+1, (-i) % halfr + halfr + 1, (fourthr+i) % halfr + 1, (-fourthr-i)%halfr + halfr + 1) + for i in range(0, fourthr)] # With an odd part, transpositions will conjugate the m-cycle to create inverse if m > 1: x += [(r+i+1, r+m-i) for i in range(0, (m-1)//2)] @@ -1000,7 +998,7 @@ def __init__(self): AUTHOR: -- Bobby Moretti (2006-10) """ - gens = [(1,2),(3,4)] + gens = [(1, 2), (3, 4)] PermutationGroup_generic.__init__(self, gens) def _repr_(self): @@ -1047,7 +1045,8 @@ def _repr_(self): sage: G = groups.permutation.Janko(1); G # optional - gap_packages internet Janko group J1 of order 175560 as a permutation group """ - return "Janko group J%s of order %s as a permutation group"%(self._n,self.order()) + return "Janko group J%s of order %s as a permutation group" % (self._n, self.order()) + class SuzukiSporadicGroup(PermutationGroup_unique): def __init__(self): @@ -1301,8 +1300,6 @@ def __init__(self, factors): 250 sage: TestSuite(G).run() # long time """ - - if not isinstance(factors, list): msg = "factors of abelian group must be a list, not {}" raise TypeError(msg.format(factors)) @@ -1433,9 +1430,9 @@ def __init__(self, n): if n == 1: gens = CyclicPermutationGroup(2).gens() elif n == 2: - gens = ((1,2),(3,4)) + gens = ((1, 2), (3, 4)) else: - gen1 = tuple((i, n-i+1) for i in range(1, n//2 +1)) + gen1 = tuple((i, n - i + 1) for i in range(1, n // 2 + 1)) gens = tuple([tuple(gen0), gen1]) PermutationGroup_generic.__init__(self, gens) @@ -1447,8 +1444,7 @@ def _repr_(self): sage: G = DihedralGroup(5); G Dihedral group of order 10 as a permutation group """ - return "Dihedral group of order %s as a permutation group"%self.order() - + return f"Dihedral group of order {self.order()} as a permutation group" class SplitMetacyclicGroup(PermutationGroup_unique): @@ -1578,12 +1574,12 @@ def __init__(self, p, m): y = [1] point = 1 for i in range(p**(m-1)-1): - next = (point + 1 + p**(m-2))%(p**(m-1)) + next = (point + 1 + p**(m-2)) % (p**(m-1)) if next == 0: next = p**(m-1) y.append(next) point = next - PermutationGroup_unique.__init__(self, gens = [x,y]) + PermutationGroup_unique.__init__(self, gens=[x, y]) def _repr_(self): """ @@ -1594,8 +1590,9 @@ def _repr_(self): """ return 'The split metacyclic group of order %s ^ %s' % (self.p, self.m) + class SemidihedralGroup(PermutationGroup_unique): - def __init__(self,m): + def __init__(self, m): r""" The semidihedral group of order `2^m`. @@ -1687,12 +1684,12 @@ def __init__(self,m): y = [1] k = 1 for i in range(2**(m-1)-1): - next = (k - 1 + 2**(m-2))%(2**(m-1)) + next = (k - 1 + 2**(m-2)) % (2**(m-1)) if next == 0: next = 2**(m-1) y.append(next) k = next - PermutationGroup_unique.__init__(self, gens = [x,y]) + PermutationGroup_unique.__init__(self, gens=[x, y]) def _repr_(self): r""" @@ -1753,7 +1750,8 @@ def _repr_(self): sage: G = MathieuGroup(12); G Mathieu group of degree 12 and order 95040 as a permutation group """ - return "Mathieu group of degree %s and order %s as a permutation group"%(self._n,self.order()) + return "Mathieu group of degree %s and order %s as a permutation group"%(self._n, self.order()) + class TransitiveGroup(PermutationGroup_unique): def __init__(self, d, n): @@ -1832,7 +1830,6 @@ def __init__(self, d, n): gap_group = libgap.TransitiveGroup(d, n) PermutationGroup_generic.__init__(self, gap_group=gap_group) - def transitive_number(self): """ Return the index of this group in the GAP database, starting at 1 @@ -1960,7 +1957,8 @@ def __contains__(self, G): sage: 1 in TransitiveGroups() False """ - return isinstance(G,TransitiveGroup) + return isinstance(G, TransitiveGroup) + class TransitiveGroupsOfDegree(CachedRepresentation, Parent): r""" @@ -2380,7 +2378,8 @@ def __contains__(self, G): sage: 1 in PrimitiveGroups() False """ - return isinstance(G,PrimitiveGroup) + return isinstance(G, PrimitiveGroup) + class PrimitiveGroupsOfDegree(CachedRepresentation, Parent): """ @@ -2418,7 +2417,7 @@ def __init__(self, n): Category of finite enumerated sets """ self._degree = n - Parent.__init__(self, category = FiniteEnumeratedSets()) + Parent.__init__(self, category=FiniteEnumeratedSets()) def _repr_(self): """ @@ -2756,8 +2755,8 @@ def ramification_module_decomposition_hurwitz_curve(self): F = self.base_ring() q = F.order() - libgap.Read(os.path.join(SAGE_EXTCODE, 'gap', 'joyner', - 'hurwitz_crv_rr_sp.gap')) + libgap.Read(Path(SAGE_EXTCODE) / 'gap' / 'joyner' / + 'hurwitz_crv_rr_sp.gap') mults = libgap.eval("ram_module_hurwitz({q})".format(q=q)) return mults.sage() @@ -2800,11 +2799,12 @@ def ramification_module_decomposition_modular_curve(self): raise ValueError("degree must be 2") F = self.base_ring() q = F.order() - libgap.Read(os.path.join(SAGE_EXTCODE, 'gap', 'joyner', - 'modular_crv_rr_sp.gap')) + libgap.Read(Path(SAGE_EXTCODE) / 'gap' / 'joyner' / + 'modular_crv_rr_sp.gap') mults = libgap.eval("ram_module_X({q})".format(q=q)) return mults.sage() + class PSp(PermutationGroup_plg): def __init__(self, n, q, name='a'): """ @@ -2868,8 +2868,10 @@ def __str__(self): """ return "The projective symplectic linear group of degree %s over %s"%(self._n, self.base_ring()) + PSP = PSp + class PermutationGroup_pug(PermutationGroup_plg): def field_of_definition(self): """ @@ -2929,7 +2931,8 @@ def _repr_(self): The projective special unitary group of degree 2 over Finite Field of size 3 """ - return "The projective special unitary group of degree %s over %s"%(self._n, self.base_ring()) + return "The projective special unitary group of degree %s over %s" % (self._n, self.base_ring()) + class PGU(PermutationGroup_pug): def __init__(self, n, q, name='a'): From f171687fd27aed783cdaeed3d1b5e9d1e63cd4ed Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Tue, 10 May 2022 17:00:39 +0200 Subject: [PATCH 381/529] deprecate has_element --- src/sage/groups/perm_gps/permgroup.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/sage/groups/perm_gps/permgroup.py b/src/sage/groups/perm_gps/permgroup.py index f10fb48f933..7e0867563f4 100644 --- a/src/sage/groups/perm_gps/permgroup.py +++ b/src/sage/groups/perm_gps/permgroup.py @@ -1009,6 +1009,13 @@ def __contains__(self, item): sage: G = PermutationGroup([[('a','b')]], domain=('a', 'b')) sage: [('a', 'b')] in G True + + sage: G = CyclicPermutationGroup(4) + sage: H = DihedralGroup(4) + sage: g = G([(1,2,3,4)]); g + (1,2,3,4) + sage: g in H + True """ try: self._element_constructor_(item) @@ -1029,12 +1036,18 @@ def has_element(self, item): sage: g = G([(1,2,3,4)]); g (1,2,3,4) sage: G.has_element(g) + doctest:warning + ... + DeprecationWarning: The method has_element is deprecated. Please use :meth:`__contains__`, i.e., `h in G` instead. + See https://trac.sagemath.org/33831 for details. True sage: h = H([(1,2),(3,4)]); h (1,2)(3,4) sage: G.has_element(h) False """ + from sage.misc.superseded import deprecation + deprecation(33831, "The method has_element is deprecated. Please use :meth:`__contains__`, i.e., `h in G` instead.") return item in self def __iter__(self): From c02327f781609e2fcd0a2541d2f1e75773741272 Mon Sep 17 00:00:00 2001 From: Vincent Delecroix <20100.delecroix@gmail.com> Date: Tue, 10 May 2022 18:17:43 +0200 Subject: [PATCH 382/529] 33652: returns -> return --- src/sage/matrix/matrix_complex_ball_dense.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/matrix/matrix_complex_ball_dense.pyx b/src/sage/matrix/matrix_complex_ball_dense.pyx index 8034aba2b43..2269af40b05 100644 --- a/src/sage/matrix/matrix_complex_ball_dense.pyx +++ b/src/sage/matrix/matrix_complex_ball_dense.pyx @@ -553,7 +553,7 @@ cdef class Matrix_complex_ball_dense(Matrix_dense): def transpose(self): r""" - Returns the transpose of ``self``. + Return the transpose of ``self``. EXAMPLES:: From 52dca7db2eec2d0536e6ce14de3b2232305a4fcd Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 10 May 2022 11:27:04 -0700 Subject: [PATCH 383/529] .github/workflows/build.yml: Add comment on python3-venv --- .github/workflows/build.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1070f3fa2d7..635389e9bdc 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -29,7 +29,9 @@ jobs: - name: Prepare run: | - # Install test tools + # Install test tools. + # Installation of python3-venv can be removed as soon as a + # base image with a release including #33822 is available apt-get install -y git python3-venv # Reuse built SAGE_LOCAL contained in the Docker image ./bootstrap From 90186ce6254d4cef0817cd5f6238993ffc1eccc0 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Tue, 10 May 2022 19:14:58 +0000 Subject: [PATCH 384/529] Fix map_reduce doctest --- src/sage/parallel/map_reduce.py | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/sage/parallel/map_reduce.py b/src/sage/parallel/map_reduce.py index dbb92129caf..79c22bacdc5 100644 --- a/src/sage/parallel/map_reduce.py +++ b/src/sage/parallel/map_reduce.py @@ -1139,17 +1139,22 @@ def start_workers(self): sage: from sage.parallel.map_reduce import RESetMapReduce sage: def children(x): + ....: sys.stdout.write(f"Starting: {x}\n") ....: sleep(float(0.5)) + ....: sys.stdout.write(f"Finished: {x}\n") ....: return [] - sage: S = RESetMapReduce(roots=[1], children=children) + sage: S = RESetMapReduce(roots=[1, 2], children=children) sage: S.setup_workers(2) - sage: S.start_workers() - sage: all(w.is_alive() for w in S._workers) - True - - sage: sleep(1) - sage: all(not w.is_alive() for w in S._workers) - True + sage: S.start_workers(); sleep(float(0.1)) + Starting: 1 + Starting: 2 + sage: [w.is_alive() for w in S._workers] + [True, True] + sage: sleep(float(1.5)) + Finished: 1 + Finished: 2 + sage: [not w.is_alive() for w in S._workers] + [True, True] Cleanup:: From 1a13f6320b022f4d05c209128740cfb41f28da5a Mon Sep 17 00:00:00 2001 From: Martin Rubey Date: Tue, 10 May 2022 22:28:16 +0200 Subject: [PATCH 385/529] fix style of warning --- src/sage/groups/perm_gps/permgroup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/groups/perm_gps/permgroup.py b/src/sage/groups/perm_gps/permgroup.py index 7e0867563f4..22a82232fc3 100644 --- a/src/sage/groups/perm_gps/permgroup.py +++ b/src/sage/groups/perm_gps/permgroup.py @@ -1038,7 +1038,7 @@ def has_element(self, item): sage: G.has_element(g) doctest:warning ... - DeprecationWarning: The method has_element is deprecated. Please use :meth:`__contains__`, i.e., `h in G` instead. + DeprecationWarning: G.has_element(g) is deprecated; use :meth:`__contains__`, i.e., `g in G` instead See https://trac.sagemath.org/33831 for details. True sage: h = H([(1,2),(3,4)]); h @@ -1047,7 +1047,7 @@ def has_element(self, item): False """ from sage.misc.superseded import deprecation - deprecation(33831, "The method has_element is deprecated. Please use :meth:`__contains__`, i.e., `h in G` instead.") + deprecation(33831, "G.has_element(g) is deprecated; use :meth:`__contains__`, i.e., `g in G` instead") return item in self def __iter__(self): From 39963ca1053e1ca9b602c9fa61d7d689ccf34f8a Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Tue, 10 May 2022 22:12:04 +0000 Subject: [PATCH 386/529] Activate debug level logging --- src/sage/parallel/map_reduce.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/parallel/map_reduce.py b/src/sage/parallel/map_reduce.py index 79c22bacdc5..7c30080ab95 100644 --- a/src/sage/parallel/map_reduce.py +++ b/src/sage/parallel/map_reduce.py @@ -564,9 +564,9 @@ `Logging facility for Python `_ for more detail on logging and log system configuration. """) -logger.setLevel(logging.WARN) +# logger.setLevel(logging.WARN) # logger.setLevel(logging.INFO) -# logger.setLevel(logging.DEBUG) +logger.setLevel(logging.DEBUG) ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) formatter = logging.Formatter( From 13f500f68553bdc4c720c64448608d216eddb5ca Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Sun, 13 Feb 2022 19:52:24 -0500 Subject: [PATCH 387/529] Trac #33213: replace SAGE_TMP in probability distribution doctests. --- src/sage/probability/probability_distribution.pyx | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/sage/probability/probability_distribution.pyx b/src/sage/probability/probability_distribution.pyx index ecc22e9bb86..f3bc8d59360 100644 --- a/src/sage/probability/probability_distribution.pyx +++ b/src/sage/probability/probability_distribution.pyx @@ -164,16 +164,14 @@ cdef class ProbabilityDistribution: EXAMPLES: - This saves the histogram plot to - ``my_general_distribution_plot.png`` in the temporary - directory ``SAGE_TMP``:: + This saves the histogram plot to a temporary file:: sage: from sage.probability.probability_distribution import GeneralDiscreteDistribution - sage: import os + sage: import tempfile sage: P = [0.3, 0.4, 0.3] sage: X = GeneralDiscreteDistribution(P) - sage: file = os.path.join(SAGE_TMP, "my_general_distribution_plot") - sage: X.generate_histogram_plot(file) + sage: with tempfile.NamedTemporaryFile() as f: + ....: X.generate_histogram_plot(f.name) """ import pylab l = [float(self.get_random_element()) for _ in range(num_samples)] From 848bcb61441a9f7a234f1612a8e311bd19de9f80 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Sun, 13 Feb 2022 11:10:57 -0500 Subject: [PATCH 388/529] Trac #33213: replace SAGE_TMP in calculus doctests. --- src/sage/calculus/calculus.py | 4 +++- src/sage/calculus/ode.pyx | 28 ++++++++++++++++------------ 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/sage/calculus/calculus.py b/src/sage/calculus/calculus.py index fbef15ce543..bd6d7b97e25 100644 --- a/src/sage/calculus/calculus.py +++ b/src/sage/calculus/calculus.py @@ -1614,7 +1614,9 @@ def laplace(ex, t, s, algorithm='maxima'): 91/8*e^(4*t) + 629/8*e^(-4*t) sage: p1 = plot(xt,0,1/2,rgbcolor=(1,0,0)) sage: p2 = plot(yt,0,1/2,rgbcolor=(0,1,0)) - sage: (p1+p2).save(os.path.join(SAGE_TMP, "de_plot.png")) + sage: import tempfile + sage: with tempfile.NamedTemporaryFile(suffix=".png") as f: + ....: (p1+p2).save(f.name) Another example:: diff --git a/src/sage/calculus/ode.pyx b/src/sage/calculus/ode.pyx index cc1b544e1ae..ebcd27141a6 100644 --- a/src/sage/calculus/ode.pyx +++ b/src/sage/calculus/ode.pyx @@ -236,8 +236,9 @@ class ode_solver(object): sage: T.function=f_1 sage: T.jacobian=j_1 sage: T.ode_solve(y_0=[1,0],t_span=[0,100],params=[10.0],num_points=1000) - sage: outfile = os.path.join(SAGE_TMP, 'sage.png') - sage: T.plot_solution(filename=outfile) + sage: import tempfile + sage: with tempfile.NamedTemporaryFile(suffix=".png") as f: + ....: T.plot_solution(filename=f.name) The solver line is equivalent to:: @@ -261,9 +262,10 @@ class ode_solver(object): By default T.plot_solution() plots the y_0, to plot general y_i use:: - sage: T.plot_solution(i=0, filename=outfile) - sage: T.plot_solution(i=1, filename=outfile) - sage: T.plot_solution(i=2, filename=outfile) + sage: with tempfile.NamedTemporaryFile(suffix=".png") as f: + ....: T.plot_solution(i=0, filename=f.name) + ....: T.plot_solution(i=1, filename=f.name) + ....: T.plot_solution(i=2, filename=f.name) The method interpolate_solution will return a spline interpolation through the points found by the solver. By default y_0 is @@ -321,13 +323,15 @@ class ode_solver(object): following (WARNING: the following is *not* automatically doctested):: - sage: T = ode_solver() # not tested - sage: T.algorithm = "bsimp" # not tested - sage: vander = van_der_pol() # not tested - sage: T.function=vander # not tested - sage: T.ode_solve(y_0 = [1,0], t_span=[0,2000], num_points=1000) # not tested - sage: T.plot_solution(i=0, filename=os.path.join(SAGE_TMP, 'test.png')) # not tested - + sage: T = ode_solver() # not tested + sage: T.algorithm = "bsimp" # not tested + sage: vander = van_der_pol() # not tested + sage: T.function=vander # not tested + sage: T.ode_solve(y_0 = [1,0], t_span=[0,2000], # not tested + ....: num_points=1000) # not tested + sage: from tempfile import NamedTemporaryFile # not tested + sage: with NamedTemporaryFile(suffix=".png") as f: # not tested + ....: T.plot_solution(i=0, filename=f.name) # not tested """ def __init__(self,function=None,jacobian=None,h = 1e-2,error_abs=1e-10,error_rel=1e-10, a=False,a_dydt=False,scale_abs=False,algorithm="rkf45",y_0=None,t_span=None,params = []): From 386562c5acb089fa44088ef92c0a7a826276e535 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Sun, 13 Feb 2022 16:36:48 -0500 Subject: [PATCH 389/529] Trac #33213: replace SAGE_TMP in generic LP backend doctests. --- src/sage/numerical/backends/generic_backend.pyx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/sage/numerical/backends/generic_backend.pyx b/src/sage/numerical/backends/generic_backend.pyx index 5e0adb0a915..94d0e0e9d9d 100644 --- a/src/sage/numerical/backends/generic_backend.pyx +++ b/src/sage/numerical/backends/generic_backend.pyx @@ -948,7 +948,9 @@ cdef class GenericBackend: 2 sage: p.add_linear_constraint([(0, 1], (1, 2)], None, 3) # optional - Nonexistent_LP_solver sage: p.set_objective([2, 5]) # optional - Nonexistent_LP_solver - sage: p.write_lp(os.path.join(SAGE_TMP, "lp_problem.lp")) # optional - Nonexistent_LP_solver + sage: from tempfile import NamedTemporaryFile # optional - Nonexistent_LP_solver + sage: with NamedTemporaryFile(suffix=".lp") as f: # optional - Nonexistent_LP_solver + ....: p.write_lp(f.name) """ raise NotImplementedError() @@ -968,7 +970,10 @@ cdef class GenericBackend: 2 sage: p.add_linear_constraint([(0, 1), (1, 2)], None, 3) # optional - Nonexistent_LP_solver sage: p.set_objective([2, 5]) # optional - Nonexistent_LP_solver - sage: p.write_lp(os.path.join(SAGE_TMP, "lp_problem.lp")) # optional - Nonexistent_LP_solver + sage: from tempfile import NamedTemporaryFile # optional - Nonexistent_LP_solver + sage: with NamedTemporaryFile(suffix=".lp") as f: # optional - Nonexistent_LP_solver + ....: p.write_lp(f.name) + """ raise NotImplementedError() From 01caa38de213af25a1ba6501e5419d35ca711561 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 10 May 2022 16:31:37 -0700 Subject: [PATCH 390/529] SAGE_ROOT/sage: Actually unconditionally determine SAGE_ROOT from $0 --- sage | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/sage b/sage index 1e31cbcb50a..10b53023fbe 100755 --- a/sage +++ b/sage @@ -108,15 +108,12 @@ resolvelinks() { # (The updated README.md and installation manual from Trac #33787 recommend to # symlink the installed version of the src/bin/sage script instead.) -if [ -z "$SAGE_ROOT" ]; then - # Get the path to $0 (this shell script) with all symbolic links - # resolved - SAGE_ROOT=`resolvelinks "$0"` || \ +# Get the path to $0 (this shell script) with all symbolic links resolved +SAGE_ROOT=`resolvelinks "$0"` || \ SAGE_ROOT="$0" - # Get the directory component - SAGE_ROOT="${SAGE_ROOT%/*}" -fi +# Get the directory component +SAGE_ROOT="${SAGE_ROOT%/*}" # Make SAGE_ROOT absolute SAGE_ROOT=`cd "$SAGE_ROOT" && pwd -P` From 59877bdcfc5864966c0ab0b79a8ad0792cb201d2 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 11 May 2022 12:18:41 -0700 Subject: [PATCH 391/529] Makefile (micro_release): Fix typo in comment --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 9e8955a07f6..9cb21f80c1d 100644 --- a/Makefile +++ b/Makefile @@ -196,7 +196,7 @@ micro_release: @echo "Removing unnecessary files & directories - make will not be functional afterwards anymore" @# We keep src/sage for some doctests that it expect it to be there and @# also because it does not add any weight with rdfind below. - @# We need src/sage/bin/ for the scripts that invoke Sage + @# We need src/bin/ for the scripts that invoke Sage @# We need sage, the script to start Sage @# We need local/, the dependencies and the built Sage library itself. @# We keep VERSION.txt. From e537bf3da74b6ccc657afcf1d48fd52addd67bf3 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 11 May 2022 12:20:05 -0700 Subject: [PATCH 392/529] sage: Remove outdated check for SAGE_ROOT/local/bin/sage --- sage | 3 --- 1 file changed, 3 deletions(-) diff --git a/sage b/sage index 3fad670c839..8dd0f648ac4 100755 --- a/sage +++ b/sage @@ -137,9 +137,6 @@ fi # Run the actual Sage script if [ -x "$SAGE_ROOT/src/bin/sage" ]; then exec "$SAGE_ROOT/src/bin/sage" "$@" -elif [ -x "$SAGE_ROOT/local/bin/sage" ]; then # if in a stripped binary - # Note in this case we assume that SAGE_LOCAL is the "local" subdirectory - exec "$SAGE_ROOT/local/bin/sage" "$@" else echo >&2 "$0: no Sage installation found in \$SAGE_ROOT=$SAGE_ROOT" exit 1 From d7a226ce7251706fa92a8a99bba6788115e504e4 Mon Sep 17 00:00:00 2001 From: "Trevor K. Karn" Date: Wed, 11 May 2022 14:30:01 -0500 Subject: [PATCH 393/529] Initial commit --- src/sage/matroids/matroid.pyx | 50 ++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index ef9096fa1d9..3941e6682c9 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -133,6 +133,7 @@ additional functionality (e.g. linear extensions). - Construction - :meth:`union() ` + - :math:`direct_sum() ` - Misc - :meth:`broken_circuit_complex() ` @@ -8011,7 +8012,7 @@ cdef class Matroid(SageObject): OUTPUT: - An instance of MatroidUnion. + An instance of :class:`MatroidUnion `. EXAMPLES:: @@ -8035,3 +8036,50 @@ cdef class Matroid(SageObject): # place this matroid at the beginning of the list matroids.insert(0, self) return union_matroid.MatroidUnion(iter(matroids)) + + def direct_sum(self, matroids): + r""" + Return the matroid direct sum with another matroid or list of + matroids. + + Let `(M_1, M_2, \ldots, M_k)` be a list of matroids where each `M_i` + has ground set `E_i`. The matroid sum `(E_1,I_1),\ldots,(E_n,I_n)` + is a matroid `(E,I)` where `E= \bigsqcup_{i=1}^n E_i` and + `I= \bigsqcup_{i=1}^n I_i`. + + INPUT: + + - ``matroids`` - a matroid or list of matroids + + OUTPUT: + + An instance of :class:`MatroidSum ` + + EXAMPLES:: + + sage: M = matroids.named_matroids.Pappus() + sage: N = matroids.named_matroids.Fano().direct_sum(M); N + Matroid of rank 6 on 16 elements as matroid sum of + Binary matroid of rank 3 on 7 elements, type (3, 0) + Matroid of rank 3 on 9 elements with circuit-closures + {2: {{'a', 'b', 'c'}, {'a', 'e', 'i'}, {'a', 'f', 'h'}, {'b', 'd', 'i'}, {'b', 'f', 'g'}, {'c', 'd', 'h'}, {'c', 'e', 'g'}, {'d', 'e', 'f'}, {'g', 'h', 'i'}}, 3: {{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'}}} + sage: len(N.independent_sets()) + 6897 + sage: len(N.bases()) + 2100 + """ + + from . import union_matroid + if isinstance(matroids, Matroid): + matroids = [matroids] + else: + for M in matroids: + if not isinstance(M, Matroid): + raise TypeError("can only take the sum with a " + "matroid or list of matroids") + matroids = [M for M in matroids if M] + if not matroids: + return self + # place this matroid at the beginning of the list + matroids.insert(0, self) + return union_matroid.MatroidSum(iter(matroids)) From 278cc0da5aa3f11a687c5a311ba9e8c09e484778 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Bissey?= Date: Thu, 12 May 2022 12:11:06 +1200 Subject: [PATCH 394/529] Remove sage_build which is only used to generate wrappers and move the generation to setup.py in all cases. --- pkgs/sagemath-standard/setup.py | 8 +++--- src/sage_setup/command/sage_build.py | 37 ---------------------------- 2 files changed, 5 insertions(+), 40 deletions(-) delete mode 100644 src/sage_setup/command/sage_build.py diff --git a/pkgs/sagemath-standard/setup.py b/pkgs/sagemath-standard/setup.py index 8d3ed741c3f..45be0c28491 100755 --- a/pkgs/sagemath-standard/setup.py +++ b/pkgs/sagemath-standard/setup.py @@ -44,13 +44,11 @@ from sage_setup.setenv import setenv setenv() - from sage_setup.command.sage_build import sage_build from sage_setup.command.sage_build_cython import sage_build_cython from sage_setup.command.sage_build_ext import sage_build_ext from sage_setup.command.sage_install import sage_install_and_clean - cmdclass = dict(build=sage_build, - build_cython=sage_build_cython, + cmdclass = dict(build_cython=sage_build_cython, build_ext=sage_build_ext, install=sage_install_and_clean) @@ -75,6 +73,10 @@ python_modules = [] cython_modules = [] else: + log.info("Generating auto-generated sources") + from sage_setup.autogen import autogen_all + autogen_all() + # TODO: This should be quiet by default print("Discovering Python/Cython source code....") t = time.time() diff --git a/src/sage_setup/command/sage_build.py b/src/sage_setup/command/sage_build.py deleted file mode 100644 index 229af4292fb..00000000000 --- a/src/sage_setup/command/sage_build.py +++ /dev/null @@ -1,37 +0,0 @@ -# Import setuptools before importing distutils, so that setuptools -# can replace distutils by its own vendored copy. -import setuptools - -from distutils import log -from distutils.command.build import build - -class sage_build(build): - sub_commands = [('build_cython', lambda *args: True)] + build.sub_commands - - def run_autogen(self): - """ - Generate auto-generated sources. - - This must be done before building the python modules, - see :trac:`22106`. - """ - from sage_setup.autogen import autogen_all - from sage_setup.find import find_python_sources - from sage.env import SAGE_SRC - - log.info("Generating auto-generated sources") - - pkgs = autogen_all() - python_packages, python_modules, cython_modules = find_python_sources( - SAGE_SRC, [ pkg.replace('.', '/') for pkg in pkgs]) - - for pkg in python_packages: - if pkg not in self.distribution.packages: - self.distribution.packages.append(pkg) - - for cython_module in cython_modules: - self.distribution.ext_modules.append(cython_module) - - def run(self): - self.run_autogen() - build.run(self) From 7bc33942f364445d82bab575065a1ff160cb7ed9 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 11 May 2022 21:24:07 -0700 Subject: [PATCH 395/529] README.md: Use ./sage in command line --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 83f04dd445f..ae7f22e225b 100644 --- a/README.md +++ b/README.md @@ -419,7 +419,7 @@ in the Installation Guide. having to either type the full path or navigate to the Sage directory and type `./sage`. This can be done by running: - $ sudo ln -s $(sage -sh -c 'ls $SAGE_ROOT/venv/bin/sage') /usr/local/bin + $ sudo ln -s $(./sage -sh -c 'ls $SAGE_ROOT/venv/bin/sage') /usr/local/bin 19. Optional: Set up SageMath as a Jupyter kernel in an existing Jupyter notebook or JupyterLab installation, as described in [section From bf849a0e708a199081329ab380ffab580535b322 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 12 May 2022 08:56:09 +0200 Subject: [PATCH 396/529] remove has_key deprceated in 25281 --- src/sage/misc/converting_dict.py | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/src/sage/misc/converting_dict.py b/src/sage/misc/converting_dict.py index 434da1489f2..48f3f5de3a5 100644 --- a/src/sage/misc/converting_dict.py +++ b/src/sage/misc/converting_dict.py @@ -35,7 +35,6 @@ sage: list(v)[0].parent() Multivariate Polynomial Ring in x, y over Algebraic Real Field """ - # **************************************************************************** # Copyright (C) 2015 Martin von Gagern # @@ -76,7 +75,6 @@ class KeyConvertingDict(dict): sage: d[5.0] = 64 sage: d["05"] 64 - """ def __init__(self, key_conversion_function, data=None): @@ -180,33 +178,6 @@ def __contains__(self, key): key = self.key_conversion_function(key) return super(KeyConvertingDict, self).__contains__(key) - def has_key(self, key): - r""" - Deprecated; present just for the sake of compatibility. - - Use ``key in self`` instead. - - INPUT: - - - ``key`` -- A value identifying the element, will be converted. - - EXAMPLES:: - - sage: from sage.misc.converting_dict import KeyConvertingDict - sage: d = KeyConvertingDict(int) - sage: d[3] = 42 - sage: d.has_key("3") - doctest:warning...: - DeprecationWarning: use 'key in dictionary' syntax instead - See https://trac.sagemath.org/25281 for details. - True - sage: d.has_key(4) - False - """ - from sage.misc.superseded import deprecation - deprecation(25281, "use 'key in dictionary' syntax instead") - return key in self - def pop(self, key, *args): r""" Remove and retrieve a given element from the dictionary. From 292144d792d0429e86a92f606c7b982eb1e151a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 12 May 2022 09:08:36 +0200 Subject: [PATCH 397/529] remove deprecated stuff from 17405 --- src/sage/matrix/matrix2.pyx | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index b68985cbc1d..e5ee75f2fbd 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -783,14 +783,13 @@ cdef class Matrix(Matrix1): sage: b = vector(QQ[I], [1+I, 2]) sage: x = A.solve_right(b) - Calling this method with anything but a vector or matrix is - deprecated:: + This method must be called with a vector or a matrix:: - sage: A = matrix(CDF, 5, [1/(i+j+1) for i in range(5) for j in range(5)]) - sage: x = A.solve_right([1]*5) - doctest:...: DeprecationWarning: solve_right should be called with - a vector or matrix - See http://trac.sagemath.org/17405 for details. + sage: A = matrix(CDF, 2, [1 for i in range(4)]) + sage: x = A.solve_right([1]*2) + Traceback (most recent call last): + ... + TypeError: the second argument must be a vector or a matrix Over inexact rings, the ``check`` parameter is ignored as the result is only an approximate solution (:trac:`13932`):: @@ -838,11 +837,7 @@ cdef class Matrix(Matrix1): try: L = B.base_ring() except AttributeError: - from sage.misc.superseded import deprecation - deprecation(17405, "solve_right should be called with a vector " - "or matrix") - from sage.modules.free_module_element import vector - B = vector(B) + raise TypeError("the second argument must be a vector or a matrix") b_is_vec = is_Vector(B) if b_is_vec: if self.nrows() != B.degree(): From 70e2c1e278b55740deaa4087108e8c6258150a10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 12 May 2022 11:57:05 +0200 Subject: [PATCH 398/529] pep cleanup for multi_polynomial_ring_base.pyx --- .../polynomial/multi_polynomial_ring_base.pyx | 212 +++++++++--------- 1 file changed, 112 insertions(+), 100 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx index 8847a6a2764..02eeb51bacf 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx @@ -1,7 +1,6 @@ r""" Base class for multivariate polynomial rings """ - import sage.misc.latex from sage.misc.cachefunc import cached_method from sage.misc.misc_c import prod @@ -85,19 +84,19 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): order = TermOrder(order, n) self.__ngens = n self.__term_order = order - self._has_singular = False #cannot convert to Singular by default + self._has_singular = False # cannot convert to Singular by default self._magma_cache = {} # Ring.__init__ already does assign the names. # It would be a mistake to call ParentWithGens.__init__ # as well, assigning the names twice. - #ParentWithGens.__init__(self, base_ring, names) + # ParentWithGens.__init__(self, base_ring, names) if base_ring.is_zero(): category = categories.rings.Rings().Finite() else: category = polynomial_default_category(base_ring.category(), n) sage.rings.ring.Ring.__init__(self, base_ring, names, category=category) - def is_integral_domain(self, proof = True): + def is_integral_domain(self, proof=True): """ EXAMPLES:: @@ -317,7 +316,8 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): from .polynomial_ring_constructor import PolynomialRing if order is None: try: - return PolynomialRing(self.base_ring(), vars, order=self.term_order()) + return PolynomialRing(self.base_ring(), vars, + order=self.term_order()) except ValueError: raise ValueError("impossible to use the original term order (most likely because it was a block order). Please specify the term order for the subring") else: @@ -449,7 +449,7 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): name_mapping = [(other_vars.index(var) if var in other_vars else -1) for var in self.variable_names()] K = self.base_ring() D = {} - var_range = xrange(len(self.variable_names())) + var_range = range(len(self.variable_names())) for ix, a in x.dict().iteritems(): ix = ETuple([0 if name_mapping[t] == -1 else ix[name_mapping[t]] for t in var_range]) D[ix] = K(a) @@ -493,7 +493,8 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): generators_rep = "no variables" else: generators_rep = ", ".join(self.variable_names()) - return "Multivariate Polynomial Ring in %s over %s"%(generators_rep, self.base_ring()) + return "Multivariate Polynomial Ring in %s over %s" % (generators_rep, + self.base_ring()) def repr_long(self): """ @@ -516,21 +517,21 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): k = self.base_ring() names = self.variable_names() T = self.term_order() - _repr = "Polynomial Ring\n" - _repr += " Base Ring : %s\n"%(k,) - _repr += " Size : %d Variables\n"%(n,) + _repr = "Polynomial Ring\n" + _repr += " Base Ring : %s\n" % (k,) + _repr += " Size : %d Variables\n" % (n,) offset = 0 i = 0 for order in T.blocks(): - _repr += " Block % 2d : Ordering : %s\n"%(i,inv_singular_name_mapping.get(order.singular_str(), order.singular_str())) - _repr += " Names : %s\n"%(", ".join(names[offset:offset + len(order)])) + _repr += " Block % 2d : Ordering : %s\n" % (i, inv_singular_name_mapping.get(order.singular_str(), order.singular_str())) + _repr += " Names : %s\n" % (", ".join(names[offset:offset + len(order)])) offset += len(order) - i+=1 + i += 1 return _repr def _latex_(self): vars = ', '.join(self.latex_variable_names()) - return "%s[%s]"%(sage.misc.latex.latex(self.base_ring()), vars) + return "%s[%s]" % (sage.misc.latex.latex(self.base_ring()), vars) def _ideal_class_(self, n=0): return multi_polynomial_ideal.MPolynomialIdeal @@ -601,7 +602,8 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): """ B = magma(self.base_ring()) Bref = B._ref() - s = 'PolynomialRing(%s,%s,%s)'%(Bref, self.ngens(), self.term_order().magma_str()) + s = 'PolynomialRing(%s,%s,%s)' % (Bref, self.ngens(), + self.term_order().magma_str()) return magma._with_names(s, self.variable_names()) def _gap_init_(self, gap=None): @@ -628,10 +630,12 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): sage: libgap(P) [x,y] """ - L = ['"%s"'%t for t in self.variable_names()] + L = ['"%s"' % t for t in self.variable_names()] if gap is not None: - return 'PolynomialRing(%s,[%s])'%(gap(self.base_ring()).name(),','.join(L)) - return 'PolynomialRing(%s,[%s])'%(self.base_ring()._gap_init_(),','.join(L)) + return 'PolynomialRing(%s,[%s])' % (gap(self.base_ring()).name(), + ','.join(L)) + return 'PolynomialRing(%s,[%s])' % (self.base_ring()._gap_init_(), + ','.join(L)) cpdef bint is_exact(self) except -2: """ @@ -647,7 +651,7 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): """ return self.base_ring().is_exact() - def is_field(self, proof = True): + def is_field(self, proof=True): """ Test whether this multivariate polynomial ring is a field. @@ -744,7 +748,6 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): except AttributeError: return self.base_ring() - def krull_dimension(self): return self.base_ring().krull_dimension() + self.ngens() @@ -757,15 +760,13 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): def __reduce__(self): """ """ - base_ring = self.base_ring() n = self.ngens() names = self.variable_names() order = self.term_order() + return unpickle_MPolynomialRing_generic_v1, (base_ring, n, names, order) - return unpickle_MPolynomialRing_generic_v1,(base_ring, n, names, order) - - def _precomp_counts(self,n, d): + def _precomp_counts(self, n, d): """ Given a number of variable n and a degree d return a tuple (C,t) such that C is a list of the cardinalities of the sets of @@ -802,15 +803,13 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): 1 sage: t 3 - """ - C = [1] #d = 0 - for dbar in xrange(1, d+1): - C.append(binomial(n+dbar-1, dbar)) - t = sum(C) - return C, t + C = [1] # d = 0 + for dbar in range(1, d + 1): + C.append(binomial(n + dbar - 1, dbar)) + return C, sum(C) - def _to_monomial(self,i, n, d): + def _to_monomial(self, i, n, d): """ Given an index i, a number of variables n and a degree d return the i-th monomial of degree d in n variables. @@ -837,18 +836,19 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): range. If it is not an infinite loop will occur. """ from sage.combinat import combination - comb = combination.from_rank(i, n+d-1, n-1) - if comb == []: + comb = combination.from_rank(i, n + d - 1, n - 1) + if not comb: return (d,) - monomial = [ comb[0] ] + monomial = [comb[0]] res = [] - for j in range(n-2): - res.append(comb[j+1]-comb[j]-1) + for j in range(n - 2): + res.append(comb[j + 1] - comb[j] - 1) monomial += res - monomial.append( n+d-1-comb[-1]-1 ) + monomial.append(n + d - 1 - comb[-1] - 1) return tuple(monomial) - def _random_monomial_upto_degree_class(self,n, degree, counts=None, total=None): + def _random_monomial_upto_degree_class(self, n, degree, counts=None, + total=None): """ Choose a random exponent tuple for `n` variables with a random degree `d`, i.e. choose the degree uniformly at random first @@ -884,16 +884,17 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): ....: more_samples() """ # bug: doesn't handle n=1 - #Select random degree - d = ZZ.random_element(0,degree+1) - total = binomial(n+d-1, d) + # Select random degree + d = ZZ.random_element(0, degree + 1) + total = binomial(n + d - 1, d) - #Select random monomial of degree d + # Select random monomial of degree d random_index = ZZ.random_element(0, total) - #Generate the corresponding monomial + # Generate the corresponding monomial return self._to_monomial(random_index, n, d) - def _random_monomial_upto_degree_uniform(self,n, degree, counts=None, total=None): + def _random_monomial_upto_degree_uniform(self, n, degree, counts=None, + total=None): """ Choose a random exponent tuple for `n` variables with a random degree up to `d`, i.e. choose a random monomial uniformly random @@ -928,17 +929,18 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): if counts is None or total is None: counts, total = self._precomp_counts(n, degree) - #Select a random one - random_index = ZZ.random_element(0, total-1) - #Figure out which degree it corresponds to + # Select a random one + random_index = ZZ.random_element(0, total - 1) + # Figure out which degree it corresponds to d = 0 while random_index >= counts[d]: random_index -= counts[d] d += 1 - #Generate the corresponding monomial + # Generate the corresponding monomial return self._to_monomial(random_index, n, d) - def random_element(self, degree=2, terms=None, choose_degree=False,*args, **kwargs): + def random_element(self, degree=2, terms=None, choose_degree=False, + *args, **kwargs): """ Return a random polynomial of at most degree `d` and at most `t` terms. @@ -1083,14 +1085,13 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): if degree == 0: return self(k.random_element(**kwargs)) - from sage.combinat.integer_vector import IntegerVectors - #total is 0. Just return + # total is 0. Just return if total == 0: return self._zero_element - elif terms < total/2: + elif terms < total / 2: # we choose random monomials if t < total/2 because then we # expect the algorithm to be faster than generating all # monomials and picking a random index from the list. if t == @@ -1112,26 +1113,27 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): elif terms <= total: # generate a list of all monomials and choose among them if not choose_degree: - M = sum([list(IntegerVectors(_d,n)) for _d in xrange(degree+1)],[]) + M = sum([list(IntegerVectors(_d, n)) + for _d in range(degree + 1)], []) # we throw away those we don't need - for mi in xrange(total - terms): - M.pop( ZZ.random_element(0,len(M)-1) ) + for mi in range(total - terms): + M.pop(ZZ.random_element(0, len(M) - 1)) M = [tuple(m) for m in M] else: - M = [list(IntegerVectors(_d,n)) for _d in xrange(degree+1)] + M = [list(IntegerVectors(_d, n)) for _d in range(degree + 1)] Mbar = [] - for mi in xrange(terms): + for mi in range(terms): # choose degree 'd' and monomial 'm' at random - d = ZZ.random_element(0,len(M)) - m = ZZ.random_element(0,len(M[d])) - Mbar.append( M[d].pop(m) ) # remove and insert + d = ZZ.random_element(0, len(M)) + m = ZZ.random_element(0, len(M[d])) + Mbar.append(M[d].pop(m)) # remove and insert if len(M[d]) == 0: - M.pop(d) # bookkeeping + M.pop(d) # bookkeeping M = [tuple(m) for m in Mbar] - C = [k.random_element(*args,**kwargs) for _ in range(len(M))] + C = [k.random_element(*args, **kwargs) for _ in range(len(M))] - return self(dict(zip(M,C))) + return self(dict(zip(M, C))) def change_ring(self, base_ring=None, names=None, order=None): """ @@ -1164,7 +1166,7 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): from .polynomial_ring_constructor import PolynomialRing return PolynomialRing(base_ring, self.ngens(), names, order=order) - def monomial(self,*exponents): + def monomial(self, *exponents): """ Return the monomial with given exponents. @@ -1180,9 +1182,9 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): sage: R.monomial(*m.degrees()) == m True """ - return self({exponents:self.base_ring().one()}) + return self({exponents: self.base_ring().one()}) - def _macaulay_resultant_getS(self,mon_deg_tuple,dlist): + def _macaulay_resultant_getS(self, mon_deg_tuple, dlist): r""" In the Macaulay resultant algorithm the list of all monomials of the total degree is partitioned into sets `S_i`. This function returns the index `i` for the set `S_i` for the given monomial. @@ -1209,37 +1211,45 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): sage: R._macaulay_resultant_getS(list(range(9))+[10],list(range(1,11))) 9 """ - for i in xrange(len(dlist)): + for i in range(len(dlist)): if mon_deg_tuple[i] - dlist[i] >= 0: return i - def _macaulay_resultant_is_reduced(self,mon_degs,dlist): + def _macaulay_resultant_is_reduced(self, mon_degs, dlist) -> bool: r""" Helper function for the Macaulay resultant algorithm. - A monomial in the variables `x_0,...,x_n` is called reduced with respect to the list of degrees `d_0,...,d_n` - if the degree of `x_i` in the monomial is `>= d_i` for exactly one `i`. This function checks this property for a monomial. + + A monomial in the variables `x_0,...,x_n` is called reduced with + respect to the list of degrees `d_0,...,d_n` + if the degree of `x_i` in the monomial is `>= d_i` for exactly + one `i`. This function checks this property for a monomial. INPUT: - ``mon_degs`` -- a monomial represented by a vector of degrees - - ``dlist`` -- a list of degrees with respect to which we check reducedness + - ``dlist`` -- a list of degrees with respect to which we check + reducedness OUTPUT: - - True/False + boolean - EXAMPLES:: + EXAMPLES: + + The monomial x^2*y^3*z is not reduced w.r.t. degrees vector [2,3,3]:: sage: R. = PolynomialRing(QQ,3) - sage: R._macaulay_resultant_is_reduced([2,3,1],[2,3,3]) # the monomial x^2*y^3*z is not reduced w.r.t. degrees vector [2,3,3] + sage: R._macaulay_resultant_is_reduced([2,3,1],[2,3,3]) False + The monomial x*y^3*z^2 is not reduced w.r.t. degrees vector [2,3,3]:: + sage: R. = PolynomialRing(QQ,3) - sage: R._macaulay_resultant_is_reduced([1,3,2],[2,3,3]) # the monomial x*y^3*z^2 is not reduced w.r.t. degrees vector [2,3,3] + sage: R._macaulay_resultant_is_reduced([1,3,2],[2,3,3]) True """ - diff = [mon_degs[i] - dlist[i] for i in xrange(0,len(dlist))] - return len([1 for d in diff if d >= 0]) == 1 + diff = [True for mi, di in zip(mon_degs, dlist) if mi >= di] + return len(diff) == 1 def _macaulay_resultant_universal_polynomials(self, dlist): r""" @@ -1266,21 +1276,21 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): Polynomial Ring in u0, u1, u2, u3, u4, u5, u6, u7, u8, u9, u10, u11 over Integer Ring) """ - n = len(dlist) - 1 - number_of_coeffs = sum([binomial(n+di,di) for di in dlist]) - U = PolynomialRing(ZZ,'u',number_of_coeffs) + n = len(dlist) - 1 + number_of_coeffs = sum([binomial(n + di, di) for di in dlist]) + U = PolynomialRing(ZZ, 'u', number_of_coeffs) d = sum(dlist) - len(dlist) + 1 flist = [] - R = PolynomialRing(U,'x',n+1) - ulist = U.gens() + R = PolynomialRing(U, 'x', n + 1) + ulist = U.gens() for d in dlist: xlist = R.gens() - degs = IntegerVectors(d, n+1) - mon_d = [prod([xlist[i]**(deg[i]) for i in xrange(0,len(deg))]) + degs = IntegerVectors(d, n + 1) + mon_d = [prod([xlist[i]**(deg[i]) for i in range(len(deg))]) for deg in degs] - f = sum([mon_d[i]*ulist[i] for i in xrange(0,len(mon_d))]) - flist.append (f) + f = sum([mon_d[i] * ulist[i] for i in range(len(mon_d))]) + flist.append(f) ulist = ulist[len(mon_d):] return flist, R @@ -1440,7 +1450,7 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): from sage.matrix.constructor import matrix from sage.matrix.constructor import zero_matrix - if len(args) == 1 and isinstance(args[0],list): + if len(args) == 1 and isinstance(args[0], list): flist = args[0] else: flist = args @@ -1454,48 +1464,49 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): sparse = kwds.pop('sparse', False) - U = self.base_ring() # ring of coefficients of self + U = self.base_ring() # ring of coefficients of self dlist = [f.degree() for f in flist] xlist = self.gens() if len(xlist) != len(dlist): - raise TypeError('number of polynomials(= %d) must equal number of variables (= %d)'%(len(dlist),len(xlist))) + raise TypeError('number of polynomials(= %d) must equal number of variables (= %d)' % (len(dlist), len(xlist))) n = len(dlist) - 1 d = sum(dlist) - len(dlist) + 1 # list of exponent-vectors(/lists) of monomials of degree d: - mons = IntegerVectors(d, n+1).list() + mons = IntegerVectors(d, n + 1).list() # a reverse index lookup for monomials: - mons_idx = { str(mon) : idx for idx,mon in enumerate(mons)} + mons_idx = {str(mon): idx for idx, mon in enumerate(mons)} mons_num = len(mons) mons_to_keep = [] newflist = [] # strip coefficients of the input polynomials: - flist=[[f.exponents(),f.coefficients()] for f in flist] - numer_matrix = zero_matrix(self.base_ring(),mons_num, sparse=sparse) + flist = [[f.exponents(), f.coefficients()] for f in flist] + numer_matrix = zero_matrix(self.base_ring(), mons_num, sparse=sparse) - for j,mon in enumerate(mons): + for j, mon in enumerate(mons): # if monomial is not reduced, then we keep it in the # denominator matrix: - if not self._macaulay_resultant_is_reduced(mon,dlist): + if not self._macaulay_resultant_is_reduced(mon, dlist): mons_to_keep.append(j) si_mon = self._macaulay_resultant_getS(mon, dlist) # Monomial is in S_i under the partition, now we reduce # the i'th degree of the monomial new_mon = list(mon) new_mon[si_mon] -= dlist[si_mon] - new_f = [[[g[k] + new_mon[k] for k in range(n+1)] + new_f = [[[g[k] + new_mon[k] for k in range(n + 1)] for g in flist[si_mon][0]], flist[si_mon][1]] - for i,mon in enumerate(new_f[0]): + for i, mon in enumerate(new_f[0]): k = mons_idx[str(mon)] - numer_matrix[j,k]=new_f[1][i] + numer_matrix[j, k] = new_f[1][i] - denom_matrix = numer_matrix.matrix_from_rows_and_columns(mons_to_keep,mons_to_keep) + denom_matrix = numer_matrix.matrix_from_rows_and_columns(mons_to_keep, + mons_to_keep) # here we choose the determinant of an empty matrix to be 1 if denom_matrix.dimensions()[0] == 0: return U(numer_matrix.det()) denom_det = denom_matrix.det() if denom_det != 0: - return U(numer_matrix.det()/denom_det) + return U(numer_matrix.det() / denom_det) # if we get to this point, the determinant of the denominator # was 0, and we get the resultant by taking the free # coefficient of the quotient of two characteristic @@ -1520,6 +1531,7 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): from sage.algebras.weyl_algebra import DifferentialWeylAlgebra return DifferentialWeylAlgebra(self) + #################### # Leave *all* old versions! From 888d18eb851f892097a0a683c01e3a95db863495 Mon Sep 17 00:00:00 2001 From: Release Manager Date: Thu, 12 May 2022 23:43:15 +0200 Subject: [PATCH 399/529] Updated SageMath version to 9.6.rc4 --- .zenodo.json | 8 ++++---- VERSION.txt | 2 +- build/pkgs/configure/checksums.ini | 6 +++--- build/pkgs/configure/package-version.txt | 2 +- build/pkgs/sagelib/package-version.txt | 2 +- src/VERSION.txt | 2 +- src/bin/sage-version.sh | 6 +++--- src/sage/version.py | 6 +++--- 8 files changed, 17 insertions(+), 17 deletions(-) diff --git a/.zenodo.json b/.zenodo.json index d2346f2f37f..89887360497 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -1,10 +1,10 @@ { "description": "Mirror of the Sage https://sagemath.org/ source tree", "license": "other-open", - "title": "sagemath/sage: 9.6.rc3", - "version": "9.6.rc3", + "title": "sagemath/sage: 9.6.rc4", + "version": "9.6.rc4", "upload_type": "software", - "publication_date": "2022-04-29", + "publication_date": "2022-05-12", "creators": [ { "affiliation": "SageMath.org", @@ -15,7 +15,7 @@ "related_identifiers": [ { "scheme": "url", - "identifier": "https://github.com/sagemath/sage/tree/9.6.rc3", + "identifier": "https://github.com/sagemath/sage/tree/9.6.rc4", "relation": "isSupplementTo" }, { diff --git a/VERSION.txt b/VERSION.txt index 161f2afb9d7..dc3ae1ae0ce 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -SageMath version 9.6.rc3, Release Date: 2022-04-29 +SageMath version 9.6.rc4, Release Date: 2022-05-12 diff --git a/build/pkgs/configure/checksums.ini b/build/pkgs/configure/checksums.ini index 5c419e0cd3b..6d491dc9d63 100644 --- a/build/pkgs/configure/checksums.ini +++ b/build/pkgs/configure/checksums.ini @@ -1,4 +1,4 @@ tarball=configure-VERSION.tar.gz -sha1=e11416ff1fbc71f612b6ffcd01376ed043611cf0 -md5=cc5d341921b9aea2ae33d8ba2227daf5 -cksum=3415160552 +sha1=ebad99b2c419469d2b491a012dc3a4d53a0fc4c0 +md5=f0696455b8ba7dc50b7d23031f52ed19 +cksum=143579459 diff --git a/build/pkgs/configure/package-version.txt b/build/pkgs/configure/package-version.txt index 3db1e644514..6d234b474a0 100644 --- a/build/pkgs/configure/package-version.txt +++ b/build/pkgs/configure/package-version.txt @@ -1 +1 @@ -164a46b53a900a8d82cc270f01952556fed42ba4 +feb23e71747e42520fe984fa377c7ce5b5af025e diff --git a/build/pkgs/sagelib/package-version.txt b/build/pkgs/sagelib/package-version.txt index 24562793a28..82b75159501 100644 --- a/build/pkgs/sagelib/package-version.txt +++ b/build/pkgs/sagelib/package-version.txt @@ -1 +1 @@ -9.6.rc3 +9.6.rc4 diff --git a/src/VERSION.txt b/src/VERSION.txt index 24562793a28..82b75159501 100644 --- a/src/VERSION.txt +++ b/src/VERSION.txt @@ -1 +1 @@ -9.6.rc3 +9.6.rc4 diff --git a/src/bin/sage-version.sh b/src/bin/sage-version.sh index f34be5ac786..edc4ff086d2 100644 --- a/src/bin/sage-version.sh +++ b/src/bin/sage-version.sh @@ -1,5 +1,5 @@ # Sage version information for shell scripts # This file is auto-generated by the sage-update-version script, do not edit! -SAGE_VERSION='9.6.rc3' -SAGE_RELEASE_DATE='2022-04-29' -SAGE_VERSION_BANNER='SageMath version 9.6.rc3, Release Date: 2022-04-29' +SAGE_VERSION='9.6.rc4' +SAGE_RELEASE_DATE='2022-05-12' +SAGE_VERSION_BANNER='SageMath version 9.6.rc4, Release Date: 2022-05-12' diff --git a/src/sage/version.py b/src/sage/version.py index 5d921980573..062dc77315b 100644 --- a/src/sage/version.py +++ b/src/sage/version.py @@ -1,5 +1,5 @@ # Sage version information for Python scripts # This file is auto-generated by the sage-update-version script, do not edit! -version = '9.6.rc3' -date = '2022-04-29' -banner = 'SageMath version 9.6.rc3, Release Date: 2022-04-29' +version = '9.6.rc4' +date = '2022-05-12' +banner = 'SageMath version 9.6.rc4, Release Date: 2022-05-12' From 0a08dfbc9a08fa03c27cf049c5f9f041e1769932 Mon Sep 17 00:00:00 2001 From: Yuan Zhou Date: Thu, 12 May 2022 17:58:09 -0400 Subject: [PATCH 400/529] return all coefficients, including the zero coefficients of P.ehrhart_series().numerator() --- src/sage/geometry/polyhedron/backend_normaliz.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/sage/geometry/polyhedron/backend_normaliz.py b/src/sage/geometry/polyhedron/backend_normaliz.py index e53560aa7ca..26a0e325712 100644 --- a/src/sage/geometry/polyhedron/backend_normaliz.py +++ b/src/sage/geometry/polyhedron/backend_normaliz.py @@ -1433,8 +1433,17 @@ def _h_star_vector_normaliz(self): sage: cube = polytopes.cube(intervals='zero_one', backend='normaliz') # optional - pynormaliz sage: cube.h_star_vector() # optional - pynormaliz [1, 4, 1] + + TESTS: + + Check that :trac:`33847` is fixed:: + + sage: L = [[1, 0, 0, 0, 0, 0], [1, 1, 0, 0, 0, 0], [1, 0, 1, 0, 0, 0], + ....: [1, 0, 0, 1, 0, 0], [1, 0, 0, 0, 1, 0], [1, 0, 0, 1, 2, 3]] + sage: P = Polyhedron(vertices=L,backend='normaliz') # optional - pynormaliz + sage: P.h_star_vector() # optional - pynormaliz """ - return self.ehrhart_series().numerator().coefficients() + return self.ehrhart_series().numerator().list() def _volume_normaliz(self, measure='euclidean'): r""" From 6027fb10ed52f1c14876a9a431b72ceec9c8425a Mon Sep 17 00:00:00 2001 From: Yuan Zhou Date: Fri, 13 May 2022 01:26:44 -0400 Subject: [PATCH 401/529] new doctest --- src/sage/geometry/polyhedron/backend_normaliz.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/geometry/polyhedron/backend_normaliz.py b/src/sage/geometry/polyhedron/backend_normaliz.py index 26a0e325712..f932b0081c4 100644 --- a/src/sage/geometry/polyhedron/backend_normaliz.py +++ b/src/sage/geometry/polyhedron/backend_normaliz.py @@ -1442,6 +1442,7 @@ def _h_star_vector_normaliz(self): ....: [1, 0, 0, 1, 0, 0], [1, 0, 0, 0, 1, 0], [1, 0, 0, 1, 2, 3]] sage: P = Polyhedron(vertices=L,backend='normaliz') # optional - pynormaliz sage: P.h_star_vector() # optional - pynormaliz + [1, 0, 2] """ return self.ehrhart_series().numerator().list() From 5bf1e6b8299f5d819dbfdb113016c2d263f2466f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 13 May 2022 09:33:29 +0200 Subject: [PATCH 402/529] ordering imports, using sleep(int(..)) and sleep(float(..)) --- src/sage/parallel/map_reduce.py | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/sage/parallel/map_reduce.py b/src/sage/parallel/map_reduce.py index 7c30080ab95..b00a9514fda 100644 --- a/src/sage/parallel/map_reduce.py +++ b/src/sage/parallel/map_reduce.py @@ -541,22 +541,21 @@ # (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** - -from collections import deque -from threading import Thread -from sage.sets.recursively_enumerated_set import RecursivelyEnumeratedSet # _generic -from sage.misc.lazy_attribute import lazy_attribute import copy import sys import random import queue import ctypes +import logging +import multiprocessing as mp +from collections import deque +from threading import Thread +from sage.sets.recursively_enumerated_set import RecursivelyEnumeratedSet # _generic +from sage.misc.lazy_attribute import lazy_attribute -import logging logger = logging.getLogger(__name__) -logger.__doc__ = ( -""" +logger.__doc__ = (""" A logger for :mod:`sage.parallel.map_reduce` .. SEEALSO:: @@ -578,7 +577,6 @@ # Set up a multiprocessing context to use for this modules (using the # 'fork' method which is basically same as on Python 2) -import multiprocessing as mp mp = mp.get_context('fork') @@ -1698,7 +1696,7 @@ def run(self): sage: w._todo.append(EX.roots()[0]) sage: w.run() - sage: sleep(1) + sage: sleep(int(1)) sage: w._todo.append(None) sage: EX.get_results() @@ -1734,7 +1732,7 @@ def run_myself(self): sage: w._todo.append(EX.roots()[0]) sage: w.run_myself() - sage: sleep(1) + sage: sleep(int(1)) sage: w._todo.append(None) sage: EX.get_results() From 279376f5e0db8842eb9065f3657a9baafcc6c2d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 13 May 2022 09:40:35 +0200 Subject: [PATCH 403/529] turn off debugging --- src/sage/parallel/map_reduce.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/parallel/map_reduce.py b/src/sage/parallel/map_reduce.py index b00a9514fda..8449e683184 100644 --- a/src/sage/parallel/map_reduce.py +++ b/src/sage/parallel/map_reduce.py @@ -563,9 +563,9 @@ `Logging facility for Python `_ for more detail on logging and log system configuration. """) -# logger.setLevel(logging.WARN) +logger.setLevel(logging.WARN) # logger.setLevel(logging.INFO) -logger.setLevel(logging.DEBUG) +# logger.setLevel(logging.DEBUG) ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) formatter = logging.Formatter( From a925aadc305b9b1f6b364f464f0a2f1e02877f03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20Leli=C3=A8vre?= Date: Fri, 13 May 2022 19:06:05 +0200 Subject: [PATCH 404/529] Fix typo ment -> meant --- src/sage/crypto/block_cipher/des.py | 2 +- src/sage/crypto/block_cipher/present.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/crypto/block_cipher/des.py b/src/sage/crypto/block_cipher/des.py index 0e6ecb06e22..4eddfba1425 100644 --- a/src/sage/crypto/block_cipher/des.py +++ b/src/sage/crypto/block_cipher/des.py @@ -6,7 +6,7 @@ This file implements the Data Encryption Standard and the corresponding key schedule as described in [U.S1999]_. -Note, this implementation is ment for experimental and educational usage only, +This implementation is meant for experimental and educational usage only, do not use it in production code! EXAMPLES: diff --git a/src/sage/crypto/block_cipher/present.py b/src/sage/crypto/block_cipher/present.py index a550f686e91..4cbb74fc241 100644 --- a/src/sage/crypto/block_cipher/present.py +++ b/src/sage/crypto/block_cipher/present.py @@ -8,7 +8,7 @@ SP-network and consists of 31 rounds. The block length is 64 bits and two key lengths of 80 and 128 bits are supported. -Note, this implementation is ment for experimental and educational usage only, +This implementation is meant for experimental and educational usage only, do not use it in production code! EXAMPLES: From 463e0a919b3a49e689e1e98dbe05348545ff5897 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Fri, 13 May 2022 20:39:13 +0000 Subject: [PATCH 405/529] Try with immeadiate flushing --- src/sage/parallel/map_reduce.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/parallel/map_reduce.py b/src/sage/parallel/map_reduce.py index 8449e683184..0eb4e7acd9f 100644 --- a/src/sage/parallel/map_reduce.py +++ b/src/sage/parallel/map_reduce.py @@ -1137,9 +1137,9 @@ def start_workers(self): sage: from sage.parallel.map_reduce import RESetMapReduce sage: def children(x): - ....: sys.stdout.write(f"Starting: {x}\n") + ....: print(f"Starting: {x}\n", flush=True) ....: sleep(float(0.5)) - ....: sys.stdout.write(f"Finished: {x}\n") + ....: print(f"Finished: {x}\n", flush=True) ....: return [] sage: S = RESetMapReduce(roots=[1, 2], children=children) sage: S.setup_workers(2) From f56a535d712eb598b207c5d88d3c2f32fbbcafaa Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Fri, 13 May 2022 22:12:01 +0000 Subject: [PATCH 406/529] Install esbonio using conda --- .gitpod.yml | 2 -- bootstrap-conda | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitpod.yml b/.gitpod.yml index c3d5a05087d..6017bd072e8 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -11,8 +11,6 @@ tasks: mamba env create --file src/environment-dev.yml --prefix venv conda config --append envs_dirs /workspace/sagetrac-mirror conda activate /workspace/sagetrac-mirror/venv - ## Install esbonio via pip as long as there is no conda package for it: https://github.com/swyddfa/esbonio/issues/371 - pip install esbonio # Build sage ./bootstrap diff --git a/bootstrap-conda b/bootstrap-conda index 356c621895b..40287f81803 100755 --- a/bootstrap-conda +++ b/bootstrap-conda @@ -65,6 +65,7 @@ echo " # Additional dev tools" >> src/environment-dev.yml echo " - openssh" >> src/environment-dev.yml echo " - pycodestyle" >> src/environment-dev.yml echo " - pytest" >> src/environment-dev.yml +echo " - esbonio" >> src/environment-dev.yml cp environment.yml environment-optional.yml echo " # optional packages" >> environment-optional.yml From 7fe3812bf840a6e4d8a08ce6af2ae761dc071265 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Sat, 14 May 2022 09:25:28 +0000 Subject: [PATCH 407/529] Increase first wait time --- src/sage/parallel/map_reduce.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/parallel/map_reduce.py b/src/sage/parallel/map_reduce.py index 0eb4e7acd9f..08f3456a999 100644 --- a/src/sage/parallel/map_reduce.py +++ b/src/sage/parallel/map_reduce.py @@ -1137,13 +1137,13 @@ def start_workers(self): sage: from sage.parallel.map_reduce import RESetMapReduce sage: def children(x): - ....: print(f"Starting: {x}\n", flush=True) + ....: print(f"Starting: {x}", flush=True) ....: sleep(float(0.5)) - ....: print(f"Finished: {x}\n", flush=True) + ....: print(f"Finished: {x}", flush=True) ....: return [] sage: S = RESetMapReduce(roots=[1, 2], children=children) sage: S.setup_workers(2) - sage: S.start_workers(); sleep(float(0.1)) + sage: S.start_workers(); sleep(float(0.4)) Starting: 1 Starting: 2 sage: [w.is_alive() for w in S._workers] From 4290b111c4e89b03fbd01d4b6478ec41d5c4b142 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Sat, 14 May 2022 09:51:34 +0000 Subject: [PATCH 408/529] Add pytest-xdist package --- build/pkgs/pytest_xdist/SPKG.rst | 18 ++++++++++++++++++ build/pkgs/pytest_xdist/dependencies | 4 ++++ build/pkgs/pytest_xdist/distros/conda.txt | 1 + build/pkgs/pytest_xdist/requirements.txt | 1 + build/pkgs/pytest_xdist/type | 1 + src/doc/en/developer/tools.rst | 9 +++++++-- 6 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 build/pkgs/pytest_xdist/SPKG.rst create mode 100644 build/pkgs/pytest_xdist/dependencies create mode 100644 build/pkgs/pytest_xdist/distros/conda.txt create mode 100644 build/pkgs/pytest_xdist/requirements.txt create mode 100644 build/pkgs/pytest_xdist/type diff --git a/build/pkgs/pytest_xdist/SPKG.rst b/build/pkgs/pytest_xdist/SPKG.rst new file mode 100644 index 00000000000..f962a257b37 --- /dev/null +++ b/build/pkgs/pytest_xdist/SPKG.rst @@ -0,0 +1,18 @@ +pytest_xdist: pytest xdist plugin for distributed testing and loop-on-failing modes +=================================================================================== + +Description +----------- + +pytest xdist plugin for distributed testing and loop-on-failing modes + +License +------- + +MIT + +Upstream Contact +---------------- + +https://pypi.org/project/pytest-xdist/ + diff --git a/build/pkgs/pytest_xdist/dependencies b/build/pkgs/pytest_xdist/dependencies new file mode 100644 index 00000000000..0738c2d7777 --- /dev/null +++ b/build/pkgs/pytest_xdist/dependencies @@ -0,0 +1,4 @@ +$(PYTHON) | $(PYTHON_TOOLCHAIN) + +---------- +All lines of this file are ignored except the first. diff --git a/build/pkgs/pytest_xdist/distros/conda.txt b/build/pkgs/pytest_xdist/distros/conda.txt new file mode 100644 index 00000000000..82d8d43dbd4 --- /dev/null +++ b/build/pkgs/pytest_xdist/distros/conda.txt @@ -0,0 +1 @@ +pytest-xdist diff --git a/build/pkgs/pytest_xdist/requirements.txt b/build/pkgs/pytest_xdist/requirements.txt new file mode 100644 index 00000000000..82d8d43dbd4 --- /dev/null +++ b/build/pkgs/pytest_xdist/requirements.txt @@ -0,0 +1 @@ +pytest-xdist diff --git a/build/pkgs/pytest_xdist/type b/build/pkgs/pytest_xdist/type new file mode 100644 index 00000000000..134d9bc32d5 --- /dev/null +++ b/build/pkgs/pytest_xdist/type @@ -0,0 +1 @@ +optional diff --git a/src/doc/en/developer/tools.rst b/src/doc/en/developer/tools.rst index 705ffcd6431..11e2938400a 100644 --- a/src/doc/en/developer/tools.rst +++ b/src/doc/en/developer/tools.rst @@ -252,13 +252,18 @@ package :mod:`sage.numerical.backends` and some modules in *Installation:* -- ``./sage -i pytest``. +- ``./sage -i pytest pytest_xdist``. *Usage:* - Tox, Sage doctester: At the end of ``./sage -t`` (or ``./sage --tox -e doctest``), Pytest is automatically invoked. -- Manual: Run ``./sage -pytest path/to/the/test_file.py`` or ``./sage -pytest`` to run all tests. +- Manual: Run ``./sage -pytest path/to/the/test_file.py`` or ``./sage -pytest`` + to run all tests. The additional argument ``-n`` can be used to + distribute tests across multiple CPUs to speed up test execution. + For example, ``./sage -pytest -n 4`` will run 4 tests in parallel, while + ``./sage -pytest -n auto`` will spawn a number of workers processes equal + to the number of available CPUs. - VS Code: Install the `Python extension `_ and follow the `offical VS Code documentation `__. From a365828e4f08db6b5a86a3d03361017beeb001d8 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 14 May 2022 11:44:05 -0700 Subject: [PATCH 409/529] build/pkgs/pytest/dependencies: Add missing dep --- build/pkgs/pytest/dependencies | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/pytest/dependencies b/build/pkgs/pytest/dependencies index fd38631bd53..7e5a90a20bd 100644 --- a/build/pkgs/pytest/dependencies +++ b/build/pkgs/pytest/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) pluggy packaging attrs py pyparsing importlib_metadata | $(PYTHON_TOOLCHAIN) +$(PYTHON) pluggy packaging attrs py pyparsing importlib_metadata tomli | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. From a2e396beb6c73f817388e3a117c73104a03da99b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 14 May 2022 11:44:20 -0700 Subject: [PATCH 410/529] build/pkgs/pytest_xdist/dependencies: Add missing dep --- build/pkgs/pytest_xdist/dependencies | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/pytest_xdist/dependencies b/build/pkgs/pytest_xdist/dependencies index 0738c2d7777..aa8c608f663 100644 --- a/build/pkgs/pytest_xdist/dependencies +++ b/build/pkgs/pytest_xdist/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) | $(PYTHON_TOOLCHAIN) +$(PYTHON) pytest | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. From ccbc21ad139c604078e2066bd9d34d514072eade Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 14 May 2022 14:07:31 -0700 Subject: [PATCH 411/529] bootstrap, bootstrap-conda, src/doc/bootstrap: Use build/bin/sage-package directly --- bootstrap | 14 +++++++------- bootstrap-conda | 4 +++- src/doc/bootstrap | 10 +++++----- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/bootstrap b/bootstrap index d059afc0482..bf6b2716674 100755 --- a/bootstrap +++ b/bootstrap @@ -85,12 +85,12 @@ bootstrap () { rm -f m4/sage_spkg_configures.m4 spkg_configures="" # initialize SAGE_ENABLE... options for standard packages - for pkgname in $(./sage --package list :standard: | sort); do + for pkgname in $(sage-package list :standard: | sort); do spkg_configures="$spkg_configures AS_VAR_SET_IF([SAGE_ENABLE_$pkgname], [], [AS_VAR_SET([SAGE_ENABLE_$pkgname], [yes])])" done # --enable-SPKG options - for pkgname in $(./sage --package list :optional: :experimental: | sort); do + for pkgname in $(sage-package list :optional: :experimental: | sort); do # Trac #29629: Temporary solution for Sage 9.1: Do not provide # --enable-SPKG options for installing pip packages if [ ! -f build/pkgs/$pkgname/requirements.txt ]; then @@ -109,12 +109,12 @@ SAGE_SPKG_ENABLE([$pkgname], [$pkgtype], [$(grep -v ^= build/pkgs/$pkgname/SPKG. esac fi done - for pkgname in $(./sage --package list --has-file spkg-configure.m4 | sort); do + for pkgname in $(sage-package list --has-file spkg-configure.m4 | sort); do echo "m4_sinclude([build/pkgs/$pkgname/spkg-configure.m4])" spkg_configures="$spkg_configures SAGE_SPKG_CONFIGURE_$(echo ${pkgname} | tr '[a-z]' '[A-Z]')" done >> m4/sage_spkg_configures.m4 - for pkgname in $(./sage --package list | sort); do + for pkgname in $(sage-package list | sort); do DIR=build/pkgs/$pkgname pkgtype="$(cat $DIR/type)" if test -f "$DIR/requirements.txt"; then @@ -143,7 +143,7 @@ SAGE_SPKG_FINALIZE([$pkgname], [$pkgtype], [$SPKG_SOURCE], [$SPKG_TREE_VAR])" done echo "$spkg_configures" >> m4/sage_spkg_configures.m4 - for pkgname in $(./sage --package list --has-file bootstrap); do + for pkgname in $(sage-package list --has-file bootstrap); do (cd build/pkgs/$pkgname && ./bootstrap) || exit 1 done @@ -262,10 +262,10 @@ save () { # Compute checksum if [ "${BOOTSTRAP_QUIET}" = "no" ]; then - ./sage --package fix-checksum configure + sage-package fix-checksum configure else # Hide the "Updating checksum..." message - ./sage --package fix-checksum configure > /dev/null + sage-package fix-checksum configure > /dev/null fi } diff --git a/bootstrap-conda b/bootstrap-conda index 356c621895b..92aea50f939 100755 --- a/bootstrap-conda +++ b/bootstrap-conda @@ -4,6 +4,8 @@ # Generate auto-generated conda environment files ######################################################################### +export PATH="$(pwd)/build/bin:$PATH" + STRIP_COMMENTS="sed s/#.*//;" RECOMMENDED_SPKG_PATTERN="@(_recommended$(for a in $(head -n 1 build/pkgs/_recommended/dependencies); do echo -n "|"$a; done))" @@ -13,7 +15,7 @@ OPTIONAL_SYSTEM_PACKAGES= SAGELIB_SYSTEM_PACKAGES= SAGELIB_OPTIONAL_SYSTEM_PACKAGES= RECOMMENDED_SYSTEM_PACKAGES= -for PKG_BASE in $(./sage --package list --has-file distros/conda.txt); do +for PKG_BASE in $(sage-package list --has-file distros/conda.txt); do PKG_SCRIPTS=build/pkgs/$PKG_BASE SYSTEM_PACKAGES_FILE=$PKG_SCRIPTS/distros/conda.txt PKG_TYPE=$(cat $PKG_SCRIPTS/type) diff --git a/src/doc/bootstrap b/src/doc/bootstrap index 90ae09160ba..7c7c5c9978c 100755 --- a/src/doc/bootstrap +++ b/src/doc/bootstrap @@ -33,7 +33,7 @@ for SYSTEM in arch debian fedora cygwin homebrew; do SAGELIB_SYSTEM_PACKAGES= SAGELIB_OPTIONAL_SYSTEM_PACKAGES= RECOMMENDED_SYSTEM_PACKAGES= - for PKG_BASE in $(./sage --package list --has-file distros/$SYSTEM.txt); do + for PKG_BASE in $(sage-package list --has-file distros/$SYSTEM.txt); do PKG_SCRIPTS=build/pkgs/$PKG_BASE SYSTEM_PACKAGES_FILE=$PKG_SCRIPTS/distros/$SYSTEM.txt PKG_TYPE=$(cat $PKG_SCRIPTS/type) @@ -91,7 +91,7 @@ Sage depends. It installs them automatically if it does not find equivalent system packages. EOF -for PKG_BASE in $(./sage --package list --has-file SPKG.rst :standard: | sort); do +for PKG_BASE in $(sage-package list --has-file SPKG.rst :standard: | sort); do echo "* :ref:\`spkg_$PKG_BASE\`" done >> "$OUTPUT_INDEX" cat >> "$OUTPUT_INDEX" <> "$OUTPUT_INDEX" cat >> "$OUTPUT_INDEX" <> "$OUTPUT_INDEX" cat >> "$OUTPUT_INDEX" < Date: Sat, 14 May 2022 14:23:39 -0700 Subject: [PATCH 412/529] src/doc/Makefile: Remove explicit use of SAGE_ROOT and the top-level sage script --- src/doc/Makefile | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/src/doc/Makefile b/src/doc/Makefile index 90bea5dfac5..7a83422d481 100644 --- a/src/doc/Makefile +++ b/src/doc/Makefile @@ -3,10 +3,12 @@ # 'make doc-html' (synonym for 'make' and 'make all') builds the html documentation. # 'make doc-pdf' builds the PDF documentation. # -# SAGE_ROOT must be defined for these to work, so these commands -# should be called by build/make/Makefile. +# The "sage" script must be in PATH, and the Sage library and the package sage_docbuild +# must be installed for these to work. +# These commands are intended to be called by build/make/Makefile via +# build/pkgs/sagemath_doc_{html,pdf}/spkg-install. # -# 'make clean' removes build artifacts; SAGE_ROOT need not be defined for this to work. +# 'make clean' removes build artifacts; the "sage" script is not needed for this to work. all: doc-html @@ -17,11 +19,11 @@ clean: # Matches doc-inventory--reference-manifolds etc. doc-inventory--%: - cd $(SAGE_ROOT) && ./sage --docbuild --no-pdf-links $(subst -,/,$(subst doc-inventory--,,$@)) inventory $(SAGE_DOCBUILD_OPTS) + sage --docbuild --no-pdf-links $(subst -,/,$(subst doc-inventory--,,$@)) inventory $(SAGE_DOCBUILD_OPTS) # Matches doc-html--developer, doc-html--reference-manifolds etc. doc-html--%: - cd $(SAGE_ROOT) && ./sage --docbuild --no-pdf-links $(subst -,/,$(subst doc-html--,,$@)) html $(SAGE_DOCBUILD_OPTS) + sage --docbuild --no-pdf-links $(subst -,/,$(subst doc-html--,,$@)) html $(SAGE_DOCBUILD_OPTS) # reference manual, inventory ifndef SAGE_ROOT @@ -29,8 +31,8 @@ doc-inventory-reference: $(error SAGE_ROOT undefined. This Makefile needs to be invoked by build/make/install) else doc-inventory-reference: - $(eval DOCS = $(shell cd $(SAGE_ROOT) && ./sage --docbuild --all-documents reference)) - @if [ -z "$(DOCS)" ]; then echo "Error: './sage --docbuild --all-documents' failed"; exit 1; fi + $(eval DOCS = $(shell sage --docbuild --all-documents reference)) + @if [ -z "$(DOCS)" ]; then echo "Error: 'sage --docbuild --all-documents' failed"; exit 1; fi $(eval BIBLIO = $(firstword $(DOCS))) $(eval OTHER_DOCS = $(wordlist 2, 100, $(DOCS))) $(MAKE) doc-inventory--$(subst /,-,$(BIBLIO)) @@ -40,8 +42,8 @@ endif # reference manual, html doc-html-reference: doc-inventory-reference - $(eval DOCS = $(shell cd $(SAGE_ROOT) && ./sage --docbuild --all-documents reference)) - @if [ -z "$(DOCS)" ]; then echo "Error: './sage --docbuild --all-documents' failed"; exit 1; fi + $(eval DOCS = $(shell sage --docbuild --all-documents reference)) + @if [ -z "$(DOCS)" ]; then echo "Error: 'sage --docbuild --all-documents' failed"; exit 1; fi $(eval BIBLIO = $(firstword $(DOCS))) $(eval OTHER_DOCS = $(wordlist 2, 100, $(DOCS))) $(MAKE) SAGE_DOCBUILD_OPTS="$(SAGE_DOCBUILD_OPTS) --no-prune-empty-dirs" doc-html--$(subst /,-,$(BIBLIO)) @@ -50,20 +52,20 @@ doc-html-reference: doc-inventory-reference # other documentation, html doc-html-other: doc-html-reference - $(eval DOCS = $(shell cd $(SAGE_ROOT) && ./sage --docbuild --all-documents all)) - @if [ -z "$(DOCS)" ]; then echo "Error: './sage --docbuild --all-documents' failed"; exit 1; fi + $(eval DOCS = $(shell sage --docbuild --all-documents all)) + @if [ -z "$(DOCS)" ]; then echo "Error: 'sage --docbuild --all-documents' failed"; exit 1; fi $(MAKE) SAGE_DOCBUILD_OPTS="$(SAGE_DOCBUILD_OPTS) --no-prune-empty-dirs" $(foreach doc, $(wordlist 2, 100, $(DOCS)), doc-html--$(subst /,-,$(doc))) doc-html: doc-html-reference doc-html-other # Matches doc-pdf--developer, doc-pdf--reference-manifolds etc. doc-pdf--%: - cd $(SAGE_ROOT) && ./sage --docbuild $(subst -,/,$(subst doc-pdf--,,$@)) pdf $(SAGE_DOCBUILD_OPTS) + sage --docbuild $(subst -,/,$(subst doc-pdf--,,$@)) pdf $(SAGE_DOCBUILD_OPTS) # reference manual, pdf doc-pdf-reference: doc-inventory-reference - $(eval DOCS = $(shell cd $(SAGE_ROOT) && ./sage --docbuild --all-documents reference)) - @if [ -z "$(DOCS)" ]; then echo "Error: './sage --docbuild --all-documents' failed"; exit 1; fi + $(eval DOCS = $(shell sage --docbuild --all-documents reference)) + @if [ -z "$(DOCS)" ]; then echo "Error: 'sage --docbuild --all-documents' failed"; exit 1; fi $(eval BIBLIO = $(firstword $(DOCS))) $(eval OTHER_DOCS = $(wordlist 2, 100, $(DOCS))) $(MAKE) SAGE_DOCBUILD_OPTS="$(SAGE_DOCBUILD_OPTS) --no-prune-empty-dirs" doc-pdf--$(subst /,-,$(BIBLIO)) @@ -72,13 +74,13 @@ doc-pdf-reference: doc-inventory-reference # other documentation, pdf doc-pdf-other: doc-html-reference - $(eval DOCS = $(shell cd $(SAGE_ROOT) && ./sage --docbuild --all-documents all)) - @if [ -z "$(DOCS)" ]; then echo "Error: './sage --docbuild --all-documents' failed"; exit 1; fi + $(eval DOCS = $(shell sage --docbuild --all-documents all)) + @if [ -z "$(DOCS)" ]; then echo "Error: 'sage --docbuild --all-documents' failed"; exit 1; fi $(MAKE) SAGE_DOCBUILD_OPTS="$(SAGE_DOCBUILD_OPTS) --no-prune-empty-dirs" $(foreach doc, $(wordlist 2, 100, $(DOCS)), doc-pdf--$(subst /,-,$(doc))) # website with pdf links doc-pdf-website: - cd $(SAGE_ROOT) && ./sage --docbuild website html $(SAGE_DOCBUILD_OPTS) + sage --docbuild website html $(SAGE_DOCBUILD_OPTS) doc-pdf: doc-pdf-reference doc-pdf-other doc-pdf-website From 7759f3c23b07b56897a691baf57e6f00b98d78b6 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 14 May 2022 14:36:37 -0700 Subject: [PATCH 413/529] Generate en/reference/repl/options.txt at build time, not bootstrap time --- Makefile | 1 - bootstrap | 1 - src/doc/Makefile | 8 +++++++- src/doc/bootstrap | 9 --------- 4 files changed, 7 insertions(+), 12 deletions(-) diff --git a/Makefile b/Makefile index 08c0d1b6beb..6f60bf31d3d 100644 --- a/Makefile +++ b/Makefile @@ -168,7 +168,6 @@ bootstrap-clean: rm -rf config configure build/make/Makefile-auto.in rm -f src/doc/en/installation/*.txt rm -rf src/doc/en/reference/spkg/*.rst - rm -f src/doc/en/reference/repl/*.txt rm -f environment.yml rm -f src/environment.yml rm -f src/environment-dev.yml diff --git a/bootstrap b/bootstrap index bf6b2716674..4d7021c4823 100755 --- a/bootstrap +++ b/bootstrap @@ -247,7 +247,6 @@ save () { build/make/Makefile-auto.in \ src/doc/en/installation/*.txt \ src/doc/en/reference/spkg/*.rst \ - src/doc/en/reference/repl/*.txt \ environment.yml \ src/environment.yml \ environment-optional.yml \ diff --git a/src/doc/Makefile b/src/doc/Makefile index 7a83422d481..62fb1cafd18 100644 --- a/src/doc/Makefile +++ b/src/doc/Makefile @@ -17,6 +17,11 @@ clean: rm -rf en/reference/sage rm -f common/*.pyc +# Sources generated at build time. (For sources generated at bootstrap time, see bootstrap.) +doc-src: + mkdir -p en/reference/repl + sage -advanced > en/reference/repl/options.txt + # Matches doc-inventory--reference-manifolds etc. doc-inventory--%: sage --docbuild --no-pdf-links $(subst -,/,$(subst doc-inventory--,,$@)) inventory $(SAGE_DOCBUILD_OPTS) @@ -30,7 +35,7 @@ ifndef SAGE_ROOT doc-inventory-reference: $(error SAGE_ROOT undefined. This Makefile needs to be invoked by build/make/install) else -doc-inventory-reference: +doc-inventory-reference: doc-src $(eval DOCS = $(shell sage --docbuild --all-documents reference)) @if [ -z "$(DOCS)" ]; then echo "Error: 'sage --docbuild --all-documents' failed"; exit 1; fi $(eval BIBLIO = $(firstword $(DOCS))) @@ -85,6 +90,7 @@ doc-pdf-website: doc-pdf: doc-pdf-reference doc-pdf-other doc-pdf-website .PHONY: all clean \ + doc-src \ doc-html doc-pdf \ doc-inventory-reference doc-html-reference doc-pdf-reference \ doc-html-other doc-pdf-other diff --git a/src/doc/bootstrap b/src/doc/bootstrap index 7c7c5c9978c..44c94627a53 100755 --- a/src/doc/bootstrap +++ b/src/doc/bootstrap @@ -151,12 +151,3 @@ for PKG_BASE in $(sage-package list --has-file SPKG.rst | sort); do (echo ".. _spkg_$PKG_BASE:" && echo && OUTPUT_RST=1 sage-spkg-info $PKG_BASE) | sed -e "s|https://trac.sagemath.org/ticket/\([0-9]*\)|:trac:\`\1\`|g" -e "s|https://arxiv.org/abs/cs/\([0-9]*\)|:arxiv:\`cs/\1\`|g" > "$OUTPUT_DIR"/$PKG_BASE.rst echo >> "$OUTPUT_INDEX" " $PKG_BASE" done - -# #30064: Create the directory first -OUTPUT_DIR="src/doc/en/reference/repl" -mkdir -p "$OUTPUT_DIR" -OUTPUT="$OUTPUT_DIR/options.txt" -if [ "${BOOTSTRAP_QUIET}" = "no" ]; then - echo >&2 $0:$LINENO: installing "$OUTPUT" -fi -./sage -advanced > "$OUTPUT" From 67c8238c067ffb62f17a7e338dab57bc7d24ce70 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 14 May 2022 17:46:11 -0700 Subject: [PATCH 414/529] src/bin/sage: Print error to error output --- src/bin/sage | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/sage b/src/bin/sage index e94cc50940e..c2fab94a77b 100755 --- a/src/bin/sage +++ b/src/bin/sage @@ -208,7 +208,7 @@ case "$1" in exec "$SAGE_ROOT/build/bin/sage-site" "$@" # fallthrough if there is no sage-site script fi - echo "Error: unknown option: $1" + echo >&2 "Error: unknown option: $1" exit 1 ;; esac From 49ad190464acfa0105371dbffe96b5f757fd0082 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 14 May 2022 19:27:16 -0700 Subject: [PATCH 415/529] m4/sage_spkg_collect.m4: Read files dependencies_{optional,order_only,check} --- m4/sage_spkg_collect.m4 | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/m4/sage_spkg_collect.m4 b/m4/sage_spkg_collect.m4 index b89985efbaa..c1d33f1073c 100644 --- a/m4/sage_spkg_collect.m4 +++ b/m4/sage_spkg_collect.m4 @@ -322,22 +322,28 @@ AC_DEFUN([SAGE_SPKG_FINALIZE], [dnl dnl dnl Determine package dependencies dnl - DEP_FILE="$DIR/dependencies" - if test -f "$DEP_FILE"; then + AS_IF([test -f "$DIR/dependencies"], [dnl dnl - the # symbol is treated as comment which is removed - DEPS=`sed 's/^ *//; s/ *#.*//; q' $DEP_FILE` - else - m4_define([ORDER_ONLY_DEPS], [])dnl - m4_case(SPKG_SOURCE, - [pip], [dnl - m4_define([ORDER_ONLY_DEPS], [pip])dnl - ])dnl - m4_ifval(ORDER_ONLY_DEPS, [dnl - DEPS="| ORDER_ONLY_DEPS" - ], [dnl - DEPS="" - ])dnl - fi + AS_VAR_SET([DEPS], [`sed 's/^ *//; s/ *#.*//; q' $DIR/dependencies`]) + ], [dnl + AS_VAR_SET([DEPS], []) + ]) + AS_IF([test -f "$DIR/dependencies_optional"], [dnl + for a in $(sed 's/^ *//; s/ *#.*//; q' "$DIR/dependencies_optional"); do + AS_VAR_APPEND([DEPS], ['$(findstring '$a',$(OPTIONAL_INSTALLED_PACKAGES)) ']) + done + ]) + AS_CASE([$DEPS], [*\|*], [], [AS_VAR_APPEND([DEPS], [" |"])]) + AS_IF([test -f "$DIR/dependencies_order_only"], [dnl + AS_VAR_APPEND([DEPS], [' '$(echo $(sed 's/^ *//; s/ *#.*//; q' $DIR/dependencies_order_only))]) + ], [dnl + m4_case(SPKG_SOURCE, [pip], [AS_VAR_APPEND([DEPS], [' pip'])])dnl + ]) + AS_IF([test -f "$DIR/dependencies_check"], [dnl + AS_VAR_APPEND([DEPS], [' $(and $(filter-out no,$(SAGE_CHECK_]SPKG_NAME[)), ']) + AS_VAR_APPEND([DEPS], [$(echo $(sed 's/^ *//; s/ *#.*//; q' $DIR/dependencies_check))]) + AS_VAR_APPEND([DEPS], [')'])dnl + ]) dnl SAGE_PACKAGE_DEPENDENCIES="${SAGE_PACKAGE_DEPENDENCIES}$(printf '\ndeps_')SPKG_NAME = ${DEPS}" dnl From d0162546ab9ff0c560f095409317921ade917472 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 14 May 2022 19:37:43 -0700 Subject: [PATCH 416/529] build/pkgs: Split dependencies_optional and dependencies_check out from dependencies --- build/pkgs/cvxopt/dependencies | 5 +---- build/pkgs/cvxopt/dependencies_check | 5 +++++ build/pkgs/database_knotinfo/dependencies | 2 +- build/pkgs/database_knotinfo/dependencies_check | 1 + build/pkgs/ipympl/dependencies | 2 +- build/pkgs/ipympl/dependencies_optional | 1 + build/pkgs/latte_int/dependencies | 3 +-- build/pkgs/latte_int/dependencies_optional | 1 + build/pkgs/mathics/dependencies | 2 +- build/pkgs/mathics/dependencies_check | 1 + build/pkgs/networkx/dependencies | 2 +- build/pkgs/polymake/dependencies | 3 +-- build/pkgs/polymake/dependencies_optional | 1 + build/pkgs/rpy2/dependencies | 3 +-- build/pkgs/rpy2/dependencies_check | 1 + build/pkgs/sage_sws2rst/dependencies | 2 +- build/pkgs/sage_sws2rst/dependencies_check | 1 + build/pkgs/sagemath_objects/dependencies | 2 +- build/pkgs/sagemath_objects/dependencies_check | 1 + build/pkgs/sagetex/dependencies | 6 +----- build/pkgs/sagetex/dependencies_check | 7 +++++++ build/pkgs/symengine_py/dependencies | 2 +- build/pkgs/symengine_py/dependencies_check | 1 + 23 files changed, 33 insertions(+), 22 deletions(-) create mode 100644 build/pkgs/cvxopt/dependencies_check create mode 100644 build/pkgs/database_knotinfo/dependencies_check create mode 100644 build/pkgs/ipympl/dependencies_optional create mode 100644 build/pkgs/latte_int/dependencies_optional create mode 100644 build/pkgs/mathics/dependencies_check create mode 100644 build/pkgs/polymake/dependencies_optional create mode 100644 build/pkgs/rpy2/dependencies_check create mode 100644 build/pkgs/sage_sws2rst/dependencies_check create mode 100644 build/pkgs/sagemath_objects/dependencies_check create mode 100644 build/pkgs/sagetex/dependencies_check create mode 100644 build/pkgs/symengine_py/dependencies_check diff --git a/build/pkgs/cvxopt/dependencies b/build/pkgs/cvxopt/dependencies index 2354fdb1c1e..d47ae01f215 100644 --- a/build/pkgs/cvxopt/dependencies +++ b/build/pkgs/cvxopt/dependencies @@ -1,7 +1,4 @@ -$(PYTHON) numpy $(BLAS) gsl glpk suitesparse | $(PYTHON_TOOLCHAIN) pkgconfig matplotlib $(and $(filter-out no,$(SAGE_CHECK_cvxopt)), pytest) - -matplotlib is needed to test cvxopt (i.e., if SAGE_CHECK=yes). See #12742. +$(PYTHON) numpy $(BLAS) gsl glpk suitesparse | $(PYTHON_TOOLCHAIN) pkgconfig ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/cvxopt/dependencies_check b/build/pkgs/cvxopt/dependencies_check new file mode 100644 index 00000000000..68469b0ce91 --- /dev/null +++ b/build/pkgs/cvxopt/dependencies_check @@ -0,0 +1,5 @@ +matplotlib pytest + +# matplotlib is needed to test cvxopt (i.e., if SAGE_CHECK=yes). See #12742. +---------- +All lines of this file are ignored except the first. diff --git a/build/pkgs/database_knotinfo/dependencies b/build/pkgs/database_knotinfo/dependencies index 30b944a731d..0738c2d7777 100644 --- a/build/pkgs/database_knotinfo/dependencies +++ b/build/pkgs/database_knotinfo/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) | $(PYTHON_TOOLCHAIN) $(and $(filter-out no,$(SAGE_CHECK_database_knotinfo)), $(SAGERUNTIME) ipywidgets sympy singular gap libhomfly libbraiding matplotlib) +$(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/database_knotinfo/dependencies_check b/build/pkgs/database_knotinfo/dependencies_check new file mode 100644 index 00000000000..3543bac84df --- /dev/null +++ b/build/pkgs/database_knotinfo/dependencies_check @@ -0,0 +1 @@ +$(SAGERUNTIME) ipywidgets sympy singular gap libhomfly libbraiding matplotlib diff --git a/build/pkgs/ipympl/dependencies b/build/pkgs/ipympl/dependencies index 56687b4dda0..b217268db20 100644 --- a/build/pkgs/ipympl/dependencies +++ b/build/pkgs/ipympl/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) | $(PYTHON_TOOLCHAIN) ipywidgets matplotlib ipykernel jupyter_packaging $(findstring jupyterlab,$(OPTIONAL_INSTALLED_PACKAGES)) +$(PYTHON) | $(PYTHON_TOOLCHAIN) ipywidgets matplotlib ipykernel jupyter_packaging ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/ipympl/dependencies_optional b/build/pkgs/ipympl/dependencies_optional new file mode 100644 index 00000000000..c9356a72837 --- /dev/null +++ b/build/pkgs/ipympl/dependencies_optional @@ -0,0 +1 @@ +jupyterlab diff --git a/build/pkgs/latte_int/dependencies b/build/pkgs/latte_int/dependencies index ddfda62bcdb..412db1855de 100644 --- a/build/pkgs/latte_int/dependencies +++ b/build/pkgs/latte_int/dependencies @@ -1,5 +1,4 @@ -$(MP_LIBRARY) ntl 4ti2 cddlib lidia $(findstring lrslib,$(OPTIONAL_INSTALLED_PACKAGES)) +$(MP_LIBRARY) ntl 4ti2 cddlib lidia ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/latte_int/dependencies_optional b/build/pkgs/latte_int/dependencies_optional new file mode 100644 index 00000000000..c762c018aa3 --- /dev/null +++ b/build/pkgs/latte_int/dependencies_optional @@ -0,0 +1 @@ +lrslib diff --git a/build/pkgs/mathics/dependencies b/build/pkgs/mathics/dependencies index ab33cbad598..ac723a5ac26 100644 --- a/build/pkgs/mathics/dependencies +++ b/build/pkgs/mathics/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) | $(PYTHON_TOOLCHAIN) pint palettable mathics_scanner $(and $(filter-out no,$(SAGE_CHECK_mathics)), $(SAGERUNTIME) ipywidgets importlib_metadata sympy mpmath matplotlib) +$(PYTHON) | $(PYTHON_TOOLCHAIN) pint palettable mathics_scanner ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/mathics/dependencies_check b/build/pkgs/mathics/dependencies_check new file mode 100644 index 00000000000..a2c2a63716e --- /dev/null +++ b/build/pkgs/mathics/dependencies_check @@ -0,0 +1 @@ +$(SAGERUNTIME) ipywidgets importlib_metadata sympy mpmath matplotlib diff --git a/build/pkgs/networkx/dependencies b/build/pkgs/networkx/dependencies index 2a20cb459ba..f26477f0d95 100644 --- a/build/pkgs/networkx/dependencies +++ b/build/pkgs/networkx/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) decorator | $(PYTHON_TOOLCHAIN) scipy $(and $(filter-out no,$(SAGE_CHECK_networkx)), pytest) +$(PYTHON) decorator | $(PYTHON_TOOLCHAIN) scipy ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/polymake/dependencies b/build/pkgs/polymake/dependencies index 7d77b977a21..b3ed8ed4299 100644 --- a/build/pkgs/polymake/dependencies +++ b/build/pkgs/polymake/dependencies @@ -1,5 +1,4 @@ -$(MP_LIBRARY) bliss cddlib $(findstring lrslib,$(OPTIONAL_INSTALLED_PACKAGES)) normaliz perl_term_readline_gnu ppl perl_cpan_polymake_prereq libxml2 | ninja_build +$(MP_LIBRARY) bliss cddlib normaliz perl_term_readline_gnu ppl perl_cpan_polymake_prereq libxml2 | ninja_build ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/polymake/dependencies_optional b/build/pkgs/polymake/dependencies_optional new file mode 100644 index 00000000000..c762c018aa3 --- /dev/null +++ b/build/pkgs/polymake/dependencies_optional @@ -0,0 +1 @@ +lrslib diff --git a/build/pkgs/rpy2/dependencies b/build/pkgs/rpy2/dependencies index 35bbdcc39c9..862745ba3e0 100644 --- a/build/pkgs/rpy2/dependencies +++ b/build/pkgs/rpy2/dependencies @@ -1,5 +1,4 @@ -$(PYTHON) r cffi tzlocal pytz | $(PYTHON_TOOLCHAIN) pycparser $(and $(filter-out no,$(SAGE_CHECK_rpy2)), pytest numpy ipython) +$(PYTHON) r cffi tzlocal pytz | $(PYTHON_TOOLCHAIN) pycparser ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/rpy2/dependencies_check b/build/pkgs/rpy2/dependencies_check new file mode 100644 index 00000000000..22c6e400a59 --- /dev/null +++ b/build/pkgs/rpy2/dependencies_check @@ -0,0 +1 @@ +pytest numpy ipython diff --git a/build/pkgs/sage_sws2rst/dependencies b/build/pkgs/sage_sws2rst/dependencies index ec13b4746e1..5ca5e27df75 100644 --- a/build/pkgs/sage_sws2rst/dependencies +++ b/build/pkgs/sage_sws2rst/dependencies @@ -1 +1 @@ -$(PYTHON) beautifulsoup4 $(SAGE_ROOT)/pkgs/sage-sws2rst/*.py | $(PYTHON_TOOLCHAIN) $(and $(filter-out no,$(SAGE_CHECK_sage_sws2rst)), tox) +$(PYTHON) beautifulsoup4 $(SAGE_ROOT)/pkgs/sage-sws2rst/*.py | $(PYTHON_TOOLCHAIN) diff --git a/build/pkgs/sage_sws2rst/dependencies_check b/build/pkgs/sage_sws2rst/dependencies_check new file mode 100644 index 00000000000..053148f8486 --- /dev/null +++ b/build/pkgs/sage_sws2rst/dependencies_check @@ -0,0 +1 @@ +tox diff --git a/build/pkgs/sagemath_objects/dependencies b/build/pkgs/sagemath_objects/dependencies index fcacb179b57..9aff58ee6b1 100644 --- a/build/pkgs/sagemath_objects/dependencies +++ b/build/pkgs/sagemath_objects/dependencies @@ -1,4 +1,4 @@ -FORCE $(PYTHON) cysignals gmpy2 ipython | $(PYTHON_TOOLCHAIN) cython pkgconfig $(and $(filter-out no,$(SAGE_CHECK)), tox) +FORCE $(PYTHON) cysignals gmpy2 ipython | $(PYTHON_TOOLCHAIN) cython pkgconfig # FORCE: Always run the spkg-install script # ipython - for the doctester diff --git a/build/pkgs/sagemath_objects/dependencies_check b/build/pkgs/sagemath_objects/dependencies_check new file mode 100644 index 00000000000..053148f8486 --- /dev/null +++ b/build/pkgs/sagemath_objects/dependencies_check @@ -0,0 +1 @@ +tox diff --git a/build/pkgs/sagetex/dependencies b/build/pkgs/sagetex/dependencies index 43e658b4ff3..29f49d5c215 100644 --- a/build/pkgs/sagetex/dependencies +++ b/build/pkgs/sagetex/dependencies @@ -1,8 +1,4 @@ -$(PYTHON) maxima scipy matplotlib pillow tachyon | $(and $(filter-out no,$(SAGE_CHECK_sagetex)), $(SAGERUNTIME) sympy elliptic_curves jmol) - -To build SageTeX, you just need Python, but to test (SAGE_CHECK=yes) -SageTeX, you actually need to run Sage, produce plots,... +$(PYTHON) maxima scipy matplotlib pillow tachyon ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/sagetex/dependencies_check b/build/pkgs/sagetex/dependencies_check new file mode 100644 index 00000000000..d24e23242d4 --- /dev/null +++ b/build/pkgs/sagetex/dependencies_check @@ -0,0 +1,7 @@ +$(SAGERUNTIME) sympy elliptic_curves jmol + +To build SageTeX, you just need Python, but to test (SAGE_CHECK=yes) +SageTeX, you actually need to run Sage, produce plots,... + +---------- +All lines of this file are ignored except the first. diff --git a/build/pkgs/symengine_py/dependencies b/build/pkgs/symengine_py/dependencies index a48b85c68e8..b041a3d5d3a 100644 --- a/build/pkgs/symengine_py/dependencies +++ b/build/pkgs/symengine_py/dependencies @@ -1,4 +1,4 @@ -symengine $(PYTHON) | cmake cython $(PYTHON_TOOLCHAIN) $(and $(filter-out no,$(SAGE_CHECK_symengine_py)), pytest) +symengine $(PYTHON) | cmake cython $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/symengine_py/dependencies_check b/build/pkgs/symengine_py/dependencies_check new file mode 100644 index 00000000000..e079f8a6038 --- /dev/null +++ b/build/pkgs/symengine_py/dependencies_check @@ -0,0 +1 @@ +pytest From a9eed4432ad2339062c99f921cd96a83cee57473 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 14 May 2022 19:56:19 -0700 Subject: [PATCH 417/529] build/bin/sage-spkg-info: Restore message '(none known)' for packages without system package info --- build/bin/sage-spkg-info | 1 + 1 file changed, 1 insertion(+) diff --git a/build/bin/sage-spkg-info b/build/bin/sage-spkg-info index 3b6e2621d71..1043c3e1b04 100755 --- a/build/bin/sage-spkg-info +++ b/build/bin/sage-spkg-info @@ -56,6 +56,7 @@ done if [ $have_repology = yes ]; then systems="$systems repology" fi +system= for system in $systems; do system_package_file="$PKG_DISTROS"/$system.txt system_packages="$(echo $(sed 's/#.*//;' $system_package_file))" From 23e7a0b45744a829df093fd8f023c0996d664b09 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 14 May 2022 20:05:21 -0700 Subject: [PATCH 418/529] build/bin/sage-spkg-info: Format dependencies --- build/bin/sage-spkg-info | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/build/bin/sage-spkg-info b/build/bin/sage-spkg-info index 1043c3e1b04..31cf05c8ff4 100755 --- a/build/bin/sage-spkg-info +++ b/build/bin/sage-spkg-info @@ -22,6 +22,36 @@ if [ -r "$PKG_SCRIPTS/type" ] ; then echo fi echo +echo "Dependencies" +echo "------------" +echo +dep= +for dep_file in dependencies dependencies_order_only; do + if [ -r "$PKG_SCRIPTS/$dep_file" ] ; then + for dep in $(sed 's/^ *//; s/ *#.*//; q' "$PKG_SCRIPTS/$dep_file"); do + case "$dep" in + # Do not use order-only syntax, too much information + \|) ;; + # Suppress dependencies on source file of the form $(SAGE_ROOT)/..., $(SAGE_SRC)/... + \$\(SAGE_*) ;; + # Suppress FORCE + FORCE) ;; + # Dependencies like $(BLAS) + \$\(*) echo "- $dep";; + # Looks like a package + *) if [ -n "$OUTPUT_RST" -a -d "$SAGE_ROOT/build/pkgs/$dep" ]; then + echo "- :ref:\`$dep\`" + else + echo "- $dep" + fi;; + esac + done + fi +done +if [ -z "$dep" ]; then + echo "None" +fi +echo echo "Version Information" echo "-------------------" echo From 5f67829480b58627197b0cb7c7788ad9651cfc2f Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 14 May 2022 20:26:44 -0700 Subject: [PATCH 419/529] build/pkgs/memory_allocator/SPKG.rst: Fix markup --- build/pkgs/memory_allocator/SPKG.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/pkgs/memory_allocator/SPKG.rst b/build/pkgs/memory_allocator/SPKG.rst index 42975c02f55..2c36e5f1105 100644 --- a/build/pkgs/memory_allocator/SPKG.rst +++ b/build/pkgs/memory_allocator/SPKG.rst @@ -1,5 +1,5 @@ -MemoryAllocator: An extension class to allocate memory easily with cython. -========================================================================== +memory\_allocator: An extension class to allocate memory easily with Cython +=========================================================================== This extension class started as part of the Sage software. From e8c283049743a282c47853eacd7f6c8a0a6ef6e2 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 14 May 2022 21:03:49 -0700 Subject: [PATCH 420/529] build/pkgs/mathics/SPKG.rst: Fix title --- build/pkgs/mathics/SPKG.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/pkgs/mathics/SPKG.rst b/build/pkgs/mathics/SPKG.rst index db4a63b84f1..09f9e87aea0 100644 --- a/build/pkgs/mathics/SPKG.rst +++ b/build/pkgs/mathics/SPKG.rst @@ -1,5 +1,5 @@ -Mathics3: A general-purpose computer algebra system. -==================================================== +mathics: A general-purpose computer algebra system +================================================== Description ----------- From 9761ef777a3c4cc679cd9a3df9da3eb7435b50e2 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 14 May 2022 21:11:43 -0700 Subject: [PATCH 421/529] build/bin/sage-spkg-info: Fix rst label --- build/bin/sage-spkg-info | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/build/bin/sage-spkg-info b/build/bin/sage-spkg-info index 31cf05c8ff4..5e762084183 100755 --- a/build/bin/sage-spkg-info +++ b/build/bin/sage-spkg-info @@ -39,8 +39,9 @@ for dep_file in dependencies dependencies_order_only; do # Dependencies like $(BLAS) \$\(*) echo "- $dep";; # Looks like a package - *) if [ -n "$OUTPUT_RST" -a -d "$SAGE_ROOT/build/pkgs/$dep" ]; then - echo "- :ref:\`$dep\`" + *) if [ -n "$OUTPUT_RST" -a -r "$SAGE_ROOT/build/pkgs/$dep/SPKG.rst" ]; then + # This RST label is set in src/doc/bootstrap + echo "- :ref:\`spkg_$dep\`" else echo "- $dep" fi;; From 5b2ed40b44354a26a42e10af6c327c270aed9d4b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 14 May 2022 21:40:32 -0700 Subject: [PATCH 422/529] build/pkgs/[a-f]*/SPKG.rst: Remove redundant Dependencies sections; incidental cleanup --- build/pkgs/4ti2/SPKG.rst | 5 ---- build/pkgs/attrs/SPKG.rst | 5 ---- build/pkgs/awali/SPKG.rst | 11 -------- build/pkgs/benzene/SPKG.rst | 5 ---- build/pkgs/bleach/SPKG.rst | 5 ---- build/pkgs/bleach/dependencies | 3 +-- build/pkgs/bliss/SPKG.rst | 5 ---- build/pkgs/boost_cropped/SPKG.rst | 5 ---- build/pkgs/buckygen/SPKG.rst | 5 ---- build/pkgs/bzip2/SPKG.rst | 6 ----- build/pkgs/certifi/SPKG.rst | 5 ---- build/pkgs/cliquer/SPKG.rst | 5 ---- build/pkgs/cmake/SPKG.rst | 8 ------ build/pkgs/combinatorial_designs/SPKG.rst | 5 ---- build/pkgs/configure/SPKG.rst | 6 ----- build/pkgs/conway_polynomials/SPKG.rst | 5 ---- build/pkgs/coxeter3/SPKG.rst | 6 ----- build/pkgs/csdp/SPKG.rst | 4 --- build/pkgs/curl/SPKG.rst | 11 -------- build/pkgs/cvxopt/SPKG.rst | 27 ------------------- build/pkgs/cycler/SPKG.rst | 7 ----- build/pkgs/cypari/SPKG.rst | 8 ------ build/pkgs/cython/SPKG.rst | 5 ---- build/pkgs/d3js/SPKG.rst | 6 ----- build/pkgs/database_cremona_ellcurve/SPKG.rst | 11 -------- build/pkgs/database_jones_numfield/SPKG.rst | 6 ----- build/pkgs/database_mutation_class/SPKG.rst | 5 ---- build/pkgs/database_odlyzko_zeta/SPKG.rst | 5 ---- build/pkgs/database_stein_watkins/SPKG.rst | 10 ------- .../pkgs/database_stein_watkins_mini/SPKG.rst | 10 ------- build/pkgs/database_symbolic_data/SPKG.rst | 9 ------- build/pkgs/dateutil/SPKG.rst | 6 ----- build/pkgs/docutils/SPKG.rst | 11 -------- build/pkgs/eclib/SPKG.rst | 7 ----- build/pkgs/fflas_ffpack/SPKG.rst | 18 ------------- build/pkgs/fplll/SPKG.rst | 6 ----- build/pkgs/fpylll/SPKG.rst | 8 ------ build/pkgs/freetype/SPKG.rst | 5 ---- build/pkgs/fricas/SPKG.rst | 5 ---- 39 files changed, 1 insertion(+), 284 deletions(-) diff --git a/build/pkgs/4ti2/SPKG.rst b/build/pkgs/4ti2/SPKG.rst index 8b13ac91bcb..1a3a5e5c9c4 100644 --- a/build/pkgs/4ti2/SPKG.rst +++ b/build/pkgs/4ti2/SPKG.rst @@ -20,8 +20,3 @@ Upstream Contact - Raymond Hemmecke, TU Munich, Germany - Matthias Köppe, UC Davis, CA, USA - -Dependencies ------------- - -GLPK, GMP. diff --git a/build/pkgs/attrs/SPKG.rst b/build/pkgs/attrs/SPKG.rst index 12e3ed868e5..8f25e11d68f 100644 --- a/build/pkgs/attrs/SPKG.rst +++ b/build/pkgs/attrs/SPKG.rst @@ -18,8 +18,3 @@ Upstream Contact ---------------- Home page: https://www.attrs.org - -Dependencies ------------- - -Python diff --git a/build/pkgs/awali/SPKG.rst b/build/pkgs/awali/SPKG.rst index 845e3dda372..117b27010ed 100644 --- a/build/pkgs/awali/SPKG.rst +++ b/build/pkgs/awali/SPKG.rst @@ -28,16 +28,5 @@ Upstream Contact Dependencies ------------ -- Python -- CMake -- Cython -- ncurses - - graphviz must be installed from your distro, and available in the path. - - -Special Update/Build Instructions ---------------------------------- - -- None diff --git a/build/pkgs/benzene/SPKG.rst b/build/pkgs/benzene/SPKG.rst index 9a31276399b..6dd94f0bb7e 100644 --- a/build/pkgs/benzene/SPKG.rst +++ b/build/pkgs/benzene/SPKG.rst @@ -24,8 +24,3 @@ version was adapted by Gunnar Brinkmann and Nico Van Cleemput for Grinvin. http://www.grinvin.org/ - -Dependencies ------------- - -- None diff --git a/build/pkgs/bleach/SPKG.rst b/build/pkgs/bleach/SPKG.rst index 688e9214eda..f7a1b5ecc64 100644 --- a/build/pkgs/bleach/SPKG.rst +++ b/build/pkgs/bleach/SPKG.rst @@ -16,8 +16,3 @@ Upstream Contact ---------------- Home Page: https://github.com/mozilla/bleach - -Dependencies ------------- - -Python, html5lib, six diff --git a/build/pkgs/bleach/dependencies b/build/pkgs/bleach/dependencies index 7b139dc904c..4a74f9bfd68 100644 --- a/build/pkgs/bleach/dependencies +++ b/build/pkgs/bleach/dependencies @@ -1,5 +1,4 @@ -$(PYTHON) packaging six | $(PYTHON_TOOLCHAIN) +$(PYTHON) packaging six webencodings | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/bliss/SPKG.rst b/build/pkgs/bliss/SPKG.rst index 236b87a1990..875bc39a2df 100644 --- a/build/pkgs/bliss/SPKG.rst +++ b/build/pkgs/bliss/SPKG.rst @@ -24,8 +24,3 @@ We apply patches generated from https://github.com/mkoeppe/bliss (branch apply_debian_patches) as our upstream. This tracks the patches from the Debian package, adding an autotools build system and adjusting the include file locations. - -Dependencies ------------- - -None diff --git a/build/pkgs/boost_cropped/SPKG.rst b/build/pkgs/boost_cropped/SPKG.rst index 2aa8d4992a1..4efa07ea966 100644 --- a/build/pkgs/boost_cropped/SPKG.rst +++ b/build/pkgs/boost_cropped/SPKG.rst @@ -31,8 +31,3 @@ Upstream Contact Website: http://www.boost.org/ See mailing list page at http://www.boost.org/community/groups.html - -Dependencies ------------- - -None diff --git a/build/pkgs/buckygen/SPKG.rst b/build/pkgs/buckygen/SPKG.rst index b522376e3c7..63a9dbef355 100644 --- a/build/pkgs/buckygen/SPKG.rst +++ b/build/pkgs/buckygen/SPKG.rst @@ -22,8 +22,3 @@ Buckygen was mainly written by Jan Goedgebeur, jan.goedgebeur[at]ugent.be. http://caagt.ugent.be/buckygen/ - -Dependencies ------------- - -- None diff --git a/build/pkgs/bzip2/SPKG.rst b/build/pkgs/bzip2/SPKG.rst index 30b3de98ac5..6aa6cda65b6 100644 --- a/build/pkgs/bzip2/SPKG.rst +++ b/build/pkgs/bzip2/SPKG.rst @@ -23,12 +23,6 @@ Upstream Contact - Website http://bzip.org/ - Author: Julian Seward -Dependencies ------------- - -None - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/certifi/SPKG.rst b/build/pkgs/certifi/SPKG.rst index 222b3923976..3b06f9d655c 100644 --- a/build/pkgs/certifi/SPKG.rst +++ b/build/pkgs/certifi/SPKG.rst @@ -16,8 +16,3 @@ Upstream Contact ---------------- Home page: https://pypi.python.org/pypi/certifi - -Dependencies ------------- - -Python, Setuptools diff --git a/build/pkgs/cliquer/SPKG.rst b/build/pkgs/cliquer/SPKG.rst index 9c0a7e25687..270e001ee6d 100644 --- a/build/pkgs/cliquer/SPKG.rst +++ b/build/pkgs/cliquer/SPKG.rst @@ -22,11 +22,6 @@ Cliquer was mainly written by Sampo Niskanen, sampo.niskanenQiki.fi https://users.aalto.fi/~pat/cliquer.html -Dependencies ------------- - -- None - Patches ------- diff --git a/build/pkgs/cmake/SPKG.rst b/build/pkgs/cmake/SPKG.rst index 0cc5039b297..33eeabf7367 100644 --- a/build/pkgs/cmake/SPKG.rst +++ b/build/pkgs/cmake/SPKG.rst @@ -27,11 +27,3 @@ Upstream Contact - https://cmake.org/ - cmake-developers@cmake.org - -Dependencies ------------- - -- curl -- zlib -- bzip2 -- xz diff --git a/build/pkgs/combinatorial_designs/SPKG.rst b/build/pkgs/combinatorial_designs/SPKG.rst index 0f2c0fbb687..f6ebb33642f 100644 --- a/build/pkgs/combinatorial_designs/SPKG.rst +++ b/build/pkgs/combinatorial_designs/SPKG.rst @@ -19,8 +19,3 @@ Upstream Contact ---------------- None - -Dependencies ------------- - -N/A diff --git a/build/pkgs/configure/SPKG.rst b/build/pkgs/configure/SPKG.rst index 29846d5e379..6b1365806d0 100644 --- a/build/pkgs/configure/SPKG.rst +++ b/build/pkgs/configure/SPKG.rst @@ -20,12 +20,6 @@ Upstream Contact Automatically generated by Sage, use trac and/or sage-devel for questions. -Dependencies ------------- - -None - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/conway_polynomials/SPKG.rst b/build/pkgs/conway_polynomials/SPKG.rst index f3673e36f12..64a5bad04df 100644 --- a/build/pkgs/conway_polynomials/SPKG.rst +++ b/build/pkgs/conway_polynomials/SPKG.rst @@ -6,11 +6,6 @@ Description Frank Lübeck's tables of Conway polynomials over finite fields. -Dependencies ------------- - -- Sage library - Upstream contact ---------------- diff --git a/build/pkgs/coxeter3/SPKG.rst b/build/pkgs/coxeter3/SPKG.rst index fa546b079d2..6efb3da16a2 100644 --- a/build/pkgs/coxeter3/SPKG.rst +++ b/build/pkgs/coxeter3/SPKG.rst @@ -37,12 +37,6 @@ Alas, Fokko Ducloux passed away in 2006. http://math.univ-lyon1.fr/~ducloux/du_Cloux.html -Dependencies ------------- - -None - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/csdp/SPKG.rst b/build/pkgs/csdp/SPKG.rst index a6776483533..b65b9305e66 100644 --- a/build/pkgs/csdp/SPKG.rst +++ b/build/pkgs/csdp/SPKG.rst @@ -19,10 +19,6 @@ Upstream Contact Dmitrii Pasechnik -Dependencies ------------- - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/curl/SPKG.rst b/build/pkgs/curl/SPKG.rst index d19345aca4f..33fac1d71e9 100644 --- a/build/pkgs/curl/SPKG.rst +++ b/build/pkgs/curl/SPKG.rst @@ -18,14 +18,3 @@ Upstream Contact According to the file README at the root of the tarball, contact is done by mailing https://curl.haxx.se/mail/ - -Dependencies ------------- - -None listed. - - -Special Update/Build Instructions ---------------------------------- - -None. diff --git a/build/pkgs/cvxopt/SPKG.rst b/build/pkgs/cvxopt/SPKG.rst index 1bb5f3813ae..0730481d997 100644 --- a/build/pkgs/cvxopt/SPKG.rst +++ b/build/pkgs/cvxopt/SPKG.rst @@ -27,30 +27,3 @@ License GPLv3 or later. Includes parts under GPLv2, GNU Lesser General Public License, v2.1. See src/LICENSE for more details. (Sage-compatible) - -Dependencies ------------- - -- GNU patch -- GSL -- GLPK - - -Special Update/Build Instructions ---------------------------------- - -- cvxopt.h.patch: Fix building with GCC on Solaris. - -- setup.py.patch: look for libraries and includes in $SAGE_LOCAL - instead of /usr. Add fortran, blas,... libraries if needed. - Build with GSL and GLPK support. - -- remove doc/html/, as it can be rebuild by invoking 'sage -sh' and - running 'make html' in doc/ - -- TODO: Add more tests in spkg-check - -- TODO: one might want to enhance the code to allow other Sage - random sources, at the moment only GSL is used in CVXOPT-1.1.3 - spkg, apparently it will need an unclear to me "with seed(..)" - construct. diff --git a/build/pkgs/cycler/SPKG.rst b/build/pkgs/cycler/SPKG.rst index 93cbed9e199..750580f9869 100644 --- a/build/pkgs/cycler/SPKG.rst +++ b/build/pkgs/cycler/SPKG.rst @@ -20,10 +20,3 @@ cycler is developed on github: https://github.com/matplotlib/cycler A more informative webpage about cycler, its motivation and usage is at http://tacaswell.github.io/cycler/ - -Dependencies ------------- - -- python -- setuptools -- six diff --git a/build/pkgs/cypari/SPKG.rst b/build/pkgs/cypari/SPKG.rst index f9473ab6206..0dd0ee8b31f 100644 --- a/build/pkgs/cypari/SPKG.rst +++ b/build/pkgs/cypari/SPKG.rst @@ -16,11 +16,3 @@ Upstream Contact ---------------- https://github.com/defeo/cypari2 - -Dependencies ------------- - -- Python -- Cython -- PARI -- cysignals diff --git a/build/pkgs/cython/SPKG.rst b/build/pkgs/cython/SPKG.rst index e7a958c78be..da9be186bde 100644 --- a/build/pkgs/cython/SPKG.rst +++ b/build/pkgs/cython/SPKG.rst @@ -30,8 +30,3 @@ Upstream Contact - http://www.cython.org/ - cython-devel@python.org - -Dependencies ------------- - -- Python diff --git a/build/pkgs/d3js/SPKG.rst b/build/pkgs/d3js/SPKG.rst index c5d838f1c84..219f731d168 100644 --- a/build/pkgs/d3js/SPKG.rst +++ b/build/pkgs/d3js/SPKG.rst @@ -20,12 +20,6 @@ Upstream Contact - Author: Mike Bostock (http://bost.ocks.org/mike/) - Home page: http://d3js.org/ -Dependencies ------------- - -None. - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/database_cremona_ellcurve/SPKG.rst b/build/pkgs/database_cremona_ellcurve/SPKG.rst index 9341e1bd335..7d37832e6cb 100644 --- a/build/pkgs/database_cremona_ellcurve/SPKG.rst +++ b/build/pkgs/database_cremona_ellcurve/SPKG.rst @@ -15,17 +15,6 @@ License Public Domain -Dependencies ------------- - -None - -Patches -~~~~~~~ - -- None - - Upstream Contact ---------------- diff --git a/build/pkgs/database_jones_numfield/SPKG.rst b/build/pkgs/database_jones_numfield/SPKG.rst index 1d5f81b68f0..14c4c73cf1d 100644 --- a/build/pkgs/database_jones_numfield/SPKG.rst +++ b/build/pkgs/database_jones_numfield/SPKG.rst @@ -18,12 +18,6 @@ Upstream Contact sage-devel@googlegroups.com -Dependencies ------------- - -None - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/database_mutation_class/SPKG.rst b/build/pkgs/database_mutation_class/SPKG.rst index e73e2c0be80..761db83425b 100644 --- a/build/pkgs/database_mutation_class/SPKG.rst +++ b/build/pkgs/database_mutation_class/SPKG.rst @@ -25,8 +25,3 @@ SPKG Maintainers ---------------- - C. Stump - -Dependencies ------------- - -- None diff --git a/build/pkgs/database_odlyzko_zeta/SPKG.rst b/build/pkgs/database_odlyzko_zeta/SPKG.rst index 17d0c366bf2..b58185fcaee 100644 --- a/build/pkgs/database_odlyzko_zeta/SPKG.rst +++ b/build/pkgs/database_odlyzko_zeta/SPKG.rst @@ -8,8 +8,3 @@ Table of zeros of the Riemann zeta function by Andrew Odlyzko. This package contains the file 'zeros6' with the first 2,001,052 zeros of the Riemann zeta function, accurate to within 4*10^(-9). - -Dependencies ------------- - -- Sage library diff --git a/build/pkgs/database_stein_watkins/SPKG.rst b/build/pkgs/database_stein_watkins/SPKG.rst index 28746bfc826..74484171f7c 100644 --- a/build/pkgs/database_stein_watkins/SPKG.rst +++ b/build/pkgs/database_stein_watkins/SPKG.rst @@ -14,13 +14,3 @@ License ------- Public Domain - -Dependencies ------------- - -None - -Patches -~~~~~~~ - -None diff --git a/build/pkgs/database_stein_watkins_mini/SPKG.rst b/build/pkgs/database_stein_watkins_mini/SPKG.rst index d9b14940131..e82989564b2 100644 --- a/build/pkgs/database_stein_watkins_mini/SPKG.rst +++ b/build/pkgs/database_stein_watkins_mini/SPKG.rst @@ -14,13 +14,3 @@ License ------- Public Domain - -Dependencies ------------- - -None - -Patches -~~~~~~~ - -None diff --git a/build/pkgs/database_symbolic_data/SPKG.rst b/build/pkgs/database_symbolic_data/SPKG.rst index f809a76ec96..18f7dc963ff 100644 --- a/build/pkgs/database_symbolic_data/SPKG.rst +++ b/build/pkgs/database_symbolic_data/SPKG.rst @@ -35,12 +35,3 @@ Upstream Contact ---------------- - Andreas Nareike - -Dependencies ------------- - - -Special Update/Build Instructions ---------------------------------- - -List patches that need to be applied and what they do diff --git a/build/pkgs/dateutil/SPKG.rst b/build/pkgs/dateutil/SPKG.rst index 796cbdb2f56..8d26c6dceb7 100644 --- a/build/pkgs/dateutil/SPKG.rst +++ b/build/pkgs/dateutil/SPKG.rst @@ -21,9 +21,3 @@ Author: Gustavo Niemeyer Home page: http://labix.org/python-dateutil https://pypi.org/project/python-dateutil/ - -Dependencies ------------- - -- Python -- Six diff --git a/build/pkgs/docutils/SPKG.rst b/build/pkgs/docutils/SPKG.rst index 2547e4facfd..c0c6da387c7 100644 --- a/build/pkgs/docutils/SPKG.rst +++ b/build/pkgs/docutils/SPKG.rst @@ -21,14 +21,3 @@ Upstream Contact Author: David Goodger Home Page: http://docutils.sourceforge.net/ - -Dependencies ------------- - -None - - -Special Update/Build Instructions ---------------------------------- - -None diff --git a/build/pkgs/eclib/SPKG.rst b/build/pkgs/eclib/SPKG.rst index cca1baa0670..5627fdcb57c 100644 --- a/build/pkgs/eclib/SPKG.rst +++ b/build/pkgs/eclib/SPKG.rst @@ -32,10 +32,3 @@ Upstream Contact - Website: http://homepages.warwick.ac.uk/staff/J.E.Cremona/mwrank/index.html - Repository: https://github.com/JohnCremona/eclib - -Dependencies ------------- - -- PARI -- NTL -- FLINT diff --git a/build/pkgs/fflas_ffpack/SPKG.rst b/build/pkgs/fflas_ffpack/SPKG.rst index 26c7e6385a1..0e3a7efdc70 100644 --- a/build/pkgs/fflas_ffpack/SPKG.rst +++ b/build/pkgs/fflas_ffpack/SPKG.rst @@ -15,25 +15,7 @@ License LGPL V2.1 or later -SPKG Repository ---------------- - - https://bitbucket.org/malb/fflas-ffpack-spkg - - Upstream Contact ---------------- - - -Dependencies ------------- - -- Givaro -- a BLAS implementation such as openblas - - -Patches -------- - -- bash.patch: fix shebang line to "#!/usr/bin/env bash" diff --git a/build/pkgs/fplll/SPKG.rst b/build/pkgs/fplll/SPKG.rst index d7c3ade83c0..2fe28e50e25 100644 --- a/build/pkgs/fplll/SPKG.rst +++ b/build/pkgs/fplll/SPKG.rst @@ -21,9 +21,3 @@ Upstream Contact - Martin Albrecht - Mailing List https://groups.google.com/forum/#!forum/fplll-devel - -Dependencies ------------- - -- gmp -- mpfr diff --git a/build/pkgs/fpylll/SPKG.rst b/build/pkgs/fpylll/SPKG.rst index 84d7bcbf7ac..199893d5761 100644 --- a/build/pkgs/fpylll/SPKG.rst +++ b/build/pkgs/fpylll/SPKG.rst @@ -16,11 +16,3 @@ Upstream Contact ---------------- https://github.com/fplll/fpylll - -Dependencies ------------- - -- Cython -- fplll -- Sage (optional) -- NumPy (optional) diff --git a/build/pkgs/freetype/SPKG.rst b/build/pkgs/freetype/SPKG.rst index 74b3f67df71..368a6763462 100644 --- a/build/pkgs/freetype/SPKG.rst +++ b/build/pkgs/freetype/SPKG.rst @@ -45,8 +45,3 @@ Upstream Contact - official: http://git.savannah.gnu.org/cgit/freetype - mirror: https://github.com/aseprite/freetype2/ - -Dependencies ------------- - -See the ``dependencies`` file. diff --git a/build/pkgs/fricas/SPKG.rst b/build/pkgs/fricas/SPKG.rst index 7d18dd6fa78..5f8e01324ef 100644 --- a/build/pkgs/fricas/SPKG.rst +++ b/build/pkgs/fricas/SPKG.rst @@ -16,8 +16,3 @@ Upstream Contact ---------------- http://fricas.sourceforge.net/ - -Dependencies ------------- - -- ecl From f9e76d552d5f64df4b3925b447fa3b10895fbdab Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 14 May 2022 21:45:21 -0700 Subject: [PATCH 423/529] build/pkgs/*/dependencies: Remove outdated boilerplate comment --- build/pkgs/4ti2/dependencies | 1 - build/pkgs/alabaster/dependencies | 1 - build/pkgs/appnope/dependencies | 1 - build/pkgs/arb/dependencies | 1 - build/pkgs/attrs/dependencies | 1 - build/pkgs/awali/dependencies | 1 - build/pkgs/babel/dependencies | 1 - build/pkgs/backcall/dependencies | 1 - build/pkgs/barvinok/dependencies | 1 - build/pkgs/bliss/dependencies | 1 - build/pkgs/boost_cropped/dependencies | 1 - build/pkgs/brial/dependencies | 1 - build/pkgs/buckygen/dependencies | 1 - build/pkgs/bzip2/dependencies | 1 - build/pkgs/cbc/dependencies | 1 - build/pkgs/ccache/dependencies | 1 - build/pkgs/cddlib/dependencies | 1 - build/pkgs/certifi/dependencies | 1 - build/pkgs/cffi/dependencies | 1 - build/pkgs/cliquer/dependencies | 1 - build/pkgs/cmake/dependencies | 1 - build/pkgs/cocoalib/dependencies | 1 - build/pkgs/combinatorial_designs/dependencies | 1 - build/pkgs/conway_polynomials/dependencies | 1 - build/pkgs/cppy/dependencies | 1 - build/pkgs/cryptominisat/dependencies | 1 - build/pkgs/csdp/dependencies | 1 - build/pkgs/curl/dependencies | 1 - build/pkgs/cycler/dependencies | 1 - build/pkgs/cypari/dependencies | 1 - build/pkgs/cysignals/dependencies | 1 - build/pkgs/cython/dependencies | 1 - build/pkgs/d3js/dependencies | 1 - build/pkgs/database_cremona_ellcurve/dependencies | 1 - build/pkgs/database_jones_numfield/dependencies | 1 - build/pkgs/database_odlyzko_zeta/dependencies | 1 - build/pkgs/database_stein_watkins/dependencies | 1 - build/pkgs/database_stein_watkins_mini/dependencies | 1 - build/pkgs/database_symbolic_data/dependencies | 1 - build/pkgs/dateutil/dependencies | 1 - build/pkgs/deformation/dependencies | 1 - build/pkgs/docutils/dependencies | 1 - build/pkgs/dot2tex/dependencies | 1 - build/pkgs/e_antic/dependencies | 1 - build/pkgs/ecl/dependencies | 1 - build/pkgs/eclib/dependencies | 1 - build/pkgs/ecm/dependencies | 1 - build/pkgs/elliptic_curves/dependencies | 1 - build/pkgs/entrypoints/dependencies | 1 - build/pkgs/fflas_ffpack/dependencies | 1 - build/pkgs/flint/dependencies | 1 - build/pkgs/flintqs/dependencies | 1 - build/pkgs/fplll/dependencies | 1 - build/pkgs/fpylll/dependencies | 1 - build/pkgs/freetype/dependencies | 1 - build/pkgs/fricas/dependencies | 1 - build/pkgs/gambit/dependencies | 1 - build/pkgs/gap/dependencies | 1 - build/pkgs/gap_packages/dependencies | 1 - build/pkgs/gc/dependencies | 1 - build/pkgs/gdb/dependencies | 1 - build/pkgs/gengetopt/dependencies | 1 - build/pkgs/gfan/dependencies | 1 - build/pkgs/giac/dependencies | 1 - build/pkgs/givaro/dependencies | 1 - build/pkgs/glpk/dependencies | 1 - build/pkgs/glucose/dependencies | 1 - build/pkgs/gmpy2/dependencies | 1 - build/pkgs/gp2c/dependencies | 1 - build/pkgs/graphs/dependencies | 1 - build/pkgs/gsl/dependencies | 1 - build/pkgs/html5lib/dependencies | 1 - build/pkgs/iconv/dependencies | 1 - build/pkgs/imagesize/dependencies | 1 - build/pkgs/iml/dependencies | 1 - build/pkgs/importlib_metadata/dependencies | 1 - build/pkgs/info/dependencies | 1 - build/pkgs/ipykernel/dependencies | 1 - build/pkgs/ipython/dependencies | 1 - build/pkgs/ipython_genutils/dependencies | 1 - build/pkgs/ipywidgets/dependencies | 1 - build/pkgs/isl/dependencies | 1 - build/pkgs/jedi/dependencies | 1 - build/pkgs/jinja2/dependencies | 1 - build/pkgs/jmol/dependencies | 1 - build/pkgs/jsonschema/dependencies | 1 - build/pkgs/jupymake/dependencies | 1 - build/pkgs/jupyter_client/dependencies | 1 - build/pkgs/jupyter_core/dependencies | 1 - build/pkgs/jupyterlab/dependencies | 1 - build/pkgs/kenzo/dependencies | 1 - build/pkgs/kiwisolver/dependencies | 1 - build/pkgs/lcalc/dependencies | 1 - build/pkgs/libatomic_ops/dependencies | 1 - build/pkgs/libffi/dependencies | 1 - build/pkgs/libgd/dependencies | 1 - build/pkgs/liblzma/dependencies | 1 - build/pkgs/libnauty/dependencies | 1 - build/pkgs/libogg/dependencies | 1 - build/pkgs/libpng/dependencies | 1 - build/pkgs/libsemigroups/dependencies | 1 - build/pkgs/libtheora/dependencies | 1 - build/pkgs/libxml2/dependencies | 1 - build/pkgs/lidia/dependencies | 1 - build/pkgs/lie/dependencies | 1 - build/pkgs/linbox/dependencies | 1 - build/pkgs/lrcalc/dependencies | 1 - build/pkgs/lrcalc_python/dependencies | 1 - build/pkgs/lrslib/dependencies | 1 - build/pkgs/m4ri/dependencies | 1 - build/pkgs/m4rie/dependencies | 1 - build/pkgs/markupsafe/dependencies | 1 - build/pkgs/matplotlib/dependencies | 1 - build/pkgs/maxima/dependencies | 1 - build/pkgs/memory_allocator/dependencies | 1 - build/pkgs/mistune/dependencies | 1 - build/pkgs/mpc/dependencies | 1 - build/pkgs/mpfi/dependencies | 1 - build/pkgs/mpfr/dependencies | 1 - build/pkgs/mpfrcx/dependencies | 1 - build/pkgs/mpmath/dependencies | 1 - build/pkgs/nauty/dependencies | 1 - build/pkgs/nbconvert/dependencies | 1 - build/pkgs/nbformat/dependencies | 1 - build/pkgs/ncurses/dependencies | 1 - build/pkgs/networkx/dependencies | 1 - build/pkgs/ninja_build/dependencies | 1 - build/pkgs/nodeenv/dependencies | 1 - build/pkgs/nodejs/dependencies | 1 - build/pkgs/normaliz/dependencies | 1 - build/pkgs/notebook/dependencies | 1 - build/pkgs/notedown/dependencies | 1 - build/pkgs/ntl/dependencies | 1 - build/pkgs/numpy/dependencies | 1 - build/pkgs/openblas/dependencies | 1 - build/pkgs/openssl/dependencies | 1 - build/pkgs/ore_algebra/dependencies | 1 - build/pkgs/packaging/dependencies | 1 - build/pkgs/pandoc_attributes/dependencies | 1 - build/pkgs/pandocfilters/dependencies | 1 - build/pkgs/pari/dependencies | 1 - build/pkgs/pari_elldata/dependencies | 1 - build/pkgs/pari_galdata/dependencies | 1 - build/pkgs/pari_galpol/dependencies | 1 - build/pkgs/pari_nftables/dependencies | 1 - build/pkgs/pari_seadata/dependencies | 1 - build/pkgs/pari_seadata_small/dependencies | 1 - build/pkgs/parso/dependencies | 1 - build/pkgs/patch/dependencies | 1 - build/pkgs/pcre/dependencies | 1 - build/pkgs/perl_term_readline_gnu/dependencies | 1 - build/pkgs/pexpect/dependencies | 1 - build/pkgs/pickleshare/dependencies | 1 - build/pkgs/pillow/dependencies | 1 - build/pkgs/pip/dependencies | 1 - build/pkgs/pkgconf/dependencies | 1 - build/pkgs/pkgconfig/dependencies | 1 - build/pkgs/planarity/dependencies | 1 - build/pkgs/plantri/dependencies | 1 - build/pkgs/polylib/dependencies | 1 - build/pkgs/polytopes_db/dependencies | 1 - build/pkgs/ppl/dependencies | 1 - build/pkgs/prometheus_client/dependencies | 1 - build/pkgs/prompt_toolkit/dependencies | 1 - build/pkgs/ptyprocess/dependencies | 1 - build/pkgs/pycosat/dependencies | 1 - build/pkgs/pycparser/dependencies | 1 - build/pkgs/pycryptosat/dependencies | 1 - build/pkgs/pycygwin/dependencies | 1 - build/pkgs/pygments/dependencies | 1 - build/pkgs/pynormaliz/dependencies | 1 - build/pkgs/pyparsing/dependencies | 1 - build/pkgs/pyrsistent/dependencies | 1 - build/pkgs/python3/dependencies | 1 - build/pkgs/python_igraph/dependencies | 1 - build/pkgs/pytz/dependencies | 1 - build/pkgs/pyzmq/dependencies | 1 - build/pkgs/qepcad/dependencies | 1 - build/pkgs/qhull/dependencies | 1 - build/pkgs/r/dependencies | 1 - build/pkgs/readline/dependencies | 1 - build/pkgs/requests/dependencies | 1 - build/pkgs/rst2ipynb/dependencies | 1 - build/pkgs/rubiks/dependencies | 1 - build/pkgs/rw/dependencies | 1 - build/pkgs/saclib/dependencies | 1 - build/pkgs/sage_numerical_backends_coin/dependencies | 1 - build/pkgs/sage_numerical_backends_cplex/dependencies | 1 - build/pkgs/sage_numerical_backends_gurobi/dependencies | 1 - build/pkgs/sage_setup/dependencies | 1 - build/pkgs/sagelib/dependencies | 1 - build/pkgs/sagenb_export/dependencies | 1 - build/pkgs/scipoptsuite/dependencies | 1 - build/pkgs/scipy/dependencies | 1 - build/pkgs/setuptools/dependencies | 1 - build/pkgs/setuptools_scm/dependencies | 1 - build/pkgs/setuptools_wheel/dependencies | 1 - build/pkgs/simplegeneric/dependencies | 1 - build/pkgs/singular/dependencies | 1 - build/pkgs/sip/dependencies | 1 - build/pkgs/six/dependencies | 1 - build/pkgs/snowballstemmer/dependencies | 1 - build/pkgs/sphinx/dependencies | 1 - build/pkgs/sphinxcontrib_applehelp/dependencies | 1 - build/pkgs/sphinxcontrib_devhelp/dependencies | 1 - build/pkgs/sphinxcontrib_htmlhelp/dependencies | 1 - build/pkgs/sphinxcontrib_jsmath/dependencies | 1 - build/pkgs/sphinxcontrib_qthelp/dependencies | 1 - build/pkgs/sphinxcontrib_serializinghtml/dependencies | 1 - build/pkgs/sphinxcontrib_websupport/dependencies | 1 - build/pkgs/sqlite/dependencies | 1 - build/pkgs/surf/dependencies | 1 - build/pkgs/symengine/dependencies | 1 - build/pkgs/symengine_py/dependencies | 1 - build/pkgs/symmetrica/dependencies | 1 - build/pkgs/sympow/dependencies | 1 - build/pkgs/sympy/dependencies | 1 - build/pkgs/tachyon/dependencies | 1 - build/pkgs/terminado/dependencies | 1 - build/pkgs/testpath/dependencies | 1 - build/pkgs/texttable/dependencies | 1 - build/pkgs/tides/dependencies | 1 - build/pkgs/topcom/dependencies | 1 - build/pkgs/tornado/dependencies | 1 - build/pkgs/tox/dependencies | 1 - build/pkgs/traitlets/dependencies | 1 - build/pkgs/tzlocal/dependencies | 1 - build/pkgs/valgrind/dependencies | 1 - build/pkgs/vcversioner/dependencies | 1 - build/pkgs/wcwidth/dependencies | 1 - build/pkgs/webencodings/dependencies | 1 - build/pkgs/wheel/dependencies | 1 - build/pkgs/widgetsnbextension/dependencies | 1 - build/pkgs/xz/dependencies | 1 - build/pkgs/zeromq/dependencies | 1 - build/pkgs/zipp/dependencies | 1 - build/pkgs/zlib/dependencies | 1 - build/pkgs/zn_poly/dependencies | 1 - 238 files changed, 238 deletions(-) diff --git a/build/pkgs/4ti2/dependencies b/build/pkgs/4ti2/dependencies index 2b36820a7c5..72c4505b110 100644 --- a/build/pkgs/4ti2/dependencies +++ b/build/pkgs/4ti2/dependencies @@ -2,4 +2,3 @@ zlib $(MP_LIBRARY) glpk ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/alabaster/dependencies b/build/pkgs/alabaster/dependencies index 15df0c4d6d8..0738c2d7777 100644 --- a/build/pkgs/alabaster/dependencies +++ b/build/pkgs/alabaster/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/appnope/dependencies b/build/pkgs/appnope/dependencies index 15df0c4d6d8..0738c2d7777 100644 --- a/build/pkgs/appnope/dependencies +++ b/build/pkgs/appnope/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/arb/dependencies b/build/pkgs/arb/dependencies index 09c8e56f94a..c95d2836ce5 100644 --- a/build/pkgs/arb/dependencies +++ b/build/pkgs/arb/dependencies @@ -2,4 +2,3 @@ $(MP_LIBRARY) mpfr flint ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/attrs/dependencies b/build/pkgs/attrs/dependencies index 8b3637a0a0e..4361e46ddaf 100644 --- a/build/pkgs/attrs/dependencies +++ b/build/pkgs/attrs/dependencies @@ -2,4 +2,3 @@ $(PYTHON) vcversioner | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/awali/dependencies b/build/pkgs/awali/dependencies index ad153b34f3e..b125e2ded92 100644 --- a/build/pkgs/awali/dependencies +++ b/build/pkgs/awali/dependencies @@ -2,4 +2,3 @@ $(PYTHON) cmake cython nbconvert ncurses ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/babel/dependencies b/build/pkgs/babel/dependencies index 2fabe3177df..41462907c20 100644 --- a/build/pkgs/babel/dependencies +++ b/build/pkgs/babel/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) pytz ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/backcall/dependencies b/build/pkgs/backcall/dependencies index 35228f20368..902a5feed13 100644 --- a/build/pkgs/backcall/dependencies +++ b/build/pkgs/backcall/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) flit_core tomli ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/barvinok/dependencies b/build/pkgs/barvinok/dependencies index e564790ea88..02d761438ff 100644 --- a/build/pkgs/barvinok/dependencies +++ b/build/pkgs/barvinok/dependencies @@ -2,4 +2,3 @@ ntl isl polylib ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/bliss/dependencies b/build/pkgs/bliss/dependencies index 3546cda4614..4f00de20375 100644 --- a/build/pkgs/bliss/dependencies +++ b/build/pkgs/bliss/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/boost_cropped/dependencies b/build/pkgs/boost_cropped/dependencies index 3546cda4614..4f00de20375 100644 --- a/build/pkgs/boost_cropped/dependencies +++ b/build/pkgs/boost_cropped/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/brial/dependencies b/build/pkgs/brial/dependencies index 1944cbeb530..fdc17b08c96 100644 --- a/build/pkgs/brial/dependencies +++ b/build/pkgs/brial/dependencies @@ -2,4 +2,3 @@ boost_cropped m4ri libpng | pkgconf ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/buckygen/dependencies b/build/pkgs/buckygen/dependencies index 3546cda4614..4f00de20375 100644 --- a/build/pkgs/buckygen/dependencies +++ b/build/pkgs/buckygen/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/bzip2/dependencies b/build/pkgs/bzip2/dependencies index dae4f925522..5598eb21a8b 100644 --- a/build/pkgs/bzip2/dependencies +++ b/build/pkgs/bzip2/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/cbc/dependencies b/build/pkgs/cbc/dependencies index 7137ee6f521..bdec3fbe76e 100644 --- a/build/pkgs/cbc/dependencies +++ b/build/pkgs/cbc/dependencies @@ -2,4 +2,3 @@ readline zlib bzip2 $(BLAS) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/ccache/dependencies b/build/pkgs/ccache/dependencies index 4c0aa5c0d31..a1eb8a80d3d 100644 --- a/build/pkgs/ccache/dependencies +++ b/build/pkgs/ccache/dependencies @@ -2,4 +2,3 @@ zlib ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/cddlib/dependencies b/build/pkgs/cddlib/dependencies index 9a77ea16f78..42dc0e9c107 100644 --- a/build/pkgs/cddlib/dependencies +++ b/build/pkgs/cddlib/dependencies @@ -2,4 +2,3 @@ $(MP_LIBRARY) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/certifi/dependencies b/build/pkgs/certifi/dependencies index 15df0c4d6d8..0738c2d7777 100644 --- a/build/pkgs/certifi/dependencies +++ b/build/pkgs/certifi/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/cffi/dependencies b/build/pkgs/cffi/dependencies index aef34bf5a4d..9e4c266ad69 100644 --- a/build/pkgs/cffi/dependencies +++ b/build/pkgs/cffi/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) pycparser ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/cliquer/dependencies b/build/pkgs/cliquer/dependencies index 3546cda4614..4f00de20375 100644 --- a/build/pkgs/cliquer/dependencies +++ b/build/pkgs/cliquer/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/cmake/dependencies b/build/pkgs/cmake/dependencies index 2b79396e60e..614b742ab6d 100644 --- a/build/pkgs/cmake/dependencies +++ b/build/pkgs/cmake/dependencies @@ -2,4 +2,3 @@ curl zlib bzip2 liblzma ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/cocoalib/dependencies b/build/pkgs/cocoalib/dependencies index 9a77ea16f78..42dc0e9c107 100644 --- a/build/pkgs/cocoalib/dependencies +++ b/build/pkgs/cocoalib/dependencies @@ -2,4 +2,3 @@ $(MP_LIBRARY) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/combinatorial_designs/dependencies b/build/pkgs/combinatorial_designs/dependencies index 3546cda4614..4f00de20375 100644 --- a/build/pkgs/combinatorial_designs/dependencies +++ b/build/pkgs/combinatorial_designs/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/conway_polynomials/dependencies b/build/pkgs/conway_polynomials/dependencies index 304d0c987a2..1700e743d59 100644 --- a/build/pkgs/conway_polynomials/dependencies +++ b/build/pkgs/conway_polynomials/dependencies @@ -2,4 +2,3 @@ $(PYTHON) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/cppy/dependencies b/build/pkgs/cppy/dependencies index 15df0c4d6d8..0738c2d7777 100644 --- a/build/pkgs/cppy/dependencies +++ b/build/pkgs/cppy/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/cryptominisat/dependencies b/build/pkgs/cryptominisat/dependencies index 18f1811f305..15e88888b6d 100644 --- a/build/pkgs/cryptominisat/dependencies +++ b/build/pkgs/cryptominisat/dependencies @@ -2,4 +2,3 @@ $(PYTHON) m4ri zlib libpng | cmake boost_cropped ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/csdp/dependencies b/build/pkgs/csdp/dependencies index 052eb4373db..40ad3c0e9b6 100644 --- a/build/pkgs/csdp/dependencies +++ b/build/pkgs/csdp/dependencies @@ -2,4 +2,3 @@ $(BLAS) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/curl/dependencies b/build/pkgs/curl/dependencies index 3546cda4614..4f00de20375 100644 --- a/build/pkgs/curl/dependencies +++ b/build/pkgs/curl/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/cycler/dependencies b/build/pkgs/cycler/dependencies index fd848c100a8..730af09b339 100644 --- a/build/pkgs/cycler/dependencies +++ b/build/pkgs/cycler/dependencies @@ -1,5 +1,4 @@ $(PYTHON) six | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/cypari/dependencies b/build/pkgs/cypari/dependencies index 3f04dd2b8f3..72b5af7ad81 100644 --- a/build/pkgs/cypari/dependencies +++ b/build/pkgs/cypari/dependencies @@ -2,4 +2,3 @@ $(PYTHON) cython pari cysignals | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/cysignals/dependencies b/build/pkgs/cysignals/dependencies index 19bc31a739c..d3225d480f1 100644 --- a/build/pkgs/cysignals/dependencies +++ b/build/pkgs/cysignals/dependencies @@ -2,4 +2,3 @@ $(PYTHON) cython pari | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/cython/dependencies b/build/pkgs/cython/dependencies index 15df0c4d6d8..0738c2d7777 100644 --- a/build/pkgs/cython/dependencies +++ b/build/pkgs/cython/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/d3js/dependencies b/build/pkgs/d3js/dependencies index 3546cda4614..4f00de20375 100644 --- a/build/pkgs/d3js/dependencies +++ b/build/pkgs/d3js/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/database_cremona_ellcurve/dependencies b/build/pkgs/database_cremona_ellcurve/dependencies index 3546cda4614..4f00de20375 100644 --- a/build/pkgs/database_cremona_ellcurve/dependencies +++ b/build/pkgs/database_cremona_ellcurve/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/database_jones_numfield/dependencies b/build/pkgs/database_jones_numfield/dependencies index 3546cda4614..4f00de20375 100644 --- a/build/pkgs/database_jones_numfield/dependencies +++ b/build/pkgs/database_jones_numfield/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/database_odlyzko_zeta/dependencies b/build/pkgs/database_odlyzko_zeta/dependencies index c1b713883fe..ec44bfaa468 100644 --- a/build/pkgs/database_odlyzko_zeta/dependencies +++ b/build/pkgs/database_odlyzko_zeta/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/database_stein_watkins/dependencies b/build/pkgs/database_stein_watkins/dependencies index 3546cda4614..4f00de20375 100644 --- a/build/pkgs/database_stein_watkins/dependencies +++ b/build/pkgs/database_stein_watkins/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/database_stein_watkins_mini/dependencies b/build/pkgs/database_stein_watkins_mini/dependencies index 3546cda4614..4f00de20375 100644 --- a/build/pkgs/database_stein_watkins_mini/dependencies +++ b/build/pkgs/database_stein_watkins_mini/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/database_symbolic_data/dependencies b/build/pkgs/database_symbolic_data/dependencies index 3546cda4614..4f00de20375 100644 --- a/build/pkgs/database_symbolic_data/dependencies +++ b/build/pkgs/database_symbolic_data/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/dateutil/dependencies b/build/pkgs/dateutil/dependencies index 4db01013112..7a972de985e 100644 --- a/build/pkgs/dateutil/dependencies +++ b/build/pkgs/dateutil/dependencies @@ -2,4 +2,3 @@ $(PYTHON) six | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/deformation/dependencies b/build/pkgs/deformation/dependencies index 09c8e56f94a..c95d2836ce5 100644 --- a/build/pkgs/deformation/dependencies +++ b/build/pkgs/deformation/dependencies @@ -2,4 +2,3 @@ $(MP_LIBRARY) mpfr flint ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/docutils/dependencies b/build/pkgs/docutils/dependencies index 15df0c4d6d8..0738c2d7777 100644 --- a/build/pkgs/docutils/dependencies +++ b/build/pkgs/docutils/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/dot2tex/dependencies b/build/pkgs/dot2tex/dependencies index e88742b6c74..c1925d16b73 100644 --- a/build/pkgs/dot2tex/dependencies +++ b/build/pkgs/dot2tex/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) pyparsing ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/e_antic/dependencies b/build/pkgs/e_antic/dependencies index 895cffa0013..ff67f31325b 100644 --- a/build/pkgs/e_antic/dependencies +++ b/build/pkgs/e_antic/dependencies @@ -2,4 +2,3 @@ $(MP_LIBRARY) flint arb ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/ecl/dependencies b/build/pkgs/ecl/dependencies index bf96c4ff887..cda6316bf5a 100644 --- a/build/pkgs/ecl/dependencies +++ b/build/pkgs/ecl/dependencies @@ -2,4 +2,3 @@ $(MP_LIBRARY) readline gc libffi ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/eclib/dependencies b/build/pkgs/eclib/dependencies index 54e7e242559..b73cfa3391a 100644 --- a/build/pkgs/eclib/dependencies +++ b/build/pkgs/eclib/dependencies @@ -2,4 +2,3 @@ pari ntl flint ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/ecm/dependencies b/build/pkgs/ecm/dependencies index 9a77ea16f78..42dc0e9c107 100644 --- a/build/pkgs/ecm/dependencies +++ b/build/pkgs/ecm/dependencies @@ -2,4 +2,3 @@ $(MP_LIBRARY) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/elliptic_curves/dependencies b/build/pkgs/elliptic_curves/dependencies index 1a36cc52351..6b134137610 100644 --- a/build/pkgs/elliptic_curves/dependencies +++ b/build/pkgs/elliptic_curves/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/entrypoints/dependencies b/build/pkgs/entrypoints/dependencies index 15df0c4d6d8..0738c2d7777 100644 --- a/build/pkgs/entrypoints/dependencies +++ b/build/pkgs/entrypoints/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/fflas_ffpack/dependencies b/build/pkgs/fflas_ffpack/dependencies index 9aba473c01b..dbb5493271d 100644 --- a/build/pkgs/fflas_ffpack/dependencies +++ b/build/pkgs/fflas_ffpack/dependencies @@ -2,4 +2,3 @@ $(MP_LIBRARY) givaro gsl $(BLAS) | pkgconf ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/flint/dependencies b/build/pkgs/flint/dependencies index 2a23f3894a5..385df4faa7d 100644 --- a/build/pkgs/flint/dependencies +++ b/build/pkgs/flint/dependencies @@ -2,4 +2,3 @@ $(MP_LIBRARY) mpfr ntl ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/flintqs/dependencies b/build/pkgs/flintqs/dependencies index 9a77ea16f78..42dc0e9c107 100644 --- a/build/pkgs/flintqs/dependencies +++ b/build/pkgs/flintqs/dependencies @@ -2,4 +2,3 @@ $(MP_LIBRARY) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/fplll/dependencies b/build/pkgs/fplll/dependencies index efb6f50c4b2..1108dc4fb21 100644 --- a/build/pkgs/fplll/dependencies +++ b/build/pkgs/fplll/dependencies @@ -2,4 +2,3 @@ $(MP_LIBRARY) mpfr ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/fpylll/dependencies b/build/pkgs/fpylll/dependencies index cc84e797e80..4b4fb1b44fb 100644 --- a/build/pkgs/fpylll/dependencies +++ b/build/pkgs/fpylll/dependencies @@ -2,4 +2,3 @@ $(PYTHON) cython cysignals numpy fplll ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/freetype/dependencies b/build/pkgs/freetype/dependencies index d4365d93067..af0f47547a8 100644 --- a/build/pkgs/freetype/dependencies +++ b/build/pkgs/freetype/dependencies @@ -2,4 +2,3 @@ libpng bzip2 ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/fricas/dependencies b/build/pkgs/fricas/dependencies index ed6be201375..fffb89e2050 100644 --- a/build/pkgs/fricas/dependencies +++ b/build/pkgs/fricas/dependencies @@ -2,4 +2,3 @@ ecl ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/gambit/dependencies b/build/pkgs/gambit/dependencies index 2040b648774..1f00cbf5321 100644 --- a/build/pkgs/gambit/dependencies +++ b/build/pkgs/gambit/dependencies @@ -2,4 +2,3 @@ cython | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/gap/dependencies b/build/pkgs/gap/dependencies index e0367988d88..a0bd86b58a1 100644 --- a/build/pkgs/gap/dependencies +++ b/build/pkgs/gap/dependencies @@ -2,4 +2,3 @@ ncurses readline zlib $(MP_LIBRARY) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/gap_packages/dependencies b/build/pkgs/gap_packages/dependencies index 21b057d2e47..342d2c8edd1 100644 --- a/build/pkgs/gap_packages/dependencies +++ b/build/pkgs/gap_packages/dependencies @@ -2,4 +2,3 @@ gap libsemigroups planarity | $(SAGERUNTIME) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/gc/dependencies b/build/pkgs/gc/dependencies index 28dadf07615..471ebd6cd85 100644 --- a/build/pkgs/gc/dependencies +++ b/build/pkgs/gc/dependencies @@ -1,4 +1,3 @@ libatomic_ops ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/gdb/dependencies b/build/pkgs/gdb/dependencies index 30508b35c45..bdf81f77180 100644 --- a/build/pkgs/gdb/dependencies +++ b/build/pkgs/gdb/dependencies @@ -2,4 +2,3 @@ mpfr zlib ncurses $(PYTHON) xz ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/gengetopt/dependencies b/build/pkgs/gengetopt/dependencies index 7a7b9cf8a80..eb5b66f34f2 100644 --- a/build/pkgs/gengetopt/dependencies +++ b/build/pkgs/gengetopt/dependencies @@ -4,4 +4,3 @@ xz is needed for unpacking the tarball when sage-bootstrap-python is ancient ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/gfan/dependencies b/build/pkgs/gfan/dependencies index 674fe7612fd..4c6301e2e5d 100644 --- a/build/pkgs/gfan/dependencies +++ b/build/pkgs/gfan/dependencies @@ -2,4 +2,3 @@ $(MP_LIBRARY) cddlib ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/giac/dependencies b/build/pkgs/giac/dependencies index c36972a1011..ddc04d1e402 100644 --- a/build/pkgs/giac/dependencies +++ b/build/pkgs/giac/dependencies @@ -2,4 +2,3 @@ readline libpng $(MP_LIBRARY) mpfr mpfi ntl gsl pari glpk curl ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/install into SAGE_ROOT/build/Makefile. diff --git a/build/pkgs/givaro/dependencies b/build/pkgs/givaro/dependencies index 9a77ea16f78..42dc0e9c107 100644 --- a/build/pkgs/givaro/dependencies +++ b/build/pkgs/givaro/dependencies @@ -2,4 +2,3 @@ $(MP_LIBRARY) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/glpk/dependencies b/build/pkgs/glpk/dependencies index 6f9a6c00fe9..9b1acf2f429 100644 --- a/build/pkgs/glpk/dependencies +++ b/build/pkgs/glpk/dependencies @@ -2,4 +2,3 @@ $(MP_LIBRARY) zlib ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/glucose/dependencies b/build/pkgs/glucose/dependencies index 4c0aa5c0d31..a1eb8a80d3d 100644 --- a/build/pkgs/glucose/dependencies +++ b/build/pkgs/glucose/dependencies @@ -2,4 +2,3 @@ zlib ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/gmpy2/dependencies b/build/pkgs/gmpy2/dependencies index 510fc637e95..98c6065dc87 100644 --- a/build/pkgs/gmpy2/dependencies +++ b/build/pkgs/gmpy2/dependencies @@ -2,4 +2,3 @@ $(PYTHON) $(MP_LIBRARY) mpfr mpc | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/gp2c/dependencies b/build/pkgs/gp2c/dependencies index 7537ca02746..92256baba2a 100644 --- a/build/pkgs/gp2c/dependencies +++ b/build/pkgs/gp2c/dependencies @@ -2,4 +2,3 @@ pari ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/install into SAGE_ROOT/build/Makefile. diff --git a/build/pkgs/graphs/dependencies b/build/pkgs/graphs/dependencies index 3546cda4614..4f00de20375 100644 --- a/build/pkgs/graphs/dependencies +++ b/build/pkgs/graphs/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/gsl/dependencies b/build/pkgs/gsl/dependencies index 576809127c7..8073e1a7f67 100644 --- a/build/pkgs/gsl/dependencies +++ b/build/pkgs/gsl/dependencies @@ -2,4 +2,3 @@ $(BLAS) | pkgconf ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/html5lib/dependencies b/build/pkgs/html5lib/dependencies index cdcfeeba041..89200065387 100644 --- a/build/pkgs/html5lib/dependencies +++ b/build/pkgs/html5lib/dependencies @@ -2,4 +2,3 @@ $(PYTHON) webencodings | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/iconv/dependencies b/build/pkgs/iconv/dependencies index 3546cda4614..4f00de20375 100644 --- a/build/pkgs/iconv/dependencies +++ b/build/pkgs/iconv/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/imagesize/dependencies b/build/pkgs/imagesize/dependencies index 15df0c4d6d8..0738c2d7777 100644 --- a/build/pkgs/imagesize/dependencies +++ b/build/pkgs/imagesize/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/iml/dependencies b/build/pkgs/iml/dependencies index 5a73e699d00..be919463819 100644 --- a/build/pkgs/iml/dependencies +++ b/build/pkgs/iml/dependencies @@ -2,4 +2,3 @@ $(MP_LIBRARY) $(BLAS) | pkgconf ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/importlib_metadata/dependencies b/build/pkgs/importlib_metadata/dependencies index 9fcc3b0cc65..77aa2a42f93 100644 --- a/build/pkgs/importlib_metadata/dependencies +++ b/build/pkgs/importlib_metadata/dependencies @@ -2,4 +2,3 @@ $(PYTHON) zipp typing_extensions | $(PYTHON_TOOLCHAIN) tomli ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/info/dependencies b/build/pkgs/info/dependencies index c2c72b44a87..5405130e47b 100644 --- a/build/pkgs/info/dependencies +++ b/build/pkgs/info/dependencies @@ -7,4 +7,3 @@ system despite not being listed explicitly anywhere. ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/ipykernel/dependencies b/build/pkgs/ipykernel/dependencies index 5b3708a31fc..03ac4f70504 100644 --- a/build/pkgs/ipykernel/dependencies +++ b/build/pkgs/ipykernel/dependencies @@ -2,4 +2,3 @@ $(PYTHON) ipython_genutils importlib_metadata argcomplete matplotlib_inline ipyt ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/ipython/dependencies b/build/pkgs/ipython/dependencies index f15f6f0aca1..afe4e745f2d 100644 --- a/build/pkgs/ipython/dependencies +++ b/build/pkgs/ipython/dependencies @@ -2,4 +2,3 @@ $(PYTHON) jinja2 tornado pyzmq pickleshare simplegeneric traitlets | $(PYTHON_TO ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/ipython_genutils/dependencies b/build/pkgs/ipython_genutils/dependencies index 15df0c4d6d8..0738c2d7777 100644 --- a/build/pkgs/ipython_genutils/dependencies +++ b/build/pkgs/ipython_genutils/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/ipywidgets/dependencies b/build/pkgs/ipywidgets/dependencies index e719deacdd0..e6cc2ed95d5 100644 --- a/build/pkgs/ipywidgets/dependencies +++ b/build/pkgs/ipywidgets/dependencies @@ -2,4 +2,3 @@ $(PYTHON) widgetsnbextension | $(PYTHON_TOOLCHAIN) ipykernel ipython traitlets ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/isl/dependencies b/build/pkgs/isl/dependencies index 9a77ea16f78..42dc0e9c107 100644 --- a/build/pkgs/isl/dependencies +++ b/build/pkgs/isl/dependencies @@ -2,4 +2,3 @@ $(MP_LIBRARY) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/jedi/dependencies b/build/pkgs/jedi/dependencies index 0f21b645bd9..60b5f820a37 100644 --- a/build/pkgs/jedi/dependencies +++ b/build/pkgs/jedi/dependencies @@ -2,4 +2,3 @@ $(PYTHON) parso | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/jinja2/dependencies b/build/pkgs/jinja2/dependencies index e8739c35b16..6947978ec42 100644 --- a/build/pkgs/jinja2/dependencies +++ b/build/pkgs/jinja2/dependencies @@ -2,4 +2,3 @@ $(PYTHON) markupsafe docutils | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/jmol/dependencies b/build/pkgs/jmol/dependencies index 50320851772..3edeff40436 100644 --- a/build/pkgs/jmol/dependencies +++ b/build/pkgs/jmol/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/jsonschema/dependencies b/build/pkgs/jsonschema/dependencies index c4bb27ca08e..543eb556459 100644 --- a/build/pkgs/jsonschema/dependencies +++ b/build/pkgs/jsonschema/dependencies @@ -2,4 +2,3 @@ $(PYTHON) vcversioner attrs importlib_metadata pyrsistent | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/jupymake/dependencies b/build/pkgs/jupymake/dependencies index bcbd220117e..c8ed956ad6a 100644 --- a/build/pkgs/jupymake/dependencies +++ b/build/pkgs/jupymake/dependencies @@ -2,4 +2,3 @@ $(PYTHON) polymake | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/jupyter_client/dependencies b/build/pkgs/jupyter_client/dependencies index d405e7b48d7..5e9a6c75874 100644 --- a/build/pkgs/jupyter_client/dependencies +++ b/build/pkgs/jupyter_client/dependencies @@ -2,4 +2,3 @@ $(PYTHON) jupyter_core | $(PYTHON_TOOLCHAIN) pyzmq dateutil nest_asyncio tornado ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/jupyter_core/dependencies b/build/pkgs/jupyter_core/dependencies index 5dcd07f89fa..6aeda10f20d 100644 --- a/build/pkgs/jupyter_core/dependencies +++ b/build/pkgs/jupyter_core/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) traitlets ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/jupyterlab/dependencies b/build/pkgs/jupyterlab/dependencies index 463f6e9d917..98ad2e94050 100644 --- a/build/pkgs/jupyterlab/dependencies +++ b/build/pkgs/jupyterlab/dependencies @@ -2,4 +2,3 @@ $(PYTHON) vcversioner jupyter_core jupyter_client jinja2 tornado ipython packagi ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/kenzo/dependencies b/build/pkgs/kenzo/dependencies index ed6be201375..fffb89e2050 100644 --- a/build/pkgs/kenzo/dependencies +++ b/build/pkgs/kenzo/dependencies @@ -2,4 +2,3 @@ ecl ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/kiwisolver/dependencies b/build/pkgs/kiwisolver/dependencies index 80b9352eb76..5df13094620 100644 --- a/build/pkgs/kiwisolver/dependencies +++ b/build/pkgs/kiwisolver/dependencies @@ -2,4 +2,3 @@ $(PYTHON) cppy | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/lcalc/dependencies b/build/pkgs/lcalc/dependencies index d42038dce36..ad46cc7f320 100644 --- a/build/pkgs/lcalc/dependencies +++ b/build/pkgs/lcalc/dependencies @@ -2,4 +2,3 @@ pari | gengetopt ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/libatomic_ops/dependencies b/build/pkgs/libatomic_ops/dependencies index 3546cda4614..4f00de20375 100644 --- a/build/pkgs/libatomic_ops/dependencies +++ b/build/pkgs/libatomic_ops/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/libffi/dependencies b/build/pkgs/libffi/dependencies index 3546cda4614..4f00de20375 100644 --- a/build/pkgs/libffi/dependencies +++ b/build/pkgs/libffi/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/libgd/dependencies b/build/pkgs/libgd/dependencies index 998d7d01593..e2cbc65b7da 100644 --- a/build/pkgs/libgd/dependencies +++ b/build/pkgs/libgd/dependencies @@ -3,4 +3,3 @@ libpng freetype xz # xz needed to unpack tarball when sage-bootstrap-python is Python < 3.3 ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/liblzma/dependencies b/build/pkgs/liblzma/dependencies index f111204fa1f..52b7ce903f8 100644 --- a/build/pkgs/liblzma/dependencies +++ b/build/pkgs/liblzma/dependencies @@ -2,7 +2,6 @@ $(SAGE_LOCAL)/$(SPKG_INST_RELDIR)/xz-$(vers_xz) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. Adding the above instead of "xz" makes sure that the dependency is not replaced by ".dummy". In this way, liblzma delegates building to xz when diff --git a/build/pkgs/libnauty/dependencies b/build/pkgs/libnauty/dependencies index 88254f7b556..cc6b7527ab9 100644 --- a/build/pkgs/libnauty/dependencies +++ b/build/pkgs/libnauty/dependencies @@ -2,7 +2,6 @@ $(SAGE_LOCAL)/$(SPKG_INST_RELDIR)/nauty-$(vers_nauty) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. Adding the above instead of "nauty" makes sure that the dependency is not replaced by ".dummy". In this way, libnauty delegates building to nauty when diff --git a/build/pkgs/libogg/dependencies b/build/pkgs/libogg/dependencies index 3546cda4614..4f00de20375 100644 --- a/build/pkgs/libogg/dependencies +++ b/build/pkgs/libogg/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/libpng/dependencies b/build/pkgs/libpng/dependencies index 4c0aa5c0d31..a1eb8a80d3d 100644 --- a/build/pkgs/libpng/dependencies +++ b/build/pkgs/libpng/dependencies @@ -2,4 +2,3 @@ zlib ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/libsemigroups/dependencies b/build/pkgs/libsemigroups/dependencies index 3546cda4614..4f00de20375 100644 --- a/build/pkgs/libsemigroups/dependencies +++ b/build/pkgs/libsemigroups/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/libtheora/dependencies b/build/pkgs/libtheora/dependencies index 42f4da7f9d4..e62d879d3a4 100644 --- a/build/pkgs/libtheora/dependencies +++ b/build/pkgs/libtheora/dependencies @@ -2,4 +2,3 @@ libogg libpng ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/libxml2/dependencies b/build/pkgs/libxml2/dependencies index 6a9b467fe73..e1903120ece 100644 --- a/build/pkgs/libxml2/dependencies +++ b/build/pkgs/libxml2/dependencies @@ -2,4 +2,3 @@ iconv zlib ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/lidia/dependencies b/build/pkgs/lidia/dependencies index 9a77ea16f78..42dc0e9c107 100644 --- a/build/pkgs/lidia/dependencies +++ b/build/pkgs/lidia/dependencies @@ -2,4 +2,3 @@ $(MP_LIBRARY) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/lie/dependencies b/build/pkgs/lie/dependencies index 299ba61f5b7..9f475af894a 100644 --- a/build/pkgs/lie/dependencies +++ b/build/pkgs/lie/dependencies @@ -2,4 +2,3 @@ readline ncurses ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/linbox/dependencies b/build/pkgs/linbox/dependencies index 98b93071996..16264e23edc 100644 --- a/build/pkgs/linbox/dependencies +++ b/build/pkgs/linbox/dependencies @@ -2,4 +2,3 @@ $(MP_LIBRARY) ntl givaro mpfr iml flint fflas_ffpack ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/lrcalc/dependencies b/build/pkgs/lrcalc/dependencies index 3546cda4614..4f00de20375 100644 --- a/build/pkgs/lrcalc/dependencies +++ b/build/pkgs/lrcalc/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/lrcalc_python/dependencies b/build/pkgs/lrcalc_python/dependencies index 63e5177ae0d..27c96045586 100644 --- a/build/pkgs/lrcalc_python/dependencies +++ b/build/pkgs/lrcalc_python/dependencies @@ -2,4 +2,3 @@ $(PYTHON) lrcalc | $(PYTHON_TOOLCHAIN) cython ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/lrslib/dependencies b/build/pkgs/lrslib/dependencies index 9a77ea16f78..42dc0e9c107 100644 --- a/build/pkgs/lrslib/dependencies +++ b/build/pkgs/lrslib/dependencies @@ -2,4 +2,3 @@ $(MP_LIBRARY) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/m4ri/dependencies b/build/pkgs/m4ri/dependencies index a32404ffb8e..a6ce9ea4411 100644 --- a/build/pkgs/m4ri/dependencies +++ b/build/pkgs/m4ri/dependencies @@ -2,4 +2,3 @@ libpng ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/m4rie/dependencies b/build/pkgs/m4rie/dependencies index 4756344de51..8c26128557d 100644 --- a/build/pkgs/m4rie/dependencies +++ b/build/pkgs/m4rie/dependencies @@ -2,4 +2,3 @@ m4ri ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/markupsafe/dependencies b/build/pkgs/markupsafe/dependencies index 15df0c4d6d8..0738c2d7777 100644 --- a/build/pkgs/markupsafe/dependencies +++ b/build/pkgs/markupsafe/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/matplotlib/dependencies b/build/pkgs/matplotlib/dependencies index 0b3e62b01c1..1fcb30a9c9d 100644 --- a/build/pkgs/matplotlib/dependencies +++ b/build/pkgs/matplotlib/dependencies @@ -2,4 +2,3 @@ $(PYTHON) numpy freetype pillow dateutil pyparsing tornado six cycler qhull font ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/maxima/dependencies b/build/pkgs/maxima/dependencies index ed6be201375..fffb89e2050 100644 --- a/build/pkgs/maxima/dependencies +++ b/build/pkgs/maxima/dependencies @@ -2,4 +2,3 @@ ecl ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/memory_allocator/dependencies b/build/pkgs/memory_allocator/dependencies index d3dac75e5f2..296a2bebad3 100644 --- a/build/pkgs/memory_allocator/dependencies +++ b/build/pkgs/memory_allocator/dependencies @@ -2,4 +2,3 @@ $(PYTHON) cython | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/mistune/dependencies b/build/pkgs/mistune/dependencies index d3dac75e5f2..296a2bebad3 100644 --- a/build/pkgs/mistune/dependencies +++ b/build/pkgs/mistune/dependencies @@ -2,4 +2,3 @@ $(PYTHON) cython | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/mpc/dependencies b/build/pkgs/mpc/dependencies index efb6f50c4b2..1108dc4fb21 100644 --- a/build/pkgs/mpc/dependencies +++ b/build/pkgs/mpc/dependencies @@ -2,4 +2,3 @@ $(MP_LIBRARY) mpfr ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/mpfi/dependencies b/build/pkgs/mpfi/dependencies index efb6f50c4b2..1108dc4fb21 100644 --- a/build/pkgs/mpfi/dependencies +++ b/build/pkgs/mpfi/dependencies @@ -2,4 +2,3 @@ $(MP_LIBRARY) mpfr ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/mpfr/dependencies b/build/pkgs/mpfr/dependencies index 9a77ea16f78..42dc0e9c107 100644 --- a/build/pkgs/mpfr/dependencies +++ b/build/pkgs/mpfr/dependencies @@ -2,4 +2,3 @@ $(MP_LIBRARY) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/mpfrcx/dependencies b/build/pkgs/mpfrcx/dependencies index f51a741fc82..1c5fe72f749 100644 --- a/build/pkgs/mpfrcx/dependencies +++ b/build/pkgs/mpfrcx/dependencies @@ -2,4 +2,3 @@ $(MP_LIBRARY) mpfr mpc ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/mpmath/dependencies b/build/pkgs/mpmath/dependencies index 15df0c4d6d8..0738c2d7777 100644 --- a/build/pkgs/mpmath/dependencies +++ b/build/pkgs/mpmath/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/nauty/dependencies b/build/pkgs/nauty/dependencies index 3546cda4614..4f00de20375 100644 --- a/build/pkgs/nauty/dependencies +++ b/build/pkgs/nauty/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/nbconvert/dependencies b/build/pkgs/nbconvert/dependencies index 86e4ceccf2e..5f8b20ddcf8 100644 --- a/build/pkgs/nbconvert/dependencies +++ b/build/pkgs/nbconvert/dependencies @@ -2,4 +2,3 @@ $(PYTHON) mistune jinja2 pygments traitlets jupyter_core nbformat entrypoints b ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/nbformat/dependencies b/build/pkgs/nbformat/dependencies index c6dc6e3aed4..252d9165ae1 100644 --- a/build/pkgs/nbformat/dependencies +++ b/build/pkgs/nbformat/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) jsonschema ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/ncurses/dependencies b/build/pkgs/ncurses/dependencies index 3546cda4614..4f00de20375 100644 --- a/build/pkgs/ncurses/dependencies +++ b/build/pkgs/ncurses/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/networkx/dependencies b/build/pkgs/networkx/dependencies index f26477f0d95..8eb6920e25d 100644 --- a/build/pkgs/networkx/dependencies +++ b/build/pkgs/networkx/dependencies @@ -2,4 +2,3 @@ $(PYTHON) decorator | $(PYTHON_TOOLCHAIN) scipy ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/ninja_build/dependencies b/build/pkgs/ninja_build/dependencies index 1a36cc52351..6b134137610 100644 --- a/build/pkgs/ninja_build/dependencies +++ b/build/pkgs/ninja_build/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/nodeenv/dependencies b/build/pkgs/nodeenv/dependencies index dc5a209df7b..16df46f57ee 100644 --- a/build/pkgs/nodeenv/dependencies +++ b/build/pkgs/nodeenv/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) certifi ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/nodejs/dependencies b/build/pkgs/nodejs/dependencies index 943a10ee5f5..a8de0ed1559 100644 --- a/build/pkgs/nodejs/dependencies +++ b/build/pkgs/nodejs/dependencies @@ -2,4 +2,3 @@ nodeenv ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/normaliz/dependencies b/build/pkgs/normaliz/dependencies index 66f3b59c2d2..a809da4b16d 100644 --- a/build/pkgs/normaliz/dependencies +++ b/build/pkgs/normaliz/dependencies @@ -2,4 +2,3 @@ $(MP_LIBRARY) flint e_antic libnauty ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/notebook/dependencies b/build/pkgs/notebook/dependencies index ba4f335e19a..9f5cb330ae2 100644 --- a/build/pkgs/notebook/dependencies +++ b/build/pkgs/notebook/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) ipython jupyter_client ipykernel nbconvert nbfor ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/notedown/dependencies b/build/pkgs/notedown/dependencies index 229a2ffe418..ea77eefc7f4 100644 --- a/build/pkgs/notedown/dependencies +++ b/build/pkgs/notedown/dependencies @@ -2,4 +2,3 @@ $(PYTHON) $(PYTHON_TOOLCHAIN) | pip nbformat nbconvert six pandoc_attributes ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/ntl/dependencies b/build/pkgs/ntl/dependencies index e675d884464..c447688066a 100644 --- a/build/pkgs/ntl/dependencies +++ b/build/pkgs/ntl/dependencies @@ -2,4 +2,3 @@ $(MP_LIBRARY) gf2x ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/numpy/dependencies b/build/pkgs/numpy/dependencies index f46820d1797..d3c0f0055e4 100644 --- a/build/pkgs/numpy/dependencies +++ b/build/pkgs/numpy/dependencies @@ -2,4 +2,3 @@ $(PYTHON) $(BLAS) gfortran | $(PYTHON_TOOLCHAIN) pkgconfig cython ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/openblas/dependencies b/build/pkgs/openblas/dependencies index 46757bc2b61..a475340050b 100644 --- a/build/pkgs/openblas/dependencies +++ b/build/pkgs/openblas/dependencies @@ -2,4 +2,3 @@ gfortran | $(PYTHON) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/openssl/dependencies b/build/pkgs/openssl/dependencies index 3546cda4614..4f00de20375 100644 --- a/build/pkgs/openssl/dependencies +++ b/build/pkgs/openssl/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/ore_algebra/dependencies b/build/pkgs/ore_algebra/dependencies index fef6fe44862..05ba0d8954b 100644 --- a/build/pkgs/ore_algebra/dependencies +++ b/build/pkgs/ore_algebra/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) $(SAGERUNTIME) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/packaging/dependencies b/build/pkgs/packaging/dependencies index 2c5e2481b17..2323f9df04a 100644 --- a/build/pkgs/packaging/dependencies +++ b/build/pkgs/packaging/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | setuptools pip wheel pyparsing setuptools_wheel ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/pandoc_attributes/dependencies b/build/pkgs/pandoc_attributes/dependencies index 30b8148c07f..64f88253c78 100644 --- a/build/pkgs/pandoc_attributes/dependencies +++ b/build/pkgs/pandoc_attributes/dependencies @@ -2,4 +2,3 @@ $(PYTHON) $(PYTHON_TOOLCHAIN) | pip pandocfilters ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/pandocfilters/dependencies b/build/pkgs/pandocfilters/dependencies index 15df0c4d6d8..0738c2d7777 100644 --- a/build/pkgs/pandocfilters/dependencies +++ b/build/pkgs/pandocfilters/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/pari/dependencies b/build/pkgs/pari/dependencies index 06ef082e690..c8379ce537b 100644 --- a/build/pkgs/pari/dependencies +++ b/build/pkgs/pari/dependencies @@ -2,4 +2,3 @@ readline $(MP_LIBRARY) | pari_galdata pari_seadata_small ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/pari_elldata/dependencies b/build/pkgs/pari_elldata/dependencies index 3546cda4614..4f00de20375 100644 --- a/build/pkgs/pari_elldata/dependencies +++ b/build/pkgs/pari_elldata/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/pari_galdata/dependencies b/build/pkgs/pari_galdata/dependencies index 3546cda4614..4f00de20375 100644 --- a/build/pkgs/pari_galdata/dependencies +++ b/build/pkgs/pari_galdata/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/pari_galpol/dependencies b/build/pkgs/pari_galpol/dependencies index 3546cda4614..4f00de20375 100644 --- a/build/pkgs/pari_galpol/dependencies +++ b/build/pkgs/pari_galpol/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/pari_nftables/dependencies b/build/pkgs/pari_nftables/dependencies index 3546cda4614..4f00de20375 100644 --- a/build/pkgs/pari_nftables/dependencies +++ b/build/pkgs/pari_nftables/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/pari_seadata/dependencies b/build/pkgs/pari_seadata/dependencies index 3546cda4614..4f00de20375 100644 --- a/build/pkgs/pari_seadata/dependencies +++ b/build/pkgs/pari_seadata/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/pari_seadata_small/dependencies b/build/pkgs/pari_seadata_small/dependencies index 3546cda4614..4f00de20375 100644 --- a/build/pkgs/pari_seadata_small/dependencies +++ b/build/pkgs/pari_seadata_small/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/parso/dependencies b/build/pkgs/parso/dependencies index 15df0c4d6d8..0738c2d7777 100644 --- a/build/pkgs/parso/dependencies +++ b/build/pkgs/parso/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/patch/dependencies b/build/pkgs/patch/dependencies index 3546cda4614..4f00de20375 100644 --- a/build/pkgs/patch/dependencies +++ b/build/pkgs/patch/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/pcre/dependencies b/build/pkgs/pcre/dependencies index 0dd12df6ad1..1ccba14e349 100644 --- a/build/pkgs/pcre/dependencies +++ b/build/pkgs/pcre/dependencies @@ -2,4 +2,3 @@ bzip2 ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/perl_term_readline_gnu/dependencies b/build/pkgs/perl_term_readline_gnu/dependencies index 6a04d4dc1ff..7d283a67703 100644 --- a/build/pkgs/perl_term_readline_gnu/dependencies +++ b/build/pkgs/perl_term_readline_gnu/dependencies @@ -2,4 +2,3 @@ readline ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/pexpect/dependencies b/build/pkgs/pexpect/dependencies index c320fcc874e..4a942502496 100644 --- a/build/pkgs/pexpect/dependencies +++ b/build/pkgs/pexpect/dependencies @@ -2,4 +2,3 @@ $(PYTHON) ptyprocess | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/pickleshare/dependencies b/build/pkgs/pickleshare/dependencies index 15df0c4d6d8..0738c2d7777 100644 --- a/build/pkgs/pickleshare/dependencies +++ b/build/pkgs/pickleshare/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/pillow/dependencies b/build/pkgs/pillow/dependencies index 48498b499f5..2ece64e58e8 100644 --- a/build/pkgs/pillow/dependencies +++ b/build/pkgs/pillow/dependencies @@ -2,4 +2,3 @@ $(PYTHON) zlib freetype | $(PYTHON_TOOLCHAIN) pkgconf ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/pip/dependencies b/build/pkgs/pip/dependencies index 6f2aa240c02..618d627629a 100644 --- a/build/pkgs/pip/dependencies +++ b/build/pkgs/pip/dependencies @@ -2,4 +2,3 @@ $(PYTHON) setuptools wheel ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/pkgconf/dependencies b/build/pkgs/pkgconf/dependencies index 5b535343f8d..47088a97fec 100644 --- a/build/pkgs/pkgconf/dependencies +++ b/build/pkgs/pkgconf/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/pkgconfig/dependencies b/build/pkgs/pkgconfig/dependencies index 628b27750cd..79554fc438d 100644 --- a/build/pkgs/pkgconfig/dependencies +++ b/build/pkgs/pkgconfig/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) pkgconf ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/planarity/dependencies b/build/pkgs/planarity/dependencies index 3546cda4614..4f00de20375 100644 --- a/build/pkgs/planarity/dependencies +++ b/build/pkgs/planarity/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/plantri/dependencies b/build/pkgs/plantri/dependencies index 3546cda4614..4f00de20375 100644 --- a/build/pkgs/plantri/dependencies +++ b/build/pkgs/plantri/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/polylib/dependencies b/build/pkgs/polylib/dependencies index 2a23f3894a5..385df4faa7d 100644 --- a/build/pkgs/polylib/dependencies +++ b/build/pkgs/polylib/dependencies @@ -2,4 +2,3 @@ $(MP_LIBRARY) mpfr ntl ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/polytopes_db/dependencies b/build/pkgs/polytopes_db/dependencies index 3546cda4614..4f00de20375 100644 --- a/build/pkgs/polytopes_db/dependencies +++ b/build/pkgs/polytopes_db/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/ppl/dependencies b/build/pkgs/ppl/dependencies index e9c206ff16e..7af120e99c2 100644 --- a/build/pkgs/ppl/dependencies +++ b/build/pkgs/ppl/dependencies @@ -2,4 +2,3 @@ $(MP_LIBRARY) glpk ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/prometheus_client/dependencies b/build/pkgs/prometheus_client/dependencies index 15df0c4d6d8..0738c2d7777 100644 --- a/build/pkgs/prometheus_client/dependencies +++ b/build/pkgs/prometheus_client/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/prompt_toolkit/dependencies b/build/pkgs/prompt_toolkit/dependencies index 35259ef6b78..57465daf937 100644 --- a/build/pkgs/prompt_toolkit/dependencies +++ b/build/pkgs/prompt_toolkit/dependencies @@ -2,4 +2,3 @@ $(PYTHON) six wcwidth | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/ptyprocess/dependencies b/build/pkgs/ptyprocess/dependencies index 15df0c4d6d8..0738c2d7777 100644 --- a/build/pkgs/ptyprocess/dependencies +++ b/build/pkgs/ptyprocess/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/pycosat/dependencies b/build/pkgs/pycosat/dependencies index 15df0c4d6d8..0738c2d7777 100644 --- a/build/pkgs/pycosat/dependencies +++ b/build/pkgs/pycosat/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/pycparser/dependencies b/build/pkgs/pycparser/dependencies index 15df0c4d6d8..0738c2d7777 100644 --- a/build/pkgs/pycparser/dependencies +++ b/build/pkgs/pycparser/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/pycryptosat/dependencies b/build/pkgs/pycryptosat/dependencies index 8b5414a59d4..b897ff72eae 100644 --- a/build/pkgs/pycryptosat/dependencies +++ b/build/pkgs/pycryptosat/dependencies @@ -2,4 +2,3 @@ $(PYTHON) m4ri zlib libpng cryptominisat | cmake boost_cropped $(PYTHON_TOOLCHAI ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/pycygwin/dependencies b/build/pkgs/pycygwin/dependencies index d3dac75e5f2..296a2bebad3 100644 --- a/build/pkgs/pycygwin/dependencies +++ b/build/pkgs/pycygwin/dependencies @@ -2,4 +2,3 @@ $(PYTHON) cython | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/pygments/dependencies b/build/pkgs/pygments/dependencies index 15df0c4d6d8..0738c2d7777 100644 --- a/build/pkgs/pygments/dependencies +++ b/build/pkgs/pygments/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/pynormaliz/dependencies b/build/pkgs/pynormaliz/dependencies index 40184a0cf5d..76200c19d23 100644 --- a/build/pkgs/pynormaliz/dependencies +++ b/build/pkgs/pynormaliz/dependencies @@ -2,4 +2,3 @@ $(PYTHON) normaliz | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/pyparsing/dependencies b/build/pkgs/pyparsing/dependencies index 3614951f5cb..d6e348e95b9 100644 --- a/build/pkgs/pyparsing/dependencies +++ b/build/pkgs/pyparsing/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | setuptools pip wheel ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/pyrsistent/dependencies b/build/pkgs/pyrsistent/dependencies index 8b3637a0a0e..4361e46ddaf 100644 --- a/build/pkgs/pyrsistent/dependencies +++ b/build/pkgs/pyrsistent/dependencies @@ -2,4 +2,3 @@ $(PYTHON) vcversioner | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/python3/dependencies b/build/pkgs/python3/dependencies index 0b9e91a711c..9bdcf05edc4 100644 --- a/build/pkgs/python3/dependencies +++ b/build/pkgs/python3/dependencies @@ -2,4 +2,3 @@ zlib readline sqlite libpng bzip2 liblzma xz libffi openssl ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/python_igraph/dependencies b/build/pkgs/python_igraph/dependencies index d76acadd7e6..67ed15160f4 100644 --- a/build/pkgs/python_igraph/dependencies +++ b/build/pkgs/python_igraph/dependencies @@ -2,4 +2,3 @@ igraph texttable $(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/pytz/dependencies b/build/pkgs/pytz/dependencies index 15df0c4d6d8..0738c2d7777 100644 --- a/build/pkgs/pytz/dependencies +++ b/build/pkgs/pytz/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/pyzmq/dependencies b/build/pkgs/pyzmq/dependencies index ab148841d34..c72b3d23340 100644 --- a/build/pkgs/pyzmq/dependencies +++ b/build/pkgs/pyzmq/dependencies @@ -2,4 +2,3 @@ $(PYTHON) cython zeromq | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/qepcad/dependencies b/build/pkgs/qepcad/dependencies index c12d9eb11b8..8e67112f53d 100644 --- a/build/pkgs/qepcad/dependencies +++ b/build/pkgs/qepcad/dependencies @@ -2,4 +2,3 @@ readline saclib ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/install into SAGE_ROOT/build/Makefile. diff --git a/build/pkgs/qhull/dependencies b/build/pkgs/qhull/dependencies index 66d6773d907..c225c495cc6 100644 --- a/build/pkgs/qhull/dependencies +++ b/build/pkgs/qhull/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/r/dependencies b/build/pkgs/r/dependencies index 281dc007225..c34daf966bd 100644 --- a/build/pkgs/r/dependencies +++ b/build/pkgs/r/dependencies @@ -2,4 +2,3 @@ $(BLAS) gfortran iconv readline bzip2 liblzma pcre curl | pkgconf ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/readline/dependencies b/build/pkgs/readline/dependencies index c3aa1a2cd99..7d1ee88ab32 100644 --- a/build/pkgs/readline/dependencies +++ b/build/pkgs/readline/dependencies @@ -2,4 +2,3 @@ ncurses ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/requests/dependencies b/build/pkgs/requests/dependencies index b1bee0c4176..b896dbc3cac 100644 --- a/build/pkgs/requests/dependencies +++ b/build/pkgs/requests/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) idna urllib3 certifi charset_normalizer ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/rst2ipynb/dependencies b/build/pkgs/rst2ipynb/dependencies index 4cf206f037d..7fcda2181e1 100644 --- a/build/pkgs/rst2ipynb/dependencies +++ b/build/pkgs/rst2ipynb/dependencies @@ -2,4 +2,3 @@ $(PYTHON) pandoc | $(PYTHON_TOOLCHAIN) notedown ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/rubiks/dependencies b/build/pkgs/rubiks/dependencies index 3546cda4614..4f00de20375 100644 --- a/build/pkgs/rubiks/dependencies +++ b/build/pkgs/rubiks/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/rw/dependencies b/build/pkgs/rw/dependencies index 3546cda4614..4f00de20375 100644 --- a/build/pkgs/rw/dependencies +++ b/build/pkgs/rw/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/saclib/dependencies b/build/pkgs/saclib/dependencies index 3546cda4614..4f00de20375 100644 --- a/build/pkgs/saclib/dependencies +++ b/build/pkgs/saclib/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/sage_numerical_backends_coin/dependencies b/build/pkgs/sage_numerical_backends_coin/dependencies index 2717db3a34f..4cbde1164f2 100644 --- a/build/pkgs/sage_numerical_backends_coin/dependencies +++ b/build/pkgs/sage_numerical_backends_coin/dependencies @@ -2,4 +2,3 @@ cbc cysignals $(SAGE_SRC)/sage/numerical/backends/generic_backend.pxd $(SAGE_SRC ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/sage_numerical_backends_cplex/dependencies b/build/pkgs/sage_numerical_backends_cplex/dependencies index bb56aad17be..0b35afa3540 100644 --- a/build/pkgs/sage_numerical_backends_cplex/dependencies +++ b/build/pkgs/sage_numerical_backends_cplex/dependencies @@ -2,4 +2,3 @@ cysignals $(SAGE_SRC)/sage/numerical/backends/generic_backend.pxd $(SAGE_SRC)/sa ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/sage_numerical_backends_gurobi/dependencies b/build/pkgs/sage_numerical_backends_gurobi/dependencies index bb56aad17be..0b35afa3540 100644 --- a/build/pkgs/sage_numerical_backends_gurobi/dependencies +++ b/build/pkgs/sage_numerical_backends_gurobi/dependencies @@ -2,4 +2,3 @@ cysignals $(SAGE_SRC)/sage/numerical/backends/generic_backend.pxd $(SAGE_SRC)/sa ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/sage_setup/dependencies b/build/pkgs/sage_setup/dependencies index d99d4aed55e..126a1206427 100644 --- a/build/pkgs/sage_setup/dependencies +++ b/build/pkgs/sage_setup/dependencies @@ -2,4 +2,3 @@ $(PYTHON) cython pkgconfig $(SAGE_ROOT)/pkgs/sage-setup/sage_setup/autogen/inter ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/sagelib/dependencies b/build/pkgs/sagelib/dependencies index c7b1154bf20..810713712ed 100644 --- a/build/pkgs/sagelib/dependencies +++ b/build/pkgs/sagelib/dependencies @@ -2,7 +2,6 @@ FORCE $(SCRIPTS) arb boost_cropped $(BLAS) brial cliquer cypari cysignals cython ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. The above are the *build-time* dependencies of the Sage library. These are, on the one hand, programs needed for the build/install process of the diff --git a/build/pkgs/sagenb_export/dependencies b/build/pkgs/sagenb_export/dependencies index bad566f78a7..26033350f88 100644 --- a/build/pkgs/sagenb_export/dependencies +++ b/build/pkgs/sagenb_export/dependencies @@ -2,4 +2,3 @@ $(PYTHON) notebook nbconvert ipython six | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/scipoptsuite/dependencies b/build/pkgs/scipoptsuite/dependencies index 46cb93de623..dfc5ec2e844 100644 --- a/build/pkgs/scipoptsuite/dependencies +++ b/build/pkgs/scipoptsuite/dependencies @@ -2,4 +2,3 @@ $(MP_LIBRARY) bliss readline | cmake ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/scipy/dependencies b/build/pkgs/scipy/dependencies index 25ae8854c01..5cd74c1c23a 100644 --- a/build/pkgs/scipy/dependencies +++ b/build/pkgs/scipy/dependencies @@ -2,4 +2,3 @@ $(PYTHON) $(BLAS) gfortran numpy pybind11 pythran | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/setuptools/dependencies b/build/pkgs/setuptools/dependencies index 304d0c987a2..1700e743d59 100644 --- a/build/pkgs/setuptools/dependencies +++ b/build/pkgs/setuptools/dependencies @@ -2,4 +2,3 @@ $(PYTHON) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/setuptools_scm/dependencies b/build/pkgs/setuptools_scm/dependencies index 22810d06619..1e7026365f0 100644 --- a/build/pkgs/setuptools_scm/dependencies +++ b/build/pkgs/setuptools_scm/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | setuptools pip wheel tomli packaging ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/setuptools_wheel/dependencies b/build/pkgs/setuptools_wheel/dependencies index 6f2aa240c02..618d627629a 100644 --- a/build/pkgs/setuptools_wheel/dependencies +++ b/build/pkgs/setuptools_wheel/dependencies @@ -2,4 +2,3 @@ $(PYTHON) setuptools wheel ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/simplegeneric/dependencies b/build/pkgs/simplegeneric/dependencies index 7b38836acd6..703d0ec7ba3 100644 --- a/build/pkgs/simplegeneric/dependencies +++ b/build/pkgs/simplegeneric/dependencies @@ -7,4 +7,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/singular/dependencies b/build/pkgs/singular/dependencies index 01af3373fa6..41222544be2 100644 --- a/build/pkgs/singular/dependencies +++ b/build/pkgs/singular/dependencies @@ -2,4 +2,3 @@ $(MP_LIBRARY) ntl flint readline mpfr cddlib ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/sip/dependencies b/build/pkgs/sip/dependencies index 304d0c987a2..1700e743d59 100644 --- a/build/pkgs/sip/dependencies +++ b/build/pkgs/sip/dependencies @@ -2,4 +2,3 @@ $(PYTHON) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/six/dependencies b/build/pkgs/six/dependencies index 15df0c4d6d8..0738c2d7777 100644 --- a/build/pkgs/six/dependencies +++ b/build/pkgs/six/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/snowballstemmer/dependencies b/build/pkgs/snowballstemmer/dependencies index 15df0c4d6d8..0738c2d7777 100644 --- a/build/pkgs/snowballstemmer/dependencies +++ b/build/pkgs/snowballstemmer/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/sphinx/dependencies b/build/pkgs/sphinx/dependencies index af979e75c97..af580c77d88 100644 --- a/build/pkgs/sphinx/dependencies +++ b/build/pkgs/sphinx/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) docutils jinja2 pygments six snowballstemmer ima ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/sphinxcontrib_applehelp/dependencies b/build/pkgs/sphinxcontrib_applehelp/dependencies index 15df0c4d6d8..0738c2d7777 100644 --- a/build/pkgs/sphinxcontrib_applehelp/dependencies +++ b/build/pkgs/sphinxcontrib_applehelp/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/sphinxcontrib_devhelp/dependencies b/build/pkgs/sphinxcontrib_devhelp/dependencies index 15df0c4d6d8..0738c2d7777 100644 --- a/build/pkgs/sphinxcontrib_devhelp/dependencies +++ b/build/pkgs/sphinxcontrib_devhelp/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/sphinxcontrib_htmlhelp/dependencies b/build/pkgs/sphinxcontrib_htmlhelp/dependencies index 15df0c4d6d8..0738c2d7777 100644 --- a/build/pkgs/sphinxcontrib_htmlhelp/dependencies +++ b/build/pkgs/sphinxcontrib_htmlhelp/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/sphinxcontrib_jsmath/dependencies b/build/pkgs/sphinxcontrib_jsmath/dependencies index 15df0c4d6d8..0738c2d7777 100644 --- a/build/pkgs/sphinxcontrib_jsmath/dependencies +++ b/build/pkgs/sphinxcontrib_jsmath/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/sphinxcontrib_qthelp/dependencies b/build/pkgs/sphinxcontrib_qthelp/dependencies index 15df0c4d6d8..0738c2d7777 100644 --- a/build/pkgs/sphinxcontrib_qthelp/dependencies +++ b/build/pkgs/sphinxcontrib_qthelp/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/sphinxcontrib_serializinghtml/dependencies b/build/pkgs/sphinxcontrib_serializinghtml/dependencies index 15df0c4d6d8..0738c2d7777 100644 --- a/build/pkgs/sphinxcontrib_serializinghtml/dependencies +++ b/build/pkgs/sphinxcontrib_serializinghtml/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/sphinxcontrib_websupport/dependencies b/build/pkgs/sphinxcontrib_websupport/dependencies index 15df0c4d6d8..0738c2d7777 100644 --- a/build/pkgs/sphinxcontrib_websupport/dependencies +++ b/build/pkgs/sphinxcontrib_websupport/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/sqlite/dependencies b/build/pkgs/sqlite/dependencies index 6a04d4dc1ff..7d283a67703 100644 --- a/build/pkgs/sqlite/dependencies +++ b/build/pkgs/sqlite/dependencies @@ -2,4 +2,3 @@ readline ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/surf/dependencies b/build/pkgs/surf/dependencies index 9a77ea16f78..42dc0e9c107 100644 --- a/build/pkgs/surf/dependencies +++ b/build/pkgs/surf/dependencies @@ -2,4 +2,3 @@ $(MP_LIBRARY) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/symengine/dependencies b/build/pkgs/symengine/dependencies index 77248f3a86e..1fc34963eda 100644 --- a/build/pkgs/symengine/dependencies +++ b/build/pkgs/symengine/dependencies @@ -2,4 +2,3 @@ $(MP_LIBRARY) arb ecm flint mpc mpfr | cmake ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/symengine_py/dependencies b/build/pkgs/symengine_py/dependencies index b041a3d5d3a..0b94df79ab9 100644 --- a/build/pkgs/symengine_py/dependencies +++ b/build/pkgs/symengine_py/dependencies @@ -2,4 +2,3 @@ symengine $(PYTHON) | cmake cython $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/symmetrica/dependencies b/build/pkgs/symmetrica/dependencies index 0fef19aa992..606ceeaec80 100644 --- a/build/pkgs/symmetrica/dependencies +++ b/build/pkgs/symmetrica/dependencies @@ -4,4 +4,3 @@ xz is needed for unpacking the tarball when sage-bootstrap-python is ancient ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/sympow/dependencies b/build/pkgs/sympow/dependencies index e78bf13b4a2..948967f0256 100644 --- a/build/pkgs/sympow/dependencies +++ b/build/pkgs/sympow/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/sympy/dependencies b/build/pkgs/sympy/dependencies index c12b8329ca4..24e1585f16e 100644 --- a/build/pkgs/sympy/dependencies +++ b/build/pkgs/sympy/dependencies @@ -2,4 +2,3 @@ $(PYTHON) mpmath | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/tachyon/dependencies b/build/pkgs/tachyon/dependencies index a32404ffb8e..a6ce9ea4411 100644 --- a/build/pkgs/tachyon/dependencies +++ b/build/pkgs/tachyon/dependencies @@ -2,4 +2,3 @@ libpng ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/terminado/dependencies b/build/pkgs/terminado/dependencies index c61d11251e3..e44a0d91033 100644 --- a/build/pkgs/terminado/dependencies +++ b/build/pkgs/terminado/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) ptyprocess tornado ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/testpath/dependencies b/build/pkgs/testpath/dependencies index 15df0c4d6d8..0738c2d7777 100644 --- a/build/pkgs/testpath/dependencies +++ b/build/pkgs/testpath/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/texttable/dependencies b/build/pkgs/texttable/dependencies index 15df0c4d6d8..0738c2d7777 100644 --- a/build/pkgs/texttable/dependencies +++ b/build/pkgs/texttable/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/tides/dependencies b/build/pkgs/tides/dependencies index efb6f50c4b2..1108dc4fb21 100644 --- a/build/pkgs/tides/dependencies +++ b/build/pkgs/tides/dependencies @@ -2,4 +2,3 @@ $(MP_LIBRARY) mpfr ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/topcom/dependencies b/build/pkgs/topcom/dependencies index 7f13f8aa14a..562554f4643 100644 --- a/build/pkgs/topcom/dependencies +++ b/build/pkgs/topcom/dependencies @@ -2,4 +2,3 @@ cddlib ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/tornado/dependencies b/build/pkgs/tornado/dependencies index 7a3a585116d..212c6234efb 100644 --- a/build/pkgs/tornado/dependencies +++ b/build/pkgs/tornado/dependencies @@ -2,4 +2,3 @@ $(PYTHON) certifi | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/tox/dependencies b/build/pkgs/tox/dependencies index a8747364ef2..5a00a282b7d 100644 --- a/build/pkgs/tox/dependencies +++ b/build/pkgs/tox/dependencies @@ -2,4 +2,3 @@ $(PYTHON) packaging six filelock pluggy py toml virtualenv importlib_metadata | ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/traitlets/dependencies b/build/pkgs/traitlets/dependencies index 242140707df..6598a788ccf 100644 --- a/build/pkgs/traitlets/dependencies +++ b/build/pkgs/traitlets/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) ipython_genutils decorator six ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/tzlocal/dependencies b/build/pkgs/tzlocal/dependencies index 15df0c4d6d8..0738c2d7777 100644 --- a/build/pkgs/tzlocal/dependencies +++ b/build/pkgs/tzlocal/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/valgrind/dependencies b/build/pkgs/valgrind/dependencies index 3546cda4614..4f00de20375 100644 --- a/build/pkgs/valgrind/dependencies +++ b/build/pkgs/valgrind/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/vcversioner/dependencies b/build/pkgs/vcversioner/dependencies index 15df0c4d6d8..0738c2d7777 100644 --- a/build/pkgs/vcversioner/dependencies +++ b/build/pkgs/vcversioner/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/wcwidth/dependencies b/build/pkgs/wcwidth/dependencies index 15df0c4d6d8..0738c2d7777 100644 --- a/build/pkgs/wcwidth/dependencies +++ b/build/pkgs/wcwidth/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/webencodings/dependencies b/build/pkgs/webencodings/dependencies index 15df0c4d6d8..0738c2d7777 100644 --- a/build/pkgs/webencodings/dependencies +++ b/build/pkgs/webencodings/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/wheel/dependencies b/build/pkgs/wheel/dependencies index dbe5d796c45..98d3e59447b 100644 --- a/build/pkgs/wheel/dependencies +++ b/build/pkgs/wheel/dependencies @@ -2,4 +2,3 @@ $(PYTHON) setuptools ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/widgetsnbextension/dependencies b/build/pkgs/widgetsnbextension/dependencies index 816ef654fc7..dd63a9f4ef1 100644 --- a/build/pkgs/widgetsnbextension/dependencies +++ b/build/pkgs/widgetsnbextension/dependencies @@ -2,4 +2,3 @@ $(PYTHON) | $(PYTHON_TOOLCHAIN) jupyter_core ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/xz/dependencies b/build/pkgs/xz/dependencies index 3546cda4614..4f00de20375 100644 --- a/build/pkgs/xz/dependencies +++ b/build/pkgs/xz/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/zeromq/dependencies b/build/pkgs/zeromq/dependencies index 3546cda4614..4f00de20375 100644 --- a/build/pkgs/zeromq/dependencies +++ b/build/pkgs/zeromq/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/zipp/dependencies b/build/pkgs/zipp/dependencies index 8b3637a0a0e..4361e46ddaf 100644 --- a/build/pkgs/zipp/dependencies +++ b/build/pkgs/zipp/dependencies @@ -2,4 +2,3 @@ $(PYTHON) vcversioner | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/zlib/dependencies b/build/pkgs/zlib/dependencies index 3546cda4614..4f00de20375 100644 --- a/build/pkgs/zlib/dependencies +++ b/build/pkgs/zlib/dependencies @@ -2,4 +2,3 @@ ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/zn_poly/dependencies b/build/pkgs/zn_poly/dependencies index 9a77ea16f78..42dc0e9c107 100644 --- a/build/pkgs/zn_poly/dependencies +++ b/build/pkgs/zn_poly/dependencies @@ -2,4 +2,3 @@ $(MP_LIBRARY) ---------- All lines of this file are ignored except the first. -It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. From 643fa512abaed8ddbb64d061150f1f9e2eebc3b4 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 14 May 2022 21:51:36 -0700 Subject: [PATCH 424/529] src/doc/en/developer/packaging.rst: Update --- src/doc/en/developer/packaging.rst | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/doc/en/developer/packaging.rst b/src/doc/en/developer/packaging.rst index 501a54c1027..de2552383f5 100644 --- a/src/doc/en/developer/packaging.rst +++ b/src/doc/en/developer/packaging.rst @@ -678,7 +678,6 @@ for ``eclib``: ---------- All lines of this file are ignored except the first. - It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. For Python packages, common dependencies include ``pip``, ``setuptools``, and ``future``. If your package depends on any of @@ -699,7 +698,6 @@ If there are no dependencies, you can use ---------- All lines of this file are ignored except the first. - It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. There are actually two kinds of dependencies: there are normal dependencies and order-only dependencies, which are weaker. The syntax @@ -718,12 +716,22 @@ If there is no ``|``, then all dependencies are normal. dependency (for example, a dependency on pip simply because the ``spkg-install`` file uses pip). + Alternatively, you can put the order-only dependencies in a separate + file ``dependencies_order_only``. + - If A has a **normal dependency** on B, it means additionally that A should be rebuilt every time that B gets updated. This is the most common kind of dependency. A normal dependency is what you need for libraries: if we upgrade NTL, we should rebuild everything which uses NTL. +Some packages are only needed for self-tests of a package (``spkg-check``). +These dependencies should be declared in a separate file ``dependencies_check``. + +Some dependencies are optional in the sense that they are only +a dependency if they are configured to be installed. These dependencies +should be declared in a separate file ``dependencies_optional``. + In order to check that the dependencies of your package are likely correct, the following command should work without errors:: From 36f0affaca91eb15e8ade8e3899a664d69223ef5 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 14 May 2022 23:19:06 -0700 Subject: [PATCH 425/529] build/pkgs/[g-z]*/SPKG.rst: Remove redundant Dependencies sections --- build/pkgs/cysignals/SPKG.rst | 6 ------ build/pkgs/defusedxml/SPKG.rst | 6 ------ build/pkgs/elliptic_curves/SPKG.rst | 5 ----- build/pkgs/frobby/SPKG.rst | 6 ------ build/pkgs/gap/SPKG.rst | 7 ------- build/pkgs/gap3/SPKG.rst | 4 ---- build/pkgs/gc/SPKG.rst | 6 ------ build/pkgs/gf2x/SPKG.rst | 6 ------ build/pkgs/gfortran/SPKG.rst | 9 --------- build/pkgs/glucose/SPKG.rst | 6 ------ build/pkgs/graphs/SPKG.rst | 4 ---- build/pkgs/gsl/SPKG.rst | 14 -------------- build/pkgs/html5lib/SPKG.rst | 4 ---- build/pkgs/iconv/SPKG.rst | 6 ------ build/pkgs/iml/SPKG.rst | 7 ------- build/pkgs/importlib_metadata/SPKG.rst | 4 ---- build/pkgs/jinja2/SPKG.rst | 9 --------- build/pkgs/jsonschema/SPKG.rst | 8 -------- build/pkgs/jupymake/SPKG.rst | 7 ------- build/pkgs/jupyterlab/SPKG.rst | 7 ------- build/pkgs/jupyterlab_widgets/SPKG.rst | 5 ----- build/pkgs/kenzo/SPKG.rst | 4 ---- build/pkgs/libatomic_ops/SPKG.rst | 6 ------ build/pkgs/libgd/SPKG.rst | 8 -------- build/pkgs/libhomfly/SPKG.rst | 4 ---- build/pkgs/liblzma/SPKG.rst | 2 -- build/pkgs/libogg/SPKG.rst | 8 -------- build/pkgs/libpng/SPKG.rst | 8 -------- build/pkgs/libtheora/SPKG.rst | 13 ------------- build/pkgs/lidia/SPKG.rst | 4 ---- build/pkgs/m4ri/SPKG.rst | 6 ------ build/pkgs/markupsafe/SPKG.rst | 4 ---- build/pkgs/mathjax/SPKG.rst | 6 ------ build/pkgs/maxima/SPKG.rst | 6 ------ build/pkgs/mcqd/SPKG.rst | 4 ---- build/pkgs/memory_allocator/SPKG.rst | 4 ---- build/pkgs/mistune/SPKG.rst | 4 ---- build/pkgs/modular_decomposition/SPKG.rst | 9 --------- build/pkgs/mpc/SPKG.rst | 7 ------- build/pkgs/mpfi/SPKG.rst | 5 ----- build/pkgs/mpfr/SPKG.rst | 7 ------- build/pkgs/mpmath/SPKG.rst | 4 ---- build/pkgs/ncurses/SPKG.rst | 6 ------ build/pkgs/ninja_build/SPKG.rst | 4 ---- build/pkgs/nodeenv/SPKG.rst | 4 ---- build/pkgs/nodejs/SPKG.rst | 4 ---- build/pkgs/normaliz/SPKG.rst | 7 ------- build/pkgs/notedown/SPKG.rst | 9 --------- build/pkgs/ntl/SPKG.rst | 7 ------- build/pkgs/numpy/SPKG.rst | 11 ----------- build/pkgs/ore_algebra/SPKG.rst | 5 ----- build/pkgs/pandoc_attributes/SPKG.rst | 8 -------- build/pkgs/pandocfilters/SPKG.rst | 6 ------ build/pkgs/pari_galdata/SPKG.rst | 4 ---- build/pkgs/pari_seadata_small/SPKG.rst | 4 ---- build/pkgs/patch/SPKG.rst | 6 ------ build/pkgs/pcre/SPKG.rst | 6 ------ build/pkgs/perl_term_readline_gnu/SPKG.rst | 4 ---- build/pkgs/pexpect/SPKG.rst | 5 ----- build/pkgs/pillow/SPKG.rst | 4 ---- build/pkgs/pip/SPKG.rst | 5 ----- build/pkgs/pkgconf/SPKG.rst | 6 ------ build/pkgs/planarity/SPKG.rst | 6 ------ build/pkgs/plantri/SPKG.rst | 4 ---- build/pkgs/polylib/SPKG.rst | 4 ---- build/pkgs/polytopes_db/SPKG.rst | 4 ---- build/pkgs/polytopes_db_4d/SPKG.rst | 4 ---- build/pkgs/ptyprocess/SPKG.rst | 4 ---- build/pkgs/pycosat/SPKG.rst | 6 ------ build/pkgs/pygments/SPKG.rst | 6 ------ build/pkgs/pynormaliz/SPKG.rst | 7 ------- build/pkgs/pyparsing/SPKG.rst | 4 ---- build/pkgs/python_igraph/SPKG.rst | 7 ------- build/pkgs/pyzmq/SPKG.rst | 8 -------- build/pkgs/qepcad/SPKG.rst | 7 ------- build/pkgs/readline/SPKG.rst | 6 ------ build/pkgs/rpy2/SPKG.rst | 4 ---- build/pkgs/rst2ipynb/SPKG.rst | 7 ------- build/pkgs/saclib/SPKG.rst | 4 ---- build/pkgs/zlib/SPKG.rst | 6 ------ 80 files changed, 472 deletions(-) diff --git a/build/pkgs/cysignals/SPKG.rst b/build/pkgs/cysignals/SPKG.rst index e866501cb1d..0329da8193b 100644 --- a/build/pkgs/cysignals/SPKG.rst +++ b/build/pkgs/cysignals/SPKG.rst @@ -17,9 +17,3 @@ Upstream Contact https://github.com/sagemath/cysignals -Dependencies ------------- - -- Python -- Cython -- PARI (optional) diff --git a/build/pkgs/defusedxml/SPKG.rst b/build/pkgs/defusedxml/SPKG.rst index 921e3061af6..44d6549a764 100644 --- a/build/pkgs/defusedxml/SPKG.rst +++ b/build/pkgs/defusedxml/SPKG.rst @@ -19,12 +19,6 @@ Upstream Contact https://pypi.org/project/defusedxml/ -Dependencies ------------- - -- pip - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/elliptic_curves/SPKG.rst b/build/pkgs/elliptic_curves/SPKG.rst index e167a6feef1..09c86a5a9e7 100644 --- a/build/pkgs/elliptic_curves/SPKG.rst +++ b/build/pkgs/elliptic_curves/SPKG.rst @@ -28,8 +28,3 @@ ellcurves - Author: William Stein - Email: wstein@gmail.com -Dependencies ------------- - -- sqlite -- python diff --git a/build/pkgs/frobby/SPKG.rst b/build/pkgs/frobby/SPKG.rst index 2586bb06902..eea712a3a9d 100644 --- a/build/pkgs/frobby/SPKG.rst +++ b/build/pkgs/frobby/SPKG.rst @@ -26,12 +26,6 @@ Upstream Contact - https://github.com/Macaulay2/frobby -Dependencies ------------- - -- GMP built with support for C++ - - Special Update/Build instructions --------------------------------- diff --git a/build/pkgs/gap/SPKG.rst b/build/pkgs/gap/SPKG.rst index c28f1881847..2f59f140a01 100644 --- a/build/pkgs/gap/SPKG.rst +++ b/build/pkgs/gap/SPKG.rst @@ -26,13 +26,6 @@ https://www.gap-system.org Mailing list at https://mail.gap-system.org/mailman/listinfo/gap -Dependencies ------------- - -- Readline -- GMP - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/gap3/SPKG.rst b/build/pkgs/gap3/SPKG.rst index bf44d2cd8e5..1152b121bfd 100644 --- a/build/pkgs/gap3/SPKG.rst +++ b/build/pkgs/gap3/SPKG.rst @@ -79,7 +79,3 @@ Patches None -Dependencies ------------- - -None diff --git a/build/pkgs/gc/SPKG.rst b/build/pkgs/gc/SPKG.rst index 3dc62b8f11e..ece6b70d3e6 100644 --- a/build/pkgs/gc/SPKG.rst +++ b/build/pkgs/gc/SPKG.rst @@ -19,12 +19,6 @@ Webpage: http://www.hboehm.info/gc/ Email List: bdwgc@lists.opendylan.org -Dependencies ------------- - -None. - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/gf2x/SPKG.rst b/build/pkgs/gf2x/SPKG.rst index 29e4d5680fe..7f4b11e994f 100644 --- a/build/pkgs/gf2x/SPKG.rst +++ b/build/pkgs/gf2x/SPKG.rst @@ -24,12 +24,6 @@ Upstream Contact - Emmanuel Thomé - Paul Zimmermann -Dependencies ------------- - -- None - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/gfortran/SPKG.rst b/build/pkgs/gfortran/SPKG.rst index d66a7b0f173..1bea5fae5fe 100644 --- a/build/pkgs/gfortran/SPKG.rst +++ b/build/pkgs/gfortran/SPKG.rst @@ -18,15 +18,6 @@ Upstream Contact http://gcc.gnu.org/ -Dependencies ------------- - -- zlib -- GMP -- MPFR -- MPC - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/glucose/SPKG.rst b/build/pkgs/glucose/SPKG.rst index f6f9beb9ca0..1a7ed45fc87 100644 --- a/build/pkgs/glucose/SPKG.rst +++ b/build/pkgs/glucose/SPKG.rst @@ -35,12 +35,6 @@ Upstream Contact Website: http://www.labri.fr/perso/lsimon/glucose/ -Dependencies ------------- - -zlib - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/graphs/SPKG.rst b/build/pkgs/graphs/SPKG.rst index 4a5f9d35ec8..fee55463698 100644 --- a/build/pkgs/graphs/SPKG.rst +++ b/build/pkgs/graphs/SPKG.rst @@ -28,7 +28,3 @@ Upstream Contact available at https://github.com/nathanncohen/strongly_regular_graphs_database. -Dependencies ------------- - -N/A diff --git a/build/pkgs/gsl/SPKG.rst b/build/pkgs/gsl/SPKG.rst index 79d0151784d..fb66a085b10 100644 --- a/build/pkgs/gsl/SPKG.rst +++ b/build/pkgs/gsl/SPKG.rst @@ -42,19 +42,5 @@ GSL mailing lists: releases are made there. -Dependencies ------------- - -- None - GSL does not depend on any other Sage package to compile, link - and pass all of GSL's self-tests. Despite that fact, BLAS is listed - as - a dependency. (It comes with its own CBLAS implementation that is - e.g. - used when running the GSL test suite during installation; however, - the - Sage library only uses it as a fall-back, if e.g. BLAS library is not - present.) - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/html5lib/SPKG.rst b/build/pkgs/html5lib/SPKG.rst index b62607c15d7..c0abaca59f3 100644 --- a/build/pkgs/html5lib/SPKG.rst +++ b/build/pkgs/html5lib/SPKG.rst @@ -17,7 +17,3 @@ Upstream Contact Home Page: https://github.com/html5lib/html5lib-python/issues -Dependencies ------------- - -Python, webencodings, six diff --git a/build/pkgs/iconv/SPKG.rst b/build/pkgs/iconv/SPKG.rst index 2604fddf232..48e0ffe761f 100644 --- a/build/pkgs/iconv/SPKG.rst +++ b/build/pkgs/iconv/SPKG.rst @@ -19,12 +19,6 @@ Upstream Contact - http://www.gnu.org/software/libiconv/ - Bug reports to bug-gnu-libiconv@gnu.org -Dependencies ------------- - -- None for the purposes of Sage, but in general gettext. - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/iml/SPKG.rst b/build/pkgs/iml/SPKG.rst index ffb045c9113..635fe9da032 100644 --- a/build/pkgs/iml/SPKG.rst +++ b/build/pkgs/iml/SPKG.rst @@ -26,13 +26,6 @@ Upstream Contact - Zhuliang Chen z4chen@uwaterloo.ca - Arne Storjohann astorjoh@uwaterloo.ca -Dependencies ------------- - -- GMP -- a BLAS implementation such as openblas - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/importlib_metadata/SPKG.rst b/build/pkgs/importlib_metadata/SPKG.rst index f77ad32a048..d1b490d0082 100644 --- a/build/pkgs/importlib_metadata/SPKG.rst +++ b/build/pkgs/importlib_metadata/SPKG.rst @@ -18,7 +18,3 @@ Upstream Contact Home page: http://importlib-metadata.readthedocs.io/ -Dependencies ------------- - -Python, Setuptools, zipp diff --git a/build/pkgs/jinja2/SPKG.rst b/build/pkgs/jinja2/SPKG.rst index dab1c25cafa..7f962f0343e 100644 --- a/build/pkgs/jinja2/SPKG.rst +++ b/build/pkgs/jinja2/SPKG.rst @@ -25,15 +25,6 @@ Author: Pocoo Team Homepage: http://jinja.pocoo.org/ -Dependencies ------------- - -- Python (>= 2.4) -- setuptools (or distribute) -- Pygments (according to 'spkg/standard/deps') -- docutils (dito, as a note only) - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/jsonschema/SPKG.rst b/build/pkgs/jsonschema/SPKG.rst index c9f40de8258..bf655277b78 100644 --- a/build/pkgs/jsonschema/SPKG.rst +++ b/build/pkgs/jsonschema/SPKG.rst @@ -17,11 +17,3 @@ Upstream Contact Home page: http://github.com/Julian/jsonschema -Dependencies ------------- - -- Python -- Setuptools -- attrs -- importlib_metadata -- pyrsistent diff --git a/build/pkgs/jupymake/SPKG.rst b/build/pkgs/jupymake/SPKG.rst index a6db0f64ab2..d2ee2c8b564 100644 --- a/build/pkgs/jupymake/SPKG.rst +++ b/build/pkgs/jupymake/SPKG.rst @@ -17,12 +17,5 @@ Upstream Contact https://github.com/polymake/JuPyMake -Dependencies ------------- - -- pip -- polymake - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/jupyterlab/SPKG.rst b/build/pkgs/jupyterlab/SPKG.rst index 3be24988c86..f728314ffae 100644 --- a/build/pkgs/jupyterlab/SPKG.rst +++ b/build/pkgs/jupyterlab/SPKG.rst @@ -17,10 +17,3 @@ Upstream Contact Home page: https://jupyter.org/ -Dependencies ------------- - -- Python -- Setuptools -- jupyter_core -- jupyter_client diff --git a/build/pkgs/jupyterlab_widgets/SPKG.rst b/build/pkgs/jupyterlab_widgets/SPKG.rst index 34913ab51b6..f17f3c08eda 100644 --- a/build/pkgs/jupyterlab_widgets/SPKG.rst +++ b/build/pkgs/jupyterlab_widgets/SPKG.rst @@ -16,8 +16,3 @@ Upstream Contact Home page: https://github.com/jupyter-widgets/ipywidgets -Dependencies ------------- - -- jupyterlab -- nodejs diff --git a/build/pkgs/kenzo/SPKG.rst b/build/pkgs/kenzo/SPKG.rst index 5d139df545e..9bca611ef82 100644 --- a/build/pkgs/kenzo/SPKG.rst +++ b/build/pkgs/kenzo/SPKG.rst @@ -21,7 +21,3 @@ Upstream Contact - https://github.com/miguelmarco/kenzo/ -Dependencies ------------- - -- ECL (Embedded Common Lisp) diff --git a/build/pkgs/libatomic_ops/SPKG.rst b/build/pkgs/libatomic_ops/SPKG.rst index a4f1c0ce805..5d376f67e91 100644 --- a/build/pkgs/libatomic_ops/SPKG.rst +++ b/build/pkgs/libatomic_ops/SPKG.rst @@ -18,12 +18,6 @@ Upstream Contact - Webpage: http://www.hboehm.info/gc/ - Email List: bdwgc@lists.opendylan.org -Dependencies ------------- - -None. - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/libgd/SPKG.rst b/build/pkgs/libgd/SPKG.rst index 33149d189fc..cade8ea66c7 100644 --- a/build/pkgs/libgd/SPKG.rst +++ b/build/pkgs/libgd/SPKG.rst @@ -25,14 +25,6 @@ Upstream Contact - Pierre Joye (http://blog.thepimp.net) - http://libgd.bitbucket.org/ -Dependencies ------------- - -- libpng -- freetype -- iconv - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/libhomfly/SPKG.rst b/build/pkgs/libhomfly/SPKG.rst index f5c61344a3b..2d349b554ad 100644 --- a/build/pkgs/libhomfly/SPKG.rst +++ b/build/pkgs/libhomfly/SPKG.rst @@ -24,7 +24,3 @@ Upstream Contact Miguel Marco (mmarco@unizar.es) -Dependencies ------------- - -- gc diff --git a/build/pkgs/liblzma/SPKG.rst b/build/pkgs/liblzma/SPKG.rst index 925da031898..373af0a91a2 100644 --- a/build/pkgs/liblzma/SPKG.rst +++ b/build/pkgs/liblzma/SPKG.rst @@ -19,5 +19,3 @@ Upstream Contact http://tukaani.org/xz/ -Dependencies ------------- diff --git a/build/pkgs/libogg/SPKG.rst b/build/pkgs/libogg/SPKG.rst index bf80b9680c6..2db78fcfcf2 100644 --- a/build/pkgs/libogg/SPKG.rst +++ b/build/pkgs/libogg/SPKG.rst @@ -49,14 +49,6 @@ Upstream Contact The Xiph.org mailing lists - see http://lists.xiph.org/mailman/listinfo -Dependencies ------------- - -This spkg provides dependencies for - -- the Sage library - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/libpng/SPKG.rst b/build/pkgs/libpng/SPKG.rst index b4ca40d71a6..414854d2ef1 100644 --- a/build/pkgs/libpng/SPKG.rst +++ b/build/pkgs/libpng/SPKG.rst @@ -28,14 +28,6 @@ https://libpng.sourceforge.io The png mailing lists - see http://www.libpng.org/pub/png/pngmisc.html#lists -Dependencies ------------- - -This spkg depends on: - -- libz - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/libtheora/SPKG.rst b/build/pkgs/libtheora/SPKG.rst index 3a75d68e7fb..0c2c9e1c642 100644 --- a/build/pkgs/libtheora/SPKG.rst +++ b/build/pkgs/libtheora/SPKG.rst @@ -48,19 +48,6 @@ Upstream Contact The Xiph.org mailing lists - see http://lists.xiph.org/mailman/listinfo -Dependencies ------------- - -This spkg depends on - -- libogg -- libpng - -This spkg provides dependencies for - -- the Sage library - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/lidia/SPKG.rst b/build/pkgs/lidia/SPKG.rst index 085cacf4e1f..7be393335db 100644 --- a/build/pkgs/lidia/SPKG.rst +++ b/build/pkgs/lidia/SPKG.rst @@ -26,7 +26,3 @@ Upstream Contact Matthias Köppe, UC Davis, CA, USA -Dependencies ------------- - -GMP. diff --git a/build/pkgs/m4ri/SPKG.rst b/build/pkgs/m4ri/SPKG.rst index 6ecd2218831..d5eb3478af3 100644 --- a/build/pkgs/m4ri/SPKG.rst +++ b/build/pkgs/m4ri/SPKG.rst @@ -20,12 +20,6 @@ Upstream Contact - Email: - Website: https://bitbucket.org/malb/m4ri -Dependencies ------------- - -- libPNG - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/markupsafe/SPKG.rst b/build/pkgs/markupsafe/SPKG.rst index 483b2aca876..907793aab6e 100644 --- a/build/pkgs/markupsafe/SPKG.rst +++ b/build/pkgs/markupsafe/SPKG.rst @@ -17,7 +17,3 @@ Upstream Contact Home page: http://github.com/mitsuhiko/markupsafe -Dependencies ------------- - -Python, setuptools diff --git a/build/pkgs/mathjax/SPKG.rst b/build/pkgs/mathjax/SPKG.rst index e7c0a7edb27..1c8e0ebc8fc 100644 --- a/build/pkgs/mathjax/SPKG.rst +++ b/build/pkgs/mathjax/SPKG.rst @@ -19,12 +19,6 @@ Upstream Contact Home page: https://www.mathjax.org/ -Dependencies ------------- - -None. - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/maxima/SPKG.rst b/build/pkgs/maxima/SPKG.rst index aac4e574185..a96fbf42354 100644 --- a/build/pkgs/maxima/SPKG.rst +++ b/build/pkgs/maxima/SPKG.rst @@ -30,12 +30,6 @@ Upstream Contact - The Maxima mailing list - see http://maxima.sourceforge.net/maximalist.html -Dependencies ------------- - -- ECL (Embedded Common Lisp) - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/mcqd/SPKG.rst b/build/pkgs/mcqd/SPKG.rst index 7e7a2b83b97..17bf4d17fd6 100644 --- a/build/pkgs/mcqd/SPKG.rst +++ b/build/pkgs/mcqd/SPKG.rst @@ -19,7 +19,3 @@ Upstream Contact MCQD is currently being maintained by Janez Konc. https://gitlab.com/janezkonc/mcqd -Dependencies ------------- - -None diff --git a/build/pkgs/memory_allocator/SPKG.rst b/build/pkgs/memory_allocator/SPKG.rst index 2c36e5f1105..e85eaa2eb0e 100644 --- a/build/pkgs/memory_allocator/SPKG.rst +++ b/build/pkgs/memory_allocator/SPKG.rst @@ -20,7 +20,3 @@ Upstream Contact https://github.com/sagemath/memory_allocator -Dependencies ------------- - -- Cython diff --git a/build/pkgs/mistune/SPKG.rst b/build/pkgs/mistune/SPKG.rst index 73c67f71a37..7d08e818625 100644 --- a/build/pkgs/mistune/SPKG.rst +++ b/build/pkgs/mistune/SPKG.rst @@ -17,7 +17,3 @@ Upstream Contact Home Page: https://github.com/lepture/mistune -Dependencies ------------- - -Python, Cython, Pip diff --git a/build/pkgs/modular_decomposition/SPKG.rst b/build/pkgs/modular_decomposition/SPKG.rst index 31c617357c1..543b8ce1b6b 100644 --- a/build/pkgs/modular_decomposition/SPKG.rst +++ b/build/pkgs/modular_decomposition/SPKG.rst @@ -21,12 +21,3 @@ Fabien de Montgolfier http://www.liafa.jussieu.fr/~fm/ -Dependencies ------------- - -None - -Patches -------- - -None diff --git a/build/pkgs/mpc/SPKG.rst b/build/pkgs/mpc/SPKG.rst index f51f4ce4ddb..821daf9f1db 100644 --- a/build/pkgs/mpc/SPKG.rst +++ b/build/pkgs/mpc/SPKG.rst @@ -28,13 +28,6 @@ The MPC team can be contacted via the MPC mailing list: mpc-discuss@lists.gforge.inria.fr -Dependencies ------------- - -- MPIR -- MPFR - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/mpfi/SPKG.rst b/build/pkgs/mpfi/SPKG.rst index 5aa81fc9db9..cb145ca0e2a 100644 --- a/build/pkgs/mpfi/SPKG.rst +++ b/build/pkgs/mpfi/SPKG.rst @@ -38,8 +38,3 @@ The MPFI website is located at http://mpfi.gforge.inria.fr/ The MPFI team can be contacted via the MPFI mailing list: mpfi-users@lists.gforge.inria.fr -Dependencies ------------- - -- GMP -- MPFR diff --git a/build/pkgs/mpfr/SPKG.rst b/build/pkgs/mpfr/SPKG.rst index b5b38b3603d..23b9d9110d1 100644 --- a/build/pkgs/mpfr/SPKG.rst +++ b/build/pkgs/mpfr/SPKG.rst @@ -39,13 +39,6 @@ The MPFR website is located at http://mpfr.org/ The MPFR team can be contacted via the MPFR mailing list: mpfr@loria.fr -Dependencies ------------- - -- GMP/MPIR -- GNU patch - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/mpmath/SPKG.rst b/build/pkgs/mpmath/SPKG.rst index 7ed4d8abe01..279d47a0318 100644 --- a/build/pkgs/mpmath/SPKG.rst +++ b/build/pkgs/mpmath/SPKG.rst @@ -23,7 +23,3 @@ Upstream Contact - http://mpmath.org - Website: https://github.com/fredrik-johansson/mpmath/ -Dependencies ------------- - -- Python diff --git a/build/pkgs/ncurses/SPKG.rst b/build/pkgs/ncurses/SPKG.rst index 208fad87814..7c50871739e 100644 --- a/build/pkgs/ncurses/SPKG.rst +++ b/build/pkgs/ncurses/SPKG.rst @@ -37,12 +37,6 @@ Upstream Contact - bug-ncurses@gnu.org -Dependencies ------------- - -None - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/ninja_build/SPKG.rst b/build/pkgs/ninja_build/SPKG.rst index 90195aa30eb..5eef3722b85 100644 --- a/build/pkgs/ninja_build/SPKG.rst +++ b/build/pkgs/ninja_build/SPKG.rst @@ -17,7 +17,3 @@ Upstream Contact https://ninja-build.org/ -Dependencies ------------- - -None diff --git a/build/pkgs/nodeenv/SPKG.rst b/build/pkgs/nodeenv/SPKG.rst index 43c94e9abf6..397d909f16d 100644 --- a/build/pkgs/nodeenv/SPKG.rst +++ b/build/pkgs/nodeenv/SPKG.rst @@ -19,7 +19,3 @@ Upstream Contact Home page: https://github.com/ekalinin/nodeenv -Dependencies ------------- - -- Python diff --git a/build/pkgs/nodejs/SPKG.rst b/build/pkgs/nodejs/SPKG.rst index 8686b7bf566..1176f4fea3b 100644 --- a/build/pkgs/nodejs/SPKG.rst +++ b/build/pkgs/nodejs/SPKG.rst @@ -18,7 +18,3 @@ Upstream Contact Home page: https://nodejs.org/ -Dependencies ------------- - -- nodeenv diff --git a/build/pkgs/normaliz/SPKG.rst b/build/pkgs/normaliz/SPKG.rst index f43f767e3d0..c2f964bc0f2 100644 --- a/build/pkgs/normaliz/SPKG.rst +++ b/build/pkgs/normaliz/SPKG.rst @@ -25,13 +25,6 @@ Upstream Contact and https://github.com/Normaliz -Dependencies ------------- - -- GMP/MPIR -- boost - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/notedown/SPKG.rst b/build/pkgs/notedown/SPKG.rst index ca460eb925a..54cc022f4d0 100644 --- a/build/pkgs/notedown/SPKG.rst +++ b/build/pkgs/notedown/SPKG.rst @@ -17,12 +17,3 @@ Upstream Contact Author: Aaron O'Leary Home page: https://github.com/aaren/notedown -Dependencies ------------- - -- Python -- setuptools -- nbformat -- nbconvert -- six -- pandoc_attributes diff --git a/build/pkgs/ntl/SPKG.rst b/build/pkgs/ntl/SPKG.rst index 0641f7317fb..31c1844d655 100644 --- a/build/pkgs/ntl/SPKG.rst +++ b/build/pkgs/ntl/SPKG.rst @@ -22,13 +22,6 @@ Upstream Contact - Victor Shoup - for contact info see http://www.shoup.net/ -Dependencies ------------- - -- gmp -- gf2x - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/numpy/SPKG.rst b/build/pkgs/numpy/SPKG.rst index 776121ca731..80279977bed 100644 --- a/build/pkgs/numpy/SPKG.rst +++ b/build/pkgs/numpy/SPKG.rst @@ -16,17 +16,6 @@ Upstream Contact - Fernando Perez - Brian Granger -Dependencies ------------- - -- GNU patch -- Python -- Lapack -- Blas -- Atlas -- Fortran - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/ore_algebra/SPKG.rst b/build/pkgs/ore_algebra/SPKG.rst index 94044a54a65..5bb799bfe5b 100644 --- a/build/pkgs/ore_algebra/SPKG.rst +++ b/build/pkgs/ore_algebra/SPKG.rst @@ -26,8 +26,3 @@ Upstream Contact - Website: https://github.com/mkauers/ore_algebra/ - Sage accounts: mkauers, mmezzarobba -Dependencies ------------- - -- None - diff --git a/build/pkgs/pandoc_attributes/SPKG.rst b/build/pkgs/pandoc_attributes/SPKG.rst index c563b04365b..91b60e01b9d 100644 --- a/build/pkgs/pandoc_attributes/SPKG.rst +++ b/build/pkgs/pandoc_attributes/SPKG.rst @@ -19,14 +19,6 @@ Upstream Contact - Author: Aaron O'Leary - Home page: https://github.com/aaren/pandoc-attributes -Dependencies ------------- - -- Python -- setuptools -- pandocfilters - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/pandocfilters/SPKG.rst b/build/pkgs/pandocfilters/SPKG.rst index a4b73da9f99..50132ed9be5 100644 --- a/build/pkgs/pandocfilters/SPKG.rst +++ b/build/pkgs/pandocfilters/SPKG.rst @@ -17,12 +17,6 @@ Upstream Contact Author: John MacFarlane Home page: https://github.com/jgm/pandocfilters -Dependencies ------------- - -- Python - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/pari_galdata/SPKG.rst b/build/pkgs/pari_galdata/SPKG.rst index 16a0c583200..099d9f87153 100644 --- a/build/pkgs/pari_galdata/SPKG.rst +++ b/build/pkgs/pari_galdata/SPKG.rst @@ -18,7 +18,3 @@ Upstream Contact http://pari.math.u-bordeaux.fr/ -Dependencies ------------- - -None (package contains data files only) diff --git a/build/pkgs/pari_seadata_small/SPKG.rst b/build/pkgs/pari_seadata_small/SPKG.rst index 6be2f5d5fd8..3aaa0917ab8 100644 --- a/build/pkgs/pari_seadata_small/SPKG.rst +++ b/build/pkgs/pari_seadata_small/SPKG.rst @@ -20,7 +20,3 @@ Upstream Contact http://pari.math.u-bordeaux.fr/ -Dependencies ------------- - -None (package contains data files only) diff --git a/build/pkgs/patch/SPKG.rst b/build/pkgs/patch/SPKG.rst index e7719fd6255..495c817cd28 100644 --- a/build/pkgs/patch/SPKG.rst +++ b/build/pkgs/patch/SPKG.rst @@ -32,12 +32,6 @@ Submit bugs: http://savannah.gnu.org/bugs/?func=additem&group=patch Mailing lists: bug-patch@gnu.org -Dependencies ------------- - -None - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/pcre/SPKG.rst b/build/pkgs/pcre/SPKG.rst index 55cbfbdbbfa..d1839c2c1df 100644 --- a/build/pkgs/pcre/SPKG.rst +++ b/build/pkgs/pcre/SPKG.rst @@ -17,12 +17,6 @@ Upstream Contact Mailing list at https://lists.exim.org/mailman/listinfo/pcre-dev -Dependencies ------------- - -None listed. - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/perl_term_readline_gnu/SPKG.rst b/build/pkgs/perl_term_readline_gnu/SPKG.rst index 402397926b1..aa2a0791d79 100644 --- a/build/pkgs/perl_term_readline_gnu/SPKG.rst +++ b/build/pkgs/perl_term_readline_gnu/SPKG.rst @@ -19,7 +19,3 @@ Upstream Contact Hiroo HAYASHI -Dependencies ------------- - -readline diff --git a/build/pkgs/pexpect/SPKG.rst b/build/pkgs/pexpect/SPKG.rst index 0c087e38265..b972eecef2f 100644 --- a/build/pkgs/pexpect/SPKG.rst +++ b/build/pkgs/pexpect/SPKG.rst @@ -20,8 +20,3 @@ Upstream Contact - http://pexpect.readthedocs.org/en/stable/ - https://github.com/pexpect/pexpect -Dependencies ------------- - -- GNU patch -- Python diff --git a/build/pkgs/pillow/SPKG.rst b/build/pkgs/pillow/SPKG.rst index 6b64325474e..6a4bd0d09c5 100644 --- a/build/pkgs/pillow/SPKG.rst +++ b/build/pkgs/pillow/SPKG.rst @@ -22,7 +22,3 @@ Upstream Contact - https://python-pillow.org/ - Homepage: http://python-imaging.github.io/ -Dependencies ------------- - -- Python diff --git a/build/pkgs/pip/SPKG.rst b/build/pkgs/pip/SPKG.rst index 55a897a9307..837967428b7 100644 --- a/build/pkgs/pip/SPKG.rst +++ b/build/pkgs/pip/SPKG.rst @@ -24,8 +24,3 @@ Upstream Contact - Mailing list: http://groups.google.com/group/python-virtualenv - Docs: https://pip.pypa.io/ -Dependencies ------------- - -- python -- setuptools diff --git a/build/pkgs/pkgconf/SPKG.rst b/build/pkgs/pkgconf/SPKG.rst index ddf6c227948..64cf2bb4ebf 100644 --- a/build/pkgs/pkgconf/SPKG.rst +++ b/build/pkgs/pkgconf/SPKG.rst @@ -18,12 +18,6 @@ Upstream Contact https://github.com/pkgconf/pkgconf -Dependencies ------------- - -- C compiler + toolchain - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/planarity/SPKG.rst b/build/pkgs/planarity/SPKG.rst index 095ac96e05b..75001aaaf32 100644 --- a/build/pkgs/planarity/SPKG.rst +++ b/build/pkgs/planarity/SPKG.rst @@ -26,12 +26,6 @@ Upstream Contact - John Boyer -Dependencies ------------- - -None - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/plantri/SPKG.rst b/build/pkgs/plantri/SPKG.rst index df6ef00e50c..df3210cec50 100644 --- a/build/pkgs/plantri/SPKG.rst +++ b/build/pkgs/plantri/SPKG.rst @@ -36,7 +36,3 @@ Brendan McKay See http://cs.anu.edu.au/~bdm/plantri -Dependencies ------------- - -- None diff --git a/build/pkgs/polylib/SPKG.rst b/build/pkgs/polylib/SPKG.rst index 89e4508cca6..23e7f1315ba 100644 --- a/build/pkgs/polylib/SPKG.rst +++ b/build/pkgs/polylib/SPKG.rst @@ -18,7 +18,3 @@ Upstream Contact - https://groups.google.com/forum/#!forum/isl-development -Dependencies ------------- - -- GMP diff --git a/build/pkgs/polytopes_db/SPKG.rst b/build/pkgs/polytopes_db/SPKG.rst index 0e43231b7db..b1a26e6e73d 100644 --- a/build/pkgs/polytopes_db/SPKG.rst +++ b/build/pkgs/polytopes_db/SPKG.rst @@ -26,7 +26,3 @@ Upstream Contact http://hep.itp.tuwien.ac.at/~kreuzer/CY/CYpalp.html -Dependencies ------------- - -None diff --git a/build/pkgs/polytopes_db_4d/SPKG.rst b/build/pkgs/polytopes_db_4d/SPKG.rst index 2e5ddcce995..589406d92d1 100644 --- a/build/pkgs/polytopes_db_4d/SPKG.rst +++ b/build/pkgs/polytopes_db_4d/SPKG.rst @@ -20,7 +20,3 @@ SPKG Maintainers Volker Braun -Dependencies ------------- - -None diff --git a/build/pkgs/ptyprocess/SPKG.rst b/build/pkgs/ptyprocess/SPKG.rst index 6cb6d2a5bd7..f72812b852d 100644 --- a/build/pkgs/ptyprocess/SPKG.rst +++ b/build/pkgs/ptyprocess/SPKG.rst @@ -26,7 +26,3 @@ Upstream Contact https://github.com/pexpect/ptyprocess -Dependencies ------------- - -- Python diff --git a/build/pkgs/pycosat/SPKG.rst b/build/pkgs/pycosat/SPKG.rst index dc146802fc4..9853e76a211 100644 --- a/build/pkgs/pycosat/SPKG.rst +++ b/build/pkgs/pycosat/SPKG.rst @@ -23,12 +23,6 @@ Upstream Contact - PicoSAT: http://fmv.jku.at/picosat/ - pycosat: https://github.com/ContinuumIO/pycosat -Dependencies ------------- - -None. - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/pygments/SPKG.rst b/build/pkgs/pygments/SPKG.rst index 7d799b5d090..4a5126cb858 100644 --- a/build/pkgs/pygments/SPKG.rst +++ b/build/pkgs/pygments/SPKG.rst @@ -35,12 +35,6 @@ Upstream Contact - Author: Georg Brandl - Home Page: https://pygments.org -Dependencies ------------- - -Python - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/pynormaliz/SPKG.rst b/build/pkgs/pynormaliz/SPKG.rst index c2dd1c97c3d..0875b81af19 100644 --- a/build/pkgs/pynormaliz/SPKG.rst +++ b/build/pkgs/pynormaliz/SPKG.rst @@ -17,12 +17,5 @@ Upstream Contact https://github.com/sebasguts/PyNormaliz -Dependencies ------------- - -- pip -- normaliz - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/pyparsing/SPKG.rst b/build/pkgs/pyparsing/SPKG.rst index 28bb37a10c6..0b765140901 100644 --- a/build/pkgs/pyparsing/SPKG.rst +++ b/build/pkgs/pyparsing/SPKG.rst @@ -18,7 +18,3 @@ Upstream Contact - Author: Paul McGuire - Home page: http://pyparsing.wikispaces.com -Dependencies ------------- - -Python diff --git a/build/pkgs/python_igraph/SPKG.rst b/build/pkgs/python_igraph/SPKG.rst index b8725f11451..6c3a52a3082 100644 --- a/build/pkgs/python_igraph/SPKG.rst +++ b/build/pkgs/python_igraph/SPKG.rst @@ -19,12 +19,5 @@ Upstream Contact http://igraph.org/python/ -Dependencies ------------- - -- python -- igraph - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/pyzmq/SPKG.rst b/build/pkgs/pyzmq/SPKG.rst index 356af355484..6896f7d256b 100644 --- a/build/pkgs/pyzmq/SPKG.rst +++ b/build/pkgs/pyzmq/SPKG.rst @@ -17,14 +17,6 @@ Upstream Contact http://www.zeromq.org -Dependencies ------------- - -- Python -- Cython -- zeromq - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/qepcad/SPKG.rst b/build/pkgs/qepcad/SPKG.rst index 1ac2993338e..fa8ef06fb7c 100644 --- a/build/pkgs/qepcad/SPKG.rst +++ b/build/pkgs/qepcad/SPKG.rst @@ -35,13 +35,6 @@ Upstream Contact https://www.usna.edu/Users/cs/wcbrown/qepcad/B/QEPCAD.html -Dependencies ------------- - -- readline -- saclib - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/readline/SPKG.rst b/build/pkgs/readline/SPKG.rst index ddf2fe5eb16..80ff0d3ef8f 100644 --- a/build/pkgs/readline/SPKG.rst +++ b/build/pkgs/readline/SPKG.rst @@ -24,12 +24,6 @@ Upstream Contact - Chet Ramey at http://cnswww.cns.cwru.edu/~chet -Dependencies ------------- - -- ncurses - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/rpy2/SPKG.rst b/build/pkgs/rpy2/SPKG.rst index 0eb0b98bda5..a4d119802f1 100644 --- a/build/pkgs/rpy2/SPKG.rst +++ b/build/pkgs/rpy2/SPKG.rst @@ -22,10 +22,6 @@ Upstream Contact - https://rpy2.bitbucket.io -Dependencies ------------- - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/rst2ipynb/SPKG.rst b/build/pkgs/rst2ipynb/SPKG.rst index ac19a2c8557..a514ae5a4c5 100644 --- a/build/pkgs/rst2ipynb/SPKG.rst +++ b/build/pkgs/rst2ipynb/SPKG.rst @@ -23,13 +23,6 @@ Upstream Contact Authors: Scott Sievert and Nicolas M. Thiéry Home page: https://github.com/nthiery/rst-to-ipynb -Dependencies ------------- - -- notedown -- pandoc - - Special Update/Build Instructions --------------------------------- diff --git a/build/pkgs/saclib/SPKG.rst b/build/pkgs/saclib/SPKG.rst index b55460978dd..06a733a7f20 100644 --- a/build/pkgs/saclib/SPKG.rst +++ b/build/pkgs/saclib/SPKG.rst @@ -35,7 +35,3 @@ Upstream Contact https://www.usna.edu/Users/cs/wcbrown/qepcad/B/QEPCAD.html -Dependencies ------------- - -None. diff --git a/build/pkgs/zlib/SPKG.rst b/build/pkgs/zlib/SPKG.rst index d7de9c4038a..5a3496935cf 100644 --- a/build/pkgs/zlib/SPKG.rst +++ b/build/pkgs/zlib/SPKG.rst @@ -18,12 +18,6 @@ Upstream Contact - http://www.zlib.net/ -Dependencies ------------- - -- None - - Special Update/Build Instructions --------------------------------- From d385f0db7500bdc8168e6f7f18d76741efa3742b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 14 May 2022 23:59:05 -0700 Subject: [PATCH 426/529] m4/sage_spkg_collect.m4: Fix for autoconf on ubuntu-focal --- m4/sage_spkg_collect.m4 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/m4/sage_spkg_collect.m4 b/m4/sage_spkg_collect.m4 index c1d33f1073c..c35a21a7efe 100644 --- a/m4/sage_spkg_collect.m4 +++ b/m4/sage_spkg_collect.m4 @@ -333,11 +333,11 @@ AC_DEFUN([SAGE_SPKG_FINALIZE], [dnl AS_VAR_APPEND([DEPS], ['$(findstring '$a',$(OPTIONAL_INSTALLED_PACKAGES)) ']) done ]) - AS_CASE([$DEPS], [*\|*], [], [AS_VAR_APPEND([DEPS], [" |"])]) + AS_CASE(["$DEPS"], [*\|*], [], [AS_VAR_APPEND([DEPS], [" |"])]) AS_IF([test -f "$DIR/dependencies_order_only"], [dnl AS_VAR_APPEND([DEPS], [' '$(echo $(sed 's/^ *//; s/ *#.*//; q' $DIR/dependencies_order_only))]) ], [dnl - m4_case(SPKG_SOURCE, [pip], [AS_VAR_APPEND([DEPS], [' pip'])])dnl + m4_case(SPKG_SOURCE, [pip], [AS_VAR_APPEND([DEPS], [' pip'])], [:])dnl ]) AS_IF([test -f "$DIR/dependencies_check"], [dnl AS_VAR_APPEND([DEPS], [' $(and $(filter-out no,$(SAGE_CHECK_]SPKG_NAME[)), ']) From 3ca0c957536113513db3a8a03049e42821af68a9 Mon Sep 17 00:00:00 2001 From: "Trevor K. Karn" Date: Wed, 11 May 2022 14:30:01 -0500 Subject: [PATCH 427/529] Initial commit --- src/sage/matroids/matroid.pyx | 50 ++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index ef9096fa1d9..3941e6682c9 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -133,6 +133,7 @@ additional functionality (e.g. linear extensions). - Construction - :meth:`union() ` + - :math:`direct_sum() ` - Misc - :meth:`broken_circuit_complex() ` @@ -8011,7 +8012,7 @@ cdef class Matroid(SageObject): OUTPUT: - An instance of MatroidUnion. + An instance of :class:`MatroidUnion `. EXAMPLES:: @@ -8035,3 +8036,50 @@ cdef class Matroid(SageObject): # place this matroid at the beginning of the list matroids.insert(0, self) return union_matroid.MatroidUnion(iter(matroids)) + + def direct_sum(self, matroids): + r""" + Return the matroid direct sum with another matroid or list of + matroids. + + Let `(M_1, M_2, \ldots, M_k)` be a list of matroids where each `M_i` + has ground set `E_i`. The matroid sum `(E_1,I_1),\ldots,(E_n,I_n)` + is a matroid `(E,I)` where `E= \bigsqcup_{i=1}^n E_i` and + `I= \bigsqcup_{i=1}^n I_i`. + + INPUT: + + - ``matroids`` - a matroid or list of matroids + + OUTPUT: + + An instance of :class:`MatroidSum ` + + EXAMPLES:: + + sage: M = matroids.named_matroids.Pappus() + sage: N = matroids.named_matroids.Fano().direct_sum(M); N + Matroid of rank 6 on 16 elements as matroid sum of + Binary matroid of rank 3 on 7 elements, type (3, 0) + Matroid of rank 3 on 9 elements with circuit-closures + {2: {{'a', 'b', 'c'}, {'a', 'e', 'i'}, {'a', 'f', 'h'}, {'b', 'd', 'i'}, {'b', 'f', 'g'}, {'c', 'd', 'h'}, {'c', 'e', 'g'}, {'d', 'e', 'f'}, {'g', 'h', 'i'}}, 3: {{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'}}} + sage: len(N.independent_sets()) + 6897 + sage: len(N.bases()) + 2100 + """ + + from . import union_matroid + if isinstance(matroids, Matroid): + matroids = [matroids] + else: + for M in matroids: + if not isinstance(M, Matroid): + raise TypeError("can only take the sum with a " + "matroid or list of matroids") + matroids = [M for M in matroids if M] + if not matroids: + return self + # place this matroid at the beginning of the list + matroids.insert(0, self) + return union_matroid.MatroidSum(iter(matroids)) From 6b079e412911fd77ce9b636b55ee31d213c7c8c0 Mon Sep 17 00:00:00 2001 From: "Trevor K. Karn" Date: Sun, 15 May 2022 08:45:55 -0500 Subject: [PATCH 428/529] Fix reviewer comments + whitespace issue --- src/sage/matroids/matroid.pyx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index 3941e6682c9..10aa0fc0b74 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -3108,7 +3108,7 @@ cdef class Matroid(SageObject): def matroid_polytope(self): r""" - Return the matroid polytope of ``self``. + src/sage/matroids/matroid.pyx Return the matroid polytope of ``self``. This is defined as the convex hull of the vertices @@ -8044,7 +8044,7 @@ cdef class Matroid(SageObject): Let `(M_1, M_2, \ldots, M_k)` be a list of matroids where each `M_i` has ground set `E_i`. The matroid sum `(E_1,I_1),\ldots,(E_n,I_n)` - is a matroid `(E,I)` where `E= \bigsqcup_{i=1}^n E_i` and + is a matroid `(E,I)` where `E= \bigsqcup_{i=1}^n E_i` and `I= \bigsqcup_{i=1}^n I_i`. INPUT: @@ -8053,13 +8053,14 @@ cdef class Matroid(SageObject): OUTPUT: - An instance of :class:`MatroidSum ` + An instance of + :class:`MatroidSum ` EXAMPLES:: sage: M = matroids.named_matroids.Pappus() sage: N = matroids.named_matroids.Fano().direct_sum(M); N - Matroid of rank 6 on 16 elements as matroid sum of + Matroid of rank 6 on 16 elements as matroid sum of Binary matroid of rank 3 on 7 elements, type (3, 0) Matroid of rank 3 on 9 elements with circuit-closures {2: {{'a', 'b', 'c'}, {'a', 'e', 'i'}, {'a', 'f', 'h'}, {'b', 'd', 'i'}, {'b', 'f', 'g'}, {'c', 'd', 'h'}, {'c', 'e', 'g'}, {'d', 'e', 'f'}, {'g', 'h', 'i'}}, 3: {{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'}}} @@ -8068,7 +8069,6 @@ cdef class Matroid(SageObject): sage: len(N.bases()) 2100 """ - from . import union_matroid if isinstance(matroids, Matroid): matroids = [matroids] From 68acfacafadf5021ebef2417925361ddca624c31 Mon Sep 17 00:00:00 2001 From: "Trevor K. Karn" Date: Sun, 15 May 2022 08:53:15 -0500 Subject: [PATCH 429/529] A reviewer change I missed --- src/sage/matroids/matroid.pyx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index 10aa0fc0b74..fcd626b7378 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -8012,7 +8012,8 @@ cdef class Matroid(SageObject): OUTPUT: - An instance of :class:`MatroidUnion `. + An instance of + :class:`MatroidUnion `. EXAMPLES:: From bf6aeb906d0b7cfb12b5dab90f4f096a6192ff43 Mon Sep 17 00:00:00 2001 From: Release Manager Date: Mon, 16 May 2022 00:11:10 +0200 Subject: [PATCH 430/529] Updated SageMath version to 9.6 --- .zenodo.json | 8 ++++---- VERSION.txt | 2 +- build/pkgs/configure/checksums.ini | 6 +++--- build/pkgs/configure/package-version.txt | 2 +- build/pkgs/sagelib/package-version.txt | 2 +- src/VERSION.txt | 2 +- src/bin/sage-version.sh | 6 +++--- src/sage/version.py | 6 +++--- 8 files changed, 17 insertions(+), 17 deletions(-) diff --git a/.zenodo.json b/.zenodo.json index 89887360497..b4b185cc8f6 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -1,10 +1,10 @@ { "description": "Mirror of the Sage https://sagemath.org/ source tree", "license": "other-open", - "title": "sagemath/sage: 9.6.rc4", - "version": "9.6.rc4", + "title": "sagemath/sage: 9.6", + "version": "9.6", "upload_type": "software", - "publication_date": "2022-05-12", + "publication_date": "2022-05-15", "creators": [ { "affiliation": "SageMath.org", @@ -15,7 +15,7 @@ "related_identifiers": [ { "scheme": "url", - "identifier": "https://github.com/sagemath/sage/tree/9.6.rc4", + "identifier": "https://github.com/sagemath/sage/tree/9.6", "relation": "isSupplementTo" }, { diff --git a/VERSION.txt b/VERSION.txt index dc3ae1ae0ce..3846fccef53 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -SageMath version 9.6.rc4, Release Date: 2022-05-12 +SageMath version 9.6, Release Date: 2022-05-15 diff --git a/build/pkgs/configure/checksums.ini b/build/pkgs/configure/checksums.ini index 6d491dc9d63..cc4571dfdfa 100644 --- a/build/pkgs/configure/checksums.ini +++ b/build/pkgs/configure/checksums.ini @@ -1,4 +1,4 @@ tarball=configure-VERSION.tar.gz -sha1=ebad99b2c419469d2b491a012dc3a4d53a0fc4c0 -md5=f0696455b8ba7dc50b7d23031f52ed19 -cksum=143579459 +sha1=f0ab7c18b3a169fdf7238fe8d70f8bce29373ef4 +md5=37b7220d90d9ec624e126ebb12cc8547 +cksum=3498005086 diff --git a/build/pkgs/configure/package-version.txt b/build/pkgs/configure/package-version.txt index 6d234b474a0..d11b601d525 100644 --- a/build/pkgs/configure/package-version.txt +++ b/build/pkgs/configure/package-version.txt @@ -1 +1 @@ -feb23e71747e42520fe984fa377c7ce5b5af025e +888d18eb851f892097a0a683c01e3a95db863495 diff --git a/build/pkgs/sagelib/package-version.txt b/build/pkgs/sagelib/package-version.txt index 82b75159501..c026ac828d0 100644 --- a/build/pkgs/sagelib/package-version.txt +++ b/build/pkgs/sagelib/package-version.txt @@ -1 +1 @@ -9.6.rc4 +9.6 diff --git a/src/VERSION.txt b/src/VERSION.txt index 82b75159501..c026ac828d0 100644 --- a/src/VERSION.txt +++ b/src/VERSION.txt @@ -1 +1 @@ -9.6.rc4 +9.6 diff --git a/src/bin/sage-version.sh b/src/bin/sage-version.sh index edc4ff086d2..9eb05556679 100644 --- a/src/bin/sage-version.sh +++ b/src/bin/sage-version.sh @@ -1,5 +1,5 @@ # Sage version information for shell scripts # This file is auto-generated by the sage-update-version script, do not edit! -SAGE_VERSION='9.6.rc4' -SAGE_RELEASE_DATE='2022-05-12' -SAGE_VERSION_BANNER='SageMath version 9.6.rc4, Release Date: 2022-05-12' +SAGE_VERSION='9.6' +SAGE_RELEASE_DATE='2022-05-15' +SAGE_VERSION_BANNER='SageMath version 9.6, Release Date: 2022-05-15' diff --git a/src/sage/version.py b/src/sage/version.py index 062dc77315b..f2eba7424d1 100644 --- a/src/sage/version.py +++ b/src/sage/version.py @@ -1,5 +1,5 @@ # Sage version information for Python scripts # This file is auto-generated by the sage-update-version script, do not edit! -version = '9.6.rc4' -date = '2022-05-12' -banner = 'SageMath version 9.6.rc4, Release Date: 2022-05-12' +version = '9.6' +date = '2022-05-15' +banner = 'SageMath version 9.6, Release Date: 2022-05-15' From 6c5903d70aeb330d6667066d5988be35a8a3d3c9 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 15 May 2022 15:14:27 -0700 Subject: [PATCH 431/529] src/sage_setup/command/sage_install.py: Split sage_install_and_clean into several classes --- src/sage_setup/command/sage_install.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/sage_setup/command/sage_install.py b/src/sage_setup/command/sage_install.py index 41a9391c130..65cd69ce700 100644 --- a/src/sage_setup/command/sage_install.py +++ b/src/sage_setup/command/sage_install.py @@ -33,10 +33,10 @@ def install_kernel_spec(self): # the install_data directory for installing our Jupyter files. SageKernelSpec.update(prefix=self.install_data) -class sage_install_and_clean(sage_install): + +class sage_clean(install): def run(self): - sage_install.run(self) t = time.time() self.clean_stale_files() log.info('Finished cleaning, time: %.2f seconds.' % (time.time() - t)) @@ -85,3 +85,9 @@ def clean_stale_files(self): dist.ext_modules, data_files, nobase_data_files) + +class sage_install_and_clean(sage_install, sage_clean): + + def run(self): + sage_install.run(self) + sage_clean.run(self) From 8953d5397487655156f83598dc1e0bc3930992d4 Mon Sep 17 00:00:00 2001 From: Miguel Marco Date: Mon, 16 May 2022 23:28:47 +0200 Subject: [PATCH 432/529] Parallelize action of braids on free group gens --- src/sage/schemes/curves/zariski_vankampen.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/sage/schemes/curves/zariski_vankampen.py b/src/sage/schemes/curves/zariski_vankampen.py index 067d42cd420..de4cc3ebfc5 100644 --- a/src/sage/schemes/curves/zariski_vankampen.py +++ b/src/sage/schemes/curves/zariski_vankampen.py @@ -1021,7 +1021,11 @@ def fundamental_group(f, simplified=True, projective=False): bm = braid_monodromy(f) n = bm[0].parent().strands() F = FreeGroup(n) - R = [x*b/x for x in F.gens() for b in bm] + @parallel + def relation(x,b): + return x*b/x + relations = list(relation([(x,b) for x in F.gens() for b in bm])) + R = [r[1] for r in relations] if projective: R.append(prod(F.gens())) G = F/R From ed4cf4c693602d31966dd63f242186e096eceba4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Bissey?= Date: Tue, 17 May 2022 12:34:58 +1200 Subject: [PATCH 433/529] clean sage/libs/gap/test from MANIFEST.in --- src/MANIFEST.in | 1 - 1 file changed, 1 deletion(-) diff --git a/src/MANIFEST.in b/src/MANIFEST.in index d154d77f3ae..44978cc8c8f 100644 --- a/src/MANIFEST.in +++ b/src/MANIFEST.in @@ -5,6 +5,5 @@ include pyproject.toml prune .tox -graft sage/libs/gap/test prune sage/ext/interpreters # In particular, __init__.py must not be present in the distribution; or sage_setup.autogen.interpreters.rebuild will not generate the code prune sage_setup From 92e9cff98ec286cec725499d61f5b19665896072 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 17 May 2022 19:34:01 -0700 Subject: [PATCH 434/529] build/pkgs/cython: Update to 0.29.30 --- build/pkgs/cython/checksums.ini | 6 +++--- build/pkgs/cython/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/cython/checksums.ini b/build/pkgs/cython/checksums.ini index d246b023155..aa1e82366c5 100644 --- a/build/pkgs/cython/checksums.ini +++ b/build/pkgs/cython/checksums.ini @@ -1,5 +1,5 @@ tarball=Cython-VERSION.tar.gz -sha1=0e85468d2af207c19530648cda271d27d03c6894 -md5=0e98543dca816300a27e7d76146a6280 -cksum=3252194174 +sha1=89c8413689f06c999caf4700fb8bab53ba6f860a +md5=3cf4001b4be42a263f163865235c39d8 +cksum=2022900074 upstream_url=https://pypi.io/packages/source/C/Cython/Cython-VERSION.tar.gz diff --git a/build/pkgs/cython/package-version.txt b/build/pkgs/cython/package-version.txt index fdd3f0e5435..0498a7acb8d 100644 --- a/build/pkgs/cython/package-version.txt +++ b/build/pkgs/cython/package-version.txt @@ -1 +1 @@ -0.29.28 +0.29.30 From 2c86c693760db6423bcfabb2f9241a7d98b9e4b6 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Wed, 18 May 2022 00:36:14 +0800 Subject: [PATCH 435/529] add ._scaling_factor() for .formal()[1] --- .../elliptic_curves/ell_curve_isogeny.py | 26 +++++++++++++++++++ .../schemes/elliptic_curves/hom_composite.py | 19 ++++++++++++++ .../elliptic_curves/weierstrass_morphism.py | 13 ++++++++++ 3 files changed, 58 insertions(+) diff --git a/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py b/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py index 77768439227..3dacb0ba27c 100644 --- a/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py +++ b/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py @@ -2768,6 +2768,32 @@ def x_rational_map(self): self.__initialize_rational_maps() return self.__X_coord_rational_map + def _scaling_factor(self): + r""" + Return ``self.formal()[1]``, but faster. + + EXAMPLES:: + + sage: E = EllipticCurve(GF(257^2), [0,1]) + sage: phi = E.isogeny(E.lift_x(240)) + sage: phi.degree() + 43 + sage: phi._scaling_factor() + 1 + sage: phi.dual()._scaling_factor() + 43 + + ALGORITHM: The "inner" isogeny is normalized by construction, + so we only need to account for the scaling factors of a pre- + and post-isomorphism. + """ + sc = Integer(1) + if self.__pre_isomorphism is not None: + sc *= self.__pre_isomorphism._scaling_factor() + if self.__post_isomorphism is not None: + sc *= self.__post_isomorphism._scaling_factor() + return sc + def kernel_polynomial(self): r""" Return the kernel polynomial of this isogeny. diff --git a/src/sage/schemes/elliptic_curves/hom_composite.py b/src/sage/schemes/elliptic_curves/hom_composite.py index 2098c7d8ee1..beb86bffaf9 100644 --- a/src/sage/schemes/elliptic_curves/hom_composite.py +++ b/src/sage/schemes/elliptic_curves/hom_composite.py @@ -765,6 +765,25 @@ def formal(self, prec=20): res = res(phi.formal(prec=prec)) return res + def _scaling_factor(self): + r""" + Return ``self.formal()[1]``, but faster. + + EXAMPLES:: + + sage: from sage.schemes.elliptic_curves.hom_composite import EllipticCurveHom_composite + sage: from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism + sage: E = EllipticCurve(GF(65537), [1,2,3,4,5]) + sage: P = E.lift_x(7321) + sage: phi = EllipticCurveHom_composite(E, P) + sage: phi = WeierstrassIsomorphism(phi.codomain(), [7,8,9,10]) * phi + sage: phi.formal() + 7*t + 65474*t^2 + 511*t^3 + 61316*t^4 + 20548*t^5 + 45511*t^6 + 37285*t^7 + 48414*t^8 + 9022*t^9 + 24025*t^10 + 35986*t^11 + 55397*t^12 + 25199*t^13 + 18744*t^14 + 46142*t^15 + 9078*t^16 + 18030*t^17 + 47599*t^18 + 12158*t^19 + 50630*t^20 + 56449*t^21 + 43320*t^22 + O(t^23) + sage: phi._scaling_factor() + 7 + """ + return prod(phi._scaling_factor() for phi in self._phis) + def is_injective(self): """ Determine whether this composite morphism has trivial kernel. diff --git a/src/sage/schemes/elliptic_curves/weierstrass_morphism.py b/src/sage/schemes/elliptic_curves/weierstrass_morphism.py index 1927ab10c55..1d4f5f9d419 100644 --- a/src/sage/schemes/elliptic_curves/weierstrass_morphism.py +++ b/src/sage/schemes/elliptic_curves/weierstrass_morphism.py @@ -898,3 +898,16 @@ def __neg__(self): w = baseWI(-1, 0, -a1, -a3) urst = baseWI.__mul__(self, w).tuple() return WeierstrassIsomorphism(self._domain, urst, self._codomain) + + def _scaling_factor(self): + r""" + Return ``self.formal()[1]``, but faster. + + EXAMPLES:: + + sage: E = EllipticCurve(QQbar, [0,1]) + sage: all(f._scaling_factor() == f.formal()[1] for f in E.automorphisms()) + True + """ + return self.u + From 2e88ff0891576391c7c3769da363db5addbf4ca3 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Wed, 18 May 2022 12:15:47 +0800 Subject: [PATCH 436/529] use ._scaling_factor() instead of .formal()[1] --- src/sage/schemes/elliptic_curves/ell_curve_isogeny.py | 4 ++-- src/sage/schemes/elliptic_curves/hom.py | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py b/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py index 3dacb0ba27c..ad8f68a6900 100644 --- a/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py +++ b/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py @@ -3346,7 +3346,7 @@ def dual(self): # trac 7096 # this should take care of the case when the isogeny is not normalized. - u = self.formal(prec=2)[1] + u = self._scaling_factor() isom = WeierstrassIsomorphism(E2pr, (u/F(d), 0, 0, 0)) E2 = isom.codomain() @@ -3369,7 +3369,7 @@ def dual(self): # the composition has the degree as a leading coefficient in # the formal expansion. - phihat_sc = phi_hat.formal(prec=2)[1] + phihat_sc = phi_hat._scaling_factor() sc = u * phihat_sc/F(d) diff --git a/src/sage/schemes/elliptic_curves/hom.py b/src/sage/schemes/elliptic_curves/hom.py index 8133410e365..9ffa4077d2a 100644 --- a/src/sage/schemes/elliptic_curves/hom.py +++ b/src/sage/schemes/elliptic_curves/hom.py @@ -394,8 +394,7 @@ def is_normalized(self): sage: phi.is_normalized() True """ - phi_formal = self.formal(prec=5) - return phi_formal[1] == 1 + return self._scaling_factor() == 1 def is_separable(self): From bd2b79169fe9c139c79f51c363d5e5a7572ee182 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Wed, 18 May 2022 08:11:07 +0200 Subject: [PATCH 437/529] 27522: fix syntax error in meth role --- src/sage/knots/link.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/knots/link.py b/src/sage/knots/link.py index 5769ef7557f..c6680df23c5 100644 --- a/src/sage/knots/link.py +++ b/src/sage/knots/link.py @@ -37,7 +37,7 @@ - Miguel Angel Marco Buzunariz - Amit Jamadagni -- Sebastian Oehms (October 2020, add :meth:`get_knotinfo` and meth:`is_isotopic`) +- Sebastian Oehms (October 2020, add :meth:`get_knotinfo` and :meth:`is_isotopic`) """ # **************************************************************************** From fb571d33bcf0d6631fb3617d425a3ef3696e3321 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Wed, 18 May 2022 22:20:36 +0800 Subject: [PATCH 438/529] turn .scaling_factor() into a public function --- .../elliptic_curves/ell_curve_isogeny.py | 23 +++++++---- src/sage/schemes/elliptic_curves/hom.py | 39 ++++++++++++++++--- .../schemes/elliptic_curves/hom_composite.py | 19 +++++++-- .../elliptic_curves/weierstrass_morphism.py | 16 ++++++-- 4 files changed, 76 insertions(+), 21 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py b/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py index ad8f68a6900..8b74de31935 100644 --- a/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py +++ b/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py @@ -2768,9 +2768,16 @@ def x_rational_map(self): self.__initialize_rational_maps() return self.__X_coord_rational_map - def _scaling_factor(self): + def scaling_factor(self): r""" - Return ``self.formal()[1]``, but faster. + Return the Weierstrass scaling factor associated to this + elliptic-curve isogeny. + + The scaling factor is the constant `u` (in the base field) + such that `\varphi^* \omega_2 = u \omega_1`, where + `\varphi: E_1\to E_2` is this isogeny and `\omega_i` are + the standard Weierstrass differentials on `E_i` defined by + `\mathrm dx/(2y+a_1x+a_3)`. EXAMPLES:: @@ -2778,9 +2785,9 @@ def _scaling_factor(self): sage: phi = E.isogeny(E.lift_x(240)) sage: phi.degree() 43 - sage: phi._scaling_factor() + sage: phi.scaling_factor() 1 - sage: phi.dual()._scaling_factor() + sage: phi.dual().scaling_factor() 43 ALGORITHM: The "inner" isogeny is normalized by construction, @@ -2789,9 +2796,9 @@ def _scaling_factor(self): """ sc = Integer(1) if self.__pre_isomorphism is not None: - sc *= self.__pre_isomorphism._scaling_factor() + sc *= self.__pre_isomorphism.scaling_factor() if self.__post_isomorphism is not None: - sc *= self.__post_isomorphism._scaling_factor() + sc *= self.__post_isomorphism.scaling_factor() return sc def kernel_polynomial(self): @@ -3346,7 +3353,7 @@ def dual(self): # trac 7096 # this should take care of the case when the isogeny is not normalized. - u = self._scaling_factor() + u = self.scaling_factor() isom = WeierstrassIsomorphism(E2pr, (u/F(d), 0, 0, 0)) E2 = isom.codomain() @@ -3369,7 +3376,7 @@ def dual(self): # the composition has the degree as a leading coefficient in # the formal expansion. - phihat_sc = phi_hat._scaling_factor() + phihat_sc = phi_hat.scaling_factor() sc = u * phihat_sc/F(d) diff --git a/src/sage/schemes/elliptic_curves/hom.py b/src/sage/schemes/elliptic_curves/hom.py index 9ffa4077d2a..4ab0210fc61 100644 --- a/src/sage/schemes/elliptic_curves/hom.py +++ b/src/sage/schemes/elliptic_curves/hom.py @@ -266,6 +266,36 @@ def x_rational_map(self): raise NotImplementedError('children must implement') + def scaling_factor(self): + r""" + Return the Weierstrass scaling factor associated to this + elliptic-curve morphism. + + The scaling factor is the constant `u` (in the base field) + such that `\varphi^* \omega_2 = u \omega_1`, where + `\varphi: E_1\to E_2` is this morphism and `\omega_i` are + the standard Weierstrass differentials on `E_i` defined by + `\mathrm dx/(2y+a_1x+a_3)`. + + Implemented by child classes. For examples, see: + + - :meth:`EllipticCurveIsogeny.scaling_factor` + - :meth:`sage.schemes.elliptic_curves.weierstrass_morphism.WeierstrassIsomorphism.scaling_factor` + - :meth:`sage.schemes.elliptic_curves.hom_composite.EllipticCurveHom_composite.scaling_factor` + + TESTS:: + + sage: from sage.schemes.elliptic_curves.hom import EllipticCurveHom + sage: EllipticCurveHom.scaling_factor(None) + Traceback (most recent call last): + ... + NotImplementedError: ... + """ + #TODO: could have a default implementation that simply + # returns .formal()[1], but it seems safer to fail + # visibly to make sure we would notice regressions + raise NotImplementedError('children must implement') + def formal(self, prec=20): r""" Return the formal isogeny associated to this elliptic-curve @@ -326,11 +356,6 @@ def is_normalized(self): `\omega_2` are the invariant differentials on `E_1` and `E_2` corresponding to the given equation. - ALGORITHM: - - The method checks if the leading term of the formal series - associated to this isogeny equals `1`. - EXAMPLES:: sage: from sage.schemes.elliptic_curves.weierstrass_morphism import WeierstrassIsomorphism @@ -393,8 +418,10 @@ def is_normalized(self): sage: phi = isom * phi sage: phi.is_normalized() True + + ALGORITHM: We check if :meth:`scaling_factor` returns `1`. """ - return self._scaling_factor() == 1 + return self.scaling_factor() == 1 def is_separable(self): diff --git a/src/sage/schemes/elliptic_curves/hom_composite.py b/src/sage/schemes/elliptic_curves/hom_composite.py index beb86bffaf9..147d1b3eb5c 100644 --- a/src/sage/schemes/elliptic_curves/hom_composite.py +++ b/src/sage/schemes/elliptic_curves/hom_composite.py @@ -765,9 +765,16 @@ def formal(self, prec=20): res = res(phi.formal(prec=prec)) return res - def _scaling_factor(self): + def scaling_factor(self): r""" - Return ``self.formal()[1]``, but faster. + Return the Weierstrass scaling factor associated to this + composite morphism. + + The scaling factor is the constant `u` (in the base field) + such that `\varphi^* \omega_2 = u \omega_1`, where + `\varphi: E_1\to E_2` is this morphism and `\omega_i` are + the standard Weierstrass differentials on `E_i` defined by + `\mathrm dx/(2y+a_1x+a_3)`. EXAMPLES:: @@ -779,10 +786,14 @@ def _scaling_factor(self): sage: phi = WeierstrassIsomorphism(phi.codomain(), [7,8,9,10]) * phi sage: phi.formal() 7*t + 65474*t^2 + 511*t^3 + 61316*t^4 + 20548*t^5 + 45511*t^6 + 37285*t^7 + 48414*t^8 + 9022*t^9 + 24025*t^10 + 35986*t^11 + 55397*t^12 + 25199*t^13 + 18744*t^14 + 46142*t^15 + 9078*t^16 + 18030*t^17 + 47599*t^18 + 12158*t^19 + 50630*t^20 + 56449*t^21 + 43320*t^22 + O(t^23) - sage: phi._scaling_factor() + sage: phi.scaling_factor() 7 + + ALGORITHM: The scaling factor is multiplicative under + composition, so we return the product of the individual + scaling factors associated to each factor. """ - return prod(phi._scaling_factor() for phi in self._phis) + return prod(phi.scaling_factor() for phi in self._phis) def is_injective(self): """ diff --git a/src/sage/schemes/elliptic_curves/weierstrass_morphism.py b/src/sage/schemes/elliptic_curves/weierstrass_morphism.py index 1d4f5f9d419..47b6255450d 100644 --- a/src/sage/schemes/elliptic_curves/weierstrass_morphism.py +++ b/src/sage/schemes/elliptic_curves/weierstrass_morphism.py @@ -899,15 +899,25 @@ def __neg__(self): urst = baseWI.__mul__(self, w).tuple() return WeierstrassIsomorphism(self._domain, urst, self._codomain) - def _scaling_factor(self): + def scaling_factor(self): r""" - Return ``self.formal()[1]``, but faster. + Return the Weierstrass scaling factor associated to this + Weierstrass isomorphism. + + The scaling factor is the constant `u` (in the base field) + such that `\varphi^* \omega_2 = u \omega_1`, where + `\varphi: E_1\to E_2` is this isomorphism and `\omega_i` are + the standard Weierstrass differentials on `E_i` defined by + `\mathrm dx/(2y+a_1x+a_3)`. EXAMPLES:: sage: E = EllipticCurve(QQbar, [0,1]) - sage: all(f._scaling_factor() == f.formal()[1] for f in E.automorphisms()) + sage: all(f.scaling_factor() == f.formal()[1] for f in E.automorphisms()) True + + ALGORITHM: The scaling factor equals the `u` component of + the tuple `(u,r,s,t)` defining the isomorphism. """ return self.u From 4473375c4a90dcb47c6c459cd9117f1571730bc3 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 18 May 2022 09:53:56 -0700 Subject: [PATCH 439/529] src/sage_setup/command/sage_install.py: Add sage_develop, use it in src/setup.py, pkgs/sagemath-standard/setup.py --- build/pkgs/sage_setup/dependencies | 2 +- pkgs/sagemath-standard/setup.py | 3 ++- src/sage_setup/command/sage_install.py | 21 +++++++++++++++++---- src/setup.py | 5 ++--- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/build/pkgs/sage_setup/dependencies b/build/pkgs/sage_setup/dependencies index d99d4aed55e..3f2349474ac 100644 --- a/build/pkgs/sage_setup/dependencies +++ b/build/pkgs/sage_setup/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) cython pkgconfig $(SAGE_ROOT)/pkgs/sage-setup/sage_setup/autogen/interpreters/specs/*.py | $(PYTHON_TOOLCHAIN) +$(PYTHON) cython pkgconfig $(SAGE_ROOT)/pkgs/sage-setup/sage_setup/autogen/interpreters/specs/*.py $(SAGE_ROOT)/pkgs/sage-setup/sage_setup/command/*.py | $(PYTHON_TOOLCHAIN) ---------- All lines of this file are ignored except the first. diff --git a/pkgs/sagemath-standard/setup.py b/pkgs/sagemath-standard/setup.py index 8d3ed741c3f..7ac2294b609 100755 --- a/pkgs/sagemath-standard/setup.py +++ b/pkgs/sagemath-standard/setup.py @@ -47,11 +47,12 @@ from sage_setup.command.sage_build import sage_build from sage_setup.command.sage_build_cython import sage_build_cython from sage_setup.command.sage_build_ext import sage_build_ext - from sage_setup.command.sage_install import sage_install_and_clean + from sage_setup.command.sage_install import sage_develop, sage_install_and_clean cmdclass = dict(build=sage_build, build_cython=sage_build_cython, build_ext=sage_build_ext, + develop=sage_develop, install=sage_install_and_clean) ######################################################### diff --git a/src/sage_setup/command/sage_install.py b/src/sage_setup/command/sage_install.py index 65cd69ce700..74f580a3091 100644 --- a/src/sage_setup/command/sage_install.py +++ b/src/sage_setup/command/sage_install.py @@ -11,12 +11,10 @@ from distutils import log from distutils.command.install import install +from setuptools.command.develop import develop -class sage_install(install): - def run(self): - install.run(self) - self.install_kernel_spec() +class install_kernel_spec_mixin: def install_kernel_spec(self): """ @@ -34,6 +32,21 @@ def install_kernel_spec(self): SageKernelSpec.update(prefix=self.install_data) +class sage_install(install, install_kernel_spec_mixin): + + def run(self): + install.run(self) + self.install_kernel_spec() + + +class sage_develop(develop, install_kernel_spec_mixin): + + def run(self): + develop.run(self) + if not self.uninstall: + self.install_kernel_spec() + + class sage_clean(install): def run(self): diff --git a/src/setup.py b/src/setup.py index 2e8659d15da..0533fa44096 100755 --- a/src/setup.py +++ b/src/setup.py @@ -6,8 +6,6 @@ ## Distribution packaging should use build/pkgs/sagelib/src/setup.py ## instead. -from __future__ import print_function - import os import platform import sys @@ -23,7 +21,7 @@ from sage.misc.package import is_package_installed_and_updated from sage_setup.command.sage_build_ext_minimal import sage_build_ext_minimal -from sage_setup.command.sage_install import sage_install +from sage_setup.command.sage_install import sage_develop, sage_install from sage_setup.find import filter_cython_sources from sage_setup.cython_options import compiler_directives, compile_time_env_variables from sage_setup.extensions import create_extension @@ -126,6 +124,7 @@ packages=python_packages, cmdclass={ "build_ext": sage_build_ext_minimal, + "develop": sage_develop, "install": sage_install, }, ext_modules=extensions From 6a7848992c68729d8df7b9f9a2b21aa2fe087414 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 18 May 2022 20:58:45 +0200 Subject: [PATCH 440/529] tweak our .lgtm file --- .lgtm.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.lgtm.yml b/.lgtm.yml index fefc94e7010..0650ffa1eee 100644 --- a/.lgtm.yml +++ b/.lgtm.yml @@ -6,6 +6,7 @@ queries: path_classifiers: imports_only: - "**/all.py" + - "**/all_*.py" - "**/*catalog*.py" - "**/species/library.py" - "**/categories/basic.py" From de00a57e22db14240f6b6893d7bf10e87eb17e57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 18 May 2022 22:01:04 +0200 Subject: [PATCH 441/529] some words about lgtm --- src/doc/en/developer/tools.rst | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/doc/en/developer/tools.rst b/src/doc/en/developer/tools.rst index 705ffcd6431..928f75623d2 100644 --- a/src/doc/en/developer/tools.rst +++ b/src/doc/en/developer/tools.rst @@ -287,5 +287,13 @@ Pyright *Documentation:* https://github.com/microsoft/pyright#documentation Pyflakes -=============================== +======== `Pyflakes `_ checks for common coding errors. + +LGTM +==== +The website `lgtm.com` offers a detailed diagnostic about the global code quality and its evolution. + +The reports can be found `here `_. + +Our choice of configuration is made in `.lgtm.yml`. From 08701a4701f1acad04a8d9663f103540c71a7cc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 19 May 2022 11:23:52 +0200 Subject: [PATCH 442/529] test that minpoly works --- src/sage/matrix/matrix2.pyx | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index b68985cbc1d..5d29eae4188 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -2825,6 +2825,20 @@ cdef class Matrix(Matrix1): self.cache('minpoly', mp) return mp + def _test_minpoly(self, **options): + """ + Check that :meth:`minpoly` works. + + EXAMPLES:: + + sage: a = matrix([[1,2],[3,4]]) + sage: a._test_minpoly() + """ + if self.nrows() == self.ncols(): + tester = self._tester(**options) + # At least check that the minimal polynomial kills the matrix + tester.assertTrue(self.minpoly().subs(x=self).is_zero()) + def charpoly(self, var = 'x', algorithm = None): r""" Returns the characteristic polynomial of self, as a polynomial over From 2457c05381f3c09923b9d5262f15716421ba4edc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 19 May 2022 12:03:41 +0200 Subject: [PATCH 443/529] better rst --- src/doc/en/developer/tools.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/en/developer/tools.rst b/src/doc/en/developer/tools.rst index 928f75623d2..4e4c2dcf4dc 100644 --- a/src/doc/en/developer/tools.rst +++ b/src/doc/en/developer/tools.rst @@ -292,8 +292,8 @@ Pyflakes LGTM ==== -The website `lgtm.com` offers a detailed diagnostic about the global code quality and its evolution. +The website ``lgtm.com`` offers a detailed diagnostic about the global code quality and its evolution. The reports can be found `here `_. -Our choice of configuration is made in `.lgtm.yml`. +Our choice of configuration is made in ``.lgtm.yml``. From ce364f737b21c2131710bbfd199936b520dc2198 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 19 May 2022 16:15:05 +0200 Subject: [PATCH 444/529] only test minpoly for exact rings --- src/sage/matrix/matrix2.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 5d29eae4188..41abcd42a16 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -2834,7 +2834,7 @@ cdef class Matrix(Matrix1): sage: a = matrix([[1,2],[3,4]]) sage: a._test_minpoly() """ - if self.nrows() == self.ncols(): + if self.nrows() == self.ncols() and self.base_ring().is_exact(): tester = self._tester(**options) # At least check that the minimal polynomial kills the matrix tester.assertTrue(self.minpoly().subs(x=self).is_zero()) From 216d945af1a918c569191473cb1890733769318d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 19 May 2022 16:39:34 +0200 Subject: [PATCH 445/529] use Gap for minpoly of Gap matrices --- src/sage/matrix/matrix_gap.pyx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/sage/matrix/matrix_gap.pyx b/src/sage/matrix/matrix_gap.pyx index 4a19dd4904e..d44c67958e3 100644 --- a/src/sage/matrix/matrix_gap.pyx +++ b/src/sage/matrix/matrix_gap.pyx @@ -416,6 +416,12 @@ cdef class Matrix_gap(Matrix_dense): """ return int(self._libgap.RankMat()) + def minpoly(self, var='x', **kwds): + po = self._libgap.MinimalPolynomial() + return po.sage().change_variable_name(var) + + minimal_polynomial = minpoly + def elementary_divisors(self): """ Return the list of elementary divisors of this matrix. From 9f476b44608a2acacf7e86bfec99a754fa80f796 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 19 May 2022 19:10:18 +0200 Subject: [PATCH 446/529] add doc, skip test --- src/sage/matrix/matrix2.pyx | 20 ++++++++++++++------ src/sage/matrix/matrix_gap.pyx | 13 +++++++++++-- src/sage/matrix/matrix_generic_dense.pyx | 2 +- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 41abcd42a16..89b2cc14ef4 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -2794,20 +2794,28 @@ cdef class Matrix(Matrix1): sage: factor(A.minpoly('y')) (y + 1) * (y + 2)^2 - """ f = self.fetch('minpoly') if not f is None: return f.change_variable_name(var) f = self.charpoly(var=var, **kwds) - if f.is_squarefree(): # is_squarefree for polys much faster than factor. - # Then f must be the minpoly - self.cache('minpoly', f) - return f + try: + no_sq = f.is_squarefree() + # is_squarefree for polys much faster than factor. + except (TypeError, NotImplementedError): + pass + else: + if no_sq: + # Then f must be the minpoly + self.cache('minpoly', f) + return f # Now we have to work harder. We find the power of each # irreducible factor that divides the minpoly. - mp = f.radical() + try: + mp = f.radical() + except (TypeError, NotImplementedError): + raise NotImplementedError("minimal polynomial not implemented") for h, e in f.factor(): if e > 1: # Find the power of B so that the dimension diff --git a/src/sage/matrix/matrix_gap.pyx b/src/sage/matrix/matrix_gap.pyx index d44c67958e3..0102d045e6c 100644 --- a/src/sage/matrix/matrix_gap.pyx +++ b/src/sage/matrix/matrix_gap.pyx @@ -417,8 +417,17 @@ cdef class Matrix_gap(Matrix_dense): return int(self._libgap.RankMat()) def minpoly(self, var='x', **kwds): - po = self._libgap.MinimalPolynomial() - return po.sage().change_variable_name(var) + """ + Compute the minimal polynomial. + + EXAMPLES:: + + sage: M = MatrixSpace(ZZ, 2, implementation='gap') + sage: M([0, 1, -1, -1]).minpoly() + x^2 + x + 1 + """ + po = self._libgap.MinimalPolynomial().sage() + return po.change_variable_name(var) minimal_polynomial = minpoly diff --git a/src/sage/matrix/matrix_generic_dense.pyx b/src/sage/matrix/matrix_generic_dense.pyx index 7c0058db1d2..49df19eacbf 100644 --- a/src/sage/matrix/matrix_generic_dense.pyx +++ b/src/sage/matrix/matrix_generic_dense.pyx @@ -28,7 +28,7 @@ cdef class Matrix_generic_dense(matrix_dense.Matrix_dense): sage: A = random_matrix(Integers(25)['x'], 2) sage: type(A) - sage: TestSuite(A).run() + sage: TestSuite(A).run(skip='_test_minpoly') Test comparisons:: From 329d4724ceb242e197af9a7a5aa4693d75a2308a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 20 May 2022 13:38:01 +0200 Subject: [PATCH 447/529] skip another test --- src/sage/matrix/matrix_dense.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/matrix/matrix_dense.pyx b/src/sage/matrix/matrix_dense.pyx index cedbe21cbdd..afc24c658e6 100644 --- a/src/sage/matrix/matrix_dense.pyx +++ b/src/sage/matrix/matrix_dense.pyx @@ -5,7 +5,7 @@ TESTS:: sage: R. = QQ[] sage: m = matrix(R,2,[0,a,b,b^2]) - sage: TestSuite(m).run() + sage: TestSuite(m).run(skip="_test_minpoly") """ cimport sage.matrix.matrix as matrix From 86f7da0b9635c69345578bec90e33c9d31b3d961 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Sat, 21 May 2022 13:42:27 +0000 Subject: [PATCH 448/529] Add pytest step --- .github/workflows/build.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b8e901d82af..5e4ace07d46 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -44,6 +44,13 @@ jobs: MAKE: make -j2 SAGE_NUM_THREADS: 2 + - name: Pytest + if: contains(github.ref, 'pytest') + run: | + ../sage -python -m pip install coverage pytest-xdist + ../sage -python -m coverage run -m pytest -c tox.ini --doctest-modules || true + working-directory: ./src + - name: Test run: | ../sage -python -m pip install coverage From 6f4efb0bf3725891b87707d71f6a9f6d354b54d7 Mon Sep 17 00:00:00 2001 From: Release Manager Date: Sun, 22 May 2022 11:59:41 +0200 Subject: [PATCH 449/529] Updated SageMath version to 9.7.beta0 --- .zenodo.json | 8 ++++---- VERSION.txt | 2 +- build/pkgs/configure/checksums.ini | 6 +++--- build/pkgs/configure/package-version.txt | 2 +- build/pkgs/sagelib/package-version.txt | 2 +- src/VERSION.txt | 2 +- src/bin/sage-version.sh | 6 +++--- src/sage/version.py | 6 +++--- 8 files changed, 17 insertions(+), 17 deletions(-) diff --git a/.zenodo.json b/.zenodo.json index b4b185cc8f6..ec3356f0e46 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -1,10 +1,10 @@ { "description": "Mirror of the Sage https://sagemath.org/ source tree", "license": "other-open", - "title": "sagemath/sage: 9.6", - "version": "9.6", + "title": "sagemath/sage: 9.7.beta0", + "version": "9.7.beta0", "upload_type": "software", - "publication_date": "2022-05-15", + "publication_date": "2022-05-22", "creators": [ { "affiliation": "SageMath.org", @@ -15,7 +15,7 @@ "related_identifiers": [ { "scheme": "url", - "identifier": "https://github.com/sagemath/sage/tree/9.6", + "identifier": "https://github.com/sagemath/sage/tree/9.7.beta0", "relation": "isSupplementTo" }, { diff --git a/VERSION.txt b/VERSION.txt index 3846fccef53..7d714ff1177 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -SageMath version 9.6, Release Date: 2022-05-15 +SageMath version 9.7.beta0, Release Date: 2022-05-22 diff --git a/build/pkgs/configure/checksums.ini b/build/pkgs/configure/checksums.ini index 4fa9b1113ec..0f55f2ef922 100644 --- a/build/pkgs/configure/checksums.ini +++ b/build/pkgs/configure/checksums.ini @@ -1,4 +1,4 @@ tarball=configure-VERSION.tar.gz -sha1=b6ec3aafbd4d0a3908c3532c98fbd85e9e6e8e13 -md5=283f9086f1adcd3edf881061f2c17995 -cksum=928965854 +sha1=9e9d35385cef955ca19f96b50c6bd3f5ceeac4fe +md5=149a9c360571ec4e67dd84ceeae25fbe +cksum=3945861789 diff --git a/build/pkgs/configure/package-version.txt b/build/pkgs/configure/package-version.txt index 8f557e5ad99..8acf0a1103e 100644 --- a/build/pkgs/configure/package-version.txt +++ b/build/pkgs/configure/package-version.txt @@ -1 +1 @@ -4e87be3dbb9e62fc1ec27685760095127c2cb632 +4f9ad1cd06c922af590d1bddd1930546a2aa4073 diff --git a/build/pkgs/sagelib/package-version.txt b/build/pkgs/sagelib/package-version.txt index c026ac828d0..52630adaf8b 100644 --- a/build/pkgs/sagelib/package-version.txt +++ b/build/pkgs/sagelib/package-version.txt @@ -1 +1 @@ -9.6 +9.7.beta0 diff --git a/src/VERSION.txt b/src/VERSION.txt index c026ac828d0..52630adaf8b 100644 --- a/src/VERSION.txt +++ b/src/VERSION.txt @@ -1 +1 @@ -9.6 +9.7.beta0 diff --git a/src/bin/sage-version.sh b/src/bin/sage-version.sh index 9eb05556679..020edde1d5c 100644 --- a/src/bin/sage-version.sh +++ b/src/bin/sage-version.sh @@ -1,5 +1,5 @@ # Sage version information for shell scripts # This file is auto-generated by the sage-update-version script, do not edit! -SAGE_VERSION='9.6' -SAGE_RELEASE_DATE='2022-05-15' -SAGE_VERSION_BANNER='SageMath version 9.6, Release Date: 2022-05-15' +SAGE_VERSION='9.7.beta0' +SAGE_RELEASE_DATE='2022-05-22' +SAGE_VERSION_BANNER='SageMath version 9.7.beta0, Release Date: 2022-05-22' diff --git a/src/sage/version.py b/src/sage/version.py index f2eba7424d1..93d63ae2e61 100644 --- a/src/sage/version.py +++ b/src/sage/version.py @@ -1,5 +1,5 @@ # Sage version information for Python scripts # This file is auto-generated by the sage-update-version script, do not edit! -version = '9.6' -date = '2022-05-15' -banner = 'SageMath version 9.6, Release Date: 2022-05-15' +version = '9.7.beta0' +date = '2022-05-22' +banner = 'SageMath version 9.7.beta0, Release Date: 2022-05-22' From 3efef4c29314e22a2c00f32f563aadacaa291309 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sun, 22 May 2022 21:43:29 +0200 Subject: [PATCH 450/529] trac #33740: simpler doctest --- src/sage/graphs/digraph_generators.py | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/src/sage/graphs/digraph_generators.py b/src/sage/graphs/digraph_generators.py index 0624a393625..12d65f4476d 100644 --- a/src/sage/graphs/digraph_generators.py +++ b/src/sage/graphs/digraph_generators.py @@ -257,19 +257,9 @@ def ButterflyGraph(self, n, vertices='strings'): (((1, 1), 0), ((1, 1), 1)), (((1, 1), 1), ((1, 0), 2)), (((1, 1), 1), ((1, 1), 2))] - sage: digraphs.ButterflyGraph(2).get_pos() - {('11', 0): (0, 0), - ('11', 1): (2, 0), - ('11', 2): (4, 0), - ('10', 0): (0, 1), - ('10', 1): (2, 1), - ('10', 2): (4, 1), - ('01', 0): (0, 2), - ('01', 1): (2, 2), - ('01', 2): (4, 2), - ('00', 0): (0, 3), - ('00', 1): (2, 3), - ('00', 2): (4, 3)} + sage: pos = digraphs.ButterflyGraph(2).get_pos() + sage: pos['11', 0] + (0, 0) TESTS:: From 8a05da7661ba110e428d4661589b251642441440 Mon Sep 17 00:00:00 2001 From: "John H. Palmieri" Date: Sun, 22 May 2022 13:46:14 -0700 Subject: [PATCH 451/529] trac 33883: typo in thematic_tutorials/steenrod_algebra_modules.rst --- src/doc/en/thematic_tutorials/steenrod_algebra_modules.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/en/thematic_tutorials/steenrod_algebra_modules.rst b/src/doc/en/thematic_tutorials/steenrod_algebra_modules.rst index c327ec6ac31..6d6513af258 100644 --- a/src/doc/en/thematic_tutorials/steenrod_algebra_modules.rst +++ b/src/doc/en/thematic_tutorials/steenrod_algebra_modules.rst @@ -721,7 +721,7 @@ There is an exact sequence which means that the indeterminacy of choosing a lift for `f \in \operatorname{Hom}_A(L, Hko)` is represented by an element in -`\operatorname{Hom}_A(L,\ker(f))`. Therefore, we can proceed to count the +`\operatorname{Hom}_A(L,\ker(q))`. Therefore, we can proceed to count the number of lifts by computing this vector space of homomorphisms:: sage: iK = q.kernel_inclusion() From 70d0c35b95bec535b1579b85830495e5b1f70ce1 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Mon, 23 May 2022 00:48:22 +0200 Subject: [PATCH 452/529] trac #33884: use a smaller random doctest in edge_disjoint_spanning_trees --- src/sage/graphs/generic_graph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index 00eb1fdbcd1..6849491eacc 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -6574,7 +6574,7 @@ def edge_disjoint_spanning_trees(self, k, algorithm=None, root=None, solver=None Check the validity of the algorithms for undirected graphs:: - sage: g = graphs.RandomGNP(30, .4) + sage: g = graphs.RandomGNP(12, .7) sage: k = Integer(g.edge_connectivity()) // 2 sage: trees = g.edge_disjoint_spanning_trees(k, algorithm="MILP") sage: all(t.is_tree() for t in trees) From a20a6ac062d29080cffe6379f5cee274138bd921 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 23 May 2022 21:02:58 +0200 Subject: [PATCH 453/529] fixing a few roles (:meth:, :func:, :wikipedia:) --- src/doc/en/developer/sage_manuals.rst | 2 +- src/sage/categories/coxeter_groups.py | 2 +- .../categories/finite_dimensional_modules_with_basis.py | 6 +++--- src/sage/categories/permutation_groups.py | 2 +- .../polyhedron/combinatorial_polyhedron/face_iterator.pyx | 2 +- src/sage/groups/cubic_braid.py | 4 ++-- src/sage/rings/padics/generic_nodes.py | 4 ++-- src/sage/rings/ring_extension.pyx | 2 +- src/sage/schemes/curves/zariski_vankampen.py | 4 ++-- 9 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/doc/en/developer/sage_manuals.rst b/src/doc/en/developer/sage_manuals.rst index 6482700b0e0..a640cc2df24 100644 --- a/src/doc/en/developer/sage_manuals.rst +++ b/src/doc/en/developer/sage_manuals.rst @@ -83,7 +83,7 @@ The documentation can contain links toward modules, classes, or methods, e.g.:: :mod:`sage.module_name` (here the link's text is the module's name) For links toward classes, methods, or function, replace **:mod:** by -**:class:**, **:meth:** or **func:** respectively. See `Sphinx' documentation +**:class:**, **:meth:** or **:func:** respectively. See `Sphinx' documentation `_. **Short links:** the link ``:func:`~sage.mod1.mod2.mod3.func1``` is equivalent diff --git a/src/sage/categories/coxeter_groups.py b/src/sage/categories/coxeter_groups.py index 58f80fa120e..543f5a3763e 100644 --- a/src/sage/categories/coxeter_groups.py +++ b/src/sage/categories/coxeter_groups.py @@ -36,7 +36,7 @@ class CoxeterGroups(Category_singleton): `I` is the *index set* of `W` and `|I|` is the *rank* of `W`. - See :Wikipedia:`Coxeter_group` for details. + See :wikipedia:`Coxeter_group` for details. EXAMPLES:: diff --git a/src/sage/categories/finite_dimensional_modules_with_basis.py b/src/sage/categories/finite_dimensional_modules_with_basis.py index c14709eb099..278a17e095c 100644 --- a/src/sage/categories/finite_dimensional_modules_with_basis.py +++ b/src/sage/categories/finite_dimensional_modules_with_basis.py @@ -1,13 +1,13 @@ r""" Finite dimensional modules with basis """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2008 Teresa Gomez-Diaz (CNRS) # 2011 Nicolas M. Thiery # # Distributed under the terms of the GNU General Public License (GPL) # http://www.gnu.org/licenses/ -#****************************************************************************** +# ***************************************************************************** import operator from sage.categories.category_with_axiom import CategoryWithAxiom_over_base_ring @@ -84,7 +84,7 @@ def annihilator(self, S, action=operator.mul, side='right', category=None): If ``self`` is a ring, ``action`` an action of ``self`` on a module `M` and `S` is a subset of `M`, we recover the - :Wikipedia:`Annihilator_%28ring_theory%29`. Similarly this + :wikipedia:`Annihilator_%28ring_theory%29`. Similarly this can be used to compute torsion or orthogonals. .. SEEALSO:: :meth:`annihilator_basis` for lots of examples. diff --git a/src/sage/categories/permutation_groups.py b/src/sage/categories/permutation_groups.py index c3191f4876d..7e71ad4d857 100644 --- a/src/sage/categories/permutation_groups.py +++ b/src/sage/categories/permutation_groups.py @@ -23,7 +23,7 @@ class PermutationGroups(Category): This distinguished action should be preserved by permutation group morphisms. For details, see - :Wikipedia:`Permutation_group#Permutation_isomorphic_groups`. + :wikipedia:`Permutation_group#Permutation_isomorphic_groups`. .. TODO:: shall we accept only permutations with finite support or not? diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx index f4abdbba69e..7e854219418 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx @@ -2014,7 +2014,7 @@ cdef inline int next_face_loop(iter_t structure) nogil except -1: cdef inline size_t n_atom_rep(iter_t structure) nogil except -1: r""" - See meth:`FaceIterator.n_atom_rep`. + See :meth:`FaceIterator.n_atom_rep`. """ if structure.face_status: return face_len_atoms(structure.face) diff --git a/src/sage/groups/cubic_braid.py b/src/sage/groups/cubic_braid.py index 66d1fbe9668..846b8710604 100644 --- a/src/sage/groups/cubic_braid.py +++ b/src/sage/groups/cubic_braid.py @@ -923,12 +923,12 @@ def _internal_test_attached_group(self, attached_group, tester): r""" It tests conversion maps from ``self`` to the given attached Group which must have been defined using the :meth:`as_classical_group`, - :meth:`as_matrix_group`, meth:`as_permutation_group` or + :meth:`as_matrix_group`, :meth:`as_permutation_group` or :meth:`as_reflection_group`. INPUT: - - ``attached_group`` -- attached group to be tested as specified above. + - ``attached_group`` -- attached group to be tested as specified above. EXAMPLES:: diff --git a/src/sage/rings/padics/generic_nodes.py b/src/sage/rings/padics/generic_nodes.py index c1a1c29ef37..b6a0625c423 100644 --- a/src/sage/rings/padics/generic_nodes.py +++ b/src/sage/rings/padics/generic_nodes.py @@ -1027,7 +1027,7 @@ def unknown(self, start_val=0, digits=None): of the previous ones. This method is used to declare a self-referent number (and optionally, to set its first digits). The definition of the number itself will be given afterwords using - to method meth:`sage.rings.padics.relaxed_template.RelaxedElement_unknown.set` + to method :meth:`sage.rings.padics.relaxed_template.RelaxedElement_unknown.set` of the element. EXAMPLES: @@ -1044,7 +1044,7 @@ def unknown(self, start_val=0, digits=None): sage: a O(5^0) - We can now use the method meth:`sage.rings.padics.relaxed_template.RelaxedElement_unknown.set` + We can now use the method :meth:`sage.rings.padics.relaxed_template.RelaxedElement_unknown.set` to define `a`. Below, for example, we say that the digits of `a` have to agree with the digits of `1 + 5 a`. Note that the factor `5` shifts the digits; the `n`-th digit of `a` is then defined by the previous ones:: diff --git a/src/sage/rings/ring_extension.pyx b/src/sage/rings/ring_extension.pyx index d4c8e179ed8..0edd33209d3 100644 --- a/src/sage/rings/ring_extension.pyx +++ b/src/sage/rings/ring_extension.pyx @@ -1177,7 +1177,7 @@ cdef class RingExtension_generic(CommutativeAlgebra): .. SEEALSO:: - !meth:`base`, :meth:`bases`, :meth:`absolute_base` + :meth:`base`, :meth:`bases`, :meth:`absolute_base` """ cdef CommutativeRing b b = self diff --git a/src/sage/schemes/curves/zariski_vankampen.py b/src/sage/schemes/curves/zariski_vankampen.py index 067d42cd420..09774ca3b7d 100644 --- a/src/sage/schemes/curves/zariski_vankampen.py +++ b/src/sage/schemes/curves/zariski_vankampen.py @@ -528,8 +528,8 @@ def roots_interval_cached(f, x0): def populate_roots_interval_cache(inputs): r""" - Call func:`roots_interval` to the inputs that have not been computed previously, - and cache them. + Call :func:`roots_interval` to the inputs that have not been + computed previously, and cache them. INPUT: From 92c97c9f1cda8fbd53c2373d5cfedb3a374021b1 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Mon, 23 May 2022 20:03:47 +0000 Subject: [PATCH 454/529] Dont test order of starting workers --- src/sage/parallel/map_reduce.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/parallel/map_reduce.py b/src/sage/parallel/map_reduce.py index 08f3456a999..a6438ea3b1d 100644 --- a/src/sage/parallel/map_reduce.py +++ b/src/sage/parallel/map_reduce.py @@ -1144,13 +1144,13 @@ def start_workers(self): sage: S = RESetMapReduce(roots=[1, 2], children=children) sage: S.setup_workers(2) sage: S.start_workers(); sleep(float(0.4)) - Starting: 1 - Starting: 2 + Starting: ... + Starting: ... sage: [w.is_alive() for w in S._workers] [True, True] sage: sleep(float(1.5)) - Finished: 1 - Finished: 2 + Finished: ... + Finished: ... sage: [not w.is_alive() for w in S._workers] [True, True] From 4ed5382215b14eff132106177fb098f54c40a4e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 12 Apr 2022 13:40:35 +0200 Subject: [PATCH 455/529] some care for pep8 in pyx files in modular/ --- .../modular/arithgroup/arithgroup_element.pyx | 2 +- src/sage/modular/arithgroup/congroup.pyx | 26 +++--- src/sage/modular/arithgroup/farey_symbol.pyx | 4 +- src/sage/modular/modsym/heilbronn.pyx | 35 ++++--- src/sage/modular/modsym/manin_symbol.pyx | 4 +- src/sage/modular/modsym/p1list.pyx | 91 ++++++++++++------- 6 files changed, 101 insertions(+), 61 deletions(-) diff --git a/src/sage/modular/arithgroup/arithgroup_element.pyx b/src/sage/modular/arithgroup/arithgroup_element.pyx index 847252780d5..86ef0e933aa 100644 --- a/src/sage/modular/arithgroup/arithgroup_element.pyx +++ b/src/sage/modular/arithgroup/arithgroup_element.pyx @@ -194,7 +194,7 @@ cdef class ArithmeticSubgroupElement(MultiplicativeGroupElement): return richcmp(self.__x, right.__x, op) def __bool__(self): - """ + r""" Return ``True``, since the ``self`` lives in SL(2,\Z), which does not contain the zero matrix. diff --git a/src/sage/modular/arithgroup/congroup.pyx b/src/sage/modular/arithgroup/congroup.pyx index 3cb2a84b334..9554ebbc11d 100644 --- a/src/sage/modular/arithgroup/congroup.pyx +++ b/src/sage/modular/arithgroup/congroup.pyx @@ -1,4 +1,4 @@ -""" +r""" Cython helper functions for congruence subgroups This file contains optimized Cython implementations of a few functions related @@ -6,13 +6,13 @@ to the standard congruence subgroups `\Gamma_0, \Gamma_1, \Gamma_H`. These functions are for internal use by routines elsewhere in the Sage library. """ -#***************************************************************************** +# **************************************************************************** # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from cysignals.memory cimport check_allocarray, sig_free @@ -28,7 +28,7 @@ from sage.matrix.matrix_integer_dense cimport Matrix_integer_dense from sage.modular.modsym.p1list import lift_to_sl2z from sage.matrix.matrix_space import MatrixSpace from sage.rings.integer_ring import ZZ -Mat2Z = MatrixSpace(ZZ,2) +Mat2Z = MatrixSpace(ZZ, 2) cdef Matrix_integer_dense genS, genT, genI genS = Matrix_integer_dense(Mat2Z, [0,-1, 1, 0], True, True) @@ -124,9 +124,11 @@ def degeneracy_coset_representatives_gamma0(int N, int M, int t): cc = M*random.randrange(-halfmax, halfmax+1) dd = random.randrange(-halfmax, halfmax+1) g = arith_int.c_xgcd_int(-cc,dd,&bb,&aa) - if g == 0: continue + if g == 0: + continue cc = cc / g - if cc % M != 0: continue + if cc % M != 0: + continue dd = dd / g # Test if we've found a new coset representative. is_new = 1 @@ -212,7 +214,6 @@ def degeneracy_coset_representatives_gamma1(int N, int M, int t): cdef int d, g, i, j, k, n, aa, bb, cc, dd, Ndivt, halfmax, is_new cdef int* R - # total number of coset representatives that we'll find n = Gamma1(N).index() / Gamma1(M).index() d = arith_int.c_gcd_int(t, N/t) @@ -226,11 +227,14 @@ def degeneracy_coset_representatives_gamma1(int N, int M, int t): cc = M*random.randrange(-halfmax, halfmax+1) dd = 1 + M*random.randrange(-halfmax, halfmax+1) g = arith_int.c_xgcd_int(-cc,dd,&bb,&aa) - if g == 0: continue + if g == 0: + continue cc = cc / g - if cc % M != 0: continue + if cc % M != 0: + continue dd = dd / g - if M != 1 and dd % M != 1: continue + if M != 1 and dd % M != 1: + continue # Test if we've found a new coset representative. is_new = 1 for i from 0 <= i < k: diff --git a/src/sage/modular/arithgroup/farey_symbol.pyx b/src/sage/modular/arithgroup/farey_symbol.pyx index 18ba31ae5dc..01b3db0b019 100644 --- a/src/sage/modular/arithgroup/farey_symbol.pyx +++ b/src/sage/modular/arithgroup/farey_symbol.pyx @@ -610,7 +610,7 @@ cdef class Farey: if forced_format == 'plain': # output not using xymatrix s = r'\left( -\infty' - a = [x._latex_() for x in self.fractions()] + ['\infty'] + a = [x._latex_() for x in self.fractions()] + [r'\infty'] b = self.pairings() for i in xrange(len(a)): u = b[i] @@ -623,7 +623,7 @@ cdef class Farey: else: # output using xymatrix s = r'\begin{xy}\xymatrix{& -\infty ' - f = [x._latex_() for x in self.fractions()]+[r'\infty'] + f = [x._latex_() for x in self.fractions()] + [r'\infty'] f.reverse() for p in self.pairings(): if p >= 0: diff --git a/src/sage/modular/modsym/heilbronn.pyx b/src/sage/modular/modsym/heilbronn.pyx index 3bfd5ffafe1..2ba337dddc4 100644 --- a/src/sage/modular/modsym/heilbronn.pyx +++ b/src/sage/modular/modsym/heilbronn.pyx @@ -211,7 +211,7 @@ cdef class Heilbronn: sig_off() cdef apply_to_polypart(self, fmpz_poly_t* ans, int i, int k): - """ + r""" INPUT: - ``ans`` - fmpz_poly_t\*; pre-allocated an @@ -402,7 +402,11 @@ cdef class HeilbronnCremona(Heilbronn): a = -b b = c x3 = q*x2 - x1 - x1 = x2; x2 = x3; y3 = q*y2 - y1; y1 = y2; y2 = y3 + x1 = x2 + x2 = x3 + y3 = q*y2 - y1 + y1 = y2 + y2 = y3 list_append4(L, x1,x2, y1,y2) self.length = L.i/4 sig_off() @@ -573,9 +577,11 @@ def hecke_images_gamma0_weight2(int u, int v, int N, indices, R): # Allocate memory to hold images of (u,v) under all Heilbronn matrices a = sig_malloc(sizeof(int)*H.length) - if not a: raise MemoryError + if not a: + raise MemoryError b = sig_malloc(sizeof(int)*H.length) - if not b: raise MemoryError + if not b: + raise MemoryError # Compute images of (u,v) under all Heilbronn matrices H.apply_only(u, v, N, a, b) @@ -708,9 +714,11 @@ def hecke_images_nonquad_character_weight2(int u, int v, int N, indices, chi, R) # Allocate memory to hold images of (u,v) under all Heilbronn matrices a = sig_malloc(sizeof(int)*H.length) - if not a: raise MemoryError + if not a: + raise MemoryError b = sig_malloc(sizeof(int)*H.length) - if not b: raise MemoryError + if not b: + raise MemoryError # Compute images of (u,v) under all Heilbronn matrices H.apply_only(u, v, N, a, b) @@ -798,16 +806,19 @@ def hecke_images_quad_character_weight2(int u, int v, int N, indices, chi, R): # are the values of the character chi. _chivals = chi.values() cdef int *chi_vals = sig_malloc(sizeof(int)*len(_chivals)) - if not chi_vals: raise MemoryError + if not chi_vals: + raise MemoryError for i in range(len(_chivals)): chi_vals[i] = _chivals[i] for i, n in enumerate(indices): H = HeilbronnCremona(n) if is_prime(n) else HeilbronnMerel(n) a = sig_malloc(sizeof(int)*H.length) - if not a: raise MemoryError + if not a: + raise MemoryError b = sig_malloc(sizeof(int)*H.length) - if not b: raise MemoryError + if not b: + raise MemoryError H.apply_only(u, v, N, a, b) for j in range(H.length): @@ -893,9 +904,11 @@ def hecke_images_gamma0_weight_k(int u, int v, int i, int N, int k, indices, R): # Allocate memory to hold images of (u,v) under all Heilbronn matrices a = sig_malloc(sizeof(int)*H.length) - if not a: raise MemoryError + if not a: + raise MemoryError b = sig_malloc(sizeof(int)*H.length) - if not b: raise MemoryError + if not b: + raise MemoryError # Compute images of (u,v) under all Heilbronn matrices H.apply_only(u, v, N, a, b) diff --git a/src/sage/modular/modsym/manin_symbol.pyx b/src/sage/modular/modsym/manin_symbol.pyx index 0a4944b4ad8..86927b91959 100644 --- a/src/sage/modular/modsym/manin_symbol.pyx +++ b/src/sage/modular/modsym/manin_symbol.pyx @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -""" +r""" Manin symbols This module defines the class ManinSymbol. A Manin symbol of @@ -19,9 +19,7 @@ monomial Manin symbols to monomial Manin symbols, up to a scalar factor. For general matrices (such as `T=[0,1,-1,-1]` and `T^2=[-1,-1;0,1]`) the image of a monomial Manin symbol is expressed as a formal sum of monomial Manin symbols, with integer coefficients. - """ - from sage.modular.cusps import Cusp from sage.rings.all import Infinity, ZZ from sage.rings.integer cimport Integer diff --git a/src/sage/modular/modsym/p1list.pyx b/src/sage/modular/modsym/p1list.pyx index fbe461c269d..aaa8aa609d7 100644 --- a/src/sage/modular/modsym/p1list.pyx +++ b/src/sage/modular/modsym/p1list.pyx @@ -68,8 +68,10 @@ cdef int c_p1_normalize_int(int N, int u, int v, u = u % N v = v % N - if u<0: u = u + N - if v<0: v = v + N + if u < 0: + u = u + N + if v < 0: + v = v + N if u == 0: uu[0] = 0 if arith_int.c_gcd_int(v,N) == 1: @@ -81,7 +83,8 @@ cdef int c_p1_normalize_int(int N, int u, int v, g = arith_int.c_xgcd_int(u, N, &s, &t) s = s % N - if s<0: s = s + N + if s < 0: + s = s + N if arith_int.c_gcd_int(g, v) != 1: uu[0] = 0 vv[0] = 0 @@ -99,7 +102,8 @@ cdef int c_p1_normalize_int(int N, int u, int v, u = g v = (s*v) % N - min_v = v; min_t = 1 + min_v = v + min_t = 1 if g!=1: Ng = N/g vNg = (v*Ng) % N @@ -108,10 +112,13 @@ cdef int c_p1_normalize_int(int N, int u, int v, v = (v + vNg) % N t = (t + Ng) % N if v(ll_s % ll_N) t = (ll_t % ll_N) s = s % N - if s<0: s = s + N + if s < 0: + s = s + N if arith_int.c_gcd_int(g, v) != 1: uu[0] = 0 vv[0] = 0 @@ -355,7 +366,8 @@ cdef int c_p1_normalize_llong(int N, int u, int v, # v = (s*v) % N v = ( ((s) * (v)) % ll_N ) - min_v = v; min_t = 1 + min_v = v + min_t = 1 if g!=1: Ng = N/g vNg = ((v * Ng) % ll_N) @@ -364,16 +376,20 @@ cdef int c_p1_normalize_llong(int N, int u, int v, v = (v + vNg) % N t = (t + Ng) % N if v (arith_llong.c_inverse_mod_longlong(( s)*( min_t), N) % ll_N) return 0 + def p1_normalize_llong(N, u, v): r""" Computes the canonical representative of @@ -449,7 +465,8 @@ def p1list_llong(int N): [(0, 1), (34603, 1), (34603, 2), (34603, 3)] """ cdef int g, u, v, s, c, d, h, d1, cmax - if N==1: return [(0,0)] + if N == 1: + return [(0, 0)] lst = [(0,1)] c = 1 @@ -478,8 +495,9 @@ def p1list_llong(int N): lst.sort() return lst + def p1list(N): - """ + r""" Return the elements of the projective line modulo `N`, `\mathbb{P}^1(\ZZ/N\ZZ)`, as a plain list of 2-tuples. @@ -600,8 +618,10 @@ cdef int p1_normalize_xgcdtable(int N, int u, int v, u = u % N v = v % N - if u<0: u = u + N - if v<0: v = v + N + if u < 0: + u = u + N + if v < 0: + v = v + N if u == 0: uu[0] = 0 if t_g[v] == 1: # "if arith_int.c_gcd_int(v,N) == 1" @@ -616,7 +636,8 @@ cdef int p1_normalize_xgcdtable(int N, int u, int v, s = t_a[u] t = t_b[u] s = s % N - if s<0: s = s + N + if s < 0: + s = s + N if g != 1 and arith_int.c_gcd_int(g, v) != 1: uu[0] = 0 vv[0] = 0 @@ -634,7 +655,8 @@ cdef int p1_normalize_xgcdtable(int N, int u, int v, u = g v = (s*v) % N - min_v = v; min_t = 1 + min_v = v + min_t = 1 if g!=1: Ng = N/g vNg = (v*Ng) % N @@ -643,10 +665,13 @@ cdef int p1_normalize_xgcdtable(int N, int u, int v, v = (v + vNg) % N t = (t + Ng) % N if vcheck_allocarray(N, sizeof(int)) self.s = check_allocarray(N, sizeof(int)) self.t = check_allocarray(N, sizeof(int)) @@ -822,10 +847,10 @@ cdef class P1List(object): 'The projective line over the integers modulo 8' """ - return "The projective line over the integers modulo %s"%self.__N + return "The projective line over the integers modulo %s" % self.__N def lift_to_sl2z(self, int i): - """ + r""" Lift the `i`'th element of this P1list to an element of `SL(2,\ZZ)`. @@ -836,7 +861,6 @@ cdef class P1List(object): INPUT: - - ``i`` - integer (the index of the element to lift). EXAMPLES:: @@ -1187,8 +1211,9 @@ cdef class export: int compute_s) except -1: return c_p1_normalize_llong(N, u, v, uu, vv, ss, compute_s) + def lift_to_sl2z_int(int c, int d, int N): - """ + r""" Lift a pair `(c, d)` to an element of `SL(2, \ZZ)`. `(c,d)` is assumed to be an element of From 5bfe5e127f0f3371d146c363f64da045f1d5438f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 13 Apr 2022 08:38:55 +0200 Subject: [PATCH 456/529] using += where possible in p1list --- src/sage/modular/modsym/p1list.pyx | 34 +++++++++++++++--------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/sage/modular/modsym/p1list.pyx b/src/sage/modular/modsym/p1list.pyx index aaa8aa609d7..df75484734e 100644 --- a/src/sage/modular/modsym/p1list.pyx +++ b/src/sage/modular/modsym/p1list.pyx @@ -69,9 +69,9 @@ cdef int c_p1_normalize_int(int N, int u, int v, u = u % N v = v % N if u < 0: - u = u + N + u += N if v < 0: - v = v + N + v += N if u == 0: uu[0] = 0 if arith_int.c_gcd_int(v,N) == 1: @@ -84,7 +84,7 @@ cdef int c_p1_normalize_int(int N, int u, int v, g = arith_int.c_xgcd_int(u, N, &s, &t) s = s % N if s < 0: - s = s + N + s += N if arith_int.c_gcd_int(g, v) != 1: uu[0] = 0 vv[0] = 0 @@ -116,9 +116,9 @@ cdef int c_p1_normalize_int(int N, int u, int v, min_t = t v = min_v if u < 0: - u = u+N + u += N if v < 0: - v = v+N + v += N uu[0] = u vv[0] = v if compute_s: @@ -329,9 +329,9 @@ cdef int c_p1_normalize_llong(int N, int u, int v, u = u % N v = v % N if u < 0: - u = u + N + u += N if v < 0: - v = v + N + v += N if u == 0: uu[0] = 0 if arith_int.c_gcd_int(v,N) == 1: @@ -347,7 +347,7 @@ cdef int c_p1_normalize_llong(int N, int u, int v, t = (ll_t % ll_N) s = s % N if s < 0: - s = s + N + s += N if arith_int.c_gcd_int(g, v) != 1: uu[0] = 0 vv[0] = 0 @@ -380,9 +380,9 @@ cdef int c_p1_normalize_llong(int N, int u, int v, min_t = t v = min_v if u < 0: - u = u+N + u += N if v < 0: - v = v+N + v += N uu[0] = u vv[0] = v if compute_s: @@ -619,9 +619,9 @@ cdef int p1_normalize_xgcdtable(int N, int u, int v, u = u % N v = v % N if u < 0: - u = u + N + u += N if v < 0: - v = v + N + v += N if u == 0: uu[0] = 0 if t_g[v] == 1: # "if arith_int.c_gcd_int(v,N) == 1" @@ -637,7 +637,7 @@ cdef int p1_normalize_xgcdtable(int N, int u, int v, t = t_b[u] s = s % N if s < 0: - s = s + N + s += N if g != 1 and arith_int.c_gcd_int(g, v) != 1: uu[0] = 0 vv[0] = 0 @@ -669,9 +669,9 @@ cdef int p1_normalize_xgcdtable(int N, int u, int v, min_t = t v = min_v if u < 0: - u = u+N + u += N if v < 0: - v = v+N + v += N uu[0] = u vv[0] = v if compute_s: @@ -1274,7 +1274,7 @@ def lift_to_sl2z_int(int c, int d, int N): if g == 1: break m = m / g - d = d + N*m + d += N * m g = arith_int.c_xgcd_int(c, d, &z1, &z2) if g != 1: @@ -1344,7 +1344,7 @@ def lift_to_sl2z_llong(llong c, llong d, int N): if g == 1: break m = m / g - d = d + N*m + d += N * m g = arith_llong.c_xgcd_longlong(c, d, &z1, &z2) if g != 1: From 3b8828413771b6b922c3018daf52052354c35ceb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 24 May 2022 10:43:54 +0200 Subject: [PATCH 457/529] get rid of some range(O,*) --- src/sage/coding/binary_code.pyx | 2 +- src/sage/geometry/integral_points.pyx | 24 +++++++++---------- src/sage/libs/mpmath/ext_impl.pyx | 2 +- src/sage/matroids/matroid.pyx | 2 +- .../polynomial/multi_polynomial_ring_base.pyx | 8 +++---- src/sage/rings/polynomial/real_roots.pyx | 15 ++++++------ src/sage/sets/recursively_enumerated_set.pyx | 2 +- src/sage/structure/element.pyx | 4 ++-- 8 files changed, 29 insertions(+), 30 deletions(-) diff --git a/src/sage/coding/binary_code.pyx b/src/sage/coding/binary_code.pyx index 11af1f7aadf..709a3e8fe76 100644 --- a/src/sage/coding/binary_code.pyx +++ b/src/sage/coding/binary_code.pyx @@ -3927,7 +3927,7 @@ cdef class BinaryCodeClassifier: sage: soc_iter = codes.databases.self_orthogonal_binary_codes(12, 6, 4) sage: L = list(soc_iter) - sage: for n in range(0, 13): + sage: for n in range(13): ....: s = 'n=%2d : '%n ....: for k in range(1,7): ....: s += '%3d '%len([C for C in L if C.length() == n and C.dimension() == k]) diff --git a/src/sage/geometry/integral_points.pyx b/src/sage/geometry/integral_points.pyx index dbacf395c9c..f8325eea1ed 100644 --- a/src/sage/geometry/integral_points.pyx +++ b/src/sage/geometry/integral_points.pyx @@ -49,12 +49,12 @@ from sage.matrix.matrix_integer_dense cimport Matrix_integer_dense ## # R*Rinv == diagonal_matrix([d]*D.ncols() + [0]*(D.nrows()-D.ncols())) ## # If R is full rank, this is Rinv = matrix(ZZ, R.inverse() * d) ## Dinv = D.transpose() -## for i in range(0,D.ncols()): +## for i in range(D.ncols()): ## Dinv[i,i] = d/D[i,i] ## Rinv = V * Dinv * U ## ## gens = [] -## for b in CartesianProduct(*[ range(0,i) for i in e ]): +## for b in CartesianProduct(*[ range(i) for i in e ]): ## # this is our generator modulo the lattice spanned by the rays ## gen_mod_rays = sum( b_i*u_i for b_i, u_i in zip(b,u) ) ## q_times_d = Rinv * gen_mod_rays @@ -175,7 +175,7 @@ cpdef tuple ray_matrix_normal_form(R): if d == ZZ.zero(): raise ValueError('The spanning points are not linearly independent!') cdef int i - Dinv = diagonal_matrix(ZZ, [ d // e[i] for i in range(0,D.ncols()) ]) + Dinv = diagonal_matrix(ZZ, [ d // e[i] for i in range(D.ncols()) ]) VDinv = V * Dinv return (e, d, VDinv) @@ -224,20 +224,20 @@ cpdef tuple loop_over_parallelotope_points(e, d, Matrix_integer_dense VDinv, cdef list gens = [] gen = lattice(ZZ.zero()) cdef Vector_integer_dense q_times_d = vector(ZZ, dim) - for base in itertools.product(*[ range(0,i) for i in e ]): - for i in range(0, dim): + for base in itertools.product(*[ range(i) for i in e ]): + for i in range(dim): s = ZZ.zero() - for j in range(0, dim): + for j in range(dim): s += VDinv.get_unsafe(i,j) * base[j] q_times_d.set_unsafe(i, s % d) - for i in range(0, ambient_dim): + for i in range(ambient_dim): s = ZZ.zero() - for j in range(0, dim): + for j in range(dim): s += R.get_unsafe(i,j) * q_times_d.get_unsafe(j) gen[i] = s / d if A is not None: s = ZZ.zero() - for i in range(0, ambient_dim): + for i in range(ambient_dim): s += A[i] * gen[i] if s > b: continue @@ -341,7 +341,7 @@ cdef translate_points(v_list, Vector_integer_dense delta): cdef int dim = delta.degree() cdef int i for v in v_list: - for i in range(0,dim): + for i in range(dim): v[i] -= delta.get_unsafe(i) @@ -549,7 +549,7 @@ cpdef rectangular_box_points(list box_min, list box_max, assert not (count_only and return_saturated) cdef int d = len(box_min) cdef int i, j - cdef list diameter = sorted([ (box_max[i]-box_min[i], i) for i in range(0,d) ], + cdef list diameter = sorted([ (box_max[i]-box_min[i], i) for i in range(d) ], reverse=True) cdef list diameter_value = [x[0] for x in diameter] cdef list diameter_index = [x[1] for x in diameter] @@ -790,7 +790,7 @@ cdef class Inequality_generic: 'generic: (2, 3, 7) x + -5 >= 0' """ s = 'generic: (' - s += ', '.join([str(self.A[i]) for i in range(0,len(self.A))]) + s += ', '.join(str(self.A[i]) for i in range(len(self.A))) s += ') x + ' + str(self.b) + ' >= 0' return s diff --git a/src/sage/libs/mpmath/ext_impl.pyx b/src/sage/libs/mpmath/ext_impl.pyx index 7a8c8ae73ed..f9b0ff2d42c 100644 --- a/src/sage/libs/mpmath/ext_impl.pyx +++ b/src/sage/libs/mpmath/ext_impl.pyx @@ -2036,7 +2036,7 @@ cdef MPF_hypsum(MPF *a, MPF *b, int p, int q, param_types, str ztype, coeffs, z, mpz_set_complex_tuple_fixed(ZRE, ZIM, z, wp) else: mpz_set_tuple_fixed(ZRE, z, wp) - for i in range(0,p): + for i in range(p): sig_check() if param_types[i] == 'Z': mpz_init(AINT[aint]) diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index ef9096fa1d9..7c21e640942 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -2351,7 +2351,7 @@ cdef class Matroid(SageObject): False """ E = list(self.groundset()) - for i in xrange(0, len(E) + 1): + for i in range(len(E) + 1): for X in combinations(E, i): XX = frozenset(X) rX = self._rank(XX) diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx index 8847a6a2764..a560dc8b59c 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx @@ -1238,7 +1238,7 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): sage: R._macaulay_resultant_is_reduced([1,3,2],[2,3,3]) # the monomial x*y^3*z^2 is not reduced w.r.t. degrees vector [2,3,3] True """ - diff = [mon_degs[i] - dlist[i] for i in xrange(0,len(dlist))] + diff = [mon_degs[i] - dlist[i] for i in range(len(dlist))] return len([1 for d in diff if d >= 0]) == 1 def _macaulay_resultant_universal_polynomials(self, dlist): @@ -1276,11 +1276,11 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): for d in dlist: xlist = R.gens() degs = IntegerVectors(d, n+1) - mon_d = [prod([xlist[i]**(deg[i]) for i in xrange(0,len(deg))]) + mon_d = [prod([xlist[i]**(deg[i]) for i in range(len(deg))]) for deg in degs] - f = sum([mon_d[i]*ulist[i] for i in xrange(0,len(mon_d))]) - flist.append (f) + f = sum([mon_d[i]*ulist[i] for i in range(len(mon_d))]) + flist.append(f) ulist = ulist[len(mon_d):] return flist, R diff --git a/src/sage/rings/polynomial/real_roots.pyx b/src/sage/rings/polynomial/real_roots.pyx index 72cd160f5b3..e5edf97ed06 100644 --- a/src/sage/rings/polynomial/real_roots.pyx +++ b/src/sage/rings/polynomial/real_roots.pyx @@ -2109,14 +2109,14 @@ def bernstein_up(d1, d2, s=None): MS = MatrixSpace(QQ, s, d1+1, sparse=False) m = MS() scale = factorial(d2)/factorial(d2-d1) - for b in range(0, d1+1): + for b in range(d1 + 1): scale2 = scale / binomial(d1, b) if (d1 - b) & 1 == 1: scale2 = -scale2 scale2 = ~scale2 - for a in range(0, s): + for a in range(s): ra = ZZ(subsample_vec(a, s, d2 + 1)) - m[a, b] = prod([ra-i for i in range(0, b)]) * prod([ra-i for i in range(d2-d1+b+1, d2+1)]) * scale2 + m[a, b] = prod([ra-i for i in range(b)]) * prod([ra-i for i in range(d2-d1+b+1, d2+1)]) * scale2 return m @@ -4369,7 +4369,7 @@ def to_bernstein(p, low=0, high=1, degree=None): raise ValueError('Bernstein degree must be at least polynomial degree') vs = ZZ ** (degree + 1) c = vs(0) - for i in range(0, p.degree() + 1): + for i in range(p.degree() + 1): c[i] = p[i] scale = ZZ(1) if low == 0: @@ -4385,7 +4385,8 @@ def to_bernstein(p, low=0, high=1, degree=None): reverse_intvec(c) taylor_shift1_intvec(c) reverse_intvec(c) - return ([c[k] / binomial(degree, k) for k in range(0, degree+1)], scale) + return ([c[k] / binomial(degree, k) for k in range(degree + 1)], scale) + def to_bernstein_warp(p): """ @@ -4399,14 +4400,12 @@ def to_bernstein_warp(p): sage: to_bernstein_warp(1 + x + x^2 + x^3 + x^4 + x^5) [1, 1/5, 1/10, 1/10, 1/5, 1] """ - c = p.list() - for i in range(len(c)): c[i] = c[i] / binomial(len(c) - 1, i) - return c + def bernstein_expand(Vector_integer_dense c, int d2): """ Given an integer vector representing a Bernstein polynomial p, and diff --git a/src/sage/sets/recursively_enumerated_set.pyx b/src/sage/sets/recursively_enumerated_set.pyx index d2193c4ada7..073e7c6e95e 100644 --- a/src/sage/sets/recursively_enumerated_set.pyx +++ b/src/sage/sets/recursively_enumerated_set.pyx @@ -273,7 +273,7 @@ convention is that the generated elements are the ``s := f(n)``, except when ....: st = set(st) # make a copy ....: if st: ....: el = st.pop() - ....: for i in range(0, len(lst)+1): + ....: for i in range(len(lst)+1): ....: yield (lst[0:i]+[el]+lst[i:], st) sage: list(children(([1,2], {3,7,9}))) [([9, 1, 2], {3, 7}), ([1, 9, 2], {3, 7}), ([1, 2, 9], {3, 7})] diff --git a/src/sage/structure/element.pyx b/src/sage/structure/element.pyx index dfd6583b149..e302e6661b8 100644 --- a/src/sage/structure/element.pyx +++ b/src/sage/structure/element.pyx @@ -823,8 +823,8 @@ cdef class Element(SageObject): variables=[] # use "gen" instead of "gens" as a ParentWithGens is not # required to have the latter - for i in xrange(0,ngens): - gen=parent.gen(i) + for i in range(ngens): + gen = parent.gen(i) if str(gen) in kwds: variables.append(kwds[str(gen)]) elif in_dict and gen in in_dict: From a9b34633fb2894270afc68201a6ff2af53765b4a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 24 May 2022 09:55:37 -0700 Subject: [PATCH 458/529] m4/sage_spkg_collect.m4: Fix up quoting --- m4/sage_spkg_collect.m4 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/m4/sage_spkg_collect.m4 b/m4/sage_spkg_collect.m4 index c35a21a7efe..e778e55abcf 100644 --- a/m4/sage_spkg_collect.m4 +++ b/m4/sage_spkg_collect.m4 @@ -335,14 +335,14 @@ AC_DEFUN([SAGE_SPKG_FINALIZE], [dnl ]) AS_CASE(["$DEPS"], [*\|*], [], [AS_VAR_APPEND([DEPS], [" |"])]) AS_IF([test -f "$DIR/dependencies_order_only"], [dnl - AS_VAR_APPEND([DEPS], [' '$(echo $(sed 's/^ *//; s/ *#.*//; q' $DIR/dependencies_order_only))]) + ADD_DEPS=$(echo $(sed 's/^ *//; s/ *#.*//; q' $DIR/dependencies_order_only)) + AS_VAR_APPEND([DEPS], [" $ADD_DEPS"]) ], [dnl m4_case(SPKG_SOURCE, [pip], [AS_VAR_APPEND([DEPS], [' pip'])], [:])dnl ]) AS_IF([test -f "$DIR/dependencies_check"], [dnl - AS_VAR_APPEND([DEPS], [' $(and $(filter-out no,$(SAGE_CHECK_]SPKG_NAME[)), ']) - AS_VAR_APPEND([DEPS], [$(echo $(sed 's/^ *//; s/ *#.*//; q' $DIR/dependencies_check))]) - AS_VAR_APPEND([DEPS], [')'])dnl + ADD_DEPS=$(echo $(sed 's/^ *//; s/ *#.*//; q' $DIR/dependencies_check)) + AS_VAR_APPEND([DEPS], [' $(and $(filter-out no,$(SAGE_CHECK_]SPKG_NAME[)), '"$ADD_DEPS"')'])dnl ]) dnl SAGE_PACKAGE_DEPENDENCIES="${SAGE_PACKAGE_DEPENDENCIES}$(printf '\ndeps_')SPKG_NAME = ${DEPS}" From 2ee71b5be9548734e247466f98c97df51ace5237 Mon Sep 17 00:00:00 2001 From: Louis Ng Date: Fri, 20 May 2022 11:42:10 -0700 Subject: [PATCH 459/529] added check for class and dimension when the input is a list or tuple --- .../polyhedron/modules/formal_polyhedra_module.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/sage/geometry/polyhedron/modules/formal_polyhedra_module.py b/src/sage/geometry/polyhedron/modules/formal_polyhedra_module.py index e3b55989563..af79c6fe830 100644 --- a/src/sage/geometry/polyhedron/modules/formal_polyhedra_module.py +++ b/src/sage/geometry/polyhedron/modules/formal_polyhedra_module.py @@ -1,6 +1,7 @@ r""" Formal modules generated by polyhedra """ +from cmath import isfinite from sage.combinat.free_module import CombinatorialFreeModule from sage.categories.graded_modules_with_basis import GradedModulesWithBasis @@ -83,6 +84,13 @@ def __classcall__(cls, base_ring, dimension, basis, category=None): """ if isinstance(basis, list): basis = tuple(basis) + if isinstance(basis, tuple): #To make sure it only check for finite input + from sage.geometry.polyhedron.base import Polyhedron_base + for P in basis: + if not isinstance(P, Polyhedron_base): + raise TypeError(f"{P} is not a polyhedron") + if P.ambient_space().dimension() != dimension: + raise TypeError(f"{P} does not belong to the ambient space") if category is None: category = GradedModulesWithBasis(base_ring) return super(FormalPolyhedraModule, cls).__classcall__(cls, From 350e87a068902f6097de93b02c5517d2547f5338 Mon Sep 17 00:00:00 2001 From: Louis Ng Date: Fri, 20 May 2022 17:03:17 -0700 Subject: [PATCH 460/529] removed unnecessary import --- src/sage/geometry/polyhedron/modules/formal_polyhedra_module.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sage/geometry/polyhedron/modules/formal_polyhedra_module.py b/src/sage/geometry/polyhedron/modules/formal_polyhedra_module.py index af79c6fe830..cd97821a951 100644 --- a/src/sage/geometry/polyhedron/modules/formal_polyhedra_module.py +++ b/src/sage/geometry/polyhedron/modules/formal_polyhedra_module.py @@ -1,7 +1,6 @@ r""" Formal modules generated by polyhedra """ -from cmath import isfinite from sage.combinat.free_module import CombinatorialFreeModule from sage.categories.graded_modules_with_basis import GradedModulesWithBasis From d04f2b593d55c8ecb1c3a0d85867a8340398f4e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 24 May 2022 20:39:05 +0200 Subject: [PATCH 461/529] some fixes in arxiv links --- src/doc/en/reference/references/index.rst | 17 ++++++++--------- .../non_symmetric_macdonald_polynomials.py | 2 +- src/sage/rings/number_field/S_unit_solver.py | 9 ++++----- src/sage/rings/polynomial/pbori/__init__.py | 8 ++++---- 4 files changed, 17 insertions(+), 19 deletions(-) diff --git a/src/doc/en/reference/references/index.rst b/src/doc/en/reference/references/index.rst index 30a792e8214..f5edfa301e4 100644 --- a/src/doc/en/reference/references/index.rst +++ b/src/doc/en/reference/references/index.rst @@ -968,7 +968,7 @@ REFERENCES: .. [BDGRTW2019] Bonderson, Delaney, Galindo, Rowell, Tran, and Wang, On invariants of modular categories beyond modular data. J. Pure Appl. Algebra 223 (2019), no. 9, 4065–4088. - :arXiv:`1805.05736`. + :arxiv:`1805.05736`. .. [BM2004] John M. Boyer and Wendy J. Myrvold, *On the Cutting Edge: *Simplified `O(n)` Planarity by Edge Addition*. Journal of Graph @@ -2060,7 +2060,7 @@ REFERENCES: .. [Dragan2018] Feodor Dragan, Michel Habib, Laurent Viennot. *Revisiting Radius, Diameter, and all Eccentricity Computation in Graphs through Certificates*. - http://arxiv.org/abs/1803.04660 + :arxiv:`1803.04660` .. [Dro1987] Carl Droms. *Isomorphisms of graph groups*. Proc. of the Amer. Math. Soc. **100** @@ -3592,7 +3592,7 @@ REFERENCES: Springer-Verlag, 2011. .. [KP2020] Lars Kastner and Marta Panizzut, *Hyperplane arrangements - in polymake*, arxiv:`2003.13548`. + in polymake*, :arxiv:`2003.13548`. .. [KPRWZ2010] \M. H. Klin, C. Pech, S. Reichard, A. Woldar, M. Zvi-Av, *Examples of computer experimentation in algebraic @@ -4486,7 +4486,7 @@ REFERENCES: .. [NaiRow2011] Naidu and Rowell, A finiteness property for braided fusion categories. Algebr. Represent. Theory 14 (2011), no. 5, 837–855. - :arXiv:`0903.4157`. + :arxiv:`0903.4157`. .. [NAR2018] Jamie R. Nunez, Christopher R. Anderson, Ryan S. Renslow *Optimizing colormaps with consideration for color vision @@ -5002,7 +5002,7 @@ REFERENCES: .. [Row2006] Eric Rowell, *From quantum groups to unitary modular tensor categories*. In Representations of algebraic groups, quantum groups, and Lie algebras, Contemp. Math., **413**, Amer. Math. Soc., Providence, RI, 2006. - :arXiv:`math/0503226`. + :arxiv:`math/0503226`. .. [RoStWa2009] Eric Rowell, Richard Stong and Zhenghan Wang, *On classification of modular tensor categories*, Comm. Math. Phys. 292, 343--389, 2009. @@ -5087,7 +5087,7 @@ REFERENCES: .. [Sag2011] Bruce E. Sagan, *The cyclic sieving phenomenon: a survey*, - :arXiv:`1008.0790v3` + :arxiv:`1008.0790v3` .. [Sah2000] Sartaj Sahni. *Data Structures, Algorithms, and Applications in Java*. McGraw-Hill, 2000. @@ -5100,12 +5100,11 @@ REFERENCES: York, 1958. .. [Sal1965] \G. Salmon: "A Treatise on the Analytic Geometry of Three - Dimensions", Vol II, Chelsea Publishing Co., New - York, 1965. + Dimensions", Vol II, Chelsea Publishing Co., New York, 1965. .. [Sal2014] \B. Salisbury. The flush statistic on semistandard Young tableaux. - :arXiv:`1401.1185` + :arxiv:`1401.1185` .. [Sam2012] \P. Samanta: *Antipodal Graphs* :doi:`10.13140/RG.2.2.28238.46409` diff --git a/src/sage/combinat/root_system/non_symmetric_macdonald_polynomials.py b/src/sage/combinat/root_system/non_symmetric_macdonald_polynomials.py index cbece412f13..b8eb4af9ab0 100644 --- a/src/sage/combinat/root_system/non_symmetric_macdonald_polynomials.py +++ b/src/sage/combinat/root_system/non_symmetric_macdonald_polynomials.py @@ -355,7 +355,7 @@ class NonSymmetricMacdonaldPolynomials(CherednikOperatorsEigenvectors): .. [LNSSS12] \C. Lenart, S. Naito, D. Sagaki, A. Schilling, M. Shimozono, A uniform model for Kirillov-Reshetikhin crystals I: Lifting - the parabolic quantum Bruhat graph, preprint :arXiv:`1211.2042` + the parabolic quantum Bruhat graph, preprint :arxiv:`1211.2042` [math.QA] .. RUBRIC:: More examples diff --git a/src/sage/rings/number_field/S_unit_solver.py b/src/sage/rings/number_field/S_unit_solver.py index 4e440c36ea0..fd1a5fe824c 100644 --- a/src/sage/rings/number_field/S_unit_solver.py +++ b/src/sage/rings/number_field/S_unit_solver.py @@ -142,7 +142,7 @@ def c3_func(SUK, prec=106): REFERENCES: - - [AKMRVW]_ arXiv:1903.00977 + - [AKMRVW]_ :arxiv:`1903.00977` """ @@ -541,7 +541,7 @@ def Omega_prime(dK, v, mu_list, prec=106): REFERENCES: - - [AKMRVW]_ arXiv:1903:.00977 + - [AKMRVW]_ :arxiv:`1903.00977` """ R = RealField(prec) @@ -645,8 +645,7 @@ def Yu_bound(SUK, v, prec=106): - [Sma1995]_ p. 825 - [Yu2007]_ p. 189--193 esp. Theorem 1 - - [AKMRVW]_ arXiv:1903.00977 - + - [AKMRVW]_ :arxiv:`1903.00977` """ # We are using Theorem 1 of "p-adic logarithmic forms and group varieties III" by Kunrui Yu. @@ -727,7 +726,7 @@ def K0_func(SUK, A, prec=106): REFERENCES: - [Sma1995]_ p. 824 - - [AKMRVW]_ arXiv:1903.00977 + - [AKMRVW]_ :arxiv:`1903.00977` """ R = RealField(prec) diff --git a/src/sage/rings/polynomial/pbori/__init__.py b/src/sage/rings/polynomial/pbori/__init__.py index f168ecd4617..69919bcc916 100644 --- a/src/sage/rings/polynomial/pbori/__init__.py +++ b/src/sage/rings/polynomial/pbori/__init__.py @@ -15,16 +15,16 @@ REFERENCES: M. Brickenstein, A. Dreyer, G. Greuel, M. Wedler, O. Wienand, -New developments in the theory of Groebner bases and applications -to formal Verification, Preprint at http://arxiv.org/abs/0801.1177 +*New developments in the theory of Groebner bases and applications* +to formal Verification, Preprint at :arxiv:`0801.1177` M. Brickenstein, A. Dreyer, PolyBoRi: -A Groebner Basis Framework for Boolean Polynomials, +*A Groebner Basis Framework for Boolean Polynomials*, Reports of Fraunhofer ITWM, No. 122, Kaiserslautern, Germany, 2007. http://www.itwm.fraunhofer.de/zentral/download/berichte/bericht122.pdf M. Brickenstein, A. Dreyer, PolyBoRi: -A framework for Groebner basis computations with Boolean polynomials, +*A framework for Groebner basis computations with Boolean polynomials*, Electronic Proceedings of the MEGA 2007 - Effective Methods in Algebraic Geometry, Strobl, Austria, June 2007. http://www.ricam.oeaw.ac.at/mega2007/electronic/electronic.html """ From 1e1972c367176b657dc811582b6d0f70ef3729df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 24 May 2022 20:41:45 +0200 Subject: [PATCH 462/529] detail --- src/sage/rings/polynomial/pbori/__init__.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/polynomial/pbori/__init__.py b/src/sage/rings/polynomial/pbori/__init__.py index 69919bcc916..8fe962e2275 100644 --- a/src/sage/rings/polynomial/pbori/__init__.py +++ b/src/sage/rings/polynomial/pbori/__init__.py @@ -14,9 +14,10 @@ The PolyBoRi Team, 2007-2011 REFERENCES: + M. Brickenstein, A. Dreyer, G. Greuel, M. Wedler, O. Wienand, -*New developments in the theory of Groebner bases and applications* -to formal Verification, Preprint at :arxiv:`0801.1177` +*New developments in the theory of Groebner bases and applications +to formal Verification*, Preprint at :arxiv:`0801.1177` M. Brickenstein, A. Dreyer, PolyBoRi: *A Groebner Basis Framework for Boolean Polynomials*, From ab156dd97eb921688d7f13082718086e1e409828 Mon Sep 17 00:00:00 2001 From: Julien Grijalva Date: Wed, 25 May 2022 00:15:13 -0600 Subject: [PATCH 463/529] Small fix to sage-bootstrap-python The sage-bootstrap-python script doesn't work with pyenv. For some reason the command "python" is treated differently from python, leading to issues. My fix was to try removing pyenv from the PATH before testing for python. --- build/bin/sage-bootstrap-python | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/build/bin/sage-bootstrap-python b/build/bin/sage-bootstrap-python index 38ceeca0f29..1bd52559acb 100755 --- a/build/bin/sage-bootstrap-python +++ b/build/bin/sage-bootstrap-python @@ -11,7 +11,15 @@ if [ -z "$SAGE_ORIG_PATH" ]; then # If not we're running from within sage-env just set the existing path SAGE_ORIG_PATH="$PATH" fi - +paths=$(echo $SAGE_ORIG_PATH | tr ":" "\n") +NEW_PATH="" +for path in $paths +do + if [[ $path != *"pyenv"* ]]; then + NEW_PATH+="$path:" + fi +done +SAGE_ORIG_PATH=${NEW_PATH::-1} # In particular, it is invoked by "bootstrap -d" for sage-download-file, # i.e., before a configure run, and by "sage-spkg", also for sage-download-file. # So it needs to find a python that has the urllib module. From 4421ac2f879bec4c6508cb85fe616fd92004410a Mon Sep 17 00:00:00 2001 From: Julien Grijalva Date: Wed, 25 May 2022 11:41:49 -0600 Subject: [PATCH 464/529] removed bash-only syntax --- build/bin/sage-bootstrap-python | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/build/bin/sage-bootstrap-python b/build/bin/sage-bootstrap-python index 1bd52559acb..513783b1c21 100755 --- a/build/bin/sage-bootstrap-python +++ b/build/bin/sage-bootstrap-python @@ -15,9 +15,10 @@ paths=$(echo $SAGE_ORIG_PATH | tr ":" "\n") NEW_PATH="" for path in $paths do - if [[ $path != *"pyenv"* ]]; then - NEW_PATH+="$path:" - fi + case "$path" in + *"pyenv"*);; + * ) NEW_PATH+="$path:";; + esac done SAGE_ORIG_PATH=${NEW_PATH::-1} # In particular, it is invoked by "bootstrap -d" for sage-download-file, From 50d92726ed8087fe252c1ef20e81f76e77dea4b2 Mon Sep 17 00:00:00 2001 From: Julien Grijalva Date: Wed, 25 May 2022 11:52:24 -0600 Subject: [PATCH 465/529] += gave strange not found errors --- build/bin/sage-bootstrap-python | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/bin/sage-bootstrap-python b/build/bin/sage-bootstrap-python index 513783b1c21..ab5e6e70ac4 100755 --- a/build/bin/sage-bootstrap-python +++ b/build/bin/sage-bootstrap-python @@ -17,7 +17,7 @@ for path in $paths do case "$path" in *"pyenv"*);; - * ) NEW_PATH+="$path:";; + * ) NEW_PATH="$NEW_PATH$path:";; esac done SAGE_ORIG_PATH=${NEW_PATH::-1} From cd208701e75de1ff3fc10b069e16f538b16d0488 Mon Sep 17 00:00:00 2001 From: Julien Grijalva Date: Wed, 25 May 2022 12:07:28 -0600 Subject: [PATCH 466/529] now works in dash shell The extra : at the end of PATH is irrelevant, the code to remove it had bash-only syntax. Additionally the script now checks if the tr command exists before using it. --- build/bin/sage-bootstrap-python | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/build/bin/sage-bootstrap-python b/build/bin/sage-bootstrap-python index ab5e6e70ac4..7afad3ed7bf 100755 --- a/build/bin/sage-bootstrap-python +++ b/build/bin/sage-bootstrap-python @@ -11,16 +11,19 @@ if [ -z "$SAGE_ORIG_PATH" ]; then # If not we're running from within sage-env just set the existing path SAGE_ORIG_PATH="$PATH" fi -paths=$(echo $SAGE_ORIG_PATH | tr ":" "\n") -NEW_PATH="" -for path in $paths -do - case "$path" in - *"pyenv"*);; - * ) NEW_PATH="$NEW_PATH$path:";; - esac -done -SAGE_ORIG_PATH=${NEW_PATH::-1} +if command -v tr &> /dev/null +then + paths=$(echo $SAGE_ORIG_PATH | tr ":" "\n") + NEW_PATH="" + for path in $paths + do + case "$path" in + *"pyenv"*);; + * ) NEW_PATH="$NEW_PATH$path:";; + esac + done + SAGE_ORIG_PATH=$NEW_PATH +fi # In particular, it is invoked by "bootstrap -d" for sage-download-file, # i.e., before a configure run, and by "sage-spkg", also for sage-download-file. # So it needs to find a python that has the urllib module. From 15cd6fec54a83db8b59373c66873d8bcd4c3ae51 Mon Sep 17 00:00:00 2001 From: Julien Grijalva Date: Wed, 25 May 2022 12:27:37 -0600 Subject: [PATCH 467/529] loop is pure sh with IFS instead of using tr --- build/bin/sage-bootstrap-python | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/build/bin/sage-bootstrap-python b/build/bin/sage-bootstrap-python index 7afad3ed7bf..6c3e20010e0 100755 --- a/build/bin/sage-bootstrap-python +++ b/build/bin/sage-bootstrap-python @@ -11,19 +11,17 @@ if [ -z "$SAGE_ORIG_PATH" ]; then # If not we're running from within sage-env just set the existing path SAGE_ORIG_PATH="$PATH" fi -if command -v tr &> /dev/null -then - paths=$(echo $SAGE_ORIG_PATH | tr ":" "\n") - NEW_PATH="" - for path in $paths - do - case "$path" in - *"pyenv"*);; - * ) NEW_PATH="$NEW_PATH$path:";; - esac - done - SAGE_ORIG_PATH=$NEW_PATH -fi +IFS=':' +NEW_PATH="" +for path in $SAGE_ORIG_PATH +do + case "$path" in + *"pyenv"*);; + * ) NEW_PATH="$NEW_PATH$path:";; + esac +done +IFS=' ' +SAGE_ORIG_PATH=$NEW_PATH # In particular, it is invoked by "bootstrap -d" for sage-download-file, # i.e., before a configure run, and by "sage-spkg", also for sage-download-file. # So it needs to find a python that has the urllib module. From b8ad9f044dc8fec23a6821cbdf892ec51254b321 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 25 May 2022 20:36:51 +0200 Subject: [PATCH 468/529] remove deprecation in nonexact.py --- src/sage/structure/nonexact.py | 31 ++++--------------------------- 1 file changed, 4 insertions(+), 27 deletions(-) diff --git a/src/sage/structure/nonexact.py b/src/sage/structure/nonexact.py index 913f42c9b19..4157295be90 100644 --- a/src/sage/structure/nonexact.py +++ b/src/sage/structure/nonexact.py @@ -1,8 +1,8 @@ r""" Precision management for non-exact objects -Manage the default precision for non-exact objects such as power series rings or -laurent series rings. +Manage the default precision for non-exact objects such as power series rings +or Laurent series rings. EXAMPLES:: @@ -25,12 +25,11 @@ .. NOTE:: Subclasses of :class:`Nonexact` which require to change the default - precision should implement a method `set_default_prec`. - + precision should implement a method ``set_default_prec``. """ - from sage.rings.integer import Integer + class Nonexact: r""" A non-exact object with default precision. @@ -39,7 +38,6 @@ class Nonexact: - ``prec`` -- a non-negative integer representing the default precision of ``self`` (default: ``20``) - """ def __init__(self, prec=20): if prec < 0: @@ -61,30 +59,9 @@ def default_prec(self): sage: R. = PowerSeriesRing(QQ, default_prec=10) sage: R.default_prec() 10 - """ try: return self._default_prec except AttributeError: self._default_prec = 20 return self._default_prec - - def set_default_prec(self, prec): - r""" - Set the default precision for ``self`` - - .. WARNING:: - - This method is outdated. If a subclass of class:`Nonexact` requires - this method, please overload it instead. - - """ - # TODO: remove in Sage 9.4 - from sage.misc.superseded import deprecation - msg = "The method set_default_prec() is deprecated and will be removed " - msg += "in a future version of Sage. The default precision is set " - msg += "during construction." - deprecation(18416, msg) - self._default_prec = Integer(prec) - - From c7a6dfa795c6b8e68cf4fcc5449bcf964ddc34a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 25 May 2022 21:22:10 +0200 Subject: [PATCH 469/529] some pep cleanup in dynamics --- .../arithmetic_dynamics/berkovich_ds.py | 4 +- .../endPN_automorphism_group.py | 20 +++---- .../endPN_minimal_model.py | 9 ++- .../product_projective_ds.py | 8 +-- .../arithmetic_dynamics/projective_ds.py | 7 +-- .../dynamics/arithmetic_dynamics/wehlerK3.py | 58 ++++++++++--------- src/sage/dynamics/cellular_automata/all.py | 1 - .../dynamics/cellular_automata/elementary.py | 1 + src/sage/dynamics/cellular_automata/glca.py | 1 - .../dynamics/complex_dynamics/mandel_julia.py | 5 +- src/sage/dynamics/finite_dynamical_system.py | 3 +- .../finite_dynamical_system_catalog.py | 15 +++-- 12 files changed, 70 insertions(+), 62 deletions(-) diff --git a/src/sage/dynamics/arithmetic_dynamics/berkovich_ds.py b/src/sage/dynamics/arithmetic_dynamics/berkovich_ds.py index ce540d77f73..0301d68b8c9 100644 --- a/src/sage/dynamics/arithmetic_dynamics/berkovich_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/berkovich_ds.py @@ -858,8 +858,8 @@ def __call__(self, x, type_3_pole_check=True): num = fraction[0].quo_rem(gcd)[0] dem = fraction[1].quo_rem(gcd)[0] if dem.is_zero(): - f = DynamicalSystem_affine(F[0]/F[1]).homogenize(1) - f = f.conjugate(Matrix([[0, 1], [1 , 0]])) + f = DynamicalSystem_affine(F[0] / F[1]).homogenize(1) + f = f.conjugate(Matrix([[0, 1], [1, 0]])) g = DynamicalSystem_Berkovich(f) return g(self.domain()(QQ(0), QQ(1))).involution_map() # if the reduction is not constant, the image is the Gauss point diff --git a/src/sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py b/src/sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py index 93948cf6014..2b6edd2d2c8 100644 --- a/src/sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py +++ b/src/sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py @@ -197,8 +197,7 @@ def automorphism_group_QQ_fixedpoints(rational_function, return_functions=False, [(alpha - zeta*beta), - (alpha*beta)*(1 - zeta), (1 - zeta), (alpha*zeta - beta)])) - - #now consider 2-periodic points + # now consider 2-periodic points psi = phi(phi(z)) f2 = psi.numerator() g2 = psi.denominator() @@ -252,7 +251,7 @@ def automorphism_group_QQ_fixedpoints(rational_function, return_functions=False, a = F(a) d = F(d) b = F(-alpha*beta) - s = ( a*z + b)/(z + d) + s = (a * z + b) / (z + d) if s(phi(z)) == phi(s(z)): if return_functions: elements.append(K(s)) @@ -268,7 +267,7 @@ def automorphism_group_QQ_fixedpoints(rational_function, return_functions=False, a = F(a) d = F(d) b = F(-alpha*beta) - s = ( a*z + b)/(z + d) + s = (a * z + b) / (z + d) if s(phi(z)) == phi(s(z)): if return_functions: elements.append(K(s)) @@ -534,7 +533,7 @@ def valid_automorphisms(automorphisms_CRT, rational_function, ht_bound, M, for x in init_lift] g = gcd(new_lift) new_lift = [x // g for x in new_lift] - if all(abs(x) <= ht_bound for x in new_lift): + if all(abs(x) <= ht_bound for x in new_lift): a, b, c, d = new_lift f = (a*z + b) / (c*z + d) if rational_function(f(z)) == f(rational_function(z)): @@ -1004,9 +1003,10 @@ def rational_function_coefficient_descent(rational_function, sigma, poly_ring): return z = poly_ring.gen(0) - numer = sum( poly_ring(ff[i])*z**fe[i] for i in range(len(ff)) ) - denom = sum( poly_ring(gg[i])*z**ge[i] for i in range(len(gg)) ) - return numer / denom + numer = sum(poly_ring(ff[i]) * z**fe[i] for i in range(len(ff))) + denom = sum(poly_ring(gg[i]) * z**ge[i] for i in range(len(gg))) + return numer / denom + def rational_function_coerce(rational_function, sigma, S_polys): r""" @@ -1626,7 +1626,7 @@ def automorphism_group_FF_alg3(rational_function): if n%p == 1: automorphisms = automorphisms + order_p_automorphisms(phi, pre_images) - ## nontrivial elements with order prime to p ## + # nontrivial elements with order prime to p # # case of 2 F-rational fixed points for pt_pair in combinations(linear_fix_pts, 2): x = pt_pair[0] @@ -1756,7 +1756,7 @@ def which_group(list_of_elements): for i in range(n-1): h = g(H[-1]) H.append(h) - H = list(set(H)) + H = list(set(H)) if len(H) == n: return 'Cyclic of order {0}'.format(n) if len(H) > max_reg_cyclic[0] and gcd(len(H), p) != p: diff --git a/src/sage/dynamics/arithmetic_dynamics/endPN_minimal_model.py b/src/sage/dynamics/arithmetic_dynamics/endPN_minimal_model.py index 06890a8eb02..9c6d5a2dd52 100644 --- a/src/sage/dynamics/arithmetic_dynamics/endPN_minimal_model.py +++ b/src/sage/dynamics/arithmetic_dynamics/endPN_minimal_model.py @@ -548,7 +548,7 @@ def BM_all_minimal(vp, return_transformation=False, D=None): z = aff_map.domain().gen(0) Res = mp.resultant() - ##### because of how the bound is compute in lemma 3.3 + # because of how the bound is compute in lemma 3.3 from sage.dynamics.arithmetic_dynamics.affine_ds import DynamicalSystem_affine h = f - z*g A = AffineSpace(BR, 1, h.parent().variable_name()) @@ -1121,14 +1121,14 @@ def coshdelta(z): G, g, v, rep, M, D, label = pts.pop() # apply ST and keep z, Sz if D > R: - break #all remaining pts are too far away + break # all remaining pts are too far away # check if it is smaller. If so, we can improve the bound count += 1 new_size = e**g.global_height(prec=prec) if new_size < current_size: - current_min = [G ,g, v, rep, M, coshdelta(v)] + current_min = [G, g, v, rep, M, coshdelta(v)] current_size = new_size - if new_size == 1: # early exit + if new_size == 1: # early exit return [current_min[1], current_min[4]] new_R = get_bound_dynamical(G, g, m=n, dynatomic=dynatomic, prec=prec, emb=emb) if new_R < R: @@ -1156,4 +1156,3 @@ def coshdelta(z): pts = insert_item(pts, new_pt, 5) return [current_min[1], current_min[4]] - diff --git a/src/sage/dynamics/arithmetic_dynamics/product_projective_ds.py b/src/sage/dynamics/arithmetic_dynamics/product_projective_ds.py index 825fdf9187a..cc9cbf8dd47 100644 --- a/src/sage/dynamics/arithmetic_dynamics/product_projective_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/product_projective_ds.py @@ -278,18 +278,18 @@ def nth_iterate_map(self, n): PHI = list(Coord_ring.gens()) while D: - if D&1: + if D & 1: PHI = [poly(*F) for poly in PHI] - if D > 1: #avoid extra iterate - F = [poly(*F) for poly in F] #'square' + if D > 1: # avoid extra iterate + F = [poly(*F) for poly in F] # 'square' D >>= 1 return DynamicalSystem_projective(PHI, domain=self.domain()) class DynamicalSystem_product_projective_field(DynamicalSystem_product_projective): - pass + class DynamicalSystem_product_projective_finite_field(DynamicalSystem_product_projective_field): def cyclegraph(self): diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py index c78a7e83472..5c5c373907f 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py @@ -973,7 +973,7 @@ def nth_iterate_map(self, n, normalize=False): else: PHI = H([Coord_ring.gen(i) for i in range(N)]) while D: - if D&1: + if D & 1: PHI = PHI*F if normalize: PHI.normalize_coordinates() @@ -2029,7 +2029,7 @@ def canonical_height(self, P, **kwds): # this looks different than Wells' Algorithm because of the difference # between what Wells' calls H_infty, # and what Green's Function returns for the infinite place - h = f.green_function(Q, 0 , **kwds) - H + R(t).log() + h = f.green_function(Q, 0, **kwds) - H + R(t).log() # The value returned by Well's algorithm may be negative. As the canonical height # is always nonnegative, so if this value is within -err of 0, return 0. if h < 0: @@ -3359,7 +3359,7 @@ def automorphism_group(self, **kwds): num_cpus = kwds.get('num_cpus', 2) if self.domain().dimension_relative() != 1: return self.conjugating_set(self, num_cpus) - if self.base_ring() != QQ and self.base_ring() != ZZ: + if self.base_ring() != QQ and self.base_ring() != ZZ: return self.conjugating_set(self, num_cpus) self.normalize_coordinates() if (self.degree() == 1) or (self.degree() == 0): @@ -3748,7 +3748,6 @@ def is_dynamical_belyi_map(self): return False return True - def critical_point_portrait(self, check=True, use_algebraic_closure=True): r""" If this dynamical system is post-critically finite, return its diff --git a/src/sage/dynamics/arithmetic_dynamics/wehlerK3.py b/src/sage/dynamics/arithmetic_dynamics/wehlerK3.py index 7e4ae461348..8f5f1f6a690 100644 --- a/src/sage/dynamics/arithmetic_dynamics/wehlerK3.py +++ b/src/sage/dynamics/arithmetic_dynamics/wehlerK3.py @@ -747,15 +747,12 @@ def is_degenerate(self): self.Hpoly(0, 0, 2), self.Hpoly(0, 1, 2)) phi = R.hom([0, 0, 0] + vars, R0) I = phi(I) - if I.dimension() != 0: - return True - return False - + return I.dimension() != 0 def degenerate_fibers(self): r""" - Function will return the (rational) degenerate fibers of the surface - defined over the base ring, or the fraction field of the base ring if it is not a field. + Return the (rational) degenerate fibers of the surface defined over + the base ring, or the fraction field of the base ring if it is not a field. ALGORITHM: @@ -828,7 +825,7 @@ def degenerate_fibers(self): J = phi1(I) if (J.dimension() == 0): Var = J.variety() - if Var != [{}]: + if Var != [{}]: for d in Var: #iterate through dictionaries P = [] #new point for z in mapvars: #assign coordinate values @@ -859,7 +856,7 @@ def degenerate_fibers(self): J = phi1(I) if (J.dimension() == 0): Var = J.variety() - if Var != [{}]: + if Var != [{}]: for d in Var: #iterate through dictionaries P = [] #new point for z in mapvars: #assign coordinate values @@ -1170,7 +1167,7 @@ def sigmaX(self, P, **kwds): e += 1 maxexp.append(e) - e = min(maxexp) + e = min(maxexp) #Fix L and Q for i in range(0,2): @@ -1423,10 +1420,10 @@ def sigmaY(self,P, **kwds): T[i] = T[i]/t**e T[i] = T[i].subs({w1:t1}) - #Defines the ideal whose solution gives `(s0,s1)` and the two points - #on the fiber - RR = PolynomialRing(BR ,5, 's0, s1, z0, z1, z2', order = 'lex') - s0,s1,z0,z1,z2 = RR.gens() + # Defines the ideal whose solution gives `(s0,s1)` and the two points + # on the fiber + RR = PolynomialRing(BR, 5, 's0, s1, z0, z1, z2', order='lex') + s0, s1, z0, z1, z2 = RR.gens() I = RR.ideal([RR(T[0]), \ RR(T[1]), \ RR(T[2]) - P[0][0]*z0, \ @@ -1448,11 +1445,11 @@ def sigmaY(self,P, **kwds): #the corresponding point on the surface if len(V) > 2: raise ValueError("cannot distinguish points in the degenerate fiber") - #We always expect to have the trivial solution (0, 0, 0) - if len(V) == 2: + # We always expect to have the trivial solution (0, 0, 0) + if len(V) == 2: for D in V: if D[s] != 0: - [a, b, c] = [D[z0], D[z1], D[z2]] + a, b, c = [D[z0], D[z1], D[z2]] else: newT = [phi(tee) for tee in T] for i in range(2): @@ -1478,10 +1475,10 @@ def sigmaY(self,P, **kwds): SS(newT[5]) - (P[0][0]*z1 + P[0][1]*z0), \ SS(newT[6]) - (P[0][0]*z2 + P[0][2]*z0), \ SS(newT[7]) - (P[0][1]*z2 + P[0][2]*z1)]) - #Find the points - SSS = PolynomialRing(BR, 3, 'z0, z1, z2',order = 'lex') - z0,z1,z2 = SSS.gens() - phi = SS.hom([0, z0, z1 ,z2], SSS) + # Find the points + SSS = PolynomialRing(BR, 3, 'z0, z1, z2', order='lex') + z0, z1, z2 = SSS.gens() + phi = SS.hom([0, z0, z1, z2], SSS) J2 = phi(II) if J2.dimension() > 0: raise ValueError("cannot distinguish points in the degenerate fiber") @@ -2101,21 +2098,27 @@ def fiber(self, p, component): elif self.Hpoly(component, 0, 1)(P0) != 0: if component == 1: Points.append(P+[Zero, One, Zero]) - Points.append(P+[-self.Hpoly(component, 0, 1)(P0),Zero,-self.Hpoly(component, 1, 2)(P0)]) + Points.append(P+[-self.Hpoly(component, 0, 1)(P0),Zero, + -self.Hpoly(component, 1, 2)(P0)]) Points.append(P+[One,Zero,Zero]) - Points.append(P+[Zero,-self.Hpoly(component, 0, 1)(P0),-self.Hpoly(component, 0, 2)(P0)]) + Points.append(P+[Zero,-self.Hpoly(component, 0, 1)(P0), + -self.Hpoly(component, 0, 2)(P0)]) else: Points.append([Zero,One,Zero]+P) - Points.append([-self.Hpoly(component, 0, 1)(P0),Zero,-self.Hpoly(component, 1, 2)(P0)] + P) + Points.append([-self.Hpoly(component, 0, 1)(P0),Zero, + -self.Hpoly(component, 1, 2)(P0)] + P) Points.append([One,Zero,Zero]+P) - Points.append([Zero,-self.Hpoly(component, 0, 1)(P0),-self.Hpoly(component, 0, 2)(P0)] + P) + Points.append([Zero,-self.Hpoly(component, 0, 1)(P0), + -self.Hpoly(component, 0, 2)(P0)] + P) elif self.Hpoly(component, 0, 2)(P0) != 0: if component == 1: Points.append(P+[Zero, Zero, One]) - Points.append(P+[-self.Hpoly(component, 0, 2)(P0),-self.Hpoly(component, 1, 2)(P0), Zero]) + Points.append(P+[-self.Hpoly(component, 0, 2)(P0), + -self.Hpoly(component, 1, 2)(P0), Zero]) else: Points.append([Zero, Zero, One]+P) - Points.append([-self.Hpoly(component, 0, 2)(P0),-self.Hpoly(component, 1, 2)(P0), Zero]+ P) + Points.append([-self.Hpoly(component, 0, 2)(P0), + -self.Hpoly(component, 1, 2)(P0), Zero] + P) elif self.Hpoly(component, 1, 2)(P0) != 0: if component == 1: Points.append(P + [Zero, Zero, One]) @@ -2487,12 +2490,13 @@ def cardinality( self): """ def getPx1(): return ([x, y, 1] for x in self.base_ring() for y in self.base_ring()) + def getPx2(): return ([x, 1, 0] for x in self.base_ring()) Count = 0 Xpoint = [1, 0, 0] Ypoint = [1, 0, 0] - #Create all possible Px1 Values + # Create all possible Px1 Values for i in getPx1(): for j in getPx1(): A = i + j diff --git a/src/sage/dynamics/cellular_automata/all.py b/src/sage/dynamics/cellular_automata/all.py index 792411f5b75..9f13ad1c13a 100644 --- a/src/sage/dynamics/cellular_automata/all.py +++ b/src/sage/dynamics/cellular_automata/all.py @@ -3,4 +3,3 @@ from sage.misc.lazy_import import lazy_import lazy_import("sage.dynamics.cellular_automata.solitons", ["SolitonCellularAutomata", "PeriodicSolitonCellularAutomata"]) - diff --git a/src/sage/dynamics/cellular_automata/elementary.py b/src/sage/dynamics/cellular_automata/elementary.py index c51b7d3377e..edd6d77aaa9 100644 --- a/src/sage/dynamics/cellular_automata/elementary.py +++ b/src/sage/dynamics/cellular_automata/elementary.py @@ -394,6 +394,7 @@ def evolve(self, number=None): prev_state = self._states[-1] next_state = [None] * self._width + def to_int(triple): return ZZ(list(reversed(triple)), base=2) if self._bdry is None: diff --git a/src/sage/dynamics/cellular_automata/glca.py b/src/sage/dynamics/cellular_automata/glca.py index af47f66d360..aa94be0cb5c 100644 --- a/src/sage/dynamics/cellular_automata/glca.py +++ b/src/sage/dynamics/cellular_automata/glca.py @@ -475,4 +475,3 @@ def _latex_(self): x -= 1 ret += "\\end{tikzpicture}" return ret - diff --git a/src/sage/dynamics/complex_dynamics/mandel_julia.py b/src/sage/dynamics/complex_dynamics/mandel_julia.py index 0dcee498874..32a15ba19c5 100644 --- a/src/sage/dynamics/complex_dynamics/mandel_julia.py +++ b/src/sage/dynamics/complex_dynamics/mandel_julia.py @@ -757,13 +757,12 @@ def julia_plot(f=None, **kwds): return interact(**widgets).widget(julia_helper) else: return interact(**widgets).widget(fast_julia_plot) - elif mandelbrot: # non-interactive with mandelbrot + elif mandelbrot: # non-interactive with mandelbrot return julia_helper(c_real, c_imag, x_center, y_center, image_width, max_iteration, pixel_count, level_sep, number_of_colors, base_color, point_color) - else: # non-interactive without mandelbrot + else: # non-interactive without mandelbrot return fast_julia_plot(c_real, c_imag, x_center, y_center, image_width, max_iteration, pixel_count, level_sep, number_of_colors, base_color) - diff --git a/src/sage/dynamics/finite_dynamical_system.py b/src/sage/dynamics/finite_dynamical_system.py index b7710f0e8ae..e5fbf568b7e 100644 --- a/src/sage/dynamics/finite_dynamical_system.py +++ b/src/sage/dynamics/finite_dynamical_system.py @@ -459,6 +459,7 @@ def evolution_power(self, n): if n not in NN: raise ValueError("the n-th power of evolution is only defined for nonnegative integers n") ev = self.evolution() + def evn(x): y = x for _ in range(n): @@ -820,6 +821,7 @@ def evolution_power(self, n): else: ev = self.inverse_evolution() n = -n + def evn(x): y = x for _ in range(n): @@ -1249,4 +1251,3 @@ def orbit_lengths(self): [2, 2, 2] """ return [len(orb) for orb in self.orbits()] - diff --git a/src/sage/dynamics/finite_dynamical_system_catalog.py b/src/sage/dynamics/finite_dynamical_system_catalog.py index fc925c2d5cf..3ba09eb9948 100755 --- a/src/sage/dynamics/finite_dynamical_system_catalog.py +++ b/src/sage/dynamics/finite_dynamical_system_catalog.py @@ -83,12 +83,14 @@ def one_line(xs): [2] """ n = len(xs) - X = range(1, n+1) + X = range(1, n + 1) xs2 = tuple(xs) + def pi(i): return xs2[i - 1] return FiniteDynamicalSystem(X, pi, create_tuple=True) + def bitstring_rotation(n, ones=None): r""" Return the invertible finite discrete dynamical system @@ -231,12 +233,14 @@ def striker_sweep(E, predicate, elements, lazy=False): from sage.combinat.subset import Subsets from sage.sets.set import Set X = [F for F in Subsets(E) if predicate(F)] + def phi(F): for e in elements: G = F.symmetric_difference(Set([e])) if predicate(G): F = G return F + def psi(F): for e in reversed(elements): G = F.symmetric_difference(Set([e])) @@ -245,6 +249,7 @@ def psi(F): return F return InvertibleFiniteDynamicalSystem(X, phi, inverse=psi) + def syt_promotion(lam): r""" Return the invertible finite discrete dynamical system @@ -266,10 +271,12 @@ def syt_promotion(lam): True """ from sage.combinat.partition import Partition - lam = Partition(lam) from sage.combinat.tableau import StandardTableaux + lam = Partition(lam) X = StandardTableaux(lam) - return InvertibleFiniteDynamicalSystem(X, lambda T : T.promotion(), inverse=lambda T : T.promotion_inverse()) + return InvertibleFiniteDynamicalSystem(X, lambda T: T.promotion(), + inverse=lambda T: T.promotion_inverse()) + def order_ideal_rowmotion(P): r""" @@ -361,9 +368,9 @@ def bulgarian_solitaire(n): """ from sage.combinat.partition import Partition, Partitions X = Partitions(n) + def phi(lam): mu = [p - 1 for p in lam if p > 0] nu = sorted(mu + [len(lam)], reverse=True) return Partition(nu) return FiniteDynamicalSystem(X, phi) - From ba6d42ebe8567ad038e058ca647606194e7d923d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 25 May 2022 21:34:46 +0200 Subject: [PATCH 470/529] pep and other details in dynamics --- .../dynamics/arithmetic_dynamics/affine_ds.py | 8 +++--- .../endPN_automorphism_group.py | 2 +- .../arithmetic_dynamics/generic_ds.py | 2 +- .../product_projective_ds.py | 2 +- .../arithmetic_dynamics/projective_ds.py | 26 +++++++++---------- .../dynamics/cellular_automata/elementary.py | 4 +-- src/sage/dynamics/cellular_automata/glca.py | 4 +-- .../dynamics/cellular_automata/solitons.py | 4 +-- .../dynamics/complex_dynamics/mandel_julia.py | 10 +++---- .../complex_dynamics/mandel_julia_helper.pyx | 2 +- 10 files changed, 31 insertions(+), 33 deletions(-) diff --git a/src/sage/dynamics/arithmetic_dynamics/affine_ds.py b/src/sage/dynamics/arithmetic_dynamics/affine_ds.py index a4f03f439bf..9db7b91f8db 100644 --- a/src/sage/dynamics/arithmetic_dynamics/affine_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/affine_ds.py @@ -276,7 +276,7 @@ def __classcall_private__(cls, morphism_or_polys, domain=None): polys = [PR(poly) for poly in polys] if domain is None: if isinstance(PR, sage.rings.abc.SymbolicRing): - raise TypeError("Symbolic Ring cannot be the base ring") + raise TypeError("symbolic ring cannot be the base ring") if fraction_field: PR = PR.ring() domain = AffineSpace(PR) @@ -290,17 +290,17 @@ def __classcall_private__(cls, morphism_or_polys, domain=None): except TypeError: raise TypeError('coefficients of polynomial not in {}'.format(domain.base_ring())) if len(polys) != domain.ambient_space().coordinate_ring().ngens(): - raise ValueError('Number of polys does not match dimension of {}'.format(domain)) + raise ValueError(f'number of polys does not match dimension of {domain}') R = domain.base_ring() if isinstance(R, sage.rings.abc.SymbolicRing): - raise TypeError("Symbolic Ring cannot be the base ring") + raise TypeError("symbolic ring cannot be the base ring") if not is_AffineSpace(domain) and not isinstance(domain, AlgebraicScheme_subscheme_affine): raise ValueError('"domain" must be an affine scheme') if R not in Fields(): return typecall(cls, polys, domain) if is_FiniteField(R): - return DynamicalSystem_affine_finite_field(polys, domain) + return DynamicalSystem_affine_finite_field(polys, domain) return DynamicalSystem_affine_field(polys, domain) def __init__(self, polys_or_rat_fncts, domain): diff --git a/src/sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py b/src/sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py index 2b6edd2d2c8..91af87e49dd 100644 --- a/src/sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py +++ b/src/sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py @@ -2017,7 +2017,7 @@ def conjugating_set_initializer(f, g): # in which all subsets of size n+1 are linearly independent, # then we fail as we cannot specify conjugations if more: - raise ValueError('no more rational preimages. try extending the base field and trying again.') + raise ValueError('no more rational preimages; try extending the base field and trying again') # if we need to add more preimages, we update loop dictionaries if more: diff --git a/src/sage/dynamics/arithmetic_dynamics/generic_ds.py b/src/sage/dynamics/arithmetic_dynamics/generic_ds.py index b3b66856b5c..3e227942256 100644 --- a/src/sage/dynamics/arithmetic_dynamics/generic_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/generic_ds.py @@ -401,7 +401,7 @@ def field_of_definition_critical(self, return_embedding=False, simplify_all=Fals space = ds.domain().ambient_space() K = ds.base_ring() if space.dimension() != 1: - raise ValueError('Ambient space of dynamical system must be either the affine line or projective line') + raise ValueError('ambient space of dynamical system must be either the affine line or projective line') if isinstance(K, (AlgebraicClosureFiniteField_generic, AlgebraicField_common)): if return_embedding: return (K, K.hom(K)) diff --git a/src/sage/dynamics/arithmetic_dynamics/product_projective_ds.py b/src/sage/dynamics/arithmetic_dynamics/product_projective_ds.py index cc9cbf8dd47..867d571db0d 100644 --- a/src/sage/dynamics/arithmetic_dynamics/product_projective_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/product_projective_ds.py @@ -331,6 +331,6 @@ def cyclegraph(self): Q = self(P) E.append([str(Q)]) else: - raise NotImplementedError("Cyclegraph for product projective spaces not implemented for subschemes") + raise NotImplementedError("cyclegraph for product projective spaces not implemented for subschemes") from sage.graphs.digraph import DiGraph return DiGraph(dict(zip(V, E)), loops=True) diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py index 5c5c373907f..dc8344b672d 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py @@ -419,7 +419,7 @@ def __classcall_private__(cls, morphism_or_polys, domain=None, names=None): except TypeError: raise TypeError('coefficients of polynomial not in {}'.format(domain.base_ring())) if len(polys) != domain.ambient_space().coordinate_ring().ngens(): - raise ValueError('Number of polys does not match dimension of {}'.format(domain)) + raise ValueError(f'number of polys does not match dimension of {domain}') R = domain.base_ring() if isinstance(R, sage.rings.abc.SymbolicRing): raise TypeError("the base ring cannot be the Symbolic Ring or a symbolic subring") @@ -3150,10 +3150,10 @@ def affine_preperiodic_model(self, m, n, return_conjugation=False): """ n = ZZ(n) if n < 1: - raise ValueError('Period must be positive') + raise ValueError('period must be positive') m = ZZ(m) if m < 0: - raise ValueError('Preperiod must be non-negative') + raise ValueError('preperiod must be non-negative') f = self CR = f.coordinate_ring() dom = f.domain() @@ -3363,7 +3363,7 @@ def automorphism_group(self, **kwds): return self.conjugating_set(self, num_cpus) self.normalize_coordinates() if (self.degree() == 1) or (self.degree() == 0): - raise NotImplementedError("Rational function of degree 1 not implemented.") + raise NotImplementedError("rational function of degree 1 not implemented") f = self.dehomogenize(1) R = PolynomialRing(f.base_ring(),'x') if is_FractionFieldElement(f[0]): @@ -4186,8 +4186,8 @@ def preperiodic_points(self, m, n, **kwds): f_sub = self.change_ring(R) R = f_sub.base_ring() #in the case when R is an embedding if isinstance(R, FractionField_1poly_field) or is_FunctionField(R): - raise NotImplementedError('Periodic points not implemented for function fields.' - + 'Clear denominators and use the polynomial ring instead.') + raise NotImplementedError('Periodic points not implemented for function fields; ' + 'clear denominators and use the polynomial ring instead') CR = f_sub.coordinate_ring() dom = f_sub.domain() PS = f_sub.codomain().ambient_space() @@ -4517,12 +4517,12 @@ def periodic_points(self, n, minimal=True, formal=False, R=None, algorithm='vari f_sub = self.change_ring(R) R = f_sub.base_ring() #in the case when R is an embedding if isinstance(R, FractionField_1poly_field) or is_FunctionField(R): - raise NotImplementedError('Periodic points not implemented for fraction function fields.' - + 'Clear denominators and use the polynomial ring instead.') + raise NotImplementedError('periodic points not implemented for fraction function fields; ' + 'clear denominators and use the polynomial ring instead') if is_FractionField(R): if is_MPolynomialRing(R.ring()): - raise NotImplementedError('Periodic points not implemented for fraction function fields.' - + 'Clear denominators and use the polynomial ring instead.') + raise NotImplementedError('periodic points not implemented for fraction function fields; ' + 'clear denominators and use the polynomial ring instead') CR = f_sub.coordinate_ring() dom = f_sub.domain() PS = f_sub.codomain().ambient_space() @@ -5309,8 +5309,8 @@ def sigma_invariants(self, n, formal=False, embedding=None, type='point', else: expected_degree = sum(d**(n*i) for i in range(N+1)) if degree_w != expected_degree: - raise ValueError('sigma polynomial dropped degree, as multiplicities were not accounted for correctly.'+ - ' try setting chow=True and/or deform=True') + raise ValueError('sigma polynomial dropped degree, as multiplicities were not accounted for correctly; ' + 'try setting chow=True and/or deform=True') if return_polynomial: return sigma_polynomial # if we are returing a numerical list, read off the coefficients @@ -8327,7 +8327,7 @@ def automorphism_group(self, **kwds): z = f[0].parent().gen() self.normalize_coordinates() if (self.degree() == 1) or (self.degree() == 0): - raise NotImplementedError("Rational function of degree 1 not implemented.") + raise NotImplementedError("rational function of degree 1 not implemented") if f[0].denominator() != 1: F = f[0].numerator().polynomial(z) / f[0].denominator().polynomial(z) else: diff --git a/src/sage/dynamics/cellular_automata/elementary.py b/src/sage/dynamics/cellular_automata/elementary.py index edd6d77aaa9..cd0915cdde7 100644 --- a/src/sage/dynamics/cellular_automata/elementary.py +++ b/src/sage/dynamics/cellular_automata/elementary.py @@ -388,7 +388,7 @@ def evolve(self, number=None): X X XX """ if number is not None: - for k in range(number): + for _ in range(number): self.evolve() return @@ -583,7 +583,7 @@ def _unicode_art_(self): █ █ █ █ █ █ █ █ ███ ███ ███ ███ ███ ███ ███ ██ """ - return UnicodeArt([u''.join(u'█' if x else u' ' for x in state) + return UnicodeArt([''.join('█' if x else ' ' for x in state) for state in self._states]) def plot(self, number=None): diff --git a/src/sage/dynamics/cellular_automata/glca.py b/src/sage/dynamics/cellular_automata/glca.py index aa94be0cb5c..46b24619ac2 100644 --- a/src/sage/dynamics/cellular_automata/glca.py +++ b/src/sage/dynamics/cellular_automata/glca.py @@ -196,14 +196,14 @@ def evolve(self, number=None): o o o o o o o """ if number is not None: - for k in range(number): + for _ in range(number): self.evolve() return prev_state = self._states[-1] next_state = [0] * (len(prev_state) + 2) - for i,val in enumerate(prev_state): + for i, val in enumerate(prev_state): next_state[i] += self._rule[val] & 0x1 next_state[i+1] += self._rule[val] & 0x2 next_state[i+2] += self._rule[val] & 0x4 diff --git a/src/sage/dynamics/cellular_automata/solitons.py b/src/sage/dynamics/cellular_automata/solitons.py index 5113084f8d6..7ae254ed69f 100644 --- a/src/sage/dynamics/cellular_automata/solitons.py +++ b/src/sage/dynamics/cellular_automata/solitons.py @@ -515,7 +515,7 @@ def evolve(self, carrier_capacity=None, carrier_index=None, number=None): carrier_index = self._vacuum if number is not None: - for k in range(number): + for _ in range(number): self.evolve(carrier_capacity, carrier_index) return @@ -1398,7 +1398,7 @@ def evolve(self, carrier_capacity=None, carrier_index=None, number=None): carrier_index = self._vacuum if number is not None: - for k in range(number): + for _ in range(number): self.evolve(carrier_capacity, carrier_index) return if carrier_capacity is None: diff --git a/src/sage/dynamics/complex_dynamics/mandel_julia.py b/src/sage/dynamics/complex_dynamics/mandel_julia.py index 32a15ba19c5..d1ce772fcbc 100644 --- a/src/sage/dynamics/complex_dynamics/mandel_julia.py +++ b/src/sage/dynamics/complex_dynamics/mandel_julia.py @@ -275,7 +275,7 @@ def mandelbrot_plot(f=None, **kwds): base_color) else: if interacts: - raise NotImplementedError("Interact only implemented for z^2 + c") + raise NotImplementedError("interact only implemented for z^2 + c") else: # Set default of max_iteration to 50 for general polynomial maps # This prevents the function from being very slow by default @@ -694,11 +694,9 @@ def julia_plot(f=None, **kwds): R = f.parent() if not (R.is_integral_domain() and (CC.is_subring(R) or CDF.is_subring(R))): - raise ValueError('Given `f` must be a complex polynomial.') - else: - raise NotImplementedError( - 'Julia sets not implemented for rational functions.' - ) + raise ValueError('given `f` must be a complex polynomial') + raise NotImplementedError( + 'Julia sets not implemented for rational functions') if (f_poly - z*z) in CC: # f is specified and of the form z^2 + c. f_is_default_after_all = True diff --git a/src/sage/dynamics/complex_dynamics/mandel_julia_helper.pyx b/src/sage/dynamics/complex_dynamics/mandel_julia_helper.pyx index 882cc6ada08..1189b55fec9 100644 --- a/src/sage/dynamics/complex_dynamics/mandel_julia_helper.pyx +++ b/src/sage/dynamics/complex_dynamics/mandel_julia_helper.pyx @@ -746,7 +746,7 @@ cpdef polynomial_mandelbrot(f, parameter=None, double x_center=0, # Split function into real and imaginary parts R = PolynomialRing(CC, [variable,parameter]) if len(R.gens()) > 2: - raise NotImplementedError("Base ring must have only 2 variables") + raise NotImplementedError("base ring must have only 2 variables") z, c = R.gens() f = R(str(f)) S = PolynomialRing(f.base_ring(), 'x,y,J,cr,ci') From 5447ee5ef8b7b2dd3702bf93d71e79e57dbf89a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 25 May 2022 21:53:46 +0200 Subject: [PATCH 471/529] fix doctests --- src/sage/dynamics/arithmetic_dynamics/affine_ds.py | 4 ++-- src/sage/dynamics/arithmetic_dynamics/projective_ds.py | 8 ++++---- src/sage/dynamics/complex_dynamics/mandel_julia.py | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/sage/dynamics/arithmetic_dynamics/affine_ds.py b/src/sage/dynamics/arithmetic_dynamics/affine_ds.py index 9db7b91f8db..421f04be9a7 100644 --- a/src/sage/dynamics/arithmetic_dynamics/affine_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/affine_ds.py @@ -193,7 +193,7 @@ class DynamicalSystem_affine(SchemeMorphism_polynomial_affine_space, sage: DynamicalSystem_affine(x^2+1) Traceback (most recent call last): ... - TypeError: Symbolic Ring cannot be the base ring + TypeError: symbolic ring cannot be the base ring """ @staticmethod @@ -230,7 +230,7 @@ def __classcall_private__(cls, morphism_or_polys, domain=None): sage: f = DynamicalSystem_affine([x+y+z, y*z]) Traceback (most recent call last): ... - ValueError: Number of polys does not match dimension of Affine Space of dimension 3 over Rational Field + ValueError: number of polys does not match dimension of Affine Space of dimension 3 over Rational Field :: diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py index dc8344b672d..07575dc2754 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py @@ -334,7 +334,7 @@ def __classcall_private__(cls, morphism_or_polys, domain=None, names=None): sage: DynamicalSystem_projective([y, x, y], domain=P1) Traceback (most recent call last): ... - ValueError: Number of polys does not match dimension of Projective Space of dimension 1 over Rational Field + ValueError: number of polys does not match dimension of Projective Space of dimension 1 over Rational Field :: @@ -5164,7 +5164,7 @@ def sigma_invariants(self, n, formal=False, embedding=None, type='point', Traceback (most recent call last): .. ValueError: sigma polynomial dropped degree, as multiplicities were not accounted - for correctly. try setting chow=True and/or deform=True + for correctly; try setting chow=True and/or deform=True :: @@ -5174,7 +5174,7 @@ def sigma_invariants(self, n, formal=False, embedding=None, type='point', Traceback (most recent call last): .. ValueError: sigma polynomial dropped degree, as multiplicities were not accounted - for correctly. try setting chow=True and/or deform=True + for correctly; try setting chow=True and/or deform=True """ n = ZZ(n) @@ -6931,7 +6931,7 @@ def conjugating_set(self, other, R=None, num_cpus=2): sage: D8.conjugating_set(D8) Traceback (most recent call last): ... - ValueError: no more rational preimages. try extending the base field and trying again. + ValueError: no more rational preimages; try extending the base field and trying again :: diff --git a/src/sage/dynamics/complex_dynamics/mandel_julia.py b/src/sage/dynamics/complex_dynamics/mandel_julia.py index d1ce772fcbc..224a484c7bb 100644 --- a/src/sage/dynamics/complex_dynamics/mandel_julia.py +++ b/src/sage/dynamics/complex_dynamics/mandel_julia.py @@ -185,7 +185,7 @@ def mandelbrot_plot(f=None, **kwds): sage: mandelbrot_plot(f, interact=True) Traceback (most recent call last): ... - NotImplementedError: Interact only implemented for z^2 + c + NotImplementedError: interact only implemented for z^2 + c """ parameter = kwds.pop("parameter", None) x_center = kwds.pop("x_center", 0.0) From c7e8063960107be1133b9a718203b8c5fe054159 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Thu, 26 May 2022 00:28:26 +0100 Subject: [PATCH 472/529] remove buggy 'tedder' modular decomposition --- src/sage/graphs/graph.py | 89 +- .../modular_decomposition.py | 2141 +---------------- 2 files changed, 97 insertions(+), 2133 deletions(-) diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index 4c3b54fd64d..089240f15e8 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -7574,7 +7574,7 @@ def cores(self, k=None, with_labels=False): return list(core.values()) @doc_index("Leftovers") - def modular_decomposition(self, algorithm='habib', style='tuple'): + def modular_decomposition(self, style='tuple'): r""" Return the modular decomposition of the current graph. @@ -7583,18 +7583,10 @@ def modular_decomposition(self, algorithm='habib', style='tuple'): module or to none of them. Every graph that has a nontrivial module can be partitioned into modules, and the increasingly fine partitions into modules form a tree. The ``modular_decomposition`` function returns - that tree. + that tree, using an `O(n^3)` algorithm of [HM1979]_. INPUT: - - ``algorithm`` -- string (default: ``'habib'``); specifies the - algorithm to use among: - - - ``'tedder'`` -- linear time algorithm of [TCHP2008]_ - - - ``'habib'`` -- `O(n^3)` algorithm of [HM1979]_. This algorithm is - much simpler and so possibly less prone to errors. - - ``style`` -- string (default: ``'tuple'``); specifies the output format: @@ -7674,14 +7666,9 @@ def modular_decomposition(self, algorithm='habib', style='tuple'): sage: g = graphs.CompleteGraph(5) sage: g.add_edge(0,5) sage: g.add_edge(0,6) - sage: g.modular_decomposition(algorithm='habib') + sage: g.modular_decomposition() (SERIES, [(PARALLEL, [(SERIES, [1, 2, 3, 4]), 5, 6]), 0]) - We get an equivalent tree when we use the algorithm of [TCHP2008]_:: - - sage: g.modular_decomposition(algorithm='tedder') - (SERIES, [(PARALLEL, [(SERIES, [4, 3, 2, 1]), 5, 6]), 0]) - We can choose output to be a :class:`~sage.combinat.rooted_tree.LabelledRootedTree`:: @@ -7698,10 +7685,7 @@ def modular_decomposition(self, algorithm='habib', style='tuple'): ALGORITHM: - When ``algorithm='tedder'`` this function uses python implementation of - algorithm published by Marc Tedder, Derek Corneil, Michel Habib and - Christophe Paul [TCHP2008]_. When ``algorithm='habib'`` this function - uses the algorithm of M. Habib and M. Maurer [HM1979]_. + This function uses the algorithm of M. Habib and M. Maurer [HM1979]_. .. SEEALSO:: @@ -7709,28 +7693,25 @@ def modular_decomposition(self, algorithm='habib', style='tuple'): - :class:`~sage.combinat.rooted_tree.LabelledRootedTree`. + .. NOTE:: + + A buggy implementation of linear time algorithm from [TCHP2008]_ was + removed in Sage 9.7. + TESTS: Empty graph:: - sage: graphs.EmptyGraph().modular_decomposition(algorithm='habib') - () - sage: graphs.EmptyGraph().modular_decomposition(algorithm='tedder') + sage: graphs.EmptyGraph().modular_decomposition() () - sage: graphs.EmptyGraph().modular_decomposition(algorithm='habib', style='tree') - None[] - sage: graphs.EmptyGraph().modular_decomposition(algorithm='tedder', style='tree') + sage: graphs.EmptyGraph().modular_decomposition(style='tree') None[] Singleton Vertex:: - sage: Graph(1).modular_decomposition(algorithm='habib') + sage: Graph(1).modular_decomposition() (PRIME, [0]) - sage: Graph(1).modular_decomposition(algorithm='tedder') - (PRIME, [0]) - sage: Graph(1).modular_decomposition(algorithm='habib', style='tree') - PRIME[0[]] - sage: Graph(1).modular_decomposition(algorithm='tedder', style='tree') + sage: Graph(1).modular_decomposition(style='tree') PRIME[0[]] Vertices may be arbitrary --- check that :trac:`24898` is fixed:: @@ -7741,22 +7722,25 @@ def modular_decomposition(self, algorithm='habib', style='tuple'): sage: sorted(md[1]) [(1, 2), (2, 3)] - Unknown algorithm:: - - sage: graphs.PathGraph(2).modular_decomposition(algorithm='abc') - Traceback (most recent call last): - ... - ValueError: algorithm must be 'habib' or 'tedder' - Unknown style:: sage: graphs.PathGraph(2).modular_decomposition(style='xyz') Traceback (most recent call last): ... ValueError: style must be 'tuple' or 'tree' + + Check that :trac:`25872` is fixed:: + + sage: G1 = Graph('FwA]w') + sage: G2 = Graph('F@Nfg') + sage: G1.is_isomorphic(G2) + True + sage: G1.modular_decomposition() + (PRIME, [1, 2, 5, 6, 0, (PARALLEL, [3, 4])]) + sage: G2.modular_decomposition() + (PRIME, [5, 6, 3, 4, 2, (PARALLEL, [0, 1])]) """ - from sage.graphs.graph_decompositions.modular_decomposition import (modular_decomposition, - NodeType, + from sage.graphs.graph_decompositions.modular_decomposition import (NodeType, habib_maurer_algorithm, create_prime_node, create_normal_node) @@ -7769,12 +7753,7 @@ def modular_decomposition(self, algorithm='habib', style='tuple'): D = create_prime_node() D.children.append(create_normal_node(self.vertices()[0])) else: - if algorithm == 'habib': - D = habib_maurer_algorithm(self) - elif algorithm == 'tedder': - D = modular_decomposition(self) - else: - raise ValueError("algorithm must be 'habib' or 'tedder'") + D = habib_maurer_algorithm(self) if style == 'tuple': if D is None: @@ -8035,23 +8014,13 @@ def is_inscribable(self, solver="ppl", verbose=0): return self.planar_dual().is_circumscribable(solver=solver, verbose=verbose) @doc_index("Graph properties") - def is_prime(self, algorithm='habib'): + def is_prime(self): r""" Test whether the current graph is prime. - INPUT: - - - ``algorithm`` -- (default: ``'tedder'``) specifies the algorithm to - use among: - - - ``'tedder'`` -- Use the linear algorithm of [TCHP2008]_. - - - ``'habib'`` -- Use the $O(n^3)$ algorithm of [HM1979]_. This is - probably slower, but is much simpler and so possibly less error - prone. - A graph is prime if all its modules are trivial (i.e. empty, all of the graph or singletons) -- see :meth:`modular_decomposition`. + Use the `O(n^3)` algorithm of [HM1979]_. EXAMPLES: @@ -8077,7 +8046,7 @@ def is_prime(self, algorithm='habib'): if self.order() <= 1: return True - D = self.modular_decomposition(algorithm=algorithm) + D = self.modular_decomposition() return D[0] == NodeType.PRIME and len(D[1]) == self.order() diff --git a/src/sage/graphs/graph_decompositions/modular_decomposition.py b/src/sage/graphs/graph_decompositions/modular_decomposition.py index 941aaa26b29..2b96578c95b 100644 --- a/src/sage/graphs/graph_decompositions/modular_decomposition.py +++ b/src/sage/graphs/graph_decompositions/modular_decomposition.py @@ -277,2055 +277,6 @@ def __eq__(self, other): self.children == other.children) -def modular_decomposition(graph): - """ - Compute the modular decomposition tree of ``graph``. - - The tree structure is represented in form of nested lists. A tree node is - an object of type Node. The Node object further contains a list of its - children - - INPUT: - - - ``graph`` -- the graph for which modular decomposition tree needs to be - computed - - OUTPUT: - - A nested list representing the modular decomposition tree computed for the - graph - - EXAMPLES: - - The Icosahedral graph is Prime:: - - sage: from sage.graphs.graph_decompositions.modular_decomposition import * - sage: print_md_tree(modular_decomposition(graphs.IcosahedralGraph())) - PRIME - 5 - 7 - 11 - 1 - 8 - 0 - 9 - 4 - 10 - 6 - 2 - 3 - - The Octahedral graph is not Prime:: - - sage: print_md_tree(modular_decomposition(graphs.OctahedralGraph())) - SERIES - PARALLEL - 2 - 3 - PARALLEL - 1 - 4 - PARALLEL - 0 - 5 - - Tetrahedral Graph is Series:: - - sage: print_md_tree(modular_decomposition(graphs.TetrahedralGraph())) - SERIES - 3 - 2 - 1 - 0 - - Modular Decomposition tree containing both parallel and series modules:: - - sage: d = {2:[4,3,5], 1:[4,3,5], 5:[3,2,1,4], 3:[1,2,5], 4:[1,2,5]} - sage: g = Graph(d) - sage: print_md_tree(modular_decomposition(g)) - SERIES - 5 - PARALLEL - 3 - 4 - PARALLEL - 1 - 2 - - TESTS: - - Bad Input:: - - sage: g = DiGraph() - sage: modular_decomposition(g) - Traceback (most recent call last): - ... - ValueError: Graph must be undirected - - Empty Graph is Prime:: - - sage: g = Graph() - sage: modular_decomposition(g) - PRIME [] - - Graph from Marc Tedder implementation of modular decomposition:: - - sage: d = {1:[5,4,3,24,6,7,8,9,2,10,11,12,13,14,16,17], 2:[1], - ....: 3:[24,9,1], 4:[5,24,9,1], 5:[4,24,9,1], 6:[7,8,9,1], - ....: 7:[6,8,9,1], 8:[6,7,9,1], 9:[6,7,8,5,4,3,1], 10:[1], - ....: 11:[12,1], 12:[11,1], 13:[14,16,17,1], 14:[13,17,1], - ....: 16:[13,17,1], 17:[13,14,16,18,1], 18:[17], 24:[5,4,3,1]} - sage: g = Graph(d) - sage: test_modular_decomposition(modular_decomposition(g), g) - True - - Graph from the :wikipedia:`Modular_decomposition`:: - - sage: d2 = {1:[2,3,4], 2:[1,4,5,6,7], 3:[1,4,5,6,7], 4:[1,2,3,5,6,7], - ....: 5:[2,3,4,6,7], 6:[2,3,4,5,8,9,10,11], - ....: 7:[2,3,4,5,8,9,10,11], 8:[6,7,9,10,11], 9:[6,7,8,10,11], - ....: 10:[6,7,8,9], 11:[6,7,8,9]} - sage: g = Graph(d2) - sage: test_modular_decomposition(modular_decomposition(g), g) - True - """ - if graph.is_directed(): - raise ValueError("Graph must be undirected") - - if not graph.order(): # Empty Graph - return create_prime_node() - - if graph.order() == 1: # Single vertex graph - root = create_normal_node(next(graph.vertex_iterator())) - return root - - if not graph.is_connected(): - - # Parallel case: the tree contains the MD trees of its connected - # components as subtrees - components = graph.connected_components() - root = create_parallel_node() - for component in components: - root.children.append(modular_decomposition(graph.subgraph(component))) - return root - elif graph.complement().is_connected(): # Prime Graph - root = create_prime_node() - else: - root = create_series_node() # Series Graph - - bfs_generator = graph.breadth_first_search(next(graph.vertex_iterator()), - report_distance=True) - - prev_level_distance = -1 # used as a demarker for different levels in bfs - prev_level_list = [] # stores the vertices in previous level - - # dictionary stores the distance of vertices from the SOURCE - vertex_dist = {} - - # dictionary stores the position of vertices w.r.t SOURCE - vertex_status = {} - vertex_status[next(graph.vertex_iterator())] = VertexPosition.SOURCE - - # Different distances from the source vertex are considered - # as different levels in the algorithm - for (vertex, distance) in bfs_generator: - vertex_dist[vertex] = distance - - # Mark the neighbours of source as LEFT_OF_SOURCE as they appear to - # left of source in the forest, other vertices are marked as - # RIGHT_OF_SOURCE - if distance == 1: - vertex_status[vertex] = VertexPosition.LEFT_OF_SOURCE - elif distance != 0: - vertex_status[vertex] = VertexPosition.RIGHT_OF_SOURCE - - if distance != prev_level_distance: # On start of new level in BFS - if prev_level_list: - # MD Tree is computed for each level and added to the forest - root.children.append(modular_decomposition(graph.subgraph(prev_level_list))) - prev_level_list = [] - prev_level_distance = distance - prev_level_list.append(vertex) - - # The last level is left out in the above loop - root.children.append(modular_decomposition(graph.subgraph(prev_level_list))) - - # The MD tree for the neighbours of source marked as LEFT_OF_SOURCE - # are placed left of Source in the forest. root.children[1] is required to - # be source and root.children[0] is required to be the MD tree for the - # neighbours therefore, the first two elements in the list are replaced - root.children[0], root.children[1] = root.children[1], root.children[0] - - root.node_type = NodeType.FOREST - clear_node_split_info(root) - number_cocomponents(root, vertex_status) - number_components(root, vertex_status) - refine(graph, root, vertex_dist, vertex_status) - promote_left(root) - promote_right(root) - promote_child(root) - assembly(graph, root, vertex_status, vertex_dist) - - if root.node_type == NodeType.FOREST: - return root.children[0] - else: - return root - - -def number_components(root, vertex_status): - """ - Number the components to the right of SOURCE vertex in the forest input to - the assembly phase - - INPUT: - - - ``root`` -- the forest which contains the components and cocomponents - - - ``vertex_status`` -- dictionary which stores the position of vertex - w.r.t SOURCE - - EXAMPLES:: - - sage: from sage.graphs.graph_decompositions.modular_decomposition import * - sage: forest = Node(NodeType.FOREST) - sage: forest.children = [create_normal_node(2), - ....: create_normal_node(3), create_normal_node(1)] - sage: series_node = Node(NodeType.SERIES) - sage: series_node.children = [create_normal_node(4), - ....: create_normal_node(5)] - sage: parallel_node = Node(NodeType.PARALLEL) - sage: parallel_node.children = [create_normal_node(6), - ....: create_normal_node(7)] - sage: forest.children.append(series_node) - sage: forest.children.append(parallel_node) - sage: vertex_status = {2: VertexPosition.LEFT_OF_SOURCE, - ....: 3: VertexPosition.SOURCE, - ....: 1: VertexPosition.RIGHT_OF_SOURCE, - ....: 4: VertexPosition.RIGHT_OF_SOURCE, - ....: 5: VertexPosition.RIGHT_OF_SOURCE, - ....: 6: VertexPosition.RIGHT_OF_SOURCE, - ....: 7: VertexPosition.RIGHT_OF_SOURCE} - sage: number_components(forest, vertex_status) - sage: forest.children[-1].children[0].comp_num - 2 - sage: forest.children[-1].children[1].comp_num - 3 - - TESTS:: - - sage: (forest.children[-1].children[0].comp_num == 2 and - ....: forest.children[-1].children[1].comp_num == 3) - True - sage: (forest.children[-2].children[0].comp_num == 1 and - ....: forest.children[-2].children[1].comp_num == 1) - True - """ - comp_num = 0 - flag = False - - if not root: # root is empty - return ValueError("Input forest {} is empty".format(root)) - - for node in root.children: - - # flag set to True after source vertex is encountered - if (node.node_type == NodeType.NORMAL and - vertex_status[node.children[0]] == VertexPosition.SOURCE): - flag = True - continue - - if not flag: # Cocomponents are skipped - continue - - comp_num += recursively_number_parts(node, comp_num, NodeType.PARALLEL) - - -def number_cocomponents(root, vertex_status): - """ - Number the cocomponents to the left of SOURCE vertex in the forest input to - the assembly phase - - INPUT: - - - ``root`` -- the forest which contains the cocomponents and components - - - ``vertex_status`` -- dictionary which stores the position of vertex - w.r.t SOURCE - - EXAMPLES:: - - sage: from sage.graphs.graph_decompositions.modular_decomposition import * - sage: forest = Node(NodeType.FOREST) - sage: forest.children = [create_normal_node(2), - ....: create_normal_node(3), create_normal_node(1)] - sage: series_node = Node(NodeType.SERIES) - sage: series_node.children = [create_normal_node(4), - ....: create_normal_node(5)] - sage: parallel_node = Node(NodeType.PARALLEL) - sage: parallel_node.children = [create_normal_node(6), - ....: create_normal_node(7)] - sage: forest.children.insert(1, series_node) - sage: forest.children.insert(2, parallel_node) - sage: vertex_status = {2: VertexPosition.LEFT_OF_SOURCE, - ....: 3: VertexPosition.SOURCE, - ....: 1: VertexPosition.RIGHT_OF_SOURCE, - ....: 4: VertexPosition.LEFT_OF_SOURCE, - ....: 5: VertexPosition.LEFT_OF_SOURCE, - ....: 6: VertexPosition.LEFT_OF_SOURCE, - ....: 7: VertexPosition.LEFT_OF_SOURCE} - sage: number_cocomponents(forest, vertex_status) - sage: forest.children[1].children[0].comp_num - 1 - sage: forest.children[1].children[1].comp_num - 2 - - TESTS:: - - sage: (forest.children[1].children[0].comp_num and - ....: forest.children[1].children[1].comp_num == 2) - True - sage: (forest.children[2].children[0].comp_num == 3 and - ....: forest.children[2].children[1].comp_num == 3) - True - """ - cocomp_num = 0 - for node in root.children: - # Only cocomponents are numbered - if (node.node_type == NodeType.NORMAL and - vertex_status[node.children[0]] == VertexPosition.SOURCE): - break - cocomp_num += recursively_number_parts(node, cocomp_num, NodeType.SERIES) - - -def recursively_number_parts(part_root, part_num, by_type): - """ - Recursively number the nodes in the (co)components(parts). - - If the ``node_type`` of ``part_root`` is same as ``by_type`` then - ``part_num`` is incremented for subtree at each child of ``part_root`` else - part is numbered by ``part_num``. - - INPUT: - - - ``part_root`` -- root of the part to be numbered - - - ``part_num`` -- input number to be used as reference for numbering - the (co)components - - - ``by_type`` -- type which determines how numbering is done - - OUTPUT: - - The value incremented to ``part_num``. - - EXAMPLES:: - - sage: from sage.graphs.graph_decompositions.modular_decomposition import * - sage: series_node = Node(NodeType.SERIES) - sage: series_node.children = [create_normal_node(4), - ....: create_normal_node(5)] - sage: recursively_number_parts(series_node, 1, NodeType.SERIES) - 2 - sage: series_node.comp_num - 1 - sage: series_node.children[0].comp_num - 1 - sage: series_node.children[1].comp_num - 2 - - TESTS:: - - sage: (series_node.comp_num == 1 and - ....: series_node.children[0].comp_num == 1 and - ....: series_node.children[1].comp_num == 2) - True - """ - # inner function - def number_subtree(subtree_root, number): - """ - set the ``comp_num`` for all the nodes in the subtree to ``number`` - - INPUT: - - - ``subtree_root`` -- root of the subtree to be numbered - - - ``number`` -- number assigned to the subtree - """ - subtree_root.comp_num = number - if subtree_root.node_type != NodeType.NORMAL: - for child in subtree_root.children: - number_subtree(child, number) - - orig_part_num = part_num - - if part_root.node_type == by_type: - # if node_type is same as tree's node_type then cocomp_num is - # incremented before assigning to each subtree - part_root.comp_num = part_num - for child in part_root.children: - number_subtree(child, part_num) - part_num += 1 - else: - # entire tree is numbered by cocomp_num - number_subtree(part_root, part_num) - part_num += 1 - return part_num - orig_part_num - - -def assembly(graph, root, vertex_status, vertex_dist): - """ - Assemble the forest obtained after the promotion phase into a modular - decomposition tree. - - INPUT: - - - ``graph`` -- graph whose MD tree is to be computed - - - ``root`` -- Forest which would be assembled into a MD tree - - - ``vertex_status`` -- Dictionary which stores the position of vertex with - respect to the source - - - ``vertex_dist`` -- Dictionary which stores the distance of vertex from - source vertex - - EXAMPLES:: - - sage: from sage.graphs.graph_decompositions.modular_decomposition import * - sage: g = Graph() - sage: g.add_vertices([1, 2, 3, 4, 5, 6, 7]) - sage: g.add_edge(2, 3) - sage: g.add_edge(4, 3) - sage: g.add_edge(5, 3) - sage: g.add_edge(2, 6) - sage: g.add_edge(2, 7) - sage: g.add_edge(6, 1) - sage: forest = Node(NodeType.FOREST) - sage: forest.children = [create_normal_node(2), - ....: create_normal_node(3), create_normal_node(1)] - sage: series_node = Node(NodeType.SERIES) - sage: series_node.children = [create_normal_node(4), - ....: create_normal_node(5)] - sage: parallel_node = Node(NodeType.PARALLEL) - sage: parallel_node.children = [create_normal_node(6), - ....: create_normal_node(7)] - sage: forest.children.insert(1, series_node) - sage: forest.children.insert(3, parallel_node) - sage: vertex_status = {2: VertexPosition.LEFT_OF_SOURCE, - ....: 3: VertexPosition.SOURCE, - ....: 1: VertexPosition.RIGHT_OF_SOURCE, - ....: 4: VertexPosition.LEFT_OF_SOURCE, - ....: 5: VertexPosition.LEFT_OF_SOURCE, - ....: 6: VertexPosition.RIGHT_OF_SOURCE, - ....: 7: VertexPosition.RIGHT_OF_SOURCE} - sage: vertex_dist = {2: 1, 4: 1, 5: 1, 3: 0, 6: 2, 7: 2, 1: 3} - sage: forest.children[0].comp_num = 1 - sage: forest.children[1].comp_num = 1 - sage: forest.children[1].children[0].comp_num = 1 - sage: forest.children[1].children[1].comp_num = 1 - sage: number_components(forest, vertex_status) - sage: assembly(g, forest, vertex_status, vertex_dist) - sage: forest.children - [PRIME [NORMAL [2], SERIES [NORMAL [4], NORMAL [5]], NORMAL [3], - PARALLEL [NORMAL [6], NORMAL [7]], NORMAL [1]]] - - sage: g.add_edge(4, 2) - sage: g.add_edge(5, 2) - sage: forest = Node(NodeType.FOREST) - sage: forest.children = [create_normal_node(2), - ....: create_normal_node(3), create_normal_node(1)] - sage: series_node = Node(NodeType.SERIES) - sage: series_node.children = [create_normal_node(4), - ....: create_normal_node(5)] - sage: parallel_node = Node(NodeType.PARALLEL) - sage: parallel_node.children = [create_normal_node(6), - ....: create_normal_node(7)] - sage: forest.children.insert(1, series_node) - sage: forest.children.insert(3, parallel_node) - sage: number_cocomponents(forest, vertex_status) - sage: assembly(g, forest, vertex_status, vertex_dist) - sage: forest.children - [PRIME [NORMAL [2], SERIES [NORMAL [4], NORMAL [5], NORMAL [3]], - PARALLEL [NORMAL [6], NORMAL [7]], NORMAL [1]]] - """ - # Maps index to the mu computed for the (co)component at the index - mu = {} - - # Stores index in the forest containing the source vertex - source_index = -1 - - # Maps index to list of vertices in the (co)component at the index - vertices_in_component = {} - - # comp_num of parent should be equal to comp_num of its first child - update_comp_num(root) - - for index, component in enumerate(root.children): - - if (component.node_type == NodeType.NORMAL and - vertex_status[component.children[0]] == VertexPosition.SOURCE): - source_index = root.children.index(component) - - vertices_in_component[index] = get_vertices(component) - component.index_in_root = index - - # compute mu values for (co)components - for index, component in enumerate(root.children): - if index < source_index: - mu[index] = compute_mu_for_co_component(graph, index, - source_index, root, - vertices_in_component) - elif index > source_index: - mu[index] = compute_mu_for_component(graph, index, - source_index, root, - vertices_in_component) - - mu[source_index] = root.children[source_index] - - # stores the leftmost cocomponent included in the module containing - # source_index - left = root.children[source_index] - - # stores the rightmost component included in the module containing - # source_index - right = root.children[source_index] - - while len(root.children) != 1: - # source_index is changed every time a new module is formed therefore - # updated. left or right are also updated every time module is formed. - - # First series module is attempted - result, source_index = check_series(root, left, right, - source_index, mu) - if result: - left = root.children[source_index].children[0] - continue - - # If series module can't be formed, parallel is tried - result, source_index = check_parallel(graph, root, left, right, - source_index, mu, vertex_dist, - vertices_in_component) - if result: - right = root.children[source_index].children[-1] - continue - - # Finally a prime module is formed if both - # series and parallel can not be created - result, source_index = check_prime(graph, root, left, right, - source_index, mu, vertex_dist, - vertices_in_component) - if result: - if root.children[source_index].children[0].index_in_root != -1: - left = root.children[source_index].children[0] - if root.children[source_index].children[-1].index_in_root != -1: - right = root.children[source_index].children[-1] - - -def update_comp_num(node): - """ - Set the ``comp_num`` of ``node`` to the ``comp_num`` of its first child. - - INPUT: - - - ``node`` -- node whose comp_num needs to be updated - - EXAMPLES:: - - sage: from sage.graphs.graph_decompositions.modular_decomposition import * - sage: forest = Node(NodeType.FOREST) - sage: forest.children = [create_normal_node(2), - ....: create_normal_node(3), create_normal_node(1)] - sage: series_node = Node(NodeType.SERIES) - sage: series_node.comp_num = 2 - sage: series_node.children = [create_normal_node(4), - ....: create_normal_node(5)] - sage: series_node.children[0].comp_num = 3 - sage: parallel_node = Node(NodeType.PARALLEL) - sage: parallel_node.children = [create_normal_node(6), - ....: create_normal_node(7)] - sage: forest.children.insert(0, series_node) - sage: forest.children.insert(3, parallel_node) - sage: update_comp_num(forest) - sage: series_node.comp_num - 3 - sage: forest.comp_num - 2 - """ - if node.node_type != NodeType.NORMAL: - node.comp_num = node.children[0].comp_num - for child in node.children: - update_comp_num(child) - - -def check_prime(graph, root, left, right, - source_index, mu, vertex_dist, - vertices_in_component): - """ - Assemble the forest to create a prime module. - - INPUT: - - - ``root`` -- forest which needs to be assembled - - - ``left`` -- the leftmost fragment of the last module - - - ``right`` -- the rightmost fragment of the last module - - - ``source_index`` -- index of the tree containing the source vertex - - - ``mu`` -- dictionary which maps the (co)components with their mu values - - - ``vertex_dist`` -- dictionary which stores the distance of vertex from - source vertex - - - ``vertices_in_component`` -- dictionary which stores a list of various - vertices in a (co)component - - OUTPUT: - - ``[module_formed, source_index]`` where ``module_formed`` is ``True`` if - module is formed else ``False`` and ``source_index`` is the index of the - new module which contains the source vertex - - EXAMPLES:: - - sage: from sage.graphs.graph_decompositions.modular_decomposition import * - sage: g = Graph() - sage: g.add_vertices([1, 2, 3, 4, 5, 6, 7]) - sage: g.add_edge(2, 3) - sage: g.add_edge(4, 3) - sage: g.add_edge(5, 3) - sage: g.add_edge(2, 6) - sage: g.add_edge(2, 7) - sage: g.add_edge(6, 1) - sage: forest = Node(NodeType.FOREST) - sage: forest.children = [create_normal_node(2), - ....: create_normal_node(3), create_normal_node(1)] - sage: series_node = Node(NodeType.SERIES) - sage: series_node.children = [create_normal_node(4), - ....: create_normal_node(5)] - sage: parallel_node = Node(NodeType.PARALLEL) - sage: parallel_node.children = [create_normal_node(6), - ....: create_normal_node(7)] - sage: forest.children.insert(1, series_node) - sage: forest.children.insert(3, parallel_node) - sage: vertex_status = {2: VertexPosition.LEFT_OF_SOURCE, - ....: 3: VertexPosition.SOURCE, - ....: 1: VertexPosition.RIGHT_OF_SOURCE, - ....: 4: VertexPosition.LEFT_OF_SOURCE, - ....: 5: VertexPosition.LEFT_OF_SOURCE, - ....: 6: VertexPosition.RIGHT_OF_SOURCE, - ....: 7: VertexPosition.RIGHT_OF_SOURCE} - sage: vertex_dist = {2: 1, 4: 1, 5: 1, 3: 0, 6: 2, 7: 2, 1: 3} - sage: source_index = 2 - sage: vertices_in_component = {} - sage: mu = {} - sage: left = right = forest.children[2] - sage: for index, component in enumerate(forest.children): - ....: vertices_in_component[index] = get_vertices(component) - ....: component.index_in_root = index - sage: for index, component in enumerate(forest.children): - ....: if index < source_index: - ....: mu[index] = compute_mu_for_co_component(g, index, - ....: source_index, forest, - ....: vertices_in_component) - ....: elif index > source_index: - ....: mu[index] = compute_mu_for_component(g, index, - ....: source_index, forest, - ....: vertices_in_component) - sage: forest.children[0].comp_num = 1 - sage: forest.children[1].comp_num = 1 - sage: forest.children[1].children[0].comp_num = 1 - sage: forest.children[1].children[1].comp_num = 1 - sage: number_components(forest, vertex_status) - sage: check_prime(g, forest, left, right, - ....: source_index, mu, vertex_dist, - ....: vertices_in_component) - [True, 0] - sage: forest.children - [PRIME [NORMAL [2], SERIES [NORMAL [4], NORMAL [5]], NORMAL [3], - PARALLEL [NORMAL [6], NORMAL [7]], NORMAL [1]]] - """ - # stores the index of rightmost component included in the prime module - new_right_index = source_index - if source_index + 1 < len(root.children): - new_right_index += 1 - - # stores the index of leftmost component included in the prime module - new_left_index = source_index - if source_index >= 1: - new_left_index -= 1 - - # stores the indices of the cocomponents included in the prime module - # the cocomponents are extracted one by one from left_queue for adding - # more components - left_queue = deque() - - # stores the indices of the components included in the prime module - # the components are extracted one by one from right_queue for adding - # more cocomponents - right_queue = deque() - - if new_left_index != source_index: - left_queue.append(new_left_index) - if new_right_index != source_index: - right_queue.append(new_right_index) - - while left_queue or right_queue: - - if left_queue: - - # cocomponent indices extracted from the queue - left_index = left_queue.popleft() - - # more components added based on the below condition - while (new_right_index < len(root.children) - 1 and - root.children[new_right_index].index_in_root < mu[left_index].index_in_root): - new_right_index += 1 - right_queue.append(new_right_index) - - # cocomponent added while cocomponent at left_index - # has cocomponent to its left with same comp_num - while has_left_cocomponent_fragment(root, left_index): - if left_index >= 1: - left_index -= 1 - if new_left_index > left_index: - left_queue.append(left_index) - new_left_index = min(left_index, new_left_index) - - if right_queue: - - # component indices extracted from the queue - right_index = right_queue.popleft() - - # more cocomponents added based on the below condition - while (new_left_index > 0 and - root.children[new_left_index].index_in_root > mu[right_index].index_in_root): - new_left_index -= 1 - left_queue.append(new_left_index) - - # component is added while component at right_index - # has component to its right with same comp_num - # or has a connected component with vertices at different - # level from the source vertex - while (has_right_component_fragment(root, right_index) or - has_right_layer_neighbor(graph, root, - right_index, vertex_dist, - vertices_in_component)): - - if has_right_layer_neighbor(graph, root, - right_index, vertex_dist, - vertices_in_component): - new_left_index = 0 - new_right_index = len(root.children) - 1 - break - - if right_index + 1 < len(root.children): - right_index += 1 - if new_right_index < right_index: - right_queue.append(right_index) - new_right_index = max(right_index, new_right_index) - - node = create_prime_node() - - # vertices or modules are added in the prime_module - for temp in range(new_left_index, new_right_index + 1): - node.children.append(root.children[temp]) - - # list elements included in the prime module - # are removed from the forest - root.children[new_left_index:new_right_index + 1] = [] - - #insert the newly created prime module in the forest - root.children.insert(new_left_index, node) - - return [True, new_left_index] - - -def check_parallel(graph, root, left, right, - source_index, mu, vertex_dist, - vertices_in_component): - """ - Assemble the forest to create a parallel module. - - INPUT: - - - ``root`` -- forest which needs to be assembled - - - ``left`` -- the leftmost fragment of the last module - - - ``right`` -- the rightmost fragment of the last module - - - ``source_index`` -- index of the tree containing the source vertex - - - ``mu`` -- dictionary which maps the (co)components with their mu values - - - ``vertex_dist`` -- dictionary which stores the distance of vertex from - source vertex - - - ``vertices_in_component`` -- dictionary which stores a list of various - vertices in a (co)component - - OUTPUT: - - ``[module_formed, source_index]`` where ``module_formed`` is ``True`` if - module is formed else ``False`` and ``source_index`` is the index of the - new module which contains the source vertex - - EXAMPLES:: - - sage: from sage.graphs.graph_decompositions.modular_decomposition import * - sage: g = Graph() - sage: g.add_vertices([1, 2, 3, 4, 5, 6, 7]) - sage: g.add_edge(2, 3) - sage: g.add_edge(4, 3) - sage: g.add_edge(5, 3) - sage: g.add_edge(2, 6) - sage: g.add_edge(2, 7) - sage: g.add_edge(2, 1) - sage: g.add_edge(4, 1) - sage: forest = Node(NodeType.FOREST) - sage: forest.children = [create_normal_node(2), - ....: create_normal_node(3)] - sage: series_node = Node(NodeType.SERIES) - sage: series_node.children = [create_normal_node(4), - ....: create_normal_node(5)] - sage: parallel_node = Node(NodeType.PARALLEL) - sage: parallel_node.children = [create_normal_node(6), - ....: create_normal_node(7), create_normal_node(1)] - sage: forest.children.insert(1, series_node) - sage: forest.children.append(parallel_node) - sage: vertex_status = {2: VertexPosition.LEFT_OF_SOURCE, - ....: 3: VertexPosition.SOURCE, - ....: 1: VertexPosition.RIGHT_OF_SOURCE, - ....: 4: VertexPosition.LEFT_OF_SOURCE, - ....: 5: VertexPosition.LEFT_OF_SOURCE, - ....: 6: VertexPosition.RIGHT_OF_SOURCE, - ....: 7: VertexPosition.RIGHT_OF_SOURCE} - sage: vertex_dist = {2: 1, 4: 1, 5: 1, 3: 0, 6: 2, 7: 2, 1: 2} - sage: source_index = 2 - sage: vertices_in_component = {} - sage: mu = {} - sage: left = right = forest.children[2] - sage: for index, component in enumerate(forest.children): - ....: vertices_in_component[index] = get_vertices(component) - ....: component.index_in_root = index - sage: for index, component in enumerate(forest.children): - ....: if index < source_index: - ....: mu[index] = compute_mu_for_co_component(g, index, - ....: source_index, forest, - ....: vertices_in_component) - ....: elif index > source_index: - ....: mu[index] = compute_mu_for_component(g, index, - ....: source_index, forest, - ....: vertices_in_component) - sage: number_components(forest, vertex_status) - sage: check_parallel(g, forest, left, right, - ....: source_index, mu, vertex_dist, - ....: vertices_in_component) - [True, 2] - sage: forest.children - [NORMAL [2], - SERIES [NORMAL [4], NORMAL [5]], - PARALLEL [NORMAL [3], NORMAL [6], NORMAL [7], NORMAL [1]]] - """ - # stores the index of rightmost component included in the parallel module - new_right_index = source_index - - while new_right_index + 1 < len(root.children): - - # component at new_right_index + 1 is added only if it doesn't have - # a component to its right with same comp_num - if has_right_component_fragment(root, new_right_index + 1): - break - - # component at new_right_index + 1 is added only if it doesn't have a - # connected component to its right with vertices at different level - # from its vertices - if has_right_layer_neighbor(graph, root, new_right_index + 1, - vertex_dist, vertices_in_component): - break - - # stores the index in root of new component to be added in the - # parallel module - i = root.children[new_right_index + 1].index_in_root - - # condition for adding more components in the parallel module - if mu[i].index_in_root >= left.index_in_root: - new_right_index += 1 - else: - break - - # if new_right_index > source_index then only parallel - # module can be formed - if source_index != new_right_index: - node = create_parallel_node() - for temp in range(source_index, new_right_index + 1): - - # if module X to be included in the new parallel module Y is also - # parallel then children of X and not X are included in Y - if root.children[temp].node_type == NodeType.PARALLEL: - for child in root.children[temp].children: - node.children.append(child) - child.index_in_root = root.children[temp].index_in_root - else: - node.children.append(root.children[temp]) - - # list elements included in the parallel module are removed from the - # forest - root.children[source_index:new_right_index + 1] = [] - - # insert the newly created parallel module into the forest - root.children.insert(source_index, node) - - return [True, source_index] - - # no parallel module was formed - return [False, source_index] - - -def check_series(root, left, right, source_index, mu): - """ - Assemble the forest to create a series module. - - INPUT: - - - ``root`` -- forest which needs to be assembled - - - ``left`` -- The leftmost fragment of the last module - - - ``right`` -- The rightmost fragment of the last module - - - ``source_index`` -- index of the tree containing the source vertex - - - ``mu`` -- dictionary which maps the (co)components with their mu values - - - ``vertex_dist`` -- dictionary which stores the distance of vertex from - source vertex - - - ``vertices_in_component`` -- dictionary which stores a list of various - vertices in a (co)component - - OUTPUT: - - ``[module_formed, source_index]`` where ``module_formed`` is ``True`` if - module is formed else ``False`` and ``source_index`` is the index of the - new module which contains the source vertex - - EXAMPLES:: - - sage: from sage.graphs.graph_decompositions.modular_decomposition import * - sage: g = Graph() - sage: g.add_vertices([1, 2, 3, 4, 5, 6, 7]) - sage: g.add_edge(2, 3) - sage: g.add_edge(4, 3) - sage: g.add_edge(5, 3) - sage: g.add_edge(2, 6) - sage: g.add_edge(2, 7) - sage: g.add_edge(2, 1) - sage: g.add_edge(6, 1) - sage: g.add_edge(4, 2) - sage: g.add_edge(5, 2) - sage: forest = Node(NodeType.FOREST) - sage: forest.children = [create_normal_node(2), - ....: create_normal_node(3), create_normal_node(1)] - sage: series_node = Node(NodeType.SERIES) - sage: series_node.children = [create_normal_node(4), - ....: create_normal_node(5)] - sage: parallel_node = Node(NodeType.PARALLEL) - sage: parallel_node.children = [create_normal_node(6), - ....: create_normal_node(7)] - sage: forest.children.insert(1, series_node) - sage: forest.children.insert(3, parallel_node) - sage: vertex_status = {2: VertexPosition.LEFT_OF_SOURCE, - ....: 3: VertexPosition.SOURCE, - ....: 1: VertexPosition.RIGHT_OF_SOURCE, - ....: 4: VertexPosition.LEFT_OF_SOURCE, - ....: 5: VertexPosition.LEFT_OF_SOURCE, - ....: 6: VertexPosition.RIGHT_OF_SOURCE, - ....: 7: VertexPosition.RIGHT_OF_SOURCE} - sage: vertex_dist = {2: 1, 4: 1, 5: 1, 3: 0, 6: 2, 7: 2, 1: 3} - sage: source_index = 2 - sage: vertices_in_component = {} - sage: mu = {} - sage: left = right = forest.children[2] - sage: for index, component in enumerate(forest.children): - ....: vertices_in_component[index] = get_vertices(component) - ....: component.index_in_root = index - sage: for index, component in enumerate(forest.children): - ....: if index < source_index: - ....: mu[index] = compute_mu_for_co_component(g, index, - ....: source_index, forest, - ....: vertices_in_component) - ....: elif index > source_index: - ....: mu[index] = compute_mu_for_component(g, index, - ....: source_index, forest, - ....: vertices_in_component) - sage: number_cocomponents(forest, vertex_status) - sage: number_components(forest, vertex_status) - sage: check_series(forest, left, right, - ....: source_index, mu) - [True, 1] - sage: forest.children - [NORMAL [2], - SERIES [NORMAL [4], NORMAL [5], NORMAL [3]], - PARALLEL [NORMAL [6], NORMAL [7]], - NORMAL [1]] - """ - # stores the index of leftmost component included in the parallel module - new_left_index = source_index - - while new_left_index > 0: - - # cocomponent at new_left_index - 1 is added only if it doesn't have - # a cocomponent to its left with same comp_num - if has_left_cocomponent_fragment(root, new_left_index - 1): - break - - # stores the index in root of new cocomponent to be added in the - # series module - i = root.children[new_left_index - 1].index_in_root - - # condition for adding more cocomponents in the series module - if mu[i].index_in_root <= right.index_in_root: - new_left_index -= 1 - else: - break - - # if new_left_index < source_index then only series module can be formed - if source_index != new_left_index: - node = create_series_node() - for temp in range(new_left_index, source_index + 1): - - if root.children[temp].node_type == NodeType.SERIES: - # if module X to be included in the new series module Y is - # also series then children of X and not X are included in Y - for child in root.children[temp].children: - child.index_in_root = root.children[temp].index_in_root - node.children.append(child) - else: - node.children.append(root.children[temp]) - - # list elements included in the series module - # are removed from the forest - root.children[new_left_index:source_index + 1] = [] - - # insert the newly created series module into the forest - root.children.insert(new_left_index, node) - - return [True, new_left_index] - - # no series module could be formed - return [False, new_left_index] - - -def has_left_cocomponent_fragment(root, cocomp_index): - """ - Check whether cocomponent at ``cocomp_index`` has a cocomponent to its left - with same ``comp_num``. - - INPUT: - - - ``root`` -- the forest to which cocomponent belongs - - - ``cocomp_index`` -- index at which cocomponent is present in root - - OUTPUT: - - ``True`` if cocomponent at ``cocomp_index`` has a cocomponent to its left with - same ``comp_num``, and ``False`` otherwise. - - EXAMPLES:: - - sage: from sage.graphs.graph_decompositions.modular_decomposition import * - sage: forest = Node(NodeType.FOREST) - sage: forest.children = [create_normal_node(2), - ....: create_normal_node(3), create_normal_node(1)] - sage: series_node = Node(NodeType.SERIES) - sage: series_node.children = [create_normal_node(4), - ....: create_normal_node(5)] - sage: parallel_node = Node(NodeType.PARALLEL) - sage: parallel_node.children = [create_normal_node(6), - ....: create_normal_node(7)] - sage: forest.children.insert(1, series_node) - sage: forest.children.insert(3, parallel_node) - sage: forest.children[0].comp_num = 1 - sage: forest.children[1].comp_num = 1 - sage: forest.children[1].children[0].comp_num = 1 - sage: forest.children[1].children[1].comp_num = 1 - sage: has_left_cocomponent_fragment(forest, 1) - True - sage: has_left_cocomponent_fragment(forest, 0) - False - """ - return any(root.children[index].comp_num == root.children[cocomp_index].comp_num - for index in range(cocomp_index)) - -def has_right_component_fragment(root, comp_index): - """ - Check whether component at ``comp_index`` has a component to its right with - same ``comp_num``. - - INPUT: - - - ``root`` -- the forest to which component belongs - - - ``comp_index`` -- index at which component is present in root - - OUTPUT: - - ``True`` if component at ``comp_index`` has a component to its right with - same ``comp_num``, and ``False`` otherwise. - - EXAMPLES:: - - sage: from sage.graphs.graph_decompositions.modular_decomposition import * - sage: forest = Node(NodeType.FOREST) - sage: forest.children = [create_normal_node(2), - ....: create_normal_node(3), create_normal_node(1)] - sage: series_node = Node(NodeType.SERIES) - sage: series_node.children = [create_normal_node(4), - ....: create_normal_node(5)] - sage: parallel_node = Node(NodeType.PARALLEL) - sage: parallel_node.children = [create_normal_node(6), - ....: create_normal_node(7)] - sage: forest.children.insert(1, series_node) - sage: forest.children.insert(3, parallel_node) - sage: forest.children[3].comp_num = 1 - sage: forest.children[4].comp_num = 1 - sage: has_right_component_fragment(forest, 3) - True - sage: has_right_component_fragment(forest, 4) - False - """ - return any(root.children[index].comp_num == root.children[comp_index].comp_num - for index in range(comp_index + 1, len(root.children))) - -def has_right_layer_neighbor(graph, root, comp_index, - vertex_dist, vertices_in_component): - """ - Check whether component at ``comp_index`` has a connected component to its - right with vertices at different level from the source vertex. - - INPUT: - - - ``root`` -- the forest to which component belongs - - - ``comp_index`` -- index at which component is present in root - - - ``vertex_dist`` -- dictionary which stores the distance of vertex from - source vertex - - - ``vertices_in_component`` -- dictionary which stores a list of various - vertices in a (co)component - - OUTPUT: - - ``True`` if component at ``comp_index`` has a right layer neighbor, and - ``False`` otherwise. - - EXAMPLES:: - - sage: from sage.graphs.graph_decompositions.modular_decomposition import * - sage: g = Graph() - sage: g.add_vertices([1, 2, 3, 4, 5, 6, 7]) - sage: g.add_edge(2, 3) - sage: g.add_edge(4, 3) - sage: g.add_edge(5, 3) - sage: g.add_edge(2, 6) - sage: g.add_edge(2, 7) - sage: g.add_edge(2, 1) - sage: g.add_edge(6, 1) - sage: forest = Node(NodeType.FOREST) - sage: forest.children = [create_normal_node(2), - ....: create_normal_node(3), create_normal_node(1)] - sage: series_node = Node(NodeType.SERIES) - sage: series_node.children = [create_normal_node(4), - ....: create_normal_node(5)] - sage: parallel_node = Node(NodeType.PARALLEL) - sage: parallel_node.children = [create_normal_node(6), - ....: create_normal_node(7)] - sage: forest.children.insert(1, series_node) - sage: forest.children.insert(3, parallel_node) - sage: vertex_dist = {2: 1, 4: 1, 5: 1, 3: 0, 6: 2, 7: 2, 1: 3} - sage: vertices_in_component = {} - sage: for index, component in enumerate(forest.children): - ....: vertices_in_component[index] = get_vertices(component) - ....: component.index_in_root = index - sage: has_right_layer_neighbor(g, forest, 3, vertex_dist, - ....: vertices_in_component) - True - - """ - for index in range(comp_index + 1, len(root.children)): - - # check vertex in component at index has different level from vertex - # in component at comp_index and are connected to each other - if ((vertex_dist[get_vertex_in(root.children[index])] > - vertex_dist[get_vertex_in(root.children[comp_index])] - ) and - (is_component_connected(graph, root.children[index].index_in_root, - root.children[comp_index].index_in_root, - vertices_in_component) - )): - return True - - return False - - -def get_vertex_in(node): - """ - Return the first vertex encountered in the depth-first traversal of the - tree rooted at node - - INPUT: - - - ``tree`` -- input modular decomposition tree - - OUTPUT: - - Return the first vertex encountered in recursion - - EXAMPLES:: - - sage: from sage.graphs.graph_decompositions.modular_decomposition import * - sage: forest = Node(NodeType.FOREST) - sage: forest.children = [create_normal_node(2), - ....: create_normal_node(3), create_normal_node(1)] - sage: series_node = Node(NodeType.SERIES) - sage: series_node.children = [create_normal_node(4), - ....: create_normal_node(5)] - sage: forest.children.insert(1, series_node) - sage: get_vertex_in(forest) - 2 - """ - while node.node_type != NodeType.NORMAL: - node = node.children[0] - return node.children[0] - -def compute_mu_for_co_component(graph, component_index, source_index, - root, vertices_in_component): - """ - Compute the mu value for co-component - - INPUT: - - - ``graph`` -- Graph whose MD tree needs to be computed - - - ``component_index`` -- index of the co-component - - - ``source_index`` -- index of the source in the forest - - - ``root`` -- the forest which needs to be assembled into a MD tree - - - ``vertices_in_component`` -- dictionary which maps index i to list of - vertices in the tree at index i in the forest - - OUTPUT: - - The mu value (component in the forest) for the co-component - - EXAMPLES:: - - sage: from sage.graphs.graph_decompositions.modular_decomposition import * - sage: g = Graph() - sage: g.add_vertices([1, 2, 3, 4, 5, 6, 7]) - sage: g.add_edge(2, 3) - sage: g.add_edge(4, 3) - sage: g.add_edge(5, 3) - sage: g.add_edge(2, 6) - sage: g.add_edge(2, 7) - sage: g.add_edge(2, 1) - sage: g.add_edge(6, 1) - sage: forest = Node(NodeType.FOREST) - sage: forest.children = [create_normal_node(2), - ....: create_normal_node(3), create_normal_node(1)] - sage: series_node = Node(NodeType.SERIES) - sage: series_node.children = [create_normal_node(4), - ....: create_normal_node(5)] - sage: parallel_node = Node(NodeType.PARALLEL) - sage: parallel_node.children = [create_normal_node(6), - ....: create_normal_node(7)] - sage: forest.children.insert(1, series_node) - sage: forest.children.insert(3, parallel_node) - sage: vertices_in_component = {} - sage: for index, component in enumerate(forest.children): - ....: vertices_in_component[index] = get_vertices(component) - sage: compute_mu_for_co_component(g, 0, 2, forest, - ....: vertices_in_component) - NORMAL [1] - sage: compute_mu_for_co_component(g, 1, 2, forest, - ....: vertices_in_component) - NORMAL [3] - """ - for index in range(len(root.children) - 1, source_index, -1): - if is_component_connected(graph, component_index, - index, vertices_in_component): - return root.children[index] - - # return the default value - return root.children[source_index] - -def compute_mu_for_component(graph, component_index, source_index, - root, vertices_in_component): - """ - Compute the mu value for component - - INPUT: - - - ``graph`` -- Graph whose MD tree needs to be computed - - - ``component_index`` -- index of the component - - - ``source_index`` -- index of the source in the forest - - - ``root`` -- the forest which needs to be assembled into a MD tree - - - ``vertices_in_component`` -- dictionary which maps index i to list of - vertices in the tree at the index i in the forest - - OUTPUT: - - The mu value (co-component in the forest) for the component - - EXAMPLES:: - - sage: from sage.graphs.graph_decompositions.modular_decomposition import * - sage: g = Graph() - sage: g.add_vertices([1, 2, 3, 4, 5, 6, 7]) - sage: g.add_edge(2, 3) - sage: g.add_edge(4, 3) - sage: g.add_edge(5, 3) - sage: g.add_edge(2, 6) - sage: g.add_edge(2, 7) - sage: g.add_edge(6, 1) - sage: forest = Node(NodeType.FOREST) - sage: forest.children = [create_normal_node(2), - ....: create_normal_node(3), create_normal_node(1)] - sage: series_node = Node(NodeType.SERIES) - sage: series_node.children = [create_normal_node(4), - ....: create_normal_node(5)] - sage: parallel_node = Node(NodeType.PARALLEL) - sage: parallel_node.children = [create_normal_node(6), - ....: create_normal_node(7)] - sage: forest.children.insert(1, series_node) - sage: forest.children.insert(3, parallel_node) - sage: vertices_in_component = {} - sage: for index, component in enumerate(forest.children): - ....: vertices_in_component[index] = get_vertices(component) - sage: compute_mu_for_component(g, 3, 2, forest, - ....: vertices_in_component) - SERIES [NORMAL [4], NORMAL [5]] - sage: compute_mu_for_component(g, 4, 2, forest, - ....: vertices_in_component) - NORMAL [2] - """ - # default mu value for a component - mu_for_component = root.children[0] - - for index in range(source_index): - if (mu_for_component == root.children[index] and - is_component_connected(graph, component_index, - index, vertices_in_component)): - mu_for_component = root.children[index + 1] - - # return the default value - return mu_for_component - - -def is_component_connected(graph, index1, index2, vertices_in_component): - """ - Check whether the two specified (co)components are connected. - - INPUT: - - - ``graph`` -- Graph whose MD tree needs to be computed - - - ``index1`` -- index of the first (co)component - - - ``index2`` -- index of the second (co)component - - - ``vertices_in_component`` -- dictionary which maps index i to list of - vertices in the tree at the index i in the forest - - OUTPUT: - - ``True`` if the (co)components are connected else ``False`` - - EXAMPLES:: - - sage: from sage.graphs.graph_decompositions.modular_decomposition import * - sage: g = Graph() - sage: g.add_vertices([1, 2, 3, 4, 5, 6, 7]) - sage: g.add_edge(2, 3) - sage: g.add_edge(4, 3) - sage: g.add_edge(5, 3) - sage: g.add_edge(2, 6) - sage: g.add_edge(2, 7) - sage: g.add_edge(6, 1) - sage: forest = Node(NodeType.FOREST) - sage: forest.children = [create_normal_node(2), - ....: create_normal_node(3), create_normal_node(1)] - sage: series_node = Node(NodeType.SERIES) - sage: series_node.children = [create_normal_node(4), - ....: create_normal_node(5)] - sage: parallel_node = Node(NodeType.PARALLEL) - sage: parallel_node.children = [create_normal_node(6), - ....: create_normal_node(7)] - sage: forest.children.insert(1, series_node) - sage: forest.children.insert(3, parallel_node) - sage: vertices_in_component = {} - sage: for index, component in enumerate(forest.children): - ....: vertices_in_component[index] = get_vertices(component) - sage: is_component_connected(g, 0, 1, vertices_in_component) - False - sage: is_component_connected(g, 0, 3, vertices_in_component) - True - """ - V1 = vertices_in_component[index1] - V2 = frozenset(vertices_in_component[index2]) - - return any(u in V2 for v in V1 for u in graph.neighbor_iterator(v)) - -def get_vertices(component_root): - """ - Compute the list of vertices in the (co)component - - INPUT: - - - ``component_root`` -- root of the (co)component whose vertices need to be - returned as a list - - OUTPUT: - - list of vertices in the (co)component - - EXAMPLES:: - - sage: from sage.graphs.graph_decompositions.modular_decomposition import * - sage: forest = Node(NodeType.FOREST) - sage: forest.children = [create_normal_node(2), - ....: create_normal_node(3), create_normal_node(1)] - sage: series_node = Node(NodeType.SERIES) - sage: series_node.children = [create_normal_node(4), - ....: create_normal_node(5)] - sage: parallel_node = Node(NodeType.PARALLEL) - sage: parallel_node.children = [create_normal_node(6), - ....: create_normal_node(7)] - sage: forest.children.insert(1, series_node) - sage: forest.children.insert(3, parallel_node) - sage: get_vertices(forest) - [2, 4, 5, 3, 6, 7, 1] - """ - vertices = [] - - # inner recursive function to recurse over the elements in the - # ``component`` - def recurse_component(node, vertices): - if node.node_type == NodeType.NORMAL: - vertices.append(node.children[0]) - return - for child in node.children: - recurse_component(child, vertices) - - recurse_component(component_root, vertices) - return vertices - -def promote_left(root): - """ - Perform the promotion phase on the forest root. - - If child and parent both are marked by LEFT_SPLIT then child is removed - and placed just before the parent - - INPUT: - - - ``root`` -- The forest which needs to be promoted - - EXAMPLES:: - - sage: from sage.graphs.graph_decompositions.modular_decomposition import * - sage: g = Graph() - sage: g.add_vertices([1, 2, 3, 4, 5, 6, 7]) - sage: g.add_edge(2, 3) - sage: g.add_edge(4, 3) - sage: g.add_edge(5, 3) - sage: g.add_edge(2, 6) - sage: g.add_edge(4, 7) - sage: g.add_edge(2, 1) - sage: g.add_edge(6, 1) - sage: g.add_edge(4, 2) - sage: g.add_edge(5, 2) - sage: forest = Node(NodeType.FOREST) - sage: forest.children = [create_normal_node(2), - ....: create_normal_node(3), create_normal_node(1)] - sage: series_node = Node(NodeType.SERIES) - sage: series_node.children = [create_normal_node(4), - ....: create_normal_node(5)] - sage: parallel_node = Node(NodeType.PARALLEL) - sage: parallel_node.children = [create_normal_node(6), - ....: create_normal_node(7)] - sage: forest.children.insert(1, series_node) - sage: forest.children.insert(3, parallel_node) - sage: vertex_status = {2: VertexPosition.LEFT_OF_SOURCE, - ....: 3: VertexPosition.SOURCE, - ....: 1: VertexPosition.RIGHT_OF_SOURCE, - ....: 4: VertexPosition.LEFT_OF_SOURCE, - ....: 5: VertexPosition.LEFT_OF_SOURCE, - ....: 6: VertexPosition.RIGHT_OF_SOURCE, - ....: 7: VertexPosition.RIGHT_OF_SOURCE} - sage: vertex_dist = {2: 1, 4: 1, 5: 1, 3: 0, 6: 2, 7: 2, 1: 3} - sage: x = {u for u in g.neighbor_iterator(2) - ....: if vertex_dist[u] != vertex_dist[2]} - sage: maximal_subtrees_with_leaves_in_x(forest, 2, x, vertex_status, - ....: False, 0) - sage: promote_left(forest) - sage: forest - FOREST [NORMAL [2], SERIES [NORMAL [4], NORMAL [5]], NORMAL [3], - PARALLEL [NORMAL [6]], PARALLEL [NORMAL [7]], - PARALLEL [], NORMAL [1]] - """ - q = deque() - - # q has [parent, child] elements as parent needs to be modified - for child in root.children: - q.append([root, child]) - - while q: - - parent, child = q.popleft() - - if child.node_type == NodeType.NORMAL: - continue - - # stores the elements to be removed from the child - to_remove = [] - - # stores the index of child in parent list - index = parent.children.index(child) - - for grand_child in child.children: - - # if tree and child both have LEFT_SPLIT then tree from - # child is inserted just before child in the parent - if grand_child.has_left_split() and child.has_left_split(): - parent.children.insert(index, grand_child) - index += 1 - to_remove.append(grand_child) - q.append([parent, grand_child]) - else: - q.append([child, grand_child]) - - for grand_child in to_remove: - child.children.remove(grand_child) - - -def promote_right(root): - """ - Perform the promotion phase on the forest root. - - If child and parent both are marked by RIGHT_SPLIT then child is removed - and placed just after the parent - - INPUT: - - - ``root`` -- the forest which needs to be promoted - - EXAMPLES:: - - sage: from sage.graphs.graph_decompositions.modular_decomposition import * - sage: g = Graph() - sage: g.add_vertices([1, 2, 3, 4, 5, 6, 7]) - sage: g.add_edge(2, 3) - sage: g.add_edge(4, 3) - sage: g.add_edge(5, 3) - sage: g.add_edge(2, 6) - sage: g.add_edge(4, 7) - sage: g.add_edge(2, 1) - sage: g.add_edge(6, 1) - sage: g.add_edge(4, 2) - sage: g.add_edge(5, 2) - sage: forest = Node(NodeType.FOREST) - sage: forest.children = [create_normal_node(2), - ....: create_normal_node(3), create_normal_node(1)] - sage: series_node = Node(NodeType.SERIES) - sage: series_node.children = [create_normal_node(4), - ....: create_normal_node(5)] - sage: parallel_node = Node(NodeType.PARALLEL) - sage: parallel_node.children = [create_normal_node(6), - ....: create_normal_node(7)] - sage: forest.children.insert(1, series_node) - sage: forest.children.insert(3, parallel_node) - sage: vertex_status = {2: VertexPosition.LEFT_OF_SOURCE, - ....: 3: VertexPosition.SOURCE, - ....: 1: VertexPosition.RIGHT_OF_SOURCE, - ....: 4: VertexPosition.LEFT_OF_SOURCE, - ....: 5: VertexPosition.LEFT_OF_SOURCE, - ....: 6: VertexPosition.RIGHT_OF_SOURCE, - ....: 7: VertexPosition.RIGHT_OF_SOURCE} - sage: vertex_dist = {2: 1, 4: 1, 5: 1, 3: 0, 6: 2, 7: 2, 1: 3} - sage: refine(g, forest, vertex_dist, vertex_status) - sage: promote_right(forest) - sage: forest - FOREST [NORMAL [2], SERIES [SERIES [NORMAL [4]], SERIES [NORMAL [5]]], - NORMAL [3], PARALLEL [], PARALLEL [NORMAL [7]], - PARALLEL [NORMAL [6]], NORMAL [1]] - """ - q = deque() - - # q has [parent, child] elements as parent needs to be modified - for child in root.children: - q.append([root, child]) - - while q: - - parent, child = q.popleft() - - if child.node_type == NodeType.NORMAL: - continue - - # stores the elements to be removed from the child - to_remove = [] - - # stores the index of child in parent list - index = parent.children.index(child) - - for grand_child in child.children: - - # if tree and child both have RIGHT_SPLIT then tree from - # child is inserted just after child in the parent - if grand_child.has_right_split() and child.has_right_split(): - parent.children.insert(index + 1, grand_child) - to_remove.append(grand_child) - q.append([parent, grand_child]) - else: - q.append([child, grand_child]) - - for grand_child in to_remove: - child.children.remove(grand_child) - - -def promote_child(root): - """ - Perform the promotion phase on the forest `root`. - - If marked parent has no children it is removed, if it has one child then - it is replaced by its child - - INPUT: - - - ``root`` -- the forest which needs to be promoted - - EXAMPLES:: - - sage: from sage.graphs.graph_decompositions.modular_decomposition import * - sage: g = Graph() - sage: g.add_vertices([1, 2, 3, 4, 5, 6, 7]) - sage: g.add_edge(2, 3) - sage: g.add_edge(4, 3) - sage: g.add_edge(5, 3) - sage: g.add_edge(2, 6) - sage: g.add_edge(4, 7) - sage: g.add_edge(2, 1) - sage: g.add_edge(6, 1) - sage: g.add_edge(4, 2) - sage: g.add_edge(5, 2) - sage: forest = Node(NodeType.FOREST) - sage: forest.children = [create_normal_node(2), - ....: create_normal_node(3), create_normal_node(1)] - sage: series_node = Node(NodeType.SERIES) - sage: series_node.children = [create_normal_node(4), - ....: create_normal_node(5)] - sage: parallel_node = Node(NodeType.PARALLEL) - sage: parallel_node.children = [create_normal_node(6), - ....: create_normal_node(7)] - sage: forest.children.insert(1, series_node) - sage: forest.children.insert(3, parallel_node) - sage: vertex_status = {2: VertexPosition.LEFT_OF_SOURCE, - ....: 3: VertexPosition.SOURCE, - ....: 1: VertexPosition.RIGHT_OF_SOURCE, - ....: 4: VertexPosition.LEFT_OF_SOURCE, - ....: 5: VertexPosition.LEFT_OF_SOURCE, - ....: 6: VertexPosition.RIGHT_OF_SOURCE, - ....: 7: VertexPosition.RIGHT_OF_SOURCE} - sage: vertex_dist = {2: 1, 4: 1, 5: 1, 3: 0, 6: 2, 7: 2, 1: 3} - sage: refine(g, forest, vertex_dist, vertex_status) - sage: promote_right(forest) - sage: promote_child(forest) - sage: forest - FOREST [NORMAL [2], SERIES [NORMAL [4], NORMAL [5]], NORMAL [3], - NORMAL [7], NORMAL [6], NORMAL [1]] - """ - q = deque() - - # q has [parent, child] elements as parent needs to be modified - for child in root.children: - q.append([root, child]) - - while q: - - parent, child = q.popleft() - - if child.node_type == NodeType.NORMAL: - continue - - # if child node itself has only one child - if (len(child.children) == 1 and - (child.node_split != NodeSplit.NO_SPLIT or - child.node_type == NodeType.FOREST)): - # replace child node by its own child - - grand_child = child.children[0] - index = parent.children.index(child) - parent.children.insert(index, grand_child) - parent.children.remove(child) - q.append([parent, grand_child]) - # if child node has no children - elif ((not child.children) and child.node_split != NodeSplit.NO_SPLIT): - # remove the child node - parent.children.remove(child) - else: - for grand_child in child.children: - q.append([child, grand_child]) - - -def clear_node_split_info(root): - """ - Set the node_split of nodes to NO_SPLIT - - INPUT: - - - ``root`` -- the forest which needs to be cleared of split information - - EXAMPLES:: - - sage: from sage.graphs.graph_decompositions.modular_decomposition import * - sage: forest = Node(NodeType.FOREST) - sage: forest.children = [create_normal_node(2), - ....: create_normal_node(3), create_normal_node(1)] - sage: series_node = Node(NodeType.SERIES) - sage: series_node.children = [create_normal_node(4), - ....: create_normal_node(5)] - sage: series_node.children[0].node_split = NodeSplit.LEFT_SPLIT - sage: series_node.node_split = NodeSplit.RIGHT_SPLIT - sage: forest.children.insert(1, series_node) - sage: clear_node_split_info(forest) - sage: series_node.node_split == NodeSplit.NO_SPLIT - True - sage: series_node.children[0].node_split == NodeSplit.NO_SPLIT - True - """ - root.node_split = NodeSplit.NO_SPLIT - - if root.node_type != NodeType.NORMAL: - for node in root.children: - clear_node_split_info(node) - - -def refine(graph, root, vertex_dist, vertex_status): - """ - Refine the forest based on the active edges - - INPUT: - - - ``graph`` -- graph whose MD tree needs to be computed - - - ``root`` -- the forest which needs to be assembled into a MD tree - - - ``vertex_dist`` -- dictionary mapping the vertex with distance from the - source - - - ``vertex_status`` -- dictionary mapping the vertex to the position w.r.t. - source - - EXAMPLES:: - - sage: from sage.graphs.graph_decompositions.modular_decomposition import * - sage: g = Graph() - sage: g.add_vertices([1, 2, 3, 4, 5, 6, 7]) - sage: g.add_edge(2, 3) - sage: g.add_edge(4, 3) - sage: g.add_edge(5, 3) - sage: g.add_edge(2, 6) - sage: g.add_edge(2, 7) - sage: g.add_edge(2, 1) - sage: g.add_edge(6, 1) - sage: g.add_edge(4, 2) - sage: g.add_edge(5, 2) - sage: forest = Node(NodeType.FOREST) - sage: forest.children = [create_normal_node(2), - ....: create_normal_node(3), create_normal_node(1)] - sage: series_node = Node(NodeType.SERIES) - sage: series_node.children = [create_normal_node(4), - ....: create_normal_node(5)] - sage: parallel_node = Node(NodeType.PARALLEL) - sage: parallel_node.children = [create_normal_node(6), - ....: create_normal_node(7)] - sage: forest.children.insert(1, series_node) - sage: forest.children.insert(3, parallel_node) - sage: vertex_status = {2: VertexPosition.LEFT_OF_SOURCE, - ....: 3: VertexPosition.SOURCE, - ....: 1: VertexPosition.RIGHT_OF_SOURCE, - ....: 4: VertexPosition.LEFT_OF_SOURCE, - ....: 5: VertexPosition.LEFT_OF_SOURCE, - ....: 6: VertexPosition.RIGHT_OF_SOURCE, - ....: 7: VertexPosition.RIGHT_OF_SOURCE} - sage: vertex_dist = {2: 1, 4: 1, 5: 1, 3: 0, 6: 2, 7: 2, 1: 3} - sage: refine(g, forest, vertex_dist, vertex_status) - sage: forest - FOREST [NORMAL [2], SERIES [NORMAL [4], NORMAL [5]], NORMAL [3], - PARALLEL [PARALLEL [NORMAL [6]], PARALLEL [NORMAL [7]]], - NORMAL [1]] - """ - x_used = [] - - # active edges of each vertex in the graph is used to refine the forest - for v in graph.vertices(): - if v in vertex_status and vertex_status[v] == VertexPosition.SOURCE: - continue - - # set of vertices connected through active edges to v - x = {u for u in graph.neighbor_iterator(v) - if vertex_dist[u] != vertex_dist[v]} - - if x not in x_used: - x_used.append(x) - maximal_subtrees_with_leaves_in_x(root, v, x, - vertex_status, False, 0) - - get_child_splits(root) - - -def get_child_splits(root): - """ - Add the node_split of children to the parent node - - INPUT: - - - ``root`` -- input modular decomposition tree - - EXAMPLES:: - - sage: from sage.graphs.graph_decompositions.modular_decomposition import * - sage: forest = Node(NodeType.FOREST) - sage: forest.children = [create_normal_node(2), - ....: create_normal_node(3), create_normal_node(1)] - sage: series_node = Node(NodeType.SERIES) - sage: series_node.children = [create_normal_node(4), - ....: create_normal_node(5)] - sage: series_node.children[0].node_split = NodeSplit.LEFT_SPLIT - sage: series_node.node_split = NodeSplit.RIGHT_SPLIT - sage: forest.children.insert(1, series_node) - sage: get_child_splits(forest) - sage: series_node.node_split == NodeSplit.BOTH_SPLIT - True - sage: forest.node_split == NodeSplit.BOTH_SPLIT - True - """ - if root.node_type != NodeType.NORMAL: - for node in root.children: - get_child_splits(node) - root.set_node_split(node.node_split) - - -def maximal_subtrees_with_leaves_in_x(root, v, x, vertex_status, - tree_left_of_source, level): - """ - Refine the forest based on the active edges(x) of vertex v - - INPUT: - - - ``root`` -- the forest which needs to be assembled into a MD tree - - - ``v`` -- the vertex used to refine - - - ``x`` -- set of vertices connected to v and at different distance - from source compared to v - - - ``vertex_status`` -- dictionary mapping the vertex to the position - w.r.t source - - - ``tree_left_of_source`` -- flag indicating whether tree is - - - ``level`` -- indicates the recursion level, 0 for root - - OUTPUT: - - ``[contained_in_x, split]`` where ``contained_in_x`` is ``True`` if all - vertices in root are subset of x else ``False`` and ``split`` is the - split which occurred at any node in root - - EXAMPLES:: - - sage: from sage.graphs.graph_decompositions.modular_decomposition import * - sage: g = Graph() - sage: g.add_vertices([1, 2, 3, 4, 5, 6, 7]) - sage: g.add_edge(2, 3) - sage: g.add_edge(4, 3) - sage: g.add_edge(5, 3) - sage: g.add_edge(2, 6) - sage: g.add_edge(2, 7) - sage: g.add_edge(2, 1) - sage: g.add_edge(6, 1) - sage: g.add_edge(4, 2) - sage: g.add_edge(5, 2) - sage: forest = Node(NodeType.FOREST) - sage: forest.children = [create_normal_node(2), - ....: create_normal_node(3), create_normal_node(1)] - sage: series_node = Node(NodeType.SERIES) - sage: series_node.children = [create_normal_node(4), - ....: create_normal_node(5)] - sage: parallel_node = Node(NodeType.PARALLEL) - sage: parallel_node.children = [create_normal_node(6), - ....: create_normal_node(7)] - sage: forest.children.insert(1, series_node) - sage: forest.children.insert(3, parallel_node) - sage: vertex_status = {2: VertexPosition.LEFT_OF_SOURCE, - ....: 3: VertexPosition.SOURCE, - ....: 1: VertexPosition.RIGHT_OF_SOURCE, - ....: 4: VertexPosition.LEFT_OF_SOURCE, - ....: 5: VertexPosition.LEFT_OF_SOURCE, - ....: 6: VertexPosition.RIGHT_OF_SOURCE, - ....: 7: VertexPosition.RIGHT_OF_SOURCE} - sage: vertex_dist = {2: 1, 4: 1, 5: 1, 3: 0, 6: 2, 7: 2, 1: 3} - sage: x = {u for u in g.neighbor_iterator(2) - ....: if vertex_dist[u] != vertex_dist[2]} - sage: maximal_subtrees_with_leaves_in_x(forest, 2, x, vertex_status, - ....: False, 0) - sage: forest - FOREST [NORMAL [2], SERIES [NORMAL [4], NORMAL [5]], NORMAL [3], - PARALLEL [NORMAL [6], NORMAL [7]], NORMAL [1]] - sage: x = {u for u in g.neighbor_iterator(1) - ....: if vertex_dist[u] != vertex_dist[1]} - sage: maximal_subtrees_with_leaves_in_x(forest, 1, x, vertex_status, - ....: False, 0) - sage: forest - FOREST [NORMAL [2], SERIES [NORMAL [4], NORMAL [5]], NORMAL [3], - PARALLEL [PARALLEL [NORMAL [6]], PARALLEL [NORMAL [7]]], - NORMAL [1]] - """ - def update_node_info(node, node_type, node_split, comp_num, subtree_list): - """ - Set the various fields for a tree node and update its subtrees - - - ``node`` -- node whose fields need to be updated - - ``node_type`` -- node_type to be set - - ``node_split`` -- node_split to be set - - ``comp_num`` -- comp_num to be set - - ``subtree_list`` -- list containing the subtrees - - """ - node.node_type = node_type - node.node_split = node_split - node.comp_num = comp_num - node.children = subtree_list - - return_split = NodeSplit.NO_SPLIT # initialize split to NO_SPLIT - - # all trees in a forest are refined using x - if root.node_type == NodeType.FOREST: - - # indicates whether tree is left of source, True if left of source - left_flag = True - - for node in root.children: - if (node.node_type == NodeType.NORMAL and - node.children[0] in vertex_status and - vertex_status[node.children[0]] == VertexPosition.SOURCE): - left_flag = False - subtree_result = maximal_subtrees_with_leaves_in_x(node, v, x, - vertex_status, - left_flag, - level) - if subtree_result: - # Mark the ancestors - root.set_node_split(subtree_result[1]) - - # handles the prime, series and parallel cases - elif root.node_type != NodeType.NORMAL: - - flag = True # indicates the entire root is contained in x - split_flag = False # indicates a split is required - Ta = [] # contains subtrees with leaves in x - Tb = [] # contains subtrees with leaves not in x - - for node in root.children: - - # refines the children of root - subtree_result = maximal_subtrees_with_leaves_in_x(node, v, x, - vertex_status, - tree_left_of_source, - level + 1) - - if subtree_result: - flag = flag and subtree_result[0] - - # add the node split of children to root - root.set_node_split(subtree_result[1]) - - if subtree_result[0]: - Ta.append(node) - split_flag = True - else: - Tb.append(node) - - if root.node_type == NodeType.PRIME: - # mark all the children of prime nodes - for node in root.children: - node.set_node_split(root.node_split) - - if flag: - # return if all subtrees are in x, no split required - return [True, root.node_split] - elif split_flag: # split required` - - split = NodeSplit.LEFT_SPLIT - - # if v is right of source and tree is also right of source then - # RIGHT_SPLIT - if (vertex_status[v] == VertexPosition.RIGHT_OF_SOURCE and - not tree_left_of_source): - split = NodeSplit.RIGHT_SPLIT - - # add the split to root node_split - root.set_node_split(split) - - if root.node_type == NodeType.PRIME: - # mark all the children of prime nodes - for node in root.children: - node.set_node_split(split) - return [False, split] - - if root.is_separated: - # if root has already been split then further split not - # required - return [flag, root.node_split] - - node_type = root.node_type - root.is_separated = True - - # root[1] would now contain Ta and Tb - root.children = [] - - # add two nodes for Ta and Tb - a = create_parallel_node() - update_node_info(a, node_type, root.node_split, - Ta[0].comp_num, Ta) - b = create_parallel_node() - update_node_info(b, node_type, root.node_split, - Tb[0].comp_num, Tb) - root.children.append(a) - root.children.append(b) - - return_split = root.node_split - return [flag, return_split] - # root is a vertex and is contained in x - elif root.children[0] in x: - return [True, root.node_split] - # root is a vertex and is not contained in x - else: - return [False, root.node_split] - def create_prime_node(): """ @@ -2417,18 +368,18 @@ def print_md_tree(root): sage: from sage.graphs.graph_decompositions.modular_decomposition import * sage: print_md_tree(modular_decomposition(graphs.IcosahedralGraph())) PRIME + 1 5 7 - 11 - 1 8 + 11 0 + 2 + 6 + 3 9 4 10 - 6 - 2 - 3 """ def recursive_print_md_tree(root, level): @@ -2699,6 +650,7 @@ def habib_maurer_algorithm(graph, g_classes=None): for sg in g_comp.connected_components()] return root +modular_decomposition = habib_maurer_algorithm #============================================================================= # Below functions are implemented to test the modular decomposition tree @@ -2797,6 +749,49 @@ def test_maximal_modules(tree_root, graph): return False return True +def get_vertices(component_root): + """ + Compute the list of vertices in the (co)component + + INPUT: + + - ``component_root`` -- root of the (co)component whose vertices need to be + returned as a list + + OUTPUT: + + list of vertices in the (co)component + + EXAMPLES:: + + sage: from sage.graphs.graph_decompositions.modular_decomposition import * + sage: forest = Node(NodeType.FOREST) + sage: forest.children = [create_normal_node(2), + ....: create_normal_node(3), create_normal_node(1)] + sage: series_node = Node(NodeType.SERIES) + sage: series_node.children = [create_normal_node(4), + ....: create_normal_node(5)] + sage: parallel_node = Node(NodeType.PARALLEL) + sage: parallel_node.children = [create_normal_node(6), + ....: create_normal_node(7)] + sage: forest.children.insert(1, series_node) + sage: forest.children.insert(3, parallel_node) + sage: get_vertices(forest) + [2, 4, 5, 3, 6, 7, 1] + """ + vertices = [] + + # inner recursive function to recurse over the elements in the + # ``component`` + def recurse_component(node, vertices): + if node.node_type == NodeType.NORMAL: + vertices.append(node.children[0]) + return + for child in node.children: + recurse_component(child, vertices) + + recurse_component(component_root, vertices) + return vertices # Function implemented for testing def get_module_type(graph): @@ -2977,15 +972,15 @@ def children_node_type(module, node_type): sage: tree_root = modular_decomposition(g) sage: print_md_tree(modular_decomposition(g)) SERIES - PARALLEL - 2 - 3 - PARALLEL - 1 - 4 - PARALLEL - 0 - 5 + PARALLEL + 0 + 5 + PARALLEL + 1 + 4 + PARALLEL + 2 + 3 sage: children_node_type(tree_root, NodeType.SERIES) False sage: children_node_type(tree_root, NodeType.PARALLEL) @@ -3014,15 +1009,15 @@ def either_connected_or_not_connected(v, vertices_in_module, graph): sage: g = graphs.OctahedralGraph() sage: print_md_tree(modular_decomposition(g)) SERIES - PARALLEL - 2 - 3 - PARALLEL - 1 - 4 - PARALLEL - 0 - 5 + PARALLEL + 0 + 5 + PARALLEL + 1 + 4 + PARALLEL + 2 + 3 sage: either_connected_or_not_connected(2, [1, 4], g) True sage: either_connected_or_not_connected(2, [3, 4], g) @@ -3054,7 +1049,7 @@ def tree_to_nested_tuple(root): sage: from sage.graphs.graph_decompositions.modular_decomposition import * sage: g = graphs.OctahedralGraph() sage: tree_to_nested_tuple(modular_decomposition(g)) - (SERIES, [(PARALLEL, [2, 3]), (PARALLEL, [1, 4]), (PARALLEL, [0, 5])]) + (SERIES, [(PARALLEL, [0, 5]), (PARALLEL, [1, 4]), (PARALLEL, [2, 3])]) """ if root.node_type == NodeType.NORMAL: return root.children[0] From 60a30a6c9db46b8836a5a2c1c2980a3d90e8922e Mon Sep 17 00:00:00 2001 From: Julien Grijalva Date: Wed, 25 May 2022 17:42:27 -0600 Subject: [PATCH 473/529] changes to $PATH construction more specific substring to test for pyenv, trailing `:` is now removed. --- build/bin/sage-bootstrap-python | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build/bin/sage-bootstrap-python b/build/bin/sage-bootstrap-python index 6c3e20010e0..ddd5a19866f 100755 --- a/build/bin/sage-bootstrap-python +++ b/build/bin/sage-bootstrap-python @@ -16,12 +16,12 @@ NEW_PATH="" for path in $SAGE_ORIG_PATH do case "$path" in - *"pyenv"*);; - * ) NEW_PATH="$NEW_PATH$path:";; + '/home/'*'/.pyenv/shims'*);; + *) NEW_PATH="$NEW_PATH$path:";; esac done IFS=' ' -SAGE_ORIG_PATH=$NEW_PATH +SAGE_ORIG_PATH=${NEW_PATH%%':'} # In particular, it is invoked by "bootstrap -d" for sage-download-file, # i.e., before a configure run, and by "sage-spkg", also for sage-download-file. # So it needs to find a python that has the urllib module. From ec49dd290ac63bfeea13a81d8a09ed102f269331 Mon Sep 17 00:00:00 2001 From: Julien Grijalva Date: Wed, 25 May 2022 18:52:28 -0600 Subject: [PATCH 474/529] less specific pyenv pattern --- build/bin/sage-bootstrap-python | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/bin/sage-bootstrap-python b/build/bin/sage-bootstrap-python index ddd5a19866f..448efa5bcc0 100755 --- a/build/bin/sage-bootstrap-python +++ b/build/bin/sage-bootstrap-python @@ -16,7 +16,7 @@ NEW_PATH="" for path in $SAGE_ORIG_PATH do case "$path" in - '/home/'*'/.pyenv/shims'*);; + */.pyenv/shims*);; *) NEW_PATH="$NEW_PATH$path:";; esac done From 22f15f5d1a2935afebdabb130797e6370be464fd Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Thu, 26 May 2022 10:45:28 +0100 Subject: [PATCH 475/529] mention trac ticket number --- src/sage/graphs/graph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index 089240f15e8..edb40ddc10d 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -7696,7 +7696,7 @@ def modular_decomposition(self, style='tuple'): .. NOTE:: A buggy implementation of linear time algorithm from [TCHP2008]_ was - removed in Sage 9.7. + removed in Sage 9.7, see :trac:`25872`. TESTS: From 790dde82614119bb7b4c5e7e22f21dd825b74dec Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 20 Apr 2022 16:59:02 -0700 Subject: [PATCH 476/529] Drop Python 3.7 support --- build/pkgs/python3/spkg-configure.m4 | 4 ++-- pkgs/sage-docbuild/setup.cfg | 3 +-- pkgs/sage-setup/setup.cfg | 4 ++-- pkgs/sagemath-categories/setup.cfg.m4 | 4 ++-- pkgs/sagemath-objects/setup.cfg.m4 | 4 ++-- pyrightconfig.json | 2 +- src/doc/de/tutorial/interactive_shell.rst | 6 +++--- src/doc/en/developer/coding_in_python.rst | 8 ++++---- src/doc/en/developer/portability_testing.rst | 2 +- src/doc/en/installation/source.rst | 2 +- src/doc/en/tutorial/interactive_shell.rst | 6 +++--- src/doc/fr/tutorial/interactive_shell.rst | 6 +++--- src/doc/ja/tutorial/interactive_shell.rst | 6 +++--- src/doc/pt/tutorial/interactive_shell.rst | 6 +++--- src/doc/ru/tutorial/interactive_shell.rst | 6 +++--- src/setup.cfg.m4 | 4 ++-- tox.ini | 11 ++++------- 17 files changed, 40 insertions(+), 44 deletions(-) diff --git a/build/pkgs/python3/spkg-configure.m4 b/build/pkgs/python3/spkg-configure.m4 index 27af5be576d..4575cd0743f 100644 --- a/build/pkgs/python3/spkg-configure.m4 +++ b/build/pkgs/python3/spkg-configure.m4 @@ -1,6 +1,6 @@ SAGE_SPKG_CONFIGURE([python3], [ - m4_pushdef([MIN_VERSION], [3.7.0]) - m4_pushdef([MIN_NONDEPRECATED_VERSION], [3.7.0]) + m4_pushdef([MIN_VERSION], [3.8.0]) + m4_pushdef([MIN_NONDEPRECATED_VERSION], [3.8.0]) m4_pushdef([LT_STABLE_VERSION], [3.11.0]) m4_pushdef([LT_VERSION], [3.11.0]) AC_ARG_WITH([python], diff --git a/pkgs/sage-docbuild/setup.cfg b/pkgs/sage-docbuild/setup.cfg index 0952f72a1d3..abc71ffcd00 100644 --- a/pkgs/sage-docbuild/setup.cfg +++ b/pkgs/sage-docbuild/setup.cfg @@ -17,10 +17,9 @@ classifiers = Operating System :: POSIX Operating System :: MacOS :: MacOS X Programming Language :: Python :: 3 :: Only - Programming Language :: Python :: 3.6 - Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 + Programming Language :: Python :: 3.10 Programming Language :: Python :: Implementation :: CPython Topic :: Scientific/Engineering :: Mathematics diff --git a/pkgs/sage-setup/setup.cfg b/pkgs/sage-setup/setup.cfg index 197fc6791dc..79fd069f7c0 100644 --- a/pkgs/sage-setup/setup.cfg +++ b/pkgs/sage-setup/setup.cfg @@ -17,9 +17,9 @@ classifiers = Operating System :: POSIX Operating System :: MacOS :: MacOS X Programming Language :: Python :: 3 :: Only - Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 + Programming Language :: Python :: 3.10 Programming Language :: Python :: Implementation :: CPython Topic :: Scientific/Engineering :: Mathematics @@ -31,7 +31,7 @@ packages = sage_setup.autogen.interpreters.specs sage_setup.command -python_requires = >=3.7, <3.11 +python_requires = >=3.8, <3.11 install_requires = pkgconfig diff --git a/pkgs/sagemath-categories/setup.cfg.m4 b/pkgs/sagemath-categories/setup.cfg.m4 index bad7e5ffd19..6bf81129de3 100644 --- a/pkgs/sagemath-categories/setup.cfg.m4 +++ b/pkgs/sagemath-categories/setup.cfg.m4 @@ -18,14 +18,14 @@ classifiers = Operating System :: POSIX Operating System :: MacOS :: MacOS X Programming Language :: Python :: 3 :: Only - Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 + Programming Language :: Python :: 3.10 Programming Language :: Python :: Implementation :: CPython Topic :: Scientific/Engineering :: Mathematics [options] -python_requires = >=3.7, <3.10 +python_requires = >=3.8, <3.11 install_requires = esyscmd(`sage-get-system-packages install-requires \ cython \ diff --git a/pkgs/sagemath-objects/setup.cfg.m4 b/pkgs/sagemath-objects/setup.cfg.m4 index d4dc4402264..34a4ffd2bc6 100644 --- a/pkgs/sagemath-objects/setup.cfg.m4 +++ b/pkgs/sagemath-objects/setup.cfg.m4 @@ -18,14 +18,14 @@ classifiers = Operating System :: POSIX Operating System :: MacOS :: MacOS X Programming Language :: Python :: 3 :: Only - Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 + Programming Language :: Python :: 3.10 Programming Language :: Python :: Implementation :: CPython Topic :: Scientific/Engineering :: Mathematics [options] -python_requires = >=3.7, <3.10 +python_requires = >=3.8, <3.11 install_requires = esyscmd(`sage-get-system-packages install-requires \ cython \ diff --git a/pyrightconfig.json b/pyrightconfig.json index ac8865ed58b..2bcc9ea2a10 100644 --- a/pyrightconfig.json +++ b/pyrightconfig.json @@ -7,7 +7,7 @@ "root": "src" } ], - "pythonVersion": "3.7", + "pythonVersion": "3.8", "exclude": ["venv"], "venvPath": "./venv/", "venv": "./", diff --git a/src/doc/de/tutorial/interactive_shell.rst b/src/doc/de/tutorial/interactive_shell.rst index 869029fa70e..822fef4ec67 100644 --- a/src/doc/de/tutorial/interactive_shell.rst +++ b/src/doc/de/tutorial/interactive_shell.rst @@ -16,7 +16,7 @@ vornehmen. Nach dem Start von Sage sehen Sie etwa folgendes: ┌────────────────────────────────────────────────────────────────────┐ │ SageMath version 9.0, Release Date: 2020-01-01 │ - │ Using Python 3.7.3. Type "help()" for help. │ + │ Using Python 3.10.4. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ @@ -176,7 +176,7 @@ in einer zukünftigen Sitzung (indem Sie einfach die Log-Datei laden). was@form:~$ sage ┌────────────────────────────────────────────────────────────────────┐ │ SageMath version 9.0, Release Date: 2020-01-01 │ - │ Using Python 3.7.3. Type "help()" for help. │ + │ Using Python 3.10.4. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ sage: logstart setup @@ -195,7 +195,7 @@ in einer zukünftigen Sitzung (indem Sie einfach die Log-Datei laden). was@form:~$ sage ┌────────────────────────────────────────────────────────────────────┐ │ SageMath version 9.0, Release Date: 2020-01-01 │ - │ Using Python 3.7.3. Type "help()" for help. │ + │ Using Python 3.10.4. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ sage: load("setup") diff --git a/src/doc/en/developer/coding_in_python.rst b/src/doc/en/developer/coding_in_python.rst index 6214eb51e4d..da8d7de2d08 100644 --- a/src/doc/en/developer/coding_in_python.rst +++ b/src/doc/en/developer/coding_in_python.rst @@ -16,14 +16,14 @@ that Sage supports. The information regarding the supported versions can be found in the files ``build/pkgs/python3/spkg-configure.m4`` and ``src/setup.cfg.m4``. -As of Sage 9.4, Python 3.7 is the oldest supported version. Hence, -all language and library features that are available in Python 3.7 can -be used; but features introduced in Python 3.8 cannot be used. If a +As of Sage 9.7, Python 3.8 is the oldest supported version. Hence, +all language and library features that are available in Python 3.8 can +be used; but features introduced in Python 3.9 cannot be used. If a feature is deprecated in a newer supported version, it must be ensured that deprecation warnings issued by Python do not lead to failures in doctests. -Some key language and library features have been backported to Python 3.7 +Some key language and library features have been backported to Python 3.8 using one of two mechanisms: - ``from __future__ import annotations`` (see diff --git a/src/doc/en/developer/portability_testing.rst b/src/doc/en/developer/portability_testing.rst index ad4b5521ffa..a0a7cbf40b8 100644 --- a/src/doc/en/developer/portability_testing.rst +++ b/src/doc/en/developer/portability_testing.rst @@ -897,7 +897,7 @@ The ``local-homebrew-macos-standard-python3_xcode`` environment installs the same packages, but uses XCode's ``/usr/bin/python3``. The ``local-homebrew-macos-standard-python3_pythonorg`` expects an -installation of Python 3.7 in +installation of Python 3.10 in ``/Library/Frameworks/Python.framework``; this is where the binary packages provided by python.org install themselves. diff --git a/src/doc/en/installation/source.rst b/src/doc/en/installation/source.rst index c235b45b5f8..4bddcc1e7b4 100644 --- a/src/doc/en/installation/source.rst +++ b/src/doc/en/installation/source.rst @@ -599,7 +599,7 @@ General procedure $ sage ┌────────────────────────────────────────────────────────────────────┐ │ SageMath version 8.8, Release Date: 2019-06-26 │ - │ Using Python 3.7.3. Type "help()" for help. │ + │ Using Python 3.10.4. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ sage: diff --git a/src/doc/en/tutorial/interactive_shell.rst b/src/doc/en/tutorial/interactive_shell.rst index 3029ad8b6b5..8c7d340f5ac 100644 --- a/src/doc/en/tutorial/interactive_shell.rst +++ b/src/doc/en/tutorial/interactive_shell.rst @@ -14,7 +14,7 @@ Sage, you get output similar to the following: ┌────────────────────────────────────────────────────────────────────┐ │ SageMath version 9.0, Release Date: 2020-01-01 │ - │ Using Python 3.7.3. Type "help()" for help. │ + │ Using Python 3.10.4. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ @@ -174,7 +174,7 @@ file). was@form:~$ sage ┌────────────────────────────────────────────────────────────────────┐ │ SageMath version 9.0, Release Date: 2020-01-01 │ - │ Using Python 3.7.3. Type "help()" for help. │ + │ Using Python 3.10.4. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ sage: logstart setup @@ -193,7 +193,7 @@ file). was@form:~$ sage ┌────────────────────────────────────────────────────────────────────┐ │ SageMath version 9.0, Release Date: 2020-01-01 │ - │ Using Python 3.7.3. Type "help()" for help. │ + │ Using Python 3.10.4. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ sage: load("setup") diff --git a/src/doc/fr/tutorial/interactive_shell.rst b/src/doc/fr/tutorial/interactive_shell.rst index c38140f781b..99e215391db 100644 --- a/src/doc/fr/tutorial/interactive_shell.rst +++ b/src/doc/fr/tutorial/interactive_shell.rst @@ -18,7 +18,7 @@ le shell Sage affiche un message de ce genre : ┌────────────────────────────────────────────────────────────────────┐ │ SageMath version 9.0, Release Date: 2020-01-01 │ - │ Using Python 3.7.3. Type "help()" for help. │ + │ Using Python 3.10.4. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ @@ -183,7 +183,7 @@ session future (en rechargeant le fichier journal). was@form:~$ sage ┌────────────────────────────────────────────────────────────────────┐ │ SageMath version 9.0, Release Date: 2020-01-01 │ - │ Using Python 3.7.3. Type "help()" for help. │ + │ Using Python 3.10.4. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ sage: logstart setup @@ -202,7 +202,7 @@ session future (en rechargeant le fichier journal). was@form:~$ sage ┌────────────────────────────────────────────────────────────────────┐ │ SageMath version 9.0, Release Date: 2020-01-01 │ - │ Using Python 3.7.3. Type "help()" for help. │ + │ Using Python 3.10.4. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ sage: load("setup") diff --git a/src/doc/ja/tutorial/interactive_shell.rst b/src/doc/ja/tutorial/interactive_shell.rst index 452914bd12a..4847d9b0775 100644 --- a/src/doc/ja/tutorial/interactive_shell.rst +++ b/src/doc/ja/tutorial/interactive_shell.rst @@ -15,7 +15,7 @@ Sageを起動すると,すぐに次のような画面が現れる: ┌────────────────────────────────────────────────────────────────────┐ │ SageMath version 9.0, Release Date: 2020-01-01 │ - │ Using Python 3.7.3. Type "help()" for help. │ + │ Using Python 3.10.4. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ @@ -164,7 +164,7 @@ Sageセッションのロギングと,セッションの保存(:ref:`section-s was@form:~$ sage ┌────────────────────────────────────────────────────────────────────┐ │ SageMath version 9.0, Release Date: 2020-01-01 │ - │ Using Python 3.7.3. Type "help()" for help. │ + │ Using Python 3.10.4. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ sage: logstart setup @@ -183,7 +183,7 @@ Sageセッションのロギングと,セッションの保存(:ref:`section-s was@form:~$ sage ┌────────────────────────────────────────────────────────────────────┐ │ SageMath version 9.0, Release Date: 2020-01-01 │ - │ Using Python 3.7.3. Type "help()" for help. │ + │ Using Python 3.10.4. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ sage: load("setup") diff --git a/src/doc/pt/tutorial/interactive_shell.rst b/src/doc/pt/tutorial/interactive_shell.rst index 1b3ec525c89..1737498abaa 100644 --- a/src/doc/pt/tutorial/interactive_shell.rst +++ b/src/doc/pt/tutorial/interactive_shell.rst @@ -17,7 +17,7 @@ obtém o seguinte: ┌────────────────────────────────────────────────────────────────────┐ │ SageMath version 9.0, Release Date: 2020-01-01 │ - │ Using Python 3.7.3. Type "help()" for help. │ + │ Using Python 3.10.4. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ sage: @@ -175,7 +175,7 @@ arquivo log). was@form:~$ sage ┌────────────────────────────────────────────────────────────────────┐ │ SageMath version 9.0, Release Date: 2020-01-01 │ - │ Using Python 3.7.3. Type "help()" for help. │ + │ Using Python 3.10.4. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ sage: logstart setup @@ -194,7 +194,7 @@ arquivo log). was@form:~$ sage ┌────────────────────────────────────────────────────────────────────┐ │ SageMath version 9.0, Release Date: 2020-01-01 │ - │ Using Python 3.7.3. Type "help()" for help. │ + │ Using Python 3.10.4. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ sage: load "setup" diff --git a/src/doc/ru/tutorial/interactive_shell.rst b/src/doc/ru/tutorial/interactive_shell.rst index 9129eeee005..621426eda9b 100644 --- a/src/doc/ru/tutorial/interactive_shell.rst +++ b/src/doc/ru/tutorial/interactive_shell.rst @@ -17,7 +17,7 @@ Sage вы увидите вывод, похожий на следующий: ┌────────────────────────────────────────────────────────────────────┐ │ SageMath version 9.0, Release Date: 2020-01-01 │ - │ Using Python 3.7.3. Type "help()" for help. │ + │ Using Python 3.10.4. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ sage: @@ -167,7 +167,7 @@ Notebook), то вы можете ввести ``%hist``, чтобы вывес was@form:~$ sage ┌────────────────────────────────────────────────────────────────────┐ │ SageMath version 9.0, Release Date: 2020-01-01 │ - │ Using Python 3.7.3. Type "help()" for help. │ + │ Using Python 3.10.4. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ sage: logstart setup @@ -186,7 +186,7 @@ Notebook), то вы можете ввести ``%hist``, чтобы вывес was@form:~$ sage ┌────────────────────────────────────────────────────────────────────┐ │ SageMath version 9.0, Release Date: 2020-01-01 │ - │ Using Python 3.7.3. Type "help()" for help. │ + │ Using Python 3.10.4. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ sage: load("setup") diff --git a/src/setup.cfg.m4 b/src/setup.cfg.m4 index aff2e5d7cf8..8f4cdd8ab0d 100644 --- a/src/setup.cfg.m4 +++ b/src/setup.cfg.m4 @@ -19,14 +19,14 @@ classifiers = Operating System :: POSIX Operating System :: MacOS :: MacOS X Programming Language :: Python :: 3 :: Only - Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 + Programming Language :: Python :: 3.10 Programming Language :: Python :: Implementation :: CPython Topic :: Scientific/Engineering :: Mathematics [options] -python_requires = >=3.7, <3.11 +python_requires = >=3.8, <3.11 install_requires = esyscmd(`sage-get-system-packages install-requires \ sage_conf \ diff --git a/tox.ini b/tox.ini index 47c10c364ef..11bb5853b81 100644 --- a/tox.ini +++ b/tox.ini @@ -286,7 +286,6 @@ setenv = # gentoo: SYSTEM=gentoo gentoo: BASE_IMAGE=sheerluck/sage-on-gentoo-stage4 - gentoo-python3.7: BASE_TAG=latest-py37 gentoo-python3.9: BASE_TAG=latest-py39 gentoo-python3.10: BASE_TAG=latest-py10 gentoo: IGNORE_MISSING_SYSTEM_PACKAGES=no @@ -506,8 +505,7 @@ setenv = # Setting "--with-system-python3=yes" explicitly in case we change the configure default # to "--with-system-python3=force" as originally proposed in #32060 PYTHON_MAJOR=3 - PYTHON_MINOR=9 - python3.7: PYTHON_MINOR=7 + PYTHON_MINOR=10 python3.8: PYTHON_MINOR=8 python3.9: PYTHON_MINOR=9 python3.10: PYTHON_MINOR=10 @@ -515,15 +513,14 @@ setenv = CONFIG_CONFIGURE_ARGS_1=--with-system-python3=yes python3_spkg: CONFIG_CONFIGURE_ARGS_1=--without-system-python3 macos-python3_xcode: CONFIG_CONFIGURE_ARGS_1=--with-system-python3=force --with-python=/usr/bin/python3 - macos-{python3_xcode,nohomebrew}-{python3.7,python3.8}: CONFIG_CONFIGURE_ARGS_1=--with-system-python3=force --with-python=/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/{env:PYTHON_MAJOR}.{env:PYTHON_MINOR}/bin/python3 + macos-{python3_xcode,nohomebrew}-{python3.8}: CONFIG_CONFIGURE_ARGS_1=--with-system-python3=force --with-python=/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/{env:PYTHON_MAJOR}.{env:PYTHON_MINOR}/bin/python3 # Homebrew keg installs - homebrew-{python3.7,python3.8,python3.9,python3.10,python3.11}: CONFIG_CONFIGURE_ARGS_1=--with-system-python3=force --with-python={env:HOMEBREW}/opt/python@{env:PYTHON_MAJOR}.{env:PYTHON_MINOR}/bin/python3 + homebrew-{python3.8,python3.9,python3.10,python3.11}: CONFIG_CONFIGURE_ARGS_1=--with-system-python3=force --with-python={env:HOMEBREW}/opt/python@{env:PYTHON_MAJOR}.{env:PYTHON_MINOR}/bin/python3 # Installers from https://www.python.org/downloads/macos/ (must manually download and install) macos-python3_pythonorg: CONFIG_CONFIGURE_ARGS_1=--with-system-python3=force --with-python=/Library/Frameworks/Python.framework/Versions/{env:PYTHON_MAJOR}.{env:PYTHON_MINOR}/bin/python3 # https://github.com/pypa/manylinux manylinux-standard: CONFIG_CONFIGURE_ARGS_1=--with-system-python3=force --with-python=/opt/python/cp{env:PYTHON_MAJOR}{env:PYTHON_MINOR}-cp{env:PYTHON_MAJOR}{env:PYTHON_MINOR}/bin/python3 - manylinux-python3.7: CONFIG_CONFIGURE_ARGS_1=--with-system-python3=force --with-python=/opt/python/cp37-cp37m/bin/python3 - manylinux-{python3.7,python3.8,python3.9,python3.10,python3.11}: EXTRA_SAGE_PACKAGES=_bootstrap xz bzip2 libffi libpng + manylinux-{python3.8,python3.9,python3.10,python3.11}: EXTRA_SAGE_PACKAGES=_bootstrap xz bzip2 libffi libpng conda: CONFIG_CONFIGURE_ARGS_1=--with-system-python3=force --with-python=python3 # # - toolchain From 4b121f76a23a80f8e474c2985223c9acbea5cf41 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Thu, 12 May 2022 14:57:23 +0100 Subject: [PATCH 477/529] Python 3.7->3.8. in few places; bump Sage version to 9.7 in tutorial --- README.md | 2 +- src/doc/de/tutorial/interactive_shell.rst | 6 +++--- src/doc/en/installation/source.rst | 2 +- src/doc/en/tutorial/interactive_shell.rst | 6 +++--- src/doc/fr/tutorial/interactive_shell.rst | 6 +++--- src/doc/ja/tutorial/interactive_shell.rst | 6 +++--- src/doc/pt/tutorial/interactive_shell.rst | 6 +++--- src/doc/ru/tutorial/interactive_shell.rst | 6 +++--- 8 files changed, 20 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 93b1d566829..734b0ecec6e 100644 --- a/README.md +++ b/README.md @@ -251,7 +251,7 @@ in the Installation Guide. ``ExtUtils::MakeMaker``), `ranlib`, `git`, `tar`, `bc`. - Python 3.4 or later, or Python 2.7, a full installation including - `urllib`; but ideally version 3.7.x, 3.8.x, 3.9.x, or 3.10.x, which + `urllib`; but ideally version 3.8.x, 3.9.x, or 3.10.x, which will avoid having to build Sage's own copy of Python 3. We have collected lists of system packages that provide these build diff --git a/src/doc/de/tutorial/interactive_shell.rst b/src/doc/de/tutorial/interactive_shell.rst index 822fef4ec67..b356ea21f45 100644 --- a/src/doc/de/tutorial/interactive_shell.rst +++ b/src/doc/de/tutorial/interactive_shell.rst @@ -15,7 +15,7 @@ vornehmen. Nach dem Start von Sage sehen Sie etwa folgendes: :: ┌────────────────────────────────────────────────────────────────────┐ - │ SageMath version 9.0, Release Date: 2020-01-01 │ + │ SageMath version 9.7, Release Date: 2022-01-10 │ │ Using Python 3.10.4. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ @@ -175,7 +175,7 @@ in einer zukünftigen Sitzung (indem Sie einfach die Log-Datei laden). was@form:~$ sage ┌────────────────────────────────────────────────────────────────────┐ - │ SageMath version 9.0, Release Date: 2020-01-01 │ + │ SageMath version 9.7, Release Date: 2022-01-10 │ │ Using Python 3.10.4. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ @@ -194,7 +194,7 @@ in einer zukünftigen Sitzung (indem Sie einfach die Log-Datei laden). Exiting Sage (CPU time 0m0.61s, Wall time 0m50.39s). was@form:~$ sage ┌────────────────────────────────────────────────────────────────────┐ - │ SageMath version 9.0, Release Date: 2020-01-01 │ + │ SageMath version 9.7, Release Date: 2022-01-10 │ │ Using Python 3.10.4. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ diff --git a/src/doc/en/installation/source.rst b/src/doc/en/installation/source.rst index 4bddcc1e7b4..1c5a86230c7 100644 --- a/src/doc/en/installation/source.rst +++ b/src/doc/en/installation/source.rst @@ -134,7 +134,7 @@ rather than building a Python 3 installation from scratch. Use the ``configure`` option ``--without-system-python3`` in case you want Python 3 built from scratch. -Sage will accept versions 3.7.x to 3.10.x. +Sage will accept versions 3.8.x to 3.10.x. You can also use ``--with-python=/path/to/python3_binary`` to tell Sage to use ``/path/to/python3_binary`` to set up the venv. Note that setting up venv requires diff --git a/src/doc/en/tutorial/interactive_shell.rst b/src/doc/en/tutorial/interactive_shell.rst index 8c7d340f5ac..7ae821e416d 100644 --- a/src/doc/en/tutorial/interactive_shell.rst +++ b/src/doc/en/tutorial/interactive_shell.rst @@ -13,7 +13,7 @@ Sage, you get output similar to the following: .. CODE-BLOCK:: text ┌────────────────────────────────────────────────────────────────────┐ - │ SageMath version 9.0, Release Date: 2020-01-01 │ + │ SageMath version 9.7, Release Date: 2022-01-10 │ │ Using Python 3.10.4. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ @@ -173,7 +173,7 @@ file). was@form:~$ sage ┌────────────────────────────────────────────────────────────────────┐ - │ SageMath version 9.0, Release Date: 2020-01-01 │ + │ SageMath version 9.7, Release Date: 2022-01-10 │ │ Using Python 3.10.4. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ @@ -192,7 +192,7 @@ file). Exiting Sage (CPU time 0m0.61s, Wall time 0m50.39s). was@form:~$ sage ┌────────────────────────────────────────────────────────────────────┐ - │ SageMath version 9.0, Release Date: 2020-01-01 │ + │ SageMath version 9.7, Release Date: 2022-01-10 │ │ Using Python 3.10.4. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ diff --git a/src/doc/fr/tutorial/interactive_shell.rst b/src/doc/fr/tutorial/interactive_shell.rst index 99e215391db..81235ccaab9 100644 --- a/src/doc/fr/tutorial/interactive_shell.rst +++ b/src/doc/fr/tutorial/interactive_shell.rst @@ -17,7 +17,7 @@ le shell Sage affiche un message de ce genre : :: ┌────────────────────────────────────────────────────────────────────┐ - │ SageMath version 9.0, Release Date: 2020-01-01 │ + │ SageMath version 9.7, Release Date: 2022-01-10 │ │ Using Python 3.10.4. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ @@ -182,7 +182,7 @@ session future (en rechargeant le fichier journal). was@form:~$ sage ┌────────────────────────────────────────────────────────────────────┐ - │ SageMath version 9.0, Release Date: 2020-01-01 │ + │ SageMath version 9.7, Release Date: 2022-01-10 │ │ Using Python 3.10.4. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ @@ -201,7 +201,7 @@ session future (en rechargeant le fichier journal). Exiting Sage (CPU time 0m0.61s, Wall time 0m50.39s). was@form:~$ sage ┌────────────────────────────────────────────────────────────────────┐ - │ SageMath version 9.0, Release Date: 2020-01-01 │ + │ SageMath version 9.7, Release Date: 2022-01-10 │ │ Using Python 3.10.4. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ diff --git a/src/doc/ja/tutorial/interactive_shell.rst b/src/doc/ja/tutorial/interactive_shell.rst index 4847d9b0775..38a5c2c4d3f 100644 --- a/src/doc/ja/tutorial/interactive_shell.rst +++ b/src/doc/ja/tutorial/interactive_shell.rst @@ -14,7 +14,7 @@ Sageを起動すると,すぐに次のような画面が現れる: :: ┌────────────────────────────────────────────────────────────────────┐ - │ SageMath version 9.0, Release Date: 2020-01-01 │ + │ SageMath version 9.7, Release Date: 2022-01-10 │ │ Using Python 3.10.4. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ @@ -163,7 +163,7 @@ Sageセッションのロギングと,セッションの保存(:ref:`section-s was@form:~$ sage ┌────────────────────────────────────────────────────────────────────┐ - │ SageMath version 9.0, Release Date: 2020-01-01 │ + │ SageMath version 9.7, Release Date: 2022-01-10 │ │ Using Python 3.10.4. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ @@ -182,7 +182,7 @@ Sageセッションのロギングと,セッションの保存(:ref:`section-s Exiting Sage (CPU time 0m0.61s, Wall time 0m50.39s). was@form:~$ sage ┌────────────────────────────────────────────────────────────────────┐ - │ SageMath version 9.0, Release Date: 2020-01-01 │ + │ SageMath version 9.7, Release Date: 2022-01-10 │ │ Using Python 3.10.4. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ diff --git a/src/doc/pt/tutorial/interactive_shell.rst b/src/doc/pt/tutorial/interactive_shell.rst index 1737498abaa..67d27269a1e 100644 --- a/src/doc/pt/tutorial/interactive_shell.rst +++ b/src/doc/pt/tutorial/interactive_shell.rst @@ -16,7 +16,7 @@ obtém o seguinte: :: ┌────────────────────────────────────────────────────────────────────┐ - │ SageMath version 9.0, Release Date: 2020-01-01 │ + │ SageMath version 9.7, Release Date: 2022-01-10 │ │ Using Python 3.10.4. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ sage: @@ -174,7 +174,7 @@ arquivo log). was@form:~$ sage ┌────────────────────────────────────────────────────────────────────┐ - │ SageMath version 9.0, Release Date: 2020-01-01 │ + │ SageMath version 9.7, Release Date: 2022-01-10 │ │ Using Python 3.10.4. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ @@ -193,7 +193,7 @@ arquivo log). Exiting Sage (CPU time 0m0.61s, Wall time 0m50.39s). was@form:~$ sage ┌────────────────────────────────────────────────────────────────────┐ - │ SageMath version 9.0, Release Date: 2020-01-01 │ + │ SageMath version 9.7, Release Date: 2022-01-10 │ │ Using Python 3.10.4. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ diff --git a/src/doc/ru/tutorial/interactive_shell.rst b/src/doc/ru/tutorial/interactive_shell.rst index 621426eda9b..e2d8a68cde6 100644 --- a/src/doc/ru/tutorial/interactive_shell.rst +++ b/src/doc/ru/tutorial/interactive_shell.rst @@ -16,7 +16,7 @@ Sage вы увидите вывод, похожий на следующий: :: ┌────────────────────────────────────────────────────────────────────┐ - │ SageMath version 9.0, Release Date: 2020-01-01 │ + │ SageMath version 9.7, Release Date: 2022-01-10 │ │ Using Python 3.10.4. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ @@ -166,7 +166,7 @@ Notebook), то вы можете ввести ``%hist``, чтобы вывес was@form:~$ sage ┌────────────────────────────────────────────────────────────────────┐ - │ SageMath version 9.0, Release Date: 2020-01-01 │ + │ SageMath version 9.7, Release Date: 2022-01-10 │ │ Using Python 3.10.4. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ @@ -185,7 +185,7 @@ Notebook), то вы можете ввести ``%hist``, чтобы вывес Exiting Sage (CPU time 0m0.61s, Wall time 0m50.39s). was@form:~$ sage ┌────────────────────────────────────────────────────────────────────┐ - │ SageMath version 9.0, Release Date: 2020-01-01 │ + │ SageMath version 9.7, Release Date: 2022-01-10 │ │ Using Python 3.10.4. Type "help()" for help. │ └────────────────────────────────────────────────────────────────────┘ From 037fc2f4ebab0dc602980d39dfada3395d2ab414 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 26 May 2022 09:47:55 -0700 Subject: [PATCH 478/529] build/pkgs/jinja2: Update to 3.1.2 --- build/pkgs/jinja2/checksums.ini | 6 +++--- build/pkgs/jinja2/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/jinja2/checksums.ini b/build/pkgs/jinja2/checksums.ini index 1e2005c59d9..f7070dfa137 100644 --- a/build/pkgs/jinja2/checksums.ini +++ b/build/pkgs/jinja2/checksums.ini @@ -1,5 +1,5 @@ tarball=Jinja2-VERSION.tar.gz -sha1=40278c4dfbbd6d21dc570bee0c63e32504e5442e -md5=964afcd0853f67f20f7b2e34e5935564 -cksum=380272436 +sha1=560f248ccb0b98256c5b50c86a002c2c1e57edb6 +md5=d31148abd89c1df1cdb077a55db27d02 +cksum=394934978 upstream_url=https://pypi.io/packages/source/j/jinja2/Jinja2-VERSION.tar.gz diff --git a/build/pkgs/jinja2/package-version.txt b/build/pkgs/jinja2/package-version.txt index 94ff29cc4de..ef538c28109 100644 --- a/build/pkgs/jinja2/package-version.txt +++ b/build/pkgs/jinja2/package-version.txt @@ -1 +1 @@ -3.1.1 +3.1.2 From dedc9c20d79d408b5e02ac4b89de5a38a5e6c48c Mon Sep 17 00:00:00 2001 From: Julien Grijalva Date: Thu, 26 May 2022 12:45:09 -0600 Subject: [PATCH 479/529] restore default IFS behavior --- build/bin/sage-bootstrap-python | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/bin/sage-bootstrap-python b/build/bin/sage-bootstrap-python index 448efa5bcc0..f78e5e62a1d 100755 --- a/build/bin/sage-bootstrap-python +++ b/build/bin/sage-bootstrap-python @@ -20,7 +20,7 @@ do *) NEW_PATH="$NEW_PATH$path:";; esac done -IFS=' ' +unset IFS SAGE_ORIG_PATH=${NEW_PATH%%':'} # In particular, it is invoked by "bootstrap -d" for sage-download-file, # i.e., before a configure run, and by "sage-spkg", also for sage-download-file. From 18593eccdf417e07094384c32f455c08540415a6 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 26 May 2022 12:02:56 -0700 Subject: [PATCH 480/529] m4/sage_spkg_collect.m4: One more space --- m4/sage_spkg_collect.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/m4/sage_spkg_collect.m4 b/m4/sage_spkg_collect.m4 index e778e55abcf..05680ea9c5d 100644 --- a/m4/sage_spkg_collect.m4 +++ b/m4/sage_spkg_collect.m4 @@ -330,7 +330,7 @@ AC_DEFUN([SAGE_SPKG_FINALIZE], [dnl ]) AS_IF([test -f "$DIR/dependencies_optional"], [dnl for a in $(sed 's/^ *//; s/ *#.*//; q' "$DIR/dependencies_optional"); do - AS_VAR_APPEND([DEPS], ['$(findstring '$a',$(OPTIONAL_INSTALLED_PACKAGES)) ']) + AS_VAR_APPEND([DEPS], [' $(findstring '$a',$(OPTIONAL_INSTALLED_PACKAGES)) ']) done ]) AS_CASE(["$DEPS"], [*\|*], [], [AS_VAR_APPEND([DEPS], [" |"])]) From f610e5a8648308b5f3d87b4ea803a63ee72f08cf Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Thu, 26 May 2022 22:18:21 +0100 Subject: [PATCH 481/529] retained 'algorithm=' with deprecation --- src/sage/graphs/graph.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index edb40ddc10d..2d617edffd3 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -7574,7 +7574,7 @@ def cores(self, k=None, with_labels=False): return list(core.values()) @doc_index("Leftovers") - def modular_decomposition(self, style='tuple'): + def modular_decomposition(self, algorithm=None, style='tuple'): r""" Return the modular decomposition of the current graph. @@ -7745,6 +7745,9 @@ def modular_decomposition(self, style='tuple'): create_prime_node, create_normal_node) + if algorithm is not None: + from sage.misc.superseded import deprecation + deprecation(25872, "algorithm=... parameter is obsolete and has no effect.") self._scream_if_not_simple() if not self.order(): @@ -8014,7 +8017,7 @@ def is_inscribable(self, solver="ppl", verbose=0): return self.planar_dual().is_circumscribable(solver=solver, verbose=verbose) @doc_index("Graph properties") - def is_prime(self): + def is_prime(self, algorithm=None): r""" Test whether the current graph is prime. @@ -8041,6 +8044,9 @@ def is_prime(self): sage: graphs.EmptyGraph().is_prime() True """ + if algorithm is not None: + from sage.misc.superseded import deprecation + deprecation(25872, "algorithm=... parameter is obsolete and has no effect.") from sage.graphs.graph_decompositions.modular_decomposition import NodeType if self.order() <= 1: From 5fb2a6ea44400e469caee82748cf863ca0c5f724 Mon Sep 17 00:00:00 2001 From: Release Manager Date: Fri, 27 May 2022 00:56:08 +0200 Subject: [PATCH 482/529] Updated SageMath version to 9.7.beta1 --- .zenodo.json | 8 ++++---- VERSION.txt | 2 +- build/pkgs/configure/checksums.ini | 6 +++--- build/pkgs/configure/package-version.txt | 2 +- build/pkgs/sagelib/package-version.txt | 2 +- src/VERSION.txt | 2 +- src/bin/sage-version.sh | 6 +++--- src/sage/version.py | 6 +++--- 8 files changed, 17 insertions(+), 17 deletions(-) diff --git a/.zenodo.json b/.zenodo.json index ec3356f0e46..be408937a6f 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -1,10 +1,10 @@ { "description": "Mirror of the Sage https://sagemath.org/ source tree", "license": "other-open", - "title": "sagemath/sage: 9.7.beta0", - "version": "9.7.beta0", + "title": "sagemath/sage: 9.7.beta1", + "version": "9.7.beta1", "upload_type": "software", - "publication_date": "2022-05-22", + "publication_date": "2022-05-26", "creators": [ { "affiliation": "SageMath.org", @@ -15,7 +15,7 @@ "related_identifiers": [ { "scheme": "url", - "identifier": "https://github.com/sagemath/sage/tree/9.7.beta0", + "identifier": "https://github.com/sagemath/sage/tree/9.7.beta1", "relation": "isSupplementTo" }, { diff --git a/VERSION.txt b/VERSION.txt index 7d714ff1177..8cb99453ed0 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -SageMath version 9.7.beta0, Release Date: 2022-05-22 +SageMath version 9.7.beta1, Release Date: 2022-05-26 diff --git a/build/pkgs/configure/checksums.ini b/build/pkgs/configure/checksums.ini index 39e33adc7cb..ef64036305b 100644 --- a/build/pkgs/configure/checksums.ini +++ b/build/pkgs/configure/checksums.ini @@ -1,4 +1,4 @@ tarball=configure-VERSION.tar.gz -sha1=76c296fd78cffcb86a75e1eb67098bd958250e24 -md5=6d80ab0acd95ffde7e1c1217fa3e3bf5 -cksum=3599310930 +sha1=e147a1128d59e97feef980eb3847798d1838565b +md5=134802b2602846ef70dba2d0740be18c +cksum=2068092591 diff --git a/build/pkgs/configure/package-version.txt b/build/pkgs/configure/package-version.txt index 325a0683c60..8f33ed65cfa 100644 --- a/build/pkgs/configure/package-version.txt +++ b/build/pkgs/configure/package-version.txt @@ -1 +1 @@ -8a099141d593f9f7348a1557d2c68790a9e0d904 +8501c7398215556ff4a4c8b05c6699949c8dfca3 diff --git a/build/pkgs/sagelib/package-version.txt b/build/pkgs/sagelib/package-version.txt index 52630adaf8b..6442b83e510 100644 --- a/build/pkgs/sagelib/package-version.txt +++ b/build/pkgs/sagelib/package-version.txt @@ -1 +1 @@ -9.7.beta0 +9.7.beta1 diff --git a/src/VERSION.txt b/src/VERSION.txt index 52630adaf8b..6442b83e510 100644 --- a/src/VERSION.txt +++ b/src/VERSION.txt @@ -1 +1 @@ -9.7.beta0 +9.7.beta1 diff --git a/src/bin/sage-version.sh b/src/bin/sage-version.sh index 020edde1d5c..bc8b231097a 100644 --- a/src/bin/sage-version.sh +++ b/src/bin/sage-version.sh @@ -1,5 +1,5 @@ # Sage version information for shell scripts # This file is auto-generated by the sage-update-version script, do not edit! -SAGE_VERSION='9.7.beta0' -SAGE_RELEASE_DATE='2022-05-22' -SAGE_VERSION_BANNER='SageMath version 9.7.beta0, Release Date: 2022-05-22' +SAGE_VERSION='9.7.beta1' +SAGE_RELEASE_DATE='2022-05-26' +SAGE_VERSION_BANNER='SageMath version 9.7.beta1, Release Date: 2022-05-26' diff --git a/src/sage/version.py b/src/sage/version.py index 93d63ae2e61..6671c264512 100644 --- a/src/sage/version.py +++ b/src/sage/version.py @@ -1,5 +1,5 @@ # Sage version information for Python scripts # This file is auto-generated by the sage-update-version script, do not edit! -version = '9.7.beta0' -date = '2022-05-22' -banner = 'SageMath version 9.7.beta0, Release Date: 2022-05-22' +version = '9.7.beta1' +date = '2022-05-26' +banner = 'SageMath version 9.7.beta1, Release Date: 2022-05-26' From 8e8045e3097f88279bbf24f1648300d4ba3ade58 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 26 May 2022 18:25:28 -0700 Subject: [PATCH 483/529] build/pkgs/jupyter_packaging/requirements.txt: Set upper version bound to avoid triggering setuptools upgrade --- build/pkgs/jupyter_packaging/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/jupyter_packaging/requirements.txt b/build/pkgs/jupyter_packaging/requirements.txt index b5ec61b7d14..c99565a4ced 100644 --- a/build/pkgs/jupyter_packaging/requirements.txt +++ b/build/pkgs/jupyter_packaging/requirements.txt @@ -1 +1 @@ -jupyter-packaging +jupyter-packaging < 0.12 From 1b8b25522629249a8063f431b962b89ee9863238 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 27 May 2022 14:59:36 +0200 Subject: [PATCH 484/529] remove inheritance from object in classes inside misc/ and repl/ --- src/sage/misc/abstract_method.py | 6 ++-- src/sage/misc/c3.pyx | 8 ++--- src/sage/misc/c3_controlled.pyx | 8 ++--- src/sage/misc/cachefunc.pxd | 4 +-- src/sage/misc/cachefunc.pyx | 38 ++++++++++---------- src/sage/misc/call.py | 2 +- src/sage/misc/classcall_metaclass.pyx | 6 ++-- src/sage/misc/decorators.py | 10 +++--- src/sage/misc/element_with_label.py | 2 +- src/sage/misc/explain_pickle.py | 20 +++++------ src/sage/misc/inherit_comparison.pyx | 2 +- src/sage/misc/instancedoc.pyx | 14 ++++---- src/sage/misc/lazy_attribute.pyx | 18 +++++----- src/sage/misc/lazy_format.py | 2 +- src/sage/misc/lazy_import.pyx | 8 ++--- src/sage/misc/lazy_list.pxd | 2 +- src/sage/misc/lazy_list.pyx | 2 +- src/sage/misc/lazy_string.pxd | 2 +- src/sage/misc/lazy_string.pyx | 2 +- src/sage/misc/misc.py | 2 +- src/sage/misc/nested_class.pyx | 18 +++++----- src/sage/misc/object_multiplexer.py | 4 +-- src/sage/misc/persist.pyx | 8 ++--- src/sage/misc/sage_input.py | 2 +- src/sage/misc/sage_timeit.py | 2 +- src/sage/misc/sage_unittest.py | 4 +-- src/sage/misc/sageinspect.py | 8 ++--- src/sage/misc/superseded.py | 14 ++++---- src/sage/misc/temporary_file.py | 4 +-- src/sage/misc/test_nested_class.py | 18 +++++----- src/sage/misc/weak_dict.pyx | 24 ++++++------- src/sage/repl/configuration.py | 2 +- src/sage/repl/display/fancy_repr.py | 6 ++-- src/sage/repl/display/formatter.py | 2 +- src/sage/repl/display/util.py | 2 +- src/sage/repl/interface_magic.py | 2 +- src/sage/repl/interpreter.py | 6 ++-- src/sage/repl/ipython_extension.py | 2 +- src/sage/repl/ipython_kernel/install.py | 2 +- src/sage/repl/ipython_kernel/widgets.py | 2 +- src/sage/repl/rich_output/display_manager.py | 2 +- 41 files changed, 146 insertions(+), 146 deletions(-) diff --git a/src/sage/misc/abstract_method.py b/src/sage/misc/abstract_method.py index 49dc59ba9fa..c9a0c76f7fb 100644 --- a/src/sage/misc/abstract_method.py +++ b/src/sage/misc/abstract_method.py @@ -33,7 +33,7 @@ def abstract_method(f=None, optional=False): We create a class with an abstract method:: - sage: class A(object): + sage: class A(): ....: ....: @abstract_method ....: def my_method(self): @@ -60,7 +60,7 @@ def abstract_method(f=None, optional=False): It is also possible to mark abstract methods as optional:: - sage: class A(object): + sage: class A(): ....: ....: @abstract_method(optional = True) ....: def my_method(self): @@ -138,7 +138,7 @@ def abstract_method(f=None, optional=False): return AbstractMethod(f, optional) -class AbstractMethod(object): +class AbstractMethod(): def __init__(self, f, optional=False): """ Constructor for abstract methods diff --git a/src/sage/misc/c3.pyx b/src/sage/misc/c3.pyx index 77eb223c250..d777a0e25ca 100644 --- a/src/sage/misc/c3.pyx +++ b/src/sage/misc/c3.pyx @@ -123,9 +123,9 @@ cpdef list C3_algorithm(object start, str bases, str attribute, bint proper): Regression test for bug #1 of :trac:`13501`:: - sage: class C(object): pass - sage: class F(object): pass - sage: class G(object): pass + sage: class C(): pass + sage: class F(): pass + sage: class G(): pass sage: class B(C,F): pass sage: class D(F,G): pass sage: class E(F): pass @@ -147,7 +147,7 @@ cpdef list C3_algorithm(object start, str bases, str attribute, bint proper): fail since ``A`` asks for ``B`` to come before ``C``, where as ``B`` is a super class of ``C``:: - sage: class B(object): pass + sage: class B(): pass sage: class C(B): pass sage: class A(B, C): pass Traceback (most recent call last): diff --git a/src/sage/misc/c3_controlled.pyx b/src/sage/misc/c3_controlled.pyx index 1b16dd62b8e..030a512f36a 100644 --- a/src/sage/misc/c3_controlled.pyx +++ b/src/sage/misc/c3_controlled.pyx @@ -31,11 +31,11 @@ The problem Consider the following hierarchy of classes:: - sage: class A1(object): pass - sage: class A2(object): + sage: class A1(): pass + sage: class A2(): ....: def foo(self): return 2 - sage: class A3(object): pass - sage: class A4(object): + sage: class A3(): pass + sage: class A4(): ....: def foo(self): return 4 sage: class A5(A2, A1): ....: def foo(self): return 5 diff --git a/src/sage/misc/cachefunc.pxd b/src/sage/misc/cachefunc.pxd index e77d6e305fd..d3cc677dece 100644 --- a/src/sage/misc/cachefunc.pxd +++ b/src/sage/misc/cachefunc.pxd @@ -3,7 +3,7 @@ from .function_mangling cimport ArgumentFixer cpdef dict_key(o) cpdef cache_key(o) -cdef class CachedFunction(object): +cdef class CachedFunction(): cdef public str __name__ cdef public str __module__ cdef ArgumentFixer _argument_fixer @@ -17,7 +17,7 @@ cdef class CachedFunction(object): cdef key cdef bint do_pickle -cdef class CachedMethod(object): +cdef class CachedMethod(): cdef str _cache_name cdef public str __name__ cdef public str __module__ diff --git a/src/sage/misc/cachefunc.pyx b/src/sage/misc/cachefunc.pyx index c74d9d83fd0..d76126c3472 100644 --- a/src/sage/misc/cachefunc.pyx +++ b/src/sage/misc/cachefunc.pyx @@ -599,7 +599,7 @@ cdef cache_key_unhashable(o): return cache_key(k) -cdef class CachedFunction(object): +cdef class CachedFunction(): """ Create a cached version of a function, which only recomputes values it hasn't already computed. Synonyme: ``cached_function`` @@ -1435,7 +1435,7 @@ cdef class WeakCachedFunction(CachedFunction): weak_cached_function = decorator_keywords(WeakCachedFunction) -class CachedMethodPickle(object): +class CachedMethodPickle(): """ This class helps to unpickle cached methods. @@ -1798,7 +1798,7 @@ cdef class CachedMethodCaller(CachedFunction): :: - sage: class Foo(object): + sage: class Foo(): ....: def __init__(self, x): ....: self._x = x ....: @cached_method @@ -1829,7 +1829,7 @@ cdef class CachedMethodCaller(CachedFunction): TESTS:: - sage: class A(object): + sage: class A(): ....: def _f_normalize(self, x, algorithm): return x ....: @cached_method(key=_f_normalize) ....: def f(self, x, algorithm='default'): return x @@ -1913,7 +1913,7 @@ cdef class CachedMethodCaller(CachedFunction): :meth:`sage.structure.sage_object.SageObject._cache_key`:: sage: K. = Qq(4) # optional - sage.rings.padics - sage: class A(object): + sage: class A(): ....: @cached_method ....: def f(self, x): return x+x sage: a = A() @@ -1956,7 +1956,7 @@ cdef class CachedMethodCaller(CachedFunction): EXAMPLES:: - sage: class CachedMethodTest(object): + sage: class CachedMethodTest(): ....: @cached_method ....: def f(self, x): ....: return x @@ -2110,7 +2110,7 @@ cdef class CachedMethodCaller(CachedFunction): EXAMPLES:: - sage: class Foo(object): + sage: class Foo(): ....: @cached_method ....: def f(self, i): ....: return i^2 @@ -2495,7 +2495,7 @@ cdef class GloballyCachedMethodCaller(CachedMethodCaller): sage: class MyParent(Parent): ....: pass - sage: class MyElement(object): + sage: class MyElement(): ....: def __init__(self, x): ....: self.x = x ....: def parent(self): @@ -2513,7 +2513,7 @@ cdef class GloballyCachedMethodCaller(CachedMethodCaller): return (self._instance, k) -cdef class CachedMethod(object): +cdef class CachedMethod(): """ A decorator that creates a cached version of an instance method of a class. @@ -2527,7 +2527,7 @@ cdef class CachedMethod(object): EXAMPLES:: - sage: class Foo(object): + sage: class Foo(): ....: @cached_method ....: def f(self, t, x=2): ....: print('computing') @@ -2561,7 +2561,7 @@ cdef class CachedMethod(object): custom cache key for inputs. In the following example, this parameter is used to ignore the ``algorithm`` keyword for caching:: - sage: class A(object): + sage: class A(): ....: def _f_normalize(self, x, algorithm): return x ....: @cached_method(key=_f_normalize) ....: def f(self, x, algorithm='default'): return x @@ -2572,7 +2572,7 @@ cdef class CachedMethod(object): The parameter ``do_pickle`` can be used to enable pickling of the cache. Usually the cache is not stored when pickling:: - sage: class A(object): + sage: class A(): ....: @cached_method ....: def f(self, x): return None sage: import __main__ @@ -2587,7 +2587,7 @@ cdef class CachedMethod(object): When ``do_pickle`` is set, the pickle contains the contents of the cache:: - sage: class A(object): + sage: class A(): ....: @cached_method(do_pickle=True) ....: def f(self, x): return None sage: __main__.A = A @@ -2624,7 +2624,7 @@ cdef class CachedMethod(object): """ EXAMPLES:: - sage: class Foo(object): + sage: class Foo(): ....: def __init__(self, x): ....: self._x = x ....: @cached_method @@ -2699,7 +2699,7 @@ cdef class CachedMethod(object): sage: from sage.misc.superseded import deprecated_function_alias - sage: class Foo(object): + sage: class Foo(): ....: def __init__(self, x): ....: self._x = x ....: @cached_method @@ -3163,7 +3163,7 @@ cdef class CachedInParentMethod(CachedMethod): Test that ``key`` works:: - sage: class A(object): + sage: class A(): ....: def __init__(self): ....: self._parent = MyParent() ....: def parent(self): return self._parent @@ -3177,7 +3177,7 @@ cdef class CachedInParentMethod(CachedMethod): Test that ``do_pickle`` works. Usually the contents of the cache are not pickled:: - sage: class A(object): + sage: class A(): ....: def __init__(self): ....: self._parent = MyParent() ....: def parent(self): return self._parent @@ -3197,7 +3197,7 @@ cdef class CachedInParentMethod(CachedMethod): Pickling can be enabled with ``do_pickle``:: - sage: class A(object): + sage: class A(): ....: def __init__(self): ....: self._parent = MyParent() ....: def parent(self): return self._parent @@ -3308,7 +3308,7 @@ cdef class CachedInParentMethod(CachedMethod): cached_in_parent_method = decorator_keywords(CachedInParentMethod) -class FileCache(object): +class FileCache(): """ :class:`FileCache` is a dictionary-like class which stores keys and values on disk. The keys take the form of a tuple ``(A,K)`` diff --git a/src/sage/misc/call.py b/src/sage/misc/call.py index 7b579f45a4d..71368bbadd5 100644 --- a/src/sage/misc/call.py +++ b/src/sage/misc/call.py @@ -18,7 +18,7 @@ ############################################# # Operators ############################################# -class AttrCallObject(object): +class AttrCallObject(): def __init__(self, name, args, kwds): """ TESTS:: diff --git a/src/sage/misc/classcall_metaclass.pyx b/src/sage/misc/classcall_metaclass.pyx index 2f7038e9a9f..191534f76ee 100644 --- a/src/sage/misc/classcall_metaclass.pyx +++ b/src/sage/misc/classcall_metaclass.pyx @@ -460,7 +460,7 @@ def typecall(pytype cls, *args, **kwds): EXAMPLES:: sage: from sage.misc.classcall_metaclass import typecall - sage: class Foo(object): pass + sage: class Foo(): pass sage: typecall(Foo) <__main__.Foo object at 0x...> sage: typecall(list) @@ -473,7 +473,7 @@ def typecall(pytype cls, *args, **kwds): # Class for timing:: -class CRef(object): +class CRef(): def __init__(self, i): """ TESTS:: @@ -538,7 +538,7 @@ def timeCall(T, int n, *args): 625 loops, best of 3: 41.4 µs per loop sage: i1 = int(1); i3 = int(3) # don't use Sage's Integer - sage: class PRef(object): + sage: class PRef(): ....: def __init__(self, i): ....: self.i = i+i1 diff --git a/src/sage/misc/decorators.py b/src/sage/misc/decorators.py index a41c8413bb8..28c52448813 100644 --- a/src/sage/misc/decorators.py +++ b/src/sage/misc/decorators.py @@ -175,7 +175,7 @@ def f(wrapper, assigned=assigned, updated=updated): # Infix operator decorator -class infix_operator(object): +class infix_operator(): """ A decorator for functions which allows for a hack that makes the function behave like an infix operator. @@ -256,7 +256,7 @@ def __call__(self, func): return wrapper_inst -class _infix_wrapper(object): +class _infix_wrapper(): function = None def __init__(self, left=None, right=None): @@ -345,7 +345,7 @@ def my_wrap(*args, **kwds): return my_wrap -class suboptions(object): +class suboptions(): def __init__(self, name, **options): """ A decorator for functions which collects all keywords @@ -428,7 +428,7 @@ def listForNone(l): return wrapper -class options(object): +class options(): def __init__(self, **options): """ A decorator for functions which allows for default options to be @@ -566,7 +566,7 @@ def reset(): return wrapper -class rename_keyword(object): +class rename_keyword(): def __init__(self, deprecated=None, deprecation=None, **renames): """ A decorator which renames keyword arguments and optionally diff --git a/src/sage/misc/element_with_label.py b/src/sage/misc/element_with_label.py index c2f513bdab8..2410851c7de 100644 --- a/src/sage/misc/element_with_label.py +++ b/src/sage/misc/element_with_label.py @@ -15,7 +15,7 @@ from sage.misc.latex import latex -class ElementWithLabel(object): +class ElementWithLabel(): """ Auxiliary class for showing/viewing :class:`Poset`s with non-injective labelings. diff --git a/src/sage/misc/explain_pickle.py b/src/sage/misc/explain_pickle.py index 946dd8057c0..b8fe3e93fe4 100644 --- a/src/sage/misc/explain_pickle.py +++ b/src/sage/misc/explain_pickle.py @@ -320,7 +320,7 @@ def name_is_valid(name): # This string is used as the representation of a mark. the_mark = 'mark' -class PickleObject(object): +class PickleObject(): r""" Pickles have a stack-based virtual machine. The explain_pickle pickle interpreter mostly uses SageInputExpressions, from sage_input, @@ -374,7 +374,7 @@ def _sage_input_(self, sib, coerced): self.immutable = True return self.expression -class PickleDict(object): +class PickleDict(): r""" An object which can be used as the value of a PickleObject. The items is a list of key-value pairs, where the keys and values are @@ -394,7 +394,7 @@ def __init__(self, items): """ self.items = items -class PickleInstance(object): +class PickleInstance(): r""" An object which can be used as the value of a PickleObject. Unlike other possible values of a PickleObject, a PickleInstance doesn't represent @@ -412,7 +412,7 @@ def __init__(self, klass): """ self.klass = klass -class PickleExplainer(object): +class PickleExplainer(): r""" An interpreter for the pickle virtual machine, that executes symbolically and constructs SageInputExpressions instead of @@ -2697,7 +2697,7 @@ def __hash__(self): return 0 -class EmptyNewstyleClass(object): +class EmptyNewstyleClass(): r""" A featureless new-style class (inherits from object); used for testing explain_pickle. @@ -2858,7 +2858,7 @@ def extend(self): raise NotImplementedError -class TestAppendNonlist(object): +class TestAppendNonlist(): r""" A list-like class, carefully designed to test exact unpickling behavior. Used for testing explain_pickle. @@ -2942,7 +2942,7 @@ def __repr__(self): return repr(self.list) -class TestBuild(object): +class TestBuild(): r""" A simple class with a __getstate__ but no __setstate__. Used for testing explain_pickle. @@ -3001,7 +3001,7 @@ def __setstate__(self, state): self.x = state[1]['y'] self.y = state[0]['x'] -class TestGlobalOldName(object): +class TestGlobalOldName(): r""" A featureless new-style class. When you try to unpickle an instance of this class, it is redirected to create a TestGlobalNewName instead. @@ -3016,7 +3016,7 @@ class TestGlobalOldName(object): pass -class TestGlobalNewName(object): +class TestGlobalNewName(): r""" A featureless new-style class. When you try to unpickle an instance of TestGlobalOldName, it is redirected to create an instance of this @@ -3048,7 +3048,7 @@ def __repr__(self): register_unpickle_override('sage.misc.explain_pickle', 'TestGlobalOldName', TestGlobalNewName, call_name=('sage.misc.explain_pickle', 'TestGlobalNewName')) -class TestGlobalFunnyName(object): +class TestGlobalFunnyName(): r""" A featureless new-style class which has a name that's not a legal Python identifier. diff --git a/src/sage/misc/inherit_comparison.pyx b/src/sage/misc/inherit_comparison.pyx index fc360533cad..a8306e83453 100644 --- a/src/sage/misc/inherit_comparison.pyx +++ b/src/sage/misc/inherit_comparison.pyx @@ -54,7 +54,7 @@ cdef class InheritComparisonMetaclass(type): sage: cython(''' ....: from sage.misc.inherit_comparison cimport InheritComparisonMetaclass ....: - ....: cdef class Base(object): + ....: cdef class Base(): ....: def __richcmp__(left, right, int op): ....: print("Calling Base.__richcmp__") ....: return left is right diff --git a/src/sage/misc/instancedoc.pyx b/src/sage/misc/instancedoc.pyx index a58fde0e081..91923bd905f 100644 --- a/src/sage/misc/instancedoc.pyx +++ b/src/sage/misc/instancedoc.pyx @@ -24,7 +24,7 @@ EXAMPLES:: sage: from sage.misc.instancedoc import instancedoc sage: @instancedoc - ....: class X(object): + ....: class X(): ....: "Class docstring" ....: def _instancedoc_(self): ....: return "Instance docstring" @@ -89,7 +89,7 @@ Check that inheritance works (after passing the subclass to :func:`instancedoc`):: sage: @instancedoc - ....: class A(object): + ....: class A(): ....: "Class A docstring" ....: def _instancedoc_(self): ....: return "Instance docstring" @@ -148,7 +148,7 @@ cdef class InstanceDocDescriptor: sage: def instancedoc(self): ....: return "Instance doc" sage: docattr = InstanceDocDescriptor("Class doc", instancedoc) - sage: class Z(object): + sage: class Z(): ....: __doc__ = InstanceDocDescriptor("Class doc", instancedoc) sage: Z.__doc__ 'Class doc' @@ -218,7 +218,7 @@ cdef class InstanceDocDescriptor: sage: def instancedoc(self): ....: return "Doc for {!r}".format(self) sage: descr = InstanceDocDescriptor("Class doc", instancedoc) - sage: class X(object): pass + sage: class X(): pass sage: obj = X() sage: descr.__set__(obj, "Custom doc") sage: obj.__doc__ @@ -246,7 +246,7 @@ cdef class InstanceDocDescriptor: sage: def instancedoc(self): ....: return "Doc for {!r}".format(self) sage: descr = InstanceDocDescriptor("Class doc", instancedoc) - sage: class X(object): pass + sage: class X(): pass sage: obj = X() sage: obj.__doc__ = "Custom doc" sage: descr.__delete__(obj) @@ -261,7 +261,7 @@ cdef class InstanceDocDescriptor: Traceback (most recent call last): ... AttributeError: attribute '__doc__' of 'list' objects is not writable - sage: descr.__delete__(object) + sage: descr.__delete__() Traceback (most recent call last): ... AttributeError: attribute '__doc__' of 'type' objects is not writable @@ -297,7 +297,7 @@ def instancedoc(cls): We get a useful error message if ``_instancedoc_`` is not defined:: sage: from sage.misc.instancedoc import instancedoc - sage: class X(object): pass + sage: class X(): pass sage: instancedoc(X) Traceback (most recent call last): ... diff --git a/src/sage/misc/lazy_attribute.pyx b/src/sage/misc/lazy_attribute.pyx index c6e7b5110bb..5d2f3fcee88 100644 --- a/src/sage/misc/lazy_attribute.pyx +++ b/src/sage/misc/lazy_attribute.pyx @@ -22,7 +22,7 @@ AUTHORS: # https://www.gnu.org/licenses/ # **************************************************************************** -cdef class _lazy_attribute(object): +cdef class _lazy_attribute(): """ Cython base class for lazy attributes. @@ -163,7 +163,7 @@ class lazy_attribute(_lazy_attribute): We create a class whose instances have a lazy attribute ``x``:: - sage: class A(object): + sage: class A(): ....: def __init__(self): ....: self.a=2 # just to have some data to calculate from ....: @@ -262,7 +262,7 @@ class lazy_attribute(_lazy_attribute): all possible without a special implementation of hasattr, so as to allow for something like:: - sage: class A (object): + sage: class A (): ....: @lazy_attribute ....: def x(self, existence_only=False): ....: if existence_only: @@ -366,11 +366,11 @@ class lazy_attribute(_lazy_attribute): w.r.t. inheritance, and maybe even ill-implemented. We illustrate this on a simple class hierarchy, with an instrumented descriptor:: - sage: class descriptor(object): + sage: class descriptor(): ....: def __get__(self, obj, cls): ....: print(cls) ....: return 1 - sage: class A(object): + sage: class A(): ....: x = descriptor() sage: class B(A): ....: pass @@ -402,7 +402,7 @@ class lazy_attribute(_lazy_attribute): Due to this, the natural implementation runs into an infinite loop in the following example:: - sage: class A(object): + sage: class A(): ....: @lazy_attribute ....: def unimplemented_A(self): ....: return NotImplemented @@ -518,7 +518,7 @@ class lazy_class_attribute(lazy_attribute): attribute is stored in the class rather than in the object. The lazy class attribute is only computed once for all the objects:: - sage: class Cl(object): + sage: class Cl(): ....: @lazy_class_attribute ....: def x(cls): ....: print("computing x") @@ -538,7 +538,7 @@ class lazy_class_attribute(lazy_attribute): First access from an object also properly triggers the computation:: - sage: class Cl1(object): + sage: class Cl1(): ....: @lazy_class_attribute ....: def x(cls): ....: print("computing x") @@ -554,7 +554,7 @@ class lazy_class_attribute(lazy_attribute): The behavior of lazy class attributes with respect to inheritance is not specified. It currently depends on the evaluation order:: - sage: class A(object): + sage: class A(): ....: @lazy_class_attribute ....: def x(cls): ....: print("computing x") diff --git a/src/sage/misc/lazy_format.py b/src/sage/misc/lazy_format.py index 88eb8798841..4a529aa1bc6 100644 --- a/src/sage/misc/lazy_format.py +++ b/src/sage/misc/lazy_format.py @@ -29,7 +29,7 @@ class LazyFormat(str): To demonstrate the lazyness, let us build an object with a broken ``__repr__`` method:: - sage: class IDontLikeBeingPrinted(object): + sage: class IDontLikeBeingPrinted(): ....: def __repr__(self): ....: raise ValueError("Don't ever try to print me !") diff --git a/src/sage/misc/lazy_import.pyx b/src/sage/misc/lazy_import.pyx index bc6078d24f2..ffb53ac3d59 100644 --- a/src/sage/misc/lazy_import.pyx +++ b/src/sage/misc/lazy_import.pyx @@ -161,7 +161,7 @@ cpdef test_fake_startup(): @cython.final -cdef class LazyImport(object): +cdef class LazyImport(): """ EXAMPLES:: @@ -477,7 +477,7 @@ cdef class LazyImport(object): Now we lazy import it as a method of a new class ``Foo``:: sage: from sage.misc.lazy_import import LazyImport - sage: class Foo(object): + sage: class Foo(): ....: my_method = LazyImport('sage.all', 'my_method') Now we can use it as a usual method:: @@ -503,7 +503,7 @@ cdef class LazyImport(object): definition is not the one that actually gets used. Thus, ``__get__`` needs to manually modify the class dict:: - sage: class Foo(object): + sage: class Foo(): ....: lazy_import('sage.all', 'plot') sage: class Bar(Foo): ....: pass @@ -1013,7 +1013,7 @@ def lazy_import(module, names, as_=None, *, We check that :func:`lazy_import` also works for methods:: - sage: class Foo(object): + sage: class Foo(): ....: lazy_import('sage.all', 'plot') sage: class Bar(Foo): ....: pass diff --git a/src/sage/misc/lazy_list.pxd b/src/sage/misc/lazy_list.pxd index 944edbf9684..f8b51b47835 100644 --- a/src/sage/misc/lazy_list.pxd +++ b/src/sage/misc/lazy_list.pxd @@ -1,4 +1,4 @@ -cdef class lazy_list_generic(object): +cdef class lazy_list_generic(): cdef list cache # the cache cdef lazy_list_generic master # a reference if self is a slice cdef Py_ssize_t start, stop, step diff --git a/src/sage/misc/lazy_list.pyx b/src/sage/misc/lazy_list.pyx index b1698ddd4bc..4e25ee39299 100644 --- a/src/sage/misc/lazy_list.pyx +++ b/src/sage/misc/lazy_list.pyx @@ -348,7 +348,7 @@ def lazy_list_formatter(L, name='lazy list', return s -cdef class lazy_list_generic(object): +cdef class lazy_list_generic(): r""" A lazy list diff --git a/src/sage/misc/lazy_string.pxd b/src/sage/misc/lazy_string.pxd index cde0aa1e73d..7f7354e03ca 100644 --- a/src/sage/misc/lazy_string.pxd +++ b/src/sage/misc/lazy_string.pxd @@ -1,4 +1,4 @@ -cdef class _LazyString(object): +cdef class _LazyString(): cdef func cdef args cdef kwargs diff --git a/src/sage/misc/lazy_string.pyx b/src/sage/misc/lazy_string.pyx index bfb5b29501b..9eaa0c8c8e5 100644 --- a/src/sage/misc/lazy_string.pyx +++ b/src/sage/misc/lazy_string.pyx @@ -136,7 +136,7 @@ def _make_lazy_string(ftype, fpickle, args, kwargs): f = fpickle return _LazyString(f, args, kwargs) -cdef class _LazyString(object): +cdef class _LazyString(): """ Lazy class for strings created by a function call or a format string. diff --git a/src/sage/misc/misc.py b/src/sage/misc/misc.py index 93f2bebdb55..da354511413 100644 --- a/src/sage/misc/misc.py +++ b/src/sage/misc/misc.py @@ -176,7 +176,7 @@ def try_read(obj, splitlines=False): Custom readable:: - sage: class MyFile(object): + sage: class MyFile(): ....: def read(self): return 'Hello world!' sage: try_read(MyFile()) 'Hello world!' diff --git a/src/sage/misc/nested_class.pyx b/src/sage/misc/nested_class.pyx index d27ec59923b..f30eec835ee 100644 --- a/src/sage/misc/nested_class.pyx +++ b/src/sage/misc/nested_class.pyx @@ -118,8 +118,8 @@ cpdef modify_for_nested_pickle(cls, str name_prefix, module, first_run=True): EXAMPLES:: sage: from sage.misc.nested_class import * - sage: class A(object): - ....: class B(object): + sage: class A(): + ....: class B(): ....: pass sage: module = sys.modules['__main__'] sage: A.B.__name__ @@ -220,7 +220,7 @@ def nested_pickle(cls): sage: from sage.misc.nested_class import nested_pickle sage: module = sys.modules['__main__'] - sage: class A(object): + sage: class A(): ....: class B: ....: pass sage: nested_pickle(A) @@ -238,7 +238,7 @@ def nested_pickle(cls): should work as a decorator:: sage: @nested_pickle # todo: not implemented - ....: class A2(object): + ....: class A2(): ....: class B: ....: pass sage: A2.B.__name__ # todo: not implemented @@ -267,7 +267,7 @@ cdef class NestedClassMetaclass(type): sage: class ASuperClass(object, metaclass=NestedClassMetaclass): ....: pass sage: class A3(ASuperClass): - ....: class B(object): + ....: class B(): ....: pass sage: A3.B.__name__ 'A3.B' @@ -282,7 +282,7 @@ cdef class NestedClassMetaclass(type): sage: from sage.misc.nested_class import NestedClassMetaclass sage: class A(object, metaclass=NestedClassMetaclass): - ....: class B(object): + ....: class B(): ....: pass sage: A.B @@ -303,7 +303,7 @@ class MainClass(object, metaclass=NestedClassMetaclass): """ - class NestedClass(object): + class NestedClass(): r""" EXAMPLES:: @@ -312,7 +312,7 @@ class MainClass(object, metaclass=NestedClassMetaclass): """ - class NestedSubClass(object): + class NestedSubClass(): r""" EXAMPLES:: @@ -362,7 +362,7 @@ nested_pickle(SubClass) def _provide_SubClass(): return SubClass -class CopiedClass(object): +class CopiedClass(): r""" A simple class to test nested_pickle. diff --git a/src/sage/misc/object_multiplexer.py b/src/sage/misc/object_multiplexer.py index dcb482b8df2..d4e811ef16e 100644 --- a/src/sage/misc/object_multiplexer.py +++ b/src/sage/misc/object_multiplexer.py @@ -21,7 +21,7 @@ # **************************************************************************** -class MultiplexFunction(object): +class MultiplexFunction(): """ A simple wrapper object for functions that are called on a list of objects. @@ -57,7 +57,7 @@ def __call__(self, *args, **kwds): return tuple(l) -class Multiplex(object): +class Multiplex(): """ Object for a list of children such that function calls on this new object implies that the same function is called on all diff --git a/src/sage/misc/persist.pyx b/src/sage/misc/persist.pyx index b71d7a32fc5..3ac5f1cc2b0 100644 --- a/src/sage/misc/persist.pyx +++ b/src/sage/misc/persist.pyx @@ -449,12 +449,12 @@ def register_unpickle_override(module, name, callable, call_name=None): :: - sage: class A(object): + sage: class A(): ....: def __init__(self,value): ....: self.original_attribute = value ....: def __repr__(self): ....: return 'A(%s)' % self.original_attribute - sage: class B(object): + sage: class B(): ....: def __init__(self,value): ....: self.new_attribute = value ....: def __setstate__(self,state): @@ -759,7 +759,7 @@ class SagePickler(_BasePickler): The following is an indirect doctest. :: - sage: class Foo(object): + sage: class Foo(): ....: def __init__(self, s): ....: self.bar = s ....: def __reduce__(self): @@ -949,7 +949,7 @@ def loads(s, compress=True, **kwargs): in a pickle. See :trac:`28444` for details. :: - sage: class Foo(object): + sage: class Foo(): ....: def __init__(self, s): ....: self.bar = s ....: def __reduce__(self): diff --git a/src/sage/misc/sage_input.py b/src/sage/misc/sage_input.py index 56286232257..57cfbe78751 100644 --- a/src/sage/misc/sage_input.py +++ b/src/sage/misc/sage_input.py @@ -1200,7 +1200,7 @@ def result(self, e): _prec_funcall = 40 _prec_atomic = 42 -class SageInputExpression(object): +class SageInputExpression(): r""" Subclasses of this class represent expressions for :func:`sage_input`. \sage classes should define a \method{_sage_input_} method, which diff --git a/src/sage/misc/sage_timeit.py b/src/sage/misc/sage_timeit.py index f2542ad5144..8250b461dd4 100644 --- a/src/sage/misc/sage_timeit.py +++ b/src/sage/misc/sage_timeit.py @@ -18,7 +18,7 @@ """ -class SageTimeitResult(object): +class SageTimeitResult(): r""" Represent the statistics of a timeit() command. diff --git a/src/sage/misc/sage_unittest.py b/src/sage/misc/sage_unittest.py index c6c6d2741dc..da99c3ea92d 100644 --- a/src/sage/misc/sage_unittest.py +++ b/src/sage/misc/sage_unittest.py @@ -17,7 +17,7 @@ import traceback -class TestSuite(object): +class TestSuite(): """ Test suites for Sage objects. @@ -576,7 +576,7 @@ def some_elements(self, S=None, repeat=None): return list(some_tuples(S, repeat, self._max_runs, self._max_samples)) -class PythonObjectWithTests(object): +class PythonObjectWithTests(): """ Utility class for running basis tests on a plain Python object (that is not in SageObject). More test methods can be added here. diff --git a/src/sage/misc/sageinspect.py b/src/sage/misc/sageinspect.py index 87df80ef514..67fc9165af8 100644 --- a/src/sage/misc/sageinspect.py +++ b/src/sage/misc/sageinspect.py @@ -1885,7 +1885,7 @@ def _sage_getdoc_unformatted(obj): ``__doc__`` attribute. This should not give an error in ``_sage_getdoc_unformatted``, see :trac:`19671`:: - sage: class NoSageDoc(object): + sage: class NoSageDoc(): ....: @property ....: def __doc__(self): ....: raise Exception("no doc here") @@ -2270,7 +2270,7 @@ def sage_getsourcelines(obj): sage: sage_getsourcelines(cachedfib)[0][0] 'def fibonacci(n, algorithm="pari") -> Integer:\n' sage: sage_getsourcelines(type(cachedfib))[0][0] - 'cdef class CachedFunction(object):\n' + 'cdef class CachedFunction():\n' TESTS:: @@ -2323,13 +2323,13 @@ def sage_getsourcelines(obj): (, ) sage: print(sage_getsource(E)) - class Element(object): + class Element(): "This is a dummy element class" pass sage: print(sage_getsource(P)) class TestNestedParent(UniqueRepresentation, Parent): ... - class Element(object): + class Element(): "This is a dummy element class" pass diff --git a/src/sage/misc/superseded.py b/src/sage/misc/superseded.py index 0d20e025a23..f3599b00fd9 100644 --- a/src/sage/misc/superseded.py +++ b/src/sage/misc/superseded.py @@ -215,7 +215,7 @@ def experimental_warning(trac_number, message, stacklevel=4): warning(trac_number, message, FutureWarning, stacklevel) -class experimental(object): +class experimental(): def __init__(self, trac_number, stacklevel=4): """ A decorator which warns about the experimental/unstable status of @@ -320,7 +320,7 @@ def wrapper(*args, **kwds): return wrapper -class __experimental_self_test(object): +class __experimental_self_test(): r""" This is a class only to demonstrate with a doc-test that the @experimental decorator only issues a warning message once (see :trac:`20601`). @@ -341,7 +341,7 @@ def __init__(self, x): print("I'm " + x) -class DeprecatedFunctionAlias(object): +class DeprecatedFunctionAlias(): """ A wrapper around methods or functions which automatically prints a deprecation message. See :func:`deprecated_function_alias`. @@ -391,7 +391,7 @@ def __name__(self): 'g' sage: from sage.misc.superseded import deprecated_function_alias - sage: class cls(object): + sage: class cls(): ....: def new_meth(self): return 42 ....: old_meth = deprecated_function_alias(13109, new_meth) sage: cls.old_meth.__name__ @@ -401,7 +401,7 @@ def __name__(self): sage: cython('\n'.join([ ....: r"from sage.misc.superseded import deprecated_function_alias", - ....: r"cdef class cython_cls(object):", + ....: r"cdef class cython_cls():", ....: r" def new_cython_meth(self):", ....: r" return 1", ....: r" old_cython_meth = deprecated_function_alias(13109, new_cython_meth)" @@ -464,7 +464,7 @@ def __get__(self, inst, cls=None): TESTS:: sage: from sage.misc.superseded import deprecated_function_alias - sage: class cls(object): + sage: class cls(): ....: def new_meth(self): return 42 ....: old_meth = deprecated_function_alias(13109, new_meth) sage: obj = cls() @@ -526,7 +526,7 @@ def deprecated_function_alias(trac_number, func): This also works for methods:: - sage: class cls(object): + sage: class cls(): ....: def new_meth(self): return 42 ....: old_meth = deprecated_function_alias(13109, new_meth) sage: cls().old_meth() diff --git a/src/sage/misc/temporary_file.py b/src/sage/misc/temporary_file.py index 461776e82f4..506bc925784 100644 --- a/src/sage/misc/temporary_file.py +++ b/src/sage/misc/temporary_file.py @@ -166,7 +166,7 @@ def tmp_filename(name="tmp_", ext=""): ################################################################# # write to a temporary file and move it in place ################################################################# -class atomic_write(object): +class atomic_write(): """ Write to a given file using a temporary file and then rename it to the target file. This renaming should be atomic on modern @@ -445,7 +445,7 @@ def __exit__(self, exc_type, exc_val, exc_tb): ################################################################# # write to a temporary directory and move it in place ################################################################# -class atomic_dir(object): +class atomic_dir(): """ Write to a given directory using a temporary directory and then rename it to the target directory. This is for creating a directory whose contents diff --git a/src/sage/misc/test_nested_class.py b/src/sage/misc/test_nested_class.py index 8e0c1ddf0c1..55973bd05b3 100644 --- a/src/sage/misc/test_nested_class.py +++ b/src/sage/misc/test_nested_class.py @@ -150,15 +150,15 @@ class Element(ElementWrapper): # Class for tests: -class B(object): +class B(): """ A normal external class. """ pass -class ABB(object): - class B(object): +class ABB(): + class B(): """ This class is broken and can't be pickled. A warning is emmited during compilation. @@ -166,18 +166,18 @@ class B(object): pass -class ABL(object): +class ABL(): """ There is no problem here. """ B = B -class ALB(object): +class ALB(): """ There is a nested class just below. Which can't be properly sphinxed. """ - class C(object): + class C(): """ Internal C class. @@ -190,7 +190,7 @@ class C(object): class ABBMeta(metaclass=NestedClassMetaclass): - class B(object): + class B(): """ B interne """ @@ -205,7 +205,7 @@ class ALBMeta(metaclass=NestedClassMetaclass): """ There is a nested class just below which is properly sphinxed. """ - class CMeta(object): + class CMeta(): """ B interne """ @@ -222,6 +222,6 @@ class TestNestedParent(UniqueRepresentation, Parent): See the test in ``sage.misc.sageinspect.sage_getsourcelines``. """ - class Element(object): + class Element(): "This is a dummy element class" pass diff --git a/src/sage/misc/weak_dict.pyx b/src/sage/misc/weak_dict.pyx index 77a3c626bbe..ac7bf3bbbd2 100644 --- a/src/sage/misc/weak_dict.pyx +++ b/src/sage/misc/weak_dict.pyx @@ -18,7 +18,7 @@ However, a problem arises if hash and comparison of the key depend on the value that is being garbage collected:: sage: import weakref - sage: class Vals(object): pass + sage: class Vals(): pass sage: class Keys: ....: def __init__(self, val): ....: self.val = weakref.ref(val) @@ -239,7 +239,7 @@ cdef class WeakValueDictionary(dict): EXAMPLES:: sage: import weakref - sage: class Vals(object): pass + sage: class Vals(): pass sage: class Keys: ....: def __init__(self, val): ....: self.val = weakref.ref(val) @@ -289,7 +289,7 @@ cdef class WeakValueDictionary(dict): The following is a stress test for weak value dictionaries:: - sage: class C(object): + sage: class C(): ....: def __init__(self, n): ....: self.n = n ....: def __lt__(self, other): @@ -383,7 +383,7 @@ cdef class WeakValueDictionary(dict): EXAMPLES:: - sage: class C(object): pass + sage: class C(): pass sage: V = [C(),C()] sage: D = sage.misc.weak_dict.WeakValueDictionary() sage: D[C()] = V[0] @@ -714,7 +714,7 @@ cdef class WeakValueDictionary(dict): TESTS:: sage: import sage.misc.weak_dict - sage: class Vals(object): pass + sage: class Vals(): pass sage: L = [Vals() for _ in range(10)] sage: D = sage.misc.weak_dict.WeakValueDictionary(enumerate(L)) sage: 3 in D # indirect doctest @@ -762,7 +762,7 @@ cdef class WeakValueDictionary(dict): EXAMPLES:: sage: import sage.misc.weak_dict - sage: class Vals(object): pass + sage: class Vals(): pass sage: L = [Vals() for _ in range(10)] sage: D = sage.misc.weak_dict.WeakValueDictionary(enumerate(L)) sage: del L[4] @@ -795,7 +795,7 @@ cdef class WeakValueDictionary(dict): EXAMPLES:: sage: import sage.misc.weak_dict - sage: class Vals(object): pass + sage: class Vals(): pass sage: L = [Vals() for _ in range(10)] sage: D = sage.misc.weak_dict.WeakValueDictionary(enumerate(L)) sage: del L[4] @@ -922,7 +922,7 @@ cdef class WeakValueDictionary(dict): ....: return self.n == other.n ....: def __ne__(self, other): ....: return self.val() != other.val() - sage: class Keys(object): + sage: class Keys(): ....: def __init__(self, n): ....: self.n = n ....: def __hash__(self): @@ -988,7 +988,7 @@ cdef class WeakValueDictionary(dict): ....: return self.n == other.n ....: def __ne__(self, other): ....: return self.val() != other.val() - sage: class Keys(object): + sage: class Keys(): ....: def __init__(self, n): ....: self.n = n ....: def __hash__(self): @@ -1098,7 +1098,7 @@ cdef class CachedWeakValueDictionary(WeakValueDictionary): sage: from sage.misc.weak_dict import WeakValueDictionary sage: D = WeakValueDictionary() - sage: class Test(object): pass + sage: class Test(): pass sage: tmp = Test() sage: D[0] = tmp sage: 0 in D @@ -1116,7 +1116,7 @@ cdef class CachedWeakValueDictionary(WeakValueDictionary): sage: from sage.misc.weak_dict import CachedWeakValueDictionary sage: D = CachedWeakValueDictionary(cache=4) - sage: class Test(object): pass + sage: class Test(): pass sage: tmp = Test() sage: D[0] = tmp sage: 0 in D @@ -1172,7 +1172,7 @@ cdef class CachedWeakValueDictionary(WeakValueDictionary): :class:`WeakValueDictionary`:: sage: D = CachedWeakValueDictionary(cache=0) - sage: class Test(object): pass + sage: class Test(): pass sage: tmp = Test() sage: D[0] = tmp sage: del tmp diff --git a/src/sage/repl/configuration.py b/src/sage/repl/configuration.py index 94f882ee933..1f2aeb27692 100644 --- a/src/sage/repl/configuration.py +++ b/src/sage/repl/configuration.py @@ -36,7 +36,7 @@ SAGE_EXTENSION = 'sage' -class SageIpythonConfiguration(object): +class SageIpythonConfiguration(): def _doctest_mode(self): """ diff --git a/src/sage/repl/display/fancy_repr.py b/src/sage/repl/display/fancy_repr.py index a606b5ef277..5c1191dc4f1 100644 --- a/src/sage/repl/display/fancy_repr.py +++ b/src/sage/repl/display/fancy_repr.py @@ -24,7 +24,7 @@ _baseclass_reprs = (object.__repr__,) -class ObjectReprABC(object): +class ObjectReprABC(): """ The abstract base class of an object representer. @@ -248,7 +248,7 @@ def __call__(self, obj, p, cycle): trailing newline, and if we don't display it you can't fix it:: - sage: class Newline(object): + sage: class Newline(): ....: def __repr__(self): ....: return 'newline\n' sage: n = Newline() @@ -317,7 +317,7 @@ def __call__(self, obj, p, cycle): Check that :trac:`18743` is fixed:: - sage: class Foo(object): + sage: class Foo(): ....: def __repr__(self): ....: return '''BBB AA RRR ....: B B A A R R diff --git a/src/sage/repl/display/formatter.py b/src/sage/repl/display/formatter.py index 9cb0bd661ea..adde08d27d2 100644 --- a/src/sage/repl/display/formatter.py +++ b/src/sage/repl/display/formatter.py @@ -177,7 +177,7 @@ def format(self, obj, include=None, exclude=None): Test that ``__repr__`` is only called once when generating text output:: - sage: class Repper(object): + sage: class Repper(): ....: def __repr__(self): ....: print('__repr__ called') ....: return 'I am repper' diff --git a/src/sage/repl/display/util.py b/src/sage/repl/display/util.py index 7f6997211fd..ee99782b6fa 100644 --- a/src/sage/repl/display/util.py +++ b/src/sage/repl/display/util.py @@ -16,7 +16,7 @@ #***************************************************************************** -class TallListFormatter(object): +class TallListFormatter(): """ Special representation for lists with tall entries (e.g. matrices) diff --git a/src/sage/repl/interface_magic.py b/src/sage/repl/interface_magic.py index a93e1c9e04c..df4b1020a2a 100644 --- a/src/sage/repl/interface_magic.py +++ b/src/sage/repl/interface_magic.py @@ -79,7 +79,7 @@ """ -class InterfaceMagic(object): +class InterfaceMagic(): @classmethod def all_iter(cls): diff --git a/src/sage/repl/interpreter.py b/src/sage/repl/interpreter.py index 84f90fca75d..2d48b2b4802 100644 --- a/src/sage/repl/interpreter.py +++ b/src/sage/repl/interpreter.py @@ -185,7 +185,7 @@ def preparser(on=True): ############################## # Sage[Terminal]InteractiveShell ############################## -class SageShellOverride(object): +class SageShellOverride(): """ Mixin to override methods in IPython's [Terminal]InteractiveShell classes. @@ -487,11 +487,11 @@ def __init__(self, *args, **kwds): def preparse_imports_from_sage(self, line): """ - Finds occurrences of strings such as ``sage(object)`` in + Finds occurrences of strings such as ``sage()`` in *line*, converts ``object`` to :attr:`shell.interface`, and replaces those strings with their identifier in the new system. This also works with strings such as - ``maxima(object)`` if :attr:`shell.interface` is + ``maxima()`` if :attr:`shell.interface` is ``maxima``. :param line: the line to transform diff --git a/src/sage/repl/ipython_extension.py b/src/sage/repl/ipython_extension.py index eb508b067f5..fc39f079cc0 100644 --- a/src/sage/repl/ipython_extension.py +++ b/src/sage/repl/ipython_extension.py @@ -416,7 +416,7 @@ def fortran(self, line, cell): return fortran(cell) -class SageCustomizations(object): +class SageCustomizations(): def __init__(self, shell=None): """ diff --git a/src/sage/repl/ipython_kernel/install.py b/src/sage/repl/ipython_kernel/install.py index 684139afb66..cfb11b51bcf 100644 --- a/src/sage/repl/ipython_kernel/install.py +++ b/src/sage/repl/ipython_kernel/install.py @@ -25,7 +25,7 @@ ) -class SageKernelSpec(object): +class SageKernelSpec(): def __init__(self, prefix=None): """ diff --git a/src/sage/repl/ipython_kernel/widgets.py b/src/sage/repl/ipython_kernel/widgets.py index d28594cd24d..dfe126a2760 100644 --- a/src/sage/repl/ipython_kernel/widgets.py +++ b/src/sage/repl/ipython_kernel/widgets.py @@ -83,7 +83,7 @@ def description(self, value): pass -class TransformWidget(object): +class TransformWidget(): """ A mixin class for a widget to transform the bare widget value for use in interactive functions. diff --git a/src/sage/repl/rich_output/display_manager.py b/src/sage/repl/rich_output/display_manager.py index 62a3adf05c4..f022335f8e6 100644 --- a/src/sage/repl/rich_output/display_manager.py +++ b/src/sage/repl/rich_output/display_manager.py @@ -118,7 +118,7 @@ class RichReprWarning(UserWarning): pass -class restricted_output(object): +class restricted_output(): def __init__(self, display_manager, output_classes): """ From c27f1f50853e4be95e2249df9f1c3b712766b68d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 27 May 2022 15:07:07 +0200 Subject: [PATCH 485/529] also no class(object) in libs/ --- src/sage/libs/coxeter3/coxeter.pyx | 2 +- src/sage/libs/gap/element.pxd | 2 +- src/sage/libs/gap/element.pyx | 2 +- src/sage/libs/gap/util.pxd | 2 +- src/sage/libs/gap/util.pyx | 2 +- src/sage/libs/ntl/ntl_GF2.pxd | 2 +- src/sage/libs/ntl/ntl_GF2.pyx | 2 +- src/sage/libs/ntl/ntl_GF2E.pxd | 2 +- src/sage/libs/ntl/ntl_GF2E.pyx | 2 +- src/sage/libs/ntl/ntl_GF2EContext.pxd | 2 +- src/sage/libs/ntl/ntl_GF2EContext.pyx | 2 +- src/sage/libs/ntl/ntl_GF2EX.pxd | 2 +- src/sage/libs/ntl/ntl_GF2EX.pyx | 2 +- src/sage/libs/ntl/ntl_GF2X.pxd | 2 +- src/sage/libs/ntl/ntl_GF2X.pyx | 2 +- src/sage/libs/ntl/ntl_ZZ.pxd | 2 +- src/sage/libs/ntl/ntl_ZZ.pyx | 2 +- src/sage/libs/ntl/ntl_ZZX.pxd | 2 +- src/sage/libs/ntl/ntl_ZZX.pyx | 2 +- src/sage/libs/ntl/ntl_ZZ_p.pxd | 2 +- src/sage/libs/ntl/ntl_ZZ_p.pyx | 2 +- src/sage/libs/ntl/ntl_ZZ_pContext.pxd | 4 ++-- src/sage/libs/ntl/ntl_ZZ_pContext.pyx | 4 ++-- src/sage/libs/ntl/ntl_ZZ_pE.pxd | 2 +- src/sage/libs/ntl/ntl_ZZ_pE.pyx | 2 +- src/sage/libs/ntl/ntl_ZZ_pEContext.pxd | 2 +- src/sage/libs/ntl/ntl_ZZ_pEContext.pyx | 2 +- src/sage/libs/ntl/ntl_ZZ_pEX.pxd | 2 +- src/sage/libs/ntl/ntl_ZZ_pEX.pyx | 2 +- src/sage/libs/ntl/ntl_ZZ_pX.pxd | 4 ++-- src/sage/libs/ntl/ntl_ZZ_pX.pyx | 4 ++-- src/sage/libs/ntl/ntl_lzz_p.pxd | 2 +- src/sage/libs/ntl/ntl_lzz_p.pyx | 2 +- src/sage/libs/ntl/ntl_lzz_pContext.pxd | 2 +- src/sage/libs/ntl/ntl_lzz_pContext.pyx | 2 +- src/sage/libs/ntl/ntl_lzz_pX.pxd | 2 +- src/sage/libs/ntl/ntl_lzz_pX.pyx | 2 +- src/sage/libs/ntl/ntl_mat_GF2.pxd | 2 +- src/sage/libs/ntl/ntl_mat_GF2.pyx | 2 +- src/sage/libs/ntl/ntl_mat_GF2E.pxd | 2 +- src/sage/libs/ntl/ntl_mat_GF2E.pyx | 2 +- src/sage/libs/ntl/ntl_mat_ZZ.pxd | 2 +- src/sage/libs/ntl/ntl_mat_ZZ.pyx | 2 +- src/sage/libs/singular/function_factory.py | 2 +- src/sage/libs/singular/ring.pyx | 2 +- 45 files changed, 49 insertions(+), 49 deletions(-) diff --git a/src/sage/libs/coxeter3/coxeter.pyx b/src/sage/libs/coxeter3/coxeter.pyx index 603261f7661..533c35b6a40 100644 --- a/src/sage/libs/coxeter3/coxeter.pyx +++ b/src/sage/libs/coxeter3/coxeter.pyx @@ -1144,7 +1144,7 @@ cdef LFlags_to_list(CoxGroup parent, LFlags f): f1 = f1 & (f1-1) return l -class CoxGroupIterator(object): +class CoxGroupIterator(): def __init__(self, group): """ A class used to iterate over all of the elements of a Coxeter group. diff --git a/src/sage/libs/gap/element.pxd b/src/sage/libs/gap/element.pxd index 84dc49d8110..a1bf8118d4f 100644 --- a/src/sage/libs/gap/element.pxd +++ b/src/sage/libs/gap/element.pxd @@ -89,7 +89,7 @@ cdef class GapElement_MethodProxy(GapElement_Function): cdef class GapElement_Record(GapElement): cpdef UInt record_name_to_index(self, name) -cdef class GapElement_RecordIterator(object): +cdef class GapElement_RecordIterator(): cdef GapElement_Record rec cdef UInt i diff --git a/src/sage/libs/gap/element.pyx b/src/sage/libs/gap/element.pyx index 0c12bc4d9e7..be43c4c3ee0 100644 --- a/src/sage/libs/gap/element.pyx +++ b/src/sage/libs/gap/element.pyx @@ -3246,7 +3246,7 @@ cdef class GapElement_Record(GapElement): return result -cdef class GapElement_RecordIterator(object): +cdef class GapElement_RecordIterator(): r""" Iterator for :class:`GapElement_Record` diff --git a/src/sage/libs/gap/util.pxd b/src/sage/libs/gap/util.pxd index 986a2db45c2..118146133f4 100644 --- a/src/sage/libs/gap/util.pxd +++ b/src/sage/libs/gap/util.pxd @@ -14,7 +14,7 @@ from .gap_includes cimport Obj ### Hooking into the GAP memory management ################################# ############################################################################ -cdef class ObjWrapper(object): +cdef class ObjWrapper(): cdef Obj value cdef ObjWrapper wrap_obj(Obj obj) diff --git a/src/sage/libs/gap/util.pyx b/src/sage/libs/gap/util.pyx index 08c4c40cc01..9d5d793a57f 100644 --- a/src/sage/libs/gap/util.pyx +++ b/src/sage/libs/gap/util.pyx @@ -36,7 +36,7 @@ from sage.interfaces.gap_workspace import prepare_workspace_dir ############################################################################ -cdef class ObjWrapper(object): +cdef class ObjWrapper(): """ Wrapper for GAP master pointers diff --git a/src/sage/libs/ntl/ntl_GF2.pxd b/src/sage/libs/ntl/ntl_GF2.pxd index 16fb73e8f10..0eff25dd32c 100644 --- a/src/sage/libs/ntl/ntl_GF2.pxd +++ b/src/sage/libs/ntl/ntl_GF2.pxd @@ -1,4 +1,4 @@ from .types cimport GF2_c -cdef class ntl_GF2(object): +cdef class ntl_GF2(): cdef GF2_c x diff --git a/src/sage/libs/ntl/ntl_GF2.pyx b/src/sage/libs/ntl/ntl_GF2.pyx index 605bd3ad936..c88034ff5c4 100644 --- a/src/sage/libs/ntl/ntl_GF2.pyx +++ b/src/sage/libs/ntl/ntl_GF2.pyx @@ -34,7 +34,7 @@ from sage.rings.integer_ring cimport IntegerRing_class # GF2: Bits ############################################################################## -cdef class ntl_GF2(object): +cdef class ntl_GF2(): r""" The \class{GF2} represents the field GF(2). Computationally speaking, it is not a particularly useful class. Its main use is diff --git a/src/sage/libs/ntl/ntl_GF2E.pxd b/src/sage/libs/ntl/ntl_GF2E.pxd index 267330c813d..8977f711078 100644 --- a/src/sage/libs/ntl/ntl_GF2E.pxd +++ b/src/sage/libs/ntl/ntl_GF2E.pxd @@ -1,7 +1,7 @@ from .types cimport GF2E_c from .ntl_GF2EContext cimport ntl_GF2EContext_class -cdef class ntl_GF2E(object): +cdef class ntl_GF2E(): cdef GF2E_c x cdef ntl_GF2EContext_class c cdef ntl_GF2E _new(self) diff --git a/src/sage/libs/ntl/ntl_GF2E.pyx b/src/sage/libs/ntl/ntl_GF2E.pyx index 252851d40ed..bc6a32ce0d3 100644 --- a/src/sage/libs/ntl/ntl_GF2E.pyx +++ b/src/sage/libs/ntl/ntl_GF2E.pyx @@ -71,7 +71,7 @@ def ntl_GF2E_random(ntl_GF2EContext_class ctx): r.x = GF2E_random() return r -cdef class ntl_GF2E(object): +cdef class ntl_GF2E(): r""" The \\class{GF2E} represents a finite extension field over GF(2) using NTL. Elements are represented as polynomials over GF(2) diff --git a/src/sage/libs/ntl/ntl_GF2EContext.pxd b/src/sage/libs/ntl/ntl_GF2EContext.pxd index 73beae27eb5..44ab9891713 100644 --- a/src/sage/libs/ntl/ntl_GF2EContext.pxd +++ b/src/sage/libs/ntl/ntl_GF2EContext.pxd @@ -1,7 +1,7 @@ from .types cimport GF2EContext_c from .ntl_GF2X cimport ntl_GF2X -cdef class ntl_GF2EContext_class(object): +cdef class ntl_GF2EContext_class(): cdef GF2EContext_c x cdef ntl_GF2X m cdef void restore_c(self) diff --git a/src/sage/libs/ntl/ntl_GF2EContext.pyx b/src/sage/libs/ntl/ntl_GF2EContext.pyx index d31f8fc6e10..11d06893505 100644 --- a/src/sage/libs/ntl/ntl_GF2EContext.pyx +++ b/src/sage/libs/ntl/ntl_GF2EContext.pyx @@ -27,7 +27,7 @@ import weakref GF2EContextDict = {} -cdef class ntl_GF2EContext_class(object): +cdef class ntl_GF2EContext_class(): def __init__(self, ntl_GF2X v): """ EXAMPLES:: diff --git a/src/sage/libs/ntl/ntl_GF2EX.pxd b/src/sage/libs/ntl/ntl_GF2EX.pxd index 11e8cc2193d..70e06122753 100644 --- a/src/sage/libs/ntl/ntl_GF2EX.pxd +++ b/src/sage/libs/ntl/ntl_GF2EX.pxd @@ -2,7 +2,7 @@ from .types cimport GF2EX_c from .ntl_GF2EContext cimport ntl_GF2EContext_class from .ntl_GF2E cimport ntl_GF2E -cdef class ntl_GF2EX(object): +cdef class ntl_GF2EX(): cdef GF2EX_c x cdef ntl_GF2EContext_class c cdef ntl_GF2E _new_element(self) diff --git a/src/sage/libs/ntl/ntl_GF2EX.pyx b/src/sage/libs/ntl/ntl_GF2EX.pyx index be37ec0313a..e9dfbab4668 100644 --- a/src/sage/libs/ntl/ntl_GF2EX.pyx +++ b/src/sage/libs/ntl/ntl_GF2EX.pyx @@ -41,7 +41,7 @@ from .ntl_GF2E cimport ntl_GF2E # ############################################################################## -cdef class ntl_GF2EX(object): +cdef class ntl_GF2EX(): r""" Minimal wrapper of NTL's GF2EX class. """ diff --git a/src/sage/libs/ntl/ntl_GF2X.pxd b/src/sage/libs/ntl/ntl_GF2X.pxd index 4015771577d..5af874d0b9e 100644 --- a/src/sage/libs/ntl/ntl_GF2X.pxd +++ b/src/sage/libs/ntl/ntl_GF2X.pxd @@ -1,4 +1,4 @@ from .types cimport GF2X_c -cdef class ntl_GF2X(object): +cdef class ntl_GF2X(): cdef GF2X_c x diff --git a/src/sage/libs/ntl/ntl_GF2X.pyx b/src/sage/libs/ntl/ntl_GF2X.pyx index 8aa4c43d348..58f536a9c8b 100644 --- a/src/sage/libs/ntl/ntl_GF2X.pyx +++ b/src/sage/libs/ntl/ntl_GF2X.pyx @@ -87,7 +87,7 @@ def GF2XHexOutput(have_hex=None): GF2XHexOutput_c[0] = 0 -cdef class ntl_GF2X(object): +cdef class ntl_GF2X(): """ Univariate Polynomials over GF(2) via NTL. """ diff --git a/src/sage/libs/ntl/ntl_ZZ.pxd b/src/sage/libs/ntl/ntl_ZZ.pxd index 2ecf42c100d..31a23b29d46 100644 --- a/src/sage/libs/ntl/ntl_ZZ.pxd +++ b/src/sage/libs/ntl/ntl_ZZ.pxd @@ -1,6 +1,6 @@ from sage.libs.ntl.types cimport ZZ_c -cdef class ntl_ZZ(object): +cdef class ntl_ZZ(): cdef ZZ_c x cdef int get_as_int(ntl_ZZ self) cdef void set_from_int(ntl_ZZ self, int value) diff --git a/src/sage/libs/ntl/ntl_ZZ.pyx b/src/sage/libs/ntl/ntl_ZZ.pyx index 5a124ef47cf..39a98da2101 100644 --- a/src/sage/libs/ntl/ntl_ZZ.pyx +++ b/src/sage/libs/ntl/ntl_ZZ.pyx @@ -46,7 +46,7 @@ cdef make_ZZ(ZZ_c* x): # ZZ: Arbitrary precision integers ############################################################################## -cdef class ntl_ZZ(object): +cdef class ntl_ZZ(): r""" The \class{ZZ} class is used to represent signed, arbitrary length integers. diff --git a/src/sage/libs/ntl/ntl_ZZX.pxd b/src/sage/libs/ntl/ntl_ZZX.pxd index 8fae49f585b..c15a3f2d1e4 100644 --- a/src/sage/libs/ntl/ntl_ZZX.pxd +++ b/src/sage/libs/ntl/ntl_ZZX.pxd @@ -1,6 +1,6 @@ from .types cimport ZZX_c -cdef class ntl_ZZX(object): +cdef class ntl_ZZX(): cdef ZZX_c x cdef void setitem_from_int(ntl_ZZX self, long i, int value) cdef int getitem_as_int(ntl_ZZX self, long i) diff --git a/src/sage/libs/ntl/ntl_ZZX.pyx b/src/sage/libs/ntl/ntl_ZZX.pyx index 8c596bd23a6..c431864a853 100644 --- a/src/sage/libs/ntl/ntl_ZZX.pyx +++ b/src/sage/libs/ntl/ntl_ZZX.pyx @@ -79,7 +79,7 @@ cdef proof_flag(t): ############################################################################## -cdef class ntl_ZZX(object): +cdef class ntl_ZZX(): r""" The class \class{ZZX} implements polynomials in $\Z[X]$, i.e., univariate polynomials with integer coefficients. diff --git a/src/sage/libs/ntl/ntl_ZZ_p.pxd b/src/sage/libs/ntl/ntl_ZZ_p.pxd index 472587744db..4863afeb2c2 100644 --- a/src/sage/libs/ntl/ntl_ZZ_p.pxd +++ b/src/sage/libs/ntl/ntl_ZZ_p.pxd @@ -1,7 +1,7 @@ from .types cimport ZZ_p_c from .ntl_ZZ_pContext cimport ntl_ZZ_pContext_class -cdef class ntl_ZZ_p(object): +cdef class ntl_ZZ_p(): cdef ZZ_p_c x cdef ntl_ZZ_pContext_class c cdef int get_as_int(ntl_ZZ_p self) diff --git a/src/sage/libs/ntl/ntl_ZZ_p.pyx b/src/sage/libs/ntl/ntl_ZZ_p.pyx index 114963b1882..7c4b024b82a 100644 --- a/src/sage/libs/ntl/ntl_ZZ_p.pyx +++ b/src/sage/libs/ntl/ntl_ZZ_p.pyx @@ -74,7 +74,7 @@ def ntl_ZZ_p_random_element(v): # ZZ_p_c: integers modulo p # ############################################################################## -cdef class ntl_ZZ_p(object): +cdef class ntl_ZZ_p(): r""" The \class{ZZ_p} class is used to represent integers modulo $p$. The modulus $p$ may be any positive integer, not necessarily prime. diff --git a/src/sage/libs/ntl/ntl_ZZ_pContext.pxd b/src/sage/libs/ntl/ntl_ZZ_pContext.pxd index 124ba102ac8..171776d85d7 100644 --- a/src/sage/libs/ntl/ntl_ZZ_pContext.pxd +++ b/src/sage/libs/ntl/ntl_ZZ_pContext.pxd @@ -3,7 +3,7 @@ from .ntl_ZZ cimport ntl_ZZ from .types cimport ZZ_c -cdef class ntl_ZZ_pContext_class(object): +cdef class ntl_ZZ_pContext_class(): cdef ZZ_pContext_c x cdef void restore_c(self) cdef ntl_ZZ p @@ -12,7 +12,7 @@ cdef class ntl_ZZ_pContext_class(object): cpdef void _assert_is_current_modulus(self) except * -cdef class ntl_ZZ_pContext_factory(object): +cdef class ntl_ZZ_pContext_factory(): cdef object context_dict cdef ntl_ZZ_pContext_class make_c(self, ntl_ZZ v) diff --git a/src/sage/libs/ntl/ntl_ZZ_pContext.pyx b/src/sage/libs/ntl/ntl_ZZ_pContext.pyx index 008e6abd8eb..dbcc8af1441 100644 --- a/src/sage/libs/ntl/ntl_ZZ_pContext.pyx +++ b/src/sage/libs/ntl/ntl_ZZ_pContext.pyx @@ -28,7 +28,7 @@ from sage.ext.cplusplus cimport ccrepr from sage.rings.integer cimport Integer -cdef class ntl_ZZ_pContext_class(object): +cdef class ntl_ZZ_pContext_class(): def __init__(self, ntl_ZZ v): """ EXAMPLES:: @@ -157,7 +157,7 @@ cdef class ntl_ZZ_pContext_class(object): ccrepr(ntl_ZZ_p_current_modulus()))) -cdef class ntl_ZZ_pContext_factory(object): +cdef class ntl_ZZ_pContext_factory(): def __init__(self): self.context_dict = {} diff --git a/src/sage/libs/ntl/ntl_ZZ_pE.pxd b/src/sage/libs/ntl/ntl_ZZ_pE.pxd index d7d265b437d..267608a016d 100644 --- a/src/sage/libs/ntl/ntl_ZZ_pE.pxd +++ b/src/sage/libs/ntl/ntl_ZZ_pE.pxd @@ -2,7 +2,7 @@ from .types cimport ZZ_pE_c from .ntl_ZZ_pEContext cimport ntl_ZZ_pEContext_class from .ntl_ZZ_pX cimport ntl_ZZ_pX -cdef class ntl_ZZ_pE(object): +cdef class ntl_ZZ_pE(): cdef ZZ_pE_c x cdef ntl_ZZ_pEContext_class c cdef ntl_ZZ_pX get_as_ZZ_pX(ntl_ZZ_pE self) diff --git a/src/sage/libs/ntl/ntl_ZZ_pE.pyx b/src/sage/libs/ntl/ntl_ZZ_pE.pyx index 6e3684521de..82fbb086127 100644 --- a/src/sage/libs/ntl/ntl_ZZ_pE.pyx +++ b/src/sage/libs/ntl/ntl_ZZ_pE.pyx @@ -54,7 +54,7 @@ ZZ_sage = IntegerRing() # ZZ_pE_c: An extension of the integers modulo p # ############################################################################## -cdef class ntl_ZZ_pE(object): +cdef class ntl_ZZ_pE(): r""" The \class{ZZ_pE} class is used to model $\Z / p\Z [x] / (f(x))$. The modulus $p$ may be any positive integer, not necessarily prime, diff --git a/src/sage/libs/ntl/ntl_ZZ_pEContext.pxd b/src/sage/libs/ntl/ntl_ZZ_pEContext.pxd index 0e4f679218e..72c9ec42eab 100644 --- a/src/sage/libs/ntl/ntl_ZZ_pEContext.pxd +++ b/src/sage/libs/ntl/ntl_ZZ_pEContext.pxd @@ -9,7 +9,7 @@ cdef struct ZZ_pEContext_ptrs: ZZ_pContext_c *zzpc -cdef class ntl_ZZ_pEContext_class(object): +cdef class ntl_ZZ_pEContext_class(): cdef ZZ_pEContext_ptrs ptrs cdef ZZ_pEContext_c x cdef ntl_ZZ_pContext_class pc diff --git a/src/sage/libs/ntl/ntl_ZZ_pEContext.pyx b/src/sage/libs/ntl/ntl_ZZ_pEContext.pyx index 69dcbff7469..bef581722bd 100644 --- a/src/sage/libs/ntl/ntl_ZZ_pEContext.pyx +++ b/src/sage/libs/ntl/ntl_ZZ_pEContext.pyx @@ -32,7 +32,7 @@ from sage.libs.ntl.ntl_ZZ cimport ntl_ZZ ZZ_pEContextDict = {} -cdef class ntl_ZZ_pEContext_class(object): +cdef class ntl_ZZ_pEContext_class(): def __init__(self, ntl_ZZ_pX f): """ EXAMPLES: diff --git a/src/sage/libs/ntl/ntl_ZZ_pEX.pxd b/src/sage/libs/ntl/ntl_ZZ_pEX.pxd index a07403c1842..b00e87bbcec 100644 --- a/src/sage/libs/ntl/ntl_ZZ_pEX.pxd +++ b/src/sage/libs/ntl/ntl_ZZ_pEX.pxd @@ -1,7 +1,7 @@ from .types cimport ZZ_pEX_c from .ntl_ZZ_pEContext cimport ntl_ZZ_pEContext_class -cdef class ntl_ZZ_pEX(object): +cdef class ntl_ZZ_pEX(): cdef ZZ_pEX_c x cdef ntl_ZZ_pEContext_class c #cdef void setitem_from_int(ntl_ZZ_pX self, long i, int value) diff --git a/src/sage/libs/ntl/ntl_ZZ_pEX.pyx b/src/sage/libs/ntl/ntl_ZZ_pEX.pyx index a23d84bd4ad..6b874b6d41e 100644 --- a/src/sage/libs/ntl/ntl_ZZ_pEX.pyx +++ b/src/sage/libs/ntl/ntl_ZZ_pEX.pyx @@ -51,7 +51,7 @@ from sage.arith.power cimport generic_power_pos # ############################################################################## -cdef class ntl_ZZ_pEX(object): +cdef class ntl_ZZ_pEX(): r""" The class \class{ZZ_pEX} implements polynomials over finite ring extensions of $\Z / p\Z$. diff --git a/src/sage/libs/ntl/ntl_ZZ_pX.pxd b/src/sage/libs/ntl/ntl_ZZ_pX.pxd index 907285b2bdd..6dfed011120 100644 --- a/src/sage/libs/ntl/ntl_ZZ_pX.pxd +++ b/src/sage/libs/ntl/ntl_ZZ_pX.pxd @@ -1,13 +1,13 @@ from .ZZ_pX cimport * from sage.libs.ntl.ntl_ZZ_pContext cimport ntl_ZZ_pContext_class -cdef class ntl_ZZ_pX(object): +cdef class ntl_ZZ_pX(): cdef ZZ_pX_c x cdef ntl_ZZ_pContext_class c cdef void setitem_from_int(ntl_ZZ_pX self, long i, int value) cdef int getitem_as_int(ntl_ZZ_pX self, long i) cdef ntl_ZZ_pX _new(self) -cdef class ntl_ZZ_pX_Modulus(object): +cdef class ntl_ZZ_pX_Modulus(): cdef ZZ_pX_Modulus_c x cdef ntl_ZZ_pX poly diff --git a/src/sage/libs/ntl/ntl_ZZ_pX.pyx b/src/sage/libs/ntl/ntl_ZZ_pX.pyx index fd70c0bbce5..2d03c23a88f 100644 --- a/src/sage/libs/ntl/ntl_ZZ_pX.pyx +++ b/src/sage/libs/ntl/ntl_ZZ_pX.pyx @@ -63,7 +63,7 @@ cdef make_ZZ_pX(ZZ_pX_c* x, ntl_ZZ_pContext_class ctx): # ############################################################################## -cdef class ntl_ZZ_pX(object): +cdef class ntl_ZZ_pX(): r""" The class \class{ZZ_pX} implements polynomial arithmetic modulo `p`. @@ -1415,7 +1415,7 @@ cdef class ntl_ZZ_pX(object): #ZZ_pX_preallocate_space(&self.x, n) sig_off() -cdef class ntl_ZZ_pX_Modulus(object): +cdef class ntl_ZZ_pX_Modulus(): """ Thin holder for ZZ_pX_Moduli. """ diff --git a/src/sage/libs/ntl/ntl_lzz_p.pxd b/src/sage/libs/ntl/ntl_lzz_p.pxd index 567345427e0..ec74b46d447 100644 --- a/src/sage/libs/ntl/ntl_lzz_p.pxd +++ b/src/sage/libs/ntl/ntl_lzz_p.pxd @@ -1,7 +1,7 @@ from .lzz_p cimport * from .ntl_lzz_pContext cimport ntl_zz_pContext_class -cdef class ntl_zz_p(object): +cdef class ntl_zz_p(): cdef zz_p_c x cdef ntl_zz_pContext_class c cdef ntl_zz_p _new(ntl_zz_p self) diff --git a/src/sage/libs/ntl/ntl_lzz_p.pyx b/src/sage/libs/ntl/ntl_lzz_p.pyx index 2152f299967..bd25c536ec3 100644 --- a/src/sage/libs/ntl/ntl_lzz_p.pyx +++ b/src/sage/libs/ntl/ntl_lzz_p.pyx @@ -59,7 +59,7 @@ ZZ_sage = IntegerRing() # ############################################################################## -cdef class ntl_zz_p(object): +cdef class ntl_zz_p(): r""" The class \class{zz_p} implements arithmetic modulo $p$, for p smaller than a machine word. diff --git a/src/sage/libs/ntl/ntl_lzz_pContext.pxd b/src/sage/libs/ntl/ntl_lzz_pContext.pxd index b5b436672c9..058d2842ecc 100644 --- a/src/sage/libs/ntl/ntl_lzz_pContext.pxd +++ b/src/sage/libs/ntl/ntl_lzz_pContext.pxd @@ -1,6 +1,6 @@ from .types cimport zz_pContext_c -cdef class ntl_zz_pContext_class(object): +cdef class ntl_zz_pContext_class(): cdef zz_pContext_c x cdef void restore_c(self) cdef long p diff --git a/src/sage/libs/ntl/ntl_lzz_pContext.pyx b/src/sage/libs/ntl/ntl_lzz_pContext.pyx index 9f69dce88b0..64301157702 100644 --- a/src/sage/libs/ntl/ntl_lzz_pContext.pyx +++ b/src/sage/libs/ntl/ntl_lzz_pContext.pyx @@ -23,7 +23,7 @@ from sage.rings.integer cimport Integer zz_pContextDict = {} -cdef class ntl_zz_pContext_class(object): +cdef class ntl_zz_pContext_class(): def __init__(self, long v): """ EXAMPLES:: diff --git a/src/sage/libs/ntl/ntl_lzz_pX.pxd b/src/sage/libs/ntl/ntl_lzz_pX.pxd index e96c44c6ae0..3ab79084299 100644 --- a/src/sage/libs/ntl/ntl_lzz_pX.pxd +++ b/src/sage/libs/ntl/ntl_lzz_pX.pxd @@ -3,7 +3,7 @@ from sage.libs.ntl.lzz_pX cimport * from sage.libs.ntl.ntl_lzz_pContext cimport ntl_zz_pContext_class -cdef class ntl_zz_pX(object): +cdef class ntl_zz_pX(): cdef zz_pX_c x cdef ntl_zz_pContext_class c cdef ntl_zz_pX _new(self) diff --git a/src/sage/libs/ntl/ntl_lzz_pX.pyx b/src/sage/libs/ntl/ntl_lzz_pX.pyx index d7a88da82fd..c181a7eae59 100644 --- a/src/sage/libs/ntl/ntl_lzz_pX.pyx +++ b/src/sage/libs/ntl/ntl_lzz_pX.pyx @@ -52,7 +52,7 @@ ZZ_sage = IntegerRing() # ############################################################################## -cdef class ntl_zz_pX(object): +cdef class ntl_zz_pX(): r""" The class \class{zz_pX} implements polynomial arithmetic modulo $p$, for p smaller than a machine word. diff --git a/src/sage/libs/ntl/ntl_mat_GF2.pxd b/src/sage/libs/ntl/ntl_mat_GF2.pxd index cae49b8313e..b900d2f9e3f 100644 --- a/src/sage/libs/ntl/ntl_mat_GF2.pxd +++ b/src/sage/libs/ntl/ntl_mat_GF2.pxd @@ -1,7 +1,7 @@ from .types cimport mat_GF2_c from .ntl_GF2 cimport ntl_GF2 -cdef class ntl_mat_GF2(object): +cdef class ntl_mat_GF2(): cdef mat_GF2_c x cdef ntl_GF2 _new_element(self) cdef ntl_mat_GF2 _new(self) diff --git a/src/sage/libs/ntl/ntl_mat_GF2.pyx b/src/sage/libs/ntl/ntl_mat_GF2.pyx index 6967d469cef..acdf12dc4dd 100644 --- a/src/sage/libs/ntl/ntl_mat_GF2.pyx +++ b/src/sage/libs/ntl/ntl_mat_GF2.pyx @@ -45,7 +45,7 @@ from sage.rings.integer cimport Integer from sage.libs.ntl.ntl_ZZ import unpickle_class_args -cdef class ntl_mat_GF2(object): +cdef class ntl_mat_GF2(): r""" The \class{mat_GF2} class implements arithmetic with matrices over $F_2$. """ diff --git a/src/sage/libs/ntl/ntl_mat_GF2E.pxd b/src/sage/libs/ntl/ntl_mat_GF2E.pxd index 3a30fca6dd6..5c8aacd5cef 100644 --- a/src/sage/libs/ntl/ntl_mat_GF2E.pxd +++ b/src/sage/libs/ntl/ntl_mat_GF2E.pxd @@ -2,7 +2,7 @@ from .types cimport mat_GF2E_c from .ntl_GF2EContext cimport ntl_GF2EContext_class from .ntl_GF2E cimport ntl_GF2E -cdef class ntl_mat_GF2E(object): +cdef class ntl_mat_GF2E(): cdef mat_GF2E_c x cdef ntl_GF2EContext_class c cdef ntl_GF2E _new_element(self) diff --git a/src/sage/libs/ntl/ntl_mat_GF2E.pyx b/src/sage/libs/ntl/ntl_mat_GF2E.pyx index 85fd9d6d46f..6cc41e9318a 100644 --- a/src/sage/libs/ntl/ntl_mat_GF2E.pyx +++ b/src/sage/libs/ntl/ntl_mat_GF2E.pyx @@ -45,7 +45,7 @@ from sage.misc.randstate cimport randstate, current_randstate from sage.libs.ntl.ntl_ZZ import unpickle_class_args -cdef class ntl_mat_GF2E(object): +cdef class ntl_mat_GF2E(): r""" The \class{mat_GF2E} class implements arithmetic with matrices over $GF(2**x)$. """ diff --git a/src/sage/libs/ntl/ntl_mat_ZZ.pxd b/src/sage/libs/ntl/ntl_mat_ZZ.pxd index af3ada9e97a..f766e82c187 100644 --- a/src/sage/libs/ntl/ntl_mat_ZZ.pxd +++ b/src/sage/libs/ntl/ntl_mat_ZZ.pxd @@ -1,5 +1,5 @@ from .types cimport mat_ZZ_c -cdef class ntl_mat_ZZ(object): +cdef class ntl_mat_ZZ(): cdef mat_ZZ_c x cdef long __nrows, __ncols diff --git a/src/sage/libs/ntl/ntl_mat_ZZ.pyx b/src/sage/libs/ntl/ntl_mat_ZZ.pyx index c9f054602e8..6f7cc3da0b9 100644 --- a/src/sage/libs/ntl/ntl_mat_ZZ.pyx +++ b/src/sage/libs/ntl/ntl_mat_ZZ.pyx @@ -67,7 +67,7 @@ cdef inline ntl_mat_ZZ make_mat_ZZ_sig_off(mat_ZZ_c* x): # ############################################################################## -cdef class ntl_mat_ZZ(object): +cdef class ntl_mat_ZZ(): # see ntl_mat_ZZ.pxd for data members r""" The \class{mat_ZZ} class implements arithmetic with matrices over $\Z$. diff --git a/src/sage/libs/singular/function_factory.py b/src/sage/libs/singular/function_factory.py index c3ba54dd371..c4b0b52372f 100644 --- a/src/sage/libs/singular/function_factory.py +++ b/src/sage/libs/singular/function_factory.py @@ -15,7 +15,7 @@ from sage.libs.singular.function import singular_function, lib, list_of_functions -class SingularFunctionFactory(object): +class SingularFunctionFactory(): """ A convenient interface to libsingular functions. """ diff --git a/src/sage/libs/singular/ring.pyx b/src/sage/libs/singular/ring.pyx index d49cf529073..04bd16e8784 100644 --- a/src/sage/libs/singular/ring.pyx +++ b/src/sage/libs/singular/ring.pyx @@ -505,7 +505,7 @@ cdef ring *singular_ring_new(base_ring, n, names, term_order) except NULL: ring_refcount_dict = defaultdict(int) -cdef class ring_wrapper_Py(object): +cdef class ring_wrapper_Py(): r""" Python object wrapping the ring pointer. From 158a42cbe5ae9bc80b481d257d4d36f4a6d346bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 27 May 2022 15:11:38 +0200 Subject: [PATCH 486/529] fix-up wrong replacement --- src/sage/repl/interpreter.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/repl/interpreter.py b/src/sage/repl/interpreter.py index 2d48b2b4802..d7ba014361d 100644 --- a/src/sage/repl/interpreter.py +++ b/src/sage/repl/interpreter.py @@ -487,11 +487,11 @@ def __init__(self, *args, **kwds): def preparse_imports_from_sage(self, line): """ - Finds occurrences of strings such as ``sage()`` in + Finds occurrences of strings such as ``sage(object)`` in *line*, converts ``object`` to :attr:`shell.interface`, and replaces those strings with their identifier in the new system. This also works with strings such as - ``maxima()`` if :attr:`shell.interface` is + ``maxima(object)`` if :attr:`shell.interface` is ``maxima``. :param line: the line to transform From 4d9a20785295fcf1730a99ea81a39e50ce2d4b73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 27 May 2022 15:22:43 +0200 Subject: [PATCH 487/529] fix W391 in combinat --- src/sage/combinat/affine_permutation.py | 1 - src/sage/combinat/chas/__init__.py | 1 - src/sage/combinat/chas/all.py | 1 - src/sage/combinat/cluster_algebra_quiver/all.py | 1 - src/sage/combinat/composition_tableau.py | 1 - src/sage/combinat/crystals/affine_factorization.py | 1 - src/sage/combinat/crystals/affinization.py | 1 - src/sage/combinat/crystals/all.py | 1 - src/sage/combinat/crystals/bkk_crystals.py | 1 - src/sage/combinat/crystals/crystals.py | 1 - src/sage/combinat/crystals/direct_sum.py | 1 - src/sage/combinat/crystals/induced_structure.py | 1 - src/sage/combinat/crystals/infinity_crystals.py | 1 - src/sage/combinat/crystals/kyoto_path_model.py | 1 - src/sage/combinat/crystals/littelmann_path.py | 1 - src/sage/combinat/crystals/monomial_crystals.py | 1 - src/sage/combinat/crystals/multisegments.py | 1 - src/sage/combinat/crystals/mv_polytopes.py | 1 - src/sage/combinat/crystals/pbw_crystal.py | 1 - src/sage/combinat/crystals/polyhedral_realization.py | 1 - src/sage/combinat/crystals/star_crystal.py | 1 - src/sage/combinat/crystals/subcrystal.py | 1 - src/sage/combinat/crystals/virtual_crystal.py | 1 - src/sage/combinat/designs/__init__.py | 1 - src/sage/combinat/free_dendriform_algebra.py | 1 - src/sage/combinat/hall_polynomial.py | 1 - src/sage/combinat/integer_matrices.py | 1 - src/sage/combinat/lr_tableau.py | 1 - src/sage/combinat/matrices/all.py | 1 - src/sage/combinat/matrices/dlxcpp.py | 2 -- src/sage/combinat/misc.py | 1 - src/sage/combinat/multiset_partition_into_sets_ordered.py | 1 - src/sage/combinat/ncsf_qsym/__init__.py | 1 - src/sage/combinat/ncsf_qsym/all.py | 1 - src/sage/combinat/ncsf_qsym/combinatorics.py | 1 - src/sage/combinat/ncsf_qsym/generic_basis_code.py | 1 - src/sage/combinat/ncsym/ncsym.py | 1 - src/sage/combinat/output.py | 1 - src/sage/combinat/path_tableaux/__init__.py | 1 - src/sage/combinat/path_tableaux/dyck_path.py | 1 - src/sage/combinat/path_tableaux/path_tableau.py | 1 - src/sage/combinat/ribbon.py | 1 - src/sage/combinat/rigged_configurations/bij_abstract_class.py | 1 - src/sage/combinat/rigged_configurations/bij_infinity.py | 1 - src/sage/combinat/rigged_configurations/bij_type_A.py | 1 - src/sage/combinat/rigged_configurations/bij_type_A2_dual.py | 1 - src/sage/combinat/rigged_configurations/bij_type_A2_odd.py | 1 - src/sage/combinat/rigged_configurations/bij_type_B.py | 1 - src/sage/combinat/rigged_configurations/bij_type_D.py | 1 - src/sage/combinat/rigged_configurations/bij_type_D_tri.py | 1 - src/sage/combinat/rigged_configurations/bij_type_D_twisted.py | 1 - src/sage/combinat/rigged_configurations/bij_type_E67.py | 1 - src/sage/combinat/rigged_configurations/bijection.py | 1 - src/sage/combinat/rigged_configurations/kleber_tree.py | 1 - src/sage/combinat/rigged_configurations/kr_tableaux.py | 1 - .../rigged_configurations/rigged_configuration_element.py | 1 - .../rigged_configurations/tensor_product_kr_tableaux_element.py | 1 - src/sage/combinat/root_system/all.py | 1 - src/sage/combinat/root_system/ambient_space.py | 1 - src/sage/combinat/root_system/cartan_matrix.py | 1 - src/sage/combinat/root_system/coxeter_type.py | 1 - src/sage/combinat/root_system/integrable_representations.py | 1 - .../combinat/root_system/non_symmetric_macdonald_polynomials.py | 1 - src/sage/combinat/root_system/root_lattice_realizations.py | 1 - src/sage/combinat/root_system/type_B.py | 1 - src/sage/combinat/root_system/type_BC_affine.py | 1 - src/sage/combinat/root_system/type_B_affine.py | 1 - src/sage/combinat/root_system/type_C_affine.py | 1 - src/sage/combinat/root_system/type_D_affine.py | 1 - src/sage/combinat/root_system/type_F_affine.py | 1 - src/sage/combinat/root_system/type_G_affine.py | 1 - src/sage/combinat/root_system/type_H.py | 1 - src/sage/combinat/root_system/type_I.py | 1 - src/sage/combinat/root_system/type_dual.py | 1 - src/sage/combinat/root_system/type_folded.py | 1 - src/sage/combinat/sf/__init__.py | 1 - src/sage/combinat/sf/character.py | 1 - src/sage/combinat/sf/dual.py | 1 - src/sage/combinat/sf/k_dual.py | 1 - src/sage/combinat/sf/kfpoly.py | 1 - src/sage/combinat/sf/orthogonal.py | 1 - src/sage/combinat/sf/sf.py | 1 - src/sage/combinat/sf/symplectic.py | 1 - src/sage/combinat/sf/witt.py | 2 -- src/sage/combinat/shifted_primed_tableau.py | 1 - src/sage/combinat/six_vertex_model.py | 1 - src/sage/combinat/species/__init__.py | 1 - src/sage/combinat/species/generating_series.py | 1 - src/sage/combinat/symmetric_group_representations.py | 1 - src/sage/combinat/words/infinite_word.py | 1 - src/sage/combinat/words/morphic.py | 2 -- src/sage/combinat/words/word_infinite_datatypes.py | 1 - 92 files changed, 95 deletions(-) diff --git a/src/sage/combinat/affine_permutation.py b/src/sage/combinat/affine_permutation.py index 11b8a5feacb..b87167bb487 100644 --- a/src/sage/combinat/affine_permutation.py +++ b/src/sage/combinat/affine_permutation.py @@ -2403,4 +2403,3 @@ def one(self): return self([1,2,3,4,5,6]) Element = AffinePermutationTypeG - diff --git a/src/sage/combinat/chas/__init__.py b/src/sage/combinat/chas/__init__.py index 8b137891791..e69de29bb2d 100644 --- a/src/sage/combinat/chas/__init__.py +++ b/src/sage/combinat/chas/__init__.py @@ -1 +0,0 @@ - diff --git a/src/sage/combinat/chas/all.py b/src/sage/combinat/chas/all.py index 899155c0385..5833abbe49c 100644 --- a/src/sage/combinat/chas/all.py +++ b/src/sage/combinat/chas/all.py @@ -18,4 +18,3 @@ lazy_import('sage.combinat.chas.fsym', ['FreeSymmetricFunctions']) lazy_import('sage.combinat.chas.wqsym', ['WordQuasiSymmetricFunctions']) - diff --git a/src/sage/combinat/cluster_algebra_quiver/all.py b/src/sage/combinat/cluster_algebra_quiver/all.py index 61fec4fde04..40b86813ba0 100644 --- a/src/sage/combinat/cluster_algebra_quiver/all.py +++ b/src/sage/combinat/cluster_algebra_quiver/all.py @@ -15,4 +15,3 @@ lazy_import("sage.combinat.cluster_algebra_quiver.quiver_mutation_type", "QuiverMutationType") lazy_import("sage.combinat.cluster_algebra_quiver.quiver", "ClusterQuiver") lazy_import("sage.combinat.cluster_algebra_quiver.cluster_seed", "ClusterSeed") - diff --git a/src/sage/combinat/composition_tableau.py b/src/sage/combinat/composition_tableau.py index 53d22a50346..64c98d81bf5 100644 --- a/src/sage/combinat/composition_tableau.py +++ b/src/sage/combinat/composition_tableau.py @@ -859,4 +859,3 @@ def get_next_pos(self, ii, jj): return ii, j return ii+1, 0 - diff --git a/src/sage/combinat/crystals/affine_factorization.py b/src/sage/combinat/crystals/affine_factorization.py index 9dfda1c5b77..b88f1e3adb1 100644 --- a/src/sage/combinat/crystals/affine_factorization.py +++ b/src/sage/combinat/crystals/affine_factorization.py @@ -506,4 +506,3 @@ def is_isomorphism(self): is_embedding = is_isomorphism is_surjective = is_isomorphism - diff --git a/src/sage/combinat/crystals/affinization.py b/src/sage/combinat/crystals/affinization.py index fc79e6c3912..49ee74d1df5 100644 --- a/src/sage/combinat/crystals/affinization.py +++ b/src/sage/combinat/crystals/affinization.py @@ -324,4 +324,3 @@ def weight(self): WLR = self.parent().weight_lattice_realization() La = WLR.fundamental_weights() return WLR.sum(c*La[i] for i,c in self._b.weight()) + self._m * WLR.null_root() - diff --git a/src/sage/combinat/crystals/all.py b/src/sage/combinat/crystals/all.py index 23955e34465..397639405c9 100644 --- a/src/sage/combinat/crystals/all.py +++ b/src/sage/combinat/crystals/all.py @@ -28,4 +28,3 @@ from sage.misc.lazy_import import lazy_import lazy_import('sage.combinat.crystals', 'catalog', 'crystals') - diff --git a/src/sage/combinat/crystals/bkk_crystals.py b/src/sage/combinat/crystals/bkk_crystals.py index bf3c3eb369b..622fbb9e350 100644 --- a/src/sage/combinat/crystals/bkk_crystals.py +++ b/src/sage/combinat/crystals/bkk_crystals.py @@ -139,4 +139,3 @@ def genuine_highest_weight_vectors(self, index_set=None): class Element(CrystalOfBKKTableauxElement): pass - diff --git a/src/sage/combinat/crystals/crystals.py b/src/sage/combinat/crystals/crystals.py index 0b3fa3998df..8b965b79c09 100644 --- a/src/sage/combinat/crystals/crystals.py +++ b/src/sage/combinat/crystals/crystals.py @@ -253,4 +253,3 @@ def _rec(self, x, state): # yield y and all elements further below yield y, "n/a", True - diff --git a/src/sage/combinat/crystals/direct_sum.py b/src/sage/combinat/crystals/direct_sum.py index 90b02717ef4..84676264822 100644 --- a/src/sage/combinat/crystals/direct_sum.py +++ b/src/sage/combinat/crystals/direct_sum.py @@ -253,4 +253,3 @@ def epsilon(self, i): 0 """ return self.value[1].epsilon(i) - diff --git a/src/sage/combinat/crystals/induced_structure.py b/src/sage/combinat/crystals/induced_structure.py index 0cf36648bba..1e89220f3ea 100644 --- a/src/sage/combinat/crystals/induced_structure.py +++ b/src/sage/combinat/crystals/induced_structure.py @@ -686,4 +686,3 @@ def weight(self): (1, 0, 1, 0) """ return self.parent()._inverse(self.value).weight() - diff --git a/src/sage/combinat/crystals/infinity_crystals.py b/src/sage/combinat/crystals/infinity_crystals.py index 919242aa1b8..0edf826c73e 100644 --- a/src/sage/combinat/crystals/infinity_crystals.py +++ b/src/sage/combinat/crystals/infinity_crystals.py @@ -725,4 +725,3 @@ def _element_constructor_(self, *args, **options): class Element(InfinityQueerCrystalOfTableauxElement): pass - diff --git a/src/sage/combinat/crystals/kyoto_path_model.py b/src/sage/combinat/crystals/kyoto_path_model.py index 0b5ad79a32f..12d3af264a6 100644 --- a/src/sage/combinat/crystals/kyoto_path_model.py +++ b/src/sage/combinat/crystals/kyoto_path_model.py @@ -492,4 +492,3 @@ def truncate(self, k=None): i = len(l) % N l.append(self.parent()._phi_dicts[i][ l[-1].Epsilon() ]) return P(*l) - diff --git a/src/sage/combinat/crystals/littelmann_path.py b/src/sage/combinat/crystals/littelmann_path.py index 6f45611e85c..4cbce3cb920 100644 --- a/src/sage/combinat/crystals/littelmann_path.py +++ b/src/sage/combinat/crystals/littelmann_path.py @@ -1489,4 +1489,3 @@ def positively_parallel_weights(v, w): if v[i]*w[i] > 0 and v[i]*w == w[i]*v: return True return False - diff --git a/src/sage/combinat/crystals/monomial_crystals.py b/src/sage/combinat/crystals/monomial_crystals.py index 73c810bd594..43d71f16747 100644 --- a/src/sage/combinat/crystals/monomial_crystals.py +++ b/src/sage/combinat/crystals/monomial_crystals.py @@ -1255,4 +1255,3 @@ def cardinality(self): return super(InfinityCrystalOfNakajimaMonomials, self).cardinality() Element = CrystalOfNakajimaMonomialsElement - diff --git a/src/sage/combinat/crystals/multisegments.py b/src/sage/combinat/crystals/multisegments.py index 7db77030117..81b01f17fcc 100644 --- a/src/sage/combinat/crystals/multisegments.py +++ b/src/sage/combinat/crystals/multisegments.py @@ -451,4 +451,3 @@ def weight(self): n = self.parent()._cartan_type.rank() return WLR.sum(-1*alpha[j % n] for k,i in self.value for j in range(ZZ(i),ZZ(i)+k)) - diff --git a/src/sage/combinat/crystals/mv_polytopes.py b/src/sage/combinat/crystals/mv_polytopes.py index 25fdd16c3f3..4ff902a7b6b 100644 --- a/src/sage/combinat/crystals/mv_polytopes.py +++ b/src/sage/combinat/crystals/mv_polytopes.py @@ -461,4 +461,3 @@ def latex_options(self): return copy(self._latex_options) Element = MVPolytope - diff --git a/src/sage/combinat/crystals/pbw_crystal.py b/src/sage/combinat/crystals/pbw_crystal.py index 3143aa32a9d..1803b501f9e 100644 --- a/src/sage/combinat/crystals/pbw_crystal.py +++ b/src/sage/combinat/crystals/pbw_crystal.py @@ -506,4 +506,3 @@ def set_default_long_word(self, word): self._default_word = tuple(word) Element = PBWCrystalElement - diff --git a/src/sage/combinat/crystals/polyhedral_realization.py b/src/sage/combinat/crystals/polyhedral_realization.py index 4440dd2ac0a..2860eec417c 100644 --- a/src/sage/combinat/crystals/polyhedral_realization.py +++ b/src/sage/combinat/crystals/polyhedral_realization.py @@ -366,4 +366,3 @@ def truncate(self, k=None): i = len(l) % N l.append(self.parent()._tp[i]) return P(*l) - diff --git a/src/sage/combinat/crystals/star_crystal.py b/src/sage/combinat/crystals/star_crystal.py index 2ed01c49422..1434eac09eb 100644 --- a/src/sage/combinat/crystals/star_crystal.py +++ b/src/sage/combinat/crystals/star_crystal.py @@ -286,4 +286,3 @@ def jump(self, i): P = self.parent().weight_lattice_realization() ac = P.simple_coroot(i) return P(self.value.weight()).scalar(ac) + self.epsilon(i) + self.value.epsilon(i) - diff --git a/src/sage/combinat/crystals/subcrystal.py b/src/sage/combinat/crystals/subcrystal.py index 81af397e59e..9881a021e27 100644 --- a/src/sage/combinat/crystals/subcrystal.py +++ b/src/sage/combinat/crystals/subcrystal.py @@ -457,4 +457,3 @@ def weight(self): (0, 1, 0, 1, 1) """ return self.value.weight() - diff --git a/src/sage/combinat/crystals/virtual_crystal.py b/src/sage/combinat/crystals/virtual_crystal.py index 81088735b4f..8cdcf92f57d 100644 --- a/src/sage/combinat/crystals/virtual_crystal.py +++ b/src/sage/combinat/crystals/virtual_crystal.py @@ -415,4 +415,3 @@ def weight(self): for i in self.index_set()) # TODO: implement a devirtualization map - diff --git a/src/sage/combinat/designs/__init__.py b/src/sage/combinat/designs/__init__.py index 8b137891791..e69de29bb2d 100644 --- a/src/sage/combinat/designs/__init__.py +++ b/src/sage/combinat/designs/__init__.py @@ -1 +0,0 @@ - diff --git a/src/sage/combinat/free_dendriform_algebra.py b/src/sage/combinat/free_dendriform_algebra.py index 32709cfaf7c..ffac8fd2452 100644 --- a/src/sage/combinat/free_dendriform_algebra.py +++ b/src/sage/combinat/free_dendriform_algebra.py @@ -936,4 +936,3 @@ def _repr_(self): Dendriform[x,y,z,t] """ return "Dendriform[%s]" % ','.join(self.vars) - diff --git a/src/sage/combinat/hall_polynomial.py b/src/sage/combinat/hall_polynomial.py index cd540de429c..19d65bc2263 100644 --- a/src/sage/combinat/hall_polynomial.py +++ b/src/sage/combinat/hall_polynomial.py @@ -184,4 +184,3 @@ def hall_polynomial(nu, mu, la, q=None): from sage.algebras.hall_algebra import HallAlgebra H = HallAlgebra(R, q) return (H[mu]*H[la]).coefficient(nu) - diff --git a/src/sage/combinat/integer_matrices.py b/src/sage/combinat/integer_matrices.py index 6b48ca6c336..44d42ce39b1 100644 --- a/src/sage/combinat/integer_matrices.py +++ b/src/sage/combinat/integer_matrices.py @@ -333,4 +333,3 @@ def integer_matrices_generator(row_sums, column_sums): t = [column_sums[i]-ci for (i, ci) in enumerate(comp)] for mat in integer_matrices_generator(row_sums[1:], t): yield [list(comp)] + mat - diff --git a/src/sage/combinat/lr_tableau.py b/src/sage/combinat/lr_tableau.py index 3348c97e7d1..3a24b1007d3 100644 --- a/src/sage/combinat/lr_tableau.py +++ b/src/sage/combinat/lr_tableau.py @@ -304,4 +304,3 @@ def _tableau_join(t1, t2, shift=0): """ return [[e1 for e1 in row1] + [e2+shift for e2 in row2 if e2 is not None] for (row1, row2) in zip_longest(t1, t2, fillvalue=[])] - diff --git a/src/sage/combinat/matrices/all.py b/src/sage/combinat/matrices/all.py index baa34da139a..0f6adbb5355 100644 --- a/src/sage/combinat/matrices/all.py +++ b/src/sage/combinat/matrices/all.py @@ -17,4 +17,3 @@ lazy_import('sage.combinat.matrices.dlxcpp', 'DLXCPP') lazy_import('sage.combinat.matrices.hadamard_matrix', ['hadamard_matrix', 'hadamard_matrix_www']) - diff --git a/src/sage/combinat/matrices/dlxcpp.py b/src/sage/combinat/matrices/dlxcpp.py index 7a5b153b759..4e12b98e325 100644 --- a/src/sage/combinat/matrices/dlxcpp.py +++ b/src/sage/combinat/matrices/dlxcpp.py @@ -129,5 +129,3 @@ def OneExactCover(M): for s in AllExactCovers(M): return s - - diff --git a/src/sage/combinat/misc.py b/src/sage/combinat/misc.py index abcd7871932..d29b31a101f 100644 --- a/src/sage/combinat/misc.py +++ b/src/sage/combinat/misc.py @@ -399,4 +399,3 @@ def check_integer_list_constraints(l, **kwargs): return None else: return result - diff --git a/src/sage/combinat/multiset_partition_into_sets_ordered.py b/src/sage/combinat/multiset_partition_into_sets_ordered.py index 77a06dc4134..8963ab00f0d 100755 --- a/src/sage/combinat/multiset_partition_into_sets_ordered.py +++ b/src/sage/combinat/multiset_partition_into_sets_ordered.py @@ -3508,4 +3508,3 @@ def f(self,i): return None w = w.f(i) return P.element_class(P, (w, breaks)) - diff --git a/src/sage/combinat/ncsf_qsym/__init__.py b/src/sage/combinat/ncsf_qsym/__init__.py index 8b137891791..e69de29bb2d 100644 --- a/src/sage/combinat/ncsf_qsym/__init__.py +++ b/src/sage/combinat/ncsf_qsym/__init__.py @@ -1 +0,0 @@ - diff --git a/src/sage/combinat/ncsf_qsym/all.py b/src/sage/combinat/ncsf_qsym/all.py index 212da647869..db6cb1f065e 100644 --- a/src/sage/combinat/ncsf_qsym/all.py +++ b/src/sage/combinat/ncsf_qsym/all.py @@ -14,4 +14,3 @@ from .qsym import QuasiSymmetricFunctions from .ncsf import NonCommutativeSymmetricFunctions - diff --git a/src/sage/combinat/ncsf_qsym/combinatorics.py b/src/sage/combinat/ncsf_qsym/combinatorics.py index 6688b4640ff..a0f8825ae3e 100644 --- a/src/sage/combinat/ncsf_qsym/combinatorics.py +++ b/src/sage/combinat/ncsf_qsym/combinatorics.py @@ -323,4 +323,3 @@ def number_of_SSRCT(content_comp, shape_comp): if cond([shape_comp[0]]+list(x), shape_comp): s += number_of_SSRCT(Comps(content_comp[1:]), x) return s - diff --git a/src/sage/combinat/ncsf_qsym/generic_basis_code.py b/src/sage/combinat/ncsf_qsym/generic_basis_code.py index d10de45aebc..3457b4cdd03 100644 --- a/src/sage/combinat/ncsf_qsym/generic_basis_code.py +++ b/src/sage/combinat/ncsf_qsym/generic_basis_code.py @@ -1432,4 +1432,3 @@ def internal_product_by_coercion(self, left, right): """ R = self.realization_of().a_realization() return self(R.internal_product(R(left), R(right))) - diff --git a/src/sage/combinat/ncsym/ncsym.py b/src/sage/combinat/ncsym/ncsym.py index 4df1db47990..6acf7dbc1c0 100644 --- a/src/sage/combinat/ncsym/ncsym.py +++ b/src/sage/combinat/ncsym/ncsym.py @@ -2109,4 +2109,3 @@ def _m_to_chi_on_basis(self, A): return self._from_dict({B: m[j,i] for j,B in enumerate(lst)}) chi = supercharacter - diff --git a/src/sage/combinat/output.py b/src/sage/combinat/output.py index 95b5cd0c046..d153149c48b 100644 --- a/src/sage/combinat/output.py +++ b/src/sage/combinat/output.py @@ -506,4 +506,3 @@ def get_len(e): return output.translate(tr) else: return output - diff --git a/src/sage/combinat/path_tableaux/__init__.py b/src/sage/combinat/path_tableaux/__init__.py index 8b137891791..e69de29bb2d 100644 --- a/src/sage/combinat/path_tableaux/__init__.py +++ b/src/sage/combinat/path_tableaux/__init__.py @@ -1 +0,0 @@ - diff --git a/src/sage/combinat/path_tableaux/dyck_path.py b/src/sage/combinat/path_tableaux/dyck_path.py index 50dbebe2839..26501ec6cc7 100644 --- a/src/sage/combinat/path_tableaux/dyck_path.py +++ b/src/sage/combinat/path_tableaux/dyck_path.py @@ -375,4 +375,3 @@ def _an_element_(self): return DyckPath([0,1,2,1,0]) Element = DyckPath - diff --git a/src/sage/combinat/path_tableaux/path_tableau.py b/src/sage/combinat/path_tableaux/path_tableau.py index 691882350c2..611f9d31310 100644 --- a/src/sage/combinat/path_tableaux/path_tableau.py +++ b/src/sage/combinat/path_tableaux/path_tableau.py @@ -722,4 +722,3 @@ def pp(self): max_width = max(max(len(x) for x in row) for row in data if row) print('\n'.join(' '.join(' '*(max_width-len(x)) + x for x in row) for row in data)) - diff --git a/src/sage/combinat/ribbon.py b/src/sage/combinat/ribbon.py index 64f06fc801d..6c662f505c7 100644 --- a/src/sage/combinat/ribbon.py +++ b/src/sage/combinat/ribbon.py @@ -17,4 +17,3 @@ #***************************************************************************** from .ribbon_shaped_tableau import RibbonShapedTableau, StandardRibbonShapedTableaux - diff --git a/src/sage/combinat/rigged_configurations/bij_abstract_class.py b/src/sage/combinat/rigged_configurations/bij_abstract_class.py index 89c82a8224b..8e6042a2663 100644 --- a/src/sage/combinat/rigged_configurations/bij_abstract_class.py +++ b/src/sage/combinat/rigged_configurations/bij_abstract_class.py @@ -542,4 +542,3 @@ def _next_index(self, r): 1 """ return r - 1 - diff --git a/src/sage/combinat/rigged_configurations/bij_infinity.py b/src/sage/combinat/rigged_configurations/bij_infinity.py index 7717c8691a2..4c675135019 100644 --- a/src/sage/combinat/rigged_configurations/bij_infinity.py +++ b/src/sage/combinat/rigged_configurations/bij_infinity.py @@ -359,4 +359,3 @@ def run(self): self.cur_dims.pop(0) # Pop off the leading column return ret_crystal_path - diff --git a/src/sage/combinat/rigged_configurations/bij_type_A.py b/src/sage/combinat/rigged_configurations/bij_type_A.py index 78de0dfa555..0a7070297db 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_A.py +++ b/src/sage/combinat/rigged_configurations/bij_type_A.py @@ -157,4 +157,3 @@ def next_state(self, height): self.cur_partitions[n - 1].rigging[row_num] = self.cur_partitions[n - 1].vacancy_numbers[row_num] return(b) - diff --git a/src/sage/combinat/rigged_configurations/bij_type_A2_dual.py b/src/sage/combinat/rigged_configurations/bij_type_A2_dual.py index 57a17f31e83..8f41efa6474 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_A2_dual.py +++ b/src/sage/combinat/rigged_configurations/bij_type_A2_dual.py @@ -332,4 +332,3 @@ def next_state(self, height): self.cur_partitions[n-1].rigging[row_num_bar_next] = self.cur_partitions[n-1].vacancy_numbers[row_num_bar_next] return(b) - diff --git a/src/sage/combinat/rigged_configurations/bij_type_A2_odd.py b/src/sage/combinat/rigged_configurations/bij_type_A2_odd.py index 34707d7b424..753c2a99c74 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_A2_odd.py +++ b/src/sage/combinat/rigged_configurations/bij_type_A2_odd.py @@ -193,4 +193,3 @@ def next_state(self, height): self.cur_partitions[n-1].rigging[ret_row_next] = self.cur_partitions[n-1].vacancy_numbers[ret_row_next] return(b) - diff --git a/src/sage/combinat/rigged_configurations/bij_type_B.py b/src/sage/combinat/rigged_configurations/bij_type_B.py index eef6dede629..05b6f56f6c9 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_B.py +++ b/src/sage/combinat/rigged_configurations/bij_type_B.py @@ -892,4 +892,3 @@ def next_state(self, height): self.cur_partitions[n-1].rigging[j-1] = vac_num - 1 return(b) - diff --git a/src/sage/combinat/rigged_configurations/bij_type_D.py b/src/sage/combinat/rigged_configurations/bij_type_D.py index 8cdd0d33edb..48ad54873ab 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_D.py +++ b/src/sage/combinat/rigged_configurations/bij_type_D.py @@ -766,4 +766,3 @@ def _correct_vacancy_nums(self): n = self.n for i in range(len(self.cur_partitions[n-1]._list)): self.cur_partitions[n-1].vacancy_numbers[i] += 1 - diff --git a/src/sage/combinat/rigged_configurations/bij_type_D_tri.py b/src/sage/combinat/rigged_configurations/bij_type_D_tri.py index dda29c33373..55159ab4f48 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_D_tri.py +++ b/src/sage/combinat/rigged_configurations/bij_type_D_tri.py @@ -384,4 +384,3 @@ def next_state(self, height): P.rigging[j-1] = vac_num - 1 return(b) - diff --git a/src/sage/combinat/rigged_configurations/bij_type_D_twisted.py b/src/sage/combinat/rigged_configurations/bij_type_D_twisted.py index 96e32e0664e..78ba3d4a071 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_D_twisted.py +++ b/src/sage/combinat/rigged_configurations/bij_type_D_twisted.py @@ -568,4 +568,3 @@ def next_state(self, height): self.cur_partitions[n-1].rigging[row_num_bar_next] = self.cur_partitions[n-1].vacancy_numbers[row_num_bar_next] return(b) - diff --git a/src/sage/combinat/rigged_configurations/bij_type_E67.py b/src/sage/combinat/rigged_configurations/bij_type_E67.py index d9d635540e6..c0ebd5735cb 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_E67.py +++ b/src/sage/combinat/rigged_configurations/bij_type_E67.py @@ -392,4 +392,3 @@ def endpoint7(r): return C((-7, 6)) elif r == 7: return C.module_generators[0] # C((7,)) - diff --git a/src/sage/combinat/rigged_configurations/bijection.py b/src/sage/combinat/rigged_configurations/bijection.py index 3815407c980..56fcbb98394 100644 --- a/src/sage/combinat/rigged_configurations/bijection.py +++ b/src/sage/combinat/rigged_configurations/bijection.py @@ -137,4 +137,3 @@ def RCToKRTBijection(rigged_configuration_elt): if typ == 'G': # D_4^{(3)} return RCToKRTBijectionTypeDTri(rigged_configuration_elt) raise NotImplementedError - diff --git a/src/sage/combinat/rigged_configurations/kleber_tree.py b/src/sage/combinat/rigged_configurations/kleber_tree.py index 4d9c040c834..df5db0f5fe8 100644 --- a/src/sage/combinat/rigged_configurations/kleber_tree.py +++ b/src/sage/combinat/rigged_configurations/kleber_tree.py @@ -1470,4 +1470,3 @@ def depth_first_iter(self, all_nodes=False): Kleber tree node with weight [0, 0, 0] and upwards edge root [1, 2, 1] """ return KleberTree.depth_first_iter(self) - diff --git a/src/sage/combinat/rigged_configurations/kr_tableaux.py b/src/sage/combinat/rigged_configurations/kr_tableaux.py index 821389b7d83..5c79e0807ef 100644 --- a/src/sage/combinat/rigged_configurations/kr_tableaux.py +++ b/src/sage/combinat/rigged_configurations/kr_tableaux.py @@ -1876,4 +1876,3 @@ def _tableau_height(self): return len(self.module_generators[0]) // self._s Element = KRTableauxTypeFromRCElement - diff --git a/src/sage/combinat/rigged_configurations/rigged_configuration_element.py b/src/sage/combinat/rigged_configurations/rigged_configuration_element.py index 6c3c897a1b4..4ef6be9811c 100644 --- a/src/sage/combinat/rigged_configurations/rigged_configuration_element.py +++ b/src/sage/combinat/rigged_configurations/rigged_configuration_element.py @@ -2406,4 +2406,3 @@ def cocharge(self): return cc / ZZ(2) + rigging_sum cc = cocharge - diff --git a/src/sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py b/src/sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py index 7658ddd0d28..87e8d0c97d0 100644 --- a/src/sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py +++ b/src/sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element.py @@ -424,4 +424,3 @@ def to_tensor_product_of_kirillov_reshetikhin_crystals(self): """ TP = self.parent().tensor_product_of_kirillov_reshetikhin_crystals() return TP(*[x.to_kirillov_reshetikhin_crystal() for x in self]) - diff --git a/src/sage/combinat/root_system/all.py b/src/sage/combinat/root_system/all.py index 622eb87b309..e49d72ea222 100644 --- a/src/sage/combinat/root_system/all.py +++ b/src/sage/combinat/root_system/all.py @@ -141,4 +141,3 @@ lazy_import('sage.combinat.root_system.non_symmetric_macdonald_polynomials', 'NonSymmetricMacdonaldPolynomials') lazy_import('sage.combinat.root_system.integrable_representations', 'IntegrableRepresentation') - diff --git a/src/sage/combinat/root_system/ambient_space.py b/src/sage/combinat/root_system/ambient_space.py index c55646e94ce..b1499f4eb4d 100644 --- a/src/sage/combinat/root_system/ambient_space.py +++ b/src/sage/combinat/root_system/ambient_space.py @@ -507,4 +507,3 @@ def to_ambient(self): return self AmbientSpace.Element = AmbientSpaceElement - diff --git a/src/sage/combinat/root_system/cartan_matrix.py b/src/sage/combinat/root_system/cartan_matrix.py index ed56efa197c..8030a093066 100644 --- a/src/sage/combinat/root_system/cartan_matrix.py +++ b/src/sage/combinat/root_system/cartan_matrix.py @@ -1164,4 +1164,3 @@ def find_cartan_type_from_matrix(CM): return None return CartanType(types) - diff --git a/src/sage/combinat/root_system/coxeter_type.py b/src/sage/combinat/root_system/coxeter_type.py index 5130d33ad8f..a8062d15c2f 100644 --- a/src/sage/combinat/root_system/coxeter_type.py +++ b/src/sage/combinat/root_system/coxeter_type.py @@ -669,4 +669,3 @@ def relabel(self, relabelling): Coxeter type of ['A', 2] relabelled by {1: -1, 2: -2} """ return CoxeterType(self._cartan_type.relabel(relabelling)) - diff --git a/src/sage/combinat/root_system/integrable_representations.py b/src/sage/combinat/root_system/integrable_representations.py index 691718b46da..edb6565ab09 100644 --- a/src/sage/combinat/root_system/integrable_representations.py +++ b/src/sage/combinat/root_system/integrable_representations.py @@ -1219,4 +1219,3 @@ def next_level(x): ldict[contr] = x[1] ret.append(weyl_character_ring.char_from_weights(ldict)) return ret - diff --git a/src/sage/combinat/root_system/non_symmetric_macdonald_polynomials.py b/src/sage/combinat/root_system/non_symmetric_macdonald_polynomials.py index cbece412f13..de8091654a3 100644 --- a/src/sage/combinat/root_system/non_symmetric_macdonald_polynomials.py +++ b/src/sage/combinat/root_system/non_symmetric_macdonald_polynomials.py @@ -1817,4 +1817,3 @@ def symmetric_macdonald_polynomial(self, mu): Torbit[c] = v * self._T.Tw([i])(Torbit[c.simple_reflection(i)]) s = s + Torbit[c] return s - diff --git a/src/sage/combinat/root_system/root_lattice_realizations.py b/src/sage/combinat/root_system/root_lattice_realizations.py index 1cd87355792..766b7932cdb 100644 --- a/src/sage/combinat/root_system/root_lattice_realizations.py +++ b/src/sage/combinat/root_system/root_lattice_realizations.py @@ -4514,4 +4514,3 @@ def is_real_root(self): False """ return self.norm_squared() > 0 - diff --git a/src/sage/combinat/root_system/type_B.py b/src/sage/combinat/root_system/type_B.py index 23a6f993665..036d9778b2f 100644 --- a/src/sage/combinat/root_system/type_B.py +++ b/src/sage/combinat/root_system/type_B.py @@ -341,4 +341,3 @@ def _default_folded_cartan_type(self): # For unpickling backward compatibility (Sage <= 4.1) from sage.misc.persist import register_unpickle_override register_unpickle_override('sage.combinat.root_system.type_B', 'ambient_space', AmbientSpace) - diff --git a/src/sage/combinat/root_system/type_BC_affine.py b/src/sage/combinat/root_system/type_BC_affine.py index 8665d908c6e..c3e0640617b 100644 --- a/src/sage/combinat/root_system/type_BC_affine.py +++ b/src/sage/combinat/root_system/type_BC_affine.py @@ -282,4 +282,3 @@ def _default_folded_cartan_type(self): n = self.n return CartanTypeFolded(self, ['A', 2*n - 1, 1], [[0]] + [[i, 2*n-i] for i in range(1, n)] + [[n]]) - diff --git a/src/sage/combinat/root_system/type_B_affine.py b/src/sage/combinat/root_system/type_B_affine.py index f818660ec4e..3e356e8cfe8 100644 --- a/src/sage/combinat/root_system/type_B_affine.py +++ b/src/sage/combinat/root_system/type_B_affine.py @@ -210,4 +210,3 @@ def _default_folded_cartan_type(self): return CartanTypeFolded(self, ['A', 1, 1], [[0], [1]]) return CartanTypeFolded(self, ['D', n + 1, 1], [[i] for i in range(n)] + [[n, n+1]]) - diff --git a/src/sage/combinat/root_system/type_C_affine.py b/src/sage/combinat/root_system/type_C_affine.py index 58d90c5961e..087a73029e5 100644 --- a/src/sage/combinat/root_system/type_C_affine.py +++ b/src/sage/combinat/root_system/type_C_affine.py @@ -181,4 +181,3 @@ def _default_folded_cartan_type(self): return CartanTypeFolded(self, ['A', 1, 1], [[0], [1]]) return CartanTypeFolded(self, ['A', 2*n-1, 1], [[0]] + [[i, 2*n-i] for i in range(1, n)] + [[n]]) - diff --git a/src/sage/combinat/root_system/type_D_affine.py b/src/sage/combinat/root_system/type_D_affine.py index 03f45ab1fda..76d086f0a91 100644 --- a/src/sage/combinat/root_system/type_D_affine.py +++ b/src/sage/combinat/root_system/type_D_affine.py @@ -202,4 +202,3 @@ def ascii_art(self, label=lambda i: i, node=None): ret += "---".join(node(label(i)) for i in range(1, n)) ret += '\n' + "".join("{!s:4}".format(label(i)) for i in range(1,n)) return ret - diff --git a/src/sage/combinat/root_system/type_F_affine.py b/src/sage/combinat/root_system/type_F_affine.py index edb6a4ac3ad..5a4aeb7d5f7 100644 --- a/src/sage/combinat/root_system/type_F_affine.py +++ b/src/sage/combinat/root_system/type_F_affine.py @@ -129,4 +129,3 @@ def _default_folded_cartan_type(self): """ from sage.combinat.root_system.type_folded import CartanTypeFolded return CartanTypeFolded(self, ['E', 6, 1], [[0], [2], [4], [3, 5], [1, 6]]) - diff --git a/src/sage/combinat/root_system/type_G_affine.py b/src/sage/combinat/root_system/type_G_affine.py index b503edd34a7..b0043e7370d 100644 --- a/src/sage/combinat/root_system/type_G_affine.py +++ b/src/sage/combinat/root_system/type_G_affine.py @@ -124,4 +124,3 @@ def _default_folded_cartan_type(self): """ from sage.combinat.root_system.type_folded import CartanTypeFolded return CartanTypeFolded(self, ['D', 4, 1], [[0], [1, 3, 4], [2]]) - diff --git a/src/sage/combinat/root_system/type_H.py b/src/sage/combinat/root_system/type_H.py index 776a92c7ebb..f6989013971 100644 --- a/src/sage/combinat/root_system/type_H.py +++ b/src/sage/combinat/root_system/type_H.py @@ -100,4 +100,3 @@ def coxeter_number(self): if self.n == 3: return 10 return 30 - diff --git a/src/sage/combinat/root_system/type_I.py b/src/sage/combinat/root_system/type_I.py index 617782f06cb..8bb3f1f6895 100644 --- a/src/sage/combinat/root_system/type_I.py +++ b/src/sage/combinat/root_system/type_I.py @@ -105,4 +105,3 @@ def coxeter_number(self): 12 """ return self.n - diff --git a/src/sage/combinat/root_system/type_dual.py b/src/sage/combinat/root_system/type_dual.py index 2d472435dd8..2fc8de77a1e 100644 --- a/src/sage/combinat/root_system/type_dual.py +++ b/src/sage/combinat/root_system/type_dual.py @@ -692,4 +692,3 @@ def _default_folded_cartan_type(self): if letter == 'G': # D_4^{(3)} return CartanTypeFolded(self, ['D', 4, 1], [[0], [1, 3, 4], [2]]) return super(CartanType, self)._default_folded_cartan_type() - diff --git a/src/sage/combinat/root_system/type_folded.py b/src/sage/combinat/root_system/type_folded.py index 93891fc941a..9482ec494c4 100644 --- a/src/sage/combinat/root_system/type_folded.py +++ b/src/sage/combinat/root_system/type_folded.py @@ -296,4 +296,3 @@ def f(i): cmax = max(c) return Family(dict( (i, int(cmax / c[i])) for i in self._cartan_type.index_set() )) - diff --git a/src/sage/combinat/sf/__init__.py b/src/sage/combinat/sf/__init__.py index 8b137891791..e69de29bb2d 100644 --- a/src/sage/combinat/sf/__init__.py +++ b/src/sage/combinat/sf/__init__.py @@ -1 +0,0 @@ - diff --git a/src/sage/combinat/sf/character.py b/src/sage/combinat/sf/character.py index ef899203813..e55f356f5d1 100644 --- a/src/sage/combinat/sf/character.py +++ b/src/sage/combinat/sf/character.py @@ -594,4 +594,3 @@ def _self_to_other_on_basis(self, lam): 3*s[1] - 2*s[1, 1] - 2*s[2] + s[2, 1] """ return self._other(self._self_to_power_on_basis(lam)) - diff --git a/src/sage/combinat/sf/dual.py b/src/sage/combinat/sf/dual.py index d801ccd3a18..677a8dcfd3f 100644 --- a/src/sage/combinat/sf/dual.py +++ b/src/sage/combinat/sf/dual.py @@ -893,4 +893,3 @@ def expand(self, n, alphabet='x'): # Backward compatibility for unpickling from sage.misc.persist import register_unpickle_override register_unpickle_override('sage.combinat.sf.dual', 'SymmetricFunctionAlgebraElement_dual', SymmetricFunctionAlgebra_dual.Element) - diff --git a/src/sage/combinat/sf/k_dual.py b/src/sage/combinat/sf/k_dual.py index 8f910a796fb..7b557b25104 100644 --- a/src/sage/combinat/sf/k_dual.py +++ b/src/sage/combinat/sf/k_dual.py @@ -1467,4 +1467,3 @@ def _m_to_F_on_basis(self, la): h = kB.khomogeneous() ks = kB.kschur() return sum( h(ks(x)).coefficient(la) * self(x) for x in PartitionsGreatestLE(sum(la), self.k)) - diff --git a/src/sage/combinat/sf/kfpoly.py b/src/sage/combinat/sf/kfpoly.py index e4a92ad2663..cf465b3e8c4 100644 --- a/src/sage/combinat/sf/kfpoly.py +++ b/src/sage/combinat/sf/kfpoly.py @@ -393,4 +393,3 @@ def weight(rg, t=None): mu = nu[k-1][i] - mid[i] res *= t**int(mu * (mu-1) // 2) return res - diff --git a/src/sage/combinat/sf/orthogonal.py b/src/sage/combinat/sf/orthogonal.py index 336ddb7c198..b0ed060ee85 100644 --- a/src/sage/combinat/sf/orthogonal.py +++ b/src/sage/combinat/sf/orthogonal.py @@ -242,4 +242,3 @@ def _s_to_o_on_basis(self, lam): for nu in Partitions(j) ) for j in range(n//2+1) # // 2 for horizontal dominoes for mu in Partitions(n-2*j) }) - diff --git a/src/sage/combinat/sf/sf.py b/src/sage/combinat/sf/sf.py index eff9d392605..b4418a40606 100644 --- a/src/sage/combinat/sf/sf.py +++ b/src/sage/combinat/sf/sf.py @@ -1613,4 +1613,3 @@ def __call__(self, partition): # will have an optional optimization for the case when there # is no repetition in the support return self._codomain._from_dict(dict(self._t(self.fake_sym.monomial(partition))), coerce = True) - diff --git a/src/sage/combinat/sf/symplectic.py b/src/sage/combinat/sf/symplectic.py index be615f2ddcb..bd5a44bd615 100644 --- a/src/sage/combinat/sf/symplectic.py +++ b/src/sage/combinat/sf/symplectic.py @@ -249,4 +249,3 @@ def _s_to_sp_on_basis(self, lam): for nu in Partitions(j) ) for j in range(n//2+1) # // 2 for vertical dominoes for mu in Partitions(n-2*j) }) - diff --git a/src/sage/combinat/sf/witt.py b/src/sage/combinat/sf/witt.py index fbc7979936b..58da090aec1 100644 --- a/src/sage/combinat/sf/witt.py +++ b/src/sage/combinat/sf/witt.py @@ -1334,5 +1334,3 @@ def verschiebung(self, n): if all( i % n == 0 for i in lam )} result_in_w_basis = parent._from_dict(dct) return parent(result_in_w_basis) - - diff --git a/src/sage/combinat/shifted_primed_tableau.py b/src/sage/combinat/shifted_primed_tableau.py index 5b8eb900ece..fbd5ab6c173 100644 --- a/src/sage/combinat/shifted_primed_tableau.py +++ b/src/sage/combinat/shifted_primed_tableau.py @@ -2727,4 +2727,3 @@ def _add_strip(sub_tab, full_tab, length): k=len(plat_list), outer=plat_list): yield list(primed_strip) + list(non_primed_strip) - diff --git a/src/sage/combinat/six_vertex_model.py b/src/sage/combinat/six_vertex_model.py index a310a84cb4b..936a7e95b52 100644 --- a/src/sage/combinat/six_vertex_model.py +++ b/src/sage/combinat/six_vertex_model.py @@ -776,4 +776,3 @@ def to_alternating_sign_matrix(self): #ASM = AlternatingSignMatrices(self.parent()._nrows) #return ASM(self.to_signed_matrix()) return AlternatingSignMatrix(self.to_signed_matrix()) - diff --git a/src/sage/combinat/species/__init__.py b/src/sage/combinat/species/__init__.py index 8b137891791..e69de29bb2d 100644 --- a/src/sage/combinat/species/__init__.py +++ b/src/sage/combinat/species/__init__.py @@ -1 +0,0 @@ - diff --git a/src/sage/combinat/species/generating_series.py b/src/sage/combinat/species/generating_series.py index 298bcd8ca94..02e1bb52332 100644 --- a/src/sage/combinat/species/generating_series.py +++ b/src/sage/combinat/species/generating_series.py @@ -1364,4 +1364,3 @@ def LogarithmCycleIndexSeries(R = RationalField()): """ CIS = CycleIndexSeriesRing(R) return CIS(_cl_gen(R)) - diff --git a/src/sage/combinat/symmetric_group_representations.py b/src/sage/combinat/symmetric_group_representations.py index b7f93ba5733..a27cd240733 100644 --- a/src/sage/combinat/symmetric_group_representations.py +++ b/src/sage/combinat/symmetric_group_representations.py @@ -1011,4 +1011,3 @@ def partition_to_vector_of_contents(partition, reverse=False): if reverse: return tuple(v)[::-1] return tuple(v) - diff --git a/src/sage/combinat/words/infinite_word.py b/src/sage/combinat/words/infinite_word.py index db8f15d577e..8baae7c1c3c 100644 --- a/src/sage/combinat/words/infinite_word.py +++ b/src/sage/combinat/words/infinite_word.py @@ -110,4 +110,3 @@ def length(self): +Infinity """ return Infinity - diff --git a/src/sage/combinat/words/morphic.py b/src/sage/combinat/words/morphic.py index 1e1c8d7847c..f84a90f6bb5 100644 --- a/src/sage/combinat/words/morphic.py +++ b/src/sage/combinat/words/morphic.py @@ -360,5 +360,3 @@ def __iter__(self): w = chain([next_w], w, self._morphism.image(next_w)) except StopIteration: return - - diff --git a/src/sage/combinat/words/word_infinite_datatypes.py b/src/sage/combinat/words/word_infinite_datatypes.py index 95664b687af..07ad69bebf0 100644 --- a/src/sage/combinat/words/word_infinite_datatypes.py +++ b/src/sage/combinat/words/word_infinite_datatypes.py @@ -1214,4 +1214,3 @@ def flush(self): self._gen = iter(self) self._list = [] self._last_index = -1 - From 4cb1b7efa9e04b4cfdfc8d02632e74bcf6914088 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 27 May 2022 15:26:28 +0200 Subject: [PATCH 488/529] fix W2 (trailing whitespaces) in combinat --- src/sage/combinat/crystals/virtual_crystal.py | 2 +- src/sage/combinat/finite_state_machine.py | 6 ++-- src/sage/combinat/recognizable_series.py | 2 +- .../bij_abstract_class.py | 2 +- .../rigged_configurations/bij_type_A2_even.py | 2 +- .../rigged_configurations/bij_type_B.py | 4 +-- .../rigged_configurations/bij_type_D.py | 2 +- src/sage/combinat/root_system/fusion_ring.py | 20 +++++------ .../root_system/integrable_representations.py | 36 +++++++++---------- src/sage/combinat/root_system/type_dual.py | 4 +-- src/sage/combinat/sf/macdonald.py | 4 +-- 11 files changed, 42 insertions(+), 42 deletions(-) diff --git a/src/sage/combinat/crystals/virtual_crystal.py b/src/sage/combinat/crystals/virtual_crystal.py index 8cdcf92f57d..a537a64bfb8 100644 --- a/src/sage/combinat/crystals/virtual_crystal.py +++ b/src/sage/combinat/crystals/virtual_crystal.py @@ -198,7 +198,7 @@ def __classcall_private__(cls, ambient, virtualization, scaling_factors, return super(Subcrystal, cls).__classcall__(cls, ambient, virtualization, scaling_factors, contained, tuple(generators), cartan_type, tuple(index_set), category) - + def __init__(self, ambient, virtualization, scaling_factors, contained, generators, cartan_type, index_set, category): """ diff --git a/src/sage/combinat/finite_state_machine.py b/src/sage/combinat/finite_state_machine.py index f52a0f129d6..3538146f22e 100644 --- a/src/sage/combinat/finite_state_machine.py +++ b/src/sage/combinat/finite_state_machine.py @@ -2012,7 +2012,7 @@ def __bool__(self): """ return True # A state cannot be zero (see __init__) - + def _epsilon_successors_(self, fsm=None): """ @@ -2491,7 +2491,7 @@ def __bool__(self): """ return True # A transition cannot be zero (see __init__) - + # **************************************************************************** @@ -3932,7 +3932,7 @@ def __bool__(self): """ return bool(self._states_) - + def __eq__(self, other): """ diff --git a/src/sage/combinat/recognizable_series.py b/src/sage/combinat/recognizable_series.py index 504fce7d808..808f5436e6e 100644 --- a/src/sage/combinat/recognizable_series.py +++ b/src/sage/combinat/recognizable_series.py @@ -901,7 +901,7 @@ def __bool__(self): return False return True - + def __hash__(self): r""" diff --git a/src/sage/combinat/rigged_configurations/bij_abstract_class.py b/src/sage/combinat/rigged_configurations/bij_abstract_class.py index 8e6042a2663..bbc3a4e5d04 100644 --- a/src/sage/combinat/rigged_configurations/bij_abstract_class.py +++ b/src/sage/combinat/rigged_configurations/bij_abstract_class.py @@ -214,7 +214,7 @@ def _update_vacancy_nums(self, a): sage: KRT = crystals.TensorProductOfKirillovReshetikhinTableaux(['A', 4, 1], [[2,1]]) sage: from sage.combinat.rigged_configurations.bij_abstract_class import KRTToRCBijectionAbstract - sage: bijection = KRTToRCBijectionAbstract(KRT(pathlist=[[3,2]])) + sage: bijection = KRTToRCBijectionAbstract(KRT(pathlist=[[3,2]])) sage: bijection._update_vacancy_nums(2) """ # Check to make sure we have a valid index (currently removed) diff --git a/src/sage/combinat/rigged_configurations/bij_type_A2_even.py b/src/sage/combinat/rigged_configurations/bij_type_A2_even.py index be1cd2c4cd3..7253b9b6579 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_A2_even.py +++ b/src/sage/combinat/rigged_configurations/bij_type_A2_even.py @@ -90,7 +90,7 @@ def next_state(self, val): for a in range(pos_val - 1, n): max_width = self.ret_rig_con[a].insert_cell(max_width) case_S[a] = max_width - + # Special case for n self._insert_cell_case_S(self.ret_rig_con[n-1]) diff --git a/src/sage/combinat/rigged_configurations/bij_type_B.py b/src/sage/combinat/rigged_configurations/bij_type_B.py index 05b6f56f6c9..c73d2a41483 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_B.py +++ b/src/sage/combinat/rigged_configurations/bij_type_B.py @@ -590,7 +590,7 @@ def run(self, verbose=False, build_graph=False): from sage.combinat.rigged_configurations.bij_type_A2_odd import RCToKRTBijectionTypeA2Odd from sage.combinat.rigged_configurations.rigged_configurations import RiggedConfigurations from sage.combinat.rigged_configurations.rigged_partition import RiggedPartition, RiggedPartitionTypeB - + # Convert to a type A_{2n-1}^{(2)} RC RC = RiggedConfigurations(['A', 2*self.n-1, 2], self.cur_dims) if verbose: @@ -868,7 +868,7 @@ def next_state(self, height): else: row_num_next = None row_num_bar_next = None - + self._update_vacancy_numbers(n - 2) if row_num is not None: self.cur_partitions[n-2].rigging[row_num] = self.cur_partitions[n-2].vacancy_numbers[row_num] diff --git a/src/sage/combinat/rigged_configurations/bij_type_D.py b/src/sage/combinat/rigged_configurations/bij_type_D.py index 48ad54873ab..b45ec097ed0 100644 --- a/src/sage/combinat/rigged_configurations/bij_type_D.py +++ b/src/sage/combinat/rigged_configurations/bij_type_D.py @@ -508,7 +508,7 @@ def run(self, verbose=False, build_graph=False): self.cur_dims[0][0] -= 1 # This takes care of the indexing b = self.next_state(self.cur_dims[0][0]) - + # Corrections for spinor if dim[0] == self.n and b == -self.n \ and self.cur_dims[0][0] == self.n - 1: diff --git a/src/sage/combinat/root_system/fusion_ring.py b/src/sage/combinat/root_system/fusion_ring.py index 315fc98e8c5..b261550db21 100644 --- a/src/sage/combinat/root_system/fusion_ring.py +++ b/src/sage/combinat/root_system/fusion_ring.py @@ -117,7 +117,7 @@ class FusionRing(WeylCharacterRing): The fusion ring has a number of methods that reflect its role as the Grothendieck ring of a *modular tensor category* (MTC). These include twist methods :meth:`Element.twist` and :meth:`Element.ribbon` - for its elements related to the ribbon structure, and the + for its elements related to the ribbon structure, and the S-matrix :meth:`s_ij`. There are two natural normalizations of the S-matrix. Both @@ -129,7 +129,7 @@ class FusionRing(WeylCharacterRing): The unitary S-matrix is `s=D^{-1/2}\tilde{s}` where .. MATH:: - + D = \sum_V d_i(V)^2. The sum is over all simple objects `V` with @@ -547,7 +547,7 @@ def virasoro_central_charge(self): field theory associated with the Fusion Ring. If `\mathfrak{g}` is the corresponding semisimple Lie algebra, this is - + .. MATH:: \frac{k\dim\mathfrak{g}}{k+h^\vee}, @@ -562,7 +562,7 @@ def virasoro_central_charge(self): is computed in :meth:`D_plus` and `D = \sum d_i^2 > 0` is computed by :meth:`global_q_dimension`. Squaring this identity and remembering that `D_+ D_- = D` gives - + .. MATH:: D_+ / D_- = e^{i\pi c/2}. @@ -707,7 +707,7 @@ def s_matrix(self, unitary=False): - ``unitary`` -- (default: ``False``) set to ``True`` to obtain the unitary S-matrix - Without the ``unitary`` parameter, this is the matrix denoted + Without the ``unitary`` parameter, this is the matrix denoted `\widetilde{s}` in [BaKi2001]_. EXAMPLES:: @@ -735,14 +735,14 @@ def s_matrix(self, unitary=False): return S / self.total_q_order() else: return S - + @cached_method def r_matrix(self, i, j, k): r""" Return the R-matrix entry corresponding to the subobject ``k`` in the tensor product of ``i`` with ``j``. - .. WARNING:: + .. WARNING:: This method only gives complete information when `N_{ij}^k = 1` (an important special case). Tables of MTC including R-matrices @@ -757,7 +757,7 @@ def r_matrix(self, i, j, k): R-matrix. This method computes that scalar. It is possible to adjust the set of embeddings `k \rightarrow i \otimes j` (called a *gauge*) so that this scalar equals - + .. MATH:: \pm \sqrt{\frac{ \theta_k }{ \theta_i \theta_j }}. @@ -906,7 +906,7 @@ def weight(self): def twist(self, reduced=True): r""" - Return a rational number `h` such that `\theta = e^{i \pi h}` + Return a rational number `h` such that `\theta = e^{i \pi h}` is the twist of ``self``. The quantity `e^{i \pi h}` is also available using :meth:`ribbon`. @@ -915,7 +915,7 @@ def twist(self, reduced=True): `h = \langle \lambda, \lambda+2\rho \rangle`, where `\rho` is half the sum of the positive roots. As in [Row2006]_, this requires normalizing - the invariant bilinear form so that + the invariant bilinear form so that `\langle \alpha, \alpha \rangle = 2` for short roots. INPUT: diff --git a/src/sage/combinat/root_system/integrable_representations.py b/src/sage/combinat/root_system/integrable_representations.py index edb6565ab09..e17e6b3c7fe 100644 --- a/src/sage/combinat/root_system/integrable_representations.py +++ b/src/sage/combinat/root_system/integrable_representations.py @@ -42,8 +42,8 @@ class IntegrableRepresentation(UniqueRepresentation, CategoryObject): .. [KacPeterson] Kac and Peterson. *Infinite-dimensional Lie algebras, theta functions and modular forms*. Adv. in Math. 53 (1984), no. 2, 125-264. - - .. [Carter] Carter, *Lie algebras of finite and affine type*. Cambridge + + .. [Carter] Carter, *Lie algebras of finite and affine type*. Cambridge University Press, 2005 If `\Lambda` is a dominant integral weight for an affine root system, @@ -61,7 +61,7 @@ class IntegrableRepresentation(UniqueRepresentation, CategoryObject): lattice and `\rho` is the Weyl vector. Moreover if `m(\mu)>0` then `\mu\in\operatorname{supp}(V)` differs from `\Lambda` by an element of the root lattice ([Ka1990]_, Propositions 11.3 and 11.4). - + Let `\delta` be the nullroot, which is the lowest positive imaginary root. Then by [Ka1990]_, Proposition 11.3 or Corollary 11.9, for fixed `\mu` the function `m(\mu - k\delta)` is a monotone increasing function of @@ -150,9 +150,9 @@ class IntegrableRepresentation(UniqueRepresentation, CategoryObject): Lambda[0] + Lambda[2] - delta: 1 5 18 55 149 372 872 1941 4141 8523 17005 33019 2*Lambda[1] - delta: 1 4 15 44 122 304 721 1612 3469 7176 14414 28124 2*Lambda[2] - 2*delta: 2 7 26 72 194 467 1084 2367 5010 10191 20198 38907 - + Examples for twisted affine types:: - + sage: Lambda = RootSystem(["A",2,2]).weight_lattice(extended=True).fundamental_weights() sage: IntegrableRepresentation(Lambda[0]).strings() {Lambda[0]: [1, 1, 2, 3, 5, 7, 11, 15, 22, 30, 42, 56]} @@ -421,7 +421,7 @@ def _inner_pq(self, pelt, qelt): mcp = pelt.monomial_coefficients() mcq = qelt.monomial_coefficients() zero = ZZ.zero() - return sum(mcp.get(i, zero) * mcq[i] / self._eps[i] for i in mcq) + return sum(mcp.get(i, zero) * mcq[i] / self._eps[i] for i in mcq) def _inner_pp(self, pelt1, pelt2): """ @@ -616,7 +616,7 @@ def _freudenthal_roots_imaginary(self, nu): EXAMPLES:: sage: Lambda = RootSystem(['B',3,1]).weight_lattice(extended=true).fundamental_weights() - sage: V = IntegrableRepresentation(Lambda[0]+Lambda[1]+Lambda[3]) + sage: V = IntegrableRepresentation(Lambda[0]+Lambda[1]+Lambda[3]) sage: [list(V._freudenthal_roots_imaginary(V.highest_weight() - mw)) ....: for mw in V.dominant_maximal_weights()] [[], [], [], [], []] @@ -631,10 +631,10 @@ def _freudenthal_roots_real(self, nu): r""" Iterate over the set of real positive roots `\alpha \in \Delta^+` in ``self`` such that `\nu - \alpha \in Q^+`. - + See [Ka1990]_ Proposition 6.3 for the way to compute the set of real roots for twisted affine case. - + INPUT: - ``nu`` -- an element in `Q` @@ -686,7 +686,7 @@ def _freudenthal_roots_real(self, nu): if rt not in ret: ret.add(rt) yield rt - + elif self._cartan_type.dual().type() == 'G': # case D^3_4 in the Kac notation for al in self._classical_roots: @@ -746,11 +746,11 @@ def _m_freudenthal(self, n): Compute the weight multiplicity using the Freudenthal multiplicity formula in ``self``. - The multiplicities of the imaginary roots for the twisted + The multiplicities of the imaginary roots for the twisted affine case are different than those for the untwisted case. See [Carter]_ Corollary 18.10 for general type and Corollary 18.15 for `A^2_{2l}` - + EXAMPLES:: sage: Lambda = RootSystem(['B',3,1]).weight_lattice(extended=true).fundamental_weights() @@ -798,7 +798,7 @@ def _m_freudenthal(self, n): # k-th element (starting from 1) is k*delta num += (4 - 2*val) * self._freudenthal_accum(mu, rt) val = 1 - val - + elif self._cartan_type.dual().type() == 'G': # D_4^{(3)} (or dual of G_2^{(1)}) for k,rt in enumerate(self._freudenthal_roots_imaginary(self._Lam - mu)): # k-th element (starting from 1) is k*delta @@ -819,7 +819,7 @@ def m(self, n): `\mu = \Lambda - \sum_i n_i \alpha_i`. INPUT: - + - ``n`` -- a tuple representing a weight `\mu`. EXAMPLES:: @@ -1115,7 +1115,7 @@ def branch(self, i=None, weyl_character_ring=None, sequence=None, depth=5): | | O---O=>=O - 1 2 3 + 1 2 3 B3~ In this example, we observe that removing the `i=2` node from the @@ -1142,14 +1142,14 @@ def branch(self, i=None, weyl_character_ring=None, sequence=None, depth=5): sage: V = IntegrableRepresentation(Lambda[0]) sage: V.cartan_type().dynkin_diagram() O---O---O=>=O---O - 0 1 2 3 4 + 0 1 2 3 4 F4~ sage: A1xC3=WeylCharacterRing("A1xC3",style="coroots") sage: A1xC3.dynkin_diagram() O - 1 + 1 O---O=<=O - 2 3 4 + 2 3 4 A1xC3 Observe that removing the `i=1` node from the ``F4~`` Dynkin diagram diff --git a/src/sage/combinat/root_system/type_dual.py b/src/sage/combinat/root_system/type_dual.py index 2fc8de77a1e..3c9e48397fe 100644 --- a/src/sage/combinat/root_system/type_dual.py +++ b/src/sage/combinat/root_system/type_dual.py @@ -272,7 +272,7 @@ def ascii_art(self, label=lambda i: i, node=None): def __eq__(self, other): """ Return whether ``self`` is equal to ``other``. - + EXAMPLES:: sage: B41 = CartanType(['B', 4, 1]) @@ -293,7 +293,7 @@ def __eq__(self, other): def __ne__(self, other): """ Return whether ``self`` is equal to ``other``. - + EXAMPLES:: sage: B41 = CartanType(['B', 4, 1]) diff --git a/src/sage/combinat/sf/macdonald.py b/src/sage/combinat/sf/macdonald.py index c797d7a0cd4..3bc4bdbfd5f 100644 --- a/src/sage/combinat/sf/macdonald.py +++ b/src/sage/combinat/sf/macdonald.py @@ -1180,7 +1180,7 @@ def _to_s(self, part): class Element(MacdonaldPolynomials_generic.Element): pass - + class MacdonaldPolynomials_h(MacdonaldPolynomials_generic): def __init__(self, macdonald): r""" @@ -1346,7 +1346,7 @@ def _m_to_self( self, f ): Convert an element ``f`` from the monomial basis to the ``H`` basis. This calculation is performed by using the fact that `H_\mu[X(1-t)]` - is `c_\mu m_\mu` plus terms which are smaller in dominance order. + is `c_\mu m_\mu` plus terms which are smaller in dominance order. The leading coefficient of the expansion of ``f`` in the `H_\mu` basis is equal to the leading coefficient of `c_\mu^{-1} f[X(1-t)]`. From 762e0b75bdb7cc939a9d7b8223872abb3e00398e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 21 Mar 2022 20:17:07 +0100 Subject: [PATCH 489/529] use language_level=3 for cython --- src/sage/arith/srange.pyx | 8 +- src/sage/combinat/words/word_datatypes.pyx | 7 +- src/sage/crypto/lwe.py | 10 +-- src/sage/matrix/matrix2.pyx | 5 +- src/sage/misc/cython.py | 2 +- src/sage/misc/parser.pyx | 80 +++++++++---------- src/sage/misc/sagedoc.py | 4 +- src/sage/rings/finite_rings/integer_mod.pyx | 3 +- src/sage/rings/integer.pyx | 2 +- src/sage/rings/real_mpfi.pyx | 6 +- src/sage/rings/real_mpfr.pyx | 4 +- .../discrete_gaussian_integer.pyx | 12 +-- src/sage/symbolic/expression.pyx | 4 +- src/sage_setup/cython_options.py | 4 +- 14 files changed, 76 insertions(+), 75 deletions(-) diff --git a/src/sage/arith/srange.pyx b/src/sage/arith/srange.pyx index 041d96996d8..c21a43c0ee1 100644 --- a/src/sage/arith/srange.pyx +++ b/src/sage/arith/srange.pyx @@ -1,4 +1,3 @@ -# cython: language_level=2 """ Ranges and the ``[1,2,..,n]`` notation @@ -16,7 +15,7 @@ AUTHORS: # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# http://www.gnu.org/licenses/ +# https://www.gnu.org/licenses/ # **************************************************************************** @@ -396,10 +395,9 @@ def ellipsis_iter(*args, step=None): if len(args) > step_magic+1: i = step_magic more = xsrange(args[i-2], args[i+1], step, coerce=False, include_endpoint=True) - a = None for a in more: + last_end = a yield a - last_end = a skip = True next_ = None step_magic += 1 @@ -428,8 +426,8 @@ def ellipsis_iter(*args, step=None): if last_end != first: yield first for a in more: + last_end = a yield a - last_end = a except StopIteration: last_end = None skip = True diff --git a/src/sage/combinat/words/word_datatypes.pyx b/src/sage/combinat/words/word_datatypes.pyx index 98d0df2616c..9c48e1af874 100644 --- a/src/sage/combinat/words/word_datatypes.pyx +++ b/src/sage/combinat/words/word_datatypes.pyx @@ -711,11 +711,10 @@ cdef class WordDatatype_str(WordDatatype): sep = sep._data else: raise ValueError("the separator must be a string") - if maxsplit is None: - return [self._parent(z) for z in self._data.split(sep)] - else: - return [self._parent(z) for z in self._data.split(sep, maxsplit)] + maxsplit = -1 + return [self._parent(z) for z in self._data.split(sep=sep, + maxsplit=maxsplit)] def partition(self, sep): r""" diff --git a/src/sage/crypto/lwe.py b/src/sage/crypto/lwe.py index 8224caf5da7..bc027e97362 100644 --- a/src/sage/crypto/lwe.py +++ b/src/sage/crypto/lwe.py @@ -274,7 +274,7 @@ def __init__(self, n, q, D, secret_dist='uniform', m=None): sage: from sage.crypto.lwe import LWE sage: lwe = LWE(n=20, q=next_prime(400), D=D); lwe - LWE(20, 401, Discrete Gaussian sampler over the Integers with sigma = 3.000000 and c = 0, 'uniform', None) + LWE(20, 401, Discrete Gaussian sampler over the Integers with sigma = 3.000000 and c = 0.000000, 'uniform', None) and sample 1000 samples:: @@ -335,10 +335,10 @@ def _repr_(self): sage: from sage.crypto.lwe import LWE sage: D = DiscreteGaussianDistributionIntegerSampler(3.0) sage: lwe = LWE(n=20, q=next_prime(400), D=D); lwe - LWE(20, 401, Discrete Gaussian sampler over the Integers with sigma = 3.000000 and c = 0, 'uniform', None) + LWE(20, 401, Discrete Gaussian sampler over the Integers with sigma = 3.000000 and c = 0.000000, 'uniform', None) sage: lwe = LWE(n=20, q=next_prime(400), D=D, secret_dist=(-3, 3)); lwe - LWE(20, 401, Discrete Gaussian sampler over the Integers with sigma = 3.000000 and c = 0, (-3, 3), None) + LWE(20, 401, Discrete Gaussian sampler over the Integers with sigma = 3.000000 and c = 0.000000, (-3, 3), None) """ if isinstance(self.secret_dist, str): return "LWE(%d, %d, %s, '%s', %s)"%(self.n,self.K.order(),self.D,self.secret_dist, self.m) @@ -388,7 +388,7 @@ def __init__(self, n, secret_dist='uniform', m=None): sage: from sage.crypto.lwe import Regev sage: Regev(n=20) - LWE(20, 401, Discrete Gaussian sampler over the Integers with sigma = 1.915069 and c = 401, 'uniform', None) + LWE(20, 401, Discrete Gaussian sampler over the Integers with sigma = 1.915069 and c = 401.000000, 'uniform', None) """ q = ZZ(next_prime(n**2)) s = RR(1/(RR(n).sqrt() * log(n, 2)**2) * q) @@ -418,7 +418,7 @@ def __init__(self, n, delta=0.01, m=None): sage: from sage.crypto.lwe import LindnerPeikert sage: LindnerPeikert(n=20) - LWE(20, 2053, Discrete Gaussian sampler over the Integers with sigma = 3.600954 and c = 0, 'noise', 168) + LWE(20, 2053, Discrete Gaussian sampler over the Integers with sigma = 3.600954 and c = 0.000000, 'noise', 168) """ if m is None: m = 2*n + 128 diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 90d87b6e49d..070d92100ac 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -1639,7 +1639,7 @@ cdef class Matrix(Matrix1): Q = (At * A) * (B * Bt) return Bt * ~Q * At - def rook_vector(self, algorithm="ButeraPernici", complement=False, use_complement=None): + def rook_vector(self, algorithm=None, complement=False, use_complement=None): r""" Return the rook vector of this matrix. @@ -1794,6 +1794,9 @@ cdef class Matrix(Matrix1): zero = self.base_ring().zero() one = self.base_ring().one() + if algorithm is None: + algorithm = "ButeraPernici" + # we first run through the coefficients of the matrix to compute the # number of non-zero coefficients and to see whether or not it contains # only elements in {0,1}... but this is not always needed diff --git a/src/sage/misc/cython.py b/src/sage/misc/cython.py index 7eadbd39cc0..150e448fd46 100644 --- a/src/sage/misc/cython.py +++ b/src/sage/misc/cython.py @@ -341,7 +341,7 @@ def cython(filename, verbose=0, compile_message=False, libraries=standard_libs, library_dirs=standard_libdirs) - directives = dict(language_level=sys.version_info[0], cdivision=True) + directives = dict(language_level=3, cdivision=True) try: # Change directories to target_dir so that Cython produces the correct diff --git a/src/sage/misc/parser.pyx b/src/sage/misc/parser.pyx index 8a563c8af2d..a365c3c79ea 100644 --- a/src/sage/misc/parser.pyx +++ b/src/sage/misc/parser.pyx @@ -272,11 +272,11 @@ cdef class Tokenizer: return NOT_EQ elif s[pos] == '=': self.pos += 2 - return '=' + return ord('=') elif s[pos] == '*' and s[pos+1] == '*': self.pos += 2 - return '^' + return ord('^') # simple tokens if s[pos] in "+-*/^()=><,[]{}!": @@ -609,13 +609,13 @@ cdef class Parser: """ cdef int token all = [] - if tokens.next() == '(': - token = ',' - while token == ',': + if tokens.next() == c'(': + token = c',' + while token == c',': all.append(self.p_list(tokens)) token = tokens.next() - if token == ')': + if token == c')': from sage.matrix.constructor import matrix return matrix(all) else: @@ -637,8 +637,8 @@ cdef class Parser: [(1, 2, 3), [a + 1, b + 2, c + 3, (d + 4,)]] """ all = [] - cdef int token = ',' - while token == ',': + cdef int token = c',' + while token == c',': token = tokens.peek() if token == MATRIX: tokens.next() @@ -651,14 +651,14 @@ cdef class Parser: else: tokens.backtrack() obj = self.p_eqn(tokens) - elif token == '[': + elif token == c'[': obj = self.p_list(tokens) - elif token == '(': + elif token == c'(': obj = self.p_tuple(tokens) elif token == EOS: return all - elif token == ']' or token == ')': - tokens.token = ',' + elif token == c']' or token == c')': + tokens.token = c',' return all else: obj = self.p_eqn(tokens) @@ -682,11 +682,11 @@ cdef class Parser: [] """ cdef int token = tokens.next() - if token != '[': + if token != c'[': self.parse_error(tokens, "Malformed list") all = self.p_sequence(tokens) token = tokens.next() - if token != ']': + if token != c']': self.parse_error(tokens, "Malformed list") return all @@ -704,20 +704,20 @@ cdef class Parser: cdef int start = tokens.pos cdef int token = tokens.next() cdef bint real_tuple = True - if token != '(': + if token != c'(': self.parse_error(tokens, "Malformed tuple") all = self.p_sequence(tokens) if len(all) == 1: if tokens.last() != c',': real_tuple = False token = tokens.next() - if token != ')': + if token != c')': self.parse_error(tokens, "Malformed tuple") if real_tuple: return tuple(all) else: token = tokens.peek() - if token == ',' or token == EOS: + if token == c',' or token == EOS: return all[0] else: # we have to reparse the entire thing as an expression @@ -753,15 +753,15 @@ cdef class Parser: """ lhs = self.p_expr(tokens) cdef int op = tokens.next() - if op == '=': + if op == c'=': return lhs == self.p_expr(tokens) elif op == NOT_EQ: return lhs != self.p_expr(tokens) - elif op == '<': + elif op == c'<': return lhs < self.p_expr(tokens) elif op == LESS_EQ: return lhs <= self.p_expr(tokens) - elif op == '>': + elif op == c'>': return lhs > self.p_expr(tokens) elif op == GREATER_EQ: return lhs >= self.p_expr(tokens) @@ -793,9 +793,9 @@ cdef class Parser: cdef int op operand1 = self.p_term(tokens) op = tokens.next() - while op == '+' or op == '-': + while op == c'+' or op == c'-': operand2 = self.p_term(tokens) - if op == '+': + if op == c'+': operand1 = operand1 + operand2 else: operand1 = operand1 - operand2 @@ -828,17 +828,17 @@ cdef class Parser: operand1 = self.p_factor(tokens) op = tokens.next() if op == NAME and self.implicit_multiplication: - op = '*' + op = c'*' tokens.backtrack() - while op == '*' or op == '/': + while op == c'*' or op == c'/': operand2 = self.p_factor(tokens) - if op == '*': + if op == c'*': operand1 = operand1 * operand2 else: operand1 = operand1 / operand2 op = tokens.next() if op == NAME and self.implicit_multiplication: - op = '*' + op = c'*' tokens.backtrack() tokens.backtrack() return operand1 @@ -862,9 +862,9 @@ cdef class Parser: t^11 """ cdef int token = tokens.next() - if token == '+': + if token == c'+': return self.p_factor(tokens) - elif token == '-': + elif token == c'-': return -self.p_factor(tokens) else: tokens.backtrack() @@ -898,13 +898,13 @@ cdef class Parser: """ operand1 = self.p_atom(tokens) cdef int token = tokens.next() - if token == '^': + if token == c'^': operand2 = self.p_factor(tokens) return operand1 ** operand2 - elif token == "!": + elif token == c"!": from sage.functions.all import factorial operand1 = factorial(operand1) - if tokens.peek() == '^': + if tokens.peek() == c'^': tokens.next() operand2 = self.p_factor(tokens) return operand1 ** operand2 @@ -949,20 +949,20 @@ cdef class Parser: elif token == NAME: name = tokens.last_token_string() token = tokens.next() - if token == '(': + if token == c'(': func = self.callable_constructor(name) args, kwds = self.p_args(tokens) token = tokens.next() - if token != ')': + if token != c')': self.parse_error(tokens, "Bad function call") return func(*args, **kwds) else: tokens.backtrack() return self.variable_constructor(name) - elif token == '(': + elif token == c'(': expr = self.p_expr(tokens) token = tokens.next() - if token != ')': + if token != c')': self.parse_error(tokens, "Mismatched parentheses") return expr else: @@ -984,10 +984,10 @@ cdef class Parser: """ args = [] kwds = {} - if tokens.peek() == ')': + if tokens.peek() == c')': return args, kwds - cdef int token = ',' - while token == ',': + cdef int token = c',' + while token == c',': arg = self.p_arg(tokens) if isinstance(arg, tuple): name, value = arg @@ -1029,11 +1029,11 @@ cdef class Parser: """ cdef int token = tokens.next() - if token == NAME and tokens.peek() == '=': + if token == NAME and tokens.peek() == c'=': name = tokens.last_token_string() tokens.next() return name, self.p_expr(tokens) - if token == "[" : + if token == c"[": tokens.backtrack() return self.p_list(tokens) else: diff --git a/src/sage/misc/sagedoc.py b/src/sage/misc/sagedoc.py index 37fd5d8b6e6..f49d375d1eb 100644 --- a/src/sage/misc/sagedoc.py +++ b/src/sage/misc/sagedoc.py @@ -609,10 +609,10 @@ def format(s, embedded=False): EXAMPLES:: sage: from sage.misc.sagedoc import format - sage: identity_matrix(2).rook_vector.__doc__[202:274] + sage: identity_matrix(2).rook_vector.__doc__[191:263] 'Let `A` be an `m` by `n` (0,1)-matrix. We identify `A` with a chessboard' - sage: format(identity_matrix(2).rook_vector.__doc__[202:274]) + sage: format(identity_matrix(2).rook_vector.__doc__[191:263]) 'Let A be an m by n (0,1)-matrix. We identify A with a chessboard\n' If the first line of the string is 'nodetex', remove 'nodetex' but diff --git a/src/sage/rings/finite_rings/integer_mod.pyx b/src/sage/rings/finite_rings/integer_mod.pyx index 0489e50b1bc..714d796ec90 100644 --- a/src/sage/rings/finite_rings/integer_mod.pyx +++ b/src/sage/rings/finite_rings/integer_mod.pyx @@ -1,4 +1,3 @@ -# cython: language_level=2 r""" Elements of `\ZZ/n\ZZ` @@ -1559,7 +1558,7 @@ cdef class IntegerMod_abstract(FiniteRingElement): if nval >= plog.valuation() + (-1 if p == 2 else 0): if self == 1: if all: - return [s*K(p*k+m.lift()) for k in range(p**(k-(2 if p==2 else 1))) for m in modp for s in sign] + return [s*K(p*a+m.lift()) for a in range(p**(k-(2 if p==2 else 1))) for m in modp for s in sign] else: return K(modp.lift()) else: diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx index 682fa8cba64..a4399439015 100644 --- a/src/sage/rings/integer.pyx +++ b/src/sage/rings/integer.pyx @@ -7099,7 +7099,7 @@ cdef int mpz_set_str_python(mpz_ptr z, char* s, int base) except -1: x += 1 # Strip spaces # Disallow a sign here - if x[0] == '-' or x[0] == '+': + if x[0] == c'-' or x[0] == c'+': x = "" # Force an error below assert base >= 2 diff --git a/src/sage/rings/real_mpfi.pyx b/src/sage/rings/real_mpfi.pyx index 1f01ff8ac55..9eada6a2bc0 100644 --- a/src/sage/rings/real_mpfi.pyx +++ b/src/sage/rings/real_mpfi.pyx @@ -1943,12 +1943,12 @@ cdef class RealIntervalFieldElement(RingElement): cdef long digits digits = strlen(lower_s) - if lower_s[0] == '-': + if lower_s[0] == b'-': digits -= 1 lower_expo -= digits digits = strlen(upper_s) - if upper_s[0] == '-': + if upper_s[0] == b'-': digits -= 1 upper_expo -= digits @@ -2117,7 +2117,7 @@ cdef class RealIntervalFieldElement(RingElement): raise MemoryError("Unable to allocate memory for the mantissa of an interval") mpz_get_str(tmp_cstr, base, lower_mpz) digits = strlen(tmp_cstr) - if tmp_cstr[0] == '-': + if tmp_cstr[0] == b'-': digits -= 1 mant_string = bytes_to_str(tmp_cstr+1) sign_string = bytes_to_str(b'-') diff --git a/src/sage/rings/real_mpfr.pyx b/src/sage/rings/real_mpfr.pyx index e9c94e4eba2..3ea8c1dee1f 100644 --- a/src/sage/rings/real_mpfr.pyx +++ b/src/sage/rings/real_mpfr.pyx @@ -2092,12 +2092,12 @@ cdef class RealNumber(sage.structure.element.RingElement): if s is NULL: raise RuntimeError("unable to convert an mpfr number to a string") # t contains just digits (no sign, decimal point or exponent) - if s[0] == '-': + t = char_to_str(s) + if t[0] == '-': sgn = "-" t = char_to_str(s + 1) else: sgn = "" - t = char_to_str(s) mpfr_free_str(s) if skip_zeroes: diff --git a/src/sage/stats/distributions/discrete_gaussian_integer.pyx b/src/sage/stats/distributions/discrete_gaussian_integer.pyx index 328c34756d8..87fbe6ca5cd 100644 --- a/src/sage/stats/distributions/discrete_gaussian_integer.pyx +++ b/src/sage/stats/distributions/discrete_gaussian_integer.pyx @@ -219,16 +219,16 @@ cdef class DiscreteGaussianDistributionIntegerSampler(SageObject): sage: from sage.stats.distributions.discrete_gaussian_integer import DiscreteGaussianDistributionIntegerSampler sage: DiscreteGaussianDistributionIntegerSampler(3.0, algorithm="uniform+online") - Discrete Gaussian sampler over the Integers with sigma = 3.000000 and c = 0 + Discrete Gaussian sampler over the Integers with sigma = 3.000000 and c = 0.000000 sage: DiscreteGaussianDistributionIntegerSampler(3.0, algorithm="uniform+table") - Discrete Gaussian sampler over the Integers with sigma = 3.000000 and c = 0 + Discrete Gaussian sampler over the Integers with sigma = 3.000000 and c = 0.000000 sage: DiscreteGaussianDistributionIntegerSampler(3.0, algorithm="uniform+logtable") - Discrete Gaussian sampler over the Integers with sigma = 3.000000 and c = 0 + Discrete Gaussian sampler over the Integers with sigma = 3.000000 and c = 0.000000 Note that ``"sigma2+logtable"`` adjusts `σ`:: sage: DiscreteGaussianDistributionIntegerSampler(3.0, algorithm="sigma2+logtable") - Discrete Gaussian sampler over the Integers with sigma = 3.397287 and c = 0 + Discrete Gaussian sampler over the Integers with sigma = 3.397287 and c = 0.000000 TESTS: @@ -491,6 +491,6 @@ cdef class DiscreteGaussianDistributionIntegerSampler(SageObject): sage: from sage.stats.distributions.discrete_gaussian_integer import DiscreteGaussianDistributionIntegerSampler sage: repr(DiscreteGaussianDistributionIntegerSampler(3.0, 2)) - 'Discrete Gaussian sampler over the Integers with sigma = 3.000000 and c = 2' + 'Discrete Gaussian sampler over the Integers with sigma = 3.000000 and c = 2.000000' """ - return "Discrete Gaussian sampler over the Integers with sigma = %f and c = %d"%(self.sigma, self.c) + return f"Discrete Gaussian sampler over the Integers with sigma = {self.sigma:.6f} and c = {self.c:.6f}" diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index eb50443ff29..5d4fba06ab2 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -14071,7 +14071,7 @@ cdef class hold_class: sage: SR(2)^5 32 """ - g_set_state('hold', True) + g_set_state(b'hold', True) def __exit__(self, *args): """ @@ -14084,7 +14084,7 @@ cdef class hold_class: sage: SR(2)^5 32 """ - g_set_state('hold', False) + g_set_state(b'hold', False) def start(self): """ diff --git a/src/sage_setup/cython_options.py b/src/sage_setup/cython_options.py index a02401c4d23..086aa070ca9 100644 --- a/src/sage_setup/cython_options.py +++ b/src/sage_setup/cython_options.py @@ -1,5 +1,6 @@ import sys + def compiler_directives(profile: bool): """ Return a list of Cython directives used for compilation. @@ -15,13 +16,14 @@ def compiler_directives(profile: bool): embedsignature=True, fast_getattr=True, # Use Python 3 (including source code semantics) for module compilation - language_level="3str", + language_level="3", # Enable support for late includes (make declarations in Cython code available to C include files) preliminary_late_includes_cy28=True, # Add hooks for Python profilers into the compiled C code profile=profile, ) + def compile_time_env_variables(): """ Return a list of environmental variables used for compilation. From 4f46253fd1ec0835321b35b027be6c4e1dad6a15 Mon Sep 17 00:00:00 2001 From: "Martin R. Albrecht" Date: Fri, 27 May 2022 16:38:34 +0100 Subject: [PATCH 490/529] FPLLL 5.4.2 and FPyLLL 0.5.7 --- build/pkgs/fplll/checksums.ini | 6 +++--- build/pkgs/fplll/package-version.txt | 2 +- build/pkgs/fpylll/checksums.ini | 6 +++--- build/pkgs/fpylll/package-version.txt | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/build/pkgs/fplll/checksums.ini b/build/pkgs/fplll/checksums.ini index c346ac9603d..2d6b70504f8 100644 --- a/build/pkgs/fplll/checksums.ini +++ b/build/pkgs/fplll/checksums.ini @@ -1,5 +1,5 @@ tarball=fplll-VERSION.tar.gz -sha1=fe1b225f2bff07b7b832ae8b20ffc85acfd231cd -md5=44db0a42c33e5aa60264b32ab0063351 -cksum=3420408626 +sha1=d84ae04deee3a29033c6e28e40c67ed14f8fff32 +md5=9e8ed4e5ff7f3231f9ccf397dca9a117 +cksum=855019078 upstream_url=https://github.com/fplll/fplll/releases/download/VERSION/fplll-VERSION.tar.gz diff --git a/build/pkgs/fplll/package-version.txt b/build/pkgs/fplll/package-version.txt index ade65226e0a..8ae03c11904 100644 --- a/build/pkgs/fplll/package-version.txt +++ b/build/pkgs/fplll/package-version.txt @@ -1 +1 @@ -5.4.1 +5.4.2 diff --git a/build/pkgs/fpylll/checksums.ini b/build/pkgs/fpylll/checksums.ini index 5255ba6aec8..5a3fc413fe2 100644 --- a/build/pkgs/fpylll/checksums.ini +++ b/build/pkgs/fpylll/checksums.ini @@ -1,5 +1,5 @@ tarball=fpylll-VERSION.tar.gz -sha1=e2a005b53fcc3a9ec1f1111f144eb75b6de7fb44 -md5=5ea3a5fe30646311ef28ca1f8e9bf2bc -cksum=690866680 +sha1=9c4951f4ec50f36805129df4b821e5ea18b7ad30 +md5=d802205f818a9ae5846f8eaa34db7b5c +cksum=3615125514 upstream_url=https://github.com/fplll/fpylll/releases/download/VERSION/fpylll-VERSION.tar.gz diff --git a/build/pkgs/fpylll/package-version.txt b/build/pkgs/fpylll/package-version.txt index b49b25336d4..d3532a107ee 100644 --- a/build/pkgs/fpylll/package-version.txt +++ b/build/pkgs/fpylll/package-version.txt @@ -1 +1 @@ -0.5.6 +0.5.7 From f7e5340e90b0505290377c7300aebb1086b94642 Mon Sep 17 00:00:00 2001 From: Utkarsh Sharma Date: Fri, 27 May 2022 21:32:06 +0530 Subject: [PATCH 491/529] Fix a typo in the docstring of the random_element method in polynomial_ring.py --- src/sage/rings/polynomial/polynomial_ring.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/polynomial/polynomial_ring.py b/src/sage/rings/polynomial/polynomial_ring.py index f88d12201da..34f25975963 100644 --- a/src/sage/rings/polynomial/polynomial_ring.py +++ b/src/sage/rings/polynomial/polynomial_ring.py @@ -1321,7 +1321,7 @@ def random_element(self, degree=(-1,2), *args, **kwds): INPUT: - - ``degree`` - optional integer for fixing the degree or + - ``degree`` - optional integer for fixing the degree or a tuple of minimum and maximum degrees. By default set to ``(-1,2)``. From e41b37f22f0f66453f997a60a757fa8ac11771ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 27 May 2022 18:43:37 +0200 Subject: [PATCH 492/529] remove inheritance of object in src/doc, doctest/ numerical/ rings/ etc --- src/doc/en/developer/coding_basics.rst | 2 +- .../tutorial-objects-and-classes.rst | 8 ++++---- src/sage/doctest/control.py | 2 +- src/sage/doctest/external.py | 2 +- src/sage/doctest/fixtures.py | 20 +++++++++---------- src/sage/doctest/forker.py | 2 +- src/sage/doctest/parsing.py | 2 +- src/sage/doctest/sources.py | 6 +++--- src/sage/interfaces/expect.py | 2 +- src/sage/interfaces/four_ti_2.py | 2 +- src/sage/interfaces/gfan.py | 2 +- src/sage/interfaces/process.pxd | 2 +- src/sage/interfaces/process.pyx | 2 +- src/sage/interfaces/tab_completion.py | 2 +- .../numerical/backends/glpk_graph_backend.pxd | 2 +- .../numerical/backends/glpk_graph_backend.pyx | 2 +- src/sage/rings/continued_fraction_gosper.py | 2 +- src/sage/rings/infinity.py | 4 ++-- src/sage/rings/invariants/invariant_theory.py | 2 +- .../rings/multi_power_series_ring_element.py | 2 +- .../number_field/number_field_element.pyx | 2 +- src/sage/rings/padics/lattice_precision.py | 2 +- .../rings/padics/padic_template_element.pxi | 4 ++-- src/sage/rings/padics/relaxed_template.pxi | 2 +- .../rings/padics/relaxed_template_header.pxi | 2 +- src/sage/rings/valuation/valuation.py | 2 +- src/sage/structure/coerce.pyx | 6 +++--- src/sage/structure/dynamic_class.py | 2 +- src/sage/structure/factory.pyx | 4 ++-- src/sage/structure/global_options.py | 10 +++++----- src/sage/structure/graphics_file.py | 2 +- src/sage/structure/indexed_generators.py | 2 +- src/sage/structure/mutability.pyx | 4 ++-- src/sage/structure/proof/proof.py | 2 +- src/sage/structure/richcmp.pyx | 8 ++++---- src/sage/structure/test_factory.py | 2 +- src/sage/structure/unique_representation.py | 4 ++-- 37 files changed, 65 insertions(+), 65 deletions(-) diff --git a/src/doc/en/developer/coding_basics.rst b/src/doc/en/developer/coding_basics.rst index 2b540852a61..2e35c533471 100644 --- a/src/doc/en/developer/coding_basics.rst +++ b/src/doc/en/developer/coding_basics.rst @@ -77,7 +77,7 @@ In particular, - Use CamelCase for class names:: - class SomeValue(object): + class SomeValue(): def __init__(self, x): self._x = 1 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 a295508e0ab..51aec989810 100644 --- a/src/doc/en/thematic_tutorials/tutorial-objects-and-classes.rst +++ b/src/doc/en/thematic_tutorials/tutorial-objects-and-classes.rst @@ -374,7 +374,7 @@ An example: glass of beverage in a restaurant Let's write a small class about glasses in a restaurant:: - sage: class Glass(object): + sage: class Glass(): ....: def __init__(self, size): ....: assert size > 0 ....: self._size = float(size) # an attribute @@ -474,7 +474,7 @@ the common behavior and then reuses the methods from this class. We first write a small class ''AbstractDish'' which implements the "clean-dirty-wash" behavior:: - sage: class AbstractDish(object): + sage: class AbstractDish(): ....: def __init__(self): ....: self._clean = True ....: def is_clean(self): @@ -604,7 +604,7 @@ Solutions to the exercises 1. Here is a solution to the first exercise:: - sage: class Glass(object): + sage: class Glass(): ....: def __init__(self, size): ....: assert size > 0 ....: self._size = float(size) @@ -686,7 +686,7 @@ Solutions to the exercises #. Here is the solution to the second exercice:: - sage: class AbstractDish(object): + sage: class AbstractDish(): ....: def __init__(self): ....: self._clean = True ....: def is_clean(self): diff --git a/src/sage/doctest/control.py b/src/sage/doctest/control.py index a9d11d0863e..2726a18c41f 100644 --- a/src/sage/doctest/control.py +++ b/src/sage/doctest/control.py @@ -284,7 +284,7 @@ def skipfile(filename, tested_optional_tags=False): return False -class Logger(object): +class Logger(): r""" File-like object which implements writing to multiple files at once. diff --git a/src/sage/doctest/external.py b/src/sage/doctest/external.py index 546835698e2..f21f5917890 100644 --- a/src/sage/doctest/external.py +++ b/src/sage/doctest/external.py @@ -370,7 +370,7 @@ def external_software(): external_software = external_software() -class AvailableSoftware(object): +class AvailableSoftware(): """ This class keeps the set of available software whose availability is detected lazily from the list of external software. diff --git a/src/sage/doctest/fixtures.py b/src/sage/doctest/fixtures.py index 13b3fb40f19..815ee825f50 100644 --- a/src/sage/doctest/fixtures.py +++ b/src/sage/doctest/fixtures.py @@ -14,7 +14,7 @@ You can use :func:`trace_method` to see how a method communicates with its surroundings:: - sage: class Foo(object): + sage: class Foo(): ....: def f(self): ....: self.y = self.g(self.x) ....: def g(self, arg): @@ -111,7 +111,7 @@ def sorted_pairs(iterable, pairs=False): return repr(val) -class AttributeAccessTracerHelper(object): +class AttributeAccessTracerHelper(): def __init__(self, delegate, prefix=" ", reads=True): r""" @@ -134,7 +134,7 @@ def __init__(self, delegate, prefix=" ", reads=True): EXAMPLES:: - sage: class Foo(object): + sage: class Foo(): ....: def f(self, *args): ....: return self.x*self.x ....: @@ -166,7 +166,7 @@ def get(self, name): EXAMPLES:: - sage: class Foo(object): + sage: class Foo(): ....: def f(self, *args): ....: return self.x*self.x ....: @@ -208,7 +208,7 @@ def set(self, name, val): EXAMPLES:: - sage: class Foo(object): + sage: class Foo(): ....: pass ....: sage: foo = Foo() @@ -224,7 +224,7 @@ def set(self, name, val): setattr(self.delegate, name, val) -class AttributeAccessTracerProxy(object): +class AttributeAccessTracerProxy(): def __init__(self, delegate, **kwds): r""" @@ -247,7 +247,7 @@ def __init__(self, delegate, **kwds): EXAMPLES:: - sage: class Foo(object): + sage: class Foo(): ....: def f(self, *args): ....: return self.x*self.x ....: @@ -281,7 +281,7 @@ def __getattribute__(self, name): EXAMPLES:: - sage: class Foo(object): + sage: class Foo(): ....: def f(self, *args): ....: return self.x*self.x ....: @@ -307,7 +307,7 @@ def __setattr__(self, name, val): EXAMPLES:: - sage: class Foo(object): + sage: class Foo(): ....: pass ....: sage: foo = Foo() @@ -344,7 +344,7 @@ def trace_method(obj, meth, **kwds): EXAMPLES:: - sage: class Foo(object): + sage: class Foo(): ....: def f(self, arg=None): ....: self.y = self.g(self.x) ....: if arg: return arg*arg diff --git a/src/sage/doctest/forker.py b/src/sage/doctest/forker.py index 39967cfbbe6..71ca8c1041b 100644 --- a/src/sage/doctest/forker.py +++ b/src/sage/doctest/forker.py @@ -2361,7 +2361,7 @@ def kill(self): return True -class DocTestTask(object): +class DocTestTask(): """ This class encapsulates the tests from a single source. diff --git a/src/sage/doctest/parsing.py b/src/sage/doctest/parsing.py index 8c8f48bd827..064414befbc 100644 --- a/src/sage/doctest/parsing.py +++ b/src/sage/doctest/parsing.py @@ -388,7 +388,7 @@ def make_marked_output(s, D): return ans -class OriginalSource(object): +class OriginalSource(): r""" Context swapping out the pre-parsed source with the original for better reporting. diff --git a/src/sage/doctest/sources.py b/src/sage/doctest/sources.py index f9470e14d2e..d0f2103c203 100644 --- a/src/sage/doctest/sources.py +++ b/src/sage/doctest/sources.py @@ -109,7 +109,7 @@ def get_basename(path): return fully_qualified_path.replace(os.path.sep, '.') -class DocTestSource(object): +class DocTestSource(): """ This class provides a common base class for different sources of doctests. @@ -1065,7 +1065,7 @@ def starting_docstring(self, line): sage: FDS.ending_docstring("'''") <...Match object...> sage: FDS.qualified_name = NestedName(FDS.basename) - sage: FDS.starting_docstring("class MyClass(object):") + sage: FDS.starting_docstring("class MyClass():") sage: FDS.starting_docstring(" def hello_world(self):") sage: FDS.starting_docstring(" '''") <...Match object...> @@ -1073,7 +1073,7 @@ def starting_docstring(self, line): sage.doctest.sources.MyClass.hello_world sage: FDS.ending_docstring(" '''") <...Match object...> - sage: FDS.starting_docstring("class NewClass(object):") + sage: FDS.starting_docstring("class NewClass():") sage: FDS.starting_docstring(" '''") <...Match object...> sage: FDS.ending_docstring(" '''") diff --git a/src/sage/interfaces/expect.py b/src/sage/interfaces/expect.py index 17c56551fed..739431a5005 100644 --- a/src/sage/interfaces/expect.py +++ b/src/sage/interfaces/expect.py @@ -87,7 +87,7 @@ # "return", "break", or "continue", raising an exception, ...) -class gc_disabled(object): +class gc_disabled(): """ This is a "with" statement context manager. Garbage collection is disabled within its scope. Nested usage is properly handled. diff --git a/src/sage/interfaces/four_ti_2.py b/src/sage/interfaces/four_ti_2.py index 72afddd70f1..92de8d2d478 100644 --- a/src/sage/interfaces/four_ti_2.py +++ b/src/sage/interfaces/four_ti_2.py @@ -41,7 +41,7 @@ import os -class FourTi2(object): +class FourTi2(): r""" This object defines an interface to the program 4ti2. Each command 4ti2 has is exposed as one method. diff --git a/src/sage/interfaces/gfan.py b/src/sage/interfaces/gfan.py index 0e5b4046f4e..686564dbdc0 100644 --- a/src/sage/interfaces/gfan.py +++ b/src/sage/interfaces/gfan.py @@ -46,7 +46,7 @@ from sage.misc.decorators import rename_keyword -class Gfan(object): +class Gfan(): """ Interface to Anders Jensen's Groebner Fan program. """ diff --git a/src/sage/interfaces/process.pxd b/src/sage/interfaces/process.pxd index 03d9a55e533..3f1ae3f0dc8 100644 --- a/src/sage/interfaces/process.pxd +++ b/src/sage/interfaces/process.pxd @@ -1,4 +1,4 @@ -cdef class ContainChildren(object): +cdef class ContainChildren(): cdef int parentpid cdef int exitcode, exceptcode cdef bint silent diff --git a/src/sage/interfaces/process.pyx b/src/sage/interfaces/process.pyx index 3e51eb0c95c..ea90d5b0de4 100644 --- a/src/sage/interfaces/process.pyx +++ b/src/sage/interfaces/process.pyx @@ -24,7 +24,7 @@ from cysignals.pselect import PSelecter from cysignals.pysignals import changesignal -cdef class ContainChildren(object): +cdef class ContainChildren(): """ Context manager which will ensure that all forked child processes will be forced to exit if they try to exit the context. diff --git a/src/sage/interfaces/tab_completion.py b/src/sage/interfaces/tab_completion.py index 0182e4c1d6d..ca106a67273 100644 --- a/src/sage/interfaces/tab_completion.py +++ b/src/sage/interfaces/tab_completion.py @@ -27,7 +27,7 @@ import builtins -class ExtraTabCompletion(object): +class ExtraTabCompletion(): def __dir__(self): """ diff --git a/src/sage/numerical/backends/glpk_graph_backend.pxd b/src/sage/numerical/backends/glpk_graph_backend.pxd index 3eebb4dc08b..1b63765de7f 100644 --- a/src/sage/numerical/backends/glpk_graph_backend.pxd +++ b/src/sage/numerical/backends/glpk_graph_backend.pxd @@ -25,7 +25,7 @@ ctypedef struct c_a_data: double x -cdef class GLPKGraphBackend(object): +cdef class GLPKGraphBackend(): cdef glp_graph * graph cpdef add_vertex(self, name = ?) cpdef list add_vertices(self, vertices) diff --git a/src/sage/numerical/backends/glpk_graph_backend.pyx b/src/sage/numerical/backends/glpk_graph_backend.pyx index e3dd95841e8..564c108fdf4 100644 --- a/src/sage/numerical/backends/glpk_graph_backend.pyx +++ b/src/sage/numerical/backends/glpk_graph_backend.pyx @@ -76,7 +76,7 @@ from sage.libs.glpk.constants cimport * from sage.libs.glpk.graph cimport * from sage.numerical.mip import MIPSolverException -cdef class GLPKGraphBackend(object): +cdef class GLPKGraphBackend(): """ GLPK Backend for access to GLPK graph functions diff --git a/src/sage/rings/continued_fraction_gosper.py b/src/sage/rings/continued_fraction_gosper.py index 07b2dcc852b..08d5dd34658 100644 --- a/src/sage/rings/continued_fraction_gosper.py +++ b/src/sage/rings/continued_fraction_gosper.py @@ -35,7 +35,7 @@ from sage.rings.infinity import Infinity from sage.rings.integer import Integer -class gosper_iterator(object): +class gosper_iterator(): r""" Iterable for the partial quotients of `(a*x+b)/(c*x+d)`, where `a, b, c, d` are integers, and `x` is a continued fraction. diff --git a/src/sage/rings/infinity.py b/src/sage/rings/infinity.py index 18adea7ca8b..c30004c8d5a 100644 --- a/src/sage/rings/infinity.py +++ b/src/sage/rings/infinity.py @@ -227,7 +227,7 @@ import sage.rings.integer_ring _obj = {} -class _uniq(object): +class _uniq(): def __new__(cls, *args): """ This ensures uniqueness of these objects. @@ -243,7 +243,7 @@ def __new__(cls, *args): return O -class AnInfinity(object): +class AnInfinity(): """ TESTS:: diff --git a/src/sage/rings/invariants/invariant_theory.py b/src/sage/rings/invariants/invariant_theory.py index 7478093452d..c37af37cc7c 100644 --- a/src/sage/rings/invariants/invariant_theory.py +++ b/src/sage/rings/invariants/invariant_theory.py @@ -4058,7 +4058,7 @@ def syzygy(self, Delta, Theta, Phi, Theta_prime, Delta_prime, U, V, T, T_prime, ###################################################################### -class InvariantTheoryFactory(object): +class InvariantTheoryFactory(): """ Factory object for invariants of multilinear forms. diff --git a/src/sage/rings/multi_power_series_ring_element.py b/src/sage/rings/multi_power_series_ring_element.py index 9ce75c73c42..b1c1a3ffb67 100644 --- a/src/sage/rings/multi_power_series_ring_element.py +++ b/src/sage/rings/multi_power_series_ring_element.py @@ -2080,7 +2080,7 @@ def laurent_series(self): raise NotImplementedError("laurent_series not defined for multivariate power series.") -class MO(object): +class MO(): """ Object representing a zero element with given precision. diff --git a/src/sage/rings/number_field/number_field_element.pyx b/src/sage/rings/number_field/number_field_element.pyx index 21e19618896..3585eee09f5 100644 --- a/src/sage/rings/number_field/number_field_element.pyx +++ b/src/sage/rings/number_field/number_field_element.pyx @@ -5451,7 +5451,7 @@ cdef class OrderElement_relative(NumberFieldElement_relative): -class CoordinateFunction(object): +class CoordinateFunction(): r""" This class provides a callable object which expresses elements in terms of powers of a fixed field generator `\alpha`. diff --git a/src/sage/rings/padics/lattice_precision.py b/src/sage/rings/padics/lattice_precision.py index 40c5bb04edd..a041394d635 100644 --- a/src/sage/rings/padics/lattice_precision.py +++ b/src/sage/rings/padics/lattice_precision.py @@ -2741,7 +2741,7 @@ def precision_lattice(self, elements=None): M *= self._p ** val return M -class pAdicLatticeElementWeakProxy(object): +class pAdicLatticeElementWeakProxy(): r""" The implementations of :class:`DifferentialPrecisionGeneric` hold weak references to :class:`pAdicLatticeElement`. They are stored in diff --git a/src/sage/rings/padics/padic_template_element.pxi b/src/sage/rings/padics/padic_template_element.pxi index b30d8cf0ae9..92fad2b1f9d 100644 --- a/src/sage/rings/padics/padic_template_element.pxi +++ b/src/sage/rings/padics/padic_template_element.pxi @@ -870,7 +870,7 @@ cdef _zero(expansion_mode mode, teich_ring): else: return _expansion_zero -cdef class ExpansionIter(object): +cdef class ExpansionIter(): """ An iterator over a `p`-adic expansion. @@ -999,7 +999,7 @@ cdef class ExpansionIter(object): else: return cexpansion_next(self.curvalue, self.mode, self.curpower, pp) -cdef class ExpansionIterable(object): +cdef class ExpansionIterable(): r""" An iterable storing a `p`-adic expansion of an element. diff --git a/src/sage/rings/padics/relaxed_template.pxi b/src/sage/rings/padics/relaxed_template.pxi index 7269da0f8f2..f87034e56e3 100644 --- a/src/sage/rings/padics/relaxed_template.pxi +++ b/src/sage/rings/padics/relaxed_template.pxi @@ -4030,7 +4030,7 @@ cdef class RelaxedElement_zeroone(RelaxedElementWithDigits): return ERROR_NOTDEFINED -cdef class ExpansionIter(object): +cdef class ExpansionIter(): """ An iterator over a `p`-adic expansion. diff --git a/src/sage/rings/padics/relaxed_template_header.pxi b/src/sage/rings/padics/relaxed_template_header.pxi index 4e3f7f825df..5425c11c45d 100644 --- a/src/sage/rings/padics/relaxed_template_header.pxi +++ b/src/sage/rings/padics/relaxed_template_header.pxi @@ -141,7 +141,7 @@ cdef class RelaxedElement_zeroone(RelaxedElementWithDigits): cdef void _setdigit_to_zero(self) cdef void _setdigit_to_one(self) -cdef class ExpansionIter(object): +cdef class ExpansionIter(): cdef RelaxedElement elt cdef expansion_mode mode cdef long start diff --git a/src/sage/rings/valuation/valuation.py b/src/sage/rings/valuation/valuation.py index 8256963d819..4cbe63fe2f9 100644 --- a/src/sage/rings/valuation/valuation.py +++ b/src/sage/rings/valuation/valuation.py @@ -1016,7 +1016,7 @@ def _ge_(self, other): return super(DiscreteValuation, self)._ge_(other) -class MacLaneApproximantNode(object): +class MacLaneApproximantNode(): r""" A node in the tree computed by :meth:`DiscreteValuation.mac_lane_approximants` diff --git a/src/sage/structure/coerce.pyx b/src/sage/structure/coerce.pyx index 884e14b5ed7..2ee2548cf59 100644 --- a/src/sage/structure/coerce.pyx +++ b/src/sage/structure/coerce.pyx @@ -1142,7 +1142,7 @@ cdef class CoercionModel: TESTS:: - sage: class Foo(object): + sage: class Foo(): ....: def __rmul__(self, left): ....: return 'hello' sage: H = Foo() @@ -1155,7 +1155,7 @@ cdef class CoercionModel: ... TypeError: unsupported operand parent(s) for *: '' and 'Integer Ring' - sage: class Nonsense(object): + sage: class Nonsense(): ....: def __init__(self, s): ....: self.s = s ....: def __repr__(self): @@ -1945,7 +1945,7 @@ cdef class CoercionModel: We support non-Sage types with the usual Python convention:: - sage: class AlwaysEqual(object): + sage: class AlwaysEqual(): ....: def __eq__(self, other): ....: return True sage: x = AlwaysEqual() diff --git a/src/sage/structure/dynamic_class.py b/src/sage/structure/dynamic_class.py index 434c2968f8d..cf165745243 100644 --- a/src/sage/structure/dynamic_class.py +++ b/src/sage/structure/dynamic_class.py @@ -166,7 +166,7 @@ def dynamic_class(name, bases, cls=None, reduction=None, doccls=None, sage: from sage.misc.lazy_attribute import lazy_attribute sage: from sage.misc.cachefunc import cached_function sage: from sage.structure.dynamic_class import dynamic_class - sage: class Foo(object): + sage: class Foo(): ....: "The Foo class" ....: def __init__(self, x): ....: self._x = x diff --git a/src/sage/structure/factory.pyx b/src/sage/structure/factory.pyx index 9a7f762646b..76fcc698bf7 100644 --- a/src/sage/structure/factory.pyx +++ b/src/sage/structure/factory.pyx @@ -590,7 +590,7 @@ def register_factory_unpickle(name, callable): sage: from sage.structure.factory import UniqueFactory, register_factory_unpickle sage: import __main__ - sage: class OldStuff(object): + sage: class OldStuff(): ....: def __init__(self, n, **extras): ....: self.n = n ....: def __repr__(self): @@ -661,7 +661,7 @@ def generic_factory_unpickle(factory, *args): sage: from sage.structure.factory import UniqueFactory sage: import __main__ - sage: class OldStuff(object): + sage: class OldStuff(): ....: def __init__(self, n, **extras): ....: self.n = n ....: def __repr__(self): diff --git a/src/sage/structure/global_options.py b/src/sage/structure/global_options.py index e2ee4834050..6a47ba55b1d 100644 --- a/src/sage/structure/global_options.py +++ b/src/sage/structure/global_options.py @@ -105,7 +105,7 @@ illustrated by an example:: sage: from sage.structure.global_options import GlobalOptions - sage: class Menu(object): + sage: class Menu(): ....: class options(GlobalOptions): ....: ''' ....: Fancy documentation @@ -393,7 +393,7 @@ class options(GlobalOptions): Check that the old call syntax still works:: - sage: class Menu(object): + sage: class Menu(): ....: options = GlobalOptions('menu', ....: doc='Fancy documentation\n'+'-'*19, end_doc='The END!', ....: entree=dict(default='soup', @@ -514,7 +514,7 @@ class options(GlobalOptions): from sage.misc.instancedoc import instancedoc -class Option(object): +class Option(): r""" An option. @@ -884,7 +884,7 @@ class GlobalOptions(metaclass=GlobalOptionsMeta): EXAMPLES:: sage: from sage.structure.global_options import GlobalOptions - sage: class Menu(object): + sage: class Menu(): ....: class options(GlobalOptions): ....: ''' ....: Fancy documentation @@ -1707,7 +1707,7 @@ def _reset(self, option=None): EXAMPLES:: sage: from sage.structure.global_options import GlobalOptions - sage: class Meal(object): + sage: class Meal(): ....: class options(GlobalOptions): ....: NAME = 'daily meal' ....: food = dict(default='bread', values=dict(bread='rye bread', salmon='a fish')) diff --git a/src/sage/structure/graphics_file.py b/src/sage/structure/graphics_file.py index d4adefba9e9..50c200804fe 100644 --- a/src/sage/structure/graphics_file.py +++ b/src/sage/structure/graphics_file.py @@ -16,7 +16,7 @@ deprecation(32988, 'the module sage.structure.graphics_file is deprecated') -class Mime(object): +class Mime(): TEXT = 'text/plain' HTML = 'text/html' LATEX = 'text/latex' diff --git a/src/sage/structure/indexed_generators.py b/src/sage/structure/indexed_generators.py index 2abac83fcea..da04658324f 100644 --- a/src/sage/structure/indexed_generators.py +++ b/src/sage/structure/indexed_generators.py @@ -14,7 +14,7 @@ from sage.structure.category_object import normalize_names -class IndexedGenerators(object): +class IndexedGenerators(): r"""nodetex Abstract base class for parents whose elements consist of generators indexed by an arbitrary set. diff --git a/src/sage/structure/mutability.pyx b/src/sage/structure/mutability.pyx index 3d54c790263..b35d26a3ccb 100644 --- a/src/sage/structure/mutability.pyx +++ b/src/sage/structure/mutability.pyx @@ -257,7 +257,7 @@ def require_mutable(f): EXAMPLES:: sage: from sage.structure.mutability import require_mutable, require_immutable - sage: class A(object): + sage: class A(): ....: def __init__(self, val): ....: self._m = val ....: @require_mutable @@ -309,7 +309,7 @@ def require_immutable(f): EXAMPLES:: sage: from sage.structure.mutability import require_mutable, require_immutable - sage: class A(object): + sage: class A(): ....: def __init__(self, val): ....: self._m = val ....: @require_mutable diff --git a/src/sage/structure/proof/proof.py b/src/sage/structure/proof/proof.py index cef06ab460d..c667704db92 100644 --- a/src/sage/structure/proof/proof.py +++ b/src/sage/structure/proof/proof.py @@ -190,7 +190,7 @@ def get_flag(t = None, subsystem = None): return t -class WithProof(object): +class WithProof(): """ Use WithProof to temporarily set the value of one of the proof systems for a block of code, with a guarantee that it will be set diff --git a/src/sage/structure/richcmp.pyx b/src/sage/structure/richcmp.pyx index f4a52c3e87f..80dab931ba9 100644 --- a/src/sage/structure/richcmp.pyx +++ b/src/sage/structure/richcmp.pyx @@ -325,7 +325,7 @@ def richcmp_method(cls): sage: C("left") == C("right") # Calls __eq__ from class A left == right - sage: class Base(object): + sage: class Base(): ....: def __eq__(self, other): ....: return False sage: @richcmp_method @@ -343,7 +343,7 @@ def richcmp_method(cls): TypeError: None is not a class sage: @richcmp_method - ....: class X(object): + ....: class X(): ....: def __eq__(self, other): ....: pass ....: def __richcmp__(self, other, op): @@ -444,7 +444,7 @@ def richcmp_by_eq_and_lt(eq_attr, lt_attr): sage: from sage.structure.richcmp import richcmp_method, richcmp_by_eq_and_lt sage: @richcmp_method - ....: class C(object): + ....: class C(): ....: __richcmp__ = richcmp_by_eq_and_lt("_eq", "_lt") ....: def _eq(self, other): ....: return True @@ -455,7 +455,7 @@ def richcmp_by_eq_and_lt(eq_attr, lt_attr): True sage: a > b # Calls b._lt(a) True - sage: class X(object): pass + sage: class X(): pass sage: x = X() sage: a == x # Does not call a._eq(x) because x does not have _eq False diff --git a/src/sage/structure/test_factory.py b/src/sage/structure/test_factory.py index 77a2ac80641..b45996c5a80 100644 --- a/src/sage/structure/test_factory.py +++ b/src/sage/structure/test_factory.py @@ -20,7 +20,7 @@ from sage.structure.factory import UniqueFactory -class A(object): +class A(): # something we can weakref pass diff --git a/src/sage/structure/unique_representation.py b/src/sage/structure/unique_representation.py index 5d8d4ad758b..9c0cae8a877 100644 --- a/src/sage/structure/unique_representation.py +++ b/src/sage/structure/unique_representation.py @@ -326,7 +326,7 @@ class will by default also be used as keys for the cache:: An example:: - sage: class C(object): + sage: class C(): ....: def __init__(self, t): ....: self.t = t ....: def __repr__(self): @@ -883,7 +883,7 @@ class CachedRepresentation(metaclass=ClasscallMetaclass): older pickles can still be reasonably unpickled. Let us create a (new style) class, and pickle one of its instances:: - sage: class MyClass4(object): + sage: class MyClass4(): ....: def __init__(self, value): ....: self.value = value sage: import __main__; __main__.MyClass4 = MyClass4 # Fake MyClass4 being defined in a python module From 344bdb4b9539d0229cfdf8fa48c64344227af979 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 27 May 2022 20:01:04 +0200 Subject: [PATCH 493/529] tweak tox.ini: activate more pycodestyle checks in cython files --- src/sage/graphs/base/boost_graph.pyx | 6 ++--- .../graphs/base/static_sparse_backend.pyx | 6 ++--- src/sage/graphs/base/static_sparse_graph.pyx | 4 +++- src/sage/graphs/connectivity.pyx | 10 ++++----- .../graphs/graph_decompositions/cutwidth.pyx | 4 ++-- src/sage/graphs/hyperbolicity.pyx | 12 +++++----- .../perm_gps/partn_ref/double_coset.pyx | 6 +++-- src/sage/libs/mpmath/ext_main.pyx | 9 +++++--- src/sage/matrix/matrix2.pyx | 22 +++++++++---------- src/sage/matrix/matrix_double_dense.pyx | 10 ++++----- src/sage/matrix/matrix_integer_dense.pyx | 2 +- src/sage/matrix/strassen.pyx | 8 ++++--- src/sage/matroids/lean_matrix.pyx | 2 +- src/sage/matroids/linear_matroid.pyx | 4 ++-- src/sage/matroids/matroid.pyx | 16 +++++++------- src/sage/modules/free_module_element.pyx | 3 ++- src/sage/modules/vector_integer_sparse.pyx | 3 ++- src/sage/modules/vector_modn_sparse.pyx | 3 ++- src/sage/modules/vector_rational_sparse.pyx | 3 ++- .../backends/interactivelp_backend.pyx | 6 +++-- src/sage/rings/bernoulli_mod_p.pyx | 5 ++--- src/sage/rings/complex_interval.pyx | 2 +- .../finite_rings/hom_finite_field_givaro.pyx | 8 +++++-- .../rings/padics/padic_generic_element.pyx | 6 +++-- .../rings/puiseux_series_ring_element.pyx | 6 +++-- src/sage/rings/sum_of_squares.pyx | 6 +++-- src/sage/sets/finite_set_map_cy.pyx | 3 ++- src/sage/stats/time_series.pyx | 3 ++- src/tox.ini | 2 +- 29 files changed, 103 insertions(+), 77 deletions(-) diff --git a/src/sage/graphs/base/boost_graph.pyx b/src/sage/graphs/base/boost_graph.pyx index 13fc6f4d83f..fe3c6b94d6f 100644 --- a/src/sage/graphs/base/boost_graph.pyx +++ b/src/sage/graphs/base/boost_graph.pyx @@ -580,7 +580,7 @@ cpdef bandwidth_heuristics(g, algorithm='cuthill_mckee'): # Tests for errors and trivial cases if not isinstance(g, Graph): raise TypeError("the input must be a Sage Graph") - if not algorithm in ['cuthill_mckee', 'king']: + if algorithm not in ['cuthill_mckee', 'king']: raise ValueError(f"unknown algorithm {algorithm!r}") if not g.num_edges(): return (0, list(g)) @@ -690,7 +690,7 @@ cpdef min_spanning_tree(g, if not isinstance(g, Graph): raise TypeError("the input must be a Sage Graph") - if not algorithm in ['Kruskal', 'Prim']: + if algorithm not in ['Kruskal', 'Prim']: raise ValueError("algorithm '%s' not yet implemented, please contribute" %(algorithm)) if g.allows_loops() or g.allows_multiple_edges(): @@ -2567,7 +2567,7 @@ cpdef diameter(G, algorithm=None, source=None, if algorithm is None: # default algorithm for diameter computation algorithm = 'DiFUB' - if not algorithm in ['2Dsweep', 'DiFUB']: + if algorithm not in ['2Dsweep', 'DiFUB']: raise ValueError("unknown algorithm for computing the diameter of directed graph") if source is None: diff --git a/src/sage/graphs/base/static_sparse_backend.pyx b/src/sage/graphs/base/static_sparse_backend.pyx index e6da26ea5f7..2e85c2290fe 100644 --- a/src/sage/graphs/base/static_sparse_backend.pyx +++ b/src/sage/graphs/base/static_sparse_backend.pyx @@ -1376,7 +1376,7 @@ cdef class StaticSparseBackend(CGraphBackend): for i in range(out_degree(cg.g, v)): u = cg.g.neighbors[v][i] - if not u in seen: + if u not in seen: yield self._vertex_to_labels[u] seen.add(u) @@ -1412,13 +1412,13 @@ cdef class StaticSparseBackend(CGraphBackend): if cg._directed: for i in range(out_degree(cg.g_rev, v)): u = cg.g_rev.neighbors[v][i] - if not u in seen: + if u not in seen: yield self._vertex_to_labels[u] seen.add(u) else: for i in range(out_degree(cg.g, v)): u = cg.g.neighbors[v][i] - if not u in seen: + if u not in seen: yield self._vertex_to_labels[u] seen.add(u) diff --git a/src/sage/graphs/base/static_sparse_graph.pyx b/src/sage/graphs/base/static_sparse_graph.pyx index b5b07c1fa89..2ca7956654d 100644 --- a/src/sage/graphs/base/static_sparse_graph.pyx +++ b/src/sage/graphs/base/static_sparse_graph.pyx @@ -1215,7 +1215,9 @@ def spectral_radius(G, prec=1e-10): v2[i] += v1[p[0]] p += 1 s += v2[i] - v3 = v1; v1 = v2; v2 = v3 + v3 = v1 + v1 = v2 + v2 = v3 sig_off() finally: diff --git a/src/sage/graphs/connectivity.pyx b/src/sage/graphs/connectivity.pyx index df6af77ce0d..2a17674bf4e 100644 --- a/src/sage/graphs/connectivity.pyx +++ b/src/sage/graphs/connectivity.pyx @@ -481,7 +481,7 @@ def blocks_and_cut_vertices(G, algorithm="Tarjan_Boost", sort=False): seen.add(v) # The first time we meet v - if not v in number: + if v not in number: # We number the vertices in the order they are reached # during DFS number[v] = num @@ -495,7 +495,7 @@ def blocks_and_cut_vertices(G, algorithm="Tarjan_Boost", sort=False): # If we never met w before, we remember the direction of # edge vw, and add w to the stack. - if not w in number: + if w not in number: edge_stack.append((v,w)) stack.append(w) @@ -730,7 +730,7 @@ def is_cut_edge(G, u, v=None, label=None): if g.is_directed(): # (u,v) is a cut-edge if u is not in the connected # component containing v of self-(u,v) - sol = not u in connected_component_containing_vertex(g,v) + sol = u not in connected_component_containing_vertex(g, v) else: # (u,v) is a cut-edge if there is no path from u to v in # self-(u,v) @@ -809,7 +809,7 @@ def is_cut_vertex(G, u, weak=False): if not isinstance(G, GenericGraph): raise TypeError("the input must be a Sage graph") - if not u in G: + if u not in G: raise ValueError("vertex ({0}) is not a vertex of the graph".format(repr(u))) # Initialization @@ -2118,7 +2118,7 @@ def cleave(G, cut_vertices=None, virtual_edges=True, solver=None, verbose=0, else: cut_vertices = list(cut_vertices) for u in cut_vertices: - if not u in G: + if u not in G: raise ValueError("vertex {} is not a vertex of the input graph".format(u)) H = G.copy(immutable=False) diff --git a/src/sage/graphs/graph_decompositions/cutwidth.pyx b/src/sage/graphs/graph_decompositions/cutwidth.pyx index 9b1711107e9..3a329fbe3d3 100644 --- a/src/sage/graphs/graph_decompositions/cutwidth.pyx +++ b/src/sage/graphs/graph_decompositions/cutwidth.pyx @@ -388,7 +388,7 @@ def cutwidth(G, algorithm="exponential", cut_off=0, solver=None, verbose=False, if not isinstance(G, Graph): raise ValueError('the first parameter must be a Graph') - if not cut_off in ZZ: + if cut_off not in ZZ: raise ValueError("the specified cut off parameter must be an integer") elif G.size() <= cut_off: # We have a trivial solution @@ -502,7 +502,7 @@ def cutwidth_dyn(G, lower_bound=0): if G.order() >= 32: raise ValueError("the graph should have at most 31 vertices") - if not lower_bound in ZZ: + if lower_bound not in ZZ: raise ValueError("the specified lower bound must be an integer") cdef FastDigraph g = FastDigraph(G) diff --git a/src/sage/graphs/hyperbolicity.pyx b/src/sage/graphs/hyperbolicity.pyx index 06f2eb1ba58..40f934cfb08 100644 --- a/src/sage/graphs/hyperbolicity.pyx +++ b/src/sage/graphs/hyperbolicity.pyx @@ -351,8 +351,8 @@ def _greedy_dominating_set(H, verbose=False): reverse=True, key=lambda x: x[0]) cdef list DOM = [] cdef set seen = set() - for _,u in V: - if not u in seen: + for _, u in V: + if u not in seen: seen.add(u) DOM.append(u) seen.update(H.neighbor_iterator(u)) @@ -1277,14 +1277,14 @@ def hyperbolicity(G, from sage.graphs.graph import Graph if not isinstance(G, Graph): raise ValueError("the input parameter must be a Graph") - if not algorithm in ['basic', 'CCL', 'CCL+FA', 'BCCM', 'dom']: + if algorithm not in ['basic', 'CCL', 'CCL+FA', 'BCCM', 'dom']: raise ValueError("algorithm '%s' not yet implemented, please contribute" %(algorithm)) if approximation_factor is None: approximation_factor = 1.0 elif approximation_factor == 1.0: pass elif algorithm in ['CCL', 'CCL+FA', 'BCCM']: - if not approximation_factor in RR or approximation_factor < 1.0: + if approximation_factor not in RR or approximation_factor < 1.0: raise ValueError("the approximation factor must be >= 1.0") else: raise ValueError("the approximation_factor is ignored when using" @@ -1294,7 +1294,7 @@ def hyperbolicity(G, elif additive_gap == 0.0: pass elif algorithm in ['CCL', 'CCL+FA', 'BCCM']: - if not additive_gap in RR or additive_gap < 0.0: + if additive_gap not in RR or additive_gap < 0.0: raise ValueError("the additive gap must be a real positive number") else: raise ValueError("the additive_gap is ignored when using the '%s' algorithm." %(algorithm)) @@ -1431,7 +1431,7 @@ def hyperbolicity(G, # We set null distances to vertices outside DOM. This way these # vertices will not be considered anymore. for i in range(N): - if not i in DOM_int: + if i not in DOM_int: for j in range(N): distances[i][j] = 0 distances[j][i] = 0 diff --git a/src/sage/groups/perm_gps/partn_ref/double_coset.pyx b/src/sage/groups/perm_gps/partn_ref/double_coset.pyx index b197321e084..6daef964ebc 100644 --- a/src/sage/groups/perm_gps/partn_ref/double_coset.pyx +++ b/src/sage/groups/perm_gps/partn_ref/double_coset.pyx @@ -436,9 +436,11 @@ cdef int double_coset(void *S1, void *S2, PartitionStack *partition1, int *order j = refine_also_by_orbits(current_ps, S2, refine_and_return_invariant, cells_to_refine_by, j, group, perm_stack) if k != j: - possible = 0; unknown = 0 + possible = 0 + unknown = 0 elif not stacks_are_equivalent(left_ps, current_ps): - possible = 0; unknown = 0 + possible = 0 + unknown = 0 else: PS_move_all_mins_to_front(current_ps) diff --git a/src/sage/libs/mpmath/ext_main.pyx b/src/sage/libs/mpmath/ext_main.pyx index 7ba4fb1c17b..81abdf0cd4b 100644 --- a/src/sage/libs/mpmath/ext_main.pyx +++ b/src/sage/libs/mpmath/ext_main.pyx @@ -76,9 +76,12 @@ cdef MPF MPF_C_0 cdef MPF MPF_C_1 cdef MPF MPF_C_2 -MPF_init(&MPF_C_0); MPF_set_zero(&MPF_C_0) -MPF_init(&MPF_C_1); MPF_set_si(&MPF_C_1, 1) -MPF_init(&MPF_C_2); MPF_set_si(&MPF_C_2, 2) +MPF_init(&MPF_C_0) +MPF_set_zero(&MPF_C_0) +MPF_init(&MPF_C_1) +MPF_set_si(&MPF_C_1, 1) +MPF_init(&MPF_C_2) +MPF_set_si(&MPF_C_2, 2) # Temporaries used for operands in binary operations cdef mpz_t tmp_mpz diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 90d87b6e49d..73c53348927 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -4407,7 +4407,7 @@ cdef class Matrix(Matrix1): algorithm = kwds.pop('algorithm', None) if algorithm is None: algorithm = 'default' - elif not algorithm in ['default', 'generic', 'flint', 'pari', 'padic', 'pluq']: + elif algorithm not in ['default', 'generic', 'flint', 'pari', 'padic', 'pluq']: raise ValueError("matrix kernel algorithm '%s' not recognized" % algorithm ) elif algorithm == 'padic' and not (is_IntegerRing(R) or is_RationalField(R)): raise ValueError("'padic' matrix kernel algorithm only available over the rationals and the integers, not over %s" % R) @@ -4424,7 +4424,7 @@ cdef class Matrix(Matrix1): basis = kwds.pop('basis', None) if basis is None: basis = 'echelon' - elif not basis in ['computed', 'echelon', 'pivot', 'LLL']: + elif basis not in ['computed', 'echelon', 'pivot', 'LLL']: raise ValueError("matrix kernel basis format '%s' not recognized" % basis ) elif basis == 'pivot' and R not in _Fields: raise ValueError('pivot basis only available over a field, not over %s' % R) @@ -5956,7 +5956,7 @@ cdef class Matrix(Matrix1): sage: A._eigenspace_format(None) == 'all' True """ - if not format in [None, 'all', 'galois']: + if format not in [None, 'all', 'galois']: msg = "format keyword must be None, 'all' or 'galois', not {0}" raise ValueError(msg.format(format)) @@ -6244,7 +6244,7 @@ cdef class Matrix(Matrix1): ... ValueError: algebraic_multiplicity keyword must be True or False """ - if not algebraic_multiplicity in [True, False]: + if algebraic_multiplicity not in [True, False]: msg = 'algebraic_multiplicity keyword must be True or False' raise ValueError(msg.format(algebraic_multiplicity)) if not self.is_square(): @@ -6486,7 +6486,7 @@ cdef class Matrix(Matrix1): ... ValueError: algebraic_multiplicity keyword must be True or False """ - if not algebraic_multiplicity in [True, False]: + if algebraic_multiplicity not in [True, False]: msg = 'algebraic_multiplicity keyword must be True or False' raise ValueError(msg.format(algebraic_multiplicity)) if not self.is_square(): @@ -8163,7 +8163,7 @@ cdef class Matrix(Matrix1): ... TypeError: subdivide must be True or False, not junk """ - if not subdivide in [True, False]: + if subdivide not in [True, False]: raise TypeError("subdivide must be True or False, not %s" % subdivide) R = self.base_ring() ident = self.matrix_space(self.nrows(), self.nrows()).one() @@ -12357,7 +12357,7 @@ cdef class Matrix(Matrix1): raise TypeError('polynomial variable must be a string or polynomial ring generator, not {0}'.format(var)) elif var.base_ring() != R: raise TypeError('polynomial generator must be over the same ring as the matrix entries') - if not basis in ['echelon', 'iterates']: + if basis not in ['echelon', 'iterates']: raise ValueError("basis format must be 'echelon' or 'iterates', not {0}".format(basis)) if not self.is_square(): raise TypeError('matrix must be square, not {0} x {1}'.format(self.nrows(), self.ncols())) @@ -13249,10 +13249,10 @@ cdef class Matrix(Matrix1): sage: P.base_ring() Finite Field of size 11 """ - if not pivot in [None, 'partial', 'nonzero']: + if pivot not in [None, 'partial', 'nonzero']: msg = "pivot strategy must be None, 'partial' or 'nonzero', not {0}" raise ValueError(msg.format(pivot)) - if not format in ['compact', 'plu']: + if format not in ['compact', 'plu']: msg = "format must be 'plu' or 'compact', not {0}" raise ValueError(msg.format(format)) @@ -13541,7 +13541,7 @@ cdef class Matrix(Matrix1): cdef Py_ssize_t m, i, j, k cdef Matrix L - if not algorithm in ['symmetric', 'hermitian']: + if algorithm not in ['symmetric', 'hermitian']: msg = "'algorithm' must be 'symmetric' or 'hermitian', not {0}" raise ValueError(msg.format(algorithm)) cache_string = 'indefinite_factorization_' + algorithm @@ -13551,7 +13551,7 @@ cdef class Matrix(Matrix1): if not self.is_square(): msg = "matrix must be square, not {0} x {1}" raise ValueError(msg.format(self.nrows(), self.ncols())) - if not algorithm in ['symmetric', 'hermitian']: + if algorithm not in ['symmetric', 'hermitian']: msg = "'algorithm' must be 'symmetric' or 'hermitian', not {0}" raise ValueError(msg.format(algorithm)) if not R.is_exact(): diff --git a/src/sage/matrix/matrix_double_dense.pyx b/src/sage/matrix/matrix_double_dense.pyx index d62c2f2c14b..d21e6713cc4 100644 --- a/src/sage/matrix/matrix_double_dense.pyx +++ b/src/sage/matrix/matrix_double_dense.pyx @@ -689,7 +689,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): p = sage.rings.integer.Integer(p) except TypeError: raise ValueError("matrix norm 'p' must be +/- infinity, 'frob' or an integer, not %s" % p) - if not p in [-2,-1,1,2]: + if p not in [-2, -1, 1, 2]: raise ValueError("matrix norm integer values of 'p' must be -2, -1, 1 or 2, not %s" % p) return sage.rings.real_double.RDF(numpy.linalg.norm(self._matrix_numpy, ord=p)) @@ -1301,7 +1301,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): tol = algorithm algorithm = other other = None - if not algorithm in ['default', 'symmetric', 'hermitian']: + if algorithm not in ['default', 'symmetric', 'hermitian']: msg = "algorithm must be 'default', 'symmetric', or 'hermitian', not {0}" raise ValueError(msg.format(algorithm)) if not self.is_square(): @@ -2347,7 +2347,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): raise TypeError('tolerance must be a real number, not {0}'.format(tol)) if tol <= 0: raise ValueError('tolerance must be positive, not {0}'.format(tol)) - if not algorithm in ['naive', 'orthonormal']: + if algorithm not in ['naive', 'orthonormal']: raise ValueError("algorithm must be 'naive' or 'orthonormal', not {0}".format(algorithm)) key = 'unitary_{0}_{1}'.format(algorithm, tol) b = self.fetch(key) @@ -2905,7 +2905,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): tol = float(tol) if tol <= 0: raise ValueError('tolerance must be positive, not {0}'.format(tol)) - if not algorithm in ['naive', 'orthonormal']: + if algorithm not in ['naive', 'orthonormal']: raise ValueError("algorithm must be 'naive' or 'orthonormal', not {0}".format(algorithm)) key = 'normal_{0}_{1}'.format(algorithm, tol) @@ -3200,7 +3200,7 @@ cdef class Matrix_double_dense(Matrix_numpy_dense): raise ValueError('Schur decomposition requires a square matrix, not a {0} x {1} matrix'.format(self.nrows(), self.ncols())) if base_ring is None: base_ring = self.base_ring() - if not base_ring in [RDF, CDF]: + if base_ring not in [RDF, CDF]: raise ValueError('base ring of Schur decomposition matrices must be RDF or CDF, not {0}'.format(base_ring)) if self.base_ring() != base_ring: diff --git a/src/sage/matrix/matrix_integer_dense.pyx b/src/sage/matrix/matrix_integer_dense.pyx index 9e35ce8395c..734f1b01964 100644 --- a/src/sage/matrix/matrix_integer_dense.pyx +++ b/src/sage/matrix/matrix_integer_dense.pyx @@ -4740,7 +4740,7 @@ cdef class Matrix_integer_dense(Matrix_dense): # Step 5: Apply p-adic solver C = B.matrix_from_columns(pivots) pivots_ = set(pivots) - non_pivots = [i for i in range(B.ncols()) if not i in pivots_] + non_pivots = [i for i in range(B.ncols()) if i not in pivots_] D = B.matrix_from_columns(non_pivots) t = verbose('calling %s solver'%solver, level=2, caller_name='p-adic echelon') if solver == 'iml': diff --git a/src/sage/matrix/strassen.pyx b/src/sage/matrix/strassen.pyx index cd7fe1fc684..cd343bd92e8 100644 --- a/src/sage/matrix/strassen.pyx +++ b/src/sage/matrix/strassen.pyx @@ -802,9 +802,11 @@ def test(n, m, R, c=2): 4 True """ from sage.matrix.constructor import matrix - A = matrix(R,n,m,range(n*m)) - B = A.__copy__(); B._echelon_in_place_classical() - C = A.__copy__(); C._echelon_strassen(c) + A = matrix(R, n, m, range(n * m)) + B = A.__copy__() + B._echelon_in_place_classical() + C = A.__copy__() + C._echelon_strassen(c) return B == C diff --git a/src/sage/matroids/lean_matrix.pyx b/src/sage/matroids/lean_matrix.pyx index 8ea413b9dd8..01aaefc2f27 100644 --- a/src/sage/matroids/lean_matrix.pyx +++ b/src/sage/matroids/lean_matrix.pyx @@ -397,7 +397,7 @@ cdef class LeanMatrix: return (left)._matrix_times_matrix_(right) else: return NotImplemented - if not left in (right).base_ring(): + if left not in (right).base_ring(): try: left = (right).base_ring()(left) except (TypeError, NotImplemented, ValueError): diff --git a/src/sage/matroids/linear_matroid.pyx b/src/sage/matroids/linear_matroid.pyx index bdc88768dde..917017f6afe 100644 --- a/src/sage/matroids/linear_matroid.pyx +++ b/src/sage/matroids/linear_matroid.pyx @@ -321,7 +321,7 @@ cdef class LinearMatroid(BasisExchangeMatroid): if keep_initial_representation: self._representation = A.copy() # Deprecated Sage matrix operation P = gauss_jordan_reduce(A, xrange(A.ncols())) - self._A = A.matrix_from_rows_and_columns(range(len(P)), [c for c in xrange(matrix.ncols()) if not c in P]) + self._A = A.matrix_from_rows_and_columns(range(len(P)), [c for c in xrange(matrix.ncols()) if c not in P]) else: reduced = True if not isinstance(reduced_matrix, LeanMatrix): @@ -5785,7 +5785,7 @@ cdef class RegularMatroid(LinearMatroid): if keep_initial_representation: self._representation = A.copy() # Deprecated Sage matrix operation P = gauss_jordan_reduce(A, xrange(A.ncols())) - self._A = A.matrix_from_rows_and_columns(range(len(P)), [c for c in xrange(matrix.ncols()) if not c in P]) + self._A = A.matrix_from_rows_and_columns(range(len(P)), [c for c in xrange(matrix.ncols()) if c not in P]) else: reduced = True if not isinstance(reduced_matrix, PlusMinusOneMatrix): diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index da767ea18f5..cef2804c2d0 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -1527,7 +1527,7 @@ cdef class Matroid(SageObject): B = frozenset(B) if not self.is_basis(B): raise ValueError("input B is not a basis of the matroid.") - if not e in self.groundset(): + if e not in self.groundset(): raise ValueError("input e is not an element of the groundset.") return self._fundamental_circuit(B, e) @@ -1897,7 +1897,7 @@ cdef class Matroid(SageObject): B = frozenset(B) if not self.is_basis(B): raise ValueError("input B is not a basis of the matroid.") - if not e in B: + if e not in B: raise ValueError("input e is not an element of B.") return self._fundamental_cocircuit(B, e) @@ -4390,13 +4390,13 @@ cdef class Matroid(SageObject): rH = self._rank(H) if rH < r: if rH + self._rank(FF.union(F)) == self._rank(FF) + r: - if not H in final_list: + if H not in final_list: temp_list.add(H) # Check upper closure (going just one level up) if r < self.full_rank() - 1: for e in self.groundset().difference(F): FF = self.closure(F.union([e])) - if self._rank(FF) > r and not FF in final_list: + if self._rank(FF) > r and FF not in final_list: temp_list.add(FF) final_list.add(F) return final_list @@ -7091,7 +7091,7 @@ cdef class Matroid(SageObject): out_neighbors[u] = other._circuit(Y.union([u])) - set([u]) # if u in X2 then out_neighbors[u] was set to empty for y in out_neighbors[u]: m2 = m + weights[y] - if not y in w or w[y] > m2: + if y not in w or w[y] > m2: predecessor[y] = u w[y] = m2 next_layer.add(y) @@ -7104,7 +7104,7 @@ cdef class Matroid(SageObject): out_neighbors[u] = X - self._closure(Y - set([u])) for x in out_neighbors[u]: m2 = m - weights[x] - if not x in w or w[x] > m2: + if x not in w or w[x] > m2: predecessor[x] = u w[x] = m2 next_layer.add(x) @@ -7256,7 +7256,7 @@ cdef class Matroid(SageObject): out_neighbors[u] = other._circuit(Y.union([u])) - set([u]) # if u in X2 then out_neighbors[u] was set to empty for y in out_neighbors[u]: m2 = m + 1 - if not y in w or w[y] > m2: + if y not in w or w[y] > m2: w[y] = m2 next_layer.add(y) todo = next_layer @@ -7275,7 +7275,7 @@ cdef class Matroid(SageObject): out_neighbors[u] = X - self._closure(Y - set([u])) for x in out_neighbors[u]: m2 = m - 1 - if not x in w or w[x] > m2: + if x not in w or w[x] > m2: w[x] = m2 next_layer.add(x) todo = next_layer diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index 9bc5a5c25e2..de627d5939a 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -2103,7 +2103,8 @@ cdef class FreeModuleElement(Vector): # abstract base class '(theta^3 + sqrt(2) + 1/2, 1/2)' """ cdef Py_ssize_t d = self._degree - if d == 0: return "()" + if d == 0: + return "()" # compute column widths S = [repr(x) for x in self.list(copy=False)] #width = max([len(x) for x in S]) diff --git a/src/sage/modules/vector_integer_sparse.pyx b/src/sage/modules/vector_integer_sparse.pyx index 7f94092a286..01c45059880 100644 --- a/src/sage/modules/vector_integer_sparse.pyx +++ b/src/sage/modules/vector_integer_sparse.pyx @@ -287,7 +287,8 @@ cdef int add_mpz_vector_init(mpz_vector* sum, # 1. Allocate memory: nz = v.num_nonzero + w.num_nonzero - if nz > v.degree: nz = v.degree + if nz > v.degree: + nz = v.degree mpz_vector_init(z, v.degree, nz) # 2. Merge entries i = 0 # index into entries of v diff --git a/src/sage/modules/vector_modn_sparse.pyx b/src/sage/modules/vector_modn_sparse.pyx index 5258c9a141a..746f9897db2 100644 --- a/src/sage/modules/vector_modn_sparse.pyx +++ b/src/sage/modules/vector_modn_sparse.pyx @@ -244,7 +244,8 @@ cdef int add_c_vector_modint_init(c_vector_modint* sum, c_vector_modint* v, # 1. Allocate memory: nz = v.num_nonzero + w.num_nonzero - if nz > v.degree: nz = v.degree + if nz > v.degree: + nz = v.degree init_c_vector_modint(z, v.p, v.degree, nz) # 2. Merge entries i = 0 # index into entries of v diff --git a/src/sage/modules/vector_rational_sparse.pyx b/src/sage/modules/vector_rational_sparse.pyx index 8b204b40e4f..78002a1a75f 100644 --- a/src/sage/modules/vector_rational_sparse.pyx +++ b/src/sage/modules/vector_rational_sparse.pyx @@ -294,7 +294,8 @@ cdef int add_mpq_vector_init(mpq_vector* sum, # 1. Allocate memory: nz = v.num_nonzero + w.num_nonzero - if nz > v.degree: nz = v.degree + if nz > v.degree: + nz = v.degree mpq_vector_init(z, v.degree, nz) # 2. Merge entries i = 0 # index into entries of v diff --git a/src/sage/numerical/backends/interactivelp_backend.pyx b/src/sage/numerical/backends/interactivelp_backend.pyx index f48853e7115..e431c604b0c 100644 --- a/src/sage/numerical/backends/interactivelp_backend.pyx +++ b/src/sage/numerical/backends/interactivelp_backend.pyx @@ -487,8 +487,10 @@ cdef class InteractiveLPBackend: """ A, b, c, x, constraint_types, variable_types, problem_type, ring, d = self._AbcxCVPRd() A = A.delete_rows((i,)) - b = list(b); del b[i] - constraint_types=list(constraint_types); del constraint_types[i] + b = list(b) + del b[i] + constraint_types = list(constraint_types) + del constraint_types[i] self.lp = InteractiveLPProblem(A, b, c, x, constraint_types, variable_types, problem_type, ring, objective_constant_term=d) diff --git a/src/sage/rings/bernoulli_mod_p.pyx b/src/sage/rings/bernoulli_mod_p.pyx index 514d32d6ec9..b46c6b41da1 100644 --- a/src/sage/rings/bernoulli_mod_p.pyx +++ b/src/sage/rings/bernoulli_mod_p.pyx @@ -39,10 +39,9 @@ from sage.rings.finite_rings.integer_mod_ring import Integers from sage.rings.bernmm import bernmm_bern_modp - def verify_bernoulli_mod_p(data): - """ - Computes checksum for Bernoulli numbers. + r""" + Compute checksum for Bernoulli numbers. It checks the identity diff --git a/src/sage/rings/complex_interval.pyx b/src/sage/rings/complex_interval.pyx index 38fcafd313c..c993ac687b2 100644 --- a/src/sage/rings/complex_interval.pyx +++ b/src/sage/rings/complex_interval.pyx @@ -732,7 +732,7 @@ cdef class ComplexIntervalFieldElement(sage.structure.element.FieldElement): return x def norm(self): - """ + r""" Return the norm of this complex number. If `c = a + bi` is a complex number, then the norm of `c` is defined as diff --git a/src/sage/rings/finite_rings/hom_finite_field_givaro.pyx b/src/sage/rings/finite_rings/hom_finite_field_givaro.pyx index 698c54e71b5..d79ea68fc25 100644 --- a/src/sage/rings/finite_rings/hom_finite_field_givaro.pyx +++ b/src/sage/rings/finite_rings/hom_finite_field_givaro.pyx @@ -82,8 +82,12 @@ cdef class SectionFiniteFieldHomomorphism_givaro(SectionFiniteFieldHomomorphism_ cdef long sb, sy while b != 0: q = a // b - sb = b; b = a-q*b; a = sb - sy = y; y = x-q*y; x = sy + sb = b + b = a - q * b + a = sb + sy = y + y = x - q * y + x = sy self._gcd = a if x < 0: diff --git a/src/sage/rings/padics/padic_generic_element.pyx b/src/sage/rings/padics/padic_generic_element.pyx index 9bacb7ce43a..5cf7d8a04f3 100644 --- a/src/sage/rings/padics/padic_generic_element.pyx +++ b/src/sage/rings/padics/padic_generic_element.pyx @@ -814,7 +814,8 @@ cdef class pAdicGenericElement(LocalGenericElement): p = R.prime() pow = self.add_bigoh(prec) arg = pow - denom = 1; trunc = prec + denom = 1 + trunc = prec if R.absolute_degree() == 1: # Special code for Zp and Qp while pow != 0: @@ -946,7 +947,8 @@ cdef class pAdicGenericElement(LocalGenericElement): # We compute b = 1 + x + x^p/p + x^(p^2)/p^2 + ... pow = self.add_bigoh(prec) b = 1 + pow - denom = 1; trunc = prec + denom = 1 + trunc = prec while pow != 0: trunc += e pow = (pow**p).add_bigoh(trunc) diff --git a/src/sage/rings/puiseux_series_ring_element.pyx b/src/sage/rings/puiseux_series_ring_element.pyx index d5a23016e53..aff90ee1f89 100644 --- a/src/sage/rings/puiseux_series_ring_element.pyx +++ b/src/sage/rings/puiseux_series_ring_element.pyx @@ -272,8 +272,10 @@ cdef class PuiseuxSeries(AlgebraElement): exponents = [ZZ(exp) for exp in set(laurent.exponents() + [laurent.prec()])] # sort exponents such that the largest will be replaced first - exp_pos = [exp for exp in exponents if exp >= 0]; exp_pos.sort(reverse=True) - exp_neg = [exp for exp in exponents if exp < 0]; exp_neg.sort() + exp_pos = [exp for exp in exponents if exp >= 0] + exp_pos.sort(reverse=True) + exp_neg = [exp for exp in exponents if exp < 0] + exp_neg.sort() exponents = exp_neg + exp_pos # replacing exponents diff --git a/src/sage/rings/sum_of_squares.pyx b/src/sage/rings/sum_of_squares.pyx index ccf8657df79..a1d3edcedef 100644 --- a/src/sage/rings/sum_of_squares.pyx +++ b/src/sage/rings/sum_of_squares.pyx @@ -66,7 +66,8 @@ cdef int two_squares_c(uint_fast32_t n, uint_fast32_t res[2]): # j = (j+nn/j)/2 jj = j*j if jj == nn: - res[0] = i<= mn and x <= mx: diff --git a/src/tox.ini b/src/tox.ini index 7e78ad2abee..15cc6d181e0 100644 --- a/src/tox.ini +++ b/src/tox.ini @@ -107,7 +107,7 @@ description = # See https://pycodestyle.pycqa.org/en/latest/intro.html#error-codes deps = pycodestyle commands = pycodestyle --select E111,E401,E701,E702,E703,W605,E711,E712,E713,E721,E722 {posargs:{toxinidir}/sage/} - pycodestyle --select E703 --filename *.pyx {posargs:{toxinidir}/sage/} + pycodestyle --select E111,E401,E703,E712,E713,E721,E722 --filename *.pyx {posargs:{toxinidir}/sage/} [pycodestyle] max-line-length = 160 From a297e3c63420fd7c269e10d8265a86bb814154c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 27 May 2022 21:54:08 +0200 Subject: [PATCH 494/529] some details inside one p-adic file --- .../polynomial_padic_capped_relative_dense.py | 154 +++++++++--------- 1 file changed, 77 insertions(+), 77 deletions(-) diff --git a/src/sage/rings/polynomial/padics/polynomial_padic_capped_relative_dense.py b/src/sage/rings/polynomial/padics/polynomial_padic_capped_relative_dense.py index 6eac70126dc..b58c485ec50 100644 --- a/src/sage/rings/polynomial/padics/polynomial_padic_capped_relative_dense.py +++ b/src/sage/rings/polynomial/padics/polynomial_padic_capped_relative_dense.py @@ -2,12 +2,12 @@ p-adic Capped Relative Dense Polynomials """ -#***************************************************************************** +# **************************************************************************** # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** import sage.rings.polynomial.polynomial_element_generic from sage.rings.polynomial.polynomial_element import Polynomial @@ -17,7 +17,7 @@ import sage.rings.integer_ring import sage.rings.padics.misc as misc import sage.rings.padics.precision_error as precision_error -import sage.rings.fraction_field_element as fraction_field_element +from sage.rings.fraction_field_element import FractionFieldElement import copy from sage.libs.pari.all import pari, pari_gen @@ -33,7 +33,7 @@ class Polynomial_padic_capped_relative_dense(Polynomial_generic_cdv, Polynomial_padic): - def __init__(self, parent, x=None, check=True, is_gen=False, construct = False, absprec = infinity, relprec = infinity): + def __init__(self, parent, x=None, check=True, is_gen=False, construct=False, absprec=infinity, relprec=infinity): """ TESTS:: @@ -65,7 +65,7 @@ def __init__(self, parent, x=None, check=True, is_gen=False, construct = False, parentbr = parent.base_ring() from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing if construct: - (self._poly, self._valbase, self._relprecs, self._normalized, self._valaddeds, self._list) = x #the last two of these may be None + (self._poly, self._valbase, self._relprecs, self._normalized, self._valaddeds, self._list) = x # the last two of these may be None return elif is_gen: self._poly = PolynomialRing(ZZ, parent.variable_name()).gen() @@ -76,15 +76,14 @@ def __init__(self, parent, x=None, check=True, is_gen=False, construct = False, self._list = None return - #First we list the types that are turned into Polynomials + # First we list the types that are turned into Polynomials if isinstance(x, ZZX): - x = Polynomial_integer_dense(PolynomialRing(ZZ, parent.variable_name()), x, construct = True) - elif isinstance(x, fraction_field_element.FractionFieldElement) and \ - x.denominator() == 1: - #Currently we ignore precision information in the denominator. This should be changed eventually + x = Polynomial_integer_dense(PolynomialRing(ZZ, parent.variable_name()), x, construct=True) + elif isinstance(x, FractionFieldElement) and x.denominator() == 1: + # Currently we ignore precision information in the denominator. This should be changed eventually x = x.numerator() - #We now coerce various types into lists of coefficients. There are fast pathways for some types of polynomials + # We now coerce various types into lists of coefficients. There are fast pathways for some types of polynomials if isinstance(x, Polynomial): if x.parent() is self.parent(): if absprec is not infinity or relprec is not infinity: @@ -104,7 +103,7 @@ def __init__(self, parent, x=None, check=True, is_gen=False, construct = False, p = parentbr.prime() self._relprecs = [c.valuation(p) + parentbr.precision_cap() for c in x.list()] self._comp_valaddeds() - self._normalized = len(self._valaddeds) == 0 or (min(self._valaddeds) == 0) + self._normalized = not self._valaddeds or min(self._valaddeds) == 0 self._list = None if absprec is not infinity or relprec is not infinity: self._adjust_prec_info(absprec, relprec) @@ -114,7 +113,7 @@ def __init__(self, parent, x=None, check=True, is_gen=False, construct = False, check = False elif isinstance(x, dict): zero = parentbr.zero() - n = max(x.keys()) if x else 0 + n = max(x) if x else 0 v = [zero] * (n + 1) for i, z in x.items(): v[i] = z @@ -126,7 +125,7 @@ def __init__(self, parent, x=None, check=True, is_gen=False, construct = False, # the type is, is to assume it coerces into the base_ring as a # constant polynomial elif not isinstance(x, list): - x = [x] # constant polynomial + x = [x] # constant polynomial # In contrast to other polynomials, the zero element is not distinguished # by having its list empty. Instead, it has list [0] @@ -136,8 +135,8 @@ def __init__(self, parent, x=None, check=True, is_gen=False, construct = False, x = [parentbr(z) for z in x] # Remove this -- for p-adics this is terrible, since it kills any non exact zero. - #if len(x) == 1 and not x[0]: - # x = [] + # if len(x) == 1 and not x[0]: + # x = [] self._list = x self._valaddeds = [a.valuation() for a in x] @@ -185,13 +184,13 @@ def _normalize(self): if val is infinity: pass elif val != 0: - self._relprecs = [max(prec - val,0) for prec in self._relprecs] - v = [Integer(0) if (e is infinity) else ((c // prime_pow(val)) % prime_pow(e)) for (c,e) in zip(selflist, self._relprecs)] + self._relprecs = [max(prec - val, 0) for prec in self._relprecs] + v = [Integer(0) if (e is infinity) else ((c // prime_pow(val)) % prime_pow(e)) for c, e in zip(selflist, self._relprecs)] self._poly = self._poly.parent()(v, check=False) self._valbase += val self._valaddeds = [c - val for c in self._valaddeds] else: - self._poly = self._poly.parent()([Integer(0) if (e is infinity) else (c % prime_pow(e)) for (c,e) in zip(selflist, self._relprecs)], check=False) + self._poly = self._poly.parent()([Integer(0) if (e is infinity) else (c % prime_pow(e)) for c, e in zip(selflist, self._relprecs)], check=False) self._normalized = True def _reduce_poly(self): @@ -223,14 +222,15 @@ def _comp_list(self): polylist = self._poly.list() polylen = len(polylist) self._list = [self.base_ring()(polylist[i], absprec=self._relprecs[i]) << self._valbase for i in range(polylen)] \ - + [self.base_ring()(0, absprec=self._relprecs[i] + self._valbase) for i in range(polylen, len(self._relprecs))] + + [self.base_ring()(0, absprec=self._relprecs[i] + self._valbase) for i in range(polylen, len(self._relprecs))] while self._list and self._list[-1]._is_exact_zero(): self._list.pop() def _comp_valaddeds(self): self._valaddeds = [] - for i in range(self._poly.degree() + 1): - tmp = self._poly.list()[i].valuation(self.parent().base_ring().prime()) + prime = self.parent().base_ring().prime() + for i, pli in enumerate(self._poly.list()): + tmp = pli.valuation(prime) if tmp is infinity or tmp > self._relprecs[i]: self._valaddeds.append(self._relprecs[i]) else: @@ -287,7 +287,7 @@ def _adjust_prec_info(self, absprec=infinity, relprec=infinity): # else: # relprec = relprec + [parent.base_ring().precision_cap()] * (preclen - len(relprec)) # self._relprec = [min(a, v + r) - self._val for (a, r, v) in zip(absprec, relprec, vallist)] -#Remember to normalize at the end if self._normalized is true because you need to reduce mod p^n +# Remember to normalize at the end if self._normalized is true because you need to reduce mod p^n def _getprecpoly(self, n): one = Integer(1) @@ -297,7 +297,7 @@ def _getvalpoly(self, n): one = Integer(1) if self._valaddeds is None: self._comp_valaddeds() - return self._poly.parent()([(0 if (c is infinity) else (one << (n * c))) for c in self._valaddeds] + \ + return self._poly.parent()([(0 if (c is infinity) else (one << (n * c))) for c in self._valaddeds] + [(0 if (c is infinity) else (one << (n * c))) for c in self._relprecs[len(self._valaddeds):]]) def list(self, copy=True): @@ -413,7 +413,7 @@ def __getitem__(self, n): if self._list is not None: return self._list[n] return self.base_ring()(self.base_ring().prime_pow(self._valbase) - * self._poly[n], absprec = self._valbase + self._relprecs[n]) + * self._poly[n], absprec=self._valbase + self._relprecs[n]) def _add_(self, right): """ @@ -441,13 +441,13 @@ def _add_(self, right): else: baseval = self._valbase # Currently we don't reduce the coefficients of the answer modulo the appropriate power of p or normalize - return Polynomial_padic_capped_relative_dense(self.parent(), \ - (selfpoly + rightpoly, \ - baseval, \ - [min(a + self._valbase - baseval, b + right._valbase - baseval) for (a, b) in - zip(_extend_by_infinity(self._relprecs, max(len(self._relprecs), len(right._relprecs))), \ - _extend_by_infinity(right._relprecs, max(len(self._relprecs), len(right._relprecs))))], \ - False, None, None), construct = True) + return Polynomial_padic_capped_relative_dense(self.parent(), + (selfpoly + rightpoly, + baseval, + [min(a + self._valbase - baseval, b + right._valbase - baseval) + for (a, b) in zip(_extend_by_infinity(self._relprecs, max(len(self._relprecs), len(right._relprecs))), + _extend_by_infinity(right._relprecs, max(len(self._relprecs), len(right._relprecs))))], + False, None, None), construct=True) def _sub_(self, right): """ @@ -475,13 +475,13 @@ def _sub_(self, right): else: baseval = self._valbase # Currently we don't reduce the coefficients of the answer modulo the appropriate power of p or normalize - return Polynomial_padic_capped_relative_dense(self.parent(), \ - (selfpoly - rightpoly, \ - baseval, \ - [min(a + self._valbase - baseval, b + right._valbase - baseval) for (a, b) in - zip(_extend_by_infinity(self._relprecs, max(len(self._relprecs), len(right._relprecs))), \ - _extend_by_infinity(right._relprecs, max(len(self._relprecs), len(right._relprecs))))], \ - False, None, None), construct = True) + return Polynomial_padic_capped_relative_dense(self.parent(), + (selfpoly - rightpoly, + baseval, + [min(a + self._valbase - baseval, b + right._valbase - baseval) + for (a, b) in zip(_extend_by_infinity(self._relprecs, max(len(self._relprecs), len(right._relprecs))), + _extend_by_infinity(right._relprecs, max(len(self._relprecs), len(right._relprecs))))], + False, None, None), construct=True) def _mul_(self, right): r""" @@ -549,7 +549,7 @@ def _mul_(self, right): self._normalize() right._normalize() zzpoly = self._poly * right._poly - if len(self._relprecs) == 0 or len(right._relprecs) == 0: + if not self._relprecs or len(right._relprecs) == 0: return self.parent()(0) n = Integer(len(self._relprecs) + len(right._relprecs) - 1).exact_log(2) + 1 precpoly1 = self._getprecpoly(n) * right._getvalpoly(n) @@ -557,7 +557,7 @@ def _mul_(self, right): # These two will be the same length tn = Integer(1) << n preclist = [min(a.valuation(tn), b.valuation(tn)) for (a, b) in zip(precpoly1.list(), precpoly2.list())] - answer = Polynomial_padic_capped_relative_dense(self.parent(), (zzpoly, self._valbase + right._valbase, preclist, False, None, None), construct = True) + answer = Polynomial_padic_capped_relative_dense(self.parent(), (zzpoly, self._valbase + right._valbase, preclist, False, None, None), construct=True) answer._reduce_poly() return answer @@ -588,8 +588,8 @@ def _rmul_(self, left): elif left._is_exact_zero(): return Polynomial_padic_capped_relative_dense(self.parent(), []) else: - return Polynomial_padic_capped_relative_dense(self.parent(), (self._poly.parent()(0), self._valbase + left.valuation(), self._valaddeds, False, self._valaddeds, None), construct = True) - return Polynomial_padic_capped_relative_dense(self.parent(), (self._poly._rmul_(unit), self._valbase + val, relprecs, False, self._valaddeds, None), construct = True) + return Polynomial_padic_capped_relative_dense(self.parent(), (self._poly.parent()(0), self._valbase + left.valuation(), self._valaddeds, False, self._valaddeds, None), construct=True) + return Polynomial_padic_capped_relative_dense(self.parent(), (self._poly._rmul_(unit), self._valbase + val, relprecs, False, self._valaddeds, None), construct=True) def _neg_(self): """ @@ -603,9 +603,9 @@ def _neg_(self): sage: -a (12 + 12*13 + O(13^2))*t^4 + (12*13 + 12*13^2 + O(13^3))*t^2 + 9 + 12*13 + O(13^2) """ - return Polynomial_padic_capped_relative_dense(self.parent(), (-self._poly, self._valbase, self._relprecs, False, self._valaddeds, None), construct = True) + return Polynomial_padic_capped_relative_dense(self.parent(), (-self._poly, self._valbase, self._relprecs, False, self._valaddeds, None), construct=True) - def lshift_coeffs(self, shift, no_list = False): + def lshift_coeffs(self, shift, no_list=False): """ Return a new polynomials whose coefficients are multiplied by p^shift. @@ -620,9 +620,9 @@ def lshift_coeffs(self, shift, no_list = False): if shift < 0: return self.rshift_coeffs(-shift, no_list) if no_list or self._list is None: - return Polynomial_padic_capped_relative_dense(self.parent(), (self._poly, self._valbase + shift, self._relprecs, False, self._valaddeds, None), construct = True) + return Polynomial_padic_capped_relative_dense(self.parent(), (self._poly, self._valbase + shift, self._relprecs, False, self._valaddeds, None), construct=True) else: - return Polynomial_padic_capped_relative_dense(self.parent(), (self._poly, self._valbase + shift, self._relprecs, False, self._valaddeds, [c.__lshift__(shift) for c in self._list]), construct = True) + return Polynomial_padic_capped_relative_dense(self.parent(), (self._poly, self._valbase + shift, self._relprecs, False, self._valaddeds, [c.__lshift__(shift) for c in self._list]), construct=True) def rshift_coeffs(self, shift, no_list=False): """ @@ -649,25 +649,25 @@ def rshift_coeffs(self, shift, no_list=False): [1 + O(13^4), O(13), O(13^2)] """ if shift < 0: - return self.lshift_coeffs(-shift, no_list) # We can't just absorb this into the next if statement because we allow rshift to preserve _normalized + return self.lshift_coeffs(-shift, no_list) # We can't just absorb this into the next if statement because we allow rshift to preserve _normalized if self.base_ring().is_field() or shift <= self._valbase: if no_list or self._list is None: - return Polynomial_padic_capped_relative_dense(self.parent(), (self._poly, self._valbase - shift, self._relprecs, self._normalized, self._valaddeds, None), construct = True) + return Polynomial_padic_capped_relative_dense(self.parent(), (self._poly, self._valbase - shift, self._relprecs, self._normalized, self._valaddeds, None), construct=True) else: - return Polynomial_padic_capped_relative_dense(self.parent(), (self._poly, self._valbase - shift, self._relprecs, self._normalized, self._valaddeds, [c.__rshift__(shift) for c in self._list]), construct = True) + return Polynomial_padic_capped_relative_dense(self.parent(), (self._poly, self._valbase - shift, self._relprecs, self._normalized, self._valaddeds, [c.__rshift__(shift) for c in self._list]), construct=True) else: shift = shift - self._valbase fdiv = self.base_ring().prime_pow(shift) - return Polynomial_padic_capped_relative_dense(self.parent(), (self._poly // fdiv, 0, [0 if a <= shift else a - shift for a in self._relprecs], False, None, None), construct = True) + return Polynomial_padic_capped_relative_dense(self.parent(), (self._poly // fdiv, 0, [0 if a <= shift else a - shift for a in self._relprecs], False, None, None), construct=True) - #def __floordiv__(self, right): - # if is_Polynomial(right) and right.is_constant() and right[0] in self.base_ring(): - # d = self.base_ring()(right[0]) - # elif (right in self.base_ring()): - # d = self.base_ring()(right) - # else: - # raise NotImplementedError - # return self._rmul_(self.base_ring()(~d.unit_part())).rshift_coeffs(d.valuation()) + # def __floordiv__(self, right): + # if is_Polynomial(right) and right.is_constant() and right[0] in self.base_ring(): + # d = self.base_ring()(right[0]) + # elif (right in self.base_ring()): + # d = self.base_ring()(right) + # else: + # raise NotImplementedError + # return self._rmul_(self.base_ring()(~d.unit_part())).rshift_coeffs(d.valuation()) def _unsafe_mutate(self, n, value): """ @@ -747,7 +747,7 @@ def __copy__(self): """ Return a copy of ``self``. """ - return Polynomial_padic_capped_relative_dense(self.parent(), (copy.copy(self._poly), self._valbase, copy.copy(self._relprecs), self._normalized, copy.copy(self._valaddeds), copy.copy(self._list)), construct = True) + return Polynomial_padic_capped_relative_dense(self.parent(), (copy.copy(self._poly), self._valbase, copy.copy(self._relprecs), self._normalized, copy.copy(self._valaddeds), copy.copy(self._list)), construct=True) def degree(self, secure=False): """ @@ -817,7 +817,7 @@ def prec_degree(self): """ return len(self._relprecs) - 1 - def precision_absolute(self, n = None): + def precision_absolute(self, n=None): """ Return absolute precision information about ``self``. @@ -846,7 +846,7 @@ def precision_absolute(self, n = None): return [c + self._valbase for c in self._relprecs] return self._relprecs[n] + self._valbase - def precision_relative(self, n = None): + def precision_relative(self, n=None): """ Return relative precision information about ``self``. @@ -910,7 +910,7 @@ def valuation_of_coefficient(self, n=None): self._comp_valaddeds() if n is None: self._normalize() - return [ c + self._valbase for c in self._valaddeds ] + return [c + self._valbase for c in self._valaddeds] n = int(n) if n < 0 or n >= len(self._relprecs): return infinity @@ -999,7 +999,7 @@ def reverse(self, degree=None): else: L = self._list[:(n + 1)] + [self.base_ring()(0)] * (n - self.prec_degree()) L.reverse() - return Polynomial_padic_capped_relative_dense(self.parent(), (self._poly.parent()(zzlist), self._valbase, relprec, self._normalized, valadded, L), construct = True) + return Polynomial_padic_capped_relative_dense(self.parent(), (self._poly.parent()(zzlist), self._valbase, relprec, self._normalized, valadded, L), construct=True) def rescale(self, a): r""" @@ -1041,7 +1041,7 @@ def rescale(self, a): zzpoly = self._poly.parent()(0) else: zzpoly = self._poly.rescale(Integer(a)) - return Polynomial_padic_capped_relative_dense(self.parent(), (zzpoly, self._valbase, relprec, False, valadded, None), construct = True) + return Polynomial_padic_capped_relative_dense(self.parent(), (zzpoly, self._valbase, relprec, False, valadded, None), construct=True) def quo_rem(self, right, secure=False): """ @@ -1070,7 +1070,7 @@ def quo_rem(self, right, secure=False): def _quo_rem_naive(self, right): """ - An implementation of quo_rem that doesn't have good run-time + An implementation of quo_rem that does not have good run-time or precision characteristics. A better one is :meth:`_quo_rem_list`. @@ -1107,7 +1107,7 @@ def _quo_rem_list(self, right, secure): b = right.list() db = right.degree(secure=secure) inv = ~b[db] - q = [ ] + q = [] for i in range(da, db - 1, -1): c = inv * a[i] q.append(c) @@ -1119,20 +1119,20 @@ def _quo_rem_list(self, right, secure): parent = PolynomialRing(K, name=self.parent().variable_name()) return parent(q), parent(a[:db]) - #def gcd(self, right): - # raise NotImplementedError + # def gcd(self, right): + # raise NotImplementedError - #def lcm(self, right): - # raise NotImplementedError + # def lcm(self, right): + # raise NotImplementedError - #def discriminant(self): - # raise NotImplementedError + # def discriminant(self): + # raise NotImplementedError def disc(self): return self.discriminant() - #def resultant(self): - # raise NotImplementedError + # def resultant(self): + # raise NotImplementedError def newton_polygon(self): r""" @@ -1325,6 +1325,6 @@ def _extend_by_infinity(L, n): def make_padic_poly(parent, x, version): if version == 0: - return parent(x, construct = True) + return parent(x, construct=True) else: raise ValueError("unknown pickling version") From c6fc3f38e7ae4b2b01bca6ba0c762a7a2bbefdd2 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 27 May 2022 17:38:41 -0700 Subject: [PATCH 495/529] src/sage/doctest/forker.py: Rewrite doctest without python 3.10 parenthesized context manager --- src/sage/doctest/forker.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/doctest/forker.py b/src/sage/doctest/forker.py index 39967cfbbe6..c0e2ba9c4b5 100644 --- a/src/sage/doctest/forker.py +++ b/src/sage/doctest/forker.py @@ -1705,8 +1705,8 @@ def parallel_dispatch(self): canceled:: sage: from tempfile import NamedTemporaryFile as NTF - sage: with ( NTF(suffix=".py", mode="w+t") as f1, - ....: NTF(suffix=".py", mode="w+t") as f2 ): + sage: with NTF(suffix=".py", mode="w+t") as f1, \ + ....: NTF(suffix=".py", mode="w+t") as f2: ....: _ = f1.write("'''\nsage: import time; time.sleep(60)\n'''") ....: f1.flush() ....: _ = f2.write("'''\nsage: True\nFalse\n'''") From fd21f2d1fa466dea5020110fae2d61f89446e67d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 28 May 2022 07:59:57 +0200 Subject: [PATCH 496/529] fix another mistake --- src/sage/misc/instancedoc.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/misc/instancedoc.pyx b/src/sage/misc/instancedoc.pyx index 91923bd905f..574287fefe9 100644 --- a/src/sage/misc/instancedoc.pyx +++ b/src/sage/misc/instancedoc.pyx @@ -261,7 +261,7 @@ cdef class InstanceDocDescriptor: Traceback (most recent call last): ... AttributeError: attribute '__doc__' of 'list' objects is not writable - sage: descr.__delete__() + sage: descr.__delete__(object) Traceback (most recent call last): ... AttributeError: attribute '__doc__' of 'type' objects is not writable From 4351efdb27bf702a4f55f9233c35b21bff6c4ac4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 28 May 2022 12:54:29 +0200 Subject: [PATCH 497/529] pep cleanup for giac and gp pexpect interfaces --- src/sage/interfaces/giac.py | 142 ++++++++++++++++++------------------ src/sage/interfaces/gp.py | 80 +++++++++----------- 2 files changed, 105 insertions(+), 117 deletions(-) diff --git a/src/sage/interfaces/giac.py b/src/sage/interfaces/giac.py index 73601ca7ff2..59fb8f54158 100644 --- a/src/sage/interfaces/giac.py +++ b/src/sage/interfaces/giac.py @@ -1,5 +1,6 @@ r""" Pexpect Interface to Giac + (You should prefer the cython interface: giacpy_sage and its libgiac command) (adapted by F. Han from William Stein and Gregg Musiker maple's interface) @@ -247,7 +248,8 @@ from sage.structure.richcmp import rich_to_bool -COMMANDS_CACHE = '%s/giac_commandlist_cache.sobj'%DOT_SAGE +COMMANDS_CACHE = '%s/giac_commandlist_cache.sobj' % DOT_SAGE + class Giac(Expect): r""" @@ -328,16 +330,17 @@ def __init__(self, maxread=None, script_subdirectory=None, server=None, server_t True """ Expect.__init__(self, - name = 'giac', - prompt = '[0-9]*>> ', - command = "giac --sage", - env = {"LANG": "C"}, - init_code= ['maple_mode(0);I:=i;'], # coercion could be broken in maple_mode - script_subdirectory = script_subdirectory, - restart_on_ctrlc = False, server = server, - server_tmpdir = server_tmpdir, - verbose_start = False, - logfile = logfile, + name='giac', + prompt='[0-9]*>> ', + command="giac --sage", + env={"LANG": "C"}, + init_code=['maple_mode(0);I:=i;'], # coercion could be broken in maple_mode + script_subdirectory=script_subdirectory, + restart_on_ctrlc=False, + server=server, + server_tmpdir=server_tmpdir, + verbose_start=False, + logfile=logfile, eval_using_file_cutoff=1000) def _function_class(self): @@ -362,7 +365,7 @@ def _keyboard_interrupt(self): self._expect.sendline(chr(3)) # send ctrl-c self._expect.expect(self._prompt) # self._expect.expect(self._prompt) - raise RuntimeError("Ctrl-c pressed while running %s"%self) + raise RuntimeError("Ctrl-c pressed while running %s" % self) def __reduce__(self): """ @@ -378,7 +381,7 @@ def __reduce__(self): def _read_in_file_command(self, filename): r""" - Returns the string used to read filename into Giac. + Return the string used to read filename into Giac. EXAMPLES:: @@ -450,7 +453,7 @@ def _install_hints(self): def expect(self): """ - Returns the pexpect object for this Giac session. + Return the pexpect object for this Giac session. EXAMPLES:: @@ -483,7 +486,6 @@ def console(self): """ giac_console() - def completions(self, s): """ Return all commands that complete the command starting with the @@ -500,7 +502,7 @@ def completions(self, s): E = self._expect E.sendline('%s%s%s' % (s, chr(63), chr(13))) t = E.timeout - E.timeout=0.3 # since some things have no completion + E.timeout = 0.3 # since some things have no completion try: E.expect('----') except pexpect.TIMEOUT: @@ -525,8 +527,8 @@ def _commands(self): True """ try: - v = sum([self.completions(chr(65+n)) for n in range(26)], []) + \ - sum([self.completions(chr(97+n)) for n in range(26)], []) + v = sum([self.completions(chr(65 + n)) for n in range(26)], []) + \ + sum([self.completions(chr(97 + n)) for n in range(26)], []) except RuntimeError: print("\n" * 3) print("*" * 70) @@ -538,7 +540,7 @@ def _commands(self): def _tab_completion(self, verbose=True, use_disk_cache=True): """ - Returns a list of all the commands defined in Giac and optionally + Return a list of all the commands defined in Giac and optionally (per default) store them to disk. EXAMPLES:: @@ -570,11 +572,11 @@ def _tab_completion(self, verbose=True, use_disk_cache=True): sage.misc.persist.save(v, COMMANDS_CACHE) return v - def cputime(self, t=None): r""" - Returns the amount of CPU time that the Giac session has used. If - ``t`` is not None, then it returns the difference + Return the amount of CPU time that the Giac session has used. + + If ``t`` is not None, then it returns the difference between the current CPU time and ``t``. EXAMPLES:: @@ -590,8 +592,7 @@ def cputime(self, t=None): """ if t is None: return float(self('time()')) - else: - return float(self('time() - %s'%float(t))) + return float(self('time() - %s' % float(t))) def _eval_line(self, line, allow_use_file=True, wait_for_prompt=True, restart_if_needed=False): """ @@ -614,9 +615,9 @@ def _eval_line(self, line, allow_use_file=True, wait_for_prompt=True, restart_if """ with gc_disabled(): z = Expect._eval_line(self, line, allow_use_file=allow_use_file, - wait_for_prompt=wait_for_prompt) + wait_for_prompt=wait_for_prompt) if z.lower().find("error") != -1: - raise RuntimeError("An error occurred running a Giac command:\nINPUT:\n%s\nOUTPUT:\n%s"%(line, z)) + raise RuntimeError("an error occurred running a Giac command:\nINPUT:\n%s\nOUTPUT:\n%s" % (line, z)) lines = (line for line in z.splitlines() if not line.startswith('Evaluation time:')) return "\n".join(lines) @@ -660,10 +661,10 @@ def set(self, var, value): sage: giac.get('xx') '2' """ - cmd = '%s:=%s:;' % (var, value) #if giac is not in maple mode ( maple_mode(0)) + cmd = '%s:=%s:;' % (var, value) # if giac is not in maple mode ( maple_mode(0)) out = self.eval(cmd) if out.find("error") != -1: - raise TypeError("Error executing code in Giac\nCODE:\n\t%s\nGiac ERROR:\n\t%s"%(cmd, out)) + raise TypeError("error executing code in Giac\nCODE:\n\t%s\nGiac ERROR:\n\t%s" % (cmd, out)) def get(self, var): """ @@ -679,7 +680,7 @@ def get(self, var): def _object_class(self): """ - Returns the class of GiacElements. + Return the class of GiacElements. EXAMPLES:: @@ -696,7 +697,7 @@ def _object_class(self): def _function_element_class(self): """ - Returns the GiacFunctionElement class. + Return the GiacFunctionElement class. EXAMPLES:: @@ -713,7 +714,7 @@ def _function_element_class(self): def _equality_symbol(self): """ - Returns the symbol used for equality testing in Giac. + Return the symbol used for equality testing in Giac. EXAMPLES:: @@ -727,7 +728,7 @@ def _equality_symbol(self): def _true_symbol(self): """ - Returns the symbol used for truth in Giac. + Return the symbol used for truth in Giac. EXAMPLES:: @@ -743,7 +744,7 @@ def _true_symbol(self): def _assign_symbol(self): """ - Returns the symbol used for assignment in Giac. + Return the symbol used for assignment in Giac. EXAMPLES:: @@ -794,7 +795,7 @@ def clear(self, var): sage: giac.get('xx') 'xx' """ - self.eval('purge(%s)'%var) + self.eval('purge(%s)' % var) def version(self): """ @@ -813,7 +814,7 @@ def version(self): class GiacFunction(ExpectFunction): def _instancedoc_(self): """ - Returns the Giac help for this function. This gets called when + Return the Giac help for this function. This gets called when doing "?" on self. EXAMPLES:: @@ -829,7 +830,7 @@ def _instancedoc_(self): class GiacFunctionElement(FunctionElement): def _instancedoc_(self): """ - Returns the Giac help for this function. This gets called when + Return the Giac help for this function. This gets called when doing "?" on self. EXAMPLES:: @@ -845,7 +846,7 @@ def _instancedoc_(self): class GiacElement(ExpectElement): def __float__(self): """ - Returns a floating point version of self. + Return a floating point version of self. EXAMPLES:: @@ -869,15 +870,14 @@ def unapply(self, var): sage: g(1,2) 4 """ - return giac('unapply(%s,%s)'%(self,var)) - + return giac('unapply(%s,%s)' % (self, var)) def __hash__(self): """ - Returns a integer representing the hash of self. + Return an integer representing the hash of ``self``. These examples are optional, and require Giac to be installed. You - don't need to install any Sage packages for this. + do not need to install any Sage packages for this. EXAMPLES:: @@ -885,7 +885,7 @@ def __hash__(self): sage: hash(m) # random 4614285348919569149 """ - return hash(giac.eval('string(%s);'%self.name())) + return hash(giac.eval('string(%s);' % self.name())) def _richcmp_(self, other, op): """ @@ -926,14 +926,15 @@ def _richcmp_(self, other, op): False """ P = self.parent() - if P.eval("evalb(%s %s %s)"%(self.name(), P._equality_symbol(), - other.name())) == P._true_symbol(): + if P.eval("evalb(%s %s %s)" % (self.name(), P._equality_symbol(), + other.name())) == P._true_symbol(): return rich_to_bool(op, 0) - # (to be tested with giac). Maple does not allow comparing objects of different types and - # it raises an error in this case. + # (to be tested with giac). Maple does not allow comparing objects + # of different types and it raises an error in this case. # We catch the error, and return True for < try: - if P.eval("evalb(%s %s %s)"%(self.name(), P._lessthan_symbol(), other.name())) == P._true_symbol(): + if P.eval("evalb(%s %s %s)" % (self.name(), P._lessthan_symbol(), + other.name())) == P._true_symbol(): return rich_to_bool(op, -1) except RuntimeError as e: msg = str(e) @@ -944,7 +945,7 @@ def _richcmp_(self, other, op): return rich_to_bool(op, 1) else: raise RuntimeError(e) - if P.eval("evalb(%s %s %s)"%(self.name(), P._greaterthan_symbol(), other.name())) == P._true_symbol(): + if P.eval("evalb(%s %s %s)" % (self.name(), P._greaterthan_symbol(), other.name())) == P._true_symbol(): return rich_to_bool(op, 1) return NotImplemented @@ -1018,18 +1019,17 @@ def _latex_(self): \frac{...x^{4}...-...y...}{...y^{2}-3...x...} """ - s = self.parent().eval('latex(%s)'%self.name()) + s = self.parent().eval('latex(%s)' % self.name()) if s.startswith('"'): s = s[1:] if s.endswith('"'): s = s[:-1] - s = s.strip() - return s + return s.strip() def _matrix_(self, R): r""" Return matrix over the (Sage) ring R determined by self, where self - should be a Giac matrix. + should be a Giac matrix. .. WARNING:: It is slow, do not convert big matrices. @@ -1057,7 +1057,7 @@ def _matrix_(self, R): entries = [[R(self[r, c]) for c in range(m)] for r in range(n)] return M(entries) - def _sage_(self, locals={}): + def _sage_(self, locals=None): r""" Convert a giac expression back to a Sage expression, if possible. @@ -1126,7 +1126,10 @@ def _sage_(self, locals={}): from sage.symbolic.expression import symbol_table from sage.calculus.calculus import symbolic_expression_from_string, SR_parser_giac - result = repr(self) # string representation + if locals is None: + locals = {} + + result = repr(self) # string representation if str(self.type()) not in ['DOM_LIST', 'vector', 'vecteur']: @@ -1137,10 +1140,10 @@ def _sage_(self, locals={}): try: return symbolic_expression_from_string(result, lsymbols, - accept_sequence=True, parser=SR_parser_giac) - + accept_sequence=True, + parser=SR_parser_giac) except Exception: - raise NotImplementedError("Unable to parse Giac output: %s" % result) + raise NotImplementedError("unable to parse Giac output: %s" % result) else: return [entry.sage() for entry in self] @@ -1158,8 +1161,8 @@ def integral(self, var='x', min=None, max=None): - ``max`` - default: None - Returns the definite integral if xmin is not None, otherwise - returns an indefinite integral. + This returns the definite integral if xmin is not None, otherwise + an indefinite integral. EXAMPLES:: @@ -1177,9 +1180,8 @@ def integral(self, var='x', min=None, max=None): """ if min is None: return giac('int(%s,%s)' % (self.name(), var)) - else: - if max is None: - raise ValueError("neither or both of min/max must be specified.") + if max is None: + raise ValueError("neither or both of min/max must be specified") return giac('int(%s,%s,%s,%s)' % (self.name(), var, giac(min), giac(max))) @@ -1197,8 +1199,8 @@ def sum(self, var, min=None, max=None): - ``max`` - default: None - Returns the definite integral if xmin is not None, otherwise - returns an indefinite integral. + This returns the definite integral if xmin is not None, otherwise + an indefinite integral. EXAMPLES:: @@ -1207,19 +1209,19 @@ def sum(self, var, min=None, max=None): """ if min is None: return giac('sum(%s,%s)' % (self.name(), var)) - else: - if max is None: - raise ValueError("neither or both of min/max must be specified.") - return giac('sum(%s,%s,%s,%s)' % (self.name(), var, - giac(min), giac(max))) + if max is None: + raise ValueError("neither or both of min/max must be specified") + return giac('sum(%s,%s,%s,%s)' % (self.name(), var, + giac(min), giac(max))) # An instance giac = Giac() + def reduce_load_Giac(): """ - Returns the giac object created in sage.interfaces.giac. + Return the giac object created in sage.interfaces.giac. EXAMPLES:: diff --git a/src/sage/interfaces/gp.py b/src/sage/interfaces/gp.py index 6d95499640e..ff925b0ac8e 100644 --- a/src/sage/interfaces/gp.py +++ b/src/sage/interfaces/gp.py @@ -138,7 +138,9 @@ # http://www.gnu.org/licenses/ # ########################################################################## +import os +from sage.env import DOT_SAGE from .expect import Expect, ExpectElement, ExpectFunction, FunctionElement from sage.misc.verbose import verbose from sage.interfaces.tab_completion import ExtraTabCompletion @@ -200,16 +202,16 @@ def __init__(self, stacksize=10000000, # 10MB True """ Expect.__init__(self, - name = 'pari', - prompt = '\\? ', + name='pari', + prompt='\\? ', # --fast so the system gprc isn't read (we configure below) - command = "gp --fast --emacs --quiet --stacksize %s"%stacksize, - maxread = maxread, + command=f"gp --fast --emacs --quiet --stacksize {stacksize}", + maxread=maxread, server=server, server_tmpdir=server_tmpdir, - script_subdirectory = script_subdirectory, - restart_on_ctrlc = False, - verbose_start = False, + script_subdirectory=script_subdirectory, + restart_on_ctrlc=False, + verbose_start=False, logfile=logfile, eval_using_file_cutoff=1024) self.__seq = 0 @@ -332,7 +334,7 @@ def _read_in_file_command(self, filename): sage: gp.get('x').strip() '22' """ - return 'read("%s")'%filename + return 'read("%s")' % filename def _tab_completion(self): """ @@ -508,7 +510,7 @@ def set_default(self, var, value): 38 # 64-bit """ old = self.get_default(var) - self._eval_line('default(%s,%s)'%(var,value)) + self._eval_line('default(%s,%s)' % (var, value)) return old def get_default(self, var): @@ -536,7 +538,7 @@ def get_default(self, var): 28 # 32-bit 38 # 64-bit """ - return eval(self._eval_line('default(%s)'%var)) + return eval(self._eval_line('default(%s)' % var)) def set(self, var, value): """ @@ -553,11 +555,10 @@ def set(self, var, value): sage: gp.get('x') '2' """ - cmd = '%s=%s;'%(var,value) + cmd = '%s=%s;' % (var, value) out = self.eval(cmd) if out.find('***') != -1: - raise TypeError("Error executing code in GP:\nCODE:\n\t%s\nPARI/GP ERROR:\n%s"%(cmd, out)) - + raise TypeError("Error executing code in GP:\nCODE:\n\t%s\nPARI/GP ERROR:\n%s" % (cmd, out)) def get(self, var): """ @@ -573,7 +574,7 @@ def get(self, var): sage: gp.get('x') '2' """ - return self.eval('print(%s)'%var) + return self.eval('print(%s)' % var) def kill(self, var): """ @@ -592,20 +593,7 @@ def kill(self, var): sage: gp.get('xx') 'xx' """ - self.eval('kill(%s)'%var) - - #def xclear(self, var): - #""" - #Clear the variable named var. - #""" - #for varname based memory -- only 65000 variables and then dead. - #self.eval('kill(%s)'%var) - # for array-based memory this is best: - #self.eval('%s=0'%var) - # However, I've commented it out, since PARI doesn't seem - # to ever free any memory on its stack anyways. - # Killing variables as above takes a lot of time in some - # cases, also. + self.eval('kill(%s)' % var) def _next_var_name(self): """ @@ -631,20 +619,19 @@ def _next_var_name(self): ....: a = g(n) # long time sage: g('length(sage)') # long time 24000 - """ self.__seq += 1 if self.__seq >= self.__var_store_len: if self.__var_store_len == 0: - self.eval('sage=vector(%s,k,0);'%self.__init_list_length) + self.eval('sage=vector(%s,k,0);' % self.__init_list_length) self.__var_store_len = self.__init_list_length else: - self.eval('sage0=concat(sage, vector(%s,k,0));'%self.__var_store_len) + self.eval('sage0=concat(sage, vector(%s,k,0));' % self.__var_store_len) self.eval('sage=sage0;') self.eval('kill(sage0);') self.__var_store_len *= 2 - verbose("doubling PARI/sage object vector: %s"%self.__var_store_len) - return 'sage[%s]'%self.__seq + verbose("doubling PARI/sage object vector: %s" % self.__var_store_len) + return 'sage[%s]' % self.__seq def _reset_expect(self): """ @@ -788,9 +775,9 @@ def help(self, command): sage: gp.help('gcd') 'gcd(x,{y}): greatest common divisor of x and y.' """ - return self.eval('?%s'%command).strip() + return self.eval('?%s' % command).strip() - def new_with_bits_prec(self, s, precision = 0): + def new_with_bits_prec(self, s, precision=0): r""" Creates a GP object from s with ``precision`` bits of precision. GP actually automatically increases this precision to @@ -824,7 +811,7 @@ def new_with_bits_prec(self, s, precision = 0): """ if precision: old_prec = self.get_real_precision() - prec = int(precision/3.321928095) + prec = int(precision / 3.321928095) self.set_real_precision(prec) x = self(s) self.set_real_precision(old_prec) @@ -955,9 +942,7 @@ def __bool__(self): False """ P = self._check_valid() - return P.eval('%s != 0'%(self.name())) == '1' - - + return P.eval('%s != 0' % (self.name())) == '1' def _complex_mpfr_field_(self, CC): """ @@ -983,7 +968,7 @@ def _complex_mpfr_field_(self, CC): # Multiplying by CC(1) is necessary here since # sage: pari(gp(1+I)).sage().parent() # Maximal Order in Number Field in i with defining polynomial x^2 + 1 - return CC((CC(1)*pari(self)).sage()) + return CC((CC.one() * pari(self)).sage()) def _complex_double_(self, CDF): """ @@ -1031,9 +1016,9 @@ def __del__(self): # out of date, e.g., for matrices it uses \pmatrix (which # causes an error if amsmath is loaded) and for rationals # it does nothing, etc. - #def _latex_(self): - # P = self._check_valid() - # return P.eval('printtex(%s)'%self.name()) + # def _latex_(self): + # P = self._check_valid() + # return P.eval('printtex(%s)'%self.name()) def _tab_completion(self): """ @@ -1063,11 +1048,11 @@ def is_GpElement(x): """ return isinstance(x, GpElement) -from sage.env import DOT_SAGE -import os # An instance -gp = Gp(logfile=os.path.join(DOT_SAGE,'gp-expect.log')) # useful for debugging! +gp = Gp(logfile=os.path.join(DOT_SAGE, 'gp-expect.log')) +# useful for debugging! + def reduce_load_GP(): """ @@ -1081,6 +1066,7 @@ def reduce_load_GP(): """ return gp + def gp_console(): """ Spawn a new GP command-line session. @@ -1108,7 +1094,7 @@ def gp_version(): """ v = gp.eval(r'\v') i = v.find("Version ") - w = v[i+len("Version "):] + w = v[i + len("Version "):] i = w.find(' ') w = w[:i] t = tuple([int(n) for n in w.split('.')]) From da1b912dde67ce48c0dff125f670bcf94ab2e6f9 Mon Sep 17 00:00:00 2001 From: "Martin R. Albrecht" Date: Sat, 28 May 2022 16:09:48 +0100 Subject: [PATCH 498/529] change more version numbers for FP(y)LLL --- build/pkgs/fplll/spkg-configure.m4 | 2 +- build/pkgs/fpylll/install-requires.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/pkgs/fplll/spkg-configure.m4 b/build/pkgs/fplll/spkg-configure.m4 index d7cc77fe6c7..c220aecc60c 100644 --- a/build/pkgs/fplll/spkg-configure.m4 +++ b/build/pkgs/fplll/spkg-configure.m4 @@ -8,7 +8,7 @@ SAGE_SPKG_CONFIGURE([fplll], [ dnl Trac #31025: FPLLL/FPyLLL make no guarantee regarding compatibility dnl other than "whatever versions were released at the same time should work together" PKG_CHECK_MODULES([FPLLL], - [fplll >= 5.4.0 fplll <= 5.4.1], + [fplll >= 5.4.0 fplll <= 5.4.2], [ AC_MSG_CHECKING([whether BKZ default strategy JSON is installed]) AC_LANG_PUSH([C++]) diff --git a/build/pkgs/fpylll/install-requires.txt b/build/pkgs/fpylll/install-requires.txt index 0461a00816f..c1a9bf38bbb 100644 --- a/build/pkgs/fpylll/install-requires.txt +++ b/build/pkgs/fpylll/install-requires.txt @@ -1 +1 @@ -fpylll >=0.5.5, <=0.5.6 +fpylll >=0.5.6, <=0.5.7 From 11a0e571365129c66e2edc52dac3a0bca4adeccf Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 28 May 2022 10:23:44 -0700 Subject: [PATCH 499/529] build/bin/write-dockerfile.sh: Add bootstrap-conda --- build/bin/write-dockerfile.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/bin/write-dockerfile.sh b/build/bin/write-dockerfile.sh index 4e2f891d506..752a9c26f58 100755 --- a/build/bin/write-dockerfile.sh +++ b/build/bin/write-dockerfile.sh @@ -207,7 +207,7 @@ FROM with-system-packages as bootstrapped #:bootstrapping: RUN mkdir -p sage WORKDIR sage -$ADD Makefile VERSION.txt COPYING.txt condarc.yml README.md bootstrap configure.ac sage .homebrew-build-env tox.ini Pipfile.m4 ./ +$ADD Makefile VERSION.txt COPYING.txt condarc.yml README.md bootstrap bootstrap-conda configure.ac sage .homebrew-build-env tox.ini Pipfile.m4 ./ $ADD src/doc/bootstrap src/doc/bootstrap $ADD src/bin src/bin $ADD src/Pipfile.m4 src/pyproject.toml.m4 src/requirements.txt.m4 src/setup.cfg.m4 src/ From a5da84a2ce4dd5cb4fb1c97046a95fddc9b3281d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 28 May 2022 10:35:21 -0700 Subject: [PATCH 500/529] src/sage/misc/{abstract_method.py,lazy_attribute.pyx}: Update doctest output --- src/sage/misc/abstract_method.py | 2 +- src/sage/misc/lazy_attribute.pyx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/misc/abstract_method.py b/src/sage/misc/abstract_method.py index 49dc59ba9fa..cd7d0a7ca39 100644 --- a/src/sage/misc/abstract_method.py +++ b/src/sage/misc/abstract_method.py @@ -193,7 +193,7 @@ def _sage_src_lines_(self): sage: src[0] 'def banner():\n' sage: lines - 81 + 89 """ from sage.misc.sageinspect import sage_getsourcelines return sage_getsourcelines(self._f) diff --git a/src/sage/misc/lazy_attribute.pyx b/src/sage/misc/lazy_attribute.pyx index c6e7b5110bb..5584c620587 100644 --- a/src/sage/misc/lazy_attribute.pyx +++ b/src/sage/misc/lazy_attribute.pyx @@ -87,7 +87,7 @@ cdef class _lazy_attribute(object): sage: src[0] 'def banner():\n' sage: lines - 81 + 89 """ from sage.misc.sageinspect import sage_getsourcelines return sage_getsourcelines(self.f) From 3884373088e5cd92df05dff406a037a14abe7353 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 28 May 2022 10:37:16 -0700 Subject: [PATCH 501/529] src/sage/tests/cmdline.py: Update doctest for changed help message --- src/sage/tests/cmdline.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/tests/cmdline.py b/src/sage/tests/cmdline.py index fccba3f12fb..1570b9c9b6a 100644 --- a/src/sage/tests/cmdline.py +++ b/src/sage/tests/cmdline.py @@ -165,7 +165,7 @@ def test_executable(args, input="", timeout=100.0, pydebug_ignore_warnings=False Test help:: sage: (out, err, ret) = test_executable(["sage", "-h"]) - sage: out.find("Optional arguments:") >= 0 + sage: out.find("evaluate cmd as sage") >= 0 True sage: err '' @@ -173,7 +173,7 @@ def test_executable(args, input="", timeout=100.0, pydebug_ignore_warnings=False 0 sage: (out, err, ret) = test_executable(["sage", "--help"]) - sage: out.find("Optional arguments:") >= 0 + sage: out.find("evaluate cmd as sage") >= 0 True sage: err '' From 1720e6009203fcc23e22ccfbf9ab657615d5c822 Mon Sep 17 00:00:00 2001 From: Thierry Monteil Date: Sun, 29 May 2022 00:27:41 +0200 Subject: [PATCH 502/529] #33930 : fix doctest for polyhedra_tutorial.rst --- src/doc/en/thematic_tutorials/geometry/polyhedra_tutorial.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/doc/en/thematic_tutorials/geometry/polyhedra_tutorial.rst b/src/doc/en/thematic_tutorials/geometry/polyhedra_tutorial.rst index c0c36091367..e4e0b1eeb8b 100644 --- a/src/doc/en/thematic_tutorials/geometry/polyhedra_tutorial.rst +++ b/src/doc/en/thematic_tutorials/geometry/polyhedra_tutorial.rst @@ -658,7 +658,8 @@ An example with quadratic field: sage: V = polytopes.dodecahedron().vertices_list() # optional - sage.rings.number_field sage: Polyhedron(vertices=V, backend='polymake') # optional - polymake # optional - sage.rings.number_field A 3-dimensional polyhedron - in (Number Field in sqrt5 with defining polynomial x^2 - 5)^3 + in (Number Field in sqrt5 with defining polynomial x^2 - 5 + with sqrt5 = 2.236067977499790?)^3 defined as the convex hull of 20 vertices .. end of output From fd8362477c57dd1722350f095e4d1cb4d58d9a7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 29 May 2022 13:31:14 +0200 Subject: [PATCH 503/529] simplify many super calls to super() in combinat --- src/sage/combinat/binary_tree.py | 12 ++-- src/sage/combinat/crystals/littelmann_path.py | 11 ++-- src/sage/combinat/diagram_algebras.py | 38 ++++++------- src/sage/combinat/finite_state_machine.py | 20 +++---- src/sage/combinat/k_tableau.py | 10 ++-- src/sage/combinat/partition_kleshchev.py | 12 ++-- src/sage/combinat/partition_tuple.py | 16 +++--- src/sage/combinat/permutation.py | 50 ++++++++--------- .../combinat/root_system/associahedron.py | 12 ++-- .../root_system/extended_affine_weyl_group.py | 12 ++-- src/sage/combinat/shifted_primed_tableau.py | 10 ++-- src/sage/combinat/tableau.py | 55 +++++++++---------- src/sage/combinat/tableau_tuple.py | 23 ++++---- src/sage/combinat/words/paths.py | 17 +++--- src/sage/combinat/words/word_datatypes.pyx | 18 +++--- .../combinat/words/word_infinite_datatypes.py | 12 ++-- 16 files changed, 161 insertions(+), 167 deletions(-) diff --git a/src/sage/combinat/binary_tree.py b/src/sage/combinat/binary_tree.py index 5fda457d72e..d8e0a46938b 100644 --- a/src/sage/combinat/binary_tree.py +++ b/src/sage/combinat/binary_tree.py @@ -234,7 +234,7 @@ def _repr_(self): if not self: return "." else: - return super(BinaryTree, self)._repr_() + return super()._repr_() def _ascii_art_(self): r""" @@ -4124,7 +4124,7 @@ def __call__(self, x=None, *args, **keywords): sage: B() . """ - return super(BinaryTrees, self).__call__(x, *args, **keywords) + return super().__call__(x, *args, **keywords) def unlabelled_trees(self): """ @@ -4190,8 +4190,8 @@ def __init__(self, size): sage: S is BinaryTrees(3) True """ - super(BinaryTrees_size, self).__init__(facade=BinaryTrees_all(), - category=FiniteEnumeratedSets()) + super().__init__(facade=BinaryTrees_all(), + category=FiniteEnumeratedSets()) self._size = size def _repr_(self): @@ -4423,8 +4423,8 @@ def __init__(self, size): sage: for i in range(1,6): ....: TestSuite(BinaryTrees(2*i-1, full=True)).run() """ - super(FullBinaryTrees_size, self).__init__(facade=BinaryTrees_all(), - category=FiniteEnumeratedSets()) + super().__init__(facade=BinaryTrees_all(), + category=FiniteEnumeratedSets()) self._size = size def _repr_(self): diff --git a/src/sage/combinat/crystals/littelmann_path.py b/src/sage/combinat/crystals/littelmann_path.py index 6f45611e85c..fd32c317943 100644 --- a/src/sage/combinat/crystals/littelmann_path.py +++ b/src/sage/combinat/crystals/littelmann_path.py @@ -165,7 +165,7 @@ def __classcall_private__(cls, starting_weight, cartan_type = None, starting_wei if starting_weight.parent() != starting_weight_parent: raise ValueError("The passed parent is not equal to parent of the inputted weight!") - return super(CrystalOfLSPaths, cls).__classcall__(cls, starting_weight, starting_weight_parent = starting_weight_parent) + return super().__classcall__(cls, starting_weight, starting_weight_parent = starting_weight_parent) def __init__(self, starting_weight, starting_weight_parent): """ @@ -702,7 +702,7 @@ def __classcall_private__(cls, weight): raise ValueError("The weight should be in the non-extended weight lattice!") La = weight.parent().basis() weight = weight - weight.level() * La[0] / La[0].level() - return super(CrystalOfLSPaths, cls).__classcall__(cls, weight, starting_weight_parent = weight.parent()) + return super().__classcall__(cls, weight, starting_weight_parent = weight.parent()) @cached_method def maximal_vector(self): @@ -1206,7 +1206,7 @@ def __classcall_private__(cls, cartan_type): True """ cartan_type = CartanType(cartan_type) - return super(InfinityCrystalOfLSPaths, cls).__classcall__(cls, cartan_type) + return super().__classcall__(cls, cartan_type) def __init__(self, cartan_type): """ @@ -1320,8 +1320,7 @@ def e(self, i, power=1, length_only=False): sage: len(B.subcrystal(max_depth=7)) 116 """ - ret = super(InfinityCrystalOfLSPaths.Element, self).e(i, power=power, - length_only=length_only) + ret = super().e(i, power=power, length_only=length_only) if ret is None: return None if length_only: @@ -1375,7 +1374,7 @@ def f(self, i, power=1, length_only=False): 2*Lambda[0] + 2*Lambda[1] + 2*Lambda[2]) """ dual_path = self.dualize() - dual_path = super(InfinityCrystalOfLSPaths.Element, dual_path).e(i, power, length_only=length_only) + dual_path = super().e(i, power, length_only=length_only) if length_only: return dual_path if dual_path is None: diff --git a/src/sage/combinat/diagram_algebras.py b/src/sage/combinat/diagram_algebras.py index de6813f7a23..eee9052ed76 100644 --- a/src/sage/combinat/diagram_algebras.py +++ b/src/sage/combinat/diagram_algebras.py @@ -257,7 +257,7 @@ def __init__(self, parent, d, check=True): sage: pd1 = da.AbstractPartitionDiagram(pd, ((-2,-1),(1,2)) ) """ self._base_diagram = tuple(sorted(tuple(sorted(i)) for i in d)) - super(AbstractPartitionDiagram, self).__init__(parent, self._base_diagram, check=check) + super().__init__(parent, self._base_diagram, check=check) def check(self): r""" @@ -588,7 +588,7 @@ def check(self): ValueError: {{-3, -1, 1, 2}} does not represent two rows of vertices of order 2 sage: pd4 = IdealDiagram([[1,-2,-1],[2]]) # indirect doctest """ - super(IdealDiagram, self).check() + super().check() if self.propagating_number() >= self.order(): raise ValueError("the diagram %s must have a propagating number smaller than the order" % self) @@ -659,7 +659,7 @@ def check(self): ValueError: {{-3, -1, 1, 2}} does not represent two rows of vertices of order 2 sage: pd4 = PlanarDiagram([[1,-2,-1],[2]]) # indirect doctest """ - super(PlanarDiagram, self).check() + super().check() if not self.is_planar(): raise ValueError("the diagram %s must be planar" % self) @@ -721,7 +721,7 @@ def check(self): ... ValueError: all blocks of {{-2, -1, 1}, {2}} must be of size 2 """ - super(TemperleyLiebDiagram, self).check() + super().check() if any(len(block) != 2 for block in self): raise ValueError("all blocks of %s must be of size 2" % self ) if not self.is_planar(): @@ -824,7 +824,7 @@ def check(self): ... ValueError: all blocks of {{-2, -1, 1, 2}} must be of size 2 """ - super(BrauerDiagram, self).check() + super().check() if any(len(i) != 2 for i in self): raise ValueError("all blocks of %s must be of size 2" % self) @@ -903,7 +903,7 @@ def _repr_normal(self): sage: bd([[1,2],[-1,-2]])._repr_normal() '{{-2, -1}, {1, 2}}' """ - return super(BrauerDiagram, self)._repr_() + return super()._repr_() def _repr_compact(self): """ @@ -1425,7 +1425,7 @@ def __contains__(self, obj): r = ZZ(self.order) else: r = ZZ(self.order + ZZ(1)/ZZ(2)) - return super(BrauerDiagrams, self).__contains__(obj) and [len(i) for i in obj] == [2]*r + return super().__contains__(obj) and [len(i) for i in obj] == [2]*r def cardinality(self): r""" @@ -1714,7 +1714,7 @@ def __contains__(self, obj): obj = self._element_constructor_(obj) except (ValueError, TypeError): return False - return super(PlanarDiagrams, self).__contains__(obj) + return super().__contains__(obj) class IdealDiagrams(AbstractPartitionDiagrams): r""" @@ -1761,7 +1761,7 @@ def __contains__(self, obj): obj = self._element_constructor_(obj) except (ValueError, TypeError): return False - return super(IdealDiagrams, self).__contains__(obj) and obj.propagating_number() < self.order + return super().__contains__(obj) and obj.propagating_number() < self.order class DiagramAlgebra(CombinatorialFreeModule): r""" @@ -2436,7 +2436,7 @@ def __classcall_private__(cls, k, q, base_ring=None, prefix="P"): """ if base_ring is None: base_ring = q.parent() - return super(PartitionAlgebra, cls).__classcall__(cls, k, q, base_ring, prefix) + return super().__classcall__(cls, k, q, base_ring, prefix) # The following is the basic constructor method for the class. # The purpose of the "prefix" is to label the basis elements @@ -2509,7 +2509,7 @@ def _element_constructor_(self, x): and self.has_coerce_map_from(x.parent().base_ring())): return sum(a * self._diag_to_Blst(d) for (d,a) in x) - return super(PartitionAlgebra, self)._element_constructor_(x) + return super()._element_constructor_(x) def _repr_(self): """ @@ -2598,7 +2598,7 @@ def _coerce_map_from_(self, R): if R.n <= self._k and self.base_ring().has_coerce_map_from(R.base_ring()): return R.module_morphism(self._perm_to_Blst, codomain=self) return None - return super(PartitionAlgebra, self)._coerce_map_from_(R) + return super()._coerce_map_from_(R) def orbit_basis(self): r""" @@ -3173,7 +3173,7 @@ def __classcall_private__(cls, *args): k, q, R = args q = R(q) alg = PartitionAlgebra(k, q, R) - return super(OrbitBasis, cls).__classcall__(cls, alg) + return super().__classcall__(cls, alg) def __init__(self, alg): """ @@ -3246,7 +3246,7 @@ def _coerce_map_from_(self, R): return self._alg.module_morphism(self._diagram_to_orbit_on_basis, codomain=self) if self._alg.coerce_map_from(R): return self._coerce_map_via([self._alg], R) - return super(OrbitBasis, self)._coerce_map_from_(R) + return super()._coerce_map_from_(R) @cached_method def one(self): @@ -3645,7 +3645,7 @@ def __classcall_private__(cls, k, q, base_ring=None, prefix="B"): """ if base_ring is None: base_ring = q.parent() - return super(BrauerAlgebra, cls).__classcall__(cls, k, q, base_ring, prefix) + return super().__classcall__(cls, k, q, base_ring, prefix) def __init__(self, k, q, base_ring, prefix): r""" @@ -3704,7 +3704,7 @@ def _coerce_map_from_(self, R): if R.n <= self._k and self.base_ring().has_coerce_map_from(R.base_ring()): return R.module_morphism(self._perm_to_Blst, codomain=self) return None - return super(BrauerAlgebra, self)._coerce_map_from_(R) + return super()._coerce_map_from_(R) def _element_constructor_(self, set_partition): r""" @@ -3836,7 +3836,7 @@ def __classcall_private__(cls, k, q, base_ring=None, prefix="T"): """ if base_ring is None: base_ring = q.parent() - return super(TemperleyLiebAlgebra, cls).__classcall__(cls, k, q, base_ring, prefix) + return super().__classcall__(cls, k, q, base_ring, prefix) def __init__(self, k, q, base_ring, prefix): r""" @@ -4003,7 +4003,7 @@ def __classcall_private__(cls, k, q, base_ring=None, prefix="Pl"): """ if base_ring is None: base_ring = q.parent() - return super(PlanarAlgebra, cls).__classcall__(cls, k, q, base_ring, prefix) + return super().__classcall__(cls, k, q, base_ring, prefix) def __init__(self, k, q, base_ring, prefix): r""" @@ -4092,7 +4092,7 @@ def __classcall_private__(cls, k, q, base_ring=None, prefix="I"): """ if base_ring is None: base_ring = q.parent() - return super(PropagatingIdeal, cls).__classcall__(cls, k, q, base_ring, prefix) + return super().__classcall__(cls, k, q, base_ring, prefix) def __init__(self, k, q, base_ring, prefix): r""" diff --git a/src/sage/combinat/finite_state_machine.py b/src/sage/combinat/finite_state_machine.py index f52a0f129d6..8615e791b6b 100644 --- a/src/sage/combinat/finite_state_machine.py +++ b/src/sage/combinat/finite_state_machine.py @@ -11018,12 +11018,10 @@ def __init__(self, *args, **kwargs): True sage: Automaton()._allow_composition_ False - """ - super(Automaton, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self._allow_composition_ = False - def _repr_(self): """ Represents the finite state machine as "Automaton with n @@ -11825,7 +11823,7 @@ class is created and is used during the processing. options['list_of_outputs'] = True options['only_accepted'] = True - result = super(Automaton, self).process(*args, **options) + result = super().process(*args, **options) if condensed_output: return any(result) @@ -11870,7 +11868,7 @@ def _process_convert_output_(self, output_data, **kwargs): (True, 'a', [1, 0, 1]) """ if kwargs['always_include_output']: - return super(Automaton, self)._process_convert_output_( + return super()._process_convert_output_( output_data, **kwargs) accept_input, current_state, output = output_data if kwargs['full_output']: @@ -12994,7 +12992,7 @@ class is created and is used during the processing. options['list_of_outputs'] = True options['only_accepted'] = True - result = super(Transducer, self).process(*args, **options) + result = super().process(*args, **options) if (condensed_output and not result or not options['full_output'] and result is None): @@ -13734,7 +13732,7 @@ def __init__(self, *args, **kwargs): ....: [False], ((0, 0),), False) tape at 0 """ - super(_FSMTapeCacheDetectEpsilon_, self).__init__(*args, **kwargs) + super().__init__(*args, **kwargs) self._visited_states_ = set() @@ -13752,7 +13750,7 @@ def __deepcopy__(self, memo): sage: TC3._visited_states_ {1} """ - new = super(_FSMTapeCacheDetectEpsilon_, self).__deepcopy__(memo) + new = super().__deepcopy__(memo) new._visited_states_ = copy(self._visited_states_) return new @@ -15099,7 +15097,7 @@ def __init__(self, *args, **kwargs): self.TapeCache = _FSMTapeCacheDetectEpsilon_ self.visited_states = {} kwargs['check_epsilon_transitions'] = False - return super(_FSMProcessIteratorEpsilon_, self).__init__(*args, **kwargs) + return super().__init__(*args, **kwargs) def _push_branch_(self, state, tape_cache, outputs): @@ -15145,7 +15143,7 @@ def _push_branch_(self, state, tape_cache, outputs): if found: return - super(_FSMProcessIteratorEpsilon_, self)._push_branch_( + super()._push_branch_( state, tape_cache, outputs) # As tape_cache may have been discarded because current already @@ -15226,7 +15224,7 @@ def __init__(self, *args, **kwargs): self.TapeCache = _FSMTapeCacheDetectAll_ self.visited_states = {} kwargs['check_epsilon_transitions'] = False - return super(_FSMProcessIteratorAll_, self).__init__(*args, **kwargs) + return super().__init__(*args, **kwargs) # **************************************************************************** diff --git a/src/sage/combinat/k_tableau.py b/src/sage/combinat/k_tableau.py index 0c1df07ba61..65b925d9ce0 100644 --- a/src/sage/combinat/k_tableau.py +++ b/src/sage/combinat/k_tableau.py @@ -438,7 +438,7 @@ def __hash__(self): if self.parent()._representation in ['core', 'bounded']: return hash(tuple(tuple(x) for x in self)) + hash(self.parent().k) else: - return super(WeakTableau_abstract, self).__hash__() + return super().__hash__() def _latex_(self): r""" @@ -1250,7 +1250,7 @@ def __classcall_private__(cls, k, shape, weight): shape = (Core(shape, k+1), Core([],k+1)) else: shape = tuple([Core(r,k+1) for r in shape]) - return super(WeakTableaux_core, cls).__classcall__(cls, k, shape, tuple(weight)) + return super().__classcall__(cls, k, shape, tuple(weight)) def __init__(self, k, shape, weight): r""" @@ -1718,7 +1718,7 @@ def __classcall_private__(cls, k, shape, weight): shape = (Partition(shape), Partition([])) else: shape = tuple([Partition(r) for r in shape]) - return super(WeakTableaux_bounded, cls).__classcall__(cls, k, shape, tuple(weight)) + return super().__classcall__(cls, k, shape, tuple(weight)) def __init__(self, k, shape, weight): r""" @@ -2139,7 +2139,7 @@ def __classcall_private__(cls, k, shape, weight): shape = (Core(shape, k+1), Core([],k+1)) else: shape = tuple([Core(r,k+1) for r in shape]) - return super(WeakTableaux_factorized_permutation, cls).__classcall__(cls, k, shape, tuple(weight)) + return super().__classcall__(cls, k, shape, tuple(weight)) def __init__(self, k, shape, weight): r""" @@ -3956,7 +3956,7 @@ def __classcall_private__(cls, k, shape, weight=None): inner_shape = Core(shape[1],k+1) if weight is not None: weight = tuple(weight) - return super(StrongTableaux, cls).__classcall__(cls, k, (outer_shape, inner_shape), weight) + return super().__classcall__(cls, k, (outer_shape, inner_shape), weight) def _repr_( self ): r""" diff --git a/src/sage/combinat/partition_kleshchev.py b/src/sage/combinat/partition_kleshchev.py index c379de07876..8fd46bc76fe 100644 --- a/src/sage/combinat/partition_kleshchev.py +++ b/src/sage/combinat/partition_kleshchev.py @@ -449,7 +449,7 @@ def is_regular(self): if self.size() == 0 or self.parent()._e == 0: return True KP = self.parent() - return super(KleshchevPartition, self).is_regular(KP._e, KP._multicharge) + return super().is_regular(KP._e, KP._multicharge) def is_restricted(self): r""" @@ -475,7 +475,8 @@ def is_restricted(self): if self.size() == 0 or self.parent()._e == 0: return True KP = self.parent() - return super(KleshchevPartition, self).is_restricted(KP._e, KP._multicharge) + return super().is_restricted(KP._e, KP._multicharge) + class KleshchevPartitionTuple(PartitionTuple): r""" @@ -1284,7 +1285,8 @@ def _element_constructor_(self, mu): if self._level>1 and KPmu._convention[0] == self._convention[0]: mu = mu[::-1] - return super(KleshchevPartitions, self)._element_constructor_(mu) + return super()._element_constructor_(mu) + class KleshchevPartitions_all(KleshchevPartitions): r""" @@ -1446,7 +1448,7 @@ def __init__(self, e, multicharge, convention): else: self.Element = KleshchevPartitionTupleCrystal - super(KleshchevPartitions_all, self).__init__(category=cat) + super().__init__(category=cat) self._e = e # for printing self._index_set = IntegerModRing(e) self._multicharge = multicharge @@ -1673,7 +1675,7 @@ def __init__(self, e, multicharge=(0,), size=0, convention='RS'): self._element_constructor_ = getattr_from_other_class(self, Partitions, '_element_constructor_') else: self.Element = KleshchevPartitionTuple - super(KleshchevPartitions_size, self).__init__(category=FiniteEnumeratedSets()) + super().__init__(category=FiniteEnumeratedSets()) self._size = size # As lists do not take negative indices the case e=0 needs to be handled # differently. Rather than doing this we set e equal to a "really big" diff --git a/src/sage/combinat/partition_tuple.py b/src/sage/combinat/partition_tuple.py index b4f54624d2f..90fbb6e6866 100644 --- a/src/sage/combinat/partition_tuple.py +++ b/src/sage/combinat/partition_tuple.py @@ -2076,7 +2076,7 @@ def __init__(self): sage: TestSuite( PartitionTuples() ).run() """ - super(PartitionTuples_all, self).__init__(category=InfiniteEnumeratedSets()) + super().__init__(category=InfiniteEnumeratedSets()) def _repr_(self): r""" @@ -2156,7 +2156,7 @@ def __init__(self, level, category=None): raise ValueError('level must be a non-negative integer') if category is None: category = InfiniteEnumeratedSets() - super(PartitionTuples_level, self).__init__(category=category) + super().__init__(category=category) self._level = level def _repr_(self): @@ -2259,8 +2259,8 @@ def __init__(self, size): """ if size not in NN: raise ValueError('size must be a non-negative integer') - super(PartitionTuples_size, self).__init__(category=InfiniteEnumeratedSets()) - self._size=size + super().__init__(category=InfiniteEnumeratedSets()) + self._size = size def _repr_(self): """ @@ -2361,9 +2361,9 @@ def __init__(self, level, size): """ if not (level in NN and size in NN): raise ValueError('n and level must be non-negative integers') - super(PartitionTuples_level_size, self).__init__(category=FiniteEnumeratedSets()) - self._level=level - self._size=size + super().__init__(category=FiniteEnumeratedSets()) + self._level = level + self._size = size def _repr_(self): """ @@ -2503,7 +2503,7 @@ def __setstate__(self, state): self.__class__=parts.__class__ self.__dict__=parts.__dict__ else: - super(PartitionTuples, self).__setstate__(state) + super().__setstate__(state) ############################################################################### # Regular partition tuples diff --git a/src/sage/combinat/permutation.py b/src/sage/combinat/permutation.py index 8eae4b7c84c..7fbcbff6f94 100644 --- a/src/sage/combinat/permutation.py +++ b/src/sage/combinat/permutation.py @@ -5611,7 +5611,7 @@ def __classcall_private__(cls, mset): sage: S1 is S2 True """ - return super(Permutations_mset, cls).__classcall__(cls, tuple(mset)) + return super().__classcall__(cls, tuple(mset)) def __init__(self, mset): """ @@ -5971,7 +5971,7 @@ def __classcall_private__(cls, s): sage: S1 is S2 True """ - return super(Permutations_set, cls).__classcall__(cls, tuple(s)) + return super().__classcall__(cls, tuple(s)) def __init__(self, s): """ @@ -6097,7 +6097,7 @@ def __classcall__(cls, mset, k): sage: S1 is S2 True """ - return super(Permutations_msetk, cls).__classcall__(cls, tuple(mset), k) + return super().__classcall__(cls, tuple(mset), k) def __init__(self, mset, k): """ @@ -6188,7 +6188,7 @@ def __classcall_private__(cls, s, k): sage: S1 is S2 True """ - return super(Permutations_setk, cls).__classcall__(cls, tuple(s), k) + return super().__classcall__(cls, tuple(s), k) def __init__(self, s, k): """ @@ -6604,7 +6604,7 @@ def _coerce_map_from_(self, G): return self._from_permutation_group_element if isinstance(G, StandardPermutations_n) and G.n <= self.n: return True - return super(StandardPermutations_n, self)._coerce_map_from_(G) + return super()._coerce_map_from_(G) def _from_permutation_group_element(self, x): """ @@ -7619,7 +7619,7 @@ def __classcall_private__(cls, d, n): sage: P1 is P2 True """ - return super(StandardPermutations_descents, cls).__classcall__(cls, tuple(sorted(d)), n) + return super().__classcall__(cls, tuple(sorted(d)), n) def __init__(self, d, n): r""" @@ -7845,7 +7845,7 @@ def __classcall_private__(cls, recoils): sage: S1 is S2 True """ - return super(StandardPermutations_recoilsfiner, cls).__classcall__(cls, Composition(recoils)) + return super().__classcall__(cls, Composition(recoils)) def __init__(self, recoils): """ @@ -7912,7 +7912,7 @@ def __classcall_private__(cls, recoils): sage: S1 is S2 True """ - return super(StandardPermutations_recoilsfatter, cls).__classcall__(cls, Composition(recoils)) + return super().__classcall__(cls, Composition(recoils)) def __init__(self, recoils): """ @@ -7986,7 +7986,7 @@ def __classcall_private__(cls, recoils): sage: S1 is S2 True """ - return super(StandardPermutations_recoils, cls).__classcall__(cls, Composition(recoils)) + return super().__classcall__(cls, Composition(recoils)) def __init__(self, recoils): """ @@ -8137,7 +8137,7 @@ def __classcall_private__(cls, p): sage: S1 is S2 True """ - return super(StandardPermutations_bruhat_smaller, cls).__classcall__(cls, Permutation(p)) + return super().__classcall__(cls, Permutation(p)) def __init__(self, p): """ @@ -8195,7 +8195,7 @@ def __classcall_private__(cls, p): sage: S1 is S2 True """ - return super(StandardPermutations_bruhat_greater, cls).__classcall__(cls, Permutation(p)) + return super().__classcall__(cls, Permutation(p)) def __init__(self, p): """ @@ -8412,7 +8412,7 @@ def __classcall_private__(cls, mset): Cyclic permutations of [1, 2, 3, 3] sage: TestSuite(CP).run() # not tested -- broken """ - return super(CyclicPermutations, cls).__classcall__(cls, tuple(mset)) + return super().__classcall__(cls, tuple(mset)) def _repr_(self): """ @@ -8527,7 +8527,7 @@ def __classcall_private__(cls, partition): True """ partition = tuple(map(tuple, partition)) - return super(CyclicPermutationsOfPartition, cls).__classcall__(cls, partition) + return super().__classcall__(cls, partition) def __init__(self, partition): """ @@ -8658,7 +8658,7 @@ def __classcall_private__(cls, a): True """ a = tuple(map(Permutation, a)) - return super(StandardPermutations_all_avoiding, cls).__classcall__(cls, a) + return super().__classcall__(cls, a) def __init__(self, a): """ @@ -8704,7 +8704,7 @@ def __contains__(self, x): sage: [2,1,3] in Permutations(avoiding=[]) True """ - if not super(StandardPermutations_all_avoiding, self).__contains__(x): + if not super().__contains__(x): return False x = Permutations()(x) return all(x.avoids(p) for p in self._a) @@ -8753,7 +8753,7 @@ def __classcall_private__(cls, n, a): True """ a = tuple(map(Permutation, a)) - return super(StandardPermutations_avoiding_generic, cls).__classcall__(cls, n, a) + return super().__classcall__(cls, n, a) def __init__(self, n, a): """ @@ -8810,7 +8810,7 @@ def __contains__(self, x): sage: [2,1,3] in Permutations(3, avoiding=[]) True """ - if not super(StandardPermutations_avoiding_generic, self).__contains__(x): + if not super().__contains__(x): return False x = Permutations()(x) return all(x.avoids(p) for p in self._a) @@ -8858,7 +8858,7 @@ def __init__(self, n): sage: P = Permutations(3, avoiding=[1, 2]) sage: TestSuite(P).run() """ - super(StandardPermutations_avoiding_12, self).__init__(n, (Permutations()([1, 2]),)) + super().__init__(n, (Permutations()([1, 2]),)) def __iter__(self): """ @@ -8889,7 +8889,7 @@ def __init__(self, n): sage: P = Permutations(3, avoiding=[2, 1]) sage: TestSuite(P).run() """ - super(StandardPermutations_avoiding_21, self).__init__(n, (Permutations()([2, 1]),)) + super().__init__(n, (Permutations()([2, 1]),)) def __iter__(self): """ @@ -8920,7 +8920,7 @@ def __init__(self, n): sage: P = Permutations(3, avoiding=[1, 3, 2]) sage: TestSuite(P).run() """ - super(StandardPermutations_avoiding_132, self).__init__(n, (Permutations()([1, 3, 2]),)) + super().__init__(n, (Permutations()([1, 3, 2]),)) def cardinality(self): """ @@ -8992,7 +8992,7 @@ def __init__(self, n): sage: P = Permutations(3, avoiding=[2, 1, 3]) sage: TestSuite(P).run() """ - super(StandardPermutations_avoiding_123, self).__init__(n, (Permutations()([1, 2, 3]),)) + super().__init__(n, (Permutations()([1, 2, 3]),)) def cardinality(self) -> Integer: """ @@ -9063,7 +9063,7 @@ def __init__(self, n): sage: P = Permutations(3, avoiding=[3, 2, 1]) sage: TestSuite(P).run() """ - super(StandardPermutations_avoiding_321, self).__init__(n, (Permutations()([3, 2, 1]),)) + super().__init__(n, (Permutations()([3, 2, 1]),)) def cardinality(self): """ @@ -9094,7 +9094,7 @@ def __init__(self, n): sage: P = Permutations(3, avoiding=[2, 3, 1]) sage: TestSuite(P).run() """ - super(StandardPermutations_avoiding_231, self).__init__(n, (Permutations()([2, 3, 1]),)) + super().__init__(n, (Permutations()([2, 3, 1]),)) def cardinality(self): """ @@ -9126,7 +9126,7 @@ def __init__(self, n): sage: P = Permutations(3, avoiding=[3, 1, 2]) sage: TestSuite(P).run() """ - super(StandardPermutations_avoiding_312, self).__init__(n, (Permutations()([3, 1, 2]),)) + super().__init__(n, (Permutations()([3, 1, 2]),)) def cardinality(self): """ @@ -9158,7 +9158,7 @@ def __init__(self, n): sage: P = Permutations(3, avoiding=[2, 1, 3]) sage: TestSuite(P).run() """ - super(StandardPermutations_avoiding_213, self).__init__(n, (Permutations()([2, 1, 3]),)) + super().__init__(n, (Permutations()([2, 1, 3]),)) def cardinality(self): """ diff --git a/src/sage/combinat/root_system/associahedron.py b/src/sage/combinat/root_system/associahedron.py index 565b5d8581a..66b134a35e7 100644 --- a/src/sage/combinat/root_system/associahedron.py +++ b/src/sage/combinat/root_system/associahedron.py @@ -189,7 +189,7 @@ def __new__(typ, parent=None, Vrep=None, Hrep=None, cartan_type=None, **kwds): if cartan_type or (parent is None and Vrep is None and Hrep is None): # Called from element constructor in ``Associahedron_base``. # Alternatively called from ``loads`` in ``loads(dumps(...))``. - return super(Associahedron_class_base, typ).__new__(typ, parent, Vrep, Hrep, **kwds) + return super().__new__(typ, parent, Vrep, Hrep, **kwds) else: # Not called from element constructor in ``Associahedron_base``. # Return a polyhedron with proper backend (not an associahedron). @@ -214,7 +214,7 @@ def __init__(self, parent, Vrep, Hrep, cartan_type=None, **kwds): """ if cartan_type: self._cartan_type = cartan_type - super(Associahedron_class_base, self).__init__(parent, Vrep, Hrep, **kwds) + super().__init__(parent, Vrep, Hrep, **kwds) else: raise ValueError("associahedron must be initialized with cartan type") @@ -375,7 +375,7 @@ def _element_constructor_(self, cartan_type, **kwds): c = rhocheck.coefficient(orbit[0].leading_support()) for beta in orbit: inequalities.append([c] + [beta.coefficient(i) for i in I]) - associahedron = super(Associahedra_base, self)._element_constructor_(None, [inequalities, []], cartan_type=cartan_type) + associahedron = super()._element_constructor_(None, [inequalities, []], cartan_type=cartan_type) return associahedron def _coerce_map_from_(self, X): @@ -416,7 +416,7 @@ def _coerce_map_from_(self, X): """ if not isinstance(X, Associahedra_base): return False - return super(Associahedra_base, self)._coerce_map_from_(X) + return super()._coerce_map_from_(X) def _pushout_(self, other): r""" @@ -441,8 +441,8 @@ def _pushout_(self, other): return Polyhedra(QQ, self.ambient_dim(), self.backend()) # Call the overwritten pushout in case it exists. - if hasattr(super(Associahedra_base, self), '_pushout_'): - return super(Associahedra_base, self)._pushout_(other) + if hasattr(super(), '_pushout_'): + return super()._pushout_(other) class Associahedra_ppl(Associahedra_base, Polyhedra_QQ_ppl): Element = Associahedron_class_ppl diff --git a/src/sage/combinat/root_system/extended_affine_weyl_group.py b/src/sage/combinat/root_system/extended_affine_weyl_group.py index a2866253194..bd02024afc6 100644 --- a/src/sage/combinat/root_system/extended_affine_weyl_group.py +++ b/src/sage/combinat/root_system/extended_affine_weyl_group.py @@ -1984,7 +1984,7 @@ def _repr_(self): sage: ExtendedAffineWeylGroup(['A',4,2]).PW0()._repr_() "Extended affine Weyl group of type ['BC', 2, 2] realized by Semidirect product of Multiplicative form of Weight lattice of the Root system of type ['C', 2] acted upon by Weyl Group of type ['C', 2] (as a matrix group acting on the weight lattice)" """ - return self.realization_of()._repr_() + " realized by " + super(ExtendedAffineWeylGroup_Class.ExtendedAffineWeylGroupPW0, self)._repr_() + return self.realization_of()._repr_() + " realized by " + super()._repr_() def from_translation(self, la): r""" @@ -2163,7 +2163,7 @@ def _repr_(self): sage: ExtendedAffineWeylGroup(['A',4,2]).W0P()._repr_() "Extended affine Weyl group of type ['BC', 2, 2] realized by Semidirect product of Weyl Group of type ['C', 2] (as a matrix group acting on the weight lattice) acting on Multiplicative form of Weight lattice of the Root system of type ['C', 2]" """ - return self.realization_of()._repr_() + " realized by " + super(ExtendedAffineWeylGroup_Class.ExtendedAffineWeylGroupW0P, self)._repr_() + return self.realization_of()._repr_() + " realized by " + super()._repr_() def S0(self): r""" @@ -2356,7 +2356,7 @@ def _repr_(self): sage: ExtendedAffineWeylGroup(['A',4,2]).WF()._repr_() "Extended affine Weyl group of type ['BC', 2, 2] realized by Semidirect product of Weyl Group of type ['BC', 2, 2] (as a matrix group acting on the root lattice) acted upon by Fundamental group of type ['BC', 2, 2]" """ - return self.realization_of()._repr_() + " realized by " + super(ExtendedAffineWeylGroup_Class.ExtendedAffineWeylGroupWF, self)._repr_() + return self.realization_of()._repr_() + " realized by " + super()._repr_() def from_affine_weyl(self, w): r""" @@ -2512,7 +2512,7 @@ def _repr_(self): sage: ExtendedAffineWeylGroup(['A',4,2]).FW()._repr_() "Extended affine Weyl group of type ['BC', 2, 2] realized by Semidirect product of Fundamental group of type ['BC', 2, 2] acting on Weyl Group of type ['BC', 2, 2] (as a matrix group acting on the root lattice)" """ - return self.realization_of()._repr_() + " realized by " + super(ExtendedAffineWeylGroup_Class.ExtendedAffineWeylGroupFW, self)._repr_() + return self.realization_of()._repr_() + " realized by " + super()._repr_() @cached_method def simple_reflections(self): @@ -2682,7 +2682,7 @@ def _repr_(self): sage: ExtendedAffineWeylGroup(['A',4,2]).PvW0()._repr_() "Extended affine Weyl group of type ['BC', 2, 2] realized by Semidirect product of Multiplicative form of Weight lattice of the Root system of type ['C', 2] acted upon by Weyl Group of type ['C', 2] (as a matrix group acting on the weight lattice)" """ - return self.realization_of()._repr_() + " realized by " + super(ExtendedAffineWeylGroup_Class.ExtendedAffineWeylGroupPvW0, self)._repr_() + return self.realization_of()._repr_() + " realized by " + super()._repr_() def from_dual_translation(self, la): r""" @@ -2847,7 +2847,7 @@ def _repr_(self): sage: ExtendedAffineWeylGroup(['A',4,2]).W0Pv()._repr_() "Extended affine Weyl group of type ['BC', 2, 2] realized by Semidirect product of Weyl Group of type ['C', 2] (as a matrix group acting on the weight lattice) acting on Multiplicative form of Weight lattice of the Root system of type ['C', 2]" """ - return self.realization_of()._repr_() + " realized by " + super(ExtendedAffineWeylGroup_Class.ExtendedAffineWeylGroupW0Pv, self)._repr_() + return self.realization_of()._repr_() + " realized by " + super()._repr_() def from_dual_translation(self, la): r""" diff --git a/src/sage/combinat/shifted_primed_tableau.py b/src/sage/combinat/shifted_primed_tableau.py index 5b8eb900ece..bb22854bdfb 100644 --- a/src/sage/combinat/shifted_primed_tableau.py +++ b/src/sage/combinat/shifted_primed_tableau.py @@ -2163,7 +2163,7 @@ def __classcall_private__(cls, shape, max_entry=None, skew=None, primed_diagonal True """ shape = _Partitions(shape) - return super(ShiftedPrimedTableaux_shape, cls).__classcall__(cls, + return super().__classcall__(cls, shape=shape, max_entry=max_entry, skew=skew, primed_diagonal=primed_diagonal) def __init__(self, shape, max_entry=None, skew=None, primed_diagonal=False): @@ -2253,7 +2253,7 @@ def _contains_tableau(self, T): ....: primed_diagonal=True)._contains_tableau(t) True """ - if not super(ShiftedPrimedTableaux_shape, self)._contains_tableau(T): + if not super()._contains_tableau(T): return False shape = [len(row) for row in T] @@ -2300,7 +2300,7 @@ def __iter__(self): 1504 """ if not self._primed_diagonal: - for T in super(ShiftedPrimedTableaux_shape, self).__iter__(): + for T in super().__iter__(): yield T return @@ -2433,7 +2433,7 @@ def _contains_tableau(self, T): sage: ShiftedPrimedTableaux(weight=(1,2))._contains_tableau(u) False """ - if not super(ShiftedPrimedTableaux_weight, self)._contains_tableau(T): + if not super()._contains_tableau(T): return False flat = [item.integer() for sublist in T for item in sublist] @@ -2566,7 +2566,7 @@ def _contains_tableau(self, T): sage: ShiftedPrimedTableaux([], weight=())._contains_tableau(u) True """ - if not super(ShiftedPrimedTableaux_weight_shape, self)._contains_tableau(T): + if not super()._contains_tableau(T): return False flat = [item.integer() for sublist in T for item in sublist] diff --git a/src/sage/combinat/tableau.py b/src/sage/combinat/tableau.py index 9d7e3cc2b41..834cfabe51d 100644 --- a/src/sage/combinat/tableau.py +++ b/src/sage/combinat/tableau.py @@ -4362,7 +4362,7 @@ def check(self): ... ValueError: expected entry to be a positive integer at (row=0, col=0). Found (0) """ - super(SemistandardTableau, self).check() + super().check() # Tableau() has checked that t is tableau, so it remains to check that # the entries of t are positive integers which are weakly increasing @@ -4487,7 +4487,7 @@ def check(self): ValueError: the entries in a row standard tableau must increase along rows and contain the numbers 1,2,...,n """ - super(RowStandardTableau, self).check() + super().check() # We have checked that t is tableau, so it remains to check that # the entries of t are positive integers that increase along rows. flatx = sorted(sum((list(row) for row in self), [])) @@ -4590,7 +4590,7 @@ def check(self): ... ValueError: the entries in each row of a semistandard tableau must be weakly increasing """ - super(StandardTableau, self).check() + super().check() # t is semistandard so we only need to check # that its entries are in bijection with {1, 2, ..., n} flattened_list = [i for row in self for i in row] @@ -5045,7 +5045,7 @@ def check(self): # Empty tableau, so trivially an increasing tableau return - super(IncreasingTableau, self).check() + super().check() # Tableau() has checked that t is tableau, so it remains to check that # the entries of t are positive integers which are weakly increasing @@ -5558,9 +5558,8 @@ def __init__(self): sage: T = sage.combinat.tableau.Tableaux_all() sage: TestSuite(T).run() - """ - super(Tableaux_all, self).__init__(category=Sets()) + super().__init__(category=Sets()) def _repr_(self): """ @@ -5601,7 +5600,7 @@ def __init__(self, n): sage: T = sage.combinat.tableau.Tableaux_size(0) sage: TestSuite(T).run() """ - super(Tableaux_size, self).__init__(category=Sets()) + super().__init__(category=Sets()) self.size = n def __contains__(self,x): @@ -6172,8 +6171,7 @@ def __init__(self, n): sage: T = sage.combinat.tableau.SemistandardTableaux_size_inf(3) sage: TestSuite(T).run() """ - super(SemistandardTableaux_size_inf, self).__init__( - category=InfiniteEnumeratedSets()) + super().__init__(category=InfiniteEnumeratedSets()) self.size = n def _repr_(self): @@ -6275,8 +6273,7 @@ def __init__(self, p): sage: TestSuite(SST).run() """ - super(SemistandardTableaux_shape_inf, self).__init__( - category=InfiniteEnumeratedSets()) + super().__init__(category=InfiniteEnumeratedSets()) self.shape = p def __contains__(self, x): @@ -6371,8 +6368,8 @@ def __init__(self, n, max_entry=None): if max_entry is None: max_entry = n - super(SemistandardTableaux_size, self).__init__(max_entry=max_entry, - category=FiniteEnumeratedSets()) + super().__init__(max_entry=max_entry, + category=FiniteEnumeratedSets()) self.size = n def _repr_(self): @@ -6569,8 +6566,8 @@ def __init__(self, p, max_entry=None): """ if max_entry is None: max_entry = sum(p) - super(SemistandardTableaux_shape, self).__init__(max_entry=max_entry, - category=FiniteEnumeratedSets()) + super().__init__(max_entry=max_entry, + category=FiniteEnumeratedSets()) self.shape = p def __iter__(self): @@ -6775,7 +6772,7 @@ def __init__(self, p, mu): sage: SST = SemistandardTableaux([2,1], [2,1]) sage: TestSuite(SST).run() """ - super(SemistandardTableaux_shape_weight, self).__init__(p, len(mu)) + super().__init__(p, len(mu)) self.weight = mu def _repr_(self): @@ -6889,8 +6886,8 @@ def __init__(self, n, mu): sage: SST = SemistandardTableaux(3, [2,1]) sage: TestSuite(SST).run() """ - super(SemistandardTableaux_size_weight, self).__init__(max_entry=len(mu), - category=FiniteEnumeratedSets()) + super().__init__(max_entry=len(mu), + category=FiniteEnumeratedSets()) self.size = n self.weight = mu @@ -7268,7 +7265,7 @@ def __init__(self, p): sage: TestSuite( RowStandardTableaux([2,1,1]) ).run() """ - super(RowStandardTableaux_shape, self).__init__(category=FiniteEnumeratedSets()) + super().__init__(category=FiniteEnumeratedSets()) self.shape = p def __contains__(self, x): @@ -7772,7 +7769,7 @@ def __init__(self, p): sage: TestSuite( StandardTableaux([2,1,1]) ).run() """ - super(StandardTableaux_shape, self).__init__(category=FiniteEnumeratedSets()) + super().__init__(category=FiniteEnumeratedSets()) self.shape = p def __contains__(self, x): @@ -8726,7 +8723,7 @@ def __init__(self, n): sage: T = IncreasingTableaux_size_inf(3) sage: TestSuite(T).run() """ - super(IncreasingTableaux_size_inf, self).__init__(category=InfiniteEnumeratedSets()) + super().__init__(category=InfiniteEnumeratedSets()) self.size = n def _repr_(self): @@ -8807,7 +8804,7 @@ def __init__(self, p): sage: TestSuite(IT).run() """ - super(IncreasingTableaux_shape_inf, self).__init__(category=InfiniteEnumeratedSets()) + super().__init__(category=InfiniteEnumeratedSets()) self.shape = p def __contains__(self, x): @@ -8895,8 +8892,8 @@ def __init__(self, n, max_entry=None): """ if max_entry is None: max_entry = n - super(IncreasingTableaux_size, self).__init__(max_entry=max_entry, - category=FiniteEnumeratedSets()) + super().__init__(max_entry=max_entry, + category=FiniteEnumeratedSets()) self.size = n def _repr_(self): @@ -9010,8 +9007,8 @@ def __init__(self, p, max_entry=None): """ if max_entry is None: max_entry = sum(p) - super(IncreasingTableaux_shape, self).__init__(max_entry=max_entry, - category=FiniteEnumeratedSets()) + super().__init__(max_entry=max_entry, + category=FiniteEnumeratedSets()) self.shape = p def __iter__(self): @@ -9123,7 +9120,7 @@ def __init__(self, p, wt): sage: IT = IncreasingTableaux([2,1], (1,0,1)) sage: TestSuite(IT).run() """ - super(IncreasingTableaux_shape_weight, self).__init__(p, len(wt)) + super().__init__(p, len(wt)) self.weight = wt def _repr_(self): @@ -9267,8 +9264,8 @@ def __init__(self, n, wt): sage: IT = IncreasingTableaux(3, (1,0,1)) sage: TestSuite(IT).run() """ - super(IncreasingTableaux_size_weight, self).__init__(max_entry=len(wt), - category=FiniteEnumeratedSets()) + super().__init__(max_entry=len(wt), + category=FiniteEnumeratedSets()) self.size = n self.weight = wt diff --git a/src/sage/combinat/tableau_tuple.py b/src/sage/combinat/tableau_tuple.py index f911ca60535..4425dcb4f27 100644 --- a/src/sage/combinat/tableau_tuple.py +++ b/src/sage/combinat/tableau_tuple.py @@ -1567,7 +1567,7 @@ def __init__(self, parent, t, check=True): except ValueError: raise ValueError('not a valid row standard tableau tuple') - super(RowStandardTableauTuple, self).__init__(parent, t) + super().__init__(parent, t) if check: # We still have to check that t is row standard. @@ -1940,7 +1940,7 @@ def __init__(self, parent, t, check=True): False """ # The check that ``t`` is valid tableau tuple is done by RowStandardTableauTuple - super(StandardTableauTuple, self).__init__(parent, t, check=check) + super().__init__(parent, t, check=check) # As StandardTableauTuple inherits from RowStandardTableauTuple t must # be row strict and contain 1,2,...,n once each, so we only need to @@ -2385,9 +2385,8 @@ def __init__(self): sage: TableauTuples() Tableau tuples - """ - super(TableauTuples_all, self).__init__(category=Sets()) + super().__init__(category=Sets()) self._level = None self._size = None @@ -2430,7 +2429,7 @@ def __init__(self, level): sage: TableauTuples(level=4)( [[[1,2],[4]],[],[],[[4,5,6],[7,8]]] ) ([[1, 2], [4]], [], [], [[4, 5, 6], [7, 8]]) """ - super(TableauTuples_level, self).__init__(category=Sets()) + super().__init__(category=Sets()) self._level = level def __contains__(self, t): @@ -2511,7 +2510,7 @@ def __init__(self, size): sage: TableauTuples(size=6) Tableau tuples of size 6 """ - super(TableauTuples_size, self).__init__(category=Sets()) + super().__init__(category=Sets()) self._size = size def __contains__(self, t): @@ -2598,7 +2597,7 @@ def __init__(self, level, size): sage: TableauTuples(4,3) Tableau tuples of level 4 and size 3 """ - super(TableauTuples_level_size, self).__init__(category=Sets()) + super().__init__(category=Sets()) self._level = level self._size = size @@ -3357,7 +3356,7 @@ def __init__(self, shape): sage: STT.cardinality() 1260 """ - super(RowStandardTableauTuples_shape, self).__init__(category=FiniteEnumeratedSets()) + super().__init__(category=FiniteEnumeratedSets()) from sage.combinat.partition_tuple import PartitionTuple self._shape = PartitionTuple(shape) self._level = len(shape) @@ -3579,7 +3578,7 @@ def __init__(self, residue): sage: tabs = RowStandardTableauTuple([[[6],[7]],[[3,4,5],[1,2]]]).residue_sequence(2,(0,0)).row_standard_tableaux() sage: TestSuite(tabs).run() # long time """ - super(RowStandardTableauTuples_residue, self).__init__(category=FiniteEnumeratedSets()) + super().__init__(category=FiniteEnumeratedSets()) self._residue = residue self._quantum_characteristic = residue.quantum_characteristic() self._multicharge = residue.multicharge() @@ -3822,7 +3821,7 @@ def __init__(self, residue, shape): if residue.size() != shape.size(): raise ValueError('the size of the shape and the length of the residue defence must coincide!') - super(RowStandardTableauTuples_residue_shape, self).__init__(residue) + super().__init__(residue) self._shape = shape # The _standard_tableaux attribute below is used to generate the @@ -4736,7 +4735,7 @@ def __init__(self, shape): sage: STT.cardinality() 210 """ - super(StandardTableauTuples_shape, self).__init__(category=FiniteEnumeratedSets()) + super().__init__(category=FiniteEnumeratedSets()) from sage.combinat.partition_tuple import PartitionTuple self._shape = PartitionTuple(shape) self._level = len(shape) @@ -5087,7 +5086,7 @@ def __init__(self, residue): sage: T = StandardTableauTuple([[[6],[7]],[[1,2,3],[4,5]]]).residue_sequence(2,(0,0)).standard_tableaux() sage: TestSuite(T).run() """ - super(StandardTableaux_residue, self).__init__(residue, category=FiniteEnumeratedSets()) + super().__init__(residue, category=FiniteEnumeratedSets()) self._level = residue.level() self._multicharge = residue.multicharge() self._quantum_characteristic = residue.quantum_characteristic() diff --git a/src/sage/combinat/words/paths.py b/src/sage/combinat/words/paths.py index 2a847391252..8e73c2331a7 100644 --- a/src/sage/combinat/words/paths.py +++ b/src/sage/combinat/words/paths.py @@ -634,7 +634,7 @@ def __init__(self, alphabet): d = [(1 ,0), (0,1), (-1,0), (0,-1)] #Construction of the class - super(WordPaths_square_grid, self).__init__(alphabet, steps=d) + super().__init__(alphabet, steps=d) @lazy_attribute def _element_classes(self): @@ -710,7 +710,7 @@ def __init__(self, alphabet): vector(K, (ZZ(1)/ZZ(2), -sqrt3/2 ))) #Construction of the class - super(WordPaths_triangle_grid, self).__init__(alphabet, steps=d) + super().__init__(alphabet, steps=d) self._infinite_word_class = None self._finite_word_class = FiniteWordPath_triangle_grid @@ -778,7 +778,7 @@ def __init__(self, alphabet): """ #Construction of the class - super(WordPaths_hexagonal_grid, self).__init__(alphabet) + super().__init__(alphabet) self._infinite_word_class = None self._finite_word_class = FiniteWordPath_hexagonal_grid @@ -847,7 +847,7 @@ def __init__(self, alphabet): """ #Construction of the class d = [(1,0,0), (0,1,0), (0,0,1), (-1,0,0), (0,-1,0), (0,0,-1)] - super(WordPaths_cube_grid, self).__init__(alphabet, steps=d) + super().__init__(alphabet, steps=d) self._infinite_word_class = None self._finite_word_class = FiniteWordPath_cube_grid @@ -913,7 +913,7 @@ def __init__(self, alphabet): """ #Construction of the class d = [(1,1), (1,-1)] - super(WordPaths_dyck, self).__init__(alphabet, steps=d) + super().__init__(alphabet, steps=d) self._infinite_word_class = None self._finite_word_class = FiniteWordPath_dyck @@ -981,7 +981,7 @@ def __init__(self, alphabet): """ #Construction of the class d = [(0,1), (1,0)] - super(WordPaths_north_east, self).__init__(alphabet, steps=d) + super().__init__(alphabet, steps=d) self._infinite_word_class = None self._finite_word_class = FiniteWordPath_north_east @@ -2144,7 +2144,7 @@ def is_simple(self): pavages*, Thèse de doctorat en Mathématiques, Montréal, UQAM, septembre 2008, 115 pages. """ - return super(FiniteWordPath_square_grid,self).is_simple() + return super().is_simple() def tikz_trajectory(self): r""" @@ -2255,9 +2255,8 @@ def __init__(self, parent, *args, **kwds): sage: f == loads(dumps(f)) True - """ - super(FiniteWordPath_hexagonal_grid, self).__init__(parent, *args, **kwds) + super().__init__(parent, *args, **kwds) class FiniteWordPath_cube_grid(FiniteWordPath_3d): pass diff --git a/src/sage/combinat/words/word_datatypes.pyx b/src/sage/combinat/words/word_datatypes.pyx index 98d0df2616c..0492a276832 100644 --- a/src/sage/combinat/words/word_datatypes.pyx +++ b/src/sage/combinat/words/word_datatypes.pyx @@ -269,7 +269,7 @@ cdef class WordDatatype_list(WordDatatype): if isinstance(other, WordDatatype_list): return self._parent(self._data + other._data) else: - return super(WordDatatype_list, self).__mul__(other) + return super().__mul__(other) __add__ = __mul__ @@ -486,7 +486,7 @@ cdef class WordDatatype_str(WordDatatype): elif isinstance(sub, str): return self._data.find(sub, start, end) else: - return super(WordDatatype_str, self).find(sub, start, end) + return super().find(sub, start, end) def rfind(self, sub, start=0, end=None): r""" @@ -524,7 +524,7 @@ cdef class WordDatatype_str(WordDatatype): elif isinstance(sub, str): return self._data.rfind(sub, start, end) else: - return super(WordDatatype_str, self).rfind(sub, start, end) + return super().rfind(sub, start, end) def __len__(self): r""" @@ -606,7 +606,7 @@ cdef class WordDatatype_str(WordDatatype): if isinstance(other, WordDatatype_str): return self._parent(self._data + other._data) else: - return super(WordDatatype_str, self).__mul__(other) + return super().__mul__(other) __add__ = __mul__ @@ -802,7 +802,7 @@ cdef class WordDatatype_str(WordDatatype): elif isinstance(other, str): return other.endswith(self._data) else: - return super(WordDatatype_str, self).is_suffix(other) + return super().is_suffix(other) def has_suffix(self, other): """ @@ -834,7 +834,7 @@ cdef class WordDatatype_str(WordDatatype): elif isinstance(other, str): return self._data.endswith(other) else: - return super(WordDatatype_str, self).has_suffix(other) + return super().has_suffix(other) def is_prefix(self, other): r""" @@ -875,7 +875,7 @@ cdef class WordDatatype_str(WordDatatype): if isinstance(other ,str): return other.startswith(self._data) else: - return super(WordDatatype_str, self).is_prefix(other) + return super().is_prefix(other) def has_prefix(self, other): r""" @@ -916,7 +916,7 @@ cdef class WordDatatype_str(WordDatatype): if isinstance(other, str): return self._data.startswith(other) else: - return super(WordDatatype_str, self).has_prefix(other) + return super().has_prefix(other) cdef class WordDatatype_tuple(WordDatatype): r""" @@ -1120,6 +1120,6 @@ cdef class WordDatatype_tuple(WordDatatype): if isinstance(other, WordDatatype_tuple): return self._parent(self._data + other._data) else: - return super(WordDatatype_tuple, self).__mul__(other) + return super().__mul__(other) __add__ = __mul__ diff --git a/src/sage/combinat/words/word_infinite_datatypes.py b/src/sage/combinat/words/word_infinite_datatypes.py index 95664b687af..45816bf0ae3 100644 --- a/src/sage/combinat/words/word_infinite_datatypes.py +++ b/src/sage/combinat/words/word_infinite_datatypes.py @@ -346,7 +346,7 @@ def __init__(self, parent, callable, length=None): sage: w.length() +Infinity """ - super(WordDatatype_callable_with_caching,self).__init__(parent,callable,length) + super().__init__(parent, callable, length) # for caching self._letter_cache = {} @@ -515,11 +515,11 @@ def __getitem__(self, key): ValueError: for infinite words, start and stop values cannot be negative """ if isinstance(key, slice): - return super(WordDatatype_callable_with_caching, self).__getitem__(key) + return super().__getitem__(key) else: if key not in self._letter_cache: self._letter_cache[key] = \ - super(WordDatatype_callable_with_caching, self).__getitem__(key) + super().__getitem__(key) return self._letter_cache[key] def __reduce__(self): @@ -945,7 +945,7 @@ def __init__(self, parent, iter, length=None): sage: w._len 8 """ - super(WordDatatype_iter_with_caching,self).__init__(parent,iter,length) + super().__init__(parent, iter, length) # we use self._data for returning an iterator through __iter__; # we use self._gen for caching self._data, self._gen = itertools.tee(self._data) @@ -1158,10 +1158,10 @@ def __getitem__(self, key): ValueError: Step for islice() must be a positive integer or None. """ if isinstance(key, slice): - return super(WordDatatype_iter_with_caching,self).__getitem__(key) + return super().__getitem__(key) else: if key < 0: - return super(WordDatatype_iter_with_caching,self).__getitem__(key) + return super().__getitem__(key) else: while self._last_index < key: try: From 89a642cd0fc0acfd364dff4d66b4af217725f7fc Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Sun, 29 May 2022 19:52:03 +0900 Subject: [PATCH 504/529] Do not import quickref and tutorial from sage.combinat --- src/sage/combinat/all.py | 5 ++++- src/sage/misc/namespace_package.py | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/sage/combinat/all.py b/src/sage/combinat/all.py index 953c6b29761..daef30fab6e 100644 --- a/src/sage/combinat/all.py +++ b/src/sage/combinat/all.py @@ -44,11 +44,14 @@ - :ref:`sage.graphs` """ +from sage.misc.namespace_package import install_doc, install_dict # install the docstring of this module to the containing package -from sage.misc.namespace_package import install_doc install_doc(__package__, __doc__) +# install modules quickref and tutorial to the containing package from . import quickref, tutorial +install_dict(__package__, {'quickref': quickref, 'tutorial': tutorial}) +del quickref, tutorial from sage.misc.lazy_import import lazy_import diff --git a/src/sage/misc/namespace_package.py b/src/sage/misc/namespace_package.py index 75d9f1d8dcc..eaa05bdfd71 100644 --- a/src/sage/misc/namespace_package.py +++ b/src/sage/misc/namespace_package.py @@ -18,3 +18,17 @@ def install_doc(package, doc): pkg = import_module(package) pkg.__doc__ = doc # enable sage.package? pkg.getdoc = lambda: doc # enable help(sage.package) + +def install_dict(package, dic): + """ + Install ``dic`` to the ``__dict__`` of the package. + + TESTS: + + sage: from sage.misc.namespace_package import install_dict + sage: install_dict('sage', {'greeting': 'hello'}) + sage: sage.greeting + 'hello' + """ + pkg = import_module(package) + pkg.__dict__.update(dic) From 7787d86268157ce19f9e0208361c69e85b988e7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 29 May 2022 14:11:17 +0200 Subject: [PATCH 505/529] use super() outside of combinat --- src/sage/algebras/lie_algebras/subalgebra.py | 24 ++++-------- src/sage/coding/abstract_code.py | 20 +++++----- src/sage/coding/grs_code.py | 22 +++++------ src/sage/geometry/toric_lattice.py | 22 +++++------ src/sage/groups/misc_gps/argument_groups.py | 17 ++++----- src/sage/misc/converting_dict.py | 16 ++++---- src/sage/misc/sage_input.py | 29 +++++++------- .../modform_hecketriangle/graded_ring.py | 24 ++++-------- .../modular/modform_hecketriangle/space.py | 21 +++++----- src/sage/rings/asymptotic/growth_group.py | 23 ++++------- src/sage/rings/asymptotic/term_monoid.py | 15 ++++---- .../function_field_valuation.py | 21 +++++----- src/sage/structure/unique_representation.py | 20 +++++----- .../topology/simplicial_set_constructions.py | 38 +++++++++---------- 14 files changed, 139 insertions(+), 173 deletions(-) diff --git a/src/sage/algebras/lie_algebras/subalgebra.py b/src/sage/algebras/lie_algebras/subalgebra.py index c9e9748a7d6..6bd13a8aaf5 100644 --- a/src/sage/algebras/lie_algebras/subalgebra.py +++ b/src/sage/algebras/lie_algebras/subalgebra.py @@ -208,8 +208,8 @@ def __classcall_private__(cls, ambient, gens, ideal=False, if ambient in LieAlgebras(ambient.base_ring()).Nilpotent(): category = category.Nilpotent() - sup = super(LieSubalgebra_finite_dimensional_with_basis, cls) - return sup.__classcall__(cls, ambient, gens, ideal, order, category) + return super().__classcall__(cls, ambient, gens, ideal, + order, category) def __init__(self, ambient, gens, ideal, order=None, category=None): r""" @@ -240,8 +240,7 @@ def __init__(self, ambient, gens, ideal, order=None, category=None): self._reorganized_indices = [self._reversed_indices.index(i) for i in ambient.indices()] - sup = super(LieSubalgebra_finite_dimensional_with_basis, self) - sup.__init__(ambient.base_ring(), category=category) + super().__init__(ambient.base_ring(), category=category) # register a coercion to the ambient Lie algebra H = Hom(self, ambient) @@ -278,8 +277,7 @@ def __contains__(self, x): if x in self.ambient(): x = self.ambient()(x) return x.to_vector() in self.module() - sup = super(LieSubalgebra_finite_dimensional_with_basis, self) - return sup.__contains__(x) + return super().__contains__(x) def __getitem__(self, x): r""" @@ -300,8 +298,7 @@ def __getitem__(self, x): """ if isinstance(x, tuple) and len(x) == 2: return self(x[0])._bracket_(self(x[1])) - sup = super(LieSubalgebra_finite_dimensional_with_basis, self) - return sup.__getitem__(x) + return super().__getitem__(x) def _repr_(self): r""" @@ -405,8 +402,7 @@ def _element_constructor_(self, x): if isinstance(x, list) and len(x) == 2: return self(x[0])._bracket_(self(x[1])) - sup = super(LieSubalgebra_finite_dimensional_with_basis, self) - return sup._element_constructor_(x) + return super()._element_constructor_(x) def _to_m(self, X): r""" @@ -766,9 +762,7 @@ def from_vector(self, v, order=None, coerce=False): """ if len(v) == self.ambient().dimension(): return self.retract(self.ambient().from_vector(v)) - - sup = super(LieSubalgebra_finite_dimensional_with_basis, self) - return sup.from_vector(v) + return super().from_vector(v) def basis_matrix(self): r""" @@ -854,9 +848,7 @@ def is_ideal(self, A): """ if A == self.ambient() and self._is_ideal: return True - - sup = super(LieSubalgebra_finite_dimensional_with_basis, self) - return sup.is_ideal(A) + return super().is_ideal(A) def reduce(self, X): r""" diff --git a/src/sage/coding/abstract_code.py b/src/sage/coding/abstract_code.py index 525bb6e63ec..ba2ec68a038 100644 --- a/src/sage/coding/abstract_code.py +++ b/src/sage/coding/abstract_code.py @@ -154,7 +154,7 @@ class AbstractCode(Parent): - inherit from AbstractCode - call AbstractCode ``__init__`` method in the subclass constructor. - Example: ``super(SubclassName, self).__init__(length, "EncoderName", + Example: ``super().__init__(length, "EncoderName", "DecoderName", "metric")``. "EncoderName" and "DecoderName" are set to ``None`` by default, a generic code class such as AbstractCode does not necessarily have to have general encoders/decoders. However, if you @@ -232,7 +232,7 @@ def __init__(self, length, default_encoder_name=None, sage: from sage.coding.abstract_code import AbstractCode sage: class MyCodeFamily(AbstractCode): ....: def __init__(self, length): - ....: super(MyCodeFamily, self).__init__(length) + ....: super().__init__(length) ....: def __iter__(self): ....: for i in range(self.length() + 1): ....: yield vector([1 for j in range(i)] + [0 for k in range(i, self.length())]) @@ -314,7 +314,7 @@ def __getstate__(self): sage: '_registered_encoders' in C.__getstate__() True """ - d = super(AbstractCode, self).__getstate__() + d = super().__getstate__() d['_registered_encoders'] = self._registered_encoders d['_registered_decoders'] = self._registered_decoders return d @@ -334,7 +334,7 @@ def __iter__(self): sage: from sage.coding.abstract_code import AbstractCode sage: class MyCode(AbstractCode): ....: def __init__(self): - ....: super(MyCode, self).__init__(10) + ....: super().__init__(10) We check we get a sensible error message while asking for an iterator over the elements of our new class: @@ -362,7 +362,7 @@ def __contains__(self, c): sage: from sage.coding.abstract_code import AbstractCode sage: class MyCode(AbstractCode): ....: def __init__(self, length): - ....: super(MyCode, self).__init__(length) + ....: super().__init__(length) We check we get a sensible error message while asking if an element is in our new class: @@ -386,7 +386,7 @@ def ambient_space(self): sage: from sage.coding.abstract_code import AbstractCode sage: class MyCode(AbstractCode): ....: def __init__(self, length): - ....: super(MyCode, self).__init__(length) + ....: super().__init__(length) sage: C = MyCode(3) sage: C.ambient_space() Traceback (most recent call last): @@ -458,7 +458,7 @@ def _repr_(self): sage: from sage.coding.abstract_code import AbstractCode sage: class MyCode(AbstractCode): ....: def __init__(self): - ....: super(MyCode, self).__init__(10) + ....: super().__init__(10) We check we get a sensible error message while asking for a string representation of an instance of our new class: @@ -486,7 +486,7 @@ def _latex_(self): sage: from sage.coding.abstract_code import AbstractCode sage: class MyCode(AbstractCode): ....: def __init__(self): - ....: super(MyCode, self).__init__(10) + ....: super().__init__(10) We check we get a sensible error message while asking for a string representation of an instance of our new class: @@ -561,7 +561,7 @@ def add_decoder(self, name, decoder): sage: class MyDecoder(sage.coding.decoder.Decoder): ....: def __init__(self, code): - ....: super(MyDecoder, self).__init__(code) + ....: super().__init__(code) ....: def _repr_(self): ....: return "MyDecoder decoder with associated code %s" % self.code() @@ -623,7 +623,7 @@ def add_encoder(self, name, encoder): sage: class MyEncoder(sage.coding.encoder.Encoder): ....: def __init__(self, code): - ....: super(MyEncoder, self).__init__(code) + ....: super().__init__(code) ....: def _repr_(self): ....: return "MyEncoder encoder with associated code %s" % self.code() diff --git a/src/sage/coding/grs_code.py b/src/sage/coding/grs_code.py index 1bdbc70727f..840152f75f9 100644 --- a/src/sage/coding/grs_code.py +++ b/src/sage/coding/grs_code.py @@ -234,7 +234,7 @@ def __init__(self, evaluation_points, dimension, column_multipliers=None): if not F.is_finite() or not F.is_field(): raise ValueError("Evaluation points must be in a finite field (and %s is not one)" % F) - super(GeneralizedReedSolomonCode, self).__init__(F, + super().__init__(F, len(self._evaluation_points), "EvaluationVector", "Gao") if dimension not in ZZ or dimension > self._length or dimension < 1: @@ -703,7 +703,7 @@ def __init__(self, code): sage: E Evaluation vector-style encoder for [40, 12, 29] Reed-Solomon Code over GF(59) """ - super(GRSEvaluationVectorEncoder, self).__init__(code) + super().__init__(code) def __eq__(self, other): r""" @@ -874,7 +874,7 @@ def __init__(self, code, polynomial_ring=None): """ from sage.rings.polynomial.polynomial_ring import PolynomialRing_commutative - super(GRSEvaluationPolynomialEncoder, self).__init__(code) + super().__init__(code) if polynomial_ring is None: self._polynomial_ring = code.base_field()['x'] else: @@ -1129,8 +1129,8 @@ def __init__(self, code): """ if not isinstance(code, GeneralizedReedSolomonCode): raise ValueError("code has to be a generalized Reed-Solomon code") - super(GRSBerlekampWelchDecoder, self).__init__(code, code.ambient_space(), - "EvaluationPolynomial") + super().__init__(code, code.ambient_space(), + "EvaluationPolynomial") def __eq__(self, other): r""" @@ -1434,8 +1434,8 @@ def __init__(self, code): """ if not isinstance(code, GeneralizedReedSolomonCode): raise ValueError("code has to be a generalized Reed-Solomon code") - super(GRSGaoDecoder, self).__init__(code, code.ambient_space(), - "EvaluationPolynomial") + super().__init__(code, code.ambient_space(), + "EvaluationPolynomial") def __eq__(self, other): r""" @@ -1833,7 +1833,7 @@ def __init__(self, code): raise ValueError("code has to be a generalized Reed-Solomon code") input_space = cartesian_product([code.ambient_space(), VectorSpace(GF(2), code.ambient_space().dimension())]) - super(GRSErrorErasureDecoder, self).__init__(code, input_space, "EvaluationVector") + super().__init__(code, input_space, "EvaluationVector") def __eq__(self, other): r""" @@ -2074,8 +2074,8 @@ def __init__(self, code): raise ValueError("code has to be a generalized Reed-Solomon code") if code.base_field().zero() in code.evaluation_points(): raise ValueError("Impossible to use this decoder over a GRS code which contains 0 amongst its evaluation points") - super(GRSKeyEquationSyndromeDecoder, self).__init__(code, code.ambient_space(), - "EvaluationVector") + super().__init__(code, code.ambient_space(), + "EvaluationVector") def __eq__(self, other): r""" @@ -2354,7 +2354,7 @@ def decode_to_message(self, r): C = self.code() if C.length() == C.dimension(): return self.connected_encoder().unencode_nocheck(r) - return super(GRSKeyEquationSyndromeDecoder, self).decode_to_message(r) + return super().decode_to_message(r) def decoding_radius(self): r""" diff --git a/src/sage/geometry/toric_lattice.py b/src/sage/geometry/toric_lattice.py index de6880174aa..203f7f63223 100644 --- a/src/sage/geometry/toric_lattice.py +++ b/src/sage/geometry/toric_lattice.py @@ -431,7 +431,7 @@ def __call__(self, *args, **kwds): sage: N2( Q.an_element() ) N2(1, 0) """ - supercall = super(ToricLattice_generic, self).__call__ + supercall = super().__call__ if args == (0, ): # Special treatment for N(0) to return (0,...,0) return supercall(*args, **kwds) @@ -474,7 +474,7 @@ def _coerce_map_from_(self, other): if (is_ToricLattice(other) and other.ambient_module() is not self.ambient_module()): return None - return super(ToricLattice_generic, self)._convert_map_from_(other) + return super()._convert_map_from_(other) def __contains__(self, point): r""" @@ -578,7 +578,7 @@ def direct_sum(self, other): [0 0 0 0 1] """ if not isinstance(other, ToricLattice_generic): - return super(ToricLattice_generic, self).direct_sum(other) + return super().direct_sum(other) def make_name(N1, N2, use_latex=False): if use_latex: @@ -630,7 +630,7 @@ def intersection(self, other): raise ValueError("%s and %s have different ambient lattices!" % (self, other)) # Construct a generic intersection, but make sure to return a lattice. - I = super(ToricLattice_generic, self).intersection(other) + I = super().intersection(other) if not is_ToricLattice(I): I = self.ambient_module().submodule(I.basis()) return I @@ -755,7 +755,7 @@ def saturation(self): sage: Ns_sat is Ns_sat.saturation() True """ - S = super(ToricLattice_generic, self).saturation() + S = super().saturation() return S if is_ToricLattice(S) else self.ambient_module().submodule(S) def span(self, gens, base_ring=ZZ, *args, **kwds): @@ -803,8 +803,7 @@ def span(self, gens, base_ring=ZZ, *args, **kwds): if is_ToricLatticeElement(g) and g not in A: raise ValueError("%s cannot generate a sublattice of %s" % (g, A)) - return super(ToricLattice_generic, self).span(gens, base_ring, - *args, **kwds) + return super().span(gens, base_ring, *args, **kwds) def span_of_basis(self, basis, base_ring=ZZ, *args, **kwds): r""" @@ -858,8 +857,7 @@ def span_of_basis(self, basis, base_ring=ZZ, *args, **kwds): if is_ToricLatticeElement(g) and g not in A: raise ValueError("%s cannot generate a sublattice of %s" % (g, A)) - return super(ToricLattice_generic, self).span_of_basis( - basis, base_ring, *args, **kwds) + return super().span_of_basis(basis, base_ring, *args, **kwds) @richcmp_method @@ -895,7 +893,7 @@ def __init__(self, rank, name, dual_name, latex_name, latex_dual_name): sage: ToricLattice(3, "N", "M", "N", "M") 3-d lattice N """ - super(ToricLattice_ambient, self).__init__(ZZ, rank) + super().__init__(ZZ, rank) self._name = name self._dual_name = dual_name self._latex_name = latex_name @@ -1490,7 +1488,7 @@ def __init__(self, V, W, check=True, positive_point=None, positive_dual_point=No W = V.submodule(W) except (TypeError, ArithmeticError): raise ArithmeticError("W must be a sublattice of V") - super(ToricLattice_quotient, self).__init__(V, W, check, **kwds) + super().__init__(V, W, check, **kwds) if (positive_point, positive_dual_point) == (None, None): self._flip_sign_of_generator = False return @@ -1799,7 +1797,7 @@ def coordinate_vector(self, x, reduce=False): sage: Q.coordinate_vector(q) (1) """ - coordinates = super(ToricLattice_quotient, self).coordinate_vector(x,reduce) + coordinates = super().coordinate_vector(x, reduce) if self._flip_sign_of_generator: assert len(coordinates) == 1, "Sign flipped for a multi-dimensional quotient!" return -coordinates diff --git a/src/sage/groups/misc_gps/argument_groups.py b/src/sage/groups/misc_gps/argument_groups.py index 708d06c6998..c2e2de81e77 100644 --- a/src/sage/groups/misc_gps/argument_groups.py +++ b/src/sage/groups/misc_gps/argument_groups.py @@ -86,7 +86,7 @@ def __init__(self, parent, element, normalize=True): """ if parent is None: raise ValueError('parent must be provided') - super(AbstractArgument, self).__init__(parent=parent) + super().__init__(parent=parent) try: element = parent.base()(element) @@ -324,8 +324,7 @@ def __classcall__(cls, base, category=None): Category of commutative groups """ category = cls._determine_category_(category) - return super(AbstractArgumentGroup, cls).__classcall__( - cls, base, category) + return super().__classcall__(cls, base, category) @staticmethod def _determine_category_(category): @@ -364,8 +363,7 @@ def __init__(self, base, category): sage: UnitCircleGroup(RR).base() # indirect doctest Real Field with 53 bits of precision """ - super(AbstractArgumentGroup, self).__init__(category=category, - base=base) + super().__init__(category=category, base=base) def __hash__(self): r""" @@ -1024,7 +1022,7 @@ def __init__(self, category): Rational Field """ from sage.rings.rational_field import QQ - return super(RootsOfUnityGroup, self).__init__(base=QQ, + return super().__init__(base=QQ, category=category) def _repr_(self): r""" @@ -1075,7 +1073,7 @@ def __init__(self, parent, element, normalize=True): sage: C(1+2*I) # indirect doctest e^(I*arg(1.00000000000000 + 2.00000000000000*I)) """ - super(ArgumentByElement, self).__init__(parent, element, normalize=normalize) + super().__init__(parent, element, normalize=normalize) if self._element_ == 0: raise ValueError('{} is not allowed'.format(element)) @@ -1422,7 +1420,7 @@ def __init__(self, parent, element, normalize=True): sage: S.an_element() # indirect doctest -1 """ - super(Sign, self).__init__(parent, int(element), normalize=normalize) + super().__init__(parent, int(element), normalize=normalize) if self._element_ not in (-1, 1): raise ValueError('{} is not allowed ' '(only -1 or 1 is)'.format(element)) @@ -1643,8 +1641,7 @@ def __init__(self, category): sage: S.base() # indirect doctest """ - return super(SignGroup, self).__init__(base=int, - category=category) + return super().__init__(base=int, category=category) def _repr_(self): r""" diff --git a/src/sage/misc/converting_dict.py b/src/sage/misc/converting_dict.py index 48f3f5de3a5..7476555e210 100644 --- a/src/sage/misc/converting_dict.py +++ b/src/sage/misc/converting_dict.py @@ -93,7 +93,7 @@ def __init__(self, key_conversion_function, data=None): sage: list(KeyConvertingDict(int, [("9", 99)]).items()) [(9, 99)] """ - super(KeyConvertingDict, self).__init__() + super().__init__() self.key_conversion_function = key_conversion_function if data: self.update(data) @@ -115,7 +115,7 @@ def __getitem__(self, key): 42 """ key = self.key_conversion_function(key) - return super(KeyConvertingDict, self).__getitem__(key) + return super().__getitem__(key) def __setitem__(self, key, value): r""" @@ -135,7 +135,7 @@ def __setitem__(self, key, value): [(3, 42)] """ key = self.key_conversion_function(key) - return super(KeyConvertingDict, self).__setitem__(key, value) + return super().__setitem__(key, value) def __delitem__(self, key): r""" @@ -155,7 +155,7 @@ def __delitem__(self, key): 0 """ key = self.key_conversion_function(key) - return super(KeyConvertingDict, self).__delitem__(key) + return super().__delitem__(key) def __contains__(self, key): r""" @@ -176,7 +176,7 @@ def __contains__(self, key): False """ key = self.key_conversion_function(key) - return super(KeyConvertingDict, self).__contains__(key) + return super().__contains__(key) def pop(self, key, *args): r""" @@ -202,7 +202,7 @@ def pop(self, key, *args): KeyError: ... """ key = self.key_conversion_function(key) - return super(KeyConvertingDict, self).pop(key, *args) + return super().pop(key, *args) def setdefault(self, key, default=None): r""" @@ -223,7 +223,7 @@ def setdefault(self, key, default=None): [(3, None)] """ key = self.key_conversion_function(key) - return super(KeyConvertingDict, self).setdefault(key, default) + return super().setdefault(key, default) def update(self, *args, **kwds): r""" @@ -253,7 +253,7 @@ def update(self, *args, **kwds): {x: 42} """ f = self.key_conversion_function - u = super(KeyConvertingDict, self).update + u = super().update if args: if len(args) != 1: raise TypeError("update expected at most 1 argument") diff --git a/src/sage/misc/sage_input.py b/src/sage/misc/sage_input.py index 56286232257..006578b8460 100644 --- a/src/sage/misc/sage_input.py +++ b/src/sage/misc/sage_input.py @@ -1774,7 +1774,7 @@ def __init__(self, sib, n): sage: sib(3)._sie_value '3' """ - super(SIE_literal_stringrep, self).__init__(sib) + super().__init__(sib) self._sie_value = str(n) self._sie_share = False @@ -1851,7 +1851,7 @@ def __init__(self, sib, func, args, kwargs): sage: sib = SageInputBuilder() sage: sie = sib('RealField')(53, rnd='RNDZ') """ - super(SIE_call, self).__init__(sib) + super().__init__(sib) self._sie_func = func self._sie_args = args self._sie_kwargs = kwargs @@ -1959,7 +1959,7 @@ def __init__(self, sib, coll, key): sage: sib.empty_subscript(sib.name('QQ')) {subscr: {atomic:QQ}[]} """ - super(SIE_subscript, self).__init__(sib) + super().__init__(sib) self._sie_coll = coll self._sie_key = key @@ -2058,7 +2058,7 @@ def __init__(self, sib, obj, attr): sage: sib.name('QQbar').zeta(5) {call: {getattr: {atomic:QQbar}.zeta}({atomic:5})} """ - super(SIE_getattr, self).__init__(sib) + super().__init__(sib) self._sie_obj = obj self._sie_attr = attr @@ -2153,7 +2153,7 @@ def __init__(self, sib, values, is_list): sage: sib(["Hello", "world"]) {list: ({atomic:'Hello'}, {atomic:'world'})} """ - super(SIE_tuple, self).__init__(sib) + super().__init__(sib) self._sie_values = values self._sie_is_list = is_list @@ -2259,7 +2259,7 @@ def __init__(self, sib, entries): sage: sib.dict([(10, 'PS2'), (12, 'PS2'), (13, 'PS3')]) {dict: {{atomic:10}:{atomic:'PS2'}, {atomic:12}:{atomic:'PS2'}, {atomic:13}:{atomic:'PS3'}}} """ - super(SIE_dict, self).__init__(sib) + super().__init__(sib) self._sie_entries = entries def __repr__(self): @@ -2349,9 +2349,8 @@ def __init__(self, sib, op, lhs, rhs): sage: sib = SageInputBuilder() sage: sib(3)*5 {binop:* {atomic:3} {atomic:5}} - """ - super(SIE_binary, self).__init__(sib) + super().__init__(sib) self._sie_op = op self._sie_operands = (lhs, rhs) @@ -2498,7 +2497,7 @@ def __init__(self, sib, op, operand): sage: -sib(3) {unop:- {atomic:3}} """ - super(SIE_unary, self).__init__(sib) + super().__init__(sib) self._sie_op = op self._sie_operand = operand @@ -2691,7 +2690,7 @@ def __init__(self, sib, constr, gen_names, gens_syntax=None): ....: gens_syntax=sib.empty_subscript(qq)) {constr_parent: {subscr: {atomic:QQ}[{atomic:'x'}]} with gens: ('x',)} """ - super(SIE_gens_constructor, self).__init__(sib) + super().__init__(sib) self._sie_constr = constr self._sie_gen_names = gen_names self._sie_gens = None # will be overwritten from .parent_with_gens() @@ -2909,7 +2908,7 @@ def __init__(self, sib, parent, name): sage: sib.gen(ZZ['x']) # indirect doctest {gen:x {constr_parent: {subscr: {atomic:ZZ}[{atomic:'x'}]} with gens: ('x',)}} """ - super(SIE_gen, self).__init__(sib) + super().__init__(sib) self._sie_parent = parent self._sie_preferred_varname = name @@ -2960,7 +2959,7 @@ def _sie_prepare(self, sif): sage: sie._sie_parent._sie_assign_gens True """ - super(SIE_gen, self)._sie_prepare(sif) + super()._sie_prepare(sif) self._sie_parent._sie_gens_referenced(sif) def _sie_format(self, sif): @@ -3065,7 +3064,7 @@ def __init__(self, sib, module, name, alt_name=None): sage: sib.import_name('sage.foo', 'happy', 'sad') {import:sage.foo/happy as sad} """ - super(SIE_import_name, self).__init__(sib) + super().__init__(sib) self._sie_formatted = False self._sie_module_name = module self._sie_object_name = name @@ -3123,7 +3122,7 @@ def _sie_prepare(self, sif): sage: sie._sie_requested_varname True """ - super(SIE_import_name, self)._sie_prepare(sif) + super()._sie_prepare(sif) self._sie_require_varname(sif) def _sie_format(self, sif): @@ -3193,7 +3192,7 @@ def __init__(self, sib, lhs, rhs): sage: sib.assign(sib.name('foo').x, sib.name('pi')) {assign: {getattr: {atomic:foo}.x} {atomic:pi}} """ - super(SIE_assign, self).__init__(sib) + super().__init__(sib) self._sie_lhs = lhs self._sie_rhs = rhs diff --git a/src/sage/modular/modform_hecketriangle/graded_ring.py b/src/sage/modular/modform_hecketriangle/graded_ring.py index 42325e3423e..13d00dbbef6 100644 --- a/src/sage/modular/modform_hecketriangle/graded_ring.py +++ b/src/sage/modular/modform_hecketriangle/graded_ring.py @@ -75,9 +75,8 @@ def __classcall__(cls, group = HeckeTriangleGroup(3), base_ring = ZZ, red_hom = sage: QuasiMeromorphicModularFormsRing(4, ZZ, 1) == QuasiMeromorphicModularFormsRing(group, base_ring, red_hom, n) True """ - (group, base_ring, red_hom, n) = canonical_parameters(group, base_ring, red_hom, n) - return super(FormsRing_abstract,cls).__classcall__(cls, group=group, base_ring=base_ring, red_hom=red_hom, n=n) + return super().__classcall__(cls, group=group, base_ring=base_ring, red_hom=red_hom, n=n) def __init__(self, group, base_ring, red_hom, n): r""" @@ -138,9 +137,8 @@ def __classcall__(cls, group = HeckeTriangleGroup(3), base_ring = ZZ, red_hom = sage: QuasiWeakModularFormsRing(5, CC, 0) == QuasiWeakModularFormsRing(group, base_ring, red_hom, n) True """ - (group, base_ring, red_hom, n) = canonical_parameters(group, base_ring, red_hom, n) - return super(FormsRing_abstract,cls).__classcall__(cls, group=group, base_ring=base_ring, red_hom=red_hom, n=n) + return super().__classcall__(cls, group=group, base_ring=base_ring, red_hom=red_hom, n=n) def __init__(self, group, base_ring, red_hom, n): r""" @@ -198,9 +196,8 @@ def __classcall__(cls, group = HeckeTriangleGroup(3), base_ring = ZZ, red_hom = sage: QuasiModularFormsRing(6, ZZ, True) == QuasiModularFormsRing(group, base_ring, red_hom, n) True """ - (group, base_ring, red_hom, n) = canonical_parameters(group, base_ring, red_hom, n) - return super(FormsRing_abstract,cls).__classcall__(cls, group=group, base_ring=base_ring, red_hom=red_hom, n=n) + return super().__classcall__(cls, group=group, base_ring=base_ring, red_hom=red_hom, n=n) def __init__(self, group, base_ring, red_hom, n): r""" @@ -258,9 +255,8 @@ def __classcall__(cls, group = HeckeTriangleGroup(3), base_ring = ZZ, red_hom = sage: QuasiCuspFormsRing(7, ZZ, 1) == QuasiCuspFormsRing(group, base_ring, red_hom, n) True """ - (group, base_ring, red_hom, n) = canonical_parameters(group, base_ring, red_hom, n) - return super(FormsRing_abstract,cls).__classcall__(cls, group=group, base_ring=base_ring, red_hom=red_hom, n=n) + return super().__classcall__(cls, group=group, base_ring=base_ring, red_hom=red_hom, n=n) def __init__(self, group, base_ring, red_hom, n): r""" @@ -318,9 +314,8 @@ def __classcall__(cls, group = HeckeTriangleGroup(3), base_ring = ZZ, red_hom = sage: MeromorphicModularFormsRing(4, ZZ, 1) == MeromorphicModularFormsRing(group, base_ring, red_hom, n) True """ - (group, base_ring, red_hom, n) = canonical_parameters(group, base_ring, red_hom, n) - return super(FormsRing_abstract,cls).__classcall__(cls, group=group, base_ring=base_ring, red_hom=red_hom, n=n) + return super().__classcall__(cls, group=group, base_ring=base_ring, red_hom=red_hom, n=n) def __init__(self, group, base_ring, red_hom, n): r""" @@ -378,9 +373,8 @@ def __classcall__(cls, group = HeckeTriangleGroup(3), base_ring = ZZ, red_hom = sage: WeakModularFormsRing(5, ZZ, 0) == WeakModularFormsRing(group, base_ring, red_hom, n) True """ - (group, base_ring, red_hom, n) = canonical_parameters(group, base_ring, red_hom, n) - return super(FormsRing_abstract,cls).__classcall__(cls, group=group, base_ring=base_ring, red_hom=red_hom, n=n) + return super().__classcall__(cls, group=group, base_ring=base_ring, red_hom=red_hom, n=n) def __init__(self, group, base_ring, red_hom, n): r""" @@ -437,9 +431,8 @@ def __classcall__(cls, group = HeckeTriangleGroup(3), base_ring = ZZ, red_hom = sage: ModularFormsRing(3, ZZ, 0) == ModularFormsRing() True """ - (group, base_ring, red_hom, n) = canonical_parameters(group, base_ring, red_hom, n) - return super(FormsRing_abstract,cls).__classcall__(cls, group=group, base_ring=base_ring, red_hom=red_hom, n=n) + return super().__classcall__(cls, group=group, base_ring=base_ring, red_hom=red_hom, n=n) def __init__(self, group, base_ring, red_hom, n): r""" @@ -497,9 +490,8 @@ def __classcall__(cls, group = HeckeTriangleGroup(3), base_ring = ZZ, red_hom = sage: CuspFormsRing(5, CC, True) == CuspFormsRing(group, base_ring, red_hom, n) True """ - (group, base_ring, red_hom, n) = canonical_parameters(group, base_ring, red_hom, n) - return super(FormsRing_abstract,cls).__classcall__(cls, group=group, base_ring=base_ring, red_hom=red_hom, n=n) + return super().__classcall__(cls, group=group, base_ring=base_ring, red_hom=red_hom, n=n) def __init__(self, group, base_ring, red_hom, n): r""" diff --git a/src/sage/modular/modform_hecketriangle/space.py b/src/sage/modular/modform_hecketriangle/space.py index 84323cf0ab9..beae939854d 100644 --- a/src/sage/modular/modform_hecketriangle/space.py +++ b/src/sage/modular/modform_hecketriangle/space.py @@ -96,9 +96,8 @@ def __classcall__(cls, group = HeckeTriangleGroup(3), base_ring = ZZ, k=QQ(0), e sage: QuasiMeromorphicModularForms(5, ZZ, 20/3, int(1)) == QuasiMeromorphicModularForms(group, base_ring, k, ep, n) True """ - (group, base_ring, k, ep, n) = canonical_parameters(group, base_ring, k, ep, n) - return super(FormsSpace_abstract,cls).__classcall__(cls, group=group, base_ring=base_ring, k=k, ep=ep, n=n) + return super().__classcall__(cls, group=group, base_ring=base_ring, k=k, ep=ep, n=n) def __init__(self, group, base_ring, k, ep, n): r""" @@ -145,7 +144,7 @@ def __classcall__(cls, group = HeckeTriangleGroup(3), base_ring = ZZ, k=QQ(0), e """ (group, base_ring, k, ep, n) = canonical_parameters(group, base_ring, k, ep, n) - return super(FormsSpace_abstract,cls).__classcall__(cls, group=group, base_ring=base_ring, k=k, ep=ep, n=n) + return super().__classcall__(cls, group=group, base_ring=base_ring, k=k, ep=ep, n=n) def __init__(self, group, base_ring, k, ep, n): r""" @@ -192,7 +191,7 @@ def __classcall__(cls, group = HeckeTriangleGroup(3), base_ring = ZZ, k=QQ(0), e """ (group, base_ring, k, ep, n) = canonical_parameters(group, base_ring, k, ep, n) - return super(FormsSpace_abstract,cls).__classcall__(cls, group=group, base_ring=base_ring, k=k, ep=ep, n=n) + return super().__classcall__(cls, group=group, base_ring=base_ring, k=k, ep=ep, n=n) def __init__(self, group, base_ring, k, ep, n): r""" @@ -354,7 +353,7 @@ def __classcall__(cls, group = HeckeTriangleGroup(3), base_ring = ZZ, k=QQ(0), e """ (group, base_ring, k, ep, n) = canonical_parameters(group, base_ring, k, ep, n) - return super(FormsSpace_abstract,cls).__classcall__(cls, group=group, base_ring=base_ring, k=k, ep=ep, n=n) + return super().__classcall__(cls, group=group, base_ring=base_ring, k=k, ep=ep, n=n) def __init__(self, group, base_ring, k, ep, n): r""" @@ -526,7 +525,7 @@ def __classcall__(cls, group = HeckeTriangleGroup(3), base_ring = ZZ, k=QQ(0), e """ (group, base_ring, k, ep, n) = canonical_parameters(group, base_ring, k, ep, n) - return super(FormsSpace_abstract,cls).__classcall__(cls, group=group, base_ring=base_ring, k=k, ep=ep, n=n) + return super().__classcall__(cls, group=group, base_ring=base_ring, k=k, ep=ep, n=n) def __init__(self, group, base_ring, k, ep, n): r""" @@ -573,7 +572,7 @@ def __classcall__(cls, group = HeckeTriangleGroup(3), base_ring = ZZ, k=QQ(0), e """ (group, base_ring, k, ep, n) = canonical_parameters(group, base_ring, k, ep, n) - return super(FormsSpace_abstract,cls).__classcall__(cls, group=group, base_ring=base_ring, k=k, ep=ep, n=n) + return super().__classcall__(cls, group=group, base_ring=base_ring, k=k, ep=ep, n=n) def __init__(self, group, base_ring, k, ep, n): r""" @@ -618,7 +617,7 @@ def __classcall__(cls, group = HeckeTriangleGroup(3), base_ring = ZZ, k=QQ(0), e """ (group, base_ring, k, ep, n) = canonical_parameters(group, base_ring, k, ep, n) - return super(FormsSpace_abstract,cls).__classcall__(cls, group=group, base_ring=base_ring, k=k, ep=ep, n=n) + return super().__classcall__(cls, group=group, base_ring=base_ring, k=k, ep=ep, n=n) def __init__(self, group, base_ring, k, ep, n): r""" @@ -769,9 +768,8 @@ def __classcall__(cls, group = HeckeTriangleGroup(3), base_ring = ZZ, k=QQ(0), e sage: CuspForms(6, ZZ, 6, 1) == CuspForms(group, base_ring, k, ep, n) True """ - (group, base_ring, k, ep, n) = canonical_parameters(group, base_ring, k, ep, n) - return super(FormsSpace_abstract,cls).__classcall__(cls, group=group, base_ring=base_ring, k=k, ep=ep, n=n) + return super().__classcall__(cls, group=group, base_ring=base_ring, k=k, ep=ep, n=n) def __init__(self, group, base_ring, k, ep, n): r""" @@ -922,9 +920,8 @@ def __classcall__(cls, group = HeckeTriangleGroup(3), base_ring = ZZ, k=QQ(0), e sage: ZeroForm(6, CC, 3, -1) == ZeroForm(group, base_ring, k, ep, n) True """ - (group, base_ring, k, ep, n) = canonical_parameters(group, base_ring, k, ep, n) - return super(FormsSpace_abstract,cls).__classcall__(cls, group=group, base_ring=base_ring, k=k, ep=ep, n=n) + return super().__classcall__(cls, group=group, base_ring=base_ring, k=k, ep=ep, n=n) def __init__(self, group, base_ring, k, ep, n): r""" diff --git a/src/sage/rings/asymptotic/growth_group.py b/src/sage/rings/asymptotic/growth_group.py index a91ec314486..98f40457f07 100644 --- a/src/sage/rings/asymptotic/growth_group.py +++ b/src/sage/rings/asymptotic/growth_group.py @@ -665,7 +665,7 @@ def __init__(self, element, *args, **kwds): ... PartialConversionValueError: wrong value """ - super(PartialConversionValueError, self).__init__(*args, **kwds) + super().__init__(*args, **kwds) self.element = element @@ -1172,7 +1172,7 @@ def __init__(self, parent, raw_element): """ if parent is None: raise ValueError('The parent must be provided') - super(GenericGrowthElement, self).__init__(parent=parent) + super().__init__(parent=parent) try: self._raw_element_ = parent.base()(raw_element) @@ -1777,8 +1777,7 @@ def __classcall__(cls, base, var=None, category=None, ignore_variables=None): cls._determine_category_axiom_mapping_, initial_category=cls._initial_category_(base)) - return super(GenericGrowthGroup, cls).__classcall__( - cls, base, var, category) + return super().__classcall__(cls, base, var, category) @staticmethod def _initial_category_(base): @@ -1888,8 +1887,7 @@ def __init__(self, base, var, category): """ self._var_ = var - super(GenericGrowthGroup, self).__init__(category=category, - base=base) + super().__init__(category=category, base=base) def _repr_short_(self): r""" @@ -2714,8 +2712,7 @@ def __init__(self, var, domain): elif not isinstance(var, Variable): var = Variable(var) self.var = var - super(ConstructionFunctor, self).__init__( - domain, Monoids() & Posets()) + super().__init__(domain, Monoids() & Posets()) def _repr_(self): r""" @@ -3896,9 +3893,7 @@ def __init__(self, var): MonomialGrowthGroup[x] """ from sage.categories.commutative_additive_monoids import CommutativeAdditiveMonoids - - super(MonomialGrowthGroupFunctor, self).__init__(var, - CommutativeAdditiveMonoids()) + super().__init__(var, CommutativeAdditiveMonoids()) def _apply_functor(self, base): r""" @@ -4420,7 +4415,7 @@ def __init__(self, base, *args, **kwds): """ from warnings import warn - super(ExponentialGrowthGroup, self).__init__(base, *args, **kwds) + super().__init__(base, *args, **kwds) if isinstance(base, sage.rings.abc.SymbolicRing) and not self._an_element_base_() > 0: warn("When using the Exponential {}, make " "assumptions on the used symbolic elements.\n" @@ -4947,9 +4942,7 @@ def __init__(self, var): ExponentialGrowthGroup[x] """ from sage.categories.monoids import Monoids - - super(ExponentialGrowthGroupFunctor, self).__init__(var, - Monoids()) + super().__init__(var, Monoids()) def _apply_functor(self, base): r""" diff --git a/src/sage/rings/asymptotic/term_monoid.py b/src/sage/rings/asymptotic/term_monoid.py index 35064d10b18..53dfbc621a1 100644 --- a/src/sage/rings/asymptotic/term_monoid.py +++ b/src/sage/rings/asymptotic/term_monoid.py @@ -389,7 +389,7 @@ def __init__(self, parent, growth): raise ValueError('The parent must be provided') self.growth = parent.growth_group(growth) - super(GenericTerm, self).__init__(parent=parent) + super().__init__(parent=parent) def construction(self): r""" @@ -1469,7 +1469,7 @@ def __classcall__(cls, term_monoid_factory, from sage.categories.posets import Posets category = Monoids() & Posets() - return super(GenericTermMonoid, cls).__classcall__( + return super().__classcall__( cls, term_monoid_factory, growth_group, coefficient_ring, category) def __init__(self, term_monoid_factory, growth_group, coefficient_ring, category): @@ -1513,7 +1513,7 @@ def __init__(self, term_monoid_factory, growth_group, coefficient_ring, category self._term_monoid_factory_ = term_monoid_factory self._growth_group_ = growth_group self._coefficient_ring_ = coefficient_ring - super(GenericTermMonoid, self).__init__(category=category) + super().__init__(category=category) @property def term_monoid_factory(self): @@ -3092,7 +3092,7 @@ def _coerce_map_from_(self, S): self.coefficient_ring.has_coerce_map_from(S.coefficient_ring): return True else: - return super(OTermMonoid, self)._coerce_map_from_(S) + return super()._coerce_map_from_(S) def _repr_(self): r""" @@ -3191,7 +3191,7 @@ def __init__(self, parent, growth, coefficient): sage: CT_ZZ(x^42, coefficient=42) Term with coefficient 42 and growth x^42 """ - super(TermWithCoefficient, self).__init__(parent=parent, growth=growth) + super().__init__(parent=parent, growth=growth) try: coefficient = parent.coefficient_ring(coefficient) except (ValueError, TypeError): @@ -3416,7 +3416,7 @@ def _calculate_pow_(self, exponent): ArithmeticError('Cannot take %s to the exponent %s in %s since its ' 'coefficient %s cannot be taken to this exponent.' % (self, exponent, self.parent(), self.coefficient)), e) - return super(TermWithCoefficient, self)._calculate_pow_(exponent, new_coefficient=c) + return super()._calculate_pow_(exponent, new_coefficient=c) def _log_coefficient_(self, base=None, locals=None): r""" @@ -3507,8 +3507,7 @@ def _eq_(self, other): sage: t == T(x^2, coefficient=1) False """ - return super(TermWithCoefficient, self)._eq_(other) and \ - self.coefficient == other.coefficient + return super()._eq_(other) and self.coefficient == other.coefficient class TermWithCoefficientMonoid(GenericTermMonoid): diff --git a/src/sage/rings/function_field/function_field_valuation.py b/src/sage/rings/function_field/function_field_valuation.py index 3747cdb6668..2573df22267 100644 --- a/src/sage/rings/function_field/function_field_valuation.py +++ b/src/sage/rings/function_field/function_field_valuation.py @@ -615,7 +615,7 @@ def element_with_valuation(self, s): """ constant_valuation = self.restriction(self.domain().constant_base_field()) if constant_valuation.is_trivial(): - return super(RationalFunctionFieldValuation_base, self).element_with_valuation(s) + return super().element_with_valuation(s) a, b = self.value_group()._element_with_valuation(constant_valuation.value_group(), s) ret = self.uniformizer()**a * constant_valuation.element_with_valuation(constant_valuation.value_group().gen()*b) @@ -672,7 +672,7 @@ def _ge_(self, other): return other.is_discrete_valuation() if isinstance(other, ClassicalFunctionFieldValuation_base): return self == other - super(ClassicalFunctionFieldValuation_base, self)._ge_(other) + super()._ge_(other) class InducedRationalFunctionFieldValuation_base(FunctionFieldValuation_base): @@ -845,7 +845,7 @@ def extensions(self, L): W = self._base_valuation.extensions(L._ring) return [L.valuation(w) for w in W] - return super(InducedRationalFunctionFieldValuation_base, self).extensions(L) + return super().extensions(L) def _call_(self, f): r""" @@ -887,7 +887,7 @@ def restriction(self, ring): """ if ring.is_subring(self._base_valuation.domain()): return self._base_valuation.restriction(ring) - return super(InducedRationalFunctionFieldValuation_base, self).restriction(ring) + return super().restriction(ring) def simplify(self, f, error=None, force=False): r""" @@ -1096,7 +1096,7 @@ def residue_ring(self): """ if not self.is_discrete_valuation(): # A pseudo valuation attaining negative infinity does typically not have a function field as its residue ring - return super(NonClassicalRationalFunctionFieldValuation, self).residue_ring() + return super().residue_ring() return self._base_valuation.residue_ring().fraction_field().function_field() @@ -1166,7 +1166,7 @@ def scale(self, scalar): """ if scalar in QQ and scalar > 0 and scalar != 1: return self.domain().valuation(self._base_valuation._initial_approximation.scale(scalar)) - return super(FunctionFieldFromLimitValuation, self).scale(scalar) + return super().scale(scalar) class FunctionFieldMappedValuation_base(FunctionFieldValuation_base, MappedValuation_base): @@ -1250,7 +1250,7 @@ def scale(self, scalar): from sage.rings.rational_field import QQ if scalar in QQ and scalar > 0 and scalar != 1: return self.domain().valuation((self._base_valuation.scale(scalar), self._to_base, self._from_base)) - return super(FunctionFieldMappedValuation_base, self).scale(scalar) + return super().scale(scalar) def _repr_(self): r""" @@ -1330,7 +1330,7 @@ def restriction(self, ring): """ if ring.is_subring(self.domain().constant_base_field()): return self._base_valuation.restriction(ring) - return super(FunctionFieldMappedValuation_base, self).restriction(ring) + return super().restriction(ring) class RationalFunctionFieldMappedValuation(FunctionFieldMappedValuationRelative_base, RationalFunctionFieldValuation_base): @@ -1461,7 +1461,7 @@ def _repr_(self): assert(self.domain().base() is not self.domain()) if repr(self._base_valuation) == repr(self.restriction(self.domain().base())): return repr(self._base_valuation) - return super(FunctionFieldExtensionMappedValuation, self)._repr_() + return super()._repr_() def restriction(self, ring): r""" @@ -1476,8 +1476,7 @@ def restriction(self, ring): sage: w = v.extension(L) sage: w.restriction(K) is v True - """ if ring.is_subring(self.domain().base()): return self._base_valuation.restriction(ring) - return super(FunctionFieldExtensionMappedValuation, self).restriction(ring) + return super().restriction(ring) diff --git a/src/sage/structure/unique_representation.py b/src/sage/structure/unique_representation.py index 5d8d4ad758b..c641550abe2 100644 --- a/src/sage/structure/unique_representation.py +++ b/src/sage/structure/unique_representation.py @@ -179,7 +179,7 @@ class will by default also be used as keys for the cache:: sage: class WrongUsage(CachedRepresentation): ....: @staticmethod ....: def __classcall__(cls, n): - ....: return super(WrongUsage,cls).__classcall__(cls, n^2) + ....: return super().__classcall__(cls, n^2) ....: def __init__(self, n): ....: self.n = n ....: def __repr__(self): @@ -205,7 +205,7 @@ class will by default also be used as keys for the cache:: sage: class BetterUsage(CachedRepresentation): ....: @staticmethod ....: def __classcall__(cls, n): - ....: return super(BetterUsage, cls).__classcall__(cls, abs(n)) + ....: return super().__classcall__(cls, abs(n)) ....: def __init__(self, n): ....: self.n = n^2 ....: def __repr__(self): @@ -249,8 +249,8 @@ class will by default also be used as keys for the cache:: ....: @staticmethod ....: def __classcall__(cls, n, implementation=0): ....: if implementation: - ....: return super(C2, cls).__classcall__(cls, (n,)*implementation) - ....: return super(C2, cls).__classcall__(cls, n) + ....: return super().__classcall__(cls, (n,)*implementation) + ....: return super().__classcall__(cls, n) ....: def __init__(self, t): ....: self.t = t ....: def __repr__(self): @@ -640,7 +640,7 @@ class CachedRepresentation(metaclass=ClasscallMetaclass): ....: @staticmethod ....: def __classcall__(cls, iterable): ....: t = tuple(iterable) - ....: return super(MyClass2, cls).__classcall__(cls, t) + ....: return super().__classcall__(cls, t) ....: ....: def __init__(self, value): ....: self.value = value @@ -667,7 +667,7 @@ class CachedRepresentation(metaclass=ClasscallMetaclass): sage: class MyClass3(UniqueRepresentation): ....: @staticmethod ....: def __classcall__(cls, value = 3): - ....: return super(MyClass3, cls).__classcall__(cls, value) + ....: return super().__classcall__(cls, value) ....: ....: def __init__(self, value): ....: self.value = value @@ -716,7 +716,7 @@ class CachedRepresentation(metaclass=ClasscallMetaclass): sage: class WrongUsage(CachedRepresentation): ....: @staticmethod ....: def __classcall__(cls, n): - ....: return super(WrongUsage,cls).__classcall__(cls, n^2) + ....: return super().__classcall__(cls, n^2) ....: def __init__(self, n): ....: self.n = n ....: def __repr__(self): @@ -742,7 +742,7 @@ class CachedRepresentation(metaclass=ClasscallMetaclass): sage: class BetterUsage(CachedRepresentation): ....: @staticmethod ....: def __classcall__(cls, n): - ....: return super(BetterUsage, cls).__classcall__(cls, abs(n)) + ....: return super().__classcall__(cls, abs(n)) ....: def __init__(self, n): ....: self.n = n^2 ....: def __repr__(self): @@ -1028,7 +1028,7 @@ def _clear_cache_(cls): sage: class B(A): ....: @staticmethod ....: def __classcall__(cls, *args, **kwds): - ....: return super(B,cls).__classcall__(cls,*args,**kwds) + ....: return super().__classcall__(cls,*args,**kwds) sage: class C(B): pass sage: a = A(1) sage: b = B(2) @@ -1061,7 +1061,7 @@ def _clear_cache_(cls): ....: @staticmethod ....: def __classcall_private__(cls, *args, **kwds): ....: print("Private B") - ....: return super(B,cls).__classcall__(cls,*args,**kwds) + ....: return super().__classcall__(cls,*args,**kwds) sage: class C(B): pass sage: a = A(1) sage: b = B(2) diff --git a/src/sage/topology/simplicial_set_constructions.py b/src/sage/topology/simplicial_set_constructions.py index 5b192d019bc..5a737558c9c 100644 --- a/src/sage/topology/simplicial_set_constructions.py +++ b/src/sage/topology/simplicial_set_constructions.py @@ -120,7 +120,7 @@ def __classcall__(self, data, ambient=None): L.append((x, None)) else: L.append((x, tuple(data[x]))) - return super(SubSimplicialSet, self).__classcall__(self, tuple(L), ambient) + return super().__classcall__(self, tuple(L), ambient) def __init__(self, data, ambient=None): r""" @@ -239,8 +239,8 @@ def __classcall_private__(self, maps=None): True """ if maps: - return super(PullbackOfSimplicialSets, self).__classcall__(self, tuple(maps)) - return super(PullbackOfSimplicialSets, self).__classcall__(self) + return super().__classcall__(self, tuple(maps)) + return super().__classcall__(self) def __init__(self, maps=None): r""" @@ -423,8 +423,8 @@ def __classcall_private__(self, maps=None): True """ if maps: - return super(PullbackOfSimplicialSets_finite, self).__classcall__(self, tuple(maps)) - return super(PullbackOfSimplicialSets_finite, self).__classcall__(self) + return super().__classcall__(self, tuple(maps)) + return super().__classcall__(self) def __init__(self, maps=None): r""" @@ -763,8 +763,8 @@ def __classcall__(cls, factors=None): True """ if factors: - return super(ProductOfSimplicialSets, cls).__classcall__(cls, factors=tuple(factors)) - return super(ProductOfSimplicialSets, cls).__classcall__(cls) + return super().__classcall__(cls, factors=tuple(factors)) + return super().__classcall__(cls) def __init__(self, factors=None): r""" @@ -1129,9 +1129,9 @@ def __classcall_private__(cls, maps=None, vertex_name=None): True """ if maps: - return super(PushoutOfSimplicialSets, cls).__classcall__(cls, maps=tuple(maps), - vertex_name=vertex_name) - return super(PushoutOfSimplicialSets, cls).__classcall__(cls, vertex_name=vertex_name) + return super().__classcall__(cls, maps=tuple(maps), + vertex_name=vertex_name) + return super().__classcall__(cls, vertex_name=vertex_name) def __init__(self, maps=None, vertex_name=None): r""" @@ -1392,9 +1392,9 @@ def __classcall_private__(cls, maps=None, vertex_name=None): True """ if maps: - return super(PushoutOfSimplicialSets_finite, cls).__classcall__(cls, maps=tuple(maps), - vertex_name=vertex_name) - return super(PushoutOfSimplicialSets_finite, cls).__classcall__(cls, vertex_name=vertex_name) + return super().__classcall__(cls, maps=tuple(maps), + vertex_name=vertex_name) + return super().__classcall__(cls, vertex_name=vertex_name) def __init__(self, maps=None, vertex_name=None): r""" @@ -1888,8 +1888,8 @@ def __classcall__(cls, factors=None): True """ if factors: - return super(SmashProductOfSimplicialSets_finite, cls).__classcall__(cls, factors=tuple(factors)) - return super(SmashProductOfSimplicialSets_finite, cls).__classcall__(cls) + return super().__classcall__(cls, factors=tuple(factors)) + return super().__classcall__(cls) def __init__(self, factors=None): r""" @@ -1964,8 +1964,8 @@ def __classcall__(cls, factors=None): True """ if factors: - return super(WedgeOfSimplicialSets, cls).__classcall__(cls, factors=tuple(factors)) - return super(WedgeOfSimplicialSets, cls).__classcall__(cls) + return super().__classcall__(cls, factors=tuple(factors)) + return super().__classcall__(cls) def __init__(self, factors=None): r""" @@ -2159,8 +2159,8 @@ def __classcall__(cls, factors=None): # Discard any empty factors. factors = [F for F in factors if F != Empty()] if factors: - return super(DisjointUnionOfSimplicialSets, cls).__classcall__(cls, factors=tuple(factors)) - return super(DisjointUnionOfSimplicialSets, cls).__classcall__(cls) + return super().__classcall__(cls, factors=tuple(factors)) + return super().__classcall__(cls) def __init__(self, factors=None): r""" From 380bdf63777f882eb5c6dd037e5caf6021051fd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 29 May 2022 17:06:00 +0200 Subject: [PATCH 506/529] fix doctests --- src/sage/combinat/crystals/littelmann_path.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/sage/combinat/crystals/littelmann_path.py b/src/sage/combinat/crystals/littelmann_path.py index fd32c317943..47a421c2b54 100644 --- a/src/sage/combinat/crystals/littelmann_path.py +++ b/src/sage/combinat/crystals/littelmann_path.py @@ -702,7 +702,7 @@ def __classcall_private__(cls, weight): raise ValueError("The weight should be in the non-extended weight lattice!") La = weight.parent().basis() weight = weight - weight.level() * La[0] / La[0].level() - return super().__classcall__(cls, weight, starting_weight_parent = weight.parent()) + return super(CrystalOfLSPaths, cls).__classcall__(cls, weight, starting_weight_parent = weight.parent()) @cached_method def maximal_vector(self): @@ -1206,7 +1206,7 @@ def __classcall_private__(cls, cartan_type): True """ cartan_type = CartanType(cartan_type) - return super().__classcall__(cls, cartan_type) + return super(InfinityCrystalOfLSPaths, cls).__classcall__(cls, cartan_type) def __init__(self, cartan_type): """ @@ -1320,7 +1320,8 @@ def e(self, i, power=1, length_only=False): sage: len(B.subcrystal(max_depth=7)) 116 """ - ret = super().e(i, power=power, length_only=length_only) + ret = super().e(i, power=power, + length_only=length_only) if ret is None: return None if length_only: @@ -1374,7 +1375,7 @@ def f(self, i, power=1, length_only=False): 2*Lambda[0] + 2*Lambda[1] + 2*Lambda[2]) """ dual_path = self.dualize() - dual_path = super().e(i, power, length_only=length_only) + dual_path = super(InfinityCrystalOfLSPaths.Element, dual_path).e(i, power, length_only=length_only) if length_only: return dual_path if dual_path is None: From bcd1e5b1246425eeceff40259d00b3a74b9e7ad9 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Sun, 29 May 2022 19:05:43 +0000 Subject: [PATCH 507/529] Improve display of short summary --- .github/workflows/build.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5e4ace07d46..837e40d4fb7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -50,6 +50,9 @@ jobs: ../sage -python -m pip install coverage pytest-xdist ../sage -python -m coverage run -m pytest -c tox.ini --doctest-modules || true working-directory: ./src + env: + # Increase the length of the lines in the "short summary" + COLUMNS: 120 - name: Test run: | From 609a56c9258e1e80d0b790496432ceb62c5e9131 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Mon, 30 May 2022 09:29:16 +0900 Subject: [PATCH 508/529] Replace sage.combinat with sage.combinat.all --- src/doc/en/reference/combinat/index.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/doc/en/reference/combinat/index.rst b/src/doc/en/reference/combinat/index.rst index 4470e97836d..1e2a6da8665 100644 --- a/src/doc/en/reference/combinat/index.rst +++ b/src/doc/en/reference/combinat/index.rst @@ -1,7 +1,10 @@ +.. _sage.combinat: + Combinatorics ============= -.. automodule:: sage.combinat +.. automodule:: sage.combinat.all + :noindex: Comprehensive Module List ------------------------- From 1b039276b5b3c0783d6035d9f90c264d13dfb398 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 30 May 2022 15:39:26 -0700 Subject: [PATCH 509/529] build/pkgs/ncurses: Update to 6.3 --- build/pkgs/ncurses/checksums.ini | 7 ++++--- build/pkgs/ncurses/package-version.txt | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/build/pkgs/ncurses/checksums.ini b/build/pkgs/ncurses/checksums.ini index 27620e7d25a..f67d0e23402 100644 --- a/build/pkgs/ncurses/checksums.ini +++ b/build/pkgs/ncurses/checksums.ini @@ -1,4 +1,5 @@ tarball=ncurses-VERSION.tar.gz -sha1=acd606135a5124905da770803c05f1f20dd3b21c -md5=ee13d052e1ead260d7c28071f46eefb1 -cksum=1470804880 +sha1=38fb1462d13b04bb900adf07918725c4b7ed0682 +md5=a2736befde5fee7d2b7eb45eb281cdbe +cksum=981463359 +upstream_url=https://ftp.gnu.org/pub/gnu/ncurses/ncurses-VERSION.tar.gz diff --git a/build/pkgs/ncurses/package-version.txt b/build/pkgs/ncurses/package-version.txt index d5bfaf7a67f..0faee7d968e 100644 --- a/build/pkgs/ncurses/package-version.txt +++ b/build/pkgs/ncurses/package-version.txt @@ -1 +1 @@ -6.0.p0 +6.3 From 38f188aaa5b91ea6b117c14a1490b3ca02ef1480 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 30 May 2022 15:42:56 -0700 Subject: [PATCH 510/529] build/pkgs/readline: Update to 8.1.2 --- build/pkgs/readline/checksums.ini | 6 +++--- build/pkgs/readline/package-version.txt | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/build/pkgs/readline/checksums.ini b/build/pkgs/readline/checksums.ini index 5e4e180686f..05d4f89539f 100644 --- a/build/pkgs/readline/checksums.ini +++ b/build/pkgs/readline/checksums.ini @@ -1,5 +1,5 @@ tarball=readline-VERSION.tar.gz -sha1=d58041c2143595dc001d2777ae9a200be30198b0 -md5=7e6c1f16aee3244a69aba6e438295ca3 -cksum=3826776229 +sha1=8a05ad0d0ad67e18c383f1b2cf6a23bcbd46f87a +md5=12819fa739a78a6172400f399ab34f81 +cksum=829245750 upstream_url=https://ftp.gnu.org/gnu/readline/readline-VERSION.tar.gz diff --git a/build/pkgs/readline/package-version.txt b/build/pkgs/readline/package-version.txt index 657c5dea53b..6b409d977b8 100644 --- a/build/pkgs/readline/package-version.txt +++ b/build/pkgs/readline/package-version.txt @@ -1,2 +1 @@ -8.0 - +8.1.2 From 2ca97e9233210fe8945a07a24307ce672fcaf60d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 30 May 2022 15:43:45 -0700 Subject: [PATCH 511/529] build/pkgs/ncurses/patches/work_around_changed_output_of_GNU_cpp_5.x.patch: Remove --- ...around_changed_output_of_GNU_cpp_5.x.patch | 24 ------------------- 1 file changed, 24 deletions(-) delete mode 100644 build/pkgs/ncurses/patches/work_around_changed_output_of_GNU_cpp_5.x.patch diff --git a/build/pkgs/ncurses/patches/work_around_changed_output_of_GNU_cpp_5.x.patch b/build/pkgs/ncurses/patches/work_around_changed_output_of_GNU_cpp_5.x.patch deleted file mode 100644 index 751ff5c3290..00000000000 --- a/build/pkgs/ncurses/patches/work_around_changed_output_of_GNU_cpp_5.x.patch +++ /dev/null @@ -1,24 +0,0 @@ -Building ncurses with GCC 5 (or more precisely, with its 'cpp') fails with a -syntax error, caused by earlier preprocessing. - -(I'm not entirely sure whether it's a GCC bug or rather caused by a new -feature which breaks further processing with 'awk' and 'sed'; I *think* -at least the 'awk' inline script "AW2" simply isn't prepared for the changed -output of 'cpp' w.r.t. line directives [1]. Anyway, the patch fixes the issue.) - -[1] https://gcc.gnu.org/gcc-5/porting_to.html - - ---- ncurses-5.9.20131221/ncurses/base/MKlib_gen.sh 2011-06-04 21:14:08.000000000 +0200 -+++ ncurses-5.9.20131221/ncurses/base/MKlib_gen.sh 2015-04-26 00:47:06.911680782 +0200 -@@ -62,7 +62,9 @@ - if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi - if test "${LC_COLLATE+set}" = set; then LC_COLLATE=C; export LC_COLLATE; fi - --preprocessor="$1 -DNCURSES_INTERNALS -I../include" -+# Work around "unexpected" output of GCC 5.x's cpp w.r.t. #line directives -+# by simply suppressing them: -+preprocessor="$1 -P -DNCURSES_INTERNALS -I../include" - AWK="$2" - USE="$3" - From 7cf3cf3d93cee3ae4df3b09ad0fcd051f9b3d06c Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Tue, 31 May 2022 13:26:56 +0800 Subject: [PATCH 512/529] fix computation of finite-field coercion (Conway into non-Conway) --- src/sage/rings/finite_rings/finite_field_base.pyx | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/finite_rings/finite_field_base.pyx b/src/sage/rings/finite_rings/finite_field_base.pyx index 582f59971f6..731bffa1e16 100644 --- a/src/sage/rings/finite_rings/finite_field_base.pyx +++ b/src/sage/rings/finite_rings/finite_field_base.pyx @@ -1497,9 +1497,18 @@ cdef class FiniteField(Field): sage: F.extension(int(3), 'a') Finite Field in a of size 2^3 - sage: F = GF(2 ** 4, 'a') + sage: F = GF(2^4, 'a') sage: F.extension(int(3), 'aa') Finite Field in aa of size 2^12 + + Randomized test for :trac:`33937`:: + + sage: p = random_prime(100) + sage: a,b = (randrange(1,10) for _ in 'ab') + sage: K. = GF(p^a) + sage: L. = K.extension(b) + sage: L(u).minpoly() == u.minpoly() + True """ from .finite_field_constructor import GF from sage.rings.polynomial.polynomial_element import is_Polynomial @@ -1525,7 +1534,7 @@ cdef class FiniteField(Field): elif hasattr(E, '_prefix') and hasattr(self, '_prefix'): pass # coercion map is automatically found else: - if self.is_conway(): # and E is Conway + if self.is_conway() and E.is_conway(): alpha = E.gen()**((E.order()-1)//(self.order()-1)) else: alpha = self.modulus().any_root(E) From 3b6be5f8156d79861f25081d3aca33ea88be21f2 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Tue, 31 May 2022 17:11:48 +0800 Subject: [PATCH 513/529] use tuple syntax for finite-field constructor --- src/sage/rings/finite_rings/finite_field_base.pyx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/sage/rings/finite_rings/finite_field_base.pyx b/src/sage/rings/finite_rings/finite_field_base.pyx index 731bffa1e16..1384ec51d4c 100644 --- a/src/sage/rings/finite_rings/finite_field_base.pyx +++ b/src/sage/rings/finite_rings/finite_field_base.pyx @@ -1497,7 +1497,7 @@ cdef class FiniteField(Field): sage: F.extension(int(3), 'a') Finite Field in a of size 2^3 - sage: F = GF(2^4, 'a') + sage: F = GF((2,4), 'a') sage: F.extension(int(3), 'aa') Finite Field in aa of size 2^12 @@ -1505,7 +1505,7 @@ cdef class FiniteField(Field): sage: p = random_prime(100) sage: a,b = (randrange(1,10) for _ in 'ab') - sage: K. = GF(p^a) + sage: K. = GF((p,a)) sage: L. = K.extension(b) sage: L(u).minpoly() == u.minpoly() True @@ -1519,16 +1519,16 @@ cdef class FiniteField(Field): latex_name = latex_names if self.degree() == 1: if isinstance(modulus, (int, Integer)): - E = GF(self.characteristic()**modulus, name=name, **kwds) + E = GF((self.characteristic(), modulus), name=name, **kwds) elif isinstance(modulus, (list, tuple)): - E = GF(self.characteristic()**(len(modulus) - 1), name=name, modulus=modulus, **kwds) + E = GF((self.characteristic(), len(modulus) - 1), name=name, modulus=modulus, **kwds) elif is_Polynomial(modulus): if modulus.change_ring(self).is_irreducible(): - E = GF(self.characteristic()**(modulus.degree()), name=name, modulus=modulus, **kwds) + E = GF((self.characteristic(), modulus.degree()), name=name, modulus=modulus, **kwds) else: E = Field.extension(self, modulus, name=name, embedding=embedding, **kwds) elif isinstance(modulus, (int, Integer)): - E = GF(self.order()**modulus, name=name, **kwds) + E = GF((self.characteristic(), self.degree() * modulus), name=name, **kwds) if E is self: pass # coercion map (identity map) is automatically found elif hasattr(E, '_prefix') and hasattr(self, '_prefix'): From 2332517aa80712b6d4bdb86e48c6ab1137ea156b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 1 Jun 2022 21:38:56 +0200 Subject: [PATCH 514/529] fix details in oeis --- src/sage/databases/oeis.py | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/src/sage/databases/oeis.py b/src/sage/databases/oeis.py index be0138b6b76..45b73054eac 100644 --- a/src/sage/databases/oeis.py +++ b/src/sage/databases/oeis.py @@ -8,7 +8,6 @@ - identify a sequence from its first terms. - obtain more terms, formulae, references, etc. for a given sequence. - AUTHORS: - Thierry Monteil (2012-02-10 -- 2013-06-21): initial version. @@ -105,7 +104,6 @@ 10: A326943: Number of T_0 sets of subsets of {1..n} that cover all n vertices and are closed under intersection. ... - What does the Taylor expansion of the `e^{e^x-1}` function have to do with primes ? @@ -127,12 +125,11 @@ 'E.g.f.: exp(exp(x) - 1).' sage: [i for i in b.comments() if 'prime' in i][-1] # optional -- internet - 'Number n is prime if mod(a(n)-2,n) = 0...' + 'Number n is prime if ...' sage: [n for n in range(2, 20) if (b(n)-2) % n == 0] # optional -- internet [2, 3, 5, 7, 11, 13, 17, 19] - .. SEEALSO:: - If you plan to do a lot of automatic searches for subsequences, you @@ -161,6 +158,8 @@ from urllib.request import urlopen from urllib.parse import urlencode from ssl import create_default_context as default_context +from collections import defaultdict +import re from sage.structure.sage_object import SageObject from sage.structure.unique_representation import UniqueRepresentation @@ -174,8 +173,6 @@ from sage.misc.html import HtmlFragment from sage.repl.preparse import preparse -from collections import defaultdict -import re oeis_url = 'https://oeis.org/' @@ -205,7 +202,7 @@ def _fetch(url): f.close() return bytes_to_str(result) except IOError as msg: - raise IOError("%s\nError fetching %s." % (msg, url)) + raise IOError("%s\nerror fetching %s" % (msg, url)) def _urls(html_string): @@ -229,7 +226,6 @@ def _urls(html_string): sage: html = 'http://example.com is not a link, but sagemath is' sage: _urls(html) ['http://sagemath.org/'] - """ urls = [] from html.parser import HTMLParser @@ -611,7 +607,7 @@ def _imaginary_entry(self, ident='A999999', keywords=''): '%o ' + ident + ' def ' + ident + '(n):\n' '%o ' + ident + ' assert(isinstance(n, (int, Integer))), "n must be an integer."\n' '%o ' + ident + ' if n < 38:\n' - '%o ' + ident + ' raise ValueError("The value %s is not accepted." %str(n))\n' + '%o ' + ident + ' raise ValueError("the value %s is not accepted" % str(n))\n' '%o ' + ident + ' elif n == 42:\n' '%o ' + ident + ' return 2\n' '%o ' + ident + ' else:\n' @@ -1365,14 +1361,14 @@ def __call__(self, k): sage: s(2) Traceback (most recent call last): ... - ValueError: Sequence A999999 is not defined (or known) for index 2 + ValueError: sequence A999999 is not defined (or known) for index 2 """ offset = self.offsets()[0] if 'cons' in self.keywords(): offset = - offset n = k - offset if not 0 <= n < len(self.first_terms()): - raise ValueError("Sequence %s is not defined (or known) for index %s" % (self.id(), k)) + raise ValueError("sequence %s is not defined (or known) for index %s" % (self.id(), k)) return self.first_terms()[n] def __getitem__(self, i): @@ -1454,7 +1450,7 @@ def __iter__(self): sage: next(i) # optional -- internet Traceback (most recent call last): ... - LookupError: Future values not provided by OEIS. + LookupError: future values not provided by OEIS :: @@ -1465,7 +1461,7 @@ def __iter__(self): ....: print(i) Traceback (most recent call last): ... - LookupError: Future values not provided by OEIS. + LookupError: future values not provided by OEIS TESTS:: @@ -1474,7 +1470,7 @@ def __iter__(self): ....: pass Traceback (most recent call last): ... - LookupError: Future values not provided by OEIS. + LookupError: future values not provided by OEIS sage: for i in s: ....: if i == 2: @@ -1488,7 +1484,7 @@ def __iter__(self): for x in self.first_terms(): yield x if not self.is_full() is True: - raise LookupError("Future values not provided by OEIS.") + raise LookupError("future values not provided by OEIS") def references(self): r""" @@ -1892,7 +1888,7 @@ def programs(self, language='all', preparsing=True, keep_comments=False): 0: def A999999(n): 1: assert(isinstance(n, (int, Integer))), "n must be an integer." 2: if n < 38: - 3: raise ValueError("The value %s is not accepted." %str(n)) + 3: raise ValueError("the value %s is not accepted" % str(n)) 4: elif n == 42: 5: return 2 6: else: From c4e817835d1744af17b4348d15ed9dff1456784a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Labb=C3=A9?= Date: Wed, 1 Jun 2022 22:00:00 +0200 Subject: [PATCH 515/529] 33944: using shutil.move instead of os.rename --- src/sage/misc/latex_standalone.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/sage/misc/latex_standalone.py b/src/sage/misc/latex_standalone.py index d4fcca9e5d0..8f698ffc2e6 100644 --- a/src/sage/misc/latex_standalone.py +++ b/src/sage/misc/latex_standalone.py @@ -728,7 +728,8 @@ def pdf(self, filename=None, view=True, program=None): # move the pdf into the good location if filename: filename = os.path.abspath(filename) - os.rename(temp_filename_pdf, filename) + import shutil + shutil.move(temp_filename_pdf, filename) return filename # open the tmp pdf @@ -816,7 +817,8 @@ def png(self, filename=None, density=150, view=True): # move the png into the good location if filename: filename = os.path.abspath(filename) - os.rename(temp_filename_png, filename) + import shutil + shutil.move(temp_filename_png, filename) return filename # open the tmp png @@ -915,7 +917,8 @@ def svg(self, filename=None, view=True, program='pdftocairo'): # move the svg into the good location if filename: filename = os.path.abspath(filename) - os.rename(temp_filename_svg, filename) + import shutil + shutil.move(temp_filename_svg, filename) return filename # open the tmp svg From aabb55adb3d7d1ddaae149245ec9c7b56b52805b Mon Sep 17 00:00:00 2001 From: "Trevor K. Karn" Date: Wed, 1 Jun 2022 13:09:04 -0700 Subject: [PATCH 516/529] Fix additional reviewer suggestions --- src/sage/matroids/matroid.pyx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/sage/matroids/matroid.pyx b/src/sage/matroids/matroid.pyx index fcd626b7378..94a69a013e0 100644 --- a/src/sage/matroids/matroid.pyx +++ b/src/sage/matroids/matroid.pyx @@ -3108,7 +3108,7 @@ cdef class Matroid(SageObject): def matroid_polytope(self): r""" - src/sage/matroids/matroid.pyx Return the matroid polytope of ``self``. + Return the matroid polytope of ``self``. This is defined as the convex hull of the vertices @@ -8064,7 +8064,10 @@ cdef class Matroid(SageObject): Matroid of rank 6 on 16 elements as matroid sum of Binary matroid of rank 3 on 7 elements, type (3, 0) Matroid of rank 3 on 9 elements with circuit-closures - {2: {{'a', 'b', 'c'}, {'a', 'e', 'i'}, {'a', 'f', 'h'}, {'b', 'd', 'i'}, {'b', 'f', 'g'}, {'c', 'd', 'h'}, {'c', 'e', 'g'}, {'d', 'e', 'f'}, {'g', 'h', 'i'}}, 3: {{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'}}} + {2: {{'a', 'b', 'c'}, {'a', 'e', 'i'}, {'a', 'f', 'h'}, + {'b', 'd', 'i'}, {'b', 'f', 'g'}, {'c', 'd', 'h'}, + {'c', 'e', 'g'}, {'d', 'e', 'f'}, {'g', 'h', 'i'}}, + 3: {{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'}}} sage: len(N.independent_sets()) 6897 sage: len(N.bases()) From 48c3e10e38aabee3c499f92f10518c8d0872713b Mon Sep 17 00:00:00 2001 From: Xavier Caruso Date: Thu, 2 Jun 2022 12:05:37 +0200 Subject: [PATCH 517/529] fix geometric Frobenius --- src/sage/libs/linkages/padics/unram_shared.pxi | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/sage/libs/linkages/padics/unram_shared.pxi b/src/sage/libs/linkages/padics/unram_shared.pxi index bcd76ad3123..10a2f5adde8 100644 --- a/src/sage/libs/linkages/padics/unram_shared.pxi +++ b/src/sage/libs/linkages/padics/unram_shared.pxi @@ -28,6 +28,10 @@ def frobenius_unram(self, arithmetic=True): sage: a a + O(5^3) + sage: R. = Zq(5^4,3) + sage: a.frobenius(arithmetic=False) + (3*a^3 + 3*a^2 + a) + (a^3 + 4*a^2 + a + 4)*5 + (3*a^2 + 2*a + 3)*5^2 + O(5^3) + sage: K. = Qq(7^3,4) sage: b = (a+1)/7 sage: c = b.frobenius(); c @@ -42,13 +46,22 @@ def frobenius_unram(self, arithmetic=True): Traceback (most recent call last): ... NotImplementedError: Frobenius automorphism only implemented for unramified extensions + + TESTS:: + + We check that :trac:`23575` is resolved: + + sage: x = R.random_element() + sage: x.frobenius(arithmetic=false).frobenius() == x + True + """ if self == 0: return self R = self.parent() p = R.prime() a = R.gen() - frob_a = R._frob_gen() + frob_a = R._frob_gen(arithmetic) ppow = self.valuation() unit = self.unit_part() coefs = unit.expansion() From 10bf02a1cbd35ca583a68923980f6c94a9136ab2 Mon Sep 17 00:00:00 2001 From: Xavier Caruso Date: Thu, 2 Jun 2022 14:00:34 +0200 Subject: [PATCH 518/529] add doctest --- src/sage/rings/padics/padic_ZZ_pX_element.pyx | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/sage/rings/padics/padic_ZZ_pX_element.pyx b/src/sage/rings/padics/padic_ZZ_pX_element.pyx index eed82ac8031..1a523e8a98d 100644 --- a/src/sage/rings/padics/padic_ZZ_pX_element.pyx +++ b/src/sage/rings/padics/padic_ZZ_pX_element.pyx @@ -483,6 +483,17 @@ cdef class pAdicZZpXElement(pAdicExtElement): 4*5 + 5^2 + 5^3 + 2*5^4 sage: (a+b).trace() 4*5 + 5^2 + 5^3 + 2*5^4 + + TESTS:: + + We check that :trac:`32072` is resolved:: + + sage: F = Qp(2) + sage: S. = F[] + sage: L. = F.ext(x^2 - 2) + sage: L(0, 20).trace() + O(2^10) + """ if base is not None: if base is self.parent(): @@ -492,7 +503,7 @@ cdef class pAdicZZpXElement(pAdicExtElement): if self._is_exact_zero(): return self.parent().ground_ring()(0) elif self._is_inexact_zero(): - return self.ground_ring(0, (self.valuation() - 1) // self.parent().e() + 1) + return self.parent().ground_ring()(0, (self.valuation() - 1) // self.parent().e() + 1) if self.valuation() >= 0: return self.parent().ground_ring()(self.matrix_mod_pn().trace()) else: From 088bdcd9456df899235b6738b91e99750c2a1459 Mon Sep 17 00:00:00 2001 From: Xavier Caruso Date: Thu, 2 Jun 2022 22:06:07 +0200 Subject: [PATCH 519/529] remove colon --- src/sage/rings/padics/padic_ZZ_pX_element.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/padics/padic_ZZ_pX_element.pyx b/src/sage/rings/padics/padic_ZZ_pX_element.pyx index 1a523e8a98d..a450f28de65 100644 --- a/src/sage/rings/padics/padic_ZZ_pX_element.pyx +++ b/src/sage/rings/padics/padic_ZZ_pX_element.pyx @@ -484,7 +484,7 @@ cdef class pAdicZZpXElement(pAdicExtElement): sage: (a+b).trace() 4*5 + 5^2 + 5^3 + 2*5^4 - TESTS:: + TESTS: We check that :trac:`32072` is resolved:: From 8238b49ecd1afd79a63ee8f5adf80ab6d9f16e9c Mon Sep 17 00:00:00 2001 From: Xavier Caruso Date: Thu, 2 Jun 2022 22:30:32 +0200 Subject: [PATCH 520/529] add normalize --- src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx b/src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx index eca79a2d8aa..c4ecd6e8c19 100644 --- a/src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx +++ b/src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx @@ -2781,6 +2781,7 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): sage: list(A(0,4).expansion()) [] """ + self._normalize() if lift_mode == 'teichmuller': zero = self.parent()(0) elif self.prime_pow.e == 1: From daf528e683fa739c38abc64d8d5b3af1b4d2dbb7 Mon Sep 17 00:00:00 2001 From: Xavier Caruso Date: Thu, 2 Jun 2022 22:33:30 +0200 Subject: [PATCH 521/529] add doctest --- src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx b/src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx index c4ecd6e8c19..6a47bf86a1d 100644 --- a/src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx +++ b/src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx @@ -2780,6 +2780,17 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): [] sage: list(A(0,4).expansion()) [] + + TESTS: + + We check that :trac:`24949` is fixed:: + + sage: R. = Zp(2).extension(x^10 + 2) + sage: x = a^4 + a^5 + sage: y = a^2 + a^3 + sage: z = x - y^2 + sage: z.expansion(4) + 0 """ self._normalize() if lift_mode == 'teichmuller': From 257b7b5b92d6a289102ee68a6073953268d0cbd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 3 Jun 2022 08:51:19 +0200 Subject: [PATCH 522/529] fix pycodestyle E306 in all pyx files --- src/sage/coding/ag_code_decoders.pyx | 1 + .../combinat/crystals/tensor_product_element.pyx | 1 + src/sage/combinat/matrices/dancing_links.pyx | 3 +++ src/sage/ext/fast_callable.pyx | 1 + .../polyhedron/combinatorial_polyhedron/base.pyx | 3 +++ src/sage/graphs/graph_coloring.pyx | 5 +++++ src/sage/graphs/strongly_regular_db.pyx | 15 ++++++++++----- src/sage/misc/c3_controlled.pyx | 1 + src/sage/misc/session.pyx | 1 + src/sage/misc/stopgap.pyx | 4 +++- src/sage/numerical/backends/generic_backend.pyx | 3 +++ src/sage/rings/finite_rings/finite_field_base.pyx | 1 + src/sage/rings/morphism.pyx | 1 + .../polynomial/skew_polynomial_finite_field.pyx | 8 ++++---- src/sage/rings/ring_extension.pyx | 1 + src/sage/rings/ring_extension_element.pyx | 1 + src/sage/rings/tate_algebra_element.pyx | 1 + 17 files changed, 41 insertions(+), 10 deletions(-) diff --git a/src/sage/coding/ag_code_decoders.pyx b/src/sage/coding/ag_code_decoders.pyx index cdf8cdcfe37..2c0390c5f67 100644 --- a/src/sage/coding/ag_code_decoders.pyx +++ b/src/sage/coding/ag_code_decoders.pyx @@ -1519,6 +1519,7 @@ cdef class Decoder_K(object): if verbose: width = 7 * (K.degree() + 2) + # auxiliary function for verbose printing def vprint_g(g, s): if verbose > 1: diff --git a/src/sage/combinat/crystals/tensor_product_element.pyx b/src/sage/combinat/crystals/tensor_product_element.pyx index 98083ecc9e4..b7f60016ecc 100644 --- a/src/sage/combinat/crystals/tensor_product_element.pyx +++ b/src/sage/combinat/crystals/tensor_product_element.pyx @@ -1857,6 +1857,7 @@ cdef class InfinityQueerCrystalOfTableauxElement(TensorProductOfQueerSuperCrysta n = self._parent._cartan_type.n + 1 zero = self._parent.weight_lattice_realization().zero() La = self._parent.weight_lattice_realization().fundamental_weights() + def fwt(i): return zero if i == n else La[i] ret -= sum((self._row_lengths[i] - 1 - self._row_lengths[i+1])*(fwt(n-i)-fwt(n-i-1)) diff --git a/src/sage/combinat/matrices/dancing_links.pyx b/src/sage/combinat/matrices/dancing_links.pyx index 93859dce9b9..953b5c4e680 100644 --- a/src/sage/combinat/matrices/dancing_links.pyx +++ b/src/sage/combinat/matrices/dancing_links.pyx @@ -666,6 +666,7 @@ cdef class dancing_linksWrapper: "where ncols={}".format(column, self.ncols())) from sage.parallel.decorate import parallel + @parallel(ncpus=ncpus) def first_solution(i): dlx = self.restrict([i]) @@ -782,6 +783,7 @@ cdef class dancing_linksWrapper: "where ncols={}".format(column, self.ncols())) from sage.parallel.decorate import parallel + @parallel(ncpus=ncpus) def all_solutions(i): dlx = self.restrict([i]) @@ -881,6 +883,7 @@ cdef class dancing_linksWrapper: "where ncols={}".format(column, self.ncols())) from sage.parallel.decorate import parallel + @parallel(ncpus=ncpus) def nb_sol(i): dlx = self.restrict([i]) diff --git a/src/sage/ext/fast_callable.pyx b/src/sage/ext/fast_callable.pyx index 888275e7a78..8582818697e 100644 --- a/src/sage/ext/fast_callable.pyx +++ b/src/sage/ext/fast_callable.pyx @@ -443,6 +443,7 @@ def fast_callable(x, domain=None, vars=None, vars = ['EXTRA_VAR0'] else: raise ValueError("list of variables must be specified for symbolic expressions") + def to_var(var): if isinstance(var, Expression_abc) and var.is_symbol(): return var diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx index 02ebcf1c79d..9811970ed29 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx @@ -1247,6 +1247,7 @@ cdef class CombinatorialPolyhedron(SageObject): # Getting the indices of the `i`-th edge. def vertex_one(size_t i): return f(self._get_edge(self._edges, i, 0)) + def vertex_two(size_t i): return f(self._get_edge(self._edges, i, 1)) @@ -1472,6 +1473,7 @@ cdef class CombinatorialPolyhedron(SageObject): # Getting the indices of the `i`-th ridge. def facet_one(size_t i): return f(self._get_edge(self._ridges, i, 0)) + def facet_two(size_t i): return f(self._get_edge(self._ridges, i, 1)) @@ -2916,6 +2918,7 @@ cdef class CombinatorialPolyhedron(SageObject): # Getting the indices of the `i`-th incidence. def face_one(size_t i): return smallInteger(self._get_edge(incidences, i, 0)) + def face_two(size_t i): return smallInteger(self._get_edge(incidences, i, 1)) diff --git a/src/sage/graphs/graph_coloring.pyx b/src/sage/graphs/graph_coloring.pyx index 8d6416be3bd..1fba8c13e2c 100644 --- a/src/sage/graphs/graph_coloring.pyx +++ b/src/sage/graphs/graph_coloring.pyx @@ -1501,6 +1501,7 @@ def round_robin(n): """ if n <= 1: raise ValueError("there must be at least two vertices in the graph") + def my_mod(x, y): return x - y * (x // y) if not n % 2: @@ -1701,12 +1702,14 @@ def linear_arboricity(g, plus_one=None, hex_colors=False, value_only=False, if hex_colors: answer = [[] for i in range(k)] + def add(uv, i): return answer[i].append(uv) else: gg = copy(g) gg.delete_edges(g.edge_iterator()) answer = [copy(gg) for i in range(k)] + def add(uv, i): return answer[i].add_edge(uv) @@ -1952,12 +1955,14 @@ def acyclic_edge_coloring(g, hex_colors=False, value_only=False, k=0, if hex_colors: answer = [[] for i in range(k)] + def add(uv, i): return answer[i].append(uv) else: gg = copy(g) gg.delete_edges(g.edge_iterator()) answer = [copy(gg) for i in range(k)] + def add(uv, i): return answer[i].add_edge(uv) diff --git a/src/sage/graphs/strongly_regular_db.pyx b/src/sage/graphs/strongly_regular_db.pyx index d98a5f553c4..16b2506e545 100644 --- a/src/sage/graphs/strongly_regular_db.pyx +++ b/src/sage/graphs/strongly_regular_db.pyx @@ -956,9 +956,11 @@ def is_complete_multipartite(int v,int k,int l,int mu): r = v//(v-k) # number of parts (of size v-k each) if l==(v-k)*(r-2) and k==mu and v == r*(v-k): from sage.graphs.generators.basic import CompleteMultipartiteGraph + def CompleteMultipartiteSRG(nparts, partsize): - return CompleteMultipartiteGraph([partsize]*nparts) - return (CompleteMultipartiteSRG, r, v-k) + return CompleteMultipartiteGraph([partsize] * nparts) + return (CompleteMultipartiteSRG, r, v - k) + @cached_function def is_polhill(int v,int k,int l,int mu): @@ -1484,6 +1486,7 @@ def is_twograph_descendant_of_srg(int v, int k0, int l, int mu): strongly_regular_graph(v+1, k, l - 2*mu + k , k - mu, existence=True) is True: try: g = strongly_regular_graph_lazy(v+1, k, l - 2*mu + k) # Sage might not know how to build g + def la(*gr): from sage.combinat.designs.twographs import twograph_descendant gg = g[0](*gr) @@ -2075,10 +2078,12 @@ def SRG_210_99_48_45(): """ from sage.libs.gap.libgap import libgap from sage.combinat.permutation import Permutation - def ekg(g0): # return arcs of the Cayley digraph of on {g,g^4} + + def ekg(g0): + # return arcs of the Cayley digraph of on {g,g^4} g = Permutation(g0) - return libgap.Set([(x, g(x)) for x in range(1,8)] + - [(x, g(g(g(g(x))))) for x in range(1,8)]) + return libgap.Set([(x, g(x)) for x in range(1, 8)] + + [(x, g(g(g(g(x))))) for x in range(1, 8)]) kd = list(map(ekg, [(7, 1, 2, 3, 4, 5), (7, 1, 3, 4, 5, 6), diff --git a/src/sage/misc/c3_controlled.pyx b/src/sage/misc/c3_controlled.pyx index 1b16dd62b8e..955a8663457 100644 --- a/src/sage/misc/c3_controlled.pyx +++ b/src/sage/misc/c3_controlled.pyx @@ -1071,6 +1071,7 @@ class HierarchyElement(object, metaclass=ClasscallMetaclass): succ = succ.neighbors_out if key is None: key = identity + @cached_function def f(x): return typecall(cls, x, [f(y) for y in succ(x)], key, f) diff --git a/src/sage/misc/session.pyx b/src/sage/misc/session.pyx index c842369c4b3..63b7fd735a3 100644 --- a/src/sage/misc/session.pyx +++ b/src/sage/misc/session.pyx @@ -218,6 +218,7 @@ def show_identifiers(hidden=False): # 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) diff --git a/src/sage/misc/stopgap.pyx b/src/sage/misc/stopgap.pyx index 555d80915b6..9ed9c4ec4dc 100644 --- a/src/sage/misc/stopgap.pyx +++ b/src/sage/misc/stopgap.pyx @@ -77,8 +77,10 @@ def stopgap(message, int ticket_no): return # We reset show_warning so that the message is not printed twice. old_format = warnings.formatwarning + def my_format(message, category, filename, lineno, line=None): - return "%s:%s:\n%s\n%s\n%s\n" % (filename, lineno, "*"*80, message, "*"*80) + return "%s:%s:\n%s\n%s\n%s\n" % (filename, lineno, + "*" * 80, message, "*" * 80) warnings.formatwarning = my_format message = message + "\nThis issue is being tracked at https://trac.sagemath.org/sage_trac/ticket/%s." % ticket_no warnings.warn(StopgapWarning(message), stacklevel=2) diff --git a/src/sage/numerical/backends/generic_backend.pyx b/src/sage/numerical/backends/generic_backend.pyx index 94d0e0e9d9d..083492018fe 100644 --- a/src/sage/numerical/backends/generic_backend.pyx +++ b/src/sage/numerical/backends/generic_backend.pyx @@ -1241,11 +1241,13 @@ cdef class GenericBackend: """ tester.assertEqual(type(self), type(cp), "Classes do not match") + def assert_equal_problem_data(method): tester.assertEqual(getattr(self, method)(), getattr(cp, method)(), "{} does not match".format(method)) for method in ("ncols", "nrows", "objective_constant_term", "problem_name", "is_maximization"): assert_equal_problem_data(method) + def assert_equal_col_data(method): for i in range(self.ncols()): tester.assertEqual(getattr(self, method)(i), getattr(cp, method)(i), @@ -1256,6 +1258,7 @@ cdef class GenericBackend: # TODO: Add a test elsewhere to ensure that variable_lower_bound, variable_upper_bound # are consistent with col_bounds. assert_equal_col_data(method) + def assert_equal_row_data(method): for i in range(self.nrows()): tester.assertEqual(getattr(self, method)(i), getattr(cp, method)(i), diff --git a/src/sage/rings/finite_rings/finite_field_base.pyx b/src/sage/rings/finite_rings/finite_field_base.pyx index 582f59971f6..edbeceaf0ab 100644 --- a/src/sage/rings/finite_rings/finite_field_base.pyx +++ b/src/sage/rings/finite_rings/finite_field_base.pyx @@ -1577,6 +1577,7 @@ cdef class FiniteField(Field): d = self.degree() D = list(reversed(d.divisors()[:-1])) P = d.support() + def make_family(gen, poly): if poly.degree() != d: return False, {} diff --git a/src/sage/rings/morphism.pyx b/src/sage/rings/morphism.pyx index 2cdd0ce4476..96a55bffd69 100644 --- a/src/sage/rings/morphism.pyx +++ b/src/sage/rings/morphism.pyx @@ -3132,6 +3132,7 @@ def _tensor_product_ring(B, A): else: names = (['y%d' % d for d in range(B.ngens())] + ['x%d' % d for d in range(A.ngens())]) + def term_order(A): # univariate rings do not have a term order if (is_PolynomialRing(A) or is_PolynomialQuotientRing(A) diff --git a/src/sage/rings/polynomial/skew_polynomial_finite_field.pyx b/src/sage/rings/polynomial/skew_polynomial_finite_field.pyx index bb7fd4275cd..220c9b87c1d 100644 --- a/src/sage/rings/polynomial/skew_polynomial_finite_field.pyx +++ b/src/sage/rings/polynomial/skew_polynomial_finite_field.pyx @@ -1091,17 +1091,17 @@ cdef class SkewPolynomial_finite_field_dense(SkewPolynomial_finite_order_dense): """ if self.is_zero(): raise ValueError("factorization of 0 not defined") + def factorizations_rec(P): if P.is_irreducible(): - yield [ (P,1) ] + yield [(P, 1)] else: for div in P._irreducible_divisors(True): Q = P // div # Here, we should update Q._norm, Q._norm_factor for factors in factorizations_rec(Q): - factors.append((div,1)) + factors.append((div, 1)) yield factors unit = self.leading_coefficient() - for factors in factorizations_rec(~unit*self): + for factors in factorizations_rec(~unit * self): yield Factorization(factors, sort=False, unit=unit) - diff --git a/src/sage/rings/ring_extension.pyx b/src/sage/rings/ring_extension.pyx index 0edd33209d3..2b649359ad4 100644 --- a/src/sage/rings/ring_extension.pyx +++ b/src/sage/rings/ring_extension.pyx @@ -643,6 +643,7 @@ cdef class RingExtension_generic(CommutativeAlgebra): method = getattr(self._backend, name) if not callable(method): raise AttributeError(AttributeErrorMessage(self, name)) + def wrapper(*args, **kwargs): output = method(*to_backend(args), **to_backend(kwargs)) return from_backend(output, self) diff --git a/src/sage/rings/ring_extension_element.pyx b/src/sage/rings/ring_extension_element.pyx index 9970e2b5ca3..04d0f1033a9 100644 --- a/src/sage/rings/ring_extension_element.pyx +++ b/src/sage/rings/ring_extension_element.pyx @@ -122,6 +122,7 @@ cdef class RingExtensionElement(CommutativeAlgebraElement): method = getattr(self._backend, name) if not callable(method): raise AttributeError(AttributeErrorMessage(self, name)) + def wrapper(*args, **kwargs): output = method(*to_backend(args), **to_backend(kwargs)) return from_backend(output, self._parent) diff --git a/src/sage/rings/tate_algebra_element.pyx b/src/sage/rings/tate_algebra_element.pyx index 0e25c9dfe9d..3f09e3722d3 100644 --- a/src/sage/rings/tate_algebra_element.pyx +++ b/src/sage/rings/tate_algebra_element.pyx @@ -2416,6 +2416,7 @@ cdef class TateAlgebraElement(CommutativeAlgebraElement): cdef TateAlgebraElement ans = self._new_c() # Hmm, shouldn't we add a keyword argument to lift_to_precision() # to specify that we don't want it to raise an error + def lift_without_error(elt): try: return elt.lift_to_precision(prec) From c5088e601fbb9b9f995ad713979e3ce4066c23cd Mon Sep 17 00:00:00 2001 From: Xavier Caruso Date: Fri, 3 Jun 2022 16:15:25 +0200 Subject: [PATCH 523/529] be more strict with conversion between padics --- src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx | 13 ++++++++----- src/sage/rings/padics/padic_template_element.pxi | 10 ++++++++++ 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx b/src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx index 6a47bf86a1d..463cc371031 100644 --- a/src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx +++ b/src/sage/rings/padics/padic_ZZ_pX_CR_element.pyx @@ -2785,12 +2785,15 @@ cdef class pAdicZZpXCRElement(pAdicZZpXElement): We check that :trac:`24949` is fixed:: - sage: R. = Zp(2).extension(x^10 + 2) - sage: x = a^4 + a^5 - sage: y = a^2 + a^3 - sage: z = x - y^2 - sage: z.expansion(4) + sage: R = Zp(2) + sage: S. = R[] + sage: A. = R.extension(x^10 + 2) + sage: u = a^4 + a^5 + sage: v = a^2 + a^3 + sage: w = u - v^2 + sage: w.expansion(4) 0 + """ self._normalize() if lift_mode == 'teichmuller': diff --git a/src/sage/rings/padics/padic_template_element.pxi b/src/sage/rings/padics/padic_template_element.pxi index b30d8cf0ae9..f2ab97737d0 100644 --- a/src/sage/rings/padics/padic_template_element.pxi +++ b/src/sage/rings/padics/padic_template_element.pxi @@ -73,6 +73,7 @@ cdef class pAdicTemplateElement(pAdicGenericElement): sage: Zp(17)(17^3, 8, 4) 17^3 + O(17^7) + """ def __init__(self, parent, x, absprec=infinity, relprec=infinity): """ @@ -107,6 +108,13 @@ cdef class pAdicTemplateElement(pAdicGenericElement): ... TypeError: p does not divide modulus 9 + :: + + sage: Zp(2)(Zp(5)(1)) + Traceback (most recent call last): + ... + TypeError: no conversion between padics when prime numbers differ + """ self.prime_pow = parent.prime_pow pAdicGenericElement.__init__(self, parent) @@ -122,6 +130,8 @@ cdef class pAdicTemplateElement(pAdicGenericElement): elif typ(pari_tmp) == t_FRAC: x = Rational(x) elif isinstance(x, pAdicGenericElement): + if self.prime_pow.prime != x.parent().prime(): + raise TypeError("no conversion between padics when prime numbers differ") if not ((x)._is_base_elt(self.prime_pow.prime) or x.parent() is self.parent()): if x.parent().modulus().change_ring(self.base_ring()) == self.parent().modulus(): x = x.polynomial().change_ring(self.base_ring()).list() From 0adf8cb96be21d41da5dc02eedb61178319f1a4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 5 Jun 2022 15:24:05 +0200 Subject: [PATCH 524/529] partial pep cleaning of sandpiles/sandpile --- src/sage/sandpiles/sandpile.py | 301 +++++++++++++++------------------ 1 file changed, 139 insertions(+), 162 deletions(-) diff --git a/src/sage/sandpiles/sandpile.py b/src/sage/sandpiles/sandpile.py index da3955bf6f2..314135bede1 100644 --- a/src/sage/sandpiles/sandpile.py +++ b/src/sage/sandpiles/sandpile.py @@ -341,7 +341,6 @@ from sage.arith.srange import xsrange from sage.modules.free_module_element import vector from sage.misc.lazy_import import lazy_import -lazy_import("sage.plot.colors", "rainbow") from sage.arith.functions import lcm from sage.arith.misc import falling_factorial from sage.rings.integer import Integer @@ -351,6 +350,7 @@ from sage.symbolic.constants import I, pi from sage.symbolic.ring import SR from sage.features.four_ti_2 import FourTi2Executable +lazy_import("sage.plot.colors", "rainbow") def _sandpile_help(cls, usage, verbose=True): @@ -496,11 +496,10 @@ def help(verbose=True): zero_config -- The all-zero configuration. zero_div -- The all-zero divisor. """ - _sandpile_help(Sandpile, dedent("""\ For detailed help with any method FOO listed below, enter "Sandpile.FOO?" or enter "S.FOO?" for any Sandpile S."""), - verbose=verbose) + verbose=verbose) def __init__(self, g, sink=None): r""" @@ -602,13 +601,13 @@ def __init__(self, g, sink=None): if p == -1: name = name + ' sandpile graph' else: - name = name[:p] + 'sandpile graph' + name[p+5:] + name = name[:p] + 'sandpile graph' + name[p + 5:] self._name = name else: self._name = 'sandpile graph' # preprocess a graph, if necessary if isinstance(g, dict) and isinstance(next(iter(g.values())), dict): - pass # this is the default format + pass # this is the default format elif isinstance(g, dict) and isinstance(next(iter(g.values())), list): processed_g = {i: dict(Counter(g[i])) for i in g} g = processed_g @@ -637,7 +636,7 @@ def __init__(self, g, sink=None): self._laplacian = self.laplacian_matrix(indegree=False) temp = list(range(self.num_verts())) del temp[self._sink_ind] - self._reduced_laplacian = self._laplacian[temp,temp] + self._reduced_laplacian = self._laplacian[temp, temp] def __copy__(self): """ @@ -722,8 +721,7 @@ def __getattr__(self, name): elif name == '_betti_complexes': self._set_betti_complexes() return deepcopy(self.__dict__[name]) - elif (name == '_postulation' or name == '_h_vector' - or name == '_hilbert_function'): + elif name in ['_postulation', '_h_vector', '_hilbert_function']: self._set_hilbert_function() return deepcopy(self.__dict__[name]) elif (name == '_ring' or name == '_unsaturated_ideal'): @@ -732,8 +730,7 @@ def __getattr__(self, name): elif name == '_ideal': self._set_ideal() return self.__dict__[name] - elif (name == '_resolution' or name == '_betti' or name == - '_singular_resolution'): + elif name in ['_resolution', '_betti', '_singular_resolution']: self._set_resolution() return self.__dict__[name] elif name == '_groebner': @@ -781,7 +778,7 @@ def _repr_(self): """ return self._name + ': ' + str(self.num_verts()) + ' vertices, sink = ' + str(self.sink()) - def show(self,**kwds): + def show(self, **kwds): r""" Draw the underlying graph. @@ -870,7 +867,6 @@ def laplacian(self): matrix - EXAMPLES:: sage: G = sandpiles.Diamond() @@ -895,7 +891,6 @@ def reduced_laplacian(self): matrix - EXAMPLES:: sage: S = sandpiles.Diamond() @@ -943,8 +938,8 @@ def _set_max_stable(self): sage: '_max_stable' in S.__dict__ True """ - m = {v:self.out_degree(v)-1 for v in self._nonsink_vertices} - self._max_stable = SandpileConfig(self,m) + m = {v: self.out_degree(v) - 1 for v in self._nonsink_vertices} + self._max_stable = SandpileConfig(self, m) def max_stable(self): r""" @@ -974,8 +969,8 @@ def _set_max_stable_div(self): sage: '_max_stable_div' in S.__dict__ True """ - m = {v:self.out_degree(v)-1 for v in self.vertices()} - self._max_stable_div = SandpileDivisor(self,m) + m = {v: self.out_degree(v) - 1 for v in self.vertices()} + self._max_stable_div = SandpileDivisor(self, m) def max_stable_div(self): r""" @@ -1006,7 +1001,7 @@ def _set_out_degrees(self): sage: '_out_degrees' in s.__dict__ True """ - self._out_degrees = {v:0 for v in self.vertices()} + self._out_degrees = {v: 0 for v in self.vertices()} for v in self.vertices(): for e in self.edges_incident(v): self._out_degrees[v] += e[2] @@ -1046,7 +1041,7 @@ def _set_in_degrees(self): sage: '_in_degrees' in s.__dict__ True """ - self._in_degrees = {v:0 for v in self.vertices()} + self._in_degrees = {v: 0 for v in self.vertices()} for e in self.edges(): self._in_degrees[e[1]] += e[2] @@ -1089,7 +1084,7 @@ def _set_burning_config(self): # TODO: Cythonize! d = self._reduced_laplacian.nrows() burn = sum(self._reduced_laplacian) - script=[1]*d # d 1s + script = [1] * d # d 1s done = False while not done: bad = -1 @@ -1101,16 +1096,16 @@ def _set_burning_config(self): done = True else: burn += self._reduced_laplacian[bad] - script[bad]+=1 + script[bad] += 1 b = iter(burn) s = iter(script) - bc = {} # burning config - bs = {} # burning script + bc = {} # burning config + bs = {} # burning script for v in self._nonsink_vertices: bc[v] = next(b) bs[v] = next(s) - self._burning_config = SandpileConfig(self,bc) - self._burning_script = SandpileConfig(self,bs) + self._burning_config = SandpileConfig(self, bc) + self._burning_script = SandpileConfig(self, bs) def burning_config(self): r""" @@ -1250,7 +1245,7 @@ def all_k_config(self, k): sage: s.all_k_config(7) {1: 7, 2: 7, 3: 7} """ - return SandpileConfig(self,[k]*(self.num_verts()-1)) + return SandpileConfig(self, [k] * (self.num_verts() - 1)) def zero_config(self): r""" @@ -1270,7 +1265,7 @@ def zero_config(self): # TODO: cythonize stabilization! # The following would presumably be moved to the SandpileConfig class - #def new_stabilize(self, config): + # def new_stabilize(self, config): # r""" # Stabilize \code{config}, returning \code{[out_config, firing_vector]}, # where \code{out_config} is the modified configuration. @@ -1293,7 +1288,7 @@ def _set_identity(self): True """ m = self._max_stable - self._identity = (m&m).dualize()&m + self._identity = (m & m).dualize() & m def identity(self, verbose=True): r""" @@ -1338,15 +1333,16 @@ def _set_recurrents(self): """ if self.name() == 'Complete sandpile graph': n = self.num_verts() - self._recurrents = [SandpileConfig(self,[n-1-i for i in p]) for p in ParkingFunctions(n-1)] + self._recurrents = [SandpileConfig(self, [n - 1 - i for i in p]) + for p in ParkingFunctions(n - 1)] elif self.name() == 'Cycle sandpile graph': n = self.num_verts() - one = [1]*(n-2) - self._recurrents = [SandpileConfig(self,[1]*(n-1))] + [SandpileConfig(self, one[:i]+[0]+one[i:]) for i in range(n-1)] + one = [1] * (n - 2) + self._recurrents = [SandpileConfig(self, [1]*(n-1))] + [SandpileConfig(self, one[:i]+[0]+one[i:]) for i in range(n - 1)] else: self._recurrents = [] active = [self._max_stable] - while active != []: + while active: c = active.pop() self._recurrents.append(c) for v in self._nonsink_vertices: @@ -1474,7 +1470,7 @@ def _set_group_gens(self): D, U, _ = self.reduced_laplacian().transpose().smith_form() F = U.inverse() self._group_gens = [SandpileConfig(self,[Integer(j) for j in F.column(i)]).equivalent_recurrent() - for i in range(F.nrows()) if D[i][i]!=1] + for i in range(F.nrows()) if D[i][i] != 1] def group_gens(self, verbose=True): r""" @@ -1562,7 +1558,7 @@ def _set_min_recurrents(self): """ if self.is_undirected(): m = min([r.deg() for r in self.recurrents()]) - rec = [r for r in self.recurrents() if r.deg()==m] + rec = [r for r in self.recurrents() if r.deg() == m] else: rec = list(self.recurrents()) for r in self.recurrents(): @@ -1669,7 +1665,6 @@ def tutte_polynomial(self): else: raise UserWarning("The underlying graph must be undirected.") - def _set_avalanche_polynomial(self): """ Compute the avalanche polynomial. See ``self.avalanche_polynomial`` for details. @@ -1736,7 +1731,6 @@ def avalanche_polynomial(self, multivariable=True): X = R.gens() return self._avalanche_polynomial.subs({X[i]:X[0] for i in range(1,self.num_verts()-1)}) - def nonspecial_divisors(self, verbose=True): r""" The nonspecial divisors. Only for undirected graphs. (See NOTE.) @@ -1863,11 +1857,11 @@ def _set_hilbert_function(self): """ v = [i.deg() for i in self._superstables] self._postulation = max(v) - self._h_vector = [v.count(i) for i in range(self._postulation+1)] + self._h_vector = [v.count(i) for i in range(self._postulation + 1)] self._hilbert_function = [1] for i in range(self._postulation): self._hilbert_function.append(self._hilbert_function[i] - +self._h_vector[i+1]) + + self._h_vector[i + 1]) def h_vector(self): r""" @@ -1879,7 +1873,6 @@ def h_vector(self): list of nonnegative integers - EXAMPLES:: sage: s = sandpiles.Grid(2,2) @@ -2255,10 +2248,10 @@ def markov_chain(self,state, distrib=None): V = self.vertices() n = len(V) if isinstance(st, list): - if len(st)==self.num_verts()-1: - st = SandpileConfig(self,st) - elif len(st)==self.num_verts(): - st = SandpileDivisor(self,st) + if len(st) == self.num_verts() - 1: + st = SandpileConfig(self, st) + elif len(st) == self.num_verts(): + st = SandpileDivisor(self, st) else: raise SyntaxError(state) if distrib is None: # default = uniform distribution @@ -2300,13 +2293,13 @@ def _set_stationary_density(self): """ if self.name() == 'Complete sandpile graph': n = Integer(self.num_verts()) - self._stationary_density = (n + QQ.one() / n + sum(falling_factorial(n,i)/n**i for i in range(1,n+1)) - 3)/2 + self._stationary_density = (n + QQ.one() / n + sum(falling_factorial(n, i) / n**i for i in range(1, n + 1)) - 3) / 2 elif self.is_undirected() and '_h_vector' not in self.__dict__: t = Graph(self).tutte_polynomial().subs(x=1) - myR = PolynomialRing(QQ,'y') + myR = PolynomialRing(QQ, 'y') y = myR.gens()[0] t = myR(t) - dt = derivative(t,y).subs(y=1) + dt = derivative(t, y).subs(y=1) t = t.subs(y=1) self._stationary_density = (self.num_edges()/2 + dt/t)/self.num_verts() else: @@ -2345,7 +2338,7 @@ def stationary_density(self): """ return self._stationary_density -#################### Functions for divisors ##################### + # ---------------- Functions for divisors ---------------- def all_k_div(self, k): r""" @@ -2452,9 +2445,9 @@ def betti_complexes(self): """ return deepcopy(self._betti_complexes) -####################################### -######### Algebraic Geometry ########## -####################################### + ####################################### + # Algebraic Geometry # + ####################################### def _set_ring(self): r""" @@ -2593,15 +2586,15 @@ def _set_resolution(self): # get the resolution in singular form res = self.ideal()._singular_().mres(0) # compute the betti numbers - #self._betti = [1] + [len(res[i]) + # self._betti = [1] + [len(res[i]) # for i in range(1,len(res)-2)] self._betti = [1] + [len(x) for x in res] # convert the resolution to a list of Sage poly matrices result = [] - zero = self._ring.gens()[0]*0 - for i in range(1, len(res)+1): + zero = self._ring.gens()[0] * 0 + for i in range(1, len(res) + 1): syz_mat = [] - new = [res[i][j] for j in range(1, int(res[i].size())+1)] + new = [res[i][j] for j in range(1, int(res[i].size()) + 1)] for j in range(self._betti[i]): row = new[j].transpose().sage_matrix(self._ring) row = [r for r in row[0]] @@ -2764,14 +2757,14 @@ def solve(self): vars_ = '({})'.format(','.join(str(i) for i in v)) L = singular.subst(self._ideal, - singular.var(singular.nvars(self._ring)), 1) + singular.var(singular.nvars(self._ring)), 1) _ = singular.ring(0, vars_, 'lp') K = singular.fetch(self._ring, L) K = singular.groebner(K) singular.LIB('solve.lib') M = K.solve(5, 1) singular.setring(M) - sol= singular('SOL').sage_structured_str_list() + sol = singular('SOL').sage_structured_str_list() sol = sol[0][0] sol = [[SR(j) for j in k] for k in sol] return sol @@ -2792,9 +2785,10 @@ def _set_points(self): n = self.num_verts() - 1 D, U, V = L.smith_form() self._points = [] - one = [1]*n + one = [1] * n + twopii = 2 * pi * I for k in range(n): - x = [exp(2*pi*I*U[k,t]/D[k,k]) for t in range(n)] + x = [exp(twopii * U[k, t] / D[k, k]) for t in range(n)] if x not in self._points and x != one: self._points.append(x) @@ -2859,7 +2853,7 @@ def symmetric_recurrents(self, orbits): """ sym_recurrents = [] active = [self._max_stable] - while active != []: + while active: c = active.pop() sym_recurrents.append(c) for orb in orbits: @@ -2871,8 +2865,9 @@ def symmetric_recurrents(self, orbits): active.append(cnext) return deepcopy(sym_recurrents) + ########################################## -########### SandpileConfig Class ######### +# SandpileConfig Class # ########################################## class SandpileConfig(dict): r""" @@ -2926,7 +2921,6 @@ def help(verbose=True): unstable -- The unstable vertices. values -- The values of the configuration as a list. """ - _sandpile_help(SandpileConfig, dedent("""\ Shortcuts for SandpileConfig operations: ~c -- stabilize @@ -2937,7 +2931,7 @@ def help(verbose=True): For detailed help with any method FOO listed below, enter "SandpileConfig.FOO?" or enter "c.FOO?" for any SandpileConfig c."""), - verbose=verbose) + verbose=verbose) def __init__(self, S, c): r""" @@ -2962,7 +2956,7 @@ def __init__(self, S, c): sage: ~(3*c) # stabilization {1: 2, 2: 2, 3: 0} """ - if len(c)==S.num_verts()-1: + if len(c) == S.num_verts()-1: if isinstance(c, (dict, SandpileConfig)): dict.__init__(self,c) elif isinstance(c, list): @@ -3547,8 +3541,8 @@ def fire_vertex(self, v): c = dict(self) c[v] -= self._sandpile.out_degree(v) for e in self._sandpile.outgoing_edges(v): - if e[1]!=self._sandpile.sink(): - c[e[1]]+=e[2] + if e[1] != self._sandpile.sink(): + c[e[1]] += e[2] return SandpileConfig(self._sandpile,c) def fire_script(self, sigma): @@ -3583,8 +3577,8 @@ def fire_script(self, sigma): v = self._vertices[i] c[v] -= sigma[i]*self._sandpile.out_degree(v) for e in self._sandpile.outgoing_edges(v): - if e[1]!=self._sandpile.sink(): - c[e[1]]+=sigma[i]*e[2] + if e[1] != self._sandpile.sink(): + c[e[1]] += sigma[i]*e[2] return SandpileConfig(self._sandpile, c) def unstable(self): @@ -3624,8 +3618,8 @@ def fire_unstable(self): for v in self.unstable(): c[v] -= self._sandpile.out_degree(v) for e in self._sandpile.outgoing_edges(v): - if e[1]!=self._sandpile.sink(): - c[e[1]]+=e[2] + if e[1] != self._sandpile.sink(): + c[e[1]] += e[2] return SandpileConfig(self._sandpile,c) def _set_stabilize(self): @@ -3727,7 +3721,6 @@ def support(self): """ return [i for i in self if self[i] !=0] - def add_random(self, distrib=None): r""" Add one grain of sand to a random vertex. Optionally, a probability @@ -3794,11 +3787,11 @@ def add_random(self, distrib=None): n = self._sandpile.num_verts() if distrib is None: # default = uniform distribution on nonsink vertices distrib = [QQ.one() / (n - 1)] * (n - 1) - if len(distrib)==n-1: # prob. dist. on nonsink vertices + if len(distrib) == n - 1: # prob. dist. on nonsink vertices X = GeneralDiscreteDistribution(distrib) V = self._sandpile.nonsink_vertices() c[V[X.get_random_element()]] += 1 - else: # prob. dist. on all the vertices + else: # prob. dist. on all the vertices X = GeneralDiscreteDistribution(distrib) V = self._sandpile.vertices() i = X.get_random_element() @@ -4128,7 +4121,7 @@ def burst_size(self, v): w = deepcopy(self) w[v] -= 1 w = w.equivalent_recurrent() - return w.deg() - self.deg() +1 + return w.deg() - self.deg() + 1 def show(self, sink=True, colors=True, heights=False, directed=None, **kwds): r""" @@ -4176,7 +4169,7 @@ def show(self, sink=True, colors=True, heights=False, directed=None, **kwds): T.relabel(a) if colors: vc = {} # vertex colors - r = rainbow(max_height) # colors + r = rainbow(max_height) # colors for i in range(max_height): vc[r[i]] = [] for i in self.sandpile().nonsink_vertices(): @@ -4198,7 +4191,7 @@ def show(self, sink=True, colors=True, heights=False, directed=None, **kwds): ############################################### -########### SandpileDivisor Class ############# +# SandpileDivisor Class # ############################################### class SandpileDivisor(dict): @@ -4256,11 +4249,10 @@ def help(verbose=True): weierstrass_pts -- The Weierstrass points (vertices). weierstrass_rank_seq -- The Weierstrass rank sequence at the given vertex. """ - _sandpile_help(SandpileDivisor, dedent("""\ For detailed help with any method FOO listed below, enter "SandpileDivisor.FOO?" or enter "D.FOO?" for any SandpileDivisor D."""), - verbose=verbose) + verbose=verbose) def __init__(self, S, D): r""" @@ -4282,9 +4274,8 @@ def __init__(self, S, D): sage: D = SandpileDivisor(S,[0,1,0,1,1,3]) sage: D.support() [1, 3, 4, 5] - """ - if len(D)==S.num_verts(): + if len(D) == S.num_verts(): if type(D) in [dict, SandpileDivisor, SandpileConfig]: dict.__init__(self,dict(D)) elif isinstance(D, list): @@ -5041,7 +5032,7 @@ def is_linearly_equivalent(self, D, with_firing_vector=False): D,U,V = self.sandpile()._smith_form b = v - w ub = U*b - if ub[-1]!=0: + if ub[-1] != 0: if with_firing_vector: return vector([]) else: @@ -5174,7 +5165,7 @@ def _set_linear_system(self): path_to_zsolve = FourTi2Executable('zsolve').absolute_filename() os.system(shlex.quote(path_to_zsolve) + ' -q ' + lin_sys + ' > ' + lin_sys_log) # process the results - zhom_file = open(lin_sys_zhom,'r') + zhom_file = open(lin_sys_zhom, 'r') except IOError: print(""" ********************************** @@ -5182,22 +5173,21 @@ def _set_linear_system(self): ********************************** """) return - ## first, the cone generators (the homogeneous points) + # first, the cone generators (the homogeneous points) a = zhom_file.read() zhom_file.close() a = a.split('\n') # a starts with two numbers. We are interested in the first one num_homog = int(a[0].split()[0]) - homog = [map(int,i.split()) for i in a[1:-1]] - ## second, the inhomogeneous points - zinhom_file = open(lin_sys_zinhom,'r') - b = zinhom_file.read() - zinhom_file.close() + homog = [map(int, i.split()) for i in a[1:-1]] + # second, the inhomogeneous points + with open(lin_sys_zinhom, 'r') as zinhom_file: + b = zinhom_file.read() b = b.split('\n') num_inhomog = int(b[0].split()[0]) - inhomog = [map(int,i.split()) for i in b[1:-1]] - self._linear_system = {'num_homog':num_homog, 'homog':homog, - 'num_inhomog':num_inhomog, 'inhomog':inhomog} + inhomog = [map(int, i.split()) for i in b[1:-1]] + self._linear_system = {'num_homog': num_homog, 'homog': homog, + 'num_inhomog': num_inhomog, 'inhomog': inhomog} def _set_polytope(self): r""" @@ -5376,9 +5366,9 @@ def effective_div(self, verbose=True, with_firing_vectors=False): return list(zip(eff, fv)) elif verbose: # verbose without firing vectors return eff - elif with_firing_vectors: # not verbose but with firing vectors + elif with_firing_vectors: # not verbose but with firing vectors return list(zip([i.values() for i in eff], fv)) - else: # not verbose, no firing vectors + else: # not verbose, no firing vectors return [i.values() for i in eff] def _set_rank(self, set_witness=False): @@ -5414,14 +5404,15 @@ def _set_rank(self, set_witness=False): """ S = self.sandpile() # If undirected and D has high degree, use Riemann-Roch. - if S.is_undirected() and not set_witness: # We've been careful about loops - g = sum(S.laplacian().diagonal())/2 - S.num_verts() + 1 - if self.deg() > 2*g - 2: + if S.is_undirected() and not set_witness: + # We've been careful about loops + g = sum(S.laplacian().diagonal()) / 2 - S.num_verts() + 1 + if self.deg() > 2 * g - 2: self._rank = self.deg() - g return # return early # If S is a complete sandpile graph and a witness is not needed, use # the Cori-Le Borgne algorithm - if S.name()=='Complete sandpile graph' and not set_witness: + if S.name() == 'Complete sandpile graph' and not set_witness: # Cori-LeBorgne algorithm n = S.num_verts() rk = -1 @@ -5446,9 +5437,9 @@ def _set_rank(self, set_witness=False): else: rk = -1 while True: - for e in integer_vectors_nk_fast_iter(rk+1,S.num_verts()): + for e in integer_vectors_nk_fast_iter(rk + 1, S.num_verts()): E = SandpileDivisor(S, e) - if (self - E).effective_div() == []: + if not (self - E).effective_div(): self._rank = rk self._rank_witness = E return @@ -5534,7 +5525,7 @@ def _set_r_of_D(self, verbose=False): eff = self.effective_div() n = self._sandpile.num_verts() r = -1 - if eff == []: + if not eff: self._r_of_D = (r, self) return else: @@ -5559,7 +5550,7 @@ def _set_r_of_D(self, verbose=False): C = d - w C = SandpileDivisor(self._sandpile,list(C)) eff = C.effective_div() - if eff == []: + if not eff: self._r_of_D = (r, SandpileDivisor(self._sandpile,list(w))) return level = new_level @@ -5643,10 +5634,10 @@ def weierstrass_gap_seq(self, v='sink', weight=True): `\mathrm{rank}(D), \mathrm{rank}(D - v), \mathrm{rank}(D - 2v), \dots` """ L = self.weierstrass_rank_seq(v) - gaps = [i for i in range(1,len(L)) if L[i]!=L[i-1]] + gaps = [i for i in range(1, len(L)) if L[i] != L[i - 1]] gaps = tuple(gaps) if weight: - return gaps, sum(gaps)-binomial(len(gaps)+1,2) + return gaps, sum(gaps) - binomial(len(gaps) + 1, 2) else: return gaps @@ -5811,7 +5802,7 @@ def _set_Dcomplex(self): simp.append(supp_E) result = [] simp.reverse() - while simp != []: + while simp: supp = simp.pop() test = True for s in simp: @@ -5955,7 +5946,7 @@ def _set_life(self): oldD = deepcopy(self) result = [oldD] while True: - if oldD.unstable()==[]: + if oldD.unstable() == []: self._life = [] return newD = oldD.fire_unstable() @@ -5989,10 +5980,7 @@ def is_alive(self, cycle=False): sage: D.is_alive(True) [{0: 4, 1: 3, 2: 3, 3: 2}, {0: 3, 1: 2, 2: 2, 3: 5}, {0: 1, 1: 4, 2: 4, 3: 3}] """ - if cycle: - return self._life - else: - return self._life != [] + return self._life if cycle else bool(self._life) def _set_stabilize(self): r""" @@ -6079,8 +6067,9 @@ def show(self, heights=True, directed=None, **kwds): # See note about this after the definition of SandpileConfig pretty.for_type(SandpileDivisor, pretty.for_type(dict, None)) + ####################################### -######### Some test graphs ############ +# Some test graphs # ####################################### def sandlib(selector=None): @@ -6114,54 +6103,37 @@ def sandlib(selector=None): """ # The convention is for the sink to be zero. sandpiles = { - 'generic':{ - 'description':'generic digraph with 6 vertices', - 'graph':{0:{},1:{0:1,3:1,4:1},2:{0:1,3:1,5:1},3:{2:1,5:1},4:{1:1,3:1},5:{2:1,3:1}} - }, - 'kite':{ - 'description':'generic undirected graphs with 5 vertices', - 'graph':{0:{}, 1:{0:1,2:1,3:1}, 2:{1:1,3:1,4:1}, 3:{1:1,2:1,4:1}, - 4:{2:1,3:1}} - }, - 'riemann-roch1':{ - 'description':'directed graph with postulation 9 and 3 maximal weight superstables', - 'graph':{0: {1: 3, 3: 1}, - 1: {0: 2, 2: 2, 3: 2}, - 2: {0: 1, 1: 1}, - 3: {0: 3, 1: 1, 2: 1} - } - }, - 'riemann-roch2':{ - 'description':'directed graph with a superstable not majorized by a maximal superstable', - 'graph':{ - 0: {}, - 1: {0: 1, 2: 1}, - 2: {0: 1, 3: 1}, - 3: {0: 1, 1: 1, 2: 1} - } - }, - 'gor':{ - 'description':'Gorenstein but not a complete intersection', - 'graph':{ - 0: {}, - 1: {0:1, 2: 1, 3: 4}, - 2: {3: 5}, - 3: {1: 1, 2: 1} - } - }, - 'ci1':{ - 'description':'complete intersection, non-DAG but equivalent to a DAG', - 'graph':{0:{}, 1: {2: 2}, 2: {0: 4, 1: 1}} - }, - 'genus2':{ - 'description':'Undirected graph of genus 2', - 'graph':{ - 0:[1,2], - 1:[0,2,3], - 2:[0,1,3], - 3:[1,2] - } - }, + 'generic': {'description': 'generic digraph with 6 vertices', + 'graph': {0: {}, 1: {0: 1, 3: 1, 4: 1}, + 2: {0: 1, 3: 1, 5: 1}, + 3: {2: 1, 5: 1}, 4: {1: 1, 3: 1}, + 5: {2: 1, 3: 1}}}, + 'kite': {'description': 'generic undirected graphs with 5 vertices', + 'graph': {0: {}, 1: {0: 1, 2: 1, 3: 1}, + 2: {1: 1, 3: 1, 4: 1}, 3: {1: 1, 2: 1, 4: 1}, + 4: {2: 1, 3: 1}}}, + 'riemann-roch1': {'description': 'directed graph with postulation 9 and 3 maximal weight superstables', + 'graph': {0: {1: 3, 3: 1}, + 1: {0: 2, 2: 2, 3: 2}, + 2: {0: 1, 1: 1}, + 3: {0: 3, 1: 1, 2: 1}}}, + 'riemann-roch2': {'description': 'directed graph with a superstable not majorized by a maximal superstable', + 'graph': {0: {}, + 1: {0: 1, 2: 1}, + 2: {0: 1, 3: 1}, + 3: {0: 1, 1: 1, 2: 1}}}, + 'gor': {'description': 'Gorenstein but not a complete intersection', + 'graph': {0: {}, + 1: {0: 1, 2: 1, 3: 4}, + 2: {3: 5}, + 3: {1: 1, 2: 1}}}, + 'ci1': {'description': 'complete intersection, non-DAG but equivalent to a DAG', + 'graph': {0: {}, 1: {2: 2}, 2: {0: 4, 1: 1}}}, + 'genus2': {'description': 'Undirected graph of genus 2', + 'graph': {0: [1, 2], + 1: [0, 2, 3], + 2: [0, 1, 3], + 3: [1, 2]}}, } if selector is None: print('') @@ -6174,11 +6146,11 @@ def sandlib(selector=None): else: return Sandpile(sandpiles[selector]['graph'], 0) + ################################################# -########## Some useful functions ################ +# Some useful functions # ################################################# - def triangle_sandpile(n): r""" A triangular sandpile. Each nonsink vertex has out-degree six. The @@ -6283,6 +6255,7 @@ def aztec_sandpile(n): aztec_sandpile[(0, 0)][vert] = out_degree return aztec_sandpile + def glue_graphs(g, h, glue_g, glue_h): r""" Glue two graphs together. @@ -6405,6 +6378,7 @@ def firing_graph(S, eff): g.add_edge((i,eff.index(new_div))) return g + def parallel_firing_graph(S, eff): r""" Creates a digraph with divisors as vertices and edges between two divisors @@ -6442,6 +6416,7 @@ def parallel_firing_graph(S, eff): g.add_edge((i,eff.index(new_div))) return g + def admissible_partitions(S, k): r""" The partitions of the vertices of `S` into `k` parts, each of which is @@ -6537,15 +6512,16 @@ def partition_sandpile(S, p): from sage.combinat.combination import Combinations g = Graph() g.add_vertices([tuple(i) for i in p]) - for u,v in Combinations(g.vertices(), 2): + for u, v in Combinations(g.vertices(), 2): for i in u: for j in v: - if (i,j,1) in S.edges(): + if (i, j, 1) in S.edges(): g.add_edge((u, v)) break for i in g.vertices(): if S.sink() in i: - return Sandpile(g,i) + return Sandpile(g, i) + def min_cycles(G, v): r""" @@ -6572,6 +6548,7 @@ def min_cycles(G, v): sp = G.shortest_paths(v) return [sp[i] for i in pr if i in sp] + def wilmes_algorithm(M): r""" Computes an integer matrix `L` with the same integer row span as `M` and From eb8340ec7fdfb6a87c161c350a0eef372037fb79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 6 Jun 2022 07:40:24 +0200 Subject: [PATCH 525/529] a few more changes in sandpile --- src/sage/sandpiles/sandpile.py | 51 +++++++++++++++------------------- 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/src/sage/sandpiles/sandpile.py b/src/sage/sandpiles/sandpile.py index 314135bede1..d28d7948d6b 100644 --- a/src/sage/sandpiles/sandpile.py +++ b/src/sage/sandpiles/sandpile.py @@ -1338,7 +1338,7 @@ def _set_recurrents(self): elif self.name() == 'Cycle sandpile graph': n = self.num_verts() one = [1] * (n - 2) - self._recurrents = [SandpileConfig(self, [1]*(n-1))] + [SandpileConfig(self, one[:i]+[0]+one[i:]) for i in range(n - 1)] + self._recurrents = [SandpileConfig(self, [1] * (n - 1))] + [SandpileConfig(self, one[:i] + [0] + one[i:]) for i in range(n - 1)] else: self._recurrents = [] active = [self._max_stable] @@ -1469,7 +1469,7 @@ def _set_group_gens(self): """ D, U, _ = self.reduced_laplacian().transpose().smith_form() F = U.inverse() - self._group_gens = [SandpileConfig(self,[Integer(j) for j in F.column(i)]).equivalent_recurrent() + self._group_gens = [SandpileConfig(self, [Integer(j) for j in F.column(i)]).equivalent_recurrent() for i in range(F.nrows()) if D[i][i] != 1] def group_gens(self, verbose=True): @@ -1521,7 +1521,7 @@ def genus(self): 1 """ if self.is_undirected(): - return self.laplacian().trace()/2 - self.num_verts() + 1 + return self.laplacian().trace() / 2 - self.num_verts() + 1 else: raise UserWarning("The underlying graph must be undirected.") @@ -1562,7 +1562,7 @@ def _set_min_recurrents(self): else: rec = list(self.recurrents()) for r in self.recurrents(): - if exists(rec, lambda x: r>x)[0]: + if exists(rec, lambda x: r > x)[0]: rec.remove(r) self._min_recurrents = rec @@ -1677,7 +1677,7 @@ def _set_avalanche_polynomial(self): True """ n = self.num_verts() - 1 - R = PolynomialRing(QQ,"x",n) + R = PolynomialRing(QQ, "x", n) A = R(0) V = [] for i in range(n): @@ -1687,7 +1687,7 @@ def _set_avalanche_polynomial(self): for r in self.recurrents(): for i in range(n): e = tuple((r + V[i]).stabilize(True)[1].values()) - A += R({e:1}) + A += R({e: 1}) self._avalanche_polynomial = A def avalanche_polynomial(self, multivariable=True): @@ -1726,10 +1726,9 @@ def avalanche_polynomial(self, multivariable=True): """ if multivariable: return deepcopy(self._avalanche_polynomial) - else: - R = self._avalanche_polynomial.parent() - X = R.gens() - return self._avalanche_polynomial.subs({X[i]:X[0] for i in range(1,self.num_verts()-1)}) + X = self._avalanche_polynomial.parent().gens() + return self._avalanche_polynomial.subs({X[i]: X[0] + for i in range(1, self.num_verts() - 1)}) def nonspecial_divisors(self, verbose=True): r""" @@ -1804,9 +1803,8 @@ def canonical_divisor(self): The underlying graph must be undirected. """ if self.is_undirected(): - return SandpileDivisor(self,[self.laplacian()[i][i] - 2 for i in range(self.num_verts())]) - else: - raise UserWarning("Only for undirected graphs.") + return SandpileDivisor(self, [self.laplacian()[i][i] - 2 for i in range(self.num_verts())]) + raise UserWarning("Only for undirected graphs.") def _set_invariant_factors(self): r""" @@ -1985,15 +1983,15 @@ def reorder_vertices(self): key=lambda v: self.distance(v, self._sink), reverse=True) perm = {} for i in range(len(verts)): - perm[verts[i]]=i + perm[verts[i]] = i old = self.dict() new = {} for i in old: entry = {} for j in old[i]: - entry[perm[j]]=old[i][j] + entry[perm[j]] = old[i][j] new[perm[i]] = entry - return Sandpile(new,len(verts)-1) + return Sandpile(new, len(verts) - 1) def _set_jacobian_representatives(self): r""" @@ -2011,26 +2009,23 @@ def _set_jacobian_representatives(self): else: ker = self.laplacian().left_kernel().basis() tau = abs(ker[self._sink_ind]) - if tau==1: - easy = True - else: - easy = False + easy = bool(tau == 1) if easy: result = [] for r in self.superstables(): - D = {v:r[v] for v in self._nonsink_vertices} + D = {v: r[v] for v in self._nonsink_vertices} D[self._sink] = - r.deg() result.append(SandpileDivisor(self, D)) self._jacobian_representatives = result else: result = [] sr = self.superstables() - order = self.group_order()/tau - while len(result) Date: Mon, 6 Jun 2022 11:16:20 +0200 Subject: [PATCH 526/529] cleaning two files in graphs/ --- src/sage/graphs/bipartite_graph.py | 72 ++++++++++++++------------- src/sage/graphs/digraph_generators.py | 33 ++++++------ 2 files changed, 56 insertions(+), 49 deletions(-) diff --git a/src/sage/graphs/bipartite_graph.py b/src/sage/graphs/bipartite_graph.py index 6d95e9c07c1..2ec92b073a1 100644 --- a/src/sage/graphs/bipartite_graph.py +++ b/src/sage/graphs/bipartite_graph.py @@ -11,7 +11,7 @@ - Ryan W. Hinton (2010-03-04): overrides for adding and deleting vertices and edges -- Enjeck M. Cleopatra(2022): fixes incorrect partite sets and adds graph +- Enjeck M. Cleopatra (2022): fixes incorrect partite sets and adds graph creation from graph6 string TESTS:: @@ -20,16 +20,13 @@ sage: loads(dumps(B)) == B True -:: - sage: B = BipartiteGraph(graphs.CycleGraph(4)) sage: B == B.copy() True sage: type(B.copy()) """ - -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2008 Robert L. Miller # 2018 Julian Rüth # 2022 Enjeck M. Cleopatra @@ -40,7 +37,6 @@ # (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** - from collections import defaultdict from collections.abc import Iterable import itertools @@ -48,9 +44,9 @@ from .generic_graph import GenericGraph from .graph import Graph from sage.rings.integer import Integer - from sage.misc.decorators import rename_keyword + class BipartiteGraph(Graph): r""" Bipartite graph. @@ -259,7 +255,7 @@ class BipartiteGraph(Graph): sage: B = BipartiteGraph(file_name) sage: B.is_isomorphic(H) True - + #. From a ``graph6`` string:: sage: B = BipartiteGraph('Bo') @@ -282,14 +278,14 @@ class BipartiteGraph(Graph): {0, 1, 2, 3} sage: B.right {4, 5, 6} - + :: sage: B = BipartiteGraph('Bo', partition=[[0], [1, 2]]) sage: B.left {0} sage: B.right {1, 2} - + :: sage: B = BipartiteGraph('F?^T_\n', partition=[[0, 1, 2], [3, 4, 5, 6]]) @@ -423,12 +419,12 @@ def __init__(self, data=None, partition=None, check=True, *args, **kwds): # methods; initialize left and right attributes self.left = set() self.right = set() - + # determine partitions and populate self.left and self.right if not alist_file: if partition is not None: left, right = set(partition[0]), set(partition[1]) - + # Some error checking. if left & right: raise ValueError("the parts are not disjoint") @@ -1321,7 +1317,7 @@ def matching_polynomial(self, algorithm="Godsil", name=None): n = A.ncols() b = [0] * (m + n + 1) for i in range(min(m, n) + 1): - b[m + n - 2*i] = a[i] * (-1) ** i + b[m + n - 2 * i] = a[i] * (-1)**i if name is None: name = 'x' K = PolynomialRing(A.base_ring(), name) @@ -1528,7 +1524,8 @@ def load_afile(self, fname): # read header information num_cols, num_rows = [int(_) for _ in fi.readline().split()] - max_col_degree, max_row_degree = [int(_) for _ in fi.readline().split()] + # next are max_col_degree, max_row_degree, not used + _ = [int(_) for _ in fi.readline().split()] col_degrees = [int(_) for _ in fi.readline().split()] row_degrees = [int(_) for _ in fi.readline().split()] @@ -1636,8 +1633,12 @@ def save_afile(self, fname): max_cdeg = max(self.degree(cnodes)) vnode_to_str = {v: str(i + 1) for i, v in enumerate(vnodes)} cnode_to_str = {v: str(i + 1) for i, v in enumerate(cnodes)} - vnbr_str = lambda idx: cnode_to_str[idx] - cnbr_str = lambda idx: vnode_to_str[idx] + + def vnbr_str(idx): + return cnode_to_str[idx] + + def cnbr_str(idx): + return vnode_to_str[idx] # write header information fi.write("%d %d\n" % (len(vnodes), len(cnodes))) @@ -1962,7 +1963,8 @@ class :class:`MixedIntegerLinearProgram m = networkx.bipartite.hopcroft_karp_matching(h) else: m = networkx.bipartite.eppstein_matching(h) - d.extend((u, v, g.edge_label(u,v)) for u,v in m.items() if v2int[u] < v2int[v]) + d.extend((u, v, g.edge_label(u, v)) for u, v in m.items() + if v2int[u] < v2int[v]) if value_only: return Integer(len(d)) @@ -2087,11 +2089,13 @@ def vertex_cover(self, algorithm="Konig", value_only=False, sage: all(B.vertex_cover(algorithm=algo, value_only=True) == 0 for algo in algorithms) True """ - if not algorithm == "Konig": - return Graph.vertex_cover(self, algorithm=algorithm, value_only=value_only, - reduction_rules=reduction_rules, solver=solver, - verbose=verbose, - integrality_tolerance=integrality_tolerance) + if algorithm != "Konig": + return Graph.vertex_cover(self, algorithm=algorithm, + value_only=value_only, + reduction_rules=reduction_rules, + solver=solver, + verbose=verbose, + integrality_tolerance=integrality_tolerance) if not self.is_connected(): VC = [] @@ -2346,9 +2350,9 @@ class by some canonization function `c`. If `G` and `H` are graphs, EXAMPLES:: - sage: B = BipartiteGraph( [(0, 4), (0, 5), (0, 6), (0, 8), (1, 5), + sage: B = BipartiteGraph( [(0, 4), (0, 5), (0, 6), (0, 8), (1, 5), ....: (1, 7), (1, 8), (2, 6), (2, 7), (2, 8), - ....: (3, 4), (3, 7), (3, 8), (4, 9), (5, 9), + ....: (3, 4), (3, 7), (3, 8), (4, 9), (5, 9), ....: (6, 9), (7, 9)] ) sage: C = B.canonical_label(partition=(B.left,B.right), algorithm='sage') sage: C @@ -2360,9 +2364,9 @@ class by some canonization function `c`. If `G` and `H` are graphs, :: - sage: B = BipartiteGraph( [(0, 4), (0, 5), (0, 6), (0, 8), (1, 5), + sage: B = BipartiteGraph( [(0, 4), (0, 5), (0, 6), (0, 8), (1, 5), ....: (1, 7), (1, 8), (2, 6), (2, 7), (2, 8), - ....: (3, 4), (3, 7), (3, 8), (4, 9), (5, 9), + ....: (3, 4), (3, 7), (3, 8), (4, 9), (5, 9), ....: (6, 9), (7, 9)] ) sage: C, cert = B.canonical_label(partition=(B.left,B.right), certificate=True, algorithm='sage') sage: C @@ -2389,10 +2393,10 @@ class by some canonization function `c`. If `G` and `H` are graphs, :meth:`~sage.graphs.generic_graph.GenericGraph.canonical_label()` """ - + if certificate: C, cert = GenericGraph.canonical_label(self, partition=partition, certificate=certificate, edge_labels=edge_labels, algorithm=algorithm, return_graph=return_graph) - + else: from sage.groups.perm_gps.partn_ref.refinement_graphs import search_tree from sage.graphs.graph import Graph @@ -2400,25 +2404,25 @@ class by some canonization function `c`. If `G` and `H` are graphs, from itertools import chain cert = {} - + if edge_labels or self.has_multiple_edges(): G, partition, relabeling = graph_isom_equivalent_non_edge_labeled_graph(self, partition, return_relabeling=True) G_vertices = list(chain(*partition)) - G_to = {u: i for i,u in enumerate(G_vertices)} + G_to = {u: i for i, u in enumerate(G_vertices)} H = Graph(len(G_vertices)) HB = H._backend - for u,v in G.edge_iterator(labels=False): + for u, v in G.edge_iterator(labels=False): HB.add_edge(G_to[u], G_to[v], None, False) GC = HB.c_graph()[0] partition = [[G_to[vv] for vv in cell] for cell in partition] a, b, c = search_tree(GC, partition, certificate=True, dig=False) - # c is a permutation to the canonical label of G, + # c is a permutation to the canonical label of G, # which depends only on isomorphism class of self. cert = {v: c[G_to[relabeling[v]]] for v in self} - + else: G_vertices = list(chain(*partition)) - G_to = {u: i for i,u in enumerate(G_vertices)} + G_to = {u: i for i, u in enumerate(G_vertices)} H = Graph(len(G_vertices)) HB = H._backend for u, v in self.edge_iterator(labels=False): diff --git a/src/sage/graphs/digraph_generators.py b/src/sage/graphs/digraph_generators.py index 9b6209ffc2f..d464c0e090d 100644 --- a/src/sage/graphs/digraph_generators.py +++ b/src/sage/graphs/digraph_generators.py @@ -65,13 +65,14 @@ # (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.cpython.string import bytes_to_str - import sys +import subprocess + +from sage.cpython.string import bytes_to_str from sage.misc.randstate import current_randstate from sage.graphs.digraph import DiGraph from sage.graphs.graph import Graph -import subprocess + class DiGraphGenerators(): r""" @@ -345,7 +346,7 @@ def Path(self, n): if n: g.add_path(list(range(n))) - g.set_pos({i: (i,0) for i in range(n)}) + g.set_pos({i: (i, 0) for i in range(n)}) return g def Paley(self, q): @@ -397,8 +398,10 @@ def Paley(self, q): raise ValueError("parameter q must be a prime power") if not mod(q, 4) == 3: raise ValueError("parameter q must be congruent to 3 mod 4") - g = DiGraph([FiniteField(q,'a'), lambda i,j: (i!=j) and (j-i).is_square()], - loops=False, name="Paley digraph with parameter {}".format(q)) + g = DiGraph([FiniteField(q, 'a'), + lambda i, j: (i != j) and (j - i).is_square()], + loops=False, + name="Paley digraph with parameter {}".format(q)) return g def TransitiveTournament(self, n): @@ -545,7 +548,7 @@ def tournaments_nauty(self, n, if strongly_connected: nauty_input += " -c" - nauty_input += " " + str(n) + " " + nauty_input += " " + str(n) + " " import shlex from sage.features.nauty import NautyExecutable @@ -979,7 +982,6 @@ def GeneralizedDeBruijn(self, n, d): GB.add_edge(u, a % n) return GB - def ImaseItoh(self, n, d): r""" Return the Imase-Itoh digraph of order `n` and degree `d`. @@ -1045,7 +1047,6 @@ def ImaseItoh(self, n, d): II.add_edge(u, a % n) return II - def Kautz(self, k, D, vertices='strings'): r""" Return the Kautz digraph of degree `d` and diameter `D`. @@ -1251,7 +1252,7 @@ def RandomDirectedAcyclicGraph(self, n, p, weight_max=None): # integers are on 31 bits. We thus set the pivot value to p*2^31 from sage.misc.prandom import randint from sage.misc.randstate import random - RAND_MAX_f = float(1<<31) + RAND_MAX_f = float(1 << 31) pp = int(round(float(p * RAND_MAX_f))) if weight_max is None: @@ -1265,11 +1266,11 @@ def RandomDirectedAcyclicGraph(self, n, p, weight_max=None): D = DiGraph(n, name=f"RandomWeightedDAG({n}, {p}, {weight_max})") D.add_edges((i, j, randint(1, weight_max)) - for i in range(n) for j in range(i) if random() < pp) + for i in range(n) for j in range(i) if random() < pp) return D - def RandomDirectedGN(self, n, kernel=lambda x:x, seed=None): + def RandomDirectedGN(self, n, kernel=lambda x: x, seed=None): r""" Return a random growing network (GN) digraph with `n` vertices. @@ -1376,7 +1377,7 @@ def RandomDirectedGNP(self, n, p, loops=False, seed=None): if seed is None: seed = current_randstate().long_seed() - return RandomGNP(n, p, directed=True, loops=loops) + return RandomGNP(n, p, directed=True, loops=loops, seed=seed) def RandomDirectedGNM(self, n, m, loops=False): r""" @@ -1672,9 +1673,11 @@ def __call__(self, vertices=None, property=lambda x: True, augment='edges', """ from copy import copy as copyfun if size is not None: - extra_property = lambda x: x.size() == size + def extra_property(x): + return x.size() == size else: - extra_property = lambda x: True + def extra_property(x): + return True if augment == 'vertices': if vertices is None: raise NotImplementedError From 905a6bb15b1e8e41b074e35658df397902bc9e75 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Mon, 6 Jun 2022 16:55:22 +0200 Subject: [PATCH 527/529] trac #33959: some care in sandpile.py --- src/sage/sandpiles/sandpile.py | 81 +++++++++++++++++----------------- 1 file changed, 40 insertions(+), 41 deletions(-) diff --git a/src/sage/sandpiles/sandpile.py b/src/sage/sandpiles/sandpile.py index d28d7948d6b..74ebc2541c2 100644 --- a/src/sage/sandpiles/sandpile.py +++ b/src/sage/sandpiles/sandpile.py @@ -616,21 +616,24 @@ def __init__(self, g, sink=None): h = g.to_dictionary(multiple_edges=True) g = {i: dict(Counter(h[i])) for i in h} else: - vi = {v: g.vertices().index(v) for v in g.vertices()} + vi = {v: i for i, v in enumerate(g.vertices())} ad = g.weighted_adjacency_matrix() - g = {v: {w: ad[vi[v], vi[w]] for w in g.neighbors(v)} - for v in g.vertices()} + g = {v: {w: ad[vi[v], vi[w]] for w in g.neighbor_iterator(v)} + for v in g} else: raise SyntaxError(g) # create digraph and initialize some variables DiGraph.__init__(self, g, weighted=True) self._dict = deepcopy(g) + vertices = self.vertices() if sink is None: - sink = self.vertices()[0] - self._sink = sink # key for sink - self._sink_ind = self.vertices().index(sink) - self._nonsink_vertices = deepcopy(self.vertices()) + self._sink = vertices[0] + self._sink_ind = 0 + else: + self._sink = sink # key for sink + self._sink_ind = vertices.index(sink) + self._nonsink_vertices = vertices del self._nonsink_vertices[self._sink_ind] # compute Laplacians: self._laplacian = self.laplacian_matrix(indegree=False) @@ -1041,8 +1044,8 @@ def _set_in_degrees(self): sage: '_in_degrees' in s.__dict__ True """ - self._in_degrees = {v: 0 for v in self.vertices()} - for e in self.edges(): + self._in_degrees = {v: 0 for v in self} + for e in self.edge_iterator(): self._in_degrees[e[1]] += e[2] def in_degree(self, v=None): @@ -1977,13 +1980,10 @@ def reorder_vertices(self): sage: T.dict() {0: {1: 1}, 1: {0: 1, 2: 1}, 2: {0: 1}} """ - - # first order the vertices according to their distance from the sink - verts = sorted(self.vertices(), - key=lambda v: self.distance(v, self._sink), reverse=True) - perm = {} - for i in range(len(verts)): - perm[verts[i]] = i + # first order the vertices according to their distance to the sink + distance_to_sink = self.reverse().shortest_path_lengths(self._sink) + verts = sorted(self, key=lambda v: distance_to_sink[v], reverse=True) + perm = {v: i for i, v in enumerate(verts)} old = self.dict() new = {} for i in old: @@ -2455,12 +2455,13 @@ def _set_ring(self): sage: '_ring' in S.__dict__ True """ - # first order the vertices according to their distance from the sink - verts = sorted(self.vertices(), - key=lambda v: self.distance(v, self._sink)) + # first order the vertices according to their distance to the sink + distance_to_sink = self.reverse().shortest_path_lengths(self._sink) + verts = sorted(self, key=lambda v: distance_to_sink[v]) # variable i refers to the i-th vertex in self.vertices() - names = [self.vertices().index(v) for v in reversed(verts)] + vertex_to_int = {v: i for i, v in enumerate(self.vertices())} + names = [vertex_to_int[v] for v in reversed(verts)] vars = '' for i in names: @@ -2471,11 +2472,11 @@ def _set_ring(self): # create the ideal gens = [] for i in self.nonsink_vertices(): - new_gen = 'x' + str(self.vertices().index(i)) + new_gen = 'x' + str(vertex_to_int[i]) new_gen += '^' + str(self.out_degree(i)) new_gen += '-' for j in self._dict[i]: - new_gen += 'x' + str(self.vertices().index(j)) + new_gen += 'x' + str(vertex_to_int[j]) new_gen += '^' + str(self._dict[i][j]) + '*' new_gen = new_gen[:-1] gens.append(new_gen) @@ -3535,7 +3536,7 @@ def fire_vertex(self, v): """ c = dict(self) c[v] -= self._sandpile.out_degree(v) - for e in self._sandpile.outgoing_edges(v): + for e in self._sandpile.outgoing_edge_iterator(v): if e[1] != self._sandpile.sink(): c[e[1]] += e[2] return SandpileConfig(self._sandpile,c) @@ -3571,7 +3572,7 @@ def fire_script(self, sigma): for i in range(len(sigma)): v = self._vertices[i] c[v] -= sigma[i]*self._sandpile.out_degree(v) - for e in self._sandpile.outgoing_edges(v): + for e in self._sandpile.outgoing_edge_iterator(v): if e[1] != self._sandpile.sink(): c[e[1]] += sigma[i]*e[2] return SandpileConfig(self._sandpile, c) @@ -3612,7 +3613,7 @@ def fire_unstable(self): c = dict(self) for v in self.unstable(): c[v] -= self._sandpile.out_degree(v) - for e in self._sandpile.outgoing_edges(v): + for e in self._sandpile.outgoing_edge_iterator(v): if e[1] != self._sandpile.sink(): c[e[1]] += e[2] return SandpileConfig(self._sandpile,c) @@ -3638,7 +3639,7 @@ def _set_stabilize(self): dm = divmod(c[v],s.out_degree(v)) c[v] = dm[1] firing_vector[v] += dm[0] - for e in s.outgoing_edges(v): + for e in s.outgoing_edge_iterator(v): if e[1] != s.sink(): c[e[1]] += dm[0]* e[2] unstable = c.unstable() @@ -4156,8 +4157,8 @@ def show(self, sink=True, colors=True, heights=False, directed=None, **kwds): T.delete_vertex(self.sandpile().sink()) if heights: a = {} - for i in T.vertices(): - if i==self.sandpile().sink(): + for i in T: + if i == self.sandpile().sink(): a[i] = str(i) else: a[i] = str(i)+":"+str(self[i]) @@ -4272,12 +4273,12 @@ def __init__(self, S, D): """ if len(D) == S.num_verts(): if type(D) in [dict, SandpileDivisor, SandpileConfig]: - dict.__init__(self,dict(D)) + dict.__init__(self, dict(D)) elif isinstance(D, list): div = {} - for i in range(S.num_verts()): - div[S.vertices()[i]] = D[i] - dict.__init__(self,div) + for i, v in enumerate(S.vertices()): + div[v] = D[i] + dict.__init__(self, div) else: raise SyntaxError(D) @@ -4809,8 +4810,8 @@ def fire_vertex(self, v): """ D = dict(self) D[v] -= self._sandpile.out_degree(v) - for e in self._sandpile.outgoing_edges(v): - D[e[1]]+=e[2] + for e in self._sandpile.outgoing_edge_iterator(v): + D[e[1]] += e[2] return SandpileDivisor(self._sandpile,D) def fire_script(self, sigma): @@ -4844,8 +4845,8 @@ def fire_script(self, sigma): for i in range(len(sigma)): v = self._vertices[i] D[v] -= sigma[i]*self._sandpile.out_degree(v) - for e in self._sandpile.outgoing_edges(v): - D[e[1]]+=sigma[i]*e[2] + for e in self._sandpile.outgoing_edge_iterator(v): + D[e[1]] += sigma[i] * e[2] return SandpileDivisor(self._sandpile, D) def unstable(self): @@ -4884,8 +4885,8 @@ def fire_unstable(self): D = dict(self) for v in self.unstable(): D[v] -= self._sandpile.out_degree(v) - for e in self._sandpile.outgoing_edges(v): - D[e[1]]+=e[2] + for e in self._sandpile.outgoing_edge_iterator(v): + D[e[1]] += e[2] return SandpileDivisor(self._sandpile,D) def _set_q_reduced(self): @@ -6052,9 +6053,7 @@ def show(self, heights=True, directed=None, **kwds): T = Graph(self.sandpile()) if heights: - a = {} - for i in T.vertices(): - a[i] = str(i) + ":" + str(T[i]) + a = {i: str(i) + ":" + str(T[i]) for i in T} T.relabel(a) T.show(**kwds) From ddda2f46316b586aff6fdce5b4b43eaa56184e76 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Mon, 6 Jun 2022 17:07:03 +0200 Subject: [PATCH 528/529] trac #33959: another change --- src/sage/sandpiles/sandpile.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/sage/sandpiles/sandpile.py b/src/sage/sandpiles/sandpile.py index 74ebc2541c2..0d9563dc291 100644 --- a/src/sage/sandpiles/sandpile.py +++ b/src/sage/sandpiles/sandpile.py @@ -4275,10 +4275,8 @@ def __init__(self, S, D): if type(D) in [dict, SandpileDivisor, SandpileConfig]: dict.__init__(self, dict(D)) elif isinstance(D, list): - div = {} - for i, v in enumerate(S.vertices()): - div[v] = D[i] - dict.__init__(self, div) + div = {v: D[i] for i, v in enumerate(S.vertices())} + dict.__init__(self, div) else: raise SyntaxError(D) From a6e696e91d2f2a3ab91031b3e1fcd795af3e6e62 Mon Sep 17 00:00:00 2001 From: Release Manager Date: Sun, 12 Jun 2022 14:18:49 +0200 Subject: [PATCH 529/529] Updated SageMath version to 9.7.beta2 --- .zenodo.json | 8 ++++---- VERSION.txt | 2 +- build/pkgs/configure/checksums.ini | 6 +++--- build/pkgs/configure/package-version.txt | 2 +- pkgs/sage-conf/VERSION.txt | 2 +- pkgs/sage-conf_pypi/VERSION.txt | 2 +- pkgs/sage-docbuild/VERSION.txt | 2 +- pkgs/sage-setup/VERSION.txt | 2 +- pkgs/sage-sws2rst/VERSION.txt | 2 +- pkgs/sagemath-categories/VERSION.txt | 2 +- pkgs/sagemath-environment/VERSION.txt | 2 +- pkgs/sagemath-objects/VERSION.txt | 2 +- pkgs/sagemath-repl/VERSION.txt | 2 +- src/VERSION.txt | 2 +- src/bin/sage-version.sh | 6 +++--- src/sage/version.py | 6 +++--- 16 files changed, 25 insertions(+), 25 deletions(-) diff --git a/.zenodo.json b/.zenodo.json index be408937a6f..f05573e690c 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -1,10 +1,10 @@ { "description": "Mirror of the Sage https://sagemath.org/ source tree", "license": "other-open", - "title": "sagemath/sage: 9.7.beta1", - "version": "9.7.beta1", + "title": "sagemath/sage: 9.7.beta2", + "version": "9.7.beta2", "upload_type": "software", - "publication_date": "2022-05-26", + "publication_date": "2022-06-12", "creators": [ { "affiliation": "SageMath.org", @@ -15,7 +15,7 @@ "related_identifiers": [ { "scheme": "url", - "identifier": "https://github.com/sagemath/sage/tree/9.7.beta1", + "identifier": "https://github.com/sagemath/sage/tree/9.7.beta2", "relation": "isSupplementTo" }, { diff --git a/VERSION.txt b/VERSION.txt index 8cb99453ed0..8f5b1728548 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -SageMath version 9.7.beta1, Release Date: 2022-05-26 +SageMath version 9.7.beta2, Release Date: 2022-06-12 diff --git a/build/pkgs/configure/checksums.ini b/build/pkgs/configure/checksums.ini index 2f353640452..1bc9808428d 100644 --- a/build/pkgs/configure/checksums.ini +++ b/build/pkgs/configure/checksums.ini @@ -1,4 +1,4 @@ tarball=configure-VERSION.tar.gz -sha1=6d548fec179a7c4d71f327f409320a06e0d9d35e -md5=7289e1187b21d5cd30a891838410fcd0 -cksum=1487266202 +sha1=fee64e7ae45bcfd9bfa1c55605a579f49b19057e +md5=42d9e4a2308a8c01f4e68f3915c3b856 +cksum=3408158874 diff --git a/build/pkgs/configure/package-version.txt b/build/pkgs/configure/package-version.txt index 615282f9973..d45eb7f9401 100644 --- a/build/pkgs/configure/package-version.txt +++ b/build/pkgs/configure/package-version.txt @@ -1 +1 @@ -6b0fd1ca2d493aec6beadae8b15f926c19070098 +b95c1659af1d26926ddf421d28b2d1f76dbc4810 diff --git a/pkgs/sage-conf/VERSION.txt b/pkgs/sage-conf/VERSION.txt index 24562793a28..4cd5a231c54 100644 --- a/pkgs/sage-conf/VERSION.txt +++ b/pkgs/sage-conf/VERSION.txt @@ -1 +1 @@ -9.6.rc3 +9.7.beta2 diff --git a/pkgs/sage-conf_pypi/VERSION.txt b/pkgs/sage-conf_pypi/VERSION.txt index 24562793a28..4cd5a231c54 100644 --- a/pkgs/sage-conf_pypi/VERSION.txt +++ b/pkgs/sage-conf_pypi/VERSION.txt @@ -1 +1 @@ -9.6.rc3 +9.7.beta2 diff --git a/pkgs/sage-docbuild/VERSION.txt b/pkgs/sage-docbuild/VERSION.txt index 24562793a28..4cd5a231c54 100644 --- a/pkgs/sage-docbuild/VERSION.txt +++ b/pkgs/sage-docbuild/VERSION.txt @@ -1 +1 @@ -9.6.rc3 +9.7.beta2 diff --git a/pkgs/sage-setup/VERSION.txt b/pkgs/sage-setup/VERSION.txt index 24562793a28..4cd5a231c54 100644 --- a/pkgs/sage-setup/VERSION.txt +++ b/pkgs/sage-setup/VERSION.txt @@ -1 +1 @@ -9.6.rc3 +9.7.beta2 diff --git a/pkgs/sage-sws2rst/VERSION.txt b/pkgs/sage-sws2rst/VERSION.txt index 24562793a28..4cd5a231c54 100644 --- a/pkgs/sage-sws2rst/VERSION.txt +++ b/pkgs/sage-sws2rst/VERSION.txt @@ -1 +1 @@ -9.6.rc3 +9.7.beta2 diff --git a/pkgs/sagemath-categories/VERSION.txt b/pkgs/sagemath-categories/VERSION.txt index 24562793a28..4cd5a231c54 100644 --- a/pkgs/sagemath-categories/VERSION.txt +++ b/pkgs/sagemath-categories/VERSION.txt @@ -1 +1 @@ -9.6.rc3 +9.7.beta2 diff --git a/pkgs/sagemath-environment/VERSION.txt b/pkgs/sagemath-environment/VERSION.txt index 27f66583915..4cd5a231c54 100644 --- a/pkgs/sagemath-environment/VERSION.txt +++ b/pkgs/sagemath-environment/VERSION.txt @@ -1 +1 @@ -9.6.rc3.post2 +9.7.beta2 diff --git a/pkgs/sagemath-objects/VERSION.txt b/pkgs/sagemath-objects/VERSION.txt index be2310e2ea1..4cd5a231c54 100644 --- a/pkgs/sagemath-objects/VERSION.txt +++ b/pkgs/sagemath-objects/VERSION.txt @@ -1 +1 @@ -9.6.rc3.post4 +9.7.beta2 diff --git a/pkgs/sagemath-repl/VERSION.txt b/pkgs/sagemath-repl/VERSION.txt index 24562793a28..4cd5a231c54 100644 --- a/pkgs/sagemath-repl/VERSION.txt +++ b/pkgs/sagemath-repl/VERSION.txt @@ -1 +1 @@ -9.6.rc3 +9.7.beta2 diff --git a/src/VERSION.txt b/src/VERSION.txt index 6442b83e510..4cd5a231c54 100644 --- a/src/VERSION.txt +++ b/src/VERSION.txt @@ -1 +1 @@ -9.7.beta1 +9.7.beta2 diff --git a/src/bin/sage-version.sh b/src/bin/sage-version.sh index bc8b231097a..3dc222edd01 100644 --- a/src/bin/sage-version.sh +++ b/src/bin/sage-version.sh @@ -1,5 +1,5 @@ # Sage version information for shell scripts # This file is auto-generated by the sage-update-version script, do not edit! -SAGE_VERSION='9.7.beta1' -SAGE_RELEASE_DATE='2022-05-26' -SAGE_VERSION_BANNER='SageMath version 9.7.beta1, Release Date: 2022-05-26' +SAGE_VERSION='9.7.beta2' +SAGE_RELEASE_DATE='2022-06-12' +SAGE_VERSION_BANNER='SageMath version 9.7.beta2, Release Date: 2022-06-12' diff --git a/src/sage/version.py b/src/sage/version.py index 6671c264512..3ea94539369 100644 --- a/src/sage/version.py +++ b/src/sage/version.py @@ -1,5 +1,5 @@ # Sage version information for Python scripts # This file is auto-generated by the sage-update-version script, do not edit! -version = '9.7.beta1' -date = '2022-05-26' -banner = 'SageMath version 9.7.beta1, Release Date: 2022-05-26' +version = '9.7.beta2' +date = '2022-06-12' +banner = 'SageMath version 9.7.beta2, Release Date: 2022-06-12'